Home | History | Annotate | Download | only in glshared
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program OpenGL ES 3.0 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 Sampler object testcases.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "glsSamplerObjectTest.hpp"
     25 
     26 #include "tcuTexture.hpp"
     27 #include "tcuSurface.hpp"
     28 #include "tcuTextureUtil.hpp"
     29 #include "tcuImageCompare.hpp"
     30 #include "tcuTestLog.hpp"
     31 #include "tcuRGBA.hpp"
     32 #include "tcuRenderTarget.hpp"
     33 #include "tcuStringTemplate.hpp"
     34 
     35 #include "gluShaderProgram.hpp"
     36 #include "gluPixelTransfer.hpp"
     37 #include "gluDrawUtil.hpp"
     38 #include "gluRenderContext.hpp"
     39 #include "gluTextureUtil.hpp"
     40 
     41 #include "glwFunctions.hpp"
     42 
     43 #include "deRandom.hpp"
     44 #include "deString.h"
     45 
     46 #include "deString.h"
     47 
     48 #include <map>
     49 
     50 namespace deqp
     51 {
     52 namespace gls
     53 {
     54 
     55 namespace
     56 {
     57 const int VIEWPORT_WIDTH	= 128;
     58 const int VIEWPORT_HEIGHT	= 128;
     59 
     60 const int TEXTURE2D_WIDTH	= 32;
     61 const int TEXTURE2D_HEIGHT	= 32;
     62 
     63 const int TEXTURE3D_WIDTH	= 32;
     64 const int TEXTURE3D_HEIGHT	= 32;
     65 const int TEXTURE3D_DEPTH	= 32;
     66 
     67 const int CUBEMAP_SIZE		= 32;
     68 
     69 } // anonymous
     70 
     71 
     72 TextureSamplerTest::TextureSamplerTest (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const TestSpec& spec)
     73 	: tcu::TestCase		(testCtx, spec.name, spec.desc)
     74 	, m_renderCtx		(renderCtx)
     75 	, m_program			(NULL)
     76 	, m_target			(spec.target)
     77 	, m_textureState	(spec.textureState)
     78 	, m_samplerState	(spec.samplerState)
     79 	, m_random			(deStringHash(spec.name))
     80 {
     81 }
     82 
     83 void TextureSamplerTest::setTextureState (const glw::Functions& gl, GLenum target, SamplingState state)
     84 {
     85 	gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, state.minFilter);
     86 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_MIN_FILTER, state.minFilter)");
     87 	gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, state.magFilter);
     88 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_MAG_FILTER, state.magFilter)");
     89 	gl.texParameteri(target, GL_TEXTURE_WRAP_S, state.wrapS);
     90 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_WRAP_S, state.wrapS)");
     91 	gl.texParameteri(target, GL_TEXTURE_WRAP_T, state.wrapT);
     92 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_WRAP_T, state.wrapT)");
     93 	gl.texParameteri(target, GL_TEXTURE_WRAP_R, state.wrapR);
     94 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_WRAP_R, state.wrapR)");
     95 	gl.texParameterf(target, GL_TEXTURE_MAX_LOD, state.maxLod);
     96 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterf(target, GL_TEXTURE_MAX_LOD, state.maxLod)");
     97 	gl.texParameterf(target, GL_TEXTURE_MIN_LOD, state.minLod);
     98 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterf(target, GL_TEXTURE_MIN_LOD, state.minLod)");
     99 }
    100 
    101 void TextureSamplerTest::setSamplerState (const glw::Functions& gl, SamplingState state, GLuint sampler)
    102 {
    103 	gl.samplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, state.minFilter);
    104 	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, state.minFilter)");
    105 	gl.samplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, state.magFilter);
    106 	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, state.magFilter)");
    107 	gl.samplerParameteri(sampler, GL_TEXTURE_WRAP_S, state.wrapS);
    108 	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, state.wrapS)");
    109 	gl.samplerParameteri(sampler, GL_TEXTURE_WRAP_T, state.wrapT);
    110 	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, state.wrapT)");
    111 	gl.samplerParameteri(sampler, GL_TEXTURE_WRAP_R, state.wrapR);
    112 	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_WRAP_R, state.wrapR)");
    113 	gl.samplerParameterf(sampler, GL_TEXTURE_MAX_LOD, state.maxLod);
    114 	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameterf(sampler, GL_TEXTURE_MAX_LOD, state.maxLod)");
    115 	gl.samplerParameterf(sampler, GL_TEXTURE_MIN_LOD, state.minLod);
    116 	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameterf(sampler, GL_TEXTURE_MIN_LOD, state.minLod)");
    117 }
    118 
    119 const char* TextureSamplerTest::selectVertexShader (GLenum target)
    120 {
    121 	switch (target)
    122 	{
    123 		case GL_TEXTURE_2D:
    124 			return
    125 			"${VTX_HDR}"
    126 			"${VTX_IN} ${HIGHP} vec2 a_position;\n"
    127 			"uniform ${HIGHP} float u_posScale;\n"
    128 			"${VTX_OUT} ${MEDIUMP} vec2 v_texCoord;\n"
    129 			"void main (void)\n"
    130 			"{\n"
    131 			"\tv_texCoord = a_position;\n"
    132 			"\tgl_Position = vec4(u_posScale * a_position, 0.0, 1.0);\n"
    133 			"}";
    134 
    135 		case GL_TEXTURE_3D:
    136 			return
    137 			"${VTX_HDR}"
    138 			"${VTX_IN} ${HIGHP} vec3 a_position;\n"
    139 			"uniform ${HIGHP} float u_posScale;\n"
    140 			"${VTX_OUT} ${MEDIUMP} vec3 v_texCoord;\n"
    141 			"void main (void)\n"
    142 			"{\n"
    143 			"\tv_texCoord = a_position;\n"
    144 			"\tgl_Position = vec4(u_posScale * a_position.xy, 0.0, 1.0);\n"
    145 			"}";
    146 
    147 		case GL_TEXTURE_CUBE_MAP:
    148 			return
    149 			"${VTX_HDR}"
    150 			"${VTX_IN} ${HIGHP} vec4 a_position;\n"
    151 			"uniform ${HIGHP} float u_posScale;\n"
    152 			"${VTX_OUT} ${MEDIUMP} vec2 v_texCoord;\n"
    153 			"void main (void)\n"
    154 			"{\n"
    155 			"\tv_texCoord = a_position.zw;\n"
    156 			"\tgl_Position = vec4(u_posScale * a_position.xy, 0.0, 1.0);\n"
    157 			"}";
    158 
    159 		default:
    160 			DE_ASSERT(false);
    161 			return NULL;
    162 	}
    163 }
    164 
    165 const char* TextureSamplerTest::selectFragmentShader (GLenum target)
    166 {
    167 	switch (target)
    168 	{
    169 		case GL_TEXTURE_2D:
    170 			return
    171 			"${FRAG_HDR}"
    172 			"uniform ${LOWP} sampler2D u_sampler;\n"
    173 			"${FRAG_IN} ${MEDIUMP} vec2 v_texCoord;\n"
    174 			"void main (void)\n"
    175 			"{\n"
    176 			"\t${FRAG_COLOR} = texture(u_sampler, v_texCoord);\n"
    177 			"}";
    178 
    179 		case GL_TEXTURE_3D:
    180 			return
    181 			"${FRAG_HDR}"
    182 			"uniform ${LOWP} sampler3D u_sampler;\n"
    183 			"${FRAG_IN} ${MEDIUMP} vec3 v_texCoord;\n"
    184 			"void main (void)\n"
    185 			"{\n"
    186 			"\t${FRAG_COLOR} = texture(u_sampler, v_texCoord);\n"
    187 			"}";
    188 
    189 		case GL_TEXTURE_CUBE_MAP:
    190 			return
    191 			"${FRAG_HDR}"
    192 			"uniform ${LOWP} samplerCube u_sampler;\n"
    193 			"${FRAG_IN} ${MEDIUMP} vec2 v_texCoord;\n"
    194 			"void main (void)\n"
    195 			"{\n"
    196 			"\t${FRAG_COLOR} = texture(u_sampler, vec3(cos(3.14 * v_texCoord.y) * sin(3.14 * v_texCoord.x), sin(3.14 * v_texCoord.y), cos(3.14 * v_texCoord.y) * cos(3.14 * v_texCoord.x)));\n"
    197 			"}";
    198 
    199 		default:
    200 			DE_ASSERT(false);
    201 			return NULL;
    202 	}
    203 }
    204 
    205 void TextureSamplerTest::init (void)
    206 {
    207 	const char* vertexShaderTemplate	= selectVertexShader(m_target);
    208 	const char* fragmentShaderTemplate	= selectFragmentShader(m_target);
    209 
    210 	std::map<std::string, std::string>	params;
    211 
    212 	if (glu::isGLSLVersionSupported(m_renderCtx.getType(), glu::GLSL_VERSION_300_ES))
    213 	{
    214 		params["VTX_HDR"]		= "#version 300 es\n";
    215 		params["FRAG_HDR"]		= "#version 300 es\nlayout(location = 0) out mediump vec4 o_color;\n";
    216 		params["VTX_IN"]		= "in";
    217 		params["VTX_OUT"]		= "out";
    218 		params["FRAG_IN"]		= "in";
    219 		params["FRAG_COLOR"]	= "o_color";
    220 		params["HIGHP"]			= "highp";
    221 		params["LOWP"]			= "lowp";
    222 		params["MEDIUMP"]		= "mediump";
    223 	}
    224 	else if (glu::isGLSLVersionSupported(m_renderCtx.getType(), glu::GLSL_VERSION_330))
    225 	{
    226 		params["VTX_HDR"]		= "#version 330\n";
    227 		params["FRAG_HDR"]		= "#version 330\nlayout(location = 0) out mediump vec4 o_color;\n";
    228 		params["VTX_IN"]		= "in";
    229 		params["VTX_OUT"]		= "out";
    230 		params["FRAG_IN"]		= "in";
    231 		params["FRAG_COLOR"]	= "o_color";
    232 		params["HIGHP"]			= "highp";
    233 		params["LOWP"]			= "lowp";
    234 		params["MEDIUMP"]		= "mediump";
    235 	}
    236 	else
    237 		DE_ASSERT(false);
    238 
    239 	DE_ASSERT(!m_program);
    240 	m_program = new glu::ShaderProgram(m_renderCtx,
    241 									   glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderTemplate).specialize(params),
    242 															   tcu::StringTemplate(fragmentShaderTemplate).specialize(params)));
    243 
    244 	if (!m_program->isOk())
    245 	{
    246 		tcu::TestLog& log = m_testCtx.getLog();
    247 		log << *m_program;
    248 		TCU_FAIL("Failed to compile shaders");
    249 	}
    250 }
    251 
    252 void TextureSamplerTest::deinit (void)
    253 {
    254 	delete m_program;
    255 	m_program = NULL;
    256 }
    257 
    258 TextureSamplerTest::~TextureSamplerTest (void)
    259 {
    260 	deinit();
    261 }
    262 
    263 const float s_positions[] = {
    264 	-1.0, -1.0,
    265 	 1.0, -1.0,
    266 	 1.0,  1.0,
    267 
    268 	 1.0,  1.0,
    269 	-1.0,  1.0,
    270 	-1.0, -1.0
    271 };
    272 
    273 const float s_positions3D[] = {
    274 	-1.0f, -1.0f, -1.0f,
    275 	 1.0f, -1.0f,  1.0f,
    276 	 1.0f,  1.0f, -1.0f,
    277 
    278 	 1.0f,  1.0f, -1.0f,
    279 	-1.0f,  1.0f,  1.0f,
    280 	-1.0f, -1.0f, -1.0f
    281 };
    282 
    283 const float s_positionsCube[] = {
    284 	-1.0f, -1.0f, -1.0f, -0.5f,
    285 	 1.0f, -1.0f,  1.0f, -0.5f,
    286 	 1.0f,  1.0f,  1.0f,  0.5f,
    287 
    288 	 1.0f,  1.0f,  1.0f,  0.5f,
    289 	-1.0f,  1.0f, -1.0f,  0.5f,
    290 	-1.0f, -1.0f, -1.0f, -0.5f
    291 };
    292 
    293 void TextureSamplerTest::render (void)
    294 {
    295 	const glw::Functions& gl = m_renderCtx.getFunctions();
    296 
    297 	GLuint	samplerLoc	= (GLuint)-1;
    298 	GLuint	scaleLoc	= (GLuint)-1;
    299 
    300 	gl.useProgram(m_program->getProgram());
    301 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram(m_program->getProgram())");
    302 
    303 	samplerLoc = gl.getUniformLocation(m_program->getProgram(), "u_sampler");
    304 	TCU_CHECK(samplerLoc != (GLuint)-1);
    305 
    306 	scaleLoc = gl.getUniformLocation(m_program->getProgram(), "u_posScale");
    307 	TCU_CHECK(scaleLoc != (GLuint)-1);
    308 
    309 	gl.clearColor(0.5f, 0.5f, 0.5f, 1.0f);
    310 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor(0.5f, 0.5f, 0.5f, 1.0f)");
    311 
    312 	gl.clear(GL_COLOR_BUFFER_BIT);
    313 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear(GL_COLOR_BUFFER_BIT)");
    314 
    315 	gl.uniform1i(samplerLoc, 0);
    316 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i(samplerLoc, 0)");
    317 
    318 	gl.uniform1f(scaleLoc, 1.0f);
    319 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f(scaleLoc, 1.0f)");
    320 
    321 	switch (m_target)
    322 	{
    323 		case GL_TEXTURE_2D:
    324 		{
    325 			glu::VertexArrayBinding vertexArrays[] =
    326 			{
    327 				glu::VertexArrayBinding(glu::BindingPoint("a_position"), glu::VertexArrayPointer(glu::VTX_COMP_FLOAT, glu::VTX_COMP_CONVERT_NONE, 2, 6, 0, s_positions))
    328 			};
    329 
    330 			glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));
    331 
    332 			gl.uniform1f(scaleLoc, 0.25f);
    333 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f(scaleLoc, 0.25f)");
    334 
    335 			glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));
    336 
    337 			break;
    338 		}
    339 
    340 		case GL_TEXTURE_3D:
    341 		{
    342 			glu::VertexArrayBinding vertexArrays[] =
    343 			{
    344 				glu::VertexArrayBinding(glu::BindingPoint("a_position"), glu::VertexArrayPointer(glu::VTX_COMP_FLOAT, glu::VTX_COMP_CONVERT_NONE, 3, 6, 0, s_positions3D))
    345 			};
    346 
    347 			glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));
    348 
    349 			gl.uniform1f(scaleLoc, 0.25f);
    350 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f(scaleLoc, 0.25f)");
    351 
    352 			glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));
    353 
    354 			break;
    355 		}
    356 
    357 		case GL_TEXTURE_CUBE_MAP:
    358 		{
    359 			glu::VertexArrayBinding vertexArrays[] =
    360 			{
    361 				glu::VertexArrayBinding(glu::BindingPoint("a_position"), glu::VertexArrayPointer(glu::VTX_COMP_FLOAT, glu::VTX_COMP_CONVERT_NONE, 4, 6, 0, s_positionsCube))
    362 			};
    363 
    364 			glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));
    365 
    366 			gl.uniform1f(scaleLoc, 0.25f);
    367 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f(scaleLoc, 0.25f)");
    368 
    369 			glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));
    370 
    371 			break;
    372 		}
    373 
    374 		default:
    375 			DE_ASSERT(false);
    376 	}
    377 }
    378 
    379 GLuint TextureSamplerTest::createTexture2D (const glw::Functions& gl)
    380 {
    381 	GLuint			texture		= (GLuint)-1;
    382 	tcu::Texture2D	refTexture	(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEXTURE2D_WIDTH, TEXTURE2D_HEIGHT);
    383 
    384 	refTexture.allocLevel(0);
    385 	tcu::fillWithComponentGradients(refTexture.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
    386 
    387 	gl.genTextures(1, &texture);
    388 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures(1, &texture)");
    389 
    390 	gl.bindTexture(GL_TEXTURE_2D, texture);
    391 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_2D, texture)");
    392 
    393 	gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, refTexture.getWidth(), refTexture.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevel(0).getDataPtr());
    394 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, refTexture.getWidth(), refTexture.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevel(0).getDataPtr())");
    395 
    396 	gl.generateMipmap(GL_TEXTURE_2D);
    397 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap(GL_TEXTURE_2D)");
    398 
    399 	gl.bindTexture(GL_TEXTURE_2D, 0);
    400 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_2D, texture)");
    401 
    402 	return texture;
    403 }
    404 
    405 GLuint TextureSamplerTest::createTexture3D (const glw::Functions& gl)
    406 {
    407 	GLuint			texture		= (GLuint)-1;
    408 	tcu::Texture3D	refTexture	(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEXTURE3D_WIDTH, TEXTURE3D_HEIGHT, TEXTURE3D_DEPTH);
    409 
    410 	refTexture.allocLevel(0);
    411 	tcu::fillWithComponentGradients(refTexture.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
    412 
    413 	gl.genTextures(1, &texture);
    414 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures(1, &texture)");
    415 
    416 	gl.bindTexture(GL_TEXTURE_3D, texture);
    417 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_3D, texture)");
    418 
    419 	gl.texImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, refTexture.getWidth(), refTexture.getHeight(), refTexture.getDepth(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevel(0).getDataPtr());
    420 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, refTexture.getWidth(), refTexture.getHeight(), refTexture.getDepth(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevel(0).getDataPtr())");
    421 
    422 	gl.generateMipmap(GL_TEXTURE_3D);
    423 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap(GL_TEXTURE_3D)");
    424 
    425 	gl.bindTexture(GL_TEXTURE_3D, 0);
    426 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_3D, 0)");
    427 
    428 	return texture;
    429 }
    430 
    431 GLuint TextureSamplerTest::createTextureCube (const glw::Functions& gl)
    432 {
    433 	GLuint				texture		= (GLuint)-1;
    434 	tcu::TextureCube	refTexture	(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), CUBEMAP_SIZE);
    435 
    436 	refTexture.allocLevel(tcu::CUBEFACE_POSITIVE_X, 0);
    437 	refTexture.allocLevel(tcu::CUBEFACE_POSITIVE_Y, 0);
    438 	refTexture.allocLevel(tcu::CUBEFACE_POSITIVE_Z, 0);
    439 	refTexture.allocLevel(tcu::CUBEFACE_NEGATIVE_X, 0);
    440 	refTexture.allocLevel(tcu::CUBEFACE_NEGATIVE_Y, 0);
    441 	refTexture.allocLevel(tcu::CUBEFACE_NEGATIVE_Z, 0);
    442 
    443 	tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_X), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
    444 	tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_Y), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
    445 	tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_Z), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
    446 	tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_X), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
    447 	tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_Y), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
    448 	tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_Z), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
    449 
    450 	gl.bindTexture(GL_TEXTURE_CUBE_MAP, texture);
    451 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_CUBE_MAP, texture)");
    452 
    453 	for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
    454 	{
    455 		const deUint32 target = glu::getGLCubeFace((tcu::CubeFace)face);
    456 		gl.texImage2D(target, 0, GL_RGBA8, refTexture.getSize(), refTexture.getSize(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevelFace(0, (tcu::CubeFace)face).getDataPtr());
    457 	}
    458 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D(GL_TEXTURE_CUBE_MAP_...) failed");
    459 
    460 	gl.generateMipmap(GL_TEXTURE_CUBE_MAP);
    461 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap(GL_TEXTURE_CUBE_MAP)");
    462 	gl.bindTexture(GL_TEXTURE_CUBE_MAP, 0);
    463 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_CUBE_MAP, texture)");
    464 
    465 	return texture;
    466 }
    467 
    468 GLuint TextureSamplerTest::createTexture (const glw::Functions& gl, GLenum target)
    469 {
    470 	switch (target)
    471 	{
    472 		case GL_TEXTURE_2D:
    473 			return createTexture2D(gl);
    474 
    475 		case GL_TEXTURE_3D:
    476 			return createTexture3D(gl);
    477 
    478 		case GL_TEXTURE_CUBE_MAP:
    479 			return createTextureCube(gl);
    480 
    481 		default:
    482 			DE_ASSERT(false);
    483 			return (GLuint)-1;
    484 	}
    485 }
    486 
    487 void TextureSamplerTest::renderReferences (tcu::Surface& textureRef, tcu::Surface& samplerRef, int x, int y)
    488 {
    489 	const glw::Functions&	gl		= m_renderCtx.getFunctions();
    490 	GLuint					texture	= createTexture(gl, m_target);
    491 
    492 	gl.viewport(x, y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
    493 	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport(x, y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT)");
    494 
    495 	gl.bindTexture(m_target, texture);
    496 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture)");
    497 
    498 	setTextureState(gl, m_target, m_textureState);
    499 	render();
    500 	glu::readPixels(m_renderCtx, x, y, textureRef.getAccess());
    501 
    502 	setTextureState(gl, m_target, m_samplerState);
    503 	render();
    504 	glu::readPixels(m_renderCtx, x, y, samplerRef.getAccess());
    505 
    506 	gl.deleteTextures(1, &texture);
    507 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures(1, &texture)");
    508 }
    509 
    510 void TextureSamplerTest::renderResults (tcu::Surface& textureResult, tcu::Surface& samplerResult, int x, int y)
    511 {
    512 	const glw::Functions&	gl		= m_renderCtx.getFunctions();
    513 	GLuint					texture	= createTexture(gl, m_target);
    514 	GLuint					sampler	= -1;
    515 
    516 	gl.viewport(x, y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
    517 	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport(x, y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT)");
    518 
    519 	gl.genSamplers(1, &sampler);
    520 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenSamplers(1, &sampler)");
    521 	TCU_CHECK(sampler != (GLuint)-1);
    522 
    523 	gl.bindSampler(0, sampler);
    524 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindSampler(0, sampler)");
    525 
    526 	// First set sampler state
    527 	setSamplerState(gl, m_samplerState, sampler);
    528 
    529 	// Set texture state
    530 	gl.bindTexture(m_target, texture);
    531 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture)");
    532 
    533 	setTextureState(gl, m_target, m_textureState);
    534 
    535 	// Render using sampler
    536 	render();
    537 	glu::readPixels(m_renderCtx, x, y, samplerResult.getAccess());
    538 
    539 	// Render without sampler
    540 	gl.bindSampler(0, 0);
    541 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindSampler(0, 0)");
    542 
    543 	render();
    544 	glu::readPixels(m_renderCtx, x, y, textureResult.getAccess());
    545 
    546 	gl.deleteSamplers(1, &sampler);
    547 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteSamplers(1, &sampler)");
    548 	gl.deleteTextures(1, &texture);
    549 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures(1, &texture)");
    550 }
    551 
    552 tcu::TestCase::IterateResult TextureSamplerTest::iterate (void)
    553 {
    554 	tcu::TestLog&	log = m_testCtx.getLog();
    555 
    556 	tcu::Surface	textureRef(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
    557 	tcu::Surface	samplerRef(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
    558 
    559 	tcu::Surface	textureResult(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
    560 	tcu::Surface	samplerResult(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
    561 
    562 	int				x = m_random.getInt(0, m_renderCtx.getRenderTarget().getWidth() - VIEWPORT_WIDTH);
    563 	int				y = m_random.getInt(0, m_renderCtx.getRenderTarget().getHeight() - VIEWPORT_HEIGHT);
    564 
    565 	renderReferences(textureRef, samplerRef, x, y);
    566 	renderResults(textureResult, samplerResult, x, y);
    567 
    568 	bool isOk = pixelThresholdCompare (log, "Sampler render result", "Result from rendering with sampler", samplerRef, samplerResult, tcu::RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT);
    569 
    570 	if (!pixelThresholdCompare (log, "Texture render result", "Result from rendering with texture state", textureRef, textureResult, tcu::RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT))
    571 		isOk = false;
    572 
    573 	if (!isOk)
    574 	{
    575 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
    576 		return STOP;
    577 	}
    578 
    579 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    580 	return STOP;
    581 }
    582 
    583 MultiTextureSamplerTest::MultiTextureSamplerTest (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const TestSpec& spec)
    584 	: TestCase			(testCtx, spec.name, spec.desc)
    585 	, m_renderCtx		(renderCtx)
    586 	, m_program			(NULL)
    587 	, m_target			(spec.target)
    588 	, m_textureState1	(spec.textureState1)
    589 	, m_textureState2	(spec.textureState2)
    590 	, m_samplerState	(spec.samplerState)
    591 	, m_random			(deStringHash(spec.name))
    592 {
    593 }
    594 
    595 void MultiTextureSamplerTest::setTextureState (const glw::Functions& gl, GLenum target, SamplingState state)
    596 {
    597 	gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, state.minFilter);
    598 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_MIN_FILTER, state.minFilter)");
    599 	gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, state.magFilter);
    600 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_MAG_FILTER, state.magFilter)");
    601 	gl.texParameteri(target, GL_TEXTURE_WRAP_S, state.wrapS);
    602 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_WRAP_S, state.wrapS)");
    603 	gl.texParameteri(target, GL_TEXTURE_WRAP_T, state.wrapT);
    604 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_WRAP_T, state.wrapT)");
    605 	gl.texParameteri(target, GL_TEXTURE_WRAP_R, state.wrapR);
    606 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(target, GL_TEXTURE_WRAP_R, state.wrapR)");
    607 	gl.texParameterf(target, GL_TEXTURE_MAX_LOD, state.maxLod);
    608 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterf(target, GL_TEXTURE_MAX_LOD, state.maxLod)");
    609 	gl.texParameterf(target, GL_TEXTURE_MIN_LOD, state.minLod);
    610 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameterf(target, GL_TEXTURE_MIN_LOD, state.minLod)");
    611 }
    612 
    613 void MultiTextureSamplerTest::setSamplerState (const glw::Functions& gl, SamplingState state, GLuint sampler)
    614 {
    615 	gl.samplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, state.minFilter);
    616 	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, state.minFilter)");
    617 	gl.samplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, state.magFilter);
    618 	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, state.magFilter)");
    619 	gl.samplerParameteri(sampler, GL_TEXTURE_WRAP_S, state.wrapS);
    620 	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, state.wrapS)");
    621 	gl.samplerParameteri(sampler, GL_TEXTURE_WRAP_T, state.wrapT);
    622 	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, state.wrapT)");
    623 	gl.samplerParameteri(sampler, GL_TEXTURE_WRAP_R, state.wrapR);
    624 	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameteri(sampler, GL_TEXTURE_WRAP_R, state.wrapR)");
    625 	gl.samplerParameterf(sampler, GL_TEXTURE_MAX_LOD, state.maxLod);
    626 	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameterf(sampler, GL_TEXTURE_MAX_LOD, state.maxLod)");
    627 	gl.samplerParameterf(sampler, GL_TEXTURE_MIN_LOD, state.minLod);
    628 	GLU_EXPECT_NO_ERROR(gl.getError(), "glSamplerParameterf(sampler, GL_TEXTURE_MIN_LOD, state.minLod)");
    629 }
    630 
    631 const char* MultiTextureSamplerTest::selectVertexShader (GLenum target)
    632 {
    633 	switch (target)
    634 	{
    635 		case GL_TEXTURE_2D:
    636 			return
    637 			"${VTX_HDR}"
    638 			"${VTX_IN} ${HIGHP} vec2 a_position;\n"
    639 			"uniform ${HIGHP} float u_posScale;\n"
    640 			"${VTX_OUT} ${MEDIUMP} vec2 v_texCoord;\n"
    641 			"void main (void)\n"
    642 			"{\n"
    643 			"\tv_texCoord = a_position;\n"
    644 			"\tgl_Position = vec4(u_posScale * a_position, 0.0, 1.0);\n"
    645 			"}";
    646 
    647 		case GL_TEXTURE_3D:
    648 			return
    649 			"${VTX_HDR}"
    650 			"${VTX_IN} ${HIGHP} vec3 a_position;\n"
    651 			"uniform ${HIGHP} float u_posScale;\n"
    652 			"${VTX_OUT} ${MEDIUMP} vec3 v_texCoord;\n"
    653 			"void main (void)\n"
    654 			"{\n"
    655 			"\tv_texCoord = a_position;\n"
    656 			"\tgl_Position = vec4(u_posScale * a_position.xy, 0.0, 1.0);\n"
    657 			"}";
    658 
    659 		case GL_TEXTURE_CUBE_MAP:
    660 			return
    661 			"${VTX_HDR}"
    662 			"${VTX_IN} ${HIGHP} vec4 a_position;\n"
    663 			"uniform ${HIGHP} float u_posScale;\n"
    664 			"${VTX_OUT} ${MEDIUMP} vec2 v_texCoord;\n"
    665 			"void main (void)\n"
    666 			"{\n"
    667 			"\tv_texCoord = a_position.zw;\n"
    668 			"\tgl_Position = vec4(u_posScale * a_position.xy, 0.0, 1.0);\n"
    669 			"}";
    670 
    671 		default:
    672 			DE_ASSERT(false);
    673 			return NULL;
    674 	}
    675 
    676 }
    677 
    678 const char* MultiTextureSamplerTest::selectFragmentShader (GLenum target)
    679 {
    680 	switch (target)
    681 	{
    682 		case GL_TEXTURE_2D:
    683 			return
    684 			"${FRAG_HDR}"
    685 			"uniform ${LOWP} sampler2D u_sampler1;\n"
    686 			"uniform ${LOWP} sampler2D u_sampler2;\n"
    687 			"${FRAG_IN} ${MEDIUMP} vec2 v_texCoord;\n"
    688 			"void main (void)\n"
    689 			"{\n"
    690 			"\t${FRAG_COLOR} = vec4(0.75, 0.75, 0.75, 1.0) * (texture(u_sampler1, v_texCoord) + texture(u_sampler2, v_texCoord));\n"
    691 			"}";
    692 
    693 			break;
    694 
    695 		case GL_TEXTURE_3D:
    696 			return
    697 			"${FRAG_HDR}"
    698 			"uniform ${LOWP} sampler3D u_sampler1;\n"
    699 			"uniform ${LOWP} sampler3D u_sampler2;\n"
    700 			"${FRAG_IN} ${MEDIUMP} vec3 v_texCoord;\n"
    701 			"void main (void)\n"
    702 			"{\n"
    703 			"\t${FRAG_COLOR} = vec4(0.75, 0.75, 0.75, 1.0) * (texture(u_sampler1, v_texCoord) + texture(u_sampler2, v_texCoord));\n"
    704 			"}";
    705 
    706 		case GL_TEXTURE_CUBE_MAP:
    707 			return
    708 			"${FRAG_HDR}"
    709 			"uniform ${LOWP} samplerCube u_sampler1;\n"
    710 			"uniform ${LOWP} samplerCube u_sampler2;\n"
    711 			"${FRAG_IN} ${MEDIUMP} vec2 v_texCoord;\n"
    712 			"void main (void)\n"
    713 			"{\n"
    714 			"\t${FRAG_COLOR} = vec4(0.5, 0.5, 0.5, 1.0) * (texture(u_sampler1, vec3(cos(3.14 * v_texCoord.y) * sin(3.14 * v_texCoord.x), sin(3.14 * v_texCoord.y), cos(3.14 * v_texCoord.y) * cos(3.14 * v_texCoord.x)))"
    715 			"+ texture(u_sampler2, vec3(cos(3.14 * v_texCoord.y) * sin(3.14 * v_texCoord.x), sin(3.14 * v_texCoord.y), cos(3.14 * v_texCoord.y) * cos(3.14 * v_texCoord.x))));\n"
    716 			"}";
    717 
    718 		default:
    719 			DE_ASSERT(false);
    720 			return NULL;
    721 	}
    722 
    723 }
    724 
    725 void MultiTextureSamplerTest::init (void)
    726 {
    727 	const char* vertexShaderTemplate	= selectVertexShader(m_target);
    728 	const char* fragmentShaderTemplate	= selectFragmentShader(m_target);
    729 
    730 	std::map<std::string, std::string>	params;
    731 
    732 	if (glu::isGLSLVersionSupported(m_renderCtx.getType(), glu::GLSL_VERSION_300_ES))
    733 	{
    734 		params["VTX_HDR"]		= "#version 300 es\n";
    735 		params["FRAG_HDR"]		= "#version 300 es\nlayout(location = 0) out mediump vec4 o_color;\n";
    736 		params["VTX_IN"]		= "in";
    737 		params["VTX_OUT"]		= "out";
    738 		params["FRAG_IN"]		= "in";
    739 		params["FRAG_COLOR"]	= "o_color";
    740 		params["HIGHP"]			= "highp";
    741 		params["LOWP"]			= "lowp";
    742 		params["MEDIUMP"]		= "mediump";
    743 	}
    744 	else if (glu::isGLSLVersionSupported(m_renderCtx.getType(), glu::GLSL_VERSION_330))
    745 	{
    746 		params["VTX_HDR"]		= "#version 330\n";
    747 		params["FRAG_HDR"]		= "#version 330\nlayout(location = 0) out mediump vec4 o_color;\n";
    748 		params["VTX_IN"]		= "in";
    749 		params["VTX_OUT"]		= "out";
    750 		params["FRAG_IN"]		= "in";
    751 		params["FRAG_COLOR"]	= "o_color";
    752 		params["HIGHP"]			= "highp";
    753 		params["LOWP"]			= "lowp";
    754 		params["MEDIUMP"]		= "mediump";
    755 	}
    756 	else
    757 		DE_ASSERT(false);
    758 
    759 	DE_ASSERT(!m_program);
    760 	m_program = new glu::ShaderProgram(m_renderCtx,
    761 									   glu::makeVtxFragSources(tcu::StringTemplate(vertexShaderTemplate).specialize(params),
    762 															   tcu::StringTemplate(fragmentShaderTemplate).specialize(params)));
    763 	if (!m_program->isOk())
    764 	{
    765 		tcu::TestLog& log = m_testCtx.getLog();
    766 
    767 		log << *m_program;
    768 		TCU_FAIL("Failed to compile shaders");
    769 	}
    770 }
    771 
    772 void MultiTextureSamplerTest::deinit (void)
    773 {
    774 	delete m_program;
    775 	m_program = NULL;
    776 }
    777 
    778 MultiTextureSamplerTest::~MultiTextureSamplerTest (void)
    779 {
    780 	deinit();
    781 }
    782 
    783 void MultiTextureSamplerTest::render (void)
    784 {
    785 	const glw::Functions& gl = m_renderCtx.getFunctions();
    786 
    787 	GLuint	samplerLoc1	= (GLuint)-1;
    788 	GLuint	samplerLoc2	= (GLuint)-1;
    789 	GLuint	scaleLoc	= (GLuint)-1;
    790 
    791 	gl.useProgram(m_program->getProgram());
    792 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram(m_program->getProgram())");
    793 
    794 	samplerLoc1 = glGetUniformLocation(m_program->getProgram(), "u_sampler1");
    795 	TCU_CHECK(samplerLoc1 != (GLuint)-1);
    796 
    797 	samplerLoc2 = glGetUniformLocation(m_program->getProgram(), "u_sampler2");
    798 	TCU_CHECK(samplerLoc2 != (GLuint)-1);
    799 
    800 	scaleLoc = glGetUniformLocation(m_program->getProgram(), "u_posScale");
    801 	TCU_CHECK(scaleLoc != (GLuint)-1);
    802 
    803 	gl.clearColor(0.5f, 0.5f, 0.5f, 1.0f);
    804 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor(0.5f, 0.5f, 0.5f, 1.0f)");
    805 
    806 	gl.clear(GL_COLOR_BUFFER_BIT);
    807 	GLU_EXPECT_NO_ERROR(gl.getError(), "glClear(GL_COLOR_BUFFER_BIT)");
    808 
    809 	gl.uniform1i(samplerLoc1, 0);
    810 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i(samplerLoc1, 0)");
    811 
    812 	gl.uniform1i(samplerLoc2, 1);
    813 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1i(samplerLoc2, 1)");
    814 
    815 	gl.uniform1f(scaleLoc, 1.0f);
    816 	GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f(scaleLoc, 1.0f)");
    817 
    818 	switch (m_target)
    819 	{
    820 		case GL_TEXTURE_2D:
    821 		{
    822 			glu::VertexArrayBinding vertexArrays[] =
    823 			{
    824 				glu::VertexArrayBinding(glu::BindingPoint("a_position"), glu::VertexArrayPointer(glu::VTX_COMP_FLOAT, glu::VTX_COMP_CONVERT_NONE, 2, 6, 0, s_positions))
    825 			};
    826 
    827 			glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));
    828 
    829 			gl.uniform1f(scaleLoc, 0.25f);
    830 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f(scaleLoc, 0.25f)");
    831 
    832 			glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));
    833 
    834 			break;
    835 		}
    836 
    837 		case GL_TEXTURE_3D:
    838 		{
    839 			glu::VertexArrayBinding vertexArrays[] =
    840 			{
    841 				glu::VertexArrayBinding(glu::BindingPoint("a_position"), glu::VertexArrayPointer(glu::VTX_COMP_FLOAT, glu::VTX_COMP_CONVERT_NONE, 3, 6, 0, s_positions3D))
    842 			};
    843 
    844 			glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));
    845 
    846 			gl.uniform1f(scaleLoc, 0.25f);
    847 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f(scaleLoc, 0.25f)");
    848 
    849 			glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));
    850 
    851 			break;
    852 		}
    853 
    854 		case GL_TEXTURE_CUBE_MAP:
    855 		{
    856 			glu::VertexArrayBinding vertexArrays[] =
    857 			{
    858 				glu::VertexArrayBinding(glu::BindingPoint("a_position"), glu::VertexArrayPointer(glu::VTX_COMP_FLOAT, glu::VTX_COMP_CONVERT_NONE, 4, 6, 0, s_positionsCube))
    859 			};
    860 
    861 			glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));
    862 
    863 			gl.uniform1f(scaleLoc, 0.25f);
    864 			GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f(scaleLoc, 0.25f)");
    865 
    866 			glu::draw(m_renderCtx, m_program->getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), vertexArrays, glu::PrimitiveList(glu::PRIMITIVETYPE_TRIANGLES, 6));
    867 
    868 			break;
    869 		}
    870 
    871 		default:
    872 			DE_ASSERT(false);
    873 	}
    874 }
    875 
    876 GLuint MultiTextureSamplerTest::createTexture2D (const glw::Functions& gl, int id)
    877 {
    878 	GLuint			texture		= (GLuint)-1;
    879 	tcu::Texture2D	refTexture	(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEXTURE2D_WIDTH, TEXTURE2D_HEIGHT);
    880 
    881 	refTexture.allocLevel(0);
    882 
    883 	gl.genTextures(1, &texture);
    884 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures(1, &texture)");
    885 
    886 	switch (id)
    887 	{
    888 		case 0:
    889 			tcu::fillWithComponentGradients(refTexture.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.5f, 0.5f));
    890 			break;
    891 
    892 		case 1:
    893 			tcu::fillWithComponentGradients(refTexture.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f));
    894 			break;
    895 
    896 		default:
    897 			DE_ASSERT(false);
    898 	}
    899 
    900 	gl.bindTexture(GL_TEXTURE_2D, texture);
    901 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_2D, texture)");
    902 
    903 	gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, refTexture.getWidth(), refTexture.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevel(0).getDataPtr());
    904 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, refTexture.getWidth(), refTexture.getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevel(0).getDataPtr())");
    905 
    906 	gl.generateMipmap(GL_TEXTURE_2D);
    907 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap(GL_TEXTURE_2D)");
    908 
    909 	gl.bindTexture(GL_TEXTURE_2D, 0);
    910 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_2D, 0)");
    911 
    912 	return texture;
    913 }
    914 
    915 GLuint MultiTextureSamplerTest::createTexture3D (const glw::Functions& gl, int id)
    916 {
    917 	GLuint			texture		= (GLuint)-1;
    918 	tcu::Texture3D	refTexture	(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), TEXTURE3D_WIDTH, TEXTURE3D_HEIGHT, TEXTURE3D_DEPTH);
    919 
    920 	refTexture.allocLevel(0);
    921 
    922 	gl.genTextures(1, &texture);
    923 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures(1, &texture)");
    924 
    925 	switch (id)
    926 	{
    927 		case 0:
    928 			tcu::fillWithComponentGradients(refTexture.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.5f, 0.5f));
    929 			break;
    930 
    931 		case 1:
    932 			tcu::fillWithComponentGradients(refTexture.getLevel(0), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 1.0f, 1.0f));
    933 			break;
    934 
    935 		default:
    936 			DE_ASSERT(false);
    937 	}
    938 
    939 	gl.bindTexture(GL_TEXTURE_3D, texture);
    940 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_3D, texture)");
    941 
    942 	gl.texImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, refTexture.getWidth(), refTexture.getHeight(), refTexture.getDepth(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevel(0).getDataPtr());
    943 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, refTexture.getWidth(), refTexture.getHeight(), refTexture.getDepth(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevel(0).getDataPtr())");
    944 
    945 	gl.generateMipmap(GL_TEXTURE_3D);
    946 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap(GL_TEXTURE_3D)");
    947 
    948 	gl.bindTexture(GL_TEXTURE_3D, 0);
    949 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_3D, 0)");
    950 
    951 	return texture;
    952 }
    953 
    954 GLuint MultiTextureSamplerTest::createTextureCube (const glw::Functions& gl, int id)
    955 {
    956 	GLuint				texture		= (GLuint)-1;
    957 	tcu::TextureCube	refTexture	(tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), CUBEMAP_SIZE);
    958 
    959 	gl.genTextures(1, &texture);
    960 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenTextures(1, &texture)");
    961 
    962 	refTexture.allocLevel(tcu::CUBEFACE_POSITIVE_X, 0);
    963 	refTexture.allocLevel(tcu::CUBEFACE_POSITIVE_Y, 0);
    964 	refTexture.allocLevel(tcu::CUBEFACE_POSITIVE_Z, 0);
    965 	refTexture.allocLevel(tcu::CUBEFACE_NEGATIVE_X, 0);
    966 	refTexture.allocLevel(tcu::CUBEFACE_NEGATIVE_Y, 0);
    967 	refTexture.allocLevel(tcu::CUBEFACE_NEGATIVE_Z, 0);
    968 
    969 	switch (id)
    970 	{
    971 		case 0:
    972 			tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_X), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f));
    973 			tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_Y), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f));
    974 			tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_Z), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f));
    975 			tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_X), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f));
    976 			tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_Y), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f));
    977 			tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_Z), tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f));
    978 			break;
    979 
    980 		case 1:
    981 			tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_X), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
    982 			tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_Y), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
    983 			tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_POSITIVE_Z), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
    984 			tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_X), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
    985 			tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_Y), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
    986 			tcu::fillWithComponentGradients(refTexture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_Z), tcu::Vec4(0.5f, 0.5f, 0.5f, 0.5f), tcu::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
    987 			break;
    988 
    989 		default:
    990 			DE_ASSERT(false);
    991 	}
    992 
    993 	gl.bindTexture(GL_TEXTURE_CUBE_MAP, texture);
    994 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_CUBE_MAP, texture)");
    995 
    996 	for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
    997 	{
    998 		const deUint32 target = glu::getGLCubeFace((tcu::CubeFace)face);
    999 		gl.texImage2D(target, 0, GL_RGBA8, refTexture.getSize(), refTexture.getSize(), 0, GL_RGBA, GL_UNSIGNED_BYTE, refTexture.getLevelFace(0, (tcu::CubeFace)face).getDataPtr());
   1000 	}
   1001 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexImage2D(GL_TEXTURE_CUBE_MAP_...) failed");
   1002 
   1003 	gl.generateMipmap(GL_TEXTURE_CUBE_MAP);
   1004 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenerateMipmap(GL_TEXTURE_CUBE_MAP)");
   1005 	gl.bindTexture(GL_TEXTURE_CUBE_MAP, 0);
   1006 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(GL_TEXTURE_CUBE_MAP, 0)");
   1007 
   1008 	return texture;
   1009 }
   1010 
   1011 GLuint MultiTextureSamplerTest::createTexture (const glw::Functions& gl, GLenum target, int id)
   1012 {
   1013 	switch (target)
   1014 	{
   1015 		case GL_TEXTURE_2D:
   1016 			return createTexture2D(gl, id);
   1017 
   1018 		case GL_TEXTURE_3D:
   1019 			return createTexture3D(gl, id);
   1020 
   1021 		case GL_TEXTURE_CUBE_MAP:
   1022 			return createTextureCube(gl, id);
   1023 
   1024 		default:
   1025 			DE_ASSERT(false);
   1026 			return (GLuint)-1;
   1027 	}
   1028 }
   1029 
   1030 void MultiTextureSamplerTest::renderReferences (tcu::Surface& textureRef, tcu::Surface& samplerRef, int x, int y)
   1031 {
   1032 	const glw::Functions&	gl			= m_renderCtx.getFunctions();
   1033 	GLuint					texture1	= createTexture(gl, m_target, 0);
   1034 	GLuint					texture2	= createTexture(gl, m_target, 1);
   1035 
   1036 	gl.viewport(x, y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
   1037 	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport(x, y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT)");
   1038 
   1039 	// Generate texture rendering reference
   1040 	gl.activeTexture(GL_TEXTURE0);
   1041 	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture(GL_TEXTURE0)");
   1042 	gl.bindTexture(m_target, texture1);
   1043 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture1)");
   1044 	setTextureState(gl, m_target, m_textureState1);
   1045 
   1046 	gl.activeTexture(GL_TEXTURE1);
   1047 	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture(GL_TEXTURE1)");
   1048 	gl.bindTexture(m_target, texture2);
   1049 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture2)");
   1050 	setTextureState(gl, m_target, m_textureState2);
   1051 
   1052 	render();
   1053 	glu::readPixels(m_renderCtx, x, y, textureRef.getAccess());
   1054 
   1055 	// Generate sampler rendering reference
   1056 	gl.activeTexture(GL_TEXTURE0);
   1057 	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture(GL_TEXTURE0)");
   1058 	gl.bindTexture(m_target, texture1);
   1059 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture1)");
   1060 	setTextureState(gl, m_target, m_samplerState);
   1061 
   1062 	gl.activeTexture(GL_TEXTURE1);
   1063 	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture(GL_TEXTURE1)");
   1064 	gl.bindTexture(m_target, texture2);
   1065 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture2)");
   1066 	setTextureState(gl, m_target, m_samplerState);
   1067 
   1068 	render();
   1069 	glu::readPixels(m_renderCtx, x, y, samplerRef.getAccess());
   1070 }
   1071 
   1072 void MultiTextureSamplerTest::renderResults (tcu::Surface& textureResult, tcu::Surface& samplerResult, int x, int y)
   1073 {
   1074 	const glw::Functions&	gl			= m_renderCtx.getFunctions();
   1075 	GLuint					texture1	= createTexture(gl, m_target, 0);
   1076 	GLuint					texture2	= createTexture(gl, m_target, 1);
   1077 	GLuint					sampler		= -1;
   1078 
   1079 	gl.viewport(x, y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
   1080 	GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport(x, y, VIEWPORT_WIDTH, VIEWPORT_HEIGHT)");
   1081 
   1082 	gl.genSamplers(1, &sampler);
   1083 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGenSamplers(1, &sampler)");
   1084 	TCU_CHECK(sampler != (GLuint)-1);
   1085 
   1086 	gl.bindSampler(0, sampler);
   1087 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindSampler(0, sampler)");
   1088 	gl.bindSampler(1, sampler);
   1089 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindSampler(1, sampler)");
   1090 
   1091 	// First set sampler state
   1092 	setSamplerState(gl, m_samplerState, sampler);
   1093 
   1094 	// Set texture state
   1095 	gl.bindTexture(m_target, texture1);
   1096 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture1)");
   1097 	setTextureState(gl, m_target, m_textureState1);
   1098 
   1099 	gl.bindTexture(m_target, texture2);
   1100 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture2)");
   1101 	setTextureState(gl, m_target, m_textureState2);
   1102 
   1103 	gl.activeTexture(GL_TEXTURE0);
   1104 	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture(GL_TEXTURE0)");
   1105 	gl.bindTexture(m_target, texture1);
   1106 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture1)");
   1107 
   1108 	gl.activeTexture(GL_TEXTURE1);
   1109 	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture(GL_TEXTURE1)");
   1110 	gl.bindTexture(m_target, texture2);
   1111 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, texture2)");
   1112 
   1113 	// Render using sampler
   1114 	render();
   1115 	glu::readPixels(m_renderCtx, x, y, samplerResult.getAccess());
   1116 
   1117 	gl.bindSampler(0, 0);
   1118 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindSampler(0, 0)");
   1119 	gl.bindSampler(1, 0);
   1120 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindSampler(1, 0)");
   1121 
   1122 	render();
   1123 	glu::readPixels(m_renderCtx, x, y, textureResult.getAccess());
   1124 
   1125 	gl.activeTexture(GL_TEXTURE0);
   1126 	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture(GL_TEXTURE0)");
   1127 	gl.bindTexture(m_target, 0);
   1128 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, 0)");
   1129 
   1130 	gl.activeTexture(GL_TEXTURE1);
   1131 	GLU_EXPECT_NO_ERROR(gl.getError(), "glActiveTexture(GL_TEXTURE1)");
   1132 	gl.bindTexture(m_target, 0);
   1133 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindTexture(m_target, 0)");
   1134 
   1135 	gl.deleteSamplers(1, &sampler);
   1136 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteSamplers(1, &sampler)");
   1137 	gl.deleteTextures(1, &texture1);
   1138 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures(1, &texture1)");
   1139 	gl.deleteTextures(1, &texture2);
   1140 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures(1, &texture2)");
   1141 }
   1142 
   1143 tcu::TestCase::IterateResult MultiTextureSamplerTest::iterate (void)
   1144 {
   1145 	tcu::TestLog&	log = m_testCtx.getLog();
   1146 
   1147 	tcu::Surface	textureRef(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
   1148 	tcu::Surface	samplerRef(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
   1149 
   1150 	tcu::Surface	textureResult(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
   1151 	tcu::Surface	samplerResult(VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
   1152 
   1153 	int				x = m_random.getInt(0, m_renderCtx.getRenderTarget().getWidth() - VIEWPORT_WIDTH);
   1154 	int				y = m_random.getInt(0, m_renderCtx.getRenderTarget().getHeight() - VIEWPORT_HEIGHT);
   1155 
   1156 	renderReferences(textureRef, samplerRef, x, y);
   1157 	renderResults(textureResult, samplerResult, x, y);
   1158 
   1159 	bool isOk = pixelThresholdCompare (log, "Sampler render result", "Result from rendering with sampler", samplerRef, samplerResult, tcu::RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT);
   1160 
   1161 	if (!pixelThresholdCompare (log, "Texture render result", "Result from rendering with texture state", textureRef, textureResult, tcu::RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT))
   1162 		isOk = false;
   1163 
   1164 	if (!isOk)
   1165 	{
   1166 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
   1167 		return STOP;
   1168 	}
   1169 
   1170 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
   1171 	return STOP;
   1172 }
   1173 
   1174 
   1175 } // gls
   1176 } // deqp
   1177