- dst[didx].f = (float) src[sidx].i;
- break;
- case GLSL_TYPE_BOOL:
- dst[didx].f = src[sidx].i ? 1.0f : 0.0f;
- break;
- case GLSL_TYPE_DOUBLE:
- dst[didx].f = *(double *)&src[sidx].f;
- break;
- default:
- assert(!"Should not get here.");
- break;
- }
- break;
- case GLSL_TYPE_DOUBLE:
- switch (uni->type->base_type) {
- case GLSL_TYPE_UINT:
- *(double *)&dst[didx].f = (double) src[sidx].u;
- break;
- case GLSL_TYPE_INT:
- case GLSL_TYPE_SAMPLER:
- case GLSL_TYPE_IMAGE:
- *(double *)&dst[didx].f = (double) src[sidx].i;
- break;
- case GLSL_TYPE_BOOL:
- *(double *)&dst[didx].f = src[sidx].i ? 1.0f : 0.0f;
- break;
- case GLSL_TYPE_FLOAT:
- *(double *)&dst[didx].f = (double) src[sidx].f;
- break;
- default:
- assert(!"Should not get here.");
- break;
- }
- 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
- * state how conversion of float uniforms to integer
- * values works, in section 6.2 "State Tables" on
- * page 267 it says:
- *
- * "Unless otherwise specified, when floating
- * point state is returned as integer values or
- * integer state is returned as floating-point
- * values it is converted in the fashion
- * described in section 6.1.2"
- *
- * That section, on page 248, says:
- *
- * "If GetIntegerv or GetInteger64v are called,
- * a floating-point value is rounded to the
- * nearest integer..."
- */
- dst[didx].i = IROUND(src[sidx].f);
- break;
- case GLSL_TYPE_BOOL:
- dst[didx].i = src[sidx].i ? 1 : 0;
- break;
- case GLSL_TYPE_DOUBLE:
- dst[didx].i = IROUNDD(*(double *)&src[sidx].f);
- break;
- default:
- assert(!"Should not get here.");
- break;
- }
- break;
-
- default:
- assert(!"Should not get here.");
- break;
- }
- }
+ dst[didx].f = (float) src[sidx].i;
+ break;
+ case GLSL_TYPE_BOOL:
+ dst[didx].f = src[sidx].i ? 1.0f : 0.0f;
+ break;
+ case GLSL_TYPE_DOUBLE: {
+ double tmp;
+ memcpy(&tmp, &src[sidx].f, sizeof(tmp));
+ dst[didx].f = tmp;
+ break;
+ }
+ case GLSL_TYPE_UINT64: {
+ uint64_t tmp;
+ memcpy(&tmp, &src[sidx].u, sizeof(tmp));
+ dst[didx].f = tmp;
+ break;
+ }
+ case GLSL_TYPE_INT64: {
+ uint64_t tmp;
+ memcpy(&tmp, &src[sidx].i, sizeof(tmp));
+ dst[didx].f = tmp;
+ break;
+ }
+ default:
+ assert(!"Should not get here.");
+ break;
+ }
+ break;
+
+ case GLSL_TYPE_DOUBLE:
+ switch (uni->type->base_type) {
+ case GLSL_TYPE_UINT: {
+ double tmp = src[sidx].u;
+ memcpy(&dst[didx].f, &tmp, sizeof(tmp));
+ break;
+ }
+ case GLSL_TYPE_INT:
+ case GLSL_TYPE_SAMPLER:
+ case GLSL_TYPE_IMAGE: {
+ double tmp = src[sidx].i;
+ memcpy(&dst[didx].f, &tmp, sizeof(tmp));
+ break;
+ }
+ case GLSL_TYPE_BOOL: {
+ double tmp = src[sidx].i ? 1.0 : 0.0;
+ memcpy(&dst[didx].f, &tmp, sizeof(tmp));
+ break;
+ }
+ case GLSL_TYPE_FLOAT: {
+ double tmp = src[sidx].f;
+ memcpy(&dst[didx].f, &tmp, sizeof(tmp));
+ break;
+ }
+ case GLSL_TYPE_UINT64: {
+ uint64_t tmpu;
+ double tmp;
+ memcpy(&tmpu, &src[sidx].u, sizeof(tmpu));
+ tmp = tmpu;
+ memcpy(&dst[didx].f, &tmp, sizeof(tmp));
+ break;
+ }
+ case GLSL_TYPE_INT64: {
+ int64_t tmpi;
+ double tmp;
+ memcpy(&tmpi, &src[sidx].i, sizeof(tmpi));
+ tmp = tmpi;
+ memcpy(&dst[didx].f, &tmp, sizeof(tmp));
+ break;
+ }
+ default:
+ assert(!"Should not get here.");
+ break;
+ }
+ break;
+
+ case GLSL_TYPE_INT:
+ switch (uni->type->base_type) {
+ case GLSL_TYPE_FLOAT:
+ /* While the GL 3.2 core spec doesn't explicitly
+ * state how conversion of float uniforms to integer
+ * values works, in section 6.2 "State Tables" on
+ * page 267 it says:
+ *
+ * "Unless otherwise specified, when floating
+ * point state is returned as integer values or
+ * integer state is returned as floating-point
+ * values it is converted in the fashion
+ * described in section 6.1.2"
+ *
+ * That section, on page 248, says:
+ *
+ * "If GetIntegerv or GetInteger64v are called,
+ * a floating-point value is rounded to the
+ * nearest integer..."
+ */
+ dst[didx].i = IROUND(src[sidx].f);
+ break;
+ 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));
+ dst[didx].i = IROUNDD(tmp);
+ break;
+ }
+ case GLSL_TYPE_UINT64: {
+ uint64_t tmp;
+ memcpy(&tmp, &src[sidx].u, sizeof(tmp));
+ dst[didx].i = tmp;
+ break;
+ }
+ case GLSL_TYPE_INT64: {
+ int64_t tmp;
+ memcpy(&tmp, &src[sidx].i, sizeof(tmp));
+ dst[didx].i = tmp;
+ break;
+ }
+ default:
+ assert(!"Should not get here.");
+ 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].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) {
+ case GLSL_TYPE_UINT: {
+ uint64_t tmp = src[sidx].u;
+ memcpy(&dst[didx].u, &tmp, sizeof(tmp));
+ break;
+ }
+ case GLSL_TYPE_INT:
+ case GLSL_TYPE_SAMPLER:
+ case GLSL_TYPE_IMAGE: {
+ int64_t tmp = src[sidx].i;
+ memcpy(&dst[didx].u, &tmp, sizeof(tmp));
+ break;
+ }
+ case GLSL_TYPE_BOOL: {
+ int64_t tmp = src[sidx].i ? 1.0f : 0.0f;
+ memcpy(&dst[didx].u, &tmp, sizeof(tmp));
+ break;
+ }
+ case GLSL_TYPE_FLOAT: {
+ int64_t tmp = src[sidx].f;
+ memcpy(&dst[didx].u, &tmp, sizeof(tmp));
+ break;
+ }
+ default:
+ assert(!"Should not get here.");
+ break;
+ }
+ break;
+
+ default:
+ assert(!"Should not get here.");
+ break;
+ }
+ }