diff options
author | Kenneth Graunke <[email protected]> | 2017-05-18 11:43:53 +0200 |
---|---|---|
committer | Iago Toral Quiroga <[email protected]> | 2017-06-01 08:44:34 +0200 |
commit | 83e74d7dc14ee0f31652cd2a6c0bb66380458f2b (patch) | |
tree | 10f9620da2f75899080e87f30021b0f202c14d5f /src/mesa/main | |
parent | 102044870042d0e5e51ef0b88e91a9d59a8fda5b (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.cpp | 62 |
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) { |