xref: /aosp_15_r20/external/angle/src/tests/gl_tests/DepthStencilTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2018 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 // DepthStencilTest:
7 //   Tests covering depth- or stencil-only rendering to make sure the other non-existing aspect is
8 //   not affecting the results (since the format may be emulated with one that has both aspects).
9 //
10 
11 #include "test_utils/ANGLETest.h"
12 
13 #include "test_utils/gl_raii.h"
14 
15 using namespace angle;
16 
17 namespace
18 {
19 
20 class DepthStencilTest : public ANGLETest<>
21 {
22   protected:
DepthStencilTest()23     DepthStencilTest()
24     {
25         setWindowWidth(128);
26         setWindowHeight(128);
27         setConfigRedBits(8);
28         setConfigGreenBits(8);
29         setConfigBlueBits(8);
30         setConfigAlphaBits(8);
31         setConfigDepthBits(24);
32         setConfigStencilBits(8);
33     }
34 
testSetUp()35     void testSetUp() override
36     {
37         glBindTexture(GL_TEXTURE_2D, mColorTexture);
38         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
39                      GL_UNSIGNED_BYTE, nullptr);
40 
41         // Setup Color/Stencil FBO with a stencil format that's emulated with packed depth/stencil.
42         glBindFramebuffer(GL_FRAMEBUFFER, mColorStencilFBO);
43 
44         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mColorTexture,
45                                0);
46         glBindRenderbuffer(GL_RENDERBUFFER, mStencilTexture);
47         glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, getWindowWidth(),
48                               getWindowHeight());
49         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
50                                   mStencilTexture);
51 
52         ASSERT_GL_NO_ERROR();
53 
54         // Note: GL_DEPTH_COMPONENT24 is allowed in GLES2 with GL_OES_depth24 extension.
55         if (getClientMajorVersion() >= 3 || IsGLExtensionEnabled("GL_OES_depth24"))
56         {
57             // Setup Color/Depth FBO with a depth format that's emulated with packed depth/stencil.
58             glBindFramebuffer(GL_FRAMEBUFFER, mColorDepthFBO);
59 
60             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
61                                    mColorTexture, 0);
62             glBindRenderbuffer(GL_RENDERBUFFER, mDepthTexture);
63             glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, getWindowWidth(),
64                                   getWindowHeight());
65             glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
66                                       mDepthTexture);
67         }
68 
69         ASSERT_GL_NO_ERROR();
70     }
71 
bindColorStencilFBO()72     void bindColorStencilFBO()
73     {
74         glBindFramebuffer(GL_FRAMEBUFFER, mColorStencilFBO);
75         mHasDepth = false;
76     }
77 
bindColorDepthFBO()78     void bindColorDepthFBO()
79     {
80         glBindFramebuffer(GL_FRAMEBUFFER, mColorDepthFBO);
81         mHasStencil = false;
82     }
83 
84     void prepareSingleEmulatedWithPacked();
85     void ensureColor(GLColor color);
86     void ensureDepthUnaffected();
87     void ensureStencilUnaffected();
88 
89   private:
90     GLFramebuffer mColorStencilFBO;
91     GLFramebuffer mColorDepthFBO;
92     GLTexture mColorTexture;
93     GLRenderbuffer mDepthTexture;
94     GLRenderbuffer mStencilTexture;
95 
96     bool mHasDepth   = true;
97     bool mHasStencil = true;
98 };
99 
100 class DepthStencilTestES3 : public DepthStencilTest
101 {
102   protected:
103     void compareDepth(uint32_t expected);
104     void clearAndCompareDepth(GLfloat depth, uint32_t expected);
105     void drawAndCompareDepth(GLProgram &program, GLfloat depth, uint32_t expected);
106 };
107 
ensureColor(GLColor color)108 void DepthStencilTest::ensureColor(GLColor color)
109 {
110     const int width  = getWindowWidth();
111     const int height = getWindowHeight();
112 
113     std::vector<GLColor> pixelData(width * height);
114     glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixelData.data());
115 
116     for (int i = 0; i < width * height; i += 16)
117     {
118         GLColor actualColor = pixelData[i];
119         EXPECT_NEAR(color.R, actualColor.R, 1);
120         EXPECT_NEAR(color.G, actualColor.G, 1);
121         EXPECT_NEAR(color.B, actualColor.B, 1);
122         EXPECT_NEAR(color.A, actualColor.A, 1);
123 
124         if (i % width == 0)
125             i += 16 * width;
126     }
127 }
128 
ensureDepthUnaffected()129 void DepthStencilTest::ensureDepthUnaffected()
130 {
131     ANGLE_GL_PROGRAM(depthTestProgram, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Blue());
132     glEnable(GL_DEPTH_TEST);
133     glDepthFunc(GL_EQUAL);
134     drawQuad(depthTestProgram, essl1_shaders::PositionAttrib(), 0.123f);
135     glDisable(GL_DEPTH_TEST);
136     ASSERT_GL_NO_ERROR();
137 
138     // Since depth shouldn't exist, the drawQuad above should succeed in turning the whole image
139     // blue.
140     ensureColor(GLColor::blue);
141 }
142 
ensureStencilUnaffected()143 void DepthStencilTest::ensureStencilUnaffected()
144 {
145     ANGLE_GL_PROGRAM(stencilTestProgram, essl1_shaders::vs::Passthrough(),
146                      essl1_shaders::fs::Green());
147     glEnable(GL_STENCIL_TEST);
148     glStencilFunc(GL_EQUAL, 0x1B, 0xFF);
149     drawQuad(stencilTestProgram, essl1_shaders::PositionAttrib(), 0.0f);
150     glDisable(GL_STENCIL_TEST);
151     ASSERT_GL_NO_ERROR();
152 
153     // Since stencil shouldn't exist, the drawQuad above should succeed in turning the whole image
154     // green.
155     ensureColor(GLColor::green);
156 }
157 
prepareSingleEmulatedWithPacked()158 void DepthStencilTest::prepareSingleEmulatedWithPacked()
159 {
160     const int w     = getWindowWidth();
161     const int h     = getWindowHeight();
162     const int whalf = w >> 1;
163     const int hhalf = h >> 1;
164 
165     // Clear to a random color, 0.75 depth and 0x36 stencil
166     Vector4 color1(0.1f, 0.2f, 0.3f, 0.4f);
167     GLColor color1RGB(color1);
168 
169     glClearColor(color1[0], color1[1], color1[2], color1[3]);
170     glClearDepthf(0.75f);
171     glClearStencil(0x36);
172     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
173     ASSERT_GL_NO_ERROR();
174 
175     // Verify color was cleared correctly.
176     EXPECT_PIXEL_COLOR_NEAR(0, 0, color1RGB, 1);
177 
178     // Use masked color to clear two channels of the image to a second color, 0.25 depth and 0x59
179     // stencil.
180     Vector4 color2(0.2f, 0.4f, 0.6f, 0.8f);
181     glClearColor(color2[0], color2[1], color2[2], color2[3]);
182     glClearDepthf(0.25f);
183     glClearStencil(0x59);
184     glColorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_FALSE);
185     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
186     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
187     ASSERT_GL_NO_ERROR();
188 
189     GLColor color2RGB(Vector4(color2[0], color1[1], color2[2], color1[3]));
190 
191     EXPECT_PIXEL_COLOR_NEAR(whalf, hhalf, color2RGB, 1);
192 
193     EXPECT_PIXEL_COLOR_NEAR(0, 0, color2RGB, 1);
194     EXPECT_PIXEL_COLOR_NEAR(w - 1, 0, color2RGB, 1);
195     EXPECT_PIXEL_COLOR_NEAR(0, h - 1, color2RGB, 1);
196     EXPECT_PIXEL_COLOR_NEAR(w - 1, h - 1, color2RGB, 1);
197 
198     // Use scissor to clear the center to a third color, 0.5 depth and 0xA9 stencil.
199     glEnable(GL_SCISSOR_TEST);
200     glScissor(whalf / 2, hhalf / 2, whalf, hhalf);
201 
202     Vector4 color3(0.3f, 0.5f, 0.7f, 0.9f);
203     GLColor color3RGB(color3);
204     glClearColor(color3[0], color3[1], color3[2], color3[3]);
205     glClearDepthf(0.5f);
206     glClearStencil(0xA9);
207     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
208     glDisable(GL_SCISSOR_TEST);
209     ASSERT_GL_NO_ERROR();
210 
211     EXPECT_PIXEL_COLOR_NEAR(whalf, hhalf, color3RGB, 1);
212 
213     EXPECT_PIXEL_COLOR_NEAR(0, 0, color2RGB, 1);
214     EXPECT_PIXEL_COLOR_NEAR(w - 1, 0, color2RGB, 1);
215     EXPECT_PIXEL_COLOR_NEAR(0, h - 1, color2RGB, 1);
216     EXPECT_PIXEL_COLOR_NEAR(w - 1, h - 1, color2RGB, 1);
217 
218     // Use scissor to draw to the right half of the image with a fourth color, 0.6 depth and 0x84
219     // stencil.
220     glEnable(GL_SCISSOR_TEST);
221     glScissor(whalf, 0, whalf, h);
222 
223     ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
224     glEnable(GL_STENCIL_TEST);
225     glStencilFunc(GL_ALWAYS, 0x84, 0xFF);
226     glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
227     glStencilMask(0xFF);
228     drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.2f);
229 
230     glDisable(GL_STENCIL_TEST);
231     glDisable(GL_SCISSOR_TEST);
232 }
233 
234 // Tests that clearing or rendering into a depth-only format doesn't affect stencil.
TEST_P(DepthStencilTest,DepthOnlyEmulatedWithPacked)235 TEST_P(DepthStencilTest, DepthOnlyEmulatedWithPacked)
236 {
237     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_OES_depth24"));
238 
239     bindColorDepthFBO();
240     prepareSingleEmulatedWithPacked();
241     ensureStencilUnaffected();
242 }
243 
244 // Tests that clearing or rendering into a stencil-only format doesn't affect depth.
TEST_P(DepthStencilTest,StencilOnlyEmulatedWithPacked)245 TEST_P(DepthStencilTest, StencilOnlyEmulatedWithPacked)
246 {
247     // http://anglebug.com/40096654
248     ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D9());
249     bindColorStencilFBO();
250     prepareSingleEmulatedWithPacked();
251     ensureDepthUnaffected();
252 }
253 
254 // Tests that drawing into stencil buffer along multiple render passes works.
TEST_P(DepthStencilTest,StencilOnlyDrawThenCopyThenDraw)255 TEST_P(DepthStencilTest, StencilOnlyDrawThenCopyThenDraw)
256 {
257     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
258     glUseProgram(drawColor);
259     GLint colorUniformLocation =
260         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
261     ASSERT_NE(colorUniformLocation, -1);
262 
263     bindColorStencilFBO();
264 
265     // Draw red once
266     glEnable(GL_STENCIL_TEST);
267     glStencilFunc(GL_ALWAYS, 0x55, 0xFF);
268     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
269     glStencilMask(0xFF);
270 
271     glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
272     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 1.0f);
273     ASSERT_GL_NO_ERROR();
274 
275     // Create a texture and copy color into it, this breaks the render pass.
276     GLTexture texture;
277     glBindTexture(GL_TEXTURE_2D, texture);
278     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, getWindowWidth(), getWindowHeight(), 0);
279 
280     // Draw green, expecting correct stencil.
281     glStencilFunc(GL_EQUAL, 0x55, 0xFF);
282     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
283 
284     glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
285     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 1.0f);
286     ASSERT_GL_NO_ERROR();
287 
288     // Verify that the texture is now green
289     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
290 
291     // For completeness, also verify that the copy texture is red
292     GLFramebuffer fbo;
293     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
294     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
295     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
296 
297     ASSERT_GL_NO_ERROR();
298 }
299 
300 // Tests that clearing depth/stencil followed by draw works when the depth/stencil attachment is a
301 // texture.
TEST_P(DepthStencilTestES3,ClearThenDraw)302 TEST_P(DepthStencilTestES3, ClearThenDraw)
303 {
304     GLFramebuffer FBO;
305     glBindFramebuffer(GL_FRAMEBUFFER, FBO);
306 
307     constexpr GLsizei kSize = 6;
308 
309     // Create framebuffer to draw into, with both color and depth attachments.
310     GLTexture color;
311     glBindTexture(GL_TEXTURE_2D, color);
312     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
313 
314     GLTexture depth;
315     glBindTexture(GL_TEXTURE_2D, depth);
316     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, kSize, kSize, 0, GL_DEPTH_STENCIL,
317                  GL_UNSIGNED_INT_24_8_OES, nullptr);
318 
319     GLFramebuffer fbo;
320     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
321     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
322     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depth, 0);
323     ASSERT_GL_NO_ERROR();
324 
325     // Set viewport and clear depth/stencil
326     glViewport(0, 0, kSize, kSize);
327     glClearDepthf(1);
328     glClearStencil(0x55);
329     glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
330 
331     // If depth is not cleared to 1, rendering would fail.
332     glEnable(GL_DEPTH_TEST);
333     glDepthFunc(GL_LESS);
334 
335     // If stencil is not clear to 0x55, rendering would fail.
336     glEnable(GL_STENCIL_TEST);
337     glStencilFunc(GL_EQUAL, 0x55, 0xFF);
338     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
339     glStencilMask(0xFF);
340 
341     // Set up program
342     ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
343 
344     // Draw red
345     drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.0f);
346     ASSERT_GL_NO_ERROR();
347 
348     // Verify.
349     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
350     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::red);
351     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::red);
352     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::red);
353 }
354 
355 // Test that VK_EXT_load_op_none is working properly when
356 // one of the depth / stencil load op is none.
357 // This reproduces a deqp failure on ARM: angleproject:7370
TEST_P(DepthStencilTestES3,LoadStoreOpNoneExtension)358 TEST_P(DepthStencilTestES3, LoadStoreOpNoneExtension)
359 {
360     GLFramebuffer fbo;
361     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
362 
363     GLRenderbuffer colorRbo;
364     glBindRenderbuffer(GL_RENDERBUFFER, colorRbo);
365     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, getWindowWidth(), getWindowHeight());
366     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
367     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
368     glClear(GL_COLOR_BUFFER_BIT);
369 
370     GLRenderbuffer depthStencilBuffer;
371     glBindRenderbuffer(GL_RENDERBUFFER, depthStencilBuffer);
372     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, getWindowWidth(),
373                           getWindowHeight());
374     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
375                               depthStencilBuffer);
376 
377     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
378     ASSERT_GL_NO_ERROR();
379 
380     glClearDepthf(1.0f);
381     glClear(GL_DEPTH_BUFFER_BIT);
382     glClearStencil(0.0f);
383     glClear(GL_STENCIL_BUFFER_BIT);
384 
385     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
386 
387     // Draw a red quad, stencil enabled, depth disabled
388     // Depth Load Op: None. Depth Store Op: None.
389     // Stencil Load Op: Load. Stencil Store Op: Store.
390     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
391     GLint colorLocation = glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
392     ASSERT_NE(-1, colorLocation);
393 
394     glDisable(GL_BLEND);
395     glEnable(GL_STENCIL_TEST);
396     glStencilFunc(GL_LEQUAL, 0, ~0u);
397     glStencilOp(GL_KEEP, GL_INCR, GL_INCR);
398     glDisable(GL_DITHER);
399     glDisable(GL_DEPTH_TEST);
400 
401     glUseProgram(program);
402     glUniform4f(colorLocation, 1.0f, 0.0f, 0.0f, 1.0f);
403     drawQuad(program, "a_position", 0.5f);
404     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
405 
406     // Draw a green quad, stencil enabled, depth enabled.
407     // Depth Load Op: Load. Depth Store Op: Store.
408     // Stencil Load Op: Load. Stencil Store Op: Store.
409     glUniform4f(colorLocation, 0.0f, 1.0f, 0.0f, 1.0f);
410     glEnable(GL_DEPTH_TEST);
411     drawQuad(program, "a_position", 0.5f);
412     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
413 }
414 
compareDepth(uint32_t expected)415 void DepthStencilTestES3::compareDepth(uint32_t expected)
416 {
417     uint32_t pixel;
418     glReadPixels(0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, &pixel);
419     ASSERT_GL_NO_ERROR();
420 
421     // Right shift by 8 bits to only compare 24 depth bits
422     // and ignore 8 undefined bits.
423     pixel = pixel >> 8;
424 
425     EXPECT_NEAR(pixel, expected, 1);
426 }
427 
clearAndCompareDepth(GLfloat depth,uint32_t expected)428 void DepthStencilTestES3::clearAndCompareDepth(GLfloat depth, uint32_t expected)
429 {
430     glClearDepthf(depth);
431     glClear(GL_DEPTH_BUFFER_BIT);
432     compareDepth(expected);
433 }
434 
drawAndCompareDepth(GLProgram & program,GLfloat positionZ,uint32_t expected)435 void DepthStencilTestES3::drawAndCompareDepth(GLProgram &program,
436                                               GLfloat positionZ,
437                                               uint32_t expected)
438 {
439     glEnable(GL_DEPTH_TEST);
440     glDepthFunc(GL_ALWAYS);
441     drawQuad(program, essl3_shaders::PositionAttrib(), positionZ, 1.0f);
442     glDisable(GL_DEPTH_TEST);
443     compareDepth(expected);
444 }
445 
TEST_P(DepthStencilTestES3,ReadPixelsDepth24)446 TEST_P(DepthStencilTestES3, ReadPixelsDepth24)
447 {
448     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_depth24") ||
449                        !IsGLExtensionEnabled("GL_NV_read_depth"));
450 
451     // The test fails on native GLES on Android in glReadPixels
452     // with GL_INVALID_OPERATION due to the format/type combination
453     // not being supported.
454     ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());
455 
456     // Create GL_DEPTH_COMPONENT24 texture
457     GLTexture depthTexture;
458     glBindTexture(GL_TEXTURE_2D, depthTexture);
459     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, getWindowWidth(), getWindowHeight(), 0,
460                  GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
461 
462     // Set up framebuffer
463     GLFramebuffer depthFBO;
464     GLRenderbuffer depthRenderbuffer;
465 
466     glBindFramebuffer(GL_FRAMEBUFFER, depthFBO);
467 
468     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
469     glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
470     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, getWindowWidth(),
471                           getWindowHeight());
472     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
473                               depthRenderbuffer);
474 
475     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
476     ASSERT_GL_NO_ERROR();
477 
478     // Test clear
479     clearAndCompareDepth(0.0f, 0x0);
480     clearAndCompareDepth(0.125f, 0x200000);
481     clearAndCompareDepth(0.5f, 0x800000);
482     clearAndCompareDepth(1.0f, 0xffffff);
483 
484     // Test draw
485     ANGLE_GL_PROGRAM(depthTestProgram, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());
486     drawAndCompareDepth(depthTestProgram, 0.0f, 0x800000);
487     drawAndCompareDepth(depthTestProgram, 0.125f, 0x8fffff);
488     drawAndCompareDepth(depthTestProgram, 0.5f, 0xbfffff);
489     drawAndCompareDepth(depthTestProgram, 1.0f, 0xffffff);
490 
491     ASSERT_GL_NO_ERROR();
492 }
493 
494 // Tests that the stencil test is correctly handled when a framebuffer is cleared before that
495 // framebuffer's stencil attachment has been configured.
TEST_P(DepthStencilTestES3,FramebufferClearThenStencilAttachedThenStencilTestState)496 TEST_P(DepthStencilTestES3, FramebufferClearThenStencilAttachedThenStencilTestState)
497 {
498     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_read_stencil"));
499 
500     GLFramebuffer fbo;
501     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
502 
503     GLRenderbuffer colorRbo;
504     glBindRenderbuffer(GL_RENDERBUFFER, colorRbo);
505     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, getWindowWidth(), getWindowHeight());
506     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
507     glClearColor(0.f, 0.f, 0.f, 0.f);
508     glClear(GL_COLOR_BUFFER_BIT);
509 
510     GLRenderbuffer stencilRbo;
511     glBindRenderbuffer(GL_RENDERBUFFER, stencilRbo);
512     glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, getWindowWidth(), getWindowHeight());
513     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencilRbo);
514     glClearStencil(2);
515     glClear(GL_STENCIL_BUFFER_BIT);
516 
517     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
518     ASSERT_GL_NO_ERROR();
519 
520     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);
521     EXPECT_PIXEL_STENCIL_EQ(0, 0, 2);
522 
523     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
524 
525     GLint colorLocation = glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
526     ASSERT_NE(-1, colorLocation);
527 
528     glUseProgram(program);
529     glUniform4f(colorLocation, 1.0f, 0.0f, 0.0f, 1.0f);
530 
531     glEnable(GL_STENCIL_TEST);
532     glStencilFunc(GL_ALWAYS, 0, 0xFF);
533     glStencilOp(GL_KEEP, GL_INCR, GL_INCR);
534     drawQuad(program, "a_position", 0.5f);
535 
536     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
537     EXPECT_PIXEL_STENCIL_EQ(0, 0, 3);
538 }
539 
540 // Tests that the stencil test is correctly handled when both the stencil test state is configured
541 // and a framebuffer is cleared before that framebuffer's stencil attachment has been configured.
TEST_P(DepthStencilTestES3,StencilTestStateThenFramebufferClearThenStencilAttached)542 TEST_P(DepthStencilTestES3, StencilTestStateThenFramebufferClearThenStencilAttached)
543 {
544     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_read_stencil"));
545 
546     glEnable(GL_STENCIL_TEST);
547     glStencilFunc(GL_ALWAYS, 0, 0xFF);
548     glStencilOp(GL_KEEP, GL_INCR, GL_INCR);
549 
550     GLFramebuffer fbo;
551     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
552 
553     GLRenderbuffer colorRbo;
554     glBindRenderbuffer(GL_RENDERBUFFER, colorRbo);
555     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, getWindowWidth(), getWindowHeight());
556     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
557     glClearColor(0.f, 0.f, 0.f, 0.f);
558     glClear(GL_COLOR_BUFFER_BIT);
559 
560     GLRenderbuffer stencilRbo;
561     glBindRenderbuffer(GL_RENDERBUFFER, stencilRbo);
562     glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, getWindowWidth(), getWindowHeight());
563     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencilRbo);
564     glClearStencil(2);
565     glClear(GL_STENCIL_BUFFER_BIT);
566 
567     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
568     ASSERT_GL_NO_ERROR();
569 
570     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);
571     EXPECT_PIXEL_STENCIL_EQ(0, 0, 2);
572 
573     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
574 
575     GLint colorLocation = glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
576     ASSERT_NE(-1, colorLocation);
577 
578     glUseProgram(program);
579     glUniform4f(colorLocation, 1.0f, 0.0f, 0.0f, 1.0f);
580 
581     drawQuad(program, "a_position", 0.5f);
582 
583     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
584     EXPECT_PIXEL_STENCIL_EQ(0, 0, 3);
585 }
586 
587 // Tests that the stencil test is correctly handled when a framebuffer is cleared before that
588 // framebuffer's stencil attachment has been configured and the stencil test state is configured
589 // during framebuffer setup.
TEST_P(DepthStencilTestES3,FramebufferClearThenStencilTestStateThenStencilAttached)590 TEST_P(DepthStencilTestES3, FramebufferClearThenStencilTestStateThenStencilAttached)
591 {
592     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_read_stencil"));
593 
594     GLFramebuffer fbo;
595     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
596 
597     GLRenderbuffer colorRbo;
598     glBindRenderbuffer(GL_RENDERBUFFER, colorRbo);
599     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, getWindowWidth(), getWindowHeight());
600     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
601     glClearColor(0.f, 0.f, 0.f, 0.f);
602     glClear(GL_COLOR_BUFFER_BIT);
603 
604     glEnable(GL_STENCIL_TEST);
605     glStencilFunc(GL_ALWAYS, 0, 0xFF);
606     glStencilOp(GL_KEEP, GL_INCR, GL_INCR);
607 
608     GLRenderbuffer stencilRbo;
609     glBindRenderbuffer(GL_RENDERBUFFER, stencilRbo);
610     glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, getWindowWidth(), getWindowHeight());
611     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencilRbo);
612     glClearStencil(2);
613     glClear(GL_STENCIL_BUFFER_BIT);
614 
615     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
616     ASSERT_GL_NO_ERROR();
617 
618     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);
619     EXPECT_PIXEL_STENCIL_EQ(0, 0, 2);
620 
621     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
622 
623     GLint colorLocation = glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
624     ASSERT_NE(-1, colorLocation);
625 
626     glUseProgram(program);
627     glUniform4f(colorLocation, 1.0f, 0.0f, 0.0f, 1.0f);
628 
629     drawQuad(program, "a_position", 0.5f);
630 
631     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
632     EXPECT_PIXEL_STENCIL_EQ(0, 0, 3);
633 }
634 
635 // Tests that drawing with read-only depth/stencil followed by depth/stencil output (in two render
636 // passes) works.  Regression test for a synchronization bug in the Vulkan backend, caught by
637 // syncval VVL.
TEST_P(DepthStencilTestES3,ReadOnlyDepthStencilThenOutputDepthStencil)638 TEST_P(DepthStencilTestES3, ReadOnlyDepthStencilThenOutputDepthStencil)
639 {
640     constexpr GLsizei kSize = 64;
641 
642     // Create FBO with color, depth and stencil
643     GLTexture texture;
644     glBindTexture(GL_TEXTURE_2D, texture);
645     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
646 
647     GLRenderbuffer renderbuffer;
648     glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
649     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);
650 
651     GLFramebuffer framebuffer;
652     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
653     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
654     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
655                               renderbuffer);
656     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
657     ASSERT_GL_NO_ERROR();
658 
659     // Initialize depth/stencil
660     glEnable(GL_DEPTH_TEST);
661     glDepthFunc(GL_ALWAYS);
662 
663     glEnable(GL_STENCIL_TEST);
664     glStencilFunc(GL_ALWAYS, 0xAA, 0xFF);
665     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
666     glStencilMask(0xFF);
667 
668     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
669     glUseProgram(drawColor);
670     GLint colorUniformLocation =
671         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
672     ASSERT_NE(colorUniformLocation, -1);
673 
674     // Draw red with depth = 1 and stencil = 0xAA
675     glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
676     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 1);
677     ASSERT_GL_NO_ERROR();
678 
679     // Break the render pass by making a copy of the color texture.
680     GLTexture copyTex;
681     glBindTexture(GL_TEXTURE_2D, copyTex);
682     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
683     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, kSize / 2, kSize / 2);
684     ASSERT_GL_NO_ERROR();
685 
686     // Disable depth/stencil output and issue a draw call that's expected to pass depth/stencil.
687     glDepthFunc(GL_LESS);
688     glDepthMask(GL_FALSE);
689     glStencilFunc(GL_EQUAL, 0xAA, 0xFF);
690     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
691 
692     // Draw green
693     glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
694     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.95);
695     ASSERT_GL_NO_ERROR();
696 
697     // Break the render pass
698     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, kSize / 2, 0, 0, 0, kSize / 2, kSize / 2);
699     ASSERT_GL_NO_ERROR();
700 
701     // Draw again to start another render pass still with depth/stencil read-only
702     glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
703     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.95);
704     ASSERT_GL_NO_ERROR();
705 
706     // Break the render pass
707     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, kSize / 2, 0, 0, kSize / 2, kSize / 2);
708     ASSERT_GL_NO_ERROR();
709 
710     // Re-enable depth/stencil output and issue a draw call that's expected to pass depth/stencil.
711     glDepthMask(GL_TRUE);
712     glStencilFunc(GL_EQUAL, 0xAB, 0xF0);
713     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
714 
715     // Draw yellow
716     glUniform4f(colorUniformLocation, 1.0f, 1.0f, 0.0f, 1.0f);
717     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.95);
718     ASSERT_GL_NO_ERROR();
719 
720     // Break the render pass
721     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, kSize / 2, kSize / 2, 0, 0, kSize / 2, kSize / 2);
722     ASSERT_GL_NO_ERROR();
723 
724     GLFramebuffer readFramebuffer;
725     glBindFramebuffer(GL_READ_FRAMEBUFFER, readFramebuffer);
726     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, copyTex, 0);
727     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
728     EXPECT_PIXEL_COLOR_EQ(kSize / 2, 0, GLColor::green);
729     EXPECT_PIXEL_COLOR_EQ(0, kSize / 2, GLColor::blue);
730     EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::yellow);
731 }
732 
733 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND(
734     DepthStencilTest,
735     ES2_VULKAN().enable(Feature::ForceFallbackFormat),
736     ES2_VULKAN_SWIFTSHADER().enable(Feature::ForceFallbackFormat),
737     ES3_VULKAN().enable(Feature::ForceFallbackFormat),
738     ES3_VULKAN_SWIFTSHADER().enable(Feature::ForceFallbackFormat));
739 
740 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DepthStencilTestES3);
741 ANGLE_INSTANTIATE_TEST_ES3_AND(
742     DepthStencilTestES3,
743     ES3_VULKAN().enable(Feature::ForceFallbackFormat),
744     ES3_VULKAN().enable(Feature::DisallowMixedDepthStencilLoadOpNoneAndLoad),
745     ES3_VULKAN_SWIFTSHADER().enable(Feature::ForceFallbackFormat));
746 
747 }  // anonymous namespace
748