From 09d13579fc66f07720e29278532790a1092dd35d Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Thu, 19 Jun 2025 15:55:17 +0800 Subject: [PATCH] [Fix]: PSO caching broken? Just re-generate on mismatch (TODO: fix this later) --- .../Implementations/EGL/Diligent/EGL_impl.cpp | 84 ++++++++++++++----- MG/MG_UTIL/Debug/Debug.cpp | 31 +++++++ MG/MG_UTIL/Debug/Debug.h | 1 + 3 files changed, 97 insertions(+), 19 deletions(-) diff --git a/MG/MG_GL/Implementations/EGL/Diligent/EGL_impl.cpp b/MG/MG_GL/Implementations/EGL/Diligent/EGL_impl.cpp index 9a075c7b..6d4df70b 100644 --- a/MG/MG_GL/Implementations/EGL/Diligent/EGL_impl.cpp +++ b/MG/MG_GL/Implementations/EGL/Diligent/EGL_impl.cpp @@ -104,7 +104,6 @@ namespace MG_Diligent { (commonState.colorMask[2] ? 4 : 0) | (commonState.colorMask[3] ? 8 : 0); hash ^= std::hash()(colorMask); - hash ^= std::hash()(commonState.blendDstAlpha); hash ^= std::hash()(capabilities[GL_BLEND]); hash ^= std::hash()(commonState.depthFunc); @@ -127,9 +126,12 @@ namespace MG_Diligent { } hash ^= std::hash()(fbInfo.ColorRTVs.size()); - for (const auto& rtv : fbInfo.ColorRTVs) { - if (rtv) { - hash ^= std::hash()(rtv->GetDesc().Format); + if (!fbInfo.pRenderPass) { + // 只有在使用隐式渲染通道时,才将渲染目标格式包含在哈希中 + for (const auto& rtv : fbInfo.ColorRTVs) { + if (rtv) { + hash ^= std::hash()(rtv->GetDesc().Format); + } } } @@ -176,17 +178,28 @@ namespace MG_Diligent { PSOCreateInfo.GraphicsPipeline.PrimitiveTopology = Diligent::PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - /* - PSOCreateInfo.GraphicsPipeline.NumRenderTargets = fbInfo.ColorRTVs.size(); - for (size_t i = 0; i < fbInfo.ColorRTVs.size(); ++i) { - if (fbInfo.ColorRTVs[i]) { - PSOCreateInfo.GraphicsPipeline.RTVFormats[i] = - fbInfo.ColorRTVs[i]->GetDesc().Format; + // 设置渲染目标数量和格式 + if (fbInfo.pRenderPass) { + // 当使用显式渲染通道时,NumRenderTargets必须为0 + PSOCreateInfo.GraphicsPipeline.NumRenderTargets = 0; + } else { + // 当使用隐式渲染通道时,需要设置渲染目标数量和格式 + PSOCreateInfo.GraphicsPipeline.NumRenderTargets = fbInfo.ColorRTVs.size(); + if (PSOCreateInfo.GraphicsPipeline.NumRenderTargets == 0) { + // 如果没有颜色附件,至少设置一个默认的 + PSOCreateInfo.GraphicsPipeline.NumRenderTargets = 1; + PSOCreateInfo.GraphicsPipeline.RTVFormats[0] = Diligent::TEX_FORMAT_RGBA8_UNORM; } else { - PSOCreateInfo.GraphicsPipeline.RTVFormats[i] = Diligent::TEX_FORMAT_RGBA8_UNORM; + for (size_t i = 0; i < fbInfo.ColorRTVs.size(); ++i) { + if (fbInfo.ColorRTVs[i]) { + PSOCreateInfo.GraphicsPipeline.RTVFormats[i] = + fbInfo.ColorRTVs[i]->GetDesc().Format; + } else { + PSOCreateInfo.GraphicsPipeline.RTVFormats[i] = Diligent::TEX_FORMAT_RGBA8_UNORM; + } + } } } - */ PSOCreateInfo.GraphicsPipeline.DSVFormat = Diligent::TEX_FORMAT_UNKNOWN; @@ -206,12 +219,28 @@ namespace MG_Diligent { (commonState.colorMask[1] ? Diligent::COLOR_MASK_GREEN : 0) | (commonState.colorMask[2] ? Diligent::COLOR_MASK_BLUE : 0) | (commonState.colorMask[3] ? Diligent::COLOR_MASK_ALPHA : 0)); -// MG_Util::Debug::LogD("Blend states: "); -// MG_Util::Debug::LogD(" BlendEnable: %s", blendDesc.RenderTargets[0].BlendEnable ? "true" : "false"); -// MG_Util::Debug::LogD(" SrcBlend: %s", MG_Util::Debug::GLEnumToString(commonState.blendSrcRGB)); -// MG_Util::Debug::LogD(" DestBlend: %s", MG_Util::Debug::GLEnumToString(commonState.blendDstRGB)); -// MG_Util::Debug::LogD(" SrcBlendAlpha: %s", MG_Util::Debug::GLEnumToString(commonState.blendSrcAlpha)); -// MG_Util::Debug::LogD(" DestBlendAlpha: %s", MG_Util::Debug::GLEnumToString(commonState.blendDstAlpha)); + + // 添加详细的混合状态调试信息 + MG_Util::Debug::LogD("Configured Blend State:"); + MG_Util::Debug::LogD(" Using explicit render pass: %s", fbInfo.pRenderPass ? "true" : "false"); + MG_Util::Debug::LogD(" NumRenderTargets: %u", PSOCreateInfo.GraphicsPipeline.NumRenderTargets); + MG_Util::Debug::LogD(" IndependentBlendEnable: %s", blendDesc.IndependentBlendEnable ? "true" : "false"); + MG_Util::Debug::LogD(" RenderTargets[0].BlendEnable: %s", blendDesc.RenderTargets[0].BlendEnable ? "true" : "false"); + MG_Util::Debug::LogD(" RenderTargets[0].SrcBlend: %d (GL: %s)", + blendDesc.RenderTargets[0].SrcBlend, + MG_Util::Debug::GLEnumToString(commonState.blendSrcRGB)); + MG_Util::Debug::LogD(" RenderTargets[0].DestBlend: %d (GL: %s)", + blendDesc.RenderTargets[0].DestBlend, + MG_Util::Debug::GLEnumToString(commonState.blendDstRGB)); + MG_Util::Debug::LogD(" RenderTargets[0].BlendOp: %d", blendDesc.RenderTargets[0].BlendOp); + MG_Util::Debug::LogD(" RenderTargets[0].SrcBlendAlpha: %d (GL: %s)", + blendDesc.RenderTargets[0].SrcBlendAlpha, + MG_Util::Debug::GLEnumToString(commonState.blendSrcAlpha)); + MG_Util::Debug::LogD(" RenderTargets[0].DestBlendAlpha: %d (GL: %s)", + blendDesc.RenderTargets[0].DestBlendAlpha, + MG_Util::Debug::GLEnumToString(commonState.blendDstAlpha)); + MG_Util::Debug::LogD(" RenderTargets[0].BlendOpAlpha: %d", blendDesc.RenderTargets[0].BlendOpAlpha); + MG_Util::Debug::LogD(" RenderTargets[0].RenderTargetWriteMask: %u", blendDesc.RenderTargets[0].RenderTargetWriteMask); Diligent::DepthStencilStateDesc &depthStencilDesc = PSOCreateInfo.GraphicsPipeline.DepthStencilDesc; depthStencilDesc.DepthEnable = commonState.capabilities[GL_DEPTH_TEST]; @@ -284,7 +313,24 @@ namespace MG_Diligent { if (it != psoCache.end() && it->second) { MG_Util::Debug::LogD("Found cached PSO: %04X%04X", it->first.programHash, it->first.stateHash); - return it->second; + // TODO: This fixes alpha states, but how does PSO cache not corresponds to GL state machine (commonState)? + // probably a problem in hashing? + auto& desc = it->second->GetGraphicsPipelineDesc(); + MG_Util::Debug::LogD("PSO state - Blend states: "); + MG_Util::Debug::LogD(" SrcBlend: %s", MG_Util::Debug::DiligentBlendFactorToString(desc.BlendDesc.RenderTargets[0].SrcBlend)); + MG_Util::Debug::LogD(" DestBlend: %s", MG_Util::Debug::DiligentBlendFactorToString(desc.BlendDesc.RenderTargets[0].DestBlend)); + MG_Util::Debug::LogD(" SrcBlendAlpha: %s", MG_Util::Debug::DiligentBlendFactorToString(desc.BlendDesc.RenderTargets[0].SrcBlendAlpha)); + MG_Util::Debug::LogD(" DestBlendAlpha: %s", MG_Util::Debug::DiligentBlendFactorToString(desc.BlendDesc.RenderTargets[0].DestBlendAlpha)); + // These asserts can fail +// assert(ConvertGLBlendFactor(commonState.blendSrcRGB) == desc.BlendDesc.RenderTargets[0].SrcBlend); +// assert(ConvertGLBlendFactor(commonState.blendDstRGB) == desc.BlendDesc.RenderTargets[0].DestBlend); +// assert(ConvertGLBlendFactor(commonState.blendSrcAlpha) == desc.BlendDesc.RenderTargets[0].SrcBlendAlpha); +// assert(ConvertGLBlendFactor(commonState.blendDstAlpha) == desc.BlendDesc.RenderTargets[0].DestBlendAlpha); + if ((ConvertGLBlendFactor(commonState.blendSrcRGB) == desc.BlendDesc.RenderTargets[0].SrcBlend) && + (ConvertGLBlendFactor(commonState.blendDstRGB) == desc.BlendDesc.RenderTargets[0].DestBlend) && + (ConvertGLBlendFactor(commonState.blendSrcAlpha) == desc.BlendDesc.RenderTargets[0].SrcBlendAlpha) && + (ConvertGLBlendFactor(commonState.blendDstAlpha) == desc.BlendDesc.RenderTargets[0].DestBlendAlpha)) + return it->second; } MG_Diligent::BuildInputLayout(program, vaState, programInfo.inputLayout); diff --git a/MG/MG_UTIL/Debug/Debug.cpp b/MG/MG_UTIL/Debug/Debug.cpp index 313fcfb1..17d2bfca 100644 --- a/MG/MG_UTIL/Debug/Debug.cpp +++ b/MG/MG_UTIL/Debug/Debug.cpp @@ -4,6 +4,7 @@ #include "Debug.h" #include "../../Includes.h" +#include "BlendState.h" namespace MG_Util::Debug { static FILE* logFile; @@ -1951,6 +1952,36 @@ void Log##name(const char* format, ...) { \ } #undef CASE } + + const char* DiligentBlendFactorToString(Diligent::BLEND_FACTOR value) { + static char str[128]; + switch (value) { +#define CASE(value) \ + case value: return #value; + CASE(Diligent::BLEND_FACTOR_UNDEFINED) + CASE(Diligent::BLEND_FACTOR_ZERO) + CASE(Diligent::BLEND_FACTOR_ONE) + CASE(Diligent::BLEND_FACTOR_SRC_COLOR) + CASE(Diligent::BLEND_FACTOR_INV_SRC_COLOR) + CASE(Diligent::BLEND_FACTOR_SRC_ALPHA) + CASE(Diligent::BLEND_FACTOR_INV_SRC_ALPHA) + CASE(Diligent::BLEND_FACTOR_DEST_ALPHA) + CASE(Diligent::BLEND_FACTOR_DEST_COLOR) + CASE(Diligent::BLEND_FACTOR_INV_DEST_COLOR) + CASE(Diligent::BLEND_FACTOR_SRC_ALPHA_SAT) + CASE(Diligent::BLEND_FACTOR_BLEND_FACTOR) + CASE(Diligent::BLEND_FACTOR_INV_BLEND_FACTOR) + CASE(Diligent::BLEND_FACTOR_SRC1_COLOR) + CASE(Diligent::BLEND_FACTOR_INV_SRC1_COLOR) + CASE(Diligent::BLEND_FACTOR_SRC1_ALPHA) + CASE(Diligent::BLEND_FACTOR_INV_SRC1_ALPHA) + + default: + sprintf(str, "0x%x", value); + return str; + } +#undef CASE + } } diff --git a/MG/MG_UTIL/Debug/Debug.h b/MG/MG_UTIL/Debug/Debug.h index 9f9fea3c..f114a47d 100644 --- a/MG/MG_UTIL/Debug/Debug.h +++ b/MG/MG_UTIL/Debug/Debug.h @@ -23,6 +23,7 @@ namespace MG_Util { void LogWrite(const char* format, va_list args); const char* GLEnumToString(::GLenum value); + const char* DiligentBlendFactorToString(Diligent::BLEND_FACTOR value); } }