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 ¶ms,
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> ¶msInfo)
147 {
148 const MaskedScissoredClearVariationsTestParams ¶ms = 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 ¶ms);
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 ¶ms)
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