Share builtin pass layout assembly utilities

This commit is contained in:
2026-04-04 13:48:13 +08:00
parent 0ebd2d4979
commit a3ba08bb99
7 changed files with 328 additions and 180 deletions

View File

@@ -274,24 +274,33 @@ bool BuiltinObjectIdPass::CreateResources(const RenderContext& context) {
m_perObjectBinding = bindingPlan.perObject;
m_firstDescriptorSet = bindingPlan.firstDescriptorSet;
std::vector<std::vector<RHI::DescriptorSetLayoutBinding>> setBindingStorage(
static_cast<size_t>(bindingPlan.maxSetIndex) + 1u);
RHI::DescriptorSetLayoutBinding constantBinding = {};
constantBinding.binding = m_perObjectBinding.binding;
constantBinding.type = static_cast<uint32_t>(RHI::DescriptorType::CBV);
constantBinding.count = 1;
setBindingStorage[m_perObjectBinding.set].push_back(constantBinding);
std::vector<BuiltinPassSetLayoutMetadata> setLayouts;
Containers::String setLayoutError;
if (!TryBuildBuiltinPassSetLayouts(bindingPlan, setLayouts, &setLayoutError)) {
Debug::Logger::Get().Error(
Debug::LogCategory::Rendering,
(Containers::String("BuiltinObjectIdPass failed to build descriptor set layouts: ") + setLayoutError).CStr());
DestroyResources();
return false;
}
if (m_perObjectBinding.set >= setLayouts.size()) {
Debug::Logger::Get().Error(
Debug::LogCategory::Rendering,
"BuiltinObjectIdPass produced an invalid PerObject descriptor set index");
DestroyResources();
return false;
}
m_perObjectSetLayout = setLayouts[m_perObjectBinding.set];
RefreshBuiltinPassSetLayoutMetadata(m_perObjectSetLayout);
std::vector<RHI::DescriptorSetLayoutDesc> setLayouts(setBindingStorage.size());
for (size_t setIndex = 0; setIndex < setBindingStorage.size(); ++setIndex) {
setLayouts[setIndex].bindings =
setBindingStorage[setIndex].empty() ? nullptr : setBindingStorage[setIndex].data();
setLayouts[setIndex].bindingCount = static_cast<uint32_t>(setBindingStorage[setIndex].size());
std::vector<RHI::DescriptorSetLayoutDesc> nativeSetLayouts(setLayouts.size());
for (size_t setIndex = 0; setIndex < setLayouts.size(); ++setIndex) {
nativeSetLayouts[setIndex] = setLayouts[setIndex].layout;
}
RHI::RHIPipelineLayoutDesc pipelineLayoutDesc = {};
pipelineLayoutDesc.setLayouts = setLayouts.empty() ? nullptr : setLayouts.data();
pipelineLayoutDesc.setLayoutCount = static_cast<uint32_t>(setLayouts.size());
pipelineLayoutDesc.setLayouts = nativeSetLayouts.empty() ? nullptr : nativeSetLayouts.data();
pipelineLayoutDesc.setLayoutCount = static_cast<uint32_t>(nativeSetLayouts.size());
m_pipelineLayout = m_device->CreatePipelineLayout(pipelineLayoutDesc);
if (m_pipelineLayout == nullptr) {
DestroyResources();
@@ -340,12 +349,14 @@ void BuiltinObjectIdPass::DestroyResources() {
m_device = nullptr;
m_backendType = RHI::RHIType::D3D12;
m_perObjectBinding = {};
m_perObjectSetLayout = {};
m_firstDescriptorSet = 0;
m_builtinObjectIdShader.Reset();
}
RHI::RHIDescriptorSet* BuiltinObjectIdPass::GetOrCreatePerObjectSet(uint64_t objectId) {
if (m_perObjectBinding.IsValid() == false) {
if (m_perObjectBinding.IsValid() == false ||
m_perObjectSetLayout.layout.bindingCount == 0) {
return nullptr;
}
@@ -355,9 +366,10 @@ RHI::RHIDescriptorSet* BuiltinObjectIdPass::GetOrCreatePerObjectSet(uint64_t obj
}
RHI::DescriptorPoolDesc poolDesc = {};
poolDesc.type = RHI::DescriptorHeapType::CBV_SRV_UAV;
poolDesc.descriptorCount = 1;
poolDesc.shaderVisible = false;
poolDesc.type = m_perObjectSetLayout.heapType;
poolDesc.descriptorCount =
CountBuiltinPassHeapDescriptors(m_perObjectSetLayout.heapType, m_perObjectSetLayout.bindings);
poolDesc.shaderVisible = m_perObjectSetLayout.shaderVisible;
OwnedDescriptorSet descriptorSet = {};
descriptorSet.pool = m_device->CreateDescriptorPool(poolDesc);
@@ -365,15 +377,7 @@ RHI::RHIDescriptorSet* BuiltinObjectIdPass::GetOrCreatePerObjectSet(uint64_t obj
return nullptr;
}
RHI::DescriptorSetLayoutBinding binding = {};
binding.binding = m_perObjectBinding.binding;
binding.type = static_cast<uint32_t>(RHI::DescriptorType::CBV);
binding.count = 1;
RHI::DescriptorSetLayoutDesc layout = {};
layout.bindings = &binding;
layout.bindingCount = 1;
descriptorSet.set = descriptorSet.pool->AllocateSet(layout);
descriptorSet.set = descriptorSet.pool->AllocateSet(m_perObjectSetLayout.layout);
if (descriptorSet.set == nullptr) {
DestroyOwnedDescriptorSet(descriptorSet);
return nullptr;