adapter.rs |
|
38239 |
command.rs |
|
61549 |
conv.rs |
|
17319 |
descriptor.rs |
|
10208 |
device.rs |
|
95567 |
instance.rs |
|
5520 |
mod.rs |
!
# DirectX12 API internals.
Generally the mapping is straightforward.
## Resource transitions
D3D12 API matches WebGPU internal states very well. The only
caveat here is issuing a special UAV barrier whenever both source
and destination states match, and they are for storage sync.
## Memory
For now, all resources are created with "committed" memory.
## Sampler Descriptor Management
At most one descriptor heap of each type can be bound at once. This
means that the descriptors from all bind groups need to be present
in the same heap, and they need to be contiguous within that heap.
This is not a problem for the SRV/CBV/UAV heap as it can be sized into
the millions of entries. However the sampler heap is limited to 2048 entries.
In order to work around this limitation, we refer to samplers indirectly by index.
The entire sampler heap is bound at once and a buffer containing all sampler indexes
for that bind group is bound. The shader then uses the index to look up the sampler
in the heap. To help visualize this, the generated HLSL looks like this:
```wgsl
@group(0) @binding(2) var myLinearSampler: sampler;
@group(1) @binding(1) var myAnisoSampler: sampler;
@group(1) @binding(4) var myCompSampler: sampler;
```
```cpp
// These bindings alias the same descriptors. Depending on the type, the shader will use the correct one.
SamplerState nagaSamplerHeap[2048]: register(s0, space0);
SamplerComparisonState nagaComparisonSamplerHeap[2048]: register(s2048, space1);
StructuredBuffer<uint> nagaGroup0SamplerIndexArray : register(t0, space0);
StructuredBuffer<uint> nagaGroup1SamplerIndexArray : register(t1, space0);
// Indexes into group 0 index array
static const SamplerState myLinearSampler = nagaSamplerHeap[nagaGroup0SamplerIndexArray[0]];
// Indexes into group 1 index array
static const SamplerState myAnisoSampler = nagaSamplerHeap[nagaGroup1SamplerIndexArray[0]];
static const SamplerComparisonState myCompSampler = nagaComparisonSamplerHeap[nagaGroup1SamplerIndexArray[1]];
```
Without this transform we would need separate set of sampler descriptors for each unique combination of samplers
in a bind group. This results in a lot of duplication and makes it easy to hit the 2048 limit. With the transform
the limit is merely 2048 unique samplers in existence, which is much more reasonable.
## Resource binding
See ['Device::create_pipeline_layout`] documentation for the structure
of the root signature corresponding to WebGPU pipeline layout.
Binding groups is mostly straightforward, with one big caveat:
all bindings have to be reset whenever the root signature changes.
This is the rule of D3D12, and we can do nothing to help it.
We detect this change at both [`crate::CommandEncoder::set_bind_group`]
and [`crate::CommandEncoder::set_render_pipeline`] with
[`crate::CommandEncoder::set_compute_pipeline`].
For this reason, in order avoid repeating the binding code,
we are binding everything in `CommandEncoder::update_root_elements`.
When the pipeline layout is changed, we reset all bindings.
Otherwise, we pass a range corresponding only to the current bind group.
! |
47597 |
sampler.rs |
Sampler management for DX12.
Nearly identical to the Vulkan sampler cache, with added descriptor heap management. |
9696 |
shader_compilation.rs |
|
11340 |
suballocation.rs |
|
14052 |
types.rs |
|
1205 |
view.rs |
wgt::TextureViewDimension::D1Array => {
desc.ViewDimension = Direct3D12::D3D12_SRV_DIMENSION_TEXTURE1DARRAY;
desc.Anonymous.Texture1DArray = Direct3D12::D3D12_TEX1D_ARRAY_SRV {
MostDetailedMip: self.mip_level_base,
MipLevels: self.mip_level_count,
FirstArraySlice: self.array_layer_base,
ArraySize: self.array_layer_count,
ResourceMinLODClamp: 0.0,
}
}
|
15593 |