Home | History | Annotate | Download | only in functional
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program OpenGL ES 3.1 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 Stencil texturing tests.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "es31fStencilTexturingTests.hpp"
     25 
     26 #include "gluStrUtil.hpp"
     27 #include "gluObjectWrapper.hpp"
     28 #include "gluRenderContext.hpp"
     29 #include "gluShaderProgram.hpp"
     30 #include "gluDrawUtil.hpp"
     31 #include "gluPixelTransfer.hpp"
     32 #include "gluTextureUtil.hpp"
     33 #include "gluContextInfo.hpp"
     34 
     35 #include "glsTextureTestUtil.hpp"
     36 
     37 #include "tcuVector.hpp"
     38 #include "tcuTexture.hpp"
     39 #include "tcuTextureUtil.hpp"
     40 #include "tcuTestLog.hpp"
     41 #include "tcuTexLookupVerifier.hpp"
     42 
     43 #include "glwFunctions.hpp"
     44 #include "glwEnums.hpp"
     45 
     46 #include "deStringUtil.hpp"
     47 
     48 namespace deqp
     49 {
     50 namespace gles31
     51 {
     52 namespace Functional
     53 {
     54 
     55 using std::vector;
     56 using std::string;
     57 using tcu::IVec4;
     58 using tcu::Vec2;
     59 using tcu::Vec4;
     60 using tcu::TestLog;
     61 using tcu::TextureLevel;
     62 using tcu::TextureFormat;
     63 
     64 namespace
     65 {
     66 
     67 static void genTestRects (vector<IVec4>& rects, int width, int height)
     68 {
     69 	int curWidth	= width;
     70 	int curHeight	= height;
     71 	int ndx			= 0;
     72 
     73 	for (;;)
     74 	{
     75 		rects.push_back(IVec4(width-curWidth, height-curHeight, curWidth, curHeight));
     76 
     77 		DE_ASSERT(curWidth >= 1 && curHeight >= 1);
     78 		if (curWidth == 1 && curHeight == 1)
     79 			break;
     80 		else if (curHeight > 1 && ((ndx%2) == 0 || curWidth == 1))
     81 			curHeight -= 1;
     82 		else
     83 			curWidth -= 1;
     84 
     85 		ndx += 1;
     86 	}
     87 }
     88 
     89 static void rectsToTriangles (const vector<IVec4>& rects, int width, int height, vector<Vec2>& positions, vector<deUint16>& indices)
     90 {
     91 	const float		w		= float(width);
     92 	const float		h		= float(height);
     93 
     94 	positions.resize(rects.size()*4);
     95 	indices.resize(rects.size()*6);
     96 
     97 	for (int rectNdx = 0; rectNdx < (int)rects.size(); rectNdx++)
     98 	{
     99 		const int		rx		= rects[rectNdx].x();
    100 		const int		ry		= rects[rectNdx].y();
    101 		const int		rw		= rects[rectNdx].z();
    102 		const int		rh		= rects[rectNdx].w();
    103 
    104 		const float		x0		= float(rx*2)/w - 1.0f;
    105 		const float		x1		= float((rx+rw)*2)/w - 1.0f;
    106 		const float		y0		= float(ry*2)/h - 1.0f;
    107 		const float		y1		= float((ry+rh)*2)/h - 1.0f;
    108 
    109 		positions[rectNdx*4 + 0] = Vec2(x0, y0);
    110 		positions[rectNdx*4 + 1] = Vec2(x1, y0);
    111 		positions[rectNdx*4 + 2] = Vec2(x0, y1);
    112 		positions[rectNdx*4 + 3] = Vec2(x1, y1);
    113 
    114 		indices[rectNdx*6 + 0] = (deUint16)(rectNdx*4 + 0);
    115 		indices[rectNdx*6 + 1] = (deUint16)(rectNdx*4 + 1);
    116 		indices[rectNdx*6 + 2] = (deUint16)(rectNdx*4 + 2);
    117 		indices[rectNdx*6 + 3] = (deUint16)(rectNdx*4 + 2);
    118 		indices[rectNdx*6 + 4] = (deUint16)(rectNdx*4 + 1);
    119 		indices[rectNdx*6 + 5] = (deUint16)(rectNdx*4 + 3);
    120 	}
    121 }
    122 
    123 static void drawTestPattern (const glu::RenderContext& renderCtx, int width, int height)
    124 {
    125 	const glu::ShaderProgram program(renderCtx, glu::ProgramSources()
    126 		<< glu::VertexSource(
    127 			"#version 300 es\n"
    128 			"in highp vec4 a_position;\n"
    129 			"void main (void)\n"
    130 			"{\n"
    131 			"	gl_Position = a_position;\n"
    132 			"}\n")
    133 		<< glu::FragmentSource(
    134 			"#version 300 es\n"
    135 			"void main (void) {}\n"));
    136 
    137 	const glw::Functions&	gl		= renderCtx.getFunctions();
    138 	vector<IVec4>			rects;
    139 	vector<Vec2>			positions;
    140 	vector<deUint16>		indices;
    141 
    142 	if (!program.isOk())
    143 		throw tcu::TestError("Compile failed");
    144 
    145 	gl.useProgram	(program.getProgram());
    146 	gl.viewport		(0, 0, width, height);
    147 	gl.clear		(GL_STENCIL_BUFFER_BIT);
    148 	gl.enable		(GL_STENCIL_TEST);
    149 	gl.stencilOp	(GL_KEEP, GL_KEEP, GL_INCR_WRAP);
    150 	gl.stencilFunc	(GL_ALWAYS, 0, ~0u);
    151 	GLU_EXPECT_NO_ERROR(gl.getError(), "State setup failed");
    152 
    153 	genTestRects	(rects, width, height);
    154 	rectsToTriangles(rects, width, height, positions, indices);
    155 
    156 	{
    157 		const glu::VertexArrayBinding posBinding = glu::va::Float("a_position", 2, (int)positions.size(), 0, positions[0].getPtr());
    158 		glu::draw(renderCtx, program.getProgram(), 1, &posBinding, glu::pr::Triangles((int)indices.size(), &indices[0]));
    159 	}
    160 
    161 	gl.disable(GL_STENCIL_TEST);
    162 }
    163 
    164 static void renderTestPatternReference (const tcu::PixelBufferAccess& dst)
    165 {
    166 	const int		stencilBits		= tcu::getTextureFormatBitDepth(tcu::getEffectiveDepthStencilAccess(dst, tcu::Sampler::MODE_STENCIL).getFormat()).x();
    167 	const deUint32	stencilMask		= (1u<<stencilBits)-1u;
    168 	vector<IVec4>	rects;
    169 
    170 	DE_ASSERT(dst.getFormat().order == TextureFormat::S || dst.getFormat().order == TextureFormat::DS);
    171 
    172 	// clear depth and stencil
    173 	if (dst.getFormat().order == TextureFormat::DS)
    174 		tcu::clearDepth(dst, 0.0f);
    175 	tcu::clearStencil(dst, 0u);
    176 
    177 	genTestRects(rects, dst.getWidth(), dst.getHeight());
    178 
    179 	for (vector<IVec4>::const_iterator rectIter = rects.begin(); rectIter != rects.end(); ++rectIter)
    180 	{
    181 		const int	x0		= rectIter->x();
    182 		const int	y0		= rectIter->y();
    183 		const int	x1		= x0+rectIter->z();
    184 		const int	y1		= y0+rectIter->w();
    185 
    186 		for (int y = y0; y < y1; y++)
    187 		{
    188 			for (int x = x0; x < x1; x++)
    189 			{
    190 				const int oldVal	= dst.getPixStencil(x, y);
    191 				const int newVal	= (oldVal+1)&stencilMask;
    192 
    193 				dst.setPixStencil(newVal, x, y);
    194 			}
    195 		}
    196 	}
    197 }
    198 
    199 static void blitStencilToColor2D (const glu::RenderContext& renderCtx, deUint32 srcTex, int width, int height)
    200 {
    201 	const glu::ShaderProgram program(renderCtx, glu::ProgramSources()
    202 		<< glu::VertexSource(
    203 			"#version 300 es\n"
    204 			"in highp vec4 a_position;\n"
    205 			"in highp vec2 a_texCoord;\n"
    206 			"out highp vec2 v_texCoord;\n"
    207 			"void main (void)\n"
    208 			"{\n"
    209 			"	gl_Position = a_position;\n"
    210 			"	v_texCoord = a_texCoord;\n"
    211 			"}\n")
    212 		<< glu::FragmentSource(
    213 			"#version 300 es\n"
    214 			"uniform highp usampler2D u_sampler;\n"
    215 			"in highp vec2 v_texCoord;\n"
    216 			"layout(location = 0) out highp uint o_stencil;\n"
    217 			"void main (void)\n"
    218 			"{\n"
    219 			"	o_stencil = texture(u_sampler, v_texCoord).x;\n"
    220 			"}\n"));
    221 
    222 	const float positions[] =
    223 	{
    224 		-1.0f, -1.0f,
    225 		+1.0f, -1.0f,
    226 		-1.0f, +1.0f,
    227 		+1.0f, +1.0f
    228 	};
    229 	const float texCoord[] =
    230 	{
    231 		0.0f, 0.0f,
    232 		1.0f, 0.0f,
    233 		0.0f, 1.0f,
    234 		1.0f, 1.0f
    235 	};
    236 	const glu::VertexArrayBinding vertexArrays[] =
    237 	{
    238 		glu::va::Float("a_position", 2, 4, 0, &positions[0]),
    239 		glu::va::Float("a_texCoord", 2, 4, 0, &texCoord[0])
    240 	};
    241 	const deUint8 indices[] = { 0, 1, 2, 2, 1, 3 };
    242 
    243 	const glw::Functions& gl = renderCtx.getFunctions();
    244 
    245 	if (!program.isOk())
    246 		throw tcu::TestError("Compile failed");
    247 
    248 	gl.activeTexture(GL_TEXTURE0);
    249 	gl.bindTexture(GL_TEXTURE_2D, srcTex);
    250 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    251 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    252 	gl.texParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
    253 	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture state setup failed");
    254 
    255 	gl.useProgram(program.getProgram());
    256 	gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_sampler"), 0);
    257 	GLU_EXPECT_NO_ERROR(gl.getError(), "Program setup failed");
    258 
    259 	gl.viewport(0, 0, width, height);
    260 	glu::draw(renderCtx, program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
    261 			  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
    262 }
    263 
    264 static void blitStencilToColor2DArray (const glu::RenderContext& renderCtx, deUint32 srcTex, int width, int height, int level)
    265 {
    266 	const glu::ShaderProgram program(renderCtx, glu::ProgramSources()
    267 		<< glu::VertexSource(
    268 			"#version 300 es\n"
    269 			"in highp vec4 a_position;\n"
    270 			"in highp vec3 a_texCoord;\n"
    271 			"out highp vec3 v_texCoord;\n"
    272 			"void main (void)\n"
    273 			"{\n"
    274 			"	gl_Position = a_position;\n"
    275 			"	v_texCoord = a_texCoord;\n"
    276 			"}\n")
    277 		<< glu::FragmentSource(
    278 			"#version 300 es\n"
    279 			"uniform highp usampler2DArray u_sampler;\n"
    280 			"in highp vec3 v_texCoord;\n"
    281 			"layout(location = 0) out highp uint o_stencil;\n"
    282 			"void main (void)\n"
    283 			"{\n"
    284 			"	o_stencil = texture(u_sampler, v_texCoord).x;\n"
    285 			"}\n"));
    286 
    287 	const float positions[] =
    288 	{
    289 		-1.0f, -1.0f,
    290 		+1.0f, -1.0f,
    291 		-1.0f, +1.0f,
    292 		+1.0f, +1.0f
    293 	};
    294 	const float texCoord[] =
    295 	{
    296 		0.0f, 0.0f, float(level),
    297 		1.0f, 0.0f, float(level),
    298 		0.0f, 1.0f, float(level),
    299 		1.0f, 1.0f, float(level)
    300 	};
    301 	const glu::VertexArrayBinding vertexArrays[] =
    302 	{
    303 		glu::va::Float("a_position", 2, 4, 0, &positions[0]),
    304 		glu::va::Float("a_texCoord", 3, 4, 0, &texCoord[0])
    305 	};
    306 	const deUint8 indices[] = { 0, 1, 2, 2, 1, 3 };
    307 
    308 	const glw::Functions& gl = renderCtx.getFunctions();
    309 
    310 	if (!program.isOk())
    311 		throw tcu::TestError("Compile failed");
    312 
    313 	gl.activeTexture(GL_TEXTURE0);
    314 	gl.bindTexture(GL_TEXTURE_2D_ARRAY, srcTex);
    315 	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    316 	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    317 	gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
    318 	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture state setup failed");
    319 
    320 	gl.useProgram(program.getProgram());
    321 	gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_sampler"), 0);
    322 	GLU_EXPECT_NO_ERROR(gl.getError(), "Program setup failed");
    323 
    324 	gl.viewport(0, 0, width, height);
    325 	glu::draw(renderCtx, program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
    326 			  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
    327 }
    328 
    329 static void blitStencilToColorCube (const glu::RenderContext& renderCtx, deUint32 srcTex, const float* texCoord, int width, int height)
    330 {
    331 	const glu::ShaderProgram program(renderCtx, glu::ProgramSources()
    332 		<< glu::VertexSource(
    333 			"#version 300 es\n"
    334 			"in highp vec4 a_position;\n"
    335 			"in highp vec3 a_texCoord;\n"
    336 			"out highp vec3 v_texCoord;\n"
    337 			"void main (void)\n"
    338 			"{\n"
    339 			"	gl_Position = a_position;\n"
    340 			"	v_texCoord = a_texCoord;\n"
    341 			"}\n")
    342 		<< glu::FragmentSource(
    343 			"#version 300 es\n"
    344 			"uniform highp usamplerCube u_sampler;\n"
    345 			"in highp vec3 v_texCoord;\n"
    346 			"layout(location = 0) out highp vec4 o_color;\n"
    347 			"void main (void)\n"
    348 			"{\n"
    349 			"	o_color.x = float(texture(u_sampler, v_texCoord).x) / 255.0;\n"
    350 			"	o_color.yzw = vec3(0.0, 0.0, 1.0);\n"
    351 			"}\n"));
    352 
    353 	const float positions[] =
    354 	{
    355 		-1.0f, -1.0f,
    356 		-1.0f, +1.0f,
    357 		+1.0f, -1.0f,
    358 		+1.0f, +1.0f
    359 	};
    360 	const glu::VertexArrayBinding vertexArrays[] =
    361 	{
    362 		glu::va::Float("a_position", 2, 4, 0, &positions[0]),
    363 		glu::va::Float("a_texCoord", 3, 4, 0, texCoord)
    364 	};
    365 	const deUint8 indices[] = { 0, 1, 2, 2, 1, 3 };
    366 
    367 	const glw::Functions& gl = renderCtx.getFunctions();
    368 
    369 	if (!program.isOk())
    370 		throw tcu::TestError("Compile failed");
    371 
    372 	gl.activeTexture(GL_TEXTURE0);
    373 	gl.bindTexture(GL_TEXTURE_CUBE_MAP, srcTex);
    374 	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    375 	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    376 	gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
    377 	GLU_EXPECT_NO_ERROR(gl.getError(), "Texture state setup failed");
    378 
    379 	gl.useProgram(program.getProgram());
    380 	gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_sampler"), 0);
    381 	GLU_EXPECT_NO_ERROR(gl.getError(), "Program setup failed");
    382 
    383 	gl.viewport(0, 0, width, height);
    384 	glu::draw(renderCtx, program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
    385 			  glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
    386 }
    387 
    388 static inline tcu::ConstPixelBufferAccess stencilToRedAccess (const tcu::ConstPixelBufferAccess& access)
    389 {
    390 	DE_ASSERT(access.getFormat() == TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8));
    391 	return tcu::ConstPixelBufferAccess(TextureFormat(TextureFormat::R, TextureFormat::UNSIGNED_INT8), access.getSize(), access.getPitch(), access.getDataPtr());
    392 }
    393 
    394 static bool compareStencilToRed (tcu::TestLog& log, const tcu::ConstPixelBufferAccess& stencilRef, const tcu::ConstPixelBufferAccess& result)
    395 {
    396 	const int		maxPrints		= 10;
    397 	int				numFailed		= 0;
    398 
    399 	DE_ASSERT(stencilRef.getFormat().order == TextureFormat::S);
    400 	DE_ASSERT(stencilRef.getWidth() == result.getWidth() && stencilRef.getHeight() == result.getHeight());
    401 
    402 	for (int y = 0; y < stencilRef.getHeight(); y++)
    403 	{
    404 		for (int x = 0; x < stencilRef.getWidth(); x++)
    405 		{
    406 			const int		ref		= stencilRef.getPixStencil(x, y);
    407 			const int		res		= result.getPixelInt(x, y).x();
    408 
    409 			if (ref != res)
    410 			{
    411 				if (numFailed < maxPrints)
    412 					log << TestLog::Message << "ERROR: Expected " << ref << ", got " << res << " at (" << x << ", " << y << ")" << TestLog::EndMessage;
    413 				else if (numFailed == maxPrints)
    414 					log << TestLog::Message << "..." << TestLog::EndMessage;
    415 
    416 				numFailed += 1;
    417 			}
    418 		}
    419 	}
    420 
    421 	log << TestLog::Message << "Found " << numFailed << " faulty pixels, comparison " << (numFailed == 0 ? "passed." : "FAILED!") << TestLog::EndMessage;
    422 
    423 	log << TestLog::ImageSet("ComparisonResult", "Image comparison result")
    424 		<< TestLog::Image("Result", "Result stencil buffer", result);
    425 
    426 	if (numFailed > 0)
    427 		log << TestLog::Image("Reference", "Reference stencil buffer", stencilToRedAccess(stencilRef));
    428 
    429 	log << TestLog::EndImageSet;
    430 
    431 	return numFailed == 0;
    432 }
    433 
    434 static bool compareRedChannel (tcu::TestLog& log, const tcu::ConstPixelBufferAccess& result, int reference)
    435 {
    436 	const int		maxPrints		= 10;
    437 	int				numFailed		= 0;
    438 
    439 	for (int y = 0; y < result.getHeight(); y++)
    440 	{
    441 		for (int x = 0; x < result.getWidth(); x++)
    442 		{
    443 			const int res = result.getPixelInt(x, y).x();
    444 
    445 			if (reference != res)
    446 			{
    447 				if (numFailed < maxPrints)
    448 					log << TestLog::Message << "ERROR: Expected " << reference << ", got " << res << " at (" << x << ", " << y << ")" << TestLog::EndMessage;
    449 				else if (numFailed == maxPrints)
    450 					log << TestLog::Message << "..." << TestLog::EndMessage;
    451 
    452 				numFailed += 1;
    453 			}
    454 		}
    455 	}
    456 
    457 	log << TestLog::Message << "Found " << numFailed << " faulty pixels, comparison " << (numFailed == 0 ? "passed." : "FAILED!") << TestLog::EndMessage;
    458 
    459 	log << TestLog::ImageSet("ComparisonResult", "Image comparison result")
    460 		<< TestLog::Image("Result", "Result stencil buffer", result);
    461 
    462 	log << TestLog::EndImageSet;
    463 
    464 	return numFailed == 0;
    465 }
    466 
    467 static void stencilToUnorm8 (const tcu::TextureCube& src, tcu::TextureCube& dst)
    468 {
    469 	for (int levelNdx = 0; levelNdx < src.getNumLevels(); levelNdx++)
    470 	{
    471 		for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
    472 		{
    473 			const tcu::CubeFace face = tcu::CubeFace(faceNdx);
    474 
    475 			if (!src.isLevelEmpty(face, levelNdx))
    476 			{
    477 				dst.allocLevel(face, levelNdx);
    478 
    479 				const tcu::ConstPixelBufferAccess	srcLevel	= src.getLevelFace(levelNdx, face);
    480 				const tcu::PixelBufferAccess		dstLevel	= dst.getLevelFace(levelNdx, face);
    481 
    482 				for (int y = 0; y < src.getSize(); y++)
    483 				for (int x = 0; x < src.getSize(); x++)
    484 					dstLevel.setPixel(Vec4(float(srcLevel.getPixStencil(x, y)) / 255.f, 0.f, 0.f, 1.f), x, y);
    485 			}
    486 		}
    487 	}
    488 }
    489 
    490 static void checkDepthStencilFormatSupport (const glu::ContextInfo& ctxInfo, deUint32 format)
    491 {
    492 	if (format == GL_STENCIL_INDEX8)
    493 	{
    494 		const char* reqExt = "GL_OES_texture_stencil8";
    495 		if (!ctxInfo.isExtensionSupported(reqExt))
    496 			throw tcu::NotSupportedError(glu::getTextureFormatStr(format).toString() + " requires " + reqExt);
    497 	}
    498 	else
    499 	{
    500 		DE_ASSERT(format == GL_DEPTH32F_STENCIL8 || format == GL_DEPTH24_STENCIL8);
    501 	}
    502 }
    503 
    504 static void checkFramebufferStatus (const glw::Functions& gl)
    505 {
    506 	const deUint32 status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
    507 
    508 	if (status == GL_FRAMEBUFFER_UNSUPPORTED)
    509 		throw tcu::NotSupportedError("Unsupported framebuffer configuration");
    510 	else if (status != GL_FRAMEBUFFER_COMPLETE)
    511 		throw tcu::TestError("Incomplete framebuffer: " + glu::getFramebufferStatusStr(status).toString());
    512 }
    513 
    514 class UploadTex2DCase : public TestCase
    515 {
    516 public:
    517 	UploadTex2DCase (Context& context, const char* name, deUint32 format)
    518 		: TestCase	(context, name, glu::getTextureFormatName(format))
    519 		, m_format	(format)
    520 	{
    521 	}
    522 
    523 	IterateResult iterate (void)
    524 	{
    525 		const glu::RenderContext&	renderCtx			= m_context.getRenderContext();
    526 		const glw::Functions&		gl					= renderCtx.getFunctions();
    527 		const int					width				= 129;
    528 		const int					height				= 113;
    529 		glu::Framebuffer			fbo					(renderCtx);
    530 		glu::Renderbuffer			colorBuf			(renderCtx);
    531 		glu::Texture				depthStencilTex		(renderCtx);
    532 		TextureLevel				uploadLevel			(glu::mapGLInternalFormat(m_format), width, height);
    533 		TextureLevel				readLevel			(TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), width, height);
    534 		TextureLevel				stencilOnlyLevel	(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), width, height);
    535 
    536 		checkDepthStencilFormatSupport(m_context.getContextInfo(), m_format);
    537 
    538 		renderTestPatternReference(uploadLevel);
    539 		renderTestPatternReference(stencilOnlyLevel);
    540 
    541 		gl.bindTexture(GL_TEXTURE_2D, *depthStencilTex);
    542 		gl.texStorage2D(GL_TEXTURE_2D, 1, m_format, width, height);
    543 		glu::texSubImage2D(renderCtx, GL_TEXTURE_2D, 0, 0, 0, uploadLevel);
    544 		GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading texture data failed");
    545 
    546 		gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
    547 		gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, width, height);
    548 
    549 		gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
    550 		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
    551 		checkFramebufferStatus(gl);
    552 
    553 		blitStencilToColor2D(renderCtx, *depthStencilTex, width, height);
    554 		glu::readPixels(renderCtx, 0, 0, readLevel);
    555 
    556 		{
    557 			const bool compareOk = compareStencilToRed(m_testCtx.getLog(), stencilOnlyLevel, readLevel);
    558 			m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
    559 									compareOk ? "Pass"				: "Image comparison failed");
    560 		}
    561 
    562 		return STOP;
    563 	}
    564 
    565 private:
    566 	const deUint32 m_format;
    567 };
    568 
    569 class UploadTex2DArrayCase : public TestCase
    570 {
    571 public:
    572 	UploadTex2DArrayCase (Context& context, const char* name, deUint32 format)
    573 		: TestCase	(context, name, glu::getTextureFormatName(format))
    574 		, m_format	(format)
    575 	{
    576 	}
    577 
    578 	IterateResult iterate (void)
    579 	{
    580 		const glu::RenderContext&	renderCtx			= m_context.getRenderContext();
    581 		const glw::Functions&		gl					= renderCtx.getFunctions();
    582 		const int					width				= 41;
    583 		const int					height				= 13;
    584 		const int					levels				= 7;
    585 		const int					ptrnLevel			= 3;
    586 		glu::Framebuffer			fbo					(renderCtx);
    587 		glu::Renderbuffer			colorBuf			(renderCtx);
    588 		glu::Texture				depthStencilTex		(renderCtx);
    589 		TextureLevel				uploadLevel			(glu::mapGLInternalFormat(m_format), width, height, levels);
    590 
    591 		checkDepthStencilFormatSupport(m_context.getContextInfo(), m_format);
    592 
    593 		for (int levelNdx = 0; levelNdx < levels; levelNdx++)
    594 		{
    595 			const tcu::PixelBufferAccess levelAccess = tcu::getSubregion(uploadLevel.getAccess(), 0, 0, levelNdx, width, height, 1);
    596 
    597 			if (levelNdx == ptrnLevel)
    598 				renderTestPatternReference(levelAccess);
    599 			else
    600 				tcu::clearStencil(levelAccess, levelNdx);
    601 		}
    602 
    603 		gl.bindTexture(GL_TEXTURE_2D_ARRAY, *depthStencilTex);
    604 		gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1, m_format, width, height, levels);
    605 		glu::texSubImage3D(renderCtx, GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, uploadLevel);
    606 		GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading texture data failed");
    607 
    608 		gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
    609 		gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, width, height);
    610 
    611 		gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
    612 		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
    613 		checkFramebufferStatus(gl);
    614 
    615 		{
    616 			TextureLevel	readLevel		(TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), width, height);
    617 			bool			allLevelsOk		= true;
    618 
    619 			for (int levelNdx = 0; levelNdx < levels; levelNdx++)
    620 			{
    621 				tcu::ScopedLogSection section(m_testCtx.getLog(), "Level" + de::toString(levelNdx), "Level " + de::toString(levelNdx));
    622 				bool levelOk;
    623 
    624 				blitStencilToColor2DArray(renderCtx, *depthStencilTex, width, height, levelNdx);
    625 				glu::readPixels(renderCtx, 0, 0, readLevel);
    626 
    627 				if (levelNdx == ptrnLevel)
    628 				{
    629 					TextureLevel reference(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), width, height);
    630 					renderTestPatternReference(reference);
    631 
    632 					levelOk = compareStencilToRed(m_testCtx.getLog(), reference, readLevel);
    633 				}
    634 				else
    635 					levelOk = compareRedChannel(m_testCtx.getLog(), readLevel, levelNdx);
    636 
    637 				if (!levelOk)
    638 				{
    639 					allLevelsOk = false;
    640 					break;
    641 				}
    642 			}
    643 
    644 			m_testCtx.setTestResult(allLevelsOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
    645 									allLevelsOk ? "Pass"				: "Image comparison failed");
    646 		}
    647 
    648 		return STOP;
    649 	}
    650 
    651 private:
    652 	const deUint32 m_format;
    653 };
    654 
    655 class UploadTexCubeCase : public TestCase
    656 {
    657 public:
    658 	UploadTexCubeCase (Context& context, const char* name, deUint32 format)
    659 		: TestCase	(context, name, glu::getTextureFormatName(format))
    660 		, m_format	(format)
    661 	{
    662 	}
    663 
    664 	IterateResult iterate (void)
    665 	{
    666 		const glu::RenderContext&	renderCtx			= m_context.getRenderContext();
    667 		const glw::Functions&		gl					= renderCtx.getFunctions();
    668 		const int					size				= 64;
    669 		const int					renderWidth			= 128;
    670 		const int					renderHeight		= 128;
    671 		vector<float>				texCoord;
    672 		glu::Framebuffer			fbo					(renderCtx);
    673 		glu::Renderbuffer			colorBuf			(renderCtx);
    674 		glu::Texture				depthStencilTex		(renderCtx);
    675 		tcu::TextureCube			texData				(glu::mapGLInternalFormat(m_format), size);
    676 		tcu::TextureLevel			result				(TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8), renderWidth, renderHeight);
    677 
    678 		checkDepthStencilFormatSupport(m_context.getContextInfo(), m_format);
    679 
    680 		for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
    681 		{
    682 			const tcu::CubeFace		face		= tcu::CubeFace(faceNdx);
    683 			const int				stencilVal	= 42*faceNdx;
    684 
    685 			texData.allocLevel(face, 0);
    686 			tcu::clearStencil(texData.getLevelFace(0, face), stencilVal);
    687 		}
    688 
    689 		glu::TextureTestUtil::computeQuadTexCoordCube(texCoord, tcu::CUBEFACE_NEGATIVE_X, Vec2(-1.5f, -1.3f), Vec2(1.3f, 1.4f));
    690 
    691 		gl.bindTexture(GL_TEXTURE_CUBE_MAP, *depthStencilTex);
    692 		gl.texStorage2D(GL_TEXTURE_CUBE_MAP, 1, m_format, size, size);
    693 
    694 		for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
    695 			glu::texSubImage2D(renderCtx, glu::getGLCubeFace(tcu::CubeFace(faceNdx)), 0, 0, 0, texData.getLevelFace(0, tcu::CubeFace(faceNdx)));
    696 
    697 		GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading texture data failed");
    698 
    699 		gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
    700 		gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, renderWidth, renderHeight);
    701 
    702 		gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
    703 		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
    704 		checkFramebufferStatus(gl);
    705 
    706 		blitStencilToColorCube(renderCtx, *depthStencilTex, &texCoord[0], renderWidth, renderHeight);
    707 		glu::readPixels(renderCtx, 0, 0, result);
    708 
    709 		{
    710 			using namespace glu::TextureTestUtil;
    711 
    712 			tcu::TextureCube		redTex			(TextureFormat(TextureFormat::R, TextureFormat::UNORM_INT8), size);
    713 			const ReferenceParams	sampleParams	(TEXTURETYPE_CUBE, tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE,
    714 																					tcu::Sampler::CLAMP_TO_EDGE,
    715 																					tcu::Sampler::CLAMP_TO_EDGE,
    716 																					tcu::Sampler::NEAREST,
    717 																					tcu::Sampler::NEAREST));
    718 			tcu::LookupPrecision	lookupPrec;
    719 			tcu::LodPrecision		lodPrec;
    720 			bool					compareOk;
    721 
    722 			lookupPrec.colorMask		= tcu::BVec4(true, true, true, true);
    723 			lookupPrec.colorThreshold	= tcu::computeFixedPointThreshold(IVec4(8, 8, 8, 8));
    724 			lookupPrec.coordBits		= tcu::IVec3(22, 22, 22);
    725 			lookupPrec.uvwBits			= tcu::IVec3(5, 5, 0);
    726 			lodPrec.lodBits				= 7;
    727 			lodPrec.derivateBits		= 16;
    728 
    729 			stencilToUnorm8(texData, redTex);
    730 
    731 			compareOk = verifyTextureResult(m_testCtx, result, redTex, &texCoord[0], sampleParams, lookupPrec, lodPrec, tcu::PixelFormat(8, 8, 8, 8));
    732 
    733 			m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
    734 									compareOk ? "Pass"				: "Image comparison failed");
    735 		}
    736 
    737 		return STOP;
    738 	}
    739 
    740 private:
    741 	const deUint32 m_format;
    742 };
    743 
    744 class RenderTex2DCase : public TestCase
    745 {
    746 public:
    747 	RenderTex2DCase (Context& context, const char* name, deUint32 format)
    748 		: TestCase	(context, name, glu::getTextureFormatName(format))
    749 		, m_format	(format)
    750 	{
    751 	}
    752 
    753 	IterateResult iterate (void)
    754 	{
    755 		const glu::RenderContext&	renderCtx		= m_context.getRenderContext();
    756 		const glw::Functions&		gl				= renderCtx.getFunctions();
    757 		const int					width			= 117;
    758 		const int					height			= 193;
    759 		glu::Framebuffer			fbo				(renderCtx);
    760 		glu::Renderbuffer			colorBuf		(renderCtx);
    761 		glu::Texture				depthStencilTex	(renderCtx);
    762 		TextureLevel				result			(TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), width, height);
    763 		TextureLevel				reference		(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), width, height);
    764 
    765 		checkDepthStencilFormatSupport(m_context.getContextInfo(), m_format);
    766 
    767 		gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
    768 		gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, width, height);
    769 
    770 		gl.bindTexture(GL_TEXTURE_2D, *depthStencilTex);
    771 		gl.texStorage2D(GL_TEXTURE_2D, 1, m_format, width, height);
    772 
    773 		gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
    774 		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
    775 		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, *depthStencilTex, 0);
    776 		checkFramebufferStatus(gl);
    777 
    778 		drawTestPattern(renderCtx, width, height);
    779 
    780 		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
    781 		checkFramebufferStatus(gl);
    782 
    783 		blitStencilToColor2D(renderCtx, *depthStencilTex, width, height);
    784 		glu::readPixels(renderCtx, 0, 0, result.getAccess());
    785 
    786 		renderTestPatternReference(reference);
    787 
    788 		{
    789 			const bool compareOk = compareStencilToRed(m_testCtx.getLog(), reference, result);
    790 			m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
    791 									compareOk ? "Pass"				: "Image comparison failed");
    792 		}
    793 
    794 		return STOP;
    795 	}
    796 
    797 private:
    798 	const deUint32 m_format;
    799 };
    800 
    801 class ClearTex2DCase : public TestCase
    802 {
    803 public:
    804 	ClearTex2DCase (Context& context, const char* name, deUint32 format)
    805 		: TestCase	(context, name, glu::getTextureFormatName(format))
    806 		, m_format	(format)
    807 	{
    808 	}
    809 
    810 	IterateResult iterate (void)
    811 	{
    812 		const glu::RenderContext&	renderCtx		= m_context.getRenderContext();
    813 		const glw::Functions&		gl				= renderCtx.getFunctions();
    814 		const int					width			= 125;
    815 		const int					height			= 117;
    816 		const int					cellSize		= 8;
    817 		glu::Framebuffer			fbo				(renderCtx);
    818 		glu::Renderbuffer			colorBuf		(renderCtx);
    819 		glu::Texture				depthStencilTex	(renderCtx);
    820 		TextureLevel				result			(TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), width, height);
    821 		TextureLevel				reference		(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), width, height);
    822 
    823 		checkDepthStencilFormatSupport(m_context.getContextInfo(), m_format);
    824 
    825 		gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
    826 		gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, width, height);
    827 
    828 		gl.bindTexture(GL_TEXTURE_2D, *depthStencilTex);
    829 		gl.texStorage2D(GL_TEXTURE_2D, 1, m_format, width, height);
    830 
    831 		gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
    832 		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
    833 		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, *depthStencilTex, 0);
    834 		checkFramebufferStatus(gl);
    835 
    836 		gl.enable(GL_SCISSOR_TEST);
    837 
    838 		for (int y = 0; y < height; y += cellSize)
    839 		{
    840 			for (int x = 0; x < width; x += cellSize)
    841 			{
    842 				const int		clearW		= de::min(cellSize, width-x);
    843 				const int		clearH		= de::min(cellSize, height-y);
    844 				const int		stencil		= int((deInt32Hash(x) ^ deInt32Hash(y)) & 0xff);
    845 
    846 				gl.clearStencil(stencil);
    847 				gl.scissor(x, y, clearW, clearH);
    848 				gl.clear(GL_STENCIL_BUFFER_BIT);
    849 
    850 				tcu::clearStencil(tcu::getSubregion(reference.getAccess(), x, y, clearW, clearH), stencil);
    851 			}
    852 		}
    853 
    854 		gl.disable(GL_SCISSOR_TEST);
    855 
    856 		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
    857 		checkFramebufferStatus(gl);
    858 
    859 		blitStencilToColor2D(renderCtx, *depthStencilTex, width, height);
    860 		glu::readPixels(renderCtx, 0, 0, result.getAccess());
    861 
    862 		{
    863 			const bool compareOk = compareStencilToRed(m_testCtx.getLog(), reference, result);
    864 			m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
    865 									compareOk ? "Pass"				: "Image comparison failed");
    866 		}
    867 
    868 		return STOP;
    869 	}
    870 
    871 private:
    872 	const deUint32 m_format;
    873 };
    874 
    875 class CompareModeCase : public TestCase
    876 {
    877 public:
    878 	CompareModeCase (Context& context, const char* name, deUint32 format)
    879 		: TestCase	(context, name, glu::getTextureFormatName(format))
    880 		, m_format	(format)
    881 	{
    882 	}
    883 
    884 	IterateResult iterate (void)
    885 	{
    886 		const glu::RenderContext&	renderCtx			= m_context.getRenderContext();
    887 		const glw::Functions&		gl					= renderCtx.getFunctions();
    888 		const int					width				= 64;
    889 		const int					height				= 64;
    890 		glu::Framebuffer			fbo					(renderCtx);
    891 		glu::Renderbuffer			colorBuf			(renderCtx);
    892 		glu::Texture				depthStencilTex		(renderCtx);
    893 		TextureLevel				uploadLevel			(glu::mapGLInternalFormat(m_format), width, height);
    894 		TextureLevel				readLevel			(TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), width, height);
    895 		TextureLevel				stencilOnlyLevel	(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), width, height);
    896 
    897 		checkDepthStencilFormatSupport(m_context.getContextInfo(), m_format);
    898 
    899 		m_testCtx.getLog() << TestLog::Message << "NOTE: Texture compare mode has no effect when reading stencil values." << TestLog::EndMessage;
    900 
    901 		renderTestPatternReference(uploadLevel);
    902 		renderTestPatternReference(stencilOnlyLevel);
    903 
    904 		gl.bindTexture(GL_TEXTURE_2D, *depthStencilTex);
    905 		gl.texStorage2D(GL_TEXTURE_2D, 1, m_format, width, height);
    906 		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
    907 		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
    908 		glu::texSubImage2D(renderCtx, GL_TEXTURE_2D, 0, 0, 0, uploadLevel);
    909 		GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading texture data failed");
    910 
    911 		gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
    912 		gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, width, height);
    913 
    914 		gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
    915 		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
    916 		checkFramebufferStatus(gl);
    917 
    918 		blitStencilToColor2D(renderCtx, *depthStencilTex, width, height);
    919 		glu::readPixels(renderCtx, 0, 0, readLevel);
    920 
    921 		{
    922 			const bool compareOk = compareStencilToRed(m_testCtx.getLog(), stencilOnlyLevel, readLevel);
    923 			m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
    924 									compareOk ? "Pass"				: "Image comparison failed");
    925 		}
    926 
    927 		return STOP;
    928 	}
    929 
    930 private:
    931 	const deUint32 m_format;
    932 };
    933 
    934 class BaseLevelCase : public TestCase
    935 {
    936 public:
    937 	BaseLevelCase (Context& context, const char* name, deUint32 format)
    938 		: TestCase	(context, name, glu::getTextureFormatName(format))
    939 		, m_format	(format)
    940 	{
    941 	}
    942 
    943 	IterateResult iterate (void)
    944 	{
    945 		const glu::RenderContext&	renderCtx			= m_context.getRenderContext();
    946 		const glw::Functions&		gl					= renderCtx.getFunctions();
    947 		const int					width				= 128;
    948 		const int					height				= 128;
    949 		const int					levelNdx			= 2;
    950 		const int					levelWidth			= width>>levelNdx;
    951 		const int					levelHeight			= height>>levelNdx;
    952 		glu::Framebuffer			fbo					(renderCtx);
    953 		glu::Renderbuffer			colorBuf			(renderCtx);
    954 		glu::Texture				depthStencilTex		(renderCtx);
    955 		TextureLevel				uploadLevel			(glu::mapGLInternalFormat(m_format), levelWidth, levelHeight);
    956 		TextureLevel				readLevel			(TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), levelWidth, levelHeight);
    957 		TextureLevel				stencilOnlyLevel	(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), levelWidth, levelHeight);
    958 
    959 		checkDepthStencilFormatSupport(m_context.getContextInfo(), m_format);
    960 
    961 		m_testCtx.getLog() << TestLog::Message << "GL_TEXTURE_BASE_LEVEL = " << levelNdx << TestLog::EndMessage;
    962 
    963 		renderTestPatternReference(uploadLevel);
    964 		renderTestPatternReference(stencilOnlyLevel);
    965 
    966 		gl.bindTexture(GL_TEXTURE_2D, *depthStencilTex);
    967 		gl.texStorage2D(GL_TEXTURE_2D, deLog2Floor32(de::max(width, height))+1, m_format, width, height);
    968 		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, levelNdx);
    969 		glu::texSubImage2D(renderCtx, GL_TEXTURE_2D, levelNdx, 0, 0, uploadLevel);
    970 		GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading texture data failed");
    971 
    972 		gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
    973 		gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, levelWidth, levelHeight);
    974 
    975 		gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
    976 		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
    977 		checkFramebufferStatus(gl);
    978 
    979 		blitStencilToColor2D(renderCtx, *depthStencilTex, levelWidth, levelHeight);
    980 		glu::readPixels(renderCtx, 0, 0, readLevel);
    981 
    982 		{
    983 			const bool compareOk = compareStencilToRed(m_testCtx.getLog(), stencilOnlyLevel, readLevel);
    984 			m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
    985 									compareOk ? "Pass"				: "Image comparison failed");
    986 		}
    987 
    988 		return STOP;
    989 	}
    990 
    991 private:
    992 	const deUint32 m_format;
    993 };
    994 
    995 } // anonymous
    996 
    997 StencilTexturingTests::StencilTexturingTests (Context& context)
    998 	: TestCaseGroup(context, "stencil_texturing", "Stencil texturing tests")
    999 {
   1000 }
   1001 
   1002 StencilTexturingTests::~StencilTexturingTests (void)
   1003 {
   1004 }
   1005 
   1006 void StencilTexturingTests::init (void)
   1007 {
   1008 	// .format
   1009 	{
   1010 		tcu::TestCaseGroup* const formatGroup = new tcu::TestCaseGroup(m_testCtx, "format", "Formats");
   1011 		addChild(formatGroup);
   1012 
   1013 		formatGroup->addChild(new UploadTex2DCase		(m_context, "depth32f_stencil8_2d",			GL_DEPTH32F_STENCIL8));
   1014 		formatGroup->addChild(new UploadTex2DArrayCase	(m_context, "depth32f_stencil8_2d_array",	GL_DEPTH32F_STENCIL8));
   1015 		formatGroup->addChild(new UploadTexCubeCase		(m_context, "depth32f_stencil8_cube",		GL_DEPTH32F_STENCIL8));
   1016 		formatGroup->addChild(new UploadTex2DCase		(m_context, "depth24_stencil8_2d",			GL_DEPTH24_STENCIL8));
   1017 		formatGroup->addChild(new UploadTex2DArrayCase	(m_context, "depth24_stencil8_2d_array",	GL_DEPTH24_STENCIL8));
   1018 		formatGroup->addChild(new UploadTexCubeCase		(m_context, "depth24_stencil8_cube",		GL_DEPTH24_STENCIL8));
   1019 
   1020 		// OES_texture_stencil8
   1021 		formatGroup->addChild(new UploadTex2DCase		(m_context, "stencil_index8_2d",			GL_STENCIL_INDEX8));
   1022 		formatGroup->addChild(new UploadTex2DArrayCase	(m_context, "stencil_index8_2d_array",		GL_STENCIL_INDEX8));
   1023 		formatGroup->addChild(new UploadTexCubeCase		(m_context, "stencil_index8_cube",			GL_STENCIL_INDEX8));
   1024 	}
   1025 
   1026 	// .render
   1027 	{
   1028 		tcu::TestCaseGroup* const readRenderGroup = new tcu::TestCaseGroup(m_testCtx, "render", "Read rendered stencil values");
   1029 		addChild(readRenderGroup);
   1030 
   1031 		readRenderGroup->addChild(new ClearTex2DCase	(m_context, "depth32f_stencil8_clear",	GL_DEPTH32F_STENCIL8));
   1032 		readRenderGroup->addChild(new RenderTex2DCase	(m_context, "depth32f_stencil8_draw",	GL_DEPTH32F_STENCIL8));
   1033 		readRenderGroup->addChild(new ClearTex2DCase	(m_context, "depth24_stencil8_clear",	GL_DEPTH24_STENCIL8));
   1034 		readRenderGroup->addChild(new RenderTex2DCase	(m_context, "depth24_stencil8_draw",	GL_DEPTH24_STENCIL8));
   1035 	}
   1036 
   1037 	// .misc
   1038 	{
   1039 		tcu::TestCaseGroup* const miscGroup = new tcu::TestCaseGroup(m_testCtx, "misc", "Misc cases");
   1040 		addChild(miscGroup);
   1041 
   1042 		miscGroup->addChild(new CompareModeCase	(m_context, "compare_mode_effect",	GL_DEPTH24_STENCIL8));
   1043 		miscGroup->addChild(new BaseLevelCase	(m_context, "base_level",			GL_DEPTH24_STENCIL8));
   1044 	}
   1045 }
   1046 
   1047 } // Functional
   1048 } // gles31
   1049 } // deqp
   1050