1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * drawElements Quality Program OpenGL (ES) Module
3e5c31af7Sopenharmony_ci * -----------------------------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
10e5c31af7Sopenharmony_ci *
11e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
12e5c31af7Sopenharmony_ci *
13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
17e5c31af7Sopenharmony_ci * limitations under the License.
18e5c31af7Sopenharmony_ci *
19e5c31af7Sopenharmony_ci *//*!
20e5c31af7Sopenharmony_ci * \file
21e5c31af7Sopenharmony_ci * \brief Texture test utilities.
22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "glsTextureTestUtil.hpp"
25e5c31af7Sopenharmony_ci#include "gluDefs.hpp"
26e5c31af7Sopenharmony_ci#include "gluDrawUtil.hpp"
27e5c31af7Sopenharmony_ci#include "gluRenderContext.hpp"
28e5c31af7Sopenharmony_ci#include "deRandom.hpp"
29e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp"
30e5c31af7Sopenharmony_ci#include "tcuVectorUtil.hpp"
31e5c31af7Sopenharmony_ci#include "tcuTextureUtil.hpp"
32e5c31af7Sopenharmony_ci#include "tcuImageCompare.hpp"
33e5c31af7Sopenharmony_ci#include "tcuStringTemplate.hpp"
34e5c31af7Sopenharmony_ci#include "tcuTexLookupVerifier.hpp"
35e5c31af7Sopenharmony_ci#include "tcuTexVerifierUtil.hpp"
36e5c31af7Sopenharmony_ci#include "glwEnums.hpp"
37e5c31af7Sopenharmony_ci#include "glwFunctions.hpp"
38e5c31af7Sopenharmony_ci#include "qpWatchDog.h"
39e5c31af7Sopenharmony_ci#include "deStringUtil.hpp"
40e5c31af7Sopenharmony_ci
41e5c31af7Sopenharmony_ciusing tcu::TestLog;
42e5c31af7Sopenharmony_ciusing std::vector;
43e5c31af7Sopenharmony_ciusing std::string;
44e5c31af7Sopenharmony_ciusing std::map;
45e5c31af7Sopenharmony_ci
46e5c31af7Sopenharmony_ciusing namespace glu::TextureTestUtil;
47e5c31af7Sopenharmony_ci
48e5c31af7Sopenharmony_cinamespace deqp
49e5c31af7Sopenharmony_ci{
50e5c31af7Sopenharmony_cinamespace gls
51e5c31af7Sopenharmony_ci{
52e5c31af7Sopenharmony_cinamespace TextureTestUtil
53e5c31af7Sopenharmony_ci{
54e5c31af7Sopenharmony_ci
55e5c31af7Sopenharmony_ciRandomViewport::RandomViewport (const tcu::RenderTarget& renderTarget, int preferredWidth, int preferredHeight, deUint32 seed)
56e5c31af7Sopenharmony_ci	: x			(0)
57e5c31af7Sopenharmony_ci	, y			(0)
58e5c31af7Sopenharmony_ci	, width		(deMin32(preferredWidth, renderTarget.getWidth()))
59e5c31af7Sopenharmony_ci	, height	(deMin32(preferredHeight, renderTarget.getHeight()))
60e5c31af7Sopenharmony_ci{
61e5c31af7Sopenharmony_ci	de::Random rnd(seed);
62e5c31af7Sopenharmony_ci	x = rnd.getInt(0, renderTarget.getWidth()	- width);
63e5c31af7Sopenharmony_ci	y = rnd.getInt(0, renderTarget.getHeight()	- height);
64e5c31af7Sopenharmony_ci}
65e5c31af7Sopenharmony_ci
66e5c31af7Sopenharmony_ciProgramLibrary::ProgramLibrary (const glu::RenderContext& context, tcu::TestLog& log, glu::GLSLVersion glslVersion, glu::Precision texCoordPrecision)
67e5c31af7Sopenharmony_ci	: m_context				(context)
68e5c31af7Sopenharmony_ci	, m_log					(log)
69e5c31af7Sopenharmony_ci	, m_glslVersion			(glslVersion)
70e5c31af7Sopenharmony_ci	, m_texCoordPrecision	(texCoordPrecision)
71e5c31af7Sopenharmony_ci{
72e5c31af7Sopenharmony_ci}
73e5c31af7Sopenharmony_ci
74e5c31af7Sopenharmony_ciProgramLibrary::~ProgramLibrary (void)
75e5c31af7Sopenharmony_ci{
76e5c31af7Sopenharmony_ci	clear();
77e5c31af7Sopenharmony_ci}
78e5c31af7Sopenharmony_ci
79e5c31af7Sopenharmony_civoid ProgramLibrary::clear (void)
80e5c31af7Sopenharmony_ci{
81e5c31af7Sopenharmony_ci	for (map<Program, glu::ShaderProgram*>::iterator i = m_programs.begin(); i != m_programs.end(); i++)
82e5c31af7Sopenharmony_ci	{
83e5c31af7Sopenharmony_ci		delete i->second;
84e5c31af7Sopenharmony_ci		i->second = DE_NULL;
85e5c31af7Sopenharmony_ci	}
86e5c31af7Sopenharmony_ci	m_programs.clear();
87e5c31af7Sopenharmony_ci}
88e5c31af7Sopenharmony_ci
89e5c31af7Sopenharmony_ciglu::ShaderProgram* ProgramLibrary::getProgram (Program program)
90e5c31af7Sopenharmony_ci{
91e5c31af7Sopenharmony_ci	if (m_programs.find(program) != m_programs.end())
92e5c31af7Sopenharmony_ci		return m_programs[program]; // Return from cache.
93e5c31af7Sopenharmony_ci
94e5c31af7Sopenharmony_ci	static const char* vertShaderTemplate =
95e5c31af7Sopenharmony_ci		"${VTX_HEADER}"
96e5c31af7Sopenharmony_ci		"${VTX_IN} highp vec4 a_position;\n"
97e5c31af7Sopenharmony_ci		"${VTX_IN} ${PRECISION} ${TEXCOORD_TYPE} a_texCoord;\n"
98e5c31af7Sopenharmony_ci		"${VTX_OUT} ${PRECISION} ${TEXCOORD_TYPE} v_texCoord;\n"
99e5c31af7Sopenharmony_ci		"\n"
100e5c31af7Sopenharmony_ci		"void main (void)\n"
101e5c31af7Sopenharmony_ci		"{\n"
102e5c31af7Sopenharmony_ci		"	gl_Position = a_position;\n"
103e5c31af7Sopenharmony_ci		"	v_texCoord = a_texCoord;\n"
104e5c31af7Sopenharmony_ci		"}\n";
105e5c31af7Sopenharmony_ci	static const char* fragShaderTemplate =
106e5c31af7Sopenharmony_ci		"${FRAG_HEADER}"
107e5c31af7Sopenharmony_ci		"${FRAG_IN} ${PRECISION} ${TEXCOORD_TYPE} v_texCoord;\n"
108e5c31af7Sopenharmony_ci		"uniform ${PRECISION} float u_bias;\n"
109e5c31af7Sopenharmony_ci		"uniform ${PRECISION} float u_ref;\n"
110e5c31af7Sopenharmony_ci		"uniform ${PRECISION} vec4 u_colorScale;\n"
111e5c31af7Sopenharmony_ci		"uniform ${PRECISION} vec4 u_colorBias;\n"
112e5c31af7Sopenharmony_ci		"uniform ${PRECISION} ${SAMPLER_TYPE} u_sampler;\n"
113e5c31af7Sopenharmony_ci		"\n"
114e5c31af7Sopenharmony_ci		"void main (void)\n"
115e5c31af7Sopenharmony_ci		"{\n"
116e5c31af7Sopenharmony_ci		"	${FRAG_COLOR} = ${LOOKUP} * u_colorScale + u_colorBias;\n"
117e5c31af7Sopenharmony_ci		"}\n";
118e5c31af7Sopenharmony_ci
119e5c31af7Sopenharmony_ci	map<string, string> params;
120e5c31af7Sopenharmony_ci
121e5c31af7Sopenharmony_ci	bool	isCube		= de::inRange<int>(program, PROGRAM_CUBE_FLOAT, PROGRAM_CUBE_SHADOW_BIAS);
122e5c31af7Sopenharmony_ci	bool	isArray		= de::inRange<int>(program, PROGRAM_2D_ARRAY_FLOAT, PROGRAM_2D_ARRAY_SHADOW)
123e5c31af7Sopenharmony_ci							|| de::inRange<int>(program, PROGRAM_1D_ARRAY_FLOAT, PROGRAM_1D_ARRAY_SHADOW);
124e5c31af7Sopenharmony_ci
125e5c31af7Sopenharmony_ci	bool	is1D		= de::inRange<int>(program, PROGRAM_1D_FLOAT, PROGRAM_1D_UINT_BIAS)
126e5c31af7Sopenharmony_ci							|| de::inRange<int>(program, PROGRAM_1D_ARRAY_FLOAT, PROGRAM_1D_ARRAY_SHADOW)
127e5c31af7Sopenharmony_ci							|| de::inRange<int>(program, PROGRAM_BUFFER_FLOAT, PROGRAM_BUFFER_UINT);
128e5c31af7Sopenharmony_ci
129e5c31af7Sopenharmony_ci	bool	is2D		= de::inRange<int>(program, PROGRAM_2D_FLOAT, PROGRAM_2D_UINT_BIAS)
130e5c31af7Sopenharmony_ci							|| de::inRange<int>(program, PROGRAM_2D_ARRAY_FLOAT, PROGRAM_2D_ARRAY_SHADOW);
131e5c31af7Sopenharmony_ci
132e5c31af7Sopenharmony_ci	bool	is3D		= de::inRange<int>(program, PROGRAM_3D_FLOAT, PROGRAM_3D_UINT_BIAS);
133e5c31af7Sopenharmony_ci	bool	isCubeArray	= de::inRange<int>(program, PROGRAM_CUBE_ARRAY_FLOAT, PROGRAM_CUBE_ARRAY_SHADOW);
134e5c31af7Sopenharmony_ci	bool	isBuffer	= de::inRange<int>(program, PROGRAM_BUFFER_FLOAT, PROGRAM_BUFFER_UINT);
135e5c31af7Sopenharmony_ci
136e5c31af7Sopenharmony_ci	if (m_glslVersion == glu::GLSL_VERSION_100_ES)
137e5c31af7Sopenharmony_ci	{
138e5c31af7Sopenharmony_ci		params["FRAG_HEADER"]	= "";
139e5c31af7Sopenharmony_ci		params["VTX_HEADER"]	= "";
140e5c31af7Sopenharmony_ci		params["VTX_IN"]		= "attribute";
141e5c31af7Sopenharmony_ci		params["VTX_OUT"]		= "varying";
142e5c31af7Sopenharmony_ci		params["FRAG_IN"]		= "varying";
143e5c31af7Sopenharmony_ci		params["FRAG_COLOR"]	= "gl_FragColor";
144e5c31af7Sopenharmony_ci	}
145e5c31af7Sopenharmony_ci	else if (m_glslVersion == glu::GLSL_VERSION_300_ES || m_glslVersion == glu::GLSL_VERSION_310_ES || m_glslVersion == glu::GLSL_VERSION_320_ES || m_glslVersion > glu::GLSL_VERSION_330)
146e5c31af7Sopenharmony_ci	{
147e5c31af7Sopenharmony_ci		const string	version	= glu::getGLSLVersionDeclaration(m_glslVersion);
148e5c31af7Sopenharmony_ci		const char*		ext		= DE_NULL;
149e5c31af7Sopenharmony_ci
150e5c31af7Sopenharmony_ci		if (glu::glslVersionIsES(m_glslVersion) && m_glslVersion != glu::GLSL_VERSION_320_ES) {
151e5c31af7Sopenharmony_ci			if (isCubeArray)
152e5c31af7Sopenharmony_ci				ext = "GL_EXT_texture_cube_map_array";
153e5c31af7Sopenharmony_ci			else if (isBuffer)
154e5c31af7Sopenharmony_ci				ext = "GL_EXT_texture_buffer";
155e5c31af7Sopenharmony_ci		}
156e5c31af7Sopenharmony_ci
157e5c31af7Sopenharmony_ci		params["FRAG_HEADER"]	= version + (ext ? string("\n#extension ") + ext + " : require" : string()) + "\nlayout(location = 0) out mediump vec4 dEQP_FragColor;\n";
158e5c31af7Sopenharmony_ci		params["VTX_HEADER"]	= version + "\n";
159e5c31af7Sopenharmony_ci		params["VTX_IN"]		= "in";
160e5c31af7Sopenharmony_ci		params["VTX_OUT"]		= "out";
161e5c31af7Sopenharmony_ci		params["FRAG_IN"]		= "in";
162e5c31af7Sopenharmony_ci		params["FRAG_COLOR"]	= "dEQP_FragColor";
163e5c31af7Sopenharmony_ci	}
164e5c31af7Sopenharmony_ci	else
165e5c31af7Sopenharmony_ci		DE_FATAL("Unsupported version");
166e5c31af7Sopenharmony_ci
167e5c31af7Sopenharmony_ci	params["PRECISION"]		= glu::getPrecisionName(m_texCoordPrecision);
168e5c31af7Sopenharmony_ci
169e5c31af7Sopenharmony_ci	if (isCubeArray)
170e5c31af7Sopenharmony_ci		params["TEXCOORD_TYPE"]	= "vec4";
171e5c31af7Sopenharmony_ci	else if (isCube || (is2D && isArray) || is3D)
172e5c31af7Sopenharmony_ci		params["TEXCOORD_TYPE"]	= "vec3";
173e5c31af7Sopenharmony_ci	else if ((is1D && isArray) || is2D)
174e5c31af7Sopenharmony_ci		params["TEXCOORD_TYPE"]	= "vec2";
175e5c31af7Sopenharmony_ci	else if (is1D)
176e5c31af7Sopenharmony_ci		params["TEXCOORD_TYPE"]	= "float";
177e5c31af7Sopenharmony_ci	else
178e5c31af7Sopenharmony_ci		DE_ASSERT(DE_FALSE);
179e5c31af7Sopenharmony_ci
180e5c31af7Sopenharmony_ci	const char*	sampler	= DE_NULL;
181e5c31af7Sopenharmony_ci	const char*	lookup	= DE_NULL;
182e5c31af7Sopenharmony_ci
183e5c31af7Sopenharmony_ci	if (m_glslVersion == glu::GLSL_VERSION_300_ES || m_glslVersion == glu::GLSL_VERSION_310_ES || m_glslVersion == glu::GLSL_VERSION_320_ES || m_glslVersion > glu::GLSL_VERSION_330)
184e5c31af7Sopenharmony_ci	{
185e5c31af7Sopenharmony_ci		switch (program)
186e5c31af7Sopenharmony_ci		{
187e5c31af7Sopenharmony_ci			case PROGRAM_2D_FLOAT:			sampler = "sampler2D";				lookup = "texture(u_sampler, v_texCoord)";												break;
188e5c31af7Sopenharmony_ci			case PROGRAM_2D_INT:			sampler = "isampler2D";				lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
189e5c31af7Sopenharmony_ci			case PROGRAM_2D_UINT:			sampler = "usampler2D";				lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
190e5c31af7Sopenharmony_ci			case PROGRAM_2D_SHADOW:			sampler = "sampler2DShadow";		lookup = "vec4(texture(u_sampler, vec3(v_texCoord, u_ref)), 0.0, 0.0, 1.0)";			break;
191e5c31af7Sopenharmony_ci			case PROGRAM_2D_FLOAT_BIAS:		sampler = "sampler2D";				lookup = "texture(u_sampler, v_texCoord, u_bias)";										break;
192e5c31af7Sopenharmony_ci			case PROGRAM_2D_INT_BIAS:		sampler = "isampler2D";				lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";								break;
193e5c31af7Sopenharmony_ci			case PROGRAM_2D_UINT_BIAS:		sampler = "usampler2D";				lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";								break;
194e5c31af7Sopenharmony_ci			case PROGRAM_2D_SHADOW_BIAS:	sampler = "sampler2DShadow";		lookup = "vec4(texture(u_sampler, vec3(v_texCoord, u_ref), u_bias), 0.0, 0.0, 1.0)";	break;
195e5c31af7Sopenharmony_ci			case PROGRAM_1D_FLOAT:			sampler = "sampler1D";				lookup = "texture(u_sampler, v_texCoord)";												break;
196e5c31af7Sopenharmony_ci			case PROGRAM_1D_INT:			sampler = "isampler1D";				lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
197e5c31af7Sopenharmony_ci			case PROGRAM_1D_UINT:			sampler = "usampler1D";				lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
198e5c31af7Sopenharmony_ci			case PROGRAM_1D_SHADOW:			sampler = "sampler1DShadow";		lookup = "vec4(texture(u_sampler, vec3(v_texCoord, u_ref)), 0.0, 0.0, 1.0)";			break;
199e5c31af7Sopenharmony_ci			case PROGRAM_1D_FLOAT_BIAS:		sampler = "sampler1D";				lookup = "texture(u_sampler, v_texCoord, u_bias)";										break;
200e5c31af7Sopenharmony_ci			case PROGRAM_1D_INT_BIAS:		sampler = "isampler1D";				lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";								break;
201e5c31af7Sopenharmony_ci			case PROGRAM_1D_UINT_BIAS:		sampler = "usampler1D";				lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";								break;
202e5c31af7Sopenharmony_ci			case PROGRAM_1D_SHADOW_BIAS:	sampler = "sampler1DShadow";		lookup = "vec4(texture(u_sampler, vec3(v_texCoord, u_ref), u_bias), 0.0, 0.0, 1.0)";	break;
203e5c31af7Sopenharmony_ci			case PROGRAM_CUBE_FLOAT:		sampler = "samplerCube";			lookup = "texture(u_sampler, v_texCoord)";												break;
204e5c31af7Sopenharmony_ci			case PROGRAM_CUBE_INT:			sampler = "isamplerCube";			lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
205e5c31af7Sopenharmony_ci			case PROGRAM_CUBE_UINT:			sampler = "usamplerCube";			lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
206e5c31af7Sopenharmony_ci			case PROGRAM_CUBE_SHADOW:		sampler = "samplerCubeShadow";		lookup = "vec4(texture(u_sampler, vec4(v_texCoord, u_ref)), 0.0, 0.0, 1.0)";			break;
207e5c31af7Sopenharmony_ci			case PROGRAM_CUBE_FLOAT_BIAS:	sampler = "samplerCube";			lookup = "texture(u_sampler, v_texCoord, u_bias)";										break;
208e5c31af7Sopenharmony_ci			case PROGRAM_CUBE_INT_BIAS:		sampler = "isamplerCube";			lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";								break;
209e5c31af7Sopenharmony_ci			case PROGRAM_CUBE_UINT_BIAS:	sampler = "usamplerCube";			lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";								break;
210e5c31af7Sopenharmony_ci			case PROGRAM_CUBE_SHADOW_BIAS:	sampler = "samplerCubeShadow";		lookup = "vec4(texture(u_sampler, vec4(v_texCoord, u_ref), u_bias), 0.0, 0.0, 1.0)";	break;
211e5c31af7Sopenharmony_ci			case PROGRAM_2D_ARRAY_FLOAT:	sampler = "sampler2DArray";			lookup = "texture(u_sampler, v_texCoord)";												break;
212e5c31af7Sopenharmony_ci			case PROGRAM_2D_ARRAY_INT:		sampler = "isampler2DArray";		lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
213e5c31af7Sopenharmony_ci			case PROGRAM_2D_ARRAY_UINT:		sampler = "usampler2DArray";		lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
214e5c31af7Sopenharmony_ci			case PROGRAM_2D_ARRAY_SHADOW:	sampler = "sampler2DArrayShadow";	lookup = "vec4(texture(u_sampler, vec4(v_texCoord, u_ref)), 0.0, 0.0, 1.0)";			break;
215e5c31af7Sopenharmony_ci			case PROGRAM_3D_FLOAT:			sampler = "sampler3D";				lookup = "texture(u_sampler, v_texCoord)";												break;
216e5c31af7Sopenharmony_ci			case PROGRAM_3D_INT:			sampler = "isampler3D";				lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
217e5c31af7Sopenharmony_ci			case PROGRAM_3D_UINT:			sampler = "usampler3D";				lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
218e5c31af7Sopenharmony_ci			case PROGRAM_3D_FLOAT_BIAS:		sampler = "sampler3D";				lookup = "texture(u_sampler, v_texCoord, u_bias)";										break;
219e5c31af7Sopenharmony_ci			case PROGRAM_3D_INT_BIAS:		sampler = "isampler3D";				lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";								break;
220e5c31af7Sopenharmony_ci			case PROGRAM_3D_UINT_BIAS:		sampler = "usampler3D";				lookup = "vec4(texture(u_sampler, v_texCoord, u_bias))";								break;
221e5c31af7Sopenharmony_ci			case PROGRAM_CUBE_ARRAY_FLOAT:	sampler = "samplerCubeArray";		lookup = "texture(u_sampler, v_texCoord)";												break;
222e5c31af7Sopenharmony_ci			case PROGRAM_CUBE_ARRAY_INT:	sampler = "isamplerCubeArray";		lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
223e5c31af7Sopenharmony_ci			case PROGRAM_CUBE_ARRAY_UINT:	sampler = "usamplerCubeArray";		lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
224e5c31af7Sopenharmony_ci			case PROGRAM_CUBE_ARRAY_SHADOW:	sampler = "samplerCubeArrayShadow";	lookup = "vec4(texture(u_sampler, vec4(v_texCoord, u_ref)), 0.0, 0.0, 1.0)";			break;
225e5c31af7Sopenharmony_ci			case PROGRAM_1D_ARRAY_FLOAT:	sampler = "sampler1DArray";			lookup = "texture(u_sampler, v_texCoord)";												break;
226e5c31af7Sopenharmony_ci			case PROGRAM_1D_ARRAY_INT:		sampler = "isampler1DArray";		lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
227e5c31af7Sopenharmony_ci			case PROGRAM_1D_ARRAY_UINT:		sampler = "usampler1DArray";		lookup = "vec4(texture(u_sampler, v_texCoord))";										break;
228e5c31af7Sopenharmony_ci			case PROGRAM_1D_ARRAY_SHADOW:	sampler = "sampler1DArrayShadow";	lookup = "vec4(texture(u_sampler, vec4(v_texCoord, u_ref)), 0.0, 0.0, 1.0)";			break;
229e5c31af7Sopenharmony_ci			case PROGRAM_BUFFER_FLOAT:		sampler = "samplerBuffer";			lookup = "texelFetch(u_sampler, int(v_texCoord))";										break;
230e5c31af7Sopenharmony_ci			case PROGRAM_BUFFER_INT:		sampler = "isamplerBuffer";			lookup = "vec4(texelFetch(u_sampler, int(v_texCoord)))";								break;
231e5c31af7Sopenharmony_ci			case PROGRAM_BUFFER_UINT:		sampler = "usamplerBuffer";			lookup = "vec4(texelFetch(u_sampler, int(v_texCoord)))";								break;
232e5c31af7Sopenharmony_ci			default:
233e5c31af7Sopenharmony_ci				DE_ASSERT(false);
234e5c31af7Sopenharmony_ci		}
235e5c31af7Sopenharmony_ci	}
236e5c31af7Sopenharmony_ci	else if (m_glslVersion == glu::GLSL_VERSION_100_ES)
237e5c31af7Sopenharmony_ci	{
238e5c31af7Sopenharmony_ci		sampler = isCube ? "samplerCube" : "sampler2D";
239e5c31af7Sopenharmony_ci
240e5c31af7Sopenharmony_ci		switch (program)
241e5c31af7Sopenharmony_ci		{
242e5c31af7Sopenharmony_ci			case PROGRAM_2D_FLOAT:			lookup = "texture2D(u_sampler, v_texCoord)";			break;
243e5c31af7Sopenharmony_ci			case PROGRAM_2D_FLOAT_BIAS:		lookup = "texture2D(u_sampler, v_texCoord, u_bias)";	break;
244e5c31af7Sopenharmony_ci			case PROGRAM_CUBE_FLOAT:		lookup = "textureCube(u_sampler, v_texCoord)";			break;
245e5c31af7Sopenharmony_ci			case PROGRAM_CUBE_FLOAT_BIAS:	lookup = "textureCube(u_sampler, v_texCoord, u_bias)";	break;
246e5c31af7Sopenharmony_ci			default:
247e5c31af7Sopenharmony_ci				DE_ASSERT(false);
248e5c31af7Sopenharmony_ci		}
249e5c31af7Sopenharmony_ci	}
250e5c31af7Sopenharmony_ci	else
251e5c31af7Sopenharmony_ci		DE_FATAL("Unsupported version");
252e5c31af7Sopenharmony_ci
253e5c31af7Sopenharmony_ci	params["SAMPLER_TYPE"]	= sampler;
254e5c31af7Sopenharmony_ci	params["LOOKUP"]		= lookup;
255e5c31af7Sopenharmony_ci
256e5c31af7Sopenharmony_ci	std::string vertSrc = tcu::StringTemplate(vertShaderTemplate).specialize(params);
257e5c31af7Sopenharmony_ci	std::string fragSrc = tcu::StringTemplate(fragShaderTemplate).specialize(params);
258e5c31af7Sopenharmony_ci
259e5c31af7Sopenharmony_ci	glu::ShaderProgram* progObj = new glu::ShaderProgram(m_context, glu::makeVtxFragSources(vertSrc, fragSrc));
260e5c31af7Sopenharmony_ci	if (!progObj->isOk())
261e5c31af7Sopenharmony_ci	{
262e5c31af7Sopenharmony_ci		m_log << *progObj;
263e5c31af7Sopenharmony_ci		delete progObj;
264e5c31af7Sopenharmony_ci		TCU_FAIL("Failed to compile shader program");
265e5c31af7Sopenharmony_ci	}
266e5c31af7Sopenharmony_ci
267e5c31af7Sopenharmony_ci	try
268e5c31af7Sopenharmony_ci	{
269e5c31af7Sopenharmony_ci		m_programs[program] = progObj;
270e5c31af7Sopenharmony_ci	}
271e5c31af7Sopenharmony_ci	catch (...)
272e5c31af7Sopenharmony_ci	{
273e5c31af7Sopenharmony_ci		delete progObj;
274e5c31af7Sopenharmony_ci		throw;
275e5c31af7Sopenharmony_ci	}
276e5c31af7Sopenharmony_ci
277e5c31af7Sopenharmony_ci	return progObj;
278e5c31af7Sopenharmony_ci}
279e5c31af7Sopenharmony_ci
280e5c31af7Sopenharmony_ciglu::Precision ProgramLibrary::getTexCoordPrecision()
281e5c31af7Sopenharmony_ci{
282e5c31af7Sopenharmony_ci	return m_texCoordPrecision;
283e5c31af7Sopenharmony_ci}
284e5c31af7Sopenharmony_ci
285e5c31af7Sopenharmony_ciTextureRenderer::TextureRenderer (const glu::RenderContext& context, tcu::TestLog& log, glu::GLSLVersion glslVersion, glu::Precision texCoordPrecision)
286e5c31af7Sopenharmony_ci	: m_renderCtx		(context)
287e5c31af7Sopenharmony_ci	, m_log				(log)
288e5c31af7Sopenharmony_ci	, m_programLibrary	(context, log, glslVersion, texCoordPrecision)
289e5c31af7Sopenharmony_ci{
290e5c31af7Sopenharmony_ci}
291e5c31af7Sopenharmony_ci
292e5c31af7Sopenharmony_ciTextureRenderer::~TextureRenderer (void)
293e5c31af7Sopenharmony_ci{
294e5c31af7Sopenharmony_ci	clear();
295e5c31af7Sopenharmony_ci}
296e5c31af7Sopenharmony_ci
297e5c31af7Sopenharmony_civoid TextureRenderer::clear (void)
298e5c31af7Sopenharmony_ci{
299e5c31af7Sopenharmony_ci	m_programLibrary.clear();
300e5c31af7Sopenharmony_ci}
301e5c31af7Sopenharmony_ci
302e5c31af7Sopenharmony_civoid TextureRenderer::renderQuad (int texUnit, const float* texCoord, TextureType texType)
303e5c31af7Sopenharmony_ci{
304e5c31af7Sopenharmony_ci	renderQuad(texUnit, texCoord, RenderParams(texType));
305e5c31af7Sopenharmony_ci}
306e5c31af7Sopenharmony_ci
307e5c31af7Sopenharmony_civoid TextureRenderer::renderQuad (int texUnit, const float* texCoord, const RenderParams& params)
308e5c31af7Sopenharmony_ci{
309e5c31af7Sopenharmony_ci	const glw::Functions&	gl			= m_renderCtx.getFunctions();
310e5c31af7Sopenharmony_ci	tcu::Vec4				wCoord		= params.flags & RenderParams::PROJECTED ? params.w : tcu::Vec4(1.0f);
311e5c31af7Sopenharmony_ci	bool					useBias		= !!(params.flags & RenderParams::USE_BIAS);
312e5c31af7Sopenharmony_ci	bool					logUniforms	= !!(params.flags & RenderParams::LOG_UNIFORMS);
313e5c31af7Sopenharmony_ci
314e5c31af7Sopenharmony_ci	// Render quad with texture.
315e5c31af7Sopenharmony_ci	float position[] =
316e5c31af7Sopenharmony_ci	{
317e5c31af7Sopenharmony_ci		-1.0f*wCoord.x(), -1.0f*wCoord.x(), 0.0f, wCoord.x(),
318e5c31af7Sopenharmony_ci		-1.0f*wCoord.y(), +1.0f*wCoord.y(), 0.0f, wCoord.y(),
319e5c31af7Sopenharmony_ci		+1.0f*wCoord.z(), -1.0f*wCoord.z(), 0.0f, wCoord.z(),
320e5c31af7Sopenharmony_ci		+1.0f*wCoord.w(), +1.0f*wCoord.w(), 0.0f, wCoord.w()
321e5c31af7Sopenharmony_ci	};
322e5c31af7Sopenharmony_ci	static const deUint16 indices[] = { 0, 1, 2, 2, 1, 3 };
323e5c31af7Sopenharmony_ci
324e5c31af7Sopenharmony_ci	Program progSpec	= PROGRAM_LAST;
325e5c31af7Sopenharmony_ci	int		numComps	= 0;
326e5c31af7Sopenharmony_ci	if (params.texType == TEXTURETYPE_2D)
327e5c31af7Sopenharmony_ci	{
328e5c31af7Sopenharmony_ci		numComps = 2;
329e5c31af7Sopenharmony_ci
330e5c31af7Sopenharmony_ci		switch (params.samplerType)
331e5c31af7Sopenharmony_ci		{
332e5c31af7Sopenharmony_ci			case SAMPLERTYPE_FLOAT:		progSpec = useBias ? PROGRAM_2D_FLOAT_BIAS	: PROGRAM_2D_FLOAT;		break;
333e5c31af7Sopenharmony_ci			case SAMPLERTYPE_INT:		progSpec = useBias ? PROGRAM_2D_INT_BIAS	: PROGRAM_2D_INT;		break;
334e5c31af7Sopenharmony_ci			case SAMPLERTYPE_UINT:		progSpec = useBias ? PROGRAM_2D_UINT_BIAS	: PROGRAM_2D_UINT;		break;
335e5c31af7Sopenharmony_ci			case SAMPLERTYPE_SHADOW:	progSpec = useBias ? PROGRAM_2D_SHADOW_BIAS	: PROGRAM_2D_SHADOW;	break;
336e5c31af7Sopenharmony_ci			default:					DE_ASSERT(false);
337e5c31af7Sopenharmony_ci		}
338e5c31af7Sopenharmony_ci	}
339e5c31af7Sopenharmony_ci	else if (params.texType == TEXTURETYPE_1D)
340e5c31af7Sopenharmony_ci	{
341e5c31af7Sopenharmony_ci		numComps = 1;
342e5c31af7Sopenharmony_ci
343e5c31af7Sopenharmony_ci		switch (params.samplerType)
344e5c31af7Sopenharmony_ci		{
345e5c31af7Sopenharmony_ci			case SAMPLERTYPE_FLOAT:		progSpec = useBias ? PROGRAM_1D_FLOAT_BIAS	: PROGRAM_1D_FLOAT;		break;
346e5c31af7Sopenharmony_ci			case SAMPLERTYPE_INT:		progSpec = useBias ? PROGRAM_1D_INT_BIAS	: PROGRAM_1D_INT;		break;
347e5c31af7Sopenharmony_ci			case SAMPLERTYPE_UINT:		progSpec = useBias ? PROGRAM_1D_UINT_BIAS	: PROGRAM_1D_UINT;		break;
348e5c31af7Sopenharmony_ci			case SAMPLERTYPE_SHADOW:	progSpec = useBias ? PROGRAM_1D_SHADOW_BIAS	: PROGRAM_1D_SHADOW;	break;
349e5c31af7Sopenharmony_ci			default:					DE_ASSERT(false);
350e5c31af7Sopenharmony_ci		}
351e5c31af7Sopenharmony_ci	}
352e5c31af7Sopenharmony_ci	else if (params.texType == TEXTURETYPE_CUBE)
353e5c31af7Sopenharmony_ci	{
354e5c31af7Sopenharmony_ci		numComps = 3;
355e5c31af7Sopenharmony_ci
356e5c31af7Sopenharmony_ci		switch (params.samplerType)
357e5c31af7Sopenharmony_ci		{
358e5c31af7Sopenharmony_ci			case SAMPLERTYPE_FLOAT:		progSpec = useBias ? PROGRAM_CUBE_FLOAT_BIAS	: PROGRAM_CUBE_FLOAT;	break;
359e5c31af7Sopenharmony_ci			case SAMPLERTYPE_INT:		progSpec = useBias ? PROGRAM_CUBE_INT_BIAS		: PROGRAM_CUBE_INT;		break;
360e5c31af7Sopenharmony_ci			case SAMPLERTYPE_UINT:		progSpec = useBias ? PROGRAM_CUBE_UINT_BIAS		: PROGRAM_CUBE_UINT;	break;
361e5c31af7Sopenharmony_ci			case SAMPLERTYPE_SHADOW:	progSpec = useBias ? PROGRAM_CUBE_SHADOW_BIAS	: PROGRAM_CUBE_SHADOW;	break;
362e5c31af7Sopenharmony_ci			default:					DE_ASSERT(false);
363e5c31af7Sopenharmony_ci		}
364e5c31af7Sopenharmony_ci	}
365e5c31af7Sopenharmony_ci	else if (params.texType == TEXTURETYPE_3D)
366e5c31af7Sopenharmony_ci	{
367e5c31af7Sopenharmony_ci		numComps = 3;
368e5c31af7Sopenharmony_ci
369e5c31af7Sopenharmony_ci		switch (params.samplerType)
370e5c31af7Sopenharmony_ci		{
371e5c31af7Sopenharmony_ci			case SAMPLERTYPE_FLOAT:		progSpec = useBias ? PROGRAM_3D_FLOAT_BIAS	: PROGRAM_3D_FLOAT;		break;
372e5c31af7Sopenharmony_ci			case SAMPLERTYPE_INT:		progSpec = useBias ? PROGRAM_3D_INT_BIAS	: PROGRAM_3D_INT;		break;
373e5c31af7Sopenharmony_ci			case SAMPLERTYPE_UINT:		progSpec = useBias ? PROGRAM_3D_UINT_BIAS	: PROGRAM_3D_UINT;		break;
374e5c31af7Sopenharmony_ci			default:					DE_ASSERT(false);
375e5c31af7Sopenharmony_ci		}
376e5c31af7Sopenharmony_ci	}
377e5c31af7Sopenharmony_ci	else if (params.texType == TEXTURETYPE_2D_ARRAY)
378e5c31af7Sopenharmony_ci	{
379e5c31af7Sopenharmony_ci		DE_ASSERT(!useBias); // \todo [2012-02-17 pyry] Support bias.
380e5c31af7Sopenharmony_ci
381e5c31af7Sopenharmony_ci		numComps = 3;
382e5c31af7Sopenharmony_ci
383e5c31af7Sopenharmony_ci		switch (params.samplerType)
384e5c31af7Sopenharmony_ci		{
385e5c31af7Sopenharmony_ci			case SAMPLERTYPE_FLOAT:		progSpec = PROGRAM_2D_ARRAY_FLOAT;	break;
386e5c31af7Sopenharmony_ci			case SAMPLERTYPE_INT:		progSpec = PROGRAM_2D_ARRAY_INT;	break;
387e5c31af7Sopenharmony_ci			case SAMPLERTYPE_UINT:		progSpec = PROGRAM_2D_ARRAY_UINT;	break;
388e5c31af7Sopenharmony_ci			case SAMPLERTYPE_SHADOW:	progSpec = PROGRAM_2D_ARRAY_SHADOW;	break;
389e5c31af7Sopenharmony_ci			default:					DE_ASSERT(false);
390e5c31af7Sopenharmony_ci		}
391e5c31af7Sopenharmony_ci	}
392e5c31af7Sopenharmony_ci	else if (params.texType == TEXTURETYPE_CUBE_ARRAY)
393e5c31af7Sopenharmony_ci	{
394e5c31af7Sopenharmony_ci		DE_ASSERT(!useBias);
395e5c31af7Sopenharmony_ci
396e5c31af7Sopenharmony_ci		numComps = 4;
397e5c31af7Sopenharmony_ci
398e5c31af7Sopenharmony_ci		switch (params.samplerType)
399e5c31af7Sopenharmony_ci		{
400e5c31af7Sopenharmony_ci			case SAMPLERTYPE_FLOAT:		progSpec = PROGRAM_CUBE_ARRAY_FLOAT;	break;
401e5c31af7Sopenharmony_ci			case SAMPLERTYPE_INT:		progSpec = PROGRAM_CUBE_ARRAY_INT;		break;
402e5c31af7Sopenharmony_ci			case SAMPLERTYPE_UINT:		progSpec = PROGRAM_CUBE_ARRAY_UINT;		break;
403e5c31af7Sopenharmony_ci			case SAMPLERTYPE_SHADOW:	progSpec = PROGRAM_CUBE_ARRAY_SHADOW;	break;
404e5c31af7Sopenharmony_ci			default:					DE_ASSERT(false);
405e5c31af7Sopenharmony_ci		}
406e5c31af7Sopenharmony_ci	}
407e5c31af7Sopenharmony_ci	else if (params.texType == TEXTURETYPE_1D_ARRAY)
408e5c31af7Sopenharmony_ci	{
409e5c31af7Sopenharmony_ci		DE_ASSERT(!useBias); // \todo [2012-02-17 pyry] Support bias.
410e5c31af7Sopenharmony_ci
411e5c31af7Sopenharmony_ci		numComps = 2;
412e5c31af7Sopenharmony_ci
413e5c31af7Sopenharmony_ci		switch (params.samplerType)
414e5c31af7Sopenharmony_ci		{
415e5c31af7Sopenharmony_ci			case SAMPLERTYPE_FLOAT:		progSpec = PROGRAM_1D_ARRAY_FLOAT;	break;
416e5c31af7Sopenharmony_ci			case SAMPLERTYPE_INT:		progSpec = PROGRAM_1D_ARRAY_INT;	break;
417e5c31af7Sopenharmony_ci			case SAMPLERTYPE_UINT:		progSpec = PROGRAM_1D_ARRAY_UINT;	break;
418e5c31af7Sopenharmony_ci			case SAMPLERTYPE_SHADOW:	progSpec = PROGRAM_1D_ARRAY_SHADOW;	break;
419e5c31af7Sopenharmony_ci			default:					DE_ASSERT(false);
420e5c31af7Sopenharmony_ci		}
421e5c31af7Sopenharmony_ci	}
422e5c31af7Sopenharmony_ci	else if (params.texType == TEXTURETYPE_BUFFER)
423e5c31af7Sopenharmony_ci	{
424e5c31af7Sopenharmony_ci		numComps = 1;
425e5c31af7Sopenharmony_ci
426e5c31af7Sopenharmony_ci		switch (params.samplerType)
427e5c31af7Sopenharmony_ci		{
428e5c31af7Sopenharmony_ci			case SAMPLERTYPE_FETCH_FLOAT:	progSpec = PROGRAM_BUFFER_FLOAT;	break;
429e5c31af7Sopenharmony_ci			case SAMPLERTYPE_FETCH_INT:		progSpec = PROGRAM_BUFFER_INT;		break;
430e5c31af7Sopenharmony_ci			case SAMPLERTYPE_FETCH_UINT:	progSpec = PROGRAM_BUFFER_UINT;		break;
431e5c31af7Sopenharmony_ci			default:						DE_ASSERT(false);
432e5c31af7Sopenharmony_ci		}
433e5c31af7Sopenharmony_ci	}
434e5c31af7Sopenharmony_ci	else
435e5c31af7Sopenharmony_ci		DE_ASSERT(DE_FALSE);
436e5c31af7Sopenharmony_ci
437e5c31af7Sopenharmony_ci	glu::ShaderProgram* program = m_programLibrary.getProgram(progSpec);
438e5c31af7Sopenharmony_ci
439e5c31af7Sopenharmony_ci	// \todo [2012-09-26 pyry] Move to ProgramLibrary and log unique programs only(?)
440e5c31af7Sopenharmony_ci	if (params.flags & RenderParams::LOG_PROGRAMS)
441e5c31af7Sopenharmony_ci		m_log << *program;
442e5c31af7Sopenharmony_ci
443e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Set vertex attributes");
444e5c31af7Sopenharmony_ci
445e5c31af7Sopenharmony_ci	// Program and uniforms.
446e5c31af7Sopenharmony_ci	deUint32 prog = program->getProgram();
447e5c31af7Sopenharmony_ci	gl.useProgram(prog);
448e5c31af7Sopenharmony_ci
449e5c31af7Sopenharmony_ci	gl.uniform1i(gl.getUniformLocation(prog, "u_sampler"), texUnit);
450e5c31af7Sopenharmony_ci	if (logUniforms)
451e5c31af7Sopenharmony_ci		m_log << TestLog::Message << "u_sampler = " << texUnit << TestLog::EndMessage;
452e5c31af7Sopenharmony_ci
453e5c31af7Sopenharmony_ci	if (useBias)
454e5c31af7Sopenharmony_ci	{
455e5c31af7Sopenharmony_ci		gl.uniform1f(gl.getUniformLocation(prog, "u_bias"), params.bias);
456e5c31af7Sopenharmony_ci		if (logUniforms)
457e5c31af7Sopenharmony_ci			m_log << TestLog::Message << "u_bias = " << params.bias << TestLog::EndMessage;
458e5c31af7Sopenharmony_ci	}
459e5c31af7Sopenharmony_ci
460e5c31af7Sopenharmony_ci	if (params.samplerType == SAMPLERTYPE_SHADOW)
461e5c31af7Sopenharmony_ci	{
462e5c31af7Sopenharmony_ci		gl.uniform1f(gl.getUniformLocation(prog, "u_ref"), params.ref);
463e5c31af7Sopenharmony_ci		if (logUniforms)
464e5c31af7Sopenharmony_ci			m_log << TestLog::Message << "u_ref = " << params.ref << TestLog::EndMessage;
465e5c31af7Sopenharmony_ci	}
466e5c31af7Sopenharmony_ci
467e5c31af7Sopenharmony_ci	gl.uniform4fv(gl.getUniformLocation(prog, "u_colorScale"),	1, params.colorScale.getPtr());
468e5c31af7Sopenharmony_ci	gl.uniform4fv(gl.getUniformLocation(prog, "u_colorBias"),	1, params.colorBias.getPtr());
469e5c31af7Sopenharmony_ci
470e5c31af7Sopenharmony_ci	if (logUniforms)
471e5c31af7Sopenharmony_ci	{
472e5c31af7Sopenharmony_ci		m_log << TestLog::Message << "u_colorScale = " << params.colorScale << TestLog::EndMessage;
473e5c31af7Sopenharmony_ci		m_log << TestLog::Message << "u_colorBias = " << params.colorBias << TestLog::EndMessage;
474e5c31af7Sopenharmony_ci	}
475e5c31af7Sopenharmony_ci
476e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "Set program state");
477e5c31af7Sopenharmony_ci
478e5c31af7Sopenharmony_ci	{
479e5c31af7Sopenharmony_ci		const glu::VertexArrayBinding vertexArrays[] =
480e5c31af7Sopenharmony_ci		{
481e5c31af7Sopenharmony_ci			glu::va::Float("a_position",	4,			4, 0, &position[0]),
482e5c31af7Sopenharmony_ci			glu::va::Float("a_texCoord",	numComps,	4, 0, texCoord)
483e5c31af7Sopenharmony_ci		};
484e5c31af7Sopenharmony_ci		glu::draw(m_renderCtx, prog, DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
485e5c31af7Sopenharmony_ci				  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
486e5c31af7Sopenharmony_ci	}
487e5c31af7Sopenharmony_ci}
488e5c31af7Sopenharmony_ci
489e5c31af7Sopenharmony_ciglu::Precision TextureRenderer::getTexCoordPrecision()
490e5c31af7Sopenharmony_ci{
491e5c31af7Sopenharmony_ci	return m_programLibrary.getTexCoordPrecision();
492e5c31af7Sopenharmony_ci}
493e5c31af7Sopenharmony_ci
494e5c31af7Sopenharmony_ci} // TextureTestUtil
495e5c31af7Sopenharmony_ci} // gls
496e5c31af7Sopenharmony_ci} // deqp
497