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