diff --git a/examples/hello_compute_rust/main.rs b/examples/hello_compute_rust/main.rs index f8eebc968b..cbdd1d2daa 100644 --- a/examples/hello_compute_rust/main.rs +++ b/examples/hello_compute_rust/main.rs @@ -83,7 +83,7 @@ fn main() { { let mut cpass = encoder.begin_compute_pass(); cpass.set_pipeline(&compute_pipeline); - cpass.set_bind_group(0, &bind_group); + cpass.set_bind_group(0, &bind_group, &[]); cpass.dispatch(numbers.len() as u32, 1, 1); } encoder.copy_buffer_to_buffer(&storage_buffer, 0, &staging_buffer, 0, size); diff --git a/examples/hello_triangle_rust/main.rs b/examples/hello_triangle_rust/main.rs index 2275bde1e7..8efeecd03e 100644 --- a/examples/hello_triangle_rust/main.rs +++ b/examples/hello_triangle_rust/main.rs @@ -122,7 +122,7 @@ fn main() { depth_stencil_attachment: None, }); rpass.set_pipeline(&render_pipeline); - rpass.set_bind_group(0, &bind_group); + rpass.set_bind_group(0, &bind_group, &[]); rpass.draw(0..3, 0..1); } diff --git a/gfx-examples/src/cube.rs b/gfx-examples/src/cube.rs index a8de95d9e7..d145d76e51 100644 --- a/gfx-examples/src/cube.rs +++ b/gfx-examples/src/cube.rs @@ -330,7 +330,7 @@ impl framework::Example for Example { depth_stencil_attachment: None, }); rpass.set_pipeline(&self.pipeline); - rpass.set_bind_group(0, &self.bind_group); + rpass.set_bind_group(0, &self.bind_group, &[]); rpass.set_index_buffer(&self.index_buf, 0); rpass.set_vertex_buffers(&[(&self.vertex_buf, 0)]); rpass.draw_indexed(0..self.index_count as u32, 0, 0..1); diff --git a/gfx-examples/src/shadow.rs b/gfx-examples/src/shadow.rs index 323963cc32..5da7be96c8 100644 --- a/gfx-examples/src/shadow.rs +++ b/gfx-examples/src/shadow.rs @@ -741,10 +741,10 @@ impl framework::Example for Example { }), }); pass.set_pipeline(&self.shadow_pass.pipeline); - pass.set_bind_group(0, &self.shadow_pass.bind_group); + pass.set_bind_group(0, &self.shadow_pass.bind_group, &[]); for entity in &self.entities { - pass.set_bind_group(1, &entity.bind_group); + pass.set_bind_group(1, &entity.bind_group, &[]); pass.set_index_buffer(&entity.index_buf, 0); pass.set_vertex_buffers(&[(&entity.vertex_buf, 0)]); pass.draw_indexed(0..entity.index_count as u32, 0, 0..1); @@ -776,10 +776,10 @@ impl framework::Example for Example { }), }); pass.set_pipeline(&self.forward_pass.pipeline); - pass.set_bind_group(0, &self.forward_pass.bind_group); + pass.set_bind_group(0, &self.forward_pass.bind_group, &[]); for entity in &self.entities { - pass.set_bind_group(1, &entity.bind_group); + pass.set_bind_group(1, &entity.bind_group, &[]); pass.set_index_buffer(&entity.index_buf, 0); pass.set_vertex_buffers(&[(&entity.vertex_buf, 0)]); pass.draw_indexed(0..entity.index_count as u32, 0, 0..1); diff --git a/wgpu-bindings/wgpu.h b/wgpu-bindings/wgpu.h index 7781d3c379..2c07c8270d 100644 --- a/wgpu-bindings/wgpu.h +++ b/wgpu-bindings/wgpu.h @@ -21,6 +21,8 @@ typedef enum { WGPUBindingType_Sampler = 1, WGPUBindingType_SampledTexture = 2, WGPUBindingType_StorageBuffer = 3, + WGPUBindingType_UniformBufferDynamic = 4, + WGPUBindingType_StorageBufferDynamic = 5, } WGPUBindingType; typedef enum { diff --git a/wgpu-native/src/binding_model.rs b/wgpu-native/src/binding_model.rs index 317755ebd4..fe7b5b1873 100644 --- a/wgpu-native/src/binding_model.rs +++ b/wgpu-native/src/binding_model.rs @@ -21,6 +21,8 @@ pub enum BindingType { Sampler = 1, SampledTexture = 2, StorageBuffer = 3, + UniformBufferDynamic = 4, + StorageBufferDynamic = 5, } #[repr(C)] diff --git a/wgpu-native/src/command/bind.rs b/wgpu-native/src/command/bind.rs index 88e43cfd06..db7670fecb 100644 --- a/wgpu-native/src/command/bind.rs +++ b/wgpu-native/src/command/bind.rs @@ -46,13 +46,13 @@ pub struct BindGroupEntry { } impl BindGroupEntry { - fn provide(&mut self, bind_group_id: BindGroupId, bind_group: &BindGroupHandle) -> Provision { + fn provide(&mut self, bind_group_id: BindGroupId, bind_group: &BindGroupHandle, offsets: &[u32]) -> Provision { let was_compatible = match self.provided { Some(BindGroupPair { layout_id, ref group_id, }) => { - if group_id.value == bind_group_id { + if group_id.value == bind_group_id && offsets.is_empty() { assert_eq!(layout_id, bind_group.layout_id); return Provision::Unchanged; } @@ -135,9 +135,10 @@ impl Binder { index: usize, bind_group_id: BindGroupId, bind_group: &BindGroupHandle, + offsets: &[u32], ) -> Option<(PipelineLayoutId, impl 'a + Iterator)> { trace!("\tBinding [{}] = group {:?}", index, bind_group_id); - match self.entries[index].provide(bind_group_id, bind_group) { + match self.entries[index].provide(bind_group_id, bind_group, offsets) { Provision::Unchanged => None, Provision::Changed { now_compatible: false, diff --git a/wgpu-native/src/command/compute.rs b/wgpu-native/src/command/compute.rs index ea11e9c69d..6ed464b784 100644 --- a/wgpu-native/src/command/compute.rs +++ b/wgpu-native/src/command/compute.rs @@ -56,6 +56,7 @@ pub extern "C" fn wgpu_compute_pass_set_bind_group( pass_id: ComputePassId, index: u32, bind_group_id: BindGroupId, + offsets: &[u32], ) { let mut pass_guard = HUB.compute_passes.write(); let pass = &mut pass_guard[pass_id]; @@ -76,7 +77,7 @@ pub extern "C" fn wgpu_compute_pass_set_bind_group( if let Some((pipeline_layout_id, follow_up)) = pass.binder - .provide_entry(index as usize, bind_group_id, bind_group) + .provide_entry(index as usize, bind_group_id, bind_group, offsets) { let pipeline_layout_guard = HUB.pipeline_layouts.read(); let bind_groups = @@ -86,7 +87,7 @@ pub extern "C" fn wgpu_compute_pass_set_bind_group( &pipeline_layout_guard[pipeline_layout_id].raw, index as usize, bind_groups, - &[], + offsets, ); } }; diff --git a/wgpu-native/src/command/render.rs b/wgpu-native/src/command/render.rs index ce3d0dfd84..a23af2b480 100644 --- a/wgpu-native/src/command/render.rs +++ b/wgpu-native/src/command/render.rs @@ -224,6 +224,7 @@ pub extern "C" fn wgpu_render_pass_set_bind_group( pass_id: RenderPassId, index: u32, bind_group_id: BindGroupId, + offsets: &[u32], ) { let mut pass_guard = HUB.render_passes.write(); let pass = &mut pass_guard[pass_id]; @@ -234,7 +235,7 @@ pub extern "C" fn wgpu_render_pass_set_bind_group( if let Some((pipeline_layout_id, follow_up)) = pass.binder - .provide_entry(index as usize, bind_group_id, bind_group) + .provide_entry(index as usize, bind_group_id, bind_group, offsets) { let pipeline_layout_guard = HUB.pipeline_layouts.read(); let bind_groups = @@ -244,7 +245,7 @@ pub extern "C" fn wgpu_render_pass_set_bind_group( &&pipeline_layout_guard[pipeline_layout_id].raw, index as usize, bind_groups, - &[], + offsets, ); } }; diff --git a/wgpu-native/src/conv.rs b/wgpu-native/src/conv.rs index b4d20f517e..b74144cd8e 100644 --- a/wgpu-native/src/conv.rs +++ b/wgpu-native/src/conv.rs @@ -78,6 +78,8 @@ pub fn map_binding_type(binding_ty: binding_model::BindingType) -> hal::pso::Des Sampler => H::Sampler, SampledTexture => H::SampledImage, StorageBuffer => H::StorageBuffer, + UniformBufferDynamic => H::UniformBufferDynamic, + StorageBufferDynamic => H::StorageBufferDynamic, } } diff --git a/wgpu-native/src/device.rs b/wgpu-native/src/device.rs index 0d51482b92..610d394273 100644 --- a/wgpu-native/src/device.rs +++ b/wgpu-native/src/device.rs @@ -462,10 +462,18 @@ impl Device { ty: hal::pso::DescriptorType::UniformBuffer, count: 10000, }, + hal::pso::DescriptorRangeDesc { + ty: hal::pso::DescriptorType::UniformBufferDynamic, + count: 100, + }, hal::pso::DescriptorRangeDesc { ty: hal::pso::DescriptorType::StorageBuffer, count: 1000, }, + hal::pso::DescriptorRangeDesc { + ty: hal::pso::DescriptorType::StorageBufferDynamic, + count: 100, + }, ], ) } @@ -1025,13 +1033,17 @@ pub fn device_create_bind_group( ) .unwrap(); let alignment = match decl.ty { - binding_model::BindingType::UniformBuffer => { + binding_model::BindingType::UniformBuffer + | binding_model::BindingType::UniformBufferDynamic => { device.limits.min_uniform_buffer_offset_alignment } - binding_model::BindingType::StorageBuffer => { + binding_model::BindingType::StorageBuffer + | binding_model::BindingType::StorageBufferDynamic => { device.limits.min_storage_buffer_offset_alignment } - _ => panic!("Mismatched buffer binding for {:?}", decl), + binding_model::BindingType::Sampler + | binding_model::BindingType::SampledTexture => + panic!("Mismatched buffer binding for {:?}", decl), }; assert_eq!( bb.offset as hal::buffer::Offset % alignment, diff --git a/wgpu-rs/src/lib.rs b/wgpu-rs/src/lib.rs index 2edd6fff34..7bddfe800e 100644 --- a/wgpu-rs/src/lib.rs +++ b/wgpu-rs/src/lib.rs @@ -838,8 +838,8 @@ impl CommandEncoder { } impl<'a> RenderPass<'a> { - pub fn set_bind_group(&mut self, index: u32, bind_group: &BindGroup) { - wgn::wgpu_render_pass_set_bind_group(self.id, index, bind_group.id); + pub fn set_bind_group(&mut self, index: u32, bind_group: &BindGroup, offsets: &[u32]) { + wgn::wgpu_render_pass_set_bind_group(self.id, index, bind_group.id, offsets); } pub fn set_pipeline(&mut self, pipeline: &RenderPipeline) { @@ -898,8 +898,8 @@ impl<'a> Drop for RenderPass<'a> { } impl<'a> ComputePass<'a> { - pub fn set_bind_group(&mut self, index: u32, bind_group: &BindGroup) { - wgn::wgpu_compute_pass_set_bind_group(self.id, index, bind_group.id); + pub fn set_bind_group(&mut self, index: u32, bind_group: &BindGroup, offsets: &[u32]) { + wgn::wgpu_compute_pass_set_bind_group(self.id, index, bind_group.id, offsets); } pub fn set_pipeline(&mut self, pipeline: &ComputePipeline) {