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 */ 63 void 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 */ 95 void 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 */ 122 void 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 130 void 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 137 void 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 147 void 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 158 void 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 171 void 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 178 void 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 188 void 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 199 void 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 211 void 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 218 void 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 225 void 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 232 void 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 239 void 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 246 void 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 253 void 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 260 void 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 **/ 269 void 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 276 void 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 286 void 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 297 void 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 309 void 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 316 void 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 323 void 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 330 void 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 339 void 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 348 void 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 357 void 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 */ 370 void 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 379 void 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 388 void 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 397 void 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 406 void 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 415 void 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 425 void 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 433 void GLAPIENTRY 434 _mesa_GetUniformfvARB(GLhandleARB program, GLint location, GLfloat *params) 435 { 436 _mesa_GetnUniformfvARB(program, location, INT_MAX, params); 437 } 438 439 440 void 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 448 void GLAPIENTRY 449 _mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint *params) 450 { 451 _mesa_GetnUniformivARB(program, location, INT_MAX, params); 452 } 453 454 455 /* GL3 */ 456 void 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 464 void GLAPIENTRY 465 _mesa_GetUniformuiv(GLhandleARB program, GLint location, GLuint *params) 466 { 467 _mesa_GetnUniformuivARB(program, location, INT_MAX, params); 468 } 469 470 471 /* GL4 */ 472 void 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 490 void GLAPIENTRY 491 _mesa_GetUniformdv(GLhandleARB program, GLint location, GLdouble *params) 492 { 493 _mesa_GetnUniformdvARB(program, location, INT_MAX, params); 494 } 495 496 497 GLint 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 /* From the GL_ARB_uniform_buffer_object spec: 526 * 527 * "The value -1 will be returned if <name> does not correspond to an 528 * active uniform variable name in <program>, if <name> is associated 529 * with a named uniform block, or if <name> starts with the reserved 530 * prefix "gl_"." 531 */ 532 if (shProg->UniformStorage[index].block_index != -1) 533 return -1; 534 535 return _mesa_uniform_merge_location_offset(index, offset); 536 } 537 538 static GLuint GLAPIENTRY 539 _mesa_GetUniformBlockIndex(GLuint program, 540 const GLchar *uniformBlockName) 541 { 542 GET_CURRENT_CONTEXT(ctx); 543 GLuint i; 544 struct gl_shader_program *shProg; 545 546 if (!ctx->Extensions.ARB_uniform_buffer_object) { 547 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformBlockIndex"); 548 return GL_INVALID_INDEX; 549 } 550 551 shProg = _mesa_lookup_shader_program_err(ctx, program, 552 "glGetUniformBlockIndex"); 553 if (!shProg) 554 return GL_INVALID_INDEX; 555 556 for (i = 0; i < shProg->NumUniformBlocks; i++) { 557 if (!strcmp(shProg->UniformBlocks[i].Name, uniformBlockName)) 558 return i; 559 } 560 561 return GL_INVALID_INDEX; 562 } 563 564 static void GLAPIENTRY 565 _mesa_GetUniformIndices(GLuint program, 566 GLsizei uniformCount, 567 const GLchar * const *uniformNames, 568 GLuint *uniformIndices) 569 { 570 GET_CURRENT_CONTEXT(ctx); 571 GLsizei i; 572 struct gl_shader_program *shProg; 573 574 if (!ctx->Extensions.ARB_uniform_buffer_object) { 575 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformIndices"); 576 return; 577 } 578 579 shProg = _mesa_lookup_shader_program_err(ctx, program, 580 "glGetUniformIndices"); 581 if (!shProg) 582 return; 583 584 if (uniformCount < 0) { 585 _mesa_error(ctx, GL_INVALID_VALUE, 586 "glGetUniformIndices(uniformCount < 0)"); 587 return; 588 } 589 590 for (i = 0; i < uniformCount; i++) { 591 unsigned offset; 592 uniformIndices[i] = _mesa_get_uniform_location(ctx, shProg, 593 uniformNames[i], &offset); 594 } 595 } 596 597 static void GLAPIENTRY 598 _mesa_UniformBlockBinding(GLuint program, 599 GLuint uniformBlockIndex, 600 GLuint uniformBlockBinding) 601 { 602 GET_CURRENT_CONTEXT(ctx); 603 struct gl_shader_program *shProg; 604 605 if (!ctx->Extensions.ARB_uniform_buffer_object) { 606 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformBlockBinding"); 607 return; 608 } 609 610 shProg = _mesa_lookup_shader_program_err(ctx, program, 611 "glUniformBlockBinding"); 612 if (!shProg) 613 return; 614 615 if (uniformBlockIndex >= shProg->NumUniformBlocks) { 616 _mesa_error(ctx, GL_INVALID_VALUE, 617 "glUniformBlockBinding(block index %d >= %d)", 618 uniformBlockIndex, shProg->NumUniformBlocks); 619 return; 620 } 621 622 if (uniformBlockBinding >= ctx->Const.MaxUniformBufferBindings) { 623 _mesa_error(ctx, GL_INVALID_VALUE, 624 "glUniformBlockBinding(block binding %d >= %d)", 625 uniformBlockBinding, ctx->Const.MaxUniformBufferBindings); 626 return; 627 } 628 629 if (shProg->UniformBlocks[uniformBlockIndex].Binding != 630 uniformBlockBinding) { 631 int i; 632 633 FLUSH_VERTICES(ctx, _NEW_BUFFER_OBJECT); 634 shProg->UniformBlocks[uniformBlockIndex].Binding = uniformBlockBinding; 635 636 for (i = 0; i < MESA_SHADER_TYPES; i++) { 637 int stage_index = shProg->UniformBlockStageIndex[i][uniformBlockIndex]; 638 639 if (stage_index != -1) { 640 struct gl_shader *sh = shProg->_LinkedShaders[i]; 641 sh->UniformBlocks[stage_index].Binding = uniformBlockBinding; 642 } 643 } 644 } 645 } 646 647 static void GLAPIENTRY 648 _mesa_GetActiveUniformBlockiv(GLuint program, 649 GLuint uniformBlockIndex, 650 GLenum pname, 651 GLint *params) 652 { 653 GET_CURRENT_CONTEXT(ctx); 654 struct gl_shader_program *shProg; 655 struct gl_uniform_block *block; 656 unsigned i; 657 658 if (!ctx->Extensions.ARB_uniform_buffer_object) { 659 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniformBlockiv"); 660 return; 661 } 662 663 shProg = _mesa_lookup_shader_program_err(ctx, program, 664 "glGetActiveUniformBlockiv"); 665 if (!shProg) 666 return; 667 668 if (uniformBlockIndex >= shProg->NumUniformBlocks) { 669 _mesa_error(ctx, GL_INVALID_VALUE, 670 "glGetActiveUniformBlockiv(block index %d >= %d)", 671 uniformBlockIndex, shProg->NumUniformBlocks); 672 return; 673 } 674 675 block = &shProg->UniformBlocks[uniformBlockIndex]; 676 677 switch (pname) { 678 case GL_UNIFORM_BLOCK_BINDING: 679 params[0] = block->Binding; 680 return; 681 682 case GL_UNIFORM_BLOCK_DATA_SIZE: 683 params[0] = block->UniformBufferSize; 684 return; 685 686 case GL_UNIFORM_BLOCK_NAME_LENGTH: 687 params[0] = strlen(block->Name) + 1; 688 return; 689 690 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: 691 params[0] = block->NumUniforms; 692 return; 693 694 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: 695 for (i = 0; i < block->NumUniforms; i++) { 696 unsigned offset; 697 params[i] = _mesa_get_uniform_location(ctx, shProg, 698 block->Uniforms[i].Name, 699 &offset); 700 } 701 return; 702 703 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: 704 params[0] = shProg->UniformBlockStageIndex[MESA_SHADER_VERTEX][uniformBlockIndex] != -1; 705 return; 706 707 case GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER: 708 params[0] = shProg->UniformBlockStageIndex[MESA_SHADER_GEOMETRY][uniformBlockIndex] != -1; 709 return; 710 711 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: 712 params[0] = shProg->UniformBlockStageIndex[MESA_SHADER_FRAGMENT][uniformBlockIndex] != -1; 713 return; 714 715 default: 716 _mesa_error(ctx, GL_INVALID_ENUM, 717 "glGetActiveUniformBlockiv(pname 0x%x (%s))", 718 pname, _mesa_lookup_enum_by_nr(pname)); 719 return; 720 } 721 } 722 723 static void GLAPIENTRY 724 _mesa_GetActiveUniformBlockName(GLuint program, 725 GLuint uniformBlockIndex, 726 GLsizei bufSize, 727 GLsizei *length, 728 GLchar *uniformBlockName) 729 { 730 GET_CURRENT_CONTEXT(ctx); 731 struct gl_shader_program *shProg; 732 struct gl_uniform_block *block; 733 734 if (!ctx->Extensions.ARB_uniform_buffer_object) { 735 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniformBlockiv"); 736 return; 737 } 738 739 if (bufSize < 0) { 740 _mesa_error(ctx, GL_INVALID_VALUE, 741 "glGetActiveUniformBlockName(bufSize %d < 0)", 742 bufSize); 743 return; 744 } 745 746 shProg = _mesa_lookup_shader_program_err(ctx, program, 747 "glGetActiveUniformBlockiv"); 748 if (!shProg) 749 return; 750 751 if (uniformBlockIndex >= shProg->NumUniformBlocks) { 752 _mesa_error(ctx, GL_INVALID_VALUE, 753 "glGetActiveUniformBlockiv(block index %d >= %d)", 754 uniformBlockIndex, shProg->NumUniformBlocks); 755 return; 756 } 757 758 block = &shProg->UniformBlocks[uniformBlockIndex]; 759 760 if (uniformBlockName) { 761 _mesa_copy_string(uniformBlockName, bufSize, length, block->Name); 762 } 763 } 764 765 static void GLAPIENTRY 766 _mesa_GetActiveUniformName(GLuint program, GLuint uniformIndex, 767 GLsizei bufSize, GLsizei *length, 768 GLchar *uniformName) 769 { 770 GET_CURRENT_CONTEXT(ctx); 771 struct gl_shader_program *shProg; 772 773 if (!ctx->Extensions.ARB_uniform_buffer_object) { 774 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniformBlockiv"); 775 return; 776 } 777 778 if (bufSize < 0) { 779 _mesa_error(ctx, GL_INVALID_VALUE, 780 "glGetActiveUniformName(bufSize %d < 0)", 781 bufSize); 782 return; 783 } 784 785 ASSERT_OUTSIDE_BEGIN_END(ctx); 786 787 shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniformName"); 788 789 if (!shProg) 790 return; 791 792 if (uniformIndex >= shProg->NumUserUniformStorage) { 793 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)"); 794 return; 795 } 796 797 if (uniformName) { 798 _mesa_copy_string(uniformName, bufSize, length, 799 shProg->UniformStorage[uniformIndex].name); 800 } 801 } 802 803 /** 804 * Plug in shader uniform-related functions into API dispatch table. 805 */ 806 void 807 _mesa_init_shader_uniform_dispatch(const struct gl_context *ctx, 808 struct _glapi_table *exec) 809 { 810 #if FEATURE_GL 811 SET_Uniform1fARB(exec, _mesa_Uniform1fARB); 812 SET_Uniform2fARB(exec, _mesa_Uniform2fARB); 813 SET_Uniform3fARB(exec, _mesa_Uniform3fARB); 814 SET_Uniform4fARB(exec, _mesa_Uniform4fARB); 815 SET_Uniform1iARB(exec, _mesa_Uniform1iARB); 816 SET_Uniform2iARB(exec, _mesa_Uniform2iARB); 817 SET_Uniform3iARB(exec, _mesa_Uniform3iARB); 818 SET_Uniform4iARB(exec, _mesa_Uniform4iARB); 819 SET_Uniform1fvARB(exec, _mesa_Uniform1fvARB); 820 SET_Uniform2fvARB(exec, _mesa_Uniform2fvARB); 821 SET_Uniform3fvARB(exec, _mesa_Uniform3fvARB); 822 SET_Uniform4fvARB(exec, _mesa_Uniform4fvARB); 823 SET_Uniform1ivARB(exec, _mesa_Uniform1ivARB); 824 SET_Uniform2ivARB(exec, _mesa_Uniform2ivARB); 825 SET_Uniform3ivARB(exec, _mesa_Uniform3ivARB); 826 SET_Uniform4ivARB(exec, _mesa_Uniform4ivARB); 827 SET_UniformMatrix2fvARB(exec, _mesa_UniformMatrix2fvARB); 828 SET_UniformMatrix3fvARB(exec, _mesa_UniformMatrix3fvARB); 829 SET_UniformMatrix4fvARB(exec, _mesa_UniformMatrix4fvARB); 830 831 SET_GetActiveUniformARB(exec, _mesa_GetActiveUniformARB); 832 SET_GetUniformLocationARB(exec, _mesa_GetUniformLocationARB); 833 SET_GetUniformfvARB(exec, _mesa_GetUniformfvARB); 834 SET_GetUniformivARB(exec, _mesa_GetUniformivARB); 835 836 /* OpenGL 2.1 */ 837 if (ctx->API != API_OPENGLES2 || _mesa_is_gles3(ctx)) { 838 SET_UniformMatrix2x3fv(exec, _mesa_UniformMatrix2x3fv); 839 SET_UniformMatrix3x2fv(exec, _mesa_UniformMatrix3x2fv); 840 SET_UniformMatrix2x4fv(exec, _mesa_UniformMatrix2x4fv); 841 SET_UniformMatrix4x2fv(exec, _mesa_UniformMatrix4x2fv); 842 SET_UniformMatrix3x4fv(exec, _mesa_UniformMatrix3x4fv); 843 SET_UniformMatrix4x3fv(exec, _mesa_UniformMatrix4x3fv); 844 845 /* OpenGL 3.0 */ 846 SET_Uniform1uiEXT(exec, _mesa_Uniform1ui); 847 SET_Uniform2uiEXT(exec, _mesa_Uniform2ui); 848 SET_Uniform3uiEXT(exec, _mesa_Uniform3ui); 849 SET_Uniform4uiEXT(exec, _mesa_Uniform4ui); 850 SET_Uniform1uivEXT(exec, _mesa_Uniform1uiv); 851 SET_Uniform2uivEXT(exec, _mesa_Uniform2uiv); 852 SET_Uniform3uivEXT(exec, _mesa_Uniform3uiv); 853 SET_Uniform4uivEXT(exec, _mesa_Uniform4uiv); 854 SET_GetUniformuivEXT(exec, _mesa_GetUniformuiv); 855 856 /* GL_ARB_robustness */ 857 SET_GetnUniformfvARB(exec, _mesa_GetnUniformfvARB); 858 SET_GetnUniformivARB(exec, _mesa_GetnUniformivARB); 859 SET_GetnUniformuivARB(exec, _mesa_GetnUniformuivARB); 860 SET_GetnUniformdvARB(exec, _mesa_GetnUniformdvARB); /* GL 4.0 */ 861 862 /* GL_ARB_uniform_buffer_object / GL 3.1 */ 863 SET_GetUniformBlockIndex(exec, _mesa_GetUniformBlockIndex); 864 SET_GetUniformIndices(exec, _mesa_GetUniformIndices); 865 SET_GetActiveUniformsiv(exec, _mesa_GetActiveUniformsiv); 866 SET_GetActiveUniformBlockiv(exec, _mesa_GetActiveUniformBlockiv); 867 SET_GetActiveUniformBlockName(exec, _mesa_GetActiveUniformBlockName); 868 SET_GetActiveUniformName(exec, _mesa_GetActiveUniformName); 869 SET_UniformBlockBinding(exec, _mesa_UniformBlockBinding); 870 } 871 #endif /* FEATURE_GL */ 872 } 873