1848b8605Smrg/* 2848b8605Smrg * Mesa 3-D graphics library 3848b8605Smrg * 4848b8605Smrg * Copyright (C) 2004-2008 Brian Paul All Rights Reserved. 5848b8605Smrg * Copyright (C) 2009-2010 VMware, Inc. All Rights Reserved. 6848b8605Smrg * Copyright © 2010, 2011 Intel Corporation 7848b8605Smrg * 8848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 9848b8605Smrg * copy of this software and associated documentation files (the "Software"), 10848b8605Smrg * to deal in the Software without restriction, including without limitation 11848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 13848b8605Smrg * Software is furnished to do so, subject to the following conditions: 14848b8605Smrg * 15848b8605Smrg * The above copyright notice and this permission notice shall be included 16848b8605Smrg * in all copies or substantial portions of the Software. 17848b8605Smrg * 18848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 22848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 24848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE. 25848b8605Smrg */ 26848b8605Smrg 27848b8605Smrg#include <stdlib.h> 28b8e80941Smrg#include <inttypes.h> /* for PRIx64 macro */ 29b8e80941Smrg#include <math.h> 30848b8605Smrg 31848b8605Smrg#include "main/context.h" 32848b8605Smrg#include "main/shaderapi.h" 33848b8605Smrg#include "main/shaderobj.h" 34b8e80941Smrg#include "main/uniforms.h" 35b8e80941Smrg#include "compiler/glsl/ir.h" 36b8e80941Smrg#include "compiler/glsl/ir_uniform.h" 37b8e80941Smrg#include "compiler/glsl/glsl_parser_extras.h" 38b8e80941Smrg#include "compiler/glsl/program.h" 39b8e80941Smrg#include "util/bitscan.h" 40848b8605Smrg 41848b8605Smrg 42848b8605Smrgextern "C" void GLAPIENTRY 43848b8605Smrg_mesa_GetActiveUniform(GLuint program, GLuint index, 44848b8605Smrg GLsizei maxLength, GLsizei *length, GLint *size, 45848b8605Smrg GLenum *type, GLcharARB *nameOut) 46848b8605Smrg{ 47848b8605Smrg GET_CURRENT_CONTEXT(ctx); 48b8e80941Smrg struct gl_shader_program *shProg; 49b8e80941Smrg struct gl_program_resource *res; 50848b8605Smrg 51b8e80941Smrg if (maxLength < 0) { 52b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(maxLength < 0)"); 53848b8605Smrg return; 54b8e80941Smrg } 55848b8605Smrg 56b8e80941Smrg shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform"); 57b8e80941Smrg if (!shProg) 58848b8605Smrg return; 59848b8605Smrg 60b8e80941Smrg res = _mesa_program_resource_find_index((struct gl_shader_program *) shProg, 61b8e80941Smrg GL_UNIFORM, index); 62848b8605Smrg 63b8e80941Smrg if (!res) { 64b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)"); 65b8e80941Smrg return; 66848b8605Smrg } 67848b8605Smrg 68b8e80941Smrg if (nameOut) 69b8e80941Smrg _mesa_get_program_resource_name(shProg, GL_UNIFORM, index, maxLength, 70b8e80941Smrg length, nameOut, "glGetActiveUniform"); 71b8e80941Smrg if (type) 72b8e80941Smrg _mesa_program_resource_prop((struct gl_shader_program *) shProg, 73b8e80941Smrg res, index, GL_TYPE, (GLint*) type, 74b8e80941Smrg "glGetActiveUniform"); 75b8e80941Smrg if (size) 76b8e80941Smrg _mesa_program_resource_prop((struct gl_shader_program *) shProg, 77b8e80941Smrg res, index, GL_ARRAY_SIZE, (GLint*) size, 78b8e80941Smrg "glGetActiveUniform"); 79b8e80941Smrg} 80848b8605Smrg 81b8e80941Smrgstatic GLenum 82b8e80941Smrgresource_prop_from_uniform_prop(GLenum uni_prop) 83b8e80941Smrg{ 84b8e80941Smrg switch (uni_prop) { 85b8e80941Smrg case GL_UNIFORM_TYPE: 86b8e80941Smrg return GL_TYPE; 87b8e80941Smrg case GL_UNIFORM_SIZE: 88b8e80941Smrg return GL_ARRAY_SIZE; 89b8e80941Smrg case GL_UNIFORM_NAME_LENGTH: 90b8e80941Smrg return GL_NAME_LENGTH; 91b8e80941Smrg case GL_UNIFORM_BLOCK_INDEX: 92b8e80941Smrg return GL_BLOCK_INDEX; 93b8e80941Smrg case GL_UNIFORM_OFFSET: 94b8e80941Smrg return GL_OFFSET; 95b8e80941Smrg case GL_UNIFORM_ARRAY_STRIDE: 96b8e80941Smrg return GL_ARRAY_STRIDE; 97b8e80941Smrg case GL_UNIFORM_MATRIX_STRIDE: 98b8e80941Smrg return GL_MATRIX_STRIDE; 99b8e80941Smrg case GL_UNIFORM_IS_ROW_MAJOR: 100b8e80941Smrg return GL_IS_ROW_MAJOR; 101b8e80941Smrg case GL_UNIFORM_ATOMIC_COUNTER_BUFFER_INDEX: 102b8e80941Smrg return GL_ATOMIC_COUNTER_BUFFER_INDEX; 103b8e80941Smrg default: 104b8e80941Smrg return 0; 105848b8605Smrg } 106848b8605Smrg} 107848b8605Smrg 108848b8605Smrgextern "C" void GLAPIENTRY 109848b8605Smrg_mesa_GetActiveUniformsiv(GLuint program, 110848b8605Smrg GLsizei uniformCount, 111848b8605Smrg const GLuint *uniformIndices, 112848b8605Smrg GLenum pname, 113848b8605Smrg GLint *params) 114848b8605Smrg{ 115848b8605Smrg GET_CURRENT_CONTEXT(ctx); 116848b8605Smrg struct gl_shader_program *shProg; 117b8e80941Smrg struct gl_program_resource *res; 118b8e80941Smrg GLenum res_prop; 119848b8605Smrg 120848b8605Smrg if (uniformCount < 0) { 121848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, 122848b8605Smrg "glGetActiveUniformsiv(uniformCount < 0)"); 123848b8605Smrg return; 124848b8605Smrg } 125848b8605Smrg 126b8e80941Smrg shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform"); 127b8e80941Smrg if (!shProg) 128b8e80941Smrg return; 129b8e80941Smrg 130b8e80941Smrg res_prop = resource_prop_from_uniform_prop(pname); 131848b8605Smrg 132b8e80941Smrg /* We need to first verify that each entry exists as active uniform. If 133b8e80941Smrg * not, generate error and do not cause any other side effects. 134b8e80941Smrg * 135b8e80941Smrg * In the case of and error condition, Page 16 (section 2.3.1 Errors) 136b8e80941Smrg * of the OpenGL 4.5 spec says: 137b8e80941Smrg * 138b8e80941Smrg * "If the generating command modifies values through a pointer argu- 139b8e80941Smrg * ment, no change is made to these values." 140b8e80941Smrg */ 141b8e80941Smrg for (int i = 0; i < uniformCount; i++) { 142b8e80941Smrg if (!_mesa_program_resource_find_index(shProg, GL_UNIFORM, 143b8e80941Smrg uniformIndices[i])) { 144b8e80941Smrg _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformsiv(index)"); 145b8e80941Smrg return; 146848b8605Smrg } 147848b8605Smrg } 148848b8605Smrg 149b8e80941Smrg for (int i = 0; i < uniformCount; i++) { 150b8e80941Smrg res = _mesa_program_resource_find_index(shProg, GL_UNIFORM, 151b8e80941Smrg uniformIndices[i]); 152b8e80941Smrg if (!_mesa_program_resource_prop(shProg, res, uniformIndices[i], 153b8e80941Smrg res_prop, ¶ms[i], 154b8e80941Smrg "glGetActiveUniformsiv")) 155848b8605Smrg break; 156848b8605Smrg } 157848b8605Smrg} 158848b8605Smrg 159848b8605Smrgstatic struct gl_uniform_storage * 160b8e80941Smrgvalidate_uniform_parameters(GLint location, GLsizei count, 161b8e80941Smrg unsigned *array_index, 162b8e80941Smrg struct gl_context *ctx, 163b8e80941Smrg struct gl_shader_program *shProg, 164b8e80941Smrg const char *caller) 165848b8605Smrg{ 166b8e80941Smrg if (shProg == NULL) { 167848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)", caller); 168848b8605Smrg return NULL; 169848b8605Smrg } 170848b8605Smrg 171848b8605Smrg /* From page 12 (page 26 of the PDF) of the OpenGL 2.1 spec: 172848b8605Smrg * 173848b8605Smrg * "If a negative number is provided where an argument of type sizei or 174848b8605Smrg * sizeiptr is specified, the error INVALID_VALUE is generated." 175848b8605Smrg */ 176848b8605Smrg if (count < 0) { 177848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, "%s(count < 0)", caller); 178848b8605Smrg return NULL; 179848b8605Smrg } 180848b8605Smrg 181b8e80941Smrg /* Check that the given location is in bounds of uniform remap table. 182b8e80941Smrg * Unlinked programs will have NumUniformRemapTable == 0, so we can take 183b8e80941Smrg * the shProg->data->LinkStatus check out of the main path. 184b8e80941Smrg */ 185b8e80941Smrg if (unlikely(location >= (GLint) shProg->NumUniformRemapTable)) { 186b8e80941Smrg if (!shProg->data->LinkStatus) 187b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)", 188b8e80941Smrg caller); 189b8e80941Smrg else 190b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)", 191b8e80941Smrg caller, location); 192b8e80941Smrg 193b8e80941Smrg return NULL; 194b8e80941Smrg } 195b8e80941Smrg 196b8e80941Smrg if (location == -1) { 197b8e80941Smrg if (!shProg->data->LinkStatus) 198b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)", 199b8e80941Smrg caller); 200b8e80941Smrg 201848b8605Smrg return NULL; 202848b8605Smrg } 203848b8605Smrg 204848b8605Smrg /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says: 205848b8605Smrg * 206848b8605Smrg * "If any of the following conditions occur, an INVALID_OPERATION 207848b8605Smrg * error is generated by the Uniform* commands, and no uniform values 208848b8605Smrg * are changed: 209848b8605Smrg * 210848b8605Smrg * ... 211848b8605Smrg * 212848b8605Smrg * - if no variable with a location of location exists in the 213848b8605Smrg * program object currently in use and location is not -1, 214848b8605Smrg * - if count is greater than one, and the uniform declared in the 215848b8605Smrg * shader is not an array variable, 216848b8605Smrg */ 217848b8605Smrg if (location < -1 || !shProg->UniformRemapTable[location]) { 218848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)", 219848b8605Smrg caller, location); 220848b8605Smrg return NULL; 221848b8605Smrg } 222848b8605Smrg 223848b8605Smrg /* If the driver storage pointer in remap table is -1, we ignore silently. 224848b8605Smrg * 225848b8605Smrg * GL_ARB_explicit_uniform_location spec says: 226848b8605Smrg * "What happens if Uniform* is called with an explicitly defined 227848b8605Smrg * uniform location, but that uniform is deemed inactive by the 228848b8605Smrg * linker? 229848b8605Smrg * 230848b8605Smrg * RESOLVED: The call is ignored for inactive uniform variables and 231848b8605Smrg * no error is generated." 232848b8605Smrg * 233848b8605Smrg */ 234848b8605Smrg if (shProg->UniformRemapTable[location] == 235848b8605Smrg INACTIVE_UNIFORM_EXPLICIT_LOCATION) 236848b8605Smrg return NULL; 237848b8605Smrg 238848b8605Smrg struct gl_uniform_storage *const uni = shProg->UniformRemapTable[location]; 239848b8605Smrg 240b8e80941Smrg /* Even though no location is assigned to a built-in uniform and this 241b8e80941Smrg * function should already have returned NULL, this test makes it explicit 242b8e80941Smrg * that we are not allowing to update the value of a built-in. 243b8e80941Smrg */ 244b8e80941Smrg if (uni->builtin) 245848b8605Smrg return NULL; 246848b8605Smrg 247b8e80941Smrg if (uni->array_elements == 0) { 248b8e80941Smrg if (count > 1) { 249b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 250b8e80941Smrg "%s(count = %u for non-array \"%s\"@%d)", 251b8e80941Smrg caller, count, uni->name, location); 252b8e80941Smrg return NULL; 253b8e80941Smrg } 254848b8605Smrg 255b8e80941Smrg assert((location - uni->remap_location) == 0); 256b8e80941Smrg *array_index = 0; 257b8e80941Smrg } else { 258b8e80941Smrg /* The array index specified by the uniform location is just the uniform 259b8e80941Smrg * location minus the base location of of the uniform. 260b8e80941Smrg */ 261b8e80941Smrg *array_index = location - uni->remap_location; 262b8e80941Smrg 263b8e80941Smrg /* If the uniform is an array, check that array_index is in bounds. 264b8e80941Smrg * array_index is unsigned so no need to check for less than zero. 265b8e80941Smrg */ 266b8e80941Smrg if (*array_index >= uni->array_elements) { 267b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "%s(location=%d)", 268b8e80941Smrg caller, location); 269b8e80941Smrg return NULL; 270b8e80941Smrg } 271848b8605Smrg } 272848b8605Smrg return uni; 273848b8605Smrg} 274848b8605Smrg 275848b8605Smrg/** 276848b8605Smrg * Called via glGetUniform[fiui]v() to get the current value of a uniform. 277848b8605Smrg */ 278848b8605Smrgextern "C" void 279848b8605Smrg_mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location, 280848b8605Smrg GLsizei bufSize, enum glsl_base_type returnType, 281848b8605Smrg GLvoid *paramsOut) 282848b8605Smrg{ 283848b8605Smrg struct gl_shader_program *shProg = 284848b8605Smrg _mesa_lookup_shader_program_err(ctx, program, "glGetUniformfv"); 285848b8605Smrg unsigned offset; 286848b8605Smrg 287848b8605Smrg struct gl_uniform_storage *const uni = 288b8e80941Smrg validate_uniform_parameters(location, 1, &offset, 289b8e80941Smrg ctx, shProg, "glGetUniform"); 290b8e80941Smrg if (uni == NULL) { 291b8e80941Smrg /* For glGetUniform, page 264 (page 278 of the PDF) of the OpenGL 2.1 292b8e80941Smrg * spec says: 293b8e80941Smrg * 294b8e80941Smrg * "The error INVALID_OPERATION is generated if program has not been 295b8e80941Smrg * linked successfully, or if location is not a valid location for 296b8e80941Smrg * program." 297b8e80941Smrg * 298b8e80941Smrg * For glUniform, page 82 (page 96 of the PDF) of the OpenGL 2.1 spec 299b8e80941Smrg * says: 300b8e80941Smrg * 301b8e80941Smrg * "If the value of location is -1, the Uniform* commands will 302b8e80941Smrg * silently ignore the data passed in, and the current uniform 303b8e80941Smrg * values will not be changed." 304b8e80941Smrg * 305b8e80941Smrg * Allowing -1 for the location parameter of glUniform allows 306b8e80941Smrg * applications to avoid error paths in the case that, for example, some 307b8e80941Smrg * uniform variable is removed by the compiler / linker after 308b8e80941Smrg * optimization. In this case, the new value of the uniform is dropped 309b8e80941Smrg * on the floor. For the case of glGetUniform, there is nothing 310b8e80941Smrg * sensible to do for a location of -1. 311b8e80941Smrg * 312b8e80941Smrg * If the location was -1, validate_unfirom_parameters will return NULL 313b8e80941Smrg * without raising an error. Raise the error here. 314b8e80941Smrg */ 315b8e80941Smrg if (location == -1) { 316b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniform(location=%d)", 317b8e80941Smrg location); 318b8e80941Smrg } 319b8e80941Smrg 320848b8605Smrg return; 321b8e80941Smrg } 322848b8605Smrg 323848b8605Smrg { 324b8e80941Smrg unsigned elements = uni->type->components(); 325b8e80941Smrg const int rmul = glsl_base_type_is_64bit(returnType) ? 2 : 1; 326b8e80941Smrg int dmul = (uni->type->is_64bit()) ? 2 : 1; 327b8e80941Smrg 328b8e80941Smrg if ((uni->type->is_sampler() || uni->type->is_image()) && 329b8e80941Smrg !uni->is_bindless) { 330b8e80941Smrg /* Non-bindless samplers/images are represented using unsigned integer 331b8e80941Smrg * 32-bit, while bindless handles are 64-bit. 332b8e80941Smrg */ 333b8e80941Smrg dmul = 1; 334b8e80941Smrg } 335848b8605Smrg 336848b8605Smrg /* Calculate the source base address *BEFORE* modifying elements to 337848b8605Smrg * account for the size of the user's buffer. 338848b8605Smrg */ 339b8e80941Smrg const union gl_constant_value *src; 340b8e80941Smrg if (ctx->Const.PackedDriverUniformStorage && 341b8e80941Smrg (uni->is_bindless || !uni->type->contains_opaque())) { 342b8e80941Smrg src = (gl_constant_value *) uni->driver_storage[0].data + 343b8e80941Smrg (offset * elements * dmul); 344b8e80941Smrg } else { 345b8e80941Smrg src = &uni->storage[offset * elements * dmul]; 346b8e80941Smrg } 347848b8605Smrg 348848b8605Smrg assert(returnType == GLSL_TYPE_FLOAT || returnType == GLSL_TYPE_INT || 349b8e80941Smrg returnType == GLSL_TYPE_UINT || returnType == GLSL_TYPE_DOUBLE || 350b8e80941Smrg returnType == GLSL_TYPE_UINT64 || returnType == GLSL_TYPE_INT64); 351b8e80941Smrg 352b8e80941Smrg /* doubles have a different size than the other 3 types */ 353b8e80941Smrg unsigned bytes = sizeof(src[0]) * elements * rmul; 354848b8605Smrg if (bufSize < 0 || bytes > (unsigned) bufSize) { 355b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 356b8e80941Smrg "glGetnUniform*vARB(out of bounds: bufSize is %d," 357b8e80941Smrg " but %u bytes are required)", bufSize, bytes); 358b8e80941Smrg return; 359848b8605Smrg } 360848b8605Smrg 361848b8605Smrg /* If the return type and the uniform's native type are "compatible," 362848b8605Smrg * just memcpy the data. If the types are not compatible, perform a 363848b8605Smrg * slower convert-and-copy process. 364848b8605Smrg */ 365b8e80941Smrg if (returnType == uni->type->base_type || 366b8e80941Smrg ((returnType == GLSL_TYPE_INT || returnType == GLSL_TYPE_UINT) && 367b8e80941Smrg (uni->type->is_sampler() || uni->type->is_image())) || 368b8e80941Smrg (returnType == GLSL_TYPE_UINT64 && uni->is_bindless)) { 369b8e80941Smrg memcpy(paramsOut, src, bytes); 370848b8605Smrg } else { 371b8e80941Smrg union gl_constant_value *const dst = 372b8e80941Smrg (union gl_constant_value *) paramsOut; 373b8e80941Smrg /* This code could be optimized by putting the loop inside the switch 374b8e80941Smrg * statements. However, this is not expected to be 375b8e80941Smrg * performance-critical code. 376b8e80941Smrg */ 377b8e80941Smrg for (unsigned i = 0; i < elements; i++) { 378b8e80941Smrg int sidx = i * dmul; 379b8e80941Smrg int didx = i * rmul; 380b8e80941Smrg 381b8e80941Smrg switch (returnType) { 382b8e80941Smrg case GLSL_TYPE_FLOAT: 383b8e80941Smrg switch (uni->type->base_type) { 384b8e80941Smrg case GLSL_TYPE_UINT: 385b8e80941Smrg dst[didx].f = (float) src[sidx].u; 386b8e80941Smrg break; 387b8e80941Smrg case GLSL_TYPE_INT: 388b8e80941Smrg case GLSL_TYPE_SAMPLER: 389b8e80941Smrg case GLSL_TYPE_IMAGE: 390b8e80941Smrg dst[didx].f = (float) src[sidx].i; 391b8e80941Smrg break; 392b8e80941Smrg case GLSL_TYPE_BOOL: 393b8e80941Smrg dst[didx].f = src[sidx].i ? 1.0f : 0.0f; 394b8e80941Smrg break; 395b8e80941Smrg case GLSL_TYPE_DOUBLE: { 396b8e80941Smrg double tmp; 397b8e80941Smrg memcpy(&tmp, &src[sidx].f, sizeof(tmp)); 398b8e80941Smrg dst[didx].f = tmp; 399b8e80941Smrg break; 400b8e80941Smrg } 401b8e80941Smrg case GLSL_TYPE_UINT64: { 402b8e80941Smrg uint64_t tmp; 403b8e80941Smrg memcpy(&tmp, &src[sidx].u, sizeof(tmp)); 404b8e80941Smrg dst[didx].f = tmp; 405b8e80941Smrg break; 406b8e80941Smrg } 407b8e80941Smrg case GLSL_TYPE_INT64: { 408b8e80941Smrg uint64_t tmp; 409b8e80941Smrg memcpy(&tmp, &src[sidx].i, sizeof(tmp)); 410b8e80941Smrg dst[didx].f = tmp; 411b8e80941Smrg break; 412b8e80941Smrg } 413b8e80941Smrg default: 414b8e80941Smrg assert(!"Should not get here."); 415b8e80941Smrg break; 416b8e80941Smrg } 417b8e80941Smrg break; 418b8e80941Smrg 419b8e80941Smrg case GLSL_TYPE_DOUBLE: 420b8e80941Smrg switch (uni->type->base_type) { 421b8e80941Smrg case GLSL_TYPE_UINT: { 422b8e80941Smrg double tmp = src[sidx].u; 423b8e80941Smrg memcpy(&dst[didx].f, &tmp, sizeof(tmp)); 424b8e80941Smrg break; 425b8e80941Smrg } 426b8e80941Smrg case GLSL_TYPE_INT: 427b8e80941Smrg case GLSL_TYPE_SAMPLER: 428b8e80941Smrg case GLSL_TYPE_IMAGE: { 429b8e80941Smrg double tmp = src[sidx].i; 430b8e80941Smrg memcpy(&dst[didx].f, &tmp, sizeof(tmp)); 431b8e80941Smrg break; 432b8e80941Smrg } 433b8e80941Smrg case GLSL_TYPE_BOOL: { 434b8e80941Smrg double tmp = src[sidx].i ? 1.0 : 0.0; 435b8e80941Smrg memcpy(&dst[didx].f, &tmp, sizeof(tmp)); 436b8e80941Smrg break; 437b8e80941Smrg } 438b8e80941Smrg case GLSL_TYPE_FLOAT: { 439b8e80941Smrg double tmp = src[sidx].f; 440b8e80941Smrg memcpy(&dst[didx].f, &tmp, sizeof(tmp)); 441b8e80941Smrg break; 442b8e80941Smrg } 443b8e80941Smrg case GLSL_TYPE_UINT64: { 444b8e80941Smrg uint64_t tmpu; 445b8e80941Smrg double tmp; 446b8e80941Smrg memcpy(&tmpu, &src[sidx].u, sizeof(tmpu)); 447b8e80941Smrg tmp = tmpu; 448b8e80941Smrg memcpy(&dst[didx].f, &tmp, sizeof(tmp)); 449b8e80941Smrg break; 450b8e80941Smrg } 451b8e80941Smrg case GLSL_TYPE_INT64: { 452b8e80941Smrg int64_t tmpi; 453b8e80941Smrg double tmp; 454b8e80941Smrg memcpy(&tmpi, &src[sidx].i, sizeof(tmpi)); 455b8e80941Smrg tmp = tmpi; 456b8e80941Smrg memcpy(&dst[didx].f, &tmp, sizeof(tmp)); 457b8e80941Smrg break; 458b8e80941Smrg } 459b8e80941Smrg default: 460b8e80941Smrg assert(!"Should not get here."); 461b8e80941Smrg break; 462b8e80941Smrg } 463b8e80941Smrg break; 464b8e80941Smrg 465b8e80941Smrg case GLSL_TYPE_INT: 466b8e80941Smrg switch (uni->type->base_type) { 467b8e80941Smrg case GLSL_TYPE_FLOAT: 468b8e80941Smrg /* While the GL 3.2 core spec doesn't explicitly 469b8e80941Smrg * state how conversion of float uniforms to integer 470b8e80941Smrg * values works, in section 6.2 "State Tables" on 471b8e80941Smrg * page 267 it says: 472b8e80941Smrg * 473b8e80941Smrg * "Unless otherwise specified, when floating 474b8e80941Smrg * point state is returned as integer values or 475b8e80941Smrg * integer state is returned as floating-point 476b8e80941Smrg * values it is converted in the fashion 477b8e80941Smrg * described in section 6.1.2" 478b8e80941Smrg * 479b8e80941Smrg * That section, on page 248, says: 480b8e80941Smrg * 481b8e80941Smrg * "If GetIntegerv or GetInteger64v are called, 482b8e80941Smrg * a floating-point value is rounded to the 483b8e80941Smrg * nearest integer..." 484b8e80941Smrg */ 485b8e80941Smrg dst[didx].i = (int64_t) roundf(src[sidx].f); 486b8e80941Smrg break; 487b8e80941Smrg case GLSL_TYPE_BOOL: 488b8e80941Smrg dst[didx].i = src[sidx].i ? 1 : 0; 489b8e80941Smrg break; 490b8e80941Smrg case GLSL_TYPE_UINT: 491b8e80941Smrg dst[didx].i = MIN2(src[sidx].i, INT_MAX); 492b8e80941Smrg break; 493b8e80941Smrg case GLSL_TYPE_DOUBLE: { 494b8e80941Smrg double tmp; 495b8e80941Smrg memcpy(&tmp, &src[sidx].f, sizeof(tmp)); 496b8e80941Smrg dst[didx].i = (int64_t) round(tmp); 497b8e80941Smrg break; 498b8e80941Smrg } 499b8e80941Smrg case GLSL_TYPE_UINT64: { 500b8e80941Smrg uint64_t tmp; 501b8e80941Smrg memcpy(&tmp, &src[sidx].u, sizeof(tmp)); 502b8e80941Smrg dst[didx].i = tmp; 503b8e80941Smrg break; 504b8e80941Smrg } 505b8e80941Smrg case GLSL_TYPE_INT64: { 506b8e80941Smrg int64_t tmp; 507b8e80941Smrg memcpy(&tmp, &src[sidx].i, sizeof(tmp)); 508b8e80941Smrg dst[didx].i = tmp; 509b8e80941Smrg break; 510b8e80941Smrg } 511b8e80941Smrg default: 512b8e80941Smrg assert(!"Should not get here."); 513b8e80941Smrg break; 514b8e80941Smrg } 515b8e80941Smrg break; 516b8e80941Smrg 517b8e80941Smrg case GLSL_TYPE_UINT: 518b8e80941Smrg switch (uni->type->base_type) { 519b8e80941Smrg case GLSL_TYPE_FLOAT: 520b8e80941Smrg /* The spec isn't terribly clear how to handle negative 521b8e80941Smrg * values with an unsigned return type. 522b8e80941Smrg * 523b8e80941Smrg * GL 4.5 section 2.2.2 ("Data Conversions for State 524b8e80941Smrg * Query Commands") says: 525b8e80941Smrg * 526b8e80941Smrg * "If a value is so large in magnitude that it cannot be 527b8e80941Smrg * represented by the returned data type, then the nearest 528b8e80941Smrg * value representable using the requested type is 529b8e80941Smrg * returned." 530b8e80941Smrg */ 531b8e80941Smrg dst[didx].u = src[sidx].f < 0.0f ? 532b8e80941Smrg 0u : (uint32_t) roundf(src[sidx].f); 533b8e80941Smrg break; 534b8e80941Smrg case GLSL_TYPE_BOOL: 535b8e80941Smrg dst[didx].i = src[sidx].i ? 1 : 0; 536b8e80941Smrg break; 537b8e80941Smrg case GLSL_TYPE_INT: 538b8e80941Smrg dst[didx].i = MAX2(src[sidx].i, 0); 539b8e80941Smrg break; 540b8e80941Smrg case GLSL_TYPE_DOUBLE: { 541b8e80941Smrg double tmp; 542b8e80941Smrg memcpy(&tmp, &src[sidx].f, sizeof(tmp)); 543b8e80941Smrg dst[didx].u = tmp < 0.0 ? 0u : (uint32_t) round(tmp); 544b8e80941Smrg break; 545b8e80941Smrg } 546b8e80941Smrg case GLSL_TYPE_UINT64: { 547b8e80941Smrg uint64_t tmp; 548b8e80941Smrg memcpy(&tmp, &src[sidx].u, sizeof(tmp)); 549b8e80941Smrg dst[didx].i = MIN2(tmp, INT_MAX); 550b8e80941Smrg break; 551b8e80941Smrg } 552b8e80941Smrg case GLSL_TYPE_INT64: { 553b8e80941Smrg int64_t tmp; 554b8e80941Smrg memcpy(&tmp, &src[sidx].i, sizeof(tmp)); 555b8e80941Smrg dst[didx].i = MAX2(tmp, 0); 556b8e80941Smrg break; 557b8e80941Smrg } 558b8e80941Smrg default: 559b8e80941Smrg unreachable("invalid uniform type"); 560b8e80941Smrg } 561b8e80941Smrg break; 562b8e80941Smrg 563b8e80941Smrg case GLSL_TYPE_INT64: 564b8e80941Smrg switch (uni->type->base_type) { 565b8e80941Smrg case GLSL_TYPE_UINT: { 566b8e80941Smrg uint64_t tmp = src[sidx].u; 567b8e80941Smrg memcpy(&dst[didx].u, &tmp, sizeof(tmp)); 568b8e80941Smrg break; 569b8e80941Smrg } 570b8e80941Smrg case GLSL_TYPE_INT: 571b8e80941Smrg case GLSL_TYPE_SAMPLER: 572b8e80941Smrg case GLSL_TYPE_IMAGE: { 573b8e80941Smrg int64_t tmp = src[sidx].i; 574b8e80941Smrg memcpy(&dst[didx].u, &tmp, sizeof(tmp)); 575b8e80941Smrg break; 576b8e80941Smrg } 577b8e80941Smrg case GLSL_TYPE_BOOL: { 578b8e80941Smrg int64_t tmp = src[sidx].i ? 1.0f : 0.0f; 579b8e80941Smrg memcpy(&dst[didx].u, &tmp, sizeof(tmp)); 580b8e80941Smrg break; 581b8e80941Smrg } 582b8e80941Smrg case GLSL_TYPE_UINT64: { 583b8e80941Smrg uint64_t u64; 584b8e80941Smrg memcpy(&u64, &src[sidx].u, sizeof(u64)); 585b8e80941Smrg int64_t tmp = MIN2(u64, INT_MAX); 586b8e80941Smrg memcpy(&dst[didx].u, &tmp, sizeof(tmp)); 587b8e80941Smrg break; 588b8e80941Smrg } 589b8e80941Smrg case GLSL_TYPE_FLOAT: { 590b8e80941Smrg int64_t tmp = (int64_t) roundf(src[sidx].f); 591b8e80941Smrg memcpy(&dst[didx].u, &tmp, sizeof(tmp)); 592b8e80941Smrg break; 593b8e80941Smrg } 594b8e80941Smrg case GLSL_TYPE_DOUBLE: { 595b8e80941Smrg double d; 596b8e80941Smrg memcpy(&d, &src[sidx].f, sizeof(d)); 597b8e80941Smrg int64_t tmp = (int64_t) round(d); 598b8e80941Smrg memcpy(&dst[didx].u, &tmp, sizeof(tmp)); 599b8e80941Smrg break; 600b8e80941Smrg } 601b8e80941Smrg default: 602b8e80941Smrg assert(!"Should not get here."); 603b8e80941Smrg break; 604b8e80941Smrg } 605b8e80941Smrg break; 606b8e80941Smrg 607b8e80941Smrg case GLSL_TYPE_UINT64: 608b8e80941Smrg switch (uni->type->base_type) { 609b8e80941Smrg case GLSL_TYPE_UINT: { 610b8e80941Smrg uint64_t tmp = src[sidx].u; 611b8e80941Smrg memcpy(&dst[didx].u, &tmp, sizeof(tmp)); 612b8e80941Smrg break; 613b8e80941Smrg } 614b8e80941Smrg case GLSL_TYPE_INT: 615b8e80941Smrg case GLSL_TYPE_SAMPLER: 616b8e80941Smrg case GLSL_TYPE_IMAGE: { 617b8e80941Smrg int64_t tmp = MAX2(src[sidx].i, 0); 618b8e80941Smrg memcpy(&dst[didx].u, &tmp, sizeof(tmp)); 619b8e80941Smrg break; 620b8e80941Smrg } 621b8e80941Smrg case GLSL_TYPE_BOOL: { 622b8e80941Smrg int64_t tmp = src[sidx].i ? 1.0f : 0.0f; 623b8e80941Smrg memcpy(&dst[didx].u, &tmp, sizeof(tmp)); 624b8e80941Smrg break; 625b8e80941Smrg } 626b8e80941Smrg case GLSL_TYPE_INT64: { 627b8e80941Smrg uint64_t i64; 628b8e80941Smrg memcpy(&i64, &src[sidx].i, sizeof(i64)); 629b8e80941Smrg uint64_t tmp = MAX2(i64, 0); 630b8e80941Smrg memcpy(&dst[didx].u, &tmp, sizeof(tmp)); 631b8e80941Smrg break; 632b8e80941Smrg } 633b8e80941Smrg case GLSL_TYPE_FLOAT: { 634b8e80941Smrg uint64_t tmp = src[sidx].f < 0.0f ? 635b8e80941Smrg 0ull : (uint64_t) roundf(src[sidx].f); 636b8e80941Smrg memcpy(&dst[didx].u, &tmp, sizeof(tmp)); 637b8e80941Smrg break; 638b8e80941Smrg } 639b8e80941Smrg case GLSL_TYPE_DOUBLE: { 640b8e80941Smrg double d; 641b8e80941Smrg memcpy(&d, &src[sidx].f, sizeof(d)); 642b8e80941Smrg uint64_t tmp = (d < 0.0) ? 0ull : (uint64_t) round(d); 643b8e80941Smrg memcpy(&dst[didx].u, &tmp, sizeof(tmp)); 644b8e80941Smrg break; 645b8e80941Smrg } 646b8e80941Smrg default: 647b8e80941Smrg assert(!"Should not get here."); 648b8e80941Smrg break; 649b8e80941Smrg } 650b8e80941Smrg break; 651b8e80941Smrg 652b8e80941Smrg default: 653b8e80941Smrg assert(!"Should not get here."); 654b8e80941Smrg break; 655b8e80941Smrg } 656b8e80941Smrg } 657848b8605Smrg } 658848b8605Smrg } 659848b8605Smrg} 660848b8605Smrg 661848b8605Smrgstatic void 662848b8605Smrglog_uniform(const void *values, enum glsl_base_type basicType, 663848b8605Smrg unsigned rows, unsigned cols, unsigned count, 664848b8605Smrg bool transpose, 665848b8605Smrg const struct gl_shader_program *shProg, 666848b8605Smrg GLint location, 667848b8605Smrg const struct gl_uniform_storage *uni) 668848b8605Smrg{ 669848b8605Smrg 670848b8605Smrg const union gl_constant_value *v = (const union gl_constant_value *) values; 671848b8605Smrg const unsigned elems = rows * cols * count; 672848b8605Smrg const char *const extra = (cols == 1) ? "uniform" : "uniform matrix"; 673848b8605Smrg 674848b8605Smrg printf("Mesa: set program %u %s \"%s\" (loc %d, type \"%s\", " 675848b8605Smrg "transpose = %s) to: ", 676848b8605Smrg shProg->Name, extra, uni->name, location, uni->type->name, 677848b8605Smrg transpose ? "true" : "false"); 678848b8605Smrg for (unsigned i = 0; i < elems; i++) { 679848b8605Smrg if (i != 0 && ((i % rows) == 0)) 680848b8605Smrg printf(", "); 681848b8605Smrg 682848b8605Smrg switch (basicType) { 683848b8605Smrg case GLSL_TYPE_UINT: 684848b8605Smrg printf("%u ", v[i].u); 685848b8605Smrg break; 686848b8605Smrg case GLSL_TYPE_INT: 687848b8605Smrg printf("%d ", v[i].i); 688848b8605Smrg break; 689b8e80941Smrg case GLSL_TYPE_UINT64: { 690b8e80941Smrg uint64_t tmp; 691b8e80941Smrg memcpy(&tmp, &v[i * 2].u, sizeof(tmp)); 692b8e80941Smrg printf("%" PRIu64 " ", tmp); 693b8e80941Smrg break; 694b8e80941Smrg } 695b8e80941Smrg case GLSL_TYPE_INT64: { 696b8e80941Smrg int64_t tmp; 697b8e80941Smrg memcpy(&tmp, &v[i * 2].u, sizeof(tmp)); 698b8e80941Smrg printf("%" PRId64 " ", tmp); 699b8e80941Smrg break; 700b8e80941Smrg } 701848b8605Smrg case GLSL_TYPE_FLOAT: 702848b8605Smrg printf("%g ", v[i].f); 703848b8605Smrg break; 704b8e80941Smrg case GLSL_TYPE_DOUBLE: { 705b8e80941Smrg double tmp; 706b8e80941Smrg memcpy(&tmp, &v[i * 2].f, sizeof(tmp)); 707b8e80941Smrg printf("%g ", tmp); 708b8e80941Smrg break; 709b8e80941Smrg } 710848b8605Smrg default: 711848b8605Smrg assert(!"Should not get here."); 712848b8605Smrg break; 713848b8605Smrg } 714848b8605Smrg } 715848b8605Smrg printf("\n"); 716848b8605Smrg fflush(stdout); 717848b8605Smrg} 718848b8605Smrg 719848b8605Smrg#if 0 720848b8605Smrgstatic void 721848b8605Smrglog_program_parameters(const struct gl_shader_program *shProg) 722848b8605Smrg{ 723848b8605Smrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 724848b8605Smrg if (shProg->_LinkedShaders[i] == NULL) 725848b8605Smrg continue; 726848b8605Smrg 727848b8605Smrg const struct gl_program *const prog = shProg->_LinkedShaders[i]->Program; 728848b8605Smrg 729848b8605Smrg printf("Program %d %s shader parameters:\n", 730848b8605Smrg shProg->Name, _mesa_shader_stage_to_string(i)); 731848b8605Smrg for (unsigned j = 0; j < prog->Parameters->NumParameters; j++) { 732b8e80941Smrg unsigned pvo = prog->Parameters->ParameterValueOffset[j]; 733b8e80941Smrg printf("%s: %u %p %f %f %f %f\n", 734848b8605Smrg prog->Parameters->Parameters[j].Name, 735b8e80941Smrg pvo, 736b8e80941Smrg prog->Parameters->ParameterValues + pvo, 737b8e80941Smrg prog->Parameters->ParameterValues[pvo].f, 738b8e80941Smrg prog->Parameters->ParameterValues[pvo + 1].f, 739b8e80941Smrg prog->Parameters->ParameterValues[pvo + 2].f, 740b8e80941Smrg prog->Parameters->ParameterValues[pvo + 3].f); 741848b8605Smrg } 742848b8605Smrg } 743848b8605Smrg fflush(stdout); 744848b8605Smrg} 745848b8605Smrg#endif 746848b8605Smrg 747848b8605Smrg/** 748848b8605Smrg * Propagate some values from uniform backing storage to driver storage 749848b8605Smrg * 750848b8605Smrg * Values propagated from uniform backing storage to driver storage 751848b8605Smrg * have all format / type conversions previously requested by the 752848b8605Smrg * driver applied. This function is most often called by the 753848b8605Smrg * implementations of \c glUniform1f, etc. and \c glUniformMatrix2f, 754848b8605Smrg * etc. 755848b8605Smrg * 756848b8605Smrg * \param uni Uniform whose data is to be propagated to driver storage 757848b8605Smrg * \param array_index If \c uni is an array, this is the element of 758848b8605Smrg * the array to be propagated. 759848b8605Smrg * \param count Number of array elements to propagate. 760848b8605Smrg */ 761848b8605Smrgextern "C" void 762848b8605Smrg_mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni, 763848b8605Smrg unsigned array_index, 764848b8605Smrg unsigned count) 765848b8605Smrg{ 766848b8605Smrg unsigned i; 767848b8605Smrg 768b8e80941Smrg const unsigned components = uni->type->vector_elements; 769b8e80941Smrg const unsigned vectors = uni->type->matrix_columns; 770b8e80941Smrg const int dmul = uni->type->is_64bit() ? 2 : 1; 771848b8605Smrg 772848b8605Smrg /* Store the data in the driver's requested type in the driver's storage 773848b8605Smrg * areas. 774848b8605Smrg */ 775b8e80941Smrg unsigned src_vector_byte_stride = components * 4 * dmul; 776848b8605Smrg 777848b8605Smrg for (i = 0; i < uni->num_driver_storage; i++) { 778848b8605Smrg struct gl_uniform_driver_storage *const store = &uni->driver_storage[i]; 779848b8605Smrg uint8_t *dst = (uint8_t *) store->data; 780848b8605Smrg const unsigned extra_stride = 781848b8605Smrg store->element_stride - (vectors * store->vector_stride); 782848b8605Smrg const uint8_t *src = 783b8e80941Smrg (uint8_t *) (&uni->storage[array_index * (dmul * components * vectors)].i); 784848b8605Smrg 785848b8605Smrg#if 0 786848b8605Smrg printf("%s: %p[%d] components=%u vectors=%u count=%u vector_stride=%u " 787848b8605Smrg "extra_stride=%u\n", 788848b8605Smrg __func__, dst, array_index, components, 789848b8605Smrg vectors, count, store->vector_stride, extra_stride); 790848b8605Smrg#endif 791848b8605Smrg 792848b8605Smrg dst += array_index * store->element_stride; 793848b8605Smrg 794848b8605Smrg switch (store->format) { 795b8e80941Smrg case uniform_native: { 796848b8605Smrg unsigned j; 797848b8605Smrg unsigned v; 798848b8605Smrg 799b8e80941Smrg if (src_vector_byte_stride == store->vector_stride) { 800b8e80941Smrg if (extra_stride) { 801b8e80941Smrg for (j = 0; j < count; j++) { 802b8e80941Smrg memcpy(dst, src, src_vector_byte_stride * vectors); 803b8e80941Smrg src += src_vector_byte_stride * vectors; 804b8e80941Smrg dst += store->vector_stride * vectors; 805848b8605Smrg 806b8e80941Smrg dst += extra_stride; 807848b8605Smrg } 808b8e80941Smrg } else { 809b8e80941Smrg /* Unigine Heaven benchmark gets here */ 810b8e80941Smrg memcpy(dst, src, src_vector_byte_stride * vectors * count); 811b8e80941Smrg src += src_vector_byte_stride * vectors * count; 812b8e80941Smrg dst += store->vector_stride * vectors * count; 813848b8605Smrg } 814b8e80941Smrg } else { 815b8e80941Smrg for (j = 0; j < count; j++) { 816b8e80941Smrg for (v = 0; v < vectors; v++) { 817b8e80941Smrg memcpy(dst, src, src_vector_byte_stride); 818b8e80941Smrg src += src_vector_byte_stride; 819b8e80941Smrg dst += store->vector_stride; 820b8e80941Smrg } 821848b8605Smrg 822b8e80941Smrg dst += extra_stride; 823b8e80941Smrg } 824848b8605Smrg } 825848b8605Smrg break; 826848b8605Smrg } 827848b8605Smrg 828b8e80941Smrg case uniform_int_float: { 829848b8605Smrg const int *isrc = (const int *) src; 830848b8605Smrg unsigned j; 831848b8605Smrg unsigned v; 832848b8605Smrg unsigned c; 833848b8605Smrg 834848b8605Smrg for (j = 0; j < count; j++) { 835848b8605Smrg for (v = 0; v < vectors; v++) { 836848b8605Smrg for (c = 0; c < components; c++) { 837b8e80941Smrg ((float *) dst)[c] = (float) *isrc; 838848b8605Smrg isrc++; 839848b8605Smrg } 840848b8605Smrg 841848b8605Smrg dst += store->vector_stride; 842848b8605Smrg } 843848b8605Smrg 844848b8605Smrg dst += extra_stride; 845848b8605Smrg } 846848b8605Smrg break; 847848b8605Smrg } 848848b8605Smrg 849848b8605Smrg default: 850848b8605Smrg assert(!"Should not get here."); 851848b8605Smrg break; 852848b8605Smrg } 853848b8605Smrg } 854848b8605Smrg} 855848b8605Smrg 856b8e80941Smrg 857848b8605Smrg/** 858b8e80941Smrg * Return printable string for a given GLSL_TYPE_x 859848b8605Smrg */ 860b8e80941Smrgstatic const char * 861b8e80941Smrgglsl_type_name(enum glsl_base_type type) 862848b8605Smrg{ 863b8e80941Smrg switch (type) { 864b8e80941Smrg case GLSL_TYPE_UINT: 865b8e80941Smrg return "uint"; 866b8e80941Smrg case GLSL_TYPE_INT: 867b8e80941Smrg return "int"; 868b8e80941Smrg case GLSL_TYPE_FLOAT: 869b8e80941Smrg return "float"; 870b8e80941Smrg case GLSL_TYPE_DOUBLE: 871b8e80941Smrg return "double"; 872b8e80941Smrg case GLSL_TYPE_UINT64: 873b8e80941Smrg return "uint64"; 874b8e80941Smrg case GLSL_TYPE_INT64: 875b8e80941Smrg return "int64"; 876b8e80941Smrg case GLSL_TYPE_BOOL: 877b8e80941Smrg return "bool"; 878b8e80941Smrg case GLSL_TYPE_SAMPLER: 879b8e80941Smrg return "sampler"; 880b8e80941Smrg case GLSL_TYPE_IMAGE: 881b8e80941Smrg return "image"; 882b8e80941Smrg case GLSL_TYPE_ATOMIC_UINT: 883b8e80941Smrg return "atomic_uint"; 884b8e80941Smrg case GLSL_TYPE_STRUCT: 885b8e80941Smrg return "struct"; 886b8e80941Smrg case GLSL_TYPE_INTERFACE: 887b8e80941Smrg return "interface"; 888b8e80941Smrg case GLSL_TYPE_ARRAY: 889b8e80941Smrg return "array"; 890b8e80941Smrg case GLSL_TYPE_VOID: 891b8e80941Smrg return "void"; 892b8e80941Smrg case GLSL_TYPE_ERROR: 893b8e80941Smrg return "error"; 894b8e80941Smrg default: 895b8e80941Smrg return "other"; 896b8e80941Smrg } 897b8e80941Smrg} 898848b8605Smrg 899b8e80941Smrg 900b8e80941Smrgstatic struct gl_uniform_storage * 901b8e80941Smrgvalidate_uniform(GLint location, GLsizei count, const GLvoid *values, 902b8e80941Smrg unsigned *offset, struct gl_context *ctx, 903b8e80941Smrg struct gl_shader_program *shProg, 904b8e80941Smrg enum glsl_base_type basicType, unsigned src_components) 905b8e80941Smrg{ 906848b8605Smrg struct gl_uniform_storage *const uni = 907b8e80941Smrg validate_uniform_parameters(location, count, offset, 908b8e80941Smrg ctx, shProg, "glUniform"); 909848b8605Smrg if (uni == NULL) 910b8e80941Smrg return NULL; 911848b8605Smrg 912b8e80941Smrg if (uni->type->is_matrix()) { 913b8e80941Smrg /* Can't set matrix uniforms (like mat4) with glUniform */ 914b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 915b8e80941Smrg "glUniform%u(uniform \"%s\"@%d is matrix)", 916b8e80941Smrg src_components, uni->name, location); 917b8e80941Smrg return NULL; 918848b8605Smrg } 919848b8605Smrg 920b8e80941Smrg /* Verify that the types are compatible. */ 921b8e80941Smrg const unsigned components = uni->type->vector_elements; 922b8e80941Smrg 923b8e80941Smrg if (components != src_components) { 924b8e80941Smrg /* glUniformN() must match float/vecN type */ 925b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 926b8e80941Smrg "glUniform%u(\"%s\"@%u has %u components, not %u)", 927b8e80941Smrg src_components, uni->name, location, 928b8e80941Smrg components, src_components); 929b8e80941Smrg return NULL; 930848b8605Smrg } 931848b8605Smrg 932848b8605Smrg bool match; 933848b8605Smrg switch (uni->type->base_type) { 934848b8605Smrg case GLSL_TYPE_BOOL: 935b8e80941Smrg match = (basicType != GLSL_TYPE_DOUBLE); 936848b8605Smrg break; 937848b8605Smrg case GLSL_TYPE_SAMPLER: 938848b8605Smrg match = (basicType == GLSL_TYPE_INT); 939848b8605Smrg break; 940b8e80941Smrg case GLSL_TYPE_IMAGE: 941b8e80941Smrg match = (basicType == GLSL_TYPE_INT && _mesa_is_desktop_gl(ctx)); 942b8e80941Smrg break; 943848b8605Smrg default: 944848b8605Smrg match = (basicType == uni->type->base_type); 945848b8605Smrg break; 946848b8605Smrg } 947848b8605Smrg 948b8e80941Smrg if (!match) { 949b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 950b8e80941Smrg "glUniform%u(\"%s\"@%d is %s, not %s)", 951b8e80941Smrg src_components, uni->name, location, 952b8e80941Smrg glsl_type_name(uni->type->base_type), 953b8e80941Smrg glsl_type_name(basicType)); 954b8e80941Smrg return NULL; 955848b8605Smrg } 956848b8605Smrg 957b8e80941Smrg if (unlikely(ctx->_Shader->Flags & GLSL_UNIFORMS)) { 958848b8605Smrg log_uniform(values, basicType, components, 1, count, 959b8e80941Smrg false, shProg, location, uni); 960848b8605Smrg } 961848b8605Smrg 962848b8605Smrg /* Page 100 (page 116 of the PDF) of the OpenGL 3.0 spec says: 963848b8605Smrg * 964848b8605Smrg * "Setting a sampler's value to i selects texture image unit number 965848b8605Smrg * i. The values of i range from zero to the implementation- dependent 966848b8605Smrg * maximum supported number of texture image units." 967848b8605Smrg * 968848b8605Smrg * In addition, table 2.3, "Summary of GL errors," on page 17 (page 33 of 969848b8605Smrg * the PDF) says: 970848b8605Smrg * 971848b8605Smrg * "Error Description Offending command 972848b8605Smrg * ignored? 973848b8605Smrg * ... 974848b8605Smrg * INVALID_VALUE Numeric argument out of range Yes" 975848b8605Smrg * 976848b8605Smrg * Based on that, when an invalid sampler is specified, we generate a 977848b8605Smrg * GL_INVALID_VALUE error and ignore the command. 978848b8605Smrg */ 979848b8605Smrg if (uni->type->is_sampler()) { 980b8e80941Smrg for (int i = 0; i < count; i++) { 981b8e80941Smrg const unsigned texUnit = ((unsigned *) values)[i]; 982848b8605Smrg 983848b8605Smrg /* check that the sampler (tex unit index) is legal */ 984848b8605Smrg if (texUnit >= ctx->Const.MaxCombinedTextureImageUnits) { 985848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, 986848b8605Smrg "glUniform1i(invalid sampler/tex unit index for " 987b8e80941Smrg "uniform %d)", location); 988b8e80941Smrg return NULL; 989848b8605Smrg } 990848b8605Smrg } 991b8e80941Smrg /* We need to reset the validate flag on changes to samplers in case 992b8e80941Smrg * two different sampler types are set to the same texture unit. 993b8e80941Smrg */ 994b8e80941Smrg ctx->_Shader->Validated = GL_FALSE; 995848b8605Smrg } 996848b8605Smrg 997848b8605Smrg if (uni->type->is_image()) { 998b8e80941Smrg for (int i = 0; i < count; i++) { 999848b8605Smrg const int unit = ((GLint *) values)[i]; 1000848b8605Smrg 1001848b8605Smrg /* check that the image unit is legal */ 1002848b8605Smrg if (unit < 0 || unit >= (int)ctx->Const.MaxImageUnits) { 1003848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, 1004848b8605Smrg "glUniform1i(invalid image unit index for uniform %d)", 1005848b8605Smrg location); 1006b8e80941Smrg return NULL; 1007848b8605Smrg } 1008848b8605Smrg } 1009848b8605Smrg } 1010848b8605Smrg 1011b8e80941Smrg return uni; 1012b8e80941Smrg} 1013b8e80941Smrg 1014b8e80941Smrgvoid 1015b8e80941Smrg_mesa_flush_vertices_for_uniforms(struct gl_context *ctx, 1016b8e80941Smrg const struct gl_uniform_storage *uni) 1017b8e80941Smrg{ 1018b8e80941Smrg /* Opaque uniforms have no storage unless they are bindless */ 1019b8e80941Smrg if (!uni->is_bindless && uni->type->contains_opaque()) { 1020b8e80941Smrg FLUSH_VERTICES(ctx, 0); 1021b8e80941Smrg return; 1022b8e80941Smrg } 1023b8e80941Smrg 1024b8e80941Smrg uint64_t new_driver_state = 0; 1025b8e80941Smrg unsigned mask = uni->active_shader_mask; 1026b8e80941Smrg 1027b8e80941Smrg while (mask) { 1028b8e80941Smrg unsigned index = u_bit_scan(&mask); 1029b8e80941Smrg 1030b8e80941Smrg assert(index < MESA_SHADER_STAGES); 1031b8e80941Smrg new_driver_state |= ctx->DriverFlags.NewShaderConstants[index]; 1032b8e80941Smrg } 1033b8e80941Smrg 1034b8e80941Smrg FLUSH_VERTICES(ctx, new_driver_state ? 0 : _NEW_PROGRAM_CONSTANTS); 1035b8e80941Smrg ctx->NewDriverState |= new_driver_state; 1036b8e80941Smrg} 1037b8e80941Smrg 1038b8e80941Smrgstatic void 1039b8e80941Smrgcopy_uniforms_to_storage(gl_constant_value *storage, 1040b8e80941Smrg struct gl_uniform_storage *uni, 1041b8e80941Smrg struct gl_context *ctx, GLsizei count, 1042b8e80941Smrg const GLvoid *values, const int size_mul, 1043b8e80941Smrg const unsigned offset, const unsigned components, 1044b8e80941Smrg enum glsl_base_type basicType) 1045b8e80941Smrg{ 1046b8e80941Smrg if (!uni->type->is_boolean() && !uni->is_bindless) { 1047b8e80941Smrg memcpy(storage, values, 1048b8e80941Smrg sizeof(storage[0]) * components * count * size_mul); 1049b8e80941Smrg } else if (uni->is_bindless) { 1050b8e80941Smrg const union gl_constant_value *src = 1051b8e80941Smrg (const union gl_constant_value *) values; 1052b8e80941Smrg GLuint64 *dst = (GLuint64 *)&storage->i; 1053b8e80941Smrg const unsigned elems = components * count; 1054b8e80941Smrg 1055b8e80941Smrg for (unsigned i = 0; i < elems; i++) { 1056b8e80941Smrg dst[i] = src[i].i; 1057b8e80941Smrg } 1058b8e80941Smrg } else { 1059b8e80941Smrg const union gl_constant_value *src = 1060b8e80941Smrg (const union gl_constant_value *) values; 1061b8e80941Smrg union gl_constant_value *dst = storage; 1062b8e80941Smrg const unsigned elems = components * count; 1063b8e80941Smrg 1064b8e80941Smrg for (unsigned i = 0; i < elems; i++) { 1065b8e80941Smrg if (basicType == GLSL_TYPE_FLOAT) { 1066b8e80941Smrg dst[i].i = src[i].f != 0.0f ? ctx->Const.UniformBooleanTrue : 0; 1067b8e80941Smrg } else { 1068b8e80941Smrg dst[i].i = src[i].i != 0 ? ctx->Const.UniformBooleanTrue : 0; 1069b8e80941Smrg } 1070b8e80941Smrg } 1071b8e80941Smrg } 1072b8e80941Smrg} 1073b8e80941Smrg 1074b8e80941Smrg 1075b8e80941Smrg/** 1076b8e80941Smrg * Called via glUniform*() functions. 1077b8e80941Smrg */ 1078b8e80941Smrgextern "C" void 1079b8e80941Smrg_mesa_uniform(GLint location, GLsizei count, const GLvoid *values, 1080b8e80941Smrg struct gl_context *ctx, struct gl_shader_program *shProg, 1081b8e80941Smrg enum glsl_base_type basicType, unsigned src_components) 1082b8e80941Smrg{ 1083b8e80941Smrg unsigned offset; 1084b8e80941Smrg int size_mul = glsl_base_type_is_64bit(basicType) ? 2 : 1; 1085b8e80941Smrg 1086b8e80941Smrg struct gl_uniform_storage *uni; 1087b8e80941Smrg if (_mesa_is_no_error_enabled(ctx)) { 1088b8e80941Smrg /* From Seciton 7.6 (UNIFORM VARIABLES) of the OpenGL 4.5 spec: 1089b8e80941Smrg * 1090b8e80941Smrg * "If the value of location is -1, the Uniform* commands will 1091b8e80941Smrg * silently ignore the data passed in, and the current uniform values 1092b8e80941Smrg * will not be changed. 1093b8e80941Smrg */ 1094b8e80941Smrg if (location == -1) 1095b8e80941Smrg return; 1096b8e80941Smrg 1097b8e80941Smrg uni = shProg->UniformRemapTable[location]; 1098b8e80941Smrg 1099b8e80941Smrg /* The array index specified by the uniform location is just the 1100b8e80941Smrg * uniform location minus the base location of of the uniform. 1101b8e80941Smrg */ 1102b8e80941Smrg assert(uni->array_elements > 0 || location == (int)uni->remap_location); 1103b8e80941Smrg offset = location - uni->remap_location; 1104b8e80941Smrg } else { 1105b8e80941Smrg uni = validate_uniform(location, count, values, &offset, ctx, shProg, 1106b8e80941Smrg basicType, src_components); 1107b8e80941Smrg if (!uni) 1108b8e80941Smrg return; 1109b8e80941Smrg } 1110b8e80941Smrg 1111b8e80941Smrg const unsigned components = uni->type->vector_elements; 1112b8e80941Smrg 1113848b8605Smrg /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says: 1114848b8605Smrg * 1115848b8605Smrg * "When loading N elements starting at an arbitrary position k in a 1116848b8605Smrg * uniform declared as an array, elements k through k + N - 1 in the 1117848b8605Smrg * array will be replaced with the new values. Values for any array 1118848b8605Smrg * element that exceeds the highest array element index used, as 1119848b8605Smrg * reported by GetActiveUniform, will be ignored by the GL." 1120848b8605Smrg * 1121848b8605Smrg * Clamp 'count' to a valid value. Note that for non-arrays a count > 1 1122848b8605Smrg * will have already generated an error. 1123848b8605Smrg */ 1124848b8605Smrg if (uni->array_elements != 0) { 1125848b8605Smrg count = MIN2(count, (int) (uni->array_elements - offset)); 1126848b8605Smrg } 1127848b8605Smrg 1128b8e80941Smrg /* We check samplers for changes and flush if needed in the sampler 1129b8e80941Smrg * handling code further down, so just skip them here. 1130b8e80941Smrg */ 1131b8e80941Smrg if (!uni->type->is_sampler()) { 1132b8e80941Smrg _mesa_flush_vertices_for_uniforms(ctx, uni); 1133b8e80941Smrg } 1134848b8605Smrg 1135848b8605Smrg /* Store the data in the "actual type" backing storage for the uniform. 1136848b8605Smrg */ 1137b8e80941Smrg gl_constant_value *storage; 1138b8e80941Smrg if (ctx->Const.PackedDriverUniformStorage && 1139b8e80941Smrg (uni->is_bindless || !uni->type->contains_opaque())) { 1140b8e80941Smrg for (unsigned s = 0; s < uni->num_driver_storage; s++) { 1141b8e80941Smrg storage = (gl_constant_value *) 1142b8e80941Smrg uni->driver_storage[s].data + (size_mul * offset * components); 1143b8e80941Smrg 1144b8e80941Smrg copy_uniforms_to_storage(storage, uni, ctx, count, values, size_mul, 1145b8e80941Smrg offset, components, basicType); 1146b8e80941Smrg } 1147848b8605Smrg } else { 1148b8e80941Smrg storage = &uni->storage[size_mul * components * offset]; 1149b8e80941Smrg copy_uniforms_to_storage(storage, uni, ctx, count, values, size_mul, 1150b8e80941Smrg offset, components, basicType); 1151848b8605Smrg 1152b8e80941Smrg _mesa_propagate_uniforms_to_driver_storage(uni, offset, count); 1153848b8605Smrg } 1154848b8605Smrg 1155848b8605Smrg /* If the uniform is a sampler, do the extra magic necessary to propagate 1156848b8605Smrg * the changes through. 1157848b8605Smrg */ 1158848b8605Smrg if (uni->type->is_sampler()) { 1159848b8605Smrg bool flushed = false; 1160848b8605Smrg 1161b8e80941Smrg shProg->SamplersValidated = GL_TRUE; 1162848b8605Smrg 1163b8e80941Smrg for (int i = 0; i < MESA_SHADER_STAGES; i++) { 1164b8e80941Smrg struct gl_linked_shader *const sh = shProg->_LinkedShaders[i]; 1165848b8605Smrg 1166b8e80941Smrg /* If the shader stage doesn't use the sampler uniform, skip this. */ 1167b8e80941Smrg if (!uni->opaque[i].active) 1168b8e80941Smrg continue; 1169848b8605Smrg 1170b8e80941Smrg bool changed = false; 1171b8e80941Smrg for (int j = 0; j < count; j++) { 1172b8e80941Smrg unsigned unit = uni->opaque[i].index + offset + j; 1173b8e80941Smrg unsigned value = ((unsigned *)values)[j]; 1174b8e80941Smrg 1175b8e80941Smrg if (uni->is_bindless) { 1176b8e80941Smrg struct gl_bindless_sampler *sampler = 1177b8e80941Smrg &sh->Program->sh.BindlessSamplers[unit]; 1178b8e80941Smrg 1179b8e80941Smrg /* Mark this bindless sampler as bound to a texture unit. 1180b8e80941Smrg */ 1181b8e80941Smrg if (sampler->unit != value || !sampler->bound) { 1182b8e80941Smrg sampler->unit = value; 1183b8e80941Smrg changed = true; 1184b8e80941Smrg } 1185b8e80941Smrg sampler->bound = true; 1186b8e80941Smrg sh->Program->sh.HasBoundBindlessSampler = true; 1187b8e80941Smrg } else { 1188b8e80941Smrg if (sh->Program->SamplerUnits[unit] != value) { 1189b8e80941Smrg sh->Program->SamplerUnits[unit] = value; 1190b8e80941Smrg changed = true; 1191b8e80941Smrg } 1192b8e80941Smrg } 1193b8e80941Smrg } 1194848b8605Smrg 1195b8e80941Smrg if (changed) { 1196b8e80941Smrg if (!flushed) { 1197b8e80941Smrg FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT | _NEW_PROGRAM); 1198b8e80941Smrg flushed = true; 1199b8e80941Smrg } 1200848b8605Smrg 1201b8e80941Smrg struct gl_program *const prog = sh->Program; 1202b8e80941Smrg _mesa_update_shader_textures_used(shProg, prog); 1203848b8605Smrg if (ctx->Driver.SamplerUniformChange) 1204b8e80941Smrg ctx->Driver.SamplerUniformChange(ctx, prog->Target, prog); 1205b8e80941Smrg } 1206848b8605Smrg } 1207848b8605Smrg } 1208848b8605Smrg 1209848b8605Smrg /* If the uniform is an image, update the mapping from image 1210848b8605Smrg * uniforms to image units present in the shader data structure. 1211848b8605Smrg */ 1212848b8605Smrg if (uni->type->is_image()) { 1213b8e80941Smrg for (int i = 0; i < MESA_SHADER_STAGES; i++) { 1214b8e80941Smrg struct gl_linked_shader *sh = shProg->_LinkedShaders[i]; 1215848b8605Smrg 1216b8e80941Smrg /* If the shader stage doesn't use the image uniform, skip this. */ 1217b8e80941Smrg if (!uni->opaque[i].active) 1218b8e80941Smrg continue; 1219848b8605Smrg 1220b8e80941Smrg for (int j = 0; j < count; j++) { 1221b8e80941Smrg unsigned unit = uni->opaque[i].index + offset + j; 1222b8e80941Smrg unsigned value = ((unsigned *)values)[j]; 1223b8e80941Smrg 1224b8e80941Smrg if (uni->is_bindless) { 1225b8e80941Smrg struct gl_bindless_image *image = 1226b8e80941Smrg &sh->Program->sh.BindlessImages[unit]; 1227b8e80941Smrg 1228b8e80941Smrg /* Mark this bindless image as bound to an image unit. 1229b8e80941Smrg */ 1230b8e80941Smrg image->unit = value; 1231b8e80941Smrg image->bound = true; 1232b8e80941Smrg sh->Program->sh.HasBoundBindlessImage = true; 1233b8e80941Smrg } else { 1234b8e80941Smrg sh->Program->sh.ImageUnits[unit] = value; 1235b8e80941Smrg } 1236848b8605Smrg } 1237848b8605Smrg } 1238848b8605Smrg 1239848b8605Smrg ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits; 1240848b8605Smrg } 1241848b8605Smrg} 1242848b8605Smrg 1243b8e80941Smrg 1244b8e80941Smrgstatic void 1245b8e80941Smrgcopy_uniform_matrix_to_storage(gl_constant_value *storage, 1246b8e80941Smrg GLsizei count, const void *values, 1247b8e80941Smrg const unsigned size_mul, const unsigned offset, 1248b8e80941Smrg const unsigned components, 1249b8e80941Smrg const unsigned vectors, bool transpose, 1250b8e80941Smrg unsigned cols, unsigned rows, 1251b8e80941Smrg enum glsl_base_type basicType) 1252b8e80941Smrg{ 1253b8e80941Smrg const unsigned elements = components * vectors; 1254b8e80941Smrg 1255b8e80941Smrg if (!transpose) { 1256b8e80941Smrg memcpy(storage, values, 1257b8e80941Smrg sizeof(storage[0]) * elements * count * size_mul); 1258b8e80941Smrg } else if (basicType == GLSL_TYPE_FLOAT) { 1259b8e80941Smrg /* Copy and transpose the matrix. 1260b8e80941Smrg */ 1261b8e80941Smrg const float *src = (const float *)values; 1262b8e80941Smrg float *dst = &storage->f; 1263b8e80941Smrg 1264b8e80941Smrg for (int i = 0; i < count; i++) { 1265b8e80941Smrg for (unsigned r = 0; r < rows; r++) { 1266b8e80941Smrg for (unsigned c = 0; c < cols; c++) { 1267b8e80941Smrg dst[(c * components) + r] = src[c + (r * vectors)]; 1268b8e80941Smrg } 1269b8e80941Smrg } 1270b8e80941Smrg 1271b8e80941Smrg dst += elements; 1272b8e80941Smrg src += elements; 1273b8e80941Smrg } 1274b8e80941Smrg } else { 1275b8e80941Smrg assert(basicType == GLSL_TYPE_DOUBLE); 1276b8e80941Smrg const double *src = (const double *)values; 1277b8e80941Smrg double *dst = (double *)&storage->f; 1278b8e80941Smrg 1279b8e80941Smrg for (int i = 0; i < count; i++) { 1280b8e80941Smrg for (unsigned r = 0; r < rows; r++) { 1281b8e80941Smrg for (unsigned c = 0; c < cols; c++) { 1282b8e80941Smrg dst[(c * components) + r] = src[c + (r * vectors)]; 1283b8e80941Smrg } 1284b8e80941Smrg } 1285b8e80941Smrg 1286b8e80941Smrg dst += elements; 1287b8e80941Smrg src += elements; 1288b8e80941Smrg } 1289b8e80941Smrg } 1290b8e80941Smrg} 1291b8e80941Smrg 1292b8e80941Smrg 1293848b8605Smrg/** 1294848b8605Smrg * Called by glUniformMatrix*() functions. 1295848b8605Smrg * Note: cols=2, rows=4 ==> array[2] of vec4 1296848b8605Smrg */ 1297848b8605Smrgextern "C" void 1298b8e80941Smrg_mesa_uniform_matrix(GLint location, GLsizei count, 1299b8e80941Smrg GLboolean transpose, const void *values, 1300b8e80941Smrg struct gl_context *ctx, struct gl_shader_program *shProg, 1301b8e80941Smrg GLuint cols, GLuint rows, enum glsl_base_type basicType) 1302848b8605Smrg{ 1303848b8605Smrg unsigned offset; 1304848b8605Smrg struct gl_uniform_storage *const uni = 1305b8e80941Smrg validate_uniform_parameters(location, count, &offset, 1306b8e80941Smrg ctx, shProg, "glUniformMatrix"); 1307848b8605Smrg if (uni == NULL) 1308848b8605Smrg return; 1309848b8605Smrg 1310848b8605Smrg if (!uni->type->is_matrix()) { 1311848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 1312848b8605Smrg "glUniformMatrix(non-matrix uniform)"); 1313848b8605Smrg return; 1314848b8605Smrg } 1315848b8605Smrg 1316b8e80941Smrg assert(basicType == GLSL_TYPE_FLOAT || basicType == GLSL_TYPE_DOUBLE); 1317b8e80941Smrg const unsigned size_mul = basicType == GLSL_TYPE_DOUBLE ? 2 : 1; 1318b8e80941Smrg 1319848b8605Smrg assert(!uni->type->is_sampler()); 1320b8e80941Smrg const unsigned vectors = uni->type->matrix_columns; 1321b8e80941Smrg const unsigned components = uni->type->vector_elements; 1322848b8605Smrg 1323848b8605Smrg /* Verify that the types are compatible. This is greatly simplified for 1324848b8605Smrg * matrices because they can only have a float base type. 1325848b8605Smrg */ 1326848b8605Smrg if (vectors != cols || components != rows) { 1327848b8605Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 1328848b8605Smrg "glUniformMatrix(matrix size mismatch)"); 1329848b8605Smrg return; 1330848b8605Smrg } 1331848b8605Smrg 1332848b8605Smrg /* GL_INVALID_VALUE is generated if `transpose' is not GL_FALSE. 1333b8e80941Smrg * http://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml 1334b8e80941Smrg */ 1335b8e80941Smrg if (transpose) { 1336b8e80941Smrg if (ctx->API == API_OPENGLES2 && ctx->Version < 30) { 1337848b8605Smrg _mesa_error(ctx, GL_INVALID_VALUE, 1338848b8605Smrg "glUniformMatrix(matrix transpose is not GL_FALSE)"); 1339848b8605Smrg return; 1340848b8605Smrg } 1341848b8605Smrg } 1342848b8605Smrg 1343b8e80941Smrg /* Section 2.11.7 (Uniform Variables) of the OpenGL 4.2 Core Profile spec 1344b8e80941Smrg * says: 1345b8e80941Smrg * 1346b8e80941Smrg * "If any of the following conditions occur, an INVALID_OPERATION 1347b8e80941Smrg * error is generated by the Uniform* commands, and no uniform values 1348b8e80941Smrg * are changed: 1349b8e80941Smrg * 1350b8e80941Smrg * ... 1351b8e80941Smrg * 1352b8e80941Smrg * - if the uniform declared in the shader is not of type boolean and 1353b8e80941Smrg * the type indicated in the name of the Uniform* command used does 1354b8e80941Smrg * not match the type of the uniform" 1355b8e80941Smrg * 1356b8e80941Smrg * There are no Boolean matrix types, so we do not need to allow 1357b8e80941Smrg * GLSL_TYPE_BOOL here (as _mesa_uniform does). 1358b8e80941Smrg */ 1359b8e80941Smrg if (uni->type->base_type != basicType) { 1360b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 1361b8e80941Smrg "glUniformMatrix%ux%u(\"%s\"@%d is %s, not %s)", 1362b8e80941Smrg cols, rows, uni->name, location, 1363b8e80941Smrg glsl_type_name(uni->type->base_type), 1364b8e80941Smrg glsl_type_name(basicType)); 1365b8e80941Smrg return; 1366b8e80941Smrg } 1367b8e80941Smrg 1368b8e80941Smrg if (unlikely(ctx->_Shader->Flags & GLSL_UNIFORMS)) { 1369b8e80941Smrg log_uniform(values, uni->type->base_type, components, vectors, count, 1370848b8605Smrg bool(transpose), shProg, location, uni); 1371848b8605Smrg } 1372848b8605Smrg 1373848b8605Smrg /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says: 1374848b8605Smrg * 1375848b8605Smrg * "When loading N elements starting at an arbitrary position k in a 1376848b8605Smrg * uniform declared as an array, elements k through k + N - 1 in the 1377848b8605Smrg * array will be replaced with the new values. Values for any array 1378848b8605Smrg * element that exceeds the highest array element index used, as 1379848b8605Smrg * reported by GetActiveUniform, will be ignored by the GL." 1380848b8605Smrg * 1381848b8605Smrg * Clamp 'count' to a valid value. Note that for non-arrays a count > 1 1382848b8605Smrg * will have already generated an error. 1383848b8605Smrg */ 1384848b8605Smrg if (uni->array_elements != 0) { 1385848b8605Smrg count = MIN2(count, (int) (uni->array_elements - offset)); 1386848b8605Smrg } 1387848b8605Smrg 1388b8e80941Smrg _mesa_flush_vertices_for_uniforms(ctx, uni); 1389848b8605Smrg 1390848b8605Smrg /* Store the data in the "actual type" backing storage for the uniform. 1391848b8605Smrg */ 1392b8e80941Smrg gl_constant_value *storage; 1393b8e80941Smrg const unsigned elements = components * vectors; 1394b8e80941Smrg if (ctx->Const.PackedDriverUniformStorage) { 1395b8e80941Smrg for (unsigned s = 0; s < uni->num_driver_storage; s++) { 1396b8e80941Smrg storage = (gl_constant_value *) 1397b8e80941Smrg uni->driver_storage[s].data + (size_mul * offset * elements); 1398b8e80941Smrg 1399b8e80941Smrg copy_uniform_matrix_to_storage(storage, count, values, size_mul, 1400b8e80941Smrg offset, components, vectors, 1401b8e80941Smrg transpose, cols, rows, basicType); 1402b8e80941Smrg } 1403848b8605Smrg } else { 1404b8e80941Smrg storage = &uni->storage[size_mul * elements * offset]; 1405b8e80941Smrg copy_uniform_matrix_to_storage(storage, count, values, size_mul, offset, 1406b8e80941Smrg components, vectors, transpose, cols, 1407b8e80941Smrg rows, basicType); 1408848b8605Smrg 1409b8e80941Smrg _mesa_propagate_uniforms_to_driver_storage(uni, offset, count); 1410848b8605Smrg } 1411b8e80941Smrg} 1412b8e80941Smrg 1413b8e80941Smrgstatic void 1414b8e80941Smrgupdate_bound_bindless_sampler_flag(struct gl_program *prog) 1415b8e80941Smrg{ 1416b8e80941Smrg unsigned i; 1417b8e80941Smrg 1418b8e80941Smrg if (likely(!prog->sh.HasBoundBindlessSampler)) 1419b8e80941Smrg return; 1420848b8605Smrg 1421b8e80941Smrg for (i = 0; i < prog->sh.NumBindlessSamplers; i++) { 1422b8e80941Smrg struct gl_bindless_sampler *sampler = &prog->sh.BindlessSamplers[i]; 1423848b8605Smrg 1424b8e80941Smrg if (sampler->bound) 1425b8e80941Smrg return; 1426b8e80941Smrg } 1427b8e80941Smrg prog->sh.HasBoundBindlessSampler = false; 1428848b8605Smrg} 1429848b8605Smrg 1430b8e80941Smrgstatic void 1431b8e80941Smrgupdate_bound_bindless_image_flag(struct gl_program *prog) 1432b8e80941Smrg{ 1433b8e80941Smrg unsigned i; 1434b8e80941Smrg 1435b8e80941Smrg if (likely(!prog->sh.HasBoundBindlessImage)) 1436b8e80941Smrg return; 1437b8e80941Smrg 1438b8e80941Smrg for (i = 0; i < prog->sh.NumBindlessImages; i++) { 1439b8e80941Smrg struct gl_bindless_image *image = &prog->sh.BindlessImages[i]; 1440b8e80941Smrg 1441b8e80941Smrg if (image->bound) 1442b8e80941Smrg return; 1443b8e80941Smrg } 1444b8e80941Smrg prog->sh.HasBoundBindlessImage = false; 1445b8e80941Smrg} 1446848b8605Smrg 1447848b8605Smrg/** 1448b8e80941Smrg * Called via glUniformHandleui64*ARB() functions. 1449848b8605Smrg */ 1450b8e80941Smrgextern "C" void 1451b8e80941Smrg_mesa_uniform_handle(GLint location, GLsizei count, const GLvoid *values, 1452b8e80941Smrg struct gl_context *ctx, struct gl_shader_program *shProg) 1453848b8605Smrg{ 1454b8e80941Smrg unsigned offset; 1455b8e80941Smrg struct gl_uniform_storage *uni; 1456848b8605Smrg 1457b8e80941Smrg if (_mesa_is_no_error_enabled(ctx)) { 1458b8e80941Smrg /* From Section 7.6 (UNIFORM VARIABLES) of the OpenGL 4.5 spec: 1459b8e80941Smrg * 1460b8e80941Smrg * "If the value of location is -1, the Uniform* commands will 1461b8e80941Smrg * silently ignore the data passed in, and the current uniform values 1462b8e80941Smrg * will not be changed. 1463b8e80941Smrg */ 1464b8e80941Smrg if (location == -1) 1465b8e80941Smrg return; 1466848b8605Smrg 1467b8e80941Smrg uni = shProg->UniformRemapTable[location]; 1468b8e80941Smrg 1469b8e80941Smrg /* The array index specified by the uniform location is just the 1470b8e80941Smrg * uniform location minus the base location of of the uniform. 1471b8e80941Smrg */ 1472b8e80941Smrg assert(uni->array_elements > 0 || location == (int)uni->remap_location); 1473b8e80941Smrg offset = location - uni->remap_location; 1474848b8605Smrg } else { 1475b8e80941Smrg uni = validate_uniform_parameters(location, count, &offset, 1476b8e80941Smrg ctx, shProg, "glUniformHandleui64*ARB"); 1477b8e80941Smrg if (!uni) 1478b8e80941Smrg return; 1479b8e80941Smrg 1480b8e80941Smrg if (!uni->is_bindless) { 1481b8e80941Smrg /* From section "Errors" of the ARB_bindless_texture spec: 1482b8e80941Smrg * 1483b8e80941Smrg * "The error INVALID_OPERATION is generated by 1484b8e80941Smrg * UniformHandleui64{v}ARB if the sampler or image uniform being 1485b8e80941Smrg * updated has the "bound_sampler" or "bound_image" layout qualifier." 1486b8e80941Smrg * 1487b8e80941Smrg * From section 4.4.6 of the ARB_bindless_texture spec: 1488b8e80941Smrg * 1489b8e80941Smrg * "In the absence of these qualifiers, sampler and image uniforms are 1490b8e80941Smrg * considered "bound". Additionally, if GL_ARB_bindless_texture is 1491b8e80941Smrg * not enabled, these uniforms are considered "bound"." 1492b8e80941Smrg */ 1493b8e80941Smrg _mesa_error(ctx, GL_INVALID_OPERATION, 1494b8e80941Smrg "glUniformHandleui64*ARB(non-bindless sampler/image uniform)"); 1495b8e80941Smrg return; 1496b8e80941Smrg } 1497848b8605Smrg } 1498848b8605Smrg 1499b8e80941Smrg const unsigned components = uni->type->vector_elements; 1500b8e80941Smrg const int size_mul = 2; 1501848b8605Smrg 1502b8e80941Smrg if (unlikely(ctx->_Shader->Flags & GLSL_UNIFORMS)) { 1503b8e80941Smrg log_uniform(values, GLSL_TYPE_UINT64, components, 1, count, 1504b8e80941Smrg false, shProg, location, uni); 1505b8e80941Smrg } 1506848b8605Smrg 1507b8e80941Smrg /* Page 82 (page 96 of the PDF) of the OpenGL 2.1 spec says: 1508b8e80941Smrg * 1509b8e80941Smrg * "When loading N elements starting at an arbitrary position k in a 1510b8e80941Smrg * uniform declared as an array, elements k through k + N - 1 in the 1511b8e80941Smrg * array will be replaced with the new values. Values for any array 1512b8e80941Smrg * element that exceeds the highest array element index used, as 1513b8e80941Smrg * reported by GetActiveUniform, will be ignored by the GL." 1514b8e80941Smrg * 1515b8e80941Smrg * Clamp 'count' to a valid value. Note that for non-arrays a count > 1 1516b8e80941Smrg * will have already generated an error. 1517848b8605Smrg */ 1518b8e80941Smrg if (uni->array_elements != 0) { 1519b8e80941Smrg count = MIN2(count, (int) (uni->array_elements - offset)); 1520b8e80941Smrg } 1521848b8605Smrg 1522b8e80941Smrg _mesa_flush_vertices_for_uniforms(ctx, uni); 1523848b8605Smrg 1524b8e80941Smrg /* Store the data in the "actual type" backing storage for the uniform. 1525848b8605Smrg */ 1526b8e80941Smrg gl_constant_value *storage; 1527b8e80941Smrg if (ctx->Const.PackedDriverUniformStorage) { 1528b8e80941Smrg for (unsigned s = 0; s < uni->num_driver_storage; s++) { 1529b8e80941Smrg storage = (gl_constant_value *) 1530b8e80941Smrg uni->driver_storage[s].data + (size_mul * offset * components); 1531b8e80941Smrg memcpy(storage, values, 1532b8e80941Smrg sizeof(uni->storage[0]) * components * count * size_mul); 1533b8e80941Smrg } 1534b8e80941Smrg } else { 1535b8e80941Smrg memcpy(&uni->storage[size_mul * components * offset], values, 1536b8e80941Smrg sizeof(uni->storage[0]) * components * count * size_mul); 1537b8e80941Smrg 1538b8e80941Smrg _mesa_propagate_uniforms_to_driver_storage(uni, offset, count); 1539848b8605Smrg } 1540848b8605Smrg 1541b8e80941Smrg if (uni->type->is_sampler()) { 1542b8e80941Smrg /* Mark this bindless sampler as not bound to a texture unit because 1543b8e80941Smrg * it refers to a texture handle. 1544b8e80941Smrg */ 1545b8e80941Smrg for (int i = 0; i < MESA_SHADER_STAGES; i++) { 1546b8e80941Smrg struct gl_linked_shader *const sh = shProg->_LinkedShaders[i]; 1547848b8605Smrg 1548b8e80941Smrg /* If the shader stage doesn't use the sampler uniform, skip this. */ 1549b8e80941Smrg if (!uni->opaque[i].active) 1550b8e80941Smrg continue; 1551848b8605Smrg 1552b8e80941Smrg for (int j = 0; j < count; j++) { 1553b8e80941Smrg unsigned unit = uni->opaque[i].index + offset + j; 1554b8e80941Smrg struct gl_bindless_sampler *sampler = 1555b8e80941Smrg &sh->Program->sh.BindlessSamplers[unit]; 1556848b8605Smrg 1557b8e80941Smrg sampler->bound = false; 1558b8e80941Smrg } 1559848b8605Smrg 1560b8e80941Smrg update_bound_bindless_sampler_flag(sh->Program); 1561b8e80941Smrg } 1562b8e80941Smrg } 1563848b8605Smrg 1564b8e80941Smrg if (uni->type->is_image()) { 1565b8e80941Smrg /* Mark this bindless image as not bound to an image unit because it 1566b8e80941Smrg * refers to a texture handle. 1567b8e80941Smrg */ 1568b8e80941Smrg for (int i = 0; i < MESA_SHADER_STAGES; i++) { 1569b8e80941Smrg struct gl_linked_shader *sh = shProg->_LinkedShaders[i]; 1570b8e80941Smrg 1571b8e80941Smrg /* If the shader stage doesn't use the sampler uniform, skip this. */ 1572b8e80941Smrg if (!uni->opaque[i].active) 1573b8e80941Smrg continue; 1574b8e80941Smrg 1575b8e80941Smrg for (int j = 0; j < count; j++) { 1576b8e80941Smrg unsigned unit = uni->opaque[i].index + offset + j; 1577b8e80941Smrg struct gl_bindless_image *image = 1578b8e80941Smrg &sh->Program->sh.BindlessImages[unit]; 1579b8e80941Smrg 1580b8e80941Smrg image->bound = false; 1581b8e80941Smrg } 1582b8e80941Smrg 1583b8e80941Smrg update_bound_bindless_image_flag(sh->Program); 1584848b8605Smrg } 1585848b8605Smrg } 1586b8e80941Smrg} 1587848b8605Smrg 1588b8e80941Smrgextern "C" bool 1589b8e80941Smrg_mesa_sampler_uniforms_are_valid(const struct gl_shader_program *shProg, 1590b8e80941Smrg char *errMsg, size_t errMsgLength) 1591b8e80941Smrg{ 1592b8e80941Smrg /* Shader does not have samplers. */ 1593b8e80941Smrg if (shProg->data->NumUniformStorage == 0) 1594b8e80941Smrg return true; 1595b8e80941Smrg 1596b8e80941Smrg if (!shProg->SamplersValidated) { 1597b8e80941Smrg _mesa_snprintf(errMsg, errMsgLength, 1598b8e80941Smrg "active samplers with a different type " 1599b8e80941Smrg "refer to the same texture image unit"); 1600b8e80941Smrg return false; 1601b8e80941Smrg } 1602848b8605Smrg return true; 1603848b8605Smrg} 1604848b8605Smrg 1605848b8605Smrgextern "C" bool 1606848b8605Smrg_mesa_sampler_uniforms_pipeline_are_valid(struct gl_pipeline_object *pipeline) 1607848b8605Smrg{ 1608848b8605Smrg /* Section 2.11.11 (Shader Execution), subheading "Validation," of the 1609848b8605Smrg * OpenGL 4.1 spec says: 1610848b8605Smrg * 1611848b8605Smrg * "[INVALID_OPERATION] is generated by any command that transfers 1612848b8605Smrg * vertices to the GL if: 1613848b8605Smrg * 1614848b8605Smrg * ... 1615848b8605Smrg * 1616848b8605Smrg * - Any two active samplers in the current program object are of 1617848b8605Smrg * different types, but refer to the same texture image unit. 1618848b8605Smrg * 1619848b8605Smrg * - The number of active samplers in the program exceeds the 1620848b8605Smrg * maximum number of texture image units allowed." 1621848b8605Smrg */ 1622b8e80941Smrg 1623b8e80941Smrg GLbitfield mask; 1624b8e80941Smrg GLbitfield TexturesUsed[MAX_COMBINED_TEXTURE_IMAGE_UNITS]; 1625848b8605Smrg unsigned active_samplers = 0; 1626b8e80941Smrg const struct gl_program **prog = 1627b8e80941Smrg (const struct gl_program **) pipeline->CurrentProgram; 1628b8e80941Smrg 1629848b8605Smrg 1630b8e80941Smrg memset(TexturesUsed, 0, sizeof(TexturesUsed)); 1631848b8605Smrg 1632848b8605Smrg for (unsigned idx = 0; idx < ARRAY_SIZE(pipeline->CurrentProgram); idx++) { 1633b8e80941Smrg if (!prog[idx]) 1634848b8605Smrg continue; 1635848b8605Smrg 1636b8e80941Smrg mask = prog[idx]->SamplersUsed; 1637b8e80941Smrg while (mask) { 1638b8e80941Smrg const int s = u_bit_scan(&mask); 1639b8e80941Smrg GLuint unit = prog[idx]->SamplerUnits[s]; 1640b8e80941Smrg GLuint tgt = prog[idx]->sh.SamplerTargets[s]; 1641848b8605Smrg 1642b8e80941Smrg /* FIXME: Samplers are initialized to 0 and Mesa doesn't do a 1643b8e80941Smrg * great job of eliminating unused uniforms currently so for now 1644b8e80941Smrg * don't throw an error if two sampler types both point to 0. 1645b8e80941Smrg */ 1646b8e80941Smrg if (unit == 0) 1647848b8605Smrg continue; 1648848b8605Smrg 1649b8e80941Smrg if (TexturesUsed[unit] & ~(1 << tgt)) { 1650b8e80941Smrg pipeline->InfoLog = 1651b8e80941Smrg ralloc_asprintf(pipeline, 1652b8e80941Smrg "Program %d: " 1653b8e80941Smrg "Texture unit %d is accessed with 2 different types", 1654b8e80941Smrg prog[idx]->Id, unit); 1655b8e80941Smrg return false; 1656848b8605Smrg } 1657b8e80941Smrg 1658b8e80941Smrg TexturesUsed[unit] |= (1 << tgt); 1659848b8605Smrg } 1660b8e80941Smrg 1661b8e80941Smrg active_samplers += prog[idx]->info.num_textures; 1662848b8605Smrg } 1663848b8605Smrg 1664848b8605Smrg if (active_samplers > MAX_COMBINED_TEXTURE_IMAGE_UNITS) { 1665848b8605Smrg pipeline->InfoLog = 1666848b8605Smrg ralloc_asprintf(pipeline, 1667848b8605Smrg "the number of active samplers %d exceed the " 1668848b8605Smrg "maximum %d", 1669848b8605Smrg active_samplers, MAX_COMBINED_TEXTURE_IMAGE_UNITS); 1670848b8605Smrg return false; 1671848b8605Smrg } 1672848b8605Smrg 1673848b8605Smrg return true; 1674848b8605Smrg} 1675