• 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 
TextureRenderer(const glu::RenderContext & context,tcu::TestLog & log,glu::GLSLVersion glslVersion,glu::Precision texCoordPrecision)280 TextureRenderer::TextureRenderer (const glu::RenderContext& context, tcu::TestLog& log, glu::GLSLVersion glslVersion, glu::Precision texCoordPrecision)
281 	: m_renderCtx		(context)
282 	, m_log				(log)
283 	, m_programLibrary	(context, log, glslVersion, texCoordPrecision)
284 {
285 }
286 
~TextureRenderer(void)287 TextureRenderer::~TextureRenderer (void)
288 {
289 	clear();
290 }
291 
clear(void)292 void TextureRenderer::clear (void)
293 {
294 	m_programLibrary.clear();
295 }
296 
renderQuad(int texUnit,const float * texCoord,TextureType texType)297 void TextureRenderer::renderQuad (int texUnit, const float* texCoord, TextureType texType)
298 {
299 	renderQuad(texUnit, texCoord, RenderParams(texType));
300 }
301 
renderQuad(int texUnit,const float * texCoord,const RenderParams & params)302 void TextureRenderer::renderQuad (int texUnit, const float* texCoord, const RenderParams& params)
303 {
304 	const glw::Functions&	gl			= m_renderCtx.getFunctions();
305 	tcu::Vec4				wCoord		= params.flags & RenderParams::PROJECTED ? params.w : tcu::Vec4(1.0f);
306 	bool					useBias		= !!(params.flags & RenderParams::USE_BIAS);
307 	bool					logUniforms	= !!(params.flags & RenderParams::LOG_UNIFORMS);
308 
309 	// Render quad with texture.
310 	float position[] =
311 	{
312 		-1.0f*wCoord.x(), -1.0f*wCoord.x(), 0.0f, wCoord.x(),
313 		-1.0f*wCoord.y(), +1.0f*wCoord.y(), 0.0f, wCoord.y(),
314 		+1.0f*wCoord.z(), -1.0f*wCoord.z(), 0.0f, wCoord.z(),
315 		+1.0f*wCoord.w(), +1.0f*wCoord.w(), 0.0f, wCoord.w()
316 	};
317 	static const deUint16 indices[] = { 0, 1, 2, 2, 1, 3 };
318 
319 	Program progSpec	= PROGRAM_LAST;
320 	int		numComps	= 0;
321 	if (params.texType == TEXTURETYPE_2D)
322 	{
323 		numComps = 2;
324 
325 		switch (params.samplerType)
326 		{
327 			case SAMPLERTYPE_FLOAT:		progSpec = useBias ? PROGRAM_2D_FLOAT_BIAS	: PROGRAM_2D_FLOAT;		break;
328 			case SAMPLERTYPE_INT:		progSpec = useBias ? PROGRAM_2D_INT_BIAS	: PROGRAM_2D_INT;		break;
329 			case SAMPLERTYPE_UINT:		progSpec = useBias ? PROGRAM_2D_UINT_BIAS	: PROGRAM_2D_UINT;		break;
330 			case SAMPLERTYPE_SHADOW:	progSpec = useBias ? PROGRAM_2D_SHADOW_BIAS	: PROGRAM_2D_SHADOW;	break;
331 			default:					DE_ASSERT(false);
332 		}
333 	}
334 	else if (params.texType == TEXTURETYPE_1D)
335 	{
336 		numComps = 1;
337 
338 		switch (params.samplerType)
339 		{
340 			case SAMPLERTYPE_FLOAT:		progSpec = useBias ? PROGRAM_1D_FLOAT_BIAS	: PROGRAM_1D_FLOAT;		break;
341 			case SAMPLERTYPE_INT:		progSpec = useBias ? PROGRAM_1D_INT_BIAS	: PROGRAM_1D_INT;		break;
342 			case SAMPLERTYPE_UINT:		progSpec = useBias ? PROGRAM_1D_UINT_BIAS	: PROGRAM_1D_UINT;		break;
343 			case SAMPLERTYPE_SHADOW:	progSpec = useBias ? PROGRAM_1D_SHADOW_BIAS	: PROGRAM_1D_SHADOW;	break;
344 			default:					DE_ASSERT(false);
345 		}
346 	}
347 	else if (params.texType == TEXTURETYPE_CUBE)
348 	{
349 		numComps = 3;
350 
351 		switch (params.samplerType)
352 		{
353 			case SAMPLERTYPE_FLOAT:		progSpec = useBias ? PROGRAM_CUBE_FLOAT_BIAS	: PROGRAM_CUBE_FLOAT;	break;
354 			case SAMPLERTYPE_INT:		progSpec = useBias ? PROGRAM_CUBE_INT_BIAS		: PROGRAM_CUBE_INT;		break;
355 			case SAMPLERTYPE_UINT:		progSpec = useBias ? PROGRAM_CUBE_UINT_BIAS		: PROGRAM_CUBE_UINT;	break;
356 			case SAMPLERTYPE_SHADOW:	progSpec = useBias ? PROGRAM_CUBE_SHADOW_BIAS	: PROGRAM_CUBE_SHADOW;	break;
357 			default:					DE_ASSERT(false);
358 		}
359 	}
360 	else if (params.texType == TEXTURETYPE_3D)
361 	{
362 		numComps = 3;
363 
364 		switch (params.samplerType)
365 		{
366 			case SAMPLERTYPE_FLOAT:		progSpec = useBias ? PROGRAM_3D_FLOAT_BIAS	: PROGRAM_3D_FLOAT;		break;
367 			case SAMPLERTYPE_INT:		progSpec = useBias ? PROGRAM_3D_INT_BIAS	: PROGRAM_3D_INT;		break;
368 			case SAMPLERTYPE_UINT:		progSpec = useBias ? PROGRAM_3D_UINT_BIAS	: PROGRAM_3D_UINT;		break;
369 			default:					DE_ASSERT(false);
370 		}
371 	}
372 	else if (params.texType == TEXTURETYPE_2D_ARRAY)
373 	{
374 		DE_ASSERT(!useBias); // \todo [2012-02-17 pyry] Support bias.
375 
376 		numComps = 3;
377 
378 		switch (params.samplerType)
379 		{
380 			case SAMPLERTYPE_FLOAT:		progSpec = PROGRAM_2D_ARRAY_FLOAT;	break;
381 			case SAMPLERTYPE_INT:		progSpec = PROGRAM_2D_ARRAY_INT;	break;
382 			case SAMPLERTYPE_UINT:		progSpec = PROGRAM_2D_ARRAY_UINT;	break;
383 			case SAMPLERTYPE_SHADOW:	progSpec = PROGRAM_2D_ARRAY_SHADOW;	break;
384 			default:					DE_ASSERT(false);
385 		}
386 	}
387 	else if (params.texType == TEXTURETYPE_CUBE_ARRAY)
388 	{
389 		DE_ASSERT(!useBias);
390 
391 		numComps = 4;
392 
393 		switch (params.samplerType)
394 		{
395 			case SAMPLERTYPE_FLOAT:		progSpec = PROGRAM_CUBE_ARRAY_FLOAT;	break;
396 			case SAMPLERTYPE_INT:		progSpec = PROGRAM_CUBE_ARRAY_INT;		break;
397 			case SAMPLERTYPE_UINT:		progSpec = PROGRAM_CUBE_ARRAY_UINT;		break;
398 			case SAMPLERTYPE_SHADOW:	progSpec = PROGRAM_CUBE_ARRAY_SHADOW;	break;
399 			default:					DE_ASSERT(false);
400 		}
401 	}
402 	else if (params.texType == TEXTURETYPE_1D_ARRAY)
403 	{
404 		DE_ASSERT(!useBias); // \todo [2012-02-17 pyry] Support bias.
405 
406 		numComps = 2;
407 
408 		switch (params.samplerType)
409 		{
410 			case SAMPLERTYPE_FLOAT:		progSpec = PROGRAM_1D_ARRAY_FLOAT;	break;
411 			case SAMPLERTYPE_INT:		progSpec = PROGRAM_1D_ARRAY_INT;	break;
412 			case SAMPLERTYPE_UINT:		progSpec = PROGRAM_1D_ARRAY_UINT;	break;
413 			case SAMPLERTYPE_SHADOW:	progSpec = PROGRAM_1D_ARRAY_SHADOW;	break;
414 			default:					DE_ASSERT(false);
415 		}
416 	}
417 	else if (params.texType == TEXTURETYPE_BUFFER)
418 	{
419 		numComps = 1;
420 
421 		switch (params.samplerType)
422 		{
423 			case SAMPLERTYPE_FETCH_FLOAT:	progSpec = PROGRAM_BUFFER_FLOAT;	break;
424 			case SAMPLERTYPE_FETCH_INT:		progSpec = PROGRAM_BUFFER_INT;		break;
425 			case SAMPLERTYPE_FETCH_UINT:	progSpec = PROGRAM_BUFFER_UINT;		break;
426 			default:						DE_ASSERT(false);
427 		}
428 	}
429 	else
430 		DE_ASSERT(DE_FALSE);
431 
432 	glu::ShaderProgram* program = m_programLibrary.getProgram(progSpec);
433 
434 	// \todo [2012-09-26 pyry] Move to ProgramLibrary and log unique programs only(?)
435 	if (params.flags & RenderParams::LOG_PROGRAMS)
436 		m_log << *program;
437 
438 	GLU_EXPECT_NO_ERROR(gl.getError(), "Set vertex attributes");
439 
440 	// Program and uniforms.
441 	deUint32 prog = program->getProgram();
442 	gl.useProgram(prog);
443 
444 	gl.uniform1i(gl.getUniformLocation(prog, "u_sampler"), texUnit);
445 	if (logUniforms)
446 		m_log << TestLog::Message << "u_sampler = " << texUnit << TestLog::EndMessage;
447 
448 	if (useBias)
449 	{
450 		gl.uniform1f(gl.getUniformLocation(prog, "u_bias"), params.bias);
451 		if (logUniforms)
452 			m_log << TestLog::Message << "u_bias = " << params.bias << TestLog::EndMessage;
453 	}
454 
455 	if (params.samplerType == SAMPLERTYPE_SHADOW)
456 	{
457 		gl.uniform1f(gl.getUniformLocation(prog, "u_ref"), params.ref);
458 		if (logUniforms)
459 			m_log << TestLog::Message << "u_ref = " << params.ref << TestLog::EndMessage;
460 	}
461 
462 	gl.uniform4fv(gl.getUniformLocation(prog, "u_colorScale"),	1, params.colorScale.getPtr());
463 	gl.uniform4fv(gl.getUniformLocation(prog, "u_colorBias"),	1, params.colorBias.getPtr());
464 
465 	if (logUniforms)
466 	{
467 		m_log << TestLog::Message << "u_colorScale = " << params.colorScale << TestLog::EndMessage;
468 		m_log << TestLog::Message << "u_colorBias = " << params.colorBias << TestLog::EndMessage;
469 	}
470 
471 	GLU_EXPECT_NO_ERROR(gl.getError(), "Set program state");
472 
473 	{
474 		const glu::VertexArrayBinding vertexArrays[] =
475 		{
476 			glu::va::Float("a_position",	4,			4, 0, &position[0]),
477 			glu::va::Float("a_texCoord",	numComps,	4, 0, texCoord)
478 		};
479 		glu::draw(m_renderCtx, prog, DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
480 				  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
481 	}
482 }
483 
484 
485 } // TextureTestUtil
486 } // gls
487 } // deqp
488