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