1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 2.0 Module
3 * -------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Shader struct tests.
22 *//*--------------------------------------------------------------------*/
24 #include "es2fShaderStructTests.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"
33 using tcu::StringTemplate;
37 using std::ostringstream;
40 using namespace deqp::gls;
51 TEXTURE_BRICK = 0 //!< Unit index for brick texture
56 FLAG_USES_TEXTURES = (1<<0),
57 FLAG_REQUIRES_DYNAMIC_LOOPS = (1<<1),
58 FLAG_REQUIRES_DYNAMIC_INDEXING = (1<<2),
59 FLAG_REQUIRES_HIGHP_FRAGMENT = (1<<3),
62 typedef void (*SetupUniformsFunc) (const glw::Functions& gl, deUint32 programID, const tcu::Vec4& constCoords);
64 class ShaderStructCase : public ShaderRenderCase
67 ShaderStructCase (Context& context, const char* name, const char* description, bool isVertexCase, deUint32 flags, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniformsFunc, const char* vertShaderSource, const char* fragShaderSource);
68 ~ShaderStructCase (void);
73 virtual void setupUniforms (int programID, const tcu::Vec4& constCoords);
76 ShaderStructCase (const ShaderStructCase&);
77 ShaderStructCase& operator= (const ShaderStructCase&);
79 const SetupUniformsFunc m_setupUniforms;
80 const deUint32 m_flags;
82 glu::Texture2D* m_brickTexture;
85 ShaderStructCase::ShaderStructCase (Context& context, const char* name, const char* description, bool isVertexCase, deUint32 flags, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniformsFunc, const char* vertShaderSource, const char* fragShaderSource)
86 : ShaderRenderCase (context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name, description, isVertexCase, evalFunc)
87 , m_setupUniforms (setupUniformsFunc)
89 , m_brickTexture (DE_NULL)
91 m_vertShaderSource = vertShaderSource;
92 m_fragShaderSource = fragShaderSource;
95 ShaderStructCase::~ShaderStructCase (void)
97 delete m_brickTexture;
100 void ShaderStructCase::init (void)
104 gls::ShaderRenderCase::init();
106 catch (const CompileFailed&)
108 if (m_flags & FLAG_REQUIRES_DYNAMIC_LOOPS)
110 const bool isSupported = m_isVertexCase ? m_ctxInfo.isVertexDynamicLoopSupported() : m_ctxInfo.isFragmentDynamicLoopSupported();
112 throw tcu::NotSupportedError("Dynamic loops not supported");
115 if ((m_flags & FLAG_USES_TEXTURES) && m_isVertexCase)
118 m_renderCtx.getFunctions().getIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &numTextures);
119 if (numTextures == 0)
120 throw tcu::NotSupportedError("Vertex shader texture access not supported");
123 if (m_flags & FLAG_REQUIRES_DYNAMIC_INDEXING)
124 throw tcu::NotSupportedError("Dynamic indexing not supported");
126 if (!m_isVertexCase && (m_flags & FLAG_REQUIRES_HIGHP_FRAGMENT) &&
127 !m_ctxInfo.isFragmentHighPrecisionSupported())
128 throw tcu::NotSupportedError("Highp in fragment shaders not supported");
133 if (m_flags & FLAG_USES_TEXTURES)
135 m_brickTexture = glu::Texture2D::create(m_renderCtx, m_ctxInfo, m_testCtx.getArchive(), "data/brick.png");
136 m_textures.push_back(TextureBinding(m_brickTexture, tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
137 tcu::Sampler::LINEAR, tcu::Sampler::LINEAR)));
138 DE_ASSERT(m_textures.size() == 1);
142 void ShaderStructCase::deinit (void)
144 gls::ShaderRenderCase::deinit();
145 delete m_brickTexture;
146 m_brickTexture = DE_NULL;
149 void ShaderStructCase::setupUniforms (int programID, const tcu::Vec4& constCoords)
151 ShaderRenderCase::setupUniforms(programID, constCoords);
153 m_setupUniforms(m_renderCtx.getFunctions(), programID, constCoords);
156 static ShaderStructCase* createStructCase (Context& context, const char* name, const char* description, bool isVertexCase, deUint32 flags, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniforms, const LineStream& shaderSrc, const std::map<std::string, std::string>* additionalParams)
158 static const char* defaultVertSrc =
159 "attribute highp vec4 a_position;\n"
160 "attribute highp vec4 a_coords;\n"
161 "varying mediump vec4 v_coords;\n\n"
164 " v_coords = a_coords;\n"
165 " gl_Position = a_position;\n"
167 static const char* defaultFragSrc =
168 "varying mediump vec4 v_color;\n\n"
171 " gl_FragColor = v_color;\n"
174 // Fill in specialization parameters.
175 std::map<std::string, std::string> spParams;
178 spParams["DECLARATIONS"] =
179 "attribute highp vec4 a_position;\n"
180 "attribute highp vec4 a_coords;\n"
181 "varying mediump vec4 v_color;";
182 spParams["COORDS"] = "a_coords";
183 spParams["DST"] = "v_color";
184 spParams["ASSIGN_POS"] = "gl_Position = a_position;";
188 spParams["DECLARATIONS"] = "varying mediump vec4 v_coords;";
189 spParams["COORDS"] = "v_coords";
190 spParams["DST"] = "gl_FragColor";
191 spParams["ASSIGN_POS"] = "";
193 if (additionalParams)
194 spParams.insert(additionalParams->begin(), additionalParams->end());
197 return new ShaderStructCase(context, name, description, isVertexCase, flags, evalFunc, setupUniforms, StringTemplate(shaderSrc.str()).specialize(spParams).c_str(), defaultFragSrc);
199 return new ShaderStructCase(context, name, description, isVertexCase, flags, evalFunc, setupUniforms, defaultVertSrc, StringTemplate(shaderSrc.str()).specialize(spParams).c_str());
202 class LocalStructTests : public TestCaseGroup
205 LocalStructTests (Context& context)
206 : TestCaseGroup(context, "local", "Local structs")
210 ~LocalStructTests (void)
214 virtual void init (void);
217 void LocalStructTests::init (void)
219 #define LOCAL_STRUCT_CASE_PARAMETERIZED(NAME, DESCRIPTION, FLAGS, SHADER_SRC, EVAL_FUNC_BODY, PARAMS) \
221 struct Eval_##NAME { static void eval (ShaderEvalContext& c) EVAL_FUNC_BODY }; /* NOLINT(EVAL_FUNC_BODY) */ \
222 addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, true, FLAGS, &Eval_##NAME::eval, DE_NULL, SHADER_SRC, PARAMS)); \
223 addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, false, FLAGS,&Eval_##NAME::eval, DE_NULL, SHADER_SRC, PARAMS));\
224 } while (deGetFalse())
226 #define LOCAL_STRUCT_CASE(NAME, DESCRIPTION, FLAGS, SHADER_SRC, EVAL_FUNC_BODY) \
227 LOCAL_STRUCT_CASE_PARAMETERIZED(NAME, DESCRIPTION, FLAGS, SHADER_SRC, EVAL_FUNC_BODY, DE_NULL)
229 LOCAL_STRUCT_CASE(basic, "Basic struct usage", 0,
232 << "uniform int ui_one;"
235 << " mediump float a;"
236 << " mediump vec3 b;"
240 << "void main (void)"
242 << " S s = S(${COORDS}.x, vec3(0.0), ui_one);"
243 << " s.b = ${COORDS}.yzw;"
244 << " ${DST} = vec4(s.a, s.b.x, s.b.y, s.c);"
248 c.color.xyz() = c.coords.swizzle(0,1,2);
251 LOCAL_STRUCT_CASE(nested, "Nested struct", 0,
254 << "uniform int ui_zero;"
255 << "uniform int ui_one;"
259 << " mediump vec2 b;"
262 << " mediump float a;"
267 << "void main (void)"
269 << " S s = S(${COORDS}.x, T(0, vec2(0.0)), ui_one);"
270 << " s.b = T(ui_zero, ${COORDS}.yz);"
271 << " ${DST} = vec4(s.a, s.b.b, s.b.a + s.c);"
275 c.color.xyz() = c.coords.swizzle(0,1,2);
278 LOCAL_STRUCT_CASE(array_member, "Struct with array member", 0,
281 << "uniform int ui_one;"
284 << " mediump float a;"
285 << " mediump float b[3];"
289 << "void main (void)"
292 << " s.a = ${COORDS}.w;"
294 << " s.b[0] = ${COORDS}.z;"
295 << " s.b[1] = ${COORDS}.y;"
296 << " s.b[2] = ${COORDS}.x;"
297 << " ${DST} = vec4(s.a, s.b[0], s.b[1], s.c);"
301 c.color.xyz() = c.coords.swizzle(3,2,1);
304 LOCAL_STRUCT_CASE(array_member_dynamic_index, "Struct with array member, dynamic indexing", FLAG_REQUIRES_DYNAMIC_INDEXING,
307 << "uniform int ui_zero;"
308 << "uniform int ui_one;"
309 << "uniform int ui_two;"
312 << " mediump float a;"
313 << " mediump float b[3];"
317 << "void main (void)"
320 << " s.a = ${COORDS}.w;"
322 << " s.b[0] = ${COORDS}.z;"
323 << " s.b[1] = ${COORDS}.y;"
324 << " s.b[2] = ${COORDS}.x;"
325 << " ${DST} = vec4(s.b[ui_one], s.b[ui_zero], s.b[ui_two], s.c);"
329 c.color.xyz() = c.coords.swizzle(1,2,0);
332 LOCAL_STRUCT_CASE(struct_array, "Struct array", 0,
335 << "uniform int ui_zero;"
336 << "uniform int ui_one;"
337 << "uniform int ui_two;"
340 << " mediump float a;"
344 << "void main (void)"
347 << " s[0] = S(${COORDS}.x, ui_zero);"
348 << " s[1].a = ${COORDS}.y;"
349 << " s[1].b = ui_one;"
350 << " s[2] = S(${COORDS}.z, ui_two);"
351 << " ${DST} = vec4(s[2].a, s[1].a, s[0].a, s[2].b - s[1].b + s[0].b);"
355 c.color.xyz() = c.coords.swizzle(2,1,0);
358 LOCAL_STRUCT_CASE(struct_array_dynamic_index, "Struct array with dynamic indexing", FLAG_REQUIRES_DYNAMIC_INDEXING,
361 << "uniform int ui_zero;"
362 << "uniform int ui_one;"
363 << "uniform int ui_two;"
366 << " mediump float a;"
370 << "void main (void)"
373 << " s[0] = S(${COORDS}.x, ui_zero);"
374 << " s[1].a = ${COORDS}.y;"
375 << " s[1].b = ui_one;"
376 << " s[2] = S(${COORDS}.z, ui_two);"
377 << " ${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);"
381 c.color.xyz() = c.coords.swizzle(2,1,0);
384 LOCAL_STRUCT_CASE(nested_struct_array, "Nested struct array", 0,
387 << "uniform int ui_zero;"
388 << "uniform int ui_one;"
389 << "uniform int ui_two;"
390 << "uniform mediump float uf_two;"
391 << "uniform mediump float uf_three;"
392 << "uniform mediump float uf_four;"
393 << "uniform mediump float uf_half;"
394 << "uniform mediump float uf_third;"
395 << "uniform mediump float uf_fourth;"
398 << " mediump float a;"
399 << " mediump vec2 b[2];"
402 << " mediump float a;"
407 << "void main (void)"
412 << " s[0].a = ${COORDS}.x;"
413 << " s[0].b[0].a = uf_half;"
414 << " s[0].b[0].b[0] = ${COORDS}.xy;"
415 << " s[0].b[0].b[1] = ${COORDS}.zw;"
416 << " s[0].b[1].a = uf_third;"
417 << " s[0].b[1].b[0] = ${COORDS}.zw;"
418 << " s[0].b[1].b[1] = ${COORDS}.xy;"
419 << " s[0].b[2].a = uf_fourth;"
420 << " s[0].b[2].b[0] = ${COORDS}.xz;"
421 << " s[0].b[2].b[1] = ${COORDS}.yw;"
422 << " s[0].c = ui_zero;"
425 << " s[1].a = ${COORDS}.w;"
426 << " s[1].b[0].a = uf_two;"
427 << " s[1].b[0].b[0] = ${COORDS}.xx;"
428 << " s[1].b[0].b[1] = ${COORDS}.yy;"
429 << " s[1].b[1].a = uf_three;"
430 << " s[1].b[1].b[0] = ${COORDS}.zz;"
431 << " s[1].b[1].b[1] = ${COORDS}.ww;"
432 << " s[1].b[2].a = uf_four;"
433 << " s[1].b[2].b[0] = ${COORDS}.yx;"
434 << " s[1].b[2].b[1] = ${COORDS}.wz;"
435 << " s[1].c = ui_one;"
437 << " 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"
438 << " mediump float g = s[1].b[0].b[0].y * s[0].b[2].a * s[1].b[2].a; // x * 0.25 * 4"
439 << " 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"
440 << " mediump float a = float(s[0].c) + s[1].b[2].a - s[1].b[1].a; // 0 + 4.0 - 3.0"
441 << " ${DST} = vec4(r, g, b, a);"
445 c.color.xyz() = c.coords.swizzle(2,0,3);
448 LOCAL_STRUCT_CASE(nested_struct_array_dynamic_index, "Nested struct array with dynamic indexing", FLAG_REQUIRES_DYNAMIC_INDEXING,
451 << "uniform int ui_zero;"
452 << "uniform int ui_one;"
453 << "uniform int ui_two;"
454 << "uniform mediump float uf_two;"
455 << "uniform mediump float uf_three;"
456 << "uniform mediump float uf_four;"
457 << "uniform mediump float uf_half;"
458 << "uniform mediump float uf_third;"
459 << "uniform mediump float uf_fourth;"
462 << " mediump float a;"
463 << " mediump vec2 b[2];"
466 << " mediump float a;"
471 << "void main (void)"
476 << " s[0].a = ${COORDS}.x;"
477 << " s[0].b[0].a = uf_half;"
478 << " s[0].b[0].b[0] = ${COORDS}.xy;"
479 << " s[0].b[0].b[1] = ${COORDS}.zw;"
480 << " s[0].b[1].a = uf_third;"
481 << " s[0].b[1].b[0] = ${COORDS}.zw;"
482 << " s[0].b[1].b[1] = ${COORDS}.xy;"
483 << " s[0].b[2].a = uf_fourth;"
484 << " s[0].b[2].b[0] = ${COORDS}.xz;"
485 << " s[0].b[2].b[1] = ${COORDS}.yw;"
486 << " s[0].c = ui_zero;"
489 << " s[1].a = ${COORDS}.w;"
490 << " s[1].b[0].a = uf_two;"
491 << " s[1].b[0].b[0] = ${COORDS}.xx;"
492 << " s[1].b[0].b[1] = ${COORDS}.yy;"
493 << " s[1].b[1].a = uf_three;"
494 << " s[1].b[1].b[0] = ${COORDS}.zz;"
495 << " s[1].b[1].b[1] = ${COORDS}.ww;"
496 << " s[1].b[2].a = uf_four;"
497 << " s[1].b[2].b[0] = ${COORDS}.yx;"
498 << " s[1].b[2].b[1] = ${COORDS}.wz;"
499 << " s[1].c = ui_one;"
501 << " 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"
502 << " 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"
503 << " 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"
504 << " 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"
505 << " ${DST} = vec4(r, g, b, a);"
509 c.color.xyz() = c.coords.swizzle(2,0,3);
512 LOCAL_STRUCT_CASE(parameter, "Struct as a function parameter", 0,
515 << "uniform int ui_one;"
518 << " mediump float a;"
519 << " mediump vec3 b;"
523 << "mediump vec4 myFunc (S s)"
525 << " return vec4(s.a, s.b.x, s.b.y, s.c);"
528 << "void main (void)"
530 << " S s = S(${COORDS}.x, vec3(0.0), ui_one);"
531 << " s.b = ${COORDS}.yzw;"
532 << " ${DST} = myFunc(s);"
536 c.color.xyz() = c.coords.swizzle(0,1,2);
544 << " ${PRECISION} vec3 red;"
545 << " ${PRECISION} vec3 blue;"
548 << "void modify (inout S s)"
550 << " s.red += vec3(0.5, 0.0, 0.0);"
551 << " s.blue += vec3(0.0, 0.0, 0.5);"
554 << "void main (void)"
557 << " s.red = vec3(0.5, 0.0, 0.0);"
558 << " s.blue = vec3(0.0, 0.0, 0.5);"
560 << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);"
561 << " if (s.red == vec3(1.0, 0.0, 0.0) && s.blue == vec3(0.0, 0.0, 1.0))"
562 << " ${DST} = vec4(1.0, 1.0, 1.0, 1.0);"
566 std::map<std::string, std::string> precisionParams;
567 precisionParams["PRECISION"] = "lowp";
568 LOCAL_STRUCT_CASE_PARAMETERIZED(
569 parameter_inout_lowp, "Struct with lowp members as an inout function parameter", 0,
572 c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0);
576 precisionParams["PRECISION"] = "mediump";
577 LOCAL_STRUCT_CASE_PARAMETERIZED(
578 parameter_inout_mediump, "Struct with mediump members as an inout function parameter", 0,
581 c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0);
585 precisionParams["PRECISION"] = "highp";
586 LOCAL_STRUCT_CASE_PARAMETERIZED(
587 parameter_inout_highp, "Struct with highp members as an inout function parameter", FLAG_REQUIRES_HIGHP_FRAGMENT,
590 c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0);
594 LOCAL_STRUCT_CASE(parameter_nested, "Nested struct as a function parameter", 0,
597 << "uniform int ui_zero;"
598 << "uniform int ui_one;"
602 << " mediump vec2 b;"
605 << " mediump float a;"
610 << "mediump vec4 myFunc (S s)"
612 << " return vec4(s.a, s.b.b, s.b.a + s.c);"
615 << "void main (void)"
617 << " S s = S(${COORDS}.x, T(0, vec2(0.0)), ui_one);"
618 << " s.b = T(ui_zero, ${COORDS}.yz);"
619 << " ${DST} = myFunc(s);"
623 c.color.xyz() = c.coords.swizzle(0,1,2);
631 << " ${PRECISION} vec3 red;"
632 << " ${PRECISION} vec3 blue;"
635 << "void modify (out S s)"
637 << " s.red = vec3(1.0, 0.0, 0.0);"
638 << " s.blue = vec3(0.0, 0.0, 1.0);"
641 << "void main (void)"
645 << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);"
646 << " if (s.red == vec3(1.0, 0.0, 0.0) && s.blue == vec3(0.0, 0.0, 1.0))"
647 << " ${DST} = vec4(1.0, 1.0, 1.0, 1.0);"
652 precisionParams["PRECISION"] = "lowp";
653 LOCAL_STRUCT_CASE_PARAMETERIZED(
654 parameter_out_lowp, "Struct with lowp members as an out function parameter", 0,
657 c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0);
661 precisionParams["PRECISION"] = "mediump";
662 LOCAL_STRUCT_CASE_PARAMETERIZED(parameter_out_mediump, "Struct with mediump members as an out function parameter", 0,
665 c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0);
669 precisionParams["PRECISION"] = "highp";
670 LOCAL_STRUCT_CASE_PARAMETERIZED(
671 parameter_out_highp, "Struct with highp members as an out function parameter", FLAG_REQUIRES_HIGHP_FRAGMENT,
674 c.color.xyz() = tcu::Vec3(1.0, 1.0, 1.0);
678 LOCAL_STRUCT_CASE(return, "Struct as a return value", 0,
681 << "uniform int ui_one;"
684 << " mediump float a;"
685 << " mediump vec3 b;"
691 << " S s = S(${COORDS}.x, vec3(0.0), ui_one);"
692 << " s.b = ${COORDS}.yzw;"
696 << "void main (void)"
698 << " S s = myFunc();"
699 << " ${DST} = vec4(s.a, s.b.x, s.b.y, s.c);"
703 c.color.xyz() = c.coords.swizzle(0,1,2);
706 LOCAL_STRUCT_CASE(return_nested, "Nested struct", 0,
709 << "uniform int ui_zero;"
710 << "uniform int ui_one;"
714 << " mediump vec2 b;"
717 << " mediump float a;"
724 << " S s = S(${COORDS}.x, T(0, vec2(0.0)), ui_one);"
725 << " s.b = T(ui_zero, ${COORDS}.yz);"
729 << "void main (void)"
731 << " S s = myFunc();"
732 << " ${DST} = vec4(s.a, s.b.b, s.b.a + s.c);"
736 c.color.xyz() = c.coords.swizzle(0,1,2);
739 LOCAL_STRUCT_CASE(conditional_assignment, "Conditional struct assignment", 0,
742 << "uniform int ui_zero;"
743 << "uniform int ui_one;"
744 << "uniform mediump float uf_one;"
747 << " mediump float a;"
748 << " mediump vec3 b;"
752 << "void main (void)"
754 << " S s = S(${COORDS}.x, ${COORDS}.yzw, ui_zero);"
755 << " if (uf_one > 0.0)"
756 << " s = S(${COORDS}.w, ${COORDS}.zyx, ui_one);"
757 << " ${DST} = vec4(s.a, s.b.xy, s.c);"
761 c.color.xyz() = c.coords.swizzle(3,2,1);
764 LOCAL_STRUCT_CASE(loop_assignment, "Struct assignment in loop", 0,
767 << "uniform int ui_zero;"
768 << "uniform int ui_one;"
771 << " mediump float a;"
772 << " mediump vec3 b;"
776 << "void main (void)"
778 << " S s = S(${COORDS}.x, ${COORDS}.yzw, ui_zero);"
779 << " for (int i = 0; i < 3; i++)"
782 << " s = S(${COORDS}.w, ${COORDS}.zyx, ui_one);"
784 << " ${DST} = vec4(s.a, s.b.xy, s.c);"
788 c.color.xyz() = c.coords.swizzle(3,2,1);
791 LOCAL_STRUCT_CASE(dynamic_loop_assignment, "Struct assignment in loop", FLAG_REQUIRES_DYNAMIC_INDEXING,
794 << "uniform int ui_zero;"
795 << "uniform int ui_one;"
796 << "uniform int ui_three;"
799 << " mediump float a;"
800 << " mediump vec3 b;"
804 << "void main (void)"
806 << " S s = S(${COORDS}.x, ${COORDS}.yzw, ui_zero);"
807 << " for (int i = 0; i < ui_three; i++)"
809 << " if (i == ui_one)"
810 << " s = S(${COORDS}.w, ${COORDS}.zyx, ui_one);"
812 << " ${DST} = vec4(s.a, s.b.xy, s.c);"
816 c.color.xyz() = c.coords.swizzle(3,2,1);
819 LOCAL_STRUCT_CASE(nested_conditional_assignment, "Conditional assignment of nested struct", 0,
822 << "uniform int ui_zero;"
823 << "uniform int ui_one;"
824 << "uniform mediump float uf_one;"
828 << " mediump vec2 b;"
831 << " mediump float a;"
836 << "void main (void)"
838 << " S s = S(${COORDS}.x, T(ui_one, ${COORDS}.yz), ui_one);"
839 << " if (uf_one > 0.0)"
840 << " s.b = T(ui_zero, ${COORDS}.zw);"
841 << " ${DST} = vec4(s.a, s.b.b, s.c - s.b.a);"
845 c.color.xyz() = c.coords.swizzle(0,2,3);
848 LOCAL_STRUCT_CASE(nested_loop_assignment, "Nested struct assignment in loop", 0,
851 << "uniform int ui_zero;"
852 << "uniform int ui_one;"
853 << "uniform mediump float uf_one;"
857 << " mediump vec2 b;"
860 << " mediump float a;"
865 << "void main (void)"
867 << " S s = S(${COORDS}.x, T(ui_one, ${COORDS}.yz), ui_one);"
868 << " for (int i = 0; i < 3; i++)"
871 << " s.b = T(ui_zero, ${COORDS}.zw);"
873 << " ${DST} = vec4(s.a, s.b.b, s.c - s.b.a);"
877 c.color.xyz() = c.coords.swizzle(0,2,3);
880 LOCAL_STRUCT_CASE(nested_dynamic_loop_assignment, "Nested struct assignment in dynamic loop", FLAG_REQUIRES_DYNAMIC_INDEXING,
883 << "uniform int ui_zero;"
884 << "uniform int ui_one;"
885 << "uniform int ui_three;"
886 << "uniform mediump float uf_one;"
890 << " mediump vec2 b;"
893 << " mediump float a;"
898 << "void main (void)"
900 << " S s = S(${COORDS}.x, T(ui_one, ${COORDS}.yz), ui_one);"
901 << " for (int i = 0; i < ui_three; i++)"
903 << " if (i == ui_one)"
904 << " s.b = T(ui_zero, ${COORDS}.zw);"
906 << " ${DST} = vec4(s.a, s.b.b, s.c - s.b.a);"
910 c.color.xyz() = c.coords.swizzle(0,2,3);
913 LOCAL_STRUCT_CASE(loop_struct_array, "Struct array usage in loop", 0,
916 << "uniform int ui_zero;"
917 << "uniform int ui_one;"
918 << "uniform int ui_two;"
921 << " mediump float a;"
925 << "void main (void)"
928 << " s[0] = S(${COORDS}.x, ui_zero);"
929 << " s[1].a = ${COORDS}.y;"
930 << " s[1].b = -ui_one;"
931 << " s[2] = S(${COORDS}.z, ui_two);"
933 << " mediump float rgb[3];"
935 << " for (int i = 0; i < 3; i++)"
937 << " rgb[i] = s[2-i].a;"
938 << " alpha += s[i].b;"
940 << " ${DST} = vec4(rgb[0], rgb[1], rgb[2], alpha);"
944 c.color.xyz() = c.coords.swizzle(2,1,0);
947 LOCAL_STRUCT_CASE(loop_nested_struct_array, "Nested struct array usage in loop", 0,
950 << "uniform int ui_zero;"
951 << "uniform int ui_one;"
952 << "uniform int ui_two;"
953 << "uniform mediump float uf_two;"
954 << "uniform mediump float uf_three;"
955 << "uniform mediump float uf_four;"
956 << "uniform mediump float uf_half;"
957 << "uniform mediump float uf_third;"
958 << "uniform mediump float uf_fourth;"
959 << "uniform mediump float uf_sixth;"
962 << " mediump float a;"
963 << " mediump vec2 b[2];"
966 << " mediump float a;"
971 << "void main (void)"
976 << " s[0].a = ${COORDS}.x;"
977 << " s[0].b[0].a = uf_half;"
978 << " s[0].b[0].b[0] = ${COORDS}.yx;"
979 << " s[0].b[0].b[1] = ${COORDS}.zx;"
980 << " s[0].b[1].a = uf_third;"
981 << " s[0].b[1].b[0] = ${COORDS}.yy;"
982 << " s[0].b[1].b[1] = ${COORDS}.wy;"
983 << " s[0].b[2].a = uf_fourth;"
984 << " s[0].b[2].b[0] = ${COORDS}.zx;"
985 << " s[0].b[2].b[1] = ${COORDS}.zy;"
986 << " s[0].c = ui_zero;"
989 << " s[1].a = ${COORDS}.w;"
990 << " s[1].b[0].a = uf_two;"
991 << " s[1].b[0].b[0] = ${COORDS}.zx;"
992 << " s[1].b[0].b[1] = ${COORDS}.zy;"
993 << " s[1].b[1].a = uf_three;"
994 << " s[1].b[1].b[0] = ${COORDS}.zz;"
995 << " s[1].b[1].b[1] = ${COORDS}.ww;"
996 << " s[1].b[2].a = uf_four;"
997 << " s[1].b[2].b[0] = ${COORDS}.yx;"
998 << " s[1].b[2].b[1] = ${COORDS}.wz;"
999 << " s[1].c = ui_one;"
1001 << " mediump float r = 0.0; // (x*3 + y*3) / 6.0"
1002 << " mediump float g = 0.0; // (y*3 + z*3) / 6.0"
1003 << " mediump float b = 0.0; // (z*3 + w*3) / 6.0"
1004 << " mediump float a = 1.0;"
1005 << " for (int i = 0; i < 2; i++)"
1007 << " for (int j = 0; j < 3; j++)"
1009 << " r += s[0].b[j].b[i].y;"
1010 << " g += s[i].b[j].b[0].x;"
1011 << " b += s[i].b[j].b[1].x;"
1012 << " a *= s[i].b[j].a;"
1015 << " ${DST} = vec4(r*uf_sixth, g*uf_sixth, b*uf_sixth, a);"
1019 c.color.xyz() = (c.coords.swizzle(0,1,2) + c.coords.swizzle(1,2,3)) * 0.5f;
1022 LOCAL_STRUCT_CASE(dynamic_loop_struct_array, "Struct array usage in dynamic loop", FLAG_REQUIRES_DYNAMIC_INDEXING|FLAG_REQUIRES_DYNAMIC_LOOPS,
1024 << "${DECLARATIONS}"
1025 << "uniform int ui_zero;"
1026 << "uniform int ui_one;"
1027 << "uniform int ui_two;"
1028 << "uniform int ui_three;"
1031 << " mediump float a;"
1032 << " mediump int b;"
1035 << "void main (void)"
1038 << " s[0] = S(${COORDS}.x, ui_zero);"
1039 << " s[1].a = ${COORDS}.y;"
1040 << " s[1].b = -ui_one;"
1041 << " s[2] = S(${COORDS}.z, ui_two);"
1043 << " mediump float rgb[3];"
1044 << " int alpha = 0;"
1045 << " for (int i = 0; i < ui_three; i++)"
1047 << " rgb[i] = s[2-i].a;"
1048 << " alpha += s[i].b;"
1050 << " ${DST} = vec4(rgb[0], rgb[1], rgb[2], alpha);"
1054 c.color.xyz() = c.coords.swizzle(2,1,0);
1057 LOCAL_STRUCT_CASE(dynamic_loop_nested_struct_array, "Nested struct array usage in dynamic loop", FLAG_REQUIRES_DYNAMIC_INDEXING|FLAG_REQUIRES_DYNAMIC_LOOPS,
1059 << "${DECLARATIONS}"
1060 << "uniform int ui_zero;"
1061 << "uniform int ui_one;"
1062 << "uniform int ui_two;"
1063 << "uniform int ui_three;"
1064 << "uniform mediump float uf_two;"
1065 << "uniform mediump float uf_three;"
1066 << "uniform mediump float uf_four;"
1067 << "uniform mediump float uf_half;"
1068 << "uniform mediump float uf_third;"
1069 << "uniform mediump float uf_fourth;"
1070 << "uniform mediump float uf_sixth;"
1073 << " mediump float a;"
1074 << " mediump vec2 b[2];"
1077 << " mediump float a;"
1082 << "void main (void)"
1087 << " s[0].a = ${COORDS}.x;"
1088 << " s[0].b[0].a = uf_half;"
1089 << " s[0].b[0].b[0] = ${COORDS}.yx;"
1090 << " s[0].b[0].b[1] = ${COORDS}.zx;"
1091 << " s[0].b[1].a = uf_third;"
1092 << " s[0].b[1].b[0] = ${COORDS}.yy;"
1093 << " s[0].b[1].b[1] = ${COORDS}.wy;"
1094 << " s[0].b[2].a = uf_fourth;"
1095 << " s[0].b[2].b[0] = ${COORDS}.zx;"
1096 << " s[0].b[2].b[1] = ${COORDS}.zy;"
1097 << " s[0].c = ui_zero;"
1100 << " s[1].a = ${COORDS}.w;"
1101 << " s[1].b[0].a = uf_two;"
1102 << " s[1].b[0].b[0] = ${COORDS}.zx;"
1103 << " s[1].b[0].b[1] = ${COORDS}.zy;"
1104 << " s[1].b[1].a = uf_three;"
1105 << " s[1].b[1].b[0] = ${COORDS}.zz;"
1106 << " s[1].b[1].b[1] = ${COORDS}.ww;"
1107 << " s[1].b[2].a = uf_four;"
1108 << " s[1].b[2].b[0] = ${COORDS}.yx;"
1109 << " s[1].b[2].b[1] = ${COORDS}.wz;"
1110 << " s[1].c = ui_one;"
1112 << " mediump float r = 0.0; // (x*3 + y*3) / 6.0"
1113 << " mediump float g = 0.0; // (y*3 + z*3) / 6.0"
1114 << " mediump float b = 0.0; // (z*3 + w*3) / 6.0"
1115 << " mediump float a = 1.0;"
1116 << " for (int i = 0; i < ui_two; i++)"
1118 << " for (int j = 0; j < ui_three; j++)"
1120 << " r += s[0].b[j].b[i].y;"
1121 << " g += s[i].b[j].b[0].x;"
1122 << " b += s[i].b[j].b[1].x;"
1123 << " a *= s[i].b[j].a;"
1126 << " ${DST} = vec4(r*uf_sixth, g*uf_sixth, b*uf_sixth, a);"
1130 c.color.xyz() = (c.coords.swizzle(0,1,2) + c.coords.swizzle(1,2,3)) * 0.5f;
1133 LOCAL_STRUCT_CASE(basic_equal, "Basic struct equality", 0,
1135 << "${DECLARATIONS}"
1136 << "uniform int ui_one;"
1137 << "uniform int ui_two;"
1140 << " mediump float a;"
1141 << " mediump vec3 b;"
1145 << "void main (void)"
1147 << " S a = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y), 2.3), ui_one);"
1148 << " S b = S(floor(${COORDS}.x+0.5), vec3(0.0, floor(${COORDS}.y), 2.3), ui_one);"
1149 << " S c = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y+0.5), 2.3), ui_one);"
1150 << " S d = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y), 2.3), ui_two);"
1151 << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);"
1152 << " if (a == b) ${DST}.x = 1.0;"
1153 << " if (a == c) ${DST}.y = 1.0;"
1154 << " if (a == d) ${DST}.z = 1.0;"
1158 if (deFloatFloor(c.coords[0]) == deFloatFloor(c.coords[0]+0.5f))
1160 if (deFloatFloor(c.coords[1]) == deFloatFloor(c.coords[1]+0.5f))
1164 LOCAL_STRUCT_CASE(basic_not_equal, "Basic struct equality", 0,
1166 << "${DECLARATIONS}"
1167 << "uniform int ui_one;"
1168 << "uniform int ui_two;"
1171 << " mediump float a;"
1172 << " mediump vec3 b;"
1176 << "void main (void)"
1178 << " S a = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y), 2.3), ui_one);"
1179 << " S b = S(floor(${COORDS}.x+0.5), vec3(0.0, floor(${COORDS}.y), 2.3), ui_one);"
1180 << " S c = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y+0.5), 2.3), ui_one);"
1181 << " S d = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y), 2.3), ui_two);"
1182 << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);"
1183 << " if (a != b) ${DST}.x = 1.0;"
1184 << " if (a != c) ${DST}.y = 1.0;"
1185 << " if (a != d) ${DST}.z = 1.0;"
1189 if (deFloatFloor(c.coords[0]) != deFloatFloor(c.coords[0]+0.5f))
1191 if (deFloatFloor(c.coords[1]) != deFloatFloor(c.coords[1]+0.5f))
1196 LOCAL_STRUCT_CASE(nested_equal, "Nested struct struct equality", 0,
1198 << "${DECLARATIONS}"
1199 << "uniform int ui_one;"
1200 << "uniform int ui_two;"
1203 << " mediump vec3 a;"
1207 << " mediump float a;"
1212 << "void main (void)"
1214 << " S a = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_one), 1);"
1215 << " S b = S(floor(${COORDS}.x+0.5), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_one), 1);"
1216 << " S c = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y+0.5), 2.3), ui_one), 1);"
1217 << " S d = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_two), 1);"
1218 << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);"
1219 << " if (a == b) ${DST}.x = 1.0;"
1220 << " if (a == c) ${DST}.y = 1.0;"
1221 << " if (a == d) ${DST}.z = 1.0;"
1225 if (deFloatFloor(c.coords[0]) == deFloatFloor(c.coords[0]+0.5f))
1227 if (deFloatFloor(c.coords[1]) == deFloatFloor(c.coords[1]+0.5f))
1231 LOCAL_STRUCT_CASE(nested_not_equal, "Nested struct struct equality", 0,
1233 << "${DECLARATIONS}"
1234 << "uniform int ui_one;"
1235 << "uniform int ui_two;"
1238 << " mediump vec3 a;"
1242 << " mediump float a;"
1247 << "void main (void)"
1249 << " S a = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_one), 1);"
1250 << " S b = S(floor(${COORDS}.x+0.5), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_one), 1);"
1251 << " S c = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y+0.5), 2.3), ui_one), 1);"
1252 << " S d = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_two), 1);"
1253 << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);"
1254 << " if (a != b) ${DST}.x = 1.0;"
1255 << " if (a != c) ${DST}.y = 1.0;"
1256 << " if (a != d) ${DST}.z = 1.0;"
1260 if (deFloatFloor(c.coords[0]) != deFloatFloor(c.coords[0]+0.5f))
1262 if (deFloatFloor(c.coords[1]) != deFloatFloor(c.coords[1]+0.5f))
1268 class UniformStructTests : public TestCaseGroup
1271 UniformStructTests (Context& context)
1272 : TestCaseGroup(context, "uniform", "Uniform structs")
1276 ~UniformStructTests (void)
1280 virtual void init (void);
1286 #define CHECK_SET_UNIFORM(NAME) GLU_EXPECT_NO_ERROR(gl.getError(), (string("Failed to set ") + (NAME)).c_str())
1288 #define MAKE_SET_VEC_UNIFORM(VECTYPE, SETUNIFORM) \
1289 void setUniform (const glw::Functions& gl, deUint32 programID, const char* name, const tcu::VECTYPE& vec) \
1291 int loc = gl.getUniformLocation(programID, name); \
1292 SETUNIFORM(loc, 1, vec.getPtr()); \
1293 CHECK_SET_UNIFORM(name); \
1295 struct SetUniform##VECTYPE##Dummy_s { int unused; }
1297 #define MAKE_SET_VEC_UNIFORM_PTR(VECTYPE, SETUNIFORM) \
1298 void setUniform (const glw::Functions& gl, deUint32 programID, const char* name, const tcu::VECTYPE* vec, int arraySize) \
1300 int loc = gl.getUniformLocation(programID, name); \
1301 SETUNIFORM(loc, arraySize, vec->getPtr()); \
1302 CHECK_SET_UNIFORM(name); \
1304 struct SetUniformPtr##VECTYPE##Dummy_s { int unused; }
1306 MAKE_SET_VEC_UNIFORM (Vec2, gl.uniform2fv);
1307 MAKE_SET_VEC_UNIFORM (Vec3, gl.uniform3fv);
1308 MAKE_SET_VEC_UNIFORM_PTR(Vec2, gl.uniform2fv);
1310 void setUniform (const glw::Functions& gl, deUint32 programID, const char* name, float value)
1312 int loc = gl.getUniformLocation(programID, name);
1313 gl.uniform1f(loc, value);
1314 CHECK_SET_UNIFORM(name);
1317 void setUniform (const glw::Functions& gl, deUint32 programID, const char* name, int value)
1319 int loc = gl.getUniformLocation(programID, name);
1320 gl.uniform1i(loc, value);
1321 CHECK_SET_UNIFORM(name);
1324 void setUniform (const glw::Functions& gl, deUint32 programID, const char* name, const float* value, int arraySize)
1326 int loc = gl.getUniformLocation(programID, name);
1327 gl.uniform1fv(loc, arraySize, value);
1328 CHECK_SET_UNIFORM(name);
1333 void UniformStructTests::init (void)
1335 #define UNIFORM_STRUCT_CASE(NAME, DESCRIPTION, FLAGS, SHADER_SRC, SET_UNIFORMS_BODY, EVAL_FUNC_BODY) \
1337 struct SetUniforms_##NAME { \
1338 static void setUniforms (const glw::Functions& gl, deUint32 programID, const tcu::Vec4& constCoords) SET_UNIFORMS_BODY /* NOLINT(SET_UNIFORMS_BODY) */ \
1340 struct Eval_##NAME { static void eval (ShaderEvalContext& c) EVAL_FUNC_BODY }; /* NOLINT(EVAL_FUNC_BODY) */ \
1341 addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, true, FLAGS, Eval_##NAME::eval, SetUniforms_##NAME::setUniforms, SHADER_SRC, DE_NULL)); \
1342 addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, false, FLAGS, Eval_##NAME::eval, SetUniforms_##NAME::setUniforms, SHADER_SRC, DE_NULL));\
1343 } while (deGetFalse())
1345 UNIFORM_STRUCT_CASE(basic, "Basic struct usage", 0,
1347 << "${DECLARATIONS}"
1348 << "uniform int ui_one;"
1351 << " mediump float a;"
1352 << " mediump vec3 b;"
1357 << "void main (void)"
1359 << " ${DST} = vec4(s.a, s.b.x, s.b.y, s.c);"
1363 setUniform(gl, programID, "s.a", constCoords.x());
1364 setUniform(gl, programID, "s.b", constCoords.swizzle(1, 2, 3));
1365 setUniform(gl, programID, "s.c", 1);
1368 c.color.xyz() = c.constCoords.swizzle(0,1,2);
1371 UNIFORM_STRUCT_CASE(nested, "Nested struct", 0,
1373 << "${DECLARATIONS}"
1374 << "uniform int ui_zero;"
1375 << "uniform int ui_one;"
1379 << " mediump vec2 b;"
1382 << " mediump float a;"
1388 << "void main (void)"
1390 << " ${DST} = vec4(s.a, s.b.b, s.b.a + s.c);"
1394 setUniform(gl, programID, "s.a", constCoords.x());
1395 setUniform(gl, programID, "s.b.a", 0);
1396 setUniform(gl, programID, "s.b.b", constCoords.swizzle(1,2));
1397 setUniform(gl, programID, "s.c", 1);
1400 c.color.xyz() = c.constCoords.swizzle(0,1,2);
1403 UNIFORM_STRUCT_CASE(array_member, "Struct with array member", 0,
1405 << "${DECLARATIONS}"
1406 << "uniform int ui_one;"
1409 << " mediump float a;"
1410 << " mediump float b[3];"
1415 << "void main (void)"
1417 << " ${DST} = vec4(s.a, s.b[0], s.b[1], s.c);"
1421 setUniform(gl, programID, "s.a", constCoords.w());
1422 setUniform(gl, programID, "s.c", 1);
1425 b[0] = constCoords.z();
1426 b[1] = constCoords.y();
1427 b[2] = constCoords.x();
1428 setUniform(gl, programID, "s.b", b, DE_LENGTH_OF_ARRAY(b));
1431 c.color.xyz() = c.constCoords.swizzle(3,2,1);
1434 UNIFORM_STRUCT_CASE(array_member_dynamic_index, "Struct with array member, dynamic indexing", FLAG_REQUIRES_DYNAMIC_INDEXING,
1436 << "${DECLARATIONS}"
1437 << "uniform int ui_zero;"
1438 << "uniform int ui_one;"
1439 << "uniform int ui_two;"
1442 << " mediump float a;"
1443 << " mediump float b[3];"
1448 << "void main (void)"
1450 << " ${DST} = vec4(s.b[ui_one], s.b[ui_zero], s.b[ui_two], s.c);"
1454 setUniform(gl, programID, "s.a", constCoords.w());
1455 setUniform(gl, programID, "s.c", 1);
1458 b[0] = constCoords.z();
1459 b[1] = constCoords.y();
1460 b[2] = constCoords.x();
1461 setUniform(gl, programID, "s.b", b, DE_LENGTH_OF_ARRAY(b));
1464 c.color.xyz() = c.constCoords.swizzle(1,2,0);
1467 UNIFORM_STRUCT_CASE(struct_array, "Struct array", 0,
1469 << "${DECLARATIONS}"
1470 << "uniform int ui_zero;"
1471 << "uniform int ui_one;"
1472 << "uniform int ui_two;"
1475 << " mediump float a;"
1476 << " mediump int b;"
1478 << "uniform S s[3];"
1480 << "void main (void)"
1482 << " ${DST} = vec4(s[2].a, s[1].a, s[0].a, s[2].b - s[1].b + s[0].b);"
1486 setUniform(gl, programID, "s[0].a", constCoords.x());
1487 setUniform(gl, programID, "s[0].b", 0);
1488 setUniform(gl, programID, "s[1].a", constCoords.y());
1489 setUniform(gl, programID, "s[1].b", 1);
1490 setUniform(gl, programID, "s[2].a", constCoords.z());
1491 setUniform(gl, programID, "s[2].b", 2);
1494 c.color.xyz() = c.constCoords.swizzle(2,1,0);
1497 UNIFORM_STRUCT_CASE(struct_array_dynamic_index, "Struct array with dynamic indexing", FLAG_REQUIRES_DYNAMIC_INDEXING,
1499 << "${DECLARATIONS}"
1500 << "uniform int ui_zero;"
1501 << "uniform int ui_one;"
1502 << "uniform int ui_two;"
1505 << " mediump float a;"
1506 << " mediump int b;"
1508 << "uniform S s[3];"
1510 << "void main (void)"
1512 << " ${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);"
1516 setUniform(gl, programID, "s[0].a", constCoords.x());
1517 setUniform(gl, programID, "s[0].b", 0);
1518 setUniform(gl, programID, "s[1].a", constCoords.y());
1519 setUniform(gl, programID, "s[1].b", 1);
1520 setUniform(gl, programID, "s[2].a", constCoords.z());
1521 setUniform(gl, programID, "s[2].b", 2);
1524 c.color.xyz() = c.constCoords.swizzle(2,1,0);
1527 UNIFORM_STRUCT_CASE(nested_struct_array, "Nested struct array", 0,
1529 << "${DECLARATIONS}"
1531 << " mediump float a;"
1532 << " mediump vec2 b[2];"
1535 << " mediump float a;"
1539 << "uniform S s[2];"
1541 << "void main (void)"
1543 << " 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"
1544 << " mediump float g = s[1].b[0].b[0].y * s[0].b[2].a * s[1].b[2].a; // x * 0.25 * 4"
1545 << " 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"
1546 << " mediump float a = float(s[0].c) + s[1].b[2].a - s[1].b[1].a; // 0 + 4.0 - 3.0"
1547 << " ${DST} = vec4(r, g, b, a);"
1553 setUniform(gl, programID, "s[0].a", constCoords.x());
1554 arr[0] = constCoords.swizzle(0,1);
1555 arr[1] = constCoords.swizzle(2,3);
1556 setUniform(gl, programID, "s[0].b[0].a", 0.5f);
1557 setUniform(gl, programID, "s[0].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1558 arr[0] = constCoords.swizzle(2,3);
1559 arr[1] = constCoords.swizzle(0,1);
1560 setUniform(gl, programID, "s[0].b[1].a", 1.0f/3.0f);
1561 setUniform(gl, programID, "s[0].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1562 arr[0] = constCoords.swizzle(0,2);
1563 arr[1] = constCoords.swizzle(1,3);
1564 setUniform(gl, programID, "s[0].b[2].a", 1.0f/4.0f);
1565 setUniform(gl, programID, "s[0].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1566 setUniform(gl, programID, "s[0].c", 0);
1568 setUniform(gl, programID, "s[1].a", constCoords.w());
1569 arr[0] = constCoords.swizzle(0,0);
1570 arr[1] = constCoords.swizzle(1,1);
1571 setUniform(gl, programID, "s[1].b[0].a", 2.0f);
1572 setUniform(gl, programID, "s[1].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1573 arr[0] = constCoords.swizzle(2,2);
1574 arr[1] = constCoords.swizzle(3,3);
1575 setUniform(gl, programID, "s[1].b[1].a", 3.0f);
1576 setUniform(gl, programID, "s[1].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1577 arr[0] = constCoords.swizzle(1,0);
1578 arr[1] = constCoords.swizzle(3,2);
1579 setUniform(gl, programID, "s[1].b[2].a", 4.0f);
1580 setUniform(gl, programID, "s[1].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1581 setUniform(gl, programID, "s[1].c", 1);
1584 c.color.xyz() = c.constCoords.swizzle(2,0,3);
1587 UNIFORM_STRUCT_CASE(nested_struct_array_dynamic_index, "Nested struct array with dynamic indexing", FLAG_REQUIRES_DYNAMIC_INDEXING,
1589 << "${DECLARATIONS}"
1590 << "uniform int ui_zero;"
1591 << "uniform int ui_one;"
1592 << "uniform int ui_two;"
1595 << " mediump float a;"
1596 << " mediump vec2 b[2];"
1599 << " mediump float a;"
1603 << "uniform S s[2];"
1605 << "void main (void)"
1607 << " 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"
1608 << " 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"
1609 << " 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"
1610 << " 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"
1611 << " ${DST} = vec4(r, g, b, a);"
1617 setUniform(gl, programID, "s[0].a", constCoords.x());
1618 arr[0] = constCoords.swizzle(0,1);
1619 arr[1] = constCoords.swizzle(2,3);
1620 setUniform(gl, programID, "s[0].b[0].a", 0.5f);
1621 setUniform(gl, programID, "s[0].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1622 arr[0] = constCoords.swizzle(2,3);
1623 arr[1] = constCoords.swizzle(0,1);
1624 setUniform(gl, programID, "s[0].b[1].a", 1.0f/3.0f);
1625 setUniform(gl, programID, "s[0].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1626 arr[0] = constCoords.swizzle(0,2);
1627 arr[1] = constCoords.swizzle(1,3);
1628 setUniform(gl, programID, "s[0].b[2].a", 1.0f/4.0f);
1629 setUniform(gl, programID, "s[0].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1630 setUniform(gl, programID, "s[0].c", 0);
1632 setUniform(gl, programID, "s[1].a", constCoords.w());
1633 arr[0] = constCoords.swizzle(0,0);
1634 arr[1] = constCoords.swizzle(1,1);
1635 setUniform(gl, programID, "s[1].b[0].a", 2.0f);
1636 setUniform(gl, programID, "s[1].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1637 arr[0] = constCoords.swizzle(2,2);
1638 arr[1] = constCoords.swizzle(3,3);
1639 setUniform(gl, programID, "s[1].b[1].a", 3.0f);
1640 setUniform(gl, programID, "s[1].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1641 arr[0] = constCoords.swizzle(1,0);
1642 arr[1] = constCoords.swizzle(3,2);
1643 setUniform(gl, programID, "s[1].b[2].a", 4.0f);
1644 setUniform(gl, programID, "s[1].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1645 setUniform(gl, programID, "s[1].c", 1);
1648 c.color.xyz() = c.constCoords.swizzle(2,0,3);
1651 UNIFORM_STRUCT_CASE(loop_struct_array, "Struct array usage in loop", 0,
1653 << "${DECLARATIONS}"
1654 << "uniform int ui_zero;"
1655 << "uniform int ui_one;"
1656 << "uniform int ui_two;"
1659 << " mediump float a;"
1660 << " mediump int b;"
1662 << "uniform S s[3];"
1664 << "void main (void)"
1666 << " mediump float rgb[3];"
1667 << " int alpha = 0;"
1668 << " for (int i = 0; i < 3; i++)"
1670 << " rgb[i] = s[2-i].a;"
1671 << " alpha += s[i].b;"
1673 << " ${DST} = vec4(rgb[0], rgb[1], rgb[2], alpha);"
1677 setUniform(gl, programID, "s[0].a", constCoords.x());
1678 setUniform(gl, programID, "s[0].b", 0);
1679 setUniform(gl, programID, "s[1].a", constCoords.y());
1680 setUniform(gl, programID, "s[1].b", -1);
1681 setUniform(gl, programID, "s[2].a", constCoords.z());
1682 setUniform(gl, programID, "s[2].b", 2);
1685 c.color.xyz() = c.constCoords.swizzle(2,1,0);
1688 UNIFORM_STRUCT_CASE(loop_nested_struct_array, "Nested struct array usage in loop", 0,
1690 << "${DECLARATIONS}"
1691 << "uniform int ui_zero;"
1692 << "uniform int ui_one;"
1693 << "uniform int ui_two;"
1694 << "uniform mediump float uf_two;"
1695 << "uniform mediump float uf_three;"
1696 << "uniform mediump float uf_four;"
1697 << "uniform mediump float uf_half;"
1698 << "uniform mediump float uf_third;"
1699 << "uniform mediump float uf_fourth;"
1700 << "uniform mediump float uf_sixth;"
1703 << " mediump float a;"
1704 << " mediump vec2 b[2];"
1707 << " mediump float a;"
1711 << "uniform S s[2];"
1713 << "void main (void)"
1715 << " mediump float r = 0.0; // (x*3 + y*3) / 6.0"
1716 << " mediump float g = 0.0; // (y*3 + z*3) / 6.0"
1717 << " mediump float b = 0.0; // (z*3 + w*3) / 6.0"
1718 << " mediump float a = 1.0;"
1719 << " for (int i = 0; i < 2; i++)"
1721 << " for (int j = 0; j < 3; j++)"
1723 << " r += s[0].b[j].b[i].y;"
1724 << " g += s[i].b[j].b[0].x;"
1725 << " b += s[i].b[j].b[1].x;"
1726 << " a *= s[i].b[j].a;"
1729 << " ${DST} = vec4(r*uf_sixth, g*uf_sixth, b*uf_sixth, a);"
1735 setUniform(gl, programID, "s[0].a", constCoords.x());
1736 arr[0] = constCoords.swizzle(1,0);
1737 arr[1] = constCoords.swizzle(2,0);
1738 setUniform(gl, programID, "s[0].b[0].a", 0.5f);
1739 setUniform(gl, programID, "s[0].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1740 arr[0] = constCoords.swizzle(1,1);
1741 arr[1] = constCoords.swizzle(3,1);
1742 setUniform(gl, programID, "s[0].b[1].a", 1.0f/3.0f);
1743 setUniform(gl, programID, "s[0].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1744 arr[0] = constCoords.swizzle(2,1);
1745 arr[1] = constCoords.swizzle(2,1);
1746 setUniform(gl, programID, "s[0].b[2].a", 1.0f/4.0f);
1747 setUniform(gl, programID, "s[0].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1748 setUniform(gl, programID, "s[0].c", 0);
1750 setUniform(gl, programID, "s[1].a", constCoords.w());
1751 arr[0] = constCoords.swizzle(2,0);
1752 arr[1] = constCoords.swizzle(2,1);
1753 setUniform(gl, programID, "s[1].b[0].a", 2.0f);
1754 setUniform(gl, programID, "s[1].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1755 arr[0] = constCoords.swizzle(2,2);
1756 arr[1] = constCoords.swizzle(3,3);
1757 setUniform(gl, programID, "s[1].b[1].a", 3.0f);
1758 setUniform(gl, programID, "s[1].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1759 arr[0] = constCoords.swizzle(1,0);
1760 arr[1] = constCoords.swizzle(3,2);
1761 setUniform(gl, programID, "s[1].b[2].a", 4.0f);
1762 setUniform(gl, programID, "s[1].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1763 setUniform(gl, programID, "s[1].c", 1);
1766 c.color.xyz() = (c.constCoords.swizzle(0,1,2) + c.constCoords.swizzle(1,2,3)) * 0.5f;
1769 UNIFORM_STRUCT_CASE(dynamic_loop_struct_array, "Struct array usage in dynamic loop", FLAG_REQUIRES_DYNAMIC_INDEXING|FLAG_REQUIRES_DYNAMIC_LOOPS,
1771 << "${DECLARATIONS}"
1772 << "uniform int ui_zero;"
1773 << "uniform int ui_one;"
1774 << "uniform int ui_two;"
1775 << "uniform int ui_three;"
1778 << " mediump float a;"
1779 << " mediump int b;"
1781 << "uniform S s[3];"
1783 << "void main (void)"
1785 << " mediump float rgb[3];"
1786 << " int alpha = 0;"
1787 << " for (int i = 0; i < ui_three; i++)"
1789 << " rgb[i] = s[2-i].a;"
1790 << " alpha += s[i].b;"
1792 << " ${DST} = vec4(rgb[0], rgb[1], rgb[2], alpha);"
1796 setUniform(gl, programID, "s[0].a", constCoords.x());
1797 setUniform(gl, programID, "s[0].b", 0);
1798 setUniform(gl, programID, "s[1].a", constCoords.y());
1799 setUniform(gl, programID, "s[1].b", -1);
1800 setUniform(gl, programID, "s[2].a", constCoords.z());
1801 setUniform(gl, programID, "s[2].b", 2);
1804 c.color.xyz() = c.constCoords.swizzle(2,1,0);
1807 UNIFORM_STRUCT_CASE(dynamic_loop_nested_struct_array, "Nested struct array usage in dynamic loop", FLAG_REQUIRES_DYNAMIC_INDEXING|FLAG_REQUIRES_DYNAMIC_LOOPS,
1809 << "${DECLARATIONS}"
1810 << "uniform int ui_zero;"
1811 << "uniform int ui_one;"
1812 << "uniform int ui_two;"
1813 << "uniform int ui_three;"
1814 << "uniform mediump float uf_two;"
1815 << "uniform mediump float uf_three;"
1816 << "uniform mediump float uf_four;"
1817 << "uniform mediump float uf_half;"
1818 << "uniform mediump float uf_third;"
1819 << "uniform mediump float uf_fourth;"
1820 << "uniform mediump float uf_sixth;"
1823 << " mediump float a;"
1824 << " mediump vec2 b[2];"
1827 << " mediump float a;"
1831 << "uniform S s[2];"
1833 << "void main (void)"
1835 << " mediump float r = 0.0; // (x*3 + y*3) / 6.0"
1836 << " mediump float g = 0.0; // (y*3 + z*3) / 6.0"
1837 << " mediump float b = 0.0; // (z*3 + w*3) / 6.0"
1838 << " mediump float a = 1.0;"
1839 << " for (int i = 0; i < ui_two; i++)"
1841 << " for (int j = 0; j < ui_three; j++)"
1843 << " r += s[0].b[j].b[i].y;"
1844 << " g += s[i].b[j].b[0].x;"
1845 << " b += s[i].b[j].b[1].x;"
1846 << " a *= s[i].b[j].a;"
1849 << " ${DST} = vec4(r*uf_sixth, g*uf_sixth, b*uf_sixth, a);"
1855 setUniform(gl, programID, "s[0].a", constCoords.x());
1856 arr[0] = constCoords.swizzle(1,0);
1857 arr[1] = constCoords.swizzle(2,0);
1858 setUniform(gl, programID, "s[0].b[0].a", 0.5f);
1859 setUniform(gl, programID, "s[0].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1860 arr[0] = constCoords.swizzle(1,1);
1861 arr[1] = constCoords.swizzle(3,1);
1862 setUniform(gl, programID, "s[0].b[1].a", 1.0f/3.0f);
1863 setUniform(gl, programID, "s[0].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1864 arr[0] = constCoords.swizzle(2,1);
1865 arr[1] = constCoords.swizzle(2,1);
1866 setUniform(gl, programID, "s[0].b[2].a", 1.0f/4.0f);
1867 setUniform(gl, programID, "s[0].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1868 setUniform(gl, programID, "s[0].c", 0);
1870 setUniform(gl, programID, "s[1].a", constCoords.w());
1871 arr[0] = constCoords.swizzle(2,0);
1872 arr[1] = constCoords.swizzle(2,1);
1873 setUniform(gl, programID, "s[1].b[0].a", 2.0f);
1874 setUniform(gl, programID, "s[1].b[0].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1875 arr[0] = constCoords.swizzle(2,2);
1876 arr[1] = constCoords.swizzle(3,3);
1877 setUniform(gl, programID, "s[1].b[1].a", 3.0f);
1878 setUniform(gl, programID, "s[1].b[1].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1879 arr[0] = constCoords.swizzle(1,0);
1880 arr[1] = constCoords.swizzle(3,2);
1881 setUniform(gl, programID, "s[1].b[2].a", 4.0f);
1882 setUniform(gl, programID, "s[1].b[2].b", &arr[0], DE_LENGTH_OF_ARRAY(arr));
1883 setUniform(gl, programID, "s[1].c", 1);
1886 c.color.xyz() = (c.constCoords.swizzle(0,1,2) + c.constCoords.swizzle(1,2,3)) * 0.5f;
1889 UNIFORM_STRUCT_CASE(sampler, "Sampler in struct", FLAG_USES_TEXTURES,
1891 << "${DECLARATIONS}"
1892 << "uniform int ui_one;"
1895 << " mediump float a;"
1896 << " mediump vec3 b;"
1901 << "void main (void)"
1903 << " ${DST} = vec4(texture2D(s.c, ${COORDS}.xy * s.b.xy + s.b.z).rgb, s.a);"
1907 DE_UNREF(constCoords);
1908 setUniform(gl, programID, "s.a", 1.0f);
1909 setUniform(gl, programID, "s.b", tcu::Vec3(0.25f, 0.25f, 0.5f));
1910 setUniform(gl, programID, "s.c", 0);
1913 c.color.xyz() = c.texture2D(TEXTURE_BRICK, c.coords.swizzle(0,1) * 0.25f + 0.5f).swizzle(0,1,2);
1916 UNIFORM_STRUCT_CASE(sampler_nested, "Sampler in nested struct", FLAG_USES_TEXTURES,
1918 << "${DECLARATIONS}"
1919 << "uniform int ui_zero;"
1920 << "uniform int ui_one;"
1924 << " mediump vec2 b;"
1927 << " mediump float a;"
1933 << "void main (void)"
1935 << " ${DST} = vec4(texture2D(s.b.a, ${COORDS}.xy * s.b.b + s.a).rgb, s.c);"
1939 DE_UNREF(constCoords);
1940 setUniform(gl, programID, "s.a", 0.5f);
1941 setUniform(gl, programID, "s.b.a", 0);
1942 setUniform(gl, programID, "s.b.b", tcu::Vec2(0.25f, 0.25f));
1943 setUniform(gl, programID, "s.c", 1);
1946 c.color.xyz() = c.texture2D(TEXTURE_BRICK, c.coords.swizzle(0,1) * 0.25f + 0.5f).swizzle(0,1,2);
1949 UNIFORM_STRUCT_CASE(sampler_array, "Sampler in struct array", FLAG_USES_TEXTURES,
1951 << "${DECLARATIONS}"
1952 << "uniform int ui_one;"
1955 << " mediump float a;"
1956 << " mediump vec3 b;"
1959 << "uniform S s[2];"
1961 << "void main (void)"
1963 << " ${DST} = vec4(texture2D(s[1].c, ${COORDS}.xy * s[0].b.xy + s[1].b.z).rgb, s[0].a);"
1967 DE_UNREF(constCoords);
1968 setUniform(gl, programID, "s[0].a", 1.0f);
1969 setUniform(gl, programID, "s[0].b", tcu::Vec3(0.25f, 0.25f, 0.25f));
1970 setUniform(gl, programID, "s[0].c", 1);
1971 setUniform(gl, programID, "s[1].a", 0.0f);
1972 setUniform(gl, programID, "s[1].b", tcu::Vec3(0.5f, 0.5f, 0.5f));
1973 setUniform(gl, programID, "s[1].c", 0);
1976 c.color.xyz() = c.texture2D(TEXTURE_BRICK, c.coords.swizzle(0,1) * 0.25f + 0.5f).swizzle(0,1,2);
1979 UNIFORM_STRUCT_CASE(sampler_in_function_arg, "Sampler in struct as function arg", FLAG_USES_TEXTURES,
1981 << "${DECLARATIONS}"
1984 << " sampler2D source;"
1987 << "mediump vec4 fun(S s) {"
1988 << " return texture2D(s.source, vec2(0.5));"
1992 << "void main (void)"
1994 << " ${DST} = fun(s);"
1998 DE_UNREF(constCoords);
1999 setUniform(gl, programID, "s.source", 0);
2002 c.color.xyz() = c.texture2D(TEXTURE_BRICK, tcu::Vec2(0.5f, 0.5f)).swizzle(0,1,2);
2005 UNIFORM_STRUCT_CASE(sampler_in_array_function_arg, "Sampler in struct as function arg", FLAG_USES_TEXTURES,
2007 << "${DECLARATIONS}"
2010 << " sampler2D source;"
2013 << "mediump vec4 fun(S s[2]) {"
2014 << " return texture2D(s[0].source, vec2(0.5));"
2017 << "uniform S s[2];"
2018 << "void main (void)"
2020 << " ${DST} = fun(s);"
2024 DE_UNREF(constCoords);
2025 setUniform(gl, programID, "s[0].source", 0);
2028 c.color.xyz() = c.texture2D(TEXTURE_BRICK, tcu::Vec2(0.5f, 0.5f)).swizzle(0,1,2);
2031 UNIFORM_STRUCT_CASE(equal, "Struct equality", 0,
2033 << "${DECLARATIONS}"
2034 << "uniform mediump float uf_one;"
2035 << "uniform int ui_two;"
2038 << " mediump float a;"
2039 << " mediump vec3 b;"
2046 << "void main (void)"
2048 << " S d = S(uf_one, vec3(0.0, floor(${COORDS}.y+1.0), 2.0), ui_two);"
2049 << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);"
2050 << " if (a == b) ${DST}.x = 1.0;"
2051 << " if (a == c) ${DST}.y = 1.0;"
2052 << " if (a == d) ${DST}.z = 1.0;"
2056 DE_UNREF(constCoords);
2057 setUniform(gl, programID, "a.a", 1.0f);
2058 setUniform(gl, programID, "a.b", tcu::Vec3(0.0f, 1.0f, 2.0f));
2059 setUniform(gl, programID, "a.c", 2);
2060 setUniform(gl, programID, "b.a", 1.0f);
2061 setUniform(gl, programID, "b.b", tcu::Vec3(0.0f, 1.0f, 2.0f));
2062 setUniform(gl, programID, "b.c", 2);
2063 setUniform(gl, programID, "c.a", 1.0f);
2064 setUniform(gl, programID, "c.b", tcu::Vec3(0.0f, 1.1f, 2.0f));
2065 setUniform(gl, programID, "c.c", 2);
2068 c.color.xy() = tcu::Vec2(1.0f, 0.0f);
2069 if (deFloatFloor(c.coords[1]+1.0f) == deFloatFloor(1.1f))
2073 UNIFORM_STRUCT_CASE(not_equal, "Struct equality", 0,
2075 << "${DECLARATIONS}"
2076 << "uniform mediump float uf_one;"
2077 << "uniform int ui_two;"
2080 << " mediump float a;"
2081 << " mediump vec3 b;"
2088 << "void main (void)"
2090 << " S d = S(uf_one, vec3(0.0, floor(${COORDS}.y+1.0), 2.0), ui_two);"
2091 << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);"
2092 << " if (a != b) ${DST}.x = 1.0;"
2093 << " if (a != c) ${DST}.y = 1.0;"
2094 << " if (a != d) ${DST}.z = 1.0;"
2098 DE_UNREF(constCoords);
2099 setUniform(gl, programID, "a.a", 1.0f);
2100 setUniform(gl, programID, "a.b", tcu::Vec3(0.0f, 1.0f, 2.0f));
2101 setUniform(gl, programID, "a.c", 2);
2102 setUniform(gl, programID, "b.a", 1.0f);
2103 setUniform(gl, programID, "b.b", tcu::Vec3(0.0f, 1.0f, 2.0f));
2104 setUniform(gl, programID, "b.c", 2);
2105 setUniform(gl, programID, "c.a", 1.0f);
2106 setUniform(gl, programID, "c.b", tcu::Vec3(0.0f, 1.1f, 2.0f));
2107 setUniform(gl, programID, "c.c", 2);
2110 c.color.xy() = tcu::Vec2(0.0f, 1.0f);
2111 if (deFloatFloor(c.coords[1]+1.0f) != deFloatFloor(1.1f))
2116 ShaderStructTests::ShaderStructTests (Context& context)
2117 : TestCaseGroup(context, "struct", "Struct Tests")
2121 ShaderStructTests::~ShaderStructTests (void)
2125 void ShaderStructTests::init (void)
2127 addChild(new LocalStructTests(m_context));
2128 addChild(new UniformStructTests(m_context));