Home | History | Annotate | Download | only in glshared
      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 
     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 
     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 
     74 ProgramLibrary::~ProgramLibrary (void)
     75 {
     76 	clear();
     77 }
     78 
     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 
     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 
    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 
    287 TextureRenderer::~TextureRenderer (void)
    288 {
    289 	clear();
    290 }
    291 
    292 void TextureRenderer::clear (void)
    293 {
    294 	m_programLibrary.clear();
    295 }
    296 
    297 void TextureRenderer::renderQuad (int texUnit, const float* texCoord, TextureType texType)
    298 {
    299 	renderQuad(texUnit, texCoord, RenderParams(texType));
    300 }
    301 
    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