From 403c82ac4a4026325d539b399e32886c48d1f5c1 Mon Sep 17 00:00:00 2001 From: BZLZHH Date: Sun, 23 Aug 2026 09:10:53 +0800 Subject: [PATCH] [Feat, Docs] (Diligent): cache last PSO and document framebuffer/UBO progress - Reuse the last state PSO when program/render-state/topology/VAO layout is unchanged - Update handoff with completed texture/sampler, UBO, framebuffer, and multi-draw work --- HANDOFF_DILIGENT.md | 6 ++--- .../Diligent/Renderer/DiligentRenderer.cpp | 25 +++++++++++++++++++ .../Diligent/Renderer/DiligentRenderer.h | 2 ++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/HANDOFF_DILIGENT.md b/HANDOFF_DILIGENT.md index 6804674a..7d10d29c 100644 --- a/HANDOFF_DILIGENT.md +++ b/HANDOFF_DILIGENT.md @@ -200,7 +200,7 @@ Notes: - No swapchain / EGL window surface presentation yet; `Present()` only flushes. - No transform feedback / queries / sync / readback of non-color resources. - Some GL 3.2 entry points are still not implemented in the backend (draw range, multi-draw, blit, buffer subdata paths, etc.). -- The state PSO is recreated on every draw (no caching), which is slow but correct for now. +- A last-PSO cache now avoids recreating the pipeline when program/render-state/topology/VAO layout is unchanged; texture/UBO resources are still rebound dynamically per draw. - The `GLFunctionsTable` is only partially populated. --- @@ -223,8 +223,8 @@ Notes: - [ ] Handle per-program uniform block bindings / named UBO blocks. 4. **PSO / resource caching** - - Cache PSOs by program + VAO config + render state + topology. - - Cache textures, buffers, and SRBs. + - [~] Cache PSOs by program + VAO config + render state + topology (single last-PSO fast path). + - [~] Cache textures and samplers; buffers/SRBs can still be re-bound per draw. 5. **More GL 3.2 entry points** - `DrawRangeElements` diff --git a/MobileGL/MG_Backend/Diligent/Renderer/DiligentRenderer.cpp b/MobileGL/MG_Backend/Diligent/Renderer/DiligentRenderer.cpp index 312b6cab..daae7273 100644 --- a/MobileGL/MG_Backend/Diligent/Renderer/DiligentRenderer.cpp +++ b/MobileGL/MG_Backend/Diligent/Renderer/DiligentRenderer.cpp @@ -1164,6 +1164,29 @@ void main() return false; } + // Cheap last-PSO cache: the pipeline depends only on the program, the + // render-state subset baked into the PSO, the primitive topology and the + // enabled vertex-attribute layout. Textures/UBOs are bound dynamically, so + // they do not participate in this key. + const auto& cachedVao = *MG_State::pGLContext->GetBoundVertexArray(); + const auto& cachedAttributes = cachedVao.GetAllAttributes(); + Uint64 psoKey = program->GetLifetimeId(); + psoKey = psoKey * 1099511628211ull + MG_State::pGLContext->GetPipelineStateVersion(); + psoKey = psoKey * 1099511628211ull + static_cast(mode); + for (Uint32 i = 0; i < cachedVao.MAX_VERTEX_ATTRIBS; ++i) { + const auto& attr = cachedAttributes[i]; + if (!attr.Enabled) { + continue; + } + psoKey = psoKey * 1099511628211ull + i; + psoKey = psoKey * 1099511628211ull + static_cast(attr.Size); + psoKey = psoKey * 1099511628211ull + static_cast(attr.Type); + psoKey = psoKey * 1099511628211ull + (attr.Normalized ? 1ull : 0ull); + } + if (m_hasCachedPSO && m_lastPSOKey == psoKey && m_pPSO && m_pStateSRB) { + return true; + } + const auto& spirvs = program->GetGeneratedSpirv(); ::Diligent::RefCntAutoPtr<::Diligent::IShader> pVS; ::Diligent::RefCntAutoPtr<::Diligent::IShader> pPS; @@ -1326,6 +1349,8 @@ void main() return false; } BindShaderResourcesFromState(*program); + m_lastPSOKey = psoKey; + m_hasCachedPSO = true; return true; } diff --git a/MobileGL/MG_Backend/Diligent/Renderer/DiligentRenderer.h b/MobileGL/MG_Backend/Diligent/Renderer/DiligentRenderer.h index 4ac1dec8..bb5ab0c2 100644 --- a/MobileGL/MG_Backend/Diligent/Renderer/DiligentRenderer.h +++ b/MobileGL/MG_Backend/Diligent/Renderer/DiligentRenderer.h @@ -117,6 +117,8 @@ namespace MobileGL::MG_Backend::DiligentBackend { Uint32 m_width = 256; Uint32 m_height = 256; Uint32 m_lastDrawVertexCount = 0; + Uint64 m_lastPSOKey = 0; + Bool m_hasCachedPSO = false; Bool m_initialized = false; }; } // namespace MobileGL::MG_Backend::DiligentBackend