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