[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
This commit is contained in:
BZLZHH
2026-08-23 09:10:53 +08:00
parent 827d46cad3
commit 403c82ac4a
3 changed files with 30 additions and 3 deletions
+3 -3
View File
@@ -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`
@@ -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<Uint64>(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<Uint64>(attr.Size);
psoKey = psoKey * 1099511628211ull + static_cast<Uint64>(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;
}
@@ -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