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