Name Description Size
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