mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-07 19:58:32 +09:00
[Fix] (DirectGLES): never skip a framebuffer bind on a stale version snapshot
BindCurrentFBO returned early when the framebuffer binding slot's version matched g_fboBindVersions - but nothing on that path ever writes that entry. Only ForceBindCurrentFBO stamps it, so the comparison was against an arbitrarily old snapshot, and any later slot version that happened to land on the same 16-bit value read as "already bound". The driver was then left on whatever framebuffer it had last been given. That is how KHR-GL32.packed_pixels.varied_rectangle.rg8i_format_rg_integer read its gradient back out of the previous subtest's framebuffer, seeing 18 where 127 was expected. It only shows up after a few thousand cases have gone by - long enough for the counter to come back around - which is why it reproduced exactly under one caselist and not at all in isolation. Drop the fast path. Skipping redundant work is BindFramebufferId's job: it shadows the driver's own draw and read bindings and drops the glBindFramebuffer when the target already holds that id, which is where the cost actually is. What is left here is one registry lookup. Takes GL32 to 100% conformance; GL30, GL31 and GL33 stay at 100%.
This commit is contained in:
@@ -1196,8 +1196,16 @@ namespace MobileGL::MG_Backend::DirectGLES {
|
||||
ZoneScopedC(TRACY_ZONECOLOR_BACKEND);
|
||||
#endif
|
||||
auto& slot = MG_State::pGLContext->GetFramebufferBindingSlot(target);
|
||||
if (slot.GetVersion() == FramebufferImpl::g_fboBindVersions[(SizeT)target]) return;
|
||||
|
||||
// No fast path on the binding slot's version. It is a 16-bit counter that only
|
||||
// ForceBindCurrentFBO ever stamps here, so the comparison was against an arbitrarily old
|
||||
// snapshot and any later slot version that happened to land on it - one wrap of the
|
||||
// counter, or simply enough rebinds - read as "already bound" and left the driver on a
|
||||
// completely different framebuffer. KHR-GL32.packed_pixels then read its gradient back
|
||||
// out of the previous subtest's framebuffer.
|
||||
//
|
||||
// Skipping the work is BindFramebufferId's job anyway: it shadows the driver's own
|
||||
// draw/read bindings and drops the glBindFramebuffer when the target already holds the id,
|
||||
// which is where the cost actually is. What is left here is one registry lookup.
|
||||
const auto& currentFBO = slot.GetBoundObject();
|
||||
if (currentFBO && currentFBO != MG_Impl::GLImpl::FramebufferImpl::pDefaultFramebufferInfo->defaultFBO) {
|
||||
const auto& backendFBOIt = FramebufferImpl::g_backendFramebufferObjects.find(currentFBO.get());
|
||||
|
||||
Reference in New Issue
Block a user