From 60e115dedfa29dd4353b2608b7f226f8f7cfa9bd Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Wed, 26 Nov 2025 10:00:06 +0100 Subject: [PATCH] mesa/st: do not drop binding prematurely MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While it's true that we currently need to eventually fall back to checking without the render-target binding, this should really be the last resort. Because otherwise we might end up picking a format that isn't possible to render to for a color-renderable internalformat. In the long run, this code should be rewritten to check *properly* if the internalformat is color-renderable or not *up front*, and not even try to fall back. But we're currently missing proper helpers for this, and reworking what we have is a fair bit of work. So for now, let's just do what we currently do, but shuffle around the order of testing things so we don't end up dropping unless we absolutely have to. Tested-by: Christian Gmeiner Reviewed-by: Marek Olšák Part-of: --- src/mesa/state_tracker/st_format.c | 83 ++++++++++++++---------------- 1 file changed, 40 insertions(+), 43 deletions(-) diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c index 1b2e3fee0ad..145c3dc8c29 100644 --- a/src/mesa/state_tracker/st_format.c +++ b/src/mesa/state_tracker/st_format.c @@ -1321,6 +1321,42 @@ st_choose_matching_format(struct st_context *st, unsigned bind, return PIPE_FORMAT_NONE; } +static mesa_format +choose_format_with_bindings(struct gl_context *ctx, GLint internalFormat, + GLenum format, GLenum type, + enum pipe_texture_target target, unsigned bindings) +{ + struct st_context *st = st_context(ctx); + + /* GLES allows the driver to choose any format which matches + * the format+type combo, because GLES only supports unsized internal + * formats and expects the driver to choose whatever suits it. + */ + if (_mesa_is_gles(ctx)) { + GLenum baseFormat = _mesa_base_tex_format(ctx, internalFormat); + GLenum basePackFormat = _mesa_base_pack_format(format); + GLenum iformat = internalFormat; + + /* Treat GL_BGRA as GL_RGBA. */ + if (iformat == GL_BGRA) + iformat = GL_RGBA; + + /* Check if the internalformat is unsized and compatible + * with the "format". + */ + if (iformat == baseFormat && iformat == basePackFormat) { + enum pipe_format pFormat = + st_choose_matching_format(st, bindings, format, type, + ctx->Unpack.SwapBytes); + + if (pFormat != PIPE_FORMAT_NONE) + return st_pipe_format_to_mesa_format(pFormat); + } + } + + return st_choose_format(st, internalFormat, format, type, target, 0, 0, + bindings, ctx->Unpack.SwapBytes, true); +} /** * Called via ctx->Driver.ChooseTextureFormat(). @@ -1414,51 +1450,12 @@ st_ChooseTextureFormat(struct gl_context *ctx, GLenum target, internalFormat == GL_LUMINANCE_ALPHA16F_ARB)) bindings |= PIPE_BIND_RENDER_TARGET; - /* GLES allows the driver to choose any format which matches - * the format+type combo, because GLES only supports unsized internal - * formats and expects the driver to choose whatever suits it. - */ - if (_mesa_is_gles(ctx)) { - GLenum baseFormat = _mesa_base_tex_format(ctx, internalFormat); - GLenum basePackFormat = _mesa_base_pack_format(format); - GLenum iformat = internalFormat; - - /* Treat GL_BGRA as GL_RGBA. */ - if (iformat == GL_BGRA) - iformat = GL_RGBA; - - /* Check if the internalformat is unsized and compatible - * with the "format". - */ - if (iformat == baseFormat && iformat == basePackFormat) { - pFormat = st_choose_matching_format(st, bindings, format, type, - ctx->Unpack.SwapBytes); - - if (pFormat != PIPE_FORMAT_NONE) - return st_pipe_format_to_mesa_format(pFormat); - - if (!is_renderbuffer) { - /* try choosing format again, this time without render - * target bindings. - */ - pFormat = st_choose_matching_format(st, PIPE_BIND_SAMPLER_VIEW, - format, type, - ctx->Unpack.SwapBytes); - if (pFormat != PIPE_FORMAT_NONE) - return st_pipe_format_to_mesa_format(pFormat); - } - } - } - - pFormat = st_choose_format(st, internalFormat, format, type, - pTarget, 0, 0, bindings, - ctx->Unpack.SwapBytes, true); + pFormat = choose_format_with_bindings(ctx, internalFormat, format, type, + pTarget, bindings); if (pFormat == PIPE_FORMAT_NONE && !is_renderbuffer) { - /* try choosing format again, this time without render target bindings */ - pFormat = st_choose_format(st, internalFormat, format, type, - pTarget, 0, 0, PIPE_BIND_SAMPLER_VIEW, - ctx->Unpack.SwapBytes, true); + pFormat = choose_format_with_bindings(ctx, internalFormat, format, type, + pTarget, PIPE_BIND_SAMPLER_VIEW); } if (pFormat == PIPE_FORMAT_NONE) {