refactor(rhi): let pipeline layouts own set metadata
This commit is contained in:
@@ -4,6 +4,32 @@
|
||||
namespace XCEngine {
|
||||
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()
|
||||
: m_device(nullptr) {
|
||||
}
|
||||
@@ -23,6 +49,38 @@ bool D3D12PipelineLayout::InitializeInternal(D3D12Device* device, const RHIPipel
|
||||
|
||||
m_device = device;
|
||||
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_descriptorRanges.clear();
|
||||
@@ -31,31 +89,33 @@ bool D3D12PipelineLayout::InitializeInternal(D3D12Device* device, const RHIPipel
|
||||
m_unorderedAccessTableRootIndex = UINT32_MAX;
|
||||
m_samplerTableRootIndex = UINT32_MAX;
|
||||
|
||||
const RHIPipelineLayoutDesc& normalizedDesc = m_desc;
|
||||
|
||||
const uint32_t rootParameterCount =
|
||||
desc.constantBufferCount +
|
||||
(desc.textureCount > 0 ? 1u : 0u) +
|
||||
(desc.uavCount > 0 ? 1u : 0u) +
|
||||
(desc.samplerCount > 0 ? 1u : 0u);
|
||||
normalizedDesc.constantBufferCount +
|
||||
(normalizedDesc.textureCount > 0 ? 1u : 0u) +
|
||||
(normalizedDesc.uavCount > 0 ? 1u : 0u) +
|
||||
(normalizedDesc.samplerCount > 0 ? 1u : 0u);
|
||||
const uint32_t descriptorRangeCount =
|
||||
(desc.textureCount > 0 ? 1u : 0u) +
|
||||
(desc.uavCount > 0 ? 1u : 0u) +
|
||||
(desc.samplerCount > 0 ? 1u : 0u);
|
||||
(normalizedDesc.textureCount > 0 ? 1u : 0u) +
|
||||
(normalizedDesc.uavCount > 0 ? 1u : 0u) +
|
||||
(normalizedDesc.samplerCount > 0 ? 1u : 0u);
|
||||
|
||||
m_rootParameters.reserve(rootParameterCount);
|
||||
m_descriptorRanges.reserve(descriptorRangeCount);
|
||||
|
||||
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);
|
||||
m_rootParameters.push_back(param);
|
||||
m_constantBufferRootIndices[i] = rootIndex;
|
||||
rootIndex++;
|
||||
}
|
||||
|
||||
if (desc.textureCount > 0) {
|
||||
if (normalizedDesc.textureCount > 0) {
|
||||
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(
|
||||
1, &m_descriptorRanges.back(), ShaderVisibility::All);
|
||||
m_rootParameters.push_back(param);
|
||||
@@ -63,9 +123,9 @@ bool D3D12PipelineLayout::InitializeInternal(D3D12Device* device, const RHIPipel
|
||||
rootIndex++;
|
||||
}
|
||||
|
||||
if (desc.uavCount > 0) {
|
||||
if (normalizedDesc.uavCount > 0) {
|
||||
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(
|
||||
1, &m_descriptorRanges.back(), ShaderVisibility::All);
|
||||
m_rootParameters.push_back(param);
|
||||
@@ -73,9 +133,9 @@ bool D3D12PipelineLayout::InitializeInternal(D3D12Device* device, const RHIPipel
|
||||
rootIndex++;
|
||||
}
|
||||
|
||||
if (desc.samplerCount > 0) {
|
||||
if (normalizedDesc.samplerCount > 0) {
|
||||
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(
|
||||
1, &m_descriptorRanges.back(), ShaderVisibility::All);
|
||||
m_rootParameters.push_back(param);
|
||||
@@ -124,6 +184,8 @@ void D3D12PipelineLayout::Shutdown() {
|
||||
m_shaderResourceTableRootIndex = UINT32_MAX;
|
||||
m_unorderedAccessTableRootIndex = UINT32_MAX;
|
||||
m_samplerTableRootIndex = UINT32_MAX;
|
||||
m_setLayouts.clear();
|
||||
m_setLayoutBindings.clear();
|
||||
m_device = nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,14 +3,75 @@
|
||||
namespace XCEngine {
|
||||
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) {
|
||||
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;
|
||||
return true;
|
||||
}
|
||||
|
||||
void OpenGLPipelineLayout::Shutdown() {
|
||||
m_desc = {};
|
||||
m_setLayouts.clear();
|
||||
m_setLayoutBindings.clear();
|
||||
m_initialized = false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user