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