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 "main/compiler.h"
26 #include "main/mtypes.h"
27 #include "main/macros.h"
30 #include "glsl_parser_extras.h"
31 #include "glsl_symbol_table.h"
33 class common_builtin
: public ::testing::Test
{
35 common_builtin(GLenum shader_type
)
36 : shader_type(shader_type
)
42 virtual void TearDown();
44 void string_starts_with_prefix(const char *str
, const char *prefix
);
45 void names_start_with_gl();
46 void uniforms_and_system_values_dont_have_explicit_location();
47 void constants_are_constant();
48 void no_invalid_variable_modes();
51 struct _mesa_glsl_parse_state
*state
;
52 struct gl_shader
*shader
;
59 common_builtin::SetUp()
61 this->mem_ctx
= ralloc_context(NULL
);
62 this->ir
.make_empty();
64 initialize_context_to_defaults(&this->ctx
, API_OPENGL_COMPAT
);
66 this->shader
= rzalloc(this->mem_ctx
, gl_shader
);
67 this->shader
->Type
= this->shader_type
;
68 this->shader
->Stage
= _mesa_shader_enum_to_shader_stage(this->shader_type
);
71 new(mem_ctx
) _mesa_glsl_parse_state(&this->ctx
, this->shader
->Stage
,
74 _mesa_glsl_initialize_types(this->state
);
75 _mesa_glsl_initialize_variables(&this->ir
, this->state
);
79 common_builtin::TearDown()
81 ralloc_free(this->mem_ctx
);
86 common_builtin::string_starts_with_prefix(const char *str
, const char *prefix
)
88 const size_t len
= strlen(prefix
);
89 char *const name_prefix
= new char[len
+ 1];
91 strncpy(name_prefix
, str
, len
);
92 name_prefix
[len
] = '\0';
93 EXPECT_STREQ(prefix
, name_prefix
) << "Bad name " << str
;
95 delete [] name_prefix
;
99 common_builtin::names_start_with_gl()
101 foreach_list(node
, &this->ir
) {
102 ir_variable
*const var
= ((ir_instruction
*) node
)->as_variable();
104 string_starts_with_prefix(var
->name
, "gl_");
109 common_builtin::uniforms_and_system_values_dont_have_explicit_location()
111 foreach_list(node
, &this->ir
) {
112 ir_variable
*const var
= ((ir_instruction
*) node
)->as_variable();
114 if (var
->data
.mode
!= ir_var_uniform
&& var
->data
.mode
!= ir_var_system_value
)
117 EXPECT_FALSE(var
->data
.explicit_location
);
118 EXPECT_EQ(-1, var
->data
.location
);
123 common_builtin::constants_are_constant()
125 foreach_list(node
, &this->ir
) {
126 ir_variable
*const var
= ((ir_instruction
*) node
)->as_variable();
128 if (var
->data
.mode
!= ir_var_auto
)
131 EXPECT_FALSE(var
->data
.explicit_location
);
132 EXPECT_EQ(-1, var
->data
.location
);
133 EXPECT_TRUE(var
->data
.read_only
);
138 common_builtin::no_invalid_variable_modes()
140 foreach_list(node
, &this->ir
) {
141 ir_variable
*const var
= ((ir_instruction
*) node
)->as_variable();
143 switch (var
->data
.mode
) {
146 case ir_var_shader_in
:
147 case ir_var_shader_out
:
148 case ir_var_system_value
:
152 ADD_FAILURE() << "Built-in variable " << var
->name
153 << " has an invalid mode " << int(var
->data
.mode
);
159 /************************************************************/
161 class vertex_builtin
: public common_builtin
{
164 : common_builtin(GL_VERTEX_SHADER
)
170 TEST_F(vertex_builtin
, names_start_with_gl
)
172 common_builtin::names_start_with_gl();
175 TEST_F(vertex_builtin
, inputs_have_explicit_location
)
177 foreach_list(node
, &this->ir
) {
178 ir_variable
*const var
= ((ir_instruction
*) node
)->as_variable();
180 if (var
->data
.mode
!= ir_var_shader_in
)
183 EXPECT_TRUE(var
->data
.explicit_location
);
184 EXPECT_NE(-1, var
->data
.location
);
185 EXPECT_GT(VERT_ATTRIB_GENERIC0
, var
->data
.location
);
186 EXPECT_EQ(0u, var
->data
.location_frac
);
190 TEST_F(vertex_builtin
, outputs_have_explicit_location
)
192 foreach_list(node
, &this->ir
) {
193 ir_variable
*const var
= ((ir_instruction
*) node
)->as_variable();
195 if (var
->data
.mode
!= ir_var_shader_out
)
198 EXPECT_TRUE(var
->data
.explicit_location
);
199 EXPECT_NE(-1, var
->data
.location
);
200 EXPECT_GT(VARYING_SLOT_VAR0
, var
->data
.location
);
201 EXPECT_EQ(0u, var
->data
.location_frac
);
203 /* Several varyings only exist in the fragment shader. Be sure that no
204 * outputs with these locations exist.
206 EXPECT_NE(VARYING_SLOT_PNTC
, var
->data
.location
);
207 EXPECT_NE(VARYING_SLOT_FACE
, var
->data
.location
);
208 EXPECT_NE(VARYING_SLOT_PRIMITIVE_ID
, var
->data
.location
);
212 TEST_F(vertex_builtin
, uniforms_and_system_values_dont_have_explicit_location
)
214 common_builtin::uniforms_and_system_values_dont_have_explicit_location();
217 TEST_F(vertex_builtin
, constants_are_constant
)
219 common_builtin::constants_are_constant();
222 TEST_F(vertex_builtin
, no_invalid_variable_modes
)
224 common_builtin::no_invalid_variable_modes();
227 /********************************************************************/
229 class fragment_builtin
: public common_builtin
{
232 : common_builtin(GL_FRAGMENT_SHADER
)
238 TEST_F(fragment_builtin
, names_start_with_gl
)
240 common_builtin::names_start_with_gl();
243 TEST_F(fragment_builtin
, inputs_have_explicit_location
)
245 foreach_list(node
, &this->ir
) {
246 ir_variable
*const var
= ((ir_instruction
*) node
)->as_variable();
248 if (var
->data
.mode
!= ir_var_shader_in
)
251 EXPECT_TRUE(var
->data
.explicit_location
);
252 EXPECT_NE(-1, var
->data
.location
);
253 EXPECT_GT(VARYING_SLOT_VAR0
, var
->data
.location
);
254 EXPECT_EQ(0u, var
->data
.location_frac
);
256 /* Several varyings only exist in the vertex / geometry shader. Be sure
257 * that no inputs with these locations exist.
259 EXPECT_TRUE(_mesa_varying_slot_in_fs((gl_varying_slot
) var
->data
.location
));
263 TEST_F(fragment_builtin
, outputs_have_explicit_location
)
265 foreach_list(node
, &this->ir
) {
266 ir_variable
*const var
= ((ir_instruction
*) node
)->as_variable();
268 if (var
->data
.mode
!= ir_var_shader_out
)
271 EXPECT_TRUE(var
->data
.explicit_location
);
272 EXPECT_NE(-1, var
->data
.location
);
274 /* gl_FragData[] has location FRAG_RESULT_DATA0. Locations beyond that
277 EXPECT_GE(FRAG_RESULT_DATA0
, var
->data
.location
);
279 EXPECT_EQ(0u, var
->data
.location_frac
);
283 TEST_F(fragment_builtin
, uniforms_and_system_values_dont_have_explicit_location
)
285 common_builtin::uniforms_and_system_values_dont_have_explicit_location();
288 TEST_F(fragment_builtin
, constants_are_constant
)
290 common_builtin::constants_are_constant();
293 TEST_F(fragment_builtin
, no_invalid_variable_modes
)
295 common_builtin::no_invalid_variable_modes();
298 /********************************************************************/
300 class geometry_builtin
: public common_builtin
{
303 : common_builtin(GL_GEOMETRY_SHADER
)
309 TEST_F(geometry_builtin
, names_start_with_gl
)
311 common_builtin::names_start_with_gl();
314 TEST_F(geometry_builtin
, inputs_have_explicit_location
)
316 foreach_list(node
, &this->ir
) {
317 ir_variable
*const var
= ((ir_instruction
*) node
)->as_variable();
319 if (var
->data
.mode
!= ir_var_shader_in
)
322 if (var
->is_interface_instance()) {
323 EXPECT_STREQ("gl_in", var
->name
);
324 EXPECT_FALSE(var
->data
.explicit_location
);
325 EXPECT_EQ(-1, var
->data
.location
);
327 ASSERT_TRUE(var
->type
->is_array());
329 const glsl_type
*const instance_type
= var
->type
->fields
.array
;
331 for (unsigned i
= 0; i
< instance_type
->length
; i
++) {
332 const glsl_struct_field
*const input
=
333 &instance_type
->fields
.structure
[i
];
335 string_starts_with_prefix(input
->name
, "gl_");
336 EXPECT_NE(-1, input
->location
);
337 EXPECT_GT(VARYING_SLOT_VAR0
, input
->location
);
339 /* Several varyings only exist in the fragment shader. Be sure
340 * that no inputs with these locations exist.
342 EXPECT_NE(VARYING_SLOT_PNTC
, input
->location
);
343 EXPECT_NE(VARYING_SLOT_FACE
, input
->location
);
346 EXPECT_TRUE(var
->data
.explicit_location
);
347 EXPECT_NE(-1, var
->data
.location
);
348 EXPECT_GT(VARYING_SLOT_VAR0
, var
->data
.location
);
349 EXPECT_EQ(0u, var
->data
.location_frac
);
352 /* Several varyings only exist in the fragment shader. Be sure that no
353 * inputs with these locations exist.
355 EXPECT_NE(VARYING_SLOT_PNTC
, var
->data
.location
);
356 EXPECT_NE(VARYING_SLOT_FACE
, var
->data
.location
);
360 TEST_F(geometry_builtin
, outputs_have_explicit_location
)
362 foreach_list(node
, &this->ir
) {
363 ir_variable
*const var
= ((ir_instruction
*) node
)->as_variable();
365 if (var
->data
.mode
!= ir_var_shader_out
)
368 EXPECT_TRUE(var
->data
.explicit_location
);
369 EXPECT_NE(-1, var
->data
.location
);
370 EXPECT_GT(VARYING_SLOT_VAR0
, var
->data
.location
);
371 EXPECT_EQ(0u, var
->data
.location_frac
);
373 /* Several varyings only exist in the fragment shader. Be sure that no
374 * outputs with these locations exist.
376 EXPECT_NE(VARYING_SLOT_PNTC
, var
->data
.location
);
377 EXPECT_NE(VARYING_SLOT_FACE
, var
->data
.location
);
381 TEST_F(geometry_builtin
, uniforms_and_system_values_dont_have_explicit_location
)
383 common_builtin::uniforms_and_system_values_dont_have_explicit_location();
386 TEST_F(geometry_builtin
, constants_are_constant
)
388 common_builtin::constants_are_constant();
391 TEST_F(geometry_builtin
, no_invalid_variable_modes
)
393 common_builtin::no_invalid_variable_modes();