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_unorderedAccessTableRootIndex = 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_DESCRIPTOR_RANGE> m_descriptorRanges;
|
||||
};
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "../RHIPipelineLayout.h"
|
||||
|
||||
namespace XCEngine {
|
||||
@@ -18,6 +20,8 @@ public:
|
||||
|
||||
private:
|
||||
RHIPipelineLayoutDesc m_desc = {};
|
||||
std::vector<DescriptorSetLayoutDesc> m_setLayouts;
|
||||
std::vector<std::vector<DescriptorSetLayoutBinding>> m_setLayoutBindings;
|
||||
bool m_initialized = false;
|
||||
};
|
||||
|
||||
|
||||
@@ -365,7 +365,21 @@ struct RHIRenderPassDesc {
|
||||
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 {
|
||||
DescriptorSetLayoutDesc* setLayouts = nullptr;
|
||||
uint32_t setLayoutCount = 0;
|
||||
uint32_t constantBufferCount = 0;
|
||||
uint32_t textureCount = 0;
|
||||
uint32_t samplerCount = 0;
|
||||
@@ -383,18 +397,6 @@ struct ResourceViewDesc {
|
||||
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 {
|
||||
void* device = nullptr;
|
||||
DescriptorHeapType type = DescriptorHeapType::CBV_SRV_UAV;
|
||||
|
||||
@@ -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