• 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(Context & context,deUint32 format)490 static void checkDepthStencilFormatSupport (Context& context, deUint32 format)
491 {
492 	if (format == GL_STENCIL_INDEX8)
493 	{
494 		const char*			reqExt		= "GL_OES_texture_stencil8";
495 		glu::ContextType	contextType	= context.getRenderContext().getType();
496 		if (!glu::contextSupports(contextType, glu::ApiType::es(3, 2)) &&
497 			!glu::contextSupports(contextType, glu::ApiType::core(4, 5)) &&
498 			!context.getContextInfo().isExtensionSupported(reqExt))
499 			throw tcu::NotSupportedError(glu::getTextureFormatStr(format).toString() + " requires " + reqExt);
500 	}
501 	else
502 	{
503 		DE_ASSERT(format == GL_DEPTH32F_STENCIL8 || format == GL_DEPTH24_STENCIL8);
504 	}
505 }
506 
checkFramebufferStatus(const glw::Functions & gl)507 static void checkFramebufferStatus (const glw::Functions& gl)
508 {
509 	const deUint32 status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
510 
511 	if (status == GL_FRAMEBUFFER_UNSUPPORTED)
512 		throw tcu::NotSupportedError("Unsupported framebuffer configuration");
513 	else if (status != GL_FRAMEBUFFER_COMPLETE)
514 		throw tcu::TestError("Incomplete framebuffer: " + glu::getFramebufferStatusStr(status).toString());
515 }
516 
517 class UploadTex2DCase : public TestCase
518 {
519 public:
UploadTex2DCase(Context & context,const char * name,deUint32 format)520 	UploadTex2DCase (Context& context, const char* name, deUint32 format)
521 		: TestCase	(context, name, glu::getTextureFormatName(format))
522 		, m_format	(format)
523 	{
524 	}
525 
iterate(void)526 	IterateResult iterate (void)
527 	{
528 		const glu::RenderContext&	renderCtx			= m_context.getRenderContext();
529 		const glw::Functions&		gl					= renderCtx.getFunctions();
530 		const int					width				= 129;
531 		const int					height				= 113;
532 		glu::Framebuffer			fbo					(renderCtx);
533 		glu::Renderbuffer			colorBuf			(renderCtx);
534 		glu::Texture				depthStencilTex		(renderCtx);
535 		TextureLevel				uploadLevel			(glu::mapGLInternalFormat(m_format), width, height);
536 		TextureLevel				readLevel			(TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), width, height);
537 		TextureLevel				stencilOnlyLevel	(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), width, height);
538 
539 		checkDepthStencilFormatSupport(m_context, m_format);
540 
541 		renderTestPatternReference(uploadLevel);
542 		renderTestPatternReference(stencilOnlyLevel);
543 
544 		gl.bindTexture(GL_TEXTURE_2D, *depthStencilTex);
545 		gl.texStorage2D(GL_TEXTURE_2D, 1, m_format, width, height);
546 		glu::texSubImage2D(renderCtx, GL_TEXTURE_2D, 0, 0, 0, uploadLevel);
547 		GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading texture data failed");
548 
549 		gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
550 		gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, width, height);
551 
552 		gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
553 		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
554 		checkFramebufferStatus(gl);
555 
556 		blitStencilToColor2D(renderCtx, *depthStencilTex, width, height);
557 		glu::readPixels(renderCtx, 0, 0, readLevel);
558 
559 		{
560 			const bool compareOk = compareStencilToRed(m_testCtx.getLog(), stencilOnlyLevel, readLevel);
561 			m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
562 									compareOk ? "Pass"				: "Image comparison failed");
563 		}
564 
565 		return STOP;
566 	}
567 
568 private:
569 	const deUint32 m_format;
570 };
571 
572 class UploadTex2DArrayCase : public TestCase
573 {
574 public:
UploadTex2DArrayCase(Context & context,const char * name,deUint32 format)575 	UploadTex2DArrayCase (Context& context, const char* name, deUint32 format)
576 		: TestCase	(context, name, glu::getTextureFormatName(format))
577 		, m_format	(format)
578 	{
579 	}
580 
iterate(void)581 	IterateResult iterate (void)
582 	{
583 		const glu::RenderContext&	renderCtx			= m_context.getRenderContext();
584 		const glw::Functions&		gl					= renderCtx.getFunctions();
585 		const int					width				= 41;
586 		const int					height				= 13;
587 		const int					levels				= 7;
588 		const int					ptrnLevel			= 3;
589 		glu::Framebuffer			fbo					(renderCtx);
590 		glu::Renderbuffer			colorBuf			(renderCtx);
591 		glu::Texture				depthStencilTex		(renderCtx);
592 		TextureLevel				uploadLevel			(glu::mapGLInternalFormat(m_format), width, height, levels);
593 
594 		checkDepthStencilFormatSupport(m_context, m_format);
595 
596 		for (int levelNdx = 0; levelNdx < levels; levelNdx++)
597 		{
598 			const tcu::PixelBufferAccess levelAccess = tcu::getSubregion(uploadLevel.getAccess(), 0, 0, levelNdx, width, height, 1);
599 
600 			if (levelNdx == ptrnLevel)
601 				renderTestPatternReference(levelAccess);
602 			else
603 				tcu::clearStencil(levelAccess, levelNdx);
604 		}
605 
606 		gl.bindTexture(GL_TEXTURE_2D_ARRAY, *depthStencilTex);
607 		gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1, m_format, width, height, levels);
608 		glu::texSubImage3D(renderCtx, GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, uploadLevel);
609 		GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading texture data failed");
610 
611 		gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
612 		gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, width, height);
613 
614 		gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
615 		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
616 		checkFramebufferStatus(gl);
617 
618 		{
619 			TextureLevel	readLevel		(TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), width, height);
620 			bool			allLevelsOk		= true;
621 
622 			for (int levelNdx = 0; levelNdx < levels; levelNdx++)
623 			{
624 				tcu::ScopedLogSection section(m_testCtx.getLog(), "Level" + de::toString(levelNdx), "Level " + de::toString(levelNdx));
625 				bool levelOk;
626 
627 				blitStencilToColor2DArray(renderCtx, *depthStencilTex, width, height, levelNdx);
628 				glu::readPixels(renderCtx, 0, 0, readLevel);
629 
630 				if (levelNdx == ptrnLevel)
631 				{
632 					TextureLevel reference(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), width, height);
633 					renderTestPatternReference(reference);
634 
635 					levelOk = compareStencilToRed(m_testCtx.getLog(), reference, readLevel);
636 				}
637 				else
638 					levelOk = compareRedChannel(m_testCtx.getLog(), readLevel, levelNdx);
639 
640 				if (!levelOk)
641 				{
642 					allLevelsOk = false;
643 					break;
644 				}
645 			}
646 
647 			m_testCtx.setTestResult(allLevelsOk ? QP_TEST_RESULT_PASS	: QP_TEST_RESULT_FAIL,
648 									allLevelsOk ? "Pass"				: "Image comparison failed");
649 		}
650 
651 		return STOP;
652 	}
653 
654 private:
655 	const deUint32 m_format;
656 };
657 
658 class UploadTexCubeCase : public TestCase
659 {
660 public:
UploadTexCubeCase(Context & context,const char * name,deUint32 format)661 	UploadTexCubeCase (Context& context, const char* name, deUint32 format)
662 		: TestCase	(context, name, glu::getTextureFormatName(format))
663 		, m_format	(format)
664 	{
665 	}
666 
iterate(void)667 	IterateResult iterate (void)
668 	{
669 		const glu::RenderContext&	renderCtx			= m_context.getRenderContext();
670 		const glw::Functions&		gl					= renderCtx.getFunctions();
671 		const int					size				= 64;
672 		const int					renderWidth			= 128;
673 		const int					renderHeight		= 128;
674 		vector<float>				texCoord;
675 		glu::Framebuffer			fbo					(renderCtx);
676 		glu::Renderbuffer			colorBuf			(renderCtx);
677 		glu::Texture				depthStencilTex		(renderCtx);
678 		tcu::TextureCube			texData				(glu::mapGLInternalFormat(m_format), size);
679 		tcu::TextureLevel			result				(TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8), renderWidth, renderHeight);
680 
681 		checkDepthStencilFormatSupport(m_context, m_format);
682 
683 		for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
684 		{
685 			const tcu::CubeFace		face		= tcu::CubeFace(faceNdx);
686 			const int				stencilVal	= 42*faceNdx;
687 
688 			texData.allocLevel(face, 0);
689 			tcu::clearStencil(texData.getLevelFace(0, face), stencilVal);
690 		}
691 
692 		glu::TextureTestUtil::computeQuadTexCoordCube(texCoord, tcu::CUBEFACE_NEGATIVE_X, Vec2(-1.5f, -1.3f), Vec2(1.3f, 1.4f));
693 
694 		gl.bindTexture(GL_TEXTURE_CUBE_MAP, *depthStencilTex);
695 		gl.texStorage2D(GL_TEXTURE_CUBE_MAP, 1, m_format, size, size);
696 
697 		for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
698 			glu::texSubImage2D(renderCtx, glu::getGLCubeFace(tcu::CubeFace(faceNdx)), 0, 0, 0, texData.getLevelFace(0, tcu::CubeFace(faceNdx)));
699 
700 		GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading texture data failed");
701 
702 		gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
703 		gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, renderWidth, renderHeight);
704 
705 		gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
706 		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
707 		checkFramebufferStatus(gl);
708 
709 		blitStencilToColorCube(renderCtx, *depthStencilTex, &texCoord[0], renderWidth, renderHeight);
710 		glu::readPixels(renderCtx, 0, 0, result);
711 
712 		{
713 			using namespace glu::TextureTestUtil;
714 
715 			tcu::TextureCube		redTex			(TextureFormat(TextureFormat::R, TextureFormat::UNORM_INT8), size);
716 			const ReferenceParams	sampleParams	(TEXTURETYPE_CUBE, tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE,
717 																					tcu::Sampler::CLAMP_TO_EDGE,
718 																					tcu::Sampler::CLAMP_TO_EDGE,
719 																					tcu::Sampler::NEAREST,
720 																					tcu::Sampler::NEAREST));
721 			tcu::LookupPrecision	lookupPrec;
722 			tcu::LodPrecision		lodPrec;
723 			bool					compareOk;
724 
725 			lookupPrec.colorMask		= tcu::BVec4(true, true, true, true);
726 			lookupPrec.colorThreshold	= tcu::computeFixedPointThreshold(IVec4(8, 8, 8, 8));
727 			lookupPrec.coordBits		= tcu::IVec3(22, 22, 22);
728 			lookupPrec.uvwBits			= tcu::IVec3(5, 5, 0);
729 			lodPrec.lodBits				= 7;
730 			lodPrec.derivateBits		= 16;
731 
732 			stencilToUnorm8(texData, redTex);
733 
734 			compareOk = verifyTextureResult(m_testCtx, result, redTex, &texCoord[0], sampleParams, lookupPrec, lodPrec, tcu::PixelFormat(8, 8, 8, 8));
735 
736 			m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
737 									compareOk ? "Pass"				: "Image comparison failed");
738 		}
739 
740 		return STOP;
741 	}
742 
743 private:
744 	const deUint32 m_format;
745 };
746 
747 class RenderTex2DCase : public TestCase
748 {
749 public:
RenderTex2DCase(Context & context,const char * name,deUint32 format)750 	RenderTex2DCase (Context& context, const char* name, deUint32 format)
751 		: TestCase	(context, name, glu::getTextureFormatName(format))
752 		, m_format	(format)
753 	{
754 	}
755 
iterate(void)756 	IterateResult iterate (void)
757 	{
758 		const glu::RenderContext&	renderCtx		= m_context.getRenderContext();
759 		const glw::Functions&		gl				= renderCtx.getFunctions();
760 		const int					width			= 117;
761 		const int					height			= 193;
762 		glu::Framebuffer			fbo				(renderCtx);
763 		glu::Renderbuffer			colorBuf		(renderCtx);
764 		glu::Texture				depthStencilTex	(renderCtx);
765 		TextureLevel				result			(TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), width, height);
766 		TextureLevel				reference		(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), width, height);
767 
768 		checkDepthStencilFormatSupport(m_context, m_format);
769 
770 		gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
771 		gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, width, height);
772 
773 		gl.bindTexture(GL_TEXTURE_2D, *depthStencilTex);
774 		gl.texStorage2D(GL_TEXTURE_2D, 1, m_format, width, height);
775 
776 		gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
777 		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
778 		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, *depthStencilTex, 0);
779 		checkFramebufferStatus(gl);
780 
781 		drawTestPattern(renderCtx, width, height);
782 
783 		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
784 		checkFramebufferStatus(gl);
785 
786 		blitStencilToColor2D(renderCtx, *depthStencilTex, width, height);
787 		glu::readPixels(renderCtx, 0, 0, result.getAccess());
788 
789 		renderTestPatternReference(reference);
790 
791 		{
792 			const bool compareOk = compareStencilToRed(m_testCtx.getLog(), reference, result);
793 			m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
794 									compareOk ? "Pass"				: "Image comparison failed");
795 		}
796 
797 		return STOP;
798 	}
799 
800 private:
801 	const deUint32 m_format;
802 };
803 
804 class ClearTex2DCase : public TestCase
805 {
806 public:
ClearTex2DCase(Context & context,const char * name,deUint32 format)807 	ClearTex2DCase (Context& context, const char* name, deUint32 format)
808 		: TestCase	(context, name, glu::getTextureFormatName(format))
809 		, m_format	(format)
810 	{
811 	}
812 
iterate(void)813 	IterateResult iterate (void)
814 	{
815 		const glu::RenderContext&	renderCtx		= m_context.getRenderContext();
816 		const glw::Functions&		gl				= renderCtx.getFunctions();
817 		const int					width			= 125;
818 		const int					height			= 117;
819 		const int					cellSize		= 8;
820 		glu::Framebuffer			fbo				(renderCtx);
821 		glu::Renderbuffer			colorBuf		(renderCtx);
822 		glu::Texture				depthStencilTex	(renderCtx);
823 		TextureLevel				result			(TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), width, height);
824 		TextureLevel				reference		(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), width, height);
825 
826 		checkDepthStencilFormatSupport(m_context, m_format);
827 
828 		gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
829 		gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, width, height);
830 
831 		gl.bindTexture(GL_TEXTURE_2D, *depthStencilTex);
832 		gl.texStorage2D(GL_TEXTURE_2D, 1, m_format, width, height);
833 
834 		gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
835 		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
836 		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, *depthStencilTex, 0);
837 		checkFramebufferStatus(gl);
838 
839 		gl.enable(GL_SCISSOR_TEST);
840 
841 		for (int y = 0; y < height; y += cellSize)
842 		{
843 			for (int x = 0; x < width; x += cellSize)
844 			{
845 				const int		clearW		= de::min(cellSize, width-x);
846 				const int		clearH		= de::min(cellSize, height-y);
847 				const int		stencil		= int((deInt32Hash(x) ^ deInt32Hash(y)) & 0xff);
848 
849 				gl.clearStencil(stencil);
850 				gl.scissor(x, y, clearW, clearH);
851 				gl.clear(GL_STENCIL_BUFFER_BIT);
852 
853 				tcu::clearStencil(tcu::getSubregion(reference.getAccess(), x, y, clearW, clearH), stencil);
854 			}
855 		}
856 
857 		gl.disable(GL_SCISSOR_TEST);
858 
859 		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
860 		checkFramebufferStatus(gl);
861 
862 		blitStencilToColor2D(renderCtx, *depthStencilTex, width, height);
863 		glu::readPixels(renderCtx, 0, 0, result.getAccess());
864 
865 		{
866 			const bool compareOk = compareStencilToRed(m_testCtx.getLog(), reference, result);
867 			m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
868 									compareOk ? "Pass"				: "Image comparison failed");
869 		}
870 
871 		return STOP;
872 	}
873 
874 private:
875 	const deUint32 m_format;
876 };
877 
878 class CompareModeCase : public TestCase
879 {
880 public:
CompareModeCase(Context & context,const char * name,deUint32 format)881 	CompareModeCase (Context& context, const char* name, deUint32 format)
882 		: TestCase	(context, name, glu::getTextureFormatName(format))
883 		, m_format	(format)
884 	{
885 	}
886 
iterate(void)887 	IterateResult iterate (void)
888 	{
889 		const glu::RenderContext&	renderCtx			= m_context.getRenderContext();
890 		const glw::Functions&		gl					= renderCtx.getFunctions();
891 		const int					width				= 64;
892 		const int					height				= 64;
893 		glu::Framebuffer			fbo					(renderCtx);
894 		glu::Renderbuffer			colorBuf			(renderCtx);
895 		glu::Texture				depthStencilTex		(renderCtx);
896 		TextureLevel				uploadLevel			(glu::mapGLInternalFormat(m_format), width, height);
897 		TextureLevel				readLevel			(TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), width, height);
898 		TextureLevel				stencilOnlyLevel	(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), width, height);
899 
900 		checkDepthStencilFormatSupport(m_context, m_format);
901 
902 		m_testCtx.getLog() << TestLog::Message << "NOTE: Texture compare mode has no effect when reading stencil values." << TestLog::EndMessage;
903 
904 		renderTestPatternReference(uploadLevel);
905 		renderTestPatternReference(stencilOnlyLevel);
906 
907 		gl.bindTexture(GL_TEXTURE_2D, *depthStencilTex);
908 		gl.texStorage2D(GL_TEXTURE_2D, 1, m_format, width, height);
909 		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
910 		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
911 		glu::texSubImage2D(renderCtx, GL_TEXTURE_2D, 0, 0, 0, uploadLevel);
912 		GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading texture data failed");
913 
914 		gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
915 		gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, width, height);
916 
917 		gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
918 		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
919 		checkFramebufferStatus(gl);
920 
921 		blitStencilToColor2D(renderCtx, *depthStencilTex, width, height);
922 		glu::readPixels(renderCtx, 0, 0, readLevel);
923 
924 		{
925 			const bool compareOk = compareStencilToRed(m_testCtx.getLog(), stencilOnlyLevel, readLevel);
926 			m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
927 									compareOk ? "Pass"				: "Image comparison failed");
928 		}
929 
930 		return STOP;
931 	}
932 
933 private:
934 	const deUint32 m_format;
935 };
936 
937 class BaseLevelCase : public TestCase
938 {
939 public:
BaseLevelCase(Context & context,const char * name,deUint32 format)940 	BaseLevelCase (Context& context, const char* name, deUint32 format)
941 		: TestCase	(context, name, glu::getTextureFormatName(format))
942 		, m_format	(format)
943 	{
944 	}
945 
iterate(void)946 	IterateResult iterate (void)
947 	{
948 		const glu::RenderContext&	renderCtx			= m_context.getRenderContext();
949 		const glw::Functions&		gl					= renderCtx.getFunctions();
950 		const int					width				= 128;
951 		const int					height				= 128;
952 		const int					levelNdx			= 2;
953 		const int					levelWidth			= width>>levelNdx;
954 		const int					levelHeight			= height>>levelNdx;
955 		glu::Framebuffer			fbo					(renderCtx);
956 		glu::Renderbuffer			colorBuf			(renderCtx);
957 		glu::Texture				depthStencilTex		(renderCtx);
958 		TextureLevel				uploadLevel			(glu::mapGLInternalFormat(m_format), levelWidth, levelHeight);
959 		TextureLevel				readLevel			(TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), levelWidth, levelHeight);
960 		TextureLevel				stencilOnlyLevel	(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), levelWidth, levelHeight);
961 
962 		checkDepthStencilFormatSupport(m_context, m_format);
963 
964 		m_testCtx.getLog() << TestLog::Message << "GL_TEXTURE_BASE_LEVEL = " << levelNdx << TestLog::EndMessage;
965 
966 		renderTestPatternReference(uploadLevel);
967 		renderTestPatternReference(stencilOnlyLevel);
968 
969 		gl.bindTexture(GL_TEXTURE_2D, *depthStencilTex);
970 		gl.texStorage2D(GL_TEXTURE_2D, deLog2Floor32(de::max(width, height))+1, m_format, width, height);
971 		gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, levelNdx);
972 		glu::texSubImage2D(renderCtx, GL_TEXTURE_2D, levelNdx, 0, 0, uploadLevel);
973 		GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading texture data failed");
974 
975 		gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
976 		gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, levelWidth, levelHeight);
977 
978 		gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
979 		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
980 		checkFramebufferStatus(gl);
981 
982 		blitStencilToColor2D(renderCtx, *depthStencilTex, levelWidth, levelHeight);
983 		glu::readPixels(renderCtx, 0, 0, readLevel);
984 
985 		{
986 			const bool compareOk = compareStencilToRed(m_testCtx.getLog(), stencilOnlyLevel, readLevel);
987 			m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
988 									compareOk ? "Pass"				: "Image comparison failed");
989 		}
990 
991 		return STOP;
992 	}
993 
994 private:
995 	const deUint32 m_format;
996 };
997 
998 } // anonymous
999 
StencilTexturingTests(Context & context)1000 StencilTexturingTests::StencilTexturingTests (Context& context)
1001 	: TestCaseGroup(context, "stencil_texturing", "Stencil texturing tests")
1002 {
1003 }
1004 
~StencilTexturingTests(void)1005 StencilTexturingTests::~StencilTexturingTests (void)
1006 {
1007 }
1008 
init(void)1009 void StencilTexturingTests::init (void)
1010 {
1011 	// .format
1012 	{
1013 		tcu::TestCaseGroup* const formatGroup = new tcu::TestCaseGroup(m_testCtx, "format", "Formats");
1014 		addChild(formatGroup);
1015 
1016 		formatGroup->addChild(new UploadTex2DCase		(m_context, "depth32f_stencil8_2d",			GL_DEPTH32F_STENCIL8));
1017 		formatGroup->addChild(new UploadTex2DArrayCase	(m_context, "depth32f_stencil8_2d_array",	GL_DEPTH32F_STENCIL8));
1018 		formatGroup->addChild(new UploadTexCubeCase		(m_context, "depth32f_stencil8_cube",		GL_DEPTH32F_STENCIL8));
1019 		formatGroup->addChild(new UploadTex2DCase		(m_context, "depth24_stencil8_2d",			GL_DEPTH24_STENCIL8));
1020 		formatGroup->addChild(new UploadTex2DArrayCase	(m_context, "depth24_stencil8_2d_array",	GL_DEPTH24_STENCIL8));
1021 		formatGroup->addChild(new UploadTexCubeCase		(m_context, "depth24_stencil8_cube",		GL_DEPTH24_STENCIL8));
1022 
1023 		// OES_texture_stencil8
1024 		formatGroup->addChild(new UploadTex2DCase		(m_context, "stencil_index8_2d",			GL_STENCIL_INDEX8));
1025 		formatGroup->addChild(new UploadTex2DArrayCase	(m_context, "stencil_index8_2d_array",		GL_STENCIL_INDEX8));
1026 		formatGroup->addChild(new UploadTexCubeCase		(m_context, "stencil_index8_cube",			GL_STENCIL_INDEX8));
1027 	}
1028 
1029 	// .render
1030 	{
1031 		tcu::TestCaseGroup* const readRenderGroup = new tcu::TestCaseGroup(m_testCtx, "render", "Read rendered stencil values");
1032 		addChild(readRenderGroup);
1033 
1034 		readRenderGroup->addChild(new ClearTex2DCase	(m_context, "depth32f_stencil8_clear",	GL_DEPTH32F_STENCIL8));
1035 		readRenderGroup->addChild(new RenderTex2DCase	(m_context, "depth32f_stencil8_draw",	GL_DEPTH32F_STENCIL8));
1036 		readRenderGroup->addChild(new ClearTex2DCase	(m_context, "depth24_stencil8_clear",	GL_DEPTH24_STENCIL8));
1037 		readRenderGroup->addChild(new RenderTex2DCase	(m_context, "depth24_stencil8_draw",	GL_DEPTH24_STENCIL8));
1038 	}
1039 
1040 	// .misc
1041 	{
1042 		tcu::TestCaseGroup* const miscGroup = new tcu::TestCaseGroup(m_testCtx, "misc", "Misc cases");
1043 		addChild(miscGroup);
1044 
1045 		miscGroup->addChild(new CompareModeCase	(m_context, "compare_mode_effect",	GL_DEPTH24_STENCIL8));
1046 		miscGroup->addChild(new BaseLevelCase	(m_context, "base_level",			GL_DEPTH24_STENCIL8));
1047 	}
1048 }
1049 
1050 } // Functional
1051 } // gles31
1052 } // deqp
1053