• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2017 The Khronos Group Inc.
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  glcPackedDepthStencilTests.cpp
21  * \brief
22  */ /*-------------------------------------------------------------------*/
23 
24 #include "glcPackedDepthStencilTests.hpp"
25 #include "deMath.h"
26 #include "gluContextInfo.hpp"
27 #include "gluDrawUtil.hpp"
28 #include "gluRenderContext.hpp"
29 #include "gluShaderProgram.hpp"
30 #include "gluStrUtil.hpp"
31 #include "glwEnums.hpp"
32 #include "glwFunctions.hpp"
33 #include "tcuRenderTarget.hpp"
34 #include "tcuTestLog.hpp"
35 #include <algorithm>
36 #include <cstring>
37 #include <stdio.h>
38 
39 using namespace glw;
40 using namespace glu;
41 
42 namespace glcts
43 {
44 
45 #define TEX_SIZE 256
46 #define TOLERANCE_LOW 0.48
47 #define TOLERANCE_HIGH 0.52
48 #define EPSILON 0.01
49 
50 enum DrawMode
51 {
52 	DEFAULT,
53 	DEPTH_SPAN1,
54 	DEPTH_SPAN2,
55 };
56 
57 struct D32F_S8
58 {
59 	GLfloat d;
60 	GLuint  s;
61 };
62 
63 // Reference texture names for the described 5 textures and framebuffers
64 // and also for identifying other cases' reference textures
65 enum TextureNames
66 {
67 	packedTexImage,
68 	packedTexRender,
69 	packedTexRenderInitStencil,
70 	packedTexRenderDepthStep,
71 	packedTexRenderStencilStep,
72 	NUM_TEXTURES,
73 	verifyCopyTexImage,
74 	verifyPartialAttachments,
75 	verifyMixedAttachments,
76 	verifyClearBufferDepth,
77 	verifyClearBufferStencil,
78 	verifyClearBufferDepthStencil,
79 	verifyBlit,
80 };
81 
82 struct TypeFormat
83 {
84 	GLenum		type;
85 	GLenum		format;
86 	const char* formatName;
87 	int			size;
88 	int			d;
89 	int			s;
90 };
91 
92 #define NUM_TEXTURE_TYPES 2
93 
94 static const TypeFormat TextureTypes[NUM_TEXTURE_TYPES] = {
95 	{ GL_UNSIGNED_INT_24_8, GL_DEPTH24_STENCIL8, "depth24_stencil8", sizeof(GLuint), 24, 8 },
96 	{ GL_FLOAT_32_UNSIGNED_INT_24_8_REV, GL_DEPTH32F_STENCIL8, "depth32f_stencil8", sizeof(GLuint) + sizeof(GLfloat),
97 	  32, 8 },
98 };
99 
100 // Texture targets for initial state checking
101 static const GLenum coreTexTargets[] = {
102 	GL_TEXTURE_2D,
103 	GL_TEXTURE_3D,
104 	GL_TEXTURE_2D_ARRAY,
105 	GL_TEXTURE_CUBE_MAP_POSITIVE_X,
106 	GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
107 	GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
108 	GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
109 	GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
110 	GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
111 	GL_TEXTURE_1D,
112 	GL_TEXTURE_1D_ARRAY,
113 	GL_TEXTURE_CUBE_MAP_ARRAY,
114 	GL_TEXTURE_RECTANGLE,
115 	GL_TEXTURE_2D_MULTISAMPLE,
116 	GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
117 	GL_PROXY_TEXTURE_1D,
118 	GL_PROXY_TEXTURE_2D,
119 	GL_PROXY_TEXTURE_3D,
120 	GL_PROXY_TEXTURE_1D_ARRAY,
121 	GL_PROXY_TEXTURE_2D_ARRAY,
122 	GL_PROXY_TEXTURE_CUBE_MAP_ARRAY,
123 	GL_PROXY_TEXTURE_RECTANGLE,
124 	GL_PROXY_TEXTURE_CUBE_MAP,
125 	GL_PROXY_TEXTURE_2D_MULTISAMPLE,
126 	GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY,
127 };
128 static const GLenum esTexTargets[] = {
129 	GL_TEXTURE_2D,
130 	GL_TEXTURE_3D,
131 	GL_TEXTURE_2D_ARRAY,
132 	GL_TEXTURE_CUBE_MAP_POSITIVE_X,
133 	GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
134 	GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
135 	GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
136 	GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
137 	GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
138 };
139 
140 // Listing of non-depth_stencil types for error tests
141 static const GLenum coreNonDepthStencilTypes[] = {
142 	GL_UNSIGNED_BYTE,
143 	GL_BYTE,
144 	GL_UNSIGNED_SHORT,
145 	GL_SHORT,
146 	GL_UNSIGNED_INT,
147 	GL_INT,
148 	GL_HALF_FLOAT,
149 	GL_FLOAT,
150 	GL_UNSIGNED_SHORT_5_6_5,
151 	GL_UNSIGNED_SHORT_4_4_4_4,
152 	GL_UNSIGNED_SHORT_5_5_5_1,
153 	GL_UNSIGNED_INT_2_10_10_10_REV,
154 	GL_UNSIGNED_INT_10F_11F_11F_REV,
155 	GL_UNSIGNED_INT_5_9_9_9_REV,
156 	GL_UNSIGNED_BYTE_3_3_2,
157 	GL_UNSIGNED_BYTE_2_3_3_REV,
158 	GL_UNSIGNED_SHORT_5_6_5_REV,
159 	GL_UNSIGNED_SHORT_4_4_4_4_REV,
160 	GL_UNSIGNED_SHORT_1_5_5_5_REV,
161 	GL_UNSIGNED_INT_8_8_8_8,
162 	GL_UNSIGNED_INT_8_8_8_8_REV,
163 	GL_UNSIGNED_INT_10_10_10_2,
164 };
165 static const GLenum esNonDepthStencilTypes[] = {
166 	GL_UNSIGNED_BYTE,
167 	GL_BYTE,
168 	GL_UNSIGNED_SHORT,
169 	GL_SHORT,
170 	GL_UNSIGNED_INT,
171 	GL_INT,
172 	GL_HALF_FLOAT,
173 	GL_FLOAT,
174 	GL_UNSIGNED_SHORT_5_6_5,
175 	GL_UNSIGNED_SHORT_4_4_4_4,
176 	GL_UNSIGNED_SHORT_5_5_5_1,
177 	GL_UNSIGNED_INT_2_10_10_10_REV,
178 	GL_UNSIGNED_INT_10F_11F_11F_REV,
179 	GL_UNSIGNED_INT_5_9_9_9_REV,
180 };
181 
182 // Listing of non-depth_stencil formats for error tests
183 static const GLenum coreNonDepthStencilFormats[] = {
184 	GL_STENCIL_INDEX, GL_RED,		  GL_GREEN,		   GL_BLUE,			 GL_RG,			  GL_RGB,		 GL_RGBA,
185 	GL_BGR,			  GL_BGRA,		  GL_RED_INTEGER,  GL_GREEN_INTEGER, GL_BLUE_INTEGER, GL_RG_INTEGER, GL_RGB_INTEGER,
186 	GL_RGBA_INTEGER,  GL_BGR_INTEGER, GL_BGRA_INTEGER,
187 };
188 static const GLenum esNonDepthStencilFormats[] = {
189 	GL_RED,
190 	GL_RG,
191 	GL_RGB,
192 	GL_RGBA,
193 	GL_LUMINANCE,		// for es3+
194 	GL_ALPHA,			// for es3+
195 	GL_LUMINANCE_ALPHA, // for es3+
196 	GL_RED_INTEGER,
197 	GL_RG_INTEGER,
198 	GL_RGB_INTEGER,
199 	GL_RGBA_INTEGER,
200 };
201 
202 // Listing of non-depth_stencil base formats for error tests
203 static const GLenum coreOtherBaseFormats[] = {
204 	GL_RED, GL_RG, GL_RGB, GL_RGBA,
205 };
206 static const GLenum esOtherBaseFormats[] = {
207 	GL_RED, GL_RG, GL_RGB, GL_RGBA, GL_LUMINANCE, GL_ALPHA, GL_LUMINANCE_ALPHA,
208 };
209 
210 struct AttachmentParam
211 {
212 	GLenum pname;
213 	GLint  value;
214 };
215 
216 #define NUM_ATTACHMENT_PARAMS_CORE 13
217 #define NUM_ATTACHMENT_PARAMS_ES 12
218 
219 static const AttachmentParam coreAttachmentParams[NUM_TEXTURE_TYPES][NUM_ATTACHMENT_PARAMS_CORE] = {
220 	{
221 		{ GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, 0 },
222 		{ GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, 0 },
223 		{ GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, 0 },
224 		{ GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, 0 },
225 		{ GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, 24 },
226 		{ GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, 8 },
227 		{ GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, GL_UNSIGNED_NORMALIZED },
228 		{ GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, GL_LINEAR },
229 		{ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, -1 },
230 		{ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, 0 },
231 		{ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, 0 },
232 		{ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, 0 },
233 		{ GL_FRAMEBUFFER_ATTACHMENT_LAYERED, 0 },
234 	},
235 	{
236 		{ GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, 0 },
237 		{ GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, 0 },
238 		{ GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, 0 },
239 		{ GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, 0 },
240 		{ GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, 32 },
241 		{ GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, 8 },
242 		{ GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, GL_FLOAT },
243 		{ GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, GL_LINEAR },
244 		{ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, -1 },
245 		{ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, 0 },
246 		{ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, 0 },
247 		{ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, 0 },
248 		{ GL_FRAMEBUFFER_ATTACHMENT_LAYERED, 0 },
249 	},
250 };
251 static const AttachmentParam esAttachmentParams[NUM_TEXTURE_TYPES][NUM_ATTACHMENT_PARAMS_ES] = {
252 	{
253 		{ GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, 0 },
254 		{ GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, 0 },
255 		{ GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, 0 },
256 		{ GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, 0 },
257 		{ GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, 24 },
258 		{ GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, 8 },
259 		{ GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, GL_UNSIGNED_NORMALIZED },
260 		{ GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, GL_LINEAR },
261 		{ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, -1 },
262 		{ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, 0 },
263 		{ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, 0 },
264 		{ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, 0 },
265 	},
266 	{
267 		{ GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE, 0 },
268 		{ GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE, 0 },
269 		{ GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE, 0 },
270 		{ GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE, 0 },
271 		{ GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE, 32 },
272 		{ GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, 8 },
273 		{ GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, GL_FLOAT },
274 		{ GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, GL_LINEAR },
275 		{ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, -1 },
276 		{ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, 0 },
277 		{ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE, 0 },
278 		{ GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER, 0 },
279 	},
280 };
281 
282 enum ColorFunction
283 {
284 	COLOR_CHECK_DEFAULT,
285 	COLOR_CHECK_DEPTH,
286 	COLOR_CHECK_STENCIL,
287 };
288 
289 class BaseTest : public deqp::TestCase
290 {
291 public:
292 	BaseTest(deqp::Context& context, const TypeFormat& tf);
293 	virtual ~BaseTest();
294 
295 	void								 init(void);
296 	virtual tcu::TestNode::IterateResult iterate(void);
297 
298 	const AttachmentParam* getAttachmentParams() const;
299 	void createGradient(std::vector<GLbyte>& data);
300 
301 	void setDrawReadBuffer(GLenum draw, GLenum read);
302 	void restoreDrawReadBuffer();
303 
304 	void createTextures();
305 	void setupTexture();
306 	void destroyTextures();
307 
308 	GLuint createProgram(const char* vsCode, const char* fsCode);
309 	void setupColorProgram(GLint& uColor);
310 	bool setupTextureProgram();
311 	bool setupStencilProgram();
312 	bool setTextureUniform(GLuint programId);
313 
314 	void drawQuad(DrawMode drawMode, GLuint program);
315 	void renderToTextures();
316 	bool verifyDepthStencilGradient(GLvoid* data, unsigned int texIndex, int width, int height);
317 	bool verifyColorGradient(GLvoid* data, unsigned int texIndex, int function, int width, int height);
318 	bool doReadPixels(GLuint texture, int function);
319 
320 protected:
321 	GLuint m_defaultFBO;
322 	GLuint m_drawBuffer;
323 	GLuint m_readBuffer;
324 
325 	const GLenum* m_textureTargets;
326 	GLuint		  m_textureTargetsCount;
327 	const GLenum* m_nonDepthStencilTypes;
328 	GLuint		  m_nonDepthStencilTypesCount;
329 	const GLenum* m_nonDepthStencilFormats;
330 	GLuint		  m_nonDepthStencilFormatsCount;
331 	const GLenum* m_otherBaseFormats;
332 	GLuint		  m_otherBaseFormatsCount;
333 
334 	const AttachmentParam* m_attachmentParams[NUM_TEXTURE_TYPES];
335 	GLuint				   m_attachmentParamsCount;
336 
337 	const TypeFormat& m_typeFormat;
338 
339 	GLuint m_textureProgram;
340 	GLuint m_colorProgram;
341 	GLuint m_stencilProgram;
342 
343 	GLuint m_textures[NUM_TEXTURES];
344 	GLuint m_framebuffers[NUM_TEXTURES];
345 };
346 
BaseTest(deqp::Context & context,const TypeFormat & tf)347 BaseTest::BaseTest(deqp::Context& context, const TypeFormat& tf)
348 	: deqp::TestCase(context, tf.formatName, "")
349 	, m_defaultFBO(0)
350 	, m_drawBuffer(GL_COLOR_ATTACHMENT0)
351 	, m_readBuffer(GL_COLOR_ATTACHMENT0)
352 	, m_textureTargets(coreTexTargets)
353 	, m_textureTargetsCount(DE_LENGTH_OF_ARRAY(coreTexTargets))
354 	, m_nonDepthStencilTypes(coreNonDepthStencilTypes)
355 	, m_nonDepthStencilTypesCount(DE_LENGTH_OF_ARRAY(coreNonDepthStencilTypes))
356 	, m_nonDepthStencilFormats(coreNonDepthStencilFormats)
357 	, m_nonDepthStencilFormatsCount(DE_LENGTH_OF_ARRAY(coreNonDepthStencilFormats))
358 	, m_otherBaseFormats(coreOtherBaseFormats)
359 	, m_otherBaseFormatsCount(DE_LENGTH_OF_ARRAY(coreOtherBaseFormats))
360 	, m_attachmentParamsCount(0)
361 	, m_typeFormat(tf)
362 	, m_textureProgram(0)
363 	, m_colorProgram(0)
364 	, m_stencilProgram(0)
365 
366 {
367 }
368 
~BaseTest()369 BaseTest::~BaseTest()
370 {
371 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
372 	if (m_textureProgram)
373 		gl.deleteProgram(m_textureProgram);
374 	if (m_colorProgram)
375 		gl.deleteProgram(m_colorProgram);
376 	if (m_stencilProgram)
377 		gl.deleteProgram(m_stencilProgram);
378 }
379 
init(void)380 void BaseTest::init(void)
381 {
382 	if (glu::isContextTypeES(m_context.getRenderContext().getType()))
383 	{
384 		m_textureTargets			  = esTexTargets;
385 		m_textureTargetsCount		  = DE_LENGTH_OF_ARRAY(esTexTargets);
386 		m_nonDepthStencilTypes		  = esNonDepthStencilTypes;
387 		m_nonDepthStencilTypesCount   = DE_LENGTH_OF_ARRAY(esNonDepthStencilTypes);
388 		m_nonDepthStencilFormats	  = esNonDepthStencilFormats;
389 		m_nonDepthStencilFormatsCount = DE_LENGTH_OF_ARRAY(esNonDepthStencilFormats);
390 		m_otherBaseFormats			  = esOtherBaseFormats;
391 		m_otherBaseFormatsCount		  = DE_LENGTH_OF_ARRAY(esOtherBaseFormats);
392 
393 		for (int i				  = 0; i < NUM_TEXTURE_TYPES; i++)
394 			m_attachmentParams[i] = esAttachmentParams[i];
395 		m_attachmentParamsCount   = NUM_ATTACHMENT_PARAMS_ES;
396 	}
397 	else
398 	{
399 		for (int i				  = 0; i < NUM_TEXTURE_TYPES; i++)
400 			m_attachmentParams[i] = coreAttachmentParams[i];
401 		m_attachmentParamsCount   = NUM_ATTACHMENT_PARAMS_CORE;
402 	}
403 }
404 
iterate(void)405 tcu::TestNode::IterateResult BaseTest::iterate(void)
406 {
407 	m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
408 	return STOP;
409 }
410 
getAttachmentParams() const411 const AttachmentParam* BaseTest::getAttachmentParams() const
412 {
413 	// find type index
414 	int index = 0;
415 	for (; index < NUM_TEXTURE_TYPES; index++)
416 	{
417 		if (TextureTypes[index].format == m_typeFormat.format)
418 			break;
419 	}
420 
421 	if (index >= NUM_TEXTURE_TYPES)
422 		TCU_FAIL("Missing attachment definition");
423 
424 	return m_attachmentParams[index];
425 }
426 
427 // Creates a gradient texture data in the given type parameter format
createGradient(std::vector<GLbyte> & data)428 void BaseTest::createGradient(std::vector<GLbyte>& data)
429 {
430 	switch (m_typeFormat.type)
431 	{
432 	case GL_UNSIGNED_INT_24_8:
433 	{
434 		data.resize(TEX_SIZE * TEX_SIZE * sizeof(GLuint));
435 		GLuint* dataPtr = reinterpret_cast<GLuint*>(&data[0]);
436 		for (int j = 0; j < TEX_SIZE; j++)
437 		{
438 			for (int i = 0; i < TEX_SIZE; i++)
439 			{
440 				GLuint  d = static_cast<GLuint>(static_cast<float>(i) / (TEX_SIZE - 1) * 0x00ffffff);
441 				GLubyte s = i & 0xff;
442 
443 				dataPtr[TEX_SIZE * j + i] = (d << 8) + s;
444 			}
445 		}
446 		return;
447 	}
448 	case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
449 	{
450 		data.resize(TEX_SIZE * TEX_SIZE * sizeof(D32F_S8));
451 		D32F_S8* dataPtr = reinterpret_cast<D32F_S8*>(&data[0]);
452 		for (int j = 0; j < TEX_SIZE; j++)
453 		{
454 			for (int i = 0; i < TEX_SIZE; i++)
455 			{
456 				D32F_S8 v				  = { static_cast<float>(i) / (TEX_SIZE - 1), static_cast<GLuint>(i & 0xff) };
457 				dataPtr[TEX_SIZE * j + i] = v;
458 			}
459 		}
460 		return;
461 	}
462 	default:
463 		TCU_FAIL("Unsuported type");
464 	}
465 }
466 
setDrawReadBuffer(GLenum draw,GLenum read)467 void BaseTest::setDrawReadBuffer(GLenum draw, GLenum read)
468 {
469 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
470 
471 	GLint drawBuffer;
472 	gl.getIntegerv(GL_DRAW_BUFFER0, &drawBuffer);
473 	m_drawBuffer = static_cast<GLuint>(drawBuffer);
474 
475 	GLint readBuffer;
476 	gl.getIntegerv(GL_READ_BUFFER, &readBuffer);
477 	m_readBuffer = static_cast<GLuint>(readBuffer);
478 
479 	gl.drawBuffers(1, &draw);
480 	gl.readBuffer(read);
481 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer");
482 }
483 
restoreDrawReadBuffer()484 void BaseTest::restoreDrawReadBuffer()
485 {
486 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
487 	gl.drawBuffers(1, &m_drawBuffer);
488 	gl.readBuffer(m_readBuffer);
489 	GLU_EXPECT_NO_ERROR(gl.getError(), "glReadBuffer");
490 }
491 
createTextures()492 void BaseTest::createTextures()
493 {
494 	// Creates all the textures and framebuffers
495 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
496 
497 	gl.genTextures(NUM_TEXTURES, m_textures);
498 	gl.genFramebuffers(NUM_TEXTURES, m_framebuffers);
499 
500 	// packedTexImage
501 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexImage]);
502 	gl.bindTexture(GL_TEXTURE_2D, m_textures[packedTexImage]);
503 	setupTexture();
504 	std::vector<GLbyte> data;
505 	createGradient(data);
506 	gl.texImage2D(GL_TEXTURE_2D, 0, m_typeFormat.format, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_STENCIL, m_typeFormat.type,
507 				  &data[0]);
508 	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexImage], 0);
509 	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexImage], 0);
510 
511 	// packedTexRender
512 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexRender]);
513 	gl.bindTexture(GL_TEXTURE_2D, m_textures[packedTexRender]);
514 	setupTexture();
515 	gl.texImage2D(GL_TEXTURE_2D, 0, m_typeFormat.format, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_STENCIL, m_typeFormat.type,
516 				  NULL);
517 	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexRender], 0);
518 	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexRender], 0);
519 
520 	// packedTexRenderInitStencil
521 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexRenderInitStencil]);
522 	gl.bindTexture(GL_TEXTURE_2D, m_textures[packedTexRenderInitStencil]);
523 	setupTexture();
524 	createGradient(data);
525 	gl.texImage2D(GL_TEXTURE_2D, 0, m_typeFormat.format, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_STENCIL, m_typeFormat.type,
526 				  &data[0]);
527 	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexRenderInitStencil],
528 							0);
529 	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
530 							m_textures[packedTexRenderInitStencil], 0);
531 
532 	// packedTexRenderDepthStep
533 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexRenderDepthStep]);
534 	gl.bindTexture(GL_TEXTURE_2D, m_textures[packedTexRenderDepthStep]);
535 	setupTexture();
536 	gl.texImage2D(GL_TEXTURE_2D, 0, m_typeFormat.format, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_STENCIL, m_typeFormat.type,
537 				  NULL);
538 	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexRenderDepthStep],
539 							0);
540 	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexRenderDepthStep],
541 							0);
542 
543 	// packedTexRenderStencilStep
544 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexRenderStencilStep]);
545 	gl.bindTexture(GL_TEXTURE_2D, m_textures[packedTexRenderStencilStep]);
546 	setupTexture();
547 	gl.texImage2D(GL_TEXTURE_2D, 0, m_typeFormat.format, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_STENCIL, m_typeFormat.type,
548 				  NULL);
549 	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexRenderStencilStep],
550 							0);
551 	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
552 							m_textures[packedTexRenderStencilStep], 0);
553 
554 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO);
555 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
556 }
557 
setupTexture()558 void BaseTest::setupTexture()
559 {
560 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
561 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
562 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
563 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
564 	gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
565 	GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri");
566 }
567 
568 // Destroys all the textures and framebuffers
destroyTextures()569 void BaseTest::destroyTextures()
570 {
571 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
572 	gl.deleteFramebuffers(NUM_TEXTURES, m_framebuffers);
573 	gl.deleteTextures(NUM_TEXTURES, m_textures);
574 }
575 
createProgram(const char * vsCode,const char * fsCode)576 GLuint BaseTest::createProgram(const char* vsCode, const char* fsCode)
577 {
578 	glu::RenderContext&   renderContext = m_context.getRenderContext();
579 	glu::ContextType	  contextType   = renderContext.getType();
580 	const glw::Functions& gl			= m_context.getRenderContext().getFunctions();
581 	glu::GLSLVersion	  glslVersion   = glu::getContextTypeGLSLVersion(contextType);
582 	const char*			  version		= glu::getGLSLVersionDeclaration(glslVersion);
583 
584 	glu::Shader vs(gl, glu::SHADERTYPE_VERTEX);
585 	const char* vSources[] = { version, vsCode };
586 	const int   vLengths[] = { int(strlen(version)), int(strlen(vsCode)) };
587 	vs.setSources(2, vSources, vLengths);
588 	vs.compile();
589 	if (!vs.getCompileStatus())
590 		TCU_FAIL("Vertex shader compilation failed");
591 
592 	glu::Shader fs(gl, glu::SHADERTYPE_FRAGMENT);
593 	const char* fSources[] = { version, fsCode };
594 	const int   fLengths[] = { int(strlen(version)), int(strlen(fsCode)) };
595 	fs.setSources(2, fSources, fLengths);
596 	fs.compile();
597 	if (!fs.getCompileStatus())
598 		TCU_FAIL("Fragment shader compilation failed");
599 
600 	GLuint p = gl.createProgram();
601 	gl.attachShader(p, vs.getShader());
602 	gl.attachShader(p, fs.getShader());
603 	gl.linkProgram(p);
604 	return p;
605 }
606 
setupColorProgram(GLint & uColor)607 void BaseTest::setupColorProgram(GLint& uColor)
608 {
609 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
610 
611 	const char* vs = "\n"
612 					 "precision highp float;\n"
613 					 "in vec4 pos;\n"
614 					 "void main() {\n"
615 					 "  gl_Position = pos;\n"
616 					 "}\n";
617 
618 	const char* fs = "\n"
619 					 "precision highp float;\n"
620 					 "out vec4 color;\n"
621 					 "uniform vec4 uColor;\n"
622 					 "void main() {\n"
623 					 "  color = uColor;\n"
624 					 "}\n";
625 
626 	// setup shader program
627 	if (!m_colorProgram)
628 		m_colorProgram = createProgram(vs, fs);
629 	if (!m_colorProgram)
630 		TCU_FAIL("Error while loading shader program");
631 
632 	gl.useProgram(m_colorProgram);
633 
634 	// Setup program uniforms
635 	uColor = gl.getUniformLocation(m_colorProgram, "uColor");
636 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation");
637 
638 	if (uColor == -1)
639 		TCU_FAIL("Error getting uniform uColor");
640 
641 	gl.uniform4f(uColor, 1.0f, 1.0f, 1.0f, 1.0f);
642 }
643 
644 // Common code for default and stencil texture rendering shaders
setTextureUniform(GLuint programId)645 bool BaseTest::setTextureUniform(GLuint programId)
646 {
647 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
648 
649 	gl.useProgram(programId);
650 
651 	GLint uniformTex = gl.getUniformLocation(programId, "tex");
652 	GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation");
653 
654 	if (uniformTex == -1)
655 	{
656 		m_testCtx.getLog() << tcu::TestLog::Message << "Error getting uniform tex" << tcu::TestLog::EndMessage;
657 		return false;
658 	}
659 
660 	gl.uniform1i(uniformTex, 0);
661 	return true;
662 }
663 
664 // Loads texture rendering shader
setupTextureProgram()665 bool BaseTest::setupTextureProgram()
666 {
667 	const char* vs = "\n"
668 					 "precision highp float;\n"
669 					 "in vec4 pos;\n"
670 					 "in vec2 UV;\n"
671 					 "out vec2 vUV;\n"
672 					 "void main() {\n"
673 					 "  gl_Position = pos;\n"
674 					 "  vUV = UV;\n"
675 					 "}\n";
676 
677 	const char* fs = "\n"
678 					 "precision highp float;\n"
679 					 "in vec2 vUV;\n"
680 					 "out vec4 color;\n"
681 					 "uniform sampler2D tex;\n"
682 					 "void main() {\n"
683 					 "  color = texture(tex, vUV).rrra;\n"
684 					 "}\n";
685 
686 	if (!m_textureProgram)
687 		m_textureProgram = createProgram(vs, fs);
688 	if (!m_textureProgram)
689 		return false;
690 
691 	return setTextureUniform(m_textureProgram);
692 }
693 
694 // Loads texture stencil rendering shader
setupStencilProgram()695 bool BaseTest::setupStencilProgram()
696 {
697 	const char* vs = "\n"
698 					 "precision highp float;\n"
699 					 "in vec4 pos;\n"
700 					 "in vec2 UV;\n"
701 					 "out vec2 vUV;\n"
702 					 "void main() {\n"
703 					 "  gl_Position = pos;\n"
704 					 "  vUV = UV;\n"
705 					 "}\n";
706 
707 	const char* fs = "\n"
708 					 "precision highp float;\n"
709 					 "in vec2 vUV;\n"
710 					 "out vec4 color;\n"
711 					 "uniform highp usampler2D tex;\n"
712 					 "void main() {\n"
713 					 "  float s = float(texture(tex, vUV).r);\n"
714 					 "  s /= 255.0;\n"
715 					 "  color = vec4(s, s, s, 1);\n"
716 					 "}\n";
717 
718 	if (!m_stencilProgram)
719 		m_stencilProgram = createProgram(vs, fs);
720 	if (!m_stencilProgram)
721 		return false;
722 
723 	return setTextureUniform(m_stencilProgram);
724 }
725 
drawQuad(DrawMode drawMode,GLuint program)726 void BaseTest::drawQuad(DrawMode drawMode, GLuint program)
727 {
728 	static const GLfloat verticesDefault[] = {
729 		-1.0f, -1.0f, 0.0f, 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
730 	};
731 
732 	static const GLfloat verticesDepthSpan1[] = {
733 		-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
734 	};
735 
736 	static const GLfloat verticesDepthSpan2[] = {
737 		-1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f,
738 	};
739 
740 	static const GLfloat texCoords[] = {
741 		0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
742 	};
743 
744 	static const deUint16 quadIndices[] = { 0, 1, 2, 2, 1, 3 };
745 	static PrimitiveList  quadPrimitive = glu::pr::TriangleStrip(DE_LENGTH_OF_ARRAY(quadIndices), quadIndices);
746 
747 	static const glu::VertexArrayBinding depthSpanVA1[] = { glu::va::Float("pos", 4, 4, 0, verticesDepthSpan1) };
748 	static const glu::VertexArrayBinding depthSpanVA2[] = { glu::va::Float("pos", 4, 4, 0, verticesDepthSpan2) };
749 	static const glu::VertexArrayBinding defaultVA[]	= { glu::va::Float("pos", 4, 4, 0, verticesDefault),
750 														 glu::va::Float("UV", 2, 4, 0, texCoords) };
751 
752 	const glu::RenderContext& renderContext = m_context.getRenderContext();
753 	if (drawMode == DEPTH_SPAN1)
754 		glu::draw(renderContext, program, 1, depthSpanVA1, quadPrimitive);
755 	else if (drawMode == DEPTH_SPAN2)
756 		glu::draw(renderContext, program, 1, depthSpanVA2, quadPrimitive);
757 	else
758 		glu::draw(renderContext, program, 2, defaultVA, quadPrimitive);
759 }
760 
761 // Renders all non-trivial startup textures
renderToTextures()762 void BaseTest::renderToTextures()
763 {
764 	const glu::RenderContext& renderContext = m_context.getRenderContext();
765 	const glw::Functions&	 gl			= renderContext.getFunctions();
766 
767 	GLint uColor;
768 	setupColorProgram(uColor);
769 
770 	gl.enable(GL_DEPTH_TEST);
771 	// depth writing must be enabled as it is disabled in places like doReadPixels
772 	gl.depthMask(GL_TRUE);
773 
774 	if (glu::isContextTypeES(renderContext.getType()))
775 		gl.clearDepthf(1.0f);
776 	else
777 		gl.clearDepth(1.0);
778 
779 	gl.depthFunc(GL_LEQUAL);
780 	gl.viewport(0, 0, TEX_SIZE, TEX_SIZE);
781 
782 	drawQuad(DEPTH_SPAN1, m_colorProgram);
783 
784 	// packedTexRender
785 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexRender]);
786 
787 	setDrawReadBuffer(GL_NONE, GL_NONE);
788 
789 	gl.enable(GL_STENCIL_TEST);
790 	gl.stencilFunc(GL_ALWAYS, 0x0, 0xFF);
791 	gl.stencilOp(GL_ZERO, GL_INCR, GL_INCR);
792 
793 	gl.clear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
794 	drawQuad(DEPTH_SPAN1, m_colorProgram);
795 
796 	gl.disable(GL_STENCIL_TEST);
797 
798 	restoreDrawReadBuffer();
799 
800 	// packedTexRenderInitStencil
801 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexRenderInitStencil]);
802 
803 	setDrawReadBuffer(GL_NONE, GL_NONE);
804 
805 	gl.clear(GL_DEPTH_BUFFER_BIT);
806 	drawQuad(DEPTH_SPAN1, m_colorProgram);
807 
808 	restoreDrawReadBuffer();
809 
810 	// packedTexRenderDepthStep
811 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexRenderDepthStep]);
812 
813 	setDrawReadBuffer(GL_NONE, GL_NONE);
814 
815 	gl.clear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
816 	drawQuad(DEPTH_SPAN2, m_colorProgram);
817 	drawQuad(DEPTH_SPAN1, m_colorProgram);
818 
819 	restoreDrawReadBuffer();
820 
821 	// packedTexRenderStencilStep
822 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexRenderStencilStep]);
823 
824 	setDrawReadBuffer(GL_NONE, GL_NONE);
825 
826 	gl.clear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
827 	gl.enable(GL_SCISSOR_TEST);
828 	gl.scissor(0, 0, TEX_SIZE, TEX_SIZE / 2);
829 
830 	gl.enable(GL_STENCIL_TEST);
831 	gl.stencilFunc(GL_ALWAYS, 0x0, 0xFF);
832 	gl.stencilOp(GL_ZERO, GL_INCR, GL_INCR);
833 	for (int i = 0; i < 256; i++)
834 		drawQuad(DEPTH_SPAN2, m_colorProgram);
835 	gl.disable(GL_SCISSOR_TEST);
836 
837 	gl.stencilFunc(GL_EQUAL, 0xFF, 0xFF);
838 	gl.clear(GL_DEPTH_BUFFER_BIT);
839 	drawQuad(DEPTH_SPAN1, m_colorProgram);
840 	gl.disable(GL_STENCIL_TEST);
841 	GLU_EXPECT_NO_ERROR(gl.getError(), "glDisable");
842 
843 	restoreDrawReadBuffer();
844 
845 	// end
846 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO);
847 	GLU_EXPECT_NO_ERROR(gl.getError(), "glBindFramebuffer");
848 }
849 
850 // Verifies DepthStencil buffer data against reference values
verifyDepthStencilGradient(GLvoid * data,unsigned int texIndex,int width,int height)851 bool BaseTest::verifyDepthStencilGradient(GLvoid* data, unsigned int texIndex, int width, int height)
852 {
853 	bool result = true;
854 
855 	int index, skip;
856 	int countD, countS;
857 
858 	index  = 0;
859 	countD = 0;
860 	countS = 0;
861 
862 	for (int j = 0; j < height; j++)
863 	{
864 		for (int i = 0; i < width; i++)
865 		{
866 			float d, dref = 0.0;
867 			int   s, sref = 0;
868 
869 			skip = 0;
870 
871 			switch (m_typeFormat.type)
872 			{
873 			case GL_UNSIGNED_INT_24_8:
874 			{
875 				GLuint v = ((GLuint*)data)[index];
876 				d		 = ((float)(v >> 8)) / 0xffffff;
877 				s		 = v & 0xff;
878 				break;
879 			}
880 			case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
881 			{
882 				D32F_S8 v = ((D32F_S8*)data)[index];
883 				d		  = v.d;
884 				s		  = v.s & 0xff;
885 				break;
886 			}
887 			default:
888 				d = -1;
889 				s = -1;
890 				break;
891 			}
892 
893 			switch (texIndex)
894 			{
895 			case packedTexImage:
896 				dref = ((float)i) / (width - 1);
897 				sref = (int)(dref * 255);
898 				break;
899 			case packedTexRender:
900 				dref = ((float)j) / (height - 1);
901 				sref = 1;
902 				break;
903 			case packedTexRenderInitStencil:
904 				dref = ((float)j) / (height - 1);
905 				sref = (int)(((float)i) / (width - 1) * 255);
906 				break;
907 			case packedTexRenderDepthStep:
908 				if (j < height * TOLERANCE_LOW)
909 				{
910 					dref = ((float)j) / (height - 1);
911 					sref = 0;
912 				}
913 				else if (j > height * TOLERANCE_HIGH)
914 				{
915 					dref = 1.0f - ((float)j) / (height - 1);
916 					sref = 0;
917 				}
918 				else
919 				{
920 					skip = 1; // give some tolerance to pixels in the middle
921 				}
922 				break;
923 			case packedTexRenderStencilStep:
924 				if (j < height * TOLERANCE_LOW)
925 				{
926 					dref = ((float)j) / (height - 1);
927 					sref = 255;
928 				}
929 				else if (j > height * TOLERANCE_HIGH)
930 				{
931 					dref = 1;
932 					sref = 0;
933 				}
934 				else
935 				{
936 					skip = 1; // give some tolerance to pixels in the middle
937 				}
938 				break;
939 			case verifyCopyTexImage:
940 				if (j < height * TOLERANCE_LOW)
941 				{
942 					dref = ((float)j) / (height - 1);
943 					sref = 1;
944 				}
945 				else if (j > height * TOLERANCE_HIGH)
946 				{
947 					dref = 0.5;
948 					sref = 1;
949 				}
950 				else
951 				{
952 					skip = 1; // give some tolerance to pixels in the middle
953 				}
954 				break;
955 			default:
956 				dref = -2;
957 				sref = -2;
958 				break;
959 			}
960 
961 			if (!skip)
962 			{
963 				if (deFloatAbs(d - dref) > EPSILON)
964 				{
965 					result = false;
966 					countD++;
967 				}
968 
969 				if (s != sref)
970 				{
971 					result = false;
972 					countS++;
973 				}
974 			}
975 			else
976 			{
977 				skip = 0;
978 			}
979 
980 			index++;
981 		}
982 	}
983 
984 	if (countD || countS)
985 	{
986 		m_testCtx.getLog() << tcu::TestLog::Message << "DEPTH_STENCIL comparison failed" << tcu::TestLog::EndMessage;
987 	}
988 	return result;
989 }
990 
991 // Verifies Color buffer data against reference values
verifyColorGradient(GLvoid * data,unsigned int texIndex,int function,int width,int height)992 bool BaseTest::verifyColorGradient(GLvoid* data, unsigned int texIndex, int function, int width, int height)
993 {
994 	bool result = true;
995 
996 	int index   = 0, skip;
997 	int channel = 0;
998 	int count   = 0;
999 
1000 	for (int j = 0; j < height; j++)
1001 	{
1002 		for (int i = 0; i < width; i++)
1003 		{
1004 			skip			= 0;
1005 			GLuint color	= ((GLuint*)data)[index];
1006 			GLuint colorref = 0;
1007 
1008 // When data back from glReadPixels with arguments GL_RGBA + GL_UNSIGNED_BYTE,
1009 // we should reverse byte order in big-endian platform for (GLuint*) pointer.
1010 #if (DE_ENDIANNESS == DE_BIG_ENDIAN)
1011             color = deReverseBytes32(color);
1012 #endif
1013 
1014 			switch (texIndex)
1015 			{
1016 			case packedTexImage:
1017 				channel  = (int)(((float)i) / (width - 1) * 255);
1018 				colorref = 0xff000000 + channel * 0x00010101;
1019 				break;
1020 			case packedTexRender:
1021 				if (function == COLOR_CHECK_DEPTH)
1022 					channel = (int)(((float)j) / (height - 1) * 255);
1023 				else
1024 					channel = 1;
1025 				colorref	= 0xff000000 + channel * 0x00010101;
1026 				break;
1027 			case packedTexRenderInitStencil:
1028 				if (function == COLOR_CHECK_DEPTH)
1029 					channel = (int)(((float)j) / (height - 1) * 255);
1030 				else
1031 					channel = (int)(((float)i) / (width - 1) * 255);
1032 				colorref	= 0xff000000 + channel * 0x00010101;
1033 				break;
1034 			case packedTexRenderDepthStep:
1035 				if (function == COLOR_CHECK_DEPTH)
1036 				{
1037 					if (j < height * TOLERANCE_LOW)
1038 						channel = (int)(((float)j) / (height - 1) * 255);
1039 					else if (j > height * TOLERANCE_HIGH)
1040 						channel = 255 - (int)(((float)j) / (height - 1) * 255);
1041 					else
1042 						skip = 1; // give some tolerance to pixels in the middle
1043 				}
1044 				else
1045 					channel = 0;
1046 				colorref	= 0xff000000 + channel * 0x00010101;
1047 				break;
1048 			case packedTexRenderStencilStep:
1049 				if (j < height * TOLERANCE_LOW)
1050 				{
1051 					if (function == COLOR_CHECK_DEPTH)
1052 						channel = (int)(((float)j) / (height - 1) * 255);
1053 					else
1054 						channel = 255;
1055 				}
1056 				else if (j > height * TOLERANCE_HIGH)
1057 					channel = (function == COLOR_CHECK_DEPTH) ? 255 : 0;
1058 				else
1059 					skip = 1; // give some tolerance to pixels in the middle
1060 				colorref = 0xff000000 + channel * 0x00010101;
1061 				break;
1062 			case verifyCopyTexImage:
1063 				if (j < height * TOLERANCE_LOW)
1064 				{
1065 					if (function == COLOR_CHECK_DEPTH)
1066 						channel = (int)(((float)j) / (height - 1) * 255);
1067 					else
1068 						channel = 1;
1069 				}
1070 				else if (j > height * TOLERANCE_HIGH)
1071 				{
1072 					channel = (function == COLOR_CHECK_DEPTH) ? 127 : 1;
1073 				}
1074 				else
1075 				{
1076 					skip = 1; // give some tolerance to pixels in the middle
1077 				}
1078 				colorref = 0xff000000 + channel * 0x00010101;
1079 				break;
1080 			case verifyPartialAttachments:
1081 				colorref = 0xffffffff;
1082 				break;
1083 			case verifyMixedAttachments:
1084 				if (j > height * TOLERANCE_HIGH)
1085 					colorref = 0xffffffff;
1086 				else if (j < height * TOLERANCE_LOW)
1087 					colorref = 0xcccccccc;
1088 				else
1089 					skip = 1;
1090 				break;
1091 			case verifyClearBufferDepth:
1092 				if ((i & 0xff) == 0xff)
1093 					colorref = 0xffffffff;
1094 				else
1095 					colorref = 0xcccccccc;
1096 				break;
1097 			case verifyClearBufferStencil:
1098 				if (i > width * TOLERANCE_HIGH)
1099 					colorref = 0xffffffff;
1100 				else if (i < width * TOLERANCE_LOW)
1101 					colorref = 0xcccccccc;
1102 				else
1103 					skip = 1;
1104 				break;
1105 			case verifyClearBufferDepthStencil:
1106 				colorref = 0xffffffff;
1107 				break;
1108 			case verifyBlit:
1109 				if (j > height * TOLERANCE_HIGH)
1110 					colorref = 0xffffffff;
1111 				else if (j < height * TOLERANCE_LOW)
1112 					colorref = 0xcccccccc;
1113 				else
1114 					skip = 1;
1115 				break;
1116 			default:
1117 				colorref = 0xdeadbeef;
1118 				break;
1119 			}
1120 
1121 			if (skip)
1122 				skip = 0;
1123 			else if (color != colorref)
1124 			{
1125 				float d	= (float)(color & 0xff) / 0xff;
1126 				float dref = (float)(colorref & 0xff) / 0xff;
1127 				if (!((function == COLOR_CHECK_DEPTH) && (deFloatAbs(d - dref) < EPSILON)))
1128 				{
1129 					result = false;
1130 					count++;
1131 				}
1132 			}
1133 
1134 			index++;
1135 		}
1136 	}
1137 
1138 	if (count)
1139 	{
1140 		m_testCtx.getLog() << tcu::TestLog::Message << "*** Color comparison failed" << tcu::TestLog::EndMessage;
1141 		result = false;
1142 	}
1143 	return result;
1144 }
1145 
1146 // Verify DepthStencil texture by replicating it to color channels
1147 // so it can be read using ReadPixels in Halti.
doReadPixels(GLuint texture,int function)1148 bool BaseTest::doReadPixels(GLuint texture, int function)
1149 {
1150 	bool				  result = true;
1151 	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
1152 
1153 	GLuint fbo;
1154 	gl.genFramebuffers(1, &fbo);
1155 	gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
1156 
1157 	GLuint texColor;
1158 	gl.genTextures(1, &texColor);
1159 	gl.bindTexture(GL_TEXTURE_2D, texColor);
1160 	setupTexture();
1161 	gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, TEX_SIZE, TEX_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1162 
1163 	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texColor, 0);
1164 	setDrawReadBuffer(GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0);
1165 
1166 	// Step 1: Verify depth values
1167 	GLenum status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
1168 	if (status != GL_FRAMEBUFFER_COMPLETE)
1169 	{
1170 		m_testCtx.getLog() << tcu::TestLog::Message << "Framebuffer is incomplete: " << status
1171 						   << tcu::TestLog::EndMessage;
1172 		result = false;
1173 	}
1174 	else
1175 	{
1176 		setupTextureProgram();
1177 
1178 		gl.bindTexture(GL_TEXTURE_2D, texture);
1179 
1180 		gl.disable(GL_DEPTH_TEST);
1181 		gl.depthMask(GL_FALSE);
1182 		gl.disable(GL_STENCIL_TEST);
1183 		gl.viewport(0, 0, TEX_SIZE, TEX_SIZE);
1184 		gl.clearColor(0.8f, 0.8f, 0.8f, 0.8f);
1185 		gl.clear(GL_COLOR_BUFFER_BIT);
1186 		drawQuad(DEFAULT, m_textureProgram);
1187 
1188 		std::vector<GLuint> dataColor(TEX_SIZE * TEX_SIZE, 0);
1189 		gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, &dataColor[0]);
1190 		result &= verifyColorGradient(&dataColor[0], function, COLOR_CHECK_DEPTH, TEX_SIZE, TEX_SIZE);
1191 
1192 		// Step 2: Verify stencil values
1193 		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texture, 0);
1194 
1195 		status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
1196 		if (status != GL_FRAMEBUFFER_COMPLETE)
1197 		{
1198 			m_testCtx.getLog() << tcu::TestLog::Message << "Framebuffer is incomplete: " << status
1199 							   << tcu::TestLog::EndMessage;
1200 			result = false;
1201 		}
1202 		else
1203 		{
1204 			GLint uColor;
1205 			setupColorProgram(uColor);
1206 
1207 			gl.clearColor(0.8f, 0.8f, 0.8f, 0.8f);
1208 			gl.clear(GL_COLOR_BUFFER_BIT);
1209 
1210 			gl.enable(GL_STENCIL_TEST);
1211 			for (int i = 0; i < 256; i++)
1212 			{
1213 				float v = i / 255.0f;
1214 				gl.uniform4f(uColor, v, v, v, 1.0f);
1215 				gl.stencilFunc(GL_EQUAL, i, 0xFF);
1216 				gl.stencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
1217 				drawQuad(DEFAULT, m_colorProgram);
1218 			}
1219 
1220 			gl.disable(GL_STENCIL_TEST);
1221 			dataColor.assign(dataColor.size(), 0);
1222 			gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, &dataColor[0]);
1223 			result &= verifyColorGradient(&dataColor[0], function, COLOR_CHECK_STENCIL, TEX_SIZE, TEX_SIZE);
1224 		}
1225 	}
1226 
1227 	// clean up
1228 	restoreDrawReadBuffer();
1229 	gl.deleteFramebuffers(1, &fbo);
1230 	gl.deleteTextures(1, &texColor);
1231 
1232 	return result;
1233 }
1234 
1235 class InitialStateTest : public deqp::TestCase
1236 {
1237 public:
1238 	InitialStateTest(deqp::Context& context);
1239 	virtual ~InitialStateTest();
1240 
1241 	virtual tcu::TestNode::IterateResult iterate(void);
1242 };
1243 
InitialStateTest(deqp::Context & context)1244 InitialStateTest::InitialStateTest(deqp::Context& context)
1245 	: deqp::TestCase(context, "initial_state", "TEXTURE_STENCIL_SIZE for the default texture objects should be 0")
1246 {
1247 }
1248 
~InitialStateTest()1249 InitialStateTest::~InitialStateTest()
1250 {
1251 }
1252 
iterate(void)1253 tcu::TestNode::IterateResult InitialStateTest::iterate(void)
1254 {
1255 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1256 
1257 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1258 	for (int i = 0; i < DE_LENGTH_OF_ARRAY(coreTexTargets); i++)
1259 	{
1260 		GLenum target = coreTexTargets[i];
1261 
1262 		GLfloat fp;
1263 		gl.getTexLevelParameterfv(target, 0, GL_TEXTURE_STENCIL_SIZE, &fp);
1264 		if (deFloatCmpNE(fp, 0.0f))
1265 		{
1266 			m_testCtx.getLog() << tcu::TestLog::Message << "gl.getTexLevelParameterfv: Parameter is not 0"
1267 							   << tcu::TestLog::EndMessage;
1268 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1269 		}
1270 
1271 		GLint ip;
1272 		gl.getTexLevelParameteriv(target, 0, GL_TEXTURE_STENCIL_SIZE, &ip);
1273 		if (deFloatCmpNE((float)ip, 0.0f))
1274 		{
1275 			m_testCtx.getLog() << tcu::TestLog::Message << "gl.getTexLevelParameteriv: Parameter is not 0"
1276 							   << tcu::TestLog::EndMessage;
1277 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1278 		}
1279 	}
1280 
1281 	return STOP;
1282 }
1283 
1284 class ValidateErrorsTest : public BaseTest
1285 {
1286 public:
1287 	ValidateErrorsTest(deqp::Context& context, const TypeFormat& tf);
1288 	virtual ~ValidateErrorsTest();
1289 
1290 	virtual tcu::TestNode::IterateResult iterate(void);
1291 
1292 protected:
1293 	bool checkErrors();
1294 };
1295 
ValidateErrorsTest(deqp::Context & context,const TypeFormat & tf)1296 ValidateErrorsTest::ValidateErrorsTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf)
1297 {
1298 }
1299 
~ValidateErrorsTest()1300 ValidateErrorsTest::~ValidateErrorsTest()
1301 {
1302 }
1303 
iterate(void)1304 tcu::TestNode::IterateResult ValidateErrorsTest::iterate(void)
1305 {
1306 	createTextures();
1307 	if (checkErrors())
1308 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1309 	else
1310 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1311 
1312 	destroyTextures();
1313 	return STOP;
1314 }
1315 
1316 //  Error tests [desktop only]:
1317 
1318 //  - The error INVALID_ENUM is generated if ReadPixels is
1319 //	called where format is DEPTH_STENCIL and type is not
1320 //	UNSIGNED_INT_24_8, or FLOAT_32_UNSIGNED_INT_24_8_REV.
1321 
1322 //  - The error INVALID_OPERATION is generated if ReadPixels
1323 //	is called where type is UNSIGNED_INT_24_8 or
1324 //	FLOAT_32_UNSIGNED_INT_24_8_REV and format is not DEPTH_STENCIL.
1325 
1326 //  - The error INVALID_OPERATION is generated if ReadPixels
1327 //	is called where format is DEPTH_STENCIL and there is not both a
1328 //	depth buffer and a stencil buffer.
1329 
1330 //  - Calling GetTexImage with a <format> of DEPTH_COMPONENT when the
1331 //	base internal format of the texture image is not DEPTH_COMPONENT
1332 //	or DEPTH_STENCIL causes the error INVALID_OPERATION.
1333 
1334 //  - Calling GetTexImage with a <format> of DEPTH_STENCIL when
1335 //	the base internal format of the texture image is not
1336 //	DEPTH_STENCIL causes the error INVALID_OPERATION.
1337 
1338 //  Error tests [Halti only]:
1339 
1340 //  - The error INVALID_ENUM is generated if ReadPixels is
1341 //	called where format is DEPTH_STENCIL.
1342 
1343 //  Error tests [desktop and Halti]:
1344 
1345 //  - TexImage generates INVALID_OPERATION if one of the base internal format
1346 //	and format is DEPTH_COMPONENT or DEPTH_STENCIL, and the other is neither
1347 //	of these values.
1348 
1349 //  - The error INVALID_OPERATION is generated if CopyTexImage
1350 //	is called where format is DEPTH_STENCIL and there is not both a
1351 //	depth buffer and a stencil buffer.
checkErrors()1352 bool ValidateErrorsTest::checkErrors()
1353 {
1354 	bool					  result = true;
1355 	GLuint					  fbo, fbo2;
1356 	GLuint					  texColor;
1357 	std::vector<GLfloat>	  data(4 * TEX_SIZE * TEX_SIZE, 0.0f);
1358 	const glu::RenderContext& renderContext = m_context.getRenderContext();
1359 	const glw::Functions&	 gl			= renderContext.getFunctions();
1360 	bool					  isContextES   = glu::isContextTypeES(renderContext.getType());
1361 
1362 	if (isContextES)
1363 	{
1364 		gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexImage]);
1365 		setDrawReadBuffer(GL_NONE, GL_NONE);
1366 		gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_DEPTH_STENCIL, m_typeFormat.type, &data[0]);
1367 
1368 		GLenum error = gl.getError();
1369 		if (((GL_INVALID_OPERATION != error) && (GL_INVALID_ENUM != error)) &&
1370 			!((GL_NO_ERROR == error) && m_context.getContextInfo().isExtensionSupported("GL_NV_read_depth_stencil")))
1371 		{
1372 			gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_DEPTH_STENCIL, m_typeFormat.type, &data[0]);
1373 			if (gl.getError() != GL_INVALID_OPERATION)
1374 				result = false;
1375 		}
1376 
1377 		restoreDrawReadBuffer();
1378 		gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO);
1379 	}
1380 	else
1381 	{
1382 		gl.bindTexture(GL_TEXTURE_2D, m_textures[packedTexImage]);
1383 		gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexImage]);
1384 		setDrawReadBuffer(GL_NONE, GL_NONE);
1385 
1386 		for (unsigned int i = 0; i < m_nonDepthStencilTypesCount; i++)
1387 		{
1388 			gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_DEPTH_STENCIL, m_nonDepthStencilTypes[i], &data[0]);
1389 			if (gl.getError() != GL_INVALID_ENUM)
1390 				result = false;
1391 		}
1392 
1393 		for (unsigned int i = 0; i < m_nonDepthStencilFormatsCount; i++)
1394 		{
1395 			gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, m_nonDepthStencilFormats[i], m_typeFormat.type, &data[0]);
1396 
1397 			if (gl.getError() != GL_INVALID_OPERATION)
1398 				result = false;
1399 		}
1400 
1401 		for (int i = 0; i < 2; i++)
1402 		{
1403 			// setup texture/fbo
1404 			gl.genTextures(1, &texColor);
1405 			gl.genFramebuffers(1, &fbo);
1406 			gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
1407 
1408 			GLenum attachmentType = (i == 0) ? GL_DEPTH_ATTACHMENT : GL_STENCIL_ATTACHMENT;
1409 			gl.framebufferTexture2D(GL_FRAMEBUFFER, attachmentType, GL_TEXTURE_2D, m_textures[packedTexImage], 0);
1410 
1411 			gl.bindTexture(GL_TEXTURE_2D, texColor);
1412 			setupTexture();
1413 			gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, TEX_SIZE, TEX_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
1414 			gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texColor, 0);
1415 
1416 			gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_DEPTH_STENCIL, m_typeFormat.type, &data[0]);
1417 			if (gl.getError() != GL_INVALID_OPERATION)
1418 				result = false;
1419 
1420 			gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO);
1421 			gl.bindTexture(GL_TEXTURE_2D, 0);
1422 			gl.deleteFramebuffers(1, &fbo);
1423 			gl.deleteTextures(1, &texColor);
1424 		}
1425 
1426 		for (unsigned int i = 0; i < m_otherBaseFormatsCount; i++)
1427 		{
1428 			GLenum format = m_otherBaseFormats[i];
1429 			gl.genTextures(1, &texColor);
1430 			gl.bindTexture(GL_TEXTURE_2D, texColor);
1431 			setupTexture();
1432 			gl.texImage2D(GL_TEXTURE_2D, 0, format, TEX_SIZE, TEX_SIZE, 0, format, GL_UNSIGNED_BYTE, 0);
1433 
1434 			if (format != GL_DEPTH_COMPONENT)
1435 			{
1436 				gl.getTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, &data[0]);
1437 
1438 				if (gl.getError() != GL_INVALID_OPERATION)
1439 					result = false;
1440 			}
1441 
1442 			gl.getTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, &data[0]);
1443 			if (gl.getError() != GL_INVALID_OPERATION)
1444 				result = false;
1445 
1446 			gl.deleteTextures(1, &texColor);
1447 		}
1448 	}
1449 
1450 	bool coreGL = !glu::isContextTypeES(m_context.getRenderContext().getType());
1451 	for (int i = 0; i < 4; i++)
1452 	{
1453 		int limit;
1454 		if (i < 2)
1455 			limit = m_nonDepthStencilFormatsCount;
1456 		else
1457 			limit = m_otherBaseFormatsCount;
1458 
1459 		for (int j = 0; j < limit; j++)
1460 		{
1461 			GLint internalFormat = 0;
1462 			GLint format		 = 0;
1463 
1464 			gl.genTextures(1, &texColor);
1465 			gl.bindTexture(GL_TEXTURE_2D, texColor);
1466 			setupTexture();
1467 
1468 			switch (i)
1469 			{
1470 			case 0:
1471 				internalFormat = GL_DEPTH_COMPONENT;
1472 				format		   = m_nonDepthStencilFormats[j];
1473 				break;
1474 			case 1:
1475 				internalFormat = GL_DEPTH_STENCIL;
1476 				format		   = m_nonDepthStencilFormats[j];
1477 				break;
1478 			case 2:
1479 				internalFormat = m_otherBaseFormats[j];
1480 				format		   = GL_DEPTH_COMPONENT;
1481 				break;
1482 			case 3:
1483 				internalFormat = m_otherBaseFormats[j];
1484 				format		   = GL_DEPTH_STENCIL;
1485 				break;
1486 			}
1487 
1488 			gl.texImage2D(GL_TEXTURE_2D, 0, internalFormat, TEX_SIZE, TEX_SIZE, 0, format,
1489 						  (format == GL_DEPTH_STENCIL) ? GL_UNSIGNED_INT_24_8 : GL_UNSIGNED_BYTE, 0);
1490 
1491 			GLenum expectedError = GL_INVALID_OPERATION;
1492 			if (coreGL && (format == GL_STENCIL_INDEX))
1493 			{
1494 				// The OpenGL 4.3 spec is imprecise about what error this should generate
1495 				// see Bugzilla 10134: TexImage with a <format> of STENCIL_INDEX
1496 				//	 4.3 core (Feb 14 2013) p. 174:
1497 				//	 (describing TexImage3D)
1498 				//		 The format STENCIL_INDEX is not allowed.
1499 				// The new OpenGL 4.4 feature ARB_texture_stencil8 removes this error. So
1500 				// the best we can do for OpenGL is to just allow any error, or no error,
1501 				// for this specific case.
1502 				gl.getError();
1503 			}
1504 			else if (gl.getError() != expectedError)
1505 				result = false;
1506 
1507 			gl.bindTexture(GL_TEXTURE_2D, 0);
1508 			gl.deleteTextures(1, &texColor);
1509 		}
1510 	}
1511 
1512 	gl.genFramebuffers(1, &fbo);
1513 	gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
1514 	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexImage], 0);
1515 
1516 	gl.genFramebuffers(1, &fbo2);
1517 	gl.bindFramebuffer(GL_FRAMEBUFFER, fbo2);
1518 	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_textures[packedTexImage], 0);
1519 
1520 	GLuint tex;
1521 	gl.genTextures(1, &tex);
1522 	gl.bindTexture(GL_TEXTURE_2D, tex);
1523 	setupTexture();
1524 	gl.texImage2D(GL_TEXTURE_2D, 0, m_typeFormat.format, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_STENCIL, m_typeFormat.type, 0);
1525 
1526 	for (int i = 0; i < 2; i++)
1527 	{
1528 		switch (i)
1529 		{
1530 		case 0:
1531 			gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
1532 			gl.bindTexture(GL_TEXTURE_2D, tex);
1533 			break;
1534 		case 1:
1535 			gl.bindFramebuffer(GL_FRAMEBUFFER, fbo2);
1536 			gl.bindTexture(GL_TEXTURE_2D, tex);
1537 			break;
1538 		}
1539 
1540 		setDrawReadBuffer(GL_NONE, GL_NONE);
1541 
1542 		gl.copyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, 0, 0, TEX_SIZE, TEX_SIZE, 0);
1543 
1544 		GLenum error = gl.getError();
1545 		if ((GL_INVALID_OPERATION != error) && (GL_INVALID_ENUM != error))
1546 		{
1547 			gl.copyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, 0, 0, TEX_SIZE, TEX_SIZE, 0);
1548 			if (gl.getError() != GL_INVALID_OPERATION)
1549 				result = false;
1550 		}
1551 
1552 		restoreDrawReadBuffer();
1553 		gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO);
1554 	}
1555 
1556 	gl.bindTexture(GL_TEXTURE_2D, 0);
1557 	gl.deleteTextures(1, &tex);
1558 
1559 	gl.deleteFramebuffers(1, &fbo);
1560 	gl.deleteFramebuffers(1, &fbo2);
1561 
1562 	return result;
1563 }
1564 
1565 class VerifyReadPixelsTest : public BaseTest
1566 {
1567 public:
1568 	VerifyReadPixelsTest(deqp::Context& context, const TypeFormat& tf);
1569 	virtual ~VerifyReadPixelsTest();
1570 
1571 	virtual tcu::TestNode::IterateResult iterate(void);
1572 };
1573 
VerifyReadPixelsTest(deqp::Context & context,const TypeFormat & tf)1574 VerifyReadPixelsTest::VerifyReadPixelsTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf)
1575 {
1576 }
1577 
~VerifyReadPixelsTest()1578 VerifyReadPixelsTest::~VerifyReadPixelsTest()
1579 {
1580 }
1581 
iterate(void)1582 tcu::TestNode::IterateResult VerifyReadPixelsTest::iterate(void)
1583 {
1584 	//  Use readpixels to verify the results for the 5 textures above are correct.
1585 	//	Note that in ES you can only use gl.readpixels on color buffers.
1586 	//  Test method:
1587 	//  - on desktop: ReadPixel DEPTH_STENCIL value to buffer. Verify gradient.
1588 	//  - on desktop/Halti: Create FBO with color/depth/stencil attachment.
1589 	//	Draw a quad with depth texture bound. Verify gradient.
1590 	//	Draw 256 times using stencil test and gradient color. Verify gradient.
1591 
1592 	const glu::RenderContext& renderContext = m_context.getRenderContext();
1593 	const glw::Functions&	 gl			= renderContext.getFunctions();
1594 	std::size_t				  dataSize		= static_cast<std::size_t>(TEX_SIZE * TEX_SIZE * m_typeFormat.size);
1595 	std::vector<GLubyte>	  data(dataSize);
1596 
1597 	createTextures();
1598 	renderToTextures();
1599 
1600 	bool result = true;
1601 	for (int i = 0; i < NUM_TEXTURES; i++)
1602 	{
1603 		// Read DEPTH_STENCIL value, applies only to desktop
1604 		if (!glu::isContextTypeES(renderContext.getType()))
1605 		{
1606 			gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[i]);
1607 
1608 			setDrawReadBuffer(GL_NONE, GL_NONE);
1609 
1610 			data.assign(TEX_SIZE * TEX_SIZE * m_typeFormat.size, 0);
1611 			gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_DEPTH_STENCIL, m_typeFormat.type, &data[0]);
1612 			result &= verifyDepthStencilGradient(&data[0], i, TEX_SIZE, TEX_SIZE);
1613 
1614 			restoreDrawReadBuffer();
1615 		}
1616 
1617 		// On ES3.2 we have to render to color buffer to verify.
1618 		// We can run this also on desktop.
1619 		result &= doReadPixels(m_textures[i], i);
1620 	}
1621 
1622 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO);
1623 
1624 	destroyTextures();
1625 	if (result)
1626 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1627 	else
1628 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1629 
1630 	return STOP;
1631 }
1632 
1633 class VerifyGetTexImageTest : public BaseTest
1634 {
1635 public:
1636 	VerifyGetTexImageTest(deqp::Context& context, const TypeFormat& tf);
1637 	virtual ~VerifyGetTexImageTest();
1638 
1639 	virtual tcu::TestNode::IterateResult iterate(void);
1640 };
1641 
VerifyGetTexImageTest(deqp::Context & context,const TypeFormat & tf)1642 VerifyGetTexImageTest::VerifyGetTexImageTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf)
1643 {
1644 }
1645 
~VerifyGetTexImageTest()1646 VerifyGetTexImageTest::~VerifyGetTexImageTest()
1647 {
1648 }
1649 
iterate(void)1650 tcu::TestNode::IterateResult VerifyGetTexImageTest::iterate(void)
1651 {
1652 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1653 	std::vector<GLubyte>  data(TEX_SIZE * TEX_SIZE * m_typeFormat.size);
1654 
1655 	createTextures();
1656 	renderToTextures();
1657 
1658 	bool result = true;
1659 	for (int i = 0; i < NUM_TEXTURES; i++)
1660 	{
1661 		data.assign(TEX_SIZE * TEX_SIZE * m_typeFormat.size, 0);
1662 		gl.bindTexture(GL_TEXTURE_2D, m_textures[i]);
1663 		gl.getTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, m_typeFormat.type, &data[0]);
1664 		result &= verifyDepthStencilGradient(&data[0], i, TEX_SIZE, TEX_SIZE);
1665 	}
1666 
1667 	destroyTextures();
1668 	if (result)
1669 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1670 	else
1671 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1672 
1673 	return STOP;
1674 }
1675 
1676 class VerifyCopyTexImageTest : public BaseTest
1677 {
1678 public:
1679 	VerifyCopyTexImageTest(deqp::Context& context, const TypeFormat& tf);
1680 	virtual ~VerifyCopyTexImageTest();
1681 
1682 	virtual tcu::TestNode::IterateResult iterate(void);
1683 };
1684 
VerifyCopyTexImageTest(deqp::Context & context,const TypeFormat & tf)1685 VerifyCopyTexImageTest::VerifyCopyTexImageTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf)
1686 {
1687 }
1688 
~VerifyCopyTexImageTest()1689 VerifyCopyTexImageTest::~VerifyCopyTexImageTest()
1690 {
1691 }
1692 
iterate(void)1693 tcu::TestNode::IterateResult VerifyCopyTexImageTest::iterate(void)
1694 {
1695 	// After rendering to depth and stencil, CopyTexImage the results to a new
1696 	// DEPTH_STENCIL texture. Attach this texture to a new FBO. Verify that
1697 	// depth and stencil tests work with the copied data.
1698 
1699 	createTextures();
1700 	renderToTextures();
1701 
1702 	bool				  result = true;
1703 	const glw::Functions& gl	 = m_context.getRenderContext().getFunctions();
1704 
1705 	// setup shader
1706 	GLint uColor;
1707 	setupColorProgram(uColor);
1708 
1709 	// setup and copy texture/fbo
1710 	GLuint tex;
1711 	gl.genTextures(1, &tex);
1712 	GLuint fbo;
1713 	gl.genFramebuffers(1, &fbo);
1714 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexRender]);
1715 	gl.bindTexture(GL_TEXTURE_2D, tex);
1716 	setupTexture();
1717 
1718 	setDrawReadBuffer(GL_NONE, GL_NONE);
1719 
1720 	gl.texImage2D(GL_TEXTURE_2D, 0, m_typeFormat.format, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_STENCIL, m_typeFormat.type,
1721 				  NULL);
1722 	gl.copyTexImage2D(GL_TEXTURE_2D, 0, m_typeFormat.format, 0, 0, TEX_SIZE, TEX_SIZE, 0);
1723 
1724 	restoreDrawReadBuffer();
1725 
1726 	gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
1727 	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex, 0);
1728 	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, tex, 0);
1729 	setDrawReadBuffer(GL_NONE, GL_NONE);
1730 
1731 	int status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
1732 	if (status != GL_FRAMEBUFFER_COMPLETE)
1733 	{
1734 		m_testCtx.getLog() << tcu::TestLog::Message << "Framebuffer is incomplete: " << status
1735 						   << tcu::TestLog::EndMessage;
1736 		result = false;
1737 		restoreDrawReadBuffer();
1738 	}
1739 	else
1740 	{
1741 		// render
1742 		gl.enable(GL_DEPTH_TEST);
1743 		gl.depthFunc(GL_LEQUAL);
1744 		gl.viewport(0, 0, TEX_SIZE, TEX_SIZE);
1745 		gl.enable(GL_STENCIL_TEST);
1746 		gl.stencilFunc(GL_EQUAL, 0x1, 0xFF);
1747 		gl.stencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
1748 		drawQuad(DEFAULT, m_colorProgram);
1749 		gl.disable(GL_STENCIL_TEST);
1750 
1751 		// verify
1752 		std::vector<GLubyte> data(TEX_SIZE * TEX_SIZE * m_typeFormat.size, 0);
1753 		gl.getTexImage(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, m_typeFormat.type, &data[0]);
1754 		result &= verifyDepthStencilGradient(&data[0], verifyCopyTexImage, TEX_SIZE, TEX_SIZE);
1755 
1756 		restoreDrawReadBuffer();
1757 
1758 		result &= doReadPixels(tex, verifyCopyTexImage);
1759 	}
1760 
1761 	// clean up
1762 	gl.deleteFramebuffers(1, &fbo);
1763 	gl.deleteTextures(1, &tex);
1764 
1765 	destroyTextures();
1766 	if (result)
1767 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1768 	else
1769 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1770 
1771 	return STOP;
1772 }
1773 
1774 class VerifyPartialAttachmentsTest : public BaseTest
1775 {
1776 public:
1777 	VerifyPartialAttachmentsTest(deqp::Context& context, const TypeFormat& tf);
1778 	virtual ~VerifyPartialAttachmentsTest();
1779 
1780 	virtual tcu::TestNode::IterateResult iterate(void);
1781 };
1782 
VerifyPartialAttachmentsTest(deqp::Context & context,const TypeFormat & tf)1783 VerifyPartialAttachmentsTest::VerifyPartialAttachmentsTest(deqp::Context& context, const TypeFormat& tf)
1784 	: BaseTest(context, tf)
1785 {
1786 }
1787 
~VerifyPartialAttachmentsTest()1788 VerifyPartialAttachmentsTest::~VerifyPartialAttachmentsTest()
1789 {
1790 }
1791 
iterate(void)1792 tcu::TestNode::IterateResult VerifyPartialAttachmentsTest::iterate(void)
1793 {
1794 	createTextures();
1795 	renderToTextures();
1796 
1797 	bool result = true;
1798 
1799 	//  - Create an FBO with a packed depth stencil renderbuffer attached to
1800 	//	DEPTH_ATTACHMENT only. If this FBO is complete, stencil test must act as
1801 	//	if there is no stencil buffer (always pass.)
1802 
1803 	//  - Create an FBO with a packed depth stencil renderbuffer attached to
1804 	//	STENCIL_ATTACHMENT only. If this FBO is complete, depth test must act as
1805 	//	if there is no depth buffer (always pass.)
1806 
1807 	//  - Create an FBO with a packed depth stencil renderbuffer attached to
1808 	//	STENCIL_ATTACHMENT only. If this FBO is complete, occlusion query must
1809 	//	act as if there is no depth buffer (always pass.)
1810 
1811 	const glu::RenderContext& renderContext = m_context.getRenderContext();
1812 	const glw::Functions&	 gl			= renderContext.getFunctions();
1813 	bool					  isContextES   = glu::isContextTypeES(renderContext.getType());
1814 
1815 	// setup shader
1816 	GLint uColor;
1817 	setupColorProgram(uColor);
1818 
1819 	GLuint occ;
1820 	gl.genQueries(1, &occ);
1821 
1822 	for (int i = 0; i < 3; i++)
1823 	{
1824 		// setup fbo
1825 		GLuint fbo;
1826 		gl.genFramebuffers(1, &fbo);
1827 		gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
1828 
1829 		GLuint rbo[2]; // color, D/S
1830 		gl.genRenderbuffers(2, rbo);
1831 		gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[0]);
1832 		gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, TEX_SIZE, TEX_SIZE);
1833 		gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[1]);
1834 		gl.renderbufferStorage(GL_RENDERBUFFER, m_typeFormat.format, TEX_SIZE, TEX_SIZE);
1835 
1836 		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo[0]);
1837 		setDrawReadBuffer(GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0);
1838 
1839 		switch (i)
1840 		{
1841 		case 0:
1842 			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo[1]);
1843 			break;
1844 		case 1:
1845 		case 2:
1846 			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo[1]);
1847 			break;
1848 		default:
1849 			result = false;
1850 		}
1851 
1852 		if (!result)
1853 			break;
1854 
1855 		int status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
1856 		if (status != GL_FRAMEBUFFER_COMPLETE)
1857 		{
1858 			m_testCtx.getLog() << tcu::TestLog::Message << "Framebuffer is incomplete: " << status
1859 							   << tcu::TestLog::EndMessage;
1860 			result = false;
1861 		}
1862 		else
1863 		{
1864 			// render
1865 			gl.viewport(0, 0, TEX_SIZE, TEX_SIZE);
1866 			if (isContextES)
1867 				gl.clearDepthf(1.0f);
1868 			else
1869 				gl.clearDepth(1.0);
1870 
1871 			gl.clearStencil(0);
1872 			gl.clearColor(0.8f, 0.8f, 0.8f, 0.8f);
1873 			gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1874 
1875 			switch (i)
1876 			{
1877 			case 0:
1878 				gl.disable(GL_DEPTH_TEST);
1879 				gl.enable(GL_STENCIL_TEST);
1880 				gl.stencilFunc(GL_NEVER, 0xFF, 0xFF);
1881 				gl.stencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
1882 				break;
1883 			case 1:
1884 				gl.enable(GL_DEPTH_TEST);
1885 				gl.depthFunc(GL_NEVER);
1886 				gl.disable(GL_STENCIL_TEST);
1887 				break;
1888 			case 2:
1889 				gl.enable(GL_DEPTH_TEST);
1890 				gl.depthFunc(GL_NEVER);
1891 				gl.disable(GL_STENCIL_TEST);
1892 				gl.beginQuery(GL_ANY_SAMPLES_PASSED, occ);
1893 				break;
1894 			default:
1895 				break;
1896 			}
1897 
1898 			drawQuad(DEFAULT, m_colorProgram);
1899 
1900 			if (i == 2)
1901 			{
1902 				GLuint n;
1903 
1904 				gl.endQuery(GL_ANY_SAMPLES_PASSED);
1905 				gl.getQueryObjectuiv(occ, GL_QUERY_RESULT, &n);
1906 
1907 				if (n > 0)
1908 				{
1909 					drawQuad(DEFAULT, m_colorProgram);
1910 				}
1911 			}
1912 
1913 			std::vector<GLuint> data(TEX_SIZE * TEX_SIZE, 0);
1914 			gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
1915 			result &= verifyColorGradient(&data[0], verifyPartialAttachments, COLOR_CHECK_DEFAULT, TEX_SIZE, TEX_SIZE);
1916 		}
1917 
1918 		restoreDrawReadBuffer();
1919 
1920 		gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO);
1921 
1922 		// clean up
1923 		gl.deleteFramebuffers(1, &fbo);
1924 		gl.deleteRenderbuffers(2, rbo);
1925 	}
1926 
1927 	gl.deleteQueries(1, &occ);
1928 
1929 	destroyTextures();
1930 	if (result)
1931 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1932 	else
1933 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1934 
1935 	return STOP;
1936 }
1937 
1938 class VerifyMixedAttachmentsTest : public BaseTest
1939 {
1940 public:
1941 	VerifyMixedAttachmentsTest(deqp::Context& context, const TypeFormat& tf);
1942 	virtual ~VerifyMixedAttachmentsTest();
1943 
1944 	virtual tcu::TestNode::IterateResult iterate(void);
1945 };
1946 
VerifyMixedAttachmentsTest(deqp::Context & context,const TypeFormat & tf)1947 VerifyMixedAttachmentsTest::VerifyMixedAttachmentsTest(deqp::Context& context, const TypeFormat& tf)
1948 	: BaseTest(context, tf)
1949 {
1950 }
1951 
~VerifyMixedAttachmentsTest()1952 VerifyMixedAttachmentsTest::~VerifyMixedAttachmentsTest()
1953 {
1954 }
1955 
iterate(void)1956 tcu::TestNode::IterateResult VerifyMixedAttachmentsTest::iterate(void)
1957 {
1958 	// Create FBOs that mix DEPTH_STENCIL renderbuffers with DEPTH or STENCIL
1959 	// renderbuffers. If these FBOs are complete, depth and stencil test
1960 	// must work properly.
1961 
1962 	// Create an FBO with two different packed depth stencil renderbuffers, one
1963 	// attached to DEPTH_ATTACHMENT and the other attached to STENCIL_ATTACHMENT.
1964 	// Querying DEPTH_STENCIL_ATTACHMENT must fail with INVALID_OPERATION. If
1965 	// this FBO is complete, depth and stencil tests must work properly.
1966 
1967 	createTextures();
1968 	renderToTextures();
1969 
1970 	bool result = true;
1971 
1972 	const glu::RenderContext& renderContext = m_context.getRenderContext();
1973 	const glw::Functions&	 gl			= renderContext.getFunctions();
1974 	bool					  isContextES   = glu::isContextTypeES(renderContext.getType());
1975 
1976 	GLint uColor;
1977 	setupColorProgram(uColor);
1978 
1979 	for (int i = 0; i < 3; i++)
1980 	{
1981 		// set up FBO/RBOs
1982 		GLuint fbo;
1983 		gl.genFramebuffers(1, &fbo);
1984 		gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
1985 
1986 		GLuint rbo[3]; // color, DEPTH_STENCIL, DEPTH/STENCIL
1987 		gl.genRenderbuffers(3, rbo);
1988 
1989 		gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[0]);
1990 		gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, TEX_SIZE, TEX_SIZE);
1991 		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo[0]);
1992 
1993 		gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[1]);
1994 		gl.renderbufferStorage(GL_RENDERBUFFER, m_typeFormat.format, TEX_SIZE, TEX_SIZE);
1995 
1996 		gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[2]);
1997 		switch (i)
1998 		{
1999 		case 0:
2000 			gl.renderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, TEX_SIZE, TEX_SIZE);
2001 			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo[1]);
2002 			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo[2]);
2003 			break;
2004 		case 1:
2005 			gl.renderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, TEX_SIZE, TEX_SIZE);
2006 			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo[1]);
2007 			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo[2]);
2008 			break;
2009 		case 2:
2010 			gl.renderbufferStorage(GL_RENDERBUFFER, m_typeFormat.format, TEX_SIZE, TEX_SIZE);
2011 			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo[1]);
2012 			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo[2]);
2013 
2014 			GLint param;
2015 			gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
2016 												   GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &param);
2017 			if (gl.getError() != GL_INVALID_OPERATION)
2018 			{
2019 				m_testCtx.getLog() << tcu::TestLog::Message
2020 								   << "Expected INVALID_OPERATION for DEPTH_STENCIL_ATTACHMENT query"
2021 								   << tcu::TestLog::EndMessage;
2022 				result = false;
2023 			}
2024 
2025 			break;
2026 		}
2027 
2028 		GLenum status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
2029 		if (status != GL_FRAMEBUFFER_COMPLETE)
2030 		{
2031 			if (status == GL_FRAMEBUFFER_UNSUPPORTED)
2032 			{
2033 				/* The spec only requires
2034 
2035 					 "when both depth and stencil attachments are present, implementations are only
2036 					  required to support framebuffer objects where both attachments refer to the same image."
2037 
2038 				   Thus, it is accepatable for an implementation returning GL_FRAMEBUFFER_UNSUPPORTED.  And the
2039 				   test can NOT be marked as fail.
2040 				 */
2041 			}
2042 			else
2043 			{
2044 				m_testCtx.getLog() << tcu::TestLog::Message << "Framebuffer is incomplete" << tcu::TestLog::EndMessage;
2045 				result = false;
2046 			}
2047 		}
2048 		else
2049 		{
2050 
2051 			// render
2052 			// step 1
2053 			gl.viewport(0, 0, TEX_SIZE, TEX_SIZE);
2054 			gl.enable(GL_DEPTH_TEST);
2055 			gl.depthFunc(GL_LEQUAL);
2056 
2057 			if (isContextES)
2058 				gl.clearDepthf(1.0f);
2059 			else
2060 				gl.clearDepth(1.0);
2061 
2062 			gl.enable(GL_STENCIL_TEST);
2063 			gl.stencilFunc(GL_ALWAYS, 0x1, 0xFF);
2064 			gl.stencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
2065 			gl.clearStencil(0);
2066 			gl.clearColor(0.8f, 0.8f, 0.8f, 0.8f);
2067 			gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2068 			drawQuad(DEPTH_SPAN1, m_colorProgram);
2069 
2070 			// step 2
2071 			gl.stencilFunc(GL_EQUAL, 0x1, 0xFF);
2072 			gl.stencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
2073 			gl.clearColor(0.8f, 0.8f, 0.8f, 0.8f);
2074 			gl.clear(GL_COLOR_BUFFER_BIT);
2075 			drawQuad(DEFAULT, m_colorProgram);
2076 
2077 			std::vector<GLuint> data(TEX_SIZE * TEX_SIZE, 0);
2078 			gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
2079 			result &= verifyColorGradient(&data[0], verifyMixedAttachments, COLOR_CHECK_DEFAULT, TEX_SIZE, TEX_SIZE);
2080 		}
2081 
2082 		// clean up
2083 		gl.deleteRenderbuffers(3, rbo);
2084 		gl.deleteFramebuffers(1, &fbo);
2085 	}
2086 
2087 	destroyTextures();
2088 	if (result)
2089 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2090 	else
2091 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2092 
2093 	return STOP;
2094 }
2095 
2096 class VerifyParametersTest : public BaseTest
2097 {
2098 public:
2099 	VerifyParametersTest(deqp::Context& context, const TypeFormat& tf);
2100 	virtual ~VerifyParametersTest();
2101 
2102 	virtual tcu::TestNode::IterateResult iterate(void);
2103 };
2104 
VerifyParametersTest(deqp::Context & context,const TypeFormat & tf)2105 VerifyParametersTest::VerifyParametersTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf)
2106 {
2107 }
2108 
~VerifyParametersTest()2109 VerifyParametersTest::~VerifyParametersTest()
2110 {
2111 }
2112 
iterate(void)2113 tcu::TestNode::IterateResult VerifyParametersTest::iterate(void)
2114 {
2115 	//  Verify GetFramebufferAttachmentParameter queries of each <pname> on
2116 	//	DEPTH_STENCIL_ATTACHMENT work correctly if both attachments are populated
2117 	//	with the same object.
2118 
2119 	createTextures();
2120 	renderToTextures();
2121 
2122 	bool result = true;
2123 
2124 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2125 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexImage]);
2126 
2127 	GLint param;
2128 	gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
2129 										   GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &param);
2130 	if (param != GL_TEXTURE)
2131 	{
2132 		m_testCtx.getLog() << tcu::TestLog::Message
2133 						   << "Invalid value for GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: " << param
2134 						   << tcu::TestLog::EndMessage;
2135 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2136 		return STOP;
2137 	}
2138 
2139 	const AttachmentParam* attachmentParams = getAttachmentParams();
2140 	for (GLuint i = 0; i < m_attachmentParamsCount; i++)
2141 	{
2142 		int	ref;
2143 		GLenum pname = attachmentParams[i].pname;
2144 		if (GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE == pname)
2145 		{
2146 			gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, pname, &param);
2147 			if (gl.getError() != GL_INVALID_OPERATION)
2148 				result = false;
2149 			continue;
2150 		}
2151 
2152 		gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, pname, &param);
2153 
2154 		ref = attachmentParams[i].value;
2155 		if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)
2156 			ref = m_textures[packedTexImage];
2157 
2158 		if (param != ref)
2159 		{
2160 			m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value for pname " << attachmentParams[i].pname
2161 							   << ": " << param << " ( expected " << ref << ")" << tcu::TestLog::EndMessage;
2162 			result = false;
2163 		}
2164 	}
2165 
2166 	destroyTextures();
2167 	if (result)
2168 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2169 	else
2170 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2171 
2172 	return STOP;
2173 }
2174 
2175 class RenderbuffersTest : public BaseTest
2176 {
2177 public:
2178 	RenderbuffersTest(deqp::Context& context, const TypeFormat& tf);
2179 	virtual ~RenderbuffersTest();
2180 
2181 	virtual tcu::TestNode::IterateResult iterate(void);
2182 };
2183 
RenderbuffersTest(deqp::Context & context,const TypeFormat & tf)2184 RenderbuffersTest::RenderbuffersTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf)
2185 {
2186 }
2187 
~RenderbuffersTest()2188 RenderbuffersTest::~RenderbuffersTest()
2189 {
2190 }
2191 
iterate(void)2192 tcu::TestNode::IterateResult RenderbuffersTest::iterate(void)
2193 {
2194 	createTextures();
2195 	renderToTextures();
2196 
2197 	bool result = true;
2198 
2199 	// Verify RENDERBUFFER_DEPTH_SIZE and RENDERBUFFER_STENCIL_SIZE report
2200 	// appropriate values for for DEPTH_STENCIL renderbuffers.
2201 
2202 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2203 
2204 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffers[packedTexImage]);
2205 
2206 	GLuint rbo;
2207 	gl.genRenderbuffers(1, &rbo);
2208 	gl.bindRenderbuffer(GL_RENDERBUFFER, rbo);
2209 	gl.renderbufferStorage(GL_RENDERBUFFER, m_typeFormat.format, TEX_SIZE, TEX_SIZE);
2210 	gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
2211 
2212 	GLint param;
2213 	gl.getRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_DEPTH_SIZE, &param);
2214 	if (param != m_typeFormat.d)
2215 	{
2216 		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid depth: " << param << ", expected: " << m_typeFormat.d
2217 						   << tcu::TestLog::EndMessage;
2218 		result = false;
2219 	}
2220 
2221 	gl.getRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_STENCIL_SIZE, &param);
2222 	if (param != m_typeFormat.s)
2223 	{
2224 		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid stencil: " << param << ", expected: " << m_typeFormat.s
2225 						   << tcu::TestLog::EndMessage;
2226 		result = false;
2227 	}
2228 
2229 	gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
2230 	gl.deleteRenderbuffers(1, &rbo);
2231 	gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO);
2232 
2233 	destroyTextures();
2234 	if (result)
2235 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2236 	else
2237 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2238 
2239 	return STOP;
2240 }
2241 
2242 class StencilSizeTest : public BaseTest
2243 {
2244 public:
2245 	StencilSizeTest(deqp::Context& context, const TypeFormat& tf);
2246 	virtual ~StencilSizeTest();
2247 
2248 	virtual tcu::TestNode::IterateResult iterate(void);
2249 };
2250 
StencilSizeTest(deqp::Context & context,const TypeFormat & tf)2251 StencilSizeTest::StencilSizeTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf)
2252 {
2253 }
2254 
~StencilSizeTest()2255 StencilSizeTest::~StencilSizeTest()
2256 {
2257 }
2258 
iterate(void)2259 tcu::TestNode::IterateResult StencilSizeTest::iterate(void)
2260 {
2261 	// [desktop only] Verify TEXTURE_STENCIL_SIZE reports 8 for DEPTH_STENCIL
2262 	// textures, and 0 for RGBA and DEPTH_COMPONENT textures.
2263 
2264 	createTextures();
2265 	renderToTextures();
2266 
2267 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2268 
2269 	bool  result = true;
2270 	GLint param;
2271 	gl.bindTexture(GL_TEXTURE_2D, m_textures[packedTexImage]);
2272 	gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_STENCIL_SIZE, &param);
2273 	if (param != 8)
2274 	{
2275 		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value for DEPTH_STENCIL stencil size: " << param
2276 						   << tcu::TestLog::EndMessage;
2277 		result = false;
2278 	}
2279 
2280 	GLuint texRGBA;
2281 	gl.genTextures(1, &texRGBA);
2282 	gl.bindTexture(GL_TEXTURE_2D, texRGBA);
2283 	setupTexture();
2284 	gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, TEX_SIZE, TEX_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
2285 	gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_STENCIL_SIZE, &param);
2286 	if (param != 0)
2287 	{
2288 		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value for RGBA stencil size: " << param
2289 						   << tcu::TestLog::EndMessage;
2290 		result = false;
2291 	}
2292 	gl.deleteTextures(1, &texRGBA);
2293 
2294 	GLuint texDepth;
2295 	gl.genTextures(1, &texDepth);
2296 	gl.bindTexture(GL_TEXTURE_2D, texDepth);
2297 	setupTexture();
2298 	gl.texImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
2299 				  0);
2300 	gl.getTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_STENCIL_SIZE, &param);
2301 	if (param != 0)
2302 	{
2303 		m_testCtx.getLog() << tcu::TestLog::Message << "Invalid value for DEPTH_COMPONENT stencil size: " << param
2304 						   << tcu::TestLog::EndMessage;
2305 		result = false;
2306 	}
2307 	gl.deleteTextures(1, &texDepth);
2308 
2309 	destroyTextures();
2310 	if (result)
2311 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2312 	else
2313 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2314 
2315 	return STOP;
2316 }
2317 
2318 class ClearBufferTest : public BaseTest
2319 {
2320 public:
2321 	ClearBufferTest(deqp::Context& context, const TypeFormat& tf);
2322 	virtual ~ClearBufferTest();
2323 
2324 	virtual tcu::TestNode::IterateResult iterate(void);
2325 };
2326 
ClearBufferTest(deqp::Context & context,const TypeFormat & tf)2327 ClearBufferTest::ClearBufferTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf)
2328 {
2329 }
2330 
~ClearBufferTest()2331 ClearBufferTest::~ClearBufferTest()
2332 {
2333 }
2334 
iterate(void)2335 tcu::TestNode::IterateResult ClearBufferTest::iterate(void)
2336 {
2337 	// Verify ClearBufferfv correctly clears the depth channel of a DEPTH_STENCIL
2338 	// FBO attachment (and does not touch the stencil channel.)
2339 	// Verify ClearBufferiv correctly clears the stencil channel of a
2340 	// DEPTH_STENCIL FBO attachment (and does not touch the depth channel.)
2341 	// Verify ClearBufferfi correctly clears the depth and stencil channels of a
2342 	// DEPTH_STENCIL FBO attachment.
2343 
2344 	createTextures();
2345 	renderToTextures();
2346 
2347 	bool	result = true;
2348 	GLfloat valuef;
2349 	GLint   valuei;
2350 	GLenum  status;
2351 
2352 	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
2353 
2354 	// setup shader
2355 	GLint uColor;
2356 	setupColorProgram(uColor);
2357 
2358 	for (int i = 0; i < 3; i++)
2359 	{
2360 		// setup texture/fbo
2361 		GLuint tex;
2362 		GLuint texColor;
2363 		GLuint fbo;
2364 		gl.genTextures(1, &tex);
2365 		gl.genTextures(1, &texColor);
2366 		gl.genFramebuffers(1, &fbo);
2367 		gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
2368 
2369 		gl.bindTexture(GL_TEXTURE_2D, tex);
2370 		setupTexture();
2371 		std::vector<GLbyte> data;
2372 		createGradient(data);
2373 		gl.texImage2D(GL_TEXTURE_2D, 0, m_typeFormat.format, TEX_SIZE, TEX_SIZE, 0, GL_DEPTH_STENCIL, m_typeFormat.type,
2374 					  &data[0]);
2375 		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, tex, 0);
2376 
2377 		gl.bindTexture(GL_TEXTURE_2D, texColor);
2378 		setupTexture();
2379 		gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, TEX_SIZE, TEX_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
2380 		gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texColor, 0);
2381 
2382 		setDrawReadBuffer(GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0);
2383 
2384 		status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
2385 		if (status != GL_FRAMEBUFFER_COMPLETE)
2386 		{
2387 			m_testCtx.getLog() << tcu::TestLog::Message << "Framebuffer is incomplete: " << status
2388 							   << tcu::TestLog::EndMessage;
2389 			result = false;
2390 		}
2391 		else
2392 		{
2393 			// clear relevant buffers
2394 			switch (i)
2395 			{
2396 			case 0:
2397 				valuef = 1.0f;
2398 				gl.clearBufferfv(GL_DEPTH, 0, &valuef);
2399 				break;
2400 			case 1:
2401 				valuei = 0xff;
2402 				gl.clearBufferiv(GL_STENCIL, 0, &valuei);
2403 				break;
2404 			case 2:
2405 				valuef = 1.0f;
2406 				valuei = 0xff;
2407 				gl.clearBufferfi(GL_DEPTH_STENCIL, 0, valuef, valuei);
2408 				break;
2409 			}
2410 
2411 			// render reference image
2412 			gl.viewport(0, 0, TEX_SIZE, TEX_SIZE);
2413 			gl.enable(GL_DEPTH_TEST);
2414 			gl.depthFunc(GL_LEQUAL);
2415 			gl.enable(GL_STENCIL_TEST);
2416 			gl.stencilFunc(GL_EQUAL, 0xFF, 0xFF);
2417 			gl.stencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
2418 			gl.clearColor(0.8f, 0.8f, 0.8f, 0.8f);
2419 			gl.clear(GL_COLOR_BUFFER_BIT);
2420 			drawQuad(DEFAULT, m_colorProgram);
2421 
2422 			// verify
2423 			std::vector<GLubyte> readData(TEX_SIZE * TEX_SIZE * 4, 0);
2424 			gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, &readData[0]);
2425 			result &=
2426 				verifyColorGradient(&readData[0], verifyClearBufferDepth + i, COLOR_CHECK_DEFAULT, TEX_SIZE, TEX_SIZE);
2427 		}
2428 
2429 		// destroy texture/fbo
2430 		restoreDrawReadBuffer();
2431 
2432 		gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO);
2433 		gl.bindTexture(GL_TEXTURE_2D, 0);
2434 		gl.deleteFramebuffers(1, &fbo);
2435 		gl.deleteTextures(1, &tex);
2436 		gl.deleteTextures(1, &texColor);
2437 	}
2438 
2439 	destroyTextures();
2440 	if (result)
2441 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2442 	else
2443 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2444 
2445 	return STOP;
2446 }
2447 
2448 class BlitTest : public BaseTest
2449 {
2450 public:
2451 	BlitTest(deqp::Context& context, const TypeFormat& tf);
2452 	virtual ~BlitTest();
2453 
2454 	virtual tcu::TestNode::IterateResult iterate(void);
2455 };
2456 
BlitTest(deqp::Context & context,const TypeFormat & tf)2457 BlitTest::BlitTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf)
2458 {
2459 }
2460 
~BlitTest()2461 BlitTest::~BlitTest()
2462 {
2463 }
2464 
iterate(void)2465 tcu::TestNode::IterateResult BlitTest::iterate(void)
2466 {
2467 	// Verify that NEAREST filtered blits of DEPTH and/or STENCIL between two
2468 	// FBOs with the same format packed depth stencil attachment work. Test
2469 	// non-multisample [1->1], multisample resolve [N->1], and multisample
2470 	// replicate [1->N] blits, for each supported value of N up to MAX_SAMPLES.
2471 
2472 	createTextures();
2473 	renderToTextures();
2474 
2475 	GLuint fbo[3]; // Framebuffers: source, dest, downsample
2476 	GLuint rbo[4]; // Renderbuffers: source D/S, dest D/S, dest color, downsample color
2477 	GLint  maxSamples;
2478 	int	srcSamples, destSamples;
2479 	bool   result = true;
2480 
2481 	const glu::RenderContext& renderContext = m_context.getRenderContext();
2482 	const glw::Functions&	 gl			= renderContext.getFunctions();
2483 	bool					  isContextES   = glu::isContextTypeES(renderContext.getType());
2484 
2485 	std::vector<GLuint> data(TEX_SIZE * TEX_SIZE);
2486 
2487 	GLint uColor;
2488 	setupColorProgram(uColor);
2489 
2490 	gl.getIntegerv(GL_MAX_SAMPLES, &maxSamples);
2491 
2492 	// ES does not allow SAMPLE_BUFFERS for the draw frame
2493 	// buffer is greater than zero when doing a blit.
2494 	int loopCount = isContextES ? 1 : 2;
2495 
2496 	for (int j = 0; j < loopCount; j++)
2497 	{
2498 		for (int i = 0; i <= maxSamples; i++)
2499 		{
2500 			// Create FBO/RBO
2501 			gl.genFramebuffers(3, fbo);
2502 			gl.genRenderbuffers(4, rbo);
2503 
2504 			if (j == 0)
2505 			{
2506 				srcSamples  = i;
2507 				destSamples = 0;
2508 			}
2509 			else
2510 			{
2511 				srcSamples  = 0;
2512 				destSamples = i;
2513 			}
2514 
2515 			gl.bindFramebuffer(GL_FRAMEBUFFER, fbo[0]);
2516 			gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[0]);
2517 			gl.renderbufferStorageMultisample(GL_RENDERBUFFER, srcSamples, m_typeFormat.format, TEX_SIZE, TEX_SIZE);
2518 			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo[0]);
2519 
2520 			gl.bindFramebuffer(GL_FRAMEBUFFER, fbo[1]);
2521 			gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[1]);
2522 			gl.renderbufferStorageMultisample(GL_RENDERBUFFER, destSamples, m_typeFormat.format, TEX_SIZE, TEX_SIZE);
2523 			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo[1]);
2524 
2525 			gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[2]);
2526 			gl.renderbufferStorageMultisample(GL_RENDERBUFFER, destSamples, GL_RGBA8, TEX_SIZE, TEX_SIZE);
2527 			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo[2]);
2528 
2529 			gl.bindFramebuffer(GL_FRAMEBUFFER, fbo[2]);
2530 			gl.bindRenderbuffer(GL_RENDERBUFFER, rbo[3]);
2531 			gl.renderbufferStorageMultisample(GL_RENDERBUFFER, 0, GL_RGBA8, TEX_SIZE, TEX_SIZE);
2532 			gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo[3]);
2533 
2534 			// Render
2535 			gl.bindFramebuffer(GL_FRAMEBUFFER, fbo[0]);
2536 			setDrawReadBuffer(GL_NONE, GL_NONE);
2537 
2538 			gl.viewport(0, 0, TEX_SIZE, TEX_SIZE);
2539 			gl.enable(GL_DEPTH_TEST);
2540 			gl.depthFunc(GL_LEQUAL);
2541 
2542 			if (isContextES)
2543 				gl.clearDepthf(1.0f);
2544 			else
2545 				gl.clearDepth(1.0);
2546 
2547 			gl.enable(GL_STENCIL_TEST);
2548 			gl.stencilFunc(GL_ALWAYS, 0x1, 0xFF);
2549 			gl.stencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
2550 			gl.clearStencil(0);
2551 			gl.clearColor(0.8f, 0.8f, 0.8f, 0.8f);
2552 			gl.clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2553 			drawQuad(DEPTH_SPAN1, m_colorProgram);
2554 
2555 			restoreDrawReadBuffer();
2556 
2557 			// Blit
2558 			gl.bindFramebuffer(GL_READ_FRAMEBUFFER, fbo[0]);
2559 			gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[1]);
2560 			setDrawReadBuffer(GL_NONE, GL_NONE);
2561 			gl.blitFramebuffer(0, 0, TEX_SIZE, TEX_SIZE, 0, 0, TEX_SIZE, TEX_SIZE,
2562 							   GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
2563 			restoreDrawReadBuffer();
2564 
2565 			// Verify
2566 			gl.bindFramebuffer(GL_FRAMEBUFFER, fbo[1]);
2567 			setDrawReadBuffer(GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0);
2568 
2569 			gl.stencilFunc(GL_EQUAL, 0x1, 0xFF);
2570 			gl.stencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
2571 			gl.clear(GL_COLOR_BUFFER_BIT);
2572 			drawQuad(DEFAULT, m_colorProgram);
2573 
2574 			restoreDrawReadBuffer();
2575 
2576 			// Downsample blit
2577 			gl.bindFramebuffer(GL_READ_FRAMEBUFFER, fbo[1]);
2578 			gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[2]);
2579 			setDrawReadBuffer(GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0);
2580 			gl.blitFramebuffer(0, 0, TEX_SIZE, TEX_SIZE, 0, 0, TEX_SIZE, TEX_SIZE, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2581 			restoreDrawReadBuffer();
2582 
2583 			gl.bindFramebuffer(GL_FRAMEBUFFER, fbo[2]);
2584 
2585 			gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]);
2586 
2587 			result &= verifyColorGradient(&data[0], verifyBlit, COLOR_CHECK_DEFAULT, TEX_SIZE, TEX_SIZE);
2588 
2589 			// Clean up
2590 			gl.bindFramebuffer(GL_FRAMEBUFFER, m_defaultFBO);
2591 			gl.bindRenderbuffer(GL_RENDERBUFFER, 0);
2592 
2593 			gl.deleteRenderbuffers(4, rbo);
2594 			gl.deleteFramebuffers(3, fbo);
2595 		}
2596 	}
2597 
2598 	destroyTextures();
2599 	if (result)
2600 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2601 	else
2602 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2603 
2604 	return STOP;
2605 }
2606 
2607 class StencilTexturingTest : public BaseTest
2608 {
2609 public:
2610 	StencilTexturingTest(deqp::Context& context, const TypeFormat& tf);
2611 	virtual ~StencilTexturingTest();
2612 
2613 	virtual tcu::TestNode::IterateResult iterate(void);
2614 };
2615 
StencilTexturingTest(deqp::Context & context,const TypeFormat & tf)2616 StencilTexturingTest::StencilTexturingTest(deqp::Context& context, const TypeFormat& tf) : BaseTest(context, tf)
2617 {
2618 }
2619 
~StencilTexturingTest()2620 StencilTexturingTest::~StencilTexturingTest()
2621 {
2622 }
2623 
iterate(void)2624 tcu::TestNode::IterateResult StencilTexturingTest::iterate(void)
2625 {
2626 	// Verifies that either depth or stencil can be sampled depending on
2627 	// GL_DEPTH_STENCIL_TEXTURE_MODE
2628 
2629 	const glu::RenderContext& renderContext = m_context.getRenderContext();
2630 	glu::ContextType		  contextType   = renderContext.getType();
2631 	const glw::Functions&	 gl			= renderContext.getFunctions();
2632 
2633 	bool notSupported = false;
2634 	if (glu::isContextTypeES(contextType))
2635 		notSupported = !glu::contextSupports(contextType, glu::ApiType::es(3, 1));
2636 	else
2637 		notSupported = !glu::contextSupports(contextType, glu::ApiType::core(4, 3));
2638 
2639 	if (notSupported)
2640 	{
2641 		m_testCtx.setTestResult(QP_TEST_RESULT_NOT_SUPPORTED, "stencil_texturing extension is not supported");
2642 		return STOP;
2643 	}
2644 
2645 	createTextures();
2646 	renderToTextures();
2647 
2648 	bool   result = true;
2649 	GLuint fbo;
2650 	gl.genFramebuffers(1, &fbo);
2651 	gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
2652 
2653 	GLuint texColor;
2654 	gl.genTextures(1, &texColor);
2655 	gl.bindTexture(GL_TEXTURE_2D, texColor);
2656 	setupTexture();
2657 	gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, TEX_SIZE, TEX_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
2658 
2659 	gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texColor, 0);
2660 	setDrawReadBuffer(GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT0);
2661 
2662 	// Step 1: Verify depth values
2663 	GLenum status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
2664 	if (status != GL_FRAMEBUFFER_COMPLETE)
2665 	{
2666 		m_testCtx.getLog() << tcu::TestLog::Message << "Framebuffer is incomplete: " << status
2667 						   << tcu::TestLog::EndMessage;
2668 		result = false;
2669 	}
2670 	else
2671 	{
2672 		gl.bindTexture(GL_TEXTURE_2D, m_textures[packedTexImage]);
2673 
2674 		gl.disable(GL_DEPTH_TEST);
2675 		gl.depthMask(GL_FALSE);
2676 		gl.disable(GL_STENCIL_TEST);
2677 		gl.viewport(0, 0, TEX_SIZE, TEX_SIZE);
2678 		gl.clearColor(0.8f, 0.8f, 0.8f, 0.8f);
2679 		gl.clear(GL_COLOR_BUFFER_BIT);
2680 
2681 		gl.texParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT);
2682 		setupTextureProgram();
2683 		drawQuad(DEFAULT, m_textureProgram);
2684 
2685 		std::vector<GLuint> dataColor(TEX_SIZE * TEX_SIZE, 0);
2686 		gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, &dataColor[0]);
2687 		result &= verifyColorGradient(&dataColor[0], packedTexImage, COLOR_CHECK_DEPTH, TEX_SIZE, TEX_SIZE);
2688 
2689 		// Step 2: Verify stencil values
2690 		gl.texParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
2691 		setupStencilProgram();
2692 		drawQuad(DEFAULT, m_stencilProgram);
2693 
2694 		dataColor.assign(TEX_SIZE * TEX_SIZE, 0);
2695 		gl.readPixels(0, 0, TEX_SIZE, TEX_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, &dataColor[0]);
2696 		result &= verifyColorGradient(&dataColor[0], packedTexImage, COLOR_CHECK_DEFAULT, TEX_SIZE, TEX_SIZE);
2697 	}
2698 
2699 	restoreDrawReadBuffer();
2700 	gl.deleteFramebuffers(1, &fbo);
2701 	gl.deleteTextures(1, &texColor);
2702 
2703 	destroyTextures();
2704 	if (result)
2705 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2706 	else
2707 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2708 
2709 	return STOP;
2710 }
2711 
PackedDepthStencilTests(deqp::Context & context)2712 PackedDepthStencilTests::PackedDepthStencilTests(deqp::Context& context)
2713 	: TestCaseGroup(context, "packed_depth_stencil", "")
2714 {
2715 }
2716 
~PackedDepthStencilTests(void)2717 PackedDepthStencilTests::~PackedDepthStencilTests(void)
2718 {
2719 }
2720 
init(void)2721 void PackedDepthStencilTests::init(void)
2722 {
2723 	TestCaseGroup* validateErrorsGroup			 = new deqp::TestCaseGroup(m_context, "validate_errors", "");
2724 	TestCaseGroup* verifyReadPixelsGroup		 = new deqp::TestCaseGroup(m_context, "verify_read_pixels", "");
2725 	TestCaseGroup* verifyGetTexImageGroup		 = new deqp::TestCaseGroup(m_context, "verify_get_tex_image", "");
2726 	TestCaseGroup* verifyCopyTexImageGroup		 = new deqp::TestCaseGroup(m_context, "verify_copy_tex_image", "");
2727 	TestCaseGroup* verifyPartialAttachmentsGroup = new deqp::TestCaseGroup(m_context, "verify_partial_attachments", "");
2728 	TestCaseGroup* verifyMixedAttachmentsGroup   = new deqp::TestCaseGroup(m_context, "verify_mixed_attachments", "");
2729 	TestCaseGroup* verifyParametersGroup		 = new deqp::TestCaseGroup(m_context, "verify_parameters", "");
2730 	TestCaseGroup* renderbuffersGroup			 = new deqp::TestCaseGroup(m_context, "renderbuffers", "");
2731 	TestCaseGroup* clearBufferGroup				 = new deqp::TestCaseGroup(m_context, "clear_buffer", "");
2732 	TestCaseGroup* blitGroup					 = new deqp::TestCaseGroup(m_context, "blit", "");
2733 	TestCaseGroup* stencilTexturingGroup		 = new deqp::TestCaseGroup(m_context, "stencil_texturing", "");
2734 	TestCaseGroup* stencilSizeGroup				 = new deqp::TestCaseGroup(m_context, "stencil_size", "");
2735 
2736 	bool isContextCoreGL = !glu::isContextTypeES(m_context.getRenderContext().getType());
2737 	if (isContextCoreGL)
2738 		validateErrorsGroup->addChild(new InitialStateTest(m_context));
2739 
2740 	for (int i = 0; i < NUM_TEXTURE_TYPES; i++)
2741 	{
2742 		const TypeFormat& typeFormat = TextureTypes[i];
2743 		validateErrorsGroup->addChild(new ValidateErrorsTest(m_context, typeFormat));
2744 		verifyReadPixelsGroup->addChild(new VerifyReadPixelsTest(m_context, typeFormat));
2745 		verifyPartialAttachmentsGroup->addChild(new VerifyPartialAttachmentsTest(m_context, typeFormat));
2746 		verifyMixedAttachmentsGroup->addChild(new VerifyMixedAttachmentsTest(m_context, typeFormat));
2747 		verifyParametersGroup->addChild(new VerifyParametersTest(m_context, typeFormat));
2748 		renderbuffersGroup->addChild(new RenderbuffersTest(m_context, typeFormat));
2749 		clearBufferGroup->addChild(new ClearBufferTest(m_context, typeFormat));
2750 		blitGroup->addChild(new BlitTest(m_context, typeFormat));
2751 		stencilTexturingGroup->addChild(new StencilTexturingTest(m_context, typeFormat));
2752 
2753 		if (isContextCoreGL)
2754 		{
2755 			verifyGetTexImageGroup->addChild(new VerifyGetTexImageTest(m_context, typeFormat));
2756 			verifyCopyTexImageGroup->addChild(new VerifyCopyTexImageTest(m_context, typeFormat));
2757 			stencilSizeGroup->addChild(new StencilSizeTest(m_context, typeFormat));
2758 		}
2759 	}
2760 
2761 	addChild(validateErrorsGroup);
2762 	addChild(verifyReadPixelsGroup);
2763 	addChild(verifyGetTexImageGroup);
2764 	addChild(verifyCopyTexImageGroup);
2765 	addChild(verifyPartialAttachmentsGroup);
2766 	addChild(verifyMixedAttachmentsGroup);
2767 	addChild(verifyParametersGroup);
2768 	addChild(renderbuffersGroup);
2769 	addChild(clearBufferGroup);
2770 	addChild(blitGroup);
2771 	addChild(stencilTexturingGroup);
2772 	addChild(stencilSizeGroup);
2773 }
2774 
2775 } /* glcts namespace */
2776