[Mesa-dev] [PATCH] mesa: Clamp GetUniformuiv values to be >= 0.

Kenneth Graunke kenneth at whitecape.org
Sun Dec 11 23:25:19 UTC 2016


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.

 --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;
+                  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.");
-- 
2.10.2



More information about the mesa-dev mailing list