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 30 namespace linker { 31 extern void 32 set_uniform_initializer(void *mem_ctx, gl_shader_program *prog, 33 const char *name, const glsl_type *type, 34 ir_constant *val); 35 } 36 37 class set_uniform_initializer : public ::testing::Test { 38 public: 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 67 void 68 set_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 79 void 80 set_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 */ 100 static unsigned 101 establish_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 */ 149 static void 150 verify_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 161 static void 162 non_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 183 TEST_F(set_uniform_initializer, int_uniform) 184 { 185 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 1); 186 } 187 188 TEST_F(set_uniform_initializer, ivec2_uniform) 189 { 190 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 2); 191 } 192 193 TEST_F(set_uniform_initializer, ivec3_uniform) 194 { 195 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 3); 196 } 197 198 TEST_F(set_uniform_initializer, ivec4_uniform) 199 { 200 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 4); 201 } 202 203 TEST_F(set_uniform_initializer, uint_uniform) 204 { 205 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 1); 206 } 207 208 TEST_F(set_uniform_initializer, uvec2_uniform) 209 { 210 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 2); 211 } 212 213 TEST_F(set_uniform_initializer, uvec3_uniform) 214 { 215 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 3); 216 } 217 218 TEST_F(set_uniform_initializer, uvec4_uniform) 219 { 220 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 4); 221 } 222 223 TEST_F(set_uniform_initializer, bool_uniform) 224 { 225 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 1); 226 } 227 228 TEST_F(set_uniform_initializer, bvec2_uniform) 229 { 230 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 2); 231 } 232 233 TEST_F(set_uniform_initializer, bvec3_uniform) 234 { 235 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 3); 236 } 237 238 TEST_F(set_uniform_initializer, bvec4_uniform) 239 { 240 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 4); 241 } 242 243 TEST_F(set_uniform_initializer, float_uniform) 244 { 245 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 2); 246 } 247 248 TEST_F(set_uniform_initializer, vec2_uniform) 249 { 250 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 2); 251 } 252 253 TEST_F(set_uniform_initializer, vec3_uniform) 254 { 255 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 3); 256 } 257 258 TEST_F(set_uniform_initializer, vec4_uniform) 259 { 260 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 4); 261 } 262 263 TEST_F(set_uniform_initializer, mat2x2_uniform) 264 { 265 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 2); 266 } 267 268 TEST_F(set_uniform_initializer, mat2x3_uniform) 269 { 270 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 3); 271 } 272 273 TEST_F(set_uniform_initializer, mat2x4_uniform) 274 { 275 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 4); 276 } 277 278 TEST_F(set_uniform_initializer, mat3x2_uniform) 279 { 280 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 2); 281 } 282 283 TEST_F(set_uniform_initializer, mat3x3_uniform) 284 { 285 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 3); 286 } 287 288 TEST_F(set_uniform_initializer, mat3x4_uniform) 289 { 290 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 4); 291 } 292 293 TEST_F(set_uniform_initializer, mat4x2_uniform) 294 { 295 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 2); 296 } 297 298 TEST_F(set_uniform_initializer, mat4x3_uniform) 299 { 300 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 3); 301 } 302 303 TEST_F(set_uniform_initializer, mat4x4_uniform) 304 { 305 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 4); 306 } 307 308 static void 309 array_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 339 TEST_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 344 TEST_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 349 TEST_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 354 TEST_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 359 TEST_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 364 TEST_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 369 TEST_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 374 TEST_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 379 TEST_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 384 TEST_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 389 TEST_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 394 TEST_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 399 TEST_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 404 TEST_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 409 TEST_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 414 TEST_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 419 TEST_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 424 TEST_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 429 TEST_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 434 TEST_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 439 TEST_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 444 TEST_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 449 TEST_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 454 TEST_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 459 TEST_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 464 TEST_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 469 TEST_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 474 TEST_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 479 TEST_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 484 TEST_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 489 TEST_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 494 TEST_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 499 TEST_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 504 TEST_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 509 TEST_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 514 TEST_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 519 TEST_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 524 TEST_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 529 TEST_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 534 TEST_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 539 TEST_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 544 TEST_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 549 TEST_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 554 TEST_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 559 TEST_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 564 TEST_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 569 TEST_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 574 TEST_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 579 TEST_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 584 TEST_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