dEQP-VK.renderpass: Set IMAGE_USAGE_TRANSFER_SRC_BIT when needed
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / shaderrender / vktShaderRenderReturnTests.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2015 The Khronos Group Inc.
6  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7  *
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:
15  *
16  * The above copyright notice(s) and this permission notice shall be included
17  * in all copies or substantial portions of the Materials.
18  *
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.
22  *
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.
30  *
31  *//*!
32  * \file
33  * \brief Shader return statement tests.
34  *//*--------------------------------------------------------------------*/
35
36 #include "vktShaderRenderReturnTests.hpp"
37 #include "vktShaderRender.hpp"
38 #include "tcuStringTemplate.hpp"
39
40 #include <map>
41 #include <string>
42
43 namespace vkt
44 {
45 namespace sr
46 {
47 namespace
48 {
49
50 enum ReturnMode
51 {
52         RETURNMODE_ALWAYS = 0,
53         RETURNMODE_NEVER,
54         RETURNMODE_DYNAMIC,
55
56         RETURNMODE_LAST
57 };
58
59 // Evaluation functions
60 inline void evalReturnAlways    (ShaderEvalContext& c) { c.color.xyz() = c.coords.swizzle(0,1,2); }
61 inline void evalReturnNever             (ShaderEvalContext& c) { c.color.xyz() = c.coords.swizzle(3,2,1); }
62 inline void evalReturnDynamic   (ShaderEvalContext& c) { c.color.xyz() = (c.coords.x()+c.coords.y() >= 0.0f) ? c.coords.swizzle(0,1,2) : c.coords.swizzle(3,2,1); }
63
64 static ShaderEvalFunc getEvalFunc (ReturnMode mode)
65 {
66         switch (mode)
67         {
68                 case RETURNMODE_ALWAYS:         return evalReturnAlways;
69                 case RETURNMODE_NEVER:          return evalReturnNever;
70                 case RETURNMODE_DYNAMIC:        return evalReturnDynamic;
71                 default:
72                         DE_ASSERT(DE_FALSE);
73                         return (ShaderEvalFunc)DE_NULL;
74         }
75 }
76
77 class ShaderReturnCase : public ShaderRenderCase
78 {
79 public:
80                                                                 ShaderReturnCase                (tcu::TestContext&                      testCtx,
81                                                                                                                  const std::string&                     name,
82                                                                                                                  const std::string&                     description,
83                                                                                                                  bool                                           isVertexCase,
84                                                                                                                  const std::string&                     shaderSource,
85                                                                                                                  const ShaderEvalFunc           evalFunc,
86                                                                                                                  const UniformSetup*            uniformFunc);
87         virtual                                         ~ShaderReturnCase               (void);
88 };
89
90 ShaderReturnCase::ShaderReturnCase (tcu::TestContext&                   testCtx,
91                                                                         const std::string&                      name,
92                                                                         const std::string&                      description,
93                                                                         bool                                            isVertexCase,
94                                                                         const std::string&                      shaderSource,
95                                                                         const ShaderEvalFunc            evalFunc,
96                                                                         const UniformSetup*                     uniformFunc)
97         : ShaderRenderCase(testCtx, name, description, isVertexCase, evalFunc, uniformFunc, DE_NULL)
98 {
99         if (isVertexCase)
100         {
101                 m_vertShaderSource = shaderSource;
102                 m_fragShaderSource =
103                         "#version 140\n"
104                         "#extension GL_ARB_separate_shader_objects : enable\n"
105                         "#extension GL_ARB_shading_language_420pack : enable\n"
106                         "layout(location = 0) in mediump vec4 v_color;\n"
107                         "layout(location = 0) out mediump vec4 o_color;\n\n"
108                         "void main (void)\n"
109                         "{\n"
110                         "    o_color = v_color;\n"
111                         "}\n";
112         }
113         else
114         {
115                 m_fragShaderSource = shaderSource;
116                 m_vertShaderSource =
117                         "#version 140\n"
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_coords;\n\n"
123                         "void main (void)\n"
124                         "{\n"
125                         "    gl_Position = a_position;\n"
126                         "    v_coords = a_coords;\n"
127                         "}\n";
128         }
129 }
130
131 ShaderReturnCase::~ShaderReturnCase (void)
132 {
133 }
134
135 class ReturnTestUniformSetup : public UniformSetup
136 {
137 public:
138                                                                 ReturnTestUniformSetup  (const BaseUniformType uniformType)
139                                                                         : m_uniformType(uniformType)
140                                                                 {}
141         virtual void                            setup                                   (ShaderRenderCaseInstance& instance, const tcu::Vec4&) const
142                                                                 {
143                                                                         instance.useUniform(0u, m_uniformType);
144                                                                 }
145
146 private:
147         const BaseUniformType           m_uniformType;
148 };
149
150 // Test case builders.
151
152 de::MovePtr<ShaderReturnCase> makeConditionalReturnInFuncCase (tcu::TestContext& context, const std::string& name, const std::string& description, ReturnMode returnMode, bool isVertex)
153 {
154         tcu::StringTemplate tmpl(
155                 "#version 140\n"
156                 "#extension GL_ARB_separate_shader_objects : enable\n"
157                 "#extension GL_ARB_shading_language_420pack : enable\n"
158                 "layout(location = ${COORDLOC}) in ${COORDPREC} vec4 ${COORDS};\n"
159                 "${EXTRADECL}\n"
160                 "${COORDPREC} vec4 getColor (void)\n"
161                 "{\n"
162                 "    if (${RETURNCOND})\n"
163                 "        return vec4(${COORDS}.xyz, 1.0);\n"
164                 "    return vec4(${COORDS}.wzy, 1.0);\n"
165                 "}\n\n"
166                 "void main (void)\n"
167                 "{\n"
168                 "${POSITIONWRITE}"
169                 "    ${OUTPUT} = getColor();\n"
170                 "}\n");
171
172         const char* coords = isVertex ? "a_coords" : "v_coords";
173
174         std::map<std::string, std::string> params;
175
176         params["COORDLOC"]              = isVertex ? "1"                        : "0";
177         params["COORDPREC"]             = isVertex ? "highp"            : "mediump";
178         params["OUTPUT"]                = isVertex ? "v_color"          : "o_color";
179         params["COORDS"]                = coords;
180         params["EXTRADECL"]             = isVertex ? "layout(location = 0) in highp vec4 a_position;\nlayout(location = 0) out mediump vec4 v_color;\n" : "layout(location = 0) out mediump vec4 o_color;\n";
181         params["POSITIONWRITE"] = isVertex ? "    gl_Position = a_position;\n" : "";
182
183         switch (returnMode)
184         {
185                 case RETURNMODE_ALWAYS:         params["RETURNCOND"] = "true";                                                                                  break;
186                 case RETURNMODE_NEVER:          params["RETURNCOND"] = "false";                                                                                 break;
187                 case RETURNMODE_DYNAMIC:        params["RETURNCOND"] = std::string(coords) + ".x+" + coords + ".y >= 0.0";      break;
188                 default:                                        DE_ASSERT(DE_FALSE);
189         }
190
191         return de::MovePtr<ShaderReturnCase>(new ShaderReturnCase(context, name, description, isVertex, tmpl.specialize(params), getEvalFunc(returnMode), DE_NULL));
192 }
193
194 de::MovePtr<ShaderReturnCase> makeOutputWriteReturnCase (tcu::TestContext& context, const std::string& name, const std::string& description, bool inFunction, ReturnMode returnMode, bool isVertex)
195 {
196         tcu::StringTemplate tmpl(
197                 inFunction
198                 ?
199                         "#version 140\n"
200                         "#extension GL_ARB_separate_shader_objects : enable\n"
201                         "#extension GL_ARB_shading_language_420pack : enable\n"
202                         "layout(location = ${COORDLOC}) in ${COORDPREC} vec4 ${COORDS};\n"
203                         "${EXTRADECL}\n"
204                         "void myfunc (void)\n"
205                         "{\n"
206                         "    ${OUTPUT} = vec4(${COORDS}.xyz, 1.0);\n"
207                         "    if (${RETURNCOND})\n"
208                         "        return;\n"
209                         "    ${OUTPUT} = vec4(${COORDS}.wzy, 1.0);\n"
210                         "}\n\n"
211                         "void main (void)\n"
212                         "{\n"
213                         "${POSITIONWRITE}"
214                         "    myfunc();\n"
215                         "}\n"
216                 :
217                         "#version 140\n"
218                         "#extension GL_ARB_separate_shader_objects : enable\n"
219                         "#extension GL_ARB_shading_language_420pack : enable\n"
220                         "layout(location = ${COORDLOC}) in ${COORDPREC} vec4 ${COORDS};\n"
221                         "${EXTRADECL}\n"
222                         "void main ()\n"
223                         "{\n"
224                         "${POSITIONWRITE}"
225                         "    ${OUTPUT} = vec4(${COORDS}.xyz, 1.0);\n"
226                         "    if (${RETURNCOND})\n"
227                         "        return;\n"
228                         "    ${OUTPUT} = vec4(${COORDS}.wzy, 1.0);\n"
229                         "}\n");
230
231         const char* coords = isVertex ? "a_coords" : "v_coords";
232
233         std::map<std::string, std::string> params;
234
235         params["COORDLOC"]              = isVertex ? "1"                        : "0";
236         params["COORDPREC"]             = isVertex ? "highp"            : "mediump";
237         params["COORDS"]                = coords;
238         params["OUTPUT"]                = isVertex ? "v_color"          : "o_color";
239         params["EXTRADECL"]             = isVertex ? "layout(location = 0) in highp vec4 a_position;\nlayout(location = 0) out mediump vec4 v_color;\n" : "layout(location = 0) out mediump vec4 o_color;\n";
240         params["POSITIONWRITE"] = isVertex ? "    gl_Position = a_position;\n" : "";
241
242         switch (returnMode)
243         {
244                 case RETURNMODE_ALWAYS:         params["RETURNCOND"] = "true";                                                                                  break;
245                 case RETURNMODE_NEVER:          params["RETURNCOND"] = "false";                                                                                 break;
246                 case RETURNMODE_DYNAMIC:        params["RETURNCOND"] = std::string(coords) + ".x+" + coords + ".y >= 0.0";      break;
247                 default:                                        DE_ASSERT(DE_FALSE);
248         }
249
250         return de::MovePtr<ShaderReturnCase>(new ShaderReturnCase(context, name, description, isVertex, tmpl.specialize(params), getEvalFunc(returnMode), DE_NULL));
251 }
252
253 de::MovePtr<ShaderReturnCase> makeReturnInLoopCase (tcu::TestContext& context, const std::string& name, const std::string& description, bool isDynamicLoop, ReturnMode returnMode, bool isVertex)
254 {
255         tcu::StringTemplate tmpl(
256                 "#version 140\n"
257                 "#extension GL_ARB_separate_shader_objects : enable\n"
258                 "#extension GL_ARB_shading_language_420pack : enable\n"
259                 "layout(location = ${COORDLOC}) in ${COORDPREC} vec4 ${COORDS};\n"
260                 "layout(binding = 0, std140) uniform something { mediump int ui_one; };\n"
261                 "${EXTRADECL}\n"
262                 "${COORDPREC} vec4 getCoords (void)\n"
263                 "{\n"
264                 "    ${COORDPREC} vec4 coords = ${COORDS};\n"
265                 "    for (int i = 0; i < ${ITERLIMIT}; i++)\n"
266                 "    {\n"
267                 "        if (${RETURNCOND})\n"
268                 "            return coords;\n"
269                 "        coords = coords.wzyx;\n"
270                 "    }\n"
271                 "    return coords;\n"
272                 "}\n\n"
273                 "void main (void)\n"
274                 "{\n"
275                 "${POSITIONWRITE}"
276                 "    ${OUTPUT} = vec4(getCoords().xyz, 1.0);\n"
277                 "}\n");
278
279         const char* coords = isVertex ? "a_coords" : "v_coords";
280
281         std::map<std::string, std::string> params;
282
283         params["COORDLOC"]              = isVertex ? "1"                        : "0";
284         params["COORDPREC"]             = isVertex ? "highp"            : "mediump";
285         params["OUTPUT"]                = isVertex ? "v_color"          : "o_color";
286         params["COORDS"]                = coords;
287         params["EXTRADECL"]             = isVertex ? "layout(location = 0) in highp vec4 a_position;\nlayout(location = 0) out mediump vec4 v_color;\n" : "layout(location = 0) out mediump vec4 o_color;\n";
288         params["POSITIONWRITE"] = isVertex ? "    gl_Position = a_position;\n" : "";
289         params["ITERLIMIT"]             = isDynamicLoop ? "ui_one" : "1";
290
291         switch (returnMode)
292         {
293                 case RETURNMODE_ALWAYS:         params["RETURNCOND"] = "true";                                                                                  break;
294                 case RETURNMODE_NEVER:          params["RETURNCOND"] = "false";                                                                                 break;
295                 case RETURNMODE_DYNAMIC:        params["RETURNCOND"] = std::string(coords) + ".x+" + coords + ".y >= 0.0";      break;
296                 default:                                        DE_ASSERT(DE_FALSE);
297         }
298
299         return de::MovePtr<ShaderReturnCase>(new ShaderReturnCase(context, name, description, isVertex, tmpl.specialize(params), getEvalFunc(returnMode), new ReturnTestUniformSetup(UI_ONE)));
300 }
301
302 static const char* getReturnModeName (ReturnMode mode)
303 {
304         switch (mode)
305         {
306                 case RETURNMODE_ALWAYS:         return "always";
307                 case RETURNMODE_NEVER:          return "never";
308                 case RETURNMODE_DYNAMIC:        return "dynamic";
309                 default:
310                         DE_ASSERT(DE_FALSE);
311                         return DE_NULL;
312         }
313 }
314
315 static const char* getReturnModeDesc (ReturnMode mode)
316 {
317         switch (mode)
318         {
319                 case RETURNMODE_ALWAYS:         return "Always return";
320                 case RETURNMODE_NEVER:          return "Never return";
321                 case RETURNMODE_DYNAMIC:        return "Return based on coords";
322                 default:
323                         DE_ASSERT(DE_FALSE);
324                         return DE_NULL;
325         }
326 }
327
328 class ShaderReturnTests : public tcu::TestCaseGroup
329 {
330 public:
331                                                         ShaderReturnTests               (tcu::TestContext& context);
332         virtual                                 ~ShaderReturnTests              (void);
333         virtual void                    init                                    (void);
334
335 private:
336                                                         ShaderReturnTests               (const ShaderReturnTests&);             // not allowed!
337         ShaderReturnTests&              operator=                               (const ShaderReturnTests&);             // not allowed!
338 };
339
340 ShaderReturnTests::ShaderReturnTests (tcu::TestContext& context)
341         : TestCaseGroup(context, "return", "Return Statement Tests")
342 {
343 }
344
345 ShaderReturnTests::~ShaderReturnTests (void)
346 {
347 }
348
349 void ShaderReturnTests::init (void)
350 {
351         addChild(new ShaderReturnCase(m_testCtx, "single_return_vertex", "Single return statement in function", true,
352                 "#version 140\n"
353                 "#extension GL_ARB_separate_shader_objects : enable\n"
354                 "#extension GL_ARB_shading_language_420pack : enable\n"
355                 "layout(location = 0) in highp vec4 a_position;\n"
356                 "layout(location = 1) in highp vec4 a_coords;\n"
357                 "layout(location = 0) out highp vec4 v_color;\n\n"
358                 "vec4 getColor (void)\n"
359                 "{\n"
360                 "    return vec4(a_coords.xyz, 1.0);\n"
361                 "}\n\n"
362                 "void main (void)\n"
363                 "{\n"
364                 "    gl_Position = a_position;\n"
365                 "    v_color = getColor();\n"
366                 "}\n", evalReturnAlways, DE_NULL));
367         addChild(new ShaderReturnCase(m_testCtx, "single_return_fragment", "Single return statement in function", false,
368                 "#version 140\n"
369                 "#extension GL_ARB_separate_shader_objects : enable\n"
370                 "#extension GL_ARB_shading_language_420pack : enable\n"
371                 "layout(location = 0) in mediump vec4 v_coords;\n"
372                 "layout(location = 0) out mediump vec4 o_color;\n"
373                 "mediump vec4 getColor (void)\n"
374                 "{\n"
375                 "    return vec4(v_coords.xyz, 1.0);\n"
376                 "}\n\n"
377                 "void main (void)\n"
378                 "{\n"
379                 "    o_color = getColor();\n"
380                 "}\n", evalReturnAlways, DE_NULL));
381
382         // Conditional return statement in function.
383         for (int returnMode = 0; returnMode < RETURNMODE_LAST; returnMode++)
384         {
385                 for (int isFragment = 0; isFragment < 2; isFragment++)
386                 {
387                         std::string                                             name            = std::string("conditional_return_") + getReturnModeName((ReturnMode)returnMode) + (isFragment ? "_fragment" : "_vertex");
388                         std::string                                             description     = std::string(getReturnModeDesc((ReturnMode)returnMode)) + " in function";
389                         de::MovePtr<ShaderReturnCase>   testCase        (makeConditionalReturnInFuncCase(m_testCtx, name, description, (ReturnMode)returnMode, isFragment == 0));
390                         addChild(testCase.release());
391                 }
392         }
393
394         // Unconditional double return in function.
395         addChild(new ShaderReturnCase(m_testCtx, "double_return_vertex", "Unconditional double return in function", true,
396                 "#version 140\n"
397                 "#extension GL_ARB_separate_shader_objects : enable\n"
398                 "#extension GL_ARB_shading_language_420pack : enable\n"
399                 "layout(location = 0) in highp vec4 a_position;\n"
400                 "layout(location = 1) in highp vec4 a_coords;\n"
401                 "layout(location = 0) out highp vec4 v_color;\n\n"
402                 "vec4 getColor (void)\n"
403                 "{\n"
404                 "    return vec4(a_coords.xyz, 1.0);\n"
405                 "    return vec4(a_coords.wzy, 1.0);\n"
406                 "}\n\n"
407                 "void main (void)\n"
408                 "{\n"
409                 "    gl_Position = a_position;\n"
410                 "    v_color = getColor();\n"
411                 "}\n", evalReturnAlways, DE_NULL));
412         addChild(new ShaderReturnCase(m_testCtx, "double_return_fragment", "Unconditional double return in function", false,
413                 "#version 140\n"
414                 "#extension GL_ARB_separate_shader_objects : enable\n"
415                 "#extension GL_ARB_shading_language_420pack : enable\n"
416                 "layout(location = 0) in mediump vec4 v_coords;\n"
417                 "layout(location = 0) out mediump vec4 o_color;\n\n"
418                 "mediump vec4 getColor (void)\n"
419                 "{\n"
420                 "    return vec4(v_coords.xyz, 1.0);\n"
421                 "    return vec4(v_coords.wzy, 1.0);\n"
422                 "}\n\n"
423                 "void main (void)\n"
424                 "{\n"
425                 "    o_color = getColor();\n"
426                 "}\n", evalReturnAlways, DE_NULL));
427
428         // Last statement in main.
429         addChild(new ShaderReturnCase(m_testCtx, "last_statement_in_main_vertex", "Return as a final statement in main()", true,
430                 "#version 140\n"
431                 "#extension GL_ARB_separate_shader_objects : enable\n"
432                 "#extension GL_ARB_shading_language_420pack : enable\n"
433                 "layout(location = 0) in highp vec4 a_position;\n"
434                 "layout(location = 1) in highp vec4 a_coords;\n"
435                 "layout(location = 0) out highp vec4 v_color;\n\n"
436                 "void main (void)\n"
437                 "{\n"
438                 "    gl_Position = a_position;\n"
439                 "    v_color = vec4(a_coords.xyz, 1.0);\n"
440                 "    return;\n"
441                 "}\n", evalReturnAlways, DE_NULL));
442         addChild(new ShaderReturnCase(m_testCtx, "last_statement_in_main_fragment", "Return as a final statement in main()", false,
443                 "#version 140\n"
444                 "#extension GL_ARB_separate_shader_objects : enable\n"
445                 "#extension GL_ARB_shading_language_420pack : enable\n"
446                 "layout(location = 0) in mediump vec4 v_coords;\n"
447                 "layout(location = 0) out mediump vec4 o_color;\n\n"
448                 "void main (void)\n"
449                 "{\n"
450                 "    o_color = vec4(v_coords.xyz, 1.0);\n"
451                 "    return;\n"
452                 "}\n", evalReturnAlways, DE_NULL));
453
454         // Return between output variable writes.
455         for (int inFunc = 0; inFunc < 2; inFunc++)
456         {
457                 for (int returnMode = 0; returnMode < RETURNMODE_LAST; returnMode++)
458                 {
459                         for (int isFragment = 0; isFragment < 2; isFragment++)
460                         {
461                                 std::string                                             name            = std::string("output_write_") + (inFunc ? "in_func_" : "") + getReturnModeName((ReturnMode)returnMode) + (isFragment ? "_fragment" : "_vertex");
462                                 std::string                                             desc            = std::string(getReturnModeDesc((ReturnMode)returnMode)) + (inFunc ? " in user-defined function" : " in main()") + " between output writes";
463                                 de::MovePtr<ShaderReturnCase>   testCase        = (makeOutputWriteReturnCase(m_testCtx, name, desc, inFunc != 0, (ReturnMode)returnMode, isFragment == 0));
464                                 addChild(testCase.release());
465                         }
466                 }
467         }
468
469         // Conditional return statement in loop.
470         for (int isDynamicLoop = 0; isDynamicLoop < 2; isDynamicLoop++)
471         {
472                 for (int returnMode = 0; returnMode < RETURNMODE_LAST; returnMode++)
473                 {
474                         for (int isFragment = 0; isFragment < 2; isFragment++)
475                         {
476                                 std::string                                             name            = std::string("return_in_") + (isDynamicLoop ? "dynamic" : "static") + "_loop_" + getReturnModeName((ReturnMode)returnMode) + (isFragment ? "_fragment" : "_vertex");
477                                 std::string                                             description     = std::string(getReturnModeDesc((ReturnMode)returnMode)) + " in loop";
478                                 de::MovePtr<ShaderReturnCase>   testCase        (makeReturnInLoopCase(m_testCtx, name, description, isDynamicLoop != 0, (ReturnMode)returnMode, isFragment == 0));
479                                 addChild(testCase.release());
480                         }
481                 }
482         }
483
484         // Unconditional return in infinite loop.
485         addChild(new ShaderReturnCase(m_testCtx, "return_in_infinite_loop_vertex", "Return in infinite loop", true,
486                 "#version 140\n"
487                 "#extension GL_ARB_separate_shader_objects : enable\n"
488                 "#extension GL_ARB_shading_language_420pack : enable\n"
489                 "layout(location = 0) in highp vec4 a_position;\n"
490                 "layout(location = 1) in highp vec4 a_coords;\n"
491                 "layout(location = 0) out highp vec4 v_color;\n"
492                 "layout(binding = 0, std140) uniform something { int ui_zero; };\n"
493                 "highp vec4 getCoords (void)\n"
494                 "{\n"
495                 "       for (int i = 1; i < 10; i += ui_zero)\n"
496                 "               return a_coords;\n"
497                 "       return a_coords.wzyx;\n"
498                 "}\n\n"
499                 "void main (void)\n"
500                 "{\n"
501                 "    gl_Position = a_position;\n"
502                 "    v_color = vec4(getCoords().xyz, 1.0);\n"
503                 "    return;\n"
504                 "}\n", evalReturnAlways, new ReturnTestUniformSetup(UI_ZERO)));
505         addChild(new ShaderReturnCase(m_testCtx, "return_in_infinite_loop_fragment", "Return in infinite loop", false,
506                 "#version 140\n"
507                 "#extension GL_ARB_separate_shader_objects : enable\n"
508                 "#extension GL_ARB_shading_language_420pack : enable\n"
509                 "layout(location = 0) in mediump vec4 v_coords;\n"
510                 "layout(location = 0) out mediump vec4 o_color;\n"
511                 "layout(binding = 0, std140) uniform something { int ui_zero; };\n\n"
512                 "mediump vec4 getCoords (void)\n"
513                 "{\n"
514                 "       for (int i = 1; i < 10; i += ui_zero)\n"
515                 "               return v_coords;\n"
516                 "       return v_coords.wzyx;\n"
517                 "}\n\n"
518                 "void main (void)\n"
519                 "{\n"
520                 "    o_color = vec4(getCoords().xyz, 1.0);\n"
521                 "    return;\n"
522                 "}\n", evalReturnAlways, new ReturnTestUniformSetup(UI_ZERO)));
523 }
524
525 } // anonymous
526
527 tcu::TestCaseGroup* createReturnTests (tcu::TestContext& testCtx)
528 {
529         return new ShaderReturnTests(testCtx);
530 }
531
532 } // sr
533 } // vkt