1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * OpenGL Conformance Test Suite
3e5c31af7Sopenharmony_ci * -----------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright (c) 2016 Google Inc.
6e5c31af7Sopenharmony_ci * Copyright (c) 2016 The Khronos Group Inc.
7e5c31af7Sopenharmony_ci *
8e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
9e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
10e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
11e5c31af7Sopenharmony_ci *
12e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
13e5c31af7Sopenharmony_ci *
14e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
15e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
16e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
18e5c31af7Sopenharmony_ci * limitations under the License.
19e5c31af7Sopenharmony_ci *
20e5c31af7Sopenharmony_ci */ /*!
21e5c31af7Sopenharmony_ci * \file
22e5c31af7Sopenharmony_ci * \brief Shader struct tests.
23e5c31af7Sopenharmony_ci */ /*-------------------------------------------------------------------*/
24e5c31af7Sopenharmony_ci
25e5c31af7Sopenharmony_ci#include "glcShaderFunctionTests.hpp"
26e5c31af7Sopenharmony_ci#include "glcShaderRenderCase.hpp"
27e5c31af7Sopenharmony_ci#include "gluTexture.hpp"
28e5c31af7Sopenharmony_ci#include "tcuStringTemplate.hpp"
29e5c31af7Sopenharmony_ci#include "tcuTextureUtil.hpp"
30e5c31af7Sopenharmony_ci
31e5c31af7Sopenharmony_ciusing namespace glu;
32e5c31af7Sopenharmony_ci
33e5c31af7Sopenharmony_cinamespace deqp
34e5c31af7Sopenharmony_ci{
35e5c31af7Sopenharmony_ci
36e5c31af7Sopenharmony_citypedef void (*SetupUniformsFunc)(const glw::Functions& gl, deUint32 programID, const tcu::Vec4& constCoords);
37e5c31af7Sopenharmony_ci
38e5c31af7Sopenharmony_ciclass ShaderFunctionCase : public ShaderRenderCase
39e5c31af7Sopenharmony_ci{
40e5c31af7Sopenharmony_cipublic:
41e5c31af7Sopenharmony_ci	ShaderFunctionCase(Context& context, const char* name, const char* description, bool isVertexCase, bool usesTextures,
42e5c31af7Sopenharmony_ci					 ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniformsFunc, const char* vertShaderSource,
43e5c31af7Sopenharmony_ci					 const char* fragShaderSource);
44e5c31af7Sopenharmony_ci	~ShaderFunctionCase(void);
45e5c31af7Sopenharmony_ci
46e5c31af7Sopenharmony_ci	void init(void);
47e5c31af7Sopenharmony_ci	void deinit(void);
48e5c31af7Sopenharmony_ci
49e5c31af7Sopenharmony_ci	virtual void setupUniforms(deUint32 programID, const tcu::Vec4& constCoords);
50e5c31af7Sopenharmony_ci
51e5c31af7Sopenharmony_ciprivate:
52e5c31af7Sopenharmony_ci	ShaderFunctionCase(const ShaderFunctionCase&);
53e5c31af7Sopenharmony_ci	ShaderFunctionCase& operator=(const ShaderFunctionCase&);
54e5c31af7Sopenharmony_ci
55e5c31af7Sopenharmony_ci	SetupUniformsFunc m_setupUniforms;
56e5c31af7Sopenharmony_ci	bool			  m_usesTexture;
57e5c31af7Sopenharmony_ci
58e5c31af7Sopenharmony_ci	glu::Texture2D* m_gradientTexture;
59e5c31af7Sopenharmony_ci};
60e5c31af7Sopenharmony_ci
61e5c31af7Sopenharmony_ciShaderFunctionCase::ShaderFunctionCase(Context& context, const char* name, const char* description, bool isVertexCase,
62e5c31af7Sopenharmony_ci								   bool usesTextures, ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniformsFunc,
63e5c31af7Sopenharmony_ci								   const char* vertShaderSource, const char* fragShaderSource)
64e5c31af7Sopenharmony_ci	: ShaderRenderCase(context.getTestContext(), context.getRenderContext(), context.getContextInfo(), name,
65e5c31af7Sopenharmony_ci					   description, isVertexCase, evalFunc)
66e5c31af7Sopenharmony_ci	, m_setupUniforms(setupUniformsFunc)
67e5c31af7Sopenharmony_ci	, m_usesTexture(usesTextures)
68e5c31af7Sopenharmony_ci	, m_gradientTexture(DE_NULL)
69e5c31af7Sopenharmony_ci{
70e5c31af7Sopenharmony_ci	m_vertShaderSource = vertShaderSource;
71e5c31af7Sopenharmony_ci	m_fragShaderSource = fragShaderSource;
72e5c31af7Sopenharmony_ci}
73e5c31af7Sopenharmony_ci
74e5c31af7Sopenharmony_ciShaderFunctionCase::~ShaderFunctionCase(void)
75e5c31af7Sopenharmony_ci{
76e5c31af7Sopenharmony_ci}
77e5c31af7Sopenharmony_ci
78e5c31af7Sopenharmony_civoid ShaderFunctionCase::init(void)
79e5c31af7Sopenharmony_ci{
80e5c31af7Sopenharmony_ci	if (m_usesTexture)
81e5c31af7Sopenharmony_ci	{
82e5c31af7Sopenharmony_ci		m_gradientTexture = new glu::Texture2D(m_renderCtx, GL_RGBA8, 128, 128);
83e5c31af7Sopenharmony_ci
84e5c31af7Sopenharmony_ci		m_gradientTexture->getRefTexture().allocLevel(0);
85e5c31af7Sopenharmony_ci		tcu::fillWithComponentGradients(m_gradientTexture->getRefTexture().getLevel(0), tcu::Vec4(0.0f),
86e5c31af7Sopenharmony_ci										tcu::Vec4(1.0f));
87e5c31af7Sopenharmony_ci		m_gradientTexture->upload();
88e5c31af7Sopenharmony_ci
89e5c31af7Sopenharmony_ci		m_textures.push_back(TextureBinding(
90e5c31af7Sopenharmony_ci			m_gradientTexture, tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
91e5c31af7Sopenharmony_ci											tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::LINEAR, tcu::Sampler::LINEAR)));
92e5c31af7Sopenharmony_ci		DE_ASSERT(m_textures.size() == 1);
93e5c31af7Sopenharmony_ci	}
94e5c31af7Sopenharmony_ci	ShaderRenderCase::init();
95e5c31af7Sopenharmony_ci}
96e5c31af7Sopenharmony_ci
97e5c31af7Sopenharmony_civoid ShaderFunctionCase::deinit(void)
98e5c31af7Sopenharmony_ci{
99e5c31af7Sopenharmony_ci	if (m_usesTexture)
100e5c31af7Sopenharmony_ci	{
101e5c31af7Sopenharmony_ci		delete m_gradientTexture;
102e5c31af7Sopenharmony_ci	}
103e5c31af7Sopenharmony_ci	ShaderRenderCase::deinit();
104e5c31af7Sopenharmony_ci}
105e5c31af7Sopenharmony_ci
106e5c31af7Sopenharmony_civoid ShaderFunctionCase::setupUniforms(deUint32 programID, const tcu::Vec4& constCoords)
107e5c31af7Sopenharmony_ci{
108e5c31af7Sopenharmony_ci	ShaderRenderCase::setupUniforms(programID, constCoords);
109e5c31af7Sopenharmony_ci	if (m_setupUniforms)
110e5c31af7Sopenharmony_ci		m_setupUniforms(m_renderCtx.getFunctions(), programID, constCoords);
111e5c31af7Sopenharmony_ci}
112e5c31af7Sopenharmony_ci
113e5c31af7Sopenharmony_cistatic ShaderFunctionCase* createStructCase(Context& context, const char* name, const char* description,
114e5c31af7Sopenharmony_ci										  glu::GLSLVersion glslVersion, bool isVertexCase, bool usesTextures,
115e5c31af7Sopenharmony_ci										  ShaderEvalFunc evalFunc, SetupUniformsFunc setupUniforms,
116e5c31af7Sopenharmony_ci										  const LineStream& shaderSrc)
117e5c31af7Sopenharmony_ci{
118e5c31af7Sopenharmony_ci	const std::string versionDecl = glu::getGLSLVersionDeclaration(glslVersion);
119e5c31af7Sopenharmony_ci
120e5c31af7Sopenharmony_ci	const std::string defaultVertSrc = versionDecl + "\n"
121e5c31af7Sopenharmony_ci													 "in highp vec4 a_position;\n"
122e5c31af7Sopenharmony_ci													 "in highp vec4 a_coords;\n"
123e5c31af7Sopenharmony_ci													 "out mediump vec4 v_coords;\n\n"
124e5c31af7Sopenharmony_ci													 "void main (void)\n"
125e5c31af7Sopenharmony_ci													 "{\n"
126e5c31af7Sopenharmony_ci													 "   v_coords = a_coords;\n"
127e5c31af7Sopenharmony_ci													 "   gl_Position = a_position;\n"
128e5c31af7Sopenharmony_ci													 "}\n";
129e5c31af7Sopenharmony_ci	const std::string defaultFragSrc = versionDecl + "\n"
130e5c31af7Sopenharmony_ci													 "in mediump vec4 v_color;\n"
131e5c31af7Sopenharmony_ci													 "layout(location = 0) out mediump vec4 o_color;\n\n"
132e5c31af7Sopenharmony_ci													 "void main (void)\n"
133e5c31af7Sopenharmony_ci													 "{\n"
134e5c31af7Sopenharmony_ci													 "   o_color = v_color;\n"
135e5c31af7Sopenharmony_ci													 "}\n";
136e5c31af7Sopenharmony_ci
137e5c31af7Sopenharmony_ci	// Fill in specialization parameters.
138e5c31af7Sopenharmony_ci	std::map<std::string, std::string> spParams;
139e5c31af7Sopenharmony_ci	if (isVertexCase)
140e5c31af7Sopenharmony_ci	{
141e5c31af7Sopenharmony_ci		spParams["HEADER"] = versionDecl + "\n"
142e5c31af7Sopenharmony_ci										   "in highp vec4 a_position;\n"
143e5c31af7Sopenharmony_ci										   "in highp vec4 a_coords;\n"
144e5c31af7Sopenharmony_ci										   "out mediump vec4 v_color;";
145e5c31af7Sopenharmony_ci		spParams["COORDS"]	 = "a_coords";
146e5c31af7Sopenharmony_ci		spParams["DST"]		   = "v_color";
147e5c31af7Sopenharmony_ci		spParams["ASSIGN_POS"] = "gl_Position = a_position;";
148e5c31af7Sopenharmony_ci	}
149e5c31af7Sopenharmony_ci	else
150e5c31af7Sopenharmony_ci	{
151e5c31af7Sopenharmony_ci		spParams["HEADER"] = versionDecl + "\n"
152e5c31af7Sopenharmony_ci										   "#ifdef GL_ES\n"
153e5c31af7Sopenharmony_ci										   "    precision mediump float;\n"
154e5c31af7Sopenharmony_ci										   "#endif\n"
155e5c31af7Sopenharmony_ci										   "\n"
156e5c31af7Sopenharmony_ci										   "in mediump vec4 v_coords;\n"
157e5c31af7Sopenharmony_ci										   "layout(location = 0) out mediump vec4 o_color;";
158e5c31af7Sopenharmony_ci		spParams["COORDS"]	 = "v_coords";
159e5c31af7Sopenharmony_ci		spParams["DST"]		   = "o_color";
160e5c31af7Sopenharmony_ci		spParams["ASSIGN_POS"] = "";
161e5c31af7Sopenharmony_ci	}
162e5c31af7Sopenharmony_ci
163e5c31af7Sopenharmony_ci	if (isVertexCase)
164e5c31af7Sopenharmony_ci		return new ShaderFunctionCase(context, name, description, isVertexCase, usesTextures, evalFunc, setupUniforms,
165e5c31af7Sopenharmony_ci									tcu::StringTemplate(shaderSrc.str()).specialize(spParams).c_str(),
166e5c31af7Sopenharmony_ci									defaultFragSrc.c_str());
167e5c31af7Sopenharmony_ci	else
168e5c31af7Sopenharmony_ci		return new ShaderFunctionCase(context, name, description, isVertexCase, usesTextures, evalFunc, setupUniforms,
169e5c31af7Sopenharmony_ci									defaultVertSrc.c_str(),
170e5c31af7Sopenharmony_ci									tcu::StringTemplate(shaderSrc.str()).specialize(spParams).c_str());
171e5c31af7Sopenharmony_ci}
172e5c31af7Sopenharmony_ci
173e5c31af7Sopenharmony_ciShaderFunctionTests::ShaderFunctionTests(Context& context, glu::GLSLVersion glslVersion)
174e5c31af7Sopenharmony_ci	: TestCaseGroup(context, "function", "Function Tests"), m_glslVersion(glslVersion)
175e5c31af7Sopenharmony_ci{
176e5c31af7Sopenharmony_ci}
177e5c31af7Sopenharmony_ci
178e5c31af7Sopenharmony_ciShaderFunctionTests::~ShaderFunctionTests(void)
179e5c31af7Sopenharmony_ci{
180e5c31af7Sopenharmony_ci}
181e5c31af7Sopenharmony_ci
182e5c31af7Sopenharmony_civoid ShaderFunctionTests::init(void)
183e5c31af7Sopenharmony_ci{
184e5c31af7Sopenharmony_ci#define FUNCTION_CASE(NAME, DESCRIPTION, SHADER_SRC, EVAL_FUNC_BODY)                                      \
185e5c31af7Sopenharmony_ci	do                                                                                                    \
186e5c31af7Sopenharmony_ci	{                                                                                                     \
187e5c31af7Sopenharmony_ci		struct Eval_##NAME                                                                                \
188e5c31af7Sopenharmony_ci		{                                                                                                 \
189e5c31af7Sopenharmony_ci			static void eval(ShaderEvalContext& c) EVAL_FUNC_BODY                                         \
190e5c31af7Sopenharmony_ci		};                                                                                                \
191e5c31af7Sopenharmony_ci		addChild(createStructCase(m_context, #NAME "_vertex", DESCRIPTION, m_glslVersion, true, false,    \
192e5c31af7Sopenharmony_ci								  &Eval_##NAME::eval, DE_NULL, SHADER_SRC));                              \
193e5c31af7Sopenharmony_ci		addChild(createStructCase(m_context, #NAME "_fragment", DESCRIPTION, m_glslVersion, false, false, \
194e5c31af7Sopenharmony_ci								  &Eval_##NAME::eval, DE_NULL, SHADER_SRC));                              \
195e5c31af7Sopenharmony_ci	} while (deGetFalse())
196e5c31af7Sopenharmony_ci
197e5c31af7Sopenharmony_ci	FUNCTION_CASE(local_variable_aliasing, "Function out parameter aliases local variable",
198e5c31af7Sopenharmony_ci				  LineStream() << "${HEADER}"
199e5c31af7Sopenharmony_ci							   << ""
200e5c31af7Sopenharmony_ci							   << "bool out_params_are_distinct(float x, out float y) {"
201e5c31af7Sopenharmony_ci							   << "    y = 2.;"
202e5c31af7Sopenharmony_ci							   << "    return x == 1. && y == 2.;"
203e5c31af7Sopenharmony_ci							   << "}"
204e5c31af7Sopenharmony_ci							   << ""
205e5c31af7Sopenharmony_ci							   << "void main (void)"
206e5c31af7Sopenharmony_ci							   << "{"
207e5c31af7Sopenharmony_ci							   << "    float x = 1.;"
208e5c31af7Sopenharmony_ci							   << "    ${DST} = out_params_are_distinct(x, x) ? vec4(0.,1.,0.,1.) : vec4(1.,0.,0.,1.);"
209e5c31af7Sopenharmony_ci							   << "    ${ASSIGN_POS}"
210e5c31af7Sopenharmony_ci							   << "}",
211e5c31af7Sopenharmony_ci				  { c.color.xyz() = tcu::Vec3(0.0f, 1.0f, 0.0f); });
212e5c31af7Sopenharmony_ci
213e5c31af7Sopenharmony_ci	FUNCTION_CASE(global_variable_aliasing, "Function out parameter aliases global variable",
214e5c31af7Sopenharmony_ci				  LineStream() << "${HEADER}"
215e5c31af7Sopenharmony_ci							   << ""
216e5c31af7Sopenharmony_ci							   << "float x = 1.;"
217e5c31af7Sopenharmony_ci							   << "bool out_params_are_distinct_from_global(out float y) {"
218e5c31af7Sopenharmony_ci							   << "    y = 2.;"
219e5c31af7Sopenharmony_ci							   << "    return x == 1. && y == 2.;"
220e5c31af7Sopenharmony_ci							   << "}"
221e5c31af7Sopenharmony_ci							   << ""
222e5c31af7Sopenharmony_ci							   << "void main (void)"
223e5c31af7Sopenharmony_ci							   << "{"
224e5c31af7Sopenharmony_ci							   << "    ${DST} = out_params_are_distinct_from_global(x) ? vec4(0.,1.,0.,1.) : vec4(1.,0.,0.,1.);"
225e5c31af7Sopenharmony_ci							   << "    ${ASSIGN_POS}"
226e5c31af7Sopenharmony_ci							   << "}",
227e5c31af7Sopenharmony_ci				  { c.color.xyz() = tcu::Vec3(0.0f, 1.0f, 0.0f); });
228e5c31af7Sopenharmony_ci}
229e5c31af7Sopenharmony_ci
230e5c31af7Sopenharmony_ci} // deqp
231