xref: /aosp_15_r20/external/deqp/modules/gles31/functional/es31fStencilTexturingTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.1 Module
3  * -------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Stencil texturing tests.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "es31fStencilTexturingTests.hpp"
25 
26 #include "gluStrUtil.hpp"
27 #include "gluObjectWrapper.hpp"
28 #include "gluRenderContext.hpp"
29 #include "gluShaderProgram.hpp"
30 #include "gluDrawUtil.hpp"
31 #include "gluPixelTransfer.hpp"
32 #include "gluTextureUtil.hpp"
33 #include "gluContextInfo.hpp"
34 
35 #include "glsTextureTestUtil.hpp"
36 
37 #include "tcuVector.hpp"
38 #include "tcuTexture.hpp"
39 #include "tcuTextureUtil.hpp"
40 #include "tcuTestLog.hpp"
41 #include "tcuTexLookupVerifier.hpp"
42 
43 #include "glwFunctions.hpp"
44 #include "glwEnums.hpp"
45 
46 #include "deStringUtil.hpp"
47 
48 namespace deqp
49 {
50 namespace gles31
51 {
52 namespace Functional
53 {
54 
55 using std::string;
56 using std::vector;
57 using tcu::IVec4;
58 using tcu::TestLog;
59 using tcu::TextureFormat;
60 using tcu::TextureLevel;
61 using tcu::Vec2;
62 using tcu::Vec4;
63 
64 namespace
65 {
66 
genTestRects(vector<IVec4> & rects,int width,int height)67 static void genTestRects(vector<IVec4> &rects, int width, int height)
68 {
69     int curWidth  = width;
70     int curHeight = height;
71     int ndx       = 0;
72 
73     for (;;)
74     {
75         rects.push_back(IVec4(width - curWidth, height - curHeight, curWidth, curHeight));
76 
77         DE_ASSERT(curWidth >= 1 && curHeight >= 1);
78         if (curWidth == 1 && curHeight == 1)
79             break;
80         else if (curHeight > 1 && ((ndx % 2) == 0 || curWidth == 1))
81             curHeight -= 1;
82         else
83             curWidth -= 1;
84 
85         ndx += 1;
86     }
87 }
88 
rectsToTriangles(const vector<IVec4> & rects,int width,int height,vector<Vec2> & positions,vector<uint16_t> & indices)89 static void rectsToTriangles(const vector<IVec4> &rects, int width, int height, vector<Vec2> &positions,
90                              vector<uint16_t> &indices)
91 {
92     const float w = float(width);
93     const float h = float(height);
94 
95     positions.resize(rects.size() * 4);
96     indices.resize(rects.size() * 6);
97 
98     for (int rectNdx = 0; rectNdx < (int)rects.size(); rectNdx++)
99     {
100         const int rx = rects[rectNdx].x();
101         const int ry = rects[rectNdx].y();
102         const int rw = rects[rectNdx].z();
103         const int rh = rects[rectNdx].w();
104 
105         const float x0 = float(rx * 2) / w - 1.0f;
106         const float x1 = float((rx + rw) * 2) / w - 1.0f;
107         const float y0 = float(ry * 2) / h - 1.0f;
108         const float y1 = float((ry + rh) * 2) / h - 1.0f;
109 
110         positions[rectNdx * 4 + 0] = Vec2(x0, y0);
111         positions[rectNdx * 4 + 1] = Vec2(x1, y0);
112         positions[rectNdx * 4 + 2] = Vec2(x0, y1);
113         positions[rectNdx * 4 + 3] = Vec2(x1, y1);
114 
115         indices[rectNdx * 6 + 0] = (uint16_t)(rectNdx * 4 + 0);
116         indices[rectNdx * 6 + 1] = (uint16_t)(rectNdx * 4 + 1);
117         indices[rectNdx * 6 + 2] = (uint16_t)(rectNdx * 4 + 2);
118         indices[rectNdx * 6 + 3] = (uint16_t)(rectNdx * 4 + 2);
119         indices[rectNdx * 6 + 4] = (uint16_t)(rectNdx * 4 + 1);
120         indices[rectNdx * 6 + 5] = (uint16_t)(rectNdx * 4 + 3);
121     }
122 }
123 
drawTestPattern(const glu::RenderContext & renderCtx,int width,int height)124 static void drawTestPattern(const glu::RenderContext &renderCtx, int width, int height)
125 {
126     const glu::ShaderProgram program(renderCtx, glu::ProgramSources()
127                                                     << glu::VertexSource("#version 300 es\n"
128                                                                          "in highp vec4 a_position;\n"
129                                                                          "void main (void)\n"
130                                                                          "{\n"
131                                                                          "    gl_Position = a_position;\n"
132                                                                          "}\n")
133                                                     << glu::FragmentSource("#version 300 es\n"
134                                                                            "void main (void) {}\n"));
135 
136     const glw::Functions &gl = renderCtx.getFunctions();
137     vector<IVec4> rects;
138     vector<Vec2> positions;
139     vector<uint16_t> indices;
140 
141     if (!program.isOk())
142         throw tcu::TestError("Compile failed");
143 
144     gl.useProgram(program.getProgram());
145     gl.viewport(0, 0, width, height);
146     gl.clear(GL_STENCIL_BUFFER_BIT);
147     gl.enable(GL_STENCIL_TEST);
148     gl.stencilOp(GL_KEEP, GL_KEEP, GL_INCR_WRAP);
149     gl.stencilFunc(GL_ALWAYS, 0, ~0u);
150     GLU_EXPECT_NO_ERROR(gl.getError(), "State setup failed");
151 
152     genTestRects(rects, width, height);
153     rectsToTriangles(rects, width, height, positions, indices);
154 
155     {
156         const glu::VertexArrayBinding posBinding =
157             glu::va::Float("a_position", 2, (int)positions.size(), 0, positions[0].getPtr());
158         glu::draw(renderCtx, program.getProgram(), 1, &posBinding,
159                   glu::pr::Triangles((int)indices.size(), &indices[0]));
160     }
161 
162     gl.disable(GL_STENCIL_TEST);
163 }
164 
renderTestPatternReference(const tcu::PixelBufferAccess & dst)165 static void renderTestPatternReference(const tcu::PixelBufferAccess &dst)
166 {
167     const int stencilBits =
168         tcu::getTextureFormatBitDepth(tcu::getEffectiveDepthStencilAccess(dst, tcu::Sampler::MODE_STENCIL).getFormat())
169             .x();
170     const uint32_t stencilMask = (1u << stencilBits) - 1u;
171     vector<IVec4> rects;
172 
173     DE_ASSERT(dst.getFormat().order == TextureFormat::S || dst.getFormat().order == TextureFormat::DS);
174 
175     // clear depth and stencil
176     if (dst.getFormat().order == TextureFormat::DS)
177         tcu::clearDepth(dst, 0.0f);
178     tcu::clearStencil(dst, 0u);
179 
180     genTestRects(rects, dst.getWidth(), dst.getHeight());
181 
182     for (vector<IVec4>::const_iterator rectIter = rects.begin(); rectIter != rects.end(); ++rectIter)
183     {
184         const int x0 = rectIter->x();
185         const int y0 = rectIter->y();
186         const int x1 = x0 + rectIter->z();
187         const int y1 = y0 + rectIter->w();
188 
189         for (int y = y0; y < y1; y++)
190         {
191             for (int x = x0; x < x1; x++)
192             {
193                 const int oldVal = dst.getPixStencil(x, y);
194                 const int newVal = (oldVal + 1) & stencilMask;
195 
196                 dst.setPixStencil(newVal, x, y);
197             }
198         }
199     }
200 }
201 
blitStencilToColor2D(const glu::RenderContext & renderCtx,uint32_t srcTex,int width,int height)202 static void blitStencilToColor2D(const glu::RenderContext &renderCtx, uint32_t srcTex, int width, int height)
203 {
204     const glu::ShaderProgram program(
205         renderCtx, glu::ProgramSources() << glu::VertexSource("#version 300 es\n"
206                                                               "in highp vec4 a_position;\n"
207                                                               "in highp vec2 a_texCoord;\n"
208                                                               "out highp vec2 v_texCoord;\n"
209                                                               "void main (void)\n"
210                                                               "{\n"
211                                                               "    gl_Position = a_position;\n"
212                                                               "    v_texCoord = a_texCoord;\n"
213                                                               "}\n")
214                                          << glu::FragmentSource("#version 300 es\n"
215                                                                 "uniform highp usampler2D u_sampler;\n"
216                                                                 "in highp vec2 v_texCoord;\n"
217                                                                 "layout(location = 0) out highp uint o_stencil;\n"
218                                                                 "void main (void)\n"
219                                                                 "{\n"
220                                                                 "    o_stencil = texture(u_sampler, v_texCoord).x;\n"
221                                                                 "}\n"));
222 
223     const float positions[]                      = {-1.0f, -1.0f, +1.0f, -1.0f, -1.0f, +1.0f, +1.0f, +1.0f};
224     const float texCoord[]                       = {0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f};
225     const glu::VertexArrayBinding vertexArrays[] = {glu::va::Float("a_position", 2, 4, 0, &positions[0]),
226                                                     glu::va::Float("a_texCoord", 2, 4, 0, &texCoord[0])};
227     const uint8_t indices[]                      = {0, 1, 2, 2, 1, 3};
228 
229     const glw::Functions &gl = renderCtx.getFunctions();
230 
231     if (!program.isOk())
232         throw tcu::TestError("Compile failed");
233 
234     gl.activeTexture(GL_TEXTURE0);
235     gl.bindTexture(GL_TEXTURE_2D, srcTex);
236     gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
237     gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
238     gl.texParameteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
239     GLU_EXPECT_NO_ERROR(gl.getError(), "Texture state setup failed");
240 
241     gl.useProgram(program.getProgram());
242     gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_sampler"), 0);
243     GLU_EXPECT_NO_ERROR(gl.getError(), "Program setup failed");
244 
245     gl.viewport(0, 0, width, height);
246     glu::draw(renderCtx, program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
247               glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
248 }
249 
blitStencilToColor2DArray(const glu::RenderContext & renderCtx,uint32_t srcTex,int width,int height,int level)250 static void blitStencilToColor2DArray(const glu::RenderContext &renderCtx, uint32_t srcTex, int width, int height,
251                                       int level)
252 {
253     const glu::ShaderProgram program(
254         renderCtx, glu::ProgramSources() << glu::VertexSource("#version 300 es\n"
255                                                               "in highp vec4 a_position;\n"
256                                                               "in highp vec3 a_texCoord;\n"
257                                                               "out highp vec3 v_texCoord;\n"
258                                                               "void main (void)\n"
259                                                               "{\n"
260                                                               "    gl_Position = a_position;\n"
261                                                               "    v_texCoord = a_texCoord;\n"
262                                                               "}\n")
263                                          << glu::FragmentSource("#version 300 es\n"
264                                                                 "uniform highp usampler2DArray u_sampler;\n"
265                                                                 "in highp vec3 v_texCoord;\n"
266                                                                 "layout(location = 0) out highp uint o_stencil;\n"
267                                                                 "void main (void)\n"
268                                                                 "{\n"
269                                                                 "    o_stencil = texture(u_sampler, v_texCoord).x;\n"
270                                                                 "}\n"));
271 
272     const float positions[]                      = {-1.0f, -1.0f, +1.0f, -1.0f, -1.0f, +1.0f, +1.0f, +1.0f};
273     const float texCoord[]                       = {0.0f, 0.0f, float(level), 1.0f, 0.0f, float(level),
274                                                     0.0f, 1.0f, float(level), 1.0f, 1.0f, float(level)};
275     const glu::VertexArrayBinding vertexArrays[] = {glu::va::Float("a_position", 2, 4, 0, &positions[0]),
276                                                     glu::va::Float("a_texCoord", 3, 4, 0, &texCoord[0])};
277     const uint8_t indices[]                      = {0, 1, 2, 2, 1, 3};
278 
279     const glw::Functions &gl = renderCtx.getFunctions();
280 
281     if (!program.isOk())
282         throw tcu::TestError("Compile failed");
283 
284     gl.activeTexture(GL_TEXTURE0);
285     gl.bindTexture(GL_TEXTURE_2D_ARRAY, srcTex);
286     gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
287     gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
288     gl.texParameteri(GL_TEXTURE_2D_ARRAY, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
289     GLU_EXPECT_NO_ERROR(gl.getError(), "Texture state setup failed");
290 
291     gl.useProgram(program.getProgram());
292     gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_sampler"), 0);
293     GLU_EXPECT_NO_ERROR(gl.getError(), "Program setup failed");
294 
295     gl.viewport(0, 0, width, height);
296     glu::draw(renderCtx, program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
297               glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
298 }
299 
blitStencilToColorCube(const glu::RenderContext & renderCtx,uint32_t srcTex,const float * texCoord,int width,int height)300 static void blitStencilToColorCube(const glu::RenderContext &renderCtx, uint32_t srcTex, const float *texCoord,
301                                    int width, int height)
302 {
303     const glu::ShaderProgram program(
304         renderCtx, glu::ProgramSources() << glu::VertexSource("#version 300 es\n"
305                                                               "in highp vec4 a_position;\n"
306                                                               "in highp vec3 a_texCoord;\n"
307                                                               "out highp vec3 v_texCoord;\n"
308                                                               "void main (void)\n"
309                                                               "{\n"
310                                                               "    gl_Position = a_position;\n"
311                                                               "    v_texCoord = a_texCoord;\n"
312                                                               "}\n")
313                                          << glu::FragmentSource(
314                                                 "#version 300 es\n"
315                                                 "uniform highp usamplerCube u_sampler;\n"
316                                                 "in highp vec3 v_texCoord;\n"
317                                                 "layout(location = 0) out highp vec4 o_color;\n"
318                                                 "void main (void)\n"
319                                                 "{\n"
320                                                 "    o_color.x = float(texture(u_sampler, v_texCoord).x) / 255.0;\n"
321                                                 "    o_color.yzw = vec3(0.0, 0.0, 1.0);\n"
322                                                 "}\n"));
323 
324     const float positions[]                      = {-1.0f, -1.0f, -1.0f, +1.0f, +1.0f, -1.0f, +1.0f, +1.0f};
325     const glu::VertexArrayBinding vertexArrays[] = {glu::va::Float("a_position", 2, 4, 0, &positions[0]),
326                                                     glu::va::Float("a_texCoord", 3, 4, 0, texCoord)};
327     const uint8_t indices[]                      = {0, 1, 2, 2, 1, 3};
328 
329     const glw::Functions &gl = renderCtx.getFunctions();
330 
331     if (!program.isOk())
332         throw tcu::TestError("Compile failed");
333 
334     gl.activeTexture(GL_TEXTURE0);
335     gl.bindTexture(GL_TEXTURE_CUBE_MAP, srcTex);
336     gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
337     gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
338     gl.texParameteri(GL_TEXTURE_CUBE_MAP, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
339     GLU_EXPECT_NO_ERROR(gl.getError(), "Texture state setup failed");
340 
341     gl.useProgram(program.getProgram());
342     gl.uniform1i(gl.getUniformLocation(program.getProgram(), "u_sampler"), 0);
343     GLU_EXPECT_NO_ERROR(gl.getError(), "Program setup failed");
344 
345     gl.viewport(0, 0, width, height);
346     glu::draw(renderCtx, program.getProgram(), DE_LENGTH_OF_ARRAY(vertexArrays), &vertexArrays[0],
347               glu::pr::Triangles(DE_LENGTH_OF_ARRAY(indices), &indices[0]));
348 }
349 
stencilToRedAccess(const tcu::ConstPixelBufferAccess & access)350 static inline tcu::ConstPixelBufferAccess stencilToRedAccess(const tcu::ConstPixelBufferAccess &access)
351 {
352     DE_ASSERT(access.getFormat() == TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8));
353     return tcu::ConstPixelBufferAccess(TextureFormat(TextureFormat::R, TextureFormat::UNSIGNED_INT8), access.getSize(),
354                                        access.getPitch(), access.getDataPtr());
355 }
356 
compareStencilToRed(tcu::TestLog & log,const tcu::ConstPixelBufferAccess & stencilRef,const tcu::ConstPixelBufferAccess & result)357 static bool compareStencilToRed(tcu::TestLog &log, const tcu::ConstPixelBufferAccess &stencilRef,
358                                 const tcu::ConstPixelBufferAccess &result)
359 {
360     const int maxPrints = 10;
361     int numFailed       = 0;
362 
363     DE_ASSERT(stencilRef.getFormat().order == TextureFormat::S);
364     DE_ASSERT(stencilRef.getWidth() == result.getWidth() && stencilRef.getHeight() == result.getHeight());
365 
366     for (int y = 0; y < stencilRef.getHeight(); y++)
367     {
368         for (int x = 0; x < stencilRef.getWidth(); x++)
369         {
370             const int ref = stencilRef.getPixStencil(x, y);
371             const int res = result.getPixelInt(x, y).x();
372 
373             if (ref != res)
374             {
375                 if (numFailed < maxPrints)
376                     log << TestLog::Message << "ERROR: Expected " << ref << ", got " << res << " at (" << x << ", " << y
377                         << ")" << TestLog::EndMessage;
378                 else if (numFailed == maxPrints)
379                     log << TestLog::Message << "..." << TestLog::EndMessage;
380 
381                 numFailed += 1;
382             }
383         }
384     }
385 
386     log << TestLog::Message << "Found " << numFailed << " faulty pixels, comparison "
387         << (numFailed == 0 ? "passed." : "FAILED!") << TestLog::EndMessage;
388 
389     log << TestLog::ImageSet("ComparisonResult", "Image comparison result")
390         << TestLog::Image("Result", "Result stencil buffer", result);
391 
392     if (numFailed > 0)
393         log << TestLog::Image("Reference", "Reference stencil buffer", stencilToRedAccess(stencilRef));
394 
395     log << TestLog::EndImageSet;
396 
397     return numFailed == 0;
398 }
399 
compareRedChannel(tcu::TestLog & log,const tcu::ConstPixelBufferAccess & result,int reference)400 static bool compareRedChannel(tcu::TestLog &log, const tcu::ConstPixelBufferAccess &result, int reference)
401 {
402     const int maxPrints = 10;
403     int numFailed       = 0;
404 
405     for (int y = 0; y < result.getHeight(); y++)
406     {
407         for (int x = 0; x < result.getWidth(); x++)
408         {
409             const int res = result.getPixelInt(x, y).x();
410 
411             if (reference != res)
412             {
413                 if (numFailed < maxPrints)
414                     log << TestLog::Message << "ERROR: Expected " << reference << ", got " << res << " at (" << x
415                         << ", " << y << ")" << TestLog::EndMessage;
416                 else if (numFailed == maxPrints)
417                     log << TestLog::Message << "..." << TestLog::EndMessage;
418 
419                 numFailed += 1;
420             }
421         }
422     }
423 
424     log << TestLog::Message << "Found " << numFailed << " faulty pixels, comparison "
425         << (numFailed == 0 ? "passed." : "FAILED!") << TestLog::EndMessage;
426 
427     log << TestLog::ImageSet("ComparisonResult", "Image comparison result")
428         << TestLog::Image("Result", "Result stencil buffer", result);
429 
430     log << TestLog::EndImageSet;
431 
432     return numFailed == 0;
433 }
434 
stencilToUnorm8(const tcu::TextureCube & src,tcu::TextureCube & dst)435 static void stencilToUnorm8(const tcu::TextureCube &src, tcu::TextureCube &dst)
436 {
437     for (int levelNdx = 0; levelNdx < src.getNumLevels(); levelNdx++)
438     {
439         for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
440         {
441             const tcu::CubeFace face = tcu::CubeFace(faceNdx);
442 
443             if (!src.isLevelEmpty(face, levelNdx))
444             {
445                 dst.allocLevel(face, levelNdx);
446 
447                 const tcu::ConstPixelBufferAccess srcLevel = src.getLevelFace(levelNdx, face);
448                 const tcu::PixelBufferAccess dstLevel      = dst.getLevelFace(levelNdx, face);
449 
450                 for (int y = 0; y < src.getSize(); y++)
451                     for (int x = 0; x < src.getSize(); x++)
452                         dstLevel.setPixel(Vec4(float(srcLevel.getPixStencil(x, y)) / 255.f, 0.f, 0.f, 1.f), x, y);
453             }
454         }
455     }
456 }
457 
checkDepthStencilFormatSupport(Context & context,uint32_t format)458 static void checkDepthStencilFormatSupport(Context &context, uint32_t format)
459 {
460     if (format == GL_STENCIL_INDEX8)
461     {
462         const char *reqExt           = "GL_OES_texture_stencil8";
463         glu::ContextType contextType = context.getRenderContext().getType();
464         if (!glu::contextSupports(contextType, glu::ApiType::es(3, 2)) &&
465             !glu::contextSupports(contextType, glu::ApiType::core(4, 5)) &&
466             !context.getContextInfo().isExtensionSupported(reqExt))
467             throw tcu::NotSupportedError(glu::getTextureFormatStr(format).toString() + " requires " + reqExt);
468     }
469     else
470     {
471         DE_ASSERT(format == GL_DEPTH32F_STENCIL8 || format == GL_DEPTH24_STENCIL8);
472     }
473 }
474 
checkFramebufferStatus(const glw::Functions & gl)475 static void checkFramebufferStatus(const glw::Functions &gl)
476 {
477     const uint32_t status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
478 
479     if (status == GL_FRAMEBUFFER_UNSUPPORTED)
480         throw tcu::NotSupportedError("Unsupported framebuffer configuration");
481     else if (status != GL_FRAMEBUFFER_COMPLETE)
482         throw tcu::TestError("Incomplete framebuffer: " + glu::getFramebufferStatusStr(status).toString());
483 }
484 
485 class UploadTex2DCase : public TestCase
486 {
487 public:
UploadTex2DCase(Context & context,const char * name,uint32_t format)488     UploadTex2DCase(Context &context, const char *name, uint32_t format)
489         : TestCase(context, name, glu::getTextureFormatName(format))
490         , m_format(format)
491     {
492     }
493 
iterate(void)494     IterateResult iterate(void)
495     {
496         const glu::RenderContext &renderCtx = m_context.getRenderContext();
497         const glw::Functions &gl            = renderCtx.getFunctions();
498         const int width                     = 129;
499         const int height                    = 113;
500         glu::Framebuffer fbo(renderCtx);
501         glu::Renderbuffer colorBuf(renderCtx);
502         glu::Texture depthStencilTex(renderCtx);
503         TextureLevel uploadLevel(glu::mapGLInternalFormat(m_format), width, height);
504         TextureLevel readLevel(TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), width, height);
505         TextureLevel stencilOnlyLevel(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), width, height);
506 
507         checkDepthStencilFormatSupport(m_context, m_format);
508 
509         renderTestPatternReference(uploadLevel);
510         renderTestPatternReference(stencilOnlyLevel);
511 
512         gl.bindTexture(GL_TEXTURE_2D, *depthStencilTex);
513         gl.texStorage2D(GL_TEXTURE_2D, 1, m_format, width, height);
514         glu::texSubImage2D(renderCtx, GL_TEXTURE_2D, 0, 0, 0, uploadLevel);
515         GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading texture data failed");
516 
517         gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
518         gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, width, height);
519 
520         gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
521         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
522         checkFramebufferStatus(gl);
523 
524         blitStencilToColor2D(renderCtx, *depthStencilTex, width, height);
525         glu::readPixels(renderCtx, 0, 0, readLevel);
526 
527         {
528             const bool compareOk = compareStencilToRed(m_testCtx.getLog(), stencilOnlyLevel, readLevel);
529             m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
530                                     compareOk ? "Pass" : "Image comparison failed");
531         }
532 
533         return STOP;
534     }
535 
536 private:
537     const uint32_t m_format;
538 };
539 
540 class UploadTex2DArrayCase : public TestCase
541 {
542 public:
UploadTex2DArrayCase(Context & context,const char * name,uint32_t format)543     UploadTex2DArrayCase(Context &context, const char *name, uint32_t format)
544         : TestCase(context, name, glu::getTextureFormatName(format))
545         , m_format(format)
546     {
547     }
548 
iterate(void)549     IterateResult iterate(void)
550     {
551         const glu::RenderContext &renderCtx = m_context.getRenderContext();
552         const glw::Functions &gl            = renderCtx.getFunctions();
553         const int width                     = 41;
554         const int height                    = 13;
555         const int levels                    = 7;
556         const int ptrnLevel                 = 3;
557         glu::Framebuffer fbo(renderCtx);
558         glu::Renderbuffer colorBuf(renderCtx);
559         glu::Texture depthStencilTex(renderCtx);
560         TextureLevel uploadLevel(glu::mapGLInternalFormat(m_format), width, height, levels);
561 
562         checkDepthStencilFormatSupport(m_context, m_format);
563 
564         for (int levelNdx = 0; levelNdx < levels; levelNdx++)
565         {
566             const tcu::PixelBufferAccess levelAccess =
567                 tcu::getSubregion(uploadLevel.getAccess(), 0, 0, levelNdx, width, height, 1);
568 
569             if (levelNdx == ptrnLevel)
570                 renderTestPatternReference(levelAccess);
571             else
572                 tcu::clearStencil(levelAccess, levelNdx);
573         }
574 
575         gl.bindTexture(GL_TEXTURE_2D_ARRAY, *depthStencilTex);
576         gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1, m_format, width, height, levels);
577         glu::texSubImage3D(renderCtx, GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, uploadLevel);
578         GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading texture data failed");
579 
580         gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
581         gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, width, height);
582 
583         gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
584         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
585         checkFramebufferStatus(gl);
586 
587         {
588             TextureLevel readLevel(TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), width, height);
589             bool allLevelsOk = true;
590 
591             for (int levelNdx = 0; levelNdx < levels; levelNdx++)
592             {
593                 tcu::ScopedLogSection section(m_testCtx.getLog(), "Level" + de::toString(levelNdx),
594                                               "Level " + de::toString(levelNdx));
595                 bool levelOk;
596 
597                 blitStencilToColor2DArray(renderCtx, *depthStencilTex, width, height, levelNdx);
598                 glu::readPixels(renderCtx, 0, 0, readLevel);
599 
600                 if (levelNdx == ptrnLevel)
601                 {
602                     TextureLevel reference(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), width,
603                                            height);
604                     renderTestPatternReference(reference);
605 
606                     levelOk = compareStencilToRed(m_testCtx.getLog(), reference, readLevel);
607                 }
608                 else
609                     levelOk = compareRedChannel(m_testCtx.getLog(), readLevel, levelNdx);
610 
611                 if (!levelOk)
612                 {
613                     allLevelsOk = false;
614                     break;
615                 }
616             }
617 
618             m_testCtx.setTestResult(allLevelsOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
619                                     allLevelsOk ? "Pass" : "Image comparison failed");
620         }
621 
622         return STOP;
623     }
624 
625 private:
626     const uint32_t m_format;
627 };
628 
629 class UploadTexCubeCase : public TestCase
630 {
631 public:
UploadTexCubeCase(Context & context,const char * name,uint32_t format)632     UploadTexCubeCase(Context &context, const char *name, uint32_t format)
633         : TestCase(context, name, glu::getTextureFormatName(format))
634         , m_format(format)
635     {
636     }
637 
iterate(void)638     IterateResult iterate(void)
639     {
640         const glu::RenderContext &renderCtx = m_context.getRenderContext();
641         const glw::Functions &gl            = renderCtx.getFunctions();
642         const int size                      = 64;
643         const int renderWidth               = 128;
644         const int renderHeight              = 128;
645         vector<float> texCoord;
646         glu::Framebuffer fbo(renderCtx);
647         glu::Renderbuffer colorBuf(renderCtx);
648         glu::Texture depthStencilTex(renderCtx);
649         tcu::TextureCube texData(glu::mapGLInternalFormat(m_format), size);
650         tcu::TextureLevel result(TextureFormat(TextureFormat::RGBA, TextureFormat::UNORM_INT8), renderWidth,
651                                  renderHeight);
652 
653         checkDepthStencilFormatSupport(m_context, m_format);
654 
655         for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
656         {
657             const tcu::CubeFace face = tcu::CubeFace(faceNdx);
658             const int stencilVal     = 42 * faceNdx;
659 
660             texData.allocLevel(face, 0);
661             tcu::clearStencil(texData.getLevelFace(0, face), stencilVal);
662         }
663 
664         glu::TextureTestUtil::computeQuadTexCoordCube(texCoord, tcu::CUBEFACE_NEGATIVE_X, Vec2(-1.5f, -1.3f),
665                                                       Vec2(1.3f, 1.4f));
666 
667         gl.bindTexture(GL_TEXTURE_CUBE_MAP, *depthStencilTex);
668         gl.texStorage2D(GL_TEXTURE_CUBE_MAP, 1, m_format, size, size);
669 
670         for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; faceNdx++)
671             glu::texSubImage2D(renderCtx, glu::getGLCubeFace(tcu::CubeFace(faceNdx)), 0, 0, 0,
672                                texData.getLevelFace(0, tcu::CubeFace(faceNdx)));
673 
674         GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading texture data failed");
675 
676         gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
677         gl.renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, renderWidth, renderHeight);
678 
679         gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
680         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
681         checkFramebufferStatus(gl);
682 
683         blitStencilToColorCube(renderCtx, *depthStencilTex, &texCoord[0], renderWidth, renderHeight);
684         glu::readPixels(renderCtx, 0, 0, result);
685 
686         {
687             using namespace glu::TextureTestUtil;
688 
689             tcu::TextureCube redTex(TextureFormat(TextureFormat::R, TextureFormat::UNORM_INT8), size);
690             const ReferenceParams sampleParams(TEXTURETYPE_CUBE,
691                                                tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
692                                                             tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST,
693                                                             tcu::Sampler::NEAREST));
694             tcu::LookupPrecision lookupPrec;
695             tcu::LodPrecision lodPrec;
696             bool compareOk;
697 
698             lookupPrec.colorMask      = tcu::BVec4(true, true, true, true);
699             lookupPrec.colorThreshold = tcu::computeFixedPointThreshold(IVec4(8, 8, 8, 8));
700             lookupPrec.coordBits      = tcu::IVec3(22, 22, 22);
701             lookupPrec.uvwBits        = tcu::IVec3(5, 5, 0);
702             lodPrec.lodBits           = 7;
703             lodPrec.derivateBits      = 16;
704 
705             stencilToUnorm8(texData, redTex);
706 
707             compareOk = verifyTextureResult(m_testCtx, result, redTex, &texCoord[0], sampleParams, lookupPrec, lodPrec,
708                                             tcu::PixelFormat(8, 8, 8, 8));
709 
710             m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
711                                     compareOk ? "Pass" : "Image comparison failed");
712         }
713 
714         return STOP;
715     }
716 
717 private:
718     const uint32_t m_format;
719 };
720 
721 class RenderTex2DCase : public TestCase
722 {
723 public:
RenderTex2DCase(Context & context,const char * name,uint32_t format)724     RenderTex2DCase(Context &context, const char *name, uint32_t format)
725         : TestCase(context, name, glu::getTextureFormatName(format))
726         , m_format(format)
727     {
728     }
729 
iterate(void)730     IterateResult iterate(void)
731     {
732         const glu::RenderContext &renderCtx = m_context.getRenderContext();
733         const glw::Functions &gl            = renderCtx.getFunctions();
734         const int width                     = 117;
735         const int height                    = 193;
736         glu::Framebuffer fbo(renderCtx);
737         glu::Renderbuffer colorBuf(renderCtx);
738         glu::Texture depthStencilTex(renderCtx);
739         TextureLevel result(TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), width, height);
740         TextureLevel reference(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), width, height);
741 
742         checkDepthStencilFormatSupport(m_context, m_format);
743 
744         gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
745         gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, width, height);
746 
747         gl.bindTexture(GL_TEXTURE_2D, *depthStencilTex);
748         gl.texStorage2D(GL_TEXTURE_2D, 1, m_format, width, height);
749 
750         gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
751         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
752         gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, *depthStencilTex, 0);
753         checkFramebufferStatus(gl);
754 
755         drawTestPattern(renderCtx, width, height);
756 
757         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
758         checkFramebufferStatus(gl);
759 
760         blitStencilToColor2D(renderCtx, *depthStencilTex, width, height);
761         glu::readPixels(renderCtx, 0, 0, result.getAccess());
762 
763         renderTestPatternReference(reference);
764 
765         {
766             const bool compareOk = compareStencilToRed(m_testCtx.getLog(), reference, result);
767             m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
768                                     compareOk ? "Pass" : "Image comparison failed");
769         }
770 
771         return STOP;
772     }
773 
774 private:
775     const uint32_t m_format;
776 };
777 
778 class ClearTex2DCase : public TestCase
779 {
780 public:
ClearTex2DCase(Context & context,const char * name,uint32_t format)781     ClearTex2DCase(Context &context, const char *name, uint32_t format)
782         : TestCase(context, name, glu::getTextureFormatName(format))
783         , m_format(format)
784     {
785     }
786 
iterate(void)787     IterateResult iterate(void)
788     {
789         const glu::RenderContext &renderCtx = m_context.getRenderContext();
790         const glw::Functions &gl            = renderCtx.getFunctions();
791         const int width                     = 125;
792         const int height                    = 117;
793         const int cellSize                  = 8;
794         glu::Framebuffer fbo(renderCtx);
795         glu::Renderbuffer colorBuf(renderCtx);
796         glu::Texture depthStencilTex(renderCtx);
797         TextureLevel result(TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), width, height);
798         TextureLevel reference(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), width, height);
799 
800         checkDepthStencilFormatSupport(m_context, m_format);
801 
802         gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
803         gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, width, height);
804 
805         gl.bindTexture(GL_TEXTURE_2D, *depthStencilTex);
806         gl.texStorage2D(GL_TEXTURE_2D, 1, m_format, width, height);
807 
808         gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
809         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
810         gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, *depthStencilTex, 0);
811         checkFramebufferStatus(gl);
812 
813         gl.enable(GL_SCISSOR_TEST);
814 
815         for (int y = 0; y < height; y += cellSize)
816         {
817             for (int x = 0; x < width; x += cellSize)
818             {
819                 const int clearW  = de::min(cellSize, width - x);
820                 const int clearH  = de::min(cellSize, height - y);
821                 const int stencil = int((deInt32Hash(x) ^ deInt32Hash(y)) & 0xff);
822 
823                 gl.clearStencil(stencil);
824                 gl.scissor(x, y, clearW, clearH);
825                 gl.clear(GL_STENCIL_BUFFER_BIT);
826 
827                 tcu::clearStencil(tcu::getSubregion(reference.getAccess(), x, y, clearW, clearH), stencil);
828             }
829         }
830 
831         gl.disable(GL_SCISSOR_TEST);
832 
833         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0);
834         checkFramebufferStatus(gl);
835 
836         blitStencilToColor2D(renderCtx, *depthStencilTex, width, height);
837         glu::readPixels(renderCtx, 0, 0, result.getAccess());
838 
839         {
840             const bool compareOk = compareStencilToRed(m_testCtx.getLog(), reference, result);
841             m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
842                                     compareOk ? "Pass" : "Image comparison failed");
843         }
844 
845         return STOP;
846     }
847 
848 private:
849     const uint32_t m_format;
850 };
851 
852 class CompareModeCase : public TestCase
853 {
854 public:
CompareModeCase(Context & context,const char * name,uint32_t format)855     CompareModeCase(Context &context, const char *name, uint32_t format)
856         : TestCase(context, name, glu::getTextureFormatName(format))
857         , m_format(format)
858     {
859     }
860 
iterate(void)861     IterateResult iterate(void)
862     {
863         const glu::RenderContext &renderCtx = m_context.getRenderContext();
864         const glw::Functions &gl            = renderCtx.getFunctions();
865         const int width                     = 64;
866         const int height                    = 64;
867         glu::Framebuffer fbo(renderCtx);
868         glu::Renderbuffer colorBuf(renderCtx);
869         glu::Texture depthStencilTex(renderCtx);
870         TextureLevel uploadLevel(glu::mapGLInternalFormat(m_format), width, height);
871         TextureLevel readLevel(TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), width, height);
872         TextureLevel stencilOnlyLevel(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), width, height);
873 
874         checkDepthStencilFormatSupport(m_context, m_format);
875 
876         m_testCtx.getLog() << TestLog::Message
877                            << "NOTE: Texture compare mode has no effect when reading stencil values."
878                            << TestLog::EndMessage;
879 
880         renderTestPatternReference(uploadLevel);
881         renderTestPatternReference(stencilOnlyLevel);
882 
883         gl.bindTexture(GL_TEXTURE_2D, *depthStencilTex);
884         gl.texStorage2D(GL_TEXTURE_2D, 1, m_format, width, height);
885         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
886         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
887         glu::texSubImage2D(renderCtx, GL_TEXTURE_2D, 0, 0, 0, uploadLevel);
888         GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading texture data failed");
889 
890         gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
891         gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, width, height);
892 
893         gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
894         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
895         checkFramebufferStatus(gl);
896 
897         blitStencilToColor2D(renderCtx, *depthStencilTex, width, height);
898         glu::readPixels(renderCtx, 0, 0, readLevel);
899 
900         {
901             const bool compareOk = compareStencilToRed(m_testCtx.getLog(), stencilOnlyLevel, readLevel);
902             m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
903                                     compareOk ? "Pass" : "Image comparison failed");
904         }
905 
906         return STOP;
907     }
908 
909 private:
910     const uint32_t m_format;
911 };
912 
913 class BaseLevelCase : public TestCase
914 {
915 public:
BaseLevelCase(Context & context,const char * name,uint32_t format)916     BaseLevelCase(Context &context, const char *name, uint32_t format)
917         : TestCase(context, name, glu::getTextureFormatName(format))
918         , m_format(format)
919     {
920     }
921 
iterate(void)922     IterateResult iterate(void)
923     {
924         const glu::RenderContext &renderCtx = m_context.getRenderContext();
925         const glw::Functions &gl            = renderCtx.getFunctions();
926         const int width                     = 128;
927         const int height                    = 128;
928         const int levelNdx                  = 2;
929         const int levelWidth                = width >> levelNdx;
930         const int levelHeight               = height >> levelNdx;
931         glu::Framebuffer fbo(renderCtx);
932         glu::Renderbuffer colorBuf(renderCtx);
933         glu::Texture depthStencilTex(renderCtx);
934         TextureLevel uploadLevel(glu::mapGLInternalFormat(m_format), levelWidth, levelHeight);
935         TextureLevel readLevel(TextureFormat(TextureFormat::RGBA, TextureFormat::UNSIGNED_INT32), levelWidth,
936                                levelHeight);
937         TextureLevel stencilOnlyLevel(TextureFormat(TextureFormat::S, TextureFormat::UNSIGNED_INT8), levelWidth,
938                                       levelHeight);
939 
940         checkDepthStencilFormatSupport(m_context, m_format);
941 
942         m_testCtx.getLog() << TestLog::Message << "GL_TEXTURE_BASE_LEVEL = " << levelNdx << TestLog::EndMessage;
943 
944         renderTestPatternReference(uploadLevel);
945         renderTestPatternReference(stencilOnlyLevel);
946 
947         gl.bindTexture(GL_TEXTURE_2D, *depthStencilTex);
948         gl.texStorage2D(GL_TEXTURE_2D, deLog2Floor32(de::max(width, height)) + 1, m_format, width, height);
949         gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, levelNdx);
950         glu::texSubImage2D(renderCtx, GL_TEXTURE_2D, levelNdx, 0, 0, uploadLevel);
951         GLU_EXPECT_NO_ERROR(gl.getError(), "Uploading texture data failed");
952 
953         gl.bindRenderbuffer(GL_RENDERBUFFER, *colorBuf);
954         gl.renderbufferStorage(GL_RENDERBUFFER, GL_R32UI, levelWidth, levelHeight);
955 
956         gl.bindFramebuffer(GL_FRAMEBUFFER, *fbo);
957         gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *colorBuf);
958         checkFramebufferStatus(gl);
959 
960         blitStencilToColor2D(renderCtx, *depthStencilTex, levelWidth, levelHeight);
961         glu::readPixels(renderCtx, 0, 0, readLevel);
962 
963         {
964             const bool compareOk = compareStencilToRed(m_testCtx.getLog(), stencilOnlyLevel, readLevel);
965             m_testCtx.setTestResult(compareOk ? QP_TEST_RESULT_PASS : QP_TEST_RESULT_FAIL,
966                                     compareOk ? "Pass" : "Image comparison failed");
967         }
968 
969         return STOP;
970     }
971 
972 private:
973     const uint32_t m_format;
974 };
975 
976 } // namespace
977 
StencilTexturingTests(Context & context)978 StencilTexturingTests::StencilTexturingTests(Context &context)
979     : TestCaseGroup(context, "stencil_texturing", "Stencil texturing tests")
980 {
981 }
982 
~StencilTexturingTests(void)983 StencilTexturingTests::~StencilTexturingTests(void)
984 {
985 }
986 
init(void)987 void StencilTexturingTests::init(void)
988 {
989     // .format
990     {
991         tcu::TestCaseGroup *const formatGroup = new tcu::TestCaseGroup(m_testCtx, "format", "Formats");
992         addChild(formatGroup);
993 
994         formatGroup->addChild(new UploadTex2DCase(m_context, "depth32f_stencil8_2d", GL_DEPTH32F_STENCIL8));
995         formatGroup->addChild(new UploadTex2DArrayCase(m_context, "depth32f_stencil8_2d_array", GL_DEPTH32F_STENCIL8));
996         formatGroup->addChild(new UploadTexCubeCase(m_context, "depth32f_stencil8_cube", GL_DEPTH32F_STENCIL8));
997         formatGroup->addChild(new UploadTex2DCase(m_context, "depth24_stencil8_2d", GL_DEPTH24_STENCIL8));
998         formatGroup->addChild(new UploadTex2DArrayCase(m_context, "depth24_stencil8_2d_array", GL_DEPTH24_STENCIL8));
999         formatGroup->addChild(new UploadTexCubeCase(m_context, "depth24_stencil8_cube", GL_DEPTH24_STENCIL8));
1000 
1001         // OES_texture_stencil8
1002         formatGroup->addChild(new UploadTex2DCase(m_context, "stencil_index8_2d", GL_STENCIL_INDEX8));
1003         formatGroup->addChild(new UploadTex2DArrayCase(m_context, "stencil_index8_2d_array", GL_STENCIL_INDEX8));
1004         formatGroup->addChild(new UploadTexCubeCase(m_context, "stencil_index8_cube", GL_STENCIL_INDEX8));
1005     }
1006 
1007     // .render
1008     {
1009         tcu::TestCaseGroup *const readRenderGroup =
1010             new tcu::TestCaseGroup(m_testCtx, "render", "Read rendered stencil values");
1011         addChild(readRenderGroup);
1012 
1013         readRenderGroup->addChild(new ClearTex2DCase(m_context, "depth32f_stencil8_clear", GL_DEPTH32F_STENCIL8));
1014         readRenderGroup->addChild(new RenderTex2DCase(m_context, "depth32f_stencil8_draw", GL_DEPTH32F_STENCIL8));
1015         readRenderGroup->addChild(new ClearTex2DCase(m_context, "depth24_stencil8_clear", GL_DEPTH24_STENCIL8));
1016         readRenderGroup->addChild(new RenderTex2DCase(m_context, "depth24_stencil8_draw", GL_DEPTH24_STENCIL8));
1017     }
1018 
1019     // .misc
1020     {
1021         tcu::TestCaseGroup *const miscGroup = new tcu::TestCaseGroup(m_testCtx, "misc", "Misc cases");
1022         addChild(miscGroup);
1023 
1024         miscGroup->addChild(new CompareModeCase(m_context, "compare_mode_effect", GL_DEPTH24_STENCIL8));
1025         miscGroup->addChild(new BaseLevelCase(m_context, "base_level", GL_DEPTH24_STENCIL8));
1026     }
1027 }
1028 
1029 } // namespace Functional
1030 } // namespace gles31
1031 } // namespace deqp
1032