summaryrefslogtreecommitdiffstats
path: root/wgpu/src/image.rs
diff options
context:
space:
mode:
Diffstat (limited to 'wgpu/src/image.rs')
-rw-r--r--wgpu/src/image.rs172
1 files changed, 95 insertions, 77 deletions
diff --git a/wgpu/src/image.rs b/wgpu/src/image.rs
index 96c9ab6d..5dc972ac 100644
--- a/wgpu/src/image.rs
+++ b/wgpu/src/image.rs
@@ -8,7 +8,7 @@ pub struct Pipeline {
cache: RefCell<HashMap<String, Memory>>,
pipeline: wgpu::RenderPipeline,
- transform: wgpu::Buffer,
+ uniforms: wgpu::Buffer,
vertices: wgpu::Buffer,
indices: wgpu::Buffer,
instances: wgpu::Buffer,
@@ -46,14 +46,16 @@ impl Pipeline {
],
});
- let matrix: [f32; 16] = Transformation::identity().into();
+ let uniforms = Uniforms {
+ transform: Transformation::identity().into(),
+ };
- let transform_buffer = device
+ let uniforms_buffer = device
.create_buffer_mapped(
- 16,
+ 1,
wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
)
- .fill_from_slice(&matrix[..]);
+ .fill_from_slice(&[uniforms]);
let constant_bind_group =
device.create_bind_group(&wgpu::BindGroupDescriptor {
@@ -62,8 +64,8 @@ impl Pipeline {
wgpu::Binding {
binding: 0,
resource: wgpu::BindingResource::Buffer {
- buffer: &transform_buffer,
- range: 0..64,
+ buffer: &uniforms_buffer,
+ range: 0..std::mem::size_of::<Uniforms>() as u64,
},
},
wgpu::Binding {
@@ -186,7 +188,7 @@ impl Pipeline {
cache: RefCell::new(HashMap::new()),
pipeline,
- transform: transform_buffer,
+ uniforms: uniforms_buffer,
vertices,
indices,
instances,
@@ -203,12 +205,15 @@ impl Pipeline {
fn load(&self, path: &str) {
if !self.cache.borrow().contains_key(path) {
- let image = image::open(path).expect("Load image").to_bgra();
-
- let _ = self
- .cache
- .borrow_mut()
- .insert(path.to_string(), Memory::Host { image });
+ let memory = if let Ok(image) = image::open(path) {
+ Memory::Host {
+ image: image.to_bgra(),
+ }
+ } else {
+ Memory::NotFound
+ };
+
+ let _ = self.cache.borrow_mut().insert(path.to_string(), memory);
}
}
@@ -221,16 +226,18 @@ impl Pipeline {
bounds: Rectangle<u32>,
target: &wgpu::TextureView,
) {
- let transform_buffer = device
- .create_buffer_mapped(16, wgpu::BufferUsage::COPY_SRC)
- .fill_from_slice(transformation.as_ref());
+ let uniforms_buffer = device
+ .create_buffer_mapped(1, wgpu::BufferUsage::COPY_SRC)
+ .fill_from_slice(&[Uniforms {
+ transform: transformation.into(),
+ }]);
encoder.copy_buffer_to_buffer(
- &transform_buffer,
+ &uniforms_buffer,
0,
- &self.transform,
+ &self.uniforms,
0,
- 16 * 4,
+ std::mem::size_of::<Uniforms>() as u64,
);
// TODO: Batch draw calls using a texture atlas
@@ -240,68 +247,70 @@ impl Pipeline {
for image in instances {
self.load(&image.path);
- let texture = self
+ if let Some(texture) = self
.cache
.borrow_mut()
.get_mut(&image.path)
.unwrap()
- .upload(device, encoder, &self.texture_layout);
-
- let instance_buffer = device
- .create_buffer_mapped(1, wgpu::BufferUsage::COPY_SRC)
- .fill_from_slice(&[Instance {
- _position: image.position,
- _scale: image.scale,
- }]);
-
- encoder.copy_buffer_to_buffer(
- &instance_buffer,
- 0,
- &self.instances,
- 0,
- mem::size_of::<Image>() as u64,
- );
-
+ .upload(device, encoder, &self.texture_layout)
{
- let mut render_pass =
- encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
- color_attachments: &[
- wgpu::RenderPassColorAttachmentDescriptor {
- attachment: target,
- resolve_target: None,
- load_op: wgpu::LoadOp::Load,
- store_op: wgpu::StoreOp::Store,
- clear_color: wgpu::Color {
- r: 0.0,
- g: 0.0,
- b: 0.0,
- a: 0.0,
- },
- },
- ],
- depth_stencil_attachment: None,
- });
-
- render_pass.set_pipeline(&self.pipeline);
- render_pass.set_bind_group(0, &self.constants, &[]);
- render_pass.set_bind_group(1, &texture, &[]);
- render_pass.set_index_buffer(&self.indices, 0);
- render_pass.set_vertex_buffers(
+ let instance_buffer = device
+ .create_buffer_mapped(1, wgpu::BufferUsage::COPY_SRC)
+ .fill_from_slice(&[Instance {
+ _position: image.position,
+ _scale: image.scale,
+ }]);
+
+ encoder.copy_buffer_to_buffer(
+ &instance_buffer,
0,
- &[(&self.vertices, 0), (&self.instances, 0)],
- );
- render_pass.set_scissor_rect(
- bounds.x,
- bounds.y,
- bounds.width,
- bounds.height,
- );
-
- render_pass.draw_indexed(
- 0..QUAD_INDICES.len() as u32,
+ &self.instances,
0,
- 0..1 as u32,
+ mem::size_of::<Instance>() as u64,
);
+
+ {
+ let mut render_pass = encoder.begin_render_pass(
+ &wgpu::RenderPassDescriptor {
+ color_attachments: &[
+ wgpu::RenderPassColorAttachmentDescriptor {
+ attachment: target,
+ resolve_target: None,
+ load_op: wgpu::LoadOp::Load,
+ store_op: wgpu::StoreOp::Store,
+ clear_color: wgpu::Color {
+ r: 0.0,
+ g: 0.0,
+ b: 0.0,
+ a: 0.0,
+ },
+ },
+ ],
+ depth_stencil_attachment: None,
+ },
+ );
+
+ render_pass.set_pipeline(&self.pipeline);
+ render_pass.set_bind_group(0, &self.constants, &[]);
+ render_pass.set_bind_group(1, &texture, &[]);
+ render_pass.set_index_buffer(&self.indices, 0);
+ render_pass.set_vertex_buffers(
+ 0,
+ &[(&self.vertices, 0), (&self.instances, 0)],
+ );
+ render_pass.set_scissor_rect(
+ bounds.x,
+ bounds.y,
+ bounds.width,
+ bounds.height,
+ );
+
+ render_pass.draw_indexed(
+ 0..QUAD_INDICES.len() as u32,
+ 0,
+ 0..1 as u32,
+ );
+ }
}
}
}
@@ -317,6 +326,7 @@ enum Memory {
width: u32,
height: u32,
},
+ NotFound,
}
impl Memory {
@@ -324,6 +334,7 @@ impl Memory {
match self {
Memory::Host { image } => image.dimensions(),
Memory::Device { width, height, .. } => (*width, *height),
+ Memory::NotFound => (1, 1),
}
}
@@ -332,7 +343,7 @@ impl Memory {
device: &wgpu::Device,
encoder: &mut wgpu::CommandEncoder,
texture_layout: &wgpu::BindGroupLayout,
- ) -> Rc<wgpu::BindGroup> {
+ ) -> Option<Rc<wgpu::BindGroup>> {
match self {
Memory::Host { image } => {
let (width, height) = image.dimensions();
@@ -402,9 +413,10 @@ impl Memory {
height,
};
- bind_group
+ Some(bind_group)
}
- Memory::Device { bind_group, .. } => bind_group.clone(),
+ Memory::Device { bind_group, .. } => Some(bind_group.clone()),
+ Memory::NotFound => None,
}
}
}
@@ -442,3 +454,9 @@ struct Instance {
_position: [f32; 2],
_scale: [f32; 2],
}
+
+#[repr(C)]
+#[derive(Debug, Clone, Copy)]
+struct Uniforms {
+ transform: [f32; 16],
+}