Skip to content

Commit bec772b

Browse files
authored
hal/vulkan: Fix multi draw indirect emulating and respect maxDrawIndirectCount (#8665)
1 parent 5444e19 commit bec772b

File tree

3 files changed

+40
-12
lines changed

3 files changed

+40
-12
lines changed

wgpu-hal/src/vulkan/adapter.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1912,6 +1912,7 @@ impl super::Instance {
19121912
depth_stencil_required_flags(),
19131913
),
19141914
multi_draw_indirect: phd_features.core.multi_draw_indirect != 0,
1915+
max_draw_indirect_count: phd_capabilities.properties.limits.max_draw_indirect_count,
19151916
non_coherent_map_mask: phd_capabilities.properties.limits.non_coherent_atom_size - 1,
19161917
can_present: true,
19171918
//TODO: make configurable

wgpu-hal/src/vulkan/command.rs

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,23 +1129,46 @@ impl crate::CommandEncoder for super::CommandEncoder {
11291129
offset: wgt::BufferAddress,
11301130
draw_count: u32,
11311131
) {
1132-
unsafe {
1133-
self.device.raw.cmd_draw_indirect(
1134-
self.active,
1135-
buffer.raw,
1136-
offset,
1137-
draw_count,
1138-
size_of::<wgt::DrawIndirectArgs>() as u32,
1139-
)
1140-
};
1132+
if draw_count >= 1
1133+
&& self.device.private_caps.multi_draw_indirect
1134+
&& draw_count <= self.device.private_caps.max_draw_indirect_count
1135+
{
1136+
unsafe {
1137+
self.device.raw.cmd_draw_indirect(
1138+
self.active,
1139+
buffer.raw,
1140+
offset,
1141+
draw_count,
1142+
size_of::<wgt::DrawIndirectArgs>() as u32,
1143+
)
1144+
};
1145+
} else {
1146+
for i in 0..draw_count {
1147+
let indirect_offset = offset
1148+
+ i as wgt::BufferAddress
1149+
* size_of::<wgt::DrawIndirectArgs>() as wgt::BufferAddress;
1150+
unsafe {
1151+
self.device.raw.cmd_draw_indirect(
1152+
self.active,
1153+
buffer.raw,
1154+
indirect_offset,
1155+
1,
1156+
size_of::<wgt::DrawIndirectArgs>() as u32,
1157+
)
1158+
};
1159+
}
1160+
}
11411161
}
11421162
unsafe fn draw_indexed_indirect(
11431163
&mut self,
11441164
buffer: &super::Buffer,
11451165
offset: wgt::BufferAddress,
11461166
draw_count: u32,
11471167
) {
1148-
if draw_count >= 1 && self.device.private_caps.multi_draw_indirect {
1168+
if draw_count >= 1
1169+
&& self.device.private_caps.multi_draw_indirect
1170+
&& draw_count <= self.device.private_caps.max_draw_indirect_count
1171+
{
11491172
unsafe {
11501173
self.device.raw.cmd_draw_indexed_indirect(
11511174
self.active,
@@ -1156,12 +1179,15 @@ impl crate::CommandEncoder for super::CommandEncoder {
11561179
)
11571180
};
11581181
} else {
1159-
for _ in 0..draw_count {
1182+
for i in 0..draw_count {
1183+
let indirect_offset = offset
1184+
+ i as wgt::BufferAddress
1185+
* size_of::<wgt::DrawIndexedIndirectArgs>() as wgt::BufferAddress;
11601186
unsafe {
11611187
self.device.raw.cmd_draw_indexed_indirect(
11621188
self.active,
11631189
buffer.raw,
1164-
offset,
1190+
indirect_offset,
11651191
1,
11661192
size_of::<wgt::DrawIndexedIndirectArgs>() as u32,
11671193
)

wgpu-hal/src/vulkan/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,7 @@ struct PrivateCapabilities {
319319
can_present: bool,
320320
non_coherent_map_mask: wgt::BufferAddress,
321321
multi_draw_indirect: bool,
322+
max_draw_indirect_count: u32,
322323

323324
/// True if this adapter advertises the [`robustBufferAccess`][vrba] feature.
324325
///

0 commit comments

Comments
 (0)