xref: /aosp_15_r20/external/angle/src/tests/gl_tests/DepthStencilFormatsTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 #include "test_utils/ANGLETest.h"
8 #include "test_utils/gl_raii.h"
9 
10 #include "common/mathutil.h"
11 #include "platform/autogen/FeaturesD3D_autogen.h"
12 
13 using namespace angle;
14 
15 struct ReadbackTestParam
16 {
17     GLuint attachment;
18     GLuint format;
19     GLuint type;
20     void *data;
21     int depthBits;
22     int stencilBits;
23 };
24 
25 class DepthStencilFormatsTestBase : public ANGLETest<>
26 {
27   protected:
DepthStencilFormatsTestBase()28     DepthStencilFormatsTestBase()
29     {
30         setWindowWidth(128);
31         setWindowHeight(128);
32         setConfigRedBits(8);
33         setConfigGreenBits(8);
34         setConfigBlueBits(8);
35         setConfigAlphaBits(8);
36     }
37 
checkTexImageFormatSupport(GLenum format,GLenum type)38     bool checkTexImageFormatSupport(GLenum format, GLenum type)
39     {
40         EXPECT_GL_NO_ERROR();
41 
42         GLuint tex = 0;
43         glGenTextures(1, &tex);
44         glBindTexture(GL_TEXTURE_2D, tex);
45         glTexImage2D(GL_TEXTURE_2D, 0, format, 1, 1, 0, format, type, nullptr);
46         glDeleteTextures(1, &tex);
47 
48         return (glGetError() == GL_NO_ERROR);
49     }
50 
checkTexStorageFormatSupport(GLenum internalFormat)51     bool checkTexStorageFormatSupport(GLenum internalFormat)
52     {
53         EXPECT_GL_NO_ERROR();
54 
55         GLuint tex = 0;
56         glGenTextures(1, &tex);
57         glBindTexture(GL_TEXTURE_2D, tex);
58         glTexStorage2DEXT(GL_TEXTURE_2D, 1, internalFormat, 1, 1);
59         glDeleteTextures(1, &tex);
60 
61         return (glGetError() == GL_NO_ERROR);
62     }
63 
checkRenderbufferFormatSupport(GLenum internalFormat)64     bool checkRenderbufferFormatSupport(GLenum internalFormat)
65     {
66         EXPECT_GL_NO_ERROR();
67 
68         GLuint rb = 0;
69         glGenRenderbuffers(1, &rb);
70         glBindRenderbuffer(GL_RENDERBUFFER, rb);
71         glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, 1, 1);
72         glDeleteRenderbuffers(1, &rb);
73 
74         return (glGetError() == GL_NO_ERROR);
75     }
76 
verifyDepthRenderBuffer(GLenum internalFormat)77     void verifyDepthRenderBuffer(GLenum internalFormat)
78     {
79         GLTexture tex;
80         glBindTexture(GL_TEXTURE_2D, tex);
81         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
82         ASSERT_GL_NO_ERROR();
83 
84         GLRenderbuffer rbDepth;
85         glBindRenderbuffer(GL_RENDERBUFFER, rbDepth);
86         glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, 1, 1);
87         ASSERT_GL_NO_ERROR();
88 
89         GLFramebuffer fbo;
90         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
91         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
92         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbDepth);
93 
94         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
95         ASSERT_GL_NO_ERROR();
96 
97         ANGLE_GL_PROGRAM(programRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
98         glEnable(GL_DEPTH_TEST);
99         glDepthFunc(GL_GEQUAL);
100         glClearDepthf(0.99f);
101         glClearColor(0, 0, 0, 1);
102         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
103 
104         // Pass Depth Test and draw red
105         float depthValue = 1.0f;
106         drawQuad(programRed, essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
107         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
108 
109         ASSERT_GL_NO_ERROR();
110 
111         ANGLE_GL_PROGRAM(programGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
112 
113         // Fail Depth Test and color buffer is unchanged
114         depthValue = 0.98f;
115         drawQuad(programGreen, essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
116         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
117 
118         ASSERT_GL_NO_ERROR();
119 
120         ANGLE_GL_PROGRAM(programBlue, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
121         glClearDepthf(0.0f);
122         glClear(GL_DEPTH_BUFFER_BIT);
123 
124         // Pass Depth Test and draw blue
125         depthValue = 0.01f;
126         drawQuad(programBlue, essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
127         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
128 
129         glDisable(GL_DEPTH_TEST);
130         ASSERT_GL_NO_ERROR();
131     }
132 
testSetUp()133     void testSetUp() override
134     {
135         constexpr char kVS[] = R"(precision highp float;
136 attribute vec4 position;
137 varying vec2 texcoord;
138 
139 void main()
140 {
141     gl_Position = position;
142     texcoord = (position.xy * 0.5) + 0.5;
143 })";
144 
145         constexpr char kFS[] = R"(precision highp float;
146 uniform sampler2D tex;
147 varying vec2 texcoord;
148 
149 void main()
150 {
151     gl_FragColor = texture2D(tex, texcoord);
152 })";
153 
154         mProgram = CompileProgram(kVS, kFS);
155         if (mProgram == 0)
156         {
157             FAIL() << "shader compilation failed.";
158         }
159 
160         mTextureUniformLocation = glGetUniformLocation(mProgram, "tex");
161         EXPECT_NE(-1, mTextureUniformLocation);
162 
163         glGenTextures(1, &mTexture);
164         ASSERT_GL_NO_ERROR();
165     }
166 
testTearDown()167     void testTearDown() override
168     {
169         glDeleteProgram(mProgram);
170         glDeleteTextures(1, &mTexture);
171     }
172 
hasReadDepthSupport() const173     bool hasReadDepthSupport() const { return IsGLExtensionEnabled("GL_NV_read_depth"); }
174 
hasReadDepthStencilSupport() const175     bool hasReadDepthStencilSupport() const
176     {
177         return IsGLExtensionEnabled("GL_NV_read_depth_stencil");
178     }
179 
hasReadStencilSupport() const180     bool hasReadStencilSupport() const { return IsGLExtensionEnabled("GL_NV_read_stencil"); }
181 
hasFloatDepthSupport() const182     bool hasFloatDepthSupport() const { return IsGLExtensionEnabled("GL_NV_depth_buffer_float2"); }
183 
184     void depthStencilReadbackCase(const ReadbackTestParam &type);
185 
186     GLuint mProgram;
187     GLuint mTexture;
188     GLint mTextureUniformLocation;
189 };
190 
191 class DepthStencilFormatsTest : public DepthStencilFormatsTestBase
192 {};
193 
194 class DepthStencilFormatsTestES3 : public DepthStencilFormatsTestBase
195 {};
196 
TEST_P(DepthStencilFormatsTest,DepthTexture)197 TEST_P(DepthStencilFormatsTest, DepthTexture)
198 {
199     bool shouldHaveTextureSupport = (IsGLExtensionEnabled("GL_ANGLE_depth_texture") ||
200                                      IsGLExtensionEnabled("GL_OES_depth_texture"));
201 
202     EXPECT_EQ(shouldHaveTextureSupport,
203               checkTexImageFormatSupport(GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT));
204     EXPECT_EQ(shouldHaveTextureSupport,
205               checkTexImageFormatSupport(GL_DEPTH_COMPONENT, GL_UNSIGNED_INT));
206 
207     if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
208     {
209         EXPECT_EQ(shouldHaveTextureSupport, checkTexStorageFormatSupport(GL_DEPTH_COMPONENT16));
210         EXPECT_EQ(shouldHaveTextureSupport, checkTexStorageFormatSupport(GL_DEPTH_COMPONENT32_OES));
211     }
212 }
213 
TEST_P(DepthStencilFormatsTest,PackedDepthStencil)214 TEST_P(DepthStencilFormatsTest, PackedDepthStencil)
215 {
216     // Expected to fail in D3D9 if GL_OES_packed_depth_stencil is not present.
217     // Expected to fail in D3D11 if GL_OES_packed_depth_stencil or GL_ANGLE_depth_texture is not
218     // present.
219 
220     bool shouldHaveRenderbufferSupport = IsGLExtensionEnabled("GL_OES_packed_depth_stencil");
221     EXPECT_EQ(shouldHaveRenderbufferSupport,
222               checkRenderbufferFormatSupport(GL_DEPTH24_STENCIL8_OES));
223 
224     bool shouldHaveTextureSupport = ((IsGLExtensionEnabled("GL_OES_packed_depth_stencil") ||
225                                       IsGLExtensionEnabled("GL_OES_depth_texture_cube_map")) &&
226                                      IsGLExtensionEnabled("GL_OES_depth_texture")) ||
227                                     IsGLExtensionEnabled("GL_ANGLE_depth_texture");
228     EXPECT_EQ(shouldHaveTextureSupport,
229               checkTexImageFormatSupport(GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES));
230 
231     if (IsGLExtensionEnabled("GL_EXT_texture_storage"))
232     {
233         bool shouldHaveTexStorageSupport = IsGLExtensionEnabled("GL_OES_packed_depth_stencil") ||
234                                            IsGLExtensionEnabled("GL_ANGLE_depth_texture");
235         EXPECT_EQ(shouldHaveTexStorageSupport,
236                   checkTexStorageFormatSupport(GL_DEPTH24_STENCIL8_OES));
237     }
238 }
239 
depthStencilReadbackCase(const ReadbackTestParam & type)240 void DepthStencilFormatsTestBase::depthStencilReadbackCase(const ReadbackTestParam &type)
241 {
242     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_depth_texture"));
243 
244     const bool hasFloatDepth = (type.type == GL_FLOAT);
245     ANGLE_SKIP_TEST_IF(hasFloatDepth && !hasFloatDepthSupport());
246 
247     const bool hasStencil = (type.format != GL_DEPTH_COMPONENT);
248 
249     const bool supportPackedDepthStencilFramebuffer = getClientMajorVersion() >= 3;
250 
251     const int res     = 2;
252     const int destRes = 4;
253 
254     GLTexture tex;
255     glBindTexture(GL_TEXTURE_2D, tex);
256     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
257     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
258     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
259     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
260 
261     // test level > 0
262     glTexImage2D(GL_TEXTURE_2D, 1, type.format, 1, 1, 0, type.format, type.type, nullptr);
263     EXPECT_GL_NO_ERROR();
264 
265     // test with data
266     glTexImage2D(GL_TEXTURE_2D, 0, type.format, 1, 1, 0, type.format, type.type, type.data);
267     EXPECT_GL_NO_ERROR();
268 
269     // test real thing
270     glTexImage2D(GL_TEXTURE_2D, 0, type.format, res, res, 0, type.format, type.type, nullptr);
271     EXPECT_GL_NO_ERROR();
272 
273     // test texSubImage2D
274     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, type.format, type.type, type.data);
275     EXPECT_GL_NO_ERROR();
276 
277     GLuint fbo = 0;
278     glGenFramebuffers(1, &fbo);
279     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
280     if (type.depthBits > 0 && type.stencilBits > 0 && !supportPackedDepthStencilFramebuffer)
281     {
282         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex, 0);
283         EXPECT_GL_NO_ERROR();
284         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, tex, 0);
285         EXPECT_GL_NO_ERROR();
286     }
287     else
288     {
289         glFramebufferTexture2D(GL_FRAMEBUFFER, type.attachment, GL_TEXTURE_2D, tex, 0);
290         EXPECT_GL_NO_ERROR();
291     }
292 
293     // Ensure DEPTH_BITS returns >= 16 bits for UNSIGNED_SHORT and UNSIGNED_INT, >= 24
294     // UNSIGNED_INT_24_8_WEBGL. If there is stencil, ensure STENCIL_BITS reports >= 8 for
295     // UNSIGNED_INT_24_8_WEBGL.
296 
297     GLint depthBits = 0;
298     glGetIntegerv(GL_DEPTH_BITS, &depthBits);
299     EXPECT_GE(depthBits, type.depthBits);
300 
301     GLint stencilBits = 0;
302     glGetIntegerv(GL_STENCIL_BITS, &stencilBits);
303     EXPECT_GE(stencilBits, type.stencilBits);
304 
305     // TODO: remove this check if the spec is updated to require these combinations to work.
306     if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
307     {
308         // try adding a color buffer.
309         GLuint colorTex = 0;
310         glGenTextures(1, &colorTex);
311         glBindTexture(GL_TEXTURE_2D, colorTex);
312         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
313         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
314         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
315         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
316         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, res, res, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
317         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
318         EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
319     }
320 
321     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
322 
323     // use the default texture to render with while we return to the depth texture.
324     glBindTexture(GL_TEXTURE_2D, 0);
325 
326     /* Setup 2x2 depth texture:
327      * 1 0.6 0.8
328      * |
329      * 0 0.2 0.4
330      *    0---1
331      */
332     GLbitfield clearBits = GL_DEPTH_BUFFER_BIT;
333     if (hasStencil)
334     {
335         clearBits |= GL_STENCIL_BUFFER_BIT;
336     }
337 
338     const GLfloat d00 = 0.2;
339     const GLfloat d01 = 0.4;
340     const GLfloat d10 = 0.6;
341     const GLfloat d11 = 0.8;
342     glEnable(GL_SCISSOR_TEST);
343     glScissor(0, 0, 1, 1);
344     glClearDepthf(d00);
345     glClearStencil(1);
346     glClear(clearBits);
347     glScissor(1, 0, 1, 1);
348     glClearDepthf(d10);
349     glClearStencil(2);
350     glClear(clearBits);
351     glScissor(0, 1, 1, 1);
352     glClearDepthf(d01);
353     glClearStencil(3);
354     glClear(clearBits);
355     glScissor(1, 1, 1, 1);
356     glClearDepthf(d11);
357     glClearStencil(4);
358     glClear(clearBits);
359     glDisable(GL_SCISSOR_TEST);
360 
361     GLubyte actualPixels[destRes * destRes * 8];
362     glReadPixels(0, 0, destRes, destRes, GL_DEPTH_COMPONENT,
363                  hasFloatDepth ? GL_FLOAT : GL_UNSIGNED_SHORT, actualPixels);
364     if (hasReadDepthSupport())
365     {
366         EXPECT_GL_NO_ERROR();
367         if (hasFloatDepth)
368         {
369             constexpr float kEpsilon = 0.002f;
370             const float *pixels      = reinterpret_cast<const float *>(actualPixels);
371             ASSERT_NEAR(pixels[0], d00, kEpsilon);
372             ASSERT_NEAR(pixels[0 + destRes], d01, kEpsilon);
373             ASSERT_NEAR(pixels[1], d10, kEpsilon);
374             ASSERT_NEAR(pixels[1 + destRes], d11, kEpsilon);
375         }
376         else
377         {
378             constexpr unsigned short kEpsilon = 2;
379             const unsigned short *pixels = reinterpret_cast<const unsigned short *>(actualPixels);
380             ASSERT_NEAR(pixels[0], gl::unorm<16>(d00), kEpsilon);
381             ASSERT_NEAR(pixels[0 + destRes], gl::unorm<16>(d01), kEpsilon);
382             ASSERT_NEAR(pixels[1], gl::unorm<16>(d10), kEpsilon);
383             ASSERT_NEAR(pixels[1 + destRes], gl::unorm<16>(d11), kEpsilon);
384         }
385     }
386     else
387     {
388         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
389     }
390     if (hasStencil)
391     {
392         glReadPixels(0, 0, destRes, destRes, GL_STENCIL_INDEX_OES, GL_UNSIGNED_BYTE, actualPixels);
393         if (hasReadStencilSupport())
394         {
395             EXPECT_GL_NO_ERROR();
396             ASSERT_TRUE((actualPixels[0] == 1) && (actualPixels[1] == 2) &&
397                         (actualPixels[0 + destRes] == 3) && (actualPixels[1 + destRes] == 4));
398         }
399         else
400         {
401             EXPECT_GL_ERROR(GL_INVALID_OPERATION);
402         }
403 
404         ASSERT(!hasFloatDepth);
405 
406         glReadPixels(0, 0, destRes, destRes, GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES,
407                      actualPixels);
408         if (hasReadDepthStencilSupport())
409         {
410             EXPECT_GL_NO_ERROR();
411 
412             struct Pixel
413             {
414                 uint32_t x;
415 
416                 uint32_t d24() const { return x >> 8; }
417 
418                 uint8_t s8() const { return x & 0xff; }
419             };
420 
421             constexpr unsigned short kEpsilon = 2;
422             const Pixel *pixels               = reinterpret_cast<const Pixel *>(actualPixels);
423 
424             ASSERT_NEAR(pixels[0].d24(), gl::unorm<24>(d00), kEpsilon);
425             ASSERT_NEAR(pixels[0 + destRes].d24(), gl::unorm<24>(d01), kEpsilon);
426             ASSERT_NEAR(pixels[1].d24(), gl::unorm<24>(d10), kEpsilon);
427             ASSERT_NEAR(pixels[1 + destRes].d24(), gl::unorm<24>(d11), kEpsilon);
428             ASSERT_TRUE((pixels[0].s8() == 1) && (pixels[1].s8() == 2) &&
429                         (pixels[0 + destRes].s8() == 3) && (pixels[1 + destRes].s8() == 4));
430         }
431         else
432         {
433             EXPECT_GL_ERROR(GL_INVALID_OPERATION);
434         }
435     }
436 }
437 
438 // This test will initialize a depth texture, clear it and read it back, if possible
TEST_P(DepthStencilFormatsTest,DepthStencilReadback_UShort)439 TEST_P(DepthStencilFormatsTest, DepthStencilReadback_UShort)
440 {
441     GLuint fakeData[10]    = {0};
442     ReadbackTestParam type = {
443         GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, fakeData, 16, 0};
444     depthStencilReadbackCase(type);
445 }
446 
447 // This test will initialize a depth texture, clear it and read it back, if possible
TEST_P(DepthStencilFormatsTest,DepthStencilReadback_UInt)448 TEST_P(DepthStencilFormatsTest, DepthStencilReadback_UInt)
449 {
450     // http://anglebug.com/40644772
451     ANGLE_SKIP_TEST_IF(IsMac() && IsIntelUHD630Mobile() && IsDesktopOpenGL());
452 
453     GLuint fakeData[10]    = {0};
454     ReadbackTestParam type = {
455         GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, fakeData, 16, 0};
456     depthStencilReadbackCase(type);
457 }
458 
459 // This test will initialize a depth texture, clear it and read it back, if possible
TEST_P(DepthStencilFormatsTest,DepthStencilReadback_Float)460 TEST_P(DepthStencilFormatsTest, DepthStencilReadback_Float)
461 {
462     // http://anglebug.com/40644772
463     ANGLE_SKIP_TEST_IF(IsMac() && IsIntelUHD630Mobile() && IsDesktopOpenGL());
464 
465     GLuint fakeData[10]    = {0};
466     ReadbackTestParam type = {GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, GL_FLOAT, fakeData, 32, 0};
467     depthStencilReadbackCase(type);
468 }
469 
470 // This test will initialize a depth texture, clear it and read it back, if possible
TEST_P(DepthStencilFormatsTest,DepthStencilReadback_DepthStencil)471 TEST_P(DepthStencilFormatsTest, DepthStencilReadback_DepthStencil)
472 {
473     GLuint fakeData[10]    = {0};
474     ReadbackTestParam type = {
475         GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8_OES, fakeData, 24, 8};
476     depthStencilReadbackCase(type);
477 }
478 
479 // Verify that packed D/S readPixels with a D32_FLOAT_S8X24_UINT attachment
TEST_P(DepthStencilFormatsTestES3,DepthStencilReadback_DepthFloatStencil)480 TEST_P(DepthStencilFormatsTestES3, DepthStencilReadback_DepthFloatStencil)
481 {
482     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_packed_depth_stencil") ||
483                        !IsGLExtensionEnabled("GL_NV_depth_buffer_float2") ||
484                        !IsGLExtensionEnabled("GL_NV_read_depth") ||
485                        !IsGLExtensionEnabled("GL_NV_read_depth_stencil") ||
486                        !IsGLExtensionEnabled("GL_NV_read_stencil"));
487 
488     GLFramebuffer FBO;
489     glBindFramebuffer(GL_FRAMEBUFFER, FBO);
490     ASSERT_GL_NO_ERROR();
491 
492     GLRenderbuffer RBO;
493     glBindRenderbuffer(GL_RENDERBUFFER, RBO);
494     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH32F_STENCIL8, getWindowWidth(),
495                           getWindowHeight());
496     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, RBO);
497     ASSERT_GL_NO_ERROR();
498 
499     constexpr float kDepthClearValue     = 0.123f;
500     constexpr uint8_t kStencilClearValue = 0x42;
501 
502     glClearDepthf(kDepthClearValue);
503     glClearStencil(kStencilClearValue);
504     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
505     ASSERT_GL_NO_ERROR();
506 
507     struct
508     {
509         float depth;
510         uint8_t stencil;
511         char unused[3];
512     } pixel = {};
513     glReadPixels(0, 0, 1, 1, GL_DEPTH_STENCIL_OES, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, &pixel);
514     EXPECT_GL_NO_ERROR();
515 
516     EXPECT_FLOAT_EQ(pixel.depth, kDepthClearValue);
517     EXPECT_EQ(pixel.stencil, kStencilClearValue);
518 }
519 
520 // This test will initialize a depth texture and then render with it and verify
521 // pixel correctness.
522 // This is modeled after webgl-depth-texture.html
TEST_P(DepthStencilFormatsTest,DepthTextureRender)523 TEST_P(DepthStencilFormatsTest, DepthTextureRender)
524 {
525     constexpr char kVS[] = R"(attribute vec4 a_position;
526 void main()
527 {
528     gl_Position = a_position;
529 })";
530 
531     constexpr char kFS[] = R"(precision mediump float;
532 uniform sampler2D u_texture;
533 uniform vec2 u_resolution;
534 void main()
535 {
536     vec2 texcoord = (gl_FragCoord.xy - vec2(0.5)) / (u_resolution - vec2(1.0));
537     gl_FragColor = texture2D(u_texture, texcoord);
538 })";
539 
540     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_depth_texture") &&
541                        !IsGLExtensionEnabled("GL_ANGLE_depth_texture"));
542 
543     bool depthTextureCubeSupport  = IsGLExtensionEnabled("GL_OES_depth_texture_cube_map");
544     bool textureSrgbDecodeSupport = IsGLExtensionEnabled("GL_EXT_texture_sRGB_decode");
545 
546     // http://anglebug.com/42262117
547     ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows() && IsD3D9());
548 
549     const int res     = 2;
550     const int destRes = 4;
551     GLint resolution;
552 
553     ANGLE_GL_PROGRAM(program, kVS, kFS);
554 
555     glUseProgram(program);
556     resolution = glGetUniformLocation(program, "u_resolution");
557     ASSERT_NE(-1, resolution);
558     glUniform2f(resolution, static_cast<float>(destRes), static_cast<float>(destRes));
559 
560     GLuint buffer;
561     glGenBuffers(1, &buffer);
562     glBindBuffer(GL_ARRAY_BUFFER, buffer);
563     float verts[] = {
564         1, 1, 1, -1, 1, 0, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 0,
565     };
566     glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
567     glEnableVertexAttribArray(0);
568     glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
569 
570     // OpenGL ES does not have a FLIPY PixelStore attribute
571     // glPixelStorei(GL_UNPACK_FLIP)
572 
573     struct TypeInfo
574     {
575         GLuint attachment;
576         GLuint format;
577         GLuint type;
578         void *data;
579         int depthBits;
580         int stencilBits;
581     };
582 
583     GLuint fakeData[10] = {0};
584 
585     std::vector<TypeInfo> types = {
586         {GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, fakeData, 16, 0},
587         {GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, fakeData, 16, 0},
588         {GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8_OES, fakeData, 24, 8},
589     };
590 
591     for (const TypeInfo &type : types)
592     {
593         GLTexture cubeTex;
594         glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTex);
595         ASSERT_GL_NO_ERROR();
596 
597         std::vector<GLuint> targets{GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
598                                     GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
599                                     GL_TEXTURE_CUBE_MAP_POSITIVE_Z, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z};
600 
601         for (const GLuint target : targets)
602         {
603             glTexImage2D(target, 0, type.format, 1, 1, 0, type.format, type.type, nullptr);
604             if (depthTextureCubeSupport)
605             {
606                 ASSERT_GL_NO_ERROR();
607             }
608             else
609             {
610                 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
611             }
612         }
613 
614         std::vector<GLuint> filterModes = {GL_LINEAR, GL_NEAREST};
615 
616         const bool supportPackedDepthStencilFramebuffer = getClientMajorVersion() >= 3;
617 
618         for (const GLuint filterMode : filterModes)
619         {
620             GLTexture tex;
621             glBindTexture(GL_TEXTURE_2D, tex);
622             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
623             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
624             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filterMode);
625             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filterMode);
626             if (textureSrgbDecodeSupport)
627             {
628                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
629             }
630 
631             // test level > 0
632             glTexImage2D(GL_TEXTURE_2D, 1, type.format, 1, 1, 0, type.format, type.type, nullptr);
633             if (IsGLExtensionEnabled("GL_OES_depth_texture"))
634             {
635                 EXPECT_GL_NO_ERROR();
636             }
637             else
638             {
639                 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
640             }
641 
642             // test with data
643             glTexImage2D(GL_TEXTURE_2D, 0, type.format, 1, 1, 0, type.format, type.type, type.data);
644             if (IsGLExtensionEnabled("GL_OES_depth_texture"))
645             {
646                 EXPECT_GL_NO_ERROR();
647             }
648             else
649             {
650                 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
651             }
652 
653             // test copyTexImage2D
654             glCopyTexImage2D(GL_TEXTURE_2D, 0, type.format, 0, 0, 1, 1, 0);
655             GLuint error = glGetError();
656             ASSERT_TRUE(error == GL_INVALID_ENUM || error == GL_INVALID_OPERATION);
657 
658             // test real thing
659             glTexImage2D(GL_TEXTURE_2D, 0, type.format, res, res, 0, type.format, type.type,
660                          nullptr);
661             EXPECT_GL_NO_ERROR();
662 
663             // test texSubImage2D
664             glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, type.format, type.type, type.data);
665             if (IsGLExtensionEnabled("GL_OES_depth_texture"))
666             {
667                 EXPECT_GL_NO_ERROR();
668             }
669             else
670             {
671                 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
672             }
673 
674             // test copyTexSubImage2D
675             glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
676             EXPECT_GL_ERROR(GL_INVALID_OPERATION);
677 
678             // test generateMipmap
679             glGenerateMipmap(GL_TEXTURE_2D);
680             EXPECT_GL_ERROR(GL_INVALID_OPERATION);
681 
682             GLuint fbo = 0;
683             glGenFramebuffers(1, &fbo);
684             glBindFramebuffer(GL_FRAMEBUFFER, fbo);
685             if (type.depthBits > 0 && type.stencilBits > 0 && !supportPackedDepthStencilFramebuffer)
686             {
687                 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex, 0);
688                 EXPECT_GL_NO_ERROR();
689                 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, tex,
690                                        0);
691                 EXPECT_GL_NO_ERROR();
692             }
693             else
694             {
695                 glFramebufferTexture2D(GL_FRAMEBUFFER, type.attachment, GL_TEXTURE_2D, tex, 0);
696                 EXPECT_GL_NO_ERROR();
697             }
698 
699             // Ensure DEPTH_BITS returns >= 16 bits for UNSIGNED_SHORT and UNSIGNED_INT, >= 24
700             // UNSIGNED_INT_24_8_WEBGL. If there is stencil, ensure STENCIL_BITS reports >= 8 for
701             // UNSIGNED_INT_24_8_WEBGL.
702 
703             GLint depthBits = 0;
704             glGetIntegerv(GL_DEPTH_BITS, &depthBits);
705             EXPECT_GE(depthBits, type.depthBits);
706 
707             GLint stencilBits = 0;
708             glGetIntegerv(GL_STENCIL_BITS, &stencilBits);
709             EXPECT_GE(stencilBits, type.stencilBits);
710 
711             // TODO: remove this check if the spec is updated to require these combinations to work.
712             if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
713             {
714                 // try adding a color buffer.
715                 GLuint colorTex = 0;
716                 glGenTextures(1, &colorTex);
717                 glBindTexture(GL_TEXTURE_2D, colorTex);
718                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
719                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
720                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
721                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
722                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, res, res, 0, GL_RGBA, GL_UNSIGNED_BYTE,
723                              nullptr);
724                 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
725                                        colorTex, 0);
726                 EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
727             }
728 
729             EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
730 
731             // use the default texture to render with while we return to the depth texture.
732             glBindTexture(GL_TEXTURE_2D, 0);
733 
734             /* Setup 2x2 depth texture:
735              * 1 0.6 0.8
736              * |
737              * 0 0.2 0.4
738              *    0---1
739              */
740             const GLfloat d00 = 0.2;
741             const GLfloat d01 = 0.4;
742             const GLfloat d10 = 0.6;
743             const GLfloat d11 = 0.8;
744             glEnable(GL_SCISSOR_TEST);
745             glScissor(0, 0, 1, 1);
746             glClearDepthf(d00);
747             glClear(GL_DEPTH_BUFFER_BIT);
748             glScissor(1, 0, 1, 1);
749             glClearDepthf(d10);
750             glClear(GL_DEPTH_BUFFER_BIT);
751             glScissor(0, 1, 1, 1);
752             glClearDepthf(d01);
753             glClear(GL_DEPTH_BUFFER_BIT);
754             glScissor(1, 1, 1, 1);
755             glClearDepthf(d11);
756             glClear(GL_DEPTH_BUFFER_BIT);
757             glDisable(GL_SCISSOR_TEST);
758 
759             // render the depth texture.
760             glBindFramebuffer(GL_FRAMEBUFFER, 0);
761             glViewport(0, 0, destRes, destRes);
762             glBindTexture(GL_TEXTURE_2D, tex);
763             glDisable(GL_DITHER);
764             glEnable(GL_DEPTH_TEST);
765             glClearColor(1, 0, 0, 1);
766             glClearDepthf(1.0);
767             glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
768             glDrawArrays(GL_TRIANGLES, 0, 6);
769 
770             GLubyte actualPixels[destRes * destRes * 4];
771             glReadPixels(0, 0, destRes, destRes, GL_RGBA, GL_UNSIGNED_BYTE, actualPixels);
772             const GLfloat eps = 0.002;
773             std::vector<GLfloat> expectedMin;
774             std::vector<GLfloat> expectedMax;
775             if (filterMode == GL_NEAREST)
776             {
777                 GLfloat init[] = {d00, d00, d10, d10, d00, d00, d10, d10,
778                                   d01, d01, d11, d11, d01, d01, d11, d11};
779                 expectedMin.insert(expectedMin.begin(), init, init + 16);
780                 expectedMax.insert(expectedMax.begin(), init, init + 16);
781 
782                 for (int i = 0; i < 16; i++)
783                 {
784                     expectedMin[i] = expectedMin[i] - eps;
785                     expectedMax[i] = expectedMax[i] + eps;
786                 }
787             }
788             else
789             {
790                 GLfloat initMin[] = {
791                     d00 - eps, d00, d00, d10 - eps, d00,       d00, d00, d10,
792                     d00,       d00, d00, d10,       d01 - eps, d01, d01, d11 - eps,
793                 };
794                 GLfloat initMax[] = {
795                     d00 + eps, d10, d10, d10 + eps, d01,       d11, d11, d11,
796                     d01,       d11, d11, d11,       d01 + eps, d11, d11, d11 + eps,
797                 };
798                 expectedMin.insert(expectedMin.begin(), initMin, initMin + 16);
799                 expectedMax.insert(expectedMax.begin(), initMax, initMax + 16);
800             }
801             for (int yy = 0; yy < destRes; ++yy)
802             {
803                 for (int xx = 0; xx < destRes; ++xx)
804                 {
805                     const int t        = xx + destRes * yy;
806                     const GLfloat was  = (GLfloat)(actualPixels[4 * t] / 255.0);  // 4bpp
807                     const GLfloat eMin = expectedMin[t];
808                     const GLfloat eMax = expectedMax[t];
809                     EXPECT_TRUE(was >= eMin && was <= eMax)
810                         << "At " << xx << ", " << yy << ", expected within [" << eMin << ", "
811                         << eMax << "] was " << was;
812                 }
813             }
814 
815             // check limitations
816             // Note: What happens if current attachment type is GL_DEPTH_STENCIL_ATTACHMENT
817             // and you try to call glFramebufferTexture2D with GL_DEPTH_ATTACHMENT?
818             // The webGL test this code came from expected that to fail.
819             // I think due to this line in ES3 spec:
820             // GL_INVALID_OPERATION is generated if textarget and texture are not compatible
821             // However, that's not the behavior I'm seeing, nor does it seem that a depth_stencil
822             // buffer isn't compatible with a depth attachment (e.g. stencil is unused).
823             if (type.attachment == GL_DEPTH_ATTACHMENT)
824             {
825                 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
826                 glFramebufferTexture2D(GL_FRAMEBUFFER, type.attachment, GL_TEXTURE_2D, 0, 0);
827                 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
828                                        tex, 0);
829                 EXPECT_GLENUM_NE(GL_NO_ERROR, glGetError());
830                 EXPECT_GLENUM_NE(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
831                 glClear(GL_DEPTH_BUFFER_BIT);
832                 EXPECT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
833                 glBindFramebuffer(GL_FRAMEBUFFER, 0);
834                 EXPECT_GL_NO_ERROR();
835             }
836         }
837     }
838 }
839 
840 // This test will initialize a frame buffer, attaching a color and 16-bit depth buffer,
841 // render to it with depth testing, and verify pixel correctness.
TEST_P(DepthStencilFormatsTest,DepthBuffer16)842 TEST_P(DepthStencilFormatsTest, DepthBuffer16)
843 {
844     verifyDepthRenderBuffer(GL_DEPTH_COMPONENT16);
845 }
846 
847 // This test will initialize a frame buffer, attaching a color and 24-bit depth buffer,
848 // render to it with depth testing, and verify pixel correctness.
TEST_P(DepthStencilFormatsTest,DepthBuffer24)849 TEST_P(DepthStencilFormatsTest, DepthBuffer24)
850 {
851     bool shouldHaveRenderbufferSupport = IsGLExtensionEnabled("GL_OES_depth24");
852     EXPECT_EQ(shouldHaveRenderbufferSupport,
853               checkRenderbufferFormatSupport(GL_DEPTH_COMPONENT24_OES));
854 
855     if (shouldHaveRenderbufferSupport)
856     {
857         verifyDepthRenderBuffer(GL_DEPTH_COMPONENT24_OES);
858     }
859 }
860 
TEST_P(DepthStencilFormatsTestES3,DrawWithDepth16)861 TEST_P(DepthStencilFormatsTestES3, DrawWithDepth16)
862 {
863     GLushort data[16];
864     for (unsigned int i = 0; i < 16; i++)
865     {
866         data[i] = std::numeric_limits<GLushort>::max();
867     }
868     glBindTexture(GL_TEXTURE_2D, mTexture);
869     glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT16, 4, 4);
870     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, data);
871 
872     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
873     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
874 
875     glUseProgram(mProgram);
876     glUniform1i(mTextureUniformLocation, 0);
877 
878     glClear(GL_COLOR_BUFFER_BIT);
879     drawQuad(mProgram, "position", 0.5f);
880 
881     ASSERT_GL_NO_ERROR();
882 
883     GLubyte pixel[4];
884     glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel);
885 
886     // Only require the red and alpha channels have the correct values, the depth texture extensions
887     // leave the green and blue channels undefined
888     ASSERT_NEAR(255, pixel[0], 2.0);
889     ASSERT_EQ(255, pixel[3]);
890 }
891 
892 // This test reproduces a driver bug on Intel windows platforms on driver version
893 // from 4815 to 4901.
894 // When rendering with Stencil buffer enabled and depth buffer disabled, large
895 // viewport will lead to memory leak and driver crash. And the pixel result
896 // is a random value.
TEST_P(DepthStencilFormatsTestES3,DrawWithLargeViewport)897 TEST_P(DepthStencilFormatsTestES3, DrawWithLargeViewport)
898 {
899     ANGLE_SKIP_TEST_IF(IsIntel() && IsWindows());
900 
901     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
902 
903     glEnable(GL_STENCIL_TEST);
904     glDisable(GL_DEPTH_TEST);
905 
906     // The iteration is to reproduce memory leak when rendering several times.
907     for (int i = 0; i < 10; ++i)
908     {
909         // Create offscreen fbo and its color attachment and depth stencil attachment.
910         GLTexture framebufferColorTexture;
911         glBindTexture(GL_TEXTURE_2D, framebufferColorTexture);
912         glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
913         ASSERT_GL_NO_ERROR();
914 
915         GLTexture framebufferStencilTexture;
916         glBindTexture(GL_TEXTURE_2D, framebufferStencilTexture);
917         glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, getWindowWidth(), getWindowHeight());
918         ASSERT_GL_NO_ERROR();
919 
920         GLFramebuffer fb;
921         glBindFramebuffer(GL_FRAMEBUFFER, fb);
922         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
923                                framebufferColorTexture, 0);
924         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
925                                framebufferStencilTexture, 0);
926 
927         EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
928         ASSERT_GL_NO_ERROR();
929 
930         GLint kStencilRef = 4;
931         glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
932         glStencilFunc(GL_ALWAYS, kStencilRef, 0xFF);
933 
934         float viewport[2];
935         glGetFloatv(GL_MAX_VIEWPORT_DIMS, viewport);
936 
937         glViewport(0, 0, static_cast<GLsizei>(viewport[0]), static_cast<GLsizei>(viewport[1]));
938         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);
939 
940         drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
941         ASSERT_GL_NO_ERROR();
942 
943         glBindFramebuffer(GL_READ_FRAMEBUFFER, fb);
944         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
945         ASSERT_GL_NO_ERROR();
946     }
947 }
948 
949 // Verify that stencil component of depth texture is uploaded
TEST_P(DepthStencilFormatsTest,VerifyDepthStencilUploadData)950 TEST_P(DepthStencilFormatsTest, VerifyDepthStencilUploadData)
951 {
952     // http://anglebug.com/42262342
953     // When bug is resolved we can remove this skip.
954     ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
955 
956     // http://anglebug.com/42262345
957     ANGLE_SKIP_TEST_IF(IsWindows() && IsVulkan() && IsAMD());
958 
959     bool shouldHaveTextureSupport = (IsGLExtensionEnabled("GL_OES_packed_depth_stencil") &&
960                                      IsGLExtensionEnabled("GL_OES_depth_texture")) ||
961                                     (getClientMajorVersion() >= 3);
962 
963     ANGLE_SKIP_TEST_IF(!shouldHaveTextureSupport ||
964                        !checkTexImageFormatSupport(GL_DEPTH_STENCIL_OES, GL_UNSIGNED_INT_24_8_OES));
965 
966     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
967 
968     glEnable(GL_STENCIL_TEST);
969     glDisable(GL_DEPTH_TEST);
970     glDepthMask(GL_FALSE);
971 
972     glViewport(0, 0, getWindowWidth(), getWindowHeight());
973     glClearColor(0, 0, 0, 1);
974 
975     // Create offscreen fbo and its color attachment and depth stencil attachment.
976     GLTexture framebufferColorTexture;
977     glBindTexture(GL_TEXTURE_2D, framebufferColorTexture);
978     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
979                  GL_UNSIGNED_BYTE, nullptr);
980     ASSERT_GL_NO_ERROR();
981 
982     // drawQuad's depth range is -1.0 to 1.0, so a depth value of 0.5 (0x7fffff) matches a drawQuad
983     // depth of 0.0.
984     std::vector<GLuint> depthStencilData(getWindowWidth() * getWindowHeight(), 0x7fffffA9);
985     GLTexture framebufferStencilTexture;
986     glBindTexture(GL_TEXTURE_2D, framebufferStencilTexture);
987     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_STENCIL, getWindowWidth(), getWindowHeight(), 0,
988                  GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8_OES, depthStencilData.data());
989     ASSERT_GL_NO_ERROR();
990 
991     GLFramebuffer fb;
992     glBindFramebuffer(GL_FRAMEBUFFER, fb);
993     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
994                            framebufferColorTexture, 0);
995 
996     if (getClientMajorVersion() >= 3)
997     {
998         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
999                                framebufferStencilTexture, 0);
1000         ASSERT_GL_NO_ERROR();
1001     }
1002     else
1003     {
1004         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
1005                                framebufferStencilTexture, 0);
1006         ASSERT_GL_NO_ERROR();
1007         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
1008                                framebufferStencilTexture, 0);
1009         ASSERT_GL_NO_ERROR();
1010     }
1011 
1012     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1013 
1014     GLint kStencilRef = 0xA9;
1015     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
1016     glStencilFunc(GL_EQUAL, kStencilRef, 0xFF);
1017 
1018     glBindFramebuffer(GL_FRAMEBUFFER, fb);
1019 
1020     glClear(GL_COLOR_BUFFER_BIT);
1021 
1022     drawQuad(program, essl1_shaders::PositionAttrib(), 1.0f);
1023     ASSERT_GL_NO_ERROR();
1024 
1025     glBindFramebuffer(GL_FRAMEBUFFER, fb);
1026     EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);
1027     ASSERT_GL_NO_ERROR();
1028 
1029     // Check Z values
1030 
1031     glClear(GL_COLOR_BUFFER_BIT);
1032     glDisable(GL_STENCIL_TEST);
1033     glEnable(GL_DEPTH_TEST);
1034     glDepthFunc(GL_LESS);
1035 
1036     drawQuad(program, essl1_shaders::PositionAttrib(), -0.1f);
1037     ASSERT_GL_NO_ERROR();
1038 
1039     EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);
1040 
1041     glClear(GL_COLOR_BUFFER_BIT);
1042 
1043     drawQuad(program, essl1_shaders::PositionAttrib(), 0.1f);
1044     ASSERT_GL_NO_ERROR();
1045 
1046     EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::black);
1047 }
1048 
1049 // Verify that depth texture's data can be uploaded correctly
TEST_P(DepthStencilFormatsTest,VerifyDepth32UploadData)1050 TEST_P(DepthStencilFormatsTest, VerifyDepth32UploadData)
1051 {
1052     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_depth_texture"));
1053 
1054     GLTexture tex;
1055     glBindTexture(GL_TEXTURE_2D, tex);
1056     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1057     ASSERT_GL_NO_ERROR();
1058 
1059     // normalized 0.99 = 0xfd70a3d6
1060     std::vector<GLuint> depthData(1, 0xfd70a3d6);
1061     GLTexture rbDepth;
1062     glBindTexture(GL_TEXTURE_2D, rbDepth);
1063     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1, 1, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
1064                  depthData.data());
1065     ASSERT_GL_NO_ERROR();
1066 
1067     GLFramebuffer fbo;
1068     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1069     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1070     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rbDepth, 0);
1071 
1072     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1073     ASSERT_GL_NO_ERROR();
1074 
1075     ANGLE_GL_PROGRAM(programRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
1076     glEnable(GL_DEPTH_TEST);
1077     glDepthFunc(GL_GEQUAL);
1078     glClearColor(0, 1, 0, 1);
1079     glClear(GL_COLOR_BUFFER_BIT);
1080 
1081     // Fail Depth Test and color buffer is unchanged
1082     float depthValue = 0.98f;
1083     drawQuad(programRed, essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
1084     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1085 
1086     // Pass Depth Test and draw red
1087     depthValue = 1.0f;
1088     drawQuad(programRed, essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
1089     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1090 
1091     ASSERT_GL_NO_ERROR();
1092 
1093     // Change depth texture data
1094     glBindTexture(GL_TEXTURE_2D, rbDepth);
1095     depthData[0] = 0x7fffffff;  // 0.5
1096     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
1097                     depthData.data());
1098     ASSERT_GL_NO_ERROR();
1099 
1100     ANGLE_GL_PROGRAM(programGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
1101 
1102     // Fail Depth Test and color buffer is unchanged
1103     depthValue = 0.48f;
1104     drawQuad(programGreen, essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
1105     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1106 
1107     ASSERT_GL_NO_ERROR();
1108 
1109     ANGLE_GL_PROGRAM(programBlue, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
1110     glClearDepthf(0.0f);
1111     glClear(GL_DEPTH_BUFFER_BIT);
1112 
1113     // Pass Depth Test and draw blue
1114     depthValue = 0.01f;
1115     drawQuad(programBlue, essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
1116     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
1117 
1118     glDisable(GL_DEPTH_TEST);
1119     ASSERT_GL_NO_ERROR();
1120 }
1121 
1122 // Verify that 16 bits depth texture's data can be uploaded correctly
TEST_P(DepthStencilFormatsTest,VerifyDepth16UploadData)1123 TEST_P(DepthStencilFormatsTest, VerifyDepth16UploadData)
1124 {
1125     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_depth_texture"));
1126 
1127     GLTexture tex;
1128     glBindTexture(GL_TEXTURE_2D, tex);
1129     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1130     ASSERT_GL_NO_ERROR();
1131 
1132     // normalized 0.99 = 0xfd6f
1133     std::vector<GLushort> depthData(1, 0xfd6f);
1134     GLTexture rbDepth;
1135     glBindTexture(GL_TEXTURE_2D, rbDepth);
1136     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 1, 1, 0, GL_DEPTH_COMPONENT,
1137                  GL_UNSIGNED_SHORT, depthData.data());
1138     ASSERT_GL_NO_ERROR();
1139 
1140     GLFramebuffer fbo;
1141     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1142     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1143     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rbDepth, 0);
1144 
1145     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1146     ASSERT_GL_NO_ERROR();
1147 
1148     ANGLE_GL_PROGRAM(programRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
1149     glEnable(GL_DEPTH_TEST);
1150     glDepthFunc(GL_GEQUAL);
1151     glClearColor(0, 1, 0, 1);
1152     glClear(GL_COLOR_BUFFER_BIT);
1153 
1154     // Fail Depth Test and color buffer is unchanged
1155     float depthValue = 0.98f;
1156     drawQuad(programRed, essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
1157     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1158 
1159     // Pass Depth Test and draw red
1160     depthValue = 1.0f;
1161     drawQuad(programRed, essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
1162     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1163 
1164     ASSERT_GL_NO_ERROR();
1165 
1166     // Change depth texture data
1167     glBindTexture(GL_TEXTURE_2D, rbDepth);
1168     depthData[0] = 0x7fff;  // 0.5
1169     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
1170                     depthData.data());
1171     ASSERT_GL_NO_ERROR();
1172 
1173     ANGLE_GL_PROGRAM(programGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
1174 
1175     // Fail Depth Test and color buffer is unchanged
1176     depthValue = 0.48f;
1177     drawQuad(programGreen, essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
1178     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1179 
1180     ASSERT_GL_NO_ERROR();
1181 
1182     ANGLE_GL_PROGRAM(programBlue, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
1183     glClearDepthf(0.0f);
1184     glClear(GL_DEPTH_BUFFER_BIT);
1185 
1186     // Pass Depth Test and draw blue
1187     depthValue = 0.01f;
1188     drawQuad(programBlue, essl1_shaders::PositionAttrib(), depthValue * 2 - 1);
1189     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
1190 
1191     glDisable(GL_DEPTH_TEST);
1192     ASSERT_GL_NO_ERROR();
1193 }
1194 
1195 class DepthStencilFormatsTestES31 : public DepthStencilFormatsTestBase
1196 {};
1197 
1198 // Test depth24 texture sample from fragment shader and then read access from compute
TEST_P(DepthStencilFormatsTestES31,DrawReadDrawDispatch)1199 TEST_P(DepthStencilFormatsTestES31, DrawReadDrawDispatch)
1200 {
1201     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_depth24") ||
1202                        !IsGLExtensionEnabled("GL_NV_read_depth"));
1203 
1204     const char kVS[] = R"(#version 310 es
1205 layout (location = 0) in vec3 pos;
1206 void main(void) {
1207     gl_Position = vec4(pos, 1.0);
1208 })";
1209 
1210     const char kFS[] = R"(#version 310 es
1211 precision highp float;
1212 uniform sampler2D tex;
1213 out vec4 fragColor;
1214 void main(void) {
1215         float d = texture(tex,vec2(0,0)).x;
1216         fragColor = vec4(d, 0, 0, 1);
1217 })";
1218 
1219     // Create depth texture
1220     GLTexture depthTexture;
1221     glActiveTexture(GL_TEXTURE0);
1222     glBindTexture(GL_TEXTURE_2D, depthTexture);
1223     // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
1224     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1225     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1226     glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT24, 1, 1);
1227 
1228     // Clear depth texture to 0.51f
1229     GLFramebuffer framebuffer;
1230     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1231     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
1232     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1233     GLfloat depthValue = 0.51f;
1234     glClearDepthf(depthValue);
1235     glClear(GL_DEPTH_BUFFER_BIT);
1236     GLuint actualDepthValue;
1237     GLfloat depthErrorTolerance = 0.001f;
1238     glReadPixels(0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, &actualDepthValue);
1239     EXPECT_NEAR(depthValue, actualDepthValue / (float)UINT_MAX, depthErrorTolerance);
1240     glBindFramebuffer(GL_FRAMEBUFFER, 0);
1241 
1242     // Render to surface with texture sample from depth texture
1243     ANGLE_GL_PROGRAM(graphicsProgram, kVS, kFS);
1244     glUseProgram(graphicsProgram);
1245     const auto &quadVertices = GetQuadVertices();
1246     GLBuffer arrayBuffer;
1247     glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer);
1248     glBufferData(GL_ARRAY_BUFFER, quadVertices.size() * sizeof(Vector3), quadVertices.data(),
1249                  GL_STATIC_DRAW);
1250     GLint positionAttributeLocation = 0;
1251     glBindAttribLocation(graphicsProgram, positionAttributeLocation, "pos");
1252     glVertexAttribPointer(positionAttributeLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
1253     glEnableVertexAttribArray(positionAttributeLocation);
1254 
1255     GLint uTextureLocation = glGetUniformLocation(graphicsProgram, "tex");
1256     ASSERT_NE(-1, uTextureLocation);
1257     glActiveTexture(GL_TEXTURE0);
1258     glBindTexture(GL_TEXTURE_2D, depthTexture);
1259     glUniform1i(uTextureLocation, 0);
1260     // Sample the depth texture from fragment shader and verify. This flushes out commands which
1261     // ensures there will be no layout transition in next renderPass.
1262     glDepthMask(false);
1263     glDisable(GL_DEPTH_TEST);
1264     glDrawArrays(GL_TRIANGLES, 0, 6);
1265     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor((GLubyte)(depthValue * 255), 0u, 0u, 255u));
1266 
1267     // Sample the depth texture from fragment shader. No image layout transition expected here.
1268     glDrawArrays(GL_TRIANGLES, 0, 6);
1269 
1270     // Sample it from compute shader while the renderPass also sample from the same texture
1271     constexpr char kCS[] = R"(#version 310 es
1272 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1273 layout(std140, binding=0) buffer buf {
1274     vec4 outData;
1275 };
1276 uniform sampler2D u_tex2D;
1277 void main()
1278 {
1279     outData = texture(u_tex2D, vec2(gl_LocalInvocationID.xy));
1280 })";
1281     ANGLE_GL_COMPUTE_PROGRAM(computeProgram, kCS);
1282     glUseProgram(computeProgram);
1283     GLBuffer ssbo;
1284     const std::vector<GLfloat> initialData(16, 0.0f);
1285     glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
1286     glBufferData(GL_SHADER_STORAGE_BUFFER, 16, initialData.data(), GL_STATIC_DRAW);
1287     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo);
1288     glDispatchCompute(1, 1, 1);
1289     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
1290     glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
1291     const GLfloat *ptr = reinterpret_cast<const GLfloat *>(
1292         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 16, GL_MAP_READ_BIT));
1293     EXPECT_NEAR(depthValue, ptr[0], depthErrorTolerance);
1294     EXPECT_GL_NO_ERROR();
1295 }
1296 
1297 ANGLE_INSTANTIATE_TEST_ES2(DepthStencilFormatsTest);
1298 
1299 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DepthStencilFormatsTestES3);
1300 ANGLE_INSTANTIATE_TEST_ES3(DepthStencilFormatsTestES3);
1301 
1302 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DepthStencilFormatsTestES31);
1303 ANGLE_INSTANTIATE_TEST_ES31(DepthStencilFormatsTestES31);
1304 
1305 class TinyDepthStencilWorkaroundTest : public ANGLETest<>
1306 {
1307   public:
TinyDepthStencilWorkaroundTest()1308     TinyDepthStencilWorkaroundTest()
1309     {
1310         setWindowWidth(512);
1311         setWindowHeight(512);
1312         setConfigRedBits(8);
1313         setConfigGreenBits(8);
1314         setConfigBlueBits(8);
1315         setConfigAlphaBits(8);
1316     }
1317 };
1318 
1319 // Tests that the tiny depth stencil textures workaround does not "stick" depth textures.
1320 // http://anglebug.com/40644610
TEST_P(TinyDepthStencilWorkaroundTest,DepthTexturesStick)1321 TEST_P(TinyDepthStencilWorkaroundTest, DepthTexturesStick)
1322 {
1323     // http://anglebug.com/40096654
1324     ANGLE_SKIP_TEST_IF((IsAndroid() && IsOpenGLES()) || (IsLinux() && IsVulkan()));
1325 
1326     constexpr char kDrawVS[] =
1327         "#version 100\n"
1328         "attribute vec3 vertex;\n"
1329         "void main () {\n"
1330         "  gl_Position = vec4(vertex.x, vertex.y, vertex.z * 2.0 - 1.0, 1);\n"
1331         "}\n";
1332 
1333     ANGLE_GL_PROGRAM(drawProgram, kDrawVS, essl1_shaders::fs::Red());
1334 
1335     constexpr char kBlitVS[] =
1336         "#version 100\n"
1337         "attribute vec2 vertex;\n"
1338         "varying vec2 position;\n"
1339         "void main () {\n"
1340         "  position = vertex * .5 + .5;\n"
1341         "  gl_Position = vec4(vertex, 0, 1);\n"
1342         "}\n";
1343 
1344     constexpr char kBlitFS[] =
1345         "#version 100\n"
1346         "precision mediump float;\n"
1347         "uniform sampler2D texture;\n"
1348         "varying vec2 position;\n"
1349         "void main () {\n"
1350         "  gl_FragColor = vec4 (texture2D (texture, position).rrr, 1.);\n"
1351         "}\n";
1352 
1353     ANGLE_GL_PROGRAM(blitProgram, kBlitVS, kBlitFS);
1354 
1355     GLint blitTextureLocation = glGetUniformLocation(blitProgram, "texture");
1356     ASSERT_NE(-1, blitTextureLocation);
1357 
1358     GLTexture colorTex;
1359     glBindTexture(GL_TEXTURE_2D, colorTex);
1360     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1361     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1362     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1363     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1364     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
1365                  GL_UNSIGNED_BYTE, nullptr);
1366     glBindTexture(GL_TEXTURE_2D, 0);
1367 
1368     GLTexture depthTex;
1369     glBindTexture(GL_TEXTURE_2D, depthTex);
1370     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1371     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1372     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1373     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
1374     ASSERT_EQ(getWindowWidth(), getWindowHeight());
1375     int levels = gl::log2(getWindowWidth());
1376     for (int mipLevel = 0; mipLevel <= levels; ++mipLevel)
1377     {
1378         int size = getWindowWidth() >> mipLevel;
1379         glTexImage2D(GL_TEXTURE_2D, mipLevel, GL_DEPTH_STENCIL, size, size, 0, GL_DEPTH_STENCIL,
1380                      GL_UNSIGNED_INT_24_8_OES, nullptr);
1381     }
1382 
1383     glBindTexture(GL_TEXTURE_2D, 0);
1384 
1385     ASSERT_GL_NO_ERROR();
1386 
1387     GLFramebuffer framebuffer;
1388     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1389 
1390     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
1391     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTex, 0);
1392 
1393     ASSERT_GL_NO_ERROR();
1394 
1395     glDepthRangef(0.0f, 1.0f);
1396     glViewport(0, 0, getWindowWidth(), getWindowHeight());
1397     glClearColor(0, 0, 0, 1);
1398 
1399     // Draw loop.
1400     for (unsigned int frame = 0; frame < 3; ++frame)
1401     {
1402         // draw into FBO
1403         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1404         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1405 
1406         glEnable(GL_DEPTH_TEST);
1407 
1408         float depth = ((frame % 2 == 0) ? 0.0f : 1.0f);
1409         drawQuad(drawProgram, "vertex", depth);
1410 
1411         glBindFramebuffer(GL_FRAMEBUFFER, 0);
1412 
1413         // blit FBO
1414         glDisable(GL_DEPTH_TEST);
1415 
1416         glUseProgram(blitProgram);
1417         glUniform1i(blitTextureLocation, 0);
1418         glBindTexture(GL_TEXTURE_2D, depthTex);
1419 
1420         drawQuad(blitProgram, "vertex", 0.5f);
1421 
1422         Vector4 depthVec(depth, depth, depth, 1);
1423         GLColor depthColor(depthVec);
1424 
1425         EXPECT_PIXEL_COLOR_NEAR(0, 0, depthColor, 1);
1426         ASSERT_GL_NO_ERROR();
1427     }
1428 }
1429 
1430 // Initialize a depth texture by writing to it in a fragment shader then attempt to read it from a
1431 // compute shader. Regression test for D3D11 not unbinding the depth texture and the sampler binding
1432 // failing.
TEST_P(DepthStencilFormatsTestES31,ReadDepthStencilInComputeShader)1433 TEST_P(DepthStencilFormatsTestES31, ReadDepthStencilInComputeShader)
1434 {
1435     constexpr char kTestVertexShader[] = R"(#version 310 es
1436 
1437 void main() {
1438   gl_PointSize = 1.0;
1439   vec2 pos[6] = vec2[6](vec2(-1.0f), vec2(1.0f, -1.0f), vec2(-1.0f, 1.0f), vec2(-1.0f, 1.0f), vec2(1.0f, -1.0f), vec2(1.0f));
1440   gl_Position = vec4(pos[uint(gl_VertexID)], 0.5f, 1.0f);
1441   return;
1442 }
1443 )";
1444 
1445     constexpr char kTestFragmentShader[] = R"(#version 310 es
1446 precision highp float;
1447 
1448 void main()
1449 {
1450   gl_FragDepth = 0.51f;
1451   return;
1452 }
1453 )";
1454 
1455     constexpr char kTestComputeShader[] = R"(#version 310 es
1456 
1457 layout(binding = 0, std430) buffer dst_buf_block_ssbo {
1458   float inner[];
1459 } dst_buf;
1460 
1461 uniform highp sampler2D tex;
1462 void blit_depth_to_buffer(uvec3 id) {
1463   uvec2 coord = (id.xy);
1464   uint dstOffset = (id.x + (id.y * 1u));
1465   dst_buf.inner[dstOffset] = texelFetch(tex, ivec2(coord), 0).x;
1466 }
1467 
1468 layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
1469 void main() {
1470   blit_depth_to_buffer(gl_GlobalInvocationID);
1471 }
1472 )";
1473 
1474     GLfloat depthValue          = 0.51f;
1475     GLfloat depthErrorTolerance = 0.001f;
1476 
1477     GLTexture depthTexture;
1478     glActiveTexture(GL_TEXTURE0);
1479     glBindTexture(GL_TEXTURE_2D, depthTexture);
1480     // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
1481     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1482     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1483     glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT32F, 1, 1);
1484 
1485     // Clear depth texture to depthValue
1486     GLFramebuffer framebuffer;
1487     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1488     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
1489     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1490 
1491     // 2. Draw and write to gl_FragDepth
1492     ANGLE_GL_PROGRAM(graphicsProgram, kTestVertexShader, kTestFragmentShader);
1493     glUseProgram(graphicsProgram);
1494     EXPECT_GL_NO_ERROR();
1495 
1496     glDrawBuffers(0, nullptr);
1497     EXPECT_GL_NO_ERROR();
1498 
1499     glClearDepthf(0.8);
1500     glEnable(GL_DEPTH_TEST);
1501     glDepthFunc(GL_ALWAYS);
1502     glDisable(GL_CULL_FACE);
1503     glDepthMask(true);
1504     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1505     glDrawArrays(GL_TRIANGLES, 0, 6);
1506     EXPECT_GL_NO_ERROR();
1507 
1508     glBindFramebuffer(GL_FRAMEBUFFER, 0);
1509 
1510     ANGLE_GL_COMPUTE_PROGRAM(computeProgram, kTestComputeShader);
1511     glUseProgram(computeProgram);
1512 
1513     GLint uTextureLocation = glGetUniformLocation(computeProgram, "tex");
1514     ASSERT_NE(-1, uTextureLocation);
1515     glActiveTexture(GL_TEXTURE0);
1516     glBindTexture(GL_TEXTURE_2D, depthTexture);
1517     glUniform1i(uTextureLocation, 0);
1518 
1519     GLBuffer ssbo;
1520     std::array<GLfloat, 16> initialData{0};
1521     glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
1522     glBufferData(GL_SHADER_STORAGE_BUFFER, 16, initialData.data(), GL_STATIC_DRAW);
1523     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo);
1524     glDispatchCompute(1, 1, 1);
1525     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
1526     glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
1527     const GLfloat *ptr = reinterpret_cast<const GLfloat *>(
1528         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, 16, GL_MAP_READ_BIT));
1529     EXPECT_NEAR(depthValue, ptr[0], depthErrorTolerance);
1530     EXPECT_GL_NO_ERROR();
1531 }
1532 
1533 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(TinyDepthStencilWorkaroundTest);
1534 ANGLE_INSTANTIATE_TEST_ES3_AND(TinyDepthStencilWorkaroundTest,
1535                                ES3_D3D11().enable(Feature::EmulateTinyStencilTextures));
1536