[Feature, Fix, Test] (GLState, GLImpl, DirectVulkan, DirectGLES): implement glTextureView over shared texture storage

This commit is contained in:
2026-08-22 10:41:52 -04:00
parent a5f36c8f8d
commit 6162603072
36 changed files with 2995 additions and 68 deletions
@@ -514,6 +514,10 @@ namespace MobileGL::MG_Util::BackendLoader {
// Optional: absent on an ES 3.2 core driver, and absent on ES 3.1 without the
// matching extension. The tier resolution below picks whichever spelling the
// driver's own support actually comes from.
// Optional by nature: ES never made texture views core, so both spellings are
// absent on plenty of drivers and neither absence is an error.
INIT_GLES_FUNC_OPTIONAL(glTextureViewEXT)
INIT_GLES_FUNC_OPTIONAL(glTextureViewOES)
INIT_GLES_FUNC_OPTIONAL(glTexBufferEXT)
INIT_GLES_FUNC_OPTIONAL(glTexBufferOES)
INIT_GLES_FUNC_OPTIONAL(glTexBufferRangeEXT)
@@ -889,6 +893,11 @@ namespace MobileGL::MG_Util::BackendLoader {
// Resolved into caps.TextureBufferSupport below, once the ES version is also known.
Bool hasExtTextureBuffer = false;
Bool hasOesTextureBuffer = false;
// Resolved into caps.SupportsTextureView below. Two spellings of one extension; the
// entry points differ only in suffix, so unlike the buffer-texture tier there is nothing
// downstream that needs to know WHICH one answered.
Bool hasExtTextureView = false;
Bool hasOesTextureView = false;
// Combined with the three entry points below; DirectGLES emulates baseInstance when this
// comes out false, so a stub pointer counting as support would silently break the draws.
Bool hasBaseInstanceExtension = false;
@@ -925,6 +934,12 @@ namespace MobileGL::MG_Util::BackendLoader {
std::strcmp(extension, "GL_OES_texture_cube_map_array") == 0) {
caps.SupportsTextureCubeMapArray = true;
}
if (std::strcmp(extension, "GL_EXT_texture_view") == 0) {
hasExtTextureView = true;
}
if (std::strcmp(extension, "GL_OES_texture_view") == 0) {
hasOesTextureView = true;
}
if (std::strcmp(extension, "GL_EXT_texture_buffer") == 0) {
hasExtTextureBuffer = true;
}
@@ -985,6 +1000,18 @@ namespace MobileGL::MG_Util::BackendLoader {
glesFuncs.glDrawArraysInstancedBaseInstanceEXT != nullptr &&
glesFuncs.glDrawElementsInstancedBaseInstanceEXT != nullptr &&
glesFuncs.glDrawElementsInstancedBaseVertexBaseInstanceEXT != nullptr;
// ES has no core texture views at any version, so this is extension-only by nature.
// Each spelling must bring its OWN entry point: a driver that advertises the OES string
// is not required to export glTextureViewEXT.
caps.SupportsTextureView = (hasExtTextureView && glesFuncs.glTextureViewEXT != nullptr) ||
(hasOesTextureView && glesFuncs.glTextureViewOES != nullptr);
// Escape hatch for the integration suite: the no-extension path is the one MobileGL has
// to refuse honestly rather than emulate, and on a driver that HAS the extension there
// would otherwise be no way to exercise that refusal (see TextureViewScenario).
if (std::getenv("MOBILEGL_DISABLE_TEXTURE_VIEW") != nullptr) {
MGLOG_I("MOBILEGL_DISABLE_TEXTURE_VIEW is set; reporting no EXT/OES_texture_view support");
caps.SupportsTextureView = false;
}
// Core from ES 3.2 on, so an extension string is not required there; below 3.2 the
// extension is, and the pointer still has to have resolved either way.
const Bool esAtLeast32 = caps.GLESVersion.Major > 3 ||
@@ -604,6 +604,12 @@ namespace MobileGL {
// support comes from GL_EXT_texture_buffer or GL_OES_texture_buffer exports the
// suffixed spellings instead, and a strict eglGetProcAddress returns NULL for the core
// one there - so resolving only the core name makes both extension tiers look absent.
GL_FUNC_TYPEDEF(void, glTextureViewEXT, GLuint texture, GLenum target, GLuint origtexture,
GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer,
GLuint numlayers)
GL_FUNC_TYPEDEF(void, glTextureViewOES, GLuint texture, GLenum target, GLuint origtexture,
GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer,
GLuint numlayers)
GL_FUNC_TYPEDEF(void, glTexBufferEXT, GLenum target, GLenum internalformat, GLuint buffer)
GL_FUNC_TYPEDEF(void, glTexBufferOES, GLenum target, GLenum internalformat, GLuint buffer)
GL_FUNC_TYPEDEF(void, glTexBufferRangeEXT, GLenum target, GLenum internalformat, GLuint buffer,
@@ -1023,6 +1029,8 @@ namespace MobileGL {
GL_FUNC_DECL(glGetSamplerParameterIuiv)
GL_FUNC_DECL(glTexBuffer)
GL_FUNC_DECL(glTexBufferRange)
GL_FUNC_DECL(glTextureViewEXT)
GL_FUNC_DECL(glTextureViewOES)
GL_FUNC_DECL(glTexBufferEXT)
GL_FUNC_DECL(glTexBufferOES)
GL_FUNC_DECL(glTexBufferRangeEXT)
@@ -1086,6 +1094,14 @@ namespace MobileGL {
Bool SupportsTextureBorderClamp = false;
// GL_TEXTURE_CUBE_MAP_ARRAY: ES 3.2 core, or EXT/OES_texture_cube_map_array before it.
Bool SupportsTextureCubeMapArray = false;
// GL_EXT_texture_view / GL_OES_texture_view: two ES texture names sharing one
// storage, i.e. the only way DirectGLES can answer glTextureView at all. ES never
// made this core - not even in 3.2 - so unlike every other capability here there is
// no version that implies it, and a driver without it leaves MobileGL with no honest
// implementation (a copy is not a view: writes through one name must be visible
// through the other). Gate on this, never on the entry points: eglGetProcAddress
// hands back live-looking stubs (see AcquireGLESFunctions).
Bool SupportsTextureView = false;
// Which spelling of buffer-texture support the host driver has. Desktop GL makes buffer
// textures core from 3.1 on, so the frontend advertises them unconditionally and an app
// may call glTexBuffer at any time; ES only gained them in 3.2, and before that only