diff options
author | Mike Blumenkrantz <michael.blumenkrantz@gmail.com> | 2024-02-14 13:35:38 -0500 |
---|---|---|
committer | Marge Bot <emma+marge@anholt.net> | 2024-02-17 16:27:20 +0000 |
commit | 893780b36251616e967f12354fab5fc0d05d79d7 (patch) | |
tree | 3b6fb76cce7b9d959c5ab583ee3ace1816f2ac15 | |
parent | c7b2ac3377ae56df5e1990c2ed03360dac9519f6 (diff) |
mesa: check driver format support for certain GetInternalformativ queries
according to spec, these should return NONE if the format is
not supported for a given texture target, but mesa was incorrectly
returning a hardcoded value for all cases without checking the driver
instead, check whether the driver can create a texture for a given
format to correctly handle this non-support case
cc: mesa-stable
Reviewed-by: Jesse Natalie <jenatali@microsoft.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27621>
-rw-r--r-- | src/mesa/main/formatquery.c | 26 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_format.c | 43 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_format.h | 3 |
3 files changed, 71 insertions, 1 deletions
diff --git a/src/mesa/main/formatquery.c b/src/mesa/main/formatquery.c index ae59413d345..396fa0a4014 100644 --- a/src/mesa/main/formatquery.c +++ b/src/mesa/main/formatquery.c @@ -1112,6 +1112,12 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, if (get_pname == 0) goto end; + /* if the resource is unsupported, zero is returned */ + if (!st_QueryTextureFormatSupport(ctx, target, internalformat)) { + buffer[0] = 0; + break; + } + _mesa_GetIntegerv(get_pname, buffer); break; } @@ -1123,6 +1129,12 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, if (!_mesa_is_array_texture(target)) goto end; + /* if the resource is unsupported, zero is returned */ + if (!st_QueryTextureFormatSupport(ctx, target, internalformat)) { + buffer[0] = 0; + break; + } + _mesa_GetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, buffer); break; @@ -1137,6 +1149,12 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, unsigned i; GLint current_value; + /* if the resource is unsupported, zero is returned */ + if (!st_QueryTextureFormatSupport(ctx, target, internalformat)) { + buffer[0] = 0; + break; + } + /* Combining the dimensions. Note that for array targets, this would * automatically include the value of MAX_LAYERS, as that value is * returned as MAX_HEIGHT or MAX_DEPTH */ @@ -1515,6 +1533,14 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, if (targetIndex < 0 || targetIndex == TEXTURE_BUFFER_INDEX) goto end; + /* If the resource is not supported for image textures, + * or if image textures are not supported, NONE is returned. + */ + if (!st_QueryTextureFormatSupport(ctx, target, internalformat)) { + buffer[0] = GL_NONE; + break; + } + /* From spec: "Equivalent to calling GetTexParameter with <value> set * to IMAGE_FORMAT_COMPATIBILITY_TYPE." * diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c index b112d74fcf0..7a6f68db2c6 100644 --- a/src/mesa/state_tracker/st_format.c +++ b/src/mesa/state_tracker/st_format.c @@ -1507,6 +1507,49 @@ st_QuerySamplesForFormat(struct gl_context *ctx, GLenum target, return num_sample_counts; } +/* check whether any texture can be allocated for a given format */ +bool +st_QueryTextureFormatSupport(struct gl_context *ctx, GLenum target, GLenum internalFormat) +{ + struct st_context *st = st_context(ctx); + + /* If an sRGB framebuffer is unsupported, sRGB formats behave like linear + * formats. + */ + if (!ctx->Extensions.EXT_sRGB) { + internalFormat = _mesa_get_linear_internalformat(internalFormat); + } + + /* multisample textures need >= 2 samples */ + unsigned min_samples = target == GL_TEXTURE_2D_MULTISAMPLE || + target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY ? 1 : 0; + unsigned max_samples = min_samples ? 16 : 1; + + /* compressed textures will be allocated as e.g., RGBA8, so check that instead */ + enum pipe_format pf = st_choose_format(st, internalFormat, GL_NONE, GL_NONE, + PIPE_TEXTURE_2D, 0, 0, 0, + false, false); + if (util_format_is_compressed(pf)) { + enum pipe_format fmts[2] = {0}; + pf = st_mesa_format_to_pipe_format(st, st_pipe_format_to_mesa_format(pf)); + fmts[0] = pf; + for (unsigned i = max_samples; i > min_samples; i >>= 1) { + if (find_supported_format(st->screen, fmts, PIPE_TEXTURE_2D, + i, i, PIPE_BIND_SAMPLER_VIEW, false)) + return true; + } + return false; + } + for (unsigned i = max_samples; i > min_samples; i >>= 1) { + if (st_choose_format(st, internalFormat, GL_NONE, GL_NONE, + PIPE_TEXTURE_2D, i, i, PIPE_BIND_SAMPLER_VIEW, + false, false)) + return true; + } + + return false; +} + /** * ARB_internalformat_query2 driver hook. diff --git a/src/mesa/state_tracker/st_format.h b/src/mesa/state_tracker/st_format.h index 9692a0bc583..21b1a7bb4bf 100644 --- a/src/mesa/state_tracker/st_format.h +++ b/src/mesa/state_tracker/st_format.h @@ -70,7 +70,8 @@ extern mesa_format st_ChooseTextureFormat(struct gl_context * ctx, GLenum target, GLint internalFormat, GLenum format, GLenum type); - +bool +st_QueryTextureFormatSupport(struct gl_context *ctx, GLenum target, GLenum internalFormat); void st_QueryInternalFormat(struct gl_context *ctx, GLenum target, GLenum internalFormat, GLenum pname, GLint *params); |