X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fmain%2Funiform_query.cpp;h=c0e3ca45e5616104909efdc880b4d52737762039;hb=326a82a255c1a72376ce2b7f3d878bfff5cb9621;hp=aca54163bff643582a1ead743d6b8d5cc560c181;hpb=cc972c2845e7c8554918e3aaaab95c1581ff5599;p=mesa.git diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp index aca54163bff..c0e3ca45e56 100644 --- a/src/mesa/main/uniform_query.cpp +++ b/src/mesa/main/uniform_query.cpp @@ -471,7 +471,7 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location, * a floating-point value is rounded to the * nearest integer..." */ - dst[didx].i = IROUND(src[sidx].f); + dst[didx].i = (int64_t) roundf(src[sidx].f); break; case GLSL_TYPE_BOOL: dst[didx].i = src[sidx].i ? 1 : 0; @@ -482,7 +482,7 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location, case GLSL_TYPE_DOUBLE: { double tmp; memcpy(&tmp, &src[sidx].f, sizeof(tmp)); - dst[didx].i = IROUNDD(tmp); + dst[didx].i = (int64_t) round(tmp); break; } case GLSL_TYPE_UINT64: { @@ -576,7 +576,14 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location, break; } case GLSL_TYPE_FLOAT: { - int64_t tmp = src[sidx].f; + int64_t tmp = (int64_t) roundf(src[sidx].f); + memcpy(&dst[didx].u, &tmp, sizeof(tmp)); + break; + } + case GLSL_TYPE_DOUBLE: { + double d; + memcpy(&d, &src[sidx].f, sizeof(d)); + int64_t tmp = (int64_t) round(d); memcpy(&dst[didx].u, &tmp, sizeof(tmp)); break; } @@ -618,6 +625,13 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location, memcpy(&dst[didx].u, &tmp, sizeof(tmp)); break; } + case GLSL_TYPE_DOUBLE: { + double d; + memcpy(&d, &src[sidx].f, sizeof(d)); + uint64_t tmp = (d < 0.0) ? 0ull : (uint64_t) round(d); + memcpy(&dst[didx].u, &tmp, sizeof(tmp)); + break; + } default: assert(!"Should not get here."); break; @@ -1260,6 +1274,70 @@ _mesa_uniform_matrix(GLint location, GLsizei count, _mesa_propagate_uniforms_to_driver_storage(uni, offset, count); } +/** + * Called via glUniformHandleui64*ARB() functions. + */ +extern "C" void +_mesa_uniform_handle(GLint location, GLsizei count, const GLvoid *values, + struct gl_context *ctx, struct gl_shader_program *shProg) +{ + unsigned offset; + struct gl_uniform_storage *const uni = + validate_uniform_parameters(location, count, &offset, + ctx, shProg, "glUniformHandleui64*ARB"); + if (uni == NULL) + return; + + if (!uni->is_bindless) { + /* From section "Errors" of the ARB_bindless_texture spec: + * + * "The error INVALID_OPERATION is generated by + * UniformHandleui64{v}ARB if the sampler or image uniform being + * updated has the "bound_sampler" or "bound_image" layout qualifier." + * + * From section 4.4.6 of the ARB_bindless_texture spec: + * + * "In the absence of these qualifiers, sampler and image uniforms are + * considered "bound". Additionally, if GL_ARB_bindless_texture is not + * enabled, these uniforms are considered "bound"." + */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glUniformHandleui64*ARB(non-bindless sampler/image uniform)"); + return; + } + + const unsigned components = uni->type->vector_elements; + const int size_mul = 2; + + if (unlikely(ctx->_Shader->Flags & GLSL_UNIFORMS)) { + log_uniform(values, GLSL_TYPE_UINT64, components, 1, count, + false, shProg, location, uni); + } + + /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says: + * + * "When loading N elements starting at an arbitrary position k in a + * uniform declared as an array, elements k through k + N - 1 in the + * array will be replaced with the new values. Values for any array + * element that exceeds the highest array element index used, as + * reported by GetActiveUniform, will be ignored by the GL." + * + * Clamp 'count' to a valid value. Note that for non-arrays a count > 1 + * will have already generated an error. + */ + if (uni->array_elements != 0) { + count = MIN2(count, (int) (uni->array_elements - offset)); + } + + FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); + + /* Store the data in the "actual type" backing storage for the uniform. + */ + memcpy(&uni->storage[size_mul * components * offset], values, + sizeof(uni->storage[0]) * components * count * size_mul); + + _mesa_propagate_uniforms_to_driver_storage(uni, offset, count); +} extern "C" bool _mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg,