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 <nicolai.haehnle@amd.com> (v2) Reviewed-by: Matt Turner <mattst88@gmail.com>
This commit is contained in:
parent
1020448700
commit
83e74d7dc1
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue