1/* 2 * Copyright © 2012 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#include <gtest/gtest.h> 24#include "main/compiler.h" 25#include "main/mtypes.h" 26#include "main/macros.h" 27#include "ralloc.h" 28#include "uniform_initializer_utils.h" 29 30namespace linker { 31extern void 32set_uniform_initializer(void *mem_ctx, gl_shader_program *prog, 33 const char *name, const glsl_type *type, 34 ir_constant *val); 35} 36 37class set_uniform_initializer : public ::testing::Test { 38public: 39 virtual void SetUp(); 40 virtual void TearDown(); 41 42 /** 43 * Index of the uniform to be tested. 44 * 45 * All of the \c set_uniform_initializer tests create several slots for 46 * unifroms. All but one of the slots is fake. This field holds the index 47 * of the slot for the uniform being tested. 48 */ 49 unsigned actual_index; 50 51 /** 52 * Name of the uniform to be tested. 53 */ 54 const char *name; 55 56 /** 57 * Shader program used in the test. 58 */ 59 struct gl_shader_program *prog; 60 61 /** 62 * Ralloc memory context used for all temporary allocations. 63 */ 64 void *mem_ctx; 65}; 66 67void 68set_uniform_initializer::SetUp() 69{ 70 this->mem_ctx = ralloc_context(NULL); 71 this->prog = rzalloc(NULL, struct gl_shader_program); 72 73 /* Set default values used by the test cases. 74 */ 75 this->actual_index = 1; 76 this->name = "i"; 77} 78 79void 80set_uniform_initializer::TearDown() 81{ 82 ralloc_free(this->mem_ctx); 83 this->mem_ctx = NULL; 84 85 ralloc_free(this->prog); 86 this->prog = NULL; 87} 88 89/** 90 * Create some uniform storage for a program. 91 * 92 * \param prog Program to get some storage 93 * \param num_storage Total number of storage slots 94 * \param index_to_set Storage slot that will actually get a value 95 * \param name Name for the actual storage slot 96 * \param type Type for the elements of the actual storage slot 97 * \param array_size Size for the array of the actual storage slot. This 98 * should be zero for non-arrays. 99 */ 100static unsigned 101establish_uniform_storage(struct gl_shader_program *prog, unsigned num_storage, 102 unsigned index_to_set, const char *name, 103 const glsl_type *type, unsigned array_size) 104{ 105 const unsigned elements = MAX2(1, array_size); 106 const unsigned data_components = elements * type->components(); 107 const unsigned total_components = MAX2(17, (data_components 108 + type->components())); 109 const unsigned red_zone_components = total_components - data_components; 110 111 prog->UniformStorage = rzalloc_array(prog, struct gl_uniform_storage, 112 num_storage); 113 prog->NumUserUniformStorage = num_storage; 114 115 prog->UniformStorage[index_to_set].name = (char *) name; 116 prog->UniformStorage[index_to_set].type = type; 117 prog->UniformStorage[index_to_set].array_elements = array_size; 118 prog->UniformStorage[index_to_set].initialized = false; 119 prog->UniformStorage[index_to_set].sampler = ~0; 120 prog->UniformStorage[index_to_set].num_driver_storage = 0; 121 prog->UniformStorage[index_to_set].driver_storage = NULL; 122 prog->UniformStorage[index_to_set].storage = 123 rzalloc_array(prog, union gl_constant_value, total_components); 124 125 fill_storage_array_with_sentinels(prog->UniformStorage[index_to_set].storage, 126 data_components, 127 red_zone_components); 128 129 for (unsigned i = 0; i < num_storage; i++) { 130 if (i == index_to_set) 131 continue; 132 133 prog->UniformStorage[i].name = (char *) "invalid slot"; 134 prog->UniformStorage[i].type = glsl_type::void_type; 135 prog->UniformStorage[i].array_elements = 0; 136 prog->UniformStorage[i].initialized = false; 137 prog->UniformStorage[i].sampler = ~0; 138 prog->UniformStorage[i].num_driver_storage = 0; 139 prog->UniformStorage[i].driver_storage = NULL; 140 prog->UniformStorage[i].storage = NULL; 141 } 142 143 return red_zone_components; 144} 145 146/** 147 * Verify that the correct uniform is marked as having been initialized. 148 */ 149static void 150verify_initialization(struct gl_shader_program *prog, unsigned actual_index) 151{ 152 for (unsigned i = 0; i < prog->NumUserUniformStorage; i++) { 153 if (i == actual_index) { 154 EXPECT_TRUE(prog->UniformStorage[actual_index].initialized); 155 } else { 156 EXPECT_FALSE(prog->UniformStorage[i].initialized); 157 } 158 } 159} 160 161static void 162non_array_test(void *mem_ctx, struct gl_shader_program *prog, 163 unsigned actual_index, const char *name, 164 enum glsl_base_type base_type, 165 unsigned columns, unsigned rows) 166{ 167 const glsl_type *const type = 168 glsl_type::get_instance(base_type, rows, columns); 169 170 unsigned red_zone_components = 171 establish_uniform_storage(prog, 3, actual_index, name, type, 0); 172 173 ir_constant *val; 174 generate_data(mem_ctx, base_type, columns, rows, val); 175 176 linker::set_uniform_initializer(mem_ctx, prog, name, type, val); 177 178 verify_initialization(prog, actual_index); 179 verify_data(prog->UniformStorage[actual_index].storage, 0, val, 180 red_zone_components); 181} 182 183TEST_F(set_uniform_initializer, int_uniform) 184{ 185 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 1); 186} 187 188TEST_F(set_uniform_initializer, ivec2_uniform) 189{ 190 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 2); 191} 192 193TEST_F(set_uniform_initializer, ivec3_uniform) 194{ 195 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 3); 196} 197 198TEST_F(set_uniform_initializer, ivec4_uniform) 199{ 200 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 4); 201} 202 203TEST_F(set_uniform_initializer, uint_uniform) 204{ 205 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 1); 206} 207 208TEST_F(set_uniform_initializer, uvec2_uniform) 209{ 210 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 2); 211} 212 213TEST_F(set_uniform_initializer, uvec3_uniform) 214{ 215 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 3); 216} 217 218TEST_F(set_uniform_initializer, uvec4_uniform) 219{ 220 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 4); 221} 222 223TEST_F(set_uniform_initializer, bool_uniform) 224{ 225 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 1); 226} 227 228TEST_F(set_uniform_initializer, bvec2_uniform) 229{ 230 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 2); 231} 232 233TEST_F(set_uniform_initializer, bvec3_uniform) 234{ 235 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 3); 236} 237 238TEST_F(set_uniform_initializer, bvec4_uniform) 239{ 240 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 4); 241} 242 243TEST_F(set_uniform_initializer, float_uniform) 244{ 245 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 2); 246} 247 248TEST_F(set_uniform_initializer, vec2_uniform) 249{ 250 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 2); 251} 252 253TEST_F(set_uniform_initializer, vec3_uniform) 254{ 255 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 3); 256} 257 258TEST_F(set_uniform_initializer, vec4_uniform) 259{ 260 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 4); 261} 262 263TEST_F(set_uniform_initializer, mat2x2_uniform) 264{ 265 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 2); 266} 267 268TEST_F(set_uniform_initializer, mat2x3_uniform) 269{ 270 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 3); 271} 272 273TEST_F(set_uniform_initializer, mat2x4_uniform) 274{ 275 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 4); 276} 277 278TEST_F(set_uniform_initializer, mat3x2_uniform) 279{ 280 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 2); 281} 282 283TEST_F(set_uniform_initializer, mat3x3_uniform) 284{ 285 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 3); 286} 287 288TEST_F(set_uniform_initializer, mat3x4_uniform) 289{ 290 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 4); 291} 292 293TEST_F(set_uniform_initializer, mat4x2_uniform) 294{ 295 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 2); 296} 297 298TEST_F(set_uniform_initializer, mat4x3_uniform) 299{ 300 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 3); 301} 302 303TEST_F(set_uniform_initializer, mat4x4_uniform) 304{ 305 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 4); 306} 307 308static void 309array_test(void *mem_ctx, struct gl_shader_program *prog, 310 unsigned actual_index, const char *name, 311 enum glsl_base_type base_type, 312 unsigned columns, unsigned rows, unsigned array_size, 313 unsigned excess_data_size) 314{ 315 const glsl_type *const element_type = 316 glsl_type::get_instance(base_type, rows, columns); 317 318 const unsigned red_zone_components = 319 establish_uniform_storage(prog, 3, actual_index, name, element_type, 320 array_size); 321 322 /* The constant value generated may have more array elements than the 323 * uniform that it initializes. In the real compiler and linker this can 324 * happen when a uniform array is compacted because some of the tail 325 * elements are not used. In this case, the type of the uniform will be 326 * modified, but the initializer will not. 327 */ 328 ir_constant *val; 329 generate_array_data(mem_ctx, base_type, columns, rows, 330 array_size + excess_data_size, val); 331 332 linker::set_uniform_initializer(mem_ctx, prog, name, element_type, val); 333 334 verify_initialization(prog, actual_index); 335 verify_data(prog->UniformStorage[actual_index].storage, array_size, 336 val, red_zone_components); 337} 338 339TEST_F(set_uniform_initializer, int_array_uniform) 340{ 341 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 1, 4, 0); 342} 343 344TEST_F(set_uniform_initializer, ivec2_array_uniform) 345{ 346 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 2, 4, 0); 347} 348 349TEST_F(set_uniform_initializer, ivec3_array_uniform) 350{ 351 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 3, 4, 0); 352} 353 354TEST_F(set_uniform_initializer, ivec4_array_uniform) 355{ 356 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 4, 4, 0); 357} 358 359TEST_F(set_uniform_initializer, uint_array_uniform) 360{ 361 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 1, 4, 0); 362} 363 364TEST_F(set_uniform_initializer, uvec2_array_uniform) 365{ 366 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 2, 4, 0); 367} 368 369TEST_F(set_uniform_initializer, uvec3_array_uniform) 370{ 371 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 3, 4, 0); 372} 373 374TEST_F(set_uniform_initializer, uvec4_array_uniform) 375{ 376 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 4, 4, 0); 377} 378 379TEST_F(set_uniform_initializer, bool_array_uniform) 380{ 381 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 1, 4, 0); 382} 383 384TEST_F(set_uniform_initializer, bvec2_array_uniform) 385{ 386 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 2, 4, 0); 387} 388 389TEST_F(set_uniform_initializer, bvec3_array_uniform) 390{ 391 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 3, 4, 0); 392} 393 394TEST_F(set_uniform_initializer, bvec4_array_uniform) 395{ 396 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 4, 4, 0); 397} 398 399TEST_F(set_uniform_initializer, float_array_uniform) 400{ 401 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 1, 4, 0); 402} 403 404TEST_F(set_uniform_initializer, vec2_array_uniform) 405{ 406 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 2, 4, 0); 407} 408 409TEST_F(set_uniform_initializer, vec3_array_uniform) 410{ 411 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 3, 4, 0); 412} 413 414TEST_F(set_uniform_initializer, vec4_array_uniform) 415{ 416 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 4, 4, 0); 417} 418 419TEST_F(set_uniform_initializer, mat2x2_array_uniform) 420{ 421 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 2, 4, 0); 422} 423 424TEST_F(set_uniform_initializer, mat2x3_array_uniform) 425{ 426 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 3, 4, 0); 427} 428 429TEST_F(set_uniform_initializer, mat2x4_array_uniform) 430{ 431 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 4, 4, 0); 432} 433 434TEST_F(set_uniform_initializer, mat3x2_array_uniform) 435{ 436 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 2, 4, 0); 437} 438 439TEST_F(set_uniform_initializer, mat3x3_array_uniform) 440{ 441 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 3, 4, 0); 442} 443 444TEST_F(set_uniform_initializer, mat3x4_array_uniform) 445{ 446 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 4, 4, 0); 447} 448 449TEST_F(set_uniform_initializer, mat4x2_array_uniform) 450{ 451 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 2, 4, 0); 452} 453 454TEST_F(set_uniform_initializer, mat4x3_array_uniform) 455{ 456 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 3, 4, 0); 457} 458 459TEST_F(set_uniform_initializer, mat4x4_array_uniform) 460{ 461 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 4, 4, 0); 462} 463 464TEST_F(set_uniform_initializer, int_array_uniform_excess_initializer) 465{ 466 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 1, 4, 5); 467} 468 469TEST_F(set_uniform_initializer, ivec2_array_uniform_excess_initializer) 470{ 471 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 2, 4, 5); 472} 473 474TEST_F(set_uniform_initializer, ivec3_array_uniform_excess_initializer) 475{ 476 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 3, 4, 5); 477} 478 479TEST_F(set_uniform_initializer, ivec4_array_uniform_excess_initializer) 480{ 481 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 4, 4, 5); 482} 483 484TEST_F(set_uniform_initializer, uint_array_uniform_excess_initializer) 485{ 486 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 1, 4, 5); 487} 488 489TEST_F(set_uniform_initializer, uvec2_array_uniform_excess_initializer) 490{ 491 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 2, 4, 5); 492} 493 494TEST_F(set_uniform_initializer, uvec3_array_uniform_excess_initializer) 495{ 496 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 3, 4, 5); 497} 498 499TEST_F(set_uniform_initializer, uvec4_array_uniform_excess_initializer) 500{ 501 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 4, 4, 5); 502} 503 504TEST_F(set_uniform_initializer, bool_array_uniform_excess_initializer) 505{ 506 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 1, 4, 5); 507} 508 509TEST_F(set_uniform_initializer, bvec2_array_uniform_excess_initializer) 510{ 511 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 2, 4, 5); 512} 513 514TEST_F(set_uniform_initializer, bvec3_array_uniform_excess_initializer) 515{ 516 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 3, 4, 5); 517} 518 519TEST_F(set_uniform_initializer, bvec4_array_uniform_excess_initializer) 520{ 521 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 4, 4, 5); 522} 523 524TEST_F(set_uniform_initializer, float_array_uniform_excess_initializer) 525{ 526 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 1, 4, 5); 527} 528 529TEST_F(set_uniform_initializer, vec2_array_uniform_excess_initializer) 530{ 531 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 2, 4, 5); 532} 533 534TEST_F(set_uniform_initializer, vec3_array_uniform_excess_initializer) 535{ 536 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 3, 4, 5); 537} 538 539TEST_F(set_uniform_initializer, vec4_array_uniform_excess_initializer) 540{ 541 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 4, 4, 5); 542} 543 544TEST_F(set_uniform_initializer, mat2x2_array_uniform_excess_initializer) 545{ 546 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 2, 4, 5); 547} 548 549TEST_F(set_uniform_initializer, mat2x3_array_uniform_excess_initializer) 550{ 551 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 3, 4, 5); 552} 553 554TEST_F(set_uniform_initializer, mat2x4_array_uniform_excess_initializer) 555{ 556 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 4, 4, 5); 557} 558 559TEST_F(set_uniform_initializer, mat3x2_array_uniform_excess_initializer) 560{ 561 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 2, 4, 5); 562} 563 564TEST_F(set_uniform_initializer, mat3x3_array_uniform_excess_initializer) 565{ 566 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 3, 4, 5); 567} 568 569TEST_F(set_uniform_initializer, mat3x4_array_uniform_excess_initializer) 570{ 571 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 4, 4, 5); 572} 573 574TEST_F(set_uniform_initializer, mat4x2_array_uniform_excess_initializer) 575{ 576 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 2, 4, 5); 577} 578 579TEST_F(set_uniform_initializer, mat4x3_array_uniform_excess_initializer) 580{ 581 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 3, 4, 5); 582} 583 584TEST_F(set_uniform_initializer, mat4x4_array_uniform_excess_initializer) 585{ 586 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 4, 4, 5); 587} 588