2 * Copyright © 2012 Intel Corporation
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:
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
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.
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"
32 set_uniform_initializer(void *mem_ctx
, gl_shader_program
*prog
,
33 const char *name
, const glsl_type
*type
,
37 class set_uniform_initializer
: public ::testing::Test
{
40 virtual void TearDown();
43 * Index of the uniform to be tested.
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.
49 unsigned actual_index
;
52 * Name of the uniform to be tested.
57 * Shader program used in the test.
59 struct gl_shader_program
*prog
;
62 * Ralloc memory context used for all temporary allocations.
68 set_uniform_initializer::SetUp()
70 this->mem_ctx
= ralloc_context(NULL
);
71 this->prog
= rzalloc(NULL
, struct gl_shader_program
);
73 /* Set default values used by the test cases.
75 this->actual_index
= 1;
80 set_uniform_initializer::TearDown()
82 ralloc_free(this->mem_ctx
);
85 ralloc_free(this->prog
);
90 * Create some uniform storage for a program.
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.
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
)
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
;
111 prog
->UniformStorage
= rzalloc_array(prog
, struct gl_uniform_storage
,
113 prog
->NumUserUniformStorage
= num_storage
;
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 for (int sh
= 0; sh
< MESA_SHADER_STAGES
; sh
++) {
120 prog
->UniformStorage
[index_to_set
].sampler
[sh
].index
= ~0;
121 prog
->UniformStorage
[index_to_set
].sampler
[sh
].active
= false;
123 prog
->UniformStorage
[index_to_set
].num_driver_storage
= 0;
124 prog
->UniformStorage
[index_to_set
].driver_storage
= NULL
;
125 prog
->UniformStorage
[index_to_set
].storage
=
126 rzalloc_array(prog
, union gl_constant_value
, total_components
);
128 fill_storage_array_with_sentinels(prog
->UniformStorage
[index_to_set
].storage
,
130 red_zone_components
);
132 for (unsigned i
= 0; i
< num_storage
; i
++) {
133 if (i
== index_to_set
)
136 prog
->UniformStorage
[i
].name
= (char *) "invalid slot";
137 prog
->UniformStorage
[i
].type
= glsl_type::void_type
;
138 prog
->UniformStorage
[i
].array_elements
= 0;
139 prog
->UniformStorage
[i
].initialized
= false;
140 for (int sh
= 0; sh
< MESA_SHADER_STAGES
; sh
++) {
141 prog
->UniformStorage
[i
].sampler
[sh
].index
= ~0;
142 prog
->UniformStorage
[i
].sampler
[sh
].active
= false;
144 prog
->UniformStorage
[i
].num_driver_storage
= 0;
145 prog
->UniformStorage
[i
].driver_storage
= NULL
;
146 prog
->UniformStorage
[i
].storage
= NULL
;
149 return red_zone_components
;
153 * Verify that the correct uniform is marked as having been initialized.
156 verify_initialization(struct gl_shader_program
*prog
, unsigned actual_index
)
158 for (unsigned i
= 0; i
< prog
->NumUserUniformStorage
; i
++) {
159 if (i
== actual_index
) {
160 EXPECT_TRUE(prog
->UniformStorage
[actual_index
].initialized
);
162 EXPECT_FALSE(prog
->UniformStorage
[i
].initialized
);
168 non_array_test(void *mem_ctx
, struct gl_shader_program
*prog
,
169 unsigned actual_index
, const char *name
,
170 enum glsl_base_type base_type
,
171 unsigned columns
, unsigned rows
)
173 const glsl_type
*const type
=
174 glsl_type::get_instance(base_type
, rows
, columns
);
176 unsigned red_zone_components
=
177 establish_uniform_storage(prog
, 3, actual_index
, name
, type
, 0);
180 generate_data(mem_ctx
, base_type
, columns
, rows
, val
);
182 linker::set_uniform_initializer(mem_ctx
, prog
, name
, type
, val
);
184 verify_initialization(prog
, actual_index
);
185 verify_data(prog
->UniformStorage
[actual_index
].storage
, 0, val
,
186 red_zone_components
);
189 TEST_F(set_uniform_initializer
, int_uniform
)
191 non_array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_INT
, 1, 1);
194 TEST_F(set_uniform_initializer
, ivec2_uniform
)
196 non_array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_INT
, 1, 2);
199 TEST_F(set_uniform_initializer
, ivec3_uniform
)
201 non_array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_INT
, 1, 3);
204 TEST_F(set_uniform_initializer
, ivec4_uniform
)
206 non_array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_INT
, 1, 4);
209 TEST_F(set_uniform_initializer
, uint_uniform
)
211 non_array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_UINT
, 1, 1);
214 TEST_F(set_uniform_initializer
, uvec2_uniform
)
216 non_array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_UINT
, 1, 2);
219 TEST_F(set_uniform_initializer
, uvec3_uniform
)
221 non_array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_UINT
, 1, 3);
224 TEST_F(set_uniform_initializer
, uvec4_uniform
)
226 non_array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_UINT
, 1, 4);
229 TEST_F(set_uniform_initializer
, bool_uniform
)
231 non_array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_BOOL
, 1, 1);
234 TEST_F(set_uniform_initializer
, bvec2_uniform
)
236 non_array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_BOOL
, 1, 2);
239 TEST_F(set_uniform_initializer
, bvec3_uniform
)
241 non_array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_BOOL
, 1, 3);
244 TEST_F(set_uniform_initializer
, bvec4_uniform
)
246 non_array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_BOOL
, 1, 4);
249 TEST_F(set_uniform_initializer
, float_uniform
)
251 non_array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 1, 2);
254 TEST_F(set_uniform_initializer
, vec2_uniform
)
256 non_array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 1, 2);
259 TEST_F(set_uniform_initializer
, vec3_uniform
)
261 non_array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 1, 3);
264 TEST_F(set_uniform_initializer
, vec4_uniform
)
266 non_array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 1, 4);
269 TEST_F(set_uniform_initializer
, mat2x2_uniform
)
271 non_array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 2, 2);
274 TEST_F(set_uniform_initializer
, mat2x3_uniform
)
276 non_array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 2, 3);
279 TEST_F(set_uniform_initializer
, mat2x4_uniform
)
281 non_array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 2, 4);
284 TEST_F(set_uniform_initializer
, mat3x2_uniform
)
286 non_array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 3, 2);
289 TEST_F(set_uniform_initializer
, mat3x3_uniform
)
291 non_array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 3, 3);
294 TEST_F(set_uniform_initializer
, mat3x4_uniform
)
296 non_array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 3, 4);
299 TEST_F(set_uniform_initializer
, mat4x2_uniform
)
301 non_array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 4, 2);
304 TEST_F(set_uniform_initializer
, mat4x3_uniform
)
306 non_array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 4, 3);
309 TEST_F(set_uniform_initializer
, mat4x4_uniform
)
311 non_array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 4, 4);
315 array_test(void *mem_ctx
, struct gl_shader_program
*prog
,
316 unsigned actual_index
, const char *name
,
317 enum glsl_base_type base_type
,
318 unsigned columns
, unsigned rows
, unsigned array_size
,
319 unsigned excess_data_size
)
321 const glsl_type
*const element_type
=
322 glsl_type::get_instance(base_type
, rows
, columns
);
324 const unsigned red_zone_components
=
325 establish_uniform_storage(prog
, 3, actual_index
, name
, element_type
,
328 /* The constant value generated may have more array elements than the
329 * uniform that it initializes. In the real compiler and linker this can
330 * happen when a uniform array is compacted because some of the tail
331 * elements are not used. In this case, the type of the uniform will be
332 * modified, but the initializer will not.
335 generate_array_data(mem_ctx
, base_type
, columns
, rows
,
336 array_size
+ excess_data_size
, val
);
338 linker::set_uniform_initializer(mem_ctx
, prog
, name
, element_type
, val
);
340 verify_initialization(prog
, actual_index
);
341 verify_data(prog
->UniformStorage
[actual_index
].storage
, array_size
,
342 val
, red_zone_components
);
345 TEST_F(set_uniform_initializer
, int_array_uniform
)
347 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_INT
, 1, 1, 4, 0);
350 TEST_F(set_uniform_initializer
, ivec2_array_uniform
)
352 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_INT
, 1, 2, 4, 0);
355 TEST_F(set_uniform_initializer
, ivec3_array_uniform
)
357 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_INT
, 1, 3, 4, 0);
360 TEST_F(set_uniform_initializer
, ivec4_array_uniform
)
362 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_INT
, 1, 4, 4, 0);
365 TEST_F(set_uniform_initializer
, uint_array_uniform
)
367 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_UINT
, 1, 1, 4, 0);
370 TEST_F(set_uniform_initializer
, uvec2_array_uniform
)
372 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_UINT
, 1, 2, 4, 0);
375 TEST_F(set_uniform_initializer
, uvec3_array_uniform
)
377 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_UINT
, 1, 3, 4, 0);
380 TEST_F(set_uniform_initializer
, uvec4_array_uniform
)
382 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_UINT
, 1, 4, 4, 0);
385 TEST_F(set_uniform_initializer
, bool_array_uniform
)
387 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_BOOL
, 1, 1, 4, 0);
390 TEST_F(set_uniform_initializer
, bvec2_array_uniform
)
392 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_BOOL
, 1, 2, 4, 0);
395 TEST_F(set_uniform_initializer
, bvec3_array_uniform
)
397 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_BOOL
, 1, 3, 4, 0);
400 TEST_F(set_uniform_initializer
, bvec4_array_uniform
)
402 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_BOOL
, 1, 4, 4, 0);
405 TEST_F(set_uniform_initializer
, float_array_uniform
)
407 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 1, 1, 4, 0);
410 TEST_F(set_uniform_initializer
, vec2_array_uniform
)
412 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 1, 2, 4, 0);
415 TEST_F(set_uniform_initializer
, vec3_array_uniform
)
417 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 1, 3, 4, 0);
420 TEST_F(set_uniform_initializer
, vec4_array_uniform
)
422 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 1, 4, 4, 0);
425 TEST_F(set_uniform_initializer
, mat2x2_array_uniform
)
427 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 2, 2, 4, 0);
430 TEST_F(set_uniform_initializer
, mat2x3_array_uniform
)
432 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 2, 3, 4, 0);
435 TEST_F(set_uniform_initializer
, mat2x4_array_uniform
)
437 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 2, 4, 4, 0);
440 TEST_F(set_uniform_initializer
, mat3x2_array_uniform
)
442 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 3, 2, 4, 0);
445 TEST_F(set_uniform_initializer
, mat3x3_array_uniform
)
447 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 3, 3, 4, 0);
450 TEST_F(set_uniform_initializer
, mat3x4_array_uniform
)
452 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 3, 4, 4, 0);
455 TEST_F(set_uniform_initializer
, mat4x2_array_uniform
)
457 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 4, 2, 4, 0);
460 TEST_F(set_uniform_initializer
, mat4x3_array_uniform
)
462 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 4, 3, 4, 0);
465 TEST_F(set_uniform_initializer
, mat4x4_array_uniform
)
467 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 4, 4, 4, 0);
470 TEST_F(set_uniform_initializer
, int_array_uniform_excess_initializer
)
472 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_INT
, 1, 1, 4, 5);
475 TEST_F(set_uniform_initializer
, ivec2_array_uniform_excess_initializer
)
477 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_INT
, 1, 2, 4, 5);
480 TEST_F(set_uniform_initializer
, ivec3_array_uniform_excess_initializer
)
482 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_INT
, 1, 3, 4, 5);
485 TEST_F(set_uniform_initializer
, ivec4_array_uniform_excess_initializer
)
487 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_INT
, 1, 4, 4, 5);
490 TEST_F(set_uniform_initializer
, uint_array_uniform_excess_initializer
)
492 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_UINT
, 1, 1, 4, 5);
495 TEST_F(set_uniform_initializer
, uvec2_array_uniform_excess_initializer
)
497 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_UINT
, 1, 2, 4, 5);
500 TEST_F(set_uniform_initializer
, uvec3_array_uniform_excess_initializer
)
502 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_UINT
, 1, 3, 4, 5);
505 TEST_F(set_uniform_initializer
, uvec4_array_uniform_excess_initializer
)
507 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_UINT
, 1, 4, 4, 5);
510 TEST_F(set_uniform_initializer
, bool_array_uniform_excess_initializer
)
512 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_BOOL
, 1, 1, 4, 5);
515 TEST_F(set_uniform_initializer
, bvec2_array_uniform_excess_initializer
)
517 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_BOOL
, 1, 2, 4, 5);
520 TEST_F(set_uniform_initializer
, bvec3_array_uniform_excess_initializer
)
522 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_BOOL
, 1, 3, 4, 5);
525 TEST_F(set_uniform_initializer
, bvec4_array_uniform_excess_initializer
)
527 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_BOOL
, 1, 4, 4, 5);
530 TEST_F(set_uniform_initializer
, float_array_uniform_excess_initializer
)
532 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 1, 1, 4, 5);
535 TEST_F(set_uniform_initializer
, vec2_array_uniform_excess_initializer
)
537 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 1, 2, 4, 5);
540 TEST_F(set_uniform_initializer
, vec3_array_uniform_excess_initializer
)
542 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 1, 3, 4, 5);
545 TEST_F(set_uniform_initializer
, vec4_array_uniform_excess_initializer
)
547 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 1, 4, 4, 5);
550 TEST_F(set_uniform_initializer
, mat2x2_array_uniform_excess_initializer
)
552 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 2, 2, 4, 5);
555 TEST_F(set_uniform_initializer
, mat2x3_array_uniform_excess_initializer
)
557 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 2, 3, 4, 5);
560 TEST_F(set_uniform_initializer
, mat2x4_array_uniform_excess_initializer
)
562 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 2, 4, 4, 5);
565 TEST_F(set_uniform_initializer
, mat3x2_array_uniform_excess_initializer
)
567 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 3, 2, 4, 5);
570 TEST_F(set_uniform_initializer
, mat3x3_array_uniform_excess_initializer
)
572 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 3, 3, 4, 5);
575 TEST_F(set_uniform_initializer
, mat3x4_array_uniform_excess_initializer
)
577 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 3, 4, 4, 5);
580 TEST_F(set_uniform_initializer
, mat4x2_array_uniform_excess_initializer
)
582 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 4, 2, 4, 5);
585 TEST_F(set_uniform_initializer
, mat4x3_array_uniform_excess_initializer
)
587 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 4, 3, 4, 5);
590 TEST_F(set_uniform_initializer
, mat4x4_array_uniform_excess_initializer
)
592 array_test(mem_ctx
, prog
, actual_index
, name
, GLSL_TYPE_FLOAT
, 4, 4, 4, 5);