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