[Feat] (DirectGLES): support rectangle textures where the emulation is exact

ES has no rectangle target and no rectangle sampler, so DirectGLES declared
GL_TEXTURE_RECTANGLE unsupported outright: the texture was never synced or bound,
and SPIRV-Cross refused the shader ("Rectangle textures are not supported on
OpenGL ES") which left the whole program unlinkable.

A rectangle texture is a single-level, clamped 2D texture whose only real
difference is that its lookups take non-normalized coordinates. Where every use
takes *integer* texel coordinates - texelFetch, textureSize - that difference
does not exist at all, and the two are the same thing. So:

- A new SPIR-V pass rewrites Dim::Rect image types to Dim::2D before
  transpiling, and restates the rectangle capabilities as Shader. It declines
  any module containing a normalized-coordinate lookup rather than emitting
  something subtly wrong; SPIRV-Cross then rejects that module exactly as
  before, so nothing that used to work changes and nothing new renders wrongly.
- The target maps to GL_TEXTURE_2D for storage, uploads and binding, alongside
  the existing 1D and 1D-array emulation.

Fixes KHR-GL31.texture_size_promotion.functional outright, which takes GL31 to
100% conformance. GL32/GL33 advance past their rectangle cases to a separate
GL_RGB16 multisample issue. No regressions across texture_swizzle, shaders30,
texture_lod_*, framebuffer_blit, packed_depth_stencil, transform_feedback,
clip_distance or draw_buffers; DirectVulkan re-verified unaffected.
This commit is contained in:
BZLZHH
2026-08-02 01:56:22 -04:00
parent 9dff24f3e1
commit 6de38c666c
4 changed files with 112 additions and 7 deletions
@@ -3344,6 +3344,17 @@ namespace MobileGL::MG_Backend::DirectGLES {
effectiveSpirv = &noperspectiveSpirv;
}
// ES has no rectangle sampler, and SPIRV-Cross refuses the whole module rather
// than approximating one. Where every use takes integer texel coordinates a
// rectangle image is indistinguishable from a 2D one, so rewrite the type and let
// it through; the pass declines anything it cannot convert exactly.
Vector<unsigned int> rectLoweredSpirv;
if (MG_Util::ShaderTranspiler::ShaderCompiler::LowerRectImagesForEssl(*effectiveSpirv,
rectLoweredSpirv) &&
!rectLoweredSpirv.empty()) {
effectiveSpirv = &rectLoweredSpirv;
}
MG_Util::ShaderTranspiler::SpvcSession spvcSession(*effectiveSpirv,
MG_Util::ShaderTranspiler::SessionUsageBit::Transpile);