mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Merge #131
131: Support dynamic offsets r=kvark a=cloudhead Closes #125 Adds support for dynamic offsets when setting a bind group. I haven't actually tried if this works with my use-case, but it's fairly straight forward. 😅 Co-authored-by: Alexis Sellier <alexis@monadic.xyz>
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -21,6 +21,8 @@ typedef enum {
|
||||
WGPUBindingType_Sampler = 1,
|
||||
WGPUBindingType_SampledTexture = 2,
|
||||
WGPUBindingType_StorageBuffer = 3,
|
||||
WGPUBindingType_UniformBufferDynamic = 4,
|
||||
WGPUBindingType_StorageBufferDynamic = 5,
|
||||
} WGPUBindingType;
|
||||
|
||||
typedef enum {
|
||||
|
||||
@@ -21,6 +21,8 @@ pub enum BindingType {
|
||||
Sampler = 1,
|
||||
SampledTexture = 2,
|
||||
StorageBuffer = 3,
|
||||
UniformBufferDynamic = 4,
|
||||
StorageBufferDynamic = 5,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
||||
@@ -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<Item = BindGroupId>)> {
|
||||
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,
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -462,10 +462,18 @@ impl<B: hal::Backend> Device<B> {
|
||||
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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user