Merge remote-tracking branch 'public/master' into vulkan
[mesa.git] / src / compiler / 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 "util/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, unsigned int boolean_true);
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->NumUniformStorage = 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 for (int sh = 0; sh < MESA_SHADER_STAGES; sh++) {
119 prog->UniformStorage[index_to_set].opaque[sh].index = ~0;
120 prog->UniformStorage[index_to_set].opaque[sh].active = false;
121 }
122 prog->UniformStorage[index_to_set].num_driver_storage = 0;
123 prog->UniformStorage[index_to_set].driver_storage = NULL;
124 prog->UniformStorage[index_to_set].storage =
125 rzalloc_array(prog, union gl_constant_value, total_components);
126
127 fill_storage_array_with_sentinels(prog->UniformStorage[index_to_set].storage,
128 data_components,
129 red_zone_components);
130
131 for (unsigned i = 0; i < num_storage; i++) {
132 if (i == index_to_set)
133 continue;
134
135 prog->UniformStorage[i].name = (char *) "invalid slot";
136 prog->UniformStorage[i].type = glsl_type::void_type;
137 prog->UniformStorage[i].array_elements = 0;
138 for (int sh = 0; sh < MESA_SHADER_STAGES; sh++) {
139 prog->UniformStorage[i].opaque[sh].index = ~0;
140 prog->UniformStorage[i].opaque[sh].active = false;
141 }
142 prog->UniformStorage[i].num_driver_storage = 0;
143 prog->UniformStorage[i].driver_storage = NULL;
144 prog->UniformStorage[i].storage = NULL;
145 }
146
147 return red_zone_components;
148 }
149
150 static void
151 non_array_test(void *mem_ctx, struct gl_shader_program *prog,
152 unsigned actual_index, const char *name,
153 enum glsl_base_type base_type,
154 unsigned columns, unsigned rows)
155 {
156 const glsl_type *const type =
157 glsl_type::get_instance(base_type, rows, columns);
158
159 unsigned red_zone_components =
160 establish_uniform_storage(prog, 3, actual_index, name, type, 0);
161
162 ir_constant *val;
163 generate_data(mem_ctx, base_type, columns, rows, val);
164
165 linker::set_uniform_initializer(mem_ctx, prog, name, type, val, 0xF00F);
166
167 verify_data(prog->UniformStorage[actual_index].storage, 0, val,
168 red_zone_components, 0xF00F);
169 }
170
171 TEST_F(set_uniform_initializer, int_uniform)
172 {
173 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 1);
174 }
175
176 TEST_F(set_uniform_initializer, ivec2_uniform)
177 {
178 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 2);
179 }
180
181 TEST_F(set_uniform_initializer, ivec3_uniform)
182 {
183 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 3);
184 }
185
186 TEST_F(set_uniform_initializer, ivec4_uniform)
187 {
188 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 4);
189 }
190
191 TEST_F(set_uniform_initializer, uint_uniform)
192 {
193 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 1);
194 }
195
196 TEST_F(set_uniform_initializer, uvec2_uniform)
197 {
198 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 2);
199 }
200
201 TEST_F(set_uniform_initializer, uvec3_uniform)
202 {
203 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 3);
204 }
205
206 TEST_F(set_uniform_initializer, uvec4_uniform)
207 {
208 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 4);
209 }
210
211 TEST_F(set_uniform_initializer, bool_uniform)
212 {
213 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 1);
214 }
215
216 TEST_F(set_uniform_initializer, bvec2_uniform)
217 {
218 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 2);
219 }
220
221 TEST_F(set_uniform_initializer, bvec3_uniform)
222 {
223 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 3);
224 }
225
226 TEST_F(set_uniform_initializer, bvec4_uniform)
227 {
228 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 4);
229 }
230
231 TEST_F(set_uniform_initializer, float_uniform)
232 {
233 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 2);
234 }
235
236 TEST_F(set_uniform_initializer, vec2_uniform)
237 {
238 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 2);
239 }
240
241 TEST_F(set_uniform_initializer, vec3_uniform)
242 {
243 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 3);
244 }
245
246 TEST_F(set_uniform_initializer, vec4_uniform)
247 {
248 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 4);
249 }
250
251 TEST_F(set_uniform_initializer, mat2x2_uniform)
252 {
253 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 2);
254 }
255
256 TEST_F(set_uniform_initializer, mat2x3_uniform)
257 {
258 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 3);
259 }
260
261 TEST_F(set_uniform_initializer, mat2x4_uniform)
262 {
263 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 4);
264 }
265
266 TEST_F(set_uniform_initializer, mat3x2_uniform)
267 {
268 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 2);
269 }
270
271 TEST_F(set_uniform_initializer, mat3x3_uniform)
272 {
273 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 3);
274 }
275
276 TEST_F(set_uniform_initializer, mat3x4_uniform)
277 {
278 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 4);
279 }
280
281 TEST_F(set_uniform_initializer, mat4x2_uniform)
282 {
283 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 2);
284 }
285
286 TEST_F(set_uniform_initializer, mat4x3_uniform)
287 {
288 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 3);
289 }
290
291 TEST_F(set_uniform_initializer, mat4x4_uniform)
292 {
293 non_array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 4);
294 }
295
296 static void
297 array_test(void *mem_ctx, struct gl_shader_program *prog,
298 unsigned actual_index, const char *name,
299 enum glsl_base_type base_type,
300 unsigned columns, unsigned rows, unsigned array_size,
301 unsigned excess_data_size)
302 {
303 const glsl_type *const element_type =
304 glsl_type::get_instance(base_type, rows, columns);
305
306 const unsigned red_zone_components =
307 establish_uniform_storage(prog, 3, actual_index, name, element_type,
308 array_size);
309
310 /* The constant value generated may have more array elements than the
311 * uniform that it initializes. In the real compiler and linker this can
312 * happen when a uniform array is compacted because some of the tail
313 * elements are not used. In this case, the type of the uniform will be
314 * modified, but the initializer will not.
315 */
316 ir_constant *val;
317 generate_array_data(mem_ctx, base_type, columns, rows,
318 array_size + excess_data_size, val);
319
320 linker::set_uniform_initializer(mem_ctx, prog, name, element_type, val,
321 0xF00F);
322
323 verify_data(prog->UniformStorage[actual_index].storage, array_size,
324 val, red_zone_components, 0xF00F);
325 }
326
327 TEST_F(set_uniform_initializer, int_array_uniform)
328 {
329 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 1, 4, 0);
330 }
331
332 TEST_F(set_uniform_initializer, ivec2_array_uniform)
333 {
334 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 2, 4, 0);
335 }
336
337 TEST_F(set_uniform_initializer, ivec3_array_uniform)
338 {
339 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 3, 4, 0);
340 }
341
342 TEST_F(set_uniform_initializer, ivec4_array_uniform)
343 {
344 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 4, 4, 0);
345 }
346
347 TEST_F(set_uniform_initializer, uint_array_uniform)
348 {
349 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 1, 4, 0);
350 }
351
352 TEST_F(set_uniform_initializer, uvec2_array_uniform)
353 {
354 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 2, 4, 0);
355 }
356
357 TEST_F(set_uniform_initializer, uvec3_array_uniform)
358 {
359 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 3, 4, 0);
360 }
361
362 TEST_F(set_uniform_initializer, uvec4_array_uniform)
363 {
364 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 4, 4, 0);
365 }
366
367 TEST_F(set_uniform_initializer, bool_array_uniform)
368 {
369 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 1, 4, 0);
370 }
371
372 TEST_F(set_uniform_initializer, bvec2_array_uniform)
373 {
374 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 2, 4, 0);
375 }
376
377 TEST_F(set_uniform_initializer, bvec3_array_uniform)
378 {
379 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 3, 4, 0);
380 }
381
382 TEST_F(set_uniform_initializer, bvec4_array_uniform)
383 {
384 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 4, 4, 0);
385 }
386
387 TEST_F(set_uniform_initializer, float_array_uniform)
388 {
389 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 1, 4, 0);
390 }
391
392 TEST_F(set_uniform_initializer, vec2_array_uniform)
393 {
394 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 2, 4, 0);
395 }
396
397 TEST_F(set_uniform_initializer, vec3_array_uniform)
398 {
399 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 3, 4, 0);
400 }
401
402 TEST_F(set_uniform_initializer, vec4_array_uniform)
403 {
404 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 4, 4, 0);
405 }
406
407 TEST_F(set_uniform_initializer, mat2x2_array_uniform)
408 {
409 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 2, 4, 0);
410 }
411
412 TEST_F(set_uniform_initializer, mat2x3_array_uniform)
413 {
414 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 3, 4, 0);
415 }
416
417 TEST_F(set_uniform_initializer, mat2x4_array_uniform)
418 {
419 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 4, 4, 0);
420 }
421
422 TEST_F(set_uniform_initializer, mat3x2_array_uniform)
423 {
424 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 2, 4, 0);
425 }
426
427 TEST_F(set_uniform_initializer, mat3x3_array_uniform)
428 {
429 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 3, 4, 0);
430 }
431
432 TEST_F(set_uniform_initializer, mat3x4_array_uniform)
433 {
434 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 4, 4, 0);
435 }
436
437 TEST_F(set_uniform_initializer, mat4x2_array_uniform)
438 {
439 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 2, 4, 0);
440 }
441
442 TEST_F(set_uniform_initializer, mat4x3_array_uniform)
443 {
444 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 3, 4, 0);
445 }
446
447 TEST_F(set_uniform_initializer, mat4x4_array_uniform)
448 {
449 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 4, 4, 0);
450 }
451
452 TEST_F(set_uniform_initializer, int_array_uniform_excess_initializer)
453 {
454 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 1, 4, 5);
455 }
456
457 TEST_F(set_uniform_initializer, ivec2_array_uniform_excess_initializer)
458 {
459 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 2, 4, 5);
460 }
461
462 TEST_F(set_uniform_initializer, ivec3_array_uniform_excess_initializer)
463 {
464 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 3, 4, 5);
465 }
466
467 TEST_F(set_uniform_initializer, ivec4_array_uniform_excess_initializer)
468 {
469 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_INT, 1, 4, 4, 5);
470 }
471
472 TEST_F(set_uniform_initializer, uint_array_uniform_excess_initializer)
473 {
474 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 1, 4, 5);
475 }
476
477 TEST_F(set_uniform_initializer, uvec2_array_uniform_excess_initializer)
478 {
479 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 2, 4, 5);
480 }
481
482 TEST_F(set_uniform_initializer, uvec3_array_uniform_excess_initializer)
483 {
484 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 3, 4, 5);
485 }
486
487 TEST_F(set_uniform_initializer, uvec4_array_uniform_excess_initializer)
488 {
489 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_UINT, 1, 4, 4, 5);
490 }
491
492 TEST_F(set_uniform_initializer, bool_array_uniform_excess_initializer)
493 {
494 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 1, 4, 5);
495 }
496
497 TEST_F(set_uniform_initializer, bvec2_array_uniform_excess_initializer)
498 {
499 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 2, 4, 5);
500 }
501
502 TEST_F(set_uniform_initializer, bvec3_array_uniform_excess_initializer)
503 {
504 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 3, 4, 5);
505 }
506
507 TEST_F(set_uniform_initializer, bvec4_array_uniform_excess_initializer)
508 {
509 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_BOOL, 1, 4, 4, 5);
510 }
511
512 TEST_F(set_uniform_initializer, float_array_uniform_excess_initializer)
513 {
514 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 1, 4, 5);
515 }
516
517 TEST_F(set_uniform_initializer, vec2_array_uniform_excess_initializer)
518 {
519 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 2, 4, 5);
520 }
521
522 TEST_F(set_uniform_initializer, vec3_array_uniform_excess_initializer)
523 {
524 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 3, 4, 5);
525 }
526
527 TEST_F(set_uniform_initializer, vec4_array_uniform_excess_initializer)
528 {
529 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 1, 4, 4, 5);
530 }
531
532 TEST_F(set_uniform_initializer, mat2x2_array_uniform_excess_initializer)
533 {
534 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 2, 4, 5);
535 }
536
537 TEST_F(set_uniform_initializer, mat2x3_array_uniform_excess_initializer)
538 {
539 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 3, 4, 5);
540 }
541
542 TEST_F(set_uniform_initializer, mat2x4_array_uniform_excess_initializer)
543 {
544 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 2, 4, 4, 5);
545 }
546
547 TEST_F(set_uniform_initializer, mat3x2_array_uniform_excess_initializer)
548 {
549 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 2, 4, 5);
550 }
551
552 TEST_F(set_uniform_initializer, mat3x3_array_uniform_excess_initializer)
553 {
554 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 3, 4, 5);
555 }
556
557 TEST_F(set_uniform_initializer, mat3x4_array_uniform_excess_initializer)
558 {
559 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 3, 4, 4, 5);
560 }
561
562 TEST_F(set_uniform_initializer, mat4x2_array_uniform_excess_initializer)
563 {
564 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 2, 4, 5);
565 }
566
567 TEST_F(set_uniform_initializer, mat4x3_array_uniform_excess_initializer)
568 {
569 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 3, 4, 5);
570 }
571
572 TEST_F(set_uniform_initializer, mat4x4_array_uniform_excess_initializer)
573 {
574 array_test(mem_ctx, prog, actual_index, name, GLSL_TYPE_FLOAT, 4, 4, 4, 5);
575 }