aboutsummaryrefslogtreecommitdiffstats
path: root/src/mesa/main
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2017-05-18 11:43:53 +0200
committerIago Toral Quiroga <[email protected]>2017-06-01 08:44:34 +0200
commit83e74d7dc14ee0f31652cd2a6c0bb66380458f2b (patch)
tree10f9620da2f75899080e87f30021b0f202c14d5f /src/mesa/main
parent102044870042d0e5e51ef0b88e91a9d59a8fda5b (diff)
mesa/main: Clamp GetUniformuiv values to be >= 0
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." v2: uint to int conversion should clamp to INT_MAX (Nicolai) v3 (Iago) - Add conversions conversions from 64-bit integer paths - Rebase on master v4: - need unsigned rounding for float/double->uint conversions (Nicolai) - use round{f}() instead of IROUND() macros (Iago) Fixes: KHR-GL45.gpu_shader_fp64.state_query Reviewed-by: Nicolai Hähnle <[email protected]> (v2) Reviewed-by: Matt Turner <[email protected]>
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/uniform_query.cpp62
1 files changed, 51 insertions, 11 deletions
diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp
index e7010adeca0..314f7d8a1b0 100644
--- a/src/mesa/main/uniform_query.cpp
+++ b/src/mesa/main/uniform_query.cpp
@@ -353,16 +353,8 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location,
* 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->is_sampler() ||
- uni->type->is_image())) ||
- ((returnType == GLSL_TYPE_UINT64 ||
- returnType == GLSL_TYPE_INT64) &&
- (uni->type->base_type == GLSL_TYPE_UINT64 ||
- uni->type->base_type == GLSL_TYPE_INT64))) {
+ ((returnType == GLSL_TYPE_INT || returnType == GLSL_TYPE_UINT) &&
+ (uni->type->is_sampler() || uni->type->is_image()))) {
memcpy(paramsOut, src, bytes);
} else {
union gl_constant_value *const dst =
@@ -460,7 +452,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
@@ -485,6 +476,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 = MIN2(src[sidx].i, INT_MAX);
+ break;
case GLSL_TYPE_DOUBLE: {
double tmp;
memcpy(&tmp, &src[sidx].f, sizeof(tmp));
@@ -509,6 +503,52 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location,
}
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].u = src[sidx].f < 0.0f ?
+ 0u : (uint32_t) roundf(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].u = tmp < 0.0 ? 0u : (uint32_t) round(tmp);
+ break;
+ }
+ case GLSL_TYPE_UINT64: {
+ uint64_t tmp;
+ memcpy(&tmp, &src[sidx].u, sizeof(tmp));
+ dst[didx].i = MIN2(tmp, INT_MAX);
+ break;
+ }
+ case GLSL_TYPE_INT64: {
+ int64_t tmp;
+ memcpy(&tmp, &src[sidx].i, sizeof(tmp));
+ dst[didx].i = MAX2(tmp, 0);
+ break;
+ }
+ default:
+ unreachable("invalid uniform type");
+ }
+ break;
+
case GLSL_TYPE_INT64:
case GLSL_TYPE_UINT64:
switch (uni->type->base_type) {