• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
9 #include "platform/FeaturesVk.h"
10 #include "test_utils/gl_raii.h"
11 #include "util/random_utils.h"
12 #include "util/shader_utils.h"
13 
14 using namespace angle;
15 
16 namespace
17 {
18 class ClearTestBase : public ANGLETest
19 {
20   protected:
ClearTestBase()21     ClearTestBase()
22     {
23         setWindowWidth(128);
24         setWindowHeight(128);
25         setConfigRedBits(8);
26         setConfigGreenBits(8);
27         setConfigBlueBits(8);
28         setConfigAlphaBits(8);
29         setConfigDepthBits(24);
30         setConfigStencilBits(8);
31     }
32 
testSetUp()33     void testSetUp() override
34     {
35         mFBOs.resize(2, 0);
36         glGenFramebuffers(2, mFBOs.data());
37 
38         ASSERT_GL_NO_ERROR();
39     }
40 
testTearDown()41     void testTearDown() override
42     {
43         if (!mFBOs.empty())
44         {
45             glDeleteFramebuffers(static_cast<GLsizei>(mFBOs.size()), mFBOs.data());
46         }
47 
48         if (!mTextures.empty())
49         {
50             glDeleteTextures(static_cast<GLsizei>(mTextures.size()), mTextures.data());
51         }
52     }
53 
54     std::vector<GLuint> mFBOs;
55     std::vector<GLuint> mTextures;
56 };
57 
58 class ClearTest : public ClearTestBase
59 {};
60 
61 class ClearTestES3 : public ClearTestBase
62 {
63   protected:
verifyDepth(float depthValue,uint32_t size)64     void verifyDepth(float depthValue, uint32_t size)
65     {
66         // Use a small shader to verify depth.
67         ANGLE_GL_PROGRAM(depthTestProgram, essl1_shaders::vs::Passthrough(),
68                          essl1_shaders::fs::Blue());
69         ANGLE_GL_PROGRAM(depthTestProgramFail, essl1_shaders::vs::Passthrough(),
70                          essl1_shaders::fs::Red());
71         glEnable(GL_DEPTH_TEST);
72         glDepthFunc(GL_LESS);
73         drawQuad(depthTestProgram, essl1_shaders::PositionAttrib(), depthValue * 2 - 1 - 0.01f);
74         drawQuad(depthTestProgramFail, essl1_shaders::PositionAttrib(), depthValue * 2 - 1 + 0.01f);
75         glDisable(GL_DEPTH_TEST);
76         ASSERT_GL_NO_ERROR();
77 
78         EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::blue, 1);
79         EXPECT_PIXEL_COLOR_NEAR(size - 1, 0, GLColor::blue, 1);
80         EXPECT_PIXEL_COLOR_NEAR(0, size - 1, GLColor::blue, 1);
81         EXPECT_PIXEL_COLOR_NEAR(size - 1, size - 1, GLColor::blue, 1);
82     }
83 
verifyStencil(uint32_t stencilValue,uint32_t size)84     void verifyStencil(uint32_t stencilValue, uint32_t size)
85     {
86         // Use another small shader to verify stencil.
87         ANGLE_GL_PROGRAM(stencilTestProgram, essl1_shaders::vs::Passthrough(),
88                          essl1_shaders::fs::Green());
89         glEnable(GL_STENCIL_TEST);
90         glStencilFunc(GL_EQUAL, stencilValue, 0xFF);
91         drawQuad(stencilTestProgram, essl1_shaders::PositionAttrib(), 0.0f);
92         glDisable(GL_STENCIL_TEST);
93         ASSERT_GL_NO_ERROR();
94 
95         EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::green, 1);
96         EXPECT_PIXEL_COLOR_NEAR(size - 1, 0, GLColor::green, 1);
97         EXPECT_PIXEL_COLOR_NEAR(0, size - 1, GLColor::green, 1);
98         EXPECT_PIXEL_COLOR_NEAR(size - 1, size - 1, GLColor::green, 1);
99     }
100 };
101 
102 class ClearTestRGB : public ANGLETest
103 {
104   protected:
ClearTestRGB()105     ClearTestRGB()
106     {
107         setWindowWidth(128);
108         setWindowHeight(128);
109         setConfigRedBits(8);
110         setConfigGreenBits(8);
111         setConfigBlueBits(8);
112     }
113 };
114 
115 // Each int parameter can have three values: don't clear, clear, or masked clear.  The bool
116 // parameter controls scissor.
117 using MaskedScissoredClearVariationsTestParams =
118     std::tuple<angle::PlatformParameters, int, int, int, bool>;
119 
ParseMaskedScissoredClearVariationsTestParams(const MaskedScissoredClearVariationsTestParams & params,bool * clearColor,bool * clearDepth,bool * clearStencil,bool * maskColor,bool * maskDepth,bool * maskStencil,bool * scissor)120 void ParseMaskedScissoredClearVariationsTestParams(
121     const MaskedScissoredClearVariationsTestParams &params,
122     bool *clearColor,
123     bool *clearDepth,
124     bool *clearStencil,
125     bool *maskColor,
126     bool *maskDepth,
127     bool *maskStencil,
128     bool *scissor)
129 {
130     int colorClearInfo   = std::get<1>(params);
131     int depthClearInfo   = std::get<2>(params);
132     int stencilClearInfo = std::get<3>(params);
133 
134     *clearColor   = colorClearInfo > 0;
135     *clearDepth   = depthClearInfo > 0;
136     *clearStencil = stencilClearInfo > 0;
137 
138     *maskColor   = colorClearInfo > 1;
139     *maskDepth   = depthClearInfo > 1;
140     *maskStencil = stencilClearInfo > 1;
141 
142     *scissor = std::get<4>(params);
143 }
144 
MaskedScissoredClearVariationsTestPrint(const::testing::TestParamInfo<MaskedScissoredClearVariationsTestParams> & paramsInfo)145 std::string MaskedScissoredClearVariationsTestPrint(
146     const ::testing::TestParamInfo<MaskedScissoredClearVariationsTestParams> &paramsInfo)
147 {
148     const MaskedScissoredClearVariationsTestParams &params = paramsInfo.param;
149     std::ostringstream out;
150 
151     out << std::get<0>(params);
152 
153     bool clearColor, clearDepth, clearStencil;
154     bool maskColor, maskDepth, maskStencil;
155     bool scissor;
156 
157     ParseMaskedScissoredClearVariationsTestParams(params, &clearColor, &clearDepth, &clearStencil,
158                                                   &maskColor, &maskDepth, &maskStencil, &scissor);
159 
160     if (scissor)
161     {
162         out << "_scissored";
163     }
164 
165     if (clearColor || clearDepth || clearStencil)
166     {
167         out << "_clear_";
168         if (clearColor)
169         {
170             out << "c";
171         }
172         if (clearDepth)
173         {
174             out << "d";
175         }
176         if (clearStencil)
177         {
178             out << "s";
179         }
180     }
181 
182     if (maskColor || maskDepth || maskStencil)
183     {
184         out << "_mask_";
185         if (maskColor)
186         {
187             out << "c";
188         }
189         if (maskDepth)
190         {
191             out << "d";
192         }
193         if (maskStencil)
194         {
195             out << "s";
196         }
197     }
198 
199     return out.str();
200 }
201 
202 class MaskedScissoredClearTestBase
203     : public ANGLETestWithParam<MaskedScissoredClearVariationsTestParams>
204 {
205   protected:
MaskedScissoredClearTestBase()206     MaskedScissoredClearTestBase()
207     {
208         setWindowWidth(128);
209         setWindowHeight(128);
210         setConfigRedBits(8);
211         setConfigGreenBits(8);
212         setConfigBlueBits(8);
213         setConfigAlphaBits(8);
214         setConfigDepthBits(24);
215         setConfigStencilBits(8);
216     }
217 
218     void maskedScissoredColorDepthStencilClear(
219         const MaskedScissoredClearVariationsTestParams &params);
220 
221     bool mHasDepth   = true;
222     bool mHasStencil = true;
223 };
224 
225 class MaskedScissoredClearTest : public MaskedScissoredClearTestBase
226 {};
227 
228 class VulkanClearTest : public MaskedScissoredClearTestBase
229 {
230   protected:
testSetUp()231     void testSetUp() override
232     {
233         glBindTexture(GL_TEXTURE_2D, mColorTexture);
234         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
235                      GL_UNSIGNED_BYTE, nullptr);
236 
237         // Setup Color/Stencil FBO with a stencil format that's emulated with packed depth/stencil.
238         glBindFramebuffer(GL_FRAMEBUFFER, mColorStencilFBO);
239 
240         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mColorTexture,
241                                0);
242         glBindRenderbuffer(GL_RENDERBUFFER, mStencilTexture);
243         glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, getWindowWidth(),
244                               getWindowHeight());
245         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
246                                   mStencilTexture);
247 
248         ASSERT_GL_NO_ERROR();
249 
250         // Note: GL_DEPTH_COMPONENT24 is not allowed in GLES2.
251         if (getClientMajorVersion() >= 3)
252         {
253             // Setup Color/Depth FBO with a depth format that's emulated with packed depth/stencil.
254             glBindFramebuffer(GL_FRAMEBUFFER, mColorDepthFBO);
255 
256             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
257                                    mColorTexture, 0);
258             glBindRenderbuffer(GL_RENDERBUFFER, mDepthTexture);
259             glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, getWindowWidth(),
260                                   getWindowHeight());
261             glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
262                                       mDepthTexture);
263         }
264 
265         ASSERT_GL_NO_ERROR();
266     }
267 
bindColorStencilFBO()268     void bindColorStencilFBO()
269     {
270         glBindFramebuffer(GL_FRAMEBUFFER, mColorStencilFBO);
271         mHasDepth = false;
272     }
273 
bindColorDepthFBO()274     void bindColorDepthFBO()
275     {
276         glBindFramebuffer(GL_FRAMEBUFFER, mColorDepthFBO);
277         mHasStencil = false;
278     }
279 
280     // Override a feature to force emulation of stencil-only and depth-only formats with a packed
281     // depth/stencil format
overrideFeaturesVk(FeaturesVk * featuresVk)282     void overrideFeaturesVk(FeaturesVk *featuresVk) override
283     {
284         featuresVk->overrideFeatures({"force_fallback_format"}, true);
285     }
286 
287   private:
288     GLFramebuffer mColorStencilFBO;
289     GLFramebuffer mColorDepthFBO;
290     GLTexture mColorTexture;
291     GLRenderbuffer mDepthTexture;
292     GLRenderbuffer mStencilTexture;
293 };
294 
295 // Test clearing the default framebuffer
TEST_P(ClearTest,DefaultFramebuffer)296 TEST_P(ClearTest, DefaultFramebuffer)
297 {
298     glClearColor(0.25f, 0.5f, 0.5f, 0.5f);
299     glClear(GL_COLOR_BUFFER_BIT);
300     EXPECT_PIXEL_NEAR(0, 0, 64, 128, 128, 128, 1.0);
301 }
302 
303 // Test clearing the default framebuffer with scissor and mask
304 // This forces down path that uses draw to do clear
TEST_P(ClearTest,EmptyScissor)305 TEST_P(ClearTest, EmptyScissor)
306 {
307     // These configs have bug that fails this test.
308     // These configs are unmaintained so skipping.
309     ANGLE_SKIP_TEST_IF(IsIntel() && IsD3D9());
310     ANGLE_SKIP_TEST_IF(IsOSX());
311     glClearColor(0.25f, 0.5f, 0.5f, 1.0f);
312     glClear(GL_COLOR_BUFFER_BIT);
313     glEnable(GL_SCISSOR_TEST);
314     glScissor(-10, 0, 5, 5);
315     glClearColor(0.5f, 0.25f, 0.75f, 0.5f);
316     glColorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_TRUE);
317     glClear(GL_COLOR_BUFFER_BIT);
318     glDisable(GL_SCISSOR_TEST);
319     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
320     EXPECT_PIXEL_NEAR(0, 0, 64, 128, 128, 255, 1.0);
321 }
322 
323 // Test clearing the RGB default framebuffer and verify that the alpha channel is not cleared
TEST_P(ClearTestRGB,DefaultFramebufferRGB)324 TEST_P(ClearTestRGB, DefaultFramebufferRGB)
325 {
326     // Some GPUs don't support RGB format default framebuffer,
327     // so skip if the back buffer has alpha bits.
328     EGLWindow *window          = getEGLWindow();
329     EGLDisplay display         = window->getDisplay();
330     EGLConfig config           = window->getConfig();
331     EGLint backbufferAlphaBits = 0;
332     eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &backbufferAlphaBits);
333     ANGLE_SKIP_TEST_IF(backbufferAlphaBits != 0);
334 
335     glClearColor(0.25f, 0.5f, 0.5f, 0.5f);
336     glClear(GL_COLOR_BUFFER_BIT);
337     EXPECT_PIXEL_NEAR(0, 0, 64, 128, 128, 255, 1.0);
338 }
339 
340 // Test clearing a RGBA8 Framebuffer
TEST_P(ClearTest,RGBA8Framebuffer)341 TEST_P(ClearTest, RGBA8Framebuffer)
342 {
343     glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
344 
345     GLTexture texture;
346 
347     glBindTexture(GL_TEXTURE_2D, texture);
348     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
349                  GL_UNSIGNED_BYTE, nullptr);
350     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
351 
352     glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
353     glClear(GL_COLOR_BUFFER_BIT);
354 
355     EXPECT_PIXEL_NEAR(0, 0, 128, 128, 128, 128, 1.0);
356 }
357 
358 // Test to validate that we can go from an RGBA framebuffer attachment, to an RGB one and still
359 // have a correct behavior after.
TEST_P(ClearTest,ChangeFramebufferAttachmentFromRGBAtoRGB)360 TEST_P(ClearTest, ChangeFramebufferAttachmentFromRGBAtoRGB)
361 {
362     // http://anglebug.com/2689
363     ANGLE_SKIP_TEST_IF(IsD3D9() || IsD3D11() || (IsOzone() && IsOpenGLES()));
364     ANGLE_SKIP_TEST_IF(IsOSX() && (IsNVIDIA() || IsIntel()) && IsDesktopOpenGL());
365     ANGLE_SKIP_TEST_IF(IsAndroid() && IsAdreno() && IsOpenGLES());
366 
367     ANGLE_GL_PROGRAM(program, angle::essl1_shaders::vs::Simple(),
368                      angle::essl1_shaders::fs::UniformColor());
369     setupQuadVertexBuffer(0.5f, 1.0f);
370     glUseProgram(program);
371     GLint positionLocation = glGetAttribLocation(program, angle::essl1_shaders::PositionAttrib());
372     ASSERT_NE(positionLocation, -1);
373     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
374     glEnableVertexAttribArray(positionLocation);
375 
376     GLint colorUniformLocation =
377         glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
378     ASSERT_NE(colorUniformLocation, -1);
379 
380     glUniform4f(colorUniformLocation, 1.0f, 1.0f, 1.0f, 0.5f);
381 
382     glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
383 
384     GLTexture texture;
385     glBindTexture(GL_TEXTURE_2D, texture);
386     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
387                  GL_UNSIGNED_BYTE, nullptr);
388     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
389 
390     // Initially clear to black.
391     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
392     glClear(GL_COLOR_BUFFER_BIT);
393 
394     // Clear with masked color.
395     glColorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_TRUE);
396     glClearColor(0.5f, 0.5f, 0.5f, 0.75f);
397     glClear(GL_COLOR_BUFFER_BIT);
398     ASSERT_GL_NO_ERROR();
399 
400     // So far so good, we have an RGBA framebuffer that we've cleared to 0.5 everywhere.
401     EXPECT_PIXEL_NEAR(0, 0, 128, 0, 128, 192, 1.0);
402 
403     // In the Vulkan backend, RGB textures are emulated with an RGBA texture format
404     // underneath and we keep a special mask to know that we shouldn't touch the alpha
405     // channel when we have that emulated texture. This test exists to validate that
406     // this mask gets updated correctly when the framebuffer attachment changes.
407     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, getWindowWidth(), getWindowHeight(), 0, GL_RGB,
408                  GL_UNSIGNED_BYTE, nullptr);
409     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
410     ASSERT_GL_NO_ERROR();
411 
412     glDrawArrays(GL_TRIANGLES, 0, 6);
413     ASSERT_GL_NO_ERROR();
414 
415     EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::magenta);
416 }
417 
418 // Test clearing a RGB8 Framebuffer with a color mask.
TEST_P(ClearTest,RGB8WithMaskFramebuffer)419 TEST_P(ClearTest, RGB8WithMaskFramebuffer)
420 {
421     glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
422 
423     GLTexture texture;
424 
425     glBindTexture(GL_TEXTURE_2D, texture);
426     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, getWindowWidth(), getWindowHeight(), 0, GL_RGB,
427                  GL_UNSIGNED_BYTE, nullptr);
428     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
429 
430     glClearColor(0.2f, 0.4f, 0.6f, 0.8f);
431     glClear(GL_COLOR_BUFFER_BIT);
432 
433     // Since there's no alpha, we expect to get 255 back instead of the clear value (204).
434     EXPECT_PIXEL_NEAR(0, 0, 51, 102, 153, 255, 1.0);
435 
436     glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);
437     glClearColor(0.1f, 0.3f, 0.5f, 0.7f);
438     glClear(GL_COLOR_BUFFER_BIT);
439 
440     // The blue channel was masked so its value should be unchanged.
441     EXPECT_PIXEL_NEAR(0, 0, 26, 77, 153, 255, 1.0);
442 
443     // Restore default.
444     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
445 }
446 
TEST_P(ClearTest,ClearIssue)447 TEST_P(ClearTest, ClearIssue)
448 {
449     glEnable(GL_DEPTH_TEST);
450     glDepthFunc(GL_LEQUAL);
451 
452     glClearColor(0.0, 1.0, 0.0, 1.0);
453     glClearDepthf(0.0);
454     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
455 
456     EXPECT_GL_NO_ERROR();
457 
458     glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
459 
460     GLRenderbuffer rbo;
461     glBindRenderbuffer(GL_RENDERBUFFER, rbo);
462     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB565, 16, 16);
463 
464     EXPECT_GL_NO_ERROR();
465 
466     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
467 
468     EXPECT_GL_NO_ERROR();
469 
470     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
471     glClearDepthf(1.0f);
472     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
473 
474     EXPECT_GL_NO_ERROR();
475 
476     glBindFramebuffer(GL_FRAMEBUFFER, 0);
477     glBindBuffer(GL_ARRAY_BUFFER, 0);
478 
479     ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
480     drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);
481 
482     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
483 }
484 
485 // Regression test for a bug where "glClearDepthf"'s argument was not clamped
486 // In GLES 2 they where declared as GLclampf and the behaviour is the same in GLES 3.2
TEST_P(ClearTest,ClearIsClamped)487 TEST_P(ClearTest, ClearIsClamped)
488 {
489     glClearDepthf(5.0f);
490 
491     GLfloat clear_depth;
492     glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clear_depth);
493     EXPECT_EQ(1.0f, clear_depth);
494 }
495 
496 // Regression test for a bug where "glDepthRangef"'s arguments were not clamped
497 // In GLES 2 they where declared as GLclampf and the behaviour is the same in GLES 3.2
TEST_P(ClearTest,DepthRangefIsClamped)498 TEST_P(ClearTest, DepthRangefIsClamped)
499 {
500     glDepthRangef(1.1f, -4.0f);
501 
502     GLfloat depth_range[2];
503     glGetFloatv(GL_DEPTH_RANGE, depth_range);
504     EXPECT_EQ(1.0f, depth_range[0]);
505     EXPECT_EQ(0.0f, depth_range[1]);
506 }
507 
508 // Test scissored clears on Depth16
TEST_P(ClearTest,Depth16Scissored)509 TEST_P(ClearTest, Depth16Scissored)
510 {
511     GLRenderbuffer renderbuffer;
512     glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
513     constexpr int kRenderbufferSize = 64;
514     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, kRenderbufferSize,
515                           kRenderbufferSize);
516 
517     GLFramebuffer fbo;
518     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
519     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer);
520 
521     glClearDepthf(0.0f);
522     glClear(GL_DEPTH_BUFFER_BIT);
523 
524     glEnable(GL_SCISSOR_TEST);
525     constexpr int kNumSteps = 13;
526     for (int ndx = 1; ndx < kNumSteps; ndx++)
527     {
528         float perc = static_cast<float>(ndx) / static_cast<float>(kNumSteps);
529         glScissor(0, 0, static_cast<int>(kRenderbufferSize * perc),
530                   static_cast<int>(kRenderbufferSize * perc));
531         glClearDepthf(perc);
532         glClear(GL_DEPTH_BUFFER_BIT);
533     }
534 }
535 
536 // Test scissored clears on Stencil8
TEST_P(ClearTest,Stencil8Scissored)537 TEST_P(ClearTest, Stencil8Scissored)
538 {
539     GLRenderbuffer renderbuffer;
540     glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
541     constexpr int kRenderbufferSize = 64;
542     glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, kRenderbufferSize, kRenderbufferSize);
543 
544     GLFramebuffer fbo;
545     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
546     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuffer);
547 
548     glClearStencil(0);
549     glClear(GL_STENCIL_BUFFER_BIT);
550 
551     glEnable(GL_SCISSOR_TEST);
552     constexpr int kNumSteps = 13;
553     for (int ndx = 1; ndx < kNumSteps; ndx++)
554     {
555         float perc = static_cast<float>(ndx) / static_cast<float>(kNumSteps);
556         glScissor(0, 0, static_cast<int>(kRenderbufferSize * perc),
557                   static_cast<int>(kRenderbufferSize * perc));
558         glClearStencil(static_cast<int>(perc * 255.0f));
559         glClear(GL_STENCIL_BUFFER_BIT);
560     }
561 }
562 
563 // Covers a bug in the Vulkan back-end where starting a new command buffer in
564 // the masked clear would not trigger descriptor sets to be re-bound.
TEST_P(ClearTest,MaskedClearThenDrawWithUniform)565 TEST_P(ClearTest, MaskedClearThenDrawWithUniform)
566 {
567     // Initialize a program with a uniform.
568     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
569     glUseProgram(program);
570 
571     GLint uniLoc = glGetUniformLocation(program, essl1_shaders::ColorUniform());
572     ASSERT_NE(-1, uniLoc);
573     glUniform4f(uniLoc, 0.0f, 1.0f, 0.0f, 1.0f);
574 
575     // Initialize position attribute.
576     GLint posLoc = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
577     ASSERT_NE(-1, posLoc);
578     setupQuadVertexBuffer(0.5f, 1.0f);
579     glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
580     glEnableVertexAttribArray(posLoc);
581 
582     // Initialize a simple FBO.
583     constexpr GLsizei kSize = 2;
584     GLTexture clearTexture;
585     glBindTexture(GL_TEXTURE_2D, clearTexture);
586     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
587 
588     GLFramebuffer fbo;
589     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
590     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, clearTexture, 0);
591 
592     glViewport(0, 0, kSize, kSize);
593 
594     // Clear and draw to flush out dirty bits.
595     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
596     glClear(GL_COLOR_BUFFER_BIT);
597 
598     glDrawArrays(GL_TRIANGLES, 0, 6);
599 
600     // Flush to trigger a new serial.
601     glFlush();
602 
603     // Enable color mask and draw again to trigger the bug.
604     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
605     glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
606     glClear(GL_COLOR_BUFFER_BIT);
607 
608     glDrawArrays(GL_TRIANGLES, 0, 6);
609 
610     ASSERT_GL_NO_ERROR();
611     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
612 }
613 
614 // Test that clearing all buffers through glClearColor followed by a clear of a specific buffer
615 // clears to the correct values.
TEST_P(ClearTestES3,ClearMultipleAttachmentsFollowedBySpecificOne)616 TEST_P(ClearTestES3, ClearMultipleAttachmentsFollowedBySpecificOne)
617 {
618     // http://anglebug.com/4092
619     ANGLE_SKIP_TEST_IF(isSwiftshader());
620     constexpr uint32_t kSize            = 16;
621     constexpr uint32_t kAttachmentCount = 4;
622     std::vector<unsigned char> pixelData(kSize * kSize * 4, 255);
623 
624     glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
625 
626     GLTexture textures[kAttachmentCount];
627     GLenum drawBuffers[kAttachmentCount];
628     GLColor clearValues[kAttachmentCount];
629 
630     for (uint32_t i = 0; i < kAttachmentCount; ++i)
631     {
632         glBindTexture(GL_TEXTURE_2D, textures[i]);
633         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
634                      pixelData.data());
635         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, textures[i],
636                                0);
637         drawBuffers[i] = GL_COLOR_ATTACHMENT0 + i;
638 
639         clearValues[i].R = static_cast<GLubyte>(1 + i * 20);
640         clearValues[i].G = static_cast<GLubyte>(7 + i * 20);
641         clearValues[i].B = static_cast<GLubyte>(12 + i * 20);
642         clearValues[i].A = static_cast<GLubyte>(16 + i * 20);
643     }
644 
645     glDrawBuffers(kAttachmentCount, drawBuffers);
646 
647     ASSERT_GL_NO_ERROR();
648     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);
649 
650     // Clear all targets.
651     angle::Vector4 clearColor = clearValues[0].toNormalizedVector();
652     glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
653     glClear(GL_COLOR_BUFFER_BIT);
654     ASSERT_GL_NO_ERROR();
655 
656     // Clear odd targets individually.
657     for (uint32_t i = 1; i < kAttachmentCount; i += 2)
658     {
659         clearColor = clearValues[i].toNormalizedVector();
660         glClearBufferfv(GL_COLOR, i, clearColor.data());
661     }
662 
663     // Even attachments should be cleared to color 0, while odd attachments are cleared to their
664     // respective color.
665     for (uint32_t i = 0; i < kAttachmentCount; ++i)
666     {
667         glReadBuffer(GL_COLOR_ATTACHMENT0 + i);
668         ASSERT_GL_NO_ERROR();
669 
670         uint32_t clearIndex   = i % 2 == 0 ? 0 : i;
671         const GLColor &expect = clearValues[clearIndex];
672 
673         EXPECT_PIXEL_COLOR_EQ(0, 0, expect);
674         EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, expect);
675         EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, expect);
676         EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, expect);
677     }
678 }
679 
680 // Test that clearing each render target individually works.  In the Vulkan backend, this should be
681 // done in a single render pass.
TEST_P(ClearTestES3,ClearMultipleAttachmentsIndividually)682 TEST_P(ClearTestES3, ClearMultipleAttachmentsIndividually)
683 {
684     constexpr uint32_t kSize             = 16;
685     constexpr uint32_t kAttachmentCount  = 2;
686     constexpr float kDepthClearValue     = 0.125f;
687     constexpr int32_t kStencilClearValue = 0x67;
688     std::vector<unsigned char> pixelData(kSize * kSize * 4, 255);
689 
690     glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
691 
692     GLTexture textures[kAttachmentCount];
693     GLRenderbuffer depthStencil;
694     GLenum drawBuffers[kAttachmentCount];
695     GLColor clearValues[kAttachmentCount];
696 
697     for (uint32_t i = 0; i < kAttachmentCount; ++i)
698     {
699         glBindTexture(GL_TEXTURE_2D, textures[i]);
700         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
701                      pixelData.data());
702         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, textures[i],
703                                0);
704         drawBuffers[i] = GL_COLOR_ATTACHMENT0 + i;
705 
706         clearValues[i].R = static_cast<GLubyte>(1 + i * 20);
707         clearValues[i].G = static_cast<GLubyte>(7 + i * 20);
708         clearValues[i].B = static_cast<GLubyte>(12 + i * 20);
709         clearValues[i].A = static_cast<GLubyte>(16 + i * 20);
710     }
711 
712     glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
713     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);
714     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
715                               depthStencil);
716 
717     glDrawBuffers(kAttachmentCount, drawBuffers);
718 
719     ASSERT_GL_NO_ERROR();
720     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);
721 
722     for (uint32_t i = 0; i < kAttachmentCount; ++i)
723     {
724         glClearBufferfv(GL_COLOR, i, clearValues[i].toNormalizedVector().data());
725     }
726 
727     glClearBufferfv(GL_DEPTH, 0, &kDepthClearValue);
728     glClearBufferiv(GL_STENCIL, 0, &kStencilClearValue);
729     ASSERT_GL_NO_ERROR();
730 
731     for (uint32_t i = 0; i < kAttachmentCount; ++i)
732     {
733         glReadBuffer(GL_COLOR_ATTACHMENT0 + i);
734         ASSERT_GL_NO_ERROR();
735 
736         const GLColor &expect = clearValues[i];
737 
738         EXPECT_PIXEL_COLOR_EQ(0, 0, expect);
739         EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, expect);
740         EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, expect);
741         EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, expect);
742     }
743 
744     glReadBuffer(GL_COLOR_ATTACHMENT0);
745     for (uint32_t i = 1; i < kAttachmentCount; ++i)
746         drawBuffers[i] = GL_NONE;
747     glDrawBuffers(kAttachmentCount, drawBuffers);
748 
749     verifyDepth(kDepthClearValue, kSize);
750     verifyStencil(kStencilClearValue, kSize);
751 }
752 
753 // Test that clearing multiple attachments in the presence of a color mask, scissor or both
754 // correctly clears all the attachments.
TEST_P(ClearTestES3,MaskedScissoredClearMultipleAttachments)755 TEST_P(ClearTestES3, MaskedScissoredClearMultipleAttachments)
756 {
757     constexpr uint32_t kSize            = 16;
758     constexpr uint32_t kAttachmentCount = 2;
759     std::vector<unsigned char> pixelData(kSize * kSize * 4, 255);
760 
761     glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
762 
763     GLTexture textures[kAttachmentCount];
764     GLenum drawBuffers[kAttachmentCount];
765 
766     for (uint32_t i = 0; i < kAttachmentCount; ++i)
767     {
768         glBindTexture(GL_TEXTURE_2D, textures[i]);
769         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
770                      pixelData.data());
771         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, textures[i],
772                                0);
773         drawBuffers[i] = GL_COLOR_ATTACHMENT0 + i;
774     }
775 
776     glDrawBuffers(kAttachmentCount, drawBuffers);
777 
778     ASSERT_GL_NO_ERROR();
779     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);
780 
781     // Masked clear
782     GLColor clearColorMasked(31, 63, 255, 191);
783     angle::Vector4 clearColor = GLColor(31, 63, 127, 191).toNormalizedVector();
784 
785     glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);
786     glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
787     glClear(GL_COLOR_BUFFER_BIT);
788     ASSERT_GL_NO_ERROR();
789 
790     // All attachments should be cleared, with the blue channel untouched
791     for (uint32_t i = 0; i < kAttachmentCount; ++i)
792     {
793         glReadBuffer(GL_COLOR_ATTACHMENT0 + i);
794         ASSERT_GL_NO_ERROR();
795 
796         EXPECT_PIXEL_COLOR_EQ(0, 0, clearColorMasked);
797         EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, clearColorMasked);
798         EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, clearColorMasked);
799         EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, clearColorMasked);
800         EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, clearColorMasked);
801     }
802 
803     // Masked scissored clear
804     GLColor clearColorMaskedScissored(63, 127, 255, 31);
805     clearColor = GLColor(63, 127, 191, 31).toNormalizedVector();
806 
807     glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
808     glEnable(GL_SCISSOR_TEST);
809     glScissor(kSize / 6, kSize / 6, kSize / 3, kSize / 3);
810     glClear(GL_COLOR_BUFFER_BIT);
811     ASSERT_GL_NO_ERROR();
812 
813     // The corners should keep the previous value while the center is cleared, except its blue
814     // channel.
815     for (uint32_t i = 0; i < kAttachmentCount; ++i)
816     {
817         glReadBuffer(GL_COLOR_ATTACHMENT0 + i);
818         ASSERT_GL_NO_ERROR();
819 
820         EXPECT_PIXEL_COLOR_EQ(0, 0, clearColorMasked);
821         EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, clearColorMasked);
822         EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, clearColorMasked);
823         EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, clearColorMasked);
824         EXPECT_PIXEL_COLOR_EQ(kSize / 3, 2 * kSize / 3, clearColorMasked);
825         EXPECT_PIXEL_COLOR_EQ(2 * kSize / 3, kSize / 3, clearColorMasked);
826         EXPECT_PIXEL_COLOR_EQ(2 * kSize / 3, 2 * kSize / 3, clearColorMasked);
827 
828         EXPECT_PIXEL_COLOR_EQ(kSize / 3, kSize / 3, clearColorMaskedScissored);
829     }
830 
831     // Scissored clear
832     GLColor clearColorScissored(127, 191, 31, 63);
833     clearColor = GLColor(127, 191, 31, 63).toNormalizedVector();
834 
835     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
836     glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
837     glClear(GL_COLOR_BUFFER_BIT);
838     ASSERT_GL_NO_ERROR();
839 
840     // The corners should keep the old value while all channels of the center are cleared.
841     for (uint32_t i = 0; i < kAttachmentCount; ++i)
842     {
843         glReadBuffer(GL_COLOR_ATTACHMENT0 + i);
844         ASSERT_GL_NO_ERROR();
845 
846         EXPECT_PIXEL_COLOR_EQ(0, 0, clearColorMasked);
847         EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, clearColorMasked);
848         EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, clearColorMasked);
849         EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, clearColorMasked);
850         EXPECT_PIXEL_COLOR_EQ(kSize / 3, 2 * kSize / 3, clearColorMasked);
851         EXPECT_PIXEL_COLOR_EQ(2 * kSize / 3, kSize / 3, clearColorMasked);
852         EXPECT_PIXEL_COLOR_EQ(2 * kSize / 3, 2 * kSize / 3, clearColorMasked);
853 
854         EXPECT_PIXEL_COLOR_EQ(kSize / 3, kSize / 3, clearColorScissored);
855     }
856 }
857 
858 // Test clearing multiple attachments in the presence of an indexed color mask.
TEST_P(ClearTestES3,MaskedIndexedClearMultipleAttachments)859 TEST_P(ClearTestES3, MaskedIndexedClearMultipleAttachments)
860 {
861     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_draw_buffers_indexed"));
862 
863     constexpr uint32_t kSize            = 16;
864     constexpr uint32_t kAttachmentCount = 4;
865     std::vector<unsigned char> pixelData(kSize * kSize * 4, 255);
866 
867     glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
868 
869     GLTexture textures[kAttachmentCount];
870     GLenum drawBuffers[kAttachmentCount];
871 
872     for (uint32_t i = 0; i < kAttachmentCount; ++i)
873     {
874         glBindTexture(GL_TEXTURE_2D, textures[i]);
875         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
876                      pixelData.data());
877         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, textures[i],
878                                0);
879         drawBuffers[i] = GL_COLOR_ATTACHMENT0 + i;
880     }
881 
882     glDrawBuffers(kAttachmentCount, drawBuffers);
883 
884     ASSERT_GL_NO_ERROR();
885     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);
886 
887     // Masked clear
888     GLColor clearColorMasked(31, 63, 255, 191);
889     angle::Vector4 clearColor = GLColor(31, 63, 127, 191).toNormalizedVector();
890 
891     // Block blue channel for all attachements
892     glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);
893 
894     // Unblock blue channel for attachments 0 and 1
895     glColorMaskiOES(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
896     glColorMaskiOES(1, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
897 
898     glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
899     glClear(GL_COLOR_BUFFER_BIT);
900     ASSERT_GL_NO_ERROR();
901 
902     // All attachments should be cleared, with the blue channel untouched for all attachments but 1.
903     for (uint32_t i = 0; i < kAttachmentCount; ++i)
904     {
905         glReadBuffer(GL_COLOR_ATTACHMENT0 + i);
906         ASSERT_GL_NO_ERROR();
907 
908         const GLColor attachmentColor = (i > 1) ? clearColorMasked : clearColor;
909         EXPECT_PIXEL_COLOR_EQ(0, 0, attachmentColor);
910         EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, attachmentColor);
911         EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, attachmentColor);
912         EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, attachmentColor);
913         EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, attachmentColor);
914     }
915 }
916 
917 // Test that clearing multiple attachments of different nature (float, int and uint) in the
918 // presence of a color mask works correctly.  In the Vulkan backend, this exercises clearWithDraw
919 // and the relevant internal shaders.
TEST_P(ClearTestES3,MaskedClearHeterogeneousAttachments)920 TEST_P(ClearTestES3, MaskedClearHeterogeneousAttachments)
921 {
922     constexpr uint32_t kSize                              = 16;
923     constexpr uint32_t kAttachmentCount                   = 3;
924     constexpr float kDepthClearValue                      = 0.256f;
925     constexpr int32_t kStencilClearValue                  = 0x1D;
926     constexpr GLenum kAttachmentFormats[kAttachmentCount] = {
927         GL_RGBA8,
928         GL_RGBA8I,
929         GL_RGBA8UI,
930     };
931     constexpr GLenum kDataFormats[kAttachmentCount] = {
932         GL_RGBA,
933         GL_RGBA_INTEGER,
934         GL_RGBA_INTEGER,
935     };
936     constexpr GLenum kDataTypes[kAttachmentCount] = {
937         GL_UNSIGNED_BYTE,
938         GL_BYTE,
939         GL_UNSIGNED_BYTE,
940     };
941 
942     std::vector<unsigned char> pixelData(kSize * kSize * 4, 0);
943 
944     glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
945 
946     GLTexture textures[kAttachmentCount];
947     GLRenderbuffer depthStencil;
948     GLenum drawBuffers[kAttachmentCount];
949 
950     for (uint32_t i = 0; i < kAttachmentCount; ++i)
951     {
952         glBindTexture(GL_TEXTURE_2D, textures[i]);
953         glTexImage2D(GL_TEXTURE_2D, 0, kAttachmentFormats[i], kSize, kSize, 0, kDataFormats[i],
954                      kDataTypes[i], pixelData.data());
955         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, textures[i],
956                                0);
957         drawBuffers[i] = GL_COLOR_ATTACHMENT0 + i;
958     }
959 
960     glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
961     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);
962     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
963                               depthStencil);
964 
965     glDrawBuffers(kAttachmentCount, drawBuffers);
966 
967     ASSERT_GL_NO_ERROR();
968     EXPECT_PIXEL_EQ(0, 0, 0, 0, 0, 0);
969 
970     // Mask out red for all clears
971     glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE);
972 
973     glClearBufferfv(GL_DEPTH, 0, &kDepthClearValue);
974     glClearBufferiv(GL_STENCIL, 0, &kStencilClearValue);
975 
976     GLColor clearValuef = {25, 50, 75, 100};
977     glClearBufferfv(GL_COLOR, 0, clearValuef.toNormalizedVector().data());
978 
979     int clearValuei[4] = {10, -20, 30, -40};
980     glClearBufferiv(GL_COLOR, 1, clearValuei);
981 
982     uint32_t clearValueui[4] = {50, 60, 70, 80};
983     glClearBufferuiv(GL_COLOR, 2, clearValueui);
984 
985     ASSERT_GL_NO_ERROR();
986 
987     {
988         glReadBuffer(GL_COLOR_ATTACHMENT0);
989         ASSERT_GL_NO_ERROR();
990 
991         GLColor expect = clearValuef;
992         expect.R       = 0;
993 
994         EXPECT_PIXEL_COLOR_EQ(0, 0, expect);
995         EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, expect);
996         EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, expect);
997         EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, expect);
998     }
999 
1000     {
1001         glReadBuffer(GL_COLOR_ATTACHMENT1);
1002         ASSERT_GL_NO_ERROR();
1003 
1004         EXPECT_PIXEL_8I(0, 0, 0, clearValuei[1], clearValuei[2], clearValuei[3]);
1005         EXPECT_PIXEL_8I(0, kSize - 1, 0, clearValuei[1], clearValuei[2], clearValuei[3]);
1006         EXPECT_PIXEL_8I(kSize - 1, 0, 0, clearValuei[1], clearValuei[2], clearValuei[3]);
1007         EXPECT_PIXEL_8I(kSize - 1, kSize - 1, 0, clearValuei[1], clearValuei[2], clearValuei[3]);
1008     }
1009 
1010     {
1011         glReadBuffer(GL_COLOR_ATTACHMENT2);
1012         ASSERT_GL_NO_ERROR();
1013 
1014         EXPECT_PIXEL_8UI(0, 0, 0, clearValueui[1], clearValueui[2], clearValueui[3]);
1015         EXPECT_PIXEL_8UI(0, kSize - 1, 0, clearValueui[1], clearValueui[2], clearValueui[3]);
1016         EXPECT_PIXEL_8UI(kSize - 1, 0, 0, clearValueui[1], clearValueui[2], clearValueui[3]);
1017         EXPECT_PIXEL_8UI(kSize - 1, kSize - 1, 0, clearValueui[1], clearValueui[2],
1018                          clearValueui[3]);
1019     }
1020 
1021     glReadBuffer(GL_COLOR_ATTACHMENT0);
1022     for (uint32_t i = 1; i < kAttachmentCount; ++i)
1023         drawBuffers[i] = GL_NONE;
1024     glDrawBuffers(kAttachmentCount, drawBuffers);
1025 
1026     verifyDepth(kDepthClearValue, kSize);
1027     verifyStencil(kStencilClearValue, kSize);
1028 }
1029 
1030 // This tests a bug where in a masked clear when calling "ClearBuffer", we would
1031 // mistakenly clear every channel (including the masked-out ones)
TEST_P(ClearTestES3,MaskedClearBufferBug)1032 TEST_P(ClearTestES3, MaskedClearBufferBug)
1033 {
1034     // TODO(syoussefi): Qualcomm driver crashes in the presence of VK_ATTACHMENT_UNUSED.
1035     // http://anglebug.com/3423
1036     ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
1037 
1038     unsigned char pixelData[] = {255, 255, 255, 255};
1039 
1040     glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
1041 
1042     GLTexture textures[2];
1043 
1044     glBindTexture(GL_TEXTURE_2D, textures[0]);
1045     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData);
1046     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
1047 
1048     glBindTexture(GL_TEXTURE_2D, textures[1]);
1049     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData);
1050     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, textures[1], 0);
1051 
1052     ASSERT_GL_NO_ERROR();
1053     EXPECT_PIXEL_EQ(0, 0, 255, 255, 255, 255);
1054 
1055     float clearValue[]   = {0, 0.5f, 0.5f, 1.0f};
1056     GLenum drawBuffers[] = {GL_NONE, GL_COLOR_ATTACHMENT1};
1057     glDrawBuffers(2, drawBuffers);
1058     glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);
1059     glClearBufferfv(GL_COLOR, 1, clearValue);
1060 
1061     ASSERT_GL_NO_ERROR();
1062     EXPECT_PIXEL_EQ(0, 0, 255, 255, 255, 255);
1063 
1064     glReadBuffer(GL_COLOR_ATTACHMENT1);
1065     ASSERT_GL_NO_ERROR();
1066 
1067     EXPECT_PIXEL_NEAR(0, 0, 0, 127, 255, 255, 1);
1068 }
1069 
TEST_P(ClearTestES3,BadFBOSerialBug)1070 TEST_P(ClearTestES3, BadFBOSerialBug)
1071 {
1072     // First make a simple framebuffer, and clear it to green
1073     glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
1074 
1075     GLTexture textures[2];
1076 
1077     glBindTexture(GL_TEXTURE_2D, textures[0]);
1078     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
1079     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
1080 
1081     GLenum drawBuffers[] = {GL_COLOR_ATTACHMENT0};
1082     glDrawBuffers(1, drawBuffers);
1083 
1084     float clearValues1[] = {0.0f, 1.0f, 0.0f, 1.0f};
1085     glClearBufferfv(GL_COLOR, 0, clearValues1);
1086 
1087     ASSERT_GL_NO_ERROR();
1088     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1089 
1090     // Next make a second framebuffer, and draw it to red
1091     // (Triggers bad applied render target serial)
1092     GLFramebuffer fbo2;
1093     glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
1094     ASSERT_GL_NO_ERROR();
1095 
1096     glBindTexture(GL_TEXTURE_2D, textures[1]);
1097     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
1098     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
1099 
1100     glDrawBuffers(1, drawBuffers);
1101 
1102     ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
1103     drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);
1104 
1105     ASSERT_GL_NO_ERROR();
1106     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1107 
1108     // Check that the first framebuffer is still green.
1109     glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
1110     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1111 }
1112 
1113 // Test that SRGB framebuffers clear to the linearized clear color
TEST_P(ClearTestES3,SRGBClear)1114 TEST_P(ClearTestES3, SRGBClear)
1115 {
1116     // First make a simple framebuffer, and clear it
1117     glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
1118 
1119     GLTexture texture;
1120 
1121     glBindTexture(GL_TEXTURE_2D, texture);
1122     glTexStorage2D(GL_TEXTURE_2D, 1, GL_SRGB8_ALPHA8, getWindowWidth(), getWindowHeight());
1123     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
1124 
1125     glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
1126     glClear(GL_COLOR_BUFFER_BIT);
1127 
1128     EXPECT_PIXEL_NEAR(0, 0, 188, 188, 188, 128, 1.0);
1129 }
1130 
1131 // Test that framebuffers with mixed SRGB/Linear attachments clear to the correct color for each
1132 // attachment
TEST_P(ClearTestES3,MixedSRGBClear)1133 TEST_P(ClearTestES3, MixedSRGBClear)
1134 {
1135     glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
1136 
1137     GLTexture textures[2];
1138 
1139     glBindTexture(GL_TEXTURE_2D, textures[0]);
1140     glTexStorage2D(GL_TEXTURE_2D, 1, GL_SRGB8_ALPHA8, getWindowWidth(), getWindowHeight());
1141     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
1142 
1143     glBindTexture(GL_TEXTURE_2D, textures[1]);
1144     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
1145     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, textures[1], 0);
1146 
1147     GLenum drawBuffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
1148     glDrawBuffers(2, drawBuffers);
1149 
1150     // Clear both textures
1151     glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
1152     glClear(GL_COLOR_BUFFER_BIT);
1153 
1154     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1155     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, 0, 0);
1156 
1157     // Check value of texture0
1158     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
1159     EXPECT_PIXEL_NEAR(0, 0, 188, 188, 188, 128, 1.0);
1160 
1161     // Check value of texture1
1162     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
1163     EXPECT_PIXEL_NEAR(0, 0, 128, 128, 128, 128, 1.0);
1164 }
1165 
1166 // This test covers a D3D11 bug where calling ClearRenderTargetView sometimes wouldn't sync
1167 // before a draw call. The test draws small quads to a larger FBO (the default back buffer).
1168 // Before each blit to the back buffer it clears the quad to a certain color using
1169 // ClearBufferfv to give a solid color. The sync problem goes away if we insert a call to
1170 // flush or finish after ClearBufferfv or each draw.
TEST_P(ClearTestES3,RepeatedClear)1171 TEST_P(ClearTestES3, RepeatedClear)
1172 {
1173     // Fails on 431.02 driver. http://anglebug.com/3748
1174     ANGLE_SKIP_TEST_IF(IsWindows() && IsNVIDIA() && IsVulkan());
1175     ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
1176 
1177     constexpr char kVS[] =
1178         "#version 300 es\n"
1179         "in highp vec2 position;\n"
1180         "out highp vec2 v_coord;\n"
1181         "void main(void)\n"
1182         "{\n"
1183         "    gl_Position = vec4(position, 0, 1);\n"
1184         "    vec2 texCoord = (position * 0.5) + 0.5;\n"
1185         "    v_coord = texCoord;\n"
1186         "}\n";
1187 
1188     constexpr char kFS[] =
1189         "#version 300 es\n"
1190         "in highp vec2 v_coord;\n"
1191         "out highp vec4 color;\n"
1192         "uniform sampler2D tex;\n"
1193         "void main()\n"
1194         "{\n"
1195         "    color = texture(tex, v_coord);\n"
1196         "}\n";
1197 
1198     ANGLE_GL_PROGRAM(program, kVS, kFS);
1199 
1200     mTextures.resize(1, 0);
1201     glGenTextures(1, mTextures.data());
1202 
1203     GLenum format           = GL_RGBA8;
1204     const int numRowsCols   = 3;
1205     const int cellSize      = 32;
1206     const int fboSize       = cellSize;
1207     const int backFBOSize   = cellSize * numRowsCols;
1208     const float fmtValueMin = 0.0f;
1209     const float fmtValueMax = 1.0f;
1210 
1211     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1212     glTexStorage2D(GL_TEXTURE_2D, 1, format, fboSize, fboSize);
1213     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1214     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1215     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1216     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1217     ASSERT_GL_NO_ERROR();
1218 
1219     glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
1220     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0);
1221     ASSERT_GL_NO_ERROR();
1222 
1223     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1224 
1225     // larger fbo bound -- clear to transparent black
1226     glUseProgram(program);
1227     GLint uniLoc = glGetUniformLocation(program, "tex");
1228     ASSERT_NE(-1, uniLoc);
1229     glUniform1i(uniLoc, 0);
1230     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1231 
1232     GLint positionLocation = glGetAttribLocation(program, "position");
1233     ASSERT_NE(-1, positionLocation);
1234 
1235     glUseProgram(program);
1236 
1237     for (int cellY = 0; cellY < numRowsCols; cellY++)
1238     {
1239         for (int cellX = 0; cellX < numRowsCols; cellX++)
1240         {
1241             int seed            = cellX + cellY * numRowsCols;
1242             const Vector4 color = RandomVec4(seed, fmtValueMin, fmtValueMax);
1243 
1244             glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
1245             glClearBufferfv(GL_COLOR, 0, color.data());
1246 
1247             glBindFramebuffer(GL_FRAMEBUFFER, 0);
1248 
1249             // Method 1: Set viewport and draw full-viewport quad
1250             glViewport(cellX * cellSize, cellY * cellSize, cellSize, cellSize);
1251             drawQuad(program, "position", 0.5f);
1252 
1253             // Uncommenting the glFinish call seems to make the test pass.
1254             // glFinish();
1255         }
1256     }
1257 
1258     std::vector<GLColor> pixelData(backFBOSize * backFBOSize);
1259     glReadPixels(0, 0, backFBOSize, backFBOSize, GL_RGBA, GL_UNSIGNED_BYTE, pixelData.data());
1260 
1261     for (int cellY = 0; cellY < numRowsCols; cellY++)
1262     {
1263         for (int cellX = 0; cellX < numRowsCols; cellX++)
1264         {
1265             int seed            = cellX + cellY * numRowsCols;
1266             const Vector4 color = RandomVec4(seed, fmtValueMin, fmtValueMax);
1267             GLColor expectedColor(color);
1268 
1269             int testN = cellX * cellSize + cellY * backFBOSize * cellSize + backFBOSize + 1;
1270             GLColor actualColor = pixelData[testN];
1271             EXPECT_NEAR(expectedColor.R, actualColor.R, 1);
1272             EXPECT_NEAR(expectedColor.G, actualColor.G, 1);
1273             EXPECT_NEAR(expectedColor.B, actualColor.B, 1);
1274             EXPECT_NEAR(expectedColor.A, actualColor.A, 1);
1275         }
1276     }
1277 
1278     ASSERT_GL_NO_ERROR();
1279 }
1280 
1281 // Test that clearing RGB8 attachments from a 2D texture array does not cause
1282 // VUID-VkImageMemoryBarrier-oldLayout-01197
TEST_P(ClearTestES3,TextureArrayRGB8)1283 TEST_P(ClearTestES3, TextureArrayRGB8)
1284 {
1285     GLFramebuffer fb;
1286     glBindFramebuffer(GL_FRAMEBUFFER, fb);
1287 
1288     GLTexture tex;
1289     glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
1290     glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGB8, 1, 1, 2);
1291     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1292     glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1293 
1294     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 0);
1295     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, tex, 0, 1);
1296 
1297     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1298 
1299     GLenum bufs[2] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
1300     glDrawBuffers(2, &bufs[0]);
1301 
1302     glClearColor(1.0, 0.0, 1.0, 1.0);
1303     glClear(GL_COLOR_BUFFER_BIT);
1304     ASSERT_GL_NO_ERROR();
1305 
1306     glBindFramebuffer(GL_READ_FRAMEBUFFER, fb);
1307 
1308     glReadBuffer(GL_COLOR_ATTACHMENT0);
1309     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);
1310 
1311     glReadBuffer(GL_COLOR_ATTACHMENT1);
1312     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);
1313 
1314     EXPECT_GL_NO_ERROR();
1315 }
1316 
maskedScissoredColorDepthStencilClear(const MaskedScissoredClearVariationsTestParams & params)1317 void MaskedScissoredClearTestBase::maskedScissoredColorDepthStencilClear(
1318     const MaskedScissoredClearVariationsTestParams &params)
1319 {
1320     // Flaky on Android Nexus 5x and Pixel 2, possible Qualcomm driver bug.
1321     // TODO(jmadill): Re-enable when possible. http://anglebug.com/2548
1322     ANGLE_SKIP_TEST_IF(IsOpenGLES() && IsAndroid());
1323 
1324     const int w      = getWindowWidth();
1325     const int h      = getWindowHeight();
1326     const int wthird = w / 3;
1327     const int hthird = h / 3;
1328 
1329     constexpr float kPreClearDepth     = 0.9f;
1330     constexpr float kClearDepth        = 0.5f;
1331     constexpr uint8_t kPreClearStencil = 0xFF;
1332     constexpr uint8_t kClearStencil    = 0x16;
1333     constexpr uint8_t kStencilMask     = 0x59;
1334     constexpr uint8_t kMaskedClearStencil =
1335         (kPreClearStencil & ~kStencilMask) | (kClearStencil & kStencilMask);
1336 
1337     bool clearColor, clearDepth, clearStencil;
1338     bool maskColor, maskDepth, maskStencil;
1339     bool scissor;
1340 
1341     ParseMaskedScissoredClearVariationsTestParams(params, &clearColor, &clearDepth, &clearStencil,
1342                                                   &maskColor, &maskDepth, &maskStencil, &scissor);
1343 
1344     // clearDepth && !maskDepth fails on Intel Ubuntu 19.04 Mesa 19.0.2 GL. http://anglebug.com/3614
1345     ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsDesktopOpenGL() && clearDepth && !maskDepth);
1346 
1347     // Clear to a random color, 0.9 depth and 0x00 stencil
1348     Vector4 color1(0.1f, 0.2f, 0.3f, 0.4f);
1349     GLColor color1RGB(color1);
1350 
1351     glClearColor(color1[0], color1[1], color1[2], color1[3]);
1352     glClearDepthf(kPreClearDepth);
1353     glClearStencil(kPreClearStencil);
1354 
1355     if (!clearColor)
1356     {
1357         // If not asked to clear color, clear it anyway, but individually.  The clear value is
1358         // still used to verify that the depth/stencil clear happened correctly.  This allows
1359         // testing for depth/stencil-only clear implementations.
1360         glClear(GL_COLOR_BUFFER_BIT);
1361     }
1362 
1363     glClear((clearColor ? GL_COLOR_BUFFER_BIT : 0) | (clearDepth ? GL_DEPTH_BUFFER_BIT : 0) |
1364             (clearStencil ? GL_STENCIL_BUFFER_BIT : 0));
1365     ASSERT_GL_NO_ERROR();
1366 
1367     // Verify color was cleared correctly.
1368     EXPECT_PIXEL_COLOR_NEAR(0, 0, color1RGB, 1);
1369 
1370     if (scissor)
1371     {
1372         glEnable(GL_SCISSOR_TEST);
1373         glScissor(wthird / 2, hthird / 2, wthird, hthird);
1374     }
1375 
1376     // Use color and stencil masks to clear to a second color, 0.5 depth and 0x59 stencil.
1377     Vector4 color2(0.2f, 0.4f, 0.6f, 0.8f);
1378     GLColor color2RGB(color2);
1379     glClearColor(color2[0], color2[1], color2[2], color2[3]);
1380     glClearDepthf(kClearDepth);
1381     glClearStencil(kClearStencil);
1382     if (maskColor)
1383     {
1384         glColorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_FALSE);
1385     }
1386     if (maskDepth)
1387     {
1388         glDepthMask(GL_FALSE);
1389     }
1390     if (maskStencil)
1391     {
1392         glStencilMask(kStencilMask);
1393     }
1394     glClear((clearColor ? GL_COLOR_BUFFER_BIT : 0) | (clearDepth ? GL_DEPTH_BUFFER_BIT : 0) |
1395             (clearStencil ? GL_STENCIL_BUFFER_BIT : 0));
1396     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1397     glDepthMask(GL_TRUE);
1398     glStencilMask(0xFF);
1399     glDisable(GL_DEPTH_TEST);
1400     glDisable(GL_STENCIL_TEST);
1401     glDisable(GL_SCISSOR_TEST);
1402     ASSERT_GL_NO_ERROR();
1403 
1404     GLColor color2MaskedRGB(color2RGB[0], color1RGB[1], color2RGB[2], color1RGB[3]);
1405 
1406     // If not clearing color, the original color should be left both in the center and corners.  If
1407     // using a scissor, the corners should be left to the original color, while the center is
1408     // possibly changed.  If using a mask, the center (and corners if not scissored), changes to
1409     // the masked results.
1410     GLColor expectedCenterColorRGB =
1411         !clearColor ? color1RGB : maskColor ? color2MaskedRGB : color2RGB;
1412     GLColor expectedCornerColorRGB = scissor ? color1RGB : expectedCenterColorRGB;
1413 
1414     // Verify second clear color mask worked as expected.
1415     EXPECT_PIXEL_COLOR_NEAR(wthird, hthird, expectedCenterColorRGB, 1);
1416 
1417     EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedCornerColorRGB, 1);
1418     EXPECT_PIXEL_COLOR_NEAR(w - 1, 0, expectedCornerColorRGB, 1);
1419     EXPECT_PIXEL_COLOR_NEAR(0, h - 1, expectedCornerColorRGB, 1);
1420     EXPECT_PIXEL_COLOR_NEAR(w - 1, h - 1, expectedCornerColorRGB, 1);
1421     EXPECT_PIXEL_COLOR_NEAR(wthird, 2 * hthird, expectedCornerColorRGB, 1);
1422     EXPECT_PIXEL_COLOR_NEAR(2 * wthird, hthird, expectedCornerColorRGB, 1);
1423     EXPECT_PIXEL_COLOR_NEAR(2 * wthird, 2 * hthird, expectedCornerColorRGB, 1);
1424 
1425     // If there is depth, but depth is not asked to be cleared, the depth buffer contains garbage,
1426     // so no particular behavior can be expected.
1427     if (clearDepth || !mHasDepth)
1428     {
1429         // We use a small shader to verify depth.
1430         ANGLE_GL_PROGRAM(depthTestProgram, essl1_shaders::vs::Passthrough(),
1431                          essl1_shaders::fs::Blue());
1432         glEnable(GL_DEPTH_TEST);
1433         glDepthFunc(maskDepth ? GL_GREATER : GL_EQUAL);
1434         // - If depth is cleared, but it's masked, kPreClearDepth should be in the depth buffer.
1435         // - If depth is cleared, but it's not masked, kClearDepth should be in the depth buffer.
1436         // - If depth is not cleared, the if above ensures there is no depth buffer at all,
1437         //   which means depth test will always pass.
1438         drawQuad(depthTestProgram, essl1_shaders::PositionAttrib(), maskDepth ? 1.0f : 0.0f);
1439         glDisable(GL_DEPTH_TEST);
1440         ASSERT_GL_NO_ERROR();
1441 
1442         // Either way, we expect blue to be written to the center.
1443         expectedCenterColorRGB = GLColor::blue;
1444         // If there is no depth, depth test always passes so the whole image must be blue.  Same if
1445         // depth write is masked.
1446         expectedCornerColorRGB =
1447             mHasDepth && scissor && !maskDepth ? expectedCornerColorRGB : GLColor::blue;
1448 
1449         EXPECT_PIXEL_COLOR_NEAR(wthird, hthird, expectedCenterColorRGB, 1);
1450 
1451         EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedCornerColorRGB, 1);
1452         EXPECT_PIXEL_COLOR_NEAR(w - 1, 0, expectedCornerColorRGB, 1);
1453         EXPECT_PIXEL_COLOR_NEAR(0, h - 1, expectedCornerColorRGB, 1);
1454         EXPECT_PIXEL_COLOR_NEAR(w - 1, h - 1, expectedCornerColorRGB, 1);
1455         EXPECT_PIXEL_COLOR_NEAR(wthird, 2 * hthird, expectedCornerColorRGB, 1);
1456         EXPECT_PIXEL_COLOR_NEAR(2 * wthird, hthird, expectedCornerColorRGB, 1);
1457         EXPECT_PIXEL_COLOR_NEAR(2 * wthird, 2 * hthird, expectedCornerColorRGB, 1);
1458     }
1459 
1460     // If there is stencil, but it's not asked to be cleared, there is similarly no expectation.
1461     if (clearStencil || !mHasStencil)
1462     {
1463         // And another small shader to verify stencil.
1464         ANGLE_GL_PROGRAM(stencilTestProgram, essl1_shaders::vs::Passthrough(),
1465                          essl1_shaders::fs::Green());
1466         glEnable(GL_STENCIL_TEST);
1467         // - If stencil is cleared, but it's masked, kMaskedClearStencil should be in the stencil
1468         //   buffer.
1469         // - If stencil is cleared, but it's not masked, kClearStencil should be in the stencil
1470         //   buffer.
1471         // - If stencil is not cleared, the if above ensures there is no stencil buffer at all,
1472         //   which means stencil test will always pass.
1473         glStencilFunc(GL_EQUAL, maskStencil ? kMaskedClearStencil : kClearStencil, 0xFF);
1474         drawQuad(stencilTestProgram, essl1_shaders::PositionAttrib(), 0.0f);
1475         glDisable(GL_STENCIL_TEST);
1476         ASSERT_GL_NO_ERROR();
1477 
1478         // Either way, we expect green to be written to the center.
1479         expectedCenterColorRGB = GLColor::green;
1480         // If there is no stencil, stencil test always passes so the whole image must be green.
1481         expectedCornerColorRGB = mHasStencil && scissor ? expectedCornerColorRGB : GLColor::green;
1482 
1483         EXPECT_PIXEL_COLOR_NEAR(wthird, hthird, expectedCenterColorRGB, 1);
1484 
1485         EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedCornerColorRGB, 1);
1486         EXPECT_PIXEL_COLOR_NEAR(w - 1, 0, expectedCornerColorRGB, 1);
1487         EXPECT_PIXEL_COLOR_NEAR(0, h - 1, expectedCornerColorRGB, 1);
1488         EXPECT_PIXEL_COLOR_NEAR(w - 1, h - 1, expectedCornerColorRGB, 1);
1489         EXPECT_PIXEL_COLOR_NEAR(wthird, 2 * hthird, expectedCornerColorRGB, 1);
1490         EXPECT_PIXEL_COLOR_NEAR(2 * wthird, hthird, expectedCornerColorRGB, 1);
1491         EXPECT_PIXEL_COLOR_NEAR(2 * wthird, 2 * hthird, expectedCornerColorRGB, 1);
1492     }
1493 }
1494 
1495 // Tests combinations of color, depth, stencil clears with or without masks or scissor.
TEST_P(MaskedScissoredClearTest,Test)1496 TEST_P(MaskedScissoredClearTest, Test)
1497 {
1498     maskedScissoredColorDepthStencilClear(GetParam());
1499 }
1500 
1501 // Tests combinations of color, depth, stencil clears with or without masks or scissor.
1502 //
1503 // This uses depth/stencil attachments that are single-channel, but are emulated with a format
1504 // that has both channels.
TEST_P(VulkanClearTest,Test)1505 TEST_P(VulkanClearTest, Test)
1506 {
1507     bool clearColor, clearDepth, clearStencil;
1508     bool maskColor, maskDepth, maskStencil;
1509     bool scissor;
1510 
1511     ParseMaskedScissoredClearVariationsTestParams(GetParam(), &clearColor, &clearDepth,
1512                                                   &clearStencil, &maskColor, &maskDepth,
1513                                                   &maskStencil, &scissor);
1514 
1515     // We only care about clearing depth xor stencil.
1516     if (clearDepth == clearStencil)
1517     {
1518         return;
1519     }
1520 
1521     if (clearDepth)
1522     {
1523         // Creating a depth-only renderbuffer is an ES3 feature.
1524         ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
1525         bindColorDepthFBO();
1526     }
1527     else
1528     {
1529         bindColorStencilFBO();
1530     }
1531 
1532     maskedScissoredColorDepthStencilClear(GetParam());
1533 }
1534 
1535 // Test that just clearing a nonexistent drawbuffer of the default framebuffer doesn't cause an
1536 // assert.
TEST_P(ClearTestES3,ClearBuffer1OnDefaultFramebufferNoAssert)1537 TEST_P(ClearTestES3, ClearBuffer1OnDefaultFramebufferNoAssert)
1538 {
1539     std::vector<GLuint> testUint(4);
1540     glClearBufferuiv(GL_COLOR, 1, testUint.data());
1541     std::vector<GLint> testInt(4);
1542     glClearBufferiv(GL_COLOR, 1, testInt.data());
1543     std::vector<GLfloat> testFloat(4);
1544     glClearBufferfv(GL_COLOR, 1, testFloat.data());
1545     EXPECT_GL_NO_ERROR();
1546 }
1547 
1548 // Clears many small concentric rectangles using scissor regions.
TEST_P(ClearTest,InceptionScissorClears)1549 TEST_P(ClearTest, InceptionScissorClears)
1550 {
1551     angle::RNG rng;
1552 
1553     constexpr GLuint kSize = 16;
1554 
1555     // Create a square user FBO so we have more control over the dimensions.
1556     GLFramebuffer fbo;
1557     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1558 
1559     GLRenderbuffer rbo;
1560     glBindRenderbuffer(GL_RENDERBUFFER, rbo);
1561     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);
1562 
1563     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
1564     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1565 
1566     glViewport(0, 0, kSize, kSize);
1567 
1568     // Draw small concentric squares using scissor.
1569     std::vector<GLColor> expectedColors;
1570     for (GLuint index = 0; index < (kSize - 1) / 2; index++)
1571     {
1572         // Do the first clear without the scissor.
1573         if (index > 0)
1574         {
1575             glEnable(GL_SCISSOR_TEST);
1576             glScissor(index, index, kSize - (index * 2), kSize - (index * 2));
1577         }
1578 
1579         GLColor color = RandomColor(&rng);
1580         expectedColors.push_back(color);
1581         Vector4 floatColor = color.toNormalizedVector();
1582         glClearColor(floatColor[0], floatColor[1], floatColor[2], floatColor[3]);
1583         glClear(GL_COLOR_BUFFER_BIT);
1584     }
1585 
1586     ASSERT_GL_NO_ERROR();
1587 
1588     std::vector<GLColor> actualColors(expectedColors.size());
1589     glReadPixels(0, kSize / 2, actualColors.size(), 1, GL_RGBA, GL_UNSIGNED_BYTE,
1590                  actualColors.data());
1591 
1592     EXPECT_EQ(expectedColors, actualColors);
1593 }
1594 
1595 // Test that clearBuffer with disabled non-zero drawbuffer or disabled read source doesn't cause an
1596 // assert.
TEST_P(ClearTestES3,ClearDisabledNonZeroAttachmentNoAssert)1597 TEST_P(ClearTestES3, ClearDisabledNonZeroAttachmentNoAssert)
1598 {
1599     // http://anglebug.com/4612
1600     ANGLE_SKIP_TEST_IF(IsOSX() && IsDesktopOpenGL());
1601 
1602     GLFramebuffer fb;
1603     glBindFramebuffer(GL_FRAMEBUFFER, fb);
1604 
1605     GLRenderbuffer rb;
1606     glBindRenderbuffer(GL_RENDERBUFFER, rb);
1607     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 16, 16);
1608 
1609     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, rb);
1610     glDrawBuffers(0, nullptr);
1611     glReadBuffer(GL_NONE);
1612 
1613     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1614 
1615     float clearColorf[4] = {0.5, 0.5, 0.5, 0.5};
1616     glClearBufferfv(GL_COLOR, 1, clearColorf);
1617 
1618     GLuint clearColorui[4] = {255, 255, 255, 255};
1619     glClearBufferuiv(GL_COLOR, 1, clearColorui);
1620 
1621     GLint clearColori[4] = {-127, -127, -127, -127};
1622     glClearBufferiv(GL_COLOR, 1, clearColori);
1623 
1624     EXPECT_GL_NO_ERROR();
1625 }
1626 
1627 #ifdef Bool
1628 // X11 craziness.
1629 #    undef Bool
1630 #endif
1631 
1632 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
1633 // tests should be run against.
1634 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(ClearTest);
1635 ANGLE_INSTANTIATE_TEST_ES3(ClearTestES3);
1636 ANGLE_INSTANTIATE_TEST_COMBINE_4(MaskedScissoredClearTest,
1637                                  MaskedScissoredClearVariationsTestPrint,
1638                                  testing::Range(0, 3),
1639                                  testing::Range(0, 3),
1640                                  testing::Range(0, 3),
1641                                  testing::Bool(),
1642                                  ES2_D3D9(),
1643                                  ES2_D3D11(),
1644                                  ES3_D3D11(),
1645                                  ES2_OPENGL(),
1646                                  ES3_OPENGL(),
1647                                  ES2_OPENGLES(),
1648                                  ES3_OPENGLES(),
1649                                  ES2_VULKAN(),
1650                                  ES3_VULKAN());
1651 ANGLE_INSTANTIATE_TEST_COMBINE_4(VulkanClearTest,
1652                                  MaskedScissoredClearVariationsTestPrint,
1653                                  testing::Range(0, 3),
1654                                  testing::Range(0, 3),
1655                                  testing::Range(0, 3),
1656                                  testing::Bool(),
1657                                  ES2_VULKAN(),
1658                                  ES3_VULKAN());
1659 
1660 // Not all ANGLE backends support RGB backbuffers
1661 ANGLE_INSTANTIATE_TEST(ClearTestRGB, ES2_D3D11(), ES3_D3D11(), ES2_VULKAN(), ES3_VULKAN());
1662 
1663 }  // anonymous namespace
1664