diff --git a/libweston/renderer-gl/gl-renderer-internal.h b/libweston/renderer-gl/gl-renderer-internal.h index bb651d4a7..4a1905e39 100644 --- a/libweston/renderer-gl/gl-renderer-internal.h +++ b/libweston/renderer-gl/gl-renderer-internal.h @@ -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, diff --git a/libweston/renderer-gl/gl-renderer.c b/libweston/renderer-gl/gl-renderer.c index 772f01441..72f9b8227 100644 --- a/libweston/renderer-gl/gl-renderer.c +++ b/libweston/renderer-gl/gl-renderer.c @@ -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; } diff --git a/libweston/renderer-gl/gl-utils.c b/libweston/renderer-gl/gl-utils.c index 16625acb7..d29d310a9 100644 --- a/libweston/renderer-gl/gl-utils.c +++ b/libweston/renderer-gl/gl-utils.c @@ -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: