mesa: implement glGetUniform for FP16 uniforms

Reviewed-by: Eric Anholt <eric@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9050>
This commit is contained in:
Marek Olšák 2021-02-14 07:02:13 -05:00 committed by Marge Bot
parent 6bf18fe036
commit d6f3ca95b3

View file

@ -345,6 +345,8 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location,
{
unsigned elements = uni->type->components();
unsigned components = uni->type->vector_elements;
const int rmul = glsl_base_type_is_64bit(returnType) ? 2 : 1;
int dmul = (uni->type->is_64bit()) ? 2 : 1;
@ -362,8 +364,16 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location,
const union gl_constant_value *src;
if (ctx->Const.PackedDriverUniformStorage &&
(uni->is_bindless || !uni->type->contains_opaque())) {
unsigned dword_elements = elements;
/* 16-bit uniforms are packed. */
if (glsl_base_type_is_16bit(uni->type->base_type)) {
dword_elements = DIV_ROUND_UP(components, 2) *
uni->type->matrix_columns;
}
src = (gl_constant_value *) uni->driver_storage[0].data +
(offset * elements * dmul);
(offset * dword_elements * dmul);
} else {
src = &uni->storage[offset * elements * dmul];
}
@ -401,9 +411,18 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location,
int sidx = i * dmul;
int didx = i * rmul;
if (glsl_base_type_is_16bit(uni->type->base_type)) {
unsigned column = i / components;
unsigned row = i % components;
sidx = column * align(components, 2) + row;
}
switch (returnType) {
case GLSL_TYPE_FLOAT:
switch (uni->type->base_type) {
case GLSL_TYPE_FLOAT16:
dst[didx].f = _mesa_half_to_float(((uint16_t*)src)[sidx]);
break;
case GLSL_TYPE_UINT:
dst[didx].f = (float) src[sidx].u;
break;
@ -441,6 +460,11 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location,
case GLSL_TYPE_DOUBLE:
switch (uni->type->base_type) {
case GLSL_TYPE_FLOAT16: {
double f = _mesa_half_to_float(((uint16_t*)src)[sidx]);
memcpy(&dst[didx].f, &f, sizeof(f));
break;
}
case GLSL_TYPE_UINT: {
double tmp = src[sidx].u;
memcpy(&dst[didx].f, &tmp, sizeof(tmp));
@ -507,6 +531,10 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location,
*/
dst[didx].i = (int64_t) roundf(src[sidx].f);
break;
case GLSL_TYPE_FLOAT16:
dst[didx].i =
(int64_t)roundf(_mesa_half_to_float(((uint16_t*)src)[sidx]));
break;
case GLSL_TYPE_BOOL:
dst[didx].i = src[sidx].i ? 1 : 0;
break;
@ -554,6 +582,11 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location,
dst[didx].u = src[sidx].f < 0.0f ?
0u : (uint32_t) roundf(src[sidx].f);
break;
case GLSL_TYPE_FLOAT16: {
float f = _mesa_half_to_float(((uint16_t*)src)[sidx]);
dst[didx].u = f < 0.0f ? 0u : (uint32_t)roundf(f);
break;
}
case GLSL_TYPE_BOOL:
dst[didx].i = src[sidx].i ? 1 : 0;
break;
@ -614,6 +647,12 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location,
memcpy(&dst[didx].u, &tmp, sizeof(tmp));
break;
}
case GLSL_TYPE_FLOAT16: {
float f = _mesa_half_to_float(((uint16_t*)src)[sidx]);
int64_t tmp = (int64_t) roundf(f);
memcpy(&dst[didx].u, &tmp, sizeof(tmp));
break;
}
case GLSL_TYPE_DOUBLE: {
double d;
memcpy(&d, &src[sidx].f, sizeof(d));
@ -659,6 +698,12 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location,
memcpy(&dst[didx].u, &tmp, sizeof(tmp));
break;
}
case GLSL_TYPE_FLOAT16: {
float f = _mesa_half_to_float(((uint16_t*)src)[sidx]);
uint64_t tmp = f < 0.0f ? 0ull : (uint64_t) roundf(f);
memcpy(&dst[didx].u, &tmp, sizeof(tmp));
break;
}
case GLSL_TYPE_DOUBLE: {
double d;
memcpy(&d, &src[sidx].f, sizeof(d));