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 #include "main/core.h" 25 #include "ir.h" 26 #include "linker.h" 27 #include "ir_uniform.h" 28 #include "glsl_symbol_table.h" 29 #include "program/hash_table.h" 30 #include "program.h" 31 32 static inline unsigned int 33 align(unsigned int a, unsigned int align) 34 { 35 return (a + align - 1) / align * align; 36 } 37 38 /** 39 * \file link_uniforms.cpp 40 * Assign locations for GLSL uniforms. 41 * 42 * \author Ian Romanick <ian.d.romanick (at) intel.com> 43 */ 44 45 /** 46 * Count the backing storage requirements for a type 47 */ 48 static unsigned 49 values_for_type(const glsl_type *type) 50 { 51 if (type->is_sampler()) { 52 return 1; 53 } else if (type->is_array() && type->fields.array->is_sampler()) { 54 return type->array_size(); 55 } else { 56 return type->component_slots(); 57 } 58 } 59 60 void 61 uniform_field_visitor::process(ir_variable *var) 62 { 63 const glsl_type *t = var->type; 64 65 /* Only strdup the name if we actually will need to modify it. */ 66 if (t->is_record() || (t->is_array() && t->fields.array->is_record())) { 67 char *name = ralloc_strdup(NULL, var->name); 68 recursion(var->type, &name, strlen(name)); 69 ralloc_free(name); 70 } else { 71 this->visit_field(t, var->name); 72 } 73 } 74 75 void 76 uniform_field_visitor::recursion(const glsl_type *t, char **name, 77 size_t name_length) 78 { 79 /* Records need to have each field processed individually. 80 * 81 * Arrays of records need to have each array element processed 82 * individually, then each field of the resulting array elements processed 83 * individually. 84 */ 85 if (t->is_record()) { 86 for (unsigned i = 0; i < t->length; i++) { 87 const char *field = t->fields.structure[i].name; 88 size_t new_length = name_length; 89 90 /* Append '.field' to the current uniform name. */ 91 ralloc_asprintf_rewrite_tail(name, &new_length, ".%s", field); 92 93 recursion(t->fields.structure[i].type, name, new_length); 94 } 95 } else if (t->is_array() && t->fields.array->is_record()) { 96 for (unsigned i = 0; i < t->length; i++) { 97 size_t new_length = name_length; 98 99 /* Append the subscript to the current uniform name */ 100 ralloc_asprintf_rewrite_tail(name, &new_length, "[%u]", i); 101 102 recursion(t->fields.array, name, new_length); 103 } 104 } else { 105 this->visit_field(t, *name); 106 } 107 } 108 109 /** 110 * Class to help calculate the storage requirements for a set of uniforms 111 * 112 * As uniforms are added to the active set the number of active uniforms and 113 * the storage requirements for those uniforms are accumulated. The active 114 * uniforms are added the the hash table supplied to the constructor. 115 * 116 * If the same uniform is added multiple times (i.e., once for each shader 117 * target), it will only be accounted once. 118 */ 119 class count_uniform_size : public uniform_field_visitor { 120 public: 121 count_uniform_size(struct string_to_uint_map *map) 122 : num_active_uniforms(0), num_values(0), num_shader_samplers(0), 123 num_shader_uniform_components(0), map(map) 124 { 125 /* empty */ 126 } 127 128 void start_shader() 129 { 130 this->num_shader_samplers = 0; 131 this->num_shader_uniform_components = 0; 132 } 133 134 /** 135 * Total number of active uniforms counted 136 */ 137 unsigned num_active_uniforms; 138 139 /** 140 * Number of data values required to back the storage for the active uniforms 141 */ 142 unsigned num_values; 143 144 /** 145 * Number of samplers used 146 */ 147 unsigned num_shader_samplers; 148 149 /** 150 * Number of uniforms used in the current shader 151 */ 152 unsigned num_shader_uniform_components; 153 154 private: 155 virtual void visit_field(const glsl_type *type, const char *name) 156 { 157 assert(!type->is_record()); 158 assert(!(type->is_array() && type->fields.array->is_record())); 159 160 /* Count the number of samplers regardless of whether the uniform is 161 * already in the hash table. The hash table prevents adding the same 162 * uniform for multiple shader targets, but in this case we want to 163 * count it for each shader target. 164 */ 165 const unsigned values = values_for_type(type); 166 if (type->contains_sampler()) { 167 this->num_shader_samplers += 168 type->is_array() ? type->array_size() : 1; 169 } else { 170 /* Accumulate the total number of uniform slots used by this shader. 171 * Note that samplers do not count against this limit because they 172 * don't use any storage on current hardware. 173 */ 174 this->num_shader_uniform_components += values; 175 } 176 177 /* If the uniform is already in the map, there's nothing more to do. 178 */ 179 unsigned id; 180 if (this->map->get(id, name)) 181 return; 182 183 this->map->put(this->num_active_uniforms, name); 184 185 /* Each leaf uniform occupies one entry in the list of active 186 * uniforms. 187 */ 188 this->num_active_uniforms++; 189 this->num_values += values; 190 } 191 192 struct string_to_uint_map *map; 193 }; 194 195 /** 196 * Class to help parcel out pieces of backing storage to uniforms 197 * 198 * Each uniform processed has some range of the \c gl_constant_value 199 * structures associated with it. The association is done by finding 200 * the uniform in the \c string_to_uint_map and using the value from 201 * the map to connect that slot in the \c gl_uniform_storage table 202 * with the next available slot in the \c gl_constant_value array. 203 * 204 * \warning 205 * This class assumes that every uniform that will be processed is 206 * already in the \c string_to_uint_map. In addition, it assumes that 207 * the \c gl_uniform_storage and \c gl_constant_value arrays are "big 208 * enough." 209 */ 210 class parcel_out_uniform_storage : public uniform_field_visitor { 211 public: 212 parcel_out_uniform_storage(struct string_to_uint_map *map, 213 struct gl_uniform_storage *uniforms, 214 union gl_constant_value *values) 215 : map(map), uniforms(uniforms), next_sampler(0), values(values) 216 { 217 memset(this->targets, 0, sizeof(this->targets)); 218 } 219 220 void start_shader() 221 { 222 this->shader_samplers_used = 0; 223 this->shader_shadow_samplers = 0; 224 } 225 226 void set_and_process(struct gl_shader_program *prog, 227 struct gl_shader *shader, 228 ir_variable *var) 229 { 230 ubo_var = NULL; 231 if (var->uniform_block != -1) { 232 struct gl_uniform_block *block = 233 &shader->UniformBlocks[var->uniform_block]; 234 235 ubo_block_index = -1; 236 for (unsigned i = 0; i < prog->NumUniformBlocks; i++) { 237 if (!strcmp(prog->UniformBlocks[i].Name, 238 shader->UniformBlocks[var->uniform_block].Name)) { 239 ubo_block_index = i; 240 break; 241 } 242 } 243 assert(ubo_block_index != -1); 244 245 ubo_var_index = var->location; 246 ubo_var = &block->Uniforms[var->location]; 247 ubo_byte_offset = ubo_var->Offset; 248 } 249 250 process(var); 251 } 252 253 struct gl_uniform_buffer_variable *ubo_var; 254 int ubo_block_index; 255 int ubo_var_index; 256 int ubo_byte_offset; 257 258 private: 259 virtual void visit_field(const glsl_type *type, const char *name) 260 { 261 assert(!type->is_record()); 262 assert(!(type->is_array() && type->fields.array->is_record())); 263 264 unsigned id; 265 bool found = this->map->get(id, name); 266 assert(found); 267 268 if (!found) 269 return; 270 271 /* If there is already storage associated with this uniform, it means 272 * that it was set while processing an earlier shader stage. For 273 * example, we may be processing the uniform in the fragment shader, but 274 * the uniform was already processed in the vertex shader. 275 */ 276 if (this->uniforms[id].storage != NULL) { 277 /* If the uniform already has storage set from another shader stage, 278 * mark the samplers used for this shader stage. 279 */ 280 if (type->contains_sampler()) { 281 const unsigned count = MAX2(1, this->uniforms[id].array_elements); 282 const unsigned shadow = (type->is_array()) 283 ? type->fields.array->sampler_shadow : type->sampler_shadow; 284 285 for (unsigned i = 0; i < count; i++) { 286 const unsigned s = this->uniforms[id].sampler + i; 287 288 this->shader_samplers_used |= 1U << s; 289 this->shader_shadow_samplers |= shadow << s; 290 } 291 } 292 293 return; 294 } 295 296 const glsl_type *base_type; 297 if (type->is_array()) { 298 this->uniforms[id].array_elements = type->length; 299 base_type = type->fields.array; 300 } else { 301 this->uniforms[id].array_elements = 0; 302 base_type = type; 303 } 304 305 if (base_type->is_sampler()) { 306 this->uniforms[id].sampler = this->next_sampler; 307 308 /* Increment the sampler by 1 for non-arrays and by the number of 309 * array elements for arrays. 310 */ 311 this->next_sampler += MAX2(1, this->uniforms[id].array_elements); 312 313 const gl_texture_index target = base_type->sampler_index(); 314 const unsigned shadow = base_type->sampler_shadow; 315 for (unsigned i = this->uniforms[id].sampler 316 ; i < MIN2(this->next_sampler, MAX_SAMPLERS) 317 ; i++) { 318 this->targets[i] = target; 319 this->shader_samplers_used |= 1U << i; 320 this->shader_shadow_samplers |= shadow << i; 321 } 322 323 } else { 324 this->uniforms[id].sampler = ~0; 325 } 326 327 this->uniforms[id].name = ralloc_strdup(this->uniforms, name); 328 this->uniforms[id].type = base_type; 329 this->uniforms[id].initialized = 0; 330 this->uniforms[id].num_driver_storage = 0; 331 this->uniforms[id].driver_storage = NULL; 332 this->uniforms[id].storage = this->values; 333 if (this->ubo_var) { 334 this->uniforms[id].block_index = this->ubo_block_index; 335 336 unsigned alignment = type->std140_base_alignment(ubo_var->RowMajor); 337 this->ubo_byte_offset = align(this->ubo_byte_offset, alignment); 338 this->uniforms[id].offset = this->ubo_byte_offset; 339 this->ubo_byte_offset += type->std140_size(ubo_var->RowMajor); 340 341 if (type->is_array()) { 342 this->uniforms[id].array_stride = 343 align(type->fields.array->std140_size(ubo_var->RowMajor), 16); 344 } else { 345 this->uniforms[id].array_stride = 0; 346 } 347 348 if (type->is_matrix() || 349 (type->is_array() && type->fields.array->is_matrix())) { 350 this->uniforms[id].matrix_stride = 16; 351 this->uniforms[id].row_major = ubo_var->RowMajor; 352 } else { 353 this->uniforms[id].matrix_stride = 0; 354 this->uniforms[id].row_major = false; 355 } 356 } else { 357 this->uniforms[id].block_index = -1; 358 this->uniforms[id].offset = -1; 359 this->uniforms[id].array_stride = -1; 360 this->uniforms[id].matrix_stride = -1; 361 this->uniforms[id].row_major = false; 362 } 363 364 this->values += values_for_type(type); 365 } 366 367 struct string_to_uint_map *map; 368 369 struct gl_uniform_storage *uniforms; 370 unsigned next_sampler; 371 372 public: 373 union gl_constant_value *values; 374 375 gl_texture_index targets[MAX_SAMPLERS]; 376 377 /** 378 * Mask of samplers used by the current shader stage. 379 */ 380 unsigned shader_samplers_used; 381 382 /** 383 * Mask of samplers used by the current shader stage for shadows. 384 */ 385 unsigned shader_shadow_samplers; 386 }; 387 388 /** 389 * Merges a uniform block into an array of uniform blocks that may or 390 * may not already contain a copy of it. 391 * 392 * Returns the index of the new block in the array. 393 */ 394 int 395 link_cross_validate_uniform_block(void *mem_ctx, 396 struct gl_uniform_block **linked_blocks, 397 unsigned int *num_linked_blocks, 398 struct gl_uniform_block *new_block) 399 { 400 for (unsigned int i = 0; i < *num_linked_blocks; i++) { 401 struct gl_uniform_block *old_block = &(*linked_blocks)[i]; 402 if (strcmp(old_block->Name, new_block->Name) == 0) { 403 if (old_block->NumUniforms != new_block->NumUniforms) { 404 return -1; 405 } 406 407 for (unsigned j = 0; j < old_block->NumUniforms; j++) { 408 if (strcmp(old_block->Uniforms[j].Name, 409 new_block->Uniforms[j].Name) != 0) 410 return -1; 411 412 if (old_block->Uniforms[j].Offset != 413 new_block->Uniforms[j].Offset) 414 return -1; 415 416 if (old_block->Uniforms[j].RowMajor != 417 new_block->Uniforms[j].RowMajor) 418 return -1; 419 } 420 return i; 421 } 422 } 423 424 *linked_blocks = reralloc(mem_ctx, *linked_blocks, 425 struct gl_uniform_block, 426 *num_linked_blocks + 1); 427 int linked_block_index = (*num_linked_blocks)++; 428 struct gl_uniform_block *linked_block = &(*linked_blocks)[linked_block_index]; 429 430 memcpy(linked_block, new_block, sizeof(*new_block)); 431 linked_block->Uniforms = ralloc_array(*linked_blocks, 432 struct gl_uniform_buffer_variable, 433 linked_block->NumUniforms); 434 435 memcpy(linked_block->Uniforms, 436 new_block->Uniforms, 437 sizeof(*linked_block->Uniforms) * linked_block->NumUniforms); 438 439 for (unsigned int i = 0; i < linked_block->NumUniforms; i++) { 440 struct gl_uniform_buffer_variable *ubo_var = 441 &linked_block->Uniforms[i]; 442 443 ubo_var->Name = ralloc_strdup(*linked_blocks, ubo_var->Name); 444 } 445 446 return linked_block_index; 447 } 448 449 /** 450 * Walks the IR and update the references to uniform blocks in the 451 * ir_variables to point at linked shader's list (previously, they 452 * would point at the uniform block list in one of the pre-linked 453 * shaders). 454 */ 455 static bool 456 link_update_uniform_buffer_variables(struct gl_shader *shader) 457 { 458 foreach_list(node, shader->ir) { 459 ir_variable *const var = ((ir_instruction *) node)->as_variable(); 460 461 if ((var == NULL) || (var->uniform_block == -1)) 462 continue; 463 464 assert(var->mode == ir_var_uniform); 465 466 bool found = false; 467 for (unsigned i = 0; i < shader->NumUniformBlocks; i++) { 468 for (unsigned j = 0; j < shader->UniformBlocks[i].NumUniforms; j++) { 469 if (!strcmp(var->name, shader->UniformBlocks[i].Uniforms[j].Name)) { 470 found = true; 471 var->uniform_block = i; 472 var->location = j; 473 break; 474 } 475 } 476 if (found) 477 break; 478 } 479 assert(found); 480 } 481 482 return true; 483 } 484 485 void 486 link_assign_uniform_block_offsets(struct gl_shader *shader) 487 { 488 for (unsigned b = 0; b < shader->NumUniformBlocks; b++) { 489 struct gl_uniform_block *block = &shader->UniformBlocks[b]; 490 491 unsigned offset = 0; 492 for (unsigned int i = 0; i < block->NumUniforms; i++) { 493 struct gl_uniform_buffer_variable *ubo_var = &block->Uniforms[i]; 494 const struct glsl_type *type = ubo_var->Type; 495 496 unsigned alignment = type->std140_base_alignment(ubo_var->RowMajor); 497 unsigned size = type->std140_size(ubo_var->RowMajor); 498 499 offset = align(offset, alignment); 500 ubo_var->Offset = offset; 501 offset += size; 502 } 503 504 /* From the GL_ARB_uniform_buffer_object spec: 505 * 506 * "For uniform blocks laid out according to [std140] rules, 507 * the minimum buffer object size returned by the 508 * UNIFORM_BLOCK_DATA_SIZE query is derived by taking the 509 * offset of the last basic machine unit consumed by the 510 * last uniform of the uniform block (including any 511 * end-of-array or end-of-structure padding), adding one, 512 * and rounding up to the next multiple of the base 513 * alignment required for a vec4." 514 */ 515 block->UniformBufferSize = align(offset, 16); 516 } 517 } 518 519 void 520 link_assign_uniform_locations(struct gl_shader_program *prog) 521 { 522 ralloc_free(prog->UniformStorage); 523 prog->UniformStorage = NULL; 524 prog->NumUserUniformStorage = 0; 525 526 if (prog->UniformHash != NULL) { 527 prog->UniformHash->clear(); 528 } else { 529 prog->UniformHash = new string_to_uint_map; 530 } 531 532 /* Uniforms that lack an initializer in the shader code have an initial 533 * value of zero. This includes sampler uniforms. 534 * 535 * Page 24 (page 30 of the PDF) of the GLSL 1.20 spec says: 536 * 537 * "The link time initial value is either the value of the variable's 538 * initializer, if present, or 0 if no initializer is present. Sampler 539 * types cannot have initializers." 540 */ 541 memset(prog->SamplerUnits, 0, sizeof(prog->SamplerUnits)); 542 543 for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 544 if (prog->_LinkedShaders[i] == NULL) 545 continue; 546 547 if (!link_update_uniform_buffer_variables(prog->_LinkedShaders[i])) 548 return; 549 } 550 551 /* First pass: Count the uniform resources used by the user-defined 552 * uniforms. While this happens, each active uniform will have an index 553 * assigned to it. 554 * 555 * Note: this is *NOT* the index that is returned to the application by 556 * glGetUniformLocation. 557 */ 558 count_uniform_size uniform_size(prog->UniformHash); 559 for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 560 if (prog->_LinkedShaders[i] == NULL) 561 continue; 562 563 /* Reset various per-shader target counts. 564 */ 565 uniform_size.start_shader(); 566 567 foreach_list(node, prog->_LinkedShaders[i]->ir) { 568 ir_variable *const var = ((ir_instruction *) node)->as_variable(); 569 570 if ((var == NULL) || (var->mode != ir_var_uniform)) 571 continue; 572 573 /* FINISHME: Update code to process built-in uniforms! 574 */ 575 if (strncmp("gl_", var->name, 3) == 0) 576 continue; 577 578 uniform_size.process(var); 579 } 580 581 prog->_LinkedShaders[i]->num_samplers = uniform_size.num_shader_samplers; 582 prog->_LinkedShaders[i]->num_uniform_components = 583 uniform_size.num_shader_uniform_components; 584 } 585 586 const unsigned num_user_uniforms = uniform_size.num_active_uniforms; 587 const unsigned num_data_slots = uniform_size.num_values; 588 589 /* On the outside chance that there were no uniforms, bail out. 590 */ 591 if (num_user_uniforms == 0) 592 return; 593 594 struct gl_uniform_storage *uniforms = 595 rzalloc_array(prog, struct gl_uniform_storage, num_user_uniforms); 596 union gl_constant_value *data = 597 rzalloc_array(uniforms, union gl_constant_value, num_data_slots); 598 #ifndef NDEBUG 599 union gl_constant_value *data_end = &data[num_data_slots]; 600 #endif 601 602 parcel_out_uniform_storage parcel(prog->UniformHash, uniforms, data); 603 604 for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 605 if (prog->_LinkedShaders[i] == NULL) 606 continue; 607 608 /* Reset various per-shader target counts. 609 */ 610 parcel.start_shader(); 611 612 foreach_list(node, prog->_LinkedShaders[i]->ir) { 613 ir_variable *const var = ((ir_instruction *) node)->as_variable(); 614 615 if ((var == NULL) || (var->mode != ir_var_uniform)) 616 continue; 617 618 /* FINISHME: Update code to process built-in uniforms! 619 */ 620 if (strncmp("gl_", var->name, 3) == 0) 621 continue; 622 623 parcel.set_and_process(prog, prog->_LinkedShaders[i], var); 624 } 625 626 prog->_LinkedShaders[i]->active_samplers = parcel.shader_samplers_used; 627 prog->_LinkedShaders[i]->shadow_samplers = parcel.shader_shadow_samplers; 628 } 629 630 assert(sizeof(prog->SamplerTargets) == sizeof(parcel.targets)); 631 memcpy(prog->SamplerTargets, parcel.targets, sizeof(prog->SamplerTargets)); 632 633 #ifndef NDEBUG 634 for (unsigned i = 0; i < num_user_uniforms; i++) { 635 assert(uniforms[i].storage != NULL); 636 } 637 638 assert(parcel.values == data_end); 639 #endif 640 641 prog->NumUserUniformStorage = num_user_uniforms; 642 prog->UniformStorage = uniforms; 643 644 link_set_uniform_initializers(prog); 645 646 return; 647 } 648