From 72532de78049da038cbc82f81c31bc28164a89c5 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Thu, 16 Jul 2026 19:44:36 -0400 Subject: [PATCH] [Fix] (MG_Util/Texture, MG_Util/Converters): canonical packed transfer types for RGBA4/RGB565/RGB10_A2UI - NormalizePixelFormat's default handed backends GL_UNSIGNED_BYTE (and a non-integer GL_RGB transfer format for RGB10_A2UI), so uploads read 4 bytes per texel from 2-byte packed shadow rows (rgba4 layers shifted by 2x slice stride) or were rejected outright; also map GL_RGB565 <-> TextureInternalFormat::RGB5 (the enum had no GL_RGB565 mapping at all, glTexImage* with it failed as unknown) --- .../Converters/GLToMG/TextureEnumConverter.cpp | 3 +++ .../Converters/MGToGL/TextureEnumConverter.cpp | 5 ++++- .../MG_Util/Texture/TextureFormatProcessor.cpp | 17 +++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/MobileGL/MG_Util/Converters/GLToMG/TextureEnumConverter.cpp b/MobileGL/MG_Util/Converters/GLToMG/TextureEnumConverter.cpp index 42ad434f..5654b5d3 100644 --- a/MobileGL/MG_Util/Converters/GLToMG/TextureEnumConverter.cpp +++ b/MobileGL/MG_Util/Converters/GLToMG/TextureEnumConverter.cpp @@ -131,6 +131,9 @@ namespace MobileGL { case GL_RGB4: return TextureInternalFormat::RGB4; case GL_RGB5: + // GL_RGB565 (GL 4.1 / ARB_ES2_compatibility, used directly by the GL CTS) is the + // ES-facing rendition of the legacy RGB5 resolution. + case GL_RGB565: return TextureInternalFormat::RGB5; case GL_RGB8: return TextureInternalFormat::RGB8; diff --git a/MobileGL/MG_Util/Converters/MGToGL/TextureEnumConverter.cpp b/MobileGL/MG_Util/Converters/MGToGL/TextureEnumConverter.cpp index f97b37bc..bee9ac88 100644 --- a/MobileGL/MG_Util/Converters/MGToGL/TextureEnumConverter.cpp +++ b/MobileGL/MG_Util/Converters/MGToGL/TextureEnumConverter.cpp @@ -113,7 +113,10 @@ namespace MobileGL { case TextureInternalFormat::RGB4: return GL_RGB4; case TextureInternalFormat::RGB5: - return GL_RGB5; + // Emit the ES-compatible GL_RGB565 rendition: desktop GL_RGB5 is not a legal + // sized internalformat on OpenGL ES backends, GL_RGB565 is (and GL 4.1+ + // accepts it too via ARB_ES2_compatibility). + return GL_RGB565; case TextureInternalFormat::RGB8: return GL_RGB8; case TextureInternalFormat::RGB8Snorm: diff --git a/MobileGL/MG_Util/Texture/TextureFormatProcessor.cpp b/MobileGL/MG_Util/Texture/TextureFormatProcessor.cpp index aa5fad0f..6d5bea22 100644 --- a/MobileGL/MG_Util/Texture/TextureFormatProcessor.cpp +++ b/MobileGL/MG_Util/Texture/TextureFormatProcessor.cpp @@ -282,12 +282,17 @@ namespace MobileGL::MG_Util::TextureFormatProcessor { // Color sized other case GL_RGB9_E5: case GL_R11F_G11F_B10F: + case GL_RGB565: *outFormat = GL_RGB; break; case GL_RGB10_A2: case GL_RGB5_A1: + case GL_RGBA4: *outFormat = GL_RGBA; break; + case GL_RGB10_A2UI: + *outFormat = GL_RGBA_INTEGER; + break; // Depth case GL_DEPTH_COMPONENT16: @@ -459,11 +464,23 @@ namespace MobileGL::MG_Util::TextureFormatProcessor { *outType = GL_UNSIGNED_INT_10F_11F_11F_REV; break; case GL_RGB10_A2: + case GL_RGB10_A2UI: *outType = GL_UNSIGNED_INT_2_10_10_10_REV; break; case GL_RGB5_A1: *outType = GL_UNSIGNED_SHORT_5_5_5_1; break; + // The shadow mip keeps these formats' packed client bytes (legacy copy path), + // so the canonical transfer type must stay the packed word — the previous + // default (GL_UNSIGNED_BYTE) made the backend read 4 bytes per texel from a + // 2-byte-per-texel shadow (KHR-GL33.pixelstoragemodes teximage rgba4/rgb565 + // sliced/garbled uploads). + case GL_RGBA4: + *outType = GL_UNSIGNED_SHORT_4_4_4_4; + break; + case GL_RGB565: + *outType = GL_UNSIGNED_SHORT_5_6_5; + break; // Depth case GL_DEPTH_COMPONENT16: