diff --git a/wgpu-core/src/device/mod.rs b/wgpu-core/src/device/mod.rs index 7589f6676f..61dc9af20d 100644 --- a/wgpu-core/src/device/mod.rs +++ b/wgpu-core/src/device/mod.rs @@ -2355,19 +2355,40 @@ impl Global { } } - if let Some(start_binding) = write_map.keys().next().cloned() { - let descriptors = write_map - .into_iter() - .flat_map(|(_, list)| list) - .collect::>(); - let write = hal::pso::DescriptorSetWrite { - set: desc_set.raw(), - binding: start_binding, - array_offset: 0, - descriptors, - }; + if !write_map.is_empty() { + #[derive(PartialEq)] + enum DescriptorType { + Buffer, + Sampler, + TextureView, + } + let mut writes = Vec::>>::new(); + let mut prev_stages = wgt::ShaderStage::empty(); + let mut prev_ty = DescriptorType::Buffer; + for (binding, list) in write_map { + let layout = &bind_group_layout.entries[&binding]; + let ty = match layout.ty { + wgt::BindingType::UniformBuffer { .. } + | wgt::BindingType::StorageBuffer { .. } => DescriptorType::Buffer, + wgt::BindingType::Sampler { .. } => DescriptorType::Sampler, + wgt::BindingType::SampledTexture { .. } + | wgt::BindingType::StorageTexture { .. } => DescriptorType::TextureView, + }; + if layout.visibility == prev_stages && ty == prev_ty { + writes.last_mut().unwrap().descriptors.extend(list); + } else { + prev_stages = layout.visibility; + prev_ty = ty; + writes.push(hal::pso::DescriptorSetWrite { + set: desc_set.raw(), + binding, + array_offset: 0, + descriptors: list.into_iter().collect(), + }); + } + } unsafe { - device.raw.write_descriptor_sets(iter::once(write)); + device.raw.write_descriptor_sets(writes); } } desc_set