uniforms.c revision 637a7eb9e981d7dbe3bdb0c39712a9183ea19e9c
1/* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 2004-2008 Brian Paul All Rights Reserved. 5 * Copyright (C) 2009-2010 VMware, Inc. All Rights Reserved. 6 * Copyright © 2010 Intel Corporation 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the "Software"), 10 * to deal in the Software without restriction, including without limitation 11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 * and/or sell copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included 16 * in all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26/** 27 * \file uniforms.c 28 * Functions related to GLSL uniform variables. 29 * \author Brian Paul 30 */ 31 32/** 33 * XXX things to do: 34 * 1. Check that the right error code is generated for all _mesa_error() calls. 35 * 2. Insert FLUSH_VERTICES calls in various places 36 */ 37 38 39#include "main/glheader.h" 40#include "main/context.h" 41#include "main/dispatch.h" 42#include "main/image.h" 43#include "main/mfeatures.h" 44#include "main/mtypes.h" 45#include "main/shaderapi.h" 46#include "main/shaderobj.h" 47#include "main/uniforms.h" 48#include "program/prog_parameter.h" 49#include "program/prog_statevars.h" 50#include "program/prog_uniform.h" 51#include "program/prog_instruction.h" 52 53 54static GLenum 55base_uniform_type(GLenum type) 56{ 57 switch (type) { 58 case GL_BOOL: 59 case GL_BOOL_VEC2: 60 case GL_BOOL_VEC3: 61 case GL_BOOL_VEC4: 62 return GL_BOOL; 63 case GL_FLOAT: 64 case GL_FLOAT_VEC2: 65 case GL_FLOAT_VEC3: 66 case GL_FLOAT_VEC4: 67 case GL_FLOAT_MAT2: 68 case GL_FLOAT_MAT2x3: 69 case GL_FLOAT_MAT2x4: 70 case GL_FLOAT_MAT3x2: 71 case GL_FLOAT_MAT3: 72 case GL_FLOAT_MAT3x4: 73 case GL_FLOAT_MAT4x2: 74 case GL_FLOAT_MAT4x3: 75 case GL_FLOAT_MAT4: 76 return GL_FLOAT; 77 case GL_UNSIGNED_INT: 78 case GL_UNSIGNED_INT_VEC2: 79 case GL_UNSIGNED_INT_VEC3: 80 case GL_UNSIGNED_INT_VEC4: 81 return GL_UNSIGNED_INT; 82 case GL_INT: 83 case GL_INT_VEC2: 84 case GL_INT_VEC3: 85 case GL_INT_VEC4: 86 return GL_INT; 87 default: 88 _mesa_problem(NULL, "Invalid type in base_uniform_type()"); 89 return GL_FLOAT; 90 } 91} 92 93 94static GLboolean 95is_boolean_type(GLenum type) 96{ 97 switch (type) { 98 case GL_BOOL: 99 case GL_BOOL_VEC2: 100 case GL_BOOL_VEC3: 101 case GL_BOOL_VEC4: 102 return GL_TRUE; 103 default: 104 return GL_FALSE; 105 } 106} 107 108 109static GLboolean 110is_sampler_type(GLenum type) 111{ 112 switch (type) { 113 case GL_SAMPLER_1D: 114 case GL_INT_SAMPLER_1D: 115 case GL_UNSIGNED_INT_SAMPLER_1D: 116 case GL_SAMPLER_2D: 117 case GL_INT_SAMPLER_2D: 118 case GL_UNSIGNED_INT_SAMPLER_2D: 119 case GL_SAMPLER_3D: 120 case GL_INT_SAMPLER_3D: 121 case GL_UNSIGNED_INT_SAMPLER_3D: 122 case GL_SAMPLER_CUBE: 123 case GL_INT_SAMPLER_CUBE: 124 case GL_UNSIGNED_INT_SAMPLER_CUBE: 125 case GL_SAMPLER_1D_SHADOW: 126 case GL_SAMPLER_2D_SHADOW: 127 case GL_SAMPLER_CUBE_SHADOW: 128 case GL_SAMPLER_2D_RECT_ARB: 129 case GL_INT_SAMPLER_2D_RECT: 130 case GL_UNSIGNED_INT_SAMPLER_2D_RECT: 131 case GL_SAMPLER_2D_RECT_SHADOW_ARB: 132 case GL_SAMPLER_1D_ARRAY_EXT: 133 case GL_INT_SAMPLER_1D_ARRAY: 134 case GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: 135 case GL_SAMPLER_2D_ARRAY_EXT: 136 case GL_INT_SAMPLER_2D_ARRAY: 137 case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: 138 case GL_SAMPLER_1D_ARRAY_SHADOW_EXT: 139 case GL_SAMPLER_2D_ARRAY_SHADOW_EXT: 140 case GL_SAMPLER_CUBE_MAP_ARRAY: 141 case GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW: 142 case GL_SAMPLER_BUFFER: 143 case GL_INT_SAMPLER_BUFFER: 144 case GL_UNSIGNED_INT_SAMPLER_BUFFER: 145 case GL_SAMPLER_2D_MULTISAMPLE: 146 case GL_INT_SAMPLER_2D_MULTISAMPLE: 147 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: 148 case GL_SAMPLER_2D_MULTISAMPLE_ARRAY: 149 case GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: 150 case GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: 151 case GL_SAMPLER_EXTERNAL_OES: 152 return GL_TRUE; 153 default: 154 return GL_FALSE; 155 } 156} 157 158 159/** 160 * Given a uniform index, return the vertex/geometry/fragment program 161 * that has that parameter, plus the position of the parameter in the 162 * parameter/constant buffer. 163 * \param shProg the shader program 164 * \param index the uniform index in [0, NumUniforms-1] 165 * \param progOut returns containing program 166 * \param posOut returns position of the uniform in the param/const buffer 167 * \return GL_TRUE for success, GL_FALSE for invalid index 168 */ 169static GLboolean 170find_uniform_parameter_pos(struct gl_shader_program *shProg, GLint index, 171 struct gl_program **progOut, GLint *posOut) 172{ 173 struct gl_program *prog = NULL; 174 GLint pos; 175 176 if (!shProg->Uniforms || 177 index < 0 || 178 index >= (GLint) shProg->Uniforms->NumUniforms) { 179 return GL_FALSE; 180 } 181 182 pos = shProg->Uniforms->Uniforms[index].VertPos; 183 if (pos >= 0) { 184 prog = shProg->_LinkedShaders[MESA_SHADER_VERTEX]->Program; 185 } 186 else { 187 pos = shProg->Uniforms->Uniforms[index].FragPos; 188 if (pos >= 0) { 189 prog = shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program; 190 } 191 else { 192 pos = shProg->Uniforms->Uniforms[index].GeomPos; 193 if (pos >= 0) { 194 prog = shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program; 195 } 196 } 197 } 198 199 if (!prog || pos < 0) 200 return GL_FALSE; /* should really never happen */ 201 202 *progOut = prog; 203 *posOut = pos; 204 205 return GL_TRUE; 206} 207 208 209/** 210 * Return pointer to a gl_program_parameter which corresponds to a uniform. 211 * \param shProg the shader program 212 * \param index the uniform index in [0, NumUniforms-1] 213 * \return gl_program_parameter point or NULL if index is invalid 214 */ 215const struct gl_program_parameter * 216get_uniform_parameter(struct gl_shader_program *shProg, GLint index) 217{ 218 struct gl_program *prog; 219 GLint progPos; 220 221 if (find_uniform_parameter_pos(shProg, index, &prog, &progPos)) 222 return &prog->Parameters->Parameters[progPos]; 223 else 224 return NULL; 225} 226 227 228static unsigned 229get_vector_elements(GLenum type) 230{ 231 switch (type) { 232 case GL_FLOAT: 233 case GL_INT: 234 case GL_BOOL: 235 case GL_UNSIGNED_INT: 236 default: /* Catch all the various sampler types. */ 237 return 1; 238 239 case GL_FLOAT_VEC2: 240 case GL_INT_VEC2: 241 case GL_BOOL_VEC2: 242 case GL_UNSIGNED_INT_VEC2: 243 return 2; 244 245 case GL_FLOAT_VEC3: 246 case GL_INT_VEC3: 247 case GL_BOOL_VEC3: 248 case GL_UNSIGNED_INT_VEC3: 249 return 3; 250 251 case GL_FLOAT_VEC4: 252 case GL_INT_VEC4: 253 case GL_BOOL_VEC4: 254 case GL_UNSIGNED_INT_VEC4: 255 return 4; 256 } 257} 258 259static void 260get_matrix_dims(GLenum type, GLint *rows, GLint *cols) 261{ 262 switch (type) { 263 case GL_FLOAT_MAT2: 264 *rows = *cols = 2; 265 break; 266 case GL_FLOAT_MAT2x3: 267 *rows = 3; 268 *cols = 2; 269 break; 270 case GL_FLOAT_MAT2x4: 271 *rows = 4; 272 *cols = 2; 273 break; 274 case GL_FLOAT_MAT3: 275 *rows = 3; 276 *cols = 3; 277 break; 278 case GL_FLOAT_MAT3x2: 279 *rows = 2; 280 *cols = 3; 281 break; 282 case GL_FLOAT_MAT3x4: 283 *rows = 4; 284 *cols = 3; 285 break; 286 case GL_FLOAT_MAT4: 287 *rows = 4; 288 *cols = 4; 289 break; 290 case GL_FLOAT_MAT4x2: 291 *rows = 2; 292 *cols = 4; 293 break; 294 case GL_FLOAT_MAT4x3: 295 *rows = 3; 296 *cols = 4; 297 break; 298 default: 299 *rows = *cols = 0; 300 } 301} 302 303 304/** 305 * Determine the number of rows and columns occupied by a uniform 306 * according to its datatype. For non-matrix types (such as GL_FLOAT_VEC4), 307 * the number of rows = 1 and cols = number of elements in the vector. 308 */ 309static void 310get_uniform_rows_cols(const struct gl_program_parameter *p, 311 GLint *rows, GLint *cols) 312{ 313 get_matrix_dims(p->DataType, rows, cols); 314 if (*rows == 0 && *cols == 0) { 315 /* not a matrix type, probably a float or vector */ 316 *rows = 1; 317 *cols = get_vector_elements(p->DataType); 318 } 319} 320 321/** 322 * Called via glGetUniform[fiui]v() to get the current value of a uniform. 323 */ 324void 325_mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location, 326 GLsizei bufSize, GLenum returnType, GLvoid *paramsOut) 327{ 328 struct gl_shader_program *shProg = 329 _mesa_lookup_shader_program_err(ctx, program, "glGetUniformfv"); 330 struct gl_program *prog; 331 GLint paramPos, offset; 332 333 if (!shProg) 334 return; 335 336 _mesa_uniform_split_location_offset(location, &location, &offset); 337 338 if (!find_uniform_parameter_pos(shProg, location, &prog, ¶mPos)) { 339 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(location)"); 340 } 341 else { 342 const struct gl_program_parameter *p = 343 &prog->Parameters->Parameters[paramPos]; 344 gl_constant_value (*values)[4]; 345 GLint rows, cols, i, j, k; 346 GLsizei numBytes; 347 GLenum storage_type; 348 349 values = prog->Parameters->ParameterValues + paramPos + offset; 350 351 get_uniform_rows_cols(p, &rows, &cols); 352 353 numBytes = rows * cols * _mesa_sizeof_type(returnType); 354 if (bufSize < numBytes) { 355 _mesa_error( ctx, GL_INVALID_OPERATION, 356 "glGetnUniformfvARB(out of bounds: bufSize is %d," 357 " but %d bytes are required)", bufSize, numBytes ); 358 return; 359 } 360 361 if (ctx->Const.NativeIntegers) { 362 storage_type = base_uniform_type(p->DataType); 363 } else { 364 storage_type = GL_FLOAT; 365 } 366 367 k = 0; 368 for (i = 0; i < rows; i++) { 369 for (j = 0; j < cols; j++ ) { 370 void *out = (char *)paramsOut + 4 * k; 371 372 switch (returnType) { 373 case GL_FLOAT: 374 switch (storage_type) { 375 case GL_FLOAT: 376 *(float *)out = values[i][j].f; 377 break; 378 case GL_INT: 379 case GL_BOOL: /* boolean is just an integer 1 or 0. */ 380 *(float *)out = values[i][j].i; 381 break; 382 case GL_UNSIGNED_INT: 383 *(float *)out = values[i][j].u; 384 break; 385 } 386 break; 387 388 case GL_INT: 389 case GL_UNSIGNED_INT: 390 switch (storage_type) { 391 case GL_FLOAT: 392 /* While the GL 3.2 core spec doesn't explicitly 393 * state how conversion of float uniforms to integer 394 * values works, in section 6.2 "State Tables" on 395 * page 267 it says: 396 * 397 * "Unless otherwise specified, when floating 398 * point state is returned as integer values or 399 * integer state is returned as floating-point 400 * values it is converted in the fashion 401 * described in section 6.1.2" 402 * 403 * That section, on page 248, says: 404 * 405 * "If GetIntegerv or GetInteger64v are called, 406 * a floating-point value is rounded to the 407 * nearest integer..." 408 */ 409 *(int *)out = IROUND(values[i][j].f); 410 break; 411 412 case GL_INT: 413 case GL_UNSIGNED_INT: 414 case GL_BOOL: 415 /* type conversions for these to int/uint are just 416 * copying the data. 417 */ 418 *(int *)out = values[i][j].i; 419 break; 420 break; 421 } 422 break; 423 } 424 425 k++; 426 } 427 } 428 } 429} 430 431 432/** 433 * Called via glGetUniformLocation(). 434 * 435 * The return value will encode two values, the uniform location and an 436 * offset (used for arrays, structs). 437 */ 438GLint 439_mesa_get_uniform_location(struct gl_context *ctx, 440 struct gl_shader_program *shProg, 441 const GLchar *name) 442{ 443 GLint offset = 0, location = -1; 444 445 /* XXX we should return -1 if the uniform was declared, but not 446 * actually used. 447 */ 448 449 /* XXX we need to be able to parse uniform names for structs and arrays 450 * such as: 451 * mymatrix[1] 452 * mystruct.field1 453 */ 454 455 { 456 /* handle 1-dimension arrays here... */ 457 char *c = strchr(name, '['); 458 if (c) { 459 /* truncate name at [ */ 460 const GLint len = c - name; 461 GLchar *newName = malloc(len + 1); 462 if (!newName) 463 return -1; /* out of mem */ 464 memcpy(newName, name, len); 465 newName[len] = 0; 466 467 location = _mesa_lookup_uniform(shProg->Uniforms, newName); 468 if (location >= 0) { 469 const GLint element = atoi(c + 1); 470 if (element > 0) { 471 /* get type of the uniform array element */ 472 const struct gl_program_parameter *p = 473 get_uniform_parameter(shProg, location); 474 if (p) { 475 GLint rows, cols; 476 get_matrix_dims(p->DataType, &rows, &cols); 477 if (rows < 1) 478 rows = 1; 479 offset = element * rows; 480 } 481 } 482 } 483 484 free(newName); 485 } 486 } 487 488 if (location < 0) { 489 location = _mesa_lookup_uniform(shProg->Uniforms, name); 490 } 491 492 if (location < 0) { 493 return -1; 494 } 495 496 return _mesa_uniform_merge_location_offset(location, offset); 497} 498 499 500 501/** 502 * Update the vertex/fragment program's TexturesUsed array. 503 * 504 * This needs to be called after glUniform(set sampler var) is called. 505 * A call to glUniform(samplerVar, value) causes a sampler to point to a 506 * particular texture unit. We know the sampler's texture target 507 * (1D/2D/3D/etc) from compile time but the sampler's texture unit is 508 * set by glUniform() calls. 509 * 510 * So, scan the program->SamplerUnits[] and program->SamplerTargets[] 511 * information to update the prog->TexturesUsed[] values. 512 * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX, 513 * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc. 514 * We'll use that info for state validation before rendering. 515 */ 516void 517_mesa_update_shader_textures_used(struct gl_program *prog) 518{ 519 GLuint s; 520 521 memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed)); 522 523 for (s = 0; s < MAX_SAMPLERS; s++) { 524 if (prog->SamplersUsed & (1 << s)) { 525 GLuint unit = prog->SamplerUnits[s]; 526 GLuint tgt = prog->SamplerTargets[s]; 527 assert(unit < Elements(prog->TexturesUsed)); 528 assert(tgt < NUM_TEXTURE_TARGETS); 529 prog->TexturesUsed[unit] |= (1 << tgt); 530 } 531 } 532} 533 534 535/** 536 * Check if the type given by userType is allowed to set a uniform of the 537 * target type. Generally, equivalence is required, but setting Boolean 538 * uniforms can be done with glUniformiv or glUniformfv. 539 */ 540static GLboolean 541compatible_types(GLenum userType, GLenum targetType) 542{ 543 if (userType == targetType) 544 return GL_TRUE; 545 546 if (targetType == GL_BOOL && (userType == GL_FLOAT || 547 userType == GL_UNSIGNED_INT || 548 userType == GL_INT)) 549 return GL_TRUE; 550 551 if (targetType == GL_BOOL_VEC2 && (userType == GL_FLOAT_VEC2 || 552 userType == GL_UNSIGNED_INT_VEC2 || 553 userType == GL_INT_VEC2)) 554 return GL_TRUE; 555 556 if (targetType == GL_BOOL_VEC3 && (userType == GL_FLOAT_VEC3 || 557 userType == GL_UNSIGNED_INT_VEC3 || 558 userType == GL_INT_VEC3)) 559 return GL_TRUE; 560 561 if (targetType == GL_BOOL_VEC4 && (userType == GL_FLOAT_VEC4 || 562 userType == GL_UNSIGNED_INT_VEC4 || 563 userType == GL_INT_VEC4)) 564 return GL_TRUE; 565 566 if (is_sampler_type(targetType) && userType == GL_INT) 567 return GL_TRUE; 568 569 return GL_FALSE; 570} 571 572 573/** 574 * Set the value of a program's uniform variable. 575 * \param program the program whose uniform to update 576 * \param index the index of the program parameter for the uniform 577 * \param offset additional parameter slot offset (for arrays) 578 * \param type the incoming datatype of 'values' 579 * \param count the number of uniforms to set 580 * \param elems number of elements per uniform (1, 2, 3 or 4) 581 * \param values the new values, of datatype 'type' 582 */ 583static void 584set_program_uniform(struct gl_context *ctx, struct gl_program *program, 585 GLint index, GLint offset, 586 GLenum type, GLsizei count, GLint elems, 587 const void *values) 588{ 589 const struct gl_program_parameter *param = 590 &program->Parameters->Parameters[index]; 591 592 assert(offset >= 0); 593 assert(elems >= 1); 594 assert(elems <= 4); 595 596 if (!compatible_types(type, param->DataType)) { 597 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)"); 598 return; 599 } 600 601 if (index + offset > (GLint) program->Parameters->Size) { 602 /* out of bounds! */ 603 return; 604 } 605 606 if (param->Type == PROGRAM_SAMPLER) { 607 /* This controls which texture unit which is used by a sampler */ 608 GLboolean changed = GL_FALSE; 609 GLint i; 610 611 /* this should have been caught by the compatible_types() check */ 612 ASSERT(type == GL_INT); 613 614 /* loop over number of samplers to change */ 615 for (i = 0; i < count; i++) { 616 GLuint sampler = (GLuint) 617 program->Parameters->ParameterValues[index+offset + i][0].f; 618 GLuint texUnit = ((GLuint *) values)[i]; 619 620 /* check that the sampler (tex unit index) is legal */ 621 if (texUnit >= ctx->Const.MaxCombinedTextureImageUnits) { 622 _mesa_error(ctx, GL_INVALID_VALUE, 623 "glUniform1(invalid sampler/tex unit index for '%s')", 624 param->Name); 625 return; 626 } 627 628 /* This maps a sampler to a texture unit: */ 629 if (sampler < MAX_SAMPLERS) { 630#if 0 631 printf("Set program %p sampler %d '%s' to unit %u\n", 632 program, sampler, param->Name, texUnit); 633#endif 634 if (program->SamplerUnits[sampler] != texUnit) { 635 program->SamplerUnits[sampler] = texUnit; 636 changed = GL_TRUE; 637 } 638 } 639 } 640 641 if (changed) { 642 /* When a sampler's value changes it usually requires rewriting 643 * a GPU program's TEX instructions since there may not be a 644 * sampler->texture lookup table. We signal this with the 645 * ProgramStringNotify() callback. 646 */ 647 FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM); 648 _mesa_update_shader_textures_used(program); 649 /* Do we need to care about the return value here? 650 * This should not be the first time the driver was notified of 651 * this program. 652 */ 653 (void) ctx->Driver.ProgramStringNotify(ctx, program->Target, program); 654 } 655 } 656 else { 657 /* ordinary uniform variable */ 658 const GLboolean isUniformBool = is_boolean_type(param->DataType); 659 const GLenum basicType = base_uniform_type(type); 660 const GLint slots = (param->Size + 3) / 4; 661 const GLint typeSize = _mesa_sizeof_glsl_type(param->DataType); 662 GLsizei k, i; 663 664 if ((GLint) param->Size > typeSize) { 665 /* an array */ 666 /* we'll ignore extra data below */ 667 } 668 else { 669 /* non-array: count must be at most one; count == 0 is handled 670 * by the loop below 671 */ 672 if (count > 1) { 673 _mesa_error(ctx, GL_INVALID_OPERATION, 674 "glUniform(uniform '%s' is not an array)", 675 param->Name); 676 return; 677 } 678 } 679 680 /* loop over number of array elements */ 681 for (k = 0; k < count; k++) { 682 gl_constant_value *uniformVal; 683 684 if (offset + k >= slots) { 685 /* Extra array data is ignored */ 686 break; 687 } 688 689 /* uniformVal (the destination) is always gl_constant_value[4] */ 690 uniformVal = program->Parameters->ParameterValues[index + offset + k]; 691 692 if (basicType == GL_INT) { 693 const GLint *iValues = ((const GLint *) values) + k * elems; 694 for (i = 0; i < elems; i++) { 695 if (!ctx->Const.NativeIntegers) 696 uniformVal[i].f = (GLfloat) iValues[i]; 697 else 698 uniformVal[i].i = iValues[i]; 699 } 700 } 701 else if (basicType == GL_UNSIGNED_INT) { 702 const GLuint *iValues = ((const GLuint *) values) + k * elems; 703 for (i = 0; i < elems; i++) { 704 if (!ctx->Const.NativeIntegers) 705 uniformVal[i].f = (GLfloat)(GLuint) iValues[i]; 706 else 707 uniformVal[i].u = iValues[i]; 708 } 709 } 710 else { 711 const GLfloat *fValues = ((const GLfloat *) values) + k * elems; 712 assert(basicType == GL_FLOAT); 713 for (i = 0; i < elems; i++) { 714 uniformVal[i].f = fValues[i]; 715 } 716 } 717 718 /* if the uniform is bool-valued, convert to 1 or 0 */ 719 if (isUniformBool) { 720 for (i = 0; i < elems; i++) { 721 if (basicType == GL_FLOAT) 722 uniformVal[i].b = uniformVal[i].f != 0.0f ? 1 : 0; 723 else 724 uniformVal[i].b = uniformVal[i].u ? 1 : 0; 725 726 if (ctx->Const.NativeIntegers) 727 uniformVal[i].u = 728 uniformVal[i].b ? ctx->Const.UniformBooleanTrue : 0; 729 else 730 uniformVal[i].f = uniformVal[i].b ? 1.0f : 0.0f; 731 } 732 } 733 } 734 } 735} 736 737 738/** 739 * Called via glUniform*() functions. 740 */ 741void 742_mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg, 743 GLint location, GLsizei count, 744 const GLvoid *values, GLenum type) 745{ 746 struct gl_uniform *uniform; 747 GLint elems, offset; 748 749 ASSERT_OUTSIDE_BEGIN_END(ctx); 750 751 if (!shProg || !shProg->LinkStatus) { 752 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(program not linked)"); 753 return; 754 } 755 756 if (location == -1) 757 return; /* The standard specifies this as a no-op */ 758 759 if (location < -1) { 760 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(location=%d)", 761 location); 762 return; 763 } 764 765 _mesa_uniform_split_location_offset(location, &location, &offset); 766 767 if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) { 768 _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(location=%d)", location); 769 return; 770 } 771 772 if (count < 0) { 773 _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(count < 0)"); 774 return; 775 } 776 777 elems = _mesa_sizeof_glsl_type(type); 778 779 FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); 780 781 uniform = &shProg->Uniforms->Uniforms[location]; 782 783 if (ctx->Shader.Flags & GLSL_UNIFORMS) { 784 const GLenum basicType = base_uniform_type(type); 785 GLint i; 786 printf("Mesa: set program %u uniform %s (loc %d) to: ", 787 shProg->Name, uniform->Name, location); 788 if (basicType == GL_INT) { 789 const GLint *v = (const GLint *) values; 790 for (i = 0; i < count * elems; i++) { 791 printf("%d ", v[i]); 792 } 793 } 794 else if (basicType == GL_UNSIGNED_INT) { 795 const GLuint *v = (const GLuint *) values; 796 for (i = 0; i < count * elems; i++) { 797 printf("%u ", v[i]); 798 } 799 } 800 else { 801 const GLfloat *v = (const GLfloat *) values; 802 assert(basicType == GL_FLOAT); 803 for (i = 0; i < count * elems; i++) { 804 printf("%g ", v[i]); 805 } 806 } 807 printf("\n"); 808 } 809 810 /* A uniform var may be used by both a vertex shader and a fragment 811 * shader. We may need to update one or both shader's uniform here: 812 */ 813 if (shProg->_LinkedShaders[MESA_SHADER_VERTEX]) { 814 /* convert uniform location to program parameter index */ 815 GLint index = uniform->VertPos; 816 if (index >= 0) { 817 set_program_uniform(ctx, 818 shProg->_LinkedShaders[MESA_SHADER_VERTEX]->Program, 819 index, offset, type, count, elems, values); 820 } 821 } 822 823 if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]) { 824 /* convert uniform location to program parameter index */ 825 GLint index = uniform->FragPos; 826 if (index >= 0) { 827 set_program_uniform(ctx, 828 shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program, 829 index, offset, type, count, elems, values); 830 } 831 } 832 833 if (shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]) { 834 /* convert uniform location to program parameter index */ 835 GLint index = uniform->GeomPos; 836 if (index >= 0) { 837 set_program_uniform(ctx, 838 shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program, 839 index, offset, type, count, elems, values); 840 } 841 } 842 843 uniform->Initialized = GL_TRUE; 844} 845 846 847/** 848 * Set a matrix-valued program parameter. 849 */ 850static void 851set_program_uniform_matrix(struct gl_context *ctx, struct gl_program *program, 852 GLuint index, GLuint offset, 853 GLuint count, GLuint rows, GLuint cols, 854 GLboolean transpose, const GLfloat *values) 855{ 856 GLuint mat, row, col; 857 GLuint src = 0; 858 const struct gl_program_parameter *param = 859 &program->Parameters->Parameters[index]; 860 const GLuint slots = (param->Size + 3) / 4; 861 const GLint typeSize = _mesa_sizeof_glsl_type(param->DataType); 862 GLint nr, nc; 863 864 /* check that the number of rows, columns is correct */ 865 get_matrix_dims(param->DataType, &nr, &nc); 866 if (rows != nr || cols != nc) { 867 _mesa_error(ctx, GL_INVALID_OPERATION, 868 "glUniformMatrix(matrix size mismatch)"); 869 return; 870 } 871 872 if ((GLint) param->Size <= typeSize) { 873 /* non-array: count must be at most one; count == 0 is handled 874 * by the loop below 875 */ 876 if (count > 1) { 877 _mesa_error(ctx, GL_INVALID_OPERATION, 878 "glUniformMatrix(uniform is not an array)"); 879 return; 880 } 881 } 882 883 /* 884 * Note: the _columns_ of a matrix are stored in program registers, not 885 * the rows. So, the loops below look a little funny. 886 * XXX could optimize this a bit... 887 */ 888 889 /* loop over matrices */ 890 for (mat = 0; mat < count; mat++) { 891 892 /* each matrix: */ 893 for (col = 0; col < cols; col++) { 894 GLfloat *v; 895 if (offset >= slots) { 896 /* Ignore writes beyond the end of (the used part of) an array */ 897 return; 898 } 899 v = (GLfloat *) program->Parameters->ParameterValues[index + offset]; 900 for (row = 0; row < rows; row++) { 901 if (transpose) { 902 v[row] = values[src + row * cols + col]; 903 } 904 else { 905 v[row] = values[src + col * rows + row]; 906 } 907 } 908 909 offset++; 910 } 911 912 src += rows * cols; /* next matrix */ 913 } 914} 915 916 917/** 918 * Called by glUniformMatrix*() functions. 919 * Note: cols=2, rows=4 ==> array[2] of vec4 920 */ 921void 922_mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg, 923 GLint cols, GLint rows, 924 GLint location, GLsizei count, 925 GLboolean transpose, const GLfloat *values) 926{ 927 struct gl_uniform *uniform; 928 GLint offset; 929 930 ASSERT_OUTSIDE_BEGIN_END(ctx); 931 932 if (!shProg || !shProg->LinkStatus) { 933 _mesa_error(ctx, GL_INVALID_OPERATION, 934 "glUniformMatrix(program not linked)"); 935 return; 936 } 937 938 if (location == -1) 939 return; /* The standard specifies this as a no-op */ 940 941 if (location < -1) { 942 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix(location)"); 943 return; 944 } 945 946 _mesa_uniform_split_location_offset(location, &location, &offset); 947 948 if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) { 949 _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix(location)"); 950 return; 951 } 952 if (values == NULL) { 953 _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix"); 954 return; 955 } 956 957 FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS); 958 959 uniform = &shProg->Uniforms->Uniforms[location]; 960 961 if (shProg->_LinkedShaders[MESA_SHADER_VERTEX]) { 962 /* convert uniform location to program parameter index */ 963 GLint index = uniform->VertPos; 964 if (index >= 0) { 965 set_program_uniform_matrix(ctx, 966 shProg->_LinkedShaders[MESA_SHADER_VERTEX]->Program, 967 index, offset, 968 count, rows, cols, transpose, values); 969 } 970 } 971 972 if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]) { 973 /* convert uniform location to program parameter index */ 974 GLint index = uniform->FragPos; 975 if (index >= 0) { 976 set_program_uniform_matrix(ctx, 977 shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program, 978 index, offset, 979 count, rows, cols, transpose, values); 980 } 981 } 982 983 if (shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]) { 984 /* convert uniform location to program parameter index */ 985 GLint index = uniform->GeomPos; 986 if (index >= 0) { 987 set_program_uniform_matrix(ctx, 988 shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program, 989 index, offset, 990 count, rows, cols, transpose, values); 991 } 992 } 993 994 uniform->Initialized = GL_TRUE; 995} 996 997 998void GLAPIENTRY 999_mesa_Uniform1fARB(GLint location, GLfloat v0) 1000{ 1001 GET_CURRENT_CONTEXT(ctx); 1002 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, &v0, GL_FLOAT); 1003} 1004 1005void GLAPIENTRY 1006_mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1) 1007{ 1008 GET_CURRENT_CONTEXT(ctx); 1009 GLfloat v[2]; 1010 v[0] = v0; 1011 v[1] = v1; 1012 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_FLOAT_VEC2); 1013} 1014 1015void GLAPIENTRY 1016_mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) 1017{ 1018 GET_CURRENT_CONTEXT(ctx); 1019 GLfloat v[3]; 1020 v[0] = v0; 1021 v[1] = v1; 1022 v[2] = v2; 1023 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_FLOAT_VEC3); 1024} 1025 1026void GLAPIENTRY 1027_mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, 1028 GLfloat v3) 1029{ 1030 GET_CURRENT_CONTEXT(ctx); 1031 GLfloat v[4]; 1032 v[0] = v0; 1033 v[1] = v1; 1034 v[2] = v2; 1035 v[3] = v3; 1036 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_FLOAT_VEC4); 1037} 1038 1039void GLAPIENTRY 1040_mesa_Uniform1iARB(GLint location, GLint v0) 1041{ 1042 GET_CURRENT_CONTEXT(ctx); 1043 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, &v0, GL_INT); 1044} 1045 1046void GLAPIENTRY 1047_mesa_Uniform2iARB(GLint location, GLint v0, GLint v1) 1048{ 1049 GET_CURRENT_CONTEXT(ctx); 1050 GLint v[2]; 1051 v[0] = v0; 1052 v[1] = v1; 1053 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_INT_VEC2); 1054} 1055 1056void GLAPIENTRY 1057_mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2) 1058{ 1059 GET_CURRENT_CONTEXT(ctx); 1060 GLint v[3]; 1061 v[0] = v0; 1062 v[1] = v1; 1063 v[2] = v2; 1064 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_INT_VEC3); 1065} 1066 1067void GLAPIENTRY 1068_mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) 1069{ 1070 GET_CURRENT_CONTEXT(ctx); 1071 GLint v[4]; 1072 v[0] = v0; 1073 v[1] = v1; 1074 v[2] = v2; 1075 v[3] = v3; 1076 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_INT_VEC4); 1077} 1078 1079void GLAPIENTRY 1080_mesa_Uniform1fvARB(GLint location, GLsizei count, const GLfloat * value) 1081{ 1082 GET_CURRENT_CONTEXT(ctx); 1083 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT); 1084} 1085 1086void GLAPIENTRY 1087_mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value) 1088{ 1089 GET_CURRENT_CONTEXT(ctx); 1090 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT_VEC2); 1091} 1092 1093void GLAPIENTRY 1094_mesa_Uniform3fvARB(GLint location, GLsizei count, const GLfloat * value) 1095{ 1096 GET_CURRENT_CONTEXT(ctx); 1097 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT_VEC3); 1098} 1099 1100void GLAPIENTRY 1101_mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value) 1102{ 1103 GET_CURRENT_CONTEXT(ctx); 1104 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT_VEC4); 1105} 1106 1107void GLAPIENTRY 1108_mesa_Uniform1ivARB(GLint location, GLsizei count, const GLint * value) 1109{ 1110 GET_CURRENT_CONTEXT(ctx); 1111 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT); 1112} 1113 1114void GLAPIENTRY 1115_mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value) 1116{ 1117 GET_CURRENT_CONTEXT(ctx); 1118 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC2); 1119} 1120 1121void GLAPIENTRY 1122_mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value) 1123{ 1124 GET_CURRENT_CONTEXT(ctx); 1125 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC3); 1126} 1127 1128void GLAPIENTRY 1129_mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value) 1130{ 1131 GET_CURRENT_CONTEXT(ctx); 1132 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC4); 1133} 1134 1135 1136/** OpenGL 3.0 GLuint-valued functions **/ 1137void GLAPIENTRY 1138_mesa_Uniform1ui(GLint location, GLuint v0) 1139{ 1140 GET_CURRENT_CONTEXT(ctx); 1141 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, &v0, GL_UNSIGNED_INT); 1142} 1143 1144void GLAPIENTRY 1145_mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1) 1146{ 1147 GET_CURRENT_CONTEXT(ctx); 1148 GLuint v[2]; 1149 v[0] = v0; 1150 v[1] = v1; 1151 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC2); 1152} 1153 1154void GLAPIENTRY 1155_mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) 1156{ 1157 GET_CURRENT_CONTEXT(ctx); 1158 GLuint v[3]; 1159 v[0] = v0; 1160 v[1] = v1; 1161 v[2] = v2; 1162 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC3); 1163} 1164 1165void GLAPIENTRY 1166_mesa_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) 1167{ 1168 GET_CURRENT_CONTEXT(ctx); 1169 GLuint v[4]; 1170 v[0] = v0; 1171 v[1] = v1; 1172 v[2] = v2; 1173 v[3] = v3; 1174 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC4); 1175} 1176 1177void GLAPIENTRY 1178_mesa_Uniform1uiv(GLint location, GLsizei count, const GLuint *value) 1179{ 1180 GET_CURRENT_CONTEXT(ctx); 1181 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT); 1182} 1183 1184void GLAPIENTRY 1185_mesa_Uniform2uiv(GLint location, GLsizei count, const GLuint *value) 1186{ 1187 GET_CURRENT_CONTEXT(ctx); 1188 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC2); 1189} 1190 1191void GLAPIENTRY 1192_mesa_Uniform3uiv(GLint location, GLsizei count, const GLuint *value) 1193{ 1194 GET_CURRENT_CONTEXT(ctx); 1195 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC3); 1196} 1197 1198void GLAPIENTRY 1199_mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value) 1200{ 1201 GET_CURRENT_CONTEXT(ctx); 1202 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC4); 1203} 1204 1205 1206 1207void GLAPIENTRY 1208_mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose, 1209 const GLfloat * value) 1210{ 1211 GET_CURRENT_CONTEXT(ctx); 1212 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram, 1213 2, 2, location, count, transpose, value); 1214} 1215 1216void GLAPIENTRY 1217_mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose, 1218 const GLfloat * value) 1219{ 1220 GET_CURRENT_CONTEXT(ctx); 1221 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram, 1222 3, 3, location, count, transpose, value); 1223} 1224 1225void GLAPIENTRY 1226_mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose, 1227 const GLfloat * value) 1228{ 1229 GET_CURRENT_CONTEXT(ctx); 1230 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram, 1231 4, 4, location, count, transpose, value); 1232} 1233 1234 1235/** 1236 * Non-square UniformMatrix are OpenGL 2.1 1237 */ 1238void GLAPIENTRY 1239_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, 1240 const GLfloat *value) 1241{ 1242 GET_CURRENT_CONTEXT(ctx); 1243 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram, 1244 2, 3, location, count, transpose, value); 1245} 1246 1247void GLAPIENTRY 1248_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, 1249 const GLfloat *value) 1250{ 1251 GET_CURRENT_CONTEXT(ctx); 1252 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram, 1253 3, 2, location, count, transpose, value); 1254} 1255 1256void GLAPIENTRY 1257_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, 1258 const GLfloat *value) 1259{ 1260 GET_CURRENT_CONTEXT(ctx); 1261 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram, 1262 2, 4, location, count, transpose, value); 1263} 1264 1265void GLAPIENTRY 1266_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, 1267 const GLfloat *value) 1268{ 1269 GET_CURRENT_CONTEXT(ctx); 1270 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram, 1271 4, 2, location, count, transpose, value); 1272} 1273 1274void GLAPIENTRY 1275_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, 1276 const GLfloat *value) 1277{ 1278 GET_CURRENT_CONTEXT(ctx); 1279 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram, 1280 3, 4, location, count, transpose, value); 1281} 1282 1283void GLAPIENTRY 1284_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, 1285 const GLfloat *value) 1286{ 1287 GET_CURRENT_CONTEXT(ctx); 1288 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram, 1289 4, 3, location, count, transpose, value); 1290} 1291 1292 1293void GLAPIENTRY 1294_mesa_GetnUniformfvARB(GLhandleARB program, GLint location, 1295 GLsizei bufSize, GLfloat *params) 1296{ 1297 GET_CURRENT_CONTEXT(ctx); 1298 _mesa_get_uniform(ctx, program, location, bufSize, GL_FLOAT, params); 1299} 1300 1301void GLAPIENTRY 1302_mesa_GetUniformfvARB(GLhandleARB program, GLint location, GLfloat *params) 1303{ 1304 _mesa_GetnUniformfvARB(program, location, INT_MAX, params); 1305} 1306 1307 1308void GLAPIENTRY 1309_mesa_GetnUniformivARB(GLhandleARB program, GLint location, 1310 GLsizei bufSize, GLint *params) 1311{ 1312 GET_CURRENT_CONTEXT(ctx); 1313 _mesa_get_uniform(ctx, program, location, bufSize, GL_INT, params); 1314} 1315 1316void GLAPIENTRY 1317_mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint *params) 1318{ 1319 _mesa_GetnUniformivARB(program, location, INT_MAX, params); 1320} 1321 1322 1323/* GL3 */ 1324void GLAPIENTRY 1325_mesa_GetnUniformuivARB(GLhandleARB program, GLint location, 1326 GLsizei bufSize, GLuint *params) 1327{ 1328 GET_CURRENT_CONTEXT(ctx); 1329 _mesa_get_uniform(ctx, program, location, bufSize, GL_UNSIGNED_INT, params); 1330} 1331 1332void GLAPIENTRY 1333_mesa_GetUniformuiv(GLhandleARB program, GLint location, GLuint *params) 1334{ 1335 _mesa_GetnUniformuivARB(program, location, INT_MAX, params); 1336} 1337 1338 1339/* GL4 */ 1340void GLAPIENTRY 1341_mesa_GetnUniformdvARB(GLhandleARB program, GLint location, 1342 GLsizei bufSize, GLdouble *params) 1343{ 1344 GET_CURRENT_CONTEXT(ctx); 1345 1346 (void) program; 1347 (void) location; 1348 (void) bufSize; 1349 (void) params; 1350 1351 /* 1352 _mesa_get_uniform(ctx, program, location, bufSize, GL_DOUBLE, params); 1353 */ 1354 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformdvARB" 1355 "(GL_ARB_gpu_shader_fp64 not implemented)"); 1356} 1357 1358void GLAPIENTRY 1359_mesa_GetUniformdv(GLhandleARB program, GLint location, GLdouble *params) 1360{ 1361 _mesa_GetnUniformdvARB(program, location, INT_MAX, params); 1362} 1363 1364 1365GLint GLAPIENTRY 1366_mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB *name) 1367{ 1368 struct gl_shader_program *shProg; 1369 1370 GET_CURRENT_CONTEXT(ctx); 1371 1372 shProg = _mesa_lookup_shader_program_err(ctx, programObj, 1373 "glGetUniformLocation"); 1374 if (!shProg) 1375 return -1; 1376 1377 /* Page 80 (page 94 of the PDF) of the OpenGL 2.1 spec says: 1378 * 1379 * "If program has not been successfully linked, the error 1380 * INVALID_OPERATION is generated." 1381 */ 1382 if (shProg->LinkStatus == GL_FALSE) { 1383 _mesa_error(ctx, GL_INVALID_OPERATION, 1384 "glGetUniformLocation(program not linked)"); 1385 return -1; 1386 } 1387 1388 return _mesa_get_uniform_location(ctx, shProg, name); 1389} 1390 1391 1392/** 1393 * Plug in shader uniform-related functions into API dispatch table. 1394 */ 1395void 1396_mesa_init_shader_uniform_dispatch(struct _glapi_table *exec) 1397{ 1398#if FEATURE_GL 1399 SET_Uniform1fARB(exec, _mesa_Uniform1fARB); 1400 SET_Uniform2fARB(exec, _mesa_Uniform2fARB); 1401 SET_Uniform3fARB(exec, _mesa_Uniform3fARB); 1402 SET_Uniform4fARB(exec, _mesa_Uniform4fARB); 1403 SET_Uniform1iARB(exec, _mesa_Uniform1iARB); 1404 SET_Uniform2iARB(exec, _mesa_Uniform2iARB); 1405 SET_Uniform3iARB(exec, _mesa_Uniform3iARB); 1406 SET_Uniform4iARB(exec, _mesa_Uniform4iARB); 1407 SET_Uniform1fvARB(exec, _mesa_Uniform1fvARB); 1408 SET_Uniform2fvARB(exec, _mesa_Uniform2fvARB); 1409 SET_Uniform3fvARB(exec, _mesa_Uniform3fvARB); 1410 SET_Uniform4fvARB(exec, _mesa_Uniform4fvARB); 1411 SET_Uniform1ivARB(exec, _mesa_Uniform1ivARB); 1412 SET_Uniform2ivARB(exec, _mesa_Uniform2ivARB); 1413 SET_Uniform3ivARB(exec, _mesa_Uniform3ivARB); 1414 SET_Uniform4ivARB(exec, _mesa_Uniform4ivARB); 1415 SET_UniformMatrix2fvARB(exec, _mesa_UniformMatrix2fvARB); 1416 SET_UniformMatrix3fvARB(exec, _mesa_UniformMatrix3fvARB); 1417 SET_UniformMatrix4fvARB(exec, _mesa_UniformMatrix4fvARB); 1418 1419 SET_GetActiveUniformARB(exec, _mesa_GetActiveUniformARB); 1420 SET_GetUniformLocationARB(exec, _mesa_GetUniformLocationARB); 1421 SET_GetUniformfvARB(exec, _mesa_GetUniformfvARB); 1422 SET_GetUniformivARB(exec, _mesa_GetUniformivARB); 1423 1424 /* OpenGL 2.1 */ 1425 SET_UniformMatrix2x3fv(exec, _mesa_UniformMatrix2x3fv); 1426 SET_UniformMatrix3x2fv(exec, _mesa_UniformMatrix3x2fv); 1427 SET_UniformMatrix2x4fv(exec, _mesa_UniformMatrix2x4fv); 1428 SET_UniformMatrix4x2fv(exec, _mesa_UniformMatrix4x2fv); 1429 SET_UniformMatrix3x4fv(exec, _mesa_UniformMatrix3x4fv); 1430 SET_UniformMatrix4x3fv(exec, _mesa_UniformMatrix4x3fv); 1431 1432 /* OpenGL 3.0 */ 1433 SET_Uniform1uiEXT(exec, _mesa_Uniform1ui); 1434 SET_Uniform2uiEXT(exec, _mesa_Uniform2ui); 1435 SET_Uniform3uiEXT(exec, _mesa_Uniform3ui); 1436 SET_Uniform4uiEXT(exec, _mesa_Uniform4ui); 1437 SET_Uniform1uivEXT(exec, _mesa_Uniform1uiv); 1438 SET_Uniform2uivEXT(exec, _mesa_Uniform2uiv); 1439 SET_Uniform3uivEXT(exec, _mesa_Uniform3uiv); 1440 SET_Uniform4uivEXT(exec, _mesa_Uniform4uiv); 1441 SET_GetUniformuivEXT(exec, _mesa_GetUniformuiv); 1442 1443 /* GL_ARB_robustness */ 1444 SET_GetnUniformfvARB(exec, _mesa_GetnUniformfvARB); 1445 SET_GetnUniformivARB(exec, _mesa_GetnUniformivARB); 1446 SET_GetnUniformuivARB(exec, _mesa_GetnUniformuivARB); 1447 SET_GetnUniformdvARB(exec, _mesa_GetnUniformdvARB); /* GL 4.0 */ 1448 1449#endif /* FEATURE_GL */ 1450} 1451