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