uniforms.c revision 5a165d1f3ae8eddb96c2d2026ac4a8f981733ac5
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#include "main/glheader.h" 39#include "main/context.h" 40#include "main/dispatch.h" 41#include "main/shaderapi.h" 42#include "main/shaderobj.h" 43#include "main/uniforms.h" 44#include "main/enums.h" 45#include "ir_uniform.h" 46#include "glsl_types.h" 47 48/** 49 * Update the vertex/fragment program's TexturesUsed array. 50 * 51 * This needs to be called after glUniform(set sampler var) is called. 52 * A call to glUniform(samplerVar, value) causes a sampler to point to a 53 * particular texture unit. We know the sampler's texture target 54 * (1D/2D/3D/etc) from compile time but the sampler's texture unit is 55 * set by glUniform() calls. 56 * 57 * So, scan the program->SamplerUnits[] and program->SamplerTargets[] 58 * information to update the prog->TexturesUsed[] values. 59 * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX, 60 * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc. 61 * We'll use that info for state validation before rendering. 62 */ 63void 64_mesa_update_shader_textures_used(struct gl_shader_program *shProg, 65 struct gl_program *prog) 66{ 67 GLuint s; 68 69 memcpy(prog->SamplerUnits, shProg->SamplerUnits, sizeof(prog->SamplerUnits)); 70 memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed)); 71 72 for (s = 0; s < MAX_SAMPLERS; s++) { 73 if (prog->SamplersUsed & (1 << s)) { 74 GLuint unit = shProg->SamplerUnits[s]; 75 GLuint tgt = shProg->SamplerTargets[s]; 76 assert(unit < Elements(prog->TexturesUsed)); 77 assert(tgt < NUM_TEXTURE_TARGETS); 78 prog->TexturesUsed[unit] |= (1 << tgt); 79 } 80 } 81} 82 83/** 84 * Connect a piece of driver storage with a part of a uniform 85 * 86 * \param uni The uniform with which the storage will be associated 87 * \param element_stride Byte-stride between array elements. 88 * \sa gl_uniform_driver_storage::element_stride. 89 * \param vector_stride Byte-stride between vectors (in a matrix). 90 * \sa gl_uniform_driver_storage::vector_stride. 91 * \param format Conversion from native format to driver format 92 * required by the driver. 93 * \param data Location to dump the data. 94 */ 95void 96_mesa_uniform_attach_driver_storage(struct gl_uniform_storage *uni, 97 unsigned element_stride, 98 unsigned vector_stride, 99 enum gl_uniform_driver_format format, 100 void *data) 101{ 102 uni->driver_storage = (struct gl_uniform_driver_storage*) 103 realloc(uni->driver_storage, 104 sizeof(struct gl_uniform_driver_storage) 105 * (uni->num_driver_storage + 1)); 106 107 uni->driver_storage[uni->num_driver_storage].element_stride = element_stride; 108 uni->driver_storage[uni->num_driver_storage].vector_stride = vector_stride; 109 uni->driver_storage[uni->num_driver_storage].format = (uint8_t) format; 110 uni->driver_storage[uni->num_driver_storage].data = data; 111 112 uni->num_driver_storage++; 113} 114 115/** 116 * Sever all connections with all pieces of driver storage for all uniforms 117 * 118 * \warning 119 * This function does \b not release any of the \c data pointers 120 * previously passed in to \c _mesa_uniform_attach_driver_stoarge. 121 */ 122void 123_mesa_uniform_detach_all_driver_storage(struct gl_uniform_storage *uni) 124{ 125 free(uni->driver_storage); 126 uni->driver_storage = NULL; 127 uni->num_driver_storage = 0; 128} 129 130void GLAPIENTRY 131_mesa_Uniform1fARB(GLint location, GLfloat v0) 132{ 133 GET_CURRENT_CONTEXT(ctx); 134 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, &v0, GL_FLOAT); 135} 136 137void GLAPIENTRY 138_mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1) 139{ 140 GET_CURRENT_CONTEXT(ctx); 141 GLfloat v[2]; 142 v[0] = v0; 143 v[1] = v1; 144 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_FLOAT_VEC2); 145} 146 147void GLAPIENTRY 148_mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) 149{ 150 GET_CURRENT_CONTEXT(ctx); 151 GLfloat v[3]; 152 v[0] = v0; 153 v[1] = v1; 154 v[2] = v2; 155 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_FLOAT_VEC3); 156} 157 158void GLAPIENTRY 159_mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, 160 GLfloat v3) 161{ 162 GET_CURRENT_CONTEXT(ctx); 163 GLfloat v[4]; 164 v[0] = v0; 165 v[1] = v1; 166 v[2] = v2; 167 v[3] = v3; 168 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_FLOAT_VEC4); 169} 170 171void GLAPIENTRY 172_mesa_Uniform1iARB(GLint location, GLint v0) 173{ 174 GET_CURRENT_CONTEXT(ctx); 175 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, &v0, GL_INT); 176} 177 178void GLAPIENTRY 179_mesa_Uniform2iARB(GLint location, GLint v0, GLint v1) 180{ 181 GET_CURRENT_CONTEXT(ctx); 182 GLint v[2]; 183 v[0] = v0; 184 v[1] = v1; 185 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_INT_VEC2); 186} 187 188void GLAPIENTRY 189_mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2) 190{ 191 GET_CURRENT_CONTEXT(ctx); 192 GLint v[3]; 193 v[0] = v0; 194 v[1] = v1; 195 v[2] = v2; 196 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_INT_VEC3); 197} 198 199void GLAPIENTRY 200_mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) 201{ 202 GET_CURRENT_CONTEXT(ctx); 203 GLint v[4]; 204 v[0] = v0; 205 v[1] = v1; 206 v[2] = v2; 207 v[3] = v3; 208 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_INT_VEC4); 209} 210 211void GLAPIENTRY 212_mesa_Uniform1fvARB(GLint location, GLsizei count, const GLfloat * value) 213{ 214 GET_CURRENT_CONTEXT(ctx); 215 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT); 216} 217 218void GLAPIENTRY 219_mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value) 220{ 221 GET_CURRENT_CONTEXT(ctx); 222 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT_VEC2); 223} 224 225void GLAPIENTRY 226_mesa_Uniform3fvARB(GLint location, GLsizei count, const GLfloat * value) 227{ 228 GET_CURRENT_CONTEXT(ctx); 229 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT_VEC3); 230} 231 232void GLAPIENTRY 233_mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value) 234{ 235 GET_CURRENT_CONTEXT(ctx); 236 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT_VEC4); 237} 238 239void GLAPIENTRY 240_mesa_Uniform1ivARB(GLint location, GLsizei count, const GLint * value) 241{ 242 GET_CURRENT_CONTEXT(ctx); 243 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT); 244} 245 246void GLAPIENTRY 247_mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value) 248{ 249 GET_CURRENT_CONTEXT(ctx); 250 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC2); 251} 252 253void GLAPIENTRY 254_mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value) 255{ 256 GET_CURRENT_CONTEXT(ctx); 257 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC3); 258} 259 260void GLAPIENTRY 261_mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value) 262{ 263 GET_CURRENT_CONTEXT(ctx); 264 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC4); 265} 266 267 268/** OpenGL 3.0 GLuint-valued functions **/ 269void GLAPIENTRY 270_mesa_Uniform1ui(GLint location, GLuint v0) 271{ 272 GET_CURRENT_CONTEXT(ctx); 273 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, &v0, GL_UNSIGNED_INT); 274} 275 276void GLAPIENTRY 277_mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1) 278{ 279 GET_CURRENT_CONTEXT(ctx); 280 GLuint v[2]; 281 v[0] = v0; 282 v[1] = v1; 283 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC2); 284} 285 286void GLAPIENTRY 287_mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) 288{ 289 GET_CURRENT_CONTEXT(ctx); 290 GLuint v[3]; 291 v[0] = v0; 292 v[1] = v1; 293 v[2] = v2; 294 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC3); 295} 296 297void GLAPIENTRY 298_mesa_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) 299{ 300 GET_CURRENT_CONTEXT(ctx); 301 GLuint v[4]; 302 v[0] = v0; 303 v[1] = v1; 304 v[2] = v2; 305 v[3] = v3; 306 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC4); 307} 308 309void GLAPIENTRY 310_mesa_Uniform1uiv(GLint location, GLsizei count, const GLuint *value) 311{ 312 GET_CURRENT_CONTEXT(ctx); 313 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT); 314} 315 316void GLAPIENTRY 317_mesa_Uniform2uiv(GLint location, GLsizei count, const GLuint *value) 318{ 319 GET_CURRENT_CONTEXT(ctx); 320 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC2); 321} 322 323void GLAPIENTRY 324_mesa_Uniform3uiv(GLint location, GLsizei count, const GLuint *value) 325{ 326 GET_CURRENT_CONTEXT(ctx); 327 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC3); 328} 329 330void GLAPIENTRY 331_mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value) 332{ 333 GET_CURRENT_CONTEXT(ctx); 334 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC4); 335} 336 337 338 339void GLAPIENTRY 340_mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose, 341 const GLfloat * value) 342{ 343 GET_CURRENT_CONTEXT(ctx); 344 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram, 345 2, 2, location, count, transpose, value); 346} 347 348void GLAPIENTRY 349_mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose, 350 const GLfloat * value) 351{ 352 GET_CURRENT_CONTEXT(ctx); 353 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram, 354 3, 3, location, count, transpose, value); 355} 356 357void GLAPIENTRY 358_mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose, 359 const GLfloat * value) 360{ 361 GET_CURRENT_CONTEXT(ctx); 362 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram, 363 4, 4, location, count, transpose, value); 364} 365 366 367/** 368 * Non-square UniformMatrix are OpenGL 2.1 369 */ 370void GLAPIENTRY 371_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, 372 const GLfloat *value) 373{ 374 GET_CURRENT_CONTEXT(ctx); 375 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram, 376 2, 3, location, count, transpose, value); 377} 378 379void GLAPIENTRY 380_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, 381 const GLfloat *value) 382{ 383 GET_CURRENT_CONTEXT(ctx); 384 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram, 385 3, 2, location, count, transpose, value); 386} 387 388void GLAPIENTRY 389_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, 390 const GLfloat *value) 391{ 392 GET_CURRENT_CONTEXT(ctx); 393 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram, 394 2, 4, location, count, transpose, value); 395} 396 397void GLAPIENTRY 398_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, 399 const GLfloat *value) 400{ 401 GET_CURRENT_CONTEXT(ctx); 402 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram, 403 4, 2, location, count, transpose, value); 404} 405 406void GLAPIENTRY 407_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, 408 const GLfloat *value) 409{ 410 GET_CURRENT_CONTEXT(ctx); 411 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram, 412 3, 4, location, count, transpose, value); 413} 414 415void GLAPIENTRY 416_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, 417 const GLfloat *value) 418{ 419 GET_CURRENT_CONTEXT(ctx); 420 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram, 421 4, 3, location, count, transpose, value); 422} 423 424 425void GLAPIENTRY 426_mesa_GetnUniformfvARB(GLhandleARB program, GLint location, 427 GLsizei bufSize, GLfloat *params) 428{ 429 GET_CURRENT_CONTEXT(ctx); 430 _mesa_get_uniform(ctx, program, location, bufSize, GLSL_TYPE_FLOAT, params); 431} 432 433void GLAPIENTRY 434_mesa_GetUniformfvARB(GLhandleARB program, GLint location, GLfloat *params) 435{ 436 _mesa_GetnUniformfvARB(program, location, INT_MAX, params); 437} 438 439 440void GLAPIENTRY 441_mesa_GetnUniformivARB(GLhandleARB program, GLint location, 442 GLsizei bufSize, GLint *params) 443{ 444 GET_CURRENT_CONTEXT(ctx); 445 _mesa_get_uniform(ctx, program, location, bufSize, GLSL_TYPE_INT, params); 446} 447 448void GLAPIENTRY 449_mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint *params) 450{ 451 _mesa_GetnUniformivARB(program, location, INT_MAX, params); 452} 453 454 455/* GL3 */ 456void GLAPIENTRY 457_mesa_GetnUniformuivARB(GLhandleARB program, GLint location, 458 GLsizei bufSize, GLuint *params) 459{ 460 GET_CURRENT_CONTEXT(ctx); 461 _mesa_get_uniform(ctx, program, location, bufSize, GLSL_TYPE_UINT, params); 462} 463 464void GLAPIENTRY 465_mesa_GetUniformuiv(GLhandleARB program, GLint location, GLuint *params) 466{ 467 _mesa_GetnUniformuivARB(program, location, INT_MAX, params); 468} 469 470 471/* GL4 */ 472void GLAPIENTRY 473_mesa_GetnUniformdvARB(GLhandleARB program, GLint location, 474 GLsizei bufSize, GLdouble *params) 475{ 476 GET_CURRENT_CONTEXT(ctx); 477 478 (void) program; 479 (void) location; 480 (void) bufSize; 481 (void) params; 482 483 /* 484 _mesa_get_uniform(ctx, program, location, bufSize, GLSL_TYPE_DOUBLE, params); 485 */ 486 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformdvARB" 487 "(GL_ARB_gpu_shader_fp64 not implemented)"); 488} 489 490void GLAPIENTRY 491_mesa_GetUniformdv(GLhandleARB program, GLint location, GLdouble *params) 492{ 493 _mesa_GetnUniformdvARB(program, location, INT_MAX, params); 494} 495 496 497GLint GLAPIENTRY 498_mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB *name) 499{ 500 struct gl_shader_program *shProg; 501 GLuint index, offset; 502 503 GET_CURRENT_CONTEXT(ctx); 504 505 shProg = _mesa_lookup_shader_program_err(ctx, programObj, 506 "glGetUniformLocation"); 507 if (!shProg) 508 return -1; 509 510 /* Page 80 (page 94 of the PDF) of the OpenGL 2.1 spec says: 511 * 512 * "If program has not been successfully linked, the error 513 * INVALID_OPERATION is generated." 514 */ 515 if (shProg->LinkStatus == GL_FALSE) { 516 _mesa_error(ctx, GL_INVALID_OPERATION, 517 "glGetUniformLocation(program not linked)"); 518 return -1; 519 } 520 521 index = _mesa_get_uniform_location(ctx, shProg, name, &offset); 522 if (index == GL_INVALID_INDEX) 523 return -1; 524 525 return _mesa_uniform_merge_location_offset(index, offset); 526} 527 528static GLuint GLAPIENTRY 529_mesa_GetUniformBlockIndex(GLuint program, 530 const GLchar *uniformBlockName) 531{ 532 GET_CURRENT_CONTEXT(ctx); 533 GLuint i; 534 struct gl_shader_program *shProg; 535 536 if (!ctx->Extensions.ARB_uniform_buffer_object) { 537 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformBlockIndex"); 538 return GL_INVALID_INDEX; 539 } 540 541 shProg = _mesa_lookup_shader_program_err(ctx, program, 542 "glGetUniformBlockIndex"); 543 if (!shProg) 544 return GL_INVALID_INDEX; 545 546 for (i = 0; i < shProg->NumUniformBlocks; i++) { 547 if (!strcmp(shProg->UniformBlocks[i].Name, uniformBlockName)) 548 return i; 549 } 550 551 return GL_INVALID_INDEX; 552} 553 554static void GLAPIENTRY 555_mesa_GetUniformIndices(GLuint program, 556 GLsizei uniformCount, 557 const GLchar * const *uniformNames, 558 GLuint *uniformIndices) 559{ 560 GET_CURRENT_CONTEXT(ctx); 561 GLsizei i; 562 struct gl_shader_program *shProg; 563 564 if (!ctx->Extensions.ARB_uniform_buffer_object) { 565 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformIndices"); 566 return; 567 } 568 569 shProg = _mesa_lookup_shader_program_err(ctx, program, 570 "glGetUniformIndices"); 571 if (!shProg) 572 return; 573 574 if (uniformCount < 0) { 575 _mesa_error(ctx, GL_INVALID_VALUE, 576 "glGetUniformIndices(uniformCount < 0)"); 577 return; 578 } 579 580 for (i = 0; i < uniformCount; i++) { 581 unsigned offset; 582 uniformIndices[i] = _mesa_get_uniform_location(ctx, shProg, 583 uniformNames[i], &offset); 584 } 585} 586 587static void GLAPIENTRY 588_mesa_UniformBlockBinding(GLuint program, 589 GLuint uniformBlockIndex, 590 GLuint uniformBlockBinding) 591{ 592 GET_CURRENT_CONTEXT(ctx); 593 struct gl_shader_program *shProg; 594 595 if (!ctx->Extensions.ARB_uniform_buffer_object) { 596 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformBlockBinding"); 597 return; 598 } 599 600 shProg = _mesa_lookup_shader_program_err(ctx, program, 601 "glUniformBlockBinding"); 602 if (!shProg) 603 return; 604 605 if (uniformBlockIndex >= shProg->NumUniformBlocks) { 606 _mesa_error(ctx, GL_INVALID_VALUE, 607 "glUniformBlockBinding(block index %d >= %d)", 608 uniformBlockIndex, shProg->NumUniformBlocks); 609 return; 610 } 611 612 if (uniformBlockBinding >= ctx->Const.MaxUniformBufferBindings) { 613 _mesa_error(ctx, GL_INVALID_VALUE, 614 "glUniformBlockBinding(block binding %d >= %d)", 615 uniformBlockBinding, ctx->Const.MaxUniformBufferBindings); 616 return; 617 } 618 619 if (shProg->UniformBlocks[uniformBlockIndex].Binding != 620 uniformBlockBinding) { 621 int i; 622 623 FLUSH_VERTICES(ctx, _NEW_BUFFER_OBJECT); 624 shProg->UniformBlocks[uniformBlockIndex].Binding = uniformBlockBinding; 625 626 for (i = 0; i < MESA_SHADER_TYPES; i++) { 627 int stage_index = shProg->UniformBlockStageIndex[i][uniformBlockIndex]; 628 629 if (stage_index != -1) { 630 struct gl_shader *sh = shProg->_LinkedShaders[i]; 631 sh->UniformBlocks[stage_index].Binding = uniformBlockBinding; 632 } 633 } 634 } 635} 636 637static void GLAPIENTRY 638_mesa_GetActiveUniformBlockiv(GLuint program, 639 GLuint uniformBlockIndex, 640 GLenum pname, 641 GLint *params) 642{ 643 GET_CURRENT_CONTEXT(ctx); 644 struct gl_shader_program *shProg; 645 struct gl_uniform_block *block; 646 647 if (!ctx->Extensions.ARB_uniform_buffer_object) { 648 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniformBlockiv"); 649 return; 650 } 651 652 shProg = _mesa_lookup_shader_program_err(ctx, program, 653 "glGetActiveUniformBlockiv"); 654 if (!shProg) 655 return; 656 657 if (uniformBlockIndex >= shProg->NumUniformBlocks) { 658 _mesa_error(ctx, GL_INVALID_VALUE, 659 "glGetActiveUniformBlockiv(block index %d >= %d)", 660 uniformBlockIndex, shProg->NumUniformBlocks); 661 return; 662 } 663 664 block = &shProg->UniformBlocks[uniformBlockIndex]; 665 666 switch (pname) { 667 case GL_UNIFORM_BLOCK_BINDING: 668 params[0] = block->Binding; 669 return; 670 671 case GL_UNIFORM_BLOCK_NAME_LENGTH: 672 params[0] = strlen(block->Name) + 1; 673 return; 674 675 default: 676 _mesa_error(ctx, GL_INVALID_ENUM, 677 "glGetActiveUniformBlockiv(pname 0x%x (%s))", 678 pname, _mesa_lookup_enum_by_nr(pname)); 679 return; 680 } 681} 682 683static void GLAPIENTRY 684_mesa_GetActiveUniformBlockName(GLuint program, 685 GLuint uniformBlockIndex, 686 GLsizei bufSize, 687 GLsizei *length, 688 GLchar *uniformBlockName) 689{ 690 GET_CURRENT_CONTEXT(ctx); 691 struct gl_shader_program *shProg; 692 struct gl_uniform_block *block; 693 694 if (!ctx->Extensions.ARB_uniform_buffer_object) { 695 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniformBlockiv"); 696 return; 697 } 698 699 if (bufSize < 0) { 700 _mesa_error(ctx, GL_INVALID_VALUE, 701 "glGetActiveUniformBlockName(bufSize %d < 0)", 702 bufSize); 703 return; 704 } 705 706 shProg = _mesa_lookup_shader_program_err(ctx, program, 707 "glGetActiveUniformBlockiv"); 708 if (!shProg) 709 return; 710 711 if (uniformBlockIndex >= shProg->NumUniformBlocks) { 712 _mesa_error(ctx, GL_INVALID_VALUE, 713 "glGetActiveUniformBlockiv(block index %d >= %d)", 714 uniformBlockIndex, shProg->NumUniformBlocks); 715 return; 716 } 717 718 block = &shProg->UniformBlocks[uniformBlockIndex]; 719 720 if (uniformBlockName) { 721 _mesa_copy_string(uniformBlockName, bufSize, length, block->Name); 722 } 723} 724 725/** 726 * Plug in shader uniform-related functions into API dispatch table. 727 */ 728void 729_mesa_init_shader_uniform_dispatch(struct _glapi_table *exec) 730{ 731#if FEATURE_GL 732 SET_Uniform1fARB(exec, _mesa_Uniform1fARB); 733 SET_Uniform2fARB(exec, _mesa_Uniform2fARB); 734 SET_Uniform3fARB(exec, _mesa_Uniform3fARB); 735 SET_Uniform4fARB(exec, _mesa_Uniform4fARB); 736 SET_Uniform1iARB(exec, _mesa_Uniform1iARB); 737 SET_Uniform2iARB(exec, _mesa_Uniform2iARB); 738 SET_Uniform3iARB(exec, _mesa_Uniform3iARB); 739 SET_Uniform4iARB(exec, _mesa_Uniform4iARB); 740 SET_Uniform1fvARB(exec, _mesa_Uniform1fvARB); 741 SET_Uniform2fvARB(exec, _mesa_Uniform2fvARB); 742 SET_Uniform3fvARB(exec, _mesa_Uniform3fvARB); 743 SET_Uniform4fvARB(exec, _mesa_Uniform4fvARB); 744 SET_Uniform1ivARB(exec, _mesa_Uniform1ivARB); 745 SET_Uniform2ivARB(exec, _mesa_Uniform2ivARB); 746 SET_Uniform3ivARB(exec, _mesa_Uniform3ivARB); 747 SET_Uniform4ivARB(exec, _mesa_Uniform4ivARB); 748 SET_UniformMatrix2fvARB(exec, _mesa_UniformMatrix2fvARB); 749 SET_UniformMatrix3fvARB(exec, _mesa_UniformMatrix3fvARB); 750 SET_UniformMatrix4fvARB(exec, _mesa_UniformMatrix4fvARB); 751 752 SET_GetActiveUniformARB(exec, _mesa_GetActiveUniformARB); 753 SET_GetUniformLocationARB(exec, _mesa_GetUniformLocationARB); 754 SET_GetUniformfvARB(exec, _mesa_GetUniformfvARB); 755 SET_GetUniformivARB(exec, _mesa_GetUniformivARB); 756 757 /* OpenGL 2.1 */ 758 SET_UniformMatrix2x3fv(exec, _mesa_UniformMatrix2x3fv); 759 SET_UniformMatrix3x2fv(exec, _mesa_UniformMatrix3x2fv); 760 SET_UniformMatrix2x4fv(exec, _mesa_UniformMatrix2x4fv); 761 SET_UniformMatrix4x2fv(exec, _mesa_UniformMatrix4x2fv); 762 SET_UniformMatrix3x4fv(exec, _mesa_UniformMatrix3x4fv); 763 SET_UniformMatrix4x3fv(exec, _mesa_UniformMatrix4x3fv); 764 765 /* OpenGL 3.0 */ 766 SET_Uniform1uiEXT(exec, _mesa_Uniform1ui); 767 SET_Uniform2uiEXT(exec, _mesa_Uniform2ui); 768 SET_Uniform3uiEXT(exec, _mesa_Uniform3ui); 769 SET_Uniform4uiEXT(exec, _mesa_Uniform4ui); 770 SET_Uniform1uivEXT(exec, _mesa_Uniform1uiv); 771 SET_Uniform2uivEXT(exec, _mesa_Uniform2uiv); 772 SET_Uniform3uivEXT(exec, _mesa_Uniform3uiv); 773 SET_Uniform4uivEXT(exec, _mesa_Uniform4uiv); 774 SET_GetUniformuivEXT(exec, _mesa_GetUniformuiv); 775 776 /* GL_ARB_robustness */ 777 SET_GetnUniformfvARB(exec, _mesa_GetnUniformfvARB); 778 SET_GetnUniformivARB(exec, _mesa_GetnUniformivARB); 779 SET_GetnUniformuivARB(exec, _mesa_GetnUniformuivARB); 780 SET_GetnUniformdvARB(exec, _mesa_GetnUniformdvARB); /* GL 4.0 */ 781 782 /* GL_ARB_uniform_buffer_object / GL 3.1 */ 783 SET_GetUniformBlockIndex(exec, _mesa_GetUniformBlockIndex); 784 SET_GetUniformIndices(exec, _mesa_GetUniformIndices); 785 SET_GetActiveUniformsiv(exec, _mesa_GetActiveUniformsiv); 786 SET_GetActiveUniformBlockiv(exec, _mesa_GetActiveUniformBlockiv); 787 SET_GetActiveUniformBlockName(exec, _mesa_GetActiveUniformBlockName); 788 SET_UniformBlockBinding(exec, _mesa_UniformBlockBinding); 789 790#endif /* FEATURE_GL */ 791} 792