1d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal/*------------------------------------------------------------------------
2d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal * Vulkan Conformance Tests
3d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal * ------------------------
4d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal *
5d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal * Copyright (c) 2015 The Khronos Group Inc.
6d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal * Copyright (c) 2015 Samsung Electronics Co., Ltd.
7c05b7f1437e619205c96eaa31c0b79ec97a0d47dPyry Haulos * Copyright (c) 2016 The Android Open Source Project
8d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal *
9d471a12fca5d3077a4ca28eebf83685f4208c3b6Pyry Haulos * Licensed under the Apache License, Version 2.0 (the "License");
10d471a12fca5d3077a4ca28eebf83685f4208c3b6Pyry Haulos * you may not use this file except in compliance with the License.
11d471a12fca5d3077a4ca28eebf83685f4208c3b6Pyry Haulos * You may obtain a copy of the License at
12d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal *
13d471a12fca5d3077a4ca28eebf83685f4208c3b6Pyry Haulos *      http://www.apache.org/licenses/LICENSE-2.0
14d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal *
15d471a12fca5d3077a4ca28eebf83685f4208c3b6Pyry Haulos * Unless required by applicable law or agreed to in writing, software
16d471a12fca5d3077a4ca28eebf83685f4208c3b6Pyry Haulos * distributed under the License is distributed on an "AS IS" BASIS,
17d471a12fca5d3077a4ca28eebf83685f4208c3b6Pyry Haulos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18d471a12fca5d3077a4ca28eebf83685f4208c3b6Pyry Haulos * See the License for the specific language governing permissions and
19d471a12fca5d3077a4ca28eebf83685f4208c3b6Pyry Haulos * limitations under the License.
20d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal *
21d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal *//*!
22d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal * \file
23d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal * \brief Shader return statement tests.
24d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal *//*--------------------------------------------------------------------*/
25d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
26d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal#include "vktShaderRenderReturnTests.hpp"
27d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal#include "vktShaderRender.hpp"
28d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal#include "tcuStringTemplate.hpp"
29d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
30d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal#include <map>
31d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal#include <string>
32d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
33d994b3a2d869497f1496273b6d9b8affb1752b20Peter Galnamespace vkt
34d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal{
35d994b3a2d869497f1496273b6d9b8affb1752b20Peter Galnamespace sr
36d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal{
37d994b3a2d869497f1496273b6d9b8affb1752b20Peter Galnamespace
38d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal{
39d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
40d994b3a2d869497f1496273b6d9b8affb1752b20Peter Galenum ReturnMode
41d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal{
42d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	RETURNMODE_ALWAYS = 0,
43d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	RETURNMODE_NEVER,
44d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	RETURNMODE_DYNAMIC,
45d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
46d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	RETURNMODE_LAST
47d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal};
48d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
49d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal// Evaluation functions
50d994b3a2d869497f1496273b6d9b8affb1752b20Peter Galinline void evalReturnAlways	(ShaderEvalContext& c) { c.color.xyz() = c.coords.swizzle(0,1,2); }
51d994b3a2d869497f1496273b6d9b8affb1752b20Peter Galinline void evalReturnNever		(ShaderEvalContext& c) { c.color.xyz() = c.coords.swizzle(3,2,1); }
52d994b3a2d869497f1496273b6d9b8affb1752b20Peter Galinline 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); }
53d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
54d994b3a2d869497f1496273b6d9b8affb1752b20Peter Galstatic ShaderEvalFunc getEvalFunc (ReturnMode mode)
55d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal{
56d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	switch (mode)
57d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	{
58d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		case RETURNMODE_ALWAYS:		return evalReturnAlways;
59d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		case RETURNMODE_NEVER:		return evalReturnNever;
60d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		case RETURNMODE_DYNAMIC:	return evalReturnDynamic;
61d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		default:
62d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			DE_ASSERT(DE_FALSE);
63d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			return (ShaderEvalFunc)DE_NULL;
64d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	}
65d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal}
66d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
67d994b3a2d869497f1496273b6d9b8affb1752b20Peter Galclass ShaderReturnCase : public ShaderRenderCase
68d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal{
69d994b3a2d869497f1496273b6d9b8affb1752b20Peter Galpublic:
70d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal								ShaderReturnCase		(tcu::TestContext&			testCtx,
71d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal														 const std::string&			name,
72d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal														 const std::string&			description,
73d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal														 bool						isVertexCase,
74d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal														 const std::string&			shaderSource,
75d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal														 const ShaderEvalFunc		evalFunc,
76d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal														 const UniformSetup*		uniformFunc);
77d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	virtual						~ShaderReturnCase		(void);
78d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal};
79d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
80d994b3a2d869497f1496273b6d9b8affb1752b20Peter GalShaderReturnCase::ShaderReturnCase (tcu::TestContext&			testCtx,
81d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal									const std::string&			name,
82d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal									const std::string&			description,
83d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal									bool						isVertexCase,
84d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal									const std::string&			shaderSource,
85d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal									const ShaderEvalFunc		evalFunc,
86d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal									const UniformSetup*			uniformFunc)
87d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	: ShaderRenderCase(testCtx, name, description, isVertexCase, evalFunc, uniformFunc, DE_NULL)
88d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal{
89d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	if (isVertexCase)
90d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	{
91d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		m_vertShaderSource = shaderSource;
92d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		m_fragShaderSource =
93168546fb8ff28c2a81bf2dd37a5f865c3730fa2dCsaba Osztrogonác			"#version 310 es\n"
94d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"layout(location = 0) in mediump vec4 v_color;\n"
95d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"layout(location = 0) out mediump vec4 o_color;\n\n"
96d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"void main (void)\n"
97d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"{\n"
98d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"    o_color = v_color;\n"
99d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"}\n";
100d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	}
101d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	else
102d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	{
103d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		m_fragShaderSource = shaderSource;
104d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		m_vertShaderSource =
105168546fb8ff28c2a81bf2dd37a5f865c3730fa2dCsaba Osztrogonác			"#version 310 es\n"
106d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"layout(location = 0) in  highp   vec4 a_position;\n"
107d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"layout(location = 1) in  highp   vec4 a_coords;\n"
108d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"layout(location = 0) out mediump vec4 v_coords;\n\n"
109d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"void main (void)\n"
110d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"{\n"
111d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"    gl_Position = a_position;\n"
112d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"    v_coords = a_coords;\n"
113d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"}\n";
114d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	}
115d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal}
116d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
117d994b3a2d869497f1496273b6d9b8affb1752b20Peter GalShaderReturnCase::~ShaderReturnCase (void)
118d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal{
119d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal}
120d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
121d994b3a2d869497f1496273b6d9b8affb1752b20Peter Galclass ReturnTestUniformSetup : public UniformSetup
122d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal{
123d994b3a2d869497f1496273b6d9b8affb1752b20Peter Galpublic:
124d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal								ReturnTestUniformSetup	(const BaseUniformType uniformType)
125d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal									: m_uniformType(uniformType)
126d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal								{}
127d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	virtual void				setup					(ShaderRenderCaseInstance& instance, const tcu::Vec4&) const
128d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal								{
129d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal									instance.useUniform(0u, m_uniformType);
130d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal								}
131d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
132d994b3a2d869497f1496273b6d9b8affb1752b20Peter Galprivate:
133d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	const BaseUniformType		m_uniformType;
134d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal};
135d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
136d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal// Test case builders.
137d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
138d994b3a2d869497f1496273b6d9b8affb1752b20Peter Galde::MovePtr<ShaderReturnCase> makeConditionalReturnInFuncCase (tcu::TestContext& context, const std::string& name, const std::string& description, ReturnMode returnMode, bool isVertex)
139d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal{
140d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	tcu::StringTemplate tmpl(
141168546fb8ff28c2a81bf2dd37a5f865c3730fa2dCsaba Osztrogonác		"#version 310 es\n"
142d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"layout(location = ${COORDLOC}) in ${COORDPREC} vec4 ${COORDS};\n"
143d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"${EXTRADECL}\n"
144d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"${COORDPREC} vec4 getColor (void)\n"
145d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"{\n"
146d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    if (${RETURNCOND})\n"
147d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"        return vec4(${COORDS}.xyz, 1.0);\n"
148d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    return vec4(${COORDS}.wzy, 1.0);\n"
149d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"}\n\n"
150d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"void main (void)\n"
151d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"{\n"
152d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"${POSITIONWRITE}"
153d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    ${OUTPUT} = getColor();\n"
154d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"}\n");
155d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
156d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	const char* coords = isVertex ? "a_coords" : "v_coords";
157d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
158d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	std::map<std::string, std::string> params;
159d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
160d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	params["COORDLOC"]		= isVertex ? "1"			: "0";
161d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	params["COORDPREC"]		= isVertex ? "highp"		: "mediump";
162d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	params["OUTPUT"]		= isVertex ? "v_color"		: "o_color";
163d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	params["COORDS"]		= coords;
164d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	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";
165d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	params["POSITIONWRITE"]	= isVertex ? "    gl_Position = a_position;\n" : "";
166d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
167d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	switch (returnMode)
168d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	{
169d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		case RETURNMODE_ALWAYS:		params["RETURNCOND"] = "true";											break;
170d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		case RETURNMODE_NEVER:		params["RETURNCOND"] = "false";											break;
171d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		case RETURNMODE_DYNAMIC:	params["RETURNCOND"] = std::string(coords) + ".x+" + coords + ".y >= 0.0";	break;
172d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		default:					DE_ASSERT(DE_FALSE);
173d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	}
174d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
175d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	return de::MovePtr<ShaderReturnCase>(new ShaderReturnCase(context, name, description, isVertex, tmpl.specialize(params), getEvalFunc(returnMode), DE_NULL));
176d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal}
177d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
178d994b3a2d869497f1496273b6d9b8affb1752b20Peter Galde::MovePtr<ShaderReturnCase> makeOutputWriteReturnCase (tcu::TestContext& context, const std::string& name, const std::string& description, bool inFunction, ReturnMode returnMode, bool isVertex)
179d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal{
180d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	tcu::StringTemplate tmpl(
181d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		inFunction
182d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		?
183168546fb8ff28c2a81bf2dd37a5f865c3730fa2dCsaba Osztrogonác			"#version 310 es\n"
184d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"layout(location = ${COORDLOC}) in ${COORDPREC} vec4 ${COORDS};\n"
185d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"${EXTRADECL}\n"
186d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"void myfunc (void)\n"
187d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"{\n"
188d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"    ${OUTPUT} = vec4(${COORDS}.xyz, 1.0);\n"
189d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"    if (${RETURNCOND})\n"
190d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"        return;\n"
191d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"    ${OUTPUT} = vec4(${COORDS}.wzy, 1.0);\n"
192d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"}\n\n"
193d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"void main (void)\n"
194d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"{\n"
195d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"${POSITIONWRITE}"
196d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"    myfunc();\n"
197d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"}\n"
198d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		:
199168546fb8ff28c2a81bf2dd37a5f865c3730fa2dCsaba Osztrogonác			"#version 310 es\n"
200d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"layout(location = ${COORDLOC}) in ${COORDPREC} vec4 ${COORDS};\n"
201d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"${EXTRADECL}\n"
202d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"void main ()\n"
203d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"{\n"
204d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"${POSITIONWRITE}"
205d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"    ${OUTPUT} = vec4(${COORDS}.xyz, 1.0);\n"
206d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"    if (${RETURNCOND})\n"
207d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"        return;\n"
208d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"    ${OUTPUT} = vec4(${COORDS}.wzy, 1.0);\n"
209d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			"}\n");
210d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
211d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	const char* coords = isVertex ? "a_coords" : "v_coords";
212d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
213d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	std::map<std::string, std::string> params;
214d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
215d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	params["COORDLOC"]		= isVertex ? "1"			: "0";
216d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	params["COORDPREC"]		= isVertex ? "highp"		: "mediump";
217d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	params["COORDS"]		= coords;
218d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	params["OUTPUT"]		= isVertex ? "v_color"		: "o_color";
219d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	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";
220d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	params["POSITIONWRITE"]	= isVertex ? "    gl_Position = a_position;\n" : "";
221d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
222d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	switch (returnMode)
223d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	{
224d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		case RETURNMODE_ALWAYS:		params["RETURNCOND"] = "true";											break;
225d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		case RETURNMODE_NEVER:		params["RETURNCOND"] = "false";											break;
226d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		case RETURNMODE_DYNAMIC:	params["RETURNCOND"] = std::string(coords) + ".x+" + coords + ".y >= 0.0";	break;
227d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		default:					DE_ASSERT(DE_FALSE);
228d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	}
229d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
230d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	return de::MovePtr<ShaderReturnCase>(new ShaderReturnCase(context, name, description, isVertex, tmpl.specialize(params), getEvalFunc(returnMode), DE_NULL));
231d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal}
232d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
233d994b3a2d869497f1496273b6d9b8affb1752b20Peter Galde::MovePtr<ShaderReturnCase> makeReturnInLoopCase (tcu::TestContext& context, const std::string& name, const std::string& description, bool isDynamicLoop, ReturnMode returnMode, bool isVertex)
234d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal{
235d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	tcu::StringTemplate tmpl(
236168546fb8ff28c2a81bf2dd37a5f865c3730fa2dCsaba Osztrogonác		"#version 310 es\n"
237d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"layout(location = ${COORDLOC}) in ${COORDPREC} vec4 ${COORDS};\n"
238d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"layout(binding = 0, std140) uniform something { mediump int ui_one; };\n"
239d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"${EXTRADECL}\n"
240d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"${COORDPREC} vec4 getCoords (void)\n"
241d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"{\n"
242d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    ${COORDPREC} vec4 coords = ${COORDS};\n"
243d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    for (int i = 0; i < ${ITERLIMIT}; i++)\n"
244d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    {\n"
245d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"        if (${RETURNCOND})\n"
246d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"            return coords;\n"
247d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"        coords = coords.wzyx;\n"
248d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    }\n"
249d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    return coords;\n"
250d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"}\n\n"
251d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"void main (void)\n"
252d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"{\n"
253d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"${POSITIONWRITE}"
254d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    ${OUTPUT} = vec4(getCoords().xyz, 1.0);\n"
255d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"}\n");
256d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
257d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	const char* coords = isVertex ? "a_coords" : "v_coords";
258d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
259d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	std::map<std::string, std::string> params;
260d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
261d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	params["COORDLOC"]		= isVertex ? "1"			: "0";
262d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	params["COORDPREC"]		= isVertex ? "highp"		: "mediump";
263d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	params["OUTPUT"]		= isVertex ? "v_color"		: "o_color";
264d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	params["COORDS"]		= coords;
265d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	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";
266d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	params["POSITIONWRITE"]	= isVertex ? "    gl_Position = a_position;\n" : "";
267d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	params["ITERLIMIT"]		= isDynamicLoop ? "ui_one" : "1";
268d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
269d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	switch (returnMode)
270d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	{
271d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		case RETURNMODE_ALWAYS:		params["RETURNCOND"] = "true";											break;
272d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		case RETURNMODE_NEVER:		params["RETURNCOND"] = "false";											break;
273d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		case RETURNMODE_DYNAMIC:	params["RETURNCOND"] = std::string(coords) + ".x+" + coords + ".y >= 0.0";	break;
274d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		default:					DE_ASSERT(DE_FALSE);
275d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	}
276d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
277d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	return de::MovePtr<ShaderReturnCase>(new ShaderReturnCase(context, name, description, isVertex, tmpl.specialize(params), getEvalFunc(returnMode), new ReturnTestUniformSetup(UI_ONE)));
278d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal}
279d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
280d994b3a2d869497f1496273b6d9b8affb1752b20Peter Galstatic const char* getReturnModeName (ReturnMode mode)
281d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal{
282d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	switch (mode)
283d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	{
284d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		case RETURNMODE_ALWAYS:		return "always";
285d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		case RETURNMODE_NEVER:		return "never";
286d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		case RETURNMODE_DYNAMIC:	return "dynamic";
287d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		default:
288d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			DE_ASSERT(DE_FALSE);
289d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			return DE_NULL;
290d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	}
291d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal}
292d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
293d994b3a2d869497f1496273b6d9b8affb1752b20Peter Galstatic const char* getReturnModeDesc (ReturnMode mode)
294d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal{
295d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	switch (mode)
296d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	{
297d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		case RETURNMODE_ALWAYS:		return "Always return";
298d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		case RETURNMODE_NEVER:		return "Never return";
299d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		case RETURNMODE_DYNAMIC:	return "Return based on coords";
300d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		default:
301d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			DE_ASSERT(DE_FALSE);
302d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			return DE_NULL;
303d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	}
304d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal}
305d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
306d994b3a2d869497f1496273b6d9b8affb1752b20Peter Galclass ShaderReturnTests : public tcu::TestCaseGroup
307d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal{
308d994b3a2d869497f1496273b6d9b8affb1752b20Peter Galpublic:
309d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal							ShaderReturnTests		(tcu::TestContext& context);
310d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	virtual					~ShaderReturnTests		(void);
311d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	virtual void			init					(void);
312d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
313d994b3a2d869497f1496273b6d9b8affb1752b20Peter Galprivate:
314d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal							ShaderReturnTests		(const ShaderReturnTests&);		// not allowed!
315d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	ShaderReturnTests&		operator=				(const ShaderReturnTests&);		// not allowed!
316d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal};
317d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
318d994b3a2d869497f1496273b6d9b8affb1752b20Peter GalShaderReturnTests::ShaderReturnTests (tcu::TestContext& context)
319d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	: TestCaseGroup(context, "return", "Return Statement Tests")
320d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal{
321d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal}
322d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
323d994b3a2d869497f1496273b6d9b8affb1752b20Peter GalShaderReturnTests::~ShaderReturnTests (void)
324d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal{
325d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal}
326d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
327d994b3a2d869497f1496273b6d9b8affb1752b20Peter Galvoid ShaderReturnTests::init (void)
328d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal{
329d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	addChild(new ShaderReturnCase(m_testCtx, "single_return_vertex", "Single return statement in function", true,
330168546fb8ff28c2a81bf2dd37a5f865c3730fa2dCsaba Osztrogonác		"#version 310 es\n"
331d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"layout(location = 0) in highp vec4 a_position;\n"
332d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"layout(location = 1) in highp vec4 a_coords;\n"
33367623b92059fc9038e956b5565b05ad07db40fc1Pyry Haulos		"layout(location = 0) out mediump vec4 v_color;\n\n"
334d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"vec4 getColor (void)\n"
335d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"{\n"
336d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    return vec4(a_coords.xyz, 1.0);\n"
337d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"}\n\n"
338d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"void main (void)\n"
339d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"{\n"
340d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    gl_Position = a_position;\n"
341d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    v_color = getColor();\n"
342d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"}\n", evalReturnAlways, DE_NULL));
343d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	addChild(new ShaderReturnCase(m_testCtx, "single_return_fragment", "Single return statement in function", false,
344168546fb8ff28c2a81bf2dd37a5f865c3730fa2dCsaba Osztrogonác		"#version 310 es\n"
345d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"layout(location = 0) in mediump vec4 v_coords;\n"
346d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"layout(location = 0) out mediump vec4 o_color;\n"
347d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"mediump vec4 getColor (void)\n"
348d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"{\n"
349d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    return vec4(v_coords.xyz, 1.0);\n"
350d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"}\n\n"
351d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"void main (void)\n"
352d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"{\n"
353d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    o_color = getColor();\n"
354d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"}\n", evalReturnAlways, DE_NULL));
355d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
356d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	// Conditional return statement in function.
357d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	for (int returnMode = 0; returnMode < RETURNMODE_LAST; returnMode++)
358d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	{
359d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		for (int isFragment = 0; isFragment < 2; isFragment++)
360d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		{
361d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			std::string						name		= std::string("conditional_return_") + getReturnModeName((ReturnMode)returnMode) + (isFragment ? "_fragment" : "_vertex");
362d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			std::string						description	= std::string(getReturnModeDesc((ReturnMode)returnMode)) + " in function";
363d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			de::MovePtr<ShaderReturnCase>	testCase	(makeConditionalReturnInFuncCase(m_testCtx, name, description, (ReturnMode)returnMode, isFragment == 0));
364d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			addChild(testCase.release());
365d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		}
366d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	}
367d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
368d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	// Unconditional double return in function.
369d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	addChild(new ShaderReturnCase(m_testCtx, "double_return_vertex", "Unconditional double return in function", true,
370168546fb8ff28c2a81bf2dd37a5f865c3730fa2dCsaba Osztrogonác		"#version 310 es\n"
371d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"layout(location = 0) in highp vec4 a_position;\n"
372d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"layout(location = 1) in highp vec4 a_coords;\n"
37367623b92059fc9038e956b5565b05ad07db40fc1Pyry Haulos		"layout(location = 0) out mediump vec4 v_color;\n\n"
374d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"vec4 getColor (void)\n"
375d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"{\n"
376d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    return vec4(a_coords.xyz, 1.0);\n"
377d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    return vec4(a_coords.wzy, 1.0);\n"
378d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"}\n\n"
379d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"void main (void)\n"
380d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"{\n"
381d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    gl_Position = a_position;\n"
382d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    v_color = getColor();\n"
383d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"}\n", evalReturnAlways, DE_NULL));
384d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	addChild(new ShaderReturnCase(m_testCtx, "double_return_fragment", "Unconditional double return in function", false,
385168546fb8ff28c2a81bf2dd37a5f865c3730fa2dCsaba Osztrogonác		"#version 310 es\n"
386d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"layout(location = 0) in mediump vec4 v_coords;\n"
387d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"layout(location = 0) out mediump vec4 o_color;\n\n"
388d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"mediump vec4 getColor (void)\n"
389d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"{\n"
390d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    return vec4(v_coords.xyz, 1.0);\n"
391d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    return vec4(v_coords.wzy, 1.0);\n"
392d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"}\n\n"
393d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"void main (void)\n"
394d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"{\n"
395d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    o_color = getColor();\n"
396d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"}\n", evalReturnAlways, DE_NULL));
397d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
398d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	// Last statement in main.
399d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	addChild(new ShaderReturnCase(m_testCtx, "last_statement_in_main_vertex", "Return as a final statement in main()", true,
400168546fb8ff28c2a81bf2dd37a5f865c3730fa2dCsaba Osztrogonác		"#version 310 es\n"
401d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"layout(location = 0) in highp vec4 a_position;\n"
402d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"layout(location = 1) in highp vec4 a_coords;\n"
40367623b92059fc9038e956b5565b05ad07db40fc1Pyry Haulos		"layout(location = 0) out mediump vec4 v_color;\n\n"
404d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"void main (void)\n"
405d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"{\n"
406d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    gl_Position = a_position;\n"
407d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    v_color = vec4(a_coords.xyz, 1.0);\n"
408d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    return;\n"
409d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"}\n", evalReturnAlways, DE_NULL));
410d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	addChild(new ShaderReturnCase(m_testCtx, "last_statement_in_main_fragment", "Return as a final statement in main()", false,
411168546fb8ff28c2a81bf2dd37a5f865c3730fa2dCsaba Osztrogonác		"#version 310 es\n"
412d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"layout(location = 0) in mediump vec4 v_coords;\n"
413d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"layout(location = 0) out mediump vec4 o_color;\n\n"
414d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"void main (void)\n"
415d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"{\n"
416d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    o_color = vec4(v_coords.xyz, 1.0);\n"
417d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    return;\n"
418d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"}\n", evalReturnAlways, DE_NULL));
419d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
420d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	// Return between output variable writes.
421d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	for (int inFunc = 0; inFunc < 2; inFunc++)
422d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	{
423d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		for (int returnMode = 0; returnMode < RETURNMODE_LAST; returnMode++)
424d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		{
425d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			for (int isFragment = 0; isFragment < 2; isFragment++)
426d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			{
427d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal				std::string						name		= std::string("output_write_") + (inFunc ? "in_func_" : "") + getReturnModeName((ReturnMode)returnMode) + (isFragment ? "_fragment" : "_vertex");
428d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal				std::string						desc		= std::string(getReturnModeDesc((ReturnMode)returnMode)) + (inFunc ? " in user-defined function" : " in main()") + " between output writes";
429d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal				de::MovePtr<ShaderReturnCase>	testCase	= (makeOutputWriteReturnCase(m_testCtx, name, desc, inFunc != 0, (ReturnMode)returnMode, isFragment == 0));
430d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal				addChild(testCase.release());
431d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			}
432d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		}
433d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	}
434d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
435d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	// Conditional return statement in loop.
436d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	for (int isDynamicLoop = 0; isDynamicLoop < 2; isDynamicLoop++)
437d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	{
438d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		for (int returnMode = 0; returnMode < RETURNMODE_LAST; returnMode++)
439d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		{
440d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			for (int isFragment = 0; isFragment < 2; isFragment++)
441d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			{
442d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal				std::string						name		= std::string("return_in_") + (isDynamicLoop ? "dynamic" : "static") + "_loop_" + getReturnModeName((ReturnMode)returnMode) + (isFragment ? "_fragment" : "_vertex");
443d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal				std::string						description	= std::string(getReturnModeDesc((ReturnMode)returnMode)) + " in loop";
444d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal				de::MovePtr<ShaderReturnCase>	testCase	(makeReturnInLoopCase(m_testCtx, name, description, isDynamicLoop != 0, (ReturnMode)returnMode, isFragment == 0));
445d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal				addChild(testCase.release());
446d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal			}
447d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		}
448d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	}
449d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
450d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	// Unconditional return in infinite loop.
451d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	addChild(new ShaderReturnCase(m_testCtx, "return_in_infinite_loop_vertex", "Return in infinite loop", true,
452168546fb8ff28c2a81bf2dd37a5f865c3730fa2dCsaba Osztrogonác		"#version 310 es\n"
453d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"layout(location = 0) in highp vec4 a_position;\n"
454d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"layout(location = 1) in highp vec4 a_coords;\n"
45567623b92059fc9038e956b5565b05ad07db40fc1Pyry Haulos		"layout(location = 0) out mediump vec4 v_color;\n"
456d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"layout(binding = 0, std140) uniform something { int ui_zero; };\n"
457d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"highp vec4 getCoords (void)\n"
458d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"{\n"
459d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"	for (int i = 1; i < 10; i += ui_zero)\n"
460d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"		return a_coords;\n"
461d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"	return a_coords.wzyx;\n"
462d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"}\n\n"
463d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"void main (void)\n"
464d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"{\n"
465d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    gl_Position = a_position;\n"
466d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    v_color = vec4(getCoords().xyz, 1.0);\n"
467d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    return;\n"
468d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"}\n", evalReturnAlways, new ReturnTestUniformSetup(UI_ZERO)));
469d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	addChild(new ShaderReturnCase(m_testCtx, "return_in_infinite_loop_fragment", "Return in infinite loop", false,
470168546fb8ff28c2a81bf2dd37a5f865c3730fa2dCsaba Osztrogonác		"#version 310 es\n"
471d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"layout(location = 0) in mediump vec4 v_coords;\n"
472d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"layout(location = 0) out mediump vec4 o_color;\n"
473d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"layout(binding = 0, std140) uniform something { int ui_zero; };\n\n"
474d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"mediump vec4 getCoords (void)\n"
475d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"{\n"
476d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"	for (int i = 1; i < 10; i += ui_zero)\n"
477d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"		return v_coords;\n"
478d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"	return v_coords.wzyx;\n"
479d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"}\n\n"
480d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"void main (void)\n"
481d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"{\n"
482d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    o_color = vec4(getCoords().xyz, 1.0);\n"
483d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"    return;\n"
484d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal		"}\n", evalReturnAlways, new ReturnTestUniformSetup(UI_ZERO)));
485d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal}
486d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
487d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal} // anonymous
488d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
489d994b3a2d869497f1496273b6d9b8affb1752b20Peter Galtcu::TestCaseGroup* createReturnTests (tcu::TestContext& testCtx)
490d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal{
491d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal	return new ShaderReturnTests(testCtx);
492d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal}
493d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal
494d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal} // sr
495d994b3a2d869497f1496273b6d9b8affb1752b20Peter Gal} // vkt
496