Fix D3D12 descriptor set staging for shader tables

This commit is contained in:
2026-04-12 11:49:12 +08:00
parent 7ee28a7969
commit 347d08463b
4 changed files with 81 additions and 2 deletions

View File

@@ -348,10 +348,12 @@ void D3D12CommandList::SetGraphicsDescriptorSets(
}
D3D12DescriptorHeap* heap = d3d12Set->GetHeap();
if (heap == nullptr || !heap->IsShaderVisible()) {
if (heap == nullptr) {
continue;
}
// Descriptor sets are staged in CPU-visible heaps and copied into this
// command list's shader-visible heaps immediately before binding.
if (heap->GetType() == DescriptorHeapType::CBV_SRV_UAV) {
const bool hasSrvTable = d3d12Layout->UsesSetLayouts()
? d3d12Layout->HasShaderResourceTable(setIndex)
@@ -581,10 +583,12 @@ void D3D12CommandList::SetComputeDescriptorSets(
}
D3D12DescriptorHeap* heap = d3d12Set->GetHeap();
if (heap == nullptr || !heap->IsShaderVisible()) {
if (heap == nullptr) {
continue;
}
// Descriptor sets are staged in CPU-visible heaps and copied into this
// command list's shader-visible heaps immediately before binding.
if (heap->GetType() == DescriptorHeapType::CBV_SRV_UAV) {
const bool hasSrvTable = d3d12Layout->UsesSetLayouts()
? d3d12Layout->HasShaderResourceTable(setIndex)

View File

@@ -77,6 +77,9 @@ D3D12_CPU_DESCRIPTOR_HANDLE D3D12DescriptorHeap::GetCPUDescriptorHandleForHeapSt
}
D3D12_GPU_DESCRIPTOR_HANDLE D3D12DescriptorHeap::GetGPUDescriptorHandleForHeapStart() const {
if (!m_shaderVisible || m_descriptorHeap == nullptr) {
return D3D12_GPU_DESCRIPTOR_HANDLE{0};
}
return m_descriptorHeap->GetGPUDescriptorHandleForHeapStart();
}
@@ -89,6 +92,10 @@ CPUDescriptorHandle D3D12DescriptorHeap::GetCPUDescriptorHandle(uint32_t index)
}
GPUDescriptorHandle D3D12DescriptorHeap::GetGPUDescriptorHandle(uint32_t index) {
if (!m_shaderVisible || m_descriptorHeap == nullptr) {
return GPUDescriptorHandle{0};
}
D3D12_GPU_DESCRIPTOR_HANDLE handle = m_descriptorHeap->GetGPUDescriptorHandleForHeapStart();
handle.ptr += index * m_descriptorSize;
GPUDescriptorHandle result;

View File

@@ -51,6 +51,10 @@ bool HasShaderPayload(const ShaderCompileDesc& desc) {
return !desc.source.empty() || !desc.fileName.empty() || !desc.compiledBinary.empty();
}
bool UsesTransientShaderVisibleDescriptorHeap(DescriptorHeapType type) {
return type == DescriptorHeapType::CBV_SRV_UAV || type == DescriptorHeapType::Sampler;
}
bool ShouldTraceVolumetricShaderCompile(const ShaderCompileDesc& desc) {
const std::string fileName = NarrowAscii(desc.fileName);
if (fileName.find("volumetric") != std::string::npos) {
@@ -1279,6 +1283,11 @@ RHIDescriptorPool* D3D12Device::CreateDescriptorPool(const DescriptorPoolDesc& d
auto* pool = new D3D12DescriptorHeap();
DescriptorPoolDesc poolDesc = desc;
poolDesc.device = m_device.Get();
if (UsesTransientShaderVisibleDescriptorHeap(poolDesc.type)) {
// Descriptor sets are staged in CPU-visible heaps and copied into the
// command list's transient shader-visible heaps before each bind.
poolDesc.shaderVisible = false;
}
if (pool->Initialize(poolDesc)) {
return pool;
}