From 5c75919b14b09d4cf1df04a8f3509ddd7b893a05 Mon Sep 17 00:00:00 2001 From: ssdfasd <2156608475@qq.com> Date: Sun, 5 Apr 2026 17:10:15 +0800 Subject: [PATCH] Improve builtin pass binding diagnostics --- .../Rendering/RenderMaterialUtility.h | 66 +++++++++++++++++++ .../Passes/BuiltinDepthStylePassBase.cpp | 8 ++- .../Pipelines/BuiltinForwardPipeline.cpp | 8 ++- 3 files changed, 80 insertions(+), 2 deletions(-) diff --git a/engine/include/XCEngine/Rendering/RenderMaterialUtility.h b/engine/include/XCEngine/Rendering/RenderMaterialUtility.h index eb308314..59dfddd2 100644 --- a/engine/include/XCEngine/Rendering/RenderMaterialUtility.h +++ b/engine/include/XCEngine/Rendering/RenderMaterialUtility.h @@ -10,6 +10,7 @@ #include #include #include +#include #include namespace XCEngine { @@ -244,6 +245,71 @@ inline BuiltinPassResourceSemantic ResolveBuiltinPassResourceSemantic( 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& 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( BuiltinPassResourceSemantic semantic, Resources::ShaderResourceType type) { diff --git a/engine/src/Rendering/Passes/BuiltinDepthStylePassBase.cpp b/engine/src/Rendering/Passes/BuiltinDepthStylePassBase.cpp index 08aa4fdd..38cd3879 100644 --- a/engine/src/Rendering/Passes/BuiltinDepthStylePassBase.cpp +++ b/engine/src/Rendering/Passes/BuiltinDepthStylePassBase.cpp @@ -422,7 +422,13 @@ BuiltinDepthStylePassBase::PassResourceLayout* BuiltinDepthStylePassBase::GetOrC BuiltinPassResourceBindingPlan bindingPlan = {}; Containers::String 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 setLayouts; diff --git a/engine/src/Rendering/Pipelines/BuiltinForwardPipeline.cpp b/engine/src/Rendering/Pipelines/BuiltinForwardPipeline.cpp index 6022500e..caeb961e 100644 --- a/engine/src/Rendering/Pipelines/BuiltinForwardPipeline.cpp +++ b/engine/src/Rendering/Pipelines/BuiltinForwardPipeline.cpp @@ -549,7 +549,13 @@ BuiltinForwardPipeline::PassResourceLayout* BuiltinForwardPipeline::GetOrCreateP BuiltinPassResourceBindingPlan bindingPlan = {}; Containers::String 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();