radeon/llvm: Fix lowering of vbuild
[mesa.git] / src / glsl / tests / set_uniform_initializer_tests.cpp
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 }