refactor(rhi): untangle d3d12 descriptor bindings

This commit is contained in:
2026-03-26 12:21:49 +08:00
parent d8e14df78a
commit 36d2f479cd
8 changed files with 511 additions and 120 deletions

View File

@@ -407,6 +407,105 @@ TEST_P(RHITestFixture, DescriptorSet_MultipleAllocations_AdvanceDescriptorOffset
delete pool;
}
TEST_P(RHITestFixture, DescriptorSet_D3D12MixedBindings_AssignDescriptorIndicesByType) {
if (GetBackendType() != RHIType::D3D12) {
GTEST_SKIP() << "D3D12-specific descriptor index verification";
}
DescriptorPoolDesc poolDesc = {};
poolDesc.type = DescriptorHeapType::CBV_SRV_UAV;
poolDesc.descriptorCount = 4;
poolDesc.shaderVisible = true;
RHIDescriptorPool* pool = GetDevice()->CreateDescriptorPool(poolDesc);
ASSERT_NE(pool, nullptr);
DescriptorSetLayoutBinding bindings[3] = {};
bindings[0].binding = 2;
bindings[0].type = static_cast<uint32_t>(DescriptorType::UAV);
bindings[0].count = 1;
bindings[1].binding = 0;
bindings[1].type = static_cast<uint32_t>(DescriptorType::CBV);
bindings[1].count = 1;
bindings[2].binding = 1;
bindings[2].type = static_cast<uint32_t>(DescriptorType::SRV);
bindings[2].count = 1;
DescriptorSetLayoutDesc layoutDesc = {};
layoutDesc.bindings = bindings;
layoutDesc.bindingCount = 3;
RHIDescriptorSet* firstSet = pool->AllocateSet(layoutDesc);
RHIDescriptorSet* secondSet = pool->AllocateSet(layoutDesc);
ASSERT_NE(firstSet, nullptr);
ASSERT_NE(secondSet, nullptr);
auto* firstD3D12Set = static_cast<D3D12DescriptorSet*>(firstSet);
auto* secondD3D12Set = static_cast<D3D12DescriptorSet*>(secondSet);
EXPECT_EQ(firstD3D12Set->GetCount(), 2u);
EXPECT_EQ(firstD3D12Set->GetDescriptorIndexForBinding(1), 0u);
EXPECT_EQ(firstD3D12Set->GetDescriptorIndexForBinding(2), 1u);
EXPECT_EQ(firstD3D12Set->GetDescriptorIndexForBinding(0), UINT32_MAX);
EXPECT_EQ(firstD3D12Set->GetOffset(), 0u);
EXPECT_EQ(secondD3D12Set->GetOffset(), 2u);
firstSet->Shutdown();
delete firstSet;
secondSet->Shutdown();
delete secondSet;
pool->Shutdown();
delete pool;
}
TEST_P(RHITestFixture, DescriptorSet_D3D12MultipleConstantBuffersUploadIndependently) {
if (GetBackendType() != RHIType::D3D12) {
GTEST_SKIP() << "D3D12-specific constant buffer verification";
}
DescriptorPoolDesc poolDesc = {};
poolDesc.type = DescriptorHeapType::CBV_SRV_UAV;
poolDesc.descriptorCount = 1;
poolDesc.shaderVisible = false;
RHIDescriptorPool* pool = GetDevice()->CreateDescriptorPool(poolDesc);
ASSERT_NE(pool, nullptr);
DescriptorSetLayoutBinding bindings[2] = {};
bindings[0].binding = 0;
bindings[0].type = static_cast<uint32_t>(DescriptorType::CBV);
bindings[0].count = 1;
bindings[1].binding = 1;
bindings[1].type = static_cast<uint32_t>(DescriptorType::CBV);
bindings[1].count = 1;
DescriptorSetLayoutDesc layoutDesc = {};
layoutDesc.bindings = bindings;
layoutDesc.bindingCount = 2;
RHIDescriptorSet* set = pool->AllocateSet(layoutDesc);
ASSERT_NE(set, nullptr);
auto* d3d12Set = static_cast<D3D12DescriptorSet*>(set);
const float firstData[16] = { 1.0f, 0.0f, 0.0f, 0.0f };
const float secondData[16] = { 2.0f, 0.0f, 0.0f, 0.0f };
d3d12Set->WriteConstant(0, firstData, sizeof(firstData));
d3d12Set->WriteConstant(1, secondData, sizeof(secondData));
ASSERT_TRUE(d3d12Set->UploadConstantBuffer(0));
ASSERT_TRUE(d3d12Set->UploadConstantBuffer(1));
const D3D12_GPU_VIRTUAL_ADDRESS firstAddress = d3d12Set->GetConstantBufferGPUAddress(0);
const D3D12_GPU_VIRTUAL_ADDRESS secondAddress = d3d12Set->GetConstantBufferGPUAddress(1);
EXPECT_NE(firstAddress, 0u);
EXPECT_NE(secondAddress, 0u);
EXPECT_NE(firstAddress, secondAddress);
set->Shutdown();
delete set;
pool->Shutdown();
delete pool;
}
TEST_P(RHITestFixture, DescriptorSet_Update_UsesBindingNumberOnOpenGL) {
if (GetBackendType() != RHIType::OpenGL) {
GTEST_SKIP() << "OpenGL-specific descriptor binding verification";

View File

@@ -146,7 +146,7 @@ TEST_P(RHITestFixture, PipelineLayout_DescriptorSetAllocation) {
delete layout;
}
TEST_P(RHITestFixture, PipelineLayout_D3D12ConstantBuffers_MapToDistinctRootParameters) {
TEST_P(RHITestFixture, PipelineLayout_D3D12TracksDistinctBindingClasses) {
if (GetBackendType() != RHIType::D3D12) {
GTEST_SKIP() << "D3D12-specific root parameter verification";
}
@@ -154,17 +154,30 @@ TEST_P(RHITestFixture, PipelineLayout_D3D12ConstantBuffers_MapToDistinctRootPara
RHIPipelineLayoutDesc desc = {};
desc.constantBufferCount = 2;
desc.textureCount = 1;
desc.uavCount = 1;
desc.samplerCount = 1;
RHIPipelineLayout* layout = GetDevice()->CreatePipelineLayout(desc);
ASSERT_NE(layout, nullptr);
auto* d3d12Layout = static_cast<D3D12PipelineLayout*>(layout);
EXPECT_TRUE(d3d12Layout->HasRootParameter(0));
EXPECT_TRUE(d3d12Layout->HasRootParameter(1));
EXPECT_TRUE(d3d12Layout->HasRootParameter(100));
EXPECT_TRUE(d3d12Layout->HasRootParameter(200));
EXPECT_NE(d3d12Layout->GetRootParameterIndex(0), d3d12Layout->GetRootParameterIndex(1));
EXPECT_TRUE(d3d12Layout->HasConstantBufferBinding(0));
EXPECT_TRUE(d3d12Layout->HasConstantBufferBinding(1));
EXPECT_FALSE(d3d12Layout->HasConstantBufferBinding(2));
EXPECT_TRUE(d3d12Layout->HasShaderResourceTable());
EXPECT_TRUE(d3d12Layout->HasUnorderedAccessTable());
EXPECT_TRUE(d3d12Layout->HasSamplerTable());
EXPECT_NE(
d3d12Layout->GetConstantBufferRootParameterIndex(0),
d3d12Layout->GetConstantBufferRootParameterIndex(1));
EXPECT_NE(
d3d12Layout->GetShaderResourceTableRootParameterIndex(),
d3d12Layout->GetUnorderedAccessTableRootParameterIndex());
EXPECT_NE(
d3d12Layout->GetUnorderedAccessTableRootParameterIndex(),
d3d12Layout->GetSamplerTableRootParameterIndex());
layout->Shutdown();
delete layout;