Improve builtin pass binding diagnostics

This commit is contained in:
2026-04-05 17:10:15 +08:00
parent 3968083da7
commit 5c75919b14
3 changed files with 80 additions and 2 deletions

View File

@@ -10,6 +10,7 @@
#include <algorithm> #include <algorithm>
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <string>
#include <vector> #include <vector>
namespace XCEngine { namespace XCEngine {
@@ -244,6 +245,71 @@ inline BuiltinPassResourceSemantic ResolveBuiltinPassResourceSemantic(
return BuiltinPassResourceSemantic::Unknown; return BuiltinPassResourceSemantic::Unknown;
} }
inline const char* BuiltinPassResourceSemanticToString(BuiltinPassResourceSemantic semantic) {
switch (semantic) {
case BuiltinPassResourceSemantic::PerObject:
return "PerObject";
case BuiltinPassResourceSemantic::Material:
return "Material";
case BuiltinPassResourceSemantic::Lighting:
return "Lighting";
case BuiltinPassResourceSemantic::ShadowReceiver:
return "ShadowReceiver";
case BuiltinPassResourceSemantic::BaseColorTexture:
return "BaseColorTexture";
case BuiltinPassResourceSemantic::ShadowMapTexture:
return "ShadowMapTexture";
case BuiltinPassResourceSemantic::LinearClampSampler:
return "LinearClampSampler";
case BuiltinPassResourceSemantic::ShadowMapSampler:
return "ShadowMapSampler";
case BuiltinPassResourceSemantic::Unknown:
default:
return "Unknown";
}
}
inline const char* ShaderResourceTypeToString(Resources::ShaderResourceType type) {
switch (type) {
case Resources::ShaderResourceType::ConstantBuffer:
return "ConstantBuffer";
case Resources::ShaderResourceType::Texture2D:
return "Texture2D";
case Resources::ShaderResourceType::TextureCube:
return "TextureCube";
case Resources::ShaderResourceType::Sampler:
return "Sampler";
default:
return "Unknown";
}
}
inline Containers::String DescribeShaderResourceBinding(
const Resources::ShaderResourceBindingDesc& binding) {
const BuiltinPassResourceSemantic resolvedSemantic = ResolveBuiltinPassResourceSemantic(binding);
return Containers::String("name=") + binding.name +
", semantic=" + binding.semantic +
", resolvedSemantic=" + Containers::String(BuiltinPassResourceSemanticToString(resolvedSemantic)) +
", type=" + Containers::String(ShaderResourceTypeToString(binding.type)) +
", set=" + Containers::String(std::to_string(binding.set).c_str()) +
", binding=" + Containers::String(std::to_string(binding.binding).c_str());
}
inline Containers::String DescribeShaderResourceBindings(
const Containers::Array<Resources::ShaderResourceBindingDesc>& bindings) {
Containers::String description;
for (size_t bindingIndex = 0; bindingIndex < bindings.Size(); ++bindingIndex) {
if (!description.Empty()) {
description += " | ";
}
description += "[" + Containers::String(std::to_string(bindingIndex).c_str()) + "] ";
description += DescribeShaderResourceBinding(bindings[bindingIndex]);
}
return description;
}
inline bool IsBuiltinPassResourceTypeCompatible( inline bool IsBuiltinPassResourceTypeCompatible(
BuiltinPassResourceSemantic semantic, BuiltinPassResourceSemantic semantic,
Resources::ShaderResourceType type) { Resources::ShaderResourceType type) {

View File

@@ -422,7 +422,13 @@ BuiltinDepthStylePassBase::PassResourceLayout* BuiltinDepthStylePassBase::GetOrC
BuiltinPassResourceBindingPlan bindingPlan = {}; BuiltinPassResourceBindingPlan bindingPlan = {};
Containers::String bindingPlanError; Containers::String bindingPlanError;
if (!TryBuildSupportedBindingPlan(*resolvedShaderPass.pass, bindingPlan, &bindingPlanError)) { if (!TryBuildSupportedBindingPlan(*resolvedShaderPass.pass, bindingPlan, &bindingPlanError)) {
return failLayout(bindingPlanError.CStr()); const Containers::String contextualError =
Containers::String("BuiltinDepthStylePassBase failed to resolve pass resource bindings for shader='") +
resolvedShaderPass.shader->GetPath() +
"', pass='" + resolvedShaderPass.passName +
"': " + bindingPlanError +
". Bindings: " + DescribeShaderResourceBindings(resolvedShaderPass.pass->resources);
return failLayout(contextualError.CStr());
} }
std::vector<BuiltinPassSetLayoutMetadata> setLayouts; std::vector<BuiltinPassSetLayoutMetadata> setLayouts;

View File

@@ -549,7 +549,13 @@ BuiltinForwardPipeline::PassResourceLayout* BuiltinForwardPipeline::GetOrCreateP
BuiltinPassResourceBindingPlan bindingPlan = {}; BuiltinPassResourceBindingPlan bindingPlan = {};
Containers::String bindingPlanError; Containers::String bindingPlanError;
if (!TryBuildBuiltinPassResourceBindingPlan(resourceBindings, bindingPlan, &bindingPlanError)) { if (!TryBuildBuiltinPassResourceBindingPlan(resourceBindings, bindingPlan, &bindingPlanError)) {
return failLayout(bindingPlanError.CStr()); const Containers::String contextualError =
Containers::String("BuiltinForwardPipeline failed to resolve pass resource bindings for shader='") +
resolvedShaderPass.shader->GetPath() +
"', pass='" + resolvedShaderPass.passName +
"': " + bindingPlanError +
". Bindings: " + DescribeShaderResourceBindings(resourceBindings);
return failLayout(contextualError.CStr());
} }
const bool hasAnyResource = !bindingPlan.bindings.Empty(); const bool hasAnyResource = !bindingPlan.bindings.Empty();