summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>2024-02-14 13:35:38 -0500
committerMarge Bot <emma+marge@anholt.net>2024-02-17 16:27:20 +0000
commit893780b36251616e967f12354fab5fc0d05d79d7 (patch)
tree3b6fb76cce7b9d959c5ab583ee3ace1816f2ac15
parentc7b2ac3377ae56df5e1990c2ed03360dac9519f6 (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.c26
-rw-r--r--src/mesa/state_tracker/st_format.c43
-rw-r--r--src/mesa/state_tracker/st_format.h3
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);