[Fix] (DirectGLES): report the alpha added by the multisample widening as ONE

A three-channel format widened to four for a multisample target gains an alpha
channel the application never asked for, and it holds whatever the draw that filled
the texture happened to write there. GL says a format without alpha reads back as
1.0, so KHR-GL33.texture_swizzle - which fills such a texture by rendering
vec4(r, g, b, 0.0) and then swizzles red from alpha - read 0 where it expected the
maximum.

Fold ONE into the texture's swizzle for exactly those textures, composed with the
swizzle the application set, so the promotion stays invisible.
This commit is contained in:
BZLZHH
2026-08-02 04:25:08 -04:00
parent e45f7ae5d4
commit 01d0f01d13
3 changed files with 34 additions and 1 deletions
+13 -1
View File
@@ -2405,7 +2405,19 @@ namespace MobileGL::MG_Backend::DirectGLES {
MGLOG_D("%s(%s:%d) ES error %s", func, file, line, MG_Util::ConvertGLEnumToString(err).c_str());
});
const auto& swizzleParams = stateTextureObject->GetAllSwizzleParams();
// A three-channel format widened to four for a multisample target (see
// NormalizePixelFormat) gains an alpha channel the frontend format does not have, and
// whatever the draw that filled it wrote there is not what GL would report: a format
// without alpha reads back as 1.0. Answer the ALPHA swizzle source with ONE so the
// promotion stays invisible, composed with the swizzle the application asked for.
Vec4<TextureSwizzleParam> swizzleParams = stateTextureObject->GetAllSwizzleParams();
if (TextureImpl::BackendTextureFormatAddsAlpha(stateTextureObject->GetFormat(), targetInternal)) {
for (SizeT channel = 0; channel < 4; ++channel) {
if (swizzleParams[channel] == TextureSwizzleParam::Alpha) {
swizzleParams[channel] = TextureSwizzleParam::One;
}
}
}
if (swizzleParams != m_cacheSwizzleParams) {
#define SYNC_TEX_SWIZZLE_PARAM_IF_CHANGED(func, glEnum) \
if (m_cacheSwizzleParams.func != swizzleParams.func) { \