diff --git a/wgpu-hal/src/vulkan/adapter.rs b/wgpu-hal/src/vulkan/adapter.rs index d1deba019d7..78c43ad15b0 100644 --- a/wgpu-hal/src/vulkan/adapter.rs +++ b/wgpu-hal/src/vulkan/adapter.rs @@ -1883,6 +1883,7 @@ impl super::Instance { depth_stencil_required_flags(), ), multi_draw_indirect: phd_features.core.multi_draw_indirect != 0, + max_draw_indirect_count: phd_capabilities.properties.limits.max_draw_indirect_count, non_coherent_map_mask: phd_capabilities.properties.limits.non_coherent_atom_size - 1, can_present: true, //TODO: make configurable diff --git a/wgpu-hal/src/vulkan/command.rs b/wgpu-hal/src/vulkan/command.rs index 95c28edab51..0286f11f530 100644 --- a/wgpu-hal/src/vulkan/command.rs +++ b/wgpu-hal/src/vulkan/command.rs @@ -1128,15 +1128,34 @@ impl crate::CommandEncoder for super::CommandEncoder { offset: wgt::BufferAddress, draw_count: u32, ) { - unsafe { - self.device.raw.cmd_draw_indirect( - self.active, - buffer.raw, - offset, - draw_count, - size_of::() as u32, - ) - }; + if draw_count >= 1 + && self.device.private_caps.multi_draw_indirect + && draw_count <= self.device.private_caps.max_draw_indirect_count + { + unsafe { + self.device.raw.cmd_draw_indirect( + self.active, + buffer.raw, + offset, + draw_count, + size_of::() as u32, + ) + }; + } else { + for i in 0..draw_count { + unsafe { + self.device.raw.cmd_draw_indirect( + self.active, + buffer.raw, + offset + + i as wgt::BufferAddress + * size_of::() as wgt::BufferAddress, + 1, + size_of::() as u32, + ) + }; + } + } } unsafe fn draw_indexed_indirect( &mut self, @@ -1144,7 +1163,10 @@ impl crate::CommandEncoder for super::CommandEncoder { offset: wgt::BufferAddress, draw_count: u32, ) { - if draw_count >= 1 && self.device.private_caps.multi_draw_indirect { + if draw_count >= 1 + && self.device.private_caps.multi_draw_indirect + && draw_count <= self.device.private_caps.max_draw_indirect_count + { unsafe { self.device.raw.cmd_draw_indexed_indirect( self.active, @@ -1155,12 +1177,14 @@ impl crate::CommandEncoder for super::CommandEncoder { ) }; } else { - for _ in 0..draw_count { + for i in 0..draw_count { unsafe { self.device.raw.cmd_draw_indexed_indirect( self.active, buffer.raw, - offset, + offset + + i as wgt::BufferAddress + * size_of::() as wgt::BufferAddress, 1, size_of::() as u32, ) diff --git a/wgpu-hal/src/vulkan/mod.rs b/wgpu-hal/src/vulkan/mod.rs index c0c35c7ed2f..d5b66018c21 100644 --- a/wgpu-hal/src/vulkan/mod.rs +++ b/wgpu-hal/src/vulkan/mod.rs @@ -319,6 +319,7 @@ struct PrivateCapabilities { can_present: bool, non_coherent_map_mask: wgt::BufferAddress, multi_draw_indirect: bool, + max_draw_indirect_count: u32, /// True if this adapter advertises the [`robustBufferAccess`][vrba] feature. ///