• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
genTestRects(vector<IVec4> & rects,int width,int height)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 
rectsToTriangles(const vector<IVec4> & rects,int width,int height,vector<Vec2> & positions,vector<deUint16> & indices)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 
drawTestPattern(const glu::RenderContext & renderCtx,int width,int height)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 
renderTestPatternReference(const tcu::PixelBufferAccess & dst)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 
blitStencilToColor2D(const glu::RenderContext & renderCtx,deUint32 srcTex,int width,int height)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 
blitStencilToColor2DArray(const glu::RenderContext & renderCtx,deUint32 srcTex,int width,int height,int level)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 
blitStencilToColorCube(const glu::RenderContext & renderCtx,deUint32 srcTex,const float * texCoord,int width,int height)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 
stencilToRedAccess(const tcu::ConstPixelBufferAccess & access)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 
compareStencilToRed(tcu::TestLog & log,const tcu::ConstPixelBufferAccess & stencilRef,const tcu::ConstPixelBufferAccess & result)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 
compareRedChannel(tcu::TestLog & log,const tcu::ConstPixelBufferAccess & result,int reference)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 
stencilToUnorm8(const tcu::TextureCube & src,tcu::TextureCube & dst)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 
checkDepthStencilFormatSupport(const glu::ContextInfo & ctxInfo,deUint32 format)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 
checkFramebufferStatus(const glw::Functions & gl)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:
UploadTex2DCase(Context & context,const char * name,deUint32 format)517 	UploadTex2DCase (Context& context, const char* name, deUint32 format)
518 		: TestCase	(context, name, glu::getTextureFormatName(format))
519 		, m_format	(format)
520 	{
521 	}
522 
iterate(void)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:
UploadTex2DArrayCase(Context & context,const char * name,deUint32 format)572 	UploadTex2DArrayCase (Context& context, const char* name, deUint32 format)
573 		: TestCase	(context, name, glu::getTextureFormatName(format))
574 		, m_format	(format)
575 	{
576 	}
577 
iterate(void)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:
UploadTexCubeCase(Context & context,const char * name,deUint32 format)658 	UploadTexCubeCase (Context& context, const char* name, deUint32 format)
659 		: TestCase	(context, name, glu::getTextureFormatName(format))
660 		, m_format	(format)
661 	{
662 	}
663 
iterate(void)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 		gls::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 gls::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:
RenderTex2DCase(Context & context,const char * name,deUint32 format)747 	RenderTex2DCase (Context& context, const char* name, deUint32 format)
748 		: TestCase	(context, name, glu::getTextureFormatName(format))
749 		, m_format	(format)
750 	{
751 	}
752 
iterate(void)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:
ClearTex2DCase(Context & context,const char * name,deUint32 format)804 	ClearTex2DCase (Context& context, const char* name, deUint32 format)
805 		: TestCase	(context, name, glu::getTextureFormatName(format))
806 		, m_format	(format)
807 	{
808 	}
809 
iterate(void)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:
CompareModeCase(Context & context,const char * name,deUint32 format)878 	CompareModeCase (Context& context, const char* name, deUint32 format)
879 		: TestCase	(context, name, glu::getTextureFormatName(format))
880 		, m_format	(format)
881 	{
882 	}
883 
iterate(void)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:
BaseLevelCase(Context & context,const char * name,deUint32 format)937 	BaseLevelCase (Context& context, const char* name, deUint32 format)
938 		: TestCase	(context, name, glu::getTextureFormatName(format))
939 		, m_format	(format)
940 	{
941 	}
942 
iterate(void)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 
StencilTexturingTests(Context & context)997 StencilTexturingTests::StencilTexturingTests (Context& context)
998 	: TestCaseGroup(context, "stencil_texturing", "Stencil texturing tests")
999 {
1000 }
1001 
~StencilTexturingTests(void)1002 StencilTexturingTests::~StencilTexturingTests (void)
1003 {
1004 }
1005 
init(void)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