Fix D3D12 descriptor set staging for shader tables
This commit is contained in:
@@ -348,10 +348,12 @@ void D3D12CommandList::SetGraphicsDescriptorSets(
|
|||||||
}
|
}
|
||||||
|
|
||||||
D3D12DescriptorHeap* heap = d3d12Set->GetHeap();
|
D3D12DescriptorHeap* heap = d3d12Set->GetHeap();
|
||||||
if (heap == nullptr || !heap->IsShaderVisible()) {
|
if (heap == nullptr) {
|
||||||
continue;
|
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) {
|
if (heap->GetType() == DescriptorHeapType::CBV_SRV_UAV) {
|
||||||
const bool hasSrvTable = d3d12Layout->UsesSetLayouts()
|
const bool hasSrvTable = d3d12Layout->UsesSetLayouts()
|
||||||
? d3d12Layout->HasShaderResourceTable(setIndex)
|
? d3d12Layout->HasShaderResourceTable(setIndex)
|
||||||
@@ -581,10 +583,12 @@ void D3D12CommandList::SetComputeDescriptorSets(
|
|||||||
}
|
}
|
||||||
|
|
||||||
D3D12DescriptorHeap* heap = d3d12Set->GetHeap();
|
D3D12DescriptorHeap* heap = d3d12Set->GetHeap();
|
||||||
if (heap == nullptr || !heap->IsShaderVisible()) {
|
if (heap == nullptr) {
|
||||||
continue;
|
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) {
|
if (heap->GetType() == DescriptorHeapType::CBV_SRV_UAV) {
|
||||||
const bool hasSrvTable = d3d12Layout->UsesSetLayouts()
|
const bool hasSrvTable = d3d12Layout->UsesSetLayouts()
|
||||||
? d3d12Layout->HasShaderResourceTable(setIndex)
|
? d3d12Layout->HasShaderResourceTable(setIndex)
|
||||||
|
|||||||
@@ -77,6 +77,9 @@ D3D12_CPU_DESCRIPTOR_HANDLE D3D12DescriptorHeap::GetCPUDescriptorHandleForHeapSt
|
|||||||
}
|
}
|
||||||
|
|
||||||
D3D12_GPU_DESCRIPTOR_HANDLE D3D12DescriptorHeap::GetGPUDescriptorHandleForHeapStart() const {
|
D3D12_GPU_DESCRIPTOR_HANDLE D3D12DescriptorHeap::GetGPUDescriptorHandleForHeapStart() const {
|
||||||
|
if (!m_shaderVisible || m_descriptorHeap == nullptr) {
|
||||||
|
return D3D12_GPU_DESCRIPTOR_HANDLE{0};
|
||||||
|
}
|
||||||
return m_descriptorHeap->GetGPUDescriptorHandleForHeapStart();
|
return m_descriptorHeap->GetGPUDescriptorHandleForHeapStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,6 +92,10 @@ CPUDescriptorHandle D3D12DescriptorHeap::GetCPUDescriptorHandle(uint32_t index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
GPUDescriptorHandle D3D12DescriptorHeap::GetGPUDescriptorHandle(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();
|
D3D12_GPU_DESCRIPTOR_HANDLE handle = m_descriptorHeap->GetGPUDescriptorHandleForHeapStart();
|
||||||
handle.ptr += index * m_descriptorSize;
|
handle.ptr += index * m_descriptorSize;
|
||||||
GPUDescriptorHandle result;
|
GPUDescriptorHandle result;
|
||||||
|
|||||||
@@ -51,6 +51,10 @@ bool HasShaderPayload(const ShaderCompileDesc& desc) {
|
|||||||
return !desc.source.empty() || !desc.fileName.empty() || !desc.compiledBinary.empty();
|
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) {
|
bool ShouldTraceVolumetricShaderCompile(const ShaderCompileDesc& desc) {
|
||||||
const std::string fileName = NarrowAscii(desc.fileName);
|
const std::string fileName = NarrowAscii(desc.fileName);
|
||||||
if (fileName.find("volumetric") != std::string::npos) {
|
if (fileName.find("volumetric") != std::string::npos) {
|
||||||
@@ -1279,6 +1283,11 @@ RHIDescriptorPool* D3D12Device::CreateDescriptorPool(const DescriptorPoolDesc& d
|
|||||||
auto* pool = new D3D12DescriptorHeap();
|
auto* pool = new D3D12DescriptorHeap();
|
||||||
DescriptorPoolDesc poolDesc = desc;
|
DescriptorPoolDesc poolDesc = desc;
|
||||||
poolDesc.device = m_device.Get();
|
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)) {
|
if (pool->Initialize(poolDesc)) {
|
||||||
return pool;
|
return pool;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "fixtures/D3D12TestFixture.h"
|
#include "fixtures/D3D12TestFixture.h"
|
||||||
|
|
||||||
|
#include "XCEngine/RHI/D3D12/D3D12DescriptorHeap.h"
|
||||||
#include "XCEngine/RHI/D3D12/D3D12DescriptorSet.h"
|
#include "XCEngine/RHI/D3D12/D3D12DescriptorSet.h"
|
||||||
#include "XCEngine/RHI/D3D12/D3D12PipelineLayout.h"
|
#include "XCEngine/RHI/D3D12/D3D12PipelineLayout.h"
|
||||||
#include "XCEngine/RHI/RHIDescriptorPool.h"
|
#include "XCEngine/RHI/RHIDescriptorPool.h"
|
||||||
@@ -54,6 +55,64 @@ TEST_F(D3D12TestFixture, DescriptorSet_MixedBindings_AssignDescriptorIndicesByTy
|
|||||||
delete pool;
|
delete pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(D3D12TestFixture, DescriptorSet_TableBindingsUseCpuVisibleStagingHeaps) {
|
||||||
|
DescriptorPoolDesc texturePoolDesc = {};
|
||||||
|
texturePoolDesc.type = DescriptorHeapType::CBV_SRV_UAV;
|
||||||
|
texturePoolDesc.descriptorCount = 2;
|
||||||
|
texturePoolDesc.shaderVisible = true;
|
||||||
|
|
||||||
|
RHIDescriptorPool* texturePool = GetDevice()->CreateDescriptorPool(texturePoolDesc);
|
||||||
|
ASSERT_NE(texturePool, nullptr);
|
||||||
|
|
||||||
|
DescriptorSetLayoutBinding textureBinding = {};
|
||||||
|
textureBinding.binding = 0;
|
||||||
|
textureBinding.type = static_cast<uint32_t>(DescriptorType::SRV);
|
||||||
|
textureBinding.count = 1;
|
||||||
|
|
||||||
|
DescriptorSetLayoutDesc textureLayoutDesc = {};
|
||||||
|
textureLayoutDesc.bindings = &textureBinding;
|
||||||
|
textureLayoutDesc.bindingCount = 1;
|
||||||
|
|
||||||
|
RHIDescriptorSet* textureSet = texturePool->AllocateSet(textureLayoutDesc);
|
||||||
|
ASSERT_NE(textureSet, nullptr);
|
||||||
|
auto* textureD3D12Set = static_cast<D3D12DescriptorSet*>(textureSet);
|
||||||
|
ASSERT_NE(textureD3D12Set->GetHeap(), nullptr);
|
||||||
|
EXPECT_FALSE(textureD3D12Set->GetHeap()->IsShaderVisible());
|
||||||
|
|
||||||
|
DescriptorPoolDesc samplerPoolDesc = {};
|
||||||
|
samplerPoolDesc.type = DescriptorHeapType::Sampler;
|
||||||
|
samplerPoolDesc.descriptorCount = 1;
|
||||||
|
samplerPoolDesc.shaderVisible = true;
|
||||||
|
|
||||||
|
RHIDescriptorPool* samplerPool = GetDevice()->CreateDescriptorPool(samplerPoolDesc);
|
||||||
|
ASSERT_NE(samplerPool, nullptr);
|
||||||
|
|
||||||
|
DescriptorSetLayoutBinding samplerBinding = {};
|
||||||
|
samplerBinding.binding = 0;
|
||||||
|
samplerBinding.type = static_cast<uint32_t>(DescriptorType::Sampler);
|
||||||
|
samplerBinding.count = 1;
|
||||||
|
|
||||||
|
DescriptorSetLayoutDesc samplerLayoutDesc = {};
|
||||||
|
samplerLayoutDesc.bindings = &samplerBinding;
|
||||||
|
samplerLayoutDesc.bindingCount = 1;
|
||||||
|
|
||||||
|
RHIDescriptorSet* samplerSet = samplerPool->AllocateSet(samplerLayoutDesc);
|
||||||
|
ASSERT_NE(samplerSet, nullptr);
|
||||||
|
auto* samplerD3D12Set = static_cast<D3D12DescriptorSet*>(samplerSet);
|
||||||
|
ASSERT_NE(samplerD3D12Set->GetHeap(), nullptr);
|
||||||
|
EXPECT_FALSE(samplerD3D12Set->GetHeap()->IsShaderVisible());
|
||||||
|
|
||||||
|
textureSet->Shutdown();
|
||||||
|
delete textureSet;
|
||||||
|
texturePool->Shutdown();
|
||||||
|
delete texturePool;
|
||||||
|
|
||||||
|
samplerSet->Shutdown();
|
||||||
|
delete samplerSet;
|
||||||
|
samplerPool->Shutdown();
|
||||||
|
delete samplerPool;
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(D3D12TestFixture, DescriptorSet_MultipleConstantBuffersUploadIndependently) {
|
TEST_F(D3D12TestFixture, DescriptorSet_MultipleConstantBuffersUploadIndependently) {
|
||||||
DescriptorPoolDesc poolDesc = {};
|
DescriptorPoolDesc poolDesc = {};
|
||||||
poolDesc.type = DescriptorHeapType::CBV_SRV_UAV;
|
poolDesc.type = DescriptorHeapType::CBV_SRV_UAV;
|
||||||
|
|||||||
Reference in New Issue
Block a user