Skip to content

Commit

Permalink
hal/dx12: support base vertex/instance
Browse files Browse the repository at this point in the history
  • Loading branch information
kvark committed Jul 27, 2021
1 parent 6cfe8bd commit 69f808c
Show file tree
Hide file tree
Showing 12 changed files with 186 additions and 136 deletions.
5 changes: 2 additions & 3 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion wgpu-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ thiserror = "1"

[dependencies.naga]
git = "https://github.com/gfx-rs/naga"
rev = "e97c8f9"
rev = "a7ac13a"
features = ["wgsl-in"]

[dependencies.wgt]
Expand Down
1 change: 1 addition & 0 deletions wgpu-core/src/device/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1723,6 +1723,7 @@ impl<A: HalApi> Device<A> {
.collect::<Vec<_>>();
let hal_desc = hal::PipelineLayoutDescriptor {
label: desc.label.borrow_option(),
flags: hal::PipelineLayoutFlags::BASE_VERTEX_INSTANCE,
bind_group_layouts: &bgl_vec,
push_constant_ranges: desc.push_constant_ranges.as_ref(),
};
Expand Down
6 changes: 3 additions & 3 deletions wgpu-hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ glow = { git = "https://github.com/grovesNL/glow", rev = "0864897a28bbdd43f89f4f

# backend: Dx12
bit-set = { version = "0.5", optional = true }
native = { package = "d3d12", version = "0.4", features = ["libloading"], optional = true }
native = { package = "d3d12", git = "https://github.com/gfx-rs/d3d12-rs", rev = "79f29c8", features = ["libloading"], optional = true }
range-alloc = { version = "0.1", optional = true }

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
Expand All @@ -65,11 +65,11 @@ core-graphics-types = "0.1"

[dependencies.naga]
git = "https://github.com/gfx-rs/naga"
rev = "e97c8f9"
rev = "a7ac13a"

[dev-dependencies.naga]
git = "https://github.com/gfx-rs/naga"
rev = "e97c8f9"
rev = "a7ac13a"
features = ["wgsl-in"]

[dev-dependencies]
Expand Down
1 change: 1 addition & 0 deletions wgpu-hal/examples/halmark/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ impl<A: hal::Api> Example<A> {

let pipeline_layout_desc = hal::PipelineLayoutDescriptor {
label: None,
flags: hal::PipelineLayoutFlags::empty(),
bind_group_layouts: &[&global_group_layout, &local_group_layout],
push_constant_ranges: &[],
};
Expand Down
78 changes: 58 additions & 20 deletions wgpu-hal/src/dx12/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl super::CommandEncoder {
self.pass.clear();
}

unsafe fn prepare_draw(&mut self) {
unsafe fn prepare_draw(&mut self, base_vertex: i32, base_instance: u32) {
let list = self.list.unwrap();
while self.pass.dirty_vertex_buffers != 0 {
let index = self.pass.dirty_vertex_buffers.trailing_zeros();
Expand All @@ -54,6 +54,24 @@ impl super::CommandEncoder {
self.pass.vertex_buffers.as_ptr().offset(index as isize),
);
}
if let Some(root_index) = self.pass.layout.special_constants_root_index {
let needs_update = match self.pass.root_elements[root_index as usize] {
super::RootElement::SpecialConstantBuffer {
base_vertex: other_vertex,
base_instance: other_instance,
} => base_vertex != other_vertex || base_instance != other_instance,
_ => true,
};
if needs_update {
self.pass.root_elements[root_index as usize] =
super::RootElement::SpecialConstantBuffer {
base_vertex,
base_instance,
};
list.set_graphics_root_constant(root_index, base_vertex as u32, 0);
list.set_graphics_root_constant(root_index, base_instance, 1);
}
}
}

fn update_root_elements(&self, range: Range<super::RootIndex>) {
Expand All @@ -63,6 +81,17 @@ impl super::CommandEncoder {
for index in range {
match self.pass.root_elements[index as usize] {
super::RootElement::Empty => {}
super::RootElement::SpecialConstantBuffer {
base_vertex,
base_instance,
} => match self.pass.kind {
Pk::Render => {
list.set_graphics_root_constant(index, base_vertex as u32, 0);
list.set_graphics_root_constant(index, base_instance, 1);
}
Pk::Compute => (),
Pk::Transfer => (),
},
super::RootElement::Table(descriptor) => match self.pass.kind {
Pk::Render => list.set_graphics_root_descriptor_table(index, descriptor),
Pk::Compute => list.set_compute_root_descriptor_table(index, descriptor),
Expand Down Expand Up @@ -94,6 +123,18 @@ impl super::CommandEncoder {
}
}
}

fn reset_signature(&mut self, layout: &super::PipelineLayoutShared) {
if let Some(root_index) = layout.special_constants_root_index {
self.pass.root_elements[root_index as usize] =
super::RootElement::SpecialConstantBuffer {
base_vertex: 0,
base_instance: 0,
};
}
self.pass.layout = layout.clone();
self.update_root_elements(0..layout.total_root_elements);
}
}

impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
Expand Down Expand Up @@ -653,14 +694,13 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
root_index += 1;
}

let update_range = if self.pass.signature == layout.raw {
info.base_root_index..root_index as super::RootIndex
if self.pass.layout.signature == layout.shared.signature {
let update_range = info.base_root_index..root_index as super::RootIndex;
self.update_root_elements(update_range);
} else {
// D3D12 requires full reset on signature change
self.pass.signature = layout.raw;
0..layout.total_root_elements
self.reset_signature(&layout.shared);
};
self.update_root_elements(update_range);
}
unsafe fn set_push_constants(
&mut self,
Expand Down Expand Up @@ -690,11 +730,10 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
unsafe fn set_render_pipeline(&mut self, pipeline: &super::RenderPipeline) {
let list = self.list.unwrap();

if self.pass.signature != pipeline.signature {
if self.pass.layout.signature != pipeline.layout.signature {
// D3D12 requires full reset on signature change
list.set_graphics_root_signature(pipeline.signature);
self.pass.signature = pipeline.signature;
self.update_root_elements(0..pipeline.total_root_elements);
list.set_graphics_root_signature(pipeline.layout.signature);
self.reset_signature(&pipeline.layout);
};

list.set_pipeline_state(pipeline.raw);
Expand Down Expand Up @@ -772,7 +811,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
start_instance: u32,
instance_count: u32,
) {
self.prepare_draw();
self.prepare_draw(start_vertex as i32, start_instance);
self.list
.unwrap()
.draw(vertex_count, instance_count, start_vertex, start_instance);
Expand All @@ -785,7 +824,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
start_instance: u32,
instance_count: u32,
) {
self.prepare_draw();
self.prepare_draw(base_vertex, start_instance);
self.list.unwrap().draw_indexed(
index_count,
instance_count,
Expand All @@ -800,7 +839,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
offset: wgt::BufferAddress,
draw_count: u32,
) {
self.prepare_draw();
self.prepare_draw(0, 0);
self.list.unwrap().ExecuteIndirect(
self.shared.cmd_signatures.draw.as_mut_ptr(),
draw_count,
Expand All @@ -816,7 +855,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
offset: wgt::BufferAddress,
draw_count: u32,
) {
self.prepare_draw();
self.prepare_draw(0, 0);
self.list.unwrap().ExecuteIndirect(
self.shared.cmd_signatures.draw_indexed.as_mut_ptr(),
draw_count,
Expand All @@ -834,7 +873,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
count_offset: wgt::BufferAddress,
max_count: u32,
) {
self.prepare_draw();
self.prepare_draw(0, 0);
self.list.unwrap().ExecuteIndirect(
self.shared.cmd_signatures.draw.as_mut_ptr(),
max_count,
Expand All @@ -852,7 +891,7 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
count_offset: wgt::BufferAddress,
max_count: u32,
) {
self.prepare_draw();
self.prepare_draw(0, 0);
self.list.unwrap().ExecuteIndirect(
self.shared.cmd_signatures.draw_indexed.as_mut_ptr(),
max_count,
Expand All @@ -875,11 +914,10 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
unsafe fn set_compute_pipeline(&mut self, pipeline: &super::ComputePipeline) {
let list = self.list.unwrap();

if self.pass.signature != pipeline.signature {
if self.pass.layout.signature != pipeline.layout.signature {
// D3D12 requires full reset on signature change
list.set_compute_root_signature(pipeline.signature);
self.pass.signature = pipeline.signature;
self.update_root_elements(0..pipeline.total_root_elements);
list.set_compute_root_signature(pipeline.layout.signature);
self.reset_signature(&pipeline.layout);
};

list.set_pipeline_state(pipeline.raw);
Expand Down
Loading

0 comments on commit 69f808c

Please sign in to comment.