swrast: fix more fetch_texel function names
[mesa.git] / src / glsl / tests / builtin_variable_test.cpp
1 /*
2 * Copyright © 2013 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 "standalone_scaffolding.h"
25 #include "main/compiler.h"
26 #include "main/mtypes.h"
27 #include "main/macros.h"
28 #include "ralloc.h"
29 #include "ir.h"
30 #include "glsl_parser_extras.h"
31 #include "glsl_symbol_table.h"
32
33 class common_builtin : public ::testing::Test {
34 public:
35 common_builtin(GLenum shader_type)
36 : shader_type(shader_type)
37 {
38 /* empty */
39 }
40
41 virtual void SetUp();
42 virtual void TearDown();
43
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();
49
50 GLenum shader_type;
51 struct _mesa_glsl_parse_state *state;
52 struct gl_shader *shader;
53 void *mem_ctx;
54 gl_context ctx;
55 exec_list ir;
56 };
57
58 void
59 common_builtin::SetUp()
60 {
61 this->mem_ctx = ralloc_context(NULL);
62 this->ir.make_empty();
63
64 initialize_context_to_defaults(&this->ctx, API_OPENGL_COMPAT);
65
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);
69
70 this->state =
71 new(mem_ctx) _mesa_glsl_parse_state(&this->ctx, this->shader->Stage,
72 this->shader);
73
74 _mesa_glsl_initialize_types(this->state);
75 _mesa_glsl_initialize_variables(&this->ir, this->state);
76 }
77
78 void
79 common_builtin::TearDown()
80 {
81 ralloc_free(this->mem_ctx);
82 this->mem_ctx = NULL;
83 }
84
85 void
86 common_builtin::string_starts_with_prefix(const char *str, const char *prefix)
87 {
88 const size_t len = strlen(prefix);
89 char *const name_prefix = new char[len + 1];
90
91 strncpy(name_prefix, str, len);
92 name_prefix[len] = '\0';
93 EXPECT_STREQ(prefix, name_prefix) << "Bad name " << str;
94
95 delete [] name_prefix;
96 }
97
98 void
99 common_builtin::names_start_with_gl()
100 {
101 foreach_list(node, &this->ir) {
102 ir_variable *const var = ((ir_instruction *) node)->as_variable();
103
104 string_starts_with_prefix(var->name, "gl_");
105 }
106 }
107
108 void
109 common_builtin::uniforms_and_system_values_dont_have_explicit_location()
110 {
111 foreach_list(node, &this->ir) {
112 ir_variable *const var = ((ir_instruction *) node)->as_variable();
113
114 if (var->data.mode != ir_var_uniform && var->data.mode != ir_var_system_value)
115 continue;
116
117 EXPECT_FALSE(var->data.explicit_location);
118 EXPECT_EQ(-1, var->data.location);
119 }
120 }
121
122 void
123 common_builtin::constants_are_constant()
124 {
125 foreach_list(node, &this->ir) {
126 ir_variable *const var = ((ir_instruction *) node)->as_variable();
127
128 if (var->data.mode != ir_var_auto)
129 continue;
130
131 EXPECT_FALSE(var->data.explicit_location);
132 EXPECT_EQ(-1, var->data.location);
133 EXPECT_TRUE(var->data.read_only);
134 }
135 }
136
137 void
138 common_builtin::no_invalid_variable_modes()
139 {
140 foreach_list(node, &this->ir) {
141 ir_variable *const var = ((ir_instruction *) node)->as_variable();
142
143 switch (var->data.mode) {
144 case ir_var_auto:
145 case ir_var_uniform:
146 case ir_var_shader_in:
147 case ir_var_shader_out:
148 case ir_var_system_value:
149 break;
150
151 default:
152 ADD_FAILURE() << "Built-in variable " << var->name
153 << " has an invalid mode " << int(var->data.mode);
154 break;
155 }
156 }
157 }
158
159 /************************************************************/
160
161 class vertex_builtin : public common_builtin {
162 public:
163 vertex_builtin()
164 : common_builtin(GL_VERTEX_SHADER)
165 {
166 /* empty */
167 }
168 };
169
170 TEST_F(vertex_builtin, names_start_with_gl)
171 {
172 common_builtin::names_start_with_gl();
173 }
174
175 TEST_F(vertex_builtin, inputs_have_explicit_location)
176 {
177 foreach_list(node, &this->ir) {
178 ir_variable *const var = ((ir_instruction *) node)->as_variable();
179
180 if (var->data.mode != ir_var_shader_in)
181 continue;
182
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);
187 }
188 }
189
190 TEST_F(vertex_builtin, outputs_have_explicit_location)
191 {
192 foreach_list(node, &this->ir) {
193 ir_variable *const var = ((ir_instruction *) node)->as_variable();
194
195 if (var->data.mode != ir_var_shader_out)
196 continue;
197
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);
202
203 /* Several varyings only exist in the fragment shader. Be sure that no
204 * outputs with these locations exist.
205 */
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);
209 }
210 }
211
212 TEST_F(vertex_builtin, uniforms_and_system_values_dont_have_explicit_location)
213 {
214 common_builtin::uniforms_and_system_values_dont_have_explicit_location();
215 }
216
217 TEST_F(vertex_builtin, constants_are_constant)
218 {
219 common_builtin::constants_are_constant();
220 }
221
222 TEST_F(vertex_builtin, no_invalid_variable_modes)
223 {
224 common_builtin::no_invalid_variable_modes();
225 }
226
227 /********************************************************************/
228
229 class fragment_builtin : public common_builtin {
230 public:
231 fragment_builtin()
232 : common_builtin(GL_FRAGMENT_SHADER)
233 {
234 /* empty */
235 }
236 };
237
238 TEST_F(fragment_builtin, names_start_with_gl)
239 {
240 common_builtin::names_start_with_gl();
241 }
242
243 TEST_F(fragment_builtin, inputs_have_explicit_location)
244 {
245 foreach_list(node, &this->ir) {
246 ir_variable *const var = ((ir_instruction *) node)->as_variable();
247
248 if (var->data.mode != ir_var_shader_in)
249 continue;
250
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);
255
256 /* Several varyings only exist in the vertex / geometry shader. Be sure
257 * that no inputs with these locations exist.
258 */
259 EXPECT_TRUE(_mesa_varying_slot_in_fs((gl_varying_slot) var->data.location));
260 }
261 }
262
263 TEST_F(fragment_builtin, outputs_have_explicit_location)
264 {
265 foreach_list(node, &this->ir) {
266 ir_variable *const var = ((ir_instruction *) node)->as_variable();
267
268 if (var->data.mode != ir_var_shader_out)
269 continue;
270
271 EXPECT_TRUE(var->data.explicit_location);
272 EXPECT_NE(-1, var->data.location);
273
274 /* gl_FragData[] has location FRAG_RESULT_DATA0. Locations beyond that
275 * are invalid.
276 */
277 EXPECT_GE(FRAG_RESULT_DATA0, var->data.location);
278
279 EXPECT_EQ(0u, var->data.location_frac);
280 }
281 }
282
283 TEST_F(fragment_builtin, uniforms_and_system_values_dont_have_explicit_location)
284 {
285 common_builtin::uniforms_and_system_values_dont_have_explicit_location();
286 }
287
288 TEST_F(fragment_builtin, constants_are_constant)
289 {
290 common_builtin::constants_are_constant();
291 }
292
293 TEST_F(fragment_builtin, no_invalid_variable_modes)
294 {
295 common_builtin::no_invalid_variable_modes();
296 }
297
298 /********************************************************************/
299
300 class geometry_builtin : public common_builtin {
301 public:
302 geometry_builtin()
303 : common_builtin(GL_GEOMETRY_SHADER)
304 {
305 /* empty */
306 }
307 };
308
309 TEST_F(geometry_builtin, names_start_with_gl)
310 {
311 common_builtin::names_start_with_gl();
312 }
313
314 TEST_F(geometry_builtin, inputs_have_explicit_location)
315 {
316 foreach_list(node, &this->ir) {
317 ir_variable *const var = ((ir_instruction *) node)->as_variable();
318
319 if (var->data.mode != ir_var_shader_in)
320 continue;
321
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);
326
327 ASSERT_TRUE(var->type->is_array());
328
329 const glsl_type *const instance_type = var->type->fields.array;
330
331 for (unsigned i = 0; i < instance_type->length; i++) {
332 const glsl_struct_field *const input =
333 &instance_type->fields.structure[i];
334
335 string_starts_with_prefix(input->name, "gl_");
336 EXPECT_NE(-1, input->location);
337 EXPECT_GT(VARYING_SLOT_VAR0, input->location);
338
339 /* Several varyings only exist in the fragment shader. Be sure
340 * that no inputs with these locations exist.
341 */
342 EXPECT_NE(VARYING_SLOT_PNTC, input->location);
343 EXPECT_NE(VARYING_SLOT_FACE, input->location);
344 }
345 } else {
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);
350 }
351
352 /* Several varyings only exist in the fragment shader. Be sure that no
353 * inputs with these locations exist.
354 */
355 EXPECT_NE(VARYING_SLOT_PNTC, var->data.location);
356 EXPECT_NE(VARYING_SLOT_FACE, var->data.location);
357 }
358 }
359
360 TEST_F(geometry_builtin, outputs_have_explicit_location)
361 {
362 foreach_list(node, &this->ir) {
363 ir_variable *const var = ((ir_instruction *) node)->as_variable();
364
365 if (var->data.mode != ir_var_shader_out)
366 continue;
367
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);
372
373 /* Several varyings only exist in the fragment shader. Be sure that no
374 * outputs with these locations exist.
375 */
376 EXPECT_NE(VARYING_SLOT_PNTC, var->data.location);
377 EXPECT_NE(VARYING_SLOT_FACE, var->data.location);
378 }
379 }
380
381 TEST_F(geometry_builtin, uniforms_and_system_values_dont_have_explicit_location)
382 {
383 common_builtin::uniforms_and_system_values_dont_have_explicit_location();
384 }
385
386 TEST_F(geometry_builtin, constants_are_constant)
387 {
388 common_builtin::constants_are_constant();
389 }
390
391 TEST_F(geometry_builtin, no_invalid_variable_modes)
392 {
393 common_builtin::no_invalid_variable_modes();
394 }