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