1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
4 *
5 * Copyright (c) 2016 Google Inc.
6 * Copyright (c) 2016 The Khronos Group Inc.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 */ /*!
21 * \file
22 * \brief Shader struct tests.
23 */ /*-------------------------------------------------------------------*/
24
25 #include "glcShaderStructTests.hpp"
26 #include "glcShaderRenderCase.hpp"
27 #include "gluTexture.hpp"
28 #include "glwEnums.hpp"
29 #include "glwFunctions.hpp"
30 #include "tcuStringTemplate.hpp"
31 #include "tcuTextureUtil.hpp"
32 #include "deMath.h"
33
34 using tcu::StringTemplate;
35
36 using std::string;
37 using std::vector;
38 using std::ostringstream;
39
40 using namespace glu;
41
42 namespace deqp
43 {
44
45 enum
46 {
47 TEXTURE_GRADIENT = 0 //!< Unit index for gradient texture
48 };
49
50 typedef void (*SetupUniformsFunc)(const glw::Functions& gl, deUint32 programID, const tcu::Vec4& constCoords);
51
52 class ShaderStructCase : public ShaderRenderCase
53 {
54 public:
55 ShaderStructCase(Context& context, const char* name, const char* description, bool isVertexCase, bool usesTextures,
56 ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniformsFunc, const char* vertShaderSource,
57 const char* fragShaderSource);
58 ~ShaderStructCase(void);
59
60 void init(void);
61 void deinit(void);
62
63 virtual void setupUniforms(deUint32 programID, const tcu::Vec4& constCoords);
64
65 private:
66 ShaderStructCase(const ShaderStructCase&);
67 ShaderStructCase& operator=(const ShaderStructCase&);
68
69 SetupUniformsFunc m_setupUniforms;
70 bool m_usesTexture;
71
72 glu::Texture2D* m_gradientTexture;
73 };
74
ShaderStructCase(Context& context, const char* name, const char* description, bool isVertexCase, bool usesTextures, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniformsFunc, const char* vertShaderSource, const char* fragShaderSource)75 ShaderStructCase::ShaderStructCase(Context& context, const char* name, const char* description, bool isVertexCase,
76 bool usesTextures, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniformsFunc,
77 const char* vertShaderSource, const char* fragShaderSource)
78 : ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name,
79 description, isVertexCase, evalFunc)
80 , m_setupUniforms(setupUniformsFunc)
81 , m_usesTexture(usesTextures)
82 , m_gradientTexture(DE_NULL)
83 {
84 m_vertShaderSource = vertShaderSource;
85 m_fragShaderSource = fragShaderSource;
86 }
87
~ShaderStructCase(void)88 ShaderStructCase::~ShaderStructCase(void)
89 {
90 }
91
init(void)92 void ShaderStructCase::init(void)
93 {
94 if (m_usesTexture)
95 {
96 m_gradientTexture = new glu::Texture2D(m_renderCtx, GL_RGBA8, 128, 128);
97
98 m_gradientTexture->getRefTexture().allocLevel(0);
99 tcu::fillWithComponentGradients(m_gradientTexture->getRefTexture().getLevel(0), tcu::Vec4(0.0f),
100 tcu::Vec4(1.0f));
101 m_gradientTexture->upload();
102
103 m_textures.push_back(TextureBinding(
104 m_gradientTexture, tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
105 tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::LINEAR, tcu::Sampler::LINEAR)));
106 DE_ASSERT(m_textures.size() == 1);
107 }
108 ShaderRenderCase::init();
109 }
110
deinit(void)111 void ShaderStructCase::deinit(void)
112 {
113 if (m_usesTexture)
114 {
115 delete m_gradientTexture;
116 }
117 ShaderRenderCase::deinit();
118 }
119
setupUniforms(deUint32 programID, const tcu::Vec4& constCoords)120 void ShaderStructCase::setupUniforms(deUint32 programID, const tcu::Vec4& constCoords)
121 {
122 ShaderRenderCase::setupUniforms(programID, constCoords);
123 if (m_setupUniforms)
124 m_setupUniforms(m_renderCtx.getFunctions(), programID, constCoords);
125 }
126
createStructCase(Context& context, const char* name, const char* description, glu::GLSLVersion glslVersion, bool isVertexCase, bool usesTextures, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniforms, const LineStream& shaderSrc)127 static ShaderStructCase* createStructCase(Context& context, const char* name, const char* description,
128 glu::GLSLVersion glslVersion, bool isVertexCase, bool usesTextures,
129 ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniforms,
130 const LineStream& shaderSrc)
131 {
132 const std::string versionDecl = glu::getGLSLVersionDeclaration(glslVersion);
133
134 const std::string defaultVertSrc = versionDecl + "\n"
135 "in highp vec4 a_position;\n"
136 "in highp vec4 a_coords;\n"
137 "out mediump vec4 v_coords;\n\n"
138 "void main (void)\n"
139 "{\n"
140 " v_coords = a_coords;\n"
141 " gl_Position = a_position;\n"
142 "}\n";
143 const std::string defaultFragSrc = versionDecl + "\n"
144 "in mediump vec4 v_color;\n"
145 "layout(location = 0) out mediump vec4 o_color;\n\n"
146 "void main (void)\n"
147 "{\n"
148 " o_color = v_color;\n"
149 "}\n";
150
151 // Fill in specialization parameters.
152 std::map<std::string, std::string> spParams;
153 if (isVertexCase)
154 {
155 spParams["HEADER"] = versionDecl + "\n"
156 "in highp vec4 a_position;\n"
157 "in highp vec4 a_coords;\n"
158 "out mediump vec4 v_color;";
159 spParams["COORDS"] = "a_coords";
160 spParams["DST"] = "v_color";
161 spParams["ASSIGN_POS"] = "gl_Position = a_position;";
162 }
163 else
164 {
165 spParams["HEADER"] = versionDecl + "\n"
166 "in mediump vec4 v_coords;\n"
167 "layout(location = 0) out mediump vec4 o_color;";
168 spParams["COORDS"] = "v_coords";
169 spParams["DST"] = "o_color";
170 spParams["ASSIGN_POS"] = "";
171 }
172
173 if (isVertexCase)
174 return new ShaderStructCase(context, name, description, isVertexCase, usesTextures, evalFunc, setupUniforms,
175 StringTemplate(shaderSrc.str()).specialize(spParams).c_str(),
176 defaultFragSrc.c_str());
177 else
178 return new ShaderStructCase(context, name, description, isVertexCase, usesTextures, evalFunc, setupUniforms,
179 defaultVertSrc.c_str(),
180 StringTemplate(shaderSrc.str()).specialize(spParams).c_str());
181 }
182
183 class LocalStructTests : public TestCaseGroup
184 {
185 public:
LocalStructTests(Context& context, glu::GLSLVersion glslVersion)186 LocalStructTests(Context& context, glu::GLSLVersion glslVersion)
187 : TestCaseGroup(context, "local", "Local structs"), m_glslVersion(glslVersion)
188 {
189 }
190
~LocalStructTests(void)191 ~LocalStructTests(void)
192 {
193 }
194
195 virtual void init(void);
196
197 private:
198 glu::GLSLVersion m_glslVersion;
199 };
200
init(void)201 void LocalStructTests::init(void)
202 {
203 #define LOCAL_STRUCT_CASE(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY) \
204 do \
205 { \
206 struct Eval_##NAME \
207 { \
208 static void eval(ShaderEvalContext& c) EVAL_FUNC_BODY \
209 }; \
210 addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, m_glslVersion, true, false, \
211 &Eval_##NAME::eval, DE_NULL, SHADER_SRC)); \
212 addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, m_glslVersion, false, false, \
213 &Eval_##NAME::eval, DE_NULL, SHADER_SRC)); \
214 } while (deGetFalse())
215
216 LOCAL_STRUCT_CASE(basic, "Basic struct usage",
217 LineStream() << "${HEADER}"
218 << "uniform int ui_one;"
219 << ""
220 << "struct S {"
221 << " mediump float a;"
222 << " mediump vec3 b;"
223 << " int c;"
224 << "};"
225 << ""
226 << "void main (void)"
227 << "{"
228 << " S s = S(${COORDS}.x, vec3(0.0), ui_one);"
229 << " s.b = ${COORDS}.yzw;"
230 << " ${DST} = vec4(s.a, s.b.x, s.b.y, s.c);"
231 << " ${ASSIGN_POS}"
232 << "}",
233 { c.color.xyz() = c.coords.swizzle(0, 1, 2); });
234
235 LOCAL_STRUCT_CASE(nested, "Nested struct",
236 LineStream() << "${HEADER}"
237 << "uniform int ui_zero;"
238 << "uniform int ui_one;"
239 << ""
240 << "struct T {"
241 << " int a;"
242 << " mediump vec2 b;"
243 << "};"
244 << "struct S {"
245 << " mediump float a;"
246 << " T b;"
247 << " int c;"
248 << "};"
249 << ""
250 << "void main (void)"
251 << "{"
252 << " S s = S(${COORDS}.x, T(0, vec2(0.0)), ui_one);"
253 << " s.b = T(ui_zero, ${COORDS}.yz);"
254 << " ${DST} = vec4(s.a, s.b.b, s.b.a + s.c);"
255 << " ${ASSIGN_POS}"
256 << "}",
257 { c.color.xyz() = c.coords.swizzle(0, 1, 2); });
258
259 LOCAL_STRUCT_CASE(array_member, "Struct with array member",
260 LineStream() << "${HEADER}"
261 << "uniform int ui_one;"
262 << ""
263 << "struct S {"
264 << " mediump float a;"
265 << " mediump float b[3];"
266 << " int c;"
267 << "};"
268 << ""
269 << "void main (void)"
270 << "{"
271 << " S s;"
272 << " s.a = ${COORDS}.w;"
273 << " s.c = ui_one;"
274 << " s.b[0] = ${COORDS}.z;"
275 << " s.b[1] = ${COORDS}.y;"
276 << " s.b[2] = ${COORDS}.x;"
277 << " ${DST} = vec4(s.a, s.b[0], s.b[1], s.c);"
278 << " ${ASSIGN_POS}"
279 << "}",
280 { c.color.xyz() = c.coords.swizzle(3, 2, 1); });
281
282 LOCAL_STRUCT_CASE(array_member_dynamic_index, "Struct with array member, dynamic indexing",
283 LineStream() << "${HEADER}"
284 << "uniform int ui_zero;"
285 << "uniform int ui_one;"
286 << "uniform int ui_two;"
287 << ""
288 << "struct S {"
289 << " mediump float a;"
290 << " mediump float b[3];"
291 << " int c;"
292 << "};"
293 << ""
294 << "void main (void)"
295 << "{"
296 << " S s;"
297 << " s.a = ${COORDS}.w;"
298 << " s.c = ui_one;"
299 << " s.b[0] = ${COORDS}.z;"
300 << " s.b[1] = ${COORDS}.y;"
301 << " s.b[2] = ${COORDS}.x;"
302 << " ${DST} = vec4(s.b[ui_one], s.b[ui_zero], s.b[ui_two], s.c);"
303 << " ${ASSIGN_POS}"
304 << "}",
305 { c.color.xyz() = c.coords.swizzle(1, 2, 0); });
306
307 LOCAL_STRUCT_CASE(struct_array, "Struct array",
308 LineStream() << "${HEADER}"
309 << "uniform int ui_zero;"
310 << "uniform int ui_one;"
311 << "uniform int ui_two;"
312 << ""
313 << "struct S {"
314 << " mediump float a;"
315 << " mediump int b;"
316 << "};"
317 << ""
318 << "void main (void)"
319 << "{"
320 << " S s[3];"
321 << " s[0] = S(${COORDS}.x, ui_zero);"
322 << " s[1].a = ${COORDS}.y;"
323 << " s[1].b = ui_one;"
324 << " s[2] = S(${COORDS}.z, ui_two);"
325 << " ${DST} = vec4(s[2].a, s[1].a, s[0].a, s[2].b - s[1].b + s[0].b);"
326 << " ${ASSIGN_POS}"
327 << "}",
328 { c.color.xyz() = c.coords.swizzle(2, 1, 0); });
329
330 LOCAL_STRUCT_CASE(
331 struct_array_dynamic_index, "Struct array with dynamic indexing",
332 LineStream()
333 << "${HEADER}"
334 << "uniform int ui_zero;"
335 << "uniform int ui_one;"
336 << "uniform int ui_two;"
337 << ""
338 << "struct S {"
339 << " mediump float a;"
340 << " mediump int b;"
341 << "};"
342 << ""
343 << "void main (void)"
344 << "{"
345 << " S s[3];"
346 << " s[0] = S(${COORDS}.x, ui_zero);"
347 << " s[1].a = ${COORDS}.y;"
348 << " s[1].b = ui_one;"
349 << " s[2] = S(${COORDS}.z, ui_two);"
350 << " ${DST} = vec4(s[ui_two].a, s[ui_one].a, s[ui_zero].a, s[ui_two].b - s[ui_one].b + s[ui_zero].b);"
351 << " ${ASSIGN_POS}"
352 << "}",
353 { c.color.xyz() = c.coords.swizzle(2, 1, 0); });
354
355 LOCAL_STRUCT_CASE(
356 nested_struct_array, "Nested struct array",
357 LineStream() << "${HEADER}"
358 << "uniform int ui_zero;"
359 << "uniform int ui_one;"
360 << "uniform int ui_two;"
361 << "uniform mediump float uf_two;"
362 << "uniform mediump float uf_three;"
363 << "uniform mediump float uf_four;"
364 << "uniform mediump float uf_half;"
365 << "uniform mediump float uf_third;"
366 << "uniform mediump float uf_fourth;"
367 << ""
368 << "struct T {"
369 << " mediump float a;"
370 << " mediump vec2 b[2];"
371 << "};"
372 << "struct S {"
373 << " mediump float a;"
374 << " T b[3];"
375 << " int c;"
376 << "};"
377 << ""
378 << "void main (void)"
379 << "{"
380 << " S s[2];"
381 << ""
382 << " // S[0]"
383 << " s[0].a = ${COORDS}.x;"
384 << " s[0].b[0].a = uf_half;"
385 << " s[0].b[0].b[0] = ${COORDS}.xy;"
386 << " s[0].b[0].b[1] = ${COORDS}.zw;"
387 << " s[0].b[1].a = uf_third;"
388 << " s[0].b[1].b[0] = ${COORDS}.zw;"
389 << " s[0].b[1].b[1] = ${COORDS}.xy;"
390 << " s[0].b[2].a = uf_fourth;"
391 << " s[0].b[2].b[0] = ${COORDS}.xz;"
392 << " s[0].b[2].b[1] = ${COORDS}.yw;"
393 << " s[0].c = ui_zero;"
394 << ""
395 << " // S[1]"
396 << " s[1].a = ${COORDS}.w;"
397 << " s[1].b[0].a = uf_two;"
398 << " s[1].b[0].b[0] = ${COORDS}.xx;"
399 << " s[1].b[0].b[1] = ${COORDS}.yy;"
400 << " s[1].b[1].a = uf_three;"
401 << " s[1].b[1].b[0] = ${COORDS}.zz;"
402 << " s[1].b[1].b[1] = ${COORDS}.ww;"
403 << " s[1].b[2].a = uf_four;"
404 << " s[1].b[2].b[0] = ${COORDS}.yx;"
405 << " s[1].b[2].b[1] = ${COORDS}.wz;"
406 << " s[1].c = ui_one;"
407 << ""
408 << " mediump float r = (s[0].b[1].b[0].x + s[1].b[2].b[1].y) * s[0].b[0].a; // (z + z) * 0.5"
409 << " mediump float g = s[1].b[0].b[0].y * s[0].b[2].a * s[1].b[2].a; // x * 0.25 * 4"
410 << " mediump float b = (s[0].b[2].b[1].y + s[0].b[1].b[0].y + s[1].a) * s[0].b[1].a; // (w + w "
411 "+ w) * 0.333"
412 << " mediump float a = float(s[0].c) + s[1].b[2].a - s[1].b[1].a; // 0 + 4.0 - 3.0"
413 << " ${DST} = vec4(r, g, b, a);"
414 << " ${ASSIGN_POS}"
415 << "}",
416 { c.color.xyz() = c.coords.swizzle(2, 0, 3); });
417
418 LOCAL_STRUCT_CASE(nested_struct_array_dynamic_index, "Nested struct array with dynamic indexing",
419 LineStream() << "${HEADER}"
420 << "uniform int ui_zero;"
421 << "uniform int ui_one;"
422 << "uniform int ui_two;"
423 << "uniform mediump float uf_two;"
424 << "uniform mediump float uf_three;"
425 << "uniform mediump float uf_four;"
426 << "uniform mediump float uf_half;"
427 << "uniform mediump float uf_third;"
428 << "uniform mediump float uf_fourth;"
429 << ""
430 << "struct T {"
431 << " mediump float a;"
432 << " mediump vec2 b[2];"
433 << "};"
434 << "struct S {"
435 << " mediump float a;"
436 << " T b[3];"
437 << " int c;"
438 << "};"
439 << ""
440 << "void main (void)"
441 << "{"
442 << " S s[2];"
443 << ""
444 << " // S[0]"
445 << " s[0].a = ${COORDS}.x;"
446 << " s[0].b[0].a = uf_half;"
447 << " s[0].b[0].b[0] = ${COORDS}.xy;"
448 << " s[0].b[0].b[1] = ${COORDS}.zw;"
449 << " s[0].b[1].a = uf_third;"
450 << " s[0].b[1].b[0] = ${COORDS}.zw;"
451 << " s[0].b[1].b[1] = ${COORDS}.xy;"
452 << " s[0].b[2].a = uf_fourth;"
453 << " s[0].b[2].b[0] = ${COORDS}.xz;"
454 << " s[0].b[2].b[1] = ${COORDS}.yw;"
455 << " s[0].c = ui_zero;"
456 << ""
457 << " // S[1]"
458 << " s[1].a = ${COORDS}.w;"
459 << " s[1].b[0].a = uf_two;"
460 << " s[1].b[0].b[0] = ${COORDS}.xx;"
461 << " s[1].b[0].b[1] = ${COORDS}.yy;"
462 << " s[1].b[1].a = uf_three;"
463 << " s[1].b[1].b[0] = ${COORDS}.zz;"
464 << " s[1].b[1].b[1] = ${COORDS}.ww;"
465 << " s[1].b[2].a = uf_four;"
466 << " s[1].b[2].b[0] = ${COORDS}.yx;"
467 << " s[1].b[2].b[1] = ${COORDS}.wz;"
468 << " s[1].c = ui_one;"
469 << ""
470 << " mediump float r = (s[0].b[ui_one].b[ui_one-1].x + "
471 "s[ui_one].b[ui_two].b[ui_zero+1].y) * s[0].b[0].a; // (z + z) * 0.5"
472 << " mediump float g = s[ui_two-1].b[ui_two-2].b[ui_zero].y * s[0].b[ui_two].a * "
473 "s[ui_one].b[2].a; // x * 0.25 * 4"
474 << " mediump float b = (s[ui_zero].b[ui_one+1].b[1].y + "
475 "s[0].b[ui_one*ui_one].b[0].y + s[ui_one].a) * s[0].b[ui_two-ui_one].a; // (w + "
476 "w + w) * 0.333"
477 << " mediump float a = float(s[ui_zero].c) + s[ui_one-ui_zero].b[ui_two].a - "
478 "s[ui_zero+ui_one].b[ui_two-ui_one].a; // 0 + 4.0 - 3.0"
479 << " ${DST} = vec4(r, g, b, a);"
480 << " ${ASSIGN_POS}"
481 << "}",
482 { c.color.xyz() = c.coords.swizzle(2, 0, 3); });
483
484 LOCAL_STRUCT_CASE(parameter, "Struct as a function parameter",
485 LineStream() << "${HEADER}"
486 << "uniform int ui_one;"
487 << ""
488 << "struct S {"
489 << " mediump float a;"
490 << " mediump vec3 b;"
491 << " int c;"
492 << "};"
493 << ""
494 << "mediump vec4 myFunc (S s)"
495 << "{"
496 << " return vec4(s.a, s.b.x, s.b.y, s.c);"
497 << "}"
498 << ""
499 << "void main (void)"
500 << "{"
501 << " S s = S(${COORDS}.x, vec3(0.0), ui_one);"
502 << " s.b = ${COORDS}.yzw;"
503 << " ${DST} = myFunc(s);"
504 << " ${ASSIGN_POS}"
505 << "}",
506 { c.color.xyz() = c.coords.swizzle(0, 1, 2); });
507
508 LOCAL_STRUCT_CASE(parameter_nested, "Nested struct as a function parameter",
509 LineStream() << "${HEADER}"
510 << "uniform int ui_zero;"
511 << "uniform int ui_one;"
512 << ""
513 << "struct T {"
514 << " int a;"
515 << " mediump vec2 b;"
516 << "};"
517 << "struct S {"
518 << " mediump float a;"
519 << " T b;"
520 << " int c;"
521 << "};"
522 << ""
523 << "mediump vec4 myFunc (S s)"
524 << "{"
525 << " return vec4(s.a, s.b.b, s.b.a + s.c);"
526 << "}"
527 << ""
528 << "void main (void)"
529 << "{"
530 << " S s = S(${COORDS}.x, T(0, vec2(0.0)), ui_one);"
531 << " s.b = T(ui_zero, ${COORDS}.yz);"
532 << " ${DST} = myFunc(s);"
533 << " ${ASSIGN_POS}"
534 << "}",
535 { c.color.xyz() = c.coords.swizzle(0, 1, 2); });
536
537 LOCAL_STRUCT_CASE(return, "Struct as a return value",
538 LineStream() << "${HEADER}"
539 << "uniform int ui_one;"
540 << ""
541 << "struct S {"
542 << " mediump float a;"
543 << " mediump vec3 b;"
544 << " int c;"
545 << "};"
546 << ""
547 << "S myFunc (void)"
548 << "{"
549 << " S s = S(${COORDS}.x, vec3(0.0), ui_one);"
550 << " s.b = ${COORDS}.yzw;"
551 << " return s;"
552 << "}"
553 << ""
554 << "void main (void)"
555 << "{"
556 << " S s = myFunc();"
557 << " ${DST} = vec4(s.a, s.b.x, s.b.y, s.c);"
558 << " ${ASSIGN_POS}"
559 << "}",
560 { c.color.xyz() = c.coords.swizzle(0, 1, 2); });
561
562 LOCAL_STRUCT_CASE(return_nested, "Nested struct",
563 LineStream() << "${HEADER}"
564 << "uniform int ui_zero;"
565 << "uniform int ui_one;"
566 << ""
567 << "struct T {"
568 << " int a;"
569 << " mediump vec2 b;"
570 << "};"
571 << "struct S {"
572 << " mediump float a;"
573 << " T b;"
574 << " int c;"
575 << "};"
576 << ""
577 << "S myFunc (void)"
578 << "{"
579 << " S s = S(${COORDS}.x, T(0, vec2(0.0)), ui_one);"
580 << " s.b = T(ui_zero, ${COORDS}.yz);"
581 << " return s;"
582 << "}"
583 << ""
584 << "void main (void)"
585 << "{"
586 << " S s = myFunc();"
587 << " ${DST} = vec4(s.a, s.b.b, s.b.a + s.c);"
588 << " ${ASSIGN_POS}"
589 << "}",
590 { c.color.xyz() = c.coords.swizzle(0, 1, 2); });
591
592 LOCAL_STRUCT_CASE(conditional_assignment, "Conditional struct assignment",
593 LineStream() << "${HEADER}"
594 << "uniform int ui_zero;"
595 << "uniform int ui_one;"
596 << "uniform mediump float uf_one;"
597 << ""
598 << "struct S {"
599 << " mediump float a;"
600 << " mediump vec3 b;"
601 << " int c;"
602 << "};"
603 << ""
604 << "void main (void)"
605 << "{"
606 << " S s = S(${COORDS}.x, ${COORDS}.yzw, ui_zero);"
607 << " if (uf_one > 0.0)"
608 << " s = S(${COORDS}.w, ${COORDS}.zyx, ui_one);"
609 << " ${DST} = vec4(s.a, s.b.xy, s.c);"
610 << " ${ASSIGN_POS}"
611 << "}",
612 { c.color.xyz() = c.coords.swizzle(3, 2, 1); });
613
614 LOCAL_STRUCT_CASE(loop_assignment, "Struct assignment in loop",
615 LineStream() << "${HEADER}"
616 << "uniform int ui_zero;"
617 << "uniform int ui_one;"
618 << ""
619 << "struct S {"
620 << " mediump float a;"
621 << " mediump vec3 b;"
622 << " int c;"
623 << "};"
624 << ""
625 << "void main (void)"
626 << "{"
627 << " S s = S(${COORDS}.x, ${COORDS}.yzw, ui_zero);"
628 << " for (int i = 0; i < 3; i++)"
629 << " {"
630 << " if (i == 1)"
631 << " s = S(${COORDS}.w, ${COORDS}.zyx, ui_one);"
632 << " }"
633 << " ${DST} = vec4(s.a, s.b.xy, s.c);"
634 << " ${ASSIGN_POS}"
635 << "}",
636 { c.color.xyz() = c.coords.swizzle(3, 2, 1); });
637
638 LOCAL_STRUCT_CASE(dynamic_loop_assignment, "Struct assignment in loop",
639 LineStream() << "${HEADER}"
640 << "uniform int ui_zero;"
641 << "uniform int ui_one;"
642 << "uniform int ui_three;"
643 << ""
644 << "struct S {"
645 << " mediump float a;"
646 << " mediump vec3 b;"
647 << " int c;"
648 << "};"
649 << ""
650 << "void main (void)"
651 << "{"
652 << " S s = S(${COORDS}.x, ${COORDS}.yzw, ui_zero);"
653 << " for (int i = 0; i < ui_three; i++)"
654 << " {"
655 << " if (i == ui_one)"
656 << " s = S(${COORDS}.w, ${COORDS}.zyx, ui_one);"
657 << " }"
658 << " ${DST} = vec4(s.a, s.b.xy, s.c);"
659 << " ${ASSIGN_POS}"
660 << "}",
661 { c.color.xyz() = c.coords.swizzle(3, 2, 1); });
662
663 LOCAL_STRUCT_CASE(nested_conditional_assignment, "Conditional assignment of nested struct",
664 LineStream() << "${HEADER}"
665 << "uniform int ui_zero;"
666 << "uniform int ui_one;"
667 << "uniform mediump float uf_one;"
668 << ""
669 << "struct T {"
670 << " int a;"
671 << " mediump vec2 b;"
672 << "};"
673 << "struct S {"
674 << " mediump float a;"
675 << " T b;"
676 << " int c;"
677 << "};"
678 << ""
679 << "void main (void)"
680 << "{"
681 << " S s = S(${COORDS}.x, T(ui_one, ${COORDS}.yz), ui_one);"
682 << " if (uf_one > 0.0)"
683 << " s.b = T(ui_zero, ${COORDS}.zw);"
684 << " ${DST} = vec4(s.a, s.b.b, s.c - s.b.a);"
685 << " ${ASSIGN_POS}"
686 << "}",
687 { c.color.xyz() = c.coords.swizzle(0, 2, 3); });
688
689 LOCAL_STRUCT_CASE(nested_loop_assignment, "Nested struct assignment in loop",
690 LineStream() << "${HEADER}"
691 << "uniform int ui_zero;"
692 << "uniform int ui_one;"
693 << "uniform mediump float uf_one;"
694 << ""
695 << "struct T {"
696 << " int a;"
697 << " mediump vec2 b;"
698 << "};"
699 << "struct S {"
700 << " mediump float a;"
701 << " T b;"
702 << " int c;"
703 << "};"
704 << ""
705 << "void main (void)"
706 << "{"
707 << " S s = S(${COORDS}.x, T(ui_one, ${COORDS}.yz), ui_one);"
708 << " for (int i = 0; i < 3; i++)"
709 << " {"
710 << " if (i == 1)"
711 << " s.b = T(ui_zero, ${COORDS}.zw);"
712 << " }"
713 << " ${DST} = vec4(s.a, s.b.b, s.c - s.b.a);"
714 << " ${ASSIGN_POS}"
715 << "}",
716 { c.color.xyz() = c.coords.swizzle(0, 2, 3); });
717
718 LOCAL_STRUCT_CASE(nested_dynamic_loop_assignment, "Nested struct assignment in dynamic loop",
719 LineStream() << "${HEADER}"
720 << "uniform int ui_zero;"
721 << "uniform int ui_one;"
722 << "uniform int ui_three;"
723 << "uniform mediump float uf_one;"
724 << ""
725 << "struct T {"
726 << " int a;"
727 << " mediump vec2 b;"
728 << "};"
729 << "struct S {"
730 << " mediump float a;"
731 << " T b;"
732 << " int c;"
733 << "};"
734 << ""
735 << "void main (void)"
736 << "{"
737 << " S s = S(${COORDS}.x, T(ui_one, ${COORDS}.yz), ui_one);"
738 << " for (int i = 0; i < ui_three; i++)"
739 << " {"
740 << " if (i == ui_one)"
741 << " s.b = T(ui_zero, ${COORDS}.zw);"
742 << " }"
743 << " ${DST} = vec4(s.a, s.b.b, s.c - s.b.a);"
744 << " ${ASSIGN_POS}"
745 << "}",
746 { c.color.xyz() = c.coords.swizzle(0, 2, 3); });
747
748 LOCAL_STRUCT_CASE(loop_struct_array, "Struct array usage in loop",
749 LineStream() << "${HEADER}"
750 << "uniform int ui_zero;"
751 << "uniform int ui_one;"
752 << "uniform int ui_two;"
753 << ""
754 << "struct S {"
755 << " mediump float a;"
756 << " mediump int b;"
757 << "};"
758 << ""
759 << "void main (void)"
760 << "{"
761 << " S s[3];"
762 << " s[0] = S(${COORDS}.x, ui_zero);"
763 << " s[1].a = ${COORDS}.y;"
764 << " s[1].b = -ui_one;"
765 << " s[2] = S(${COORDS}.z, ui_two);"
766 << ""
767 << " mediump float rgb[3];"
768 << " int alpha = 0;"
769 << " for (int i = 0; i < 3; i++)"
770 << " {"
771 << " rgb[i] = s[2-i].a;"
772 << " alpha += s[i].b;"
773 << " }"
774 << " ${DST} = vec4(rgb[0], rgb[1], rgb[2], alpha);"
775 << " ${ASSIGN_POS}"
776 << "}",
777 { c.color.xyz() = c.coords.swizzle(2, 1, 0); });
778
779 LOCAL_STRUCT_CASE(loop_nested_struct_array, "Nested struct array usage in loop",
780 LineStream() << "${HEADER}"
781 << "uniform int ui_zero;"
782 << "uniform int ui_one;"
783 << "uniform int ui_two;"
784 << "uniform mediump float uf_two;"
785 << "uniform mediump float uf_three;"
786 << "uniform mediump float uf_four;"
787 << "uniform mediump float uf_half;"
788 << "uniform mediump float uf_third;"
789 << "uniform mediump float uf_fourth;"
790 << "uniform mediump float uf_sixth;"
791 << ""
792 << "struct T {"
793 << " mediump float a;"
794 << " mediump vec2 b[2];"
795 << "};"
796 << "struct S {"
797 << " mediump float a;"
798 << " T b[3];"
799 << " int c;"
800 << "};"
801 << ""
802 << "void main (void)"
803 << "{"
804 << " S s[2];"
805 << ""
806 << " // S[0]"
807 << " s[0].a = ${COORDS}.x;"
808 << " s[0].b[0].a = uf_half;"
809 << " s[0].b[0].b[0] = ${COORDS}.yx;"
810 << " s[0].b[0].b[1] = ${COORDS}.zx;"
811 << " s[0].b[1].a = uf_third;"
812 << " s[0].b[1].b[0] = ${COORDS}.yy;"
813 << " s[0].b[1].b[1] = ${COORDS}.wy;"
814 << " s[0].b[2].a = uf_fourth;"
815 << " s[0].b[2].b[0] = ${COORDS}.zx;"
816 << " s[0].b[2].b[1] = ${COORDS}.zy;"
817 << " s[0].c = ui_zero;"
818 << ""
819 << " // S[1]"
820 << " s[1].a = ${COORDS}.w;"
821 << " s[1].b[0].a = uf_two;"
822 << " s[1].b[0].b[0] = ${COORDS}.zx;"
823 << " s[1].b[0].b[1] = ${COORDS}.zy;"
824 << " s[1].b[1].a = uf_three;"
825 << " s[1].b[1].b[0] = ${COORDS}.zz;"
826 << " s[1].b[1].b[1] = ${COORDS}.ww;"
827 << " s[1].b[2].a = uf_four;"
828 << " s[1].b[2].b[0] = ${COORDS}.yx;"
829 << " s[1].b[2].b[1] = ${COORDS}.wz;"
830 << " s[1].c = ui_one;"
831 << ""
832 << " mediump float r = 0.0; // (x*3 + y*3) / 6.0"
833 << " mediump float g = 0.0; // (y*3 + z*3) / 6.0"
834 << " mediump float b = 0.0; // (z*3 + w*3) / 6.0"
835 << " mediump float a = 1.0;"
836 << " for (int i = 0; i < 2; i++)"
837 << " {"
838 << " for (int j = 0; j < 3; j++)"
839 << " {"
840 << " r += s[0].b[j].b[i].y;"
841 << " g += s[i].b[j].b[0].x;"
842 << " b += s[i].b[j].b[1].x;"
843 << " a *= s[i].b[j].a;"
844 << " }"
845 << " }"
846 << " ${DST} = vec4(r*uf_sixth, g*uf_sixth, b*uf_sixth, a);"
847 << " ${ASSIGN_POS}"
848 << "}",
849 { c.color.xyz() = (c.coords.swizzle(0, 1, 2) + c.coords.swizzle(1, 2, 3)) * 0.5f; });
850
851 LOCAL_STRUCT_CASE(dynamic_loop_struct_array, "Struct array usage in dynamic loop",
852 LineStream() << "${HEADER}"
853 << "uniform int ui_zero;"
854 << "uniform int ui_one;"
855 << "uniform int ui_two;"
856 << "uniform int ui_three;"
857 << ""
858 << "struct S {"
859 << " mediump float a;"
860 << " mediump int b;"
861 << "};"
862 << ""
863 << "void main (void)"
864 << "{"
865 << " S s[3];"
866 << " s[0] = S(${COORDS}.x, ui_zero);"
867 << " s[1].a = ${COORDS}.y;"
868 << " s[1].b = -ui_one;"
869 << " s[2] = S(${COORDS}.z, ui_two);"
870 << ""
871 << " mediump float rgb[3];"
872 << " int alpha = 0;"
873 << " for (int i = 0; i < ui_three; i++)"
874 << " {"
875 << " rgb[i] = s[2-i].a;"
876 << " alpha += s[i].b;"
877 << " }"
878 << " ${DST} = vec4(rgb[0], rgb[1], rgb[2], alpha);"
879 << " ${ASSIGN_POS}"
880 << "}",
881 { c.color.xyz() = c.coords.swizzle(2, 1, 0); });
882
883 LOCAL_STRUCT_CASE(dynamic_loop_nested_struct_array, "Nested struct array usage in dynamic loop",
884 LineStream() << "${HEADER}"
885 << "uniform int ui_zero;"
886 << "uniform int ui_one;"
887 << "uniform int ui_two;"
888 << "uniform int ui_three;"
889 << "uniform mediump float uf_two;"
890 << "uniform mediump float uf_three;"
891 << "uniform mediump float uf_four;"
892 << "uniform mediump float uf_half;"
893 << "uniform mediump float uf_third;"
894 << "uniform mediump float uf_fourth;"
895 << "uniform mediump float uf_sixth;"
896 << ""
897 << "struct T {"
898 << " mediump float a;"
899 << " mediump vec2 b[2];"
900 << "};"
901 << "struct S {"
902 << " mediump float a;"
903 << " T b[3];"
904 << " int c;"
905 << "};"
906 << ""
907 << "void main (void)"
908 << "{"
909 << " S s[2];"
910 << ""
911 << " // S[0]"
912 << " s[0].a = ${COORDS}.x;"
913 << " s[0].b[0].a = uf_half;"
914 << " s[0].b[0].b[0] = ${COORDS}.yx;"
915 << " s[0].b[0].b[1] = ${COORDS}.zx;"
916 << " s[0].b[1].a = uf_third;"
917 << " s[0].b[1].b[0] = ${COORDS}.yy;"
918 << " s[0].b[1].b[1] = ${COORDS}.wy;"
919 << " s[0].b[2].a = uf_fourth;"
920 << " s[0].b[2].b[0] = ${COORDS}.zx;"
921 << " s[0].b[2].b[1] = ${COORDS}.zy;"
922 << " s[0].c = ui_zero;"
923 << ""
924 << " // S[1]"
925 << " s[1].a = ${COORDS}.w;"
926 << " s[1].b[0].a = uf_two;"
927 << " s[1].b[0].b[0] = ${COORDS}.zx;"
928 << " s[1].b[0].b[1] = ${COORDS}.zy;"
929 << " s[1].b[1].a = uf_three;"
930 << " s[1].b[1].b[0] = ${COORDS}.zz;"
931 << " s[1].b[1].b[1] = ${COORDS}.ww;"
932 << " s[1].b[2].a = uf_four;"
933 << " s[1].b[2].b[0] = ${COORDS}.yx;"
934 << " s[1].b[2].b[1] = ${COORDS}.wz;"
935 << " s[1].c = ui_one;"
936 << ""
937 << " mediump float r = 0.0; // (x*3 + y*3) / 6.0"
938 << " mediump float g = 0.0; // (y*3 + z*3) / 6.0"
939 << " mediump float b = 0.0; // (z*3 + w*3) / 6.0"
940 << " mediump float a = 1.0;"
941 << " for (int i = 0; i < ui_two; i++)"
942 << " {"
943 << " for (int j = 0; j < ui_three; j++)"
944 << " {"
945 << " r += s[0].b[j].b[i].y;"
946 << " g += s[i].b[j].b[0].x;"
947 << " b += s[i].b[j].b[1].x;"
948 << " a *= s[i].b[j].a;"
949 << " }"
950 << " }"
951 << " ${DST} = vec4(r*uf_sixth, g*uf_sixth, b*uf_sixth, a);"
952 << " ${ASSIGN_POS}"
953 << "}",
954 { c.color.xyz() = (c.coords.swizzle(0, 1, 2) + c.coords.swizzle(1, 2, 3)) * 0.5f; });
955
956 LOCAL_STRUCT_CASE(basic_equal, "Basic struct equality",
957 LineStream()
958 << "${HEADER}"
959 << "uniform int ui_one;"
960 << "uniform int ui_two;"
961 << ""
962 << "struct S {"
963 << " mediump float a;"
964 << " mediump vec3 b;"
965 << " int c;"
966 << "};"
967 << ""
968 << "void main (void)"
969 << "{"
970 << " S a = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y), 2.3), ui_one);"
971 << " S b = S(floor(${COORDS}.x+0.5), vec3(0.0, floor(${COORDS}.y), 2.3), ui_one);"
972 << " S c = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y+0.5), 2.3), ui_one);"
973 << " S d = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y), 2.3), ui_two);"
974 << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);"
975 << " if (a == b) ${DST}.x = 1.0;"
976 << " if (a == c) ${DST}.y = 1.0;"
977 << " if (a == d) ${DST}.z = 1.0;"
978 << " ${ASSIGN_POS}"
979 << "}",
980 {
981 if (deFloatFloor(c.coords[0]) == deFloatFloor(c.coords[0]+0.5f))
982 c.color.x() = 1.0f;
983 if (deFloatFloor(c.coords[1]) == deFloatFloor(c.coords[1]+0.5f))
984 c.color.y() = 1.0f;
985 });
986
987 LOCAL_STRUCT_CASE(basic_not_equal, "Basic struct equality",
988 LineStream()
989 << "${HEADER}"
990 << "uniform int ui_one;"
991 << "uniform int ui_two;"
992 << ""
993 << "struct S {"
994 << " mediump float a;"
995 << " mediump vec3 b;"
996 << " int c;"
997 << "};"
998 << ""
999 << "void main (void)"
1000 << "{"
1001 << " S a = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y), 2.3), ui_one);"
1002 << " S b = S(floor(${COORDS}.x+0.5), vec3(0.0, floor(${COORDS}.y), 2.3), ui_one);"
1003 << " S c = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y+0.5), 2.3), ui_one);"
1004 << " S d = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y), 2.3), ui_two);"
1005 << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);"
1006 << " if (a != b) ${DST}.x = 1.0;"
1007 << " if (a != c) ${DST}.y = 1.0;"
1008 << " if (a != d) ${DST}.z = 1.0;"
1009 << " ${ASSIGN_POS}"
1010 << "}",
1011 {
1012 if (deFloatFloor(c.coords[0]) != deFloatFloor(c.coords[0]+0.5f))
1013 c.color.x() = 1.0f;
1014 if (deFloatFloor(c.coords[1]) != deFloatFloor(c.coords[1]+0.5f))
1015 c.color.y() = 1.0f;
1016 c.color.z() = 1.0f;
1017 });
1018
1019 LOCAL_STRUCT_CASE(nested_equal, "Nested struct struct equality",
1020 LineStream()
1021 << "${HEADER}"
1022 << "uniform int ui_one;"
1023 << "uniform int ui_two;"
1024 << ""
1025 << "struct T {"
1026 << " mediump vec3 a;"
1027 << " int b;"
1028 << "};"
1029 << "struct S {"
1030 << " mediump float a;"
1031 << " T b;"
1032 << " int c;"
1033 << "};"
1034 << ""
1035 << "void main (void)"
1036 << "{"
1037 << " S a = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_one), 1);"
1038 << " S b = S(floor(${COORDS}.x+0.5), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_one), 1);"
1039 << " S c = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y+0.5), 2.3), ui_one), 1);"
1040 << " S d = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_two), 1);"
1041 << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);"
1042 << " if (a == b) ${DST}.x = 1.0;"
1043 << " if (a == c) ${DST}.y = 1.0;"
1044 << " if (a == d) ${DST}.z = 1.0;"
1045 << " ${ASSIGN_POS}"
1046 << "}",
1047 {
1048 if (deFloatFloor(c.coords[0]) == deFloatFloor(c.coords[0]+0.5f))
1049 c.color.x() = 1.0f;
1050 if (deFloatFloor(c.coords[1]) == deFloatFloor(c.coords[1]+0.5f))
1051 c.color.y() = 1.0f;
1052 });
1053
1054 LOCAL_STRUCT_CASE(nested_not_equal, "Nested struct struct equality",
1055 LineStream()
1056 << "${HEADER}"
1057 << "uniform int ui_one;"
1058 << "uniform int ui_two;"
1059 << ""
1060 << "struct T {"
1061 << " mediump vec3 a;"
1062 << " int b;"
1063 << "};"
1064 << "struct S {"
1065 << " mediump float a;"
1066 << " T b;"
1067 << " int c;"
1068 << "};"
1069 << ""
1070 << "void main (void)"
1071 << "{"
1072 << " S a = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_one), 1);"
1073 << " S b = S(floor(${COORDS}.x+0.5), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_one), 1);"
1074 << " S c = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y+0.5), 2.3), ui_one), 1);"
1075 << " S d = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_two), 1);"
1076 << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);"
1077 << " if (a != b) ${DST}.x = 1.0;"
1078 << " if (a != c) ${DST}.y = 1.0;"
1079 << " if (a != d) ${DST}.z = 1.0;"
1080 << " ${ASSIGN_POS}"
1081 << "}",
1082 {
1083 if (deFloatFloor(c.coords[0]) != deFloatFloor(c.coords[0]+0.5f))
1084 c.color.x() = 1.0f;
1085 if (deFloatFloor(c.coords[1]) != deFloatFloor(c.coords[1]+0.5f))
1086 c.color.y() = 1.0f;
1087 c.color.z() = 1.0f;
1088 });
1089
1090 LOCAL_STRUCT_CASE(array_member_equality, "Struct with array members equality",
1091 LineStream()
1092 << "${HEADER}"
1093 << ""
1094 << "struct S {"
1095 << " bool m[2];"
1096 << "};"
1097 << ""
1098 << "void main (void)"
1099 << "{"
1100 << " S a;"
1101 << " a.m[0] = true;"
1102 << " a.m[1] = false;"
1103 << ""
1104 << " S b;"
1105 << " b.m[0] = true;"
1106 << " b.m[1] = false;"
1107 << ""
1108 << " S c;"
1109 << " c.m[0] = true;"
1110 << " c.m[1] = true;"
1111 << ""
1112 << " ${DST} = vec4(0.0, 0.0, 1.0, 1.0);"
1113 << " if (a == b) ${DST}.x = 1.0;"
1114 << " if (a != c) ${DST}.y = 1.0;"
1115 << " ${ASSIGN_POS}"
1116 << "}",
1117 {
1118 c.color.x() = 1.0f;
1119 c.color.y() = 1.0f;
1120 c.color.z() = 1.0f;
1121 });
1122 }
1123
1124 class UniformStructTests : public TestCaseGroup
1125 {
1126 public:
UniformStructTests(Context& context, glu::GLSLVersion glslVersion)1127 UniformStructTests(Context& context, glu::GLSLVersion glslVersion)
1128 : TestCaseGroup(context, "uniform", "Uniform structs"), m_glslVersion(glslVersion)
1129 {
1130 }
1131
~UniformStructTests(void)1132 ~UniformStructTests(void)
1133 {
1134 }
1135
1136 virtual void init(void);
1137
1138 private:
1139 glu::GLSLVersion m_glslVersion;
1140 };
1141
1142 namespace
1143 {
1144
1145 #define CHECK_SET_UNIFORM(NAME) GLU_EXPECT_NO_ERROR(gl.getError(), (string("Failed to set ") + NAME).c_str())
1146
1147 #define MAKE_SET_VEC_UNIFORM(VECTYPE, SETUNIFORM) \
1148 void setUniform(const glw::Functions& gl, deUint32 programID, const char* name, const tcu::VECTYPE& vec) \
1149 { \
1150 int loc = gl.getUniformLocation(programID, name); \
1151 SETUNIFORM(loc, 1, vec.getPtr()); \
1152 CHECK_SET_UNIFORM(name); \
1153 } \
1154 struct SetUniform##VECTYPE##Unused_s \
1155 { \
1156 int unused; \
1157 }
1158
1159 #define MAKE_SET_VEC_UNIFORM_PTR(VECTYPE, SETUNIFORM) \
1160 void setUniform(const glw::Functions& gl, deUint32 programID, const char* name, const tcu::VECTYPE* vec, \
1161 int arraySize) \
1162 { \
1163 int loc = gl.getUniformLocation(programID, name); \
1164 SETUNIFORM(loc, arraySize, vec->getPtr()); \
1165 CHECK_SET_UNIFORM(name); \
1166 } \
1167 struct SetUniformPtr##VECTYPE##Unused_s \
1168 { \
1169 int unused; \
1170 }
1171
1172 MAKE_SET_VEC_UNIFORM(Vec2, gl.uniform2fv);
1173 MAKE_SET_VEC_UNIFORM(Vec3, gl.uniform3fv);
1174 MAKE_SET_VEC_UNIFORM_PTR(Vec2, gl.uniform2fv);
1175
setUniform(const glw::Functions& gl, deUint32 programID, const char* name, float value)1176 void setUniform(const glw::Functions& gl, deUint32 programID, const char* name, float value)
1177 {
1178 int loc = gl.getUniformLocation(programID, name);
1179 gl.uniform1f(loc, value);
1180 CHECK_SET_UNIFORM(name);
1181 }
1182
setUniform(const glw::Functions& gl, deUint32 programID, const char* name, int value)1183 void setUniform(const glw::Functions& gl, deUint32 programID, const char* name, int value)
1184 {
1185 int loc = gl.getUniformLocation(programID, name);
1186 gl.uniform1i(loc, value);
1187 CHECK_SET_UNIFORM(name);
1188 }
1189
setUniform(const glw::Functions& gl, deUint32 programID, const char* name, const float* value, int arraySize)1190 void setUniform(const glw::Functions& gl, deUint32 programID, const char* name, const float* value, int arraySize)
1191 {
1192 int loc = gl.getUniformLocation(programID, name);
1193 gl.uniform1fv(loc, arraySize, value);
1194 CHECK_SET_UNIFORM(name);
1195 }
1196
1197 } // anonymous
1198
init(void)1199 void UniformStructTests::init(void)
1200 {
1201 #define UNIFORM_STRUCT_CASE(NAME, DESCRIPTION, TEXTURES, SHADER_SRC, SET_UNIFORMS_BODY, EVAL_FUNC_BODY) \
1202 do \
1203 { \
1204 struct SetUniforms_##NAME \
1205 { \
1206 static void setUniforms(const glw::Functions& gl, deUint32 programID, \
1207 const tcu::Vec4& constCoords) SET_UNIFORMS_BODY \
1208 }; \
1209 struct Eval_##NAME \
1210 { \
1211 static void eval(ShaderEvalContext& c) EVAL_FUNC_BODY \
1212 }; \
1213 addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, m_glslVersion, true, TEXTURES, \
1214 Eval_##NAME::eval, SetUniforms_##NAME::setUniforms, SHADER_SRC)); \
1215 addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, m_glslVersion, false, TEXTURES, \
1216 Eval_##NAME::eval, SetUniforms_##NAME::setUniforms, SHADER_SRC)); \
1217 } while (deGetFalse())
1218
1219 UNIFORM_STRUCT_CASE(basic, "Basic struct usage", false,
1220 LineStream() << "${HEADER}"
1221 << "uniform int ui_one;"
1222 << ""
1223 << "struct S {"
1224 << " mediump float a;"
1225 << " mediump vec3 b;"
1226 << " int c;"
1227 << "};"
1228 << "uniform S s;"
1229 << ""
1230 << "void main (void)"
1231 << "{"
1232 << " ${DST} = vec4(s.a, s.b.x, s.b.y, s.c);"
1233 << " ${ASSIGN_POS}"
1234 << "}",
1235 {
1236 setUniform(gl, programID, "s.a", constCoords.x());
1237 setUniform(gl, programID, "s.b", constCoords.swizzle(1, 2, 3));
1238 setUniform(gl, programID, "s.c", 1);
1239 },
1240 { c.color.xyz() = c.constCoords.swizzle(0, 1, 2); });
1241
1242 UNIFORM_STRUCT_CASE(nested, "Nested struct", false,
1243 LineStream() << "${HEADER}"
1244 << "uniform int ui_zero;"
1245 << "uniform int ui_one;"
1246 << ""
1247 << "struct T {"
1248 << " int a;"
1249 << " mediump vec2 b;"
1250 << "};"
1251 << "struct S {"
1252 << " mediump float a;"
1253 << " T b;"
1254 << " int c;"
1255 << "};"
1256 << "uniform S s;"
1257 << ""
1258 << "void main (void)"
1259 << "{"
1260 << " ${DST} = vec4(s.a, s.b.b, s.b.a + s.c);"
1261 << " ${ASSIGN_POS}"
1262 << "}",
1263 {
1264 setUniform(gl, programID, "s.a", constCoords.x());
1265 setUniform(gl, programID, "s.b.a", 0);
1266 setUniform(gl, programID, "s.b.b", constCoords.swizzle(1, 2));
1267 setUniform(gl, programID, "s.c", 1);
1268 },
1269 { c.color.xyz() = c.constCoords.swizzle(0, 1, 2); });
1270
1271 UNIFORM_STRUCT_CASE(array_member, "Struct with array member", false,
1272 LineStream() << "${HEADER}"
1273 << "uniform int ui_one;"
1274 << ""
1275 << "struct S {"
1276 << " mediump float a;"
1277 << " mediump float b[3];"
1278 << " int c;"
1279 << "};"
1280 << "uniform S s;"
1281 << ""
1282 << "void main (void)"
1283 << "{"
1284 << " ${DST} = vec4(s.a, s.b[0], s.b[1], s.c);"
1285 << " ${ASSIGN_POS}"
1286 << "}",
1287 {
1288 setUniform(gl, programID, "s.a", constCoords.w());
1289 setUniform(gl, programID, "s.c", 1);
1290
1291 float b[3];
1292 b[0] = constCoords.z();
1293 b[1] = constCoords.y();
1294 b[2] = constCoords.x();
1295 setUniform(gl, programID, "s.b", b, DE_LENGTH_OF_ARRAY(b));
1296 },
1297 { c.color.xyz() = c.constCoords.swizzle(3, 2, 1); });
1298
1299 UNIFORM_STRUCT_CASE(array_member_dynamic_index, "Struct with array member, dynamic indexing", false,
1300 LineStream() << "${HEADER}"
1301 << "uniform int ui_zero;"
1302 << "uniform int ui_one;"
1303 << "uniform int ui_two;"
1304 << ""
1305 << "struct S {"
1306 << " mediump float a;"
1307 << " mediump float b[3];"
1308 << " int c;"
1309 << "};"
1310 << "uniform S s;"
1311 << ""
1312 << "void main (void)"
1313 << "{"
1314 << " ${DST} = vec4(s.b[ui_one], s.b[ui_zero], s.b[ui_two], s.c);"
1315 << " ${ASSIGN_POS}"
1316 << "}",
1317 {
1318 setUniform(gl, programID, "s.a", constCoords.w());
1319 setUniform(gl, programID, "s.c", 1);
1320
1321 float b[3];
1322 b[0] = constCoords.z();
1323 b[1] = constCoords.y();
1324 b[2] = constCoords.x();
1325 setUniform(gl, programID, "s.b", b, DE_LENGTH_OF_ARRAY(b));
1326 },
1327 { c.color.xyz() = c.constCoords.swizzle(1, 2, 0); });
1328
1329 UNIFORM_STRUCT_CASE(struct_array, "Struct array", false,
1330 LineStream() << "${HEADER}"
1331 << "uniform int ui_zero;"
1332 << "uniform int ui_one;"
1333 << "uniform int ui_two;"
1334 << ""
1335 << "struct S {"
1336 << " mediump float a;"
1337 << " mediump int b;"
1338 << "};"
1339 << "uniform S s[3];"
1340 << ""
1341 << "void main (void)"
1342 << "{"
1343 << " ${DST} = vec4(s[2].a, s[1].a, s[0].a, s[2].b - s[1].b + s[0].b);"
1344 << " ${ASSIGN_POS}"
1345 << "}",
1346 {
1347 setUniform(gl, programID, "s[0].a", constCoords.x());
1348 setUniform(gl, programID, "s[0].b", 0);
1349 setUniform(gl, programID, "s[1].a", constCoords.y());
1350 setUniform(gl, programID, "s[1].b", 1);
1351 setUniform(gl, programID, "s[2].a", constCoords.z());
1352 setUniform(gl, programID, "s[2].b", 2);
1353 },
1354 { c.color.xyz() = c.constCoords.swizzle(2, 1, 0); });
1355
1356 UNIFORM_STRUCT_CASE(
1357 struct_array_dynamic_index, "Struct array with dynamic indexing", false,
1358 LineStream()
1359 << "${HEADER}"
1360 << "uniform int ui_zero;"
1361 << "uniform int ui_one;"
1362 << "uniform int ui_two;"
1363 << ""
1364 << "struct S {"
1365 << " mediump float a;"
1366 << " mediump int b;"
1367 << "};"
1368 << "uniform S s[3];"
1369 << ""
1370 << "void main (void)"
1371 << "{"
1372 << " ${DST} = vec4(s[ui_two].a, s[ui_one].a, s[ui_zero].a, s[ui_two].b - s[ui_one].b + s[ui_zero].b);"
1373 << " ${ASSIGN_POS}"
1374 << "}",
1375 {
1376 setUniform(gl, programID, "s[0].a", constCoords.x());
1377 setUniform(gl, programID, "s[0].b", 0);
1378 setUniform(gl, programID, "s[1].a", constCoords.y());
1379 setUniform(gl, programID, "s[1].b", 1);
1380 setUniform(gl, programID, "s[2].a", constCoords.z());
1381 setUniform(gl, programID, "s[2].b", 2);
1382 },
1383 { c.color.xyz() = c.constCoords.swizzle(2, 1, 0); });
1384
1385 UNIFORM_STRUCT_CASE(
1386 nested_struct_array, "Nested struct array", false,
1387 LineStream() << "${HEADER}"
1388 << "struct T {"
1389 << " mediump float a;"
1390 << " mediump vec2 b[2];"
1391 << "};"
1392 << "struct S {"
1393 << " mediump float a;"
1394 << " T b[3];"
1395 << " int c;"
1396 << "};"
1397 << "uniform S s[2];"
1398 << ""
1399 << "void main (void)"
1400 << "{"
1401 << " mediump float r = (s[0].b[1].b[0].x + s[1].b[2].b[1].y) * s[0].b[0].a; // (z + z) * 0.5"
1402 << " mediump float g = s[1].b[0].b[0].y * s[0].b[2].a * s[1].b[2].a; // x * 0.25 * 4"
1403 << " mediump float b = (s[0].b[2].b[1].y + s[0].b[1].b[0].y + s[1].a) * s[0].b[1].a; // (w + w "
1404 "+ w) * 0.333"
1405 << " mediump float a = float(s[0].c) + s[1].b[2].a - s[1].b[1].a; // 0 + 4.0 - 3.0"
1406 << " ${DST} = vec4(r, g, b, a);"
1407 << " ${ASSIGN_POS}"
1408 << "}",
1409 {
1410 tcu::Vec2 arr[2];
1411
1412 setUniform(gl, programID, "s[0].a", constCoords.x());
1413 arr[0] = constCoords.swizzle(0, 1);
1414 arr[1] = constCoords.swizzle(2, 3);
1415 setUniform(gl, programID, "s[0].b[0].a", 0.5f);
1416 setUniform(gl, programID, "s[0].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1417 arr[0] = constCoords.swizzle(2, 3);
1418 arr[1] = constCoords.swizzle(0, 1);
1419 setUniform(gl, programID, "s[0].b[1].a", 1.0f / 3.0f);
1420 setUniform(gl, programID, "s[0].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1421 arr[0] = constCoords.swizzle(0, 2);
1422 arr[1] = constCoords.swizzle(1, 3);
1423 setUniform(gl, programID, "s[0].b[2].a", 1.0f / 4.0f);
1424 setUniform(gl, programID, "s[0].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1425 setUniform(gl, programID, "s[0].c", 0);
1426
1427 setUniform(gl, programID, "s[1].a", constCoords.w());
1428 arr[0] = constCoords.swizzle(0, 0);
1429 arr[1] = constCoords.swizzle(1, 1);
1430 setUniform(gl, programID, "s[1].b[0].a", 2.0f);
1431 setUniform(gl, programID, "s[1].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1432 arr[0] = constCoords.swizzle(2, 2);
1433 arr[1] = constCoords.swizzle(3, 3);
1434 setUniform(gl, programID, "s[1].b[1].a", 3.0f);
1435 setUniform(gl, programID, "s[1].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1436 arr[0] = constCoords.swizzle(1, 0);
1437 arr[1] = constCoords.swizzle(3, 2);
1438 setUniform(gl, programID, "s[1].b[2].a", 4.0f);
1439 setUniform(gl, programID, "s[1].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1440 setUniform(gl, programID, "s[1].c", 1);
1441 },
1442 { c.color.xyz() = c.constCoords.swizzle(2, 0, 3); });
1443
1444 UNIFORM_STRUCT_CASE(nested_struct_array_dynamic_index, "Nested struct array with dynamic indexing", false,
1445 LineStream() << "${HEADER}"
1446 << "uniform int ui_zero;"
1447 << "uniform int ui_one;"
1448 << "uniform int ui_two;"
1449 << ""
1450 << "struct T {"
1451 << " mediump float a;"
1452 << " mediump vec2 b[2];"
1453 << "};"
1454 << "struct S {"
1455 << " mediump float a;"
1456 << " T b[3];"
1457 << " int c;"
1458 << "};"
1459 << "uniform S s[2];"
1460 << ""
1461 << "void main (void)"
1462 << "{"
1463 << " mediump float r = (s[0].b[ui_one].b[ui_one-1].x + "
1464 "s[ui_one].b[ui_two].b[ui_zero+1].y) * s[0].b[0].a; // (z + z) * 0.5"
1465 << " mediump float g = s[ui_two-1].b[ui_two-2].b[ui_zero].y * s[0].b[ui_two].a "
1466 "* s[ui_one].b[2].a; // x * 0.25 * 4"
1467 << " mediump float b = (s[ui_zero].b[ui_one+1].b[1].y + "
1468 "s[0].b[ui_one*ui_one].b[0].y + s[ui_one].a) * s[0].b[ui_two-ui_one].a; // (w "
1469 "+ w + w) * 0.333"
1470 << " mediump float a = float(s[ui_zero].c) + s[ui_one-ui_zero].b[ui_two].a - "
1471 "s[ui_zero+ui_one].b[ui_two-ui_one].a; // 0 + 4.0 - 3.0"
1472 << " ${DST} = vec4(r, g, b, a);"
1473 << " ${ASSIGN_POS}"
1474 << "}",
1475 {
1476 tcu::Vec2 arr[2];
1477
1478 setUniform(gl, programID, "s[0].a", constCoords.x());
1479 arr[0] = constCoords.swizzle(0, 1);
1480 arr[1] = constCoords.swizzle(2, 3);
1481 setUniform(gl, programID, "s[0].b[0].a", 0.5f);
1482 setUniform(gl, programID, "s[0].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1483 arr[0] = constCoords.swizzle(2, 3);
1484 arr[1] = constCoords.swizzle(0, 1);
1485 setUniform(gl, programID, "s[0].b[1].a", 1.0f / 3.0f);
1486 setUniform(gl, programID, "s[0].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1487 arr[0] = constCoords.swizzle(0, 2);
1488 arr[1] = constCoords.swizzle(1, 3);
1489 setUniform(gl, programID, "s[0].b[2].a", 1.0f / 4.0f);
1490 setUniform(gl, programID, "s[0].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1491 setUniform(gl, programID, "s[0].c", 0);
1492
1493 setUniform(gl, programID, "s[1].a", constCoords.w());
1494 arr[0] = constCoords.swizzle(0, 0);
1495 arr[1] = constCoords.swizzle(1, 1);
1496 setUniform(gl, programID, "s[1].b[0].a", 2.0f);
1497 setUniform(gl, programID, "s[1].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1498 arr[0] = constCoords.swizzle(2, 2);
1499 arr[1] = constCoords.swizzle(3, 3);
1500 setUniform(gl, programID, "s[1].b[1].a", 3.0f);
1501 setUniform(gl, programID, "s[1].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1502 arr[0] = constCoords.swizzle(1, 0);
1503 arr[1] = constCoords.swizzle(3, 2);
1504 setUniform(gl, programID, "s[1].b[2].a", 4.0f);
1505 setUniform(gl, programID, "s[1].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1506 setUniform(gl, programID, "s[1].c", 1);
1507 },
1508 { c.color.xyz() = c.constCoords.swizzle(2, 0, 3); });
1509
1510 UNIFORM_STRUCT_CASE(loop_struct_array, "Struct array usage in loop", false,
1511 LineStream() << "${HEADER}"
1512 << "uniform int ui_zero;"
1513 << "uniform int ui_one;"
1514 << "uniform int ui_two;"
1515 << ""
1516 << "struct S {"
1517 << " mediump float a;"
1518 << " mediump int b;"
1519 << "};"
1520 << "uniform S s[3];"
1521 << ""
1522 << "void main (void)"
1523 << "{"
1524 << " mediump float rgb[3];"
1525 << " int alpha = 0;"
1526 << " for (int i = 0; i < 3; i++)"
1527 << " {"
1528 << " rgb[i] = s[2-i].a;"
1529 << " alpha += s[i].b;"
1530 << " }"
1531 << " ${DST} = vec4(rgb[0], rgb[1], rgb[2], alpha);"
1532 << " ${ASSIGN_POS}"
1533 << "}",
1534 {
1535 setUniform(gl, programID, "s[0].a", constCoords.x());
1536 setUniform(gl, programID, "s[0].b", 0);
1537 setUniform(gl, programID, "s[1].a", constCoords.y());
1538 setUniform(gl, programID, "s[1].b", -1);
1539 setUniform(gl, programID, "s[2].a", constCoords.z());
1540 setUniform(gl, programID, "s[2].b", 2);
1541 },
1542 { c.color.xyz() = c.constCoords.swizzle(2, 1, 0); });
1543
1544 UNIFORM_STRUCT_CASE(loop_nested_struct_array, "Nested struct array usage in loop", false,
1545 LineStream() << "${HEADER}"
1546 << "uniform int ui_zero;"
1547 << "uniform int ui_one;"
1548 << "uniform int ui_two;"
1549 << "uniform mediump float uf_two;"
1550 << "uniform mediump float uf_three;"
1551 << "uniform mediump float uf_four;"
1552 << "uniform mediump float uf_half;"
1553 << "uniform mediump float uf_third;"
1554 << "uniform mediump float uf_fourth;"
1555 << "uniform mediump float uf_sixth;"
1556 << ""
1557 << "struct T {"
1558 << " mediump float a;"
1559 << " mediump vec2 b[2];"
1560 << "};"
1561 << "struct S {"
1562 << " mediump float a;"
1563 << " T b[3];"
1564 << " int c;"
1565 << "};"
1566 << "uniform S s[2];"
1567 << ""
1568 << "void main (void)"
1569 << "{"
1570 << " mediump float r = 0.0; // (x*3 + y*3) / 6.0"
1571 << " mediump float g = 0.0; // (y*3 + z*3) / 6.0"
1572 << " mediump float b = 0.0; // (z*3 + w*3) / 6.0"
1573 << " mediump float a = 1.0;"
1574 << " for (int i = 0; i < 2; i++)"
1575 << " {"
1576 << " for (int j = 0; j < 3; j++)"
1577 << " {"
1578 << " r += s[0].b[j].b[i].y;"
1579 << " g += s[i].b[j].b[0].x;"
1580 << " b += s[i].b[j].b[1].x;"
1581 << " a *= s[i].b[j].a;"
1582 << " }"
1583 << " }"
1584 << " ${DST} = vec4(r*uf_sixth, g*uf_sixth, b*uf_sixth, a);"
1585 << " ${ASSIGN_POS}"
1586 << "}",
1587 {
1588 tcu::Vec2 arr[2];
1589
1590 setUniform(gl, programID, "s[0].a", constCoords.x());
1591 arr[0] = constCoords.swizzle(1, 0);
1592 arr[1] = constCoords.swizzle(2, 0);
1593 setUniform(gl, programID, "s[0].b[0].a", 0.5f);
1594 setUniform(gl, programID, "s[0].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1595 arr[0] = constCoords.swizzle(1, 1);
1596 arr[1] = constCoords.swizzle(3, 1);
1597 setUniform(gl, programID, "s[0].b[1].a", 1.0f / 3.0f);
1598 setUniform(gl, programID, "s[0].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1599 arr[0] = constCoords.swizzle(2, 1);
1600 arr[1] = constCoords.swizzle(2, 1);
1601 setUniform(gl, programID, "s[0].b[2].a", 1.0f / 4.0f);
1602 setUniform(gl, programID, "s[0].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1603 setUniform(gl, programID, "s[0].c", 0);
1604
1605 setUniform(gl, programID, "s[1].a", constCoords.w());
1606 arr[0] = constCoords.swizzle(2, 0);
1607 arr[1] = constCoords.swizzle(2, 1);
1608 setUniform(gl, programID, "s[1].b[0].a", 2.0f);
1609 setUniform(gl, programID, "s[1].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1610 arr[0] = constCoords.swizzle(2, 2);
1611 arr[1] = constCoords.swizzle(3, 3);
1612 setUniform(gl, programID, "s[1].b[1].a", 3.0f);
1613 setUniform(gl, programID, "s[1].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1614 arr[0] = constCoords.swizzle(1, 0);
1615 arr[1] = constCoords.swizzle(3, 2);
1616 setUniform(gl, programID, "s[1].b[2].a", 4.0f);
1617 setUniform(gl, programID, "s[1].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1618 setUniform(gl, programID, "s[1].c", 1);
1619 },
1620 { c.color.xyz() = (c.constCoords.swizzle(0, 1, 2) + c.constCoords.swizzle(1, 2, 3)) * 0.5f; });
1621
1622 UNIFORM_STRUCT_CASE(dynamic_loop_struct_array, "Struct array usage in dynamic loop", false,
1623 LineStream() << "${HEADER}"
1624 << "uniform int ui_zero;"
1625 << "uniform int ui_one;"
1626 << "uniform int ui_two;"
1627 << "uniform int ui_three;"
1628 << ""
1629 << "struct S {"
1630 << " mediump float a;"
1631 << " mediump int b;"
1632 << "};"
1633 << "uniform S s[3];"
1634 << ""
1635 << "void main (void)"
1636 << "{"
1637 << " mediump float rgb[3];"
1638 << " int alpha = 0;"
1639 << " for (int i = 0; i < ui_three; i++)"
1640 << " {"
1641 << " rgb[i] = s[2-i].a;"
1642 << " alpha += s[i].b;"
1643 << " }"
1644 << " ${DST} = vec4(rgb[0], rgb[1], rgb[2], alpha);"
1645 << " ${ASSIGN_POS}"
1646 << "}",
1647 {
1648 setUniform(gl, programID, "s[0].a", constCoords.x());
1649 setUniform(gl, programID, "s[0].b", 0);
1650 setUniform(gl, programID, "s[1].a", constCoords.y());
1651 setUniform(gl, programID, "s[1].b", -1);
1652 setUniform(gl, programID, "s[2].a", constCoords.z());
1653 setUniform(gl, programID, "s[2].b", 2);
1654 },
1655 { c.color.xyz() = c.constCoords.swizzle(2, 1, 0); });
1656
1657 UNIFORM_STRUCT_CASE(dynamic_loop_nested_struct_array, "Nested struct array usage in dynamic loop", false,
1658 LineStream() << "${HEADER}"
1659 << "uniform int ui_zero;"
1660 << "uniform int ui_one;"
1661 << "uniform int ui_two;"
1662 << "uniform int ui_three;"
1663 << "uniform mediump float uf_two;"
1664 << "uniform mediump float uf_three;"
1665 << "uniform mediump float uf_four;"
1666 << "uniform mediump float uf_half;"
1667 << "uniform mediump float uf_third;"
1668 << "uniform mediump float uf_fourth;"
1669 << "uniform mediump float uf_sixth;"
1670 << ""
1671 << "struct T {"
1672 << " mediump float a;"
1673 << " mediump vec2 b[2];"
1674 << "};"
1675 << "struct S {"
1676 << " mediump float a;"
1677 << " T b[3];"
1678 << " int c;"
1679 << "};"
1680 << "uniform S s[2];"
1681 << ""
1682 << "void main (void)"
1683 << "{"
1684 << " mediump float r = 0.0; // (x*3 + y*3) / 6.0"
1685 << " mediump float g = 0.0; // (y*3 + z*3) / 6.0"
1686 << " mediump float b = 0.0; // (z*3 + w*3) / 6.0"
1687 << " mediump float a = 1.0;"
1688 << " for (int i = 0; i < ui_two; i++)"
1689 << " {"
1690 << " for (int j = 0; j < ui_three; j++)"
1691 << " {"
1692 << " r += s[0].b[j].b[i].y;"
1693 << " g += s[i].b[j].b[0].x;"
1694 << " b += s[i].b[j].b[1].x;"
1695 << " a *= s[i].b[j].a;"
1696 << " }"
1697 << " }"
1698 << " ${DST} = vec4(r*uf_sixth, g*uf_sixth, b*uf_sixth, a);"
1699 << " ${ASSIGN_POS}"
1700 << "}",
1701 {
1702 tcu::Vec2 arr[2];
1703
1704 setUniform(gl, programID, "s[0].a", constCoords.x());
1705 arr[0] = constCoords.swizzle(1, 0);
1706 arr[1] = constCoords.swizzle(2, 0);
1707 setUniform(gl, programID, "s[0].b[0].a", 0.5f);
1708 setUniform(gl, programID, "s[0].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1709 arr[0] = constCoords.swizzle(1, 1);
1710 arr[1] = constCoords.swizzle(3, 1);
1711 setUniform(gl, programID, "s[0].b[1].a", 1.0f / 3.0f);
1712 setUniform(gl, programID, "s[0].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1713 arr[0] = constCoords.swizzle(2, 1);
1714 arr[1] = constCoords.swizzle(2, 1);
1715 setUniform(gl, programID, "s[0].b[2].a", 1.0f / 4.0f);
1716 setUniform(gl, programID, "s[0].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1717 setUniform(gl, programID, "s[0].c", 0);
1718
1719 setUniform(gl, programID, "s[1].a", constCoords.w());
1720 arr[0] = constCoords.swizzle(2, 0);
1721 arr[1] = constCoords.swizzle(2, 1);
1722 setUniform(gl, programID, "s[1].b[0].a", 2.0f);
1723 setUniform(gl, programID, "s[1].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1724 arr[0] = constCoords.swizzle(2, 2);
1725 arr[1] = constCoords.swizzle(3, 3);
1726 setUniform(gl, programID, "s[1].b[1].a", 3.0f);
1727 setUniform(gl, programID, "s[1].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1728 arr[0] = constCoords.swizzle(1, 0);
1729 arr[1] = constCoords.swizzle(3, 2);
1730 setUniform(gl, programID, "s[1].b[2].a", 4.0f);
1731 setUniform(gl, programID, "s[1].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1732 setUniform(gl, programID, "s[1].c", 1);
1733 },
1734 { c.color.xyz() = (c.constCoords.swizzle(0, 1, 2) + c.constCoords.swizzle(1, 2, 3)) * 0.5f; });
1735
1736 UNIFORM_STRUCT_CASE(
1737 sampler, "Sampler in struct", true,
1738 LineStream() << "${HEADER}"
1739 << "uniform int ui_one;"
1740 << ""
1741 << "struct S {"
1742 << " mediump float a;"
1743 << " mediump vec3 b;"
1744 << " sampler2D c;"
1745 << "};"
1746 << "uniform S s;"
1747 << ""
1748 << "void main (void)"
1749 << "{"
1750 << " ${DST} = vec4(texture(s.c, ${COORDS}.xy * s.b.xy + s.b.z).rgb, s.a);"
1751 << " ${ASSIGN_POS}"
1752 << "}",
1753 {
1754 DE_UNREF(constCoords);
1755 setUniform(gl, programID, "s.a", 1.0f);
1756 setUniform(gl, programID, "s.b", tcu::Vec3(0.75f, 0.75f, 0.1f));
1757 setUniform(gl, programID, "s.c", TEXTURE_GRADIENT);
1758 },
1759 { c.color.xyz() = c.texture2D(TEXTURE_GRADIENT, c.coords.swizzle(0, 1) * 0.75f + 0.1f).swizzle(0, 1, 2); });
1760
1761 UNIFORM_STRUCT_CASE(
1762 sampler_nested, "Sampler in nested struct", true,
1763 LineStream() << "${HEADER}"
1764 << "uniform int ui_zero;"
1765 << "uniform int ui_one;"
1766 << ""
1767 << "struct T {"
1768 << " sampler2D a;"
1769 << " mediump vec2 b;"
1770 << "};"
1771 << "struct S {"
1772 << " mediump float a;"
1773 << " T b;"
1774 << " int c;"
1775 << "};"
1776 << "uniform S s;"
1777 << ""
1778 << "void main (void)"
1779 << "{"
1780 << " ${DST} = vec4(texture(s.b.a, ${COORDS}.xy * s.b.b + s.a).rgb, s.c);"
1781 << " ${ASSIGN_POS}"
1782 << "}",
1783 {
1784 DE_UNREF(constCoords);
1785 setUniform(gl, programID, "s.a", 0.1f);
1786 setUniform(gl, programID, "s.b.a", TEXTURE_GRADIENT);
1787 setUniform(gl, programID, "s.b.b", tcu::Vec2(0.75f, 0.75f));
1788 setUniform(gl, programID, "s.c", 1);
1789 },
1790 { c.color.xyz() = c.texture2D(TEXTURE_GRADIENT, c.coords.swizzle(0, 1) * 0.75f + 0.1f).swizzle(0, 1, 2); });
1791
1792 UNIFORM_STRUCT_CASE(
1793 sampler_array, "Sampler in struct array", true,
1794 LineStream() << "${HEADER}"
1795 << "uniform int ui_one;"
1796 << ""
1797 << "struct S {"
1798 << " mediump float a;"
1799 << " mediump vec3 b;"
1800 << " sampler2D c;"
1801 << "};"
1802 << "uniform S s[2];"
1803 << ""
1804 << "void main (void)"
1805 << "{"
1806 << " ${DST} = vec4(texture(s[1].c, ${COORDS}.xy * s[0].b.xy + s[1].b.z).rgb, s[0].a);"
1807 << " ${ASSIGN_POS}"
1808 << "}",
1809 {
1810 DE_UNREF(constCoords);
1811 setUniform(gl, programID, "s[0].a", 1.0f);
1812 setUniform(gl, programID, "s[0].b", tcu::Vec3(0.75f, 0.75f, 0.25f));
1813 setUniform(gl, programID, "s[0].c", 1);
1814 setUniform(gl, programID, "s[1].a", 0.0f);
1815 setUniform(gl, programID, "s[1].b", tcu::Vec3(0.5f, 0.5f, 0.1f));
1816 setUniform(gl, programID, "s[1].c", TEXTURE_GRADIENT);
1817 },
1818 { c.color.xyz() = c.texture2D(TEXTURE_GRADIENT, c.coords.swizzle(0, 1) * 0.75f + 0.1f).swizzle(0, 1, 2); });
1819 }
1820
ShaderStructTests(Context& context, glu::GLSLVersion glslVersion)1821 ShaderStructTests::ShaderStructTests(Context& context, glu::GLSLVersion glslVersion)
1822 : TestCaseGroup(context, "struct", "Struct Tests"), m_glslVersion(glslVersion)
1823 {
1824 }
1825
~ShaderStructTests(void)1826 ShaderStructTests::~ShaderStructTests(void)
1827 {
1828 }
1829
init(void)1830 void ShaderStructTests::init(void)
1831 {
1832 addChild(new LocalStructTests(m_context, m_glslVersion));
1833 addChild(new UniformStructTests(m_context, m_glslVersion));
1834 }
1835
1836 } // deqp
1837