gl-renderer: Add OES_required_internalformat support to utilities

Before the creation of the EXT_texture_storage extension,
OES_required_internalformat used to guarantee minimal FBO and texture
precisions to OpenGL ES 1 and 2 implementations using sized internal
formats.

Note that new external format and type combinations (like for instance
GL_RGB and GL_UNSIGNED_BYTE for the GL_RGB565 sized internal format)
should be available when OES_required_internalformat is supported.
This isn't supported by this wrapper for now because of the implicit
conversion in gl_texture_2d_init() that forces a specific type when
EXT_texture_storage isn't available.

Signed-off-by: Loïc Molinari <loic.molinari@collabora.com>
This commit is contained in:
Loïc Molinari 2024-09-20 15:31:20 +02:00 committed by Daniel Stone
parent 43bbd15437
commit dcee21f02f
3 changed files with 56 additions and 23 deletions

View file

@ -140,6 +140,7 @@ enum gl_extension_flag {
EXTENSION_OES_EGL_IMAGE = 1ull << 22,
EXTENSION_OES_EGL_IMAGE_EXTERNAL = 1ull << 23,
EXTENSION_OES_MAPBUFFER = 1ull << 24,
EXTENSION_OES_REQUIRED_INTERNALFORMAT = 1ull << 25,
EXTENSION_OES_RGB8_RGBA8 = 1ull << 26,
EXTENSION_OES_TEXTURE_FLOAT = 1ull << 28,
EXTENSION_OES_TEXTURE_FLOAT_LINEAR = 1ull << 29,

View file

@ -298,6 +298,7 @@ static const struct gl_extension_table extension_table[] = {
EXT("GL_OES_EGL_image", EXTENSION_OES_EGL_IMAGE),
EXT("GL_OES_EGL_image_external", EXTENSION_OES_EGL_IMAGE_EXTERNAL),
EXT("GL_OES_mapbuffer", EXTENSION_OES_MAPBUFFER),
EXT("GL_OES_required_internalformat", EXTENSION_OES_REQUIRED_INTERNALFORMAT),
EXT("GL_OES_rgb8_rgba8", EXTENSION_OES_RGB8_RGBA8),
EXT("GL_OES_texture_float", EXTENSION_OES_TEXTURE_FLOAT),
EXT("GL_OES_texture_float_linear", EXTENSION_OES_TEXTURE_FLOAT_LINEAR),
@ -4882,6 +4883,9 @@ gl_renderer_setup(struct weston_compositor *ec)
yesno(gl_features_has(gr, FEATURE_GPU_TIMELINE)));
weston_log_continue(STAMP_SPACE "Texture immutability: %s\n",
yesno(gl_features_has(gr, FEATURE_TEXTURE_IMMUTABILITY)));
weston_log_continue(STAMP_SPACE "Required precision: %s\n",
yesno(gr->gl_version >= gl_version(3, 0) ||
gl_extensions_has(gr, EXTENSION_OES_REQUIRED_INTERNALFORMAT)));
return 0;
}

View file

@ -729,105 +729,129 @@ gl_texture_2d_init(struct gl_renderer *gr,
gr->tex_storage_2d(GL_TEXTURE_2D, levels, format, width,
height);
} else {
GLenum type;
GLenum external_format, type;
int i;
/* Implicit conversion to external format for supported
* subset. */
switch (format) {
case GL_R8:
format = gl_features_has(gr, FEATURE_TEXTURE_RG) ?
GL_RED : GL_LUMINANCE;
if (gl_features_has(gr, FEATURE_TEXTURE_RG)) {
format = external_format = GL_RED;
} else if (!gl_extensions_has(gr, EXTENSION_OES_REQUIRED_INTERNALFORMAT)) {
format = external_format = GL_LUMINANCE;
} else {
format = GL_LUMINANCE8_OES;
external_format = GL_LUMINANCE;
}
type = GL_UNSIGNED_BYTE;
break;
case GL_R16F:
format = gl_features_has(gr, FEATURE_TEXTURE_RG) ?
format = external_format = gl_features_has(gr, FEATURE_TEXTURE_RG) ?
GL_RED : GL_LUMINANCE;
type = GL_HALF_FLOAT_OES;
break;
case GL_R32F:
format = gl_features_has(gr, FEATURE_TEXTURE_RG) ?
format = external_format = gl_features_has(gr, FEATURE_TEXTURE_RG) ?
GL_RED : GL_LUMINANCE;
type = GL_FLOAT;
break;
case GL_RG8:
format = gl_features_has(gr, FEATURE_TEXTURE_RG) ?
GL_RG : GL_LUMINANCE_ALPHA;
if (gl_features_has(gr, FEATURE_TEXTURE_RG)) {
format = external_format = GL_RG;
} else if (!gl_extensions_has(gr, EXTENSION_OES_REQUIRED_INTERNALFORMAT)) {
format = external_format = GL_LUMINANCE_ALPHA;
} else {
format = GL_LUMINANCE8_ALPHA8_OES;
external_format = GL_LUMINANCE_ALPHA;
}
type = GL_UNSIGNED_BYTE;
break;
case GL_RG16F:
format = gl_features_has(gr, FEATURE_TEXTURE_RG) ?
format = external_format = gl_features_has(gr, FEATURE_TEXTURE_RG) ?
GL_RG : GL_LUMINANCE_ALPHA;
type = GL_HALF_FLOAT_OES;
break;
case GL_RG32F:
format = gl_features_has(gr, FEATURE_TEXTURE_RG) ?
format = external_format = gl_features_has(gr, FEATURE_TEXTURE_RG) ?
GL_RG : GL_LUMINANCE_ALPHA;
type = GL_FLOAT;
break;
case GL_RGB8:
format = GL_RGB;
if (!gl_extensions_has(gr, EXTENSION_OES_REQUIRED_INTERNALFORMAT))
format = GL_RGB;
external_format = GL_RGB;
type = GL_UNSIGNED_BYTE;
break;
case GL_RGB565:
format = GL_RGB;
if (!gl_extensions_has(gr, EXTENSION_OES_REQUIRED_INTERNALFORMAT))
format = GL_RGB;
external_format = GL_RGB;
type = GL_UNSIGNED_SHORT_5_6_5;
break;
case GL_RGB16F:
format = GL_RGB;
format = external_format = GL_RGB;
type = GL_HALF_FLOAT_OES;
break;
case GL_RGB32F:
format = GL_RGB;
format = external_format = GL_RGB;
type = GL_FLOAT;
break;
case GL_R11F_G11F_B10F:
format = GL_RGB;
format = external_format = GL_RGB;
type = GL_UNSIGNED_INT_10F_11F_11F_REV;
break;
case GL_RGB9_E5:
format = GL_RGB;
format = external_format = GL_RGB;
type = GL_UNSIGNED_INT_5_9_9_9_REV;
break;
case GL_RGBA8:
format = GL_RGBA;
if (!gl_extensions_has(gr, EXTENSION_OES_REQUIRED_INTERNALFORMAT))
format = GL_RGBA;
external_format = GL_RGBA;
type = GL_UNSIGNED_BYTE;
break;
case GL_RGBA4:
format = GL_RGBA;
if (!gl_extensions_has(gr, EXTENSION_OES_REQUIRED_INTERNALFORMAT))
format = GL_RGBA;
external_format = GL_RGBA;
type = GL_UNSIGNED_SHORT_4_4_4_4;
break;
case GL_RGB5_A1:
format = GL_RGBA;
if (!gl_extensions_has(gr, EXTENSION_OES_REQUIRED_INTERNALFORMAT))
format = GL_RGBA;
external_format = GL_RGBA;
type = GL_UNSIGNED_SHORT_5_5_5_1;
break;
case GL_RGB10_A2:
format = GL_RGBA;
if (!gl_extensions_has(gr, EXTENSION_OES_REQUIRED_INTERNALFORMAT))
format = GL_RGBA;
external_format = GL_RGBA;
type = GL_UNSIGNED_INT_2_10_10_10_REV;
break;
case GL_RGBA16F:
format = GL_RGBA;
format = external_format = GL_RGBA;
type = GL_HALF_FLOAT_OES;
break;
case GL_RGBA32F:
format = GL_RGBA;
format = external_format = GL_RGBA;
type = GL_FLOAT;
break;
@ -839,7 +863,7 @@ gl_texture_2d_init(struct gl_renderer *gr,
/* Allocate storage. */
for (i = 0; i < levels; i++) {
glTexImage2D(GL_TEXTURE_2D, i, format, width, height, 0,
format, type, NULL);
external_format, type, NULL);
width = MAX(width / 2, 1);
height = MAX(height / 2, 1);
}
@ -962,10 +986,14 @@ gl_fbo_is_format_supported(struct gl_renderer *gr,
return gl_extensions_has(gr, EXTENSION_QCOM_RENDER_SRGB_R8_RG8);
case GL_RGB8:
case GL_RGBA8:
return gr->gl_version >= gl_version(3, 0) ||
gl_extensions_has(gr, EXTENSION_OES_RGB8_RGBA8);
case GL_RGBA8:
return gr->gl_version >= gl_version(3, 0) ||
gl_extensions_has(gr, EXTENSION_OES_RGB8_RGBA8) ||
gl_extensions_has(gr, EXTENSION_OES_REQUIRED_INTERNALFORMAT);
case GL_SRGB8_ALPHA8:
case GL_R8I:
case GL_R8UI: