1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and/or associated documentation files (the
10 * "Materials"), to deal in the Materials without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sublicense, and/or sell copies of the Materials, and to
13 * permit persons to whom the Materials are furnished to do so, subject to
14 * the following conditions:
16 * The above copyright notice(s) and this permission notice shall be included
17 * in all copies or substantial portions of the Materials.
19 * The Materials are Confidential Information as defined by the
20 * Khronos Membership Agreement until designated non-confidential by Khronos,
21 * at which point this condition clause shall be removed.
23 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
27 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
33 * \brief Shader struct tests.
34 *//*--------------------------------------------------------------------*/
36 #include "vktShaderRenderStructTests.hpp"
37 #include "vktShaderRender.hpp"
38 #include "tcuStringTemplate.hpp"
48 class ShaderStructCase : public ShaderRenderCase
51 ShaderStructCase (tcu::TestContext& testCtx,
52 const std::string& name,
53 const std::string& description,
55 ShaderEvalFunc evalFunc,
56 UniformSetupFunc setupUniformsFunc,
57 const std::string& vertShaderSource,
58 const std::string& fragShaderSource);
59 ~ShaderStructCase (void);
62 ShaderStructCase (const ShaderStructCase&);
63 ShaderStructCase& operator= (const ShaderStructCase&);
66 ShaderStructCase::ShaderStructCase (tcu::TestContext& testCtx,
67 const std::string& name,
68 const std::string& description,
70 ShaderEvalFunc evalFunc,
71 UniformSetupFunc setupUniformsFunc,
72 const std::string& vertShaderSource,
73 const std::string& fragShaderSource)
74 : ShaderRenderCase (testCtx, name, description, isVertexCase, evalFunc, new UniformSetup(setupUniformsFunc), DE_NULL)
76 m_vertShaderSource = vertShaderSource;
77 m_fragShaderSource = fragShaderSource;
80 ShaderStructCase::~ShaderStructCase (void)
84 static de::MovePtr<ShaderStructCase> createStructCase (tcu::TestContext& testCtx, const std::string& name, const std::string& description, bool isVertexCase, ShaderEvalFunc evalFunc, UniformSetupFunc uniformFunc, const LineStream& shaderSrc)
86 static std::string defaultVertSrc =
88 "#extension GL_ARB_separate_shader_objects : enable\n"
89 "#extension GL_ARB_shading_language_420pack : enable\n"
90 "layout(location = 0) in highp vec4 a_position;\n"
91 "layout(location = 1) in highp vec4 a_coords;\n"
92 "layout(location = 0) out mediump vec4 v_coords;\n\n"
95 " v_coords = a_coords;\n"
96 " gl_Position = a_position;\n"
98 static std::string defaultFragSrc =
100 "#extension GL_ARB_separate_shader_objects : enable\n"
101 "#extension GL_ARB_shading_language_420pack : enable\n"
102 "layout(location = 0) in mediump vec4 v_color;\n"
103 "layout(location = 0) out mediump vec4 o_color;\n\n"
106 " o_color = v_color;\n"
109 // Fill in specialization parameters and build the shader source.
112 std::map<std::string, std::string> spParams;
118 "#extension GL_ARB_separate_shader_objects : enable\n"
119 "#extension GL_ARB_shading_language_420pack : enable\n"
120 "layout(location = 0) in highp vec4 a_position;\n"
121 "layout(location = 1) in highp vec4 a_coords;\n"
122 "layout(location = 0) out mediump vec4 v_color;";
123 spParams["COORDS"] = "a_coords";
124 spParams["DST"] = "v_color";
125 spParams["ASSIGN_POS"] = "gl_Position = a_position;";
127 vertSrc = tcu::StringTemplate(shaderSrc.str()).specialize(spParams);
128 fragSrc = defaultFragSrc;
134 "#extension GL_ARB_separate_shader_objects : enable\n"
135 "#extension GL_ARB_shading_language_420pack : enable\n"
136 "layout(location = 0) in mediump vec4 v_coords;\n"
137 "layout(location = 0) out mediump vec4 o_color;";
138 spParams["COORDS"] = "v_coords";
139 spParams["DST"] = "o_color";
140 spParams["ASSIGN_POS"] = "";
142 vertSrc = defaultVertSrc;
143 fragSrc = tcu::StringTemplate(shaderSrc.str()).specialize(spParams);
146 return de::MovePtr<ShaderStructCase>(new ShaderStructCase(testCtx, name, description, isVertexCase, evalFunc, uniformFunc, vertSrc, fragSrc));
149 class LocalStructTests : public tcu::TestCaseGroup
152 LocalStructTests (tcu::TestContext& testCtx)
153 : TestCaseGroup(testCtx, "local", "Local structs")
157 ~LocalStructTests (void)
161 virtual void init (void);
164 void LocalStructTests::init (void)
166 #define LOCAL_STRUCT_CASE(NAME, DESCRIPTION, SHADER_SRC, SET_UNIFORMS_BODY, EVAL_FUNC_BODY) \
168 struct SetUniforms_##NAME { static void setUniforms (ShaderRenderCaseInstance& instance, const tcu::Vec4&) SET_UNIFORMS_BODY }; \
169 struct Eval_##NAME { static void eval (ShaderEvalContext& c) EVAL_FUNC_BODY }; \
170 addChild(createStructCase(m_testCtx, #NAME "_vertex", DESCRIPTION, true, &Eval_##NAME::eval, &SetUniforms_##NAME::setUniforms, SHADER_SRC).release()); \
171 addChild(createStructCase(m_testCtx, #NAME "_fragment", DESCRIPTION, false, &Eval_##NAME::eval, &SetUniforms_##NAME::setUniforms, SHADER_SRC).release()); \
172 } while (deGetFalse())
174 LOCAL_STRUCT_CASE(basic, "Basic struct usage",
177 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_one; };"
180 << " mediump float a;"
181 << " mediump vec3 b;"
185 << "void main (void)"
187 << " S s = S(${COORDS}.x, vec3(0.0), ui_one);"
188 << " s.b = ${COORDS}.yzw;"
189 << " ${DST} = vec4(s.a, s.b.x, s.b.y, s.c);"
193 instance.useUniform(0u, UI_ONE);
196 c.color.xyz() = c.coords.swizzle(0, 1, 2);
199 LOCAL_STRUCT_CASE(nested, "Nested struct",
202 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_zero; };"
203 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_one; };"
207 << " mediump vec2 b;"
210 << " mediump float a;"
215 << "void main (void)"
217 << " S s = S(${COORDS}.x, T(0, vec2(0.0)), ui_one);"
218 << " s.b = T(ui_zero, ${COORDS}.yz);"
219 << " ${DST} = vec4(s.a, s.b.b, s.b.a + s.c);"
223 instance.useUniform(0u, UI_ZERO);
224 instance.useUniform(1u, UI_ONE);
227 c.color.xyz() = c.coords.swizzle(0, 1, 2);
230 LOCAL_STRUCT_CASE(array_member, "Struct with array member",
233 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_one; };"
236 << " mediump float a;"
237 << " mediump float b[3];"
241 << "void main (void)"
244 << " s.a = ${COORDS}.w;"
246 << " s.b[0] = ${COORDS}.z;"
247 << " s.b[1] = ${COORDS}.y;"
248 << " s.b[2] = ${COORDS}.x;"
249 << " ${DST} = vec4(s.a, s.b[0], s.b[1], s.c);"
253 instance.useUniform(0u, UI_ONE);
256 c.color.xyz() = c.coords.swizzle(3, 2, 1);
259 LOCAL_STRUCT_CASE(array_member_dynamic_index, "Struct with array member, dynamic indexing",
262 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_zero; };"
263 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_one; };"
264 << "layout (std140, set = 0, binding = 2) uniform buffer2 { int ui_two; };"
267 << " mediump float a;"
268 << " mediump float b[3];"
272 << "void main (void)"
275 << " s.a = ${COORDS}.w;"
277 << " s.b[0] = ${COORDS}.z;"
278 << " s.b[1] = ${COORDS}.y;"
279 << " s.b[2] = ${COORDS}.x;"
280 << " ${DST} = vec4(s.b[ui_one], s.b[ui_zero], s.b[ui_two], s.c);"
284 instance.useUniform(0u, UI_ZERO);
285 instance.useUniform(1u, UI_ONE);
286 instance.useUniform(2u, UI_TWO);
289 c.color.xyz() = c.coords.swizzle(1,2,0);
292 LOCAL_STRUCT_CASE(struct_array, "Struct array",
295 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_zero; };"
296 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_one; };"
297 << "layout (std140, set = 0, binding = 2) uniform buffer2 { int ui_two; };"
300 << " mediump float a;"
304 << "void main (void)"
307 << " s[0] = S(${COORDS}.x, ui_zero);"
308 << " s[1].a = ${COORDS}.y;"
309 << " s[1].b = ui_one;"
310 << " s[2] = S(${COORDS}.z, ui_two);"
311 << " ${DST} = vec4(s[2].a, s[1].a, s[0].a, s[2].b - s[1].b + s[0].b);"
315 instance.useUniform(0u, UI_ZERO);
316 instance.useUniform(1u, UI_ONE);
317 instance.useUniform(2u, UI_TWO);
320 c.color.xyz() = c.coords.swizzle(2, 1, 0);
323 LOCAL_STRUCT_CASE(struct_array_dynamic_index, "Struct array with dynamic indexing",
326 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_zero; };"
327 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_one; };"
328 << "layout (std140, set = 0, binding = 2) uniform buffer2 { int ui_two; };"
331 << " mediump float a;"
335 << "void main (void)"
338 << " s[0] = S(${COORDS}.x, ui_zero);"
339 << " s[1].a = ${COORDS}.y;"
340 << " s[1].b = ui_one;"
341 << " s[2] = S(${COORDS}.z, ui_two);"
342 << " ${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);"
346 instance.useUniform(0u, UI_ZERO);
347 instance.useUniform(1u, UI_ONE);
348 instance.useUniform(2u, UI_TWO);
351 c.color.xyz() = c.coords.swizzle(2, 1, 0);
354 LOCAL_STRUCT_CASE(nested_struct_array, "Nested struct array",
357 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_zero; };"
358 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_one; };"
359 << "layout (std140, set = 0, binding = 2) uniform buffer2 { int ui_two; };"
360 << "layout (std140, set = 0, binding = 3) uniform buffer3 { mediump float uf_two; };"
361 << "layout (std140, set = 0, binding = 4) uniform buffer4 { mediump float uf_three; };"
362 << "layout (std140, set = 0, binding = 5) uniform buffer5 { mediump float uf_four; };"
363 << "layout (std140, set = 0, binding = 6) uniform buffer6 { mediump float uf_half; };"
364 << "layout (std140, set = 0, binding = 7) uniform buffer7 { mediump float uf_third; };"
365 << "layout (std140, set = 0, binding = 8) uniform buffer8 { mediump float uf_fourth; };"
368 << " mediump float a;"
369 << " mediump vec2 b[2];"
372 << " mediump float a;"
377 << "void main (void)"
382 << " s[0].a = ${COORDS}.x;"
383 << " s[0].b[0].a = uf_half;"
384 << " s[0].b[0].b[0] = ${COORDS}.xy;"
385 << " s[0].b[0].b[1] = ${COORDS}.zw;"
386 << " s[0].b[1].a = uf_third;"
387 << " s[0].b[1].b[0] = ${COORDS}.zw;"
388 << " s[0].b[1].b[1] = ${COORDS}.xy;"
389 << " s[0].b[2].a = uf_fourth;"
390 << " s[0].b[2].b[0] = ${COORDS}.xz;"
391 << " s[0].b[2].b[1] = ${COORDS}.yw;"
392 << " s[0].c = ui_zero;"
395 << " s[1].a = ${COORDS}.w;"
396 << " s[1].b[0].a = uf_two;"
397 << " s[1].b[0].b[0] = ${COORDS}.xx;"
398 << " s[1].b[0].b[1] = ${COORDS}.yy;"
399 << " s[1].b[1].a = uf_three;"
400 << " s[1].b[1].b[0] = ${COORDS}.zz;"
401 << " s[1].b[1].b[1] = ${COORDS}.ww;"
402 << " s[1].b[2].a = uf_four;"
403 << " s[1].b[2].b[0] = ${COORDS}.yx;"
404 << " s[1].b[2].b[1] = ${COORDS}.wz;"
405 << " s[1].c = ui_one;"
407 << " 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"
408 << " mediump float g = s[1].b[0].b[0].y * s[0].b[2].a * s[1].b[2].a; // x * 0.25 * 4"
409 << " 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"
410 << " mediump float a = float(s[0].c) + s[1].b[2].a - s[1].b[1].a; // 0 + 4.0 - 3.0"
411 << " ${DST} = vec4(r, g, b, a);"
415 instance.useUniform(0u, UI_ZERO);
416 instance.useUniform(1u, UI_ONE);
417 instance.useUniform(2u, UI_TWO);
418 instance.useUniform(3u, UF_TWO);
419 instance.useUniform(4u, UF_THREE);
420 instance.useUniform(5u, UF_FOUR);
421 instance.useUniform(6u, UF_HALF);
422 instance.useUniform(7u, UF_THIRD);
423 instance.useUniform(8u, UF_FOURTH);
426 c.color.xyz() = c.coords.swizzle(2, 0, 3);
429 LOCAL_STRUCT_CASE(nested_struct_array_dynamic_index, "Nested struct array with dynamic indexing",
432 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_zero; };"
433 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_one; };"
434 << "layout (std140, set = 0, binding = 2) uniform buffer2 { int ui_two; };"
435 << "layout (std140, set = 0, binding = 3) uniform buffer3 { mediump float uf_two; };"
436 << "layout (std140, set = 0, binding = 4) uniform buffer4 { mediump float uf_three; };"
437 << "layout (std140, set = 0, binding = 5) uniform buffer5 { mediump float uf_four; };"
438 << "layout (std140, set = 0, binding = 6) uniform buffer6 { mediump float uf_half; };"
439 << "layout (std140, set = 0, binding = 7) uniform buffer7 { mediump float uf_third; };"
440 << "layout (std140, set = 0, binding = 8) uniform buffer8 { mediump float uf_fourth; };"
443 << " mediump float a;"
444 << " mediump vec2 b[2];"
447 << " mediump float a;"
452 << "void main (void)"
457 << " s[0].a = ${COORDS}.x;"
458 << " s[0].b[0].a = uf_half;"
459 << " s[0].b[0].b[0] = ${COORDS}.xy;"
460 << " s[0].b[0].b[1] = ${COORDS}.zw;"
461 << " s[0].b[1].a = uf_third;"
462 << " s[0].b[1].b[0] = ${COORDS}.zw;"
463 << " s[0].b[1].b[1] = ${COORDS}.xy;"
464 << " s[0].b[2].a = uf_fourth;"
465 << " s[0].b[2].b[0] = ${COORDS}.xz;"
466 << " s[0].b[2].b[1] = ${COORDS}.yw;"
467 << " s[0].c = ui_zero;"
470 << " s[1].a = ${COORDS}.w;"
471 << " s[1].b[0].a = uf_two;"
472 << " s[1].b[0].b[0] = ${COORDS}.xx;"
473 << " s[1].b[0].b[1] = ${COORDS}.yy;"
474 << " s[1].b[1].a = uf_three;"
475 << " s[1].b[1].b[0] = ${COORDS}.zz;"
476 << " s[1].b[1].b[1] = ${COORDS}.ww;"
477 << " s[1].b[2].a = uf_four;"
478 << " s[1].b[2].b[0] = ${COORDS}.yx;"
479 << " s[1].b[2].b[1] = ${COORDS}.wz;"
480 << " s[1].c = ui_one;"
482 << " 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"
483 << " 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"
484 << " 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"
485 << " 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"
486 << " ${DST} = vec4(r, g, b, a);"
490 instance.useUniform(0u, UI_ZERO);
491 instance.useUniform(1u, UI_ONE);
492 instance.useUniform(2u, UI_TWO);
493 instance.useUniform(3u, UF_TWO);
494 instance.useUniform(4u, UF_THREE);
495 instance.useUniform(5u, UF_FOUR);
496 instance.useUniform(6u, UF_HALF);
497 instance.useUniform(7u, UF_THIRD);
498 instance.useUniform(8u, UF_FOURTH);
501 c.color.xyz() = c.coords.swizzle(2, 0, 3);
504 LOCAL_STRUCT_CASE(parameter, "Struct as a function parameter",
507 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_one; };"
510 << " mediump float a;"
511 << " mediump vec3 b;"
515 << "mediump vec4 myFunc (S s)"
517 << " return vec4(s.a, s.b.x, s.b.y, s.c);"
520 << "void main (void)"
522 << " S s = S(${COORDS}.x, vec3(0.0), ui_one);"
523 << " s.b = ${COORDS}.yzw;"
524 << " ${DST} = myFunc(s);"
528 instance.useUniform(0u, UI_ONE);
531 c.color.xyz() = c.coords.swizzle(0, 1, 2);
534 LOCAL_STRUCT_CASE(parameter_nested, "Nested struct as a function parameter",
537 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_zero; };"
538 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_one; };"
542 << " mediump vec2 b;"
545 << " mediump float a;"
550 << "mediump vec4 myFunc (S s)"
552 << " return vec4(s.a, s.b.b, s.b.a + s.c);"
555 << "void main (void)"
557 << " S s = S(${COORDS}.x, T(0, vec2(0.0)), ui_one);"
558 << " s.b = T(ui_zero, ${COORDS}.yz);"
559 << " ${DST} = myFunc(s);"
563 instance.useUniform(0u, UI_ZERO);
564 instance.useUniform(1u, UI_ONE);
567 c.color.xyz() = c.coords.swizzle(0, 1, 2);
570 LOCAL_STRUCT_CASE(return, "Struct as a return value",
573 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_one; };"
576 << " mediump float a;"
577 << " mediump vec3 b;"
583 << " S s = S(${COORDS}.x, vec3(0.0), ui_one);"
584 << " s.b = ${COORDS}.yzw;"
588 << "void main (void)"
590 << " S s = myFunc();"
591 << " ${DST} = vec4(s.a, s.b.x, s.b.y, s.c);"
595 instance.useUniform(0u, UI_ONE);
598 c.color.xyz() = c.coords.swizzle(0, 1, 2);
601 LOCAL_STRUCT_CASE(return_nested, "Nested struct",
604 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_zero; };"
605 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_one; };"
609 << " mediump vec2 b;"
612 << " mediump float a;"
619 << " S s = S(${COORDS}.x, T(0, vec2(0.0)), ui_one);"
620 << " s.b = T(ui_zero, ${COORDS}.yz);"
624 << "void main (void)"
626 << " S s = myFunc();"
627 << " ${DST} = vec4(s.a, s.b.b, s.b.a + s.c);"
631 instance.useUniform(0u, UI_ZERO);
632 instance.useUniform(1u, UI_ONE);
635 c.color.xyz() = c.coords.swizzle(0, 1, 2);
638 LOCAL_STRUCT_CASE(conditional_assignment, "Conditional struct assignment",
641 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_zero; };"
642 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_one; };"
643 << "layout (std140, set = 0, binding = 2) uniform buffer2 { mediump float uf_one; };"
646 << " mediump float a;"
647 << " mediump vec3 b;"
651 << "void main (void)"
653 << " S s = S(${COORDS}.x, ${COORDS}.yzw, ui_zero);"
654 << " if (uf_one > 0.0)"
655 << " s = S(${COORDS}.w, ${COORDS}.zyx, ui_one);"
656 << " ${DST} = vec4(s.a, s.b.xy, s.c);"
660 instance.useUniform(0u, UI_ZERO);
661 instance.useUniform(1u, UI_ONE);
662 instance.useUniform(2u, UF_ONE);
665 c.color.xyz() = c.coords.swizzle(3, 2, 1);
668 LOCAL_STRUCT_CASE(loop_assignment, "Struct assignment in loop",
671 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_zero; };"
672 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_one; };"
675 << " mediump float a;"
676 << " mediump vec3 b;"
680 << "void main (void)"
682 << " S s = S(${COORDS}.x, ${COORDS}.yzw, ui_zero);"
683 << " for (int i = 0; i < 3; i++)"
686 << " s = S(${COORDS}.w, ${COORDS}.zyx, ui_one);"
688 << " ${DST} = vec4(s.a, s.b.xy, s.c);"
692 instance.useUniform(0u, UI_ZERO);
693 instance.useUniform(1u, UI_ONE);
696 c.color.xyz() = c.coords.swizzle(3, 2, 1);
699 LOCAL_STRUCT_CASE(dynamic_loop_assignment, "Struct assignment in loop",
702 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_zero; };"
703 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_one; };"
704 << "layout (std140, set = 0, binding = 2) uniform buffer2 { int ui_three; };"
707 << " mediump float a;"
708 << " mediump vec3 b;"
712 << "void main (void)"
714 << " S s = S(${COORDS}.x, ${COORDS}.yzw, ui_zero);"
715 << " for (int i = 0; i < ui_three; i++)"
717 << " if (i == ui_one)"
718 << " s = S(${COORDS}.w, ${COORDS}.zyx, ui_one);"
720 << " ${DST} = vec4(s.a, s.b.xy, s.c);"
724 instance.useUniform(0u, UI_ZERO);
725 instance.useUniform(1u, UI_ONE);
726 instance.useUniform(2u, UI_THREE);
729 c.color.xyz() = c.coords.swizzle(3, 2, 1);
732 LOCAL_STRUCT_CASE(nested_conditional_assignment, "Conditional assignment of nested struct",
735 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_zero; };"
736 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_one; };"
737 << "layout (std140, set = 0, binding = 2) uniform buffer2 { mediump float uf_one; };"
741 << " mediump vec2 b;"
744 << " mediump float a;"
749 << "void main (void)"
751 << " S s = S(${COORDS}.x, T(ui_one, ${COORDS}.yz), ui_one);"
752 << " if (uf_one > 0.0)"
753 << " s.b = T(ui_zero, ${COORDS}.zw);"
754 << " ${DST} = vec4(s.a, s.b.b, s.c - s.b.a);"
758 instance.useUniform(0u, UI_ZERO);
759 instance.useUniform(1u, UI_ONE);
760 instance.useUniform(2u, UF_ONE);
763 c.color.xyz() = c.coords.swizzle(0, 2, 3);
766 LOCAL_STRUCT_CASE(nested_loop_assignment, "Nested struct assignment in loop",
769 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_zero; };"
770 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_one; };"
771 << "layout (std140, set = 0, binding = 2) uniform buffer2 { mediump float uf_one; };"
775 << " mediump vec2 b;"
778 << " mediump float a;"
783 << "void main (void)"
785 << " S s = S(${COORDS}.x, T(ui_one, ${COORDS}.yz), ui_one);"
786 << " for (int i = 0; i < 3; i++)"
789 << " s.b = T(ui_zero, ${COORDS}.zw);"
791 << " ${DST} = vec4(s.a, s.b.b, s.c - s.b.a);"
795 instance.useUniform(0u, UI_ZERO);
796 instance.useUniform(1u, UI_ONE);
797 instance.useUniform(2u, UF_ONE);
800 c.color.xyz() = c.coords.swizzle(0, 2, 3);
803 LOCAL_STRUCT_CASE(nested_dynamic_loop_assignment, "Nested struct assignment in dynamic loop",
806 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_zero; };"
807 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_one; };"
808 << "layout (std140, set = 0, binding = 2) uniform buffer2 { int ui_three; };"
809 << "layout (std140, set = 0, binding = 3) uniform buffer3 { mediump float uf_one; };"
813 << " mediump vec2 b;"
816 << " mediump float a;"
821 << "void main (void)"
823 << " S s = S(${COORDS}.x, T(ui_one, ${COORDS}.yz), ui_one);"
824 << " for (int i = 0; i < ui_three; i++)"
826 << " if (i == ui_one)"
827 << " s.b = T(ui_zero, ${COORDS}.zw);"
829 << " ${DST} = vec4(s.a, s.b.b, s.c - s.b.a);"
833 instance.useUniform(0u, UI_ZERO);
834 instance.useUniform(1u, UI_ONE);
835 instance.useUniform(2u, UI_THREE);
836 instance.useUniform(3u, UF_ONE);
839 c.color.xyz() = c.coords.swizzle(0, 2, 3);
842 LOCAL_STRUCT_CASE(loop_struct_array, "Struct array usage in loop",
845 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_zero; };"
846 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_one; };"
847 << "layout (std140, set = 0, binding = 2) uniform buffer2 { int ui_two; };"
850 << " mediump float a;"
854 << "void main (void)"
857 << " s[0] = S(${COORDS}.x, ui_zero);"
858 << " s[1].a = ${COORDS}.y;"
859 << " s[1].b = -ui_one;"
860 << " s[2] = S(${COORDS}.z, ui_two);"
862 << " mediump float rgb[3];"
864 << " for (int i = 0; i < 3; i++)"
866 << " rgb[i] = s[2-i].a;"
867 << " alpha += s[i].b;"
869 << " ${DST} = vec4(rgb[0], rgb[1], rgb[2], alpha);"
873 instance.useUniform(0u, UI_ZERO);
874 instance.useUniform(1u, UI_ONE);
875 instance.useUniform(2u, UI_TWO);
878 c.color.xyz() = c.coords.swizzle(2, 1, 0);
881 LOCAL_STRUCT_CASE(loop_nested_struct_array, "Nested struct array usage in loop",
884 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_zero; };"
885 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_one; };"
886 << "layout (std140, set = 0, binding = 2) uniform buffer2 { int ui_two; };"
887 << "layout (std140, set = 0, binding = 3) uniform buffer3 { mediump float uf_two; };"
888 << "layout (std140, set = 0, binding = 4) uniform buffer4 { mediump float uf_three; };"
889 << "layout (std140, set = 0, binding = 5) uniform buffer5 { mediump float uf_four; };"
890 << "layout (std140, set = 0, binding = 6) uniform buffer6 { mediump float uf_half; };"
891 << "layout (std140, set = 0, binding = 7) uniform buffer7 { mediump float uf_third; };"
892 << "layout (std140, set = 0, binding = 8) uniform buffer8 { mediump float uf_fourth; };"
893 << "layout (std140, set = 0, binding = 9) uniform buffer9 { mediump float uf_sixth; };"
896 << " mediump float a;"
897 << " mediump vec2 b[2];"
900 << " mediump float a;"
905 << "void main (void)"
910 << " s[0].a = ${COORDS}.x;"
911 << " s[0].b[0].a = uf_half;"
912 << " s[0].b[0].b[0] = ${COORDS}.yx;"
913 << " s[0].b[0].b[1] = ${COORDS}.zx;"
914 << " s[0].b[1].a = uf_third;"
915 << " s[0].b[1].b[0] = ${COORDS}.yy;"
916 << " s[0].b[1].b[1] = ${COORDS}.wy;"
917 << " s[0].b[2].a = uf_fourth;"
918 << " s[0].b[2].b[0] = ${COORDS}.zx;"
919 << " s[0].b[2].b[1] = ${COORDS}.zy;"
920 << " s[0].c = ui_zero;"
923 << " s[1].a = ${COORDS}.w;"
924 << " s[1].b[0].a = uf_two;"
925 << " s[1].b[0].b[0] = ${COORDS}.zx;"
926 << " s[1].b[0].b[1] = ${COORDS}.zy;"
927 << " s[1].b[1].a = uf_three;"
928 << " s[1].b[1].b[0] = ${COORDS}.zz;"
929 << " s[1].b[1].b[1] = ${COORDS}.ww;"
930 << " s[1].b[2].a = uf_four;"
931 << " s[1].b[2].b[0] = ${COORDS}.yx;"
932 << " s[1].b[2].b[1] = ${COORDS}.wz;"
933 << " s[1].c = ui_one;"
935 << " mediump float r = 0.0; // (x*3 + y*3) / 6.0"
936 << " mediump float g = 0.0; // (y*3 + z*3) / 6.0"
937 << " mediump float b = 0.0; // (z*3 + w*3) / 6.0"
938 << " mediump float a = 1.0;"
939 << " for (int i = 0; i < 2; i++)"
941 << " for (int j = 0; j < 3; j++)"
943 << " r += s[0].b[j].b[i].y;"
944 << " g += s[i].b[j].b[0].x;"
945 << " b += s[i].b[j].b[1].x;"
946 << " a *= s[i].b[j].a;"
949 << " ${DST} = vec4(r*uf_sixth, g*uf_sixth, b*uf_sixth, a);"
953 instance.useUniform(0u, UI_ZERO);
954 instance.useUniform(1u, UI_ONE);
955 instance.useUniform(2u, UI_TWO);
956 instance.useUniform(3u, UF_TWO);
957 instance.useUniform(4u, UF_THREE);
958 instance.useUniform(5u, UF_FOUR);
959 instance.useUniform(6u, UF_HALF);
960 instance.useUniform(7u, UF_THIRD);
961 instance.useUniform(8u, UF_FOURTH);
962 instance.useUniform(9u, UF_SIXTH);
965 c.color.xyz() = (c.coords.swizzle(0, 1, 2) + c.coords.swizzle(1, 2, 3)) * 0.5f;
968 LOCAL_STRUCT_CASE(dynamic_loop_struct_array, "Struct array usage in dynamic loop",
971 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_zero; };"
972 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_one; };"
973 << "layout (std140, set = 0, binding = 2) uniform buffer2 { int ui_two; };"
974 << "layout (std140, set = 0, binding = 3) uniform buffer3 { int ui_three; };"
977 << " mediump float a;"
981 << "void main (void)"
984 << " s[0] = S(${COORDS}.x, ui_zero);"
985 << " s[1].a = ${COORDS}.y;"
986 << " s[1].b = -ui_one;"
987 << " s[2] = S(${COORDS}.z, ui_two);"
989 << " mediump float rgb[3];"
991 << " for (int i = 0; i < ui_three; i++)"
993 << " rgb[i] = s[2-i].a;"
994 << " alpha += s[i].b;"
996 << " ${DST} = vec4(rgb[0], rgb[1], rgb[2], alpha);"
1000 instance.useUniform(0u, UI_ZERO);
1001 instance.useUniform(1u, UI_ONE);
1002 instance.useUniform(2u, UI_TWO);
1003 instance.useUniform(3u, UI_THREE);
1006 c.color.xyz() = c.coords.swizzle(2, 1, 0);
1009 LOCAL_STRUCT_CASE(dynamic_loop_nested_struct_array, "Nested struct array usage in dynamic loop",
1012 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_zero; };"
1013 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_one; };"
1014 << "layout (std140, set = 0, binding = 2) uniform buffer2 { int ui_two; };"
1015 << "layout (std140, set = 0, binding = 3) uniform buffer3 { int ui_three; };"
1016 << "layout (std140, set = 0, binding = 4) uniform buffer4 { mediump float uf_two; };"
1017 << "layout (std140, set = 0, binding = 5) uniform buffer5 { mediump float uf_three; };"
1018 << "layout (std140, set = 0, binding = 6) uniform buffer6 { mediump float uf_four; };"
1019 << "layout (std140, set = 0, binding = 7) uniform buffer7 { mediump float uf_half; };"
1020 << "layout (std140, set = 0, binding = 8) uniform buffer8 { mediump float uf_third; };"
1021 << "layout (std140, set = 0, binding = 9) uniform buffer9 { mediump float uf_fourth; };"
1022 << "layout (std140, set = 0, binding = 10) uniform buffer10 { mediump float uf_sixth; };"
1025 << " mediump float a;"
1026 << " mediump vec2 b[2];"
1029 << " mediump float a;"
1034 << "void main (void)"
1038 << " s[0].a = ${COORDS}.x;"
1039 << " s[0].b[0].a = uf_half;"
1040 << " s[0].b[0].b[0] = ${COORDS}.yx;"
1041 << " s[0].b[0].b[1] = ${COORDS}.zx;"
1042 << " s[0].b[1].a = uf_third;"
1043 << " s[0].b[1].b[0] = ${COORDS}.yy;"
1044 << " s[0].b[1].b[1] = ${COORDS}.wy;"
1045 << " s[0].b[2].a = uf_fourth;"
1046 << " s[0].b[2].b[0] = ${COORDS}.zx;"
1047 << " s[0].b[2].b[1] = ${COORDS}.zy;"
1048 << " s[0].c = ui_zero;"
1050 << " s[1].a = ${COORDS}.w;"
1051 << " s[1].b[0].a = uf_two;"
1052 << " s[1].b[0].b[0] = ${COORDS}.zx;"
1053 << " s[1].b[0].b[1] = ${COORDS}.zy;"
1054 << " s[1].b[1].a = uf_three;"
1055 << " s[1].b[1].b[0] = ${COORDS}.zz;"
1056 << " s[1].b[1].b[1] = ${COORDS}.ww;"
1057 << " s[1].b[2].a = uf_four;"
1058 << " s[1].b[2].b[0] = ${COORDS}.yx;"
1059 << " s[1].b[2].b[1] = ${COORDS}.wz;"
1060 << " s[1].c = ui_one;"
1062 << " mediump float r = 0.0; // (x*3 + y*3) / 6.0"
1063 << " mediump float g = 0.0; // (y*3 + z*3) / 6.0"
1064 << " mediump float b = 0.0; // (z*3 + w*3) / 6.0"
1065 << " mediump float a = 1.0;"
1066 << " for (int i = 0; i < ui_two; i++)"
1068 << " for (int j = 0; j < ui_three; j++)"
1070 << " r += s[0].b[j].b[i].y;"
1071 << " g += s[i].b[j].b[0].x;"
1072 << " b += s[i].b[j].b[1].x;"
1073 << " a *= s[i].b[j].a;"
1076 << " ${DST} = vec4(r*uf_sixth, g*uf_sixth, b*uf_sixth, a);"
1080 instance.useUniform(0u, UI_ZERO);
1081 instance.useUniform(1u, UI_ONE);
1082 instance.useUniform(2u, UI_TWO);
1083 instance.useUniform(3u, UI_THREE);
1084 instance.useUniform(4u, UF_TWO);
1085 instance.useUniform(5u, UF_THREE);
1086 instance.useUniform(6u, UF_FOUR);
1087 instance.useUniform(7u, UF_HALF);
1088 instance.useUniform(8u, UF_THIRD);
1089 instance.useUniform(9u, UF_FOURTH);
1090 instance.useUniform(10u, UF_SIXTH);
1093 c.color.xyz() = (c.coords.swizzle(0, 1, 2) + c.coords.swizzle(1, 2, 3)) * 0.5f;
1096 LOCAL_STRUCT_CASE(basic_equal, "Basic struct equality",
1099 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_one; };"
1100 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_two; };"
1103 << " mediump float a;"
1104 << " mediump vec3 b;"
1108 << "void main (void)"
1110 << " S a = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y), 2.3), ui_one);"
1111 << " S b = S(floor(${COORDS}.x+0.5), vec3(0.0, floor(${COORDS}.y), 2.3), ui_one);"
1112 << " S c = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y+0.5), 2.3), ui_one);"
1113 << " S d = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y), 2.3), ui_two);"
1114 << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);"
1115 << " if (a == b) ${DST}.x = 1.0;"
1116 << " if (a == c) ${DST}.y = 1.0;"
1117 << " if (a == d) ${DST}.z = 1.0;"
1121 instance.useUniform(0u, UI_ONE);
1122 instance.useUniform(1u, UI_TWO);
1125 if (deFloatFloor(c.coords[0]) == deFloatFloor(c.coords[0] + 0.5f))
1127 if (deFloatFloor(c.coords[1]) == deFloatFloor(c.coords[1] + 0.5f))
1131 LOCAL_STRUCT_CASE(basic_not_equal, "Basic struct equality",
1134 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_one; };"
1135 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_two; };"
1138 << " mediump float a;"
1139 << " mediump vec3 b;"
1143 << "void main (void)"
1145 << " S a = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y), 2.3), ui_one);"
1146 << " S b = S(floor(${COORDS}.x+0.5), vec3(0.0, floor(${COORDS}.y), 2.3), ui_one);"
1147 << " S c = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y+0.5), 2.3), ui_one);"
1148 << " S d = S(floor(${COORDS}.x), vec3(0.0, floor(${COORDS}.y), 2.3), ui_two);"
1149 << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);"
1150 << " if (a != b) ${DST}.x = 1.0;"
1151 << " if (a != c) ${DST}.y = 1.0;"
1152 << " if (a != d) ${DST}.z = 1.0;"
1156 instance.useUniform(0u, UI_ONE);
1157 instance.useUniform(1u, UI_TWO);
1160 if (deFloatFloor(c.coords[0]) != deFloatFloor(c.coords[0] + 0.5f))
1162 if (deFloatFloor(c.coords[1]) != deFloatFloor(c.coords[1] + 0.5f))
1167 LOCAL_STRUCT_CASE(nested_equal, "Nested struct struct equality",
1170 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_one; };"
1171 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_two; };"
1174 << " mediump vec3 a;"
1178 << " mediump float a;"
1183 << "void main (void)"
1185 << " S a = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_one), 1);"
1186 << " S b = S(floor(${COORDS}.x+0.5), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_one), 1);"
1187 << " S c = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y+0.5), 2.3), ui_one), 1);"
1188 << " S d = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_two), 1);"
1189 << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);"
1190 << " if (a == b) ${DST}.x = 1.0;"
1191 << " if (a == c) ${DST}.y = 1.0;"
1192 << " if (a == d) ${DST}.z = 1.0;"
1196 instance.useUniform(0u, UI_ONE);
1197 instance.useUniform(1u, UI_TWO);
1200 if (deFloatFloor(c.coords[0]) == deFloatFloor(c.coords[0] + 0.5f))
1202 if (deFloatFloor(c.coords[1]) == deFloatFloor(c.coords[1] + 0.5f))
1206 LOCAL_STRUCT_CASE(nested_not_equal, "Nested struct struct equality",
1209 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_one; };"
1210 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_two; };"
1213 << " mediump vec3 a;"
1217 << " mediump float a;"
1222 << "void main (void)"
1224 << " S a = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_one), 1);"
1225 << " S b = S(floor(${COORDS}.x+0.5), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_one), 1);"
1226 << " S c = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y+0.5), 2.3), ui_one), 1);"
1227 << " S d = S(floor(${COORDS}.x), T(vec3(0.0, floor(${COORDS}.y), 2.3), ui_two), 1);"
1228 << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);"
1229 << " if (a != b) ${DST}.x = 1.0;"
1230 << " if (a != c) ${DST}.y = 1.0;"
1231 << " if (a != d) ${DST}.z = 1.0;"
1235 instance.useUniform(0u, UI_ONE);
1236 instance.useUniform(1u, UI_TWO);
1239 if (deFloatFloor(c.coords[0]) != deFloatFloor(c.coords[0] + 0.5f))
1241 if (deFloatFloor(c.coords[1]) != deFloatFloor(c.coords[1] + 0.5f))
1247 class UniformStructTests : public tcu::TestCaseGroup
1250 UniformStructTests (tcu::TestContext& testCtx)
1251 : TestCaseGroup(testCtx, "uniform", "Uniform structs")
1255 ~UniformStructTests (void)
1259 virtual void init (void);
1262 void UniformStructTests::init (void)
1264 #define UNIFORM_STRUCT_CASE(NAME, DESCRIPTION, SHADER_SRC, SET_UNIFORMS_BODY, EVAL_FUNC_BODY) \
1266 struct SetUniforms_##NAME { static void setUniforms (ShaderRenderCaseInstance& instance, const tcu::Vec4& constCoords) SET_UNIFORMS_BODY }; \
1267 struct Eval_##NAME { static void eval (ShaderEvalContext& c) EVAL_FUNC_BODY }; \
1268 addChild(createStructCase(m_testCtx, #NAME "_vertex", DESCRIPTION, true, Eval_##NAME::eval, SetUniforms_##NAME::setUniforms, SHADER_SRC).release()); \
1269 addChild(createStructCase(m_testCtx, #NAME "_fragment", DESCRIPTION, false, Eval_##NAME::eval, SetUniforms_##NAME::setUniforms, SHADER_SRC).release()); \
1270 } while (deGetFalse())
1272 UNIFORM_STRUCT_CASE(basic, "Basic struct usage",
1275 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_one; };"
1278 << " mediump float a;"
1279 << " mediump vec3 b;"
1282 << "layout (std140, set = 0, binding = 1) uniform buffer1 { S s; };"
1284 << "void main (void)"
1286 << " ${DST} = vec4(s.a, s.b.x, s.b.y, s.c);"
1290 instance.useUniform(0u, UI_ONE);
1300 s.a = constCoords.x();
1301 s.b = constCoords.swizzle(1, 2, 3);
1303 instance.addUniform(1u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, sizeof(S), &s);
1306 c.color.xyz() = c.constCoords.swizzle(0, 1, 2);
1309 UNIFORM_STRUCT_CASE(nested, "Nested struct",
1312 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_zero; };"
1313 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_one; };"
1317 << " mediump vec2 b;"
1320 << " mediump float a;"
1324 << "layout (std140, set = 0, binding = 2) uniform buffer2 { S s; };"
1326 << "void main (void)"
1328 << " ${DST} = vec4(s.a, s.b.b, s.b.a + s.c);"
1332 instance.useUniform(0u, UI_ZERO);
1333 instance.useUniform(1u, UI_ONE);
1350 s.a = constCoords.x();
1352 s.b.b = constCoords.swizzle(1, 2);
1354 instance.addUniform(2u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,sizeof(S), &s);
1357 c.color.xyz() = c.constCoords.swizzle(0, 1, 2);
1360 UNIFORM_STRUCT_CASE(array_member, "Struct with array member",
1363 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_one; };"
1366 << " mediump float a;"
1367 << " mediump float b[3];"
1370 << "layout (std140, set = 0, binding = 1) uniform buffer1 { S s; };"
1372 << "void main (void)"
1374 << " ${DST} = vec4(s.a, s.b[0], s.b[1], s.c);"
1378 instance.useUniform(0u, UI_ONE);
1380 struct paddedFloat {
1392 s.a.value = constCoords.w();
1393 s.b[0].value = constCoords.z();
1394 s.b[1].value = constCoords.y();
1395 s.b[2].value = constCoords.x();
1397 instance.addUniform(1u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,sizeof(S), &s);
1400 c.color.xyz() = c.constCoords.swizzle(3, 2, 1);
1403 UNIFORM_STRUCT_CASE(array_member_dynamic_index, "Struct with array member, dynamic indexing",
1406 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_zero; };"
1407 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_one; };"
1408 << "layout (std140, set = 0, binding = 2) uniform buffer2 { int ui_two; };"
1411 << " mediump float a;"
1412 << " mediump float b[3];"
1415 << "layout (std140, set = 0, binding = 3) uniform buffer3 { S s; };"
1417 << "void main (void)"
1419 << " ${DST} = vec4(s.b[ui_one], s.b[ui_zero], s.b[ui_two], s.c);"
1423 instance.useUniform(0u, UI_ZERO);
1424 instance.useUniform(1u, UI_ONE);
1425 instance.useUniform(2u, UI_TWO);
1427 struct paddedFloat {
1439 s.a.value = constCoords.w();
1440 s.b[0].value = constCoords.z();
1441 s.b[1].value = constCoords.y();
1442 s.b[2].value = constCoords.x();
1444 instance.addUniform(3u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, sizeof(S), &s);
1447 c.color.xyz() = c.constCoords.swizzle(1, 2, 0);
1450 UNIFORM_STRUCT_CASE(struct_array, "Struct array",
1453 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_zero; };"
1454 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_one; };"
1455 << "layout (std140, set = 0, binding = 2) uniform buffer2 { int ui_two; };"
1458 << " mediump float a;"
1459 << " mediump int b;"
1461 << "layout (std140, set = 0, binding = 3) uniform buffer3 { S s[3]; };"
1463 << "void main (void)"
1465 << " ${DST} = vec4(s[2].a, s[1].a, s[0].a, s[2].b - s[1].b + s[0].b);"
1469 instance.useUniform(0u, UI_ZERO);
1470 instance.useUniform(1u, UI_ONE);
1471 instance.useUniform(2u, UI_TWO);
1480 s[0].a = constCoords.x();
1482 s[1].a = constCoords.y();
1484 s[2].a = constCoords.z();
1486 instance.addUniform(3u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 3 * sizeof(S), s);
1489 c.color.xyz() = c.constCoords.swizzle(2, 1, 0);
1492 UNIFORM_STRUCT_CASE(struct_array_dynamic_index, "Struct array with dynamic indexing",
1495 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_zero; };"
1496 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_one; };"
1497 << "layout (std140, set = 0, binding = 2) uniform buffer2 { int ui_two; };"
1500 << " mediump float a;"
1501 << " mediump int b;"
1503 << "layout (std140, set = 0, binding = 3) uniform buffer3 { S s[3]; };"
1505 << "void main (void)"
1507 << " ${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);"
1511 instance.useUniform(0u, UI_ZERO);
1512 instance.useUniform(1u, UI_ONE);
1513 instance.useUniform(2u, UI_TWO);
1522 s[0].a = constCoords.x();
1524 s[1].a = constCoords.y();
1526 s[2].a = constCoords.z();
1528 instance.addUniform(3u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 3 * sizeof(S), s);
1531 c.color.xyz() = c.constCoords.swizzle(2, 1, 0);
1534 UNIFORM_STRUCT_CASE(nested_struct_array, "Nested struct array",
1538 << " mediump float a;"
1539 << " mediump vec2 b[2];"
1542 << " mediump float a;"
1546 << "layout (std140, set = 0, binding = 0) uniform buffer0 { S s[2]; };"
1548 << "void main (void)"
1550 << " 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"
1551 << " mediump float g = s[1].b[0].b[0].y * s[0].b[2].a * s[1].b[2].a; // x * 0.25 * 4"
1552 << " 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"
1553 << " mediump float a = float(s[0].c) + s[1].b[2].a - s[1].b[1].a; // 0 + 4.0 - 3.0"
1554 << " ${DST} = vec4(r, g, b, a);"
1574 s[0].a = constCoords.x();
1576 s[0].b[0].b[0] = constCoords.swizzle(0,1,0,0);
1577 s[0].b[0].b[1] = constCoords.swizzle(2,3,0,0);
1578 s[0].b[1].a = 1.0f / 3.0f;
1579 s[0].b[1].b[0] = constCoords.swizzle(2,3,0,0);
1580 s[0].b[1].b[1] = constCoords.swizzle(0,1,0,0);
1581 s[0].b[2].a = 1.0f / 4.0f;
1582 s[0].b[2].b[0] = constCoords.swizzle(0,2,0,0);
1583 s[0].b[2].b[1] = constCoords.swizzle(1,3,0,0);
1586 s[1].a = constCoords.w();
1588 s[1].b[0].b[0] = constCoords.swizzle(0,0,0,0);
1589 s[1].b[0].b[1] = constCoords.swizzle(1,1,0,0);
1591 s[1].b[1].b[0] = constCoords.swizzle(2,2,0,0);
1592 s[1].b[1].b[1] = constCoords.swizzle(3,3,0,0);
1594 s[1].b[2].b[0] = constCoords.swizzle(1,0,0,0);
1595 s[1].b[2].b[1] = constCoords.swizzle(3,2,0,0);
1598 instance.addUniform(0u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2 * sizeof(S), s);
1601 c.color.xyz() = c.constCoords.swizzle(2, 0, 3);
1604 UNIFORM_STRUCT_CASE(nested_struct_array_dynamic_index, "Nested struct array with dynamic indexing",
1607 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_zero; };"
1608 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_one; };"
1609 << "layout (std140, set = 0, binding = 2) uniform buffer2 { int ui_two; };"
1612 << " mediump float a;"
1613 << " mediump vec2 b[2];"
1616 << " mediump float a;"
1620 << "layout (set = 0, binding = 3) uniform buffer3 { S s[2]; };"
1622 << "void main (void)"
1624 << " 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"
1625 << " 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"
1626 << " 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"
1627 << " 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"
1628 << " ${DST} = vec4(r, g, b, a);"
1647 s[0].a = constCoords.x();
1649 s[0].b[0].b[0] = constCoords.swizzle(0,1,0,0);
1650 s[0].b[0].b[1] = constCoords.swizzle(2,3,0,0);
1651 s[0].b[1].a = 1.0f / 3.0f;
1652 s[0].b[1].b[0] = constCoords.swizzle(2,3,0,0);
1653 s[0].b[1].b[1] = constCoords.swizzle(0,1,0,0);
1654 s[0].b[2].a = 1.0f / 4.0f;
1655 s[0].b[2].b[0] = constCoords.swizzle(0,2,0,0);
1656 s[0].b[2].b[1] = constCoords.swizzle(1,3,0,0);
1659 s[1].a = constCoords.w();
1661 s[1].b[0].b[0] = constCoords.swizzle(0,0,0,0);
1662 s[1].b[0].b[1] = constCoords.swizzle(1,1,0,0);
1664 s[1].b[1].b[0] = constCoords.swizzle(2,2,0,0);
1665 s[1].b[1].b[1] = constCoords.swizzle(3,3,0,0);
1667 s[1].b[2].b[0] = constCoords.swizzle(1,0,0,0);
1668 s[1].b[2].b[1] = constCoords.swizzle(3,2,0,0);
1671 instance.useUniform(0u, UI_ZERO);
1672 instance.useUniform(1u, UI_ONE);
1673 instance.useUniform(2u, UI_TWO);
1674 instance.addUniform(3u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2 * sizeof(S), s);
1677 c.color.xyz() = c.constCoords.swizzle(2, 0, 3);
1679 UNIFORM_STRUCT_CASE(loop_struct_array, "Struct array usage in loop",
1682 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_zero; };"
1683 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_one; };"
1684 << "layout (std140, set = 0, binding = 2) uniform buffer2 { int ui_two; };"
1687 << " mediump float a;"
1688 << " mediump int b;"
1690 << "layout (std140, set = 0, binding = 3) uniform buffer3 { S s[3]; };"
1692 << "void main (void)"
1694 << " mediump float rgb[3];"
1695 << " int alpha = 0;"
1696 << " for (int i = 0; i < 3; i++)"
1698 << " rgb[i] = s[2-i].a;"
1699 << " alpha += s[i].b;"
1701 << " ${DST} = vec4(rgb[0], rgb[1], rgb[2], alpha);"
1705 instance.useUniform(0u, UI_ZERO);
1706 instance.useUniform(1u, UI_ONE);
1707 instance.useUniform(2u, UI_TWO);
1716 s[0].a = constCoords.x();
1718 s[1].a = constCoords.y();
1720 s[2].a = constCoords.z();
1722 instance.addUniform(3u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 3u * sizeof(S), s);
1725 c.color.xyz() = c.constCoords.swizzle(2, 1, 0);
1728 UNIFORM_STRUCT_CASE(loop_nested_struct_array, "Nested struct array usage in loop",
1731 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_zero; };"
1732 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_one; };"
1733 << "layout (std140, set = 0, binding = 2) uniform buffer2 { int ui_two; };"
1734 << "layout (std140, set = 0, binding = 3) uniform buffer3 { mediump float uf_two; };"
1735 << "layout (std140, set = 0, binding = 4) uniform buffer4 { mediump float uf_three; };"
1736 << "layout (std140, set = 0, binding = 5) uniform buffer5 { mediump float uf_four; };"
1737 << "layout (std140, set = 0, binding = 6) uniform buffer6 { mediump float uf_half; };"
1738 << "layout (std140, set = 0, binding = 7) uniform buffer7 { mediump float uf_third; };"
1739 << "layout (std140, set = 0, binding = 8) uniform buffer8 { mediump float uf_fourth; };"
1740 << "layout (std140, set = 0, binding = 9) uniform buffer9 { mediump float uf_sixth; };"
1743 << " mediump float a;"
1744 << " mediump vec2 b[2];"
1747 << " mediump float a;"
1751 << "layout (std140, set = 0, binding = 10) uniform buffer10 { S s[2]; };"
1753 << "void main (void)"
1755 << " mediump float r = 0.0; // (x*3 + y*3) / 6.0"
1756 << " mediump float g = 0.0; // (y*3 + z*3) / 6.0"
1757 << " mediump float b = 0.0; // (z*3 + w*3) / 6.0"
1758 << " mediump float a = 1.0;"
1759 << " for (int i = 0; i < 2; i++)"
1761 << " for (int j = 0; j < 3; j++)"
1763 << " r += s[0].b[j].b[i].y;"
1764 << " g += s[i].b[j].b[0].x;"
1765 << " b += s[i].b[j].b[1].x;"
1766 << " a *= s[i].b[j].a;"
1769 << " ${DST} = vec4(r*uf_sixth, g*uf_sixth, b*uf_sixth, a);"
1773 instance.useUniform(0u, UI_ZERO);
1774 instance.useUniform(1u, UI_ONE);
1775 instance.useUniform(2u, UI_TWO);
1776 instance.useUniform(3u, UF_TWO);
1777 instance.useUniform(4u, UF_THREE);
1778 instance.useUniform(5u, UF_FOUR);
1779 instance.useUniform(6u, UF_HALF);
1780 instance.useUniform(7u, UF_THIRD);
1781 instance.useUniform(8u, UF_FOURTH);
1782 instance.useUniform(9u, UF_SIXTH);
1799 s[0].a = constCoords.x();
1801 s[0].b[0].b[0] = constCoords.swizzle(1,0,0,0);
1802 s[0].b[0].b[1] = constCoords.swizzle(2,0,0,0);
1803 s[0].b[1].a = 1.0f / 3.0f;
1804 s[0].b[1].b[0] = constCoords.swizzle(1,1,0,0);
1805 s[0].b[1].b[1] = constCoords.swizzle(3,1,0,0);
1806 s[0].b[2].a = 1.0f / 4.0f;
1807 s[0].b[2].b[0] = constCoords.swizzle(2,1,0,0);
1808 s[0].b[2].b[1] = constCoords.swizzle(2,1,0,0);
1811 s[1].a = constCoords.w();
1813 s[1].b[0].b[0] = constCoords.swizzle(2,0,0,0);
1814 s[1].b[0].b[1] = constCoords.swizzle(2,1,0,0);
1816 s[1].b[1].b[0] = constCoords.swizzle(2,2,0,0);
1817 s[1].b[1].b[1] = constCoords.swizzle(3,3,0,0);
1819 s[1].b[2].b[0] = constCoords.swizzle(1,0,0,0);
1820 s[1].b[2].b[1] = constCoords.swizzle(3,2,0,0);
1823 instance.addUniform(10u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2 * sizeof(S), s);
1827 c.color.xyz() = (c.constCoords.swizzle(0, 1, 2) + c.constCoords.swizzle(1, 2, 3)) * 0.5f;
1830 UNIFORM_STRUCT_CASE(dynamic_loop_struct_array, "Struct array usage in dynamic loop",
1833 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_zero; };"
1834 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_one; };"
1835 << "layout (std140, set = 0, binding = 2) uniform buffer2 { int ui_two; };"
1836 << "layout (std140, set = 0, binding = 3) uniform buffer3 { int ui_three; };"
1839 << " mediump float a;"
1840 << " mediump int b;"
1842 << "layout (std140, set = 0, binding = 4) uniform buffer4 { S s[3]; };"
1844 << "void main (void)"
1846 << " mediump float rgb[3];"
1847 << " int alpha = 0;"
1848 << " for (int i = 0; i < ui_three; i++)"
1850 << " rgb[i] = s[2-i].a;"
1851 << " alpha += s[i].b;"
1853 << " ${DST} = vec4(rgb[0], rgb[1], rgb[2], alpha);"
1857 instance.useUniform(0u, UI_ZERO);
1858 instance.useUniform(1u, UI_ONE);
1859 instance.useUniform(2u, UI_TWO);
1860 instance.useUniform(3u, UI_THREE);
1869 s[0].a = constCoords.x();
1871 s[1].a = constCoords.y();
1873 s[2].a = constCoords.z();
1875 instance.addUniform(4u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 3u * sizeof(S), s);
1879 c.color.xyz() = c.constCoords.swizzle(2, 1, 0);
1882 UNIFORM_STRUCT_CASE(dynamic_loop_nested_struct_array, "Nested struct array usage in dynamic loop",
1885 << "layout (std140, set = 0, binding = 0) uniform buffer0 { int ui_zero; };"
1886 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_one; };"
1887 << "layout (std140, set = 0, binding = 2) uniform buffer2 { int ui_two; };"
1888 << "layout (std140, set = 0, binding = 3) uniform buffer3 { int ui_three; };"
1889 << "layout (std140, set = 0, binding = 4) uniform buffer4 { mediump float uf_two; };"
1890 << "layout (std140, set = 0, binding = 5) uniform buffer5 { mediump float uf_three; };"
1891 << "layout (std140, set = 0, binding = 6) uniform buffer6 { mediump float uf_four; };"
1892 << "layout (std140, set = 0, binding = 7) uniform buffer7 { mediump float uf_half; };"
1893 << "layout (std140, set = 0, binding = 8) uniform buffer8 { mediump float uf_third; };"
1894 << "layout (std140, set = 0, binding = 9) uniform buffer9 { mediump float uf_fourth; };"
1895 << "layout (std140, set = 0, binding = 10) uniform buffer10 { mediump float uf_sixth; };"
1898 << " mediump float a;"
1899 << " mediump vec2 b[2];"
1902 << " mediump float a;"
1906 << "layout (std140, set = 0, binding = 10) uniform buffer11 { S s[2]; };"
1908 << "void main (void)"
1910 << " mediump float r = 0.0; // (x*3 + y*3) / 6.0"
1911 << " mediump float g = 0.0; // (y*3 + z*3) / 6.0"
1912 << " mediump float b = 0.0; // (z*3 + w*3) / 6.0"
1913 << " mediump float a = 1.0;"
1914 << " for (int i = 0; i < ui_two; i++)"
1916 << " for (int j = 0; j < ui_three; j++)"
1918 << " r += s[0].b[j].b[i].y;"
1919 << " g += s[i].b[j].b[0].x;"
1920 << " b += s[i].b[j].b[1].x;"
1921 << " a *= s[i].b[j].a;"
1924 << " ${DST} = vec4(r*uf_sixth, g*uf_sixth, b*uf_sixth, a);"
1928 instance.useUniform(0u, UI_ZERO);
1929 instance.useUniform(1u, UI_ONE);
1930 instance.useUniform(2u, UI_TWO);
1931 instance.useUniform(3u, UI_THREE);
1932 instance.useUniform(4u, UF_TWO);
1933 instance.useUniform(5u, UF_THREE);
1934 instance.useUniform(6u, UF_FOUR);
1935 instance.useUniform(7u, UF_HALF);
1936 instance.useUniform(8u, UF_THIRD);
1937 instance.useUniform(9u, UF_FOURTH);
1938 instance.useUniform(10u, UF_SIXTH);
1955 s[0].a = constCoords.x();
1957 s[0].b[0].b[0] = constCoords.swizzle(1,0,0,0);
1958 s[0].b[0].b[1] = constCoords.swizzle(2,0,0,0);
1959 s[0].b[1].a = 1.0f / 3.0f;
1960 s[0].b[1].b[0] = constCoords.swizzle(1,1,0,0);
1961 s[0].b[1].b[1] = constCoords.swizzle(3,1,0,0);
1962 s[0].b[2].a = 1.0f / 4.0f;
1963 s[0].b[2].b[0] = constCoords.swizzle(2,1,0,0);
1964 s[0].b[2].b[1] = constCoords.swizzle(2,1,0,0);
1967 s[1].a = constCoords.w();
1969 s[1].b[0].b[0] = constCoords.swizzle(2,0,0,0);
1970 s[1].b[0].b[1] = constCoords.swizzle(2,1,0,0);
1972 s[1].b[1].b[0] = constCoords.swizzle(2,2,0,0);
1973 s[1].b[1].b[1] = constCoords.swizzle(3,3,0,0);
1975 s[1].b[2].b[0] = constCoords.swizzle(1,0,0,0);
1976 s[1].b[2].b[1] = constCoords.swizzle(3,2,0,0);
1979 instance.addUniform(11u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2 * sizeof(S), s);
1983 c.color.xyz() = (c.constCoords.swizzle(0, 1, 2) + c.constCoords.swizzle(1, 2, 3)) * 0.5f;
1986 UNIFORM_STRUCT_CASE(equal, "Struct equality",
1989 << "layout (std140, set = 0, binding = 0) uniform buffer0 { mediump float uf_one; };"
1990 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_two; };"
1993 << " mediump float a;"
1994 << " mediump vec3 b;"
1997 << "layout (std140, set = 0, binding = 2) uniform buffer2 { S a; };"
1998 << "layout (std140, set = 0, binding = 3) uniform buffer3 { S b; };"
1999 << "layout (std140, set = 0, binding = 4) uniform buffer4 { S c; };"
2001 << "void main (void)"
2003 << " S d = S(uf_one, vec3(0.0, floor(${COORDS}.y+1.0), 2.0), ui_two);"
2004 << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);"
2005 << " if (a == b) ${DST}.x = 1.0;"
2006 << " if (a == c) ${DST}.y = 1.0;"
2007 << " if (a == d) ${DST}.z = 1.0;"
2011 DE_UNREF(constCoords);
2012 instance.useUniform(0u, UF_ONE);
2013 instance.useUniform(1u, UI_TWO);
2024 sa.b = tcu::Vec3(0.0f, 1.0f, 2.0f);
2026 instance.addUniform(2u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, sizeof(S), &sa);
2030 sb.b = tcu::Vec3(0.0f, 1.0f, 2.0f);
2032 instance.addUniform(3u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, sizeof(S), &sb);
2036 sc.b = tcu::Vec3(0.0f, 1.1f, 2.0f);
2038 instance.addUniform(4u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, sizeof(S), &sc);
2041 c.color.xy() = tcu::Vec2(1.0f, 0.0f);
2042 if (deFloatFloor(c.coords[1] + 1.0f) == deFloatFloor(1.1f))
2046 UNIFORM_STRUCT_CASE(not_equal, "Struct equality",
2049 << "layout (std140, set = 0, binding = 0) uniform buffer0 { mediump float uf_one; };"
2050 << "layout (std140, set = 0, binding = 1) uniform buffer1 { int ui_two; };"
2053 << " mediump float a;"
2054 << " mediump vec3 b;"
2057 << "layout (std140, set = 0, binding = 2) uniform buffer2 { S a; };"
2058 << "layout (std140, set = 0, binding = 3) uniform buffer3 { S b; };"
2059 << "layout (std140, set = 0, binding = 4) uniform buffer4 { S c; };"
2061 << "void main (void)"
2063 << " S d = S(uf_one, vec3(0.0, floor(${COORDS}.y+1.0), 2.0), ui_two);"
2064 << " ${DST} = vec4(0.0, 0.0, 0.0, 1.0);"
2065 << " if (a != b) ${DST}.x = 1.0;"
2066 << " if (a != c) ${DST}.y = 1.0;"
2067 << " if (a != d) ${DST}.z = 1.0;"
2071 DE_UNREF(constCoords);
2072 instance.useUniform(0u, UF_ONE);
2073 instance.useUniform(1u, UI_TWO);
2084 sa.b = tcu::Vec3(0.0f, 1.0f, 2.0f);
2086 instance.addUniform(2u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, sizeof(S), &sa);
2090 sb.b = tcu::Vec3(0.0f, 1.0f, 2.0f);
2092 instance.addUniform(3u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, sizeof(S), &sb);
2096 sc.b = tcu::Vec3(0.0f, 1.1f, 2.0f);
2098 instance.addUniform(4u, vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, sizeof(S), &sc);
2101 c.color.xy() = tcu::Vec2(0.0f, 1.0f);
2102 if (deFloatFloor(c.coords[1] + 1.0f) != deFloatFloor(1.1f))
2107 class ShaderStructTests : public tcu::TestCaseGroup
2110 ShaderStructTests (tcu::TestContext& context);
2111 virtual ~ShaderStructTests (void);
2113 virtual void init (void);
2116 ShaderStructTests (const ShaderStructTests&); // not allowed!
2117 ShaderStructTests& operator= (const ShaderStructTests&); // not allowed!
2120 ShaderStructTests::ShaderStructTests (tcu::TestContext& testCtx)
2121 : TestCaseGroup(testCtx, "struct", "Struct Tests")
2125 ShaderStructTests::~ShaderStructTests (void)
2129 void ShaderStructTests::init (void)
2131 addChild(new LocalStructTests(m_testCtx));
2132 addChild(new UniformStructTests(m_testCtx));
2137 tcu::TestCaseGroup* createStructTests (tcu::TestContext& testCtx)
2139 return new ShaderStructTests(testCtx);