2 * Copyright © 2013 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 "standalone_scaffolding.h"
25 #include "util/compiler.h"
26 #include "main/mtypes.h"
27 #include "main/macros.h"
29 #include "glsl_parser_extras.h"
30 #include "glsl_symbol_table.h"
32 class common_builtin
: public ::testing::Test
{
34 common_builtin(GLenum shader_type
)
35 : shader_type(shader_type
)
41 virtual void TearDown();
43 void string_starts_with_prefix(const char *str
, const char *prefix
);
44 void names_start_with_gl();
45 void uniforms_and_system_values_dont_have_explicit_location();
46 void constants_are_constant();
47 void no_invalid_variable_modes();
50 struct _mesa_glsl_parse_state
*state
;
51 struct gl_shader
*shader
;
58 common_builtin::SetUp()
60 glsl_type_singleton_init_or_ref();
62 this->mem_ctx
= ralloc_context(NULL
);
63 this->ir
.make_empty();
65 initialize_context_to_defaults(&this->ctx
, API_OPENGL_COMPAT
);
67 this->shader
= rzalloc(this->mem_ctx
, gl_shader
);
68 this->shader
->Type
= this->shader_type
;
69 this->shader
->Stage
= _mesa_shader_enum_to_shader_stage(this->shader_type
);
72 new(mem_ctx
) _mesa_glsl_parse_state(&this->ctx
, this->shader
->Stage
,
75 _mesa_glsl_initialize_types(this->state
);
76 _mesa_glsl_initialize_variables(&this->ir
, this->state
);
80 common_builtin::TearDown()
82 ralloc_free(this->mem_ctx
);
85 glsl_type_singleton_decref();
89 common_builtin::string_starts_with_prefix(const char *str
, const char *prefix
)
91 const size_t len
= strlen(prefix
);
92 char *const name_prefix
= new char[len
+ 1];
94 strncpy(name_prefix
, str
, len
);
95 name_prefix
[len
] = '\0';
96 EXPECT_STREQ(prefix
, name_prefix
) << "Bad name " << str
;
98 delete [] name_prefix
;
102 common_builtin::names_start_with_gl()
104 foreach_in_list(ir_instruction
, node
, &this->ir
) {
105 ir_variable
*const var
= node
->as_variable();
107 string_starts_with_prefix(var
->name
, "gl_");
112 common_builtin::uniforms_and_system_values_dont_have_explicit_location()
114 foreach_in_list(ir_instruction
, node
, &this->ir
) {
115 ir_variable
*const var
= node
->as_variable();
117 if (var
->data
.mode
!= ir_var_uniform
&& var
->data
.mode
!= ir_var_system_value
)
120 EXPECT_FALSE(var
->data
.explicit_location
);
121 EXPECT_EQ(-1, var
->data
.location
);
126 common_builtin::constants_are_constant()
128 foreach_in_list(ir_instruction
, node
, &this->ir
) {
129 ir_variable
*const var
= node
->as_variable();
131 if (var
->data
.mode
!= ir_var_auto
)
134 EXPECT_FALSE(var
->data
.explicit_location
);
135 EXPECT_EQ(-1, var
->data
.location
);
136 EXPECT_TRUE(var
->data
.read_only
);
141 common_builtin::no_invalid_variable_modes()
143 foreach_in_list(ir_instruction
, node
, &this->ir
) {
144 ir_variable
*const var
= node
->as_variable();
146 switch (var
->data
.mode
) {
149 case ir_var_shader_in
:
150 case ir_var_shader_out
:
151 case ir_var_system_value
:
155 ADD_FAILURE() << "Built-in variable " << var
->name
156 << " has an invalid mode " << int(var
->data
.mode
);
162 /************************************************************/
164 class vertex_builtin
: public common_builtin
{
167 : common_builtin(GL_VERTEX_SHADER
)
173 TEST_F(vertex_builtin
, names_start_with_gl
)
175 common_builtin::names_start_with_gl();
178 TEST_F(vertex_builtin
, inputs_have_explicit_location
)
180 foreach_in_list(ir_instruction
, node
, &this->ir
) {
181 ir_variable
*const var
= node
->as_variable();
183 if (var
->data
.mode
!= ir_var_shader_in
)
186 EXPECT_TRUE(var
->data
.explicit_location
);
187 EXPECT_NE(-1, var
->data
.location
);
188 EXPECT_GT(VERT_ATTRIB_GENERIC0
, var
->data
.location
);
189 EXPECT_EQ(0u, var
->data
.location_frac
);
193 TEST_F(vertex_builtin
, outputs_have_explicit_location
)
195 foreach_in_list(ir_instruction
, node
, &this->ir
) {
196 ir_variable
*const var
= node
->as_variable();
198 if (var
->data
.mode
!= ir_var_shader_out
)
201 EXPECT_TRUE(var
->data
.explicit_location
);
202 EXPECT_NE(-1, var
->data
.location
);
203 EXPECT_GT(VARYING_SLOT_VAR0
, var
->data
.location
);
204 EXPECT_EQ(0u, var
->data
.location_frac
);
206 /* Several varyings only exist in the fragment shader. Be sure that no
207 * outputs with these locations exist.
209 EXPECT_NE(VARYING_SLOT_PNTC
, var
->data
.location
);
210 EXPECT_NE(VARYING_SLOT_FACE
, var
->data
.location
);
211 EXPECT_NE(VARYING_SLOT_PRIMITIVE_ID
, var
->data
.location
);
215 TEST_F(vertex_builtin
, uniforms_and_system_values_dont_have_explicit_location
)
217 common_builtin::uniforms_and_system_values_dont_have_explicit_location();
220 TEST_F(vertex_builtin
, constants_are_constant
)
222 common_builtin::constants_are_constant();
225 TEST_F(vertex_builtin
, no_invalid_variable_modes
)
227 common_builtin::no_invalid_variable_modes();
230 /********************************************************************/
232 class fragment_builtin
: public common_builtin
{
235 : common_builtin(GL_FRAGMENT_SHADER
)
241 TEST_F(fragment_builtin
, names_start_with_gl
)
243 common_builtin::names_start_with_gl();
246 TEST_F(fragment_builtin
, inputs_have_explicit_location
)
248 foreach_in_list(ir_instruction
, node
, &this->ir
) {
249 ir_variable
*const var
= node
->as_variable();
251 if (var
->data
.mode
!= ir_var_shader_in
)
254 EXPECT_TRUE(var
->data
.explicit_location
);
255 EXPECT_NE(-1, var
->data
.location
);
256 EXPECT_GT(VARYING_SLOT_VAR0
, var
->data
.location
);
257 EXPECT_EQ(0u, var
->data
.location_frac
);
259 /* Several varyings only exist in the vertex / geometry shader. Be sure
260 * that no inputs with these locations exist.
262 EXPECT_TRUE(_mesa_varying_slot_in_fs((gl_varying_slot
) var
->data
.location
));
266 TEST_F(fragment_builtin
, outputs_have_explicit_location
)
268 foreach_in_list(ir_instruction
, node
, &this->ir
) {
269 ir_variable
*const var
= node
->as_variable();
271 if (var
->data
.mode
!= ir_var_shader_out
)
274 EXPECT_TRUE(var
->data
.explicit_location
);
275 EXPECT_NE(-1, var
->data
.location
);
277 /* gl_FragData[] has location FRAG_RESULT_DATA0. Locations beyond that
280 EXPECT_GE(FRAG_RESULT_DATA0
, var
->data
.location
);
282 EXPECT_EQ(0u, var
->data
.location_frac
);
286 TEST_F(fragment_builtin
, uniforms_and_system_values_dont_have_explicit_location
)
288 common_builtin::uniforms_and_system_values_dont_have_explicit_location();
291 TEST_F(fragment_builtin
, constants_are_constant
)
293 common_builtin::constants_are_constant();
296 TEST_F(fragment_builtin
, no_invalid_variable_modes
)
298 common_builtin::no_invalid_variable_modes();
301 /********************************************************************/
303 class geometry_builtin
: public common_builtin
{
306 : common_builtin(GL_GEOMETRY_SHADER
)
312 TEST_F(geometry_builtin
, names_start_with_gl
)
314 common_builtin::names_start_with_gl();
317 TEST_F(geometry_builtin
, inputs_have_explicit_location
)
319 foreach_in_list(ir_instruction
, node
, &this->ir
) {
320 ir_variable
*const var
= node
->as_variable();
322 if (var
->data
.mode
!= ir_var_shader_in
)
325 if (var
->is_interface_instance()) {
326 EXPECT_STREQ("gl_in", var
->name
);
327 EXPECT_FALSE(var
->data
.explicit_location
);
328 EXPECT_EQ(-1, var
->data
.location
);
330 ASSERT_TRUE(var
->type
->is_array());
332 const glsl_type
*const instance_type
= var
->type
->fields
.array
;
334 for (unsigned i
= 0; i
< instance_type
->length
; i
++) {
335 const glsl_struct_field
*const input
=
336 &instance_type
->fields
.structure
[i
];
338 string_starts_with_prefix(input
->name
, "gl_");
339 EXPECT_NE(-1, input
->location
);
340 EXPECT_GT(VARYING_SLOT_VAR0
, input
->location
);
342 /* Several varyings only exist in the fragment shader. Be sure
343 * that no inputs with these locations exist.
345 EXPECT_NE(VARYING_SLOT_PNTC
, input
->location
);
346 EXPECT_NE(VARYING_SLOT_FACE
, input
->location
);
349 EXPECT_TRUE(var
->data
.explicit_location
);
350 EXPECT_NE(-1, var
->data
.location
);
351 EXPECT_GT(VARYING_SLOT_VAR0
, var
->data
.location
);
352 EXPECT_EQ(0u, var
->data
.location_frac
);
355 /* Several varyings only exist in the fragment shader. Be sure that no
356 * inputs with these locations exist.
358 EXPECT_NE(VARYING_SLOT_PNTC
, var
->data
.location
);
359 EXPECT_NE(VARYING_SLOT_FACE
, var
->data
.location
);
363 TEST_F(geometry_builtin
, outputs_have_explicit_location
)
365 foreach_in_list(ir_instruction
, node
, &this->ir
) {
366 ir_variable
*const var
= node
->as_variable();
368 if (var
->data
.mode
!= ir_var_shader_out
)
371 EXPECT_TRUE(var
->data
.explicit_location
);
372 EXPECT_NE(-1, var
->data
.location
);
373 EXPECT_GT(VARYING_SLOT_VAR0
, var
->data
.location
);
374 EXPECT_EQ(0u, var
->data
.location_frac
);
376 /* Several varyings only exist in the fragment shader. Be sure that no
377 * outputs with these locations exist.
379 EXPECT_NE(VARYING_SLOT_PNTC
, var
->data
.location
);
380 EXPECT_NE(VARYING_SLOT_FACE
, var
->data
.location
);
384 TEST_F(geometry_builtin
, uniforms_and_system_values_dont_have_explicit_location
)
386 common_builtin::uniforms_and_system_values_dont_have_explicit_location();
389 TEST_F(geometry_builtin
, constants_are_constant
)
391 common_builtin::constants_are_constant();
394 TEST_F(geometry_builtin
, no_invalid_variable_modes
)
396 common_builtin::no_invalid_variable_modes();