[Feat] (MG_Util, DirectGLES, DirectVulkan): normalize rectangle coordinates in the module

Neither target API has GL_TEXTURE_RECTANGLE: ESSL has no rectangle sampler, and
Vulkan's SPIR-V environment does not allow Dim::Rect. Both emulate it on a plain 2D
texture, and the two differ in exactly one way - a rectangle lookup addresses texels
where a 2D one addresses [0,1].

That one difference now lives in one SPIR-V pass, so neither backend has to know about
it: every lookup taking normalized coordinates gets its coordinate divided by the size
the texture reports, and the image type is then rewritten to 2D. Magma had no rectangle
handling at all - it fed Dim::Rect straight to Vulkan, which read the texel coordinates
as normalized and sampled the edge, so all fifteen KHR-GL40.texture_gather.*-2drect
cases came back holding the clear colour.

This replaces the ESSL text rewrite that did the same divide for DirectGLES only. Doing
it in the module instead is both shorter and stricter: the pass resolves an operation's
image type through the sampled-image and pointer wrappers rather than matching a
sampler name in generated source, so it cannot be fooled by an expression where it
expected an identifier, and it needs no help from the frontend reflection to know which
samplers were rectangles.

Still declined, as before: the Dref *sample* forms, whose coordinate carries the compare
value in its last component, and the projective ones, where the divide would have to
happen after the perspective divide. texelFetch is deliberately untouched - integer
texel coordinates mean the same thing on both targets.

KHR-GL40.texture_gather: Magma 66 failures -> 2, Espryt stays at 75/75.
This commit is contained in:
BZLZHH
2026-08-04 13:25:40 -04:00
parent 44ee6b66b3
commit 28d0af6f04
11 changed files with 263 additions and 192 deletions
+1 -1
View File
@@ -1870,7 +1870,7 @@ TEST_F(TextureTest, DirectGLESTreats2DArrayAsSupportedTextureTarget) {
// Every desktop-only target is stored on an ES one (MapToBackendTextureTarget): 1D and
// 1D-array as 2D / 2D-array, matching SPIRV-Cross's ES 1D-as-2D shader emission, and
// rectangle as a plain 2D - it is single-level and already clamps, so only the
// non-normalized coordinates differ and LowerRectImagesForEssl handles those.
// non-normalized coordinates differ and LowerRectImages handles those.
EXPECT_TRUE(IsSupportedTextureTarget(TextureTarget::Texture1D));
EXPECT_TRUE(IsSupportedTextureTarget(TextureTarget::Texture1DArray));
EXPECT_TRUE(IsSupportedTextureTarget(TextureTarget::TextureRectangle));