From 7bd2f0831327113a4a51ff4d6903e7db9cb8e3d1 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Sat, 22 Aug 2026 13:40:35 -0400 Subject: [PATCH] [Fix] (DirectGLES): stop advertising GL_ARB_texture_view, whose functional half fails on a host driver that has EXT_texture_view --- MobileGL/Config.h | 7 +++++++ MobileGL/ConfigLoader.cpp | 1 + .../DirectGLES/BackendObject_DirectGLES.cpp | 18 +++++++++++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/MobileGL/Config.h b/MobileGL/Config.h index 4ee37b48..78626248 100644 --- a/MobileGL/Config.h +++ b/MobileGL/Config.h @@ -69,6 +69,13 @@ namespace MobileGL::MG_Config { struct FeaturesTable { // MOBILEGL_DISABLE_TIMERQUERY: do not advertise or use GPU timer queries. Bool DisableTimerQuery = false; + // MOBILEGL_ENABLE_GLES_TEXTURE_VIEW: advertise GL_ARB_texture_view on DirectGLES when + // the host ES driver has EXT/OES_texture_view. Off by default: the host extension is + // present on Adreno 830 and the functional half of KHR-GL4{2,3}.texture_view still fails + // there, because the view's ES internalformat is normalized independently of the storage + // it aliases (see BackendObject_DirectGLES::BuildAdvertisedExtensions). The flag exists + // so that work can be done without editing the gate. + Bool EnableGlesTextureView = false; // MOBILEGL_ENABLE_SPIRV_VALIDATION: validate generated and transformed SPIR-V. // Disabled by default because validation is a diagnostics-only cost. Bool EnableSpirvValidation = false; diff --git a/MobileGL/ConfigLoader.cpp b/MobileGL/ConfigLoader.cpp index c86a47ab..23cb5f1d 100644 --- a/MobileGL/ConfigLoader.cpp +++ b/MobileGL/ConfigLoader.cpp @@ -162,6 +162,7 @@ namespace MobileGL::MG_ConfigLoader { inline void InitFeatures() { auto& features = MG_Config::Features; features.DisableTimerQuery = QueryEnvFlag("MOBILEGL_DISABLE_TIMERQUERY"); + features.EnableGlesTextureView = QueryEnvFlag("MOBILEGL_ENABLE_GLES_TEXTURE_VIEW"); features.EnableSpirvValidation = QueryEnvFlag("MOBILEGL_ENABLE_SPIRV_VALIDATION"); features.UseAngle = QueryEnvFlag("MOBILEGL_USE_ANGLE"); #if defined(MOBILEGL_TRACE_ANGLE_VARIANTS) diff --git a/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp b/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp index 544d0e26..99164716 100644 --- a/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp +++ b/MobileGL/MG_Backend/DirectGLES/BackendObject_DirectGLES.cpp @@ -1096,7 +1096,23 @@ namespace MobileGL::MG_Backend::DirectGLES { // a single shading pass). A copy-based fallback satisfies neither half, and fails // silently; withholding the string and answering glTextureView with INVALID_OPERATION is // the only behaviour that cannot be mistaken for success. - if (textureViewSupported) { + // + // The host extension is necessary and NOT sufficient, which is why this second gate + // exists. Adreno 830 has EXT_texture_view, and on it the whole functional half of + // KHR-GL4{2,3}.texture_view fails: base_and_max_levels, reference_counting and + // view_sampling Fail and view_classes crashes, while only the two pure-API cases + // (errors, gettexparameter - neither of which touches the host view) pass. The cause is + // known and is MobileGL's, not the driver's: SyncTextureViewToBackend normalizes the + // VIEW's ES internalformat independently of the storage it aliases, so whenever the two + // land on different renderability carriers the host rejects the pair, the error is + // swallowed, and the view is left as a storage-less name that samples as zeros. + // DirectVulkan builds the view as a second VkImageView over one VkImage and has no such + // seam - it passes 5 of the 7 cases on the same device - so the string stays there. + // + // Until that reconciliation exists, advertising here would be the same lie the comment + // above refuses to tell, just with an extra prerequisite met. Set + // MOBILEGL_ENABLE_GLES_TEXTURE_VIEW=1 to re-enable it for that work. + if (textureViewSupported && MG_Config::Features.EnableGlesTextureView) { extensions.push_back(E_GL_ARB_texture_view); } // Only advertised when the host ES driver actually filters anisotropically: the sampler