From 9cdc82fbdd7c8b5c08f121365b56a96906261d7c Mon Sep 17 00:00:00 2001 From: BZLZHH Date: Wed, 5 Aug 2026 06:08:59 -0400 Subject: [PATCH] [Fix] (MG_Backend): actually bind the sampler object DirectGLES just synced BindCurrentTextures' program-driven path synced a bound sampler object's parameters to its backend object and then never put it on the texture unit, so every sampler object was inert and the driver kept sampling with the texture's own parameters - direct_state_access.samplers_functional read black where the sampler's NEAREST filtering should have given red. The bind alone is a regression, and the CTS says so loudly: a sampler left on a unit by an earlier draw keeps being applied, and a multisample texture takes no sampler object at all, so the next draw against one is rejected and all 27 textures_storage_multisample_3d_* cases fail. The sibling path in the same function had an empty else branch where the unbind belonged; it now unbinds, making the two symmetric. Takes samplers_functional from failing to passing on Espryt, with no other case moving in either direction. --- MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp index ba805d69..41e88bbd 100644 --- a/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp +++ b/MobileGL/MG_Backend/DirectGLES/DirectGLES.cpp @@ -1663,8 +1663,11 @@ namespace MobileGL::MG_Backend::DirectGLES { if (backendSamplerIt != SamplerImpl::g_backendSamplerObjects.end()) { backendSamplerIt->second->Bind(unit); } - } else { + // Symmetric with the bind above: a sampler object left on the unit by an earlier + // draw keeps being applied, and on a multisample texture - which takes no sampler + // object at all - the draw is rejected outright. + SamplerImpl::UnbindSampler(unit); } } } @@ -1844,6 +1847,10 @@ namespace MobileGL::MG_Backend::DirectGLES { backendObj = MakeShared(); } backendObj->SyncToBackend(samplerObject); + // Syncing the object's parameters is not the same as putting it on the + // unit: without this the driver kept sampling with the texture's own + // parameters and every sampler object was inert. + backendObj->Bind(unit); } else { SamplerImpl::UnbindSampler(unit); }