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