Skip to content

Commit

Permalink
Merge #754
Browse files Browse the repository at this point in the history
754: Implement MultiDrawIndirect Extensions r=kvark a=cwfitzgerald

**Connections**

Closes #742.

**Description**

These extensions, especially when combined with binding indexing, allow the creation of extremely cpu-efficient gpu powered pipelines.

Adds two extensions allowing various types of multi-draw-indirect
- MULTI_DRAW_INDIRECT (giving `multi_draw_indirect` and `multi_draw_indexed_indirect`)
- MULTI_DRAW_INDIRECT_COUNT (giving `multi_draw_indirect_count` and `multi_draw_indexed_indirect_count`)

This adds what I believe to be an extra restriction on the `*count` family of functions when compared to the underlying api. The buffer _must_ be large enough to draw `max_count` draws, even if that many draws are never drawn. This makes these operations no more unsafe than indirect would be, which is currently safe.

I did not implement these for renderbundles, but there's no reason they couldn't work, so those branches are marked with `unimplemented` as opposed to `unreachable`.

Additional Changes:
- Added some validation to the normal `draw_*_indirect` functions to prevent buffer overruns.
- The DX12 gfx-hal backend requires the strides to _always_ be non-zero, so I modified the normal indirect draws to use explicit strides.
- Made device limits and features `pub(crate)` as they need to be checked in random places in the code.

**Testing**

The change was tested using a modified version of wgpu-rs's texture-array example using a variety of permutations. I have not been able to test regular MULTI_DRAW_INDIRECT on mac, but I see no reason why that wouldn't work.

gfx-rs/wgpu-rs#414

Co-authored-by: Connor Fitzgerald <connorwadefitzgerald@gmail.com>
  • Loading branch information
bors[bot] and cwfitzgerald authored Jun 28, 2020
2 parents a79222d + 441b6e0 commit 43c67ac
Show file tree
Hide file tree
Showing 7 changed files with 340 additions and 44 deletions.
18 changes: 9 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions wgpu-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ bitflags = "1.0"
copyless = "0.1"
fxhash = "0.2"
log = "0.4"
hal = { package = "gfx-hal", version = "0.5.2" }
hal = { package = "gfx-hal", version = "0.5.3" }
gfx-backend-empty = "0.5"
parking_lot = "0.10"
raw-window-handle = { version = "0.3", optional = true }
Expand Down Expand Up @@ -60,15 +60,15 @@ version = "0.5"

[target.'cfg(any(target_os = "ios", target_os = "macos"))'.dependencies]
gfx-backend-metal = { version = "0.5.4" }
gfx-backend-vulkan = { version = "0.5.6", optional = true }
gfx-backend-vulkan = { version = "0.5.9", optional = true }

[target.'cfg(all(unix, not(target_os = "ios"), not(target_os = "macos")))'.dependencies]
gfx-backend-vulkan = { version = "0.5.6" }
gfx-backend-vulkan = { version = "0.5.9" }

[target.'cfg(windows)'.dependencies]
gfx-backend-dx12 = { version = "0.5.6" }
gfx-backend-dx12 = { version = "0.5.8" }
gfx-backend-dx11 = { version = "0.5" }
gfx-backend-vulkan = { version = "0.5.8" }
gfx-backend-vulkan = { version = "0.5.9" }

[target.'cfg(any(target_os = "linux", target_os = "macos", target_os = "windows", target_os = "dragonfly", target_os = "freebsd"))'.dependencies]
battery = { version = "0.7", optional = true }
Expand Down
46 changes: 34 additions & 12 deletions wgpu-core/src/command/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,14 +203,26 @@ impl RenderBundle {
first_instance..first_instance + instance_count,
);
}
RenderCommand::DrawIndirect { buffer_id, offset } => {
RenderCommand::MultiDrawIndirect {
buffer_id,
offset,
count: None,
indexed: false,
} => {
let buffer = &buffer_guard[buffer_id];
comb.draw_indirect(&buffer.raw, offset, 1, 0);
}
RenderCommand::DrawIndexedIndirect { buffer_id, offset } => {
RenderCommand::MultiDrawIndirect {
buffer_id,
offset,
count: None,
indexed: true,
} => {
let buffer = &buffer_guard[buffer_id];
comb.draw_indexed_indirect(&buffer.raw, offset, 1, 0);
}
RenderCommand::MultiDrawIndirect { .. }
| RenderCommand::MultiDrawIndirectCount { .. } => unimplemented!(),
RenderCommand::PushDebugGroup { color: _, len: _ } => unimplemented!(),
RenderCommand::InsertDebugMarker { color: _, len: _ } => unimplemented!(),
RenderCommand::PopDebugGroup => unimplemented!(),
Expand Down Expand Up @@ -652,9 +664,11 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
commands.extend(state.flush_binds());
commands.push(command);
}
RenderCommand::DrawIndirect {
RenderCommand::MultiDrawIndirect {
buffer_id,
offset: _,
count: None,
indexed: false,
} => {
let buffer = state
.trackers
Expand All @@ -671,9 +685,11 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
commands.extend(state.flush_binds());
commands.push(command);
}
RenderCommand::DrawIndexedIndirect {
RenderCommand::MultiDrawIndirect {
buffer_id,
offset: _,
count: None,
indexed: true,
} => {
let buffer = state
.trackers
Expand All @@ -691,6 +707,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
commands.extend(state.flush_binds());
commands.push(command);
}
RenderCommand::MultiDrawIndirect { .. }
| RenderCommand::MultiDrawIndirectCount { .. } => unimplemented!(),
RenderCommand::PushDebugGroup { color: _, len: _ } => unimplemented!(),
RenderCommand::InsertDebugMarker { color: _, len: _ } => unimplemented!(),
RenderCommand::PopDebugGroup => unimplemented!(),
Expand Down Expand Up @@ -872,10 +890,12 @@ pub mod bundle_ffi {
offset: BufferAddress,
) {
span!(_guard, DEBUG, "RenderBundle::draw_indirect");
bundle
.base
.commands
.push(RenderCommand::DrawIndirect { buffer_id, offset });
bundle.base.commands.push(RenderCommand::MultiDrawIndirect {
buffer_id,
offset,
count: None,
indexed: false,
});
}

#[no_mangle]
Expand All @@ -885,10 +905,12 @@ pub mod bundle_ffi {
offset: BufferAddress,
) {
span!(_guard, DEBUG, "RenderBundle::draw_indexed_indirect");
bundle
.base
.commands
.push(RenderCommand::DrawIndexedIndirect { buffer_id, offset });
bundle.base.commands.push(RenderCommand::MultiDrawIndirect {
buffer_id,
offset,
count: None,
indexed: true,
});
}

#[no_mangle]
Expand Down
Loading

0 comments on commit 43c67ac

Please sign in to comment.