1/* 2 * Copyright © 2011 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24/** 25 * \file shader_query.cpp 26 * C-to-C++ bridge functions to query GLSL shader data 27 * 28 * \author Ian Romanick <ian.d.romanick@intel.com> 29 */ 30 31#include "main/context.h" 32#include "main/enums.h" 33#include "main/shaderapi.h" 34#include "main/shaderobj.h" 35#include "main/uniforms.h" 36#include "compiler/glsl/glsl_symbol_table.h" 37#include "compiler/glsl/ir.h" 38#include "compiler/glsl/linker_util.h" 39#include "compiler/glsl/string_to_uint_map.h" 40#include "util/mesa-sha1.h" 41#include "c99_alloca.h" 42#include "api_exec_decl.h" 43 44static GLint 45program_resource_location(struct gl_program_resource *res, 46 unsigned array_index); 47 48/** 49 * Declare convenience functions to return resource data in a given type. 50 * Warning! this is not type safe so be *very* careful when using these. 51 */ 52#define DECL_RESOURCE_FUNC(name, type) \ 53const type * RESOURCE_ ## name (gl_program_resource *res) { \ 54 assert(res->Data); \ 55 return (type *) res->Data; \ 56} 57 58DECL_RESOURCE_FUNC(VAR, gl_shader_variable); 59DECL_RESOURCE_FUNC(UBO, gl_uniform_block); 60DECL_RESOURCE_FUNC(UNI, gl_uniform_storage); 61DECL_RESOURCE_FUNC(ATC, gl_active_atomic_buffer); 62DECL_RESOURCE_FUNC(XFV, gl_transform_feedback_varying_info); 63DECL_RESOURCE_FUNC(XFB, gl_transform_feedback_buffer); 64DECL_RESOURCE_FUNC(SUB, gl_subroutine_function); 65 66static GLenum 67mediump_to_highp_type(GLenum type) 68{ 69 switch (type) { 70 case GL_FLOAT16_NV: 71 return GL_FLOAT; 72 case GL_FLOAT16_VEC2_NV: 73 return GL_FLOAT_VEC2; 74 case GL_FLOAT16_VEC3_NV: 75 return GL_FLOAT_VEC3; 76 case GL_FLOAT16_VEC4_NV: 77 return GL_FLOAT_VEC4; 78 case GL_FLOAT16_MAT2_AMD: 79 return GL_FLOAT_MAT2; 80 case GL_FLOAT16_MAT3_AMD: 81 return GL_FLOAT_MAT3; 82 case GL_FLOAT16_MAT4_AMD: 83 return GL_FLOAT_MAT4; 84 case GL_FLOAT16_MAT2x3_AMD: 85 return GL_FLOAT_MAT2x3; 86 case GL_FLOAT16_MAT2x4_AMD: 87 return GL_FLOAT_MAT2x4; 88 case GL_FLOAT16_MAT3x2_AMD: 89 return GL_FLOAT_MAT3x2; 90 case GL_FLOAT16_MAT3x4_AMD: 91 return GL_FLOAT_MAT3x4; 92 case GL_FLOAT16_MAT4x2_AMD: 93 return GL_FLOAT_MAT4x2; 94 case GL_FLOAT16_MAT4x3_AMD: 95 return GL_FLOAT_MAT4x3; 96 default: 97 return type; 98 } 99} 100 101static void 102bind_attrib_location(struct gl_context *ctx, 103 struct gl_shader_program *const shProg, GLuint index, 104 const GLchar *name, bool no_error) 105{ 106 if (!name) 107 return; 108 109 if (!no_error) { 110 if (strncmp(name, "gl_", 3) == 0) { 111 _mesa_error(ctx, GL_INVALID_OPERATION, 112 "glBindAttribLocation(illegal name)"); 113 return; 114 } 115 116 if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) { 117 _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocation(%u >= %u)", 118 index, ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs); 119 return; 120 } 121 } 122 123 /* Replace the current value if it's already in the list. Add 124 * VERT_ATTRIB_GENERIC0 because that's how the linker differentiates 125 * between built-in attributes and user-defined attributes. 126 */ 127 shProg->AttributeBindings->put(index + VERT_ATTRIB_GENERIC0, name); 128 129 /* 130 * Note that this attribute binding won't go into effect until 131 * glLinkProgram is called again. 132 */ 133} 134 135void GLAPIENTRY 136_mesa_BindAttribLocation_no_error(GLuint program, GLuint index, 137 const GLchar *name) 138{ 139 GET_CURRENT_CONTEXT(ctx); 140 141 struct gl_shader_program *const shProg = 142 _mesa_lookup_shader_program(ctx, program); 143 bind_attrib_location(ctx, shProg, index, name, true); 144} 145 146void GLAPIENTRY 147_mesa_BindAttribLocation(GLuint program, GLuint index, 148 const GLchar *name) 149{ 150 GET_CURRENT_CONTEXT(ctx); 151 152 struct gl_shader_program *const shProg = 153 _mesa_lookup_shader_program_err(ctx, program, "glBindAttribLocation"); 154 if (!shProg) 155 return; 156 157 bind_attrib_location(ctx, shProg, index, name, false); 158} 159 160void GLAPIENTRY 161_mesa_GetActiveAttrib(GLuint program, GLuint desired_index, 162 GLsizei maxLength, GLsizei * length, GLint * size, 163 GLenum * type, GLchar * name) 164{ 165 GET_CURRENT_CONTEXT(ctx); 166 struct gl_shader_program *shProg; 167 168 if (maxLength < 0) { 169 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(maxLength < 0)"); 170 return; 171 } 172 173 shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib"); 174 if (!shProg) 175 return; 176 177 if (!shProg->data->LinkStatus) { 178 _mesa_error(ctx, GL_INVALID_VALUE, 179 "glGetActiveAttrib(program not linked)"); 180 return; 181 } 182 183 if (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) { 184 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(no vertex shader)"); 185 return; 186 } 187 188 struct gl_program_resource *res = 189 _mesa_program_resource_find_index(shProg, GL_PROGRAM_INPUT, 190 desired_index); 191 192 /* User asked for index that does not exist. */ 193 if (!res) { 194 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)"); 195 return; 196 } 197 198 const gl_shader_variable *const var = RESOURCE_VAR(res); 199 200 const char *var_name = var->name.string; 201 202 _mesa_copy_string(name, maxLength, length, var_name); 203 204 if (size) 205 _mesa_program_resource_prop(shProg, res, desired_index, GL_ARRAY_SIZE, 206 size, false, "glGetActiveAttrib"); 207 208 if (type) 209 _mesa_program_resource_prop(shProg, res, desired_index, GL_TYPE, 210 (GLint *) type, false, "glGetActiveAttrib"); 211} 212 213GLint GLAPIENTRY 214_mesa_GetAttribLocation(GLuint program, const GLchar * name) 215{ 216 GET_CURRENT_CONTEXT(ctx); 217 struct gl_shader_program *const shProg = 218 _mesa_lookup_shader_program_err(ctx, program, "glGetAttribLocation"); 219 220 if (!shProg) { 221 return -1; 222 } 223 224 if (!shProg->data->LinkStatus) { 225 _mesa_error(ctx, GL_INVALID_OPERATION, 226 "glGetAttribLocation(program not linked)"); 227 return -1; 228 } 229 230 if (!name) 231 return -1; 232 233 /* Not having a vertex shader is not an error. 234 */ 235 if (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) 236 return -1; 237 238 unsigned array_index = 0; 239 struct gl_program_resource *res = 240 _mesa_program_resource_find_name(shProg, GL_PROGRAM_INPUT, name, 241 &array_index); 242 243 if (!res) 244 return -1; 245 246 return program_resource_location(res, array_index); 247} 248 249unsigned 250_mesa_count_active_attribs(struct gl_shader_program *shProg) 251{ 252 if (!shProg->data->LinkStatus 253 || shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) { 254 return 0; 255 } 256 257 struct gl_program_resource *res = shProg->data->ProgramResourceList; 258 unsigned count = 0; 259 for (unsigned j = 0; j < shProg->data->NumProgramResourceList; 260 j++, res++) { 261 if (res->Type == GL_PROGRAM_INPUT && 262 res->StageReferences & (1 << MESA_SHADER_VERTEX)) 263 count++; 264 } 265 return count; 266} 267 268 269size_t 270_mesa_longest_attribute_name_length(struct gl_shader_program *shProg) 271{ 272 if (!shProg->data->LinkStatus 273 || shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) { 274 return 0; 275 } 276 277 struct gl_program_resource *res = shProg->data->ProgramResourceList; 278 size_t longest = 0; 279 for (unsigned j = 0; j < shProg->data->NumProgramResourceList; 280 j++, res++) { 281 if (res->Type == GL_PROGRAM_INPUT && 282 res->StageReferences & (1 << MESA_SHADER_VERTEX)) { 283 284 /* From the ARB_gl_spirv spec: 285 * 286 * "If pname is ACTIVE_ATTRIBUTE_MAX_LENGTH, the length of the 287 * longest active attribute name, including a null terminator, is 288 * returned. If no active attributes exist, zero is returned. If 289 * no name reflection information is available, one is returned." 290 */ 291 const size_t length = RESOURCE_VAR(res)->name.length; 292 293 if (length >= longest) 294 longest = length + 1; 295 } 296 } 297 298 return longest; 299} 300 301void static 302bind_frag_data_location(struct gl_shader_program *const shProg, 303 const char *name, unsigned colorNumber, 304 unsigned index) 305{ 306 /* Replace the current value if it's already in the list. Add 307 * FRAG_RESULT_DATA0 because that's how the linker differentiates 308 * between built-in attributes and user-defined attributes. 309 */ 310 shProg->FragDataBindings->put(colorNumber + FRAG_RESULT_DATA0, name); 311 shProg->FragDataIndexBindings->put(index, name); 312 313 /* 314 * Note that this binding won't go into effect until 315 * glLinkProgram is called again. 316 */ 317} 318 319void GLAPIENTRY 320_mesa_BindFragDataLocation(GLuint program, GLuint colorNumber, 321 const GLchar *name) 322{ 323 _mesa_BindFragDataLocationIndexed(program, colorNumber, 0, name); 324} 325 326void GLAPIENTRY 327_mesa_BindFragDataLocation_no_error(GLuint program, GLuint colorNumber, 328 const GLchar *name) 329{ 330 GET_CURRENT_CONTEXT(ctx); 331 332 if (!name) 333 return; 334 335 struct gl_shader_program *const shProg = 336 _mesa_lookup_shader_program(ctx, program); 337 338 bind_frag_data_location(shProg, name, colorNumber, 0); 339} 340 341void GLAPIENTRY 342_mesa_BindFragDataLocationIndexed(GLuint program, GLuint colorNumber, 343 GLuint index, const GLchar *name) 344{ 345 GET_CURRENT_CONTEXT(ctx); 346 347 struct gl_shader_program *const shProg = 348 _mesa_lookup_shader_program_err(ctx, program, "glBindFragDataLocationIndexed"); 349 if (!shProg) 350 return; 351 352 if (!name) 353 return; 354 355 if (strncmp(name, "gl_", 3) == 0) { 356 _mesa_error(ctx, GL_INVALID_OPERATION, "glBindFragDataLocationIndexed(illegal name)"); 357 return; 358 } 359 360 if (index > 1) { 361 _mesa_error(ctx, GL_INVALID_VALUE, "glBindFragDataLocationIndexed(index)"); 362 return; 363 } 364 365 if (index == 0 && colorNumber >= ctx->Const.MaxDrawBuffers) { 366 _mesa_error(ctx, GL_INVALID_VALUE, "glBindFragDataLocationIndexed(colorNumber)"); 367 return; 368 } 369 370 if (index == 1 && colorNumber >= ctx->Const.MaxDualSourceDrawBuffers) { 371 _mesa_error(ctx, GL_INVALID_VALUE, "glBindFragDataLocationIndexed(colorNumber)"); 372 return; 373 } 374 375 bind_frag_data_location(shProg, name, colorNumber, index); 376} 377 378void GLAPIENTRY 379_mesa_BindFragDataLocationIndexed_no_error(GLuint program, GLuint colorNumber, 380 GLuint index, const GLchar *name) 381{ 382 GET_CURRENT_CONTEXT(ctx); 383 384 if (!name) 385 return; 386 387 struct gl_shader_program *const shProg = 388 _mesa_lookup_shader_program(ctx, program); 389 390 bind_frag_data_location(shProg, name, colorNumber, index); 391} 392 393GLint GLAPIENTRY 394_mesa_GetFragDataIndex(GLuint program, const GLchar *name) 395{ 396 GET_CURRENT_CONTEXT(ctx); 397 struct gl_shader_program *const shProg = 398 _mesa_lookup_shader_program_err(ctx, program, "glGetFragDataIndex"); 399 400 if (!shProg) { 401 return -1; 402 } 403 404 if (!shProg->data->LinkStatus) { 405 _mesa_error(ctx, GL_INVALID_OPERATION, 406 "glGetFragDataIndex(program not linked)"); 407 return -1; 408 } 409 410 if (!name) 411 return -1; 412 413 /* Not having a fragment shader is not an error. 414 */ 415 if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL) 416 return -1; 417 418 return _mesa_program_resource_location_index(shProg, GL_PROGRAM_OUTPUT, 419 name); 420} 421 422GLint GLAPIENTRY 423_mesa_GetFragDataLocation(GLuint program, const GLchar *name) 424{ 425 GET_CURRENT_CONTEXT(ctx); 426 struct gl_shader_program *const shProg = 427 _mesa_lookup_shader_program_err(ctx, program, "glGetFragDataLocation"); 428 429 if (!shProg) { 430 return -1; 431 } 432 433 if (!shProg->data->LinkStatus) { 434 _mesa_error(ctx, GL_INVALID_OPERATION, 435 "glGetFragDataLocation(program not linked)"); 436 return -1; 437 } 438 439 if (!name) 440 return -1; 441 442 /* Not having a fragment shader is not an error. 443 */ 444 if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL) 445 return -1; 446 447 unsigned array_index = 0; 448 struct gl_program_resource *res = 449 _mesa_program_resource_find_name(shProg, GL_PROGRAM_OUTPUT, name, 450 &array_index); 451 452 if (!res) 453 return -1; 454 455 return program_resource_location(res, array_index); 456} 457 458const char* 459_mesa_program_resource_name(struct gl_program_resource *res) 460{ 461 switch (res->Type) { 462 case GL_UNIFORM_BLOCK: 463 case GL_SHADER_STORAGE_BLOCK: 464 return RESOURCE_UBO(res)->name.string; 465 case GL_TRANSFORM_FEEDBACK_VARYING: 466 return RESOURCE_XFV(res)->name.string; 467 case GL_PROGRAM_INPUT: 468 case GL_PROGRAM_OUTPUT: 469 return RESOURCE_VAR(res)->name.string; 470 case GL_UNIFORM: 471 case GL_BUFFER_VARIABLE: 472 return RESOURCE_UNI(res)->name.string; 473 case GL_VERTEX_SUBROUTINE_UNIFORM: 474 case GL_GEOMETRY_SUBROUTINE_UNIFORM: 475 case GL_FRAGMENT_SUBROUTINE_UNIFORM: 476 case GL_COMPUTE_SUBROUTINE_UNIFORM: 477 case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: 478 case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: 479 return RESOURCE_UNI(res)->name.string + MESA_SUBROUTINE_PREFIX_LEN; 480 case GL_VERTEX_SUBROUTINE: 481 case GL_GEOMETRY_SUBROUTINE: 482 case GL_FRAGMENT_SUBROUTINE: 483 case GL_COMPUTE_SUBROUTINE: 484 case GL_TESS_CONTROL_SUBROUTINE: 485 case GL_TESS_EVALUATION_SUBROUTINE: 486 return RESOURCE_SUB(res)->name.string; 487 default: 488 break; 489 } 490 return NULL; 491} 492 493int 494_mesa_program_resource_name_length(struct gl_program_resource *res) 495{ 496 switch (res->Type) { 497 case GL_UNIFORM_BLOCK: 498 case GL_SHADER_STORAGE_BLOCK: 499 return RESOURCE_UBO(res)->name.length; 500 case GL_TRANSFORM_FEEDBACK_VARYING: 501 return RESOURCE_XFV(res)->name.length; 502 case GL_PROGRAM_INPUT: 503 case GL_PROGRAM_OUTPUT: 504 return RESOURCE_VAR(res)->name.length; 505 case GL_UNIFORM: 506 case GL_BUFFER_VARIABLE: 507 return RESOURCE_UNI(res)->name.length; 508 case GL_VERTEX_SUBROUTINE_UNIFORM: 509 case GL_GEOMETRY_SUBROUTINE_UNIFORM: 510 case GL_FRAGMENT_SUBROUTINE_UNIFORM: 511 case GL_COMPUTE_SUBROUTINE_UNIFORM: 512 case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: 513 case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: 514 return RESOURCE_UNI(res)->name.length - MESA_SUBROUTINE_PREFIX_LEN; 515 case GL_VERTEX_SUBROUTINE: 516 case GL_GEOMETRY_SUBROUTINE: 517 case GL_FRAGMENT_SUBROUTINE: 518 case GL_COMPUTE_SUBROUTINE: 519 case GL_TESS_CONTROL_SUBROUTINE: 520 case GL_TESS_EVALUATION_SUBROUTINE: 521 return RESOURCE_SUB(res)->name.length; 522 default: 523 break; 524 } 525 return 0; 526} 527 528bool 529_mesa_program_get_resource_name(struct gl_program_resource *res, 530 struct gl_resource_name *out) 531{ 532 switch (res->Type) { 533 case GL_UNIFORM_BLOCK: 534 case GL_SHADER_STORAGE_BLOCK: 535 *out = RESOURCE_UBO(res)->name; 536 return out->string != NULL; 537 case GL_TRANSFORM_FEEDBACK_VARYING: 538 *out = RESOURCE_XFV(res)->name; 539 return out->string != NULL; 540 case GL_PROGRAM_INPUT: 541 case GL_PROGRAM_OUTPUT: 542 *out = RESOURCE_VAR(res)->name; 543 return out->string != NULL; 544 case GL_UNIFORM: 545 case GL_BUFFER_VARIABLE: 546 *out = RESOURCE_UNI(res)->name; 547 return out->string != NULL; 548 case GL_VERTEX_SUBROUTINE_UNIFORM: 549 case GL_GEOMETRY_SUBROUTINE_UNIFORM: 550 case GL_FRAGMENT_SUBROUTINE_UNIFORM: 551 case GL_COMPUTE_SUBROUTINE_UNIFORM: 552 case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: 553 case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: 554 *out = RESOURCE_UNI(res)->name; 555 out->string += MESA_SUBROUTINE_PREFIX_LEN; 556 out->length -= MESA_SUBROUTINE_PREFIX_LEN; 557 assert(out->string); /* always non-NULL */ 558 return true; 559 case GL_VERTEX_SUBROUTINE: 560 case GL_GEOMETRY_SUBROUTINE: 561 case GL_FRAGMENT_SUBROUTINE: 562 case GL_COMPUTE_SUBROUTINE: 563 case GL_TESS_CONTROL_SUBROUTINE: 564 case GL_TESS_EVALUATION_SUBROUTINE: 565 *out = RESOURCE_SUB(res)->name; 566 return out->string != NULL; 567 default: 568 return false; 569 } 570} 571 572unsigned 573_mesa_program_resource_array_size(struct gl_program_resource *res) 574{ 575 switch (res->Type) { 576 case GL_TRANSFORM_FEEDBACK_VARYING: 577 return RESOURCE_XFV(res)->Size > 1 ? 578 RESOURCE_XFV(res)->Size : 0; 579 case GL_PROGRAM_INPUT: 580 case GL_PROGRAM_OUTPUT: 581 return RESOURCE_VAR(res)->type->length; 582 case GL_UNIFORM: 583 case GL_VERTEX_SUBROUTINE_UNIFORM: 584 case GL_GEOMETRY_SUBROUTINE_UNIFORM: 585 case GL_FRAGMENT_SUBROUTINE_UNIFORM: 586 case GL_COMPUTE_SUBROUTINE_UNIFORM: 587 case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: 588 case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: 589 return RESOURCE_UNI(res)->array_elements; 590 case GL_BUFFER_VARIABLE: 591 /* Unsized arrays */ 592 if (RESOURCE_UNI(res)->array_stride > 0 && 593 RESOURCE_UNI(res)->array_elements == 0) 594 return 1; 595 else 596 return RESOURCE_UNI(res)->array_elements; 597 case GL_VERTEX_SUBROUTINE: 598 case GL_GEOMETRY_SUBROUTINE: 599 case GL_FRAGMENT_SUBROUTINE: 600 case GL_COMPUTE_SUBROUTINE: 601 case GL_TESS_CONTROL_SUBROUTINE: 602 case GL_TESS_EVALUATION_SUBROUTINE: 603 case GL_ATOMIC_COUNTER_BUFFER: 604 case GL_UNIFORM_BLOCK: 605 case GL_SHADER_STORAGE_BLOCK: 606 return 0; 607 default: 608 assert(!"support for resource type not implemented"); 609 } 610 return 0; 611} 612 613/** 614 * Checks if array subscript is valid and if so sets array_index. 615 */ 616static bool 617valid_array_index(const GLchar *name, int len, unsigned *array_index) 618{ 619 long idx = 0; 620 const GLchar *out_base_name_end; 621 622 idx = link_util_parse_program_resource_name(name, len, &out_base_name_end); 623 if (idx < 0) 624 return false; 625 626 if (array_index) 627 *array_index = idx; 628 629 return true; 630} 631 632static struct gl_program_resource * 633search_resource_hash(struct gl_shader_program *shProg, 634 GLenum programInterface, const char *name, int len, 635 unsigned *array_index) 636{ 637 unsigned type = GET_PROGRAM_RESOURCE_TYPE_FROM_GLENUM(programInterface); 638 assert(type < ARRAY_SIZE(shProg->data->ProgramResourceHash)); 639 640 if (!shProg->data->ProgramResourceHash[type]) 641 return NULL; 642 643 const char *base_name_end; 644 long index = link_util_parse_program_resource_name(name, len, &base_name_end); 645 char *name_copy; 646 647 /* If dealing with array, we need to get the basename. */ 648 if (index >= 0) { 649 name_copy = (char *) alloca(base_name_end - name + 1); 650 memcpy(name_copy, name, base_name_end - name); 651 name_copy[base_name_end - name] = '\0'; 652 len = base_name_end - name; 653 } else { 654 name_copy = (char*) name; 655 } 656 657 uint32_t hash = _mesa_hash_string_with_length(name_copy, len); 658 struct hash_entry *entry = 659 _mesa_hash_table_search_pre_hashed(shProg->data->ProgramResourceHash[type], 660 hash, name_copy); 661 if (!entry) 662 return NULL; 663 664 if (array_index) 665 *array_index = index >= 0 ? index : 0; 666 667 return (struct gl_program_resource *)entry->data; 668} 669 670/* Find a program resource with specific name in given interface. 671 */ 672struct gl_program_resource * 673_mesa_program_resource_find_name(struct gl_shader_program *shProg, 674 GLenum programInterface, const char *name, 675 unsigned *array_index) 676{ 677 if (name == NULL) 678 return NULL; 679 680 int len = strlen(name); 681 682 /* If we have a name, try the ProgramResourceHash first. */ 683 struct gl_program_resource *res = 684 search_resource_hash(shProg, programInterface, name, len, array_index); 685 686 if (res) 687 return res; 688 689 res = shProg->data->ProgramResourceList; 690 for (unsigned i = 0; i < shProg->data->NumProgramResourceList; i++, res++) { 691 if (res->Type != programInterface) 692 continue; 693 694 struct gl_resource_name rname; 695 696 /* Since ARB_gl_spirv lack of name reflections is a possibility */ 697 if (!_mesa_program_get_resource_name(res, &rname)) 698 continue; 699 700 bool found = false; 701 702 /* From ARB_program_interface_query spec: 703 * 704 * "uint GetProgramResourceIndex(uint program, enum programInterface, 705 * const char *name); 706 * [...] 707 * If <name> exactly matches the name string of one of the active 708 * resources for <programInterface>, the index of the matched resource is 709 * returned. Additionally, if <name> would exactly match the name string 710 * of an active resource if "[0]" were appended to <name>, the index of 711 * the matched resource is returned. [...]" 712 * 713 * "A string provided to GetProgramResourceLocation or 714 * GetProgramResourceLocationIndex is considered to match an active variable 715 * if: 716 * 717 * * the string exactly matches the name of the active variable; 718 * 719 * * if the string identifies the base name of an active array, where the 720 * string would exactly match the name of the variable if the suffix 721 * "[0]" were appended to the string; [...]" 722 */ 723 /* Remove array's index from interface block name comparison only if 724 * array's index is zero and the resulting string length is the same 725 * than the provided name's length. 726 */ 727 int length_without_array_index = 728 rname.last_square_bracket >= 0 ? rname.last_square_bracket : rname.length; 729 bool rname_has_array_index_zero = rname.suffix_is_zero_square_bracketed && 730 rname.last_square_bracket == len; 731 732 if (len >= rname.length && strncmp(rname.string, name, rname.length) == 0) 733 found = true; 734 else if (rname_has_array_index_zero && 735 strncmp(rname.string, name, length_without_array_index) == 0) 736 found = true; 737 738 if (found) { 739 switch (programInterface) { 740 case GL_UNIFORM_BLOCK: 741 case GL_SHADER_STORAGE_BLOCK: 742 /* Basename match, check if array or struct. */ 743 if (rname_has_array_index_zero || 744 name[rname.length] == '\0' || 745 name[rname.length] == '[' || 746 name[rname.length] == '.') { 747 return res; 748 } 749 break; 750 case GL_TRANSFORM_FEEDBACK_VARYING: 751 case GL_BUFFER_VARIABLE: 752 case GL_UNIFORM: 753 case GL_VERTEX_SUBROUTINE_UNIFORM: 754 case GL_GEOMETRY_SUBROUTINE_UNIFORM: 755 case GL_FRAGMENT_SUBROUTINE_UNIFORM: 756 case GL_COMPUTE_SUBROUTINE_UNIFORM: 757 case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: 758 case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: 759 case GL_VERTEX_SUBROUTINE: 760 case GL_GEOMETRY_SUBROUTINE: 761 case GL_FRAGMENT_SUBROUTINE: 762 case GL_COMPUTE_SUBROUTINE: 763 case GL_TESS_CONTROL_SUBROUTINE: 764 case GL_TESS_EVALUATION_SUBROUTINE: 765 if (name[rname.length] == '.') { 766 return res; 767 } 768 FALLTHROUGH; 769 case GL_PROGRAM_INPUT: 770 case GL_PROGRAM_OUTPUT: 771 if (name[rname.length] == '\0') { 772 return res; 773 } else if (name[rname.length] == '[' && 774 valid_array_index(name, len, array_index)) { 775 return res; 776 } 777 break; 778 default: 779 assert(!"not implemented for given interface"); 780 } 781 } 782 } 783 return NULL; 784} 785 786/* Find an uniform or buffer variable program resource with an specific offset 787 * inside a block with an specific binding. 788 * 789 * Valid interfaces are GL_BUFFER_VARIABLE and GL_UNIFORM. 790 */ 791static struct gl_program_resource * 792program_resource_find_binding_offset(struct gl_shader_program *shProg, 793 GLenum programInterface, 794 const GLuint binding, 795 const GLint offset) 796{ 797 798 /* First we need to get the BLOCK_INDEX from the BUFFER_BINDING */ 799 GLenum blockInterface; 800 801 switch (programInterface) { 802 case GL_BUFFER_VARIABLE: 803 blockInterface = GL_SHADER_STORAGE_BLOCK; 804 break; 805 case GL_UNIFORM: 806 blockInterface = GL_UNIFORM_BLOCK; 807 break; 808 default: 809 assert("Invalid program interface"); 810 return NULL; 811 } 812 813 int block_index = -1; 814 int starting_index = -1; 815 struct gl_program_resource *res = shProg->data->ProgramResourceList; 816 817 /* Blocks are added to the resource list in the same order that they are 818 * added to UniformBlocks/ShaderStorageBlocks. Furthermore, all the blocks 819 * of each type (UBO/SSBO) are contiguous, so we can infer block_index from 820 * the resource list. 821 */ 822 for (unsigned i = 0; i < shProg->data->NumProgramResourceList; i++, res++) { 823 if (res->Type != blockInterface) 824 continue; 825 826 /* Store the first index where a resource of the specific interface is. */ 827 if (starting_index == -1) 828 starting_index = i; 829 830 const struct gl_uniform_block *block = RESOURCE_UBO(res); 831 832 if (block->Binding == binding) { 833 /* For arrays, or arrays of arrays of blocks, we want the resource 834 * for the block with base index. Most properties for members of each 835 * block are inherited from the block with the base index, including 836 * a uniform being active or not. 837 */ 838 block_index = i - starting_index - block->linearized_array_index; 839 break; 840 } 841 } 842 843 if (block_index == -1) 844 return NULL; 845 846 /* We now look for the resource corresponding to the uniform or buffer 847 * variable using the BLOCK_INDEX and OFFSET. 848 */ 849 res = shProg->data->ProgramResourceList; 850 for (unsigned i = 0; i < shProg->data->NumProgramResourceList; i++, res++) { 851 if (res->Type != programInterface) 852 continue; 853 854 const struct gl_uniform_storage *uniform = RESOURCE_UNI(res); 855 856 if (uniform->block_index == block_index && uniform->offset == offset) { 857 return res; 858 } 859 } 860 861 return NULL; 862} 863 864/* Checks if an uniform or buffer variable is in the active program resource 865 * list. 866 * 867 * It takes into accout that for variables coming from SPIR-V binaries their 868 * names could not be available (ARB_gl_spirv). In that case, it will use the 869 * the offset and the block binding to locate the resource. 870 * 871 * Valid interfaces are GL_BUFFER_VARIABLE and GL_UNIFORM. 872 */ 873struct gl_program_resource * 874_mesa_program_resource_find_active_variable(struct gl_shader_program *shProg, 875 GLenum programInterface, 876 const gl_uniform_block *block, 877 unsigned index) 878{ 879 struct gl_program_resource *res; 880 struct gl_uniform_buffer_variable uni = block->Uniforms[index]; 881 882 assert(programInterface == GL_UNIFORM || 883 programInterface == GL_BUFFER_VARIABLE); 884 885 if (uni.IndexName) { 886 res = _mesa_program_resource_find_name(shProg, programInterface, uni.IndexName, 887 NULL); 888 } else { 889 /* As the resource has no associated name (ARB_gl_spirv), 890 * we can use the UBO/SSBO binding and offset to find it. 891 */ 892 res = program_resource_find_binding_offset(shProg, programInterface, 893 block->Binding, uni.Offset); 894 } 895 896 return res; 897} 898 899static GLuint 900calc_resource_index(struct gl_shader_program *shProg, 901 struct gl_program_resource *res) 902{ 903 unsigned i; 904 GLuint index = 0; 905 for (i = 0; i < shProg->data->NumProgramResourceList; i++) { 906 if (&shProg->data->ProgramResourceList[i] == res) 907 return index; 908 if (shProg->data->ProgramResourceList[i].Type == res->Type) 909 index++; 910 } 911 return GL_INVALID_INDEX; 912} 913 914/** 915 * Calculate index for the given resource. 916 */ 917GLuint 918_mesa_program_resource_index(struct gl_shader_program *shProg, 919 struct gl_program_resource *res) 920{ 921 if (!res) 922 return GL_INVALID_INDEX; 923 924 switch (res->Type) { 925 case GL_ATOMIC_COUNTER_BUFFER: 926 return RESOURCE_ATC(res) - shProg->data->AtomicBuffers; 927 case GL_VERTEX_SUBROUTINE: 928 case GL_GEOMETRY_SUBROUTINE: 929 case GL_FRAGMENT_SUBROUTINE: 930 case GL_COMPUTE_SUBROUTINE: 931 case GL_TESS_CONTROL_SUBROUTINE: 932 case GL_TESS_EVALUATION_SUBROUTINE: 933 return RESOURCE_SUB(res)->index; 934 case GL_UNIFORM_BLOCK: 935 case GL_SHADER_STORAGE_BLOCK: 936 case GL_TRANSFORM_FEEDBACK_BUFFER: 937 case GL_TRANSFORM_FEEDBACK_VARYING: 938 default: 939 return calc_resource_index(shProg, res); 940 } 941} 942 943/** 944 * Find a program resource that points to given data. 945 */ 946static struct gl_program_resource* 947program_resource_find_data(struct gl_shader_program *shProg, void *data) 948{ 949 struct gl_program_resource *res = shProg->data->ProgramResourceList; 950 for (unsigned i = 0; i < shProg->data->NumProgramResourceList; 951 i++, res++) { 952 if (res->Data == data) 953 return res; 954 } 955 return NULL; 956} 957 958/* Find a program resource with specific index in given interface. 959 */ 960struct gl_program_resource * 961_mesa_program_resource_find_index(struct gl_shader_program *shProg, 962 GLenum programInterface, GLuint index) 963{ 964 struct gl_program_resource *res = shProg->data->ProgramResourceList; 965 int idx = -1; 966 967 for (unsigned i = 0; i < shProg->data->NumProgramResourceList; 968 i++, res++) { 969 if (res->Type != programInterface) 970 continue; 971 972 switch (res->Type) { 973 case GL_UNIFORM_BLOCK: 974 case GL_ATOMIC_COUNTER_BUFFER: 975 case GL_SHADER_STORAGE_BLOCK: 976 case GL_TRANSFORM_FEEDBACK_BUFFER: 977 if (_mesa_program_resource_index(shProg, res) == index) 978 return res; 979 break; 980 case GL_TRANSFORM_FEEDBACK_VARYING: 981 case GL_PROGRAM_INPUT: 982 case GL_PROGRAM_OUTPUT: 983 case GL_UNIFORM: 984 case GL_VERTEX_SUBROUTINE_UNIFORM: 985 case GL_GEOMETRY_SUBROUTINE_UNIFORM: 986 case GL_FRAGMENT_SUBROUTINE_UNIFORM: 987 case GL_COMPUTE_SUBROUTINE_UNIFORM: 988 case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: 989 case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: 990 case GL_VERTEX_SUBROUTINE: 991 case GL_GEOMETRY_SUBROUTINE: 992 case GL_FRAGMENT_SUBROUTINE: 993 case GL_COMPUTE_SUBROUTINE: 994 case GL_TESS_CONTROL_SUBROUTINE: 995 case GL_TESS_EVALUATION_SUBROUTINE: 996 case GL_BUFFER_VARIABLE: 997 if (++idx == (int) index) 998 return res; 999 break; 1000 default: 1001 assert(!"not implemented for given interface"); 1002 } 1003 } 1004 return NULL; 1005} 1006 1007/* Function returns if resource name is expected to have index 1008 * appended into it. 1009 * 1010 * 1011 * Page 61 (page 73 of the PDF) in section 2.11 of the OpenGL ES 3.0 1012 * spec says: 1013 * 1014 * "If the active uniform is an array, the uniform name returned in 1015 * name will always be the name of the uniform array appended with 1016 * "[0]"." 1017 * 1018 * The same text also appears in the OpenGL 4.2 spec. It does not, 1019 * however, appear in any previous spec. Previous specifications are 1020 * ambiguous in this regard. However, either name can later be passed 1021 * to glGetUniformLocation (and related APIs), so there shouldn't be any 1022 * harm in always appending "[0]" to uniform array names. 1023 */ 1024static bool 1025add_index_to_name(struct gl_program_resource *res) 1026{ 1027 /* Transform feedback varyings have array index already appended 1028 * in their names. 1029 */ 1030 return res->Type != GL_TRANSFORM_FEEDBACK_VARYING; 1031} 1032 1033/* Get name length of a program resource. This consists of 1034 * base name + 3 for '[0]' if resource is an array. 1035 */ 1036extern unsigned 1037_mesa_program_resource_name_length_array(struct gl_program_resource *res) 1038{ 1039 int length = _mesa_program_resource_name_length(res); 1040 1041 /* For shaders constructed from SPIR-V binaries, variables may not 1042 * have names associated with them. 1043 */ 1044 if (!length) 1045 return 0; 1046 1047 if (_mesa_program_resource_array_size(res) && add_index_to_name(res)) 1048 length += 3; 1049 return length; 1050} 1051 1052/* Get full name of a program resource. 1053 */ 1054bool 1055_mesa_get_program_resource_name(struct gl_shader_program *shProg, 1056 GLenum programInterface, GLuint index, 1057 GLsizei bufSize, GLsizei *length, 1058 GLchar *name, bool glthread, 1059 const char *caller) 1060{ 1061 GET_CURRENT_CONTEXT(ctx); 1062 1063 /* Find resource with given interface and index. */ 1064 struct gl_program_resource *res = 1065 _mesa_program_resource_find_index(shProg, programInterface, index); 1066 1067 /* The error INVALID_VALUE is generated if <index> is greater than 1068 * or equal to the number of entries in the active resource list for 1069 * <programInterface>. 1070 */ 1071 if (!res) { 1072 _mesa_error_glthread_safe(ctx, GL_INVALID_VALUE, glthread, 1073 "%s(index %u)", caller, index); 1074 return false; 1075 } 1076 1077 if (bufSize < 0) { 1078 _mesa_error_glthread_safe(ctx, GL_INVALID_VALUE, glthread, 1079 "%s(bufSize %d)", caller, bufSize); 1080 return false; 1081 } 1082 1083 GLsizei localLength; 1084 1085 if (length == NULL) 1086 length = &localLength; 1087 1088 _mesa_copy_string(name, bufSize, length, _mesa_program_resource_name(res)); 1089 1090 /* The resource name can be NULL for shaders constructed from SPIR-V 1091 * binaries. In that case, we do not add the '[0]'. 1092 */ 1093 if (name && name[0] != '\0' && 1094 _mesa_program_resource_array_size(res) && add_index_to_name(res)) { 1095 int i; 1096 1097 /* The comparison is strange because *length does *NOT* include the 1098 * terminating NUL, but maxLength does. 1099 */ 1100 for (i = 0; i < 3 && (*length + i + 1) < bufSize; i++) 1101 name[*length + i] = "[0]"[i]; 1102 1103 name[*length + i] = '\0'; 1104 *length += i; 1105 } 1106 return true; 1107} 1108 1109static GLint 1110program_resource_location(struct gl_program_resource *res, unsigned array_index) 1111{ 1112 switch (res->Type) { 1113 case GL_PROGRAM_INPUT: { 1114 const gl_shader_variable *var = RESOURCE_VAR(res); 1115 1116 if (var->location == -1) 1117 return -1; 1118 1119 /* If the input is an array, fail if the index is out of bounds. */ 1120 if (array_index > 0 1121 && array_index >= var->type->length) { 1122 return -1; 1123 } 1124 return var->location + 1125 (array_index * var->type->without_array()->matrix_columns); 1126 } 1127 case GL_PROGRAM_OUTPUT: 1128 if (RESOURCE_VAR(res)->location == -1) 1129 return -1; 1130 1131 /* If the output is an array, fail if the index is out of bounds. */ 1132 if (array_index > 0 1133 && array_index >= RESOURCE_VAR(res)->type->length) { 1134 return -1; 1135 } 1136 return RESOURCE_VAR(res)->location + array_index; 1137 case GL_UNIFORM: 1138 /* If the uniform is built-in, fail. */ 1139 if (RESOURCE_UNI(res)->builtin) 1140 return -1; 1141 1142 /* From page 79 of the OpenGL 4.2 spec: 1143 * 1144 * "A valid name cannot be a structure, an array of structures, or any 1145 * portion of a single vector or a matrix." 1146 */ 1147 if (RESOURCE_UNI(res)->type->without_array()->is_struct()) 1148 return -1; 1149 1150 /* From the GL_ARB_uniform_buffer_object spec: 1151 * 1152 * "The value -1 will be returned if <name> does not correspond to an 1153 * active uniform variable name in <program>, if <name> is associated 1154 * with a named uniform block, or if <name> starts with the reserved 1155 * prefix "gl_"." 1156 */ 1157 if (RESOURCE_UNI(res)->block_index != -1 || 1158 RESOURCE_UNI(res)->atomic_buffer_index != -1) 1159 return -1; 1160 1161 FALLTHROUGH; 1162 case GL_VERTEX_SUBROUTINE_UNIFORM: 1163 case GL_GEOMETRY_SUBROUTINE_UNIFORM: 1164 case GL_FRAGMENT_SUBROUTINE_UNIFORM: 1165 case GL_COMPUTE_SUBROUTINE_UNIFORM: 1166 case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: 1167 case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: 1168 /* If the uniform is an array, fail if the index is out of bounds. */ 1169 if (array_index > 0 1170 && array_index >= RESOURCE_UNI(res)->array_elements) { 1171 return -1; 1172 } 1173 1174 /* location in remap table + array element offset */ 1175 return RESOURCE_UNI(res)->remap_location + array_index; 1176 default: 1177 return -1; 1178 } 1179} 1180 1181/** 1182 * Function implements following location queries: 1183 * glGetUniformLocation 1184 */ 1185GLint 1186_mesa_program_resource_location(struct gl_shader_program *shProg, 1187 GLenum programInterface, const char *name) 1188{ 1189 unsigned array_index = 0; 1190 struct gl_program_resource *res = 1191 _mesa_program_resource_find_name(shProg, programInterface, name, 1192 &array_index); 1193 1194 /* Resource not found. */ 1195 if (!res) 1196 return -1; 1197 1198 return program_resource_location(res, array_index); 1199} 1200 1201static GLint 1202_get_resource_location_index(struct gl_program_resource *res) 1203{ 1204 /* Non-existent variable or resource is not referenced by fragment stage. */ 1205 if (!res || !(res->StageReferences & (1 << MESA_SHADER_FRAGMENT))) 1206 return -1; 1207 1208 /* From OpenGL 4.5 spec, 7.3 Program Objects 1209 * "The value -1 will be returned by either command... 1210 * ... or if name identifies an active variable that does not have a 1211 * valid location assigned. 1212 */ 1213 if (RESOURCE_VAR(res)->location == -1) 1214 return -1; 1215 return RESOURCE_VAR(res)->index; 1216} 1217 1218/** 1219 * Function implements following index queries: 1220 * glGetFragDataIndex 1221 */ 1222GLint 1223_mesa_program_resource_location_index(struct gl_shader_program *shProg, 1224 GLenum programInterface, const char *name) 1225{ 1226 struct gl_program_resource *res = 1227 _mesa_program_resource_find_name(shProg, programInterface, name, NULL); 1228 1229 return _get_resource_location_index(res); 1230} 1231 1232static uint8_t 1233stage_from_enum(GLenum ref) 1234{ 1235 switch (ref) { 1236 case GL_REFERENCED_BY_VERTEX_SHADER: 1237 return MESA_SHADER_VERTEX; 1238 case GL_REFERENCED_BY_TESS_CONTROL_SHADER: 1239 return MESA_SHADER_TESS_CTRL; 1240 case GL_REFERENCED_BY_TESS_EVALUATION_SHADER: 1241 return MESA_SHADER_TESS_EVAL; 1242 case GL_REFERENCED_BY_GEOMETRY_SHADER: 1243 return MESA_SHADER_GEOMETRY; 1244 case GL_REFERENCED_BY_FRAGMENT_SHADER: 1245 return MESA_SHADER_FRAGMENT; 1246 case GL_REFERENCED_BY_COMPUTE_SHADER: 1247 return MESA_SHADER_COMPUTE; 1248 default: 1249 assert(!"shader stage not supported"); 1250 return MESA_SHADER_STAGES; 1251 } 1252} 1253 1254/** 1255 * Check if resource is referenced by given 'referenced by' stage enum. 1256 * ATC and UBO resources hold stage references of their own. 1257 */ 1258static bool 1259is_resource_referenced(struct gl_shader_program *shProg, 1260 struct gl_program_resource *res, 1261 GLuint index, uint8_t stage) 1262{ 1263 /* First, check if we even have such a stage active. */ 1264 if (!shProg->_LinkedShaders[stage]) 1265 return false; 1266 1267 if (res->Type == GL_ATOMIC_COUNTER_BUFFER) 1268 return RESOURCE_ATC(res)->StageReferences[stage]; 1269 1270 if (res->Type == GL_UNIFORM_BLOCK) 1271 return shProg->data->UniformBlocks[index].stageref & (1 << stage); 1272 1273 if (res->Type == GL_SHADER_STORAGE_BLOCK) 1274 return shProg->data->ShaderStorageBlocks[index].stageref & (1 << stage); 1275 1276 return res->StageReferences & (1 << stage); 1277} 1278 1279static unsigned 1280get_buffer_property(struct gl_shader_program *shProg, 1281 struct gl_program_resource *res, const GLenum prop, 1282 GLint *val, bool glthread, const char *caller) 1283{ 1284 GET_CURRENT_CONTEXT(ctx); 1285 if (res->Type != GL_UNIFORM_BLOCK && 1286 res->Type != GL_ATOMIC_COUNTER_BUFFER && 1287 res->Type != GL_SHADER_STORAGE_BLOCK && 1288 res->Type != GL_TRANSFORM_FEEDBACK_BUFFER) 1289 goto invalid_operation; 1290 1291 if (res->Type == GL_UNIFORM_BLOCK) { 1292 switch (prop) { 1293 case GL_BUFFER_BINDING: 1294 *val = RESOURCE_UBO(res)->Binding; 1295 return 1; 1296 case GL_BUFFER_DATA_SIZE: 1297 *val = RESOURCE_UBO(res)->UniformBufferSize; 1298 return 1; 1299 case GL_NUM_ACTIVE_VARIABLES: 1300 *val = 0; 1301 for (unsigned i = 0; i < RESOURCE_UBO(res)->NumUniforms; i++) { 1302 struct gl_program_resource *uni = 1303 _mesa_program_resource_find_active_variable( 1304 shProg, 1305 GL_UNIFORM, 1306 RESOURCE_UBO(res), 1307 i); 1308 1309 if (!uni) 1310 continue; 1311 (*val)++; 1312 } 1313 return 1; 1314 case GL_ACTIVE_VARIABLES: { 1315 unsigned num_values = 0; 1316 for (unsigned i = 0; i < RESOURCE_UBO(res)->NumUniforms; i++) { 1317 struct gl_program_resource *uni = 1318 _mesa_program_resource_find_active_variable( 1319 shProg, 1320 GL_UNIFORM, 1321 RESOURCE_UBO(res), 1322 i); 1323 1324 if (!uni) 1325 continue; 1326 *val++ = 1327 _mesa_program_resource_index(shProg, uni); 1328 num_values++; 1329 } 1330 return num_values; 1331 } 1332 } 1333 } else if (res->Type == GL_SHADER_STORAGE_BLOCK) { 1334 switch (prop) { 1335 case GL_BUFFER_BINDING: 1336 *val = RESOURCE_UBO(res)->Binding; 1337 return 1; 1338 case GL_BUFFER_DATA_SIZE: 1339 *val = RESOURCE_UBO(res)->UniformBufferSize; 1340 return 1; 1341 case GL_NUM_ACTIVE_VARIABLES: 1342 *val = 0; 1343 for (unsigned i = 0; i < RESOURCE_UBO(res)->NumUniforms; i++) { 1344 struct gl_program_resource *uni = 1345 _mesa_program_resource_find_active_variable( 1346 shProg, 1347 GL_BUFFER_VARIABLE, 1348 RESOURCE_UBO(res), 1349 i); 1350 1351 if (!uni) 1352 continue; 1353 (*val)++; 1354 } 1355 return 1; 1356 case GL_ACTIVE_VARIABLES: { 1357 unsigned num_values = 0; 1358 for (unsigned i = 0; i < RESOURCE_UBO(res)->NumUniforms; i++) { 1359 struct gl_program_resource *uni = 1360 _mesa_program_resource_find_active_variable( 1361 shProg, 1362 GL_BUFFER_VARIABLE, 1363 RESOURCE_UBO(res), 1364 i); 1365 1366 if (!uni) 1367 continue; 1368 *val++ = 1369 _mesa_program_resource_index(shProg, uni); 1370 num_values++; 1371 } 1372 return num_values; 1373 } 1374 } 1375 } else if (res->Type == GL_ATOMIC_COUNTER_BUFFER) { 1376 switch (prop) { 1377 case GL_BUFFER_BINDING: 1378 *val = RESOURCE_ATC(res)->Binding; 1379 return 1; 1380 case GL_BUFFER_DATA_SIZE: 1381 *val = RESOURCE_ATC(res)->MinimumSize; 1382 return 1; 1383 case GL_NUM_ACTIVE_VARIABLES: 1384 *val = RESOURCE_ATC(res)->NumUniforms; 1385 return 1; 1386 case GL_ACTIVE_VARIABLES: 1387 for (unsigned i = 0; i < RESOURCE_ATC(res)->NumUniforms; i++) { 1388 /* Active atomic buffer contains index to UniformStorage. Find 1389 * out gl_program_resource via data pointer and then calculate 1390 * index of that uniform. 1391 */ 1392 unsigned idx = RESOURCE_ATC(res)->Uniforms[i]; 1393 struct gl_program_resource *uni = 1394 program_resource_find_data(shProg, 1395 &shProg->data->UniformStorage[idx]); 1396 assert(uni); 1397 *val++ = _mesa_program_resource_index(shProg, uni); 1398 } 1399 return RESOURCE_ATC(res)->NumUniforms; 1400 } 1401 } else if (res->Type == GL_TRANSFORM_FEEDBACK_BUFFER) { 1402 switch (prop) { 1403 case GL_BUFFER_BINDING: 1404 *val = RESOURCE_XFB(res)->Binding; 1405 return 1; 1406 case GL_NUM_ACTIVE_VARIABLES: 1407 *val = RESOURCE_XFB(res)->NumVaryings; 1408 return 1; 1409 case GL_ACTIVE_VARIABLES: 1410 struct gl_transform_feedback_info *linked_xfb = 1411 shProg->last_vert_prog->sh.LinkedTransformFeedback; 1412 for (int i = 0; i < linked_xfb->NumVarying; i++) { 1413 unsigned index = linked_xfb->Varyings[i].BufferIndex; 1414 struct gl_program_resource *buf_res = 1415 _mesa_program_resource_find_index(shProg, 1416 GL_TRANSFORM_FEEDBACK_BUFFER, 1417 index); 1418 assert(buf_res); 1419 if (res == buf_res) { 1420 *val++ = i; 1421 } 1422 } 1423 return RESOURCE_XFB(res)->NumVaryings; 1424 } 1425 } 1426 assert(!"support for property type not implemented"); 1427 1428invalid_operation: 1429 _mesa_error_glthread_safe(ctx, GL_INVALID_OPERATION, glthread, 1430 "%s(%s prop %s)", caller, 1431 _mesa_enum_to_string(res->Type), 1432 _mesa_enum_to_string(prop)); 1433 1434 return 0; 1435} 1436 1437unsigned 1438_mesa_program_resource_prop(struct gl_shader_program *shProg, 1439 struct gl_program_resource *res, GLuint index, 1440 const GLenum prop, GLint *val, bool glthread, 1441 const char *caller) 1442{ 1443 GET_CURRENT_CONTEXT(ctx); 1444 1445#define VALIDATE_TYPE(type)\ 1446 if (res->Type != type)\ 1447 goto invalid_operation; 1448 1449#define VALIDATE_TYPE_2(type1, type2)\ 1450 if (res->Type != type1 && res->Type != type2)\ 1451 goto invalid_operation; 1452 1453 switch(prop) { 1454 case GL_NAME_LENGTH: 1455 switch (res->Type) { 1456 case GL_ATOMIC_COUNTER_BUFFER: 1457 case GL_TRANSFORM_FEEDBACK_BUFFER: 1458 goto invalid_operation; 1459 default: 1460 /* Resource name length + terminator. */ 1461 *val = _mesa_program_resource_name_length_array(res) + 1; 1462 } 1463 return 1; 1464 case GL_TYPE: 1465 switch (res->Type) { 1466 case GL_UNIFORM: 1467 case GL_BUFFER_VARIABLE: 1468 *val = RESOURCE_UNI(res)->type->gl_type; 1469 *val = mediump_to_highp_type(*val); 1470 return 1; 1471 case GL_PROGRAM_INPUT: 1472 case GL_PROGRAM_OUTPUT: 1473 *val = RESOURCE_VAR(res)->type->gl_type; 1474 *val = mediump_to_highp_type(*val); 1475 return 1; 1476 case GL_TRANSFORM_FEEDBACK_VARYING: 1477 *val = RESOURCE_XFV(res)->Type; 1478 *val = mediump_to_highp_type(*val); 1479 return 1; 1480 default: 1481 goto invalid_operation; 1482 } 1483 case GL_ARRAY_SIZE: 1484 switch (res->Type) { 1485 case GL_UNIFORM: 1486 case GL_BUFFER_VARIABLE: 1487 case GL_VERTEX_SUBROUTINE_UNIFORM: 1488 case GL_GEOMETRY_SUBROUTINE_UNIFORM: 1489 case GL_FRAGMENT_SUBROUTINE_UNIFORM: 1490 case GL_COMPUTE_SUBROUTINE_UNIFORM: 1491 case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: 1492 case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: 1493 1494 /* Test if a buffer variable is an array or an unsized array. 1495 * Unsized arrays return zero as array size. 1496 */ 1497 if (RESOURCE_UNI(res)->is_shader_storage && 1498 RESOURCE_UNI(res)->array_stride > 0) 1499 *val = RESOURCE_UNI(res)->array_elements; 1500 else 1501 *val = MAX2(RESOURCE_UNI(res)->array_elements, 1); 1502 return 1; 1503 case GL_PROGRAM_INPUT: 1504 case GL_PROGRAM_OUTPUT: 1505 *val = MAX2(_mesa_program_resource_array_size(res), 1); 1506 return 1; 1507 case GL_TRANSFORM_FEEDBACK_VARYING: 1508 *val = RESOURCE_XFV(res)->Size; 1509 return 1; 1510 default: 1511 goto invalid_operation; 1512 } 1513 case GL_OFFSET: 1514 switch (res->Type) { 1515 case GL_UNIFORM: 1516 case GL_BUFFER_VARIABLE: 1517 *val = RESOURCE_UNI(res)->offset; 1518 return 1; 1519 case GL_TRANSFORM_FEEDBACK_VARYING: 1520 *val = RESOURCE_XFV(res)->Offset; 1521 return 1; 1522 default: 1523 goto invalid_operation; 1524 } 1525 case GL_BLOCK_INDEX: 1526 VALIDATE_TYPE_2(GL_UNIFORM, GL_BUFFER_VARIABLE); 1527 *val = RESOURCE_UNI(res)->block_index; 1528 return 1; 1529 case GL_ARRAY_STRIDE: 1530 VALIDATE_TYPE_2(GL_UNIFORM, GL_BUFFER_VARIABLE); 1531 *val = RESOURCE_UNI(res)->array_stride; 1532 return 1; 1533 case GL_MATRIX_STRIDE: 1534 VALIDATE_TYPE_2(GL_UNIFORM, GL_BUFFER_VARIABLE); 1535 *val = RESOURCE_UNI(res)->matrix_stride; 1536 return 1; 1537 case GL_IS_ROW_MAJOR: 1538 VALIDATE_TYPE_2(GL_UNIFORM, GL_BUFFER_VARIABLE); 1539 *val = RESOURCE_UNI(res)->row_major; 1540 return 1; 1541 case GL_ATOMIC_COUNTER_BUFFER_INDEX: 1542 VALIDATE_TYPE(GL_UNIFORM); 1543 *val = RESOURCE_UNI(res)->atomic_buffer_index; 1544 return 1; 1545 case GL_BUFFER_BINDING: 1546 case GL_BUFFER_DATA_SIZE: 1547 case GL_NUM_ACTIVE_VARIABLES: 1548 case GL_ACTIVE_VARIABLES: 1549 return get_buffer_property(shProg, res, prop, val, glthread, caller); 1550 case GL_REFERENCED_BY_COMPUTE_SHADER: 1551 if (!_mesa_has_compute_shaders(ctx)) 1552 goto invalid_enum; 1553 FALLTHROUGH; 1554 case GL_REFERENCED_BY_VERTEX_SHADER: 1555 case GL_REFERENCED_BY_TESS_CONTROL_SHADER: 1556 case GL_REFERENCED_BY_TESS_EVALUATION_SHADER: 1557 case GL_REFERENCED_BY_GEOMETRY_SHADER: 1558 case GL_REFERENCED_BY_FRAGMENT_SHADER: 1559 switch (res->Type) { 1560 case GL_UNIFORM: 1561 case GL_PROGRAM_INPUT: 1562 case GL_PROGRAM_OUTPUT: 1563 case GL_UNIFORM_BLOCK: 1564 case GL_BUFFER_VARIABLE: 1565 case GL_SHADER_STORAGE_BLOCK: 1566 case GL_ATOMIC_COUNTER_BUFFER: 1567 *val = is_resource_referenced(shProg, res, index, 1568 stage_from_enum(prop)); 1569 return 1; 1570 default: 1571 goto invalid_operation; 1572 } 1573 case GL_LOCATION: 1574 switch (res->Type) { 1575 case GL_UNIFORM: 1576 case GL_VERTEX_SUBROUTINE_UNIFORM: 1577 case GL_GEOMETRY_SUBROUTINE_UNIFORM: 1578 case GL_FRAGMENT_SUBROUTINE_UNIFORM: 1579 case GL_COMPUTE_SUBROUTINE_UNIFORM: 1580 case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: 1581 case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: 1582 case GL_PROGRAM_INPUT: 1583 case GL_PROGRAM_OUTPUT: 1584 *val = program_resource_location(res, 0); 1585 return 1; 1586 default: 1587 goto invalid_operation; 1588 } 1589 case GL_LOCATION_COMPONENT: 1590 switch (res->Type) { 1591 case GL_PROGRAM_INPUT: 1592 case GL_PROGRAM_OUTPUT: 1593 *val = RESOURCE_VAR(res)->component; 1594 return 1; 1595 default: 1596 goto invalid_operation; 1597 } 1598 case GL_LOCATION_INDEX: { 1599 int tmp; 1600 if (res->Type != GL_PROGRAM_OUTPUT) 1601 goto invalid_operation; 1602 tmp = program_resource_location(res, 0); 1603 if (tmp == -1) 1604 *val = -1; 1605 else 1606 *val = _get_resource_location_index(res); 1607 return 1; 1608 } 1609 case GL_NUM_COMPATIBLE_SUBROUTINES: 1610 if (res->Type != GL_VERTEX_SUBROUTINE_UNIFORM && 1611 res->Type != GL_FRAGMENT_SUBROUTINE_UNIFORM && 1612 res->Type != GL_GEOMETRY_SUBROUTINE_UNIFORM && 1613 res->Type != GL_COMPUTE_SUBROUTINE_UNIFORM && 1614 res->Type != GL_TESS_CONTROL_SUBROUTINE_UNIFORM && 1615 res->Type != GL_TESS_EVALUATION_SUBROUTINE_UNIFORM) 1616 goto invalid_operation; 1617 *val = RESOURCE_UNI(res)->num_compatible_subroutines; 1618 return 1; 1619 case GL_COMPATIBLE_SUBROUTINES: { 1620 const struct gl_uniform_storage *uni; 1621 struct gl_program *p; 1622 unsigned count, i; 1623 int j; 1624 1625 if (res->Type != GL_VERTEX_SUBROUTINE_UNIFORM && 1626 res->Type != GL_FRAGMENT_SUBROUTINE_UNIFORM && 1627 res->Type != GL_GEOMETRY_SUBROUTINE_UNIFORM && 1628 res->Type != GL_COMPUTE_SUBROUTINE_UNIFORM && 1629 res->Type != GL_TESS_CONTROL_SUBROUTINE_UNIFORM && 1630 res->Type != GL_TESS_EVALUATION_SUBROUTINE_UNIFORM) 1631 goto invalid_operation; 1632 uni = RESOURCE_UNI(res); 1633 1634 p = shProg->_LinkedShaders[_mesa_shader_stage_from_subroutine_uniform(res->Type)]->Program; 1635 count = 0; 1636 for (i = 0; i < p->sh.NumSubroutineFunctions; i++) { 1637 struct gl_subroutine_function *fn = &p->sh.SubroutineFunctions[i]; 1638 for (j = 0; j < fn->num_compat_types; j++) { 1639 if (fn->types[j] == uni->type) { 1640 val[count++] = i; 1641 break; 1642 } 1643 } 1644 } 1645 return count; 1646 } 1647 1648 case GL_TOP_LEVEL_ARRAY_SIZE: 1649 VALIDATE_TYPE(GL_BUFFER_VARIABLE); 1650 *val = RESOURCE_UNI(res)->top_level_array_size; 1651 return 1; 1652 1653 case GL_TOP_LEVEL_ARRAY_STRIDE: 1654 VALIDATE_TYPE(GL_BUFFER_VARIABLE); 1655 *val = RESOURCE_UNI(res)->top_level_array_stride; 1656 return 1; 1657 1658 /* GL_ARB_tessellation_shader */ 1659 case GL_IS_PER_PATCH: 1660 switch (res->Type) { 1661 case GL_PROGRAM_INPUT: 1662 case GL_PROGRAM_OUTPUT: 1663 *val = RESOURCE_VAR(res)->patch; 1664 return 1; 1665 default: 1666 goto invalid_operation; 1667 } 1668 1669 case GL_TRANSFORM_FEEDBACK_BUFFER_INDEX: 1670 VALIDATE_TYPE(GL_TRANSFORM_FEEDBACK_VARYING); 1671 *val = RESOURCE_XFV(res)->BufferIndex; 1672 return 1; 1673 case GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE: 1674 VALIDATE_TYPE(GL_TRANSFORM_FEEDBACK_BUFFER); 1675 *val = RESOURCE_XFB(res)->Stride * 4; 1676 return 1; 1677 1678 default: 1679 goto invalid_enum; 1680 } 1681 1682#undef VALIDATE_TYPE 1683#undef VALIDATE_TYPE_2 1684 1685invalid_enum: 1686 _mesa_error_glthread_safe(ctx, GL_INVALID_ENUM, glthread, 1687 "%s(%s prop %s)", caller, 1688 _mesa_enum_to_string(res->Type), 1689 _mesa_enum_to_string(prop)); 1690 return 0; 1691 1692invalid_operation: 1693 _mesa_error_glthread_safe(ctx, GL_INVALID_OPERATION, glthread, 1694 "%s(%s prop %s)", caller, 1695 _mesa_enum_to_string(res->Type), 1696 _mesa_enum_to_string(prop)); 1697 return 0; 1698} 1699 1700extern void 1701_mesa_get_program_resourceiv(struct gl_shader_program *shProg, 1702 GLenum programInterface, GLuint index, GLsizei propCount, 1703 const GLenum *props, GLsizei bufSize, 1704 GLsizei *length, GLint *params) 1705{ 1706 GET_CURRENT_CONTEXT(ctx); 1707 GLint *val = (GLint *) params; 1708 const GLenum *prop = props; 1709 GLsizei amount = 0; 1710 1711 struct gl_program_resource *res = 1712 _mesa_program_resource_find_index(shProg, programInterface, index); 1713 1714 /* No such resource found or bufSize negative. */ 1715 if (!res || bufSize < 0) { 1716 _mesa_error(ctx, GL_INVALID_VALUE, 1717 "glGetProgramResourceiv(%s index %d bufSize %d)", 1718 _mesa_enum_to_string(programInterface), index, bufSize); 1719 return; 1720 } 1721 1722 /* Write propCount values until error occurs or bufSize reached. */ 1723 for (int i = 0; i < propCount && i < bufSize; i++, val++, prop++) { 1724 int props_written = 1725 _mesa_program_resource_prop(shProg, res, index, *prop, val, 1726 false, "glGetProgramResourceiv"); 1727 1728 /* Error happened. */ 1729 if (props_written == 0) 1730 return; 1731 1732 amount += props_written; 1733 } 1734 1735 /* If <length> is not NULL, the actual number of integer values 1736 * written to <params> will be written to <length>. 1737 */ 1738 if (length) 1739 *length = amount; 1740} 1741 1742extern void 1743_mesa_get_program_interfaceiv(struct gl_shader_program *shProg, 1744 GLenum programInterface, GLenum pname, 1745 GLint *params) 1746{ 1747 GET_CURRENT_CONTEXT(ctx); 1748 unsigned i; 1749 1750 /* Validate pname against interface. */ 1751 switch(pname) { 1752 case GL_ACTIVE_RESOURCES: 1753 for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) 1754 if (shProg->data->ProgramResourceList[i].Type == programInterface) 1755 (*params)++; 1756 break; 1757 case GL_MAX_NAME_LENGTH: 1758 if (programInterface == GL_ATOMIC_COUNTER_BUFFER || 1759 programInterface == GL_TRANSFORM_FEEDBACK_BUFFER) { 1760 _mesa_error(ctx, GL_INVALID_OPERATION, 1761 "glGetProgramInterfaceiv(%s pname %s)", 1762 _mesa_enum_to_string(programInterface), 1763 _mesa_enum_to_string(pname)); 1764 return; 1765 } 1766 /* Name length consists of base name, 3 additional chars '[0]' if 1767 * resource is an array and finally 1 char for string terminator. 1768 */ 1769 for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) { 1770 if (shProg->data->ProgramResourceList[i].Type != programInterface) 1771 continue; 1772 unsigned len = 1773 _mesa_program_resource_name_length_array(&shProg->data->ProgramResourceList[i]); 1774 *params = MAX2((unsigned)*params, len + 1); 1775 } 1776 break; 1777 case GL_MAX_NUM_ACTIVE_VARIABLES: 1778 switch (programInterface) { 1779 case GL_UNIFORM_BLOCK: 1780 for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) { 1781 if (shProg->data->ProgramResourceList[i].Type == programInterface) { 1782 struct gl_uniform_block *block = 1783 (struct gl_uniform_block *) 1784 shProg->data->ProgramResourceList[i].Data; 1785 *params = MAX2((unsigned)*params, block->NumUniforms); 1786 } 1787 } 1788 break; 1789 case GL_SHADER_STORAGE_BLOCK: 1790 for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) { 1791 if (shProg->data->ProgramResourceList[i].Type == programInterface) { 1792 struct gl_uniform_block *block = 1793 (struct gl_uniform_block *) 1794 shProg->data->ProgramResourceList[i].Data; 1795 GLint block_params = 0; 1796 for (unsigned j = 0; j < block->NumUniforms; j++) { 1797 struct gl_program_resource *uni = 1798 _mesa_program_resource_find_active_variable( 1799 shProg, 1800 GL_BUFFER_VARIABLE, 1801 block, 1802 j); 1803 if (!uni) 1804 continue; 1805 block_params++; 1806 } 1807 *params = MAX2(*params, block_params); 1808 } 1809 } 1810 break; 1811 case GL_ATOMIC_COUNTER_BUFFER: 1812 for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) { 1813 if (shProg->data->ProgramResourceList[i].Type == programInterface) { 1814 struct gl_active_atomic_buffer *buffer = 1815 (struct gl_active_atomic_buffer *) 1816 shProg->data->ProgramResourceList[i].Data; 1817 *params = MAX2((unsigned)*params, buffer->NumUniforms); 1818 } 1819 } 1820 break; 1821 case GL_TRANSFORM_FEEDBACK_BUFFER: 1822 for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) { 1823 if (shProg->data->ProgramResourceList[i].Type == programInterface) { 1824 struct gl_transform_feedback_buffer *buffer = 1825 (struct gl_transform_feedback_buffer *) 1826 shProg->data->ProgramResourceList[i].Data; 1827 *params = MAX2((unsigned)*params, buffer->NumVaryings); 1828 } 1829 } 1830 break; 1831 default: 1832 _mesa_error(ctx, GL_INVALID_OPERATION, 1833 "glGetProgramInterfaceiv(%s pname %s)", 1834 _mesa_enum_to_string(programInterface), 1835 _mesa_enum_to_string(pname)); 1836 } 1837 break; 1838 case GL_MAX_NUM_COMPATIBLE_SUBROUTINES: 1839 switch (programInterface) { 1840 case GL_VERTEX_SUBROUTINE_UNIFORM: 1841 case GL_FRAGMENT_SUBROUTINE_UNIFORM: 1842 case GL_GEOMETRY_SUBROUTINE_UNIFORM: 1843 case GL_COMPUTE_SUBROUTINE_UNIFORM: 1844 case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: 1845 case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: { 1846 for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) { 1847 if (shProg->data->ProgramResourceList[i].Type == programInterface) { 1848 struct gl_uniform_storage *uni = 1849 (struct gl_uniform_storage *) 1850 shProg->data->ProgramResourceList[i].Data; 1851 *params = MAX2((unsigned)*params, uni->num_compatible_subroutines); 1852 } 1853 } 1854 break; 1855 } 1856 1857 default: 1858 _mesa_error(ctx, GL_INVALID_OPERATION, 1859 "glGetProgramInterfaceiv(%s pname %s)", 1860 _mesa_enum_to_string(programInterface), 1861 _mesa_enum_to_string(pname)); 1862 } 1863 break; 1864 default: 1865 _mesa_error(ctx, GL_INVALID_OPERATION, 1866 "glGetProgramInterfaceiv(pname %s)", 1867 _mesa_enum_to_string(pname)); 1868 } 1869} 1870 1871static bool 1872validate_io(struct gl_program *producer, struct gl_program *consumer) 1873{ 1874 if (producer->sh.data->linked_stages == consumer->sh.data->linked_stages) 1875 return true; 1876 1877 const bool producer_is_array_stage = 1878 producer->info.stage == MESA_SHADER_TESS_CTRL; 1879 const bool consumer_is_array_stage = 1880 consumer->info.stage == MESA_SHADER_GEOMETRY || 1881 consumer->info.stage == MESA_SHADER_TESS_CTRL || 1882 consumer->info.stage == MESA_SHADER_TESS_EVAL; 1883 1884 bool valid = true; 1885 1886 gl_shader_variable const **outputs = 1887 (gl_shader_variable const **) calloc(producer->sh.data->NumProgramResourceList, 1888 sizeof(gl_shader_variable *)); 1889 if (outputs == NULL) 1890 return false; 1891 1892 /* Section 7.4.1 (Shader Interface Matching) of the OpenGL ES 3.1 spec 1893 * says: 1894 * 1895 * At an interface between program objects, the set of inputs and 1896 * outputs are considered to match exactly if and only if: 1897 * 1898 * - Every declared input variable has a matching output, as described 1899 * above. 1900 * - There are no user-defined output variables declared without a 1901 * matching input variable declaration. 1902 * 1903 * Every input has an output, and every output has an input. Scan the list 1904 * of producer resources once, and generate the list of outputs. As inputs 1905 * and outputs are matched, remove the matched outputs from the set. At 1906 * the end, the set must be empty. If the set is not empty, then there is 1907 * some output that did not have an input. 1908 */ 1909 unsigned num_outputs = 0; 1910 for (unsigned i = 0; i < producer->sh.data->NumProgramResourceList; i++) { 1911 struct gl_program_resource *res = 1912 &producer->sh.data->ProgramResourceList[i]; 1913 1914 if (res->Type != GL_PROGRAM_OUTPUT) 1915 continue; 1916 1917 gl_shader_variable const *const var = RESOURCE_VAR(res); 1918 1919 /* Section 7.4.1 (Shader Interface Matching) of the OpenGL ES 3.1 spec 1920 * says: 1921 * 1922 * Built-in inputs or outputs do not affect interface matching. 1923 */ 1924 if (is_gl_identifier(var->name.string)) 1925 continue; 1926 1927 outputs[num_outputs++] = var; 1928 } 1929 1930 unsigned match_index = 0; 1931 for (unsigned i = 0; i < consumer->sh.data->NumProgramResourceList; i++) { 1932 struct gl_program_resource *res = 1933 &consumer->sh.data->ProgramResourceList[i]; 1934 1935 if (res->Type != GL_PROGRAM_INPUT) 1936 continue; 1937 1938 gl_shader_variable const *const consumer_var = RESOURCE_VAR(res); 1939 gl_shader_variable const *producer_var = NULL; 1940 1941 if (is_gl_identifier(consumer_var->name.string)) 1942 continue; 1943 1944 /* Inputs with explicit locations match other outputs with explicit 1945 * locations by location instead of by name. 1946 */ 1947 if (consumer_var->explicit_location) { 1948 for (unsigned j = 0; j < num_outputs; j++) { 1949 const gl_shader_variable *const var = outputs[j]; 1950 1951 if (var->explicit_location && 1952 consumer_var->location == var->location) { 1953 producer_var = var; 1954 match_index = j; 1955 break; 1956 } 1957 } 1958 } else { 1959 for (unsigned j = 0; j < num_outputs; j++) { 1960 const gl_shader_variable *const var = outputs[j]; 1961 1962 if (!var->explicit_location && 1963 strcmp(consumer_var->name.string, var->name.string) == 0) { 1964 producer_var = var; 1965 match_index = j; 1966 break; 1967 } 1968 } 1969 } 1970 1971 /* Section 7.4.1 (Shader Interface Matching) of the OpenGL ES 3.1 spec 1972 * says: 1973 * 1974 * - An output variable is considered to match an input variable in 1975 * the subsequent shader if: 1976 * 1977 * - the two variables match in name, type, and qualification; or 1978 * 1979 * - the two variables are declared with the same location 1980 * qualifier and match in type and qualification. 1981 */ 1982 if (producer_var == NULL) { 1983 valid = false; 1984 goto out; 1985 } 1986 1987 /* An output cannot match more than one input, so remove the output from 1988 * the set of possible outputs. 1989 */ 1990 outputs[match_index] = NULL; 1991 num_outputs--; 1992 if (match_index < num_outputs) 1993 outputs[match_index] = outputs[num_outputs]; 1994 1995 /* Section 7.4.1 (Shader Interface Matching) of the ES 3.2 spec says: 1996 * 1997 * "Tessellation control shader per-vertex output variables and 1998 * blocks and tessellation control, tessellation evaluation, and 1999 * geometry shader per-vertex input variables and blocks are 2000 * required to be declared as arrays, with each element representing 2001 * input or output values for a single vertex of a multi-vertex 2002 * primitive. For the purposes of interface matching, such variables 2003 * and blocks are treated as though they were not declared as 2004 * arrays." 2005 * 2006 * So we unwrap those types before matching. 2007 */ 2008 const glsl_type *consumer_type = consumer_var->type; 2009 const glsl_type *consumer_interface_type = consumer_var->interface_type; 2010 const glsl_type *producer_type = producer_var->type; 2011 const glsl_type *producer_interface_type = producer_var->interface_type; 2012 2013 if (consumer_is_array_stage) { 2014 if (consumer_interface_type) { 2015 /* the interface is the array; the underlying types should match */ 2016 if (consumer_interface_type->is_array() && !consumer_var->patch) 2017 consumer_interface_type = consumer_interface_type->fields.array; 2018 } else { 2019 if (consumer_type->is_array() && !consumer_var->patch) 2020 consumer_type = consumer_type->fields.array; 2021 } 2022 } 2023 2024 if (producer_is_array_stage) { 2025 if (producer_interface_type) { 2026 /* the interface is the array; the underlying types should match */ 2027 if (producer_interface_type->is_array() && !producer_var->patch) 2028 producer_interface_type = producer_interface_type->fields.array; 2029 } else { 2030 if (producer_type->is_array() && !producer_var->patch) 2031 producer_type = producer_type->fields.array; 2032 } 2033 } 2034 2035 if (producer_type != consumer_type) { 2036 valid = false; 2037 goto out; 2038 } 2039 2040 if (producer_interface_type != consumer_interface_type) { 2041 valid = false; 2042 goto out; 2043 } 2044 2045 /* Section 9.2.2 (Separable Programs) of the GLSL ES spec says: 2046 * 2047 * Qualifier Class| Qualifier |in/out 2048 * ---------------+-------------+------ 2049 * Storage | in | 2050 * | out | N/A 2051 * | uniform | 2052 * ---------------+-------------+------ 2053 * Auxiliary | centroid | No 2054 * ---------------+-------------+------ 2055 * | location | Yes 2056 * | Block layout| N/A 2057 * | binding | N/A 2058 * | offset | N/A 2059 * | format | N/A 2060 * ---------------+-------------+------ 2061 * Interpolation | smooth | 2062 * | flat | Yes 2063 * ---------------+-------------+------ 2064 * | lowp | 2065 * Precision | mediump | Yes 2066 * | highp | 2067 * ---------------+-------------+------ 2068 * Variance | invariant | No 2069 * ---------------+-------------+------ 2070 * Memory | all | N/A 2071 * 2072 * Note that location mismatches are detected by the loops above that 2073 * find the producer variable that goes with the consumer variable. 2074 */ 2075 unsigned producer_interpolation = producer_var->interpolation; 2076 unsigned consumer_interpolation = consumer_var->interpolation; 2077 if (producer_interpolation == INTERP_MODE_NONE) 2078 producer_interpolation = INTERP_MODE_SMOOTH; 2079 if (consumer_interpolation == INTERP_MODE_NONE) 2080 consumer_interpolation = INTERP_MODE_SMOOTH; 2081 if (producer_interpolation != consumer_interpolation) { 2082 valid = false; 2083 goto out; 2084 } 2085 2086 if (producer_var->precision != consumer_var->precision) { 2087 valid = false; 2088 goto out; 2089 } 2090 2091 if (producer_var->outermost_struct_type != consumer_var->outermost_struct_type) { 2092 valid = false; 2093 goto out; 2094 } 2095 } 2096 2097 out: 2098 free(outputs); 2099 return valid && num_outputs == 0; 2100} 2101 2102/** 2103 * Validate inputs against outputs in a program pipeline. 2104 */ 2105extern "C" bool 2106_mesa_validate_pipeline_io(struct gl_pipeline_object *pipeline) 2107{ 2108 struct gl_program **prog = (struct gl_program **) pipeline->CurrentProgram; 2109 2110 /* Find first active stage in pipeline. */ 2111 unsigned idx, prev = 0; 2112 for (idx = 0; idx < ARRAY_SIZE(pipeline->CurrentProgram); idx++) { 2113 if (prog[idx]) { 2114 prev = idx; 2115 break; 2116 } 2117 } 2118 2119 for (idx = prev + 1; idx < ARRAY_SIZE(pipeline->CurrentProgram); idx++) { 2120 if (prog[idx]) { 2121 /* Pipeline might include both non-compute and a compute program, do 2122 * not attempt to validate varyings between non-compute and compute 2123 * stage. 2124 */ 2125 if (prog[idx]->info.stage == MESA_SHADER_COMPUTE) 2126 break; 2127 2128 if (!validate_io(prog[prev], prog[idx])) 2129 return false; 2130 2131 prev = idx; 2132 } 2133 } 2134 return true; 2135} 2136 2137extern "C" void 2138_mesa_program_resource_hash_destroy(struct gl_shader_program *shProg) 2139{ 2140 for (unsigned i = 0; i < ARRAY_SIZE(shProg->data->ProgramResourceHash); i++) { 2141 if (shProg->data->ProgramResourceHash[i]) { 2142 _mesa_hash_table_destroy(shProg->data->ProgramResourceHash[i], NULL); 2143 shProg->data->ProgramResourceHash[i] = NULL; 2144 } 2145 } 2146} 2147 2148extern "C" void 2149_mesa_create_program_resource_hash(struct gl_shader_program *shProg) 2150{ 2151 /* Rebuild resource hash. */ 2152 _mesa_program_resource_hash_destroy(shProg); 2153 2154 struct gl_program_resource *res = shProg->data->ProgramResourceList; 2155 for (unsigned i = 0; i < shProg->data->NumProgramResourceList; i++, res++) { 2156 struct gl_resource_name name; 2157 if (_mesa_program_get_resource_name(res, &name)) { 2158 unsigned type = GET_PROGRAM_RESOURCE_TYPE_FROM_GLENUM(res->Type); 2159 assert(type < ARRAY_SIZE(shProg->data->ProgramResourceHash)); 2160 2161 if (!shProg->data->ProgramResourceHash[type]) { 2162 shProg->data->ProgramResourceHash[type] = 2163 _mesa_hash_table_create(shProg, _mesa_hash_string, 2164 _mesa_key_string_equal); 2165 } 2166 2167 _mesa_hash_table_insert(shProg->data->ProgramResourceHash[type], 2168 name.string, res); 2169 } 2170 } 2171} 2172