refactor(rhi): let pipeline layouts own set metadata
This commit is contained in:
@@ -47,6 +47,8 @@ private:
|
|||||||
uint32_t m_shaderResourceTableRootIndex = UINT32_MAX;
|
uint32_t m_shaderResourceTableRootIndex = UINT32_MAX;
|
||||||
uint32_t m_unorderedAccessTableRootIndex = UINT32_MAX;
|
uint32_t m_unorderedAccessTableRootIndex = UINT32_MAX;
|
||||||
uint32_t m_samplerTableRootIndex = UINT32_MAX;
|
uint32_t m_samplerTableRootIndex = UINT32_MAX;
|
||||||
|
std::vector<DescriptorSetLayoutDesc> m_setLayouts;
|
||||||
|
std::vector<std::vector<DescriptorSetLayoutBinding>> m_setLayoutBindings;
|
||||||
std::vector<D3D12_ROOT_PARAMETER> m_rootParameters;
|
std::vector<D3D12_ROOT_PARAMETER> m_rootParameters;
|
||||||
std::vector<D3D12_DESCRIPTOR_RANGE> m_descriptorRanges;
|
std::vector<D3D12_DESCRIPTOR_RANGE> m_descriptorRanges;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "../RHIPipelineLayout.h"
|
#include "../RHIPipelineLayout.h"
|
||||||
|
|
||||||
namespace XCEngine {
|
namespace XCEngine {
|
||||||
@@ -18,6 +20,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
RHIPipelineLayoutDesc m_desc = {};
|
RHIPipelineLayoutDesc m_desc = {};
|
||||||
|
std::vector<DescriptorSetLayoutDesc> m_setLayouts;
|
||||||
|
std::vector<std::vector<DescriptorSetLayoutBinding>> m_setLayoutBindings;
|
||||||
bool m_initialized = false;
|
bool m_initialized = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -365,7 +365,21 @@ struct RHIRenderPassDesc {
|
|||||||
bool hasDepthStencil = false;
|
bool hasDepthStencil = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DescriptorSetLayoutBinding {
|
||||||
|
uint32_t binding = 0;
|
||||||
|
uint32_t type = 0;
|
||||||
|
uint32_t count = 0;
|
||||||
|
uint32_t visibility = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DescriptorSetLayoutDesc {
|
||||||
|
DescriptorSetLayoutBinding* bindings = nullptr;
|
||||||
|
uint32_t bindingCount = 0;
|
||||||
|
};
|
||||||
|
|
||||||
struct RHIPipelineLayoutDesc {
|
struct RHIPipelineLayoutDesc {
|
||||||
|
DescriptorSetLayoutDesc* setLayouts = nullptr;
|
||||||
|
uint32_t setLayoutCount = 0;
|
||||||
uint32_t constantBufferCount = 0;
|
uint32_t constantBufferCount = 0;
|
||||||
uint32_t textureCount = 0;
|
uint32_t textureCount = 0;
|
||||||
uint32_t samplerCount = 0;
|
uint32_t samplerCount = 0;
|
||||||
@@ -383,18 +397,6 @@ struct ResourceViewDesc {
|
|||||||
uint32_t structureByteStride = 0;
|
uint32_t structureByteStride = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DescriptorSetLayoutBinding {
|
|
||||||
uint32_t binding = 0;
|
|
||||||
uint32_t type = 0;
|
|
||||||
uint32_t count = 0;
|
|
||||||
uint32_t visibility = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DescriptorSetLayoutDesc {
|
|
||||||
DescriptorSetLayoutBinding* bindings = nullptr;
|
|
||||||
uint32_t bindingCount = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DescriptorPoolDesc {
|
struct DescriptorPoolDesc {
|
||||||
void* device = nullptr;
|
void* device = nullptr;
|
||||||
DescriptorHeapType type = DescriptorHeapType::CBV_SRV_UAV;
|
DescriptorHeapType type = DescriptorHeapType::CBV_SRV_UAV;
|
||||||
|
|||||||
@@ -4,6 +4,32 @@
|
|||||||
namespace XCEngine {
|
namespace XCEngine {
|
||||||
namespace RHI {
|
namespace RHI {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void AccumulateDescriptorCounts(const DescriptorSetLayoutDesc& setLayout, RHIPipelineLayoutDesc& desc) {
|
||||||
|
for (uint32_t bindingIndex = 0; bindingIndex < setLayout.bindingCount; ++bindingIndex) {
|
||||||
|
const DescriptorSetLayoutBinding& binding = setLayout.bindings[bindingIndex];
|
||||||
|
switch (static_cast<DescriptorType>(binding.type)) {
|
||||||
|
case DescriptorType::CBV:
|
||||||
|
desc.constantBufferCount += binding.count;
|
||||||
|
break;
|
||||||
|
case DescriptorType::SRV:
|
||||||
|
desc.textureCount += binding.count;
|
||||||
|
break;
|
||||||
|
case DescriptorType::UAV:
|
||||||
|
desc.uavCount += binding.count;
|
||||||
|
break;
|
||||||
|
case DescriptorType::Sampler:
|
||||||
|
desc.samplerCount += binding.count;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
D3D12PipelineLayout::D3D12PipelineLayout()
|
D3D12PipelineLayout::D3D12PipelineLayout()
|
||||||
: m_device(nullptr) {
|
: m_device(nullptr) {
|
||||||
}
|
}
|
||||||
@@ -23,6 +49,38 @@ bool D3D12PipelineLayout::InitializeInternal(D3D12Device* device, const RHIPipel
|
|||||||
|
|
||||||
m_device = device;
|
m_device = device;
|
||||||
m_desc = desc;
|
m_desc = desc;
|
||||||
|
m_setLayouts.clear();
|
||||||
|
m_setLayoutBindings.clear();
|
||||||
|
|
||||||
|
if (desc.setLayoutCount > 0 && desc.setLayouts != nullptr) {
|
||||||
|
m_desc.constantBufferCount = 0;
|
||||||
|
m_desc.textureCount = 0;
|
||||||
|
m_desc.samplerCount = 0;
|
||||||
|
m_desc.uavCount = 0;
|
||||||
|
|
||||||
|
m_setLayouts.resize(desc.setLayoutCount);
|
||||||
|
m_setLayoutBindings.resize(desc.setLayoutCount);
|
||||||
|
|
||||||
|
for (uint32_t setIndex = 0; setIndex < desc.setLayoutCount; ++setIndex) {
|
||||||
|
const DescriptorSetLayoutDesc& srcSetLayout = desc.setLayouts[setIndex];
|
||||||
|
auto& dstBindings = m_setLayoutBindings[setIndex];
|
||||||
|
if (srcSetLayout.bindingCount > 0 && srcSetLayout.bindings != nullptr) {
|
||||||
|
dstBindings.assign(
|
||||||
|
srcSetLayout.bindings,
|
||||||
|
srcSetLayout.bindings + srcSetLayout.bindingCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
DescriptorSetLayoutDesc dstSetLayout = {};
|
||||||
|
dstSetLayout.bindingCount = srcSetLayout.bindingCount;
|
||||||
|
dstSetLayout.bindings = dstBindings.empty() ? nullptr : dstBindings.data();
|
||||||
|
m_setLayouts[setIndex] = dstSetLayout;
|
||||||
|
|
||||||
|
AccumulateDescriptorCounts(dstSetLayout, m_desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_desc.setLayouts = m_setLayouts.data();
|
||||||
|
m_desc.setLayoutCount = static_cast<uint32_t>(m_setLayouts.size());
|
||||||
|
}
|
||||||
|
|
||||||
m_rootParameters.clear();
|
m_rootParameters.clear();
|
||||||
m_descriptorRanges.clear();
|
m_descriptorRanges.clear();
|
||||||
@@ -31,31 +89,33 @@ bool D3D12PipelineLayout::InitializeInternal(D3D12Device* device, const RHIPipel
|
|||||||
m_unorderedAccessTableRootIndex = UINT32_MAX;
|
m_unorderedAccessTableRootIndex = UINT32_MAX;
|
||||||
m_samplerTableRootIndex = UINT32_MAX;
|
m_samplerTableRootIndex = UINT32_MAX;
|
||||||
|
|
||||||
|
const RHIPipelineLayoutDesc& normalizedDesc = m_desc;
|
||||||
|
|
||||||
const uint32_t rootParameterCount =
|
const uint32_t rootParameterCount =
|
||||||
desc.constantBufferCount +
|
normalizedDesc.constantBufferCount +
|
||||||
(desc.textureCount > 0 ? 1u : 0u) +
|
(normalizedDesc.textureCount > 0 ? 1u : 0u) +
|
||||||
(desc.uavCount > 0 ? 1u : 0u) +
|
(normalizedDesc.uavCount > 0 ? 1u : 0u) +
|
||||||
(desc.samplerCount > 0 ? 1u : 0u);
|
(normalizedDesc.samplerCount > 0 ? 1u : 0u);
|
||||||
const uint32_t descriptorRangeCount =
|
const uint32_t descriptorRangeCount =
|
||||||
(desc.textureCount > 0 ? 1u : 0u) +
|
(normalizedDesc.textureCount > 0 ? 1u : 0u) +
|
||||||
(desc.uavCount > 0 ? 1u : 0u) +
|
(normalizedDesc.uavCount > 0 ? 1u : 0u) +
|
||||||
(desc.samplerCount > 0 ? 1u : 0u);
|
(normalizedDesc.samplerCount > 0 ? 1u : 0u);
|
||||||
|
|
||||||
m_rootParameters.reserve(rootParameterCount);
|
m_rootParameters.reserve(rootParameterCount);
|
||||||
m_descriptorRanges.reserve(descriptorRangeCount);
|
m_descriptorRanges.reserve(descriptorRangeCount);
|
||||||
|
|
||||||
uint32_t rootIndex = 0;
|
uint32_t rootIndex = 0;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < desc.constantBufferCount; ++i) {
|
for (uint32_t i = 0; i < normalizedDesc.constantBufferCount; ++i) {
|
||||||
D3D12_ROOT_PARAMETER param = D3D12RootSignature::CreateCBV(i, ShaderVisibility::All, 0);
|
D3D12_ROOT_PARAMETER param = D3D12RootSignature::CreateCBV(i, ShaderVisibility::All, 0);
|
||||||
m_rootParameters.push_back(param);
|
m_rootParameters.push_back(param);
|
||||||
m_constantBufferRootIndices[i] = rootIndex;
|
m_constantBufferRootIndices[i] = rootIndex;
|
||||||
rootIndex++;
|
rootIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (desc.textureCount > 0) {
|
if (normalizedDesc.textureCount > 0) {
|
||||||
m_descriptorRanges.push_back(D3D12RootSignature::CreateDescriptorRange(
|
m_descriptorRanges.push_back(D3D12RootSignature::CreateDescriptorRange(
|
||||||
D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 0, desc.textureCount, 0));
|
D3D12_DESCRIPTOR_RANGE_TYPE_SRV, 0, normalizedDesc.textureCount, 0));
|
||||||
D3D12_ROOT_PARAMETER param = D3D12RootSignature::CreateDescriptorTable(
|
D3D12_ROOT_PARAMETER param = D3D12RootSignature::CreateDescriptorTable(
|
||||||
1, &m_descriptorRanges.back(), ShaderVisibility::All);
|
1, &m_descriptorRanges.back(), ShaderVisibility::All);
|
||||||
m_rootParameters.push_back(param);
|
m_rootParameters.push_back(param);
|
||||||
@@ -63,9 +123,9 @@ bool D3D12PipelineLayout::InitializeInternal(D3D12Device* device, const RHIPipel
|
|||||||
rootIndex++;
|
rootIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (desc.uavCount > 0) {
|
if (normalizedDesc.uavCount > 0) {
|
||||||
m_descriptorRanges.push_back(D3D12RootSignature::CreateDescriptorRange(
|
m_descriptorRanges.push_back(D3D12RootSignature::CreateDescriptorRange(
|
||||||
D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 0, desc.uavCount, 0));
|
D3D12_DESCRIPTOR_RANGE_TYPE_UAV, 0, normalizedDesc.uavCount, 0));
|
||||||
D3D12_ROOT_PARAMETER param = D3D12RootSignature::CreateDescriptorTable(
|
D3D12_ROOT_PARAMETER param = D3D12RootSignature::CreateDescriptorTable(
|
||||||
1, &m_descriptorRanges.back(), ShaderVisibility::All);
|
1, &m_descriptorRanges.back(), ShaderVisibility::All);
|
||||||
m_rootParameters.push_back(param);
|
m_rootParameters.push_back(param);
|
||||||
@@ -73,9 +133,9 @@ bool D3D12PipelineLayout::InitializeInternal(D3D12Device* device, const RHIPipel
|
|||||||
rootIndex++;
|
rootIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (desc.samplerCount > 0) {
|
if (normalizedDesc.samplerCount > 0) {
|
||||||
m_descriptorRanges.push_back(D3D12RootSignature::CreateDescriptorRange(
|
m_descriptorRanges.push_back(D3D12RootSignature::CreateDescriptorRange(
|
||||||
D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 0, desc.samplerCount, 0));
|
D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER, 0, normalizedDesc.samplerCount, 0));
|
||||||
D3D12_ROOT_PARAMETER param = D3D12RootSignature::CreateDescriptorTable(
|
D3D12_ROOT_PARAMETER param = D3D12RootSignature::CreateDescriptorTable(
|
||||||
1, &m_descriptorRanges.back(), ShaderVisibility::All);
|
1, &m_descriptorRanges.back(), ShaderVisibility::All);
|
||||||
m_rootParameters.push_back(param);
|
m_rootParameters.push_back(param);
|
||||||
@@ -124,6 +184,8 @@ void D3D12PipelineLayout::Shutdown() {
|
|||||||
m_shaderResourceTableRootIndex = UINT32_MAX;
|
m_shaderResourceTableRootIndex = UINT32_MAX;
|
||||||
m_unorderedAccessTableRootIndex = UINT32_MAX;
|
m_unorderedAccessTableRootIndex = UINT32_MAX;
|
||||||
m_samplerTableRootIndex = UINT32_MAX;
|
m_samplerTableRootIndex = UINT32_MAX;
|
||||||
|
m_setLayouts.clear();
|
||||||
|
m_setLayoutBindings.clear();
|
||||||
m_device = nullptr;
|
m_device = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,75 @@
|
|||||||
namespace XCEngine {
|
namespace XCEngine {
|
||||||
namespace RHI {
|
namespace RHI {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void AccumulateDescriptorCounts(const DescriptorSetLayoutDesc& setLayout, RHIPipelineLayoutDesc& desc) {
|
||||||
|
for (uint32_t bindingIndex = 0; bindingIndex < setLayout.bindingCount; ++bindingIndex) {
|
||||||
|
const DescriptorSetLayoutBinding& binding = setLayout.bindings[bindingIndex];
|
||||||
|
switch (static_cast<DescriptorType>(binding.type)) {
|
||||||
|
case DescriptorType::CBV:
|
||||||
|
desc.constantBufferCount += binding.count;
|
||||||
|
break;
|
||||||
|
case DescriptorType::SRV:
|
||||||
|
desc.textureCount += binding.count;
|
||||||
|
break;
|
||||||
|
case DescriptorType::UAV:
|
||||||
|
desc.uavCount += binding.count;
|
||||||
|
break;
|
||||||
|
case DescriptorType::Sampler:
|
||||||
|
desc.samplerCount += binding.count;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
bool OpenGLPipelineLayout::Initialize(const RHIPipelineLayoutDesc& desc) {
|
bool OpenGLPipelineLayout::Initialize(const RHIPipelineLayoutDesc& desc) {
|
||||||
m_desc = desc;
|
m_desc = desc;
|
||||||
|
m_setLayouts.clear();
|
||||||
|
m_setLayoutBindings.clear();
|
||||||
|
|
||||||
|
if (desc.setLayoutCount > 0 && desc.setLayouts != nullptr) {
|
||||||
|
m_desc.constantBufferCount = 0;
|
||||||
|
m_desc.textureCount = 0;
|
||||||
|
m_desc.samplerCount = 0;
|
||||||
|
m_desc.uavCount = 0;
|
||||||
|
|
||||||
|
m_setLayouts.resize(desc.setLayoutCount);
|
||||||
|
m_setLayoutBindings.resize(desc.setLayoutCount);
|
||||||
|
|
||||||
|
for (uint32_t setIndex = 0; setIndex < desc.setLayoutCount; ++setIndex) {
|
||||||
|
const DescriptorSetLayoutDesc& srcSetLayout = desc.setLayouts[setIndex];
|
||||||
|
auto& dstBindings = m_setLayoutBindings[setIndex];
|
||||||
|
if (srcSetLayout.bindingCount > 0 && srcSetLayout.bindings != nullptr) {
|
||||||
|
dstBindings.assign(
|
||||||
|
srcSetLayout.bindings,
|
||||||
|
srcSetLayout.bindings + srcSetLayout.bindingCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
DescriptorSetLayoutDesc dstSetLayout = {};
|
||||||
|
dstSetLayout.bindingCount = srcSetLayout.bindingCount;
|
||||||
|
dstSetLayout.bindings = dstBindings.empty() ? nullptr : dstBindings.data();
|
||||||
|
m_setLayouts[setIndex] = dstSetLayout;
|
||||||
|
|
||||||
|
AccumulateDescriptorCounts(dstSetLayout, m_desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_desc.setLayouts = m_setLayouts.data();
|
||||||
|
m_desc.setLayoutCount = static_cast<uint32_t>(m_setLayouts.size());
|
||||||
|
}
|
||||||
|
|
||||||
m_initialized = true;
|
m_initialized = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLPipelineLayout::Shutdown() {
|
void OpenGLPipelineLayout::Shutdown() {
|
||||||
m_desc = {};
|
m_desc = {};
|
||||||
|
m_setLayouts.clear();
|
||||||
|
m_setLayoutBindings.clear();
|
||||||
m_initialized = false;
|
m_initialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "fixtures/RHITestFixture.h"
|
#include "fixtures/RHITestFixture.h"
|
||||||
#include "XCEngine/RHI/D3D12/D3D12PipelineLayout.h"
|
#include "XCEngine/RHI/D3D12/D3D12PipelineLayout.h"
|
||||||
|
#include "XCEngine/RHI/OpenGL/OpenGLPipelineLayout.h"
|
||||||
#include "XCEngine/RHI/RHIPipelineLayout.h"
|
#include "XCEngine/RHI/RHIPipelineLayout.h"
|
||||||
#include "XCEngine/RHI/RHIDescriptorSet.h"
|
#include "XCEngine/RHI/RHIDescriptorSet.h"
|
||||||
|
|
||||||
@@ -146,6 +147,62 @@ TEST_P(RHITestFixture, PipelineLayout_DescriptorSetAllocation) {
|
|||||||
delete layout;
|
delete layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, PipelineLayout_DeepCopiesSetLayoutsAndInfersCounts) {
|
||||||
|
DescriptorSetLayoutBinding set0Bindings[1] = {};
|
||||||
|
set0Bindings[0].binding = 0;
|
||||||
|
set0Bindings[0].type = static_cast<uint32_t>(DescriptorType::CBV);
|
||||||
|
set0Bindings[0].count = 1;
|
||||||
|
|
||||||
|
DescriptorSetLayoutBinding set1Bindings[2] = {};
|
||||||
|
set1Bindings[0].binding = 1;
|
||||||
|
set1Bindings[0].type = static_cast<uint32_t>(DescriptorType::SRV);
|
||||||
|
set1Bindings[0].count = 2;
|
||||||
|
set1Bindings[1].binding = 3;
|
||||||
|
set1Bindings[1].type = static_cast<uint32_t>(DescriptorType::Sampler);
|
||||||
|
set1Bindings[1].count = 1;
|
||||||
|
|
||||||
|
DescriptorSetLayoutDesc setLayouts[2] = {};
|
||||||
|
setLayouts[0].bindings = set0Bindings;
|
||||||
|
setLayouts[0].bindingCount = 1;
|
||||||
|
setLayouts[1].bindings = set1Bindings;
|
||||||
|
setLayouts[1].bindingCount = 2;
|
||||||
|
|
||||||
|
RHIPipelineLayoutDesc desc = {};
|
||||||
|
desc.setLayouts = setLayouts;
|
||||||
|
desc.setLayoutCount = 2;
|
||||||
|
|
||||||
|
RHIPipelineLayout* layout = GetDevice()->CreatePipelineLayout(desc);
|
||||||
|
ASSERT_NE(layout, nullptr);
|
||||||
|
|
||||||
|
set0Bindings[0].binding = 99;
|
||||||
|
set1Bindings[0].count = 7;
|
||||||
|
setLayouts[1].bindingCount = 0;
|
||||||
|
|
||||||
|
const RHIPipelineLayoutDesc* storedDesc = nullptr;
|
||||||
|
if (GetBackendType() == RHIType::D3D12) {
|
||||||
|
storedDesc = &static_cast<D3D12PipelineLayout*>(layout)->GetDesc();
|
||||||
|
} else {
|
||||||
|
storedDesc = &static_cast<OpenGLPipelineLayout*>(layout)->GetDesc();
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT_NE(storedDesc, nullptr);
|
||||||
|
ASSERT_EQ(storedDesc->setLayoutCount, 2u);
|
||||||
|
ASSERT_NE(storedDesc->setLayouts, nullptr);
|
||||||
|
ASSERT_EQ(storedDesc->setLayouts[0].bindingCount, 1u);
|
||||||
|
ASSERT_EQ(storedDesc->setLayouts[1].bindingCount, 2u);
|
||||||
|
ASSERT_NE(storedDesc->setLayouts[0].bindings, nullptr);
|
||||||
|
ASSERT_NE(storedDesc->setLayouts[1].bindings, nullptr);
|
||||||
|
EXPECT_EQ(storedDesc->setLayouts[0].bindings[0].binding, 0u);
|
||||||
|
EXPECT_EQ(storedDesc->setLayouts[1].bindings[0].count, 2u);
|
||||||
|
EXPECT_EQ(storedDesc->constantBufferCount, 1u);
|
||||||
|
EXPECT_EQ(storedDesc->textureCount, 2u);
|
||||||
|
EXPECT_EQ(storedDesc->samplerCount, 1u);
|
||||||
|
EXPECT_EQ(storedDesc->uavCount, 0u);
|
||||||
|
|
||||||
|
layout->Shutdown();
|
||||||
|
delete layout;
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(RHITestFixture, PipelineLayout_D3D12TracksDistinctBindingClasses) {
|
TEST_P(RHITestFixture, PipelineLayout_D3D12TracksDistinctBindingClasses) {
|
||||||
if (GetBackendType() != RHIType::D3D12) {
|
if (GetBackendType() != RHIType::D3D12) {
|
||||||
GTEST_SKIP() << "D3D12-specific root parameter verification";
|
GTEST_SKIP() << "D3D12-specific root parameter verification";
|
||||||
@@ -182,3 +239,59 @@ TEST_P(RHITestFixture, PipelineLayout_D3D12TracksDistinctBindingClasses) {
|
|||||||
layout->Shutdown();
|
layout->Shutdown();
|
||||||
delete layout;
|
delete layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_P(RHITestFixture, PipelineLayout_D3D12InfersBindingClassesFromSetLayouts) {
|
||||||
|
if (GetBackendType() != RHIType::D3D12) {
|
||||||
|
GTEST_SKIP() << "D3D12-specific root parameter verification";
|
||||||
|
}
|
||||||
|
|
||||||
|
DescriptorSetLayoutBinding set0Bindings[1] = {};
|
||||||
|
set0Bindings[0].binding = 0;
|
||||||
|
set0Bindings[0].type = static_cast<uint32_t>(DescriptorType::CBV);
|
||||||
|
set0Bindings[0].count = 1;
|
||||||
|
|
||||||
|
DescriptorSetLayoutBinding set1Bindings[1] = {};
|
||||||
|
set1Bindings[0].binding = 0;
|
||||||
|
set1Bindings[0].type = static_cast<uint32_t>(DescriptorType::SRV);
|
||||||
|
set1Bindings[0].count = 1;
|
||||||
|
|
||||||
|
DescriptorSetLayoutBinding set2Bindings[1] = {};
|
||||||
|
set2Bindings[0].binding = 0;
|
||||||
|
set2Bindings[0].type = static_cast<uint32_t>(DescriptorType::UAV);
|
||||||
|
set2Bindings[0].count = 1;
|
||||||
|
|
||||||
|
DescriptorSetLayoutBinding set3Bindings[1] = {};
|
||||||
|
set3Bindings[0].binding = 0;
|
||||||
|
set3Bindings[0].type = static_cast<uint32_t>(DescriptorType::Sampler);
|
||||||
|
set3Bindings[0].count = 1;
|
||||||
|
|
||||||
|
DescriptorSetLayoutDesc setLayouts[4] = {};
|
||||||
|
setLayouts[0].bindings = set0Bindings;
|
||||||
|
setLayouts[0].bindingCount = 1;
|
||||||
|
setLayouts[1].bindings = set1Bindings;
|
||||||
|
setLayouts[1].bindingCount = 1;
|
||||||
|
setLayouts[2].bindings = set2Bindings;
|
||||||
|
setLayouts[2].bindingCount = 1;
|
||||||
|
setLayouts[3].bindings = set3Bindings;
|
||||||
|
setLayouts[3].bindingCount = 1;
|
||||||
|
|
||||||
|
RHIPipelineLayoutDesc desc = {};
|
||||||
|
desc.setLayouts = setLayouts;
|
||||||
|
desc.setLayoutCount = 4;
|
||||||
|
|
||||||
|
RHIPipelineLayout* layout = GetDevice()->CreatePipelineLayout(desc);
|
||||||
|
ASSERT_NE(layout, nullptr);
|
||||||
|
|
||||||
|
auto* d3d12Layout = static_cast<D3D12PipelineLayout*>(layout);
|
||||||
|
EXPECT_TRUE(d3d12Layout->HasConstantBufferBinding(0));
|
||||||
|
EXPECT_TRUE(d3d12Layout->HasShaderResourceTable());
|
||||||
|
EXPECT_TRUE(d3d12Layout->HasUnorderedAccessTable());
|
||||||
|
EXPECT_TRUE(d3d12Layout->HasSamplerTable());
|
||||||
|
EXPECT_EQ(d3d12Layout->GetDesc().constantBufferCount, 1u);
|
||||||
|
EXPECT_EQ(d3d12Layout->GetDesc().textureCount, 1u);
|
||||||
|
EXPECT_EQ(d3d12Layout->GetDesc().uavCount, 1u);
|
||||||
|
EXPECT_EQ(d3d12Layout->GetDesc().samplerCount, 1u);
|
||||||
|
|
||||||
|
layout->Shutdown();
|
||||||
|
delete layout;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user