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>
(cherry picked from commit 893780b362)
This commit is contained in:
Mike Blumenkrantz 2024-02-14 13:35:38 -05:00 committed by Eric Engestrom
parent c126631fe7
commit e814fc81b0
4 changed files with 72 additions and 2 deletions

View file

@ -2754,7 +2754,7 @@
"description": "mesa: check driver format support for certain GetInternalformativ queries",
"nominated": true,
"nomination_type": 0,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": null,
"notes": null

View file

@ -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."
*

View file

@ -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.

View file

@ -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);