[Mesa-dev] [PATCH] mesa: Clamp GetUniformuiv values to be >= 0.
Nicolai Hähnle
nhaehnle at gmail.com
Mon Dec 12 09:43:51 UTC 2016
On 12.12.2016 00:25, Kenneth Graunke wrote:
> Section 2.2.2 (Data Conversions For State Query Commands) of the
> OpenGL 4.5 October 24th 2016 specification says:
>
> "If a command returning unsigned integer data is called, such as
> GetSamplerParameterIuiv, negative values are clamped to zero."
>
> Fixes GL44-CTS.gpu_shader_fp64.state_query.
>
> Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
> ---
> src/mesa/main/uniform_query.cpp | 48 +++++++++++++++++++++++++++++++++--------
> 1 file changed, 39 insertions(+), 9 deletions(-)
>
> Hey Nicolai,
>
> I wrote a similar patch a while back, but never got around to sending it,
> since I realized that the gl45release branch expects our current behavior,
> and the change to make the CTS expect clamping is only on the master branch.
>
> Apparently I made some additional changes, compared to yours. I figured
> I'd send this along and let you see if you think any of my extra changes
> are still necessary. If so, feel free to fold them into your patch.
>
> I also think we need to fix several other glGet* commands...it's just that
> this is the only one currently tested. A bunch work because the values
> returned can't be negative.
I think your patch is a strict superset of what mine does and should be
used instead. I do have one comment below, with that fixed it has my R-b.
There is the more general question of how to cope with those cases where
the CTS requires non-standard behavior. I think we should insist on
doing the right thing in Mesa, and push for changes to the CTS.
Until quite recently, I've been occupied by radeonsi- and
Gallium-specific bugs, but that's changing and I'm looking into using
CTS master rather than back-porting fixes to the dead gl45release branch
(hence this patch).
>
> --Ken
>
> diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp
> index db700df..f05a29f 100644
> --- a/src/mesa/main/uniform_query.cpp
> +++ b/src/mesa/main/uniform_query.cpp
> @@ -347,14 +347,10 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location,
> * just memcpy the data. If the types are not compatible, perform a
> * slower convert-and-copy process.
> */
> - if (returnType == uni->type->base_type
> - || ((returnType == GLSL_TYPE_INT
> - || returnType == GLSL_TYPE_UINT)
> - &&
> - (uni->type->base_type == GLSL_TYPE_INT
> - || uni->type->base_type == GLSL_TYPE_UINT
> - || uni->type->base_type == GLSL_TYPE_SAMPLER
> - || uni->type->base_type == GLSL_TYPE_IMAGE))) {
> + if (returnType == uni->type->base_type ||
> + ((returnType == GLSL_TYPE_INT || returnType == GLSL_TYPE_UINT) &&
> + (uni->type->base_type == GLSL_TYPE_SAMPLER ||
> + uni->type->base_type == GLSL_TYPE_IMAGE))) {
> memcpy(paramsOut, src, bytes);
> } else {
> union gl_constant_value *const dst =
> @@ -422,7 +418,6 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location,
> }
> break;
> case GLSL_TYPE_INT:
> - case GLSL_TYPE_UINT:
> switch (uni->type->base_type) {
> case GLSL_TYPE_FLOAT:
> /* While the GL 3.2 core spec doesn't explicitly
> @@ -447,6 +442,9 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location,
> case GLSL_TYPE_BOOL:
> dst[didx].i = src[sidx].i ? 1 : 0;
> break;
> + case GLSL_TYPE_UINT:
> + dst[didx].i = src[sidx].i;
I think this should be
dst[didx].i = MIN2(src[sidx].u, INT_MAX);
Cheers,
Nicolai
> + break;
> case GLSL_TYPE_DOUBLE: {
> double tmp;
> memcpy(&tmp, &src[sidx].f, sizeof(tmp));
> @@ -458,6 +456,38 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location,
> break;
> }
> break;
> + case GLSL_TYPE_UINT:
> + switch (uni->type->base_type) {
> + case GLSL_TYPE_FLOAT:
> + /* The spec isn't terribly clear how to handle negative
> + * values with an unsigned return type.
> + *
> + * GL 4.5 section 2.2.2 ("Data Conversions for State
> + * Query Commands") says:
> + *
> + * "If a value is so large in magnitude that it cannot be
> + * represented by the returned data type, then the nearest
> + * value representable using the requested type is
> + * returned."
> + */
> + dst[didx].i = src[sidx].f < 0.0f ? 0 : IROUND(src[sidx].f);
> + break;
> + case GLSL_TYPE_BOOL:
> + dst[didx].i = src[sidx].i ? 1 : 0;
> + break;
> + case GLSL_TYPE_INT:
> + dst[didx].i = MAX2(src[sidx].i, 0);
> + break;
> + case GLSL_TYPE_DOUBLE: {
> + double tmp;
> + memcpy(&tmp, &src[sidx].f, sizeof(tmp));
> + dst[didx].i = tmp < 0.0 ? 0 : IROUNDD(tmp);
> + break;
> + }
> + default:
> + unreachable("invalid uniform type");
> + }
> + break;
>
> default:
> assert(!"Should not get here.");
>
More information about the mesa-dev
mailing list