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 "test_utils/gl_raii.h"
10 #include "util/random_utils.h"
11 #include "util/shader_utils.h"
12 #include "util/test_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
72 GLboolean hasDepthTest = GL_FALSE;
73 GLboolean hasDepthWrite = GL_TRUE;
74 GLint prevDepthFunc = GL_ALWAYS;
75
76 glGetBooleanv(GL_DEPTH_TEST, &hasDepthTest);
77 glGetBooleanv(GL_DEPTH_WRITEMASK, &hasDepthWrite);
78 glGetIntegerv(GL_DEPTH_FUNC, &prevDepthFunc);
79
80 if (!hasDepthTest)
81 {
82 glEnable(GL_DEPTH_TEST);
83 }
84 if (hasDepthWrite)
85 {
86 glDepthMask(GL_FALSE);
87 }
88 glDepthFunc(GL_LESS);
89 drawQuad(depthTestProgram, essl1_shaders::PositionAttrib(), depthValue * 2 - 1 - 0.01f);
90 drawQuad(depthTestProgramFail, essl1_shaders::PositionAttrib(), depthValue * 2 - 1 + 0.01f);
91 if (!hasDepthTest)
92 {
93 glDisable(GL_DEPTH_TEST);
94 }
95 if (hasDepthWrite)
96 {
97 glDepthMask(GL_TRUE);
98 }
99 glDepthFunc(prevDepthFunc);
100 ASSERT_GL_NO_ERROR();
101
102 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::blue, 1);
103 EXPECT_PIXEL_COLOR_NEAR(size - 1, 0, GLColor::blue, 1);
104 EXPECT_PIXEL_COLOR_NEAR(0, size - 1, GLColor::blue, 1);
105 EXPECT_PIXEL_COLOR_NEAR(size - 1, size - 1, GLColor::blue, 1);
106 }
107
verifyStencil(uint32_t stencilValue,uint32_t size)108 void verifyStencil(uint32_t stencilValue, uint32_t size)
109 {
110 // Use another small shader to verify stencil.
111 ANGLE_GL_PROGRAM(stencilTestProgram, essl1_shaders::vs::Passthrough(),
112 essl1_shaders::fs::Green());
113 GLboolean hasStencilTest = GL_FALSE;
114 GLint prevStencilFunc = GL_ALWAYS;
115 GLint prevStencilValue = 0xFF;
116 GLint prevStencilRef = 0xFF;
117 GLint prevStencilFail = GL_KEEP;
118 GLint prevStencilDepthFail = GL_KEEP;
119 GLint prevStencilDepthPass = GL_KEEP;
120
121 glGetBooleanv(GL_STENCIL_TEST, &hasStencilTest);
122 glGetIntegerv(GL_STENCIL_FUNC, &prevStencilFunc);
123 glGetIntegerv(GL_STENCIL_VALUE_MASK, &prevStencilValue);
124 glGetIntegerv(GL_STENCIL_REF, &prevStencilRef);
125 glGetIntegerv(GL_STENCIL_FAIL, &prevStencilFail);
126 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &prevStencilDepthFail);
127 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &prevStencilDepthPass);
128
129 if (!hasStencilTest)
130 {
131 glEnable(GL_STENCIL_TEST);
132 }
133 glStencilFunc(GL_EQUAL, stencilValue, 0xFF);
134 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
135 drawQuad(stencilTestProgram, essl1_shaders::PositionAttrib(), 0.0f);
136 if (!hasStencilTest)
137 {
138 glDisable(GL_STENCIL_TEST);
139 }
140 glStencilFunc(prevStencilFunc, prevStencilValue, prevStencilRef);
141 glStencilOp(prevStencilFail, prevStencilDepthFail, prevStencilDepthPass);
142 ASSERT_GL_NO_ERROR();
143
144 EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::green, 1);
145 EXPECT_PIXEL_COLOR_NEAR(size - 1, 0, GLColor::green, 1);
146 EXPECT_PIXEL_COLOR_NEAR(0, size - 1, GLColor::green, 1);
147 EXPECT_PIXEL_COLOR_NEAR(size - 1, size - 1, GLColor::green, 1);
148 }
149 };
150
151 class ClearTestES31 : public ClearTestES3
152 {};
153
154 class ClearTestRGB : public ANGLETest<>
155 {
156 protected:
ClearTestRGB()157 ClearTestRGB()
158 {
159 setWindowWidth(128);
160 setWindowHeight(128);
161 setConfigRedBits(8);
162 setConfigGreenBits(8);
163 setConfigBlueBits(8);
164 }
165 };
166
167 class ClearTestRGB_ES3 : public ClearTestRGB
168 {};
169
170 class ClearTextureEXTTest : public ANGLETest<>
171 {
172 protected:
ClearTextureEXTTest()173 ClearTextureEXTTest()
174 {
175 setWindowWidth(128);
176 setWindowHeight(128);
177 setConfigRedBits(8);
178 setConfigGreenBits(8);
179 setConfigBlueBits(8);
180 setConfigAlphaBits(8);
181 }
182 };
183
184 // Each int parameter can have three values: don't clear, clear, or masked clear. The bool
185 // parameter controls scissor.
186 using MaskedScissoredClearVariationsTestParams =
187 std::tuple<angle::PlatformParameters, int, int, int, bool>;
188
ParseMaskedScissoredClearVariationsTestParams(const MaskedScissoredClearVariationsTestParams & params,bool * clearColor,bool * clearDepth,bool * clearStencil,bool * maskColor,bool * maskDepth,bool * maskStencil,bool * scissor)189 void ParseMaskedScissoredClearVariationsTestParams(
190 const MaskedScissoredClearVariationsTestParams ¶ms,
191 bool *clearColor,
192 bool *clearDepth,
193 bool *clearStencil,
194 bool *maskColor,
195 bool *maskDepth,
196 bool *maskStencil,
197 bool *scissor)
198 {
199 int colorClearInfo = std::get<1>(params);
200 int depthClearInfo = std::get<2>(params);
201 int stencilClearInfo = std::get<3>(params);
202
203 *clearColor = colorClearInfo > 0;
204 *clearDepth = depthClearInfo > 0;
205 *clearStencil = stencilClearInfo > 0;
206
207 *maskColor = colorClearInfo > 1;
208 *maskDepth = depthClearInfo > 1;
209 *maskStencil = stencilClearInfo > 1;
210
211 *scissor = std::get<4>(params);
212 }
213
MaskedScissoredClearVariationsTestPrint(const::testing::TestParamInfo<MaskedScissoredClearVariationsTestParams> & paramsInfo)214 std::string MaskedScissoredClearVariationsTestPrint(
215 const ::testing::TestParamInfo<MaskedScissoredClearVariationsTestParams> ¶msInfo)
216 {
217 const MaskedScissoredClearVariationsTestParams ¶ms = paramsInfo.param;
218 std::ostringstream out;
219
220 out << std::get<0>(params);
221
222 bool clearColor, clearDepth, clearStencil;
223 bool maskColor, maskDepth, maskStencil;
224 bool scissor;
225
226 ParseMaskedScissoredClearVariationsTestParams(params, &clearColor, &clearDepth, &clearStencil,
227 &maskColor, &maskDepth, &maskStencil, &scissor);
228
229 if (scissor || clearColor || clearDepth || clearStencil || maskColor || maskDepth ||
230 maskStencil)
231 {
232 out << "_";
233 }
234
235 if (scissor)
236 {
237 out << "_scissored";
238 }
239
240 if (clearColor || clearDepth || clearStencil)
241 {
242 out << "_clear_";
243 if (clearColor)
244 {
245 out << "c";
246 }
247 if (clearDepth)
248 {
249 out << "d";
250 }
251 if (clearStencil)
252 {
253 out << "s";
254 }
255 }
256
257 if (maskColor || maskDepth || maskStencil)
258 {
259 out << "_mask_";
260 if (maskColor)
261 {
262 out << "c";
263 }
264 if (maskDepth)
265 {
266 out << "d";
267 }
268 if (maskStencil)
269 {
270 out << "s";
271 }
272 }
273
274 return out.str();
275 }
276
277 class MaskedScissoredClearTestBase : public ANGLETest<MaskedScissoredClearVariationsTestParams>
278 {
279 protected:
MaskedScissoredClearTestBase()280 MaskedScissoredClearTestBase()
281 {
282 setWindowWidth(128);
283 setWindowHeight(128);
284 setConfigRedBits(8);
285 setConfigGreenBits(8);
286 setConfigBlueBits(8);
287 setConfigAlphaBits(8);
288 setConfigDepthBits(24);
289 setConfigStencilBits(8);
290 }
291
292 void maskedScissoredColorDepthStencilClear(
293 const MaskedScissoredClearVariationsTestParams ¶ms);
294
295 bool mHasDepth = true;
296 bool mHasStencil = true;
297 };
298
299 class MaskedScissoredClearTest : public MaskedScissoredClearTestBase
300 {};
301
302 // Overrides a feature to force emulation of stencil-only and depth-only formats with a packed
303 // depth/stencil format
304 class VulkanClearTest : public MaskedScissoredClearTestBase
305 {
306 protected:
testSetUp()307 void testSetUp() override
308 {
309 glBindTexture(GL_TEXTURE_2D, mColorTexture);
310 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
311 GL_UNSIGNED_BYTE, nullptr);
312
313 // Setup Color/Stencil FBO with a stencil format that's emulated with packed depth/stencil.
314 glBindFramebuffer(GL_FRAMEBUFFER, mColorStencilFBO);
315
316 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mColorTexture,
317 0);
318 glBindRenderbuffer(GL_RENDERBUFFER, mStencilTexture);
319 glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, getWindowWidth(),
320 getWindowHeight());
321 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
322 mStencilTexture);
323
324 ASSERT_GL_NO_ERROR();
325
326 // Note: GL_DEPTH_COMPONENT24 is not allowed in GLES2.
327 if (getClientMajorVersion() >= 3)
328 {
329 // Setup Color/Depth FBO with a depth format that's emulated with packed depth/stencil.
330 glBindFramebuffer(GL_FRAMEBUFFER, mColorDepthFBO);
331
332 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
333 mColorTexture, 0);
334 glBindRenderbuffer(GL_RENDERBUFFER, mDepthTexture);
335 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, getWindowWidth(),
336 getWindowHeight());
337 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
338 mDepthTexture);
339 }
340
341 ASSERT_GL_NO_ERROR();
342 }
343
bindColorStencilFBO()344 void bindColorStencilFBO()
345 {
346 glBindFramebuffer(GL_FRAMEBUFFER, mColorStencilFBO);
347 mHasDepth = false;
348 }
349
bindColorDepthFBO()350 void bindColorDepthFBO()
351 {
352 glBindFramebuffer(GL_FRAMEBUFFER, mColorDepthFBO);
353 mHasStencil = false;
354 }
355
356 private:
357 GLFramebuffer mColorStencilFBO;
358 GLFramebuffer mColorDepthFBO;
359 GLTexture mColorTexture;
360 GLRenderbuffer mDepthTexture;
361 GLRenderbuffer mStencilTexture;
362 };
363
364 // Test clearing the default framebuffer
TEST_P(ClearTest,DefaultFramebuffer)365 TEST_P(ClearTest, DefaultFramebuffer)
366 {
367 glClearColor(0.25f, 0.5f, 0.5f, 0.5f);
368 glClear(GL_COLOR_BUFFER_BIT);
369 EXPECT_PIXEL_NEAR(0, 0, 64, 128, 128, 128, 1.0);
370 }
371
372 // Test clearing the default framebuffer with scissor and mask
373 // This forces down path that uses draw to do clear
TEST_P(ClearTest,EmptyScissor)374 TEST_P(ClearTest, EmptyScissor)
375 {
376 // These configs have bug that fails this test.
377 // These configs are unmaintained so skipping.
378 ANGLE_SKIP_TEST_IF(IsIntel() && IsD3D9());
379 ANGLE_SKIP_TEST_IF(IsIntel() && IsMac() && IsOpenGL());
380 glClearColor(0.25f, 0.5f, 0.5f, 1.0f);
381 glClear(GL_COLOR_BUFFER_BIT);
382 glEnable(GL_SCISSOR_TEST);
383 glScissor(-10, 0, 5, 5);
384 glClearColor(0.5f, 0.25f, 0.75f, 0.5f);
385 glColorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_TRUE);
386 glClear(GL_COLOR_BUFFER_BIT);
387 glDisable(GL_SCISSOR_TEST);
388 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
389 EXPECT_PIXEL_NEAR(0, 0, 64, 128, 128, 255, 1.0);
390 }
391
392 // Test clearing the RGB default framebuffer and verify that the alpha channel is not cleared
TEST_P(ClearTestRGB,DefaultFramebufferRGB)393 TEST_P(ClearTestRGB, DefaultFramebufferRGB)
394 {
395 // Some GPUs don't support RGB format default framebuffer,
396 // so skip if the back buffer has alpha bits.
397 EGLWindow *window = getEGLWindow();
398 EGLDisplay display = window->getDisplay();
399 EGLConfig config = window->getConfig();
400 EGLint backbufferAlphaBits = 0;
401 eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &backbufferAlphaBits);
402 ANGLE_SKIP_TEST_IF(backbufferAlphaBits != 0);
403
404 glClearColor(0.25f, 0.5f, 0.5f, 0.5f);
405 glClear(GL_COLOR_BUFFER_BIT);
406 EXPECT_PIXEL_NEAR(0, 0, 64, 128, 128, 255, 1.0);
407 }
408
409 // Invalidate the RGB default framebuffer and verify that the alpha channel is not cleared, and
410 // stays set after drawing.
TEST_P(ClearTestRGB_ES3,InvalidateDefaultFramebufferRGB)411 TEST_P(ClearTestRGB_ES3, InvalidateDefaultFramebufferRGB)
412 {
413 ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
414
415 // Some GPUs don't support RGB format default framebuffer,
416 // so skip if the back buffer has alpha bits.
417 EGLWindow *window = getEGLWindow();
418 EGLDisplay display = window->getDisplay();
419 EGLConfig config = window->getConfig();
420 EGLint backbufferAlphaBits = 0;
421 eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &backbufferAlphaBits);
422 ANGLE_SKIP_TEST_IF(backbufferAlphaBits != 0);
423
424 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
425 glClear(GL_COLOR_BUFFER_BIT);
426 // Verify that even though Alpha is cleared to 0.0 for this RGB FBO, it should be read back as
427 // 1.0, since the glReadPixels() is issued with GL_RGBA.
428 // OpenGL ES 3.2 spec:
429 // 16.1.3 Obtaining Pixels from the Framebuffer
430 // If G, B, or A values are not present in the internal format, they are taken to be zero,
431 // zero, and one respectively.
432 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
433
434 const GLenum discards[] = {GL_COLOR};
435 glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, discards);
436
437 // Don't explicitly clear, but draw blue (make sure alpha is not cleared)
438 drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);
439 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
440 }
441
442 // Draw with a shader that outputs alpha=0.5. Readback and ensure that alpha=1.
TEST_P(ClearTestRGB_ES3,ShaderOutputsAlphaVerifyReadingAlphaIsOne)443 TEST_P(ClearTestRGB_ES3, ShaderOutputsAlphaVerifyReadingAlphaIsOne)
444 {
445 ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
446 glUseProgram(blueProgram);
447
448 // Some GPUs don't support RGB format default framebuffer,
449 // so skip if the back buffer has alpha bits.
450 EGLWindow *window = getEGLWindow();
451 EGLDisplay display = window->getDisplay();
452 EGLConfig config = window->getConfig();
453 EGLint backbufferAlphaBits = 0;
454 eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &backbufferAlphaBits);
455 ANGLE_SKIP_TEST_IF(backbufferAlphaBits != 0);
456
457 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
458 glClear(GL_COLOR_BUFFER_BIT);
459 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
460
461 GLint colorUniformLocation =
462 glGetUniformLocation(blueProgram, angle::essl1_shaders::ColorUniform());
463 ASSERT_NE(colorUniformLocation, -1);
464 glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 0.5f);
465 ASSERT_GL_NO_ERROR();
466
467 // Don't explicitly clear, but draw blue (make sure alpha is not cleared)
468 drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);
469 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
470 }
471
472 // Test clearing a RGBA8 Framebuffer
TEST_P(ClearTest,RGBA8Framebuffer)473 TEST_P(ClearTest, RGBA8Framebuffer)
474 {
475 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
476
477 GLTexture texture;
478
479 glBindTexture(GL_TEXTURE_2D, texture);
480 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
481 GL_UNSIGNED_BYTE, nullptr);
482 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
483
484 glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
485 glClear(GL_COLOR_BUFFER_BIT);
486
487 EXPECT_PIXEL_NEAR(0, 0, 128, 128, 128, 128, 1.0);
488 }
489
490 // Test uploading a texture and then clearing a RGBA8 Framebuffer
TEST_P(ClearTest,TextureUploadAndRGBA8Framebuffer)491 TEST_P(ClearTest, TextureUploadAndRGBA8Framebuffer)
492 {
493 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
494
495 GLTexture texture;
496
497 constexpr uint32_t kSize = 16;
498 std::vector<GLColor> pixelData(kSize * kSize, GLColor::blue);
499 glBindTexture(GL_TEXTURE_2D, texture);
500 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
501 pixelData.data());
502 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
503
504 EXPECT_PIXEL_NEAR(0, 0, 0, 0, 255, 255, 1.0);
505
506 glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
507 glClear(GL_COLOR_BUFFER_BIT);
508
509 EXPECT_PIXEL_NEAR(0, 0, 128, 128, 128, 128, 1.0);
510 }
511
512 // Test to validate that we can go from an RGBA framebuffer attachment, to an RGB one and still
513 // have a correct behavior after.
TEST_P(ClearTest,ChangeFramebufferAttachmentFromRGBAtoRGB)514 TEST_P(ClearTest, ChangeFramebufferAttachmentFromRGBAtoRGB)
515 {
516 // http://anglebug.com/40096508
517 ANGLE_SKIP_TEST_IF(IsAndroid() && IsAdreno() && IsOpenGLES());
518
519 // http://anglebug.com/40644765
520 ANGLE_SKIP_TEST_IF(IsMac() && IsDesktopOpenGL() && IsIntel());
521
522 ANGLE_GL_PROGRAM(program, angle::essl1_shaders::vs::Simple(),
523 angle::essl1_shaders::fs::UniformColor());
524 setupQuadVertexBuffer(0.5f, 1.0f);
525 glUseProgram(program);
526 GLint positionLocation = glGetAttribLocation(program, angle::essl1_shaders::PositionAttrib());
527 ASSERT_NE(positionLocation, -1);
528 glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
529 glEnableVertexAttribArray(positionLocation);
530
531 GLint colorUniformLocation =
532 glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
533 ASSERT_NE(colorUniformLocation, -1);
534
535 glUniform4f(colorUniformLocation, 1.0f, 1.0f, 1.0f, 0.5f);
536
537 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
538
539 GLTexture texture;
540 glBindTexture(GL_TEXTURE_2D, texture);
541 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
542 GL_UNSIGNED_BYTE, nullptr);
543 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
544
545 // Initially clear to black.
546 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
547 glClear(GL_COLOR_BUFFER_BIT);
548
549 // Clear with masked color.
550 glColorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_TRUE);
551 glClearColor(0.5f, 0.5f, 0.5f, 0.75f);
552 glClear(GL_COLOR_BUFFER_BIT);
553 ASSERT_GL_NO_ERROR();
554
555 // So far so good, we have an RGBA framebuffer that we've cleared to 0.5 everywhere.
556 EXPECT_PIXEL_NEAR(0, 0, 128, 0, 128, 192, 1.0);
557
558 // In the Vulkan backend, RGB textures are emulated with an RGBA texture format
559 // underneath and we keep a special mask to know that we shouldn't touch the alpha
560 // channel when we have that emulated texture. This test exists to validate that
561 // this mask gets updated correctly when the framebuffer attachment changes.
562 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, getWindowWidth(), getWindowHeight(), 0, GL_RGB,
563 GL_UNSIGNED_BYTE, nullptr);
564 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
565 ASSERT_GL_NO_ERROR();
566
567 glDrawArrays(GL_TRIANGLES, 0, 6);
568 ASSERT_GL_NO_ERROR();
569
570 EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::magenta);
571 }
572
573 // Test clearing a RGB8 Framebuffer with a color mask.
TEST_P(ClearTest,RGB8WithMaskFramebuffer)574 TEST_P(ClearTest, RGB8WithMaskFramebuffer)
575 {
576 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
577
578 GLTexture texture;
579
580 glBindTexture(GL_TEXTURE_2D, texture);
581 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, getWindowWidth(), getWindowHeight(), 0, GL_RGB,
582 GL_UNSIGNED_BYTE, nullptr);
583 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
584
585 glClearColor(0.2f, 0.4f, 0.6f, 0.8f);
586 glClear(GL_COLOR_BUFFER_BIT);
587
588 // Since there's no alpha, we expect to get 255 back instead of the clear value (204).
589 EXPECT_PIXEL_NEAR(0, 0, 51, 102, 153, 255, 1.0);
590
591 glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);
592 glClearColor(0.1f, 0.3f, 0.5f, 0.7f);
593 glClear(GL_COLOR_BUFFER_BIT);
594
595 // The blue channel was masked so its value should be unchanged.
596 EXPECT_PIXEL_NEAR(0, 0, 26, 77, 153, 255, 1.0);
597
598 // Restore default.
599 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
600 }
601
TEST_P(ClearTest,ClearIssue)602 TEST_P(ClearTest, ClearIssue)
603 {
604 glEnable(GL_DEPTH_TEST);
605 glDepthFunc(GL_LEQUAL);
606
607 glClearColor(0.0, 1.0, 0.0, 1.0);
608 glClearDepthf(0.0);
609 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
610
611 EXPECT_GL_NO_ERROR();
612
613 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
614
615 GLRenderbuffer rbo;
616 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
617 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB565, 16, 16);
618
619 EXPECT_GL_NO_ERROR();
620
621 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
622
623 EXPECT_GL_NO_ERROR();
624
625 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
626 glClearDepthf(1.0f);
627 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
628
629 EXPECT_GL_NO_ERROR();
630
631 glBindFramebuffer(GL_FRAMEBUFFER, 0);
632 glBindBuffer(GL_ARRAY_BUFFER, 0);
633
634 ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
635 drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);
636
637 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
638 }
639
640 // Regression test for a bug where "glClearDepthf"'s argument was not clamped
641 // In GLES 2 they where declared as GLclampf and the behaviour is the same in GLES 3.2
TEST_P(ClearTest,ClearIsClamped)642 TEST_P(ClearTest, ClearIsClamped)
643 {
644 glClearDepthf(5.0f);
645
646 GLfloat clear_depth;
647 glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clear_depth);
648 EXPECT_EQ(1.0f, clear_depth);
649 }
650
651 // Regression test for a bug where "glDepthRangef"'s arguments were not clamped
652 // In GLES 2 they where declared as GLclampf and the behaviour is the same in GLES 3.2
TEST_P(ClearTest,DepthRangefIsClamped)653 TEST_P(ClearTest, DepthRangefIsClamped)
654 {
655 glDepthRangef(1.1f, -4.0f);
656
657 GLfloat depth_range[2];
658 glGetFloatv(GL_DEPTH_RANGE, depth_range);
659 EXPECT_EQ(1.0f, depth_range[0]);
660 EXPECT_EQ(0.0f, depth_range[1]);
661 }
662
663 // Test scissored clears on Depth16
TEST_P(ClearTest,Depth16Scissored)664 TEST_P(ClearTest, Depth16Scissored)
665 {
666 GLRenderbuffer renderbuffer;
667 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
668 constexpr int kRenderbufferSize = 64;
669 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, kRenderbufferSize,
670 kRenderbufferSize);
671
672 GLFramebuffer fbo;
673 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
674 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer);
675
676 glClearDepthf(0.0f);
677 glClear(GL_DEPTH_BUFFER_BIT);
678
679 glEnable(GL_SCISSOR_TEST);
680 constexpr int kNumSteps = 13;
681 for (int ndx = 1; ndx < kNumSteps; ndx++)
682 {
683 float perc = static_cast<float>(ndx) / static_cast<float>(kNumSteps);
684 glScissor(0, 0, static_cast<int>(kRenderbufferSize * perc),
685 static_cast<int>(kRenderbufferSize * perc));
686 glClearDepthf(perc);
687 glClear(GL_DEPTH_BUFFER_BIT);
688 }
689 }
690
691 // Test scissored clears on Stencil8
TEST_P(ClearTest,Stencil8Scissored)692 TEST_P(ClearTest, Stencil8Scissored)
693 {
694 GLRenderbuffer renderbuffer;
695 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
696 constexpr int kRenderbufferSize = 64;
697 glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, kRenderbufferSize, kRenderbufferSize);
698
699 GLFramebuffer fbo;
700 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
701 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuffer);
702
703 glClearStencil(0);
704 glClear(GL_STENCIL_BUFFER_BIT);
705
706 glEnable(GL_SCISSOR_TEST);
707 constexpr int kNumSteps = 13;
708 for (int ndx = 1; ndx < kNumSteps; ndx++)
709 {
710 float perc = static_cast<float>(ndx) / static_cast<float>(kNumSteps);
711 glScissor(0, 0, static_cast<int>(kRenderbufferSize * perc),
712 static_cast<int>(kRenderbufferSize * perc));
713 glClearStencil(static_cast<int>(perc * 255.0f));
714 glClear(GL_STENCIL_BUFFER_BIT);
715 }
716 }
717
718 // Covers a bug in the Vulkan back-end where starting a new command buffer in
719 // the masked clear would not trigger descriptor sets to be re-bound.
TEST_P(ClearTest,MaskedClearThenDrawWithUniform)720 TEST_P(ClearTest, MaskedClearThenDrawWithUniform)
721 {
722 // Initialize a program with a uniform.
723 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
724 glUseProgram(program);
725
726 GLint uniLoc = glGetUniformLocation(program, essl1_shaders::ColorUniform());
727 ASSERT_NE(-1, uniLoc);
728 glUniform4f(uniLoc, 0.0f, 1.0f, 0.0f, 1.0f);
729
730 // Initialize position attribute.
731 GLint posLoc = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
732 ASSERT_NE(-1, posLoc);
733 setupQuadVertexBuffer(0.5f, 1.0f);
734 glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
735 glEnableVertexAttribArray(posLoc);
736
737 // Initialize a simple FBO.
738 constexpr GLsizei kSize = 2;
739 GLTexture clearTexture;
740 glBindTexture(GL_TEXTURE_2D, clearTexture);
741 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
742
743 GLFramebuffer fbo;
744 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
745 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, clearTexture, 0);
746
747 glViewport(0, 0, kSize, kSize);
748
749 // Clear and draw to flush out dirty bits.
750 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
751 glClear(GL_COLOR_BUFFER_BIT);
752
753 glDrawArrays(GL_TRIANGLES, 0, 6);
754
755 // Flush to trigger a new serial.
756 glFlush();
757
758 // Enable color mask and draw again to trigger the bug.
759 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
760 glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
761 glClear(GL_COLOR_BUFFER_BIT);
762
763 glDrawArrays(GL_TRIANGLES, 0, 6);
764
765 ASSERT_GL_NO_ERROR();
766 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
767 }
768
769 // Clear with a mask to verify that masked clear is done properly
770 // (can't use inline or RenderOp clear when some color channels are masked)
TEST_P(ClearTestES3,ClearPlusMaskDrawAndClear)771 TEST_P(ClearTestES3, ClearPlusMaskDrawAndClear)
772 {
773 // Initialize a program with a uniform.
774 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
775 glUseProgram(program);
776
777 GLint uniLoc = glGetUniformLocation(program, essl1_shaders::ColorUniform());
778 ASSERT_NE(-1, uniLoc);
779 glUniform4f(uniLoc, 0.0f, 1.0f, 0.0f, 1.0f);
780
781 // Initialize position attribute.
782 GLint posLoc = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
783 ASSERT_NE(-1, posLoc);
784 setupQuadVertexBuffer(0.5f, 1.0f);
785 glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
786 glEnableVertexAttribArray(posLoc);
787
788 // Initialize a simple FBO.
789 constexpr GLsizei kSize = 2;
790 GLTexture clearTexture;
791 glBindTexture(GL_TEXTURE_2D, clearTexture);
792 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
793
794 GLFramebuffer fbo;
795 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
796 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, clearTexture, 0);
797
798 GLRenderbuffer depthStencil;
799 glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
800 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);
801 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
802 depthStencil);
803 ASSERT_GL_NO_ERROR();
804
805 glViewport(0, 0, kSize, kSize);
806
807 // Clear and draw to flush out dirty bits.
808 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
809 glClearDepthf(1.0f);
810 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
811
812 // Draw green rectangle
813 glDrawArrays(GL_TRIANGLES, 0, 6);
814
815 // Enable color mask and draw again to trigger the bug.
816 glColorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_TRUE);
817 glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
818 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
819
820 // Draw purple-ish rectangle, green should be masked off
821 glUniform4f(uniLoc, 1.0f, 0.25f, 1.0f, 1.0f);
822 glDrawArrays(GL_TRIANGLES, 0, 6);
823
824 ASSERT_GL_NO_ERROR();
825 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);
826 }
827
828 // Test that clearing all buffers through glClearColor followed by a clear of a specific buffer
829 // clears to the correct values.
TEST_P(ClearTestES3,ClearMultipleAttachmentsFollowedBySpecificOne)830 TEST_P(ClearTestES3, ClearMultipleAttachmentsFollowedBySpecificOne)
831 {
832 constexpr uint32_t kSize = 16;
833 constexpr uint32_t kAttachmentCount = 4;
834 std::vector<unsigned char> pixelData(kSize * kSize * 4, 255);
835
836 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
837
838 GLTexture textures[kAttachmentCount];
839 GLenum drawBuffers[kAttachmentCount];
840 GLColor clearValues[kAttachmentCount];
841
842 for (uint32_t i = 0; i < kAttachmentCount; ++i)
843 {
844 glBindTexture(GL_TEXTURE_2D, textures[i]);
845 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
846 pixelData.data());
847 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, textures[i],
848 0);
849 drawBuffers[i] = GL_COLOR_ATTACHMENT0 + i;
850
851 clearValues[i].R = static_cast<GLubyte>(1 + i * 20);
852 clearValues[i].G = static_cast<GLubyte>(7 + i * 20);
853 clearValues[i].B = static_cast<GLubyte>(12 + i * 20);
854 clearValues[i].A = static_cast<GLubyte>(16 + i * 20);
855 }
856
857 glDrawBuffers(kAttachmentCount, drawBuffers);
858
859 ASSERT_GL_NO_ERROR();
860 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);
861
862 // Clear all targets.
863 angle::Vector4 clearColor = clearValues[0].toNormalizedVector();
864 glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
865 glClear(GL_COLOR_BUFFER_BIT);
866 ASSERT_GL_NO_ERROR();
867
868 // Clear odd targets individually.
869 for (uint32_t i = 1; i < kAttachmentCount; i += 2)
870 {
871 clearColor = clearValues[i].toNormalizedVector();
872 glClearBufferfv(GL_COLOR, i, clearColor.data());
873 }
874
875 // Even attachments should be cleared to color 0, while odd attachments are cleared to their
876 // respective color.
877 for (uint32_t i = 0; i < kAttachmentCount; ++i)
878 {
879 glReadBuffer(GL_COLOR_ATTACHMENT0 + i);
880 ASSERT_GL_NO_ERROR();
881
882 uint32_t clearIndex = i % 2 == 0 ? 0 : i;
883 const GLColor &expect = clearValues[clearIndex];
884
885 EXPECT_PIXEL_COLOR_EQ(0, 0, expect);
886 EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, expect);
887 EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, expect);
888 EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, expect);
889 }
890 }
891
892 // Test that clearing each render target individually works. In the Vulkan backend, this should be
893 // done in a single render pass.
TEST_P(ClearTestES3,ClearMultipleAttachmentsIndividually)894 TEST_P(ClearTestES3, ClearMultipleAttachmentsIndividually)
895 {
896 // http://anglebug.com/40096714
897 ANGLE_SKIP_TEST_IF(IsWindows() && IsIntel() && IsVulkan());
898
899 constexpr uint32_t kSize = 16;
900 constexpr uint32_t kAttachmentCount = 2;
901 constexpr float kDepthClearValue = 0.125f;
902 constexpr int32_t kStencilClearValue = 0x67;
903 std::vector<unsigned char> pixelData(kSize * kSize * 4, 255);
904
905 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
906
907 GLTexture textures[kAttachmentCount];
908 GLRenderbuffer depthStencil;
909 GLenum drawBuffers[kAttachmentCount];
910 GLColor clearValues[kAttachmentCount];
911
912 for (uint32_t i = 0; i < kAttachmentCount; ++i)
913 {
914 glBindTexture(GL_TEXTURE_2D, textures[i]);
915 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
916 pixelData.data());
917 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, textures[i],
918 0);
919 drawBuffers[i] = GL_COLOR_ATTACHMENT0 + i;
920
921 clearValues[i].R = static_cast<GLubyte>(1 + i * 20);
922 clearValues[i].G = static_cast<GLubyte>(7 + i * 20);
923 clearValues[i].B = static_cast<GLubyte>(12 + i * 20);
924 clearValues[i].A = static_cast<GLubyte>(16 + i * 20);
925 }
926
927 glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
928 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);
929 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
930 depthStencil);
931
932 glDrawBuffers(kAttachmentCount, drawBuffers);
933
934 ASSERT_GL_NO_ERROR();
935 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);
936
937 for (uint32_t i = 0; i < kAttachmentCount; ++i)
938 {
939 glClearBufferfv(GL_COLOR, i, clearValues[i].toNormalizedVector().data());
940 }
941
942 glClearBufferfv(GL_DEPTH, 0, &kDepthClearValue);
943 glClearBufferiv(GL_STENCIL, 0, &kStencilClearValue);
944 ASSERT_GL_NO_ERROR();
945
946 for (uint32_t i = 0; i < kAttachmentCount; ++i)
947 {
948 glReadBuffer(GL_COLOR_ATTACHMENT0 + i);
949 ASSERT_GL_NO_ERROR();
950
951 const GLColor &expect = clearValues[i];
952
953 EXPECT_PIXEL_COLOR_EQ(0, 0, expect);
954 EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, expect);
955 EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, expect);
956 EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, expect);
957 }
958
959 glReadBuffer(GL_COLOR_ATTACHMENT0);
960 for (uint32_t i = 1; i < kAttachmentCount; ++i)
961 drawBuffers[i] = GL_NONE;
962 glDrawBuffers(kAttachmentCount, drawBuffers);
963
964 verifyDepth(kDepthClearValue, kSize);
965 verifyStencil(kStencilClearValue, kSize);
966 }
967
968 // Test that clearing multiple attachments in the presence of a color mask, scissor or both
969 // correctly clears all the attachments.
TEST_P(ClearTestES3,MaskedScissoredClearMultipleAttachments)970 TEST_P(ClearTestES3, MaskedScissoredClearMultipleAttachments)
971 {
972 constexpr uint32_t kSize = 16;
973 constexpr uint32_t kAttachmentCount = 2;
974 std::vector<unsigned char> pixelData(kSize * kSize * 4, 255);
975
976 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
977
978 GLTexture textures[kAttachmentCount];
979 GLenum drawBuffers[kAttachmentCount];
980
981 for (uint32_t i = 0; i < kAttachmentCount; ++i)
982 {
983 glBindTexture(GL_TEXTURE_2D, textures[i]);
984 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
985 pixelData.data());
986 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, textures[i],
987 0);
988 drawBuffers[i] = GL_COLOR_ATTACHMENT0 + i;
989 }
990
991 glDrawBuffers(kAttachmentCount, drawBuffers);
992
993 ASSERT_GL_NO_ERROR();
994 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);
995
996 // Masked clear
997 GLColor clearColorMasked(31, 63, 255, 191);
998 angle::Vector4 clearColor = GLColor(31, 63, 127, 191).toNormalizedVector();
999
1000 glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);
1001 glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
1002 glClear(GL_COLOR_BUFFER_BIT);
1003 ASSERT_GL_NO_ERROR();
1004
1005 // All attachments should be cleared, with the blue channel untouched
1006 for (uint32_t i = 0; i < kAttachmentCount; ++i)
1007 {
1008 glReadBuffer(GL_COLOR_ATTACHMENT0 + i);
1009 ASSERT_GL_NO_ERROR();
1010
1011 EXPECT_PIXEL_COLOR_EQ(0, 0, clearColorMasked);
1012 EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, clearColorMasked);
1013 EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, clearColorMasked);
1014 EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, clearColorMasked);
1015 EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, clearColorMasked);
1016 }
1017
1018 // Masked scissored clear
1019 GLColor clearColorMaskedScissored(63, 127, 255, 31);
1020 clearColor = GLColor(63, 127, 191, 31).toNormalizedVector();
1021
1022 glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
1023 glEnable(GL_SCISSOR_TEST);
1024 glScissor(kSize / 6, kSize / 6, kSize / 3, kSize / 3);
1025 glClear(GL_COLOR_BUFFER_BIT);
1026 ASSERT_GL_NO_ERROR();
1027
1028 // The corners should keep the previous value while the center is cleared, except its blue
1029 // channel.
1030 for (uint32_t i = 0; i < kAttachmentCount; ++i)
1031 {
1032 glReadBuffer(GL_COLOR_ATTACHMENT0 + i);
1033 ASSERT_GL_NO_ERROR();
1034
1035 EXPECT_PIXEL_COLOR_EQ(0, 0, clearColorMasked);
1036 EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, clearColorMasked);
1037 EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, clearColorMasked);
1038 EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, clearColorMasked);
1039 EXPECT_PIXEL_COLOR_EQ(kSize / 3, 2 * kSize / 3, clearColorMasked);
1040 EXPECT_PIXEL_COLOR_EQ(2 * kSize / 3, kSize / 3, clearColorMasked);
1041 EXPECT_PIXEL_COLOR_EQ(2 * kSize / 3, 2 * kSize / 3, clearColorMasked);
1042
1043 EXPECT_PIXEL_COLOR_EQ(kSize / 3, kSize / 3, clearColorMaskedScissored);
1044 }
1045
1046 // Scissored clear
1047 GLColor clearColorScissored(127, 191, 31, 63);
1048 clearColor = GLColor(127, 191, 31, 63).toNormalizedVector();
1049
1050 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1051 glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
1052 glClear(GL_COLOR_BUFFER_BIT);
1053 ASSERT_GL_NO_ERROR();
1054
1055 // The corners should keep the old value while all channels of the center are cleared.
1056 for (uint32_t i = 0; i < kAttachmentCount; ++i)
1057 {
1058 glReadBuffer(GL_COLOR_ATTACHMENT0 + i);
1059 ASSERT_GL_NO_ERROR();
1060
1061 EXPECT_PIXEL_COLOR_EQ(0, 0, clearColorMasked);
1062 EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, clearColorMasked);
1063 EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, clearColorMasked);
1064 EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, clearColorMasked);
1065 EXPECT_PIXEL_COLOR_EQ(kSize / 3, 2 * kSize / 3, clearColorMasked);
1066 EXPECT_PIXEL_COLOR_EQ(2 * kSize / 3, kSize / 3, clearColorMasked);
1067 EXPECT_PIXEL_COLOR_EQ(2 * kSize / 3, 2 * kSize / 3, clearColorMasked);
1068
1069 EXPECT_PIXEL_COLOR_EQ(kSize / 3, kSize / 3, clearColorScissored);
1070 }
1071 }
1072
1073 // Test clearing multiple attachments in the presence of an indexed color mask.
TEST_P(ClearTestES3,MaskedIndexedClearMultipleAttachments)1074 TEST_P(ClearTestES3, MaskedIndexedClearMultipleAttachments)
1075 {
1076 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_draw_buffers_indexed"));
1077
1078 constexpr uint32_t kSize = 16;
1079 constexpr uint32_t kAttachmentCount = 4;
1080 std::vector<unsigned char> pixelData(kSize * kSize * 4, 255);
1081
1082 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
1083
1084 GLTexture textures[kAttachmentCount];
1085 GLenum drawBuffers[kAttachmentCount];
1086
1087 for (uint32_t i = 0; i < kAttachmentCount; ++i)
1088 {
1089 glBindTexture(GL_TEXTURE_2D, textures[i]);
1090 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1091 pixelData.data());
1092 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, textures[i],
1093 0);
1094 drawBuffers[i] = GL_COLOR_ATTACHMENT0 + i;
1095 }
1096
1097 glDrawBuffers(kAttachmentCount, drawBuffers);
1098
1099 ASSERT_GL_NO_ERROR();
1100 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);
1101
1102 // Masked clear
1103 GLColor clearColorMasked(31, 63, 255, 191);
1104 angle::Vector4 clearColor = GLColor(31, 63, 127, 191).toNormalizedVector();
1105
1106 // Block blue channel for all attachements
1107 glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);
1108
1109 // Unblock blue channel for attachments 0 and 1
1110 glColorMaskiOES(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1111 glColorMaskiOES(1, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1112
1113 glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
1114 glClear(GL_COLOR_BUFFER_BIT);
1115 ASSERT_GL_NO_ERROR();
1116
1117 // All attachments should be cleared, with the blue channel untouched for all attachments but 1.
1118 for (uint32_t i = 0; i < kAttachmentCount; ++i)
1119 {
1120 glReadBuffer(GL_COLOR_ATTACHMENT0 + i);
1121 ASSERT_GL_NO_ERROR();
1122
1123 const GLColor attachmentColor = (i > 1) ? clearColorMasked : clearColor;
1124 EXPECT_PIXEL_COLOR_EQ(0, 0, attachmentColor);
1125 EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, attachmentColor);
1126 EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, attachmentColor);
1127 EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, attachmentColor);
1128 EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, attachmentColor);
1129 }
1130 }
1131
1132 // Test that clearing multiple attachments of different nature (float, int and uint) in the
1133 // presence of a color mask works correctly. In the Vulkan backend, this exercises clearWithDraw
1134 // and the relevant internal shaders.
TEST_P(ClearTestES3,MaskedClearHeterogeneousAttachments)1135 TEST_P(ClearTestES3, MaskedClearHeterogeneousAttachments)
1136 {
1137 // http://anglebug.com/40096714
1138 ANGLE_SKIP_TEST_IF(IsWindows() && IsIntel() && IsVulkan());
1139
1140 constexpr uint32_t kSize = 16;
1141 constexpr uint32_t kAttachmentCount = 3;
1142 constexpr float kDepthClearValue = 0.256f;
1143 constexpr int32_t kStencilClearValue = 0x1D;
1144 constexpr GLenum kAttachmentFormats[kAttachmentCount] = {
1145 GL_RGBA8,
1146 GL_RGBA8I,
1147 GL_RGBA8UI,
1148 };
1149 constexpr GLenum kDataFormats[kAttachmentCount] = {
1150 GL_RGBA,
1151 GL_RGBA_INTEGER,
1152 GL_RGBA_INTEGER,
1153 };
1154 constexpr GLenum kDataTypes[kAttachmentCount] = {
1155 GL_UNSIGNED_BYTE,
1156 GL_BYTE,
1157 GL_UNSIGNED_BYTE,
1158 };
1159
1160 std::vector<unsigned char> pixelData(kSize * kSize * 4, 0);
1161
1162 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
1163
1164 GLTexture textures[kAttachmentCount];
1165 GLRenderbuffer depthStencil;
1166 GLenum drawBuffers[kAttachmentCount];
1167
1168 for (uint32_t i = 0; i < kAttachmentCount; ++i)
1169 {
1170 glBindTexture(GL_TEXTURE_2D, textures[i]);
1171 glTexImage2D(GL_TEXTURE_2D, 0, kAttachmentFormats[i], kSize, kSize, 0, kDataFormats[i],
1172 kDataTypes[i], pixelData.data());
1173 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, textures[i],
1174 0);
1175 drawBuffers[i] = GL_COLOR_ATTACHMENT0 + i;
1176 }
1177
1178 glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
1179 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);
1180 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
1181 depthStencil);
1182
1183 glDrawBuffers(kAttachmentCount, drawBuffers);
1184
1185 ASSERT_GL_NO_ERROR();
1186 EXPECT_PIXEL_EQ(0, 0, 0, 0, 0, 0);
1187
1188 // Mask out red for all clears
1189 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE);
1190
1191 glClearBufferfv(GL_DEPTH, 0, &kDepthClearValue);
1192 glClearBufferiv(GL_STENCIL, 0, &kStencilClearValue);
1193
1194 GLColor clearValuef = {25, 50, 75, 100};
1195 glClearBufferfv(GL_COLOR, 0, clearValuef.toNormalizedVector().data());
1196
1197 int clearValuei[4] = {10, -20, 30, -40};
1198 glClearBufferiv(GL_COLOR, 1, clearValuei);
1199
1200 uint32_t clearValueui[4] = {50, 60, 70, 80};
1201 glClearBufferuiv(GL_COLOR, 2, clearValueui);
1202
1203 ASSERT_GL_NO_ERROR();
1204
1205 {
1206 glReadBuffer(GL_COLOR_ATTACHMENT0);
1207 ASSERT_GL_NO_ERROR();
1208
1209 GLColor expect = clearValuef;
1210 expect.R = 0;
1211
1212 EXPECT_PIXEL_COLOR_EQ(0, 0, expect);
1213 EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, expect);
1214 EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, expect);
1215 EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, expect);
1216 }
1217
1218 {
1219 glReadBuffer(GL_COLOR_ATTACHMENT1);
1220 ASSERT_GL_NO_ERROR();
1221
1222 EXPECT_PIXEL_8I(0, 0, 0, clearValuei[1], clearValuei[2], clearValuei[3]);
1223 EXPECT_PIXEL_8I(0, kSize - 1, 0, clearValuei[1], clearValuei[2], clearValuei[3]);
1224 EXPECT_PIXEL_8I(kSize - 1, 0, 0, clearValuei[1], clearValuei[2], clearValuei[3]);
1225 EXPECT_PIXEL_8I(kSize - 1, kSize - 1, 0, clearValuei[1], clearValuei[2], clearValuei[3]);
1226 }
1227
1228 {
1229 glReadBuffer(GL_COLOR_ATTACHMENT2);
1230 ASSERT_GL_NO_ERROR();
1231
1232 EXPECT_PIXEL_8UI(0, 0, 0, clearValueui[1], clearValueui[2], clearValueui[3]);
1233 EXPECT_PIXEL_8UI(0, kSize - 1, 0, clearValueui[1], clearValueui[2], clearValueui[3]);
1234 EXPECT_PIXEL_8UI(kSize - 1, 0, 0, clearValueui[1], clearValueui[2], clearValueui[3]);
1235 EXPECT_PIXEL_8UI(kSize - 1, kSize - 1, 0, clearValueui[1], clearValueui[2],
1236 clearValueui[3]);
1237 }
1238
1239 glReadBuffer(GL_COLOR_ATTACHMENT0);
1240 for (uint32_t i = 1; i < kAttachmentCount; ++i)
1241 drawBuffers[i] = GL_NONE;
1242 glDrawBuffers(kAttachmentCount, drawBuffers);
1243
1244 verifyDepth(kDepthClearValue, kSize);
1245 verifyStencil(kStencilClearValue, kSize);
1246 }
1247
1248 // Test that clearing multiple attachments of different nature (float, int and uint) in the
1249 // presence of a scissor test works correctly. In the Vulkan backend, this exercises clearWithDraw
1250 // and the relevant internal shaders.
TEST_P(ClearTestES3,ScissoredClearHeterogeneousAttachments)1251 TEST_P(ClearTestES3, ScissoredClearHeterogeneousAttachments)
1252 {
1253 // http://anglebug.com/40096714
1254 ANGLE_SKIP_TEST_IF(IsWindows() && IsIntel() && IsVulkan());
1255
1256 // http://anglebug.com/42263682
1257 ANGLE_SKIP_TEST_IF(IsWindows() && (IsOpenGL() || IsD3D11()) && IsAMD());
1258
1259 // http://anglebug.com/42263790
1260 ANGLE_SKIP_TEST_IF(IsWindows7() && IsD3D11() && IsNVIDIA());
1261
1262 constexpr uint32_t kSize = 16;
1263 constexpr uint32_t kHalfSize = kSize / 2;
1264 constexpr uint32_t kAttachmentCount = 3;
1265 constexpr float kDepthClearValue = 0.256f;
1266 constexpr int32_t kStencilClearValue = 0x1D;
1267 constexpr GLenum kAttachmentFormats[kAttachmentCount] = {
1268 GL_RGBA8,
1269 GL_RGBA8I,
1270 GL_RGBA8UI,
1271 };
1272 constexpr GLenum kDataFormats[kAttachmentCount] = {
1273 GL_RGBA,
1274 GL_RGBA_INTEGER,
1275 GL_RGBA_INTEGER,
1276 };
1277 constexpr GLenum kDataTypes[kAttachmentCount] = {
1278 GL_UNSIGNED_BYTE,
1279 GL_BYTE,
1280 GL_UNSIGNED_BYTE,
1281 };
1282
1283 std::vector<unsigned char> pixelData(kSize * kSize * 4, 0);
1284
1285 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
1286
1287 GLTexture textures[kAttachmentCount];
1288 GLRenderbuffer depthStencil;
1289 GLenum drawBuffers[kAttachmentCount];
1290
1291 for (uint32_t i = 0; i < kAttachmentCount; ++i)
1292 {
1293 glBindTexture(GL_TEXTURE_2D, textures[i]);
1294 glTexImage2D(GL_TEXTURE_2D, 0, kAttachmentFormats[i], kSize, kSize, 0, kDataFormats[i],
1295 kDataTypes[i], pixelData.data());
1296 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, textures[i],
1297 0);
1298 drawBuffers[i] = GL_COLOR_ATTACHMENT0 + i;
1299 }
1300
1301 glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
1302 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);
1303 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
1304 depthStencil);
1305
1306 glDrawBuffers(kAttachmentCount, drawBuffers);
1307
1308 ASSERT_GL_NO_ERROR();
1309 EXPECT_PIXEL_EQ(0, 0, 0, 0, 0, 0);
1310
1311 // Enable scissor test
1312 glScissor(0, 0, kHalfSize, kHalfSize);
1313 glEnable(GL_SCISSOR_TEST);
1314
1315 GLColor clearValuef = {25, 50, 75, 100};
1316 angle::Vector4 clearValuefv = clearValuef.toNormalizedVector();
1317
1318 glClearColor(clearValuefv.x(), clearValuefv.y(), clearValuefv.z(), clearValuefv.w());
1319 glClearDepthf(kDepthClearValue);
1320
1321 // clear stencil.
1322 glClearBufferiv(GL_STENCIL, 0, &kStencilClearValue);
1323
1324 // clear float color attachment & depth together
1325 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1326
1327 // clear integer attachment.
1328 int clearValuei[4] = {10, -20, 30, -40};
1329 glClearBufferiv(GL_COLOR, 1, clearValuei);
1330
1331 // clear unsigned integer attachment
1332 uint32_t clearValueui[4] = {50, 60, 70, 80};
1333 glClearBufferuiv(GL_COLOR, 2, clearValueui);
1334
1335 ASSERT_GL_NO_ERROR();
1336
1337 {
1338 glReadBuffer(GL_COLOR_ATTACHMENT0);
1339 ASSERT_GL_NO_ERROR();
1340
1341 GLColor expect = clearValuef;
1342
1343 EXPECT_PIXEL_COLOR_EQ(0, 0, expect);
1344 EXPECT_PIXEL_COLOR_EQ(0, kHalfSize - 1, expect);
1345 EXPECT_PIXEL_COLOR_EQ(kHalfSize - 1, 0, expect);
1346 EXPECT_PIXEL_COLOR_EQ(kHalfSize - 1, kHalfSize - 1, expect);
1347 EXPECT_PIXEL_EQ(kHalfSize + 1, kHalfSize + 1, 0, 0, 0, 0);
1348 }
1349
1350 {
1351 glReadBuffer(GL_COLOR_ATTACHMENT1);
1352 ASSERT_GL_NO_ERROR();
1353
1354 EXPECT_PIXEL_8I(0, 0, clearValuei[0], clearValuei[1], clearValuei[2], clearValuei[3]);
1355 EXPECT_PIXEL_8I(0, kHalfSize - 1, clearValuei[0], clearValuei[1], clearValuei[2],
1356 clearValuei[3]);
1357 EXPECT_PIXEL_8I(kHalfSize - 1, 0, clearValuei[0], clearValuei[1], clearValuei[2],
1358 clearValuei[3]);
1359 EXPECT_PIXEL_8I(kHalfSize - 1, kHalfSize - 1, clearValuei[0], clearValuei[1],
1360 clearValuei[2], clearValuei[3]);
1361 EXPECT_PIXEL_8I(kHalfSize + 1, kHalfSize + 1, 0, 0, 0, 0);
1362 }
1363
1364 {
1365 glReadBuffer(GL_COLOR_ATTACHMENT2);
1366 ASSERT_GL_NO_ERROR();
1367
1368 EXPECT_PIXEL_8UI(0, 0, clearValueui[0], clearValueui[1], clearValueui[2], clearValueui[3]);
1369 EXPECT_PIXEL_8UI(0, kHalfSize - 1, clearValueui[0], clearValueui[1], clearValueui[2],
1370 clearValueui[3]);
1371 EXPECT_PIXEL_8UI(kHalfSize - 1, 0, clearValueui[0], clearValueui[1], clearValueui[2],
1372 clearValueui[3]);
1373 EXPECT_PIXEL_8UI(kHalfSize - 1, kHalfSize - 1, clearValueui[0], clearValueui[1],
1374 clearValueui[2], clearValueui[3]);
1375 EXPECT_PIXEL_8UI(kHalfSize + 1, kHalfSize + 1, 0, 0, 0, 0);
1376 }
1377
1378 glReadBuffer(GL_COLOR_ATTACHMENT0);
1379 for (uint32_t i = 1; i < kAttachmentCount; ++i)
1380 drawBuffers[i] = GL_NONE;
1381 glDrawBuffers(kAttachmentCount, drawBuffers);
1382
1383 verifyDepth(kDepthClearValue, kHalfSize);
1384 verifyStencil(kStencilClearValue, kHalfSize);
1385 }
1386
1387 // This tests a bug where in a masked clear when calling "ClearBuffer", we would
1388 // mistakenly clear every channel (including the masked-out ones)
TEST_P(ClearTestES3,MaskedClearBufferBug)1389 TEST_P(ClearTestES3, MaskedClearBufferBug)
1390 {
1391 unsigned char pixelData[] = {255, 255, 255, 255};
1392
1393 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
1394
1395 GLTexture textures[2];
1396
1397 glBindTexture(GL_TEXTURE_2D, textures[0]);
1398 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData);
1399 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
1400
1401 glBindTexture(GL_TEXTURE_2D, textures[1]);
1402 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData);
1403 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, textures[1], 0);
1404
1405 ASSERT_GL_NO_ERROR();
1406 EXPECT_PIXEL_EQ(0, 0, 255, 255, 255, 255);
1407
1408 float clearValue[] = {0, 0.5f, 0.5f, 1.0f};
1409 GLenum drawBuffers[] = {GL_NONE, GL_COLOR_ATTACHMENT1};
1410 glDrawBuffers(2, drawBuffers);
1411 glColorMask(GL_TRUE, GL_TRUE, GL_FALSE, GL_TRUE);
1412 glClearBufferfv(GL_COLOR, 1, clearValue);
1413
1414 ASSERT_GL_NO_ERROR();
1415 EXPECT_PIXEL_EQ(0, 0, 255, 255, 255, 255);
1416
1417 glReadBuffer(GL_COLOR_ATTACHMENT1);
1418 ASSERT_GL_NO_ERROR();
1419
1420 EXPECT_PIXEL_NEAR(0, 0, 0, 127, 255, 255, 1);
1421 }
1422
1423 // Test that stencil clears works if reference and write mask have no common bits. The write mask
1424 // is the only thing that dictates which bits should be written to, and this is a regression test
1425 // for a bug where the clear was no-oped if the (reference & writemask) == 0 instead of just
1426 // writemask == 0.
TEST_P(ClearTestES3,ClearStencilWithNonOverlappingWriteMaskAndReferenceBits)1427 TEST_P(ClearTestES3, ClearStencilWithNonOverlappingWriteMaskAndReferenceBits)
1428 {
1429 constexpr uint32_t kSize = 16;
1430
1431 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
1432
1433 GLTexture textures;
1434 GLRenderbuffer depthStencil;
1435
1436 glBindTexture(GL_TEXTURE_2D, textures);
1437 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1438 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures, 0);
1439
1440 glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
1441 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);
1442 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
1443 depthStencil);
1444 // Initialize the stencil buffer.
1445 glClearDepthf(0);
1446 glClearStencil(0xEC);
1447
1448 glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1449 verifyStencil(0xEC, kSize);
1450
1451 // Clear the color buffer again to make sure there are no stale data.
1452 glClearColor(0.25, 0.5, 0.75, 1.0);
1453 glClear(GL_COLOR_BUFFER_BIT);
1454 EXPECT_PIXEL_NEAR(0, 0, 63, 127, 191, 255, 1.0);
1455
1456 // Set the stencil write mask to 0xF0
1457 glStencilMask(0xF0);
1458
1459 // Set the stencil reference to 0x0F. It shouldn't matter
1460 glStencilFunc(GL_EQUAL, 0x55, 0x0F);
1461 glStencilOp(GL_INCR, GL_INCR, GL_INCR);
1462
1463 // Clear stencil again. Only the top four bits should be written.
1464 const GLint kStencilClearValue = 0x59;
1465 glClearBufferiv(GL_STENCIL, 0, &kStencilClearValue);
1466 verifyStencil(0x5C, kSize);
1467 }
1468
1469 // Regression test for a serial tracking bug.
TEST_P(ClearTestES3,BadFBOSerialBug)1470 TEST_P(ClearTestES3, BadFBOSerialBug)
1471 {
1472 // First make a simple framebuffer, and clear it to green
1473 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
1474
1475 GLTexture textures[2];
1476
1477 glBindTexture(GL_TEXTURE_2D, textures[0]);
1478 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
1479 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
1480
1481 GLenum drawBuffers[] = {GL_COLOR_ATTACHMENT0};
1482 glDrawBuffers(1, drawBuffers);
1483
1484 float clearValues1[] = {0.0f, 1.0f, 0.0f, 1.0f};
1485 glClearBufferfv(GL_COLOR, 0, clearValues1);
1486
1487 ASSERT_GL_NO_ERROR();
1488 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1489
1490 // Next make a second framebuffer, and draw it to red
1491 // (Triggers bad applied render target serial)
1492 GLFramebuffer fbo2;
1493 glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
1494 ASSERT_GL_NO_ERROR();
1495
1496 glBindTexture(GL_TEXTURE_2D, textures[1]);
1497 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
1498 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
1499
1500 glDrawBuffers(1, drawBuffers);
1501
1502 ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
1503 drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);
1504
1505 ASSERT_GL_NO_ERROR();
1506 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1507
1508 // Check that the first framebuffer is still green.
1509 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
1510 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1511 }
1512
1513 // Test that SRGB framebuffers clear to the linearized clear color
TEST_P(ClearTestES3,SRGBClear)1514 TEST_P(ClearTestES3, SRGBClear)
1515 {
1516 // First make a simple framebuffer, and clear it
1517 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
1518
1519 GLTexture texture;
1520
1521 glBindTexture(GL_TEXTURE_2D, texture);
1522 glTexStorage2D(GL_TEXTURE_2D, 1, GL_SRGB8_ALPHA8, getWindowWidth(), getWindowHeight());
1523 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
1524
1525 glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
1526 glClear(GL_COLOR_BUFFER_BIT);
1527
1528 EXPECT_PIXEL_NEAR(0, 0, 188, 188, 188, 128, 1.0);
1529 }
1530
1531 // Test that framebuffers with mixed SRGB/Linear attachments clear to the correct color for each
1532 // attachment
TEST_P(ClearTestES3,MixedSRGBClear)1533 TEST_P(ClearTestES3, MixedSRGBClear)
1534 {
1535 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
1536
1537 GLTexture textures[2];
1538
1539 glBindTexture(GL_TEXTURE_2D, textures[0]);
1540 glTexStorage2D(GL_TEXTURE_2D, 1, GL_SRGB8_ALPHA8, getWindowWidth(), getWindowHeight());
1541 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
1542
1543 glBindTexture(GL_TEXTURE_2D, textures[1]);
1544 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
1545 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, textures[1], 0);
1546
1547 GLenum drawBuffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
1548 glDrawBuffers(2, drawBuffers);
1549
1550 // Clear both textures
1551 glClearColor(0.5f, 0.5f, 0.5f, 0.5f);
1552 glClear(GL_COLOR_BUFFER_BIT);
1553
1554 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1555 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, 0, 0);
1556
1557 // Check value of texture0
1558 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0], 0);
1559 EXPECT_PIXEL_NEAR(0, 0, 188, 188, 188, 128, 1.0);
1560
1561 // Check value of texture1
1562 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1], 0);
1563 EXPECT_PIXEL_NEAR(0, 0, 128, 128, 128, 128, 1.0);
1564 }
1565
1566 // This test covers a D3D11 bug where calling ClearRenderTargetView sometimes wouldn't sync
1567 // before a draw call. The test draws small quads to a larger FBO (the default back buffer).
1568 // Before each blit to the back buffer it clears the quad to a certain color using
1569 // ClearBufferfv to give a solid color. The sync problem goes away if we insert a call to
1570 // flush or finish after ClearBufferfv or each draw.
TEST_P(ClearTestES3,RepeatedClear)1571 TEST_P(ClearTestES3, RepeatedClear)
1572 {
1573 // Fails on 431.02 driver. http://anglebug.com/40644697
1574 ANGLE_SKIP_TEST_IF(IsWindows() && IsNVIDIA() && IsVulkan());
1575 ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
1576
1577 constexpr char kVS[] =
1578 "#version 300 es\n"
1579 "in highp vec2 position;\n"
1580 "out highp vec2 v_coord;\n"
1581 "void main(void)\n"
1582 "{\n"
1583 " gl_Position = vec4(position, 0, 1);\n"
1584 " vec2 texCoord = (position * 0.5) + 0.5;\n"
1585 " v_coord = texCoord;\n"
1586 "}\n";
1587
1588 constexpr char kFS[] =
1589 "#version 300 es\n"
1590 "in highp vec2 v_coord;\n"
1591 "out highp vec4 color;\n"
1592 "uniform sampler2D tex;\n"
1593 "void main()\n"
1594 "{\n"
1595 " color = texture(tex, v_coord);\n"
1596 "}\n";
1597
1598 ANGLE_GL_PROGRAM(program, kVS, kFS);
1599
1600 mTextures.resize(1, 0);
1601 glGenTextures(1, mTextures.data());
1602
1603 GLenum format = GL_RGBA8;
1604 const int numRowsCols = 3;
1605 const int cellSize = 32;
1606 const int fboSize = cellSize;
1607 const int backFBOSize = cellSize * numRowsCols;
1608 const float fmtValueMin = 0.0f;
1609 const float fmtValueMax = 1.0f;
1610
1611 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1612 glTexStorage2D(GL_TEXTURE_2D, 1, format, fboSize, fboSize);
1613 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1614 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1615 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1616 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1617 ASSERT_GL_NO_ERROR();
1618
1619 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
1620 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0);
1621 ASSERT_GL_NO_ERROR();
1622
1623 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1624
1625 // larger fbo bound -- clear to transparent black
1626 glUseProgram(program);
1627 GLint uniLoc = glGetUniformLocation(program, "tex");
1628 ASSERT_NE(-1, uniLoc);
1629 glUniform1i(uniLoc, 0);
1630 glBindTexture(GL_TEXTURE_2D, mTextures[0]);
1631
1632 GLint positionLocation = glGetAttribLocation(program, "position");
1633 ASSERT_NE(-1, positionLocation);
1634
1635 glUseProgram(program);
1636
1637 for (int cellY = 0; cellY < numRowsCols; cellY++)
1638 {
1639 for (int cellX = 0; cellX < numRowsCols; cellX++)
1640 {
1641 int seed = cellX + cellY * numRowsCols;
1642 const Vector4 color = RandomVec4(seed, fmtValueMin, fmtValueMax);
1643
1644 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
1645 glClearBufferfv(GL_COLOR, 0, color.data());
1646
1647 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1648
1649 // Method 1: Set viewport and draw full-viewport quad
1650 glViewport(cellX * cellSize, cellY * cellSize, cellSize, cellSize);
1651 drawQuad(program, "position", 0.5f);
1652
1653 // Uncommenting the glFinish call seems to make the test pass.
1654 // glFinish();
1655 }
1656 }
1657
1658 std::vector<GLColor> pixelData(backFBOSize * backFBOSize);
1659 glReadPixels(0, 0, backFBOSize, backFBOSize, GL_RGBA, GL_UNSIGNED_BYTE, pixelData.data());
1660
1661 for (int cellY = 0; cellY < numRowsCols; cellY++)
1662 {
1663 for (int cellX = 0; cellX < numRowsCols; cellX++)
1664 {
1665 int seed = cellX + cellY * numRowsCols;
1666 const Vector4 color = RandomVec4(seed, fmtValueMin, fmtValueMax);
1667 GLColor expectedColor(color);
1668
1669 int testN = cellX * cellSize + cellY * backFBOSize * cellSize + backFBOSize + 1;
1670 GLColor actualColor = pixelData[testN];
1671 EXPECT_NEAR(expectedColor.R, actualColor.R, 1);
1672 EXPECT_NEAR(expectedColor.G, actualColor.G, 1);
1673 EXPECT_NEAR(expectedColor.B, actualColor.B, 1);
1674 EXPECT_NEAR(expectedColor.A, actualColor.A, 1);
1675 }
1676 }
1677
1678 ASSERT_GL_NO_ERROR();
1679 }
1680
1681 // Test that clearing RGB8 attachments work when verified through sampling.
TEST_P(ClearTestES3,ClearRGB8)1682 TEST_P(ClearTestES3, ClearRGB8)
1683 {
1684 GLFramebuffer fb;
1685 glBindFramebuffer(GL_FRAMEBUFFER, fb);
1686
1687 GLTexture tex;
1688 glBindTexture(GL_TEXTURE_2D, tex);
1689 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, 1, 1);
1690 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1691 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1692
1693 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
1694 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1695
1696 // Clear the texture through framebuffer.
1697 const GLubyte kClearColor[] = {63, 127, 191, 55};
1698 glClearColor(kClearColor[0] / 255.0f, kClearColor[1] / 255.0f, kClearColor[2] / 255.0f,
1699 kClearColor[3] / 255.0f);
1700 glClear(GL_COLOR_BUFFER_BIT);
1701 ASSERT_GL_NO_ERROR();
1702
1703 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1704
1705 // Sample from it and verify clear is done.
1706 ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Texture2DLod(), essl3_shaders::fs::Texture2DLod());
1707 glUseProgram(program);
1708 GLint textureLocation = glGetUniformLocation(program, essl3_shaders::Texture2DUniform());
1709 ASSERT_NE(-1, textureLocation);
1710 GLint lodLocation = glGetUniformLocation(program, essl3_shaders::LodUniform());
1711 ASSERT_NE(-1, lodLocation);
1712
1713 glUniform1i(textureLocation, 0);
1714 glUniform1f(lodLocation, 0);
1715
1716 drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
1717
1718 EXPECT_PIXEL_NEAR(0, 0, kClearColor[0], kClearColor[1], kClearColor[2], 255, 1);
1719 ASSERT_GL_NO_ERROR();
1720 }
1721
1722 // Test that clearing RGB8 attachments from a 2D texture array does not cause
1723 // VUID-VkImageMemoryBarrier-oldLayout-01197
TEST_P(ClearTestES3,TextureArrayRGB8)1724 TEST_P(ClearTestES3, TextureArrayRGB8)
1725 {
1726 GLFramebuffer fb;
1727 glBindFramebuffer(GL_FRAMEBUFFER, fb);
1728
1729 GLTexture tex;
1730 glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
1731 glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGB8, 1, 1, 2);
1732 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1733 glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1734
1735 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 0);
1736 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, tex, 0, 1);
1737
1738 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1739
1740 GLenum bufs[2] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
1741 glDrawBuffers(2, &bufs[0]);
1742
1743 glClearColor(1.0, 0.0, 1.0, 1.0);
1744 glClear(GL_COLOR_BUFFER_BIT);
1745 ASSERT_GL_NO_ERROR();
1746
1747 glBindFramebuffer(GL_READ_FRAMEBUFFER, fb);
1748
1749 glReadBuffer(GL_COLOR_ATTACHMENT0);
1750 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);
1751
1752 glReadBuffer(GL_COLOR_ATTACHMENT1);
1753 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);
1754
1755 EXPECT_GL_NO_ERROR();
1756 }
1757
maskedScissoredColorDepthStencilClear(const MaskedScissoredClearVariationsTestParams & params)1758 void MaskedScissoredClearTestBase::maskedScissoredColorDepthStencilClear(
1759 const MaskedScissoredClearVariationsTestParams ¶ms)
1760 {
1761 // Flaky on Android Nexus 5x and Pixel 2, possible Qualcomm driver bug.
1762 // TODO(jmadill): Re-enable when possible. http://anglebug.com/42261257
1763 ANGLE_SKIP_TEST_IF(IsOpenGLES() && IsAndroid());
1764
1765 const int w = getWindowWidth();
1766 const int h = getWindowHeight();
1767 const int wthird = w / 3;
1768 const int hthird = h / 3;
1769
1770 constexpr float kPreClearDepth = 0.9f;
1771 constexpr float kClearDepth = 0.5f;
1772 constexpr uint8_t kPreClearStencil = 0xFF;
1773 constexpr uint8_t kClearStencil = 0x16;
1774 constexpr uint8_t kStencilMask = 0x59;
1775 constexpr uint8_t kMaskedClearStencil =
1776 (kPreClearStencil & ~kStencilMask) | (kClearStencil & kStencilMask);
1777
1778 bool clearColor, clearDepth, clearStencil;
1779 bool maskColor, maskDepth, maskStencil;
1780 bool scissor;
1781
1782 ParseMaskedScissoredClearVariationsTestParams(params, &clearColor, &clearDepth, &clearStencil,
1783 &maskColor, &maskDepth, &maskStencil, &scissor);
1784
1785 // Clear to a random color, 0.9 depth and 0x00 stencil
1786 Vector4 color1(0.1f, 0.2f, 0.3f, 0.4f);
1787 GLColor color1RGB(color1);
1788
1789 glClearColor(color1[0], color1[1], color1[2], color1[3]);
1790 glClearDepthf(kPreClearDepth);
1791 glClearStencil(kPreClearStencil);
1792
1793 if (!clearColor)
1794 {
1795 // If not asked to clear color, clear it anyway, but individually. The clear value is
1796 // still used to verify that the depth/stencil clear happened correctly. This allows
1797 // testing for depth/stencil-only clear implementations.
1798 glClear(GL_COLOR_BUFFER_BIT);
1799 }
1800
1801 glClear((clearColor ? GL_COLOR_BUFFER_BIT : 0) | (clearDepth ? GL_DEPTH_BUFFER_BIT : 0) |
1802 (clearStencil ? GL_STENCIL_BUFFER_BIT : 0));
1803 ASSERT_GL_NO_ERROR();
1804
1805 // Verify color was cleared correctly.
1806 EXPECT_PIXEL_COLOR_NEAR(0, 0, color1RGB, 1);
1807
1808 if (scissor)
1809 {
1810 glEnable(GL_SCISSOR_TEST);
1811 glScissor(wthird / 2, hthird / 2, wthird, hthird);
1812 }
1813
1814 // Use color and stencil masks to clear to a second color, 0.5 depth and 0x59 stencil.
1815 Vector4 color2(0.2f, 0.4f, 0.6f, 0.8f);
1816 GLColor color2RGB(color2);
1817 glClearColor(color2[0], color2[1], color2[2], color2[3]);
1818 glClearDepthf(kClearDepth);
1819 glClearStencil(kClearStencil);
1820 if (maskColor)
1821 {
1822 glColorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_FALSE);
1823 }
1824 if (maskDepth)
1825 {
1826 glDepthMask(GL_FALSE);
1827 }
1828 if (maskStencil)
1829 {
1830 glStencilMask(kStencilMask);
1831 }
1832 glClear((clearColor ? GL_COLOR_BUFFER_BIT : 0) | (clearDepth ? GL_DEPTH_BUFFER_BIT : 0) |
1833 (clearStencil ? GL_STENCIL_BUFFER_BIT : 0));
1834 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1835 glDepthMask(GL_TRUE);
1836 glStencilMask(0xFF);
1837 glDisable(GL_DEPTH_TEST);
1838 glDisable(GL_STENCIL_TEST);
1839 glDisable(GL_SCISSOR_TEST);
1840 ASSERT_GL_NO_ERROR();
1841
1842 GLColor color2MaskedRGB(color2RGB[0], color1RGB[1], color2RGB[2], color1RGB[3]);
1843
1844 // If not clearing color, the original color should be left both in the center and corners. If
1845 // using a scissor, the corners should be left to the original color, while the center is
1846 // possibly changed. If using a mask, the center (and corners if not scissored), changes to
1847 // the masked results.
1848 GLColor expectedCenterColorRGB = !clearColor ? color1RGB
1849 : maskColor ? color2MaskedRGB
1850 : color2RGB;
1851 GLColor expectedCornerColorRGB = scissor ? color1RGB : expectedCenterColorRGB;
1852
1853 // Verify second clear color mask worked as expected.
1854 EXPECT_PIXEL_COLOR_NEAR(wthird, hthird, expectedCenterColorRGB, 1);
1855
1856 EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedCornerColorRGB, 1);
1857 EXPECT_PIXEL_COLOR_NEAR(w - 1, 0, expectedCornerColorRGB, 1);
1858 EXPECT_PIXEL_COLOR_NEAR(0, h - 1, expectedCornerColorRGB, 1);
1859 EXPECT_PIXEL_COLOR_NEAR(w - 1, h - 1, expectedCornerColorRGB, 1);
1860 EXPECT_PIXEL_COLOR_NEAR(wthird, 2 * hthird, expectedCornerColorRGB, 1);
1861 EXPECT_PIXEL_COLOR_NEAR(2 * wthird, hthird, expectedCornerColorRGB, 1);
1862 EXPECT_PIXEL_COLOR_NEAR(2 * wthird, 2 * hthird, expectedCornerColorRGB, 1);
1863
1864 // If there is depth, but depth is not asked to be cleared, the depth buffer contains garbage,
1865 // so no particular behavior can be expected.
1866 if (clearDepth || !mHasDepth)
1867 {
1868 // We use a small shader to verify depth.
1869 ANGLE_GL_PROGRAM(depthTestProgram, essl1_shaders::vs::Passthrough(),
1870 essl1_shaders::fs::Blue());
1871 glEnable(GL_DEPTH_TEST);
1872 glDepthFunc(maskDepth ? GL_GREATER : GL_EQUAL);
1873 // - If depth is cleared, but it's masked, kPreClearDepth should be in the depth buffer.
1874 // - If depth is cleared, but it's not masked, kClearDepth should be in the depth buffer.
1875 // - If depth is not cleared, the if above ensures there is no depth buffer at all,
1876 // which means depth test will always pass.
1877 drawQuad(depthTestProgram, essl1_shaders::PositionAttrib(), maskDepth ? 1.0f : 0.0f);
1878 glDisable(GL_DEPTH_TEST);
1879 ASSERT_GL_NO_ERROR();
1880
1881 // Either way, we expect blue to be written to the center.
1882 expectedCenterColorRGB = GLColor::blue;
1883 // If there is no depth, depth test always passes so the whole image must be blue. Same if
1884 // depth write is masked.
1885 expectedCornerColorRGB =
1886 mHasDepth && scissor && !maskDepth ? expectedCornerColorRGB : GLColor::blue;
1887
1888 EXPECT_PIXEL_COLOR_NEAR(wthird, hthird, expectedCenterColorRGB, 1);
1889
1890 EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedCornerColorRGB, 1);
1891 EXPECT_PIXEL_COLOR_NEAR(w - 1, 0, expectedCornerColorRGB, 1);
1892 EXPECT_PIXEL_COLOR_NEAR(0, h - 1, expectedCornerColorRGB, 1);
1893 EXPECT_PIXEL_COLOR_NEAR(w - 1, h - 1, expectedCornerColorRGB, 1);
1894 EXPECT_PIXEL_COLOR_NEAR(wthird, 2 * hthird, expectedCornerColorRGB, 1);
1895 EXPECT_PIXEL_COLOR_NEAR(2 * wthird, hthird, expectedCornerColorRGB, 1);
1896 EXPECT_PIXEL_COLOR_NEAR(2 * wthird, 2 * hthird, expectedCornerColorRGB, 1);
1897 }
1898
1899 // If there is stencil, but it's not asked to be cleared, there is similarly no expectation.
1900 if (clearStencil || !mHasStencil)
1901 {
1902 // And another small shader to verify stencil.
1903 ANGLE_GL_PROGRAM(stencilTestProgram, essl1_shaders::vs::Passthrough(),
1904 essl1_shaders::fs::Green());
1905 glEnable(GL_STENCIL_TEST);
1906 // - If stencil is cleared, but it's masked, kMaskedClearStencil should be in the stencil
1907 // buffer.
1908 // - If stencil is cleared, but it's not masked, kClearStencil should be in the stencil
1909 // buffer.
1910 // - If stencil is not cleared, the if above ensures there is no stencil buffer at all,
1911 // which means stencil test will always pass.
1912 glStencilFunc(GL_EQUAL, maskStencil ? kMaskedClearStencil : kClearStencil, 0xFF);
1913 drawQuad(stencilTestProgram, essl1_shaders::PositionAttrib(), 0.0f);
1914 glDisable(GL_STENCIL_TEST);
1915 ASSERT_GL_NO_ERROR();
1916
1917 // Either way, we expect green to be written to the center.
1918 expectedCenterColorRGB = GLColor::green;
1919 // If there is no stencil, stencil test always passes so the whole image must be green.
1920 expectedCornerColorRGB = mHasStencil && scissor ? expectedCornerColorRGB : GLColor::green;
1921
1922 EXPECT_PIXEL_COLOR_NEAR(wthird, hthird, expectedCenterColorRGB, 1);
1923
1924 EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedCornerColorRGB, 1);
1925 EXPECT_PIXEL_COLOR_NEAR(w - 1, 0, expectedCornerColorRGB, 1);
1926 EXPECT_PIXEL_COLOR_NEAR(0, h - 1, expectedCornerColorRGB, 1);
1927 EXPECT_PIXEL_COLOR_NEAR(w - 1, h - 1, expectedCornerColorRGB, 1);
1928 EXPECT_PIXEL_COLOR_NEAR(wthird, 2 * hthird, expectedCornerColorRGB, 1);
1929 EXPECT_PIXEL_COLOR_NEAR(2 * wthird, hthird, expectedCornerColorRGB, 1);
1930 EXPECT_PIXEL_COLOR_NEAR(2 * wthird, 2 * hthird, expectedCornerColorRGB, 1);
1931 }
1932 }
1933
1934 // Tests combinations of color, depth, stencil clears with or without masks or scissor.
TEST_P(MaskedScissoredClearTest,Test)1935 TEST_P(MaskedScissoredClearTest, Test)
1936 {
1937 maskedScissoredColorDepthStencilClear(GetParam());
1938 }
1939
1940 // Tests combinations of color, depth, stencil clears with or without masks or scissor.
1941 //
1942 // This uses depth/stencil attachments that are single-channel, but are emulated with a format
1943 // that has both channels.
TEST_P(VulkanClearTest,Test)1944 TEST_P(VulkanClearTest, Test)
1945 {
1946 bool clearColor, clearDepth, clearStencil;
1947 bool maskColor, maskDepth, maskStencil;
1948 bool scissor;
1949
1950 ParseMaskedScissoredClearVariationsTestParams(GetParam(), &clearColor, &clearDepth,
1951 &clearStencil, &maskColor, &maskDepth,
1952 &maskStencil, &scissor);
1953
1954 // We only care about clearing depth xor stencil.
1955 if (clearDepth == clearStencil)
1956 {
1957 return;
1958 }
1959
1960 if (clearDepth)
1961 {
1962 // Creating a depth-only renderbuffer is an ES3 feature.
1963 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
1964 bindColorDepthFBO();
1965 }
1966 else
1967 {
1968 bindColorStencilFBO();
1969 }
1970
1971 maskedScissoredColorDepthStencilClear(GetParam());
1972 }
1973
1974 // Tests that clearing a non existing attachment works.
TEST_P(ClearTest,ClearColorThenClearNonExistingDepthStencil)1975 TEST_P(ClearTest, ClearColorThenClearNonExistingDepthStencil)
1976 {
1977 constexpr GLsizei kSize = 16;
1978
1979 GLTexture color;
1980 glBindTexture(GL_TEXTURE_2D, color);
1981 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1982
1983 GLFramebuffer fbo;
1984 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1985 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
1986 ASSERT_GL_NO_ERROR();
1987 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1988
1989 // Clear color.
1990 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
1991 glClear(GL_COLOR_BUFFER_BIT);
1992
1993 // Clear depth/stencil.
1994 glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1995 ASSERT_GL_NO_ERROR();
1996
1997 // Read back color.
1998 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1999 }
2000
2001 // Tests that clearing a non existing attachment works.
TEST_P(ClearTestES3,ClearDepthStencilThenClearNonExistingColor)2002 TEST_P(ClearTestES3, ClearDepthStencilThenClearNonExistingColor)
2003 {
2004 constexpr GLsizei kSize = 16;
2005
2006 GLRenderbuffer depth;
2007 glBindRenderbuffer(GL_RENDERBUFFER, depth);
2008 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);
2009
2010 GLFramebuffer fbo;
2011 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2012 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depth);
2013 ASSERT_GL_NO_ERROR();
2014 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2015
2016 // Clear depth/stencil.
2017 glClearDepthf(1.0f);
2018 glClearStencil(0xAA);
2019 glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2020 ASSERT_GL_NO_ERROR();
2021
2022 // Clear color.
2023 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
2024 glClear(GL_COLOR_BUFFER_BIT);
2025 ASSERT_GL_NO_ERROR();
2026 }
2027
2028 // Test that just clearing a nonexistent drawbuffer of the default framebuffer doesn't cause an
2029 // assert.
TEST_P(ClearTestES3,ClearBuffer1OnDefaultFramebufferNoAssert)2030 TEST_P(ClearTestES3, ClearBuffer1OnDefaultFramebufferNoAssert)
2031 {
2032 std::vector<GLuint> testUint(4);
2033 glClearBufferuiv(GL_COLOR, 1, testUint.data());
2034 std::vector<GLint> testInt(4);
2035 glClearBufferiv(GL_COLOR, 1, testInt.data());
2036 std::vector<GLfloat> testFloat(4);
2037 glClearBufferfv(GL_COLOR, 1, testFloat.data());
2038 EXPECT_GL_NO_ERROR();
2039 }
2040
2041 // Clears many small concentric rectangles using scissor regions.
TEST_P(ClearTest,InceptionScissorClears)2042 TEST_P(ClearTest, InceptionScissorClears)
2043 {
2044 angle::RNG rng;
2045
2046 constexpr GLuint kSize = 16;
2047
2048 // Create a square user FBO so we have more control over the dimensions.
2049 GLFramebuffer fbo;
2050 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2051
2052 GLRenderbuffer rbo;
2053 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
2054 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);
2055
2056 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
2057 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2058
2059 glViewport(0, 0, kSize, kSize);
2060
2061 // Draw small concentric squares using scissor.
2062 std::vector<GLColor> expectedColors;
2063 for (GLuint index = 0; index < (kSize - 1) / 2; index++)
2064 {
2065 // Do the first clear without the scissor.
2066 if (index > 0)
2067 {
2068 glEnable(GL_SCISSOR_TEST);
2069 glScissor(index, index, kSize - (index * 2), kSize - (index * 2));
2070 }
2071
2072 GLColor color = RandomColor(&rng);
2073 expectedColors.push_back(color);
2074 Vector4 floatColor = color.toNormalizedVector();
2075 glClearColor(floatColor[0], floatColor[1], floatColor[2], floatColor[3]);
2076 glClear(GL_COLOR_BUFFER_BIT);
2077 }
2078
2079 ASSERT_GL_NO_ERROR();
2080
2081 std::vector<GLColor> actualColors(expectedColors.size());
2082 glReadPixels(0, kSize / 2, actualColors.size(), 1, GL_RGBA, GL_UNSIGNED_BYTE,
2083 actualColors.data());
2084
2085 EXPECT_EQ(expectedColors, actualColors);
2086 }
2087
2088 // Clears many small concentric rectangles using scissor regions.
TEST_P(ClearTest,DrawThenInceptionScissorClears)2089 TEST_P(ClearTest, DrawThenInceptionScissorClears)
2090 {
2091 angle::RNG rng;
2092
2093 constexpr GLuint kSize = 16;
2094
2095 // Create a square user FBO so we have more control over the dimensions.
2096 GLFramebuffer fbo;
2097 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2098
2099 GLRenderbuffer rbo;
2100 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
2101 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);
2102
2103 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
2104 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2105
2106 glViewport(0, 0, kSize, kSize);
2107
2108 ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
2109 drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.5f);
2110 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2111
2112 // Draw small concentric squares using scissor.
2113 std::vector<GLColor> expectedColors;
2114 for (GLuint index = 0; index < (kSize - 1) / 2; index++)
2115 {
2116 // Do the first clear without the scissor.
2117 if (index > 0)
2118 {
2119 glEnable(GL_SCISSOR_TEST);
2120 glScissor(index, index, kSize - (index * 2), kSize - (index * 2));
2121 }
2122
2123 GLColor color = RandomColor(&rng);
2124 expectedColors.push_back(color);
2125 Vector4 floatColor = color.toNormalizedVector();
2126 glClearColor(floatColor[0], floatColor[1], floatColor[2], floatColor[3]);
2127 glClear(GL_COLOR_BUFFER_BIT);
2128 }
2129
2130 ASSERT_GL_NO_ERROR();
2131
2132 std::vector<GLColor> actualColors(expectedColors.size());
2133 glReadPixels(0, kSize / 2, actualColors.size(), 1, GL_RGBA, GL_UNSIGNED_BYTE,
2134 actualColors.data());
2135
2136 EXPECT_EQ(expectedColors, actualColors);
2137 }
2138
2139 // Test that clearBuffer with disabled non-zero drawbuffer or disabled read source doesn't cause an
2140 // assert.
TEST_P(ClearTestES3,ClearDisabledNonZeroAttachmentNoAssert)2141 TEST_P(ClearTestES3, ClearDisabledNonZeroAttachmentNoAssert)
2142 {
2143 // http://anglebug.com/40644728
2144 ANGLE_SKIP_TEST_IF(IsMac() && IsDesktopOpenGL());
2145
2146 GLFramebuffer fb;
2147 glBindFramebuffer(GL_FRAMEBUFFER, fb);
2148
2149 GLRenderbuffer rb;
2150 glBindRenderbuffer(GL_RENDERBUFFER, rb);
2151 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 16, 16);
2152
2153 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, rb);
2154 glDrawBuffers(0, nullptr);
2155 glReadBuffer(GL_NONE);
2156
2157 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2158
2159 float clearColorf[4] = {0.5, 0.5, 0.5, 0.5};
2160 glClearBufferfv(GL_COLOR, 1, clearColorf);
2161
2162 GLuint clearColorui[4] = {255, 255, 255, 255};
2163 glClearBufferuiv(GL_COLOR, 1, clearColorui);
2164
2165 GLint clearColori[4] = {-127, -127, -127, -127};
2166 glClearBufferiv(GL_COLOR, 1, clearColori);
2167
2168 EXPECT_GL_NO_ERROR();
2169 }
2170
2171 // Test that having a framebuffer with maximum number of attachments and clearing color, depth and
2172 // stencil works.
TEST_P(ClearTestES3,ClearMaxAttachments)2173 TEST_P(ClearTestES3, ClearMaxAttachments)
2174 {
2175 // http://anglebug.com/40644728
2176 ANGLE_SKIP_TEST_IF(IsMac() && IsDesktopOpenGL());
2177 // http://anglebug.com/42263935
2178 ANGLE_SKIP_TEST_IF(IsAMD() && IsD3D11());
2179
2180 constexpr GLsizei kSize = 16;
2181
2182 GLint maxDrawBuffers = 0;
2183 glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
2184 ASSERT_GE(maxDrawBuffers, 4);
2185
2186 // Setup framebuffer.
2187 GLFramebuffer fb;
2188 glBindFramebuffer(GL_FRAMEBUFFER, fb);
2189
2190 std::vector<GLRenderbuffer> color(maxDrawBuffers);
2191 std::vector<GLenum> drawBuffers(maxDrawBuffers);
2192
2193 for (GLint colorIndex = 0; colorIndex < maxDrawBuffers; ++colorIndex)
2194 {
2195 glBindRenderbuffer(GL_RENDERBUFFER, color[colorIndex]);
2196 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);
2197 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + colorIndex,
2198 GL_RENDERBUFFER, color[colorIndex]);
2199
2200 drawBuffers[colorIndex] = GL_COLOR_ATTACHMENT0 + colorIndex;
2201 }
2202
2203 GLRenderbuffer depthStencil;
2204 glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
2205 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);
2206 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2207 depthStencil);
2208
2209 EXPECT_GL_NO_ERROR();
2210 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2211
2212 glDrawBuffers(maxDrawBuffers, drawBuffers.data());
2213
2214 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
2215 glClearDepthf(1.0f);
2216 glClearStencil(0x55);
2217 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2218 EXPECT_GL_NO_ERROR();
2219
2220 // Verify that every color attachment is cleared correctly.
2221 for (GLint colorIndex = 0; colorIndex < maxDrawBuffers; ++colorIndex)
2222 {
2223 glReadBuffer(GL_COLOR_ATTACHMENT0 + colorIndex);
2224
2225 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2226 EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::red);
2227 EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::red);
2228 EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::red);
2229 }
2230
2231 // Verify that depth and stencil attachments are cleared correctly.
2232 GLFramebuffer fbVerify;
2233 glBindFramebuffer(GL_FRAMEBUFFER, fbVerify);
2234
2235 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color[0]);
2236 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2237 depthStencil);
2238
2239 // If depth is not cleared to 1, rendering would fail.
2240 glEnable(GL_DEPTH_TEST);
2241 glDepthFunc(GL_LESS);
2242
2243 // If stencil is not cleared to 0x55, rendering would fail.
2244 glEnable(GL_STENCIL_TEST);
2245 glStencilFunc(GL_EQUAL, 0x55, 0xFF);
2246 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
2247 glStencilMask(0xFF);
2248
2249 // Draw green.
2250 ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
2251 drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.95f);
2252
2253 // Verify that green was drawn.
2254 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2255 EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::green);
2256 EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::green);
2257 EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::green);
2258 }
2259
2260 // Test that having a framebuffer with maximum number of attachments and clearing color, depth and
2261 // stencil after a draw call works.
TEST_P(ClearTestES3,ClearMaxAttachmentsAfterDraw)2262 TEST_P(ClearTestES3, ClearMaxAttachmentsAfterDraw)
2263 {
2264 // http://anglebug.com/40644728
2265 ANGLE_SKIP_TEST_IF(IsMac() && IsDesktopOpenGL());
2266
2267 constexpr GLsizei kSize = 16;
2268
2269 GLint maxDrawBuffers = 0;
2270 glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
2271 ASSERT_GE(maxDrawBuffers, 4);
2272
2273 // Setup framebuffer.
2274 GLFramebuffer fb;
2275 glBindFramebuffer(GL_FRAMEBUFFER, fb);
2276
2277 std::vector<GLRenderbuffer> color(maxDrawBuffers);
2278 std::vector<GLenum> drawBuffers(maxDrawBuffers);
2279
2280 for (GLint colorIndex = 0; colorIndex < maxDrawBuffers; ++colorIndex)
2281 {
2282 glBindRenderbuffer(GL_RENDERBUFFER, color[colorIndex]);
2283 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);
2284 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + colorIndex,
2285 GL_RENDERBUFFER, color[colorIndex]);
2286
2287 drawBuffers[colorIndex] = GL_COLOR_ATTACHMENT0 + colorIndex;
2288 }
2289
2290 GLRenderbuffer depthStencil;
2291 glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
2292 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);
2293 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2294 depthStencil);
2295
2296 EXPECT_GL_NO_ERROR();
2297 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2298
2299 glDrawBuffers(maxDrawBuffers, drawBuffers.data());
2300
2301 // Issue a draw call to render blue, depth=0 and stencil 0x3C to the attachments.
2302 glEnable(GL_DEPTH_TEST);
2303 glDepthFunc(GL_ALWAYS);
2304
2305 glEnable(GL_STENCIL_TEST);
2306 glStencilFunc(GL_ALWAYS, 0x3C, 0xFF);
2307 glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
2308 glStencilMask(0xFF);
2309
2310 // Generate shader for this framebuffer.
2311 std::stringstream strstr;
2312 strstr << "#version 300 es\n"
2313 "precision highp float;\n";
2314 for (GLint colorIndex = 0; colorIndex < maxDrawBuffers; ++colorIndex)
2315 {
2316 strstr << "layout(location = " << colorIndex << ") out vec4 value" << colorIndex << ";\n";
2317 }
2318 strstr << "void main()\n"
2319 "{\n";
2320 for (GLint colorIndex = 0; colorIndex < maxDrawBuffers; ++colorIndex)
2321 {
2322 strstr << "value" << colorIndex << " = vec4(0.0f, 0.0f, 1.0f, 1.0f);\n";
2323 }
2324 strstr << "}\n";
2325
2326 ANGLE_GL_PROGRAM(drawMRT, essl3_shaders::vs::Simple(), strstr.str().c_str());
2327 drawQuad(drawMRT, essl3_shaders::PositionAttrib(), 0.0f);
2328 ASSERT_GL_NO_ERROR();
2329
2330 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
2331 glClearDepthf(1.0f);
2332 glClearStencil(0x55);
2333 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2334 EXPECT_GL_NO_ERROR();
2335
2336 // Verify that every color attachment is cleared correctly.
2337 for (GLint colorIndex = 0; colorIndex < maxDrawBuffers; ++colorIndex)
2338 {
2339 glReadBuffer(GL_COLOR_ATTACHMENT0 + colorIndex);
2340
2341 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red) << colorIndex;
2342 EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::red) << colorIndex;
2343 EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::red) << colorIndex;
2344 EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::red) << colorIndex;
2345 }
2346
2347 // Verify that depth and stencil attachments are cleared correctly.
2348 GLFramebuffer fbVerify;
2349 glBindFramebuffer(GL_FRAMEBUFFER, fbVerify);
2350
2351 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color[0]);
2352 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2353 depthStencil);
2354
2355 // If depth is not cleared to 1, rendering would fail.
2356 glDepthFunc(GL_LESS);
2357
2358 // If stencil is not cleared to 0x55, rendering would fail.
2359 glStencilFunc(GL_EQUAL, 0x55, 0xFF);
2360 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
2361
2362 // Draw green.
2363 ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
2364 drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.95f);
2365
2366 // Verify that green was drawn.
2367 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2368 EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::green);
2369 EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::green);
2370 EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::green);
2371 }
2372
2373 // Test that mixed masked clear works after clear.
TEST_P(ClearTestES3,ClearThenMixedMaskedClear)2374 TEST_P(ClearTestES3, ClearThenMixedMaskedClear)
2375 {
2376 constexpr GLsizei kSize = 16;
2377
2378 // Setup framebuffer.
2379 GLRenderbuffer color;
2380 glBindRenderbuffer(GL_RENDERBUFFER, color);
2381 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);
2382
2383 GLRenderbuffer depthStencil;
2384 glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
2385 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);
2386
2387 GLFramebuffer fb;
2388 glBindFramebuffer(GL_FRAMEBUFFER, fb);
2389 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color);
2390 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2391 depthStencil);
2392 EXPECT_GL_NO_ERROR();
2393 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2394
2395 // Clear color and depth/stencil
2396 glClearColor(0.1f, 1.0f, 0.0f, 0.7f);
2397 glClearDepthf(0.0f);
2398 glClearStencil(0x55);
2399 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2400
2401 // Clear again, but with color and stencil masked
2402 glClearColor(1.0f, 0.2f, 0.6f, 1.0f);
2403 glClearDepthf(1.0f);
2404 glClearStencil(0x3C);
2405 glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_TRUE);
2406 glStencilMask(0xF0);
2407 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2408
2409 // Issue a draw call to verify color, depth and stencil.
2410
2411 // If depth is not cleared to 1, rendering would fail.
2412 glEnable(GL_DEPTH_TEST);
2413 glDepthFunc(GL_LESS);
2414
2415 // If stencil is not cleared to 0x35, rendering would fail.
2416 glEnable(GL_STENCIL_TEST);
2417 glStencilFunc(GL_EQUAL, 0x35, 0xFF);
2418 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
2419 glStencilMask(0xFF);
2420 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
2421
2422 ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
2423 glUseProgram(drawColor);
2424 GLint colorUniformLocation =
2425 glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
2426 ASSERT_NE(colorUniformLocation, -1);
2427
2428 // Blend half-transparent blue into the color buffer.
2429 glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 0.5f);
2430 glEnable(GL_BLEND);
2431 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2432 drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.95f);
2433 ASSERT_GL_NO_ERROR();
2434
2435 // Verify that the color buffer is now gray
2436 const GLColor kExpected(127, 127, 127, 191);
2437 EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpected, 1);
2438 EXPECT_PIXEL_COLOR_NEAR(0, kSize - 1, kExpected, 1);
2439 EXPECT_PIXEL_COLOR_NEAR(kSize - 1, 0, kExpected, 1);
2440 EXPECT_PIXEL_COLOR_NEAR(kSize - 1, kSize - 1, kExpected, 1);
2441 }
2442
2443 // Test that clearing stencil after a draw call works.
TEST_P(ClearTestES3,ClearStencilAfterDraw)2444 TEST_P(ClearTestES3, ClearStencilAfterDraw)
2445 {
2446 // http://anglebug.com/40644728
2447 ANGLE_SKIP_TEST_IF(IsMac() && IsDesktopOpenGL());
2448
2449 constexpr GLsizei kSize = 16;
2450
2451 GLint maxDrawBuffers = 0;
2452 glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
2453 ASSERT_GE(maxDrawBuffers, 4);
2454
2455 // Setup framebuffer.
2456 GLFramebuffer fb;
2457 glBindFramebuffer(GL_FRAMEBUFFER, fb);
2458
2459 std::vector<GLRenderbuffer> color(maxDrawBuffers);
2460 std::vector<GLenum> drawBuffers(maxDrawBuffers);
2461
2462 for (GLint colorIndex = 0; colorIndex < maxDrawBuffers; ++colorIndex)
2463 {
2464 glBindRenderbuffer(GL_RENDERBUFFER, color[colorIndex]);
2465 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);
2466 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + colorIndex,
2467 GL_RENDERBUFFER, color[colorIndex]);
2468
2469 drawBuffers[colorIndex] = GL_COLOR_ATTACHMENT0 + colorIndex;
2470 }
2471
2472 GLRenderbuffer depthStencil;
2473 glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
2474 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);
2475 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2476 depthStencil);
2477
2478 EXPECT_GL_NO_ERROR();
2479 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2480
2481 glDrawBuffers(maxDrawBuffers, drawBuffers.data());
2482
2483 // Issue a draw call to render blue and stencil 0x3C to the attachments.
2484 glEnable(GL_STENCIL_TEST);
2485 glStencilFunc(GL_ALWAYS, 0x3C, 0xFF);
2486 glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
2487 glStencilMask(0xFF);
2488
2489 // Generate shader for this framebuffer.
2490 std::stringstream strstr;
2491 strstr << "#version 300 es\n"
2492 "precision highp float;\n";
2493 for (GLint colorIndex = 0; colorIndex < maxDrawBuffers; ++colorIndex)
2494 {
2495 strstr << "layout(location = " << colorIndex << ") out vec4 value" << colorIndex << ";\n";
2496 }
2497 strstr << "void main()\n"
2498 "{\n";
2499 for (GLint colorIndex = 0; colorIndex < maxDrawBuffers; ++colorIndex)
2500 {
2501 strstr << "value" << colorIndex << " = vec4(0.0f, 0.0f, 1.0f, 1.0f);\n";
2502 }
2503 strstr << "}\n";
2504
2505 ANGLE_GL_PROGRAM(drawMRT, essl3_shaders::vs::Simple(), strstr.str().c_str());
2506 drawQuad(drawMRT, essl3_shaders::PositionAttrib(), 0.0f);
2507 ASSERT_GL_NO_ERROR();
2508
2509 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
2510 glClearStencil(0x55);
2511 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2512 EXPECT_GL_NO_ERROR();
2513
2514 // Verify that every color attachment is cleared correctly.
2515 for (GLint colorIndex = 0; colorIndex < maxDrawBuffers; ++colorIndex)
2516 {
2517 glReadBuffer(GL_COLOR_ATTACHMENT0 + colorIndex);
2518
2519 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2520 EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::red);
2521 EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::red);
2522 EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::red);
2523 }
2524
2525 // Verify that depth and stencil attachments are cleared correctly.
2526 GLFramebuffer fbVerify;
2527 glBindFramebuffer(GL_FRAMEBUFFER, fbVerify);
2528
2529 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color[0]);
2530 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2531 depthStencil);
2532
2533 // If stencil is not cleared to 0x55, rendering would fail.
2534 glStencilFunc(GL_EQUAL, 0x55, 0xFF);
2535 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
2536
2537 // Draw green.
2538 ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
2539 drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.95f);
2540
2541 // Verify that green was drawn.
2542 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2543 EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::green);
2544 EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::green);
2545 EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::green);
2546 }
2547
2548 // Test that mid-render pass clearing of mixed used and unused color attachments works.
TEST_P(ClearTestES3,MixedRenderPassClearMixedUsedUnusedAttachments)2549 TEST_P(ClearTestES3, MixedRenderPassClearMixedUsedUnusedAttachments)
2550 {
2551 // http://anglebug.com/40644728
2552 ANGLE_SKIP_TEST_IF(IsMac() && IsDesktopOpenGL());
2553
2554 constexpr GLsizei kSize = 16;
2555
2556 // Setup framebuffer.
2557 GLFramebuffer fb;
2558 glBindFramebuffer(GL_FRAMEBUFFER, fb);
2559
2560 GLRenderbuffer color[2];
2561
2562 for (GLint colorIndex = 0; colorIndex < 2; ++colorIndex)
2563 {
2564 glBindRenderbuffer(GL_RENDERBUFFER, color[colorIndex]);
2565 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);
2566 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + colorIndex,
2567 GL_RENDERBUFFER, color[colorIndex]);
2568 }
2569 EXPECT_GL_NO_ERROR();
2570 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2571
2572 // Disable color attachment 0.
2573 GLenum drawBuffers[] = {GL_NONE, GL_COLOR_ATTACHMENT1};
2574 glDrawBuffers(2, drawBuffers);
2575
2576 // Draw into color attachment 1
2577 constexpr char kFS[] = R"(#version 300 es
2578 precision highp float;
2579 layout(location = 0) out vec4 color0;
2580 layout(location = 1) out vec4 color1;
2581 void main()
2582 {
2583 color0 = vec4(0, 0, 1, 1);
2584 color1 = vec4(1, 0, 0, 1);
2585 })";
2586
2587 ANGLE_GL_PROGRAM(drawMRT, essl3_shaders::vs::Simple(), kFS);
2588 drawQuad(drawMRT, essl3_shaders::PositionAttrib(), 0.0f);
2589 ASSERT_GL_NO_ERROR();
2590
2591 // Color attachment 0 is now uninitialized, while color attachment 1 is red.
2592 // Re-enable color attachment 0 and clear both attachments to green.
2593 drawBuffers[0] = GL_COLOR_ATTACHMENT0;
2594 glDrawBuffers(2, drawBuffers);
2595
2596 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
2597 glClear(GL_COLOR_BUFFER_BIT);
2598 EXPECT_GL_NO_ERROR();
2599
2600 // Verify that both color attachments are now green.
2601 glReadBuffer(GL_COLOR_ATTACHMENT0);
2602 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2603 glReadBuffer(GL_COLOR_ATTACHMENT1);
2604 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2605 EXPECT_GL_NO_ERROR();
2606 }
2607
2608 // Test that draw without state change after masked clear works
TEST_P(ClearTestES3,DrawClearThenDrawWithoutStateChange)2609 TEST_P(ClearTestES3, DrawClearThenDrawWithoutStateChange)
2610 {
2611 swapBuffers();
2612 constexpr GLsizei kSize = 16;
2613
2614 // Setup framebuffer.
2615 GLRenderbuffer color;
2616 glBindRenderbuffer(GL_RENDERBUFFER, color);
2617 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);
2618
2619 GLFramebuffer fb;
2620 glBindFramebuffer(GL_FRAMEBUFFER, fb);
2621 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color);
2622 EXPECT_GL_NO_ERROR();
2623 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2624
2625 // Clear color initially.
2626 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
2627 glClear(GL_COLOR_BUFFER_BIT);
2628
2629 // Mask color.
2630 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
2631
2632 ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
2633 glUseProgram(drawColor);
2634 GLint colorUniformLocation =
2635 glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
2636 ASSERT_NE(colorUniformLocation, -1);
2637
2638 // Initialize position attribute.
2639 GLint posLoc = glGetAttribLocation(drawColor, essl1_shaders::PositionAttrib());
2640 ASSERT_NE(-1, posLoc);
2641 setupQuadVertexBuffer(0.5f, 1.0f);
2642 glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
2643 glEnableVertexAttribArray(posLoc);
2644
2645 // Draw red.
2646 glViewport(0, 0, kSize, kSize);
2647 glClearColor(0.0f, 1.0f, 0.0f, 0.0f);
2648 glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 0.5f);
2649 glDrawArrays(GL_TRIANGLES, 0, 6);
2650
2651 // Clear to green without any state change.
2652 glClear(GL_COLOR_BUFFER_BIT);
2653
2654 // Draw red again without any state change.
2655 glDrawArrays(GL_TRIANGLES, 0, 6);
2656
2657 // Verify that the color buffer is now red
2658 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2659 EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::red);
2660 EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::red);
2661 EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::red);
2662 }
2663
2664 // Test that clear stencil value is correctly masked to 8 bits.
TEST_P(ClearTest,ClearStencilMask)2665 TEST_P(ClearTest, ClearStencilMask)
2666 {
2667 GLint stencilBits = 0;
2668 glGetIntegerv(GL_STENCIL_BITS, &stencilBits);
2669 EXPECT_EQ(stencilBits, 8);
2670
2671 ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
2672 glUseProgram(drawColor);
2673
2674 glClearColor(0, 0, 0, 1);
2675 glClear(GL_COLOR_BUFFER_BIT);
2676 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2677
2678 // Clear stencil value must be masked to 0x42
2679 glClearStencil(0x142);
2680 glClear(GL_STENCIL_BUFFER_BIT);
2681
2682 // Check that the stencil test works as expected
2683 glEnable(GL_STENCIL_TEST);
2684
2685 // Negative case
2686 glStencilFunc(GL_NOTEQUAL, 0x42, 0xFF);
2687 drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
2688 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2689
2690 // Positive case
2691 glStencilFunc(GL_EQUAL, 0x42, 0xFF);
2692 drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
2693 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2694
2695 ASSERT_GL_NO_ERROR();
2696 }
2697
2698 // Test that glClearBufferiv correctly masks the clear stencil value.
TEST_P(ClearTestES3,ClearBufferivStencilMask)2699 TEST_P(ClearTestES3, ClearBufferivStencilMask)
2700 {
2701 GLint stencilBits = 0;
2702 glGetIntegerv(GL_STENCIL_BITS, &stencilBits);
2703 EXPECT_EQ(stencilBits, 8);
2704
2705 ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
2706 glUseProgram(drawColor);
2707
2708 glClearColor(0, 0, 0, 1);
2709 glClear(GL_COLOR_BUFFER_BIT);
2710 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2711
2712 // Clear stencil value must be masked to 0x42
2713 const GLint kStencilClearValue = 0x142;
2714 glClearBufferiv(GL_STENCIL, 0, &kStencilClearValue);
2715
2716 // Check that the stencil test works as expected
2717 glEnable(GL_STENCIL_TEST);
2718
2719 // Negative case
2720 glStencilFunc(GL_NOTEQUAL, 0x42, 0xFF);
2721 drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
2722 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2723
2724 // Positive case
2725 glStencilFunc(GL_EQUAL, 0x42, 0xFF);
2726 drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
2727 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2728
2729 ASSERT_GL_NO_ERROR();
2730 }
2731
2732 // Test that glClearBufferfi correctly masks the clear stencil value.
TEST_P(ClearTestES3,ClearBufferfiStencilMask)2733 TEST_P(ClearTestES3, ClearBufferfiStencilMask)
2734 {
2735 GLint stencilBits = 0;
2736 glGetIntegerv(GL_STENCIL_BITS, &stencilBits);
2737 EXPECT_EQ(stencilBits, 8);
2738
2739 ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
2740 glUseProgram(drawColor);
2741
2742 glClearColor(0, 0, 0, 1);
2743 glClear(GL_COLOR_BUFFER_BIT);
2744 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2745
2746 // Clear stencil value must be masked to 0x42
2747 glClearBufferfi(GL_DEPTH_STENCIL, 0, 0.5f, 0x142);
2748
2749 // Check that the stencil test works as expected
2750 glEnable(GL_STENCIL_TEST);
2751
2752 // Negative case
2753 glStencilFunc(GL_NOTEQUAL, 0x42, 0xFF);
2754 drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
2755 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2756
2757 // Positive case
2758 glStencilFunc(GL_EQUAL, 0x42, 0xFF);
2759 drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
2760 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2761
2762 ASSERT_GL_NO_ERROR();
2763 }
2764
2765 // Test that glClearBufferfi works when stencil attachment is not present.
TEST_P(ClearTestES3,ClearBufferfiNoStencilAttachment)2766 TEST_P(ClearTestES3, ClearBufferfiNoStencilAttachment)
2767 {
2768 constexpr GLsizei kSize = 16;
2769
2770 GLRenderbuffer color;
2771 glBindRenderbuffer(GL_RENDERBUFFER, color);
2772 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);
2773
2774 GLRenderbuffer depth;
2775 glBindRenderbuffer(GL_RENDERBUFFER, depth);
2776 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, kSize, kSize);
2777
2778 GLFramebuffer fbo;
2779 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2780 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color);
2781 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);
2782 EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2783 EXPECT_GL_NO_ERROR();
2784
2785 // Clear depth/stencil with glClearBufferfi. Note that the stencil attachment doesn't exist.
2786 glClearBufferfi(GL_DEPTH_STENCIL, 0, 0.5f, 0x55);
2787 EXPECT_GL_NO_ERROR();
2788
2789 // Verify depth is cleared correctly.
2790 verifyDepth(0.5f, kSize);
2791 }
2792
2793 // Test that scissored clear followed by non-scissored draw works. Ensures that when scissor size
2794 // is expanded, the clear operation remains limited to the scissor region. Written to catch
2795 // potential future bugs if loadOp=CLEAR is used in the Vulkan backend for a small render pass and
2796 // then the render area is mistakenly enlarged.
TEST_P(ClearTest,ScissoredClearThenNonScissoredDraw)2797 TEST_P(ClearTest, ScissoredClearThenNonScissoredDraw)
2798 {
2799 constexpr GLsizei kSize = 16;
2800 const std::vector<GLColor> kInitialData(kSize * kSize, GLColor::red);
2801
2802 // Setup framebuffer. Initialize color with red.
2803 GLTexture color;
2804 glBindTexture(GL_TEXTURE_2D, color);
2805 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2806 kInitialData.data());
2807
2808 GLFramebuffer fb;
2809 glBindFramebuffer(GL_FRAMEBUFFER, fb);
2810 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
2811 EXPECT_GL_NO_ERROR();
2812 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2813
2814 // Issue a scissored clear to green.
2815 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
2816 glScissor(kSize / 2, 0, kSize / 2, kSize);
2817 glEnable(GL_SCISSOR_TEST);
2818 glClear(GL_COLOR_BUFFER_BIT);
2819
2820 // Expand the scissor and blend blue into the framebuffer.
2821 glScissor(0, 0, kSize, kSize);
2822 glEnable(GL_BLEND);
2823 glBlendFunc(GL_ONE, GL_ONE);
2824
2825 ANGLE_GL_PROGRAM(drawBlue, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
2826 drawQuad(drawBlue, essl1_shaders::PositionAttrib(), 0.5f);
2827 ASSERT_GL_NO_ERROR();
2828
2829 // Verify that the left half is magenta, and the right half is cyan.
2830 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);
2831 EXPECT_PIXEL_COLOR_EQ(kSize / 2 - 1, 0, GLColor::magenta);
2832 EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::magenta);
2833 EXPECT_PIXEL_COLOR_EQ(kSize / 2 - 1, kSize - 1, GLColor::magenta);
2834
2835 EXPECT_PIXEL_COLOR_EQ(kSize / 2, 0, GLColor::cyan);
2836 EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize - 1, GLColor::cyan);
2837 EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::cyan);
2838 EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::cyan);
2839 }
2840
2841 // Test that clear followed by a scissored masked clear works.
TEST_P(ClearTest,ClearThenScissoredMaskedClear)2842 TEST_P(ClearTest, ClearThenScissoredMaskedClear)
2843 {
2844 constexpr GLsizei kSize = 16;
2845
2846 // Setup framebuffer
2847 GLTexture color;
2848 glBindTexture(GL_TEXTURE_2D, color);
2849 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2850
2851 GLFramebuffer fb;
2852 glBindFramebuffer(GL_FRAMEBUFFER, fb);
2853 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
2854 EXPECT_GL_NO_ERROR();
2855 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2856
2857 // Clear to red.
2858 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
2859 glClear(GL_COLOR_BUFFER_BIT);
2860
2861 // Mask red and clear to green with a scissor
2862 glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_TRUE);
2863 glScissor(0, 0, kSize / 2, kSize);
2864 glEnable(GL_SCISSOR_TEST);
2865 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
2866 glClear(GL_COLOR_BUFFER_BIT);
2867
2868 // Verify that the left half is yellow, and the right half is red.
2869 EXPECT_PIXEL_RECT_EQ(0, 0, kSize / 2, kSize, GLColor::yellow);
2870 EXPECT_PIXEL_RECT_EQ(kSize / 2, 0, kSize / 2, kSize, GLColor::red);
2871 }
2872
2873 // Test that a scissored stencil clear followed by a full clear works.
TEST_P(ClearTestES3,StencilScissoredClearThenFullClear)2874 TEST_P(ClearTestES3, StencilScissoredClearThenFullClear)
2875 {
2876 constexpr GLsizei kSize = 128;
2877
2878 GLint stencilBits = 0;
2879 glGetIntegerv(GL_STENCIL_BITS, &stencilBits);
2880 EXPECT_EQ(stencilBits, 8);
2881
2882 // Clear stencil value must be masked to 0x42
2883 glClearBufferfi(GL_DEPTH_STENCIL, 0, 0.5f, 0x142);
2884
2885 glClearColor(1, 0, 0, 1);
2886 glClear(GL_COLOR_BUFFER_BIT);
2887 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2888
2889 // Shrink the render area.
2890 glScissor(kSize / 2, 0, kSize / 2, kSize);
2891 glEnable(GL_SCISSOR_TEST);
2892
2893 // Clear stencil.
2894 glClearBufferfi(GL_DEPTH_STENCIL, 0, 0.5f, 0x64);
2895
2896 // Grow the render area.
2897 glScissor(0, 0, kSize, kSize);
2898 glEnable(GL_SCISSOR_TEST);
2899
2900 // Check that the stencil test works as expected
2901 glEnable(GL_STENCIL_TEST);
2902
2903 // Scissored region is green, outside is red (clear color)
2904 glStencilFunc(GL_EQUAL, 0x64, 0xFF);
2905 ANGLE_GL_PROGRAM(drawGreen, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());
2906 glUseProgram(drawGreen);
2907 drawQuad(drawGreen, essl3_shaders::PositionAttrib(), 0.5f);
2908 EXPECT_PIXEL_RECT_EQ(0, 0, kSize / 2, kSize, GLColor::red);
2909 EXPECT_PIXEL_RECT_EQ(kSize / 2, 0, kSize / 2, kSize, GLColor::green);
2910
2911 // Outside scissored region is blue.
2912 glStencilFunc(GL_EQUAL, 0x42, 0xFF);
2913 ANGLE_GL_PROGRAM(drawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());
2914 glUseProgram(drawBlue);
2915 drawQuad(drawBlue, essl3_shaders::PositionAttrib(), 0.5f);
2916 EXPECT_PIXEL_RECT_EQ(0, 0, kSize / 2, kSize, GLColor::blue);
2917 EXPECT_PIXEL_RECT_EQ(kSize / 2, 0, kSize / 2, kSize, GLColor::green);
2918
2919 ASSERT_GL_NO_ERROR();
2920 }
2921
2922 // This is a test that must be verified visually.
2923 //
2924 // Tests that clear of the default framebuffer applies to the window.
TEST_P(ClearTest,DISABLED_ClearReachesWindow)2925 TEST_P(ClearTest, DISABLED_ClearReachesWindow)
2926 {
2927 ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
2928
2929 // Draw blue.
2930 drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);
2931 swapBuffers();
2932
2933 // Use glClear to clear to red. Regression test for the Vulkan backend where this clear
2934 // remained "deferred" and didn't make it to the window on swap.
2935 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
2936 glClear(GL_COLOR_BUFFER_BIT);
2937 swapBuffers();
2938
2939 // Wait for visual verification.
2940 angle::Sleep(2000);
2941 }
2942
2943 // Tests that masked clear after a no-op framebuffer binding change with an open render pass works.
TEST_P(ClearTest,DrawThenChangeFBOBindingAndBackThenMaskedClear)2944 TEST_P(ClearTest, DrawThenChangeFBOBindingAndBackThenMaskedClear)
2945 {
2946 ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
2947
2948 // Draw blue.
2949 drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);
2950
2951 // Change framebuffer and back
2952 glBindFramebuffer(GL_FRAMEBUFFER, mFBOs[0]);
2953 glBindFramebuffer(GL_FRAMEBUFFER, 0);
2954
2955 // Masked clear
2956 glColorMask(1, 0, 0, 1);
2957 glClearColor(1.0f, 0.5f, 0.5f, 1.0f);
2958 glClear(GL_COLOR_BUFFER_BIT);
2959
2960 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);
2961 }
2962
2963 // Test that clearing slices of a 3D texture and reading them back works.
TEST_P(ClearTestES3,ClearAndReadPixels3DTexture)2964 TEST_P(ClearTestES3, ClearAndReadPixels3DTexture)
2965 {
2966 constexpr uint32_t kWidth = 128;
2967 constexpr uint32_t kHeight = 128;
2968 constexpr uint32_t kDepth = 7;
2969
2970 GLTexture texture;
2971 glBindTexture(GL_TEXTURE_3D, texture);
2972 glTexStorage3D(GL_TEXTURE_3D, 1, GL_RGBA8, kWidth, kHeight, kDepth);
2973 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
2974
2975 std::array<GLColor, kDepth> clearColors = {
2976 GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow,
2977 GLColor::cyan, GLColor::magenta, GLColor::white,
2978 };
2979
2980 GLFramebuffer framebuffer;
2981 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
2982
2983 for (uint32_t z = 0; z < kDepth; ++z)
2984 {
2985 glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0, z);
2986 glClearBufferfv(GL_COLOR, 0, clearColors[z].toNormalizedVector().data());
2987 }
2988
2989 for (uint32_t z = 0; z < kDepth; ++z)
2990 {
2991 glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0, z);
2992 EXPECT_PIXEL_COLOR_EQ(0, 0, clearColors[z]);
2993 }
2994 }
2995
2996 // Test that clearing stencil with zero first byte in mask doesn't crash.
TEST_P(ClearTestES3,ClearStencilZeroFirstByteMask)2997 TEST_P(ClearTestES3, ClearStencilZeroFirstByteMask)
2998 {
2999 glStencilMask(0xe7d6a900);
3000 glClear(GL_STENCIL_BUFFER_BIT);
3001 }
3002
3003 // Same test as ClearStencilZeroFirstByteMask, but using glClearBufferiv.
TEST_P(ClearTestES3,ClearBufferStencilZeroFirstByteMask)3004 TEST_P(ClearTestES3, ClearBufferStencilZeroFirstByteMask)
3005 {
3006 glStencilMask(0xe7d6a900);
3007 const GLint kStencilClearValue = 0x55;
3008 glClearBufferiv(GL_STENCIL, 0, &kStencilClearValue);
3009 }
3010
3011 // Test that mid render pass clear after draw sets the render pass size correctly.
TEST_P(ClearTestES3,ScissoredDrawThenFullClear)3012 TEST_P(ClearTestES3, ScissoredDrawThenFullClear)
3013 {
3014 const int w = getWindowWidth();
3015 const int h = getWindowHeight();
3016
3017 // Use viewport to imply scissor on the draw call
3018 glViewport(w / 4, h / 4, w / 2, h / 2);
3019
3020 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Blue());
3021 drawQuad(program, essl1_shaders::PositionAttrib(), 0);
3022
3023 // Mid-render-pass clear without scissor or viewport change, which covers the whole framebuffer.
3024 glClearColor(1, 1, 0, 1);
3025 glClear(GL_COLOR_BUFFER_BIT);
3026
3027 EXPECT_PIXEL_RECT_EQ(0, 0, w, h, GLColor::yellow);
3028 }
3029
3030 // Test that mid render pass clear after masked clear sets the render pass size correctly.
TEST_P(ClearTestES3,MaskedScissoredClearThenFullClear)3031 TEST_P(ClearTestES3, MaskedScissoredClearThenFullClear)
3032 {
3033 const int w = getWindowWidth();
3034 const int h = getWindowHeight();
3035
3036 // Use viewport to imply a small scissor on (non-existing) draw calls. This is important to
3037 // make sure render area that's derived from scissor+viewport for draw calls doesn't
3038 // accidentally fix render area derived from scissor for clear calls.
3039 glViewport(w / 2, h / 2, 1, 1);
3040
3041 glEnable(GL_SCISSOR_TEST);
3042 glScissor(w / 4, h / 4, w / 2, h / 2);
3043 glColorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_FALSE);
3044 glClearColor(0.13, 0.38, 0.87, 0.65);
3045 glClear(GL_COLOR_BUFFER_BIT);
3046
3047 // Mid-render-pass clear without scissor, which covers the whole framebuffer.
3048 glDisable(GL_SCISSOR_TEST);
3049 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3050 glClearColor(1, 1, 0, 1);
3051 glClear(GL_COLOR_BUFFER_BIT);
3052
3053 EXPECT_PIXEL_RECT_EQ(0, 0, w, h, GLColor::yellow);
3054 }
3055
3056 // Test that mid render pass masked clear after masked clear sets the render pass size correctly.
TEST_P(ClearTestES3,MaskedScissoredClearThenFullMaskedClear)3057 TEST_P(ClearTestES3, MaskedScissoredClearThenFullMaskedClear)
3058 {
3059 const int w = getWindowWidth();
3060 const int h = getWindowHeight();
3061
3062 // Make sure the framebuffer is initialized.
3063 glClearColor(0, 0, 0, 1);
3064 glClear(GL_COLOR_BUFFER_BIT);
3065 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
3066
3067 // Use viewport to imply a small scissor on (non-existing) draw calls This is important to
3068 // make sure render area that's derived from scissor+viewport for draw calls doesn't
3069 // accidentally fix render area derived from scissor for clear calls.
3070 glViewport(w / 2, h / 2, 1, 1);
3071
3072 glEnable(GL_SCISSOR_TEST);
3073 glScissor(w / 4, h / 4, w / 2, h / 2);
3074 glColorMask(GL_TRUE, GL_FALSE, GL_TRUE, GL_FALSE);
3075 glClearColor(1, 1, 0, 1);
3076 glClear(GL_COLOR_BUFFER_BIT);
3077
3078 // Mid-render-pass clear without scissor, which covers the whole framebuffer.
3079 glDisable(GL_SCISSOR_TEST);
3080 glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE);
3081 glClearColor(1, 1, 1, 1);
3082 glClear(GL_COLOR_BUFFER_BIT);
3083
3084 EXPECT_PIXEL_RECT_EQ(0, 0, w / 4, h, GLColor::green);
3085 EXPECT_PIXEL_RECT_EQ(w / 4, 0, w / 2, h / 4, GLColor::green);
3086 EXPECT_PIXEL_RECT_EQ(w / 4, 3 * h / 4, w / 2, h / 4, GLColor::green);
3087 EXPECT_PIXEL_RECT_EQ(3 * w / 4, 0, w / 4, h, GLColor::green);
3088
3089 EXPECT_PIXEL_RECT_EQ(w / 4, h / 4, w / 2, h / 2, GLColor::yellow);
3090 }
3091
3092 // Test that reclearing color to the same value works.
TEST_P(ClearTestES3,RepeatedColorClear)3093 TEST_P(ClearTestES3, RepeatedColorClear)
3094 {
3095 glClearColor(1, 1, 0, 1);
3096 glClear(GL_COLOR_BUFFER_BIT);
3097 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
3098
3099 glClear(GL_COLOR_BUFFER_BIT);
3100 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
3101
3102 ASSERT_GL_NO_ERROR();
3103 }
3104
3105 // Test that reclearing depth to the same value works.
TEST_P(ClearTestES3,RepeatedDepthClear)3106 TEST_P(ClearTestES3, RepeatedDepthClear)
3107 {
3108 glClearDepthf(0.25f);
3109 glClear(GL_DEPTH_BUFFER_BIT);
3110
3111 verifyDepth(0.25f, 1);
3112
3113 glClear(GL_DEPTH_BUFFER_BIT);
3114
3115 verifyDepth(0.25f, 1);
3116
3117 ASSERT_GL_NO_ERROR();
3118 }
3119
3120 // Test that reclearing stencil to the same value works.
TEST_P(ClearTestES3,RepeatedStencilClear)3121 TEST_P(ClearTestES3, RepeatedStencilClear)
3122 {
3123 glClearStencil(0xE4);
3124 glClear(GL_STENCIL_BUFFER_BIT);
3125 verifyStencil(0xE4, 1);
3126
3127 glClear(GL_STENCIL_BUFFER_BIT);
3128 verifyStencil(0xE4, 1);
3129
3130 ASSERT_GL_NO_ERROR();
3131 }
3132
3133 // Test that reclearing color to the same value works if color was written to in between with a draw
3134 // call.
TEST_P(ClearTestES3,RepeatedColorClearWithDrawInBetween)3135 TEST_P(ClearTestES3, RepeatedColorClearWithDrawInBetween)
3136 {
3137 glClearColor(1, 0, 0, 1);
3138 glClear(GL_COLOR_BUFFER_BIT);
3139 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3140
3141 glClear(GL_COLOR_BUFFER_BIT);
3142 glEnable(GL_BLEND);
3143 glBlendFunc(GL_ONE, GL_ONE);
3144 ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Green());
3145 drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0);
3146 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
3147
3148 glClear(GL_COLOR_BUFFER_BIT);
3149 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3150
3151 ASSERT_GL_NO_ERROR();
3152 }
3153
3154 // Test that reclearing depth to the same value works if depth was written to in between with a draw
3155 // call.
TEST_P(ClearTestES3,RepeatedDepthClearWithDrawInBetween)3156 TEST_P(ClearTestES3, RepeatedDepthClearWithDrawInBetween)
3157 {
3158 glClearDepthf(0.25f);
3159 glClear(GL_DEPTH_BUFFER_BIT);
3160
3161 ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Green());
3162 glEnable(GL_DEPTH_TEST);
3163 glDepthFunc(GL_ALWAYS);
3164 drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.75f);
3165
3166 glClear(GL_DEPTH_BUFFER_BIT);
3167 glDepthMask(GL_FALSE);
3168 verifyDepth(0.25f, 1);
3169
3170 ASSERT_GL_NO_ERROR();
3171 }
3172
3173 // Test that reclearing stencil to the same value works if stencil was written to in between with a
3174 // draw call.
TEST_P(ClearTestES3,RepeatedStencilClearWithDrawInBetween)3175 TEST_P(ClearTestES3, RepeatedStencilClearWithDrawInBetween)
3176 {
3177 glClearStencil(0xE4);
3178 glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
3179 glStencilFunc(GL_ALWAYS, 0x3C, 0xFF);
3180 glEnable(GL_STENCIL_TEST);
3181
3182 glClear(GL_STENCIL_BUFFER_BIT);
3183 ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Green());
3184 drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.75f);
3185
3186 glClear(GL_STENCIL_BUFFER_BIT);
3187 verifyStencil(0xE4, 1);
3188
3189 ASSERT_GL_NO_ERROR();
3190 }
3191
3192 // Test that reclearing color to the same value works if color was written to in between with
3193 // glCopyTexSubImage2D.
TEST_P(ClearTestES3,RepeatedColorClearWithCopyInBetween)3194 TEST_P(ClearTestES3, RepeatedColorClearWithCopyInBetween)
3195 {
3196 GLTexture color;
3197 glBindTexture(GL_TEXTURE_2D, color);
3198 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
3199
3200 GLFramebuffer fbo;
3201 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3202 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
3203 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3204
3205 // Clear the texture
3206 glClearColor(1, 0, 0, 1);
3207 glClear(GL_COLOR_BUFFER_BIT);
3208 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3209
3210 // Replace the framebuffer texture
3211 GLTexture color2;
3212 glBindTexture(GL_TEXTURE_2D, color2);
3213 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
3214 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color2, 0);
3215 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3216
3217 // Clear the new texture and copy it to the old texture
3218 glClearColor(0, 1, 0, 1);
3219 glClear(GL_COLOR_BUFFER_BIT);
3220 glBindTexture(GL_TEXTURE_2D, color);
3221 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, getWindowWidth(), getWindowHeight());
3222
3223 // Attach the original texture back to the framebuffer and verify the copy.
3224 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
3225 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3226 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3227
3228 // Clear to the original value and make sure it's applied.
3229 glClearColor(1, 0, 0, 1);
3230 glClear(GL_COLOR_BUFFER_BIT);
3231 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3232
3233 ASSERT_GL_NO_ERROR();
3234 }
3235
3236 // Test that reclearing color to the same value works if color was written to in between with a
3237 // blit.
TEST_P(ClearTestES3,RepeatedColorClearWithBlitInBetween)3238 TEST_P(ClearTestES3, RepeatedColorClearWithBlitInBetween)
3239 {
3240 GLTexture color;
3241 glBindTexture(GL_TEXTURE_2D, color);
3242 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
3243
3244 GLFramebuffer fbo;
3245 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3246 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
3247 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3248
3249 // Clear the texture
3250 glClearColor(1, 0, 0, 1);
3251 glClear(GL_COLOR_BUFFER_BIT);
3252 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3253
3254 // Create another framebuffer as blit src
3255 GLTexture color2;
3256 glBindTexture(GL_TEXTURE_2D, color2);
3257 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
3258
3259 GLFramebuffer fbo2;
3260 glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
3261 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color2, 0);
3262 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3263
3264 // Clear the new framebuffer and blit it to the old one
3265 glClearColor(0, 1, 0, 1);
3266 glClear(GL_COLOR_BUFFER_BIT);
3267 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
3268 glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
3269 getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
3270
3271 // Verify the copy is done correctly.
3272 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
3273 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3274
3275 // Clear to the original value and make sure it's applied.
3276 glClearColor(1, 0, 0, 1);
3277 glClear(GL_COLOR_BUFFER_BIT);
3278 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3279
3280 ASSERT_GL_NO_ERROR();
3281 }
3282
3283 // Test that reclearing depth to the same value works if depth was written to in between with a
3284 // blit.
TEST_P(ClearTestES3,RepeatedDepthClearWithBlitInBetween)3285 TEST_P(ClearTestES3, RepeatedDepthClearWithBlitInBetween)
3286 {
3287 GLTexture color;
3288 glBindTexture(GL_TEXTURE_2D, color);
3289 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
3290
3291 GLRenderbuffer depth;
3292 glBindRenderbuffer(GL_RENDERBUFFER, depth);
3293 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, getWindowWidth(),
3294 getWindowHeight());
3295
3296 GLFramebuffer fbo;
3297 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3298 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
3299 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);
3300 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3301
3302 // Clear depth
3303 glClearDepthf(0.25f);
3304 glClearColor(1, 0, 0, 1);
3305 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
3306 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3307 verifyDepth(0.25f, 1);
3308
3309 // Create another framebuffer as blit src
3310 GLRenderbuffer depth2;
3311 glBindRenderbuffer(GL_RENDERBUFFER, depth2);
3312 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, getWindowWidth(),
3313 getWindowHeight());
3314
3315 GLFramebuffer fbo2;
3316 glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
3317 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth2);
3318 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3319
3320 // Clear the new framebuffer and blit it to the old one
3321 glClearDepthf(0.75f);
3322 glClear(GL_DEPTH_BUFFER_BIT);
3323 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
3324 glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
3325 getWindowHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
3326
3327 // Verify the copy is done correctly.
3328 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
3329 verifyDepth(0.75f, 1);
3330
3331 // Clear to the original value and make sure it's applied.
3332 glClearDepthf(0.25f);
3333 glClear(GL_DEPTH_BUFFER_BIT);
3334 verifyDepth(0.25f, 1);
3335
3336 ASSERT_GL_NO_ERROR();
3337 }
3338
3339 // Test that reclearing stencil to the same value works if stencil was written to in between with a
3340 // blit.
TEST_P(ClearTestES3,RepeatedStencilClearWithBlitInBetween)3341 TEST_P(ClearTestES3, RepeatedStencilClearWithBlitInBetween)
3342 {
3343 GLTexture color;
3344 glBindTexture(GL_TEXTURE_2D, color);
3345 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
3346
3347 GLRenderbuffer stencil;
3348 glBindRenderbuffer(GL_RENDERBUFFER, stencil);
3349 glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, getWindowWidth(), getWindowHeight());
3350
3351 GLFramebuffer fbo;
3352 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3353 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
3354 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencil);
3355 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3356
3357 // Clear stencil
3358 glClearStencil(0xE4);
3359 glClearColor(1, 0, 0, 1);
3360 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3361 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3362 verifyStencil(0xE4, 1);
3363
3364 // Create another framebuffer as blit src
3365 GLRenderbuffer stencil2;
3366 glBindRenderbuffer(GL_RENDERBUFFER, stencil2);
3367 glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, getWindowWidth(), getWindowHeight());
3368
3369 GLFramebuffer fbo2;
3370 glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
3371 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencil2);
3372 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3373
3374 // Clear the new framebuffer and blit it to the old one
3375 glClearStencil(0x35);
3376 glClear(GL_STENCIL_BUFFER_BIT);
3377 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
3378 glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
3379 getWindowHeight(), GL_STENCIL_BUFFER_BIT, GL_NEAREST);
3380
3381 // Verify the copy is done correctly.
3382 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
3383 verifyStencil(0x35, 1);
3384
3385 // Clear to the original value and make sure it's applied.
3386 glClearStencil(0xE4);
3387 glClear(GL_STENCIL_BUFFER_BIT);
3388 verifyStencil(0xE4, 1);
3389
3390 ASSERT_GL_NO_ERROR();
3391 }
3392
3393 // Test that reclearing color to the same value works if color was written to in between with a
3394 // compute shader.
TEST_P(ClearTestES31,RepeatedColorClearWithDispatchInBetween)3395 TEST_P(ClearTestES31, RepeatedColorClearWithDispatchInBetween)
3396 {
3397 GLTexture color;
3398 glBindTexture(GL_TEXTURE_2D, color);
3399 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
3400
3401 GLFramebuffer fbo;
3402 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3403 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
3404 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3405
3406 // Clear the texture
3407 glClearColor(1, 0, 0, 1);
3408 glClear(GL_COLOR_BUFFER_BIT);
3409 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3410
3411 // Write to the texture with a compute shader.
3412 constexpr char kCS[] = R"(#version 310 es
3413 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
3414 layout(rgba8) uniform highp writeonly image2D imageOut;
3415 void main()
3416 {
3417 imageStore(imageOut, ivec2(gl_GlobalInvocationID.xy), vec4(0, 1, 0, 1));
3418 })";
3419
3420 ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
3421 glUseProgram(program);
3422 glBindImageTexture(0, color, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8);
3423
3424 glDispatchCompute(getWindowWidth(), getWindowHeight(), 1);
3425 EXPECT_GL_NO_ERROR();
3426
3427 glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
3428
3429 // Verify the compute shader overwrites the image correctly.
3430 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3431
3432 // Clear to the original value and make sure it's applied.
3433 glClearColor(1, 0, 0, 1);
3434 glClear(GL_COLOR_BUFFER_BIT);
3435 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3436
3437 ASSERT_GL_NO_ERROR();
3438 }
3439
3440 // Test that clearing a 3D image bound to a layered framebuffer works using only attachment 0.
TEST_P(ClearTestES31,Bind3DTextureAndClearUsingAttachment0)3441 TEST_P(ClearTestES31, Bind3DTextureAndClearUsingAttachment0)
3442 {
3443 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
3444
3445 constexpr uint32_t kSize = 16;
3446 constexpr uint32_t kAttachmentCount = 4;
3447 std::vector<GLColor> pixelData(kSize * kSize * kAttachmentCount, GLColor::white);
3448
3449 GLTexture texture3D;
3450 glBindTexture(GL_TEXTURE_3D, texture3D);
3451 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, kSize, kSize, kAttachmentCount, 0, GL_RGBA,
3452 GL_UNSIGNED_BYTE, pixelData.data());
3453
3454 GLFramebuffer fbo;
3455 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3456 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_LAYERS, kAttachmentCount);
3457 glFramebufferTextureEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture3D, 0);
3458 ASSERT_GL_NO_ERROR();
3459
3460 glClearColor(1.0, 0.0, 0.0, 1.0);
3461 glClear(GL_COLOR_BUFFER_BIT);
3462
3463 for (uint32_t i = 0; i < kAttachmentCount; ++i)
3464 {
3465 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture3D, 0, i);
3466 ASSERT_GL_NO_ERROR();
3467 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3468 ASSERT_GL_NO_ERROR();
3469 }
3470 }
3471
3472 // Test that clearing a 3D image bound to a layered framebuffer works using multiple attachments.
TEST_P(ClearTestES31,Bind3DTextureAndClearUsingMultipleAttachments)3473 TEST_P(ClearTestES31, Bind3DTextureAndClearUsingMultipleAttachments)
3474 {
3475 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
3476
3477 constexpr uint32_t kSize = 16;
3478 constexpr uint32_t kAttachmentCount = 4;
3479 std::vector<GLColor> pixelData(kSize * kSize * kAttachmentCount, GLColor::white);
3480
3481 GLTexture texture3D;
3482 glBindTexture(GL_TEXTURE_3D, texture3D);
3483 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, kSize, kSize, kAttachmentCount, 0, GL_RGBA,
3484 GL_UNSIGNED_BYTE, pixelData.data());
3485
3486 GLFramebuffer fbo;
3487 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3488 glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_LAYERS, kAttachmentCount);
3489 glFramebufferTextureEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture3D, 0);
3490 ASSERT_GL_NO_ERROR();
3491
3492 glClearColor(1.0, 0.0, 0.0, 1.0);
3493 glClear(GL_COLOR_BUFFER_BIT);
3494
3495 const GLenum usedAttachment[kAttachmentCount] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
3496 GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT1};
3497 for (uint32_t i = 0; i < kAttachmentCount; ++i)
3498 {
3499 glFramebufferTextureLayer(GL_FRAMEBUFFER, usedAttachment[i], texture3D, 0, i);
3500 ASSERT_GL_NO_ERROR();
3501 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3502 ASSERT_GL_NO_ERROR();
3503 }
3504 }
3505
3506 // Test that reclearing depth to the same value works if depth is blit after clear, and depth is
3507 // modified in between with a draw call.
TEST_P(ClearTestES3,RepeatedDepthClearWithBlitAfterClearAndDrawInBetween)3508 TEST_P(ClearTestES3, RepeatedDepthClearWithBlitAfterClearAndDrawInBetween)
3509 {
3510 glClearDepthf(0.25f);
3511 glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3512
3513 // Make sure clear is flushed.
3514 GLRenderbuffer depth;
3515 glBindRenderbuffer(GL_RENDERBUFFER, depth);
3516 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, getWindowWidth(),
3517 getWindowHeight());
3518
3519 GLFramebuffer fbo;
3520 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
3521 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);
3522 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
3523
3524 glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
3525 getWindowHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
3526
3527 // Draw to depth, and break the render pass.
3528 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
3529 ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Green());
3530 glEnable(GL_DEPTH_TEST);
3531 glDepthFunc(GL_ALWAYS);
3532 drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.75f);
3533 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3534
3535 // Clear back to the original value
3536 glClear(GL_DEPTH_BUFFER_BIT);
3537
3538 // Blit again.
3539 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
3540 glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
3541 getWindowHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
3542
3543 // Make sure the cleared value is in destination, not the modified value.
3544 GLTexture color;
3545 glBindTexture(GL_TEXTURE_2D, color);
3546 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
3547
3548 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
3549 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
3550 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
3551 verifyDepth(0.25f, 1);
3552
3553 ASSERT_GL_NO_ERROR();
3554 }
3555
3556 // Test that gaps in framebuffer attachments do not cause race
3557 // conditions when a clear op is followed by a draw call.
TEST_P(ClearTestES3,DrawAfterClearWithGaps)3558 TEST_P(ClearTestES3, DrawAfterClearWithGaps)
3559 {
3560 constexpr char kVS[] = R"(#version 300 es
3561 precision highp float;
3562 void main() {
3563 vec2 offset = vec2((gl_VertexID & 1) == 0 ? -1.0 : 1.0, (gl_VertexID & 2) == 0 ? -1.0 : 1.0);
3564 gl_Position = vec4(offset * 0.125 - 0.5, 0.0, 1.0);
3565 })";
3566
3567 constexpr char kFS[] = R"(#version 300 es
3568 precision mediump float;
3569 layout(location=0) out vec4 color0;
3570 layout(location=2) out vec4 color2;
3571 void main() {
3572 color0 = vec4(1, 0, 1, 1);
3573 color2 = vec4(1, 1, 0, 1);
3574 })";
3575
3576 ANGLE_GL_PROGRAM(program, kVS, kFS);
3577 glUseProgram(program);
3578
3579 constexpr int kSize = 1024;
3580
3581 GLRenderbuffer rb0;
3582 glBindRenderbuffer(GL_RENDERBUFFER, rb0);
3583 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);
3584
3585 GLRenderbuffer rb2;
3586 glBindRenderbuffer(GL_RENDERBUFFER, rb2);
3587 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);
3588
3589 GLFramebuffer fb;
3590 glBindFramebuffer(GL_FRAMEBUFFER, fb);
3591 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb0);
3592 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_RENDERBUFFER, rb2);
3593
3594 GLenum bufs[3] = {GL_COLOR_ATTACHMENT0, GL_NONE, GL_COLOR_ATTACHMENT2};
3595 glDrawBuffers(3, bufs);
3596 glReadBuffer(GL_COLOR_ATTACHMENT2);
3597
3598 glClearColor(0, 1, 0, 1);
3599 glViewport(0, 0, kSize, kSize);
3600
3601 // Draw immediately after clear
3602 glClear(GL_COLOR_BUFFER_BIT);
3603 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3604
3605 std::vector<GLColor> pixels(kSize * kSize, GLColor::transparentBlack);
3606 glReadPixels(0, 0, kSize, kSize, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
3607 ASSERT_GL_NO_ERROR();
3608
3609 for (int y = 0; y < kSize; ++y)
3610 {
3611 for (int x = 0; x < kSize; ++x)
3612 {
3613 const GLColor color = pixels[y * kSize + x];
3614 if (x > 192 && x < 319 && y > 192 && y < 319)
3615 {
3616 EXPECT_EQ(color, GLColor::yellow) << "at " << x << ", " << y;
3617 }
3618 else if (x < 191 || x > 320 || y < 191 || y > 320)
3619 {
3620 EXPECT_EQ(color, GLColor::green) << "at " << x << ", " << y;
3621 }
3622 }
3623 }
3624 }
3625
3626 // Test that mid render pass clears work with gaps in locations.
TEST_P(ClearTestES3,MidRenderPassClearWithGaps)3627 TEST_P(ClearTestES3, MidRenderPassClearWithGaps)
3628 {
3629 constexpr char kVS[] = R"(#version 300 es
3630 precision highp float;
3631 void main() {
3632 // gl_VertexID x y
3633 // 0 -1 -1
3634 // 1 1 -1
3635 // 2 -1 1
3636 // 3 1 1
3637 int bit0 = gl_VertexID & 1;
3638 int bit1 = gl_VertexID >> 1;
3639 gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, gl_VertexID % 2 == 0 ? -1 : 1, 1);
3640 })";
3641
3642 constexpr char kFS[] = R"(#version 300 es
3643 precision mediump float;
3644 layout(location=0) out vec4 color0;
3645 layout(location=2) out vec4 color2;
3646 uniform vec4 color0in;
3647 uniform vec4 color1in;
3648 void main() {
3649 color0 = color0in;
3650 color2 = color1in;
3651 })";
3652
3653 ANGLE_GL_PROGRAM(program, kVS, kFS);
3654 glUseProgram(program);
3655
3656 const GLint color0InLoc = glGetUniformLocation(program, "color0in");
3657 const GLint color1InLoc = glGetUniformLocation(program, "color1in");
3658 ASSERT_NE(color0InLoc, -1);
3659 ASSERT_NE(color1InLoc, -1);
3660
3661 constexpr int kSize = 23;
3662
3663 GLRenderbuffer rb0;
3664 glBindRenderbuffer(GL_RENDERBUFFER, rb0);
3665 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);
3666
3667 GLRenderbuffer rb2;
3668 glBindRenderbuffer(GL_RENDERBUFFER, rb2);
3669 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize, kSize);
3670
3671 GLFramebuffer fb;
3672 glBindFramebuffer(GL_FRAMEBUFFER, fb);
3673 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb0);
3674 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_RENDERBUFFER, rb2);
3675
3676 GLenum bufs[3] = {GL_COLOR_ATTACHMENT0, GL_NONE, GL_COLOR_ATTACHMENT2};
3677 glDrawBuffers(3, bufs);
3678
3679 glViewport(0, 0, kSize, kSize);
3680
3681 // Start with a draw call
3682 glUniform4f(color0InLoc, 0.1, 0.2, 0.3, 0.4);
3683 glUniform4f(color1InLoc, 0.05, 0.15, 0.25, 0.35);
3684 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3685
3686 // Clear in the middle of the render pass
3687 glClearColor(1, 0, 0, 0.6);
3688 glClear(GL_COLOR_BUFFER_BIT);
3689
3690 // Draw with blend, and verify results
3691 glEnable(GL_BLEND);
3692 glBlendFunc(GL_ONE, GL_ONE);
3693 glUniform4f(color0InLoc, 0, 1, 0, 0.5);
3694 glUniform4f(color1InLoc, 0, 0, 1, 0.5);
3695 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
3696
3697 glReadBuffer(GL_COLOR_ATTACHMENT0);
3698 EXPECT_PIXEL_RECT_EQ(0, 0, kSize, kSize, GLColor::yellow);
3699
3700 glReadBuffer(GL_COLOR_ATTACHMENT2);
3701 EXPECT_PIXEL_RECT_EQ(0, 0, kSize, kSize, GLColor::magenta);
3702 }
3703
3704 // Test that reclearing stencil to the same value works if stencil is blit after clear, and stencil
3705 // is modified in between with a draw call.
TEST_P(ClearTestES3,RepeatedStencilClearWithBlitAfterClearAndDrawInBetween)3706 TEST_P(ClearTestES3, RepeatedStencilClearWithBlitAfterClearAndDrawInBetween)
3707 {
3708 glClearStencil(0xE4);
3709 glClear(GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
3710
3711 // Make sure clear is flushed.
3712 GLRenderbuffer stencil;
3713 glBindRenderbuffer(GL_RENDERBUFFER, stencil);
3714 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, getWindowWidth(),
3715 getWindowHeight());
3716
3717 GLFramebuffer fbo;
3718 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
3719 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, stencil);
3720 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
3721
3722 glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
3723 getWindowHeight(), GL_STENCIL_BUFFER_BIT, GL_NEAREST);
3724
3725 // Draw to stencil, and break the render pass.
3726 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
3727 ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Green());
3728 glEnable(GL_STENCIL_TEST);
3729 glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
3730 glStencilFunc(GL_ALWAYS, 0x3C, 0xFF);
3731 drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.75f);
3732 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3733
3734 // Clear back to the original value
3735 glClear(GL_STENCIL_BUFFER_BIT);
3736
3737 // Blit again.
3738 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
3739 glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
3740 getWindowHeight(), GL_STENCIL_BUFFER_BIT, GL_NEAREST);
3741
3742 // Make sure the cleared value is in destination, not the modified value.
3743 GLTexture color;
3744 glBindTexture(GL_TEXTURE_2D, color);
3745 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
3746
3747 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
3748 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
3749 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
3750 verifyStencil(0xE4, 1);
3751
3752 ASSERT_GL_NO_ERROR();
3753 }
3754
3755 // Test basic functionality of clearing a 2D texture with GL_EXT_clear_texture.
TEST_P(ClearTextureEXTTest,Clear2D)3756 TEST_P(ClearTextureEXTTest, Clear2D)
3757 {
3758 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
3759
3760 // Create a 16x16 texture with no data.
3761 GLTexture tex;
3762 glBindTexture(GL_TEXTURE_2D, tex);
3763 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3764
3765 GLFramebuffer fbo;
3766 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3767 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
3768 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3769
3770 // Clear the entire texture
3771 glClearTexImageEXT(tex, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
3772 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::red);
3773
3774 // Clear each corner to a different color
3775 glClearTexSubImageEXT(tex, 0, 0, 0, 0, 8, 8, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3776 glClearTexSubImageEXT(tex, 0, 8, 0, 0, 8, 8, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::blue);
3777 glClearTexSubImageEXT(tex, 0, 0, 8, 0, 8, 8, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::cyan);
3778 glClearTexSubImageEXT(tex, 0, 8, 8, 0, 8, 8, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::yellow);
3779
3780 EXPECT_PIXEL_RECT_EQ(0, 0, 8, 8, GLColor::transparentBlack);
3781 EXPECT_PIXEL_RECT_EQ(8, 0, 8, 8, GLColor::blue);
3782 EXPECT_PIXEL_RECT_EQ(0, 8, 8, 8, GLColor::cyan);
3783 EXPECT_PIXEL_RECT_EQ(8, 8, 8, 8, GLColor::yellow);
3784 }
3785
3786 // Test basic functionality of clearing a 2D RGB texture with GL_EXT_clear_texture.
TEST_P(ClearTextureEXTTest,Clear2DRGB)3787 TEST_P(ClearTextureEXTTest, Clear2DRGB)
3788 {
3789 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
3790
3791 // Create a 16x16 texture with no data.
3792 GLTexture tex;
3793 glBindTexture(GL_TEXTURE_2D, tex);
3794 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 16, 16, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
3795
3796 GLFramebuffer fbo;
3797 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3798 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
3799 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3800
3801 // Clear the entire texture
3802 glClearTexImageEXT(tex, 0, GL_RGB, GL_UNSIGNED_BYTE, &GLColor::red);
3803 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::red);
3804
3805 // Clear each corner to a different color
3806 glClearTexSubImageEXT(tex, 0, 0, 0, 0, 8, 8, 1, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
3807 glClearTexSubImageEXT(tex, 0, 8, 0, 0, 8, 8, 1, GL_RGB, GL_UNSIGNED_BYTE, &GLColor::blue);
3808 glClearTexSubImageEXT(tex, 0, 0, 8, 0, 8, 8, 1, GL_RGB, GL_UNSIGNED_BYTE, &GLColor::cyan);
3809 glClearTexSubImageEXT(tex, 0, 8, 8, 0, 8, 8, 1, GL_RGB, GL_UNSIGNED_BYTE, &GLColor::yellow);
3810
3811 EXPECT_PIXEL_RECT_EQ(0, 0, 8, 8, GLColor::black);
3812 EXPECT_PIXEL_RECT_EQ(8, 0, 8, 8, GLColor::blue);
3813 EXPECT_PIXEL_RECT_EQ(0, 8, 8, 8, GLColor::cyan);
3814 EXPECT_PIXEL_RECT_EQ(8, 8, 8, 8, GLColor::yellow);
3815 }
3816
3817 // Test basic functionality of clearing a part of a 2D texture with GL_EXT_clear_texture.
TEST_P(ClearTextureEXTTest,Clear2DSubImage)3818 TEST_P(ClearTextureEXTTest, Clear2DSubImage)
3819 {
3820 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
3821
3822 // Create a 16x16 texture with no data.
3823 GLTexture tex;
3824 glBindTexture(GL_TEXTURE_2D, tex);
3825 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3826
3827 GLFramebuffer fbo;
3828 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3829 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
3830 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3831
3832 // Clear the center to a different color
3833 glClearTexSubImageEXT(tex, 0, 4, 4, 0, 8, 8, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::cyan);
3834 EXPECT_PIXEL_RECT_EQ(4, 4, 8, 8, GLColor::cyan);
3835 }
3836
3837 // Test clearing a 2D RGBA4 texture with GL_EXT_clear_texture.
TEST_P(ClearTextureEXTTest,Clear2DRGBA4)3838 TEST_P(ClearTextureEXTTest, Clear2DRGBA4)
3839 {
3840 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
3841
3842 // Create a 16x16 texture with no data.
3843 GLTexture tex;
3844 glBindTexture(GL_TEXTURE_2D, tex);
3845 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA4, 16, 16, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4,
3846 nullptr);
3847
3848 GLFramebuffer fbo;
3849 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3850 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
3851 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3852
3853 // Clear the entire texture, then clear each corner to a different color.
3854 GLushort colorRed = 0xF00F;
3855 GLushort colorGreen = 0x0F0F;
3856 GLushort colorBlue = 0x00FF;
3857 GLushort colorYellow = 0xFF0F;
3858
3859 glClearTexImageEXT(tex, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, &colorGreen);
3860 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::green);
3861
3862 glClearTexSubImageEXT(tex, 0, 0, 0, 0, 8, 8, 1, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, nullptr);
3863 glClearTexSubImageEXT(tex, 0, 8, 0, 0, 8, 8, 1, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, &colorBlue);
3864 glClearTexSubImageEXT(tex, 0, 0, 8, 0, 8, 8, 1, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, &colorRed);
3865 glClearTexSubImageEXT(tex, 0, 8, 8, 0, 8, 8, 1, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4,
3866 &colorYellow);
3867
3868 EXPECT_PIXEL_RECT_EQ(0, 0, 8, 8, GLColor::transparentBlack);
3869 EXPECT_PIXEL_RECT_EQ(8, 0, 8, 8, GLColor::blue);
3870 EXPECT_PIXEL_RECT_EQ(0, 8, 8, 8, GLColor::red);
3871 EXPECT_PIXEL_RECT_EQ(8, 8, 8, 8, GLColor::yellow);
3872 }
3873
3874 // Test clearing a 2D RGB8 Snorm texture with GL_EXT_clear_texture.
TEST_P(ClearTextureEXTTest,Clear2DRGB8Snorm)3875 TEST_P(ClearTextureEXTTest, Clear2DRGB8Snorm)
3876 {
3877 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
3878
3879 // Create a 16x16 texture with no data.
3880 GLTexture tex;
3881 glBindTexture(GL_TEXTURE_2D, tex);
3882 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8_SNORM, 16, 16, 0, GL_RGB, GL_BYTE, nullptr);
3883 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3884 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3885
3886 // Clear the entire texture.
3887 GLint colorGreenRGBSnorm = 0x007F00;
3888 glClearTexImageEXT(tex, 0, GL_RGB, GL_BYTE, &colorGreenRGBSnorm);
3889
3890 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
3891 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
3892 EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::green);
3893 }
3894
3895 // Test basic functionality of clearing 2D textures with GL_EXT_clear_texture using nullptr.
TEST_P(ClearTextureEXTTest,Clear2DWithNull)3896 TEST_P(ClearTextureEXTTest, Clear2DWithNull)
3897 {
3898 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
3899
3900 // Create two 16x16 textures with prior data.
3901 std::vector<GLColor> redBlock(16 * 16, GLColor::red);
3902 GLTexture tex;
3903 glBindTexture(GL_TEXTURE_2D, tex);
3904 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 16, 16, 0, GL_RGB, GL_UNSIGNED_BYTE, redBlock.data());
3905
3906 GLTexture tex2;
3907 glBindTexture(GL_TEXTURE_2D, tex2);
3908 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, redBlock.data());
3909
3910 // Clear the RGB texture.
3911 GLFramebuffer fbo;
3912 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3913 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
3914 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3915
3916 GLColor outputColor;
3917 glClearTexImageEXT(tex, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
3918 glReadPixels(0, 0, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, &outputColor);
3919 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::black);
3920
3921 // Clear the RGBA texture.
3922 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2, 0);
3923 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3924
3925 glClearTexImageEXT(tex2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3926 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &outputColor);
3927 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::transparentBlack);
3928 }
3929
3930 // Test basic functionality of clearing a 2D texture while bound to another.
TEST_P(ClearTextureEXTTest,Clear2DDifferentBinding)3931 TEST_P(ClearTextureEXTTest, Clear2DDifferentBinding)
3932 {
3933 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
3934
3935 // Create two 16x16 textures with no data.
3936 GLTexture tex1;
3937 glBindTexture(GL_TEXTURE_2D, tex1);
3938 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3939
3940 GLTexture tex2;
3941 glBindTexture(GL_TEXTURE_2D, tex2);
3942 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3943
3944 // Use clear on both textures while none are bound.
3945 glBindTexture(GL_TEXTURE_2D, 0);
3946 glClearTexImageEXT(tex1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
3947 glClearTexImageEXT(tex2, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::blue);
3948
3949 // Bind to one texture while clearing the other.
3950 glBindTexture(GL_TEXTURE_2D, tex2);
3951 glClearTexImageEXT(tex1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
3952
3953 GLFramebuffer fbo;
3954 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3955 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex1, 0);
3956 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3957 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::green);
3958
3959 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2, 0);
3960 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3961 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::blue);
3962 }
3963
3964 // Test basic functionality of clearing 2D textures without binding to them.
TEST_P(ClearTextureEXTTest,Clear2DNoBinding)3965 TEST_P(ClearTextureEXTTest, Clear2DNoBinding)
3966 {
3967 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
3968
3969 // Create two 16x16 textures with no data.
3970 GLTexture tex1;
3971 glBindTexture(GL_TEXTURE_2D, tex1);
3972 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3973
3974 GLTexture tex2;
3975 glBindTexture(GL_TEXTURE_2D, tex2);
3976 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3977
3978 // Use clear on both textures while bound to neither.
3979 glBindTexture(GL_TEXTURE_2D, 0);
3980 glClearTexImageEXT(tex1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
3981 glClearTexImageEXT(tex2, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::blue);
3982
3983 GLFramebuffer fbo;
3984 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3985 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex1, 0);
3986 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3987 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::red);
3988
3989 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex2, 0);
3990 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3991 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::blue);
3992 }
3993
3994 // Test basic functionality of clearing a 2D texture with prior staged update.
TEST_P(ClearTextureEXTTest,Clear2DOverwritePriorContent)3995 TEST_P(ClearTextureEXTTest, Clear2DOverwritePriorContent)
3996 {
3997 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
3998
3999 // Create a 16x16 texture with some data.
4000 std::vector<GLColor> redBlock(16 * 16, GLColor::red);
4001 GLTexture tex;
4002 glBindTexture(GL_TEXTURE_2D, tex);
4003 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, redBlock.data());
4004
4005 GLFramebuffer fbo;
4006 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4007 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
4008 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4009
4010 // Clear the entire texture.
4011 glClearTexImageEXT(tex, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::blue);
4012 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::blue);
4013 }
4014
4015 // Test clearing a 2D texture using a depth of zero.
TEST_P(ClearTextureEXTTest,Clear2DWithZeroDepth)4016 TEST_P(ClearTextureEXTTest, Clear2DWithZeroDepth)
4017 {
4018 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
4019
4020 // Create a 16x16 texture and fully clear it.
4021 GLTexture tex;
4022 glBindTexture(GL_TEXTURE_2D, tex);
4023 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4024 glClearTexImageEXT(tex, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
4025
4026 // Clear the 2D texture using depth of zero.
4027 glClearTexSubImageEXT(tex, 0, 0, 0, 0, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::blue);
4028
4029 GLFramebuffer fbo;
4030 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4031 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
4032 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4033
4034 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::green);
4035 }
4036
4037 // Test basic functionality of clearing a 2D texture defined using glTexStorage().
TEST_P(ClearTextureEXTTest,Clear2DTexStorage)4038 TEST_P(ClearTextureEXTTest, Clear2DTexStorage)
4039 {
4040 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
4041
4042 // Create a 16x16 mipmap texture.
4043 GLTexture tex;
4044 glBindTexture(GL_TEXTURE_2D, tex);
4045 glTexStorage2D(GL_TEXTURE_2D, 5, GL_RGBA8, 16, 16);
4046
4047 // Define texture mip levels by clearing them.
4048 glClearTexImageEXT(tex, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
4049 glClearTexImageEXT(tex, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
4050 glClearTexImageEXT(tex, 2, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::blue);
4051 glClearTexImageEXT(tex, 3, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::magenta);
4052 ASSERT_GL_NO_ERROR();
4053
4054 // Bind to framebuffer and verify.
4055 GLFramebuffer fbo;
4056 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4057
4058 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
4059 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4060 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::red);
4061
4062 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 1);
4063 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4064 EXPECT_PIXEL_RECT_EQ(0, 0, 8, 8, GLColor::green);
4065
4066 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 2);
4067 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4068 EXPECT_PIXEL_RECT_EQ(0, 0, 4, 4, GLColor::blue);
4069
4070 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 3);
4071 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4072 EXPECT_PIXEL_RECT_EQ(0, 0, 2, 2, GLColor::magenta);
4073 }
4074
4075 // Test that a single full clear for the 3D texture works.
TEST_P(ClearTextureEXTTest,Clear3DSingleFull)4076 TEST_P(ClearTextureEXTTest, Clear3DSingleFull)
4077 {
4078 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
4079 constexpr uint32_t kWidth = 4;
4080 constexpr uint32_t kHeight = 4;
4081 constexpr uint32_t kDepth = 4;
4082
4083 GLTexture texture;
4084 glBindTexture(GL_TEXTURE_3D, texture);
4085 glTexStorage3D(GL_TEXTURE_3D, 1, GL_RGBA8, kWidth, kHeight, kDepth);
4086 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
4087
4088 glClearTexImageEXT(texture, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::white);
4089 GLFramebuffer fbo;
4090 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4091 for (uint32_t z = 0; z < kDepth; ++z)
4092 {
4093 glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0, z);
4094 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::white);
4095 }
4096 }
4097
4098 // Test that a simple clear for the entire texture works.
TEST_P(ClearTextureEXTTest,Clear3DWhole)4099 TEST_P(ClearTextureEXTTest, Clear3DWhole)
4100 {
4101 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
4102 constexpr uint32_t kWidth = 4;
4103 constexpr uint32_t kHeight = 4;
4104 constexpr uint32_t kDepth = 4;
4105
4106 GLTexture texture;
4107 glBindTexture(GL_TEXTURE_3D, texture);
4108 glTexStorage3D(GL_TEXTURE_3D, 1, GL_RGBA8, kWidth, kHeight, kDepth);
4109 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
4110
4111 glClearTexImageEXT(texture, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::white);
4112 GLFramebuffer fbo;
4113 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4114 for (uint32_t z = 0; z < kDepth; ++z)
4115 {
4116 glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0, z);
4117 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::white);
4118 }
4119
4120 glClearTexSubImageEXT(texture, 0, 0, 0, 0, kWidth, kHeight, kDepth, GL_RGBA, GL_UNSIGNED_BYTE,
4121 &GLColor::green);
4122 for (uint32_t z = 0; z < kDepth; ++z)
4123 {
4124 glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0, z);
4125 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
4126 }
4127 }
4128
4129 // Test that clearing slices of a 3D texture and reading them back works.
TEST_P(ClearTextureEXTTest,Clear3DLayers)4130 TEST_P(ClearTextureEXTTest, Clear3DLayers)
4131 {
4132 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
4133 constexpr uint32_t kWidth = 128;
4134 constexpr uint32_t kHeight = 128;
4135 constexpr uint32_t kDepth = 7;
4136
4137 GLTexture texture;
4138 glBindTexture(GL_TEXTURE_3D, texture);
4139 glTexStorage3D(GL_TEXTURE_3D, 1, GL_RGBA8, kWidth, kHeight, kDepth);
4140 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
4141
4142 std::array<GLColor, kDepth> clearColors = {
4143 GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow,
4144 GLColor::cyan, GLColor::magenta, GLColor::white,
4145 };
4146
4147 GLFramebuffer fbo;
4148 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4149
4150 glClearTexImageEXT(texture, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4151 for (uint32_t z = 0; z < kDepth; ++z)
4152 {
4153 glClearTexSubImageEXT(texture, 0, 0, 0, z, kWidth, kHeight, 1, GL_RGBA, GL_UNSIGNED_BYTE,
4154 &clearColors[z]);
4155 }
4156
4157 for (uint32_t z = 0; z < kDepth; ++z)
4158 {
4159 glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0, z);
4160 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, clearColors[z]);
4161 }
4162 }
4163
4164 // Test that clearing slices of a 3D texture with dimensions of zero does not change it.
TEST_P(ClearTextureEXTTest,Clear3DZeroDims)4165 TEST_P(ClearTextureEXTTest, Clear3DZeroDims)
4166 {
4167 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
4168 constexpr uint32_t kWidth = 4;
4169 constexpr uint32_t kHeight = 4;
4170 constexpr uint32_t kDepth = 4;
4171
4172 GLTexture texture;
4173 glBindTexture(GL_TEXTURE_3D, texture);
4174 glTexStorage3D(GL_TEXTURE_3D, 1, GL_RGBA8, kWidth, kHeight, kDepth);
4175 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
4176 glClearTexImageEXT(texture, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::white);
4177
4178 // Dimensions of zero for clear are valid. However, they should not change the texture.
4179 GLFramebuffer fbo;
4180 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4181
4182 glClearTexSubImageEXT(texture, 0, 0, 0, 0, 0, kHeight, kDepth, GL_RGBA, GL_UNSIGNED_BYTE,
4183 &GLColor::red);
4184 ASSERT_GL_NO_ERROR();
4185 glClearTexSubImageEXT(texture, 0, 0, 0, 0, kWidth, 0, kDepth, GL_RGBA, GL_UNSIGNED_BYTE,
4186 &GLColor::green);
4187 ASSERT_GL_NO_ERROR();
4188 glClearTexSubImageEXT(texture, 0, 0, 0, 0, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4189 &GLColor::blue);
4190 ASSERT_GL_NO_ERROR();
4191 glClearTexSubImageEXT(texture, 0, 0, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4192 ASSERT_GL_NO_ERROR();
4193
4194 for (uint32_t z = 0; z < kDepth; ++z)
4195 {
4196 glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0, z);
4197 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::white);
4198 }
4199 }
4200
4201 // Test that clearing blocks of a 3D texture and reading them back works.
TEST_P(ClearTextureEXTTest,Clear3DBlocks)4202 TEST_P(ClearTextureEXTTest, Clear3DBlocks)
4203 {
4204 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
4205 constexpr uint32_t kWidth = 16;
4206 constexpr uint32_t kHeight = 16;
4207 constexpr uint32_t kDepth = 16;
4208
4209 GLTexture texture;
4210 glBindTexture(GL_TEXTURE_3D, texture);
4211 glTexStorage3D(GL_TEXTURE_3D, 1, GL_RGBA8, kWidth, kHeight, kDepth);
4212 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAX_LEVEL, 0);
4213
4214 std::array<GLColor, 8> clearColors = {GLColor::red, GLColor::green, GLColor::blue,
4215 GLColor::yellow, GLColor::cyan, GLColor::magenta,
4216 GLColor::white, GLColor::red};
4217
4218 GLFramebuffer fbo;
4219 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4220
4221 for (uint32_t k = 0; k < 2; ++k)
4222 {
4223 for (uint32_t j = 0; j < 2; ++j)
4224 {
4225 for (uint32_t i = 0; i < 2; ++i)
4226 {
4227 glClearTexSubImageEXT(texture, 0, i * kWidth / 2, j * kHeight / 2, k * kDepth / 2,
4228 kWidth / 2, kHeight / 2, kDepth / 2, GL_RGBA,
4229 GL_UNSIGNED_BYTE, &clearColors[(k << 2) + (j << 1) + i]);
4230 }
4231 }
4232 }
4233
4234 for (uint32_t z = 0; z < kDepth / 2; ++z)
4235 {
4236 glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0, z);
4237 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth / 2, kHeight / 2, clearColors[0]);
4238 EXPECT_PIXEL_RECT_EQ(kWidth / 2, 0, kWidth / 2, kHeight / 2, clearColors[1]);
4239 EXPECT_PIXEL_RECT_EQ(0, kHeight / 2, kWidth / 2, kHeight / 2, clearColors[2]);
4240 EXPECT_PIXEL_RECT_EQ(kWidth / 2, kHeight / 2, kWidth / 2, kHeight / 2, clearColors[3]);
4241 }
4242 for (uint32_t z = kDepth / 2; z < kDepth; ++z)
4243 {
4244 glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0, z);
4245 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth / 2, kHeight / 2, clearColors[4]);
4246 EXPECT_PIXEL_RECT_EQ(kWidth / 2, 0, kWidth / 2, kHeight / 2, clearColors[5]);
4247 EXPECT_PIXEL_RECT_EQ(0, kHeight / 2, kWidth / 2, kHeight / 2, clearColors[6]);
4248 EXPECT_PIXEL_RECT_EQ(kWidth / 2, kHeight / 2, kWidth / 2, kHeight / 2, clearColors[7]);
4249 }
4250 }
4251
4252 // Test that clearing slices of a 3D texture and reading them back works.
TEST_P(ClearTextureEXTTest,Clear2DArray)4253 TEST_P(ClearTextureEXTTest, Clear2DArray)
4254 {
4255 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
4256 constexpr uint32_t kWidth = 64;
4257 constexpr uint32_t kHeight = 64;
4258 constexpr uint32_t kDepth = 4;
4259
4260 GLTexture texture;
4261 glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
4262 glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, kWidth, kHeight, kDepth);
4263
4264 std::array<GLColor, kDepth> clearColors = {GLColor::red, GLColor::green, GLColor::blue,
4265 GLColor::yellow};
4266
4267 GLFramebuffer fbo;
4268 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4269
4270 glClearTexImageEXT(texture, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4271 for (uint32_t z = 0; z < kDepth; ++z)
4272 {
4273 glClearTexSubImageEXT(texture, 0, 0, 0, z, kWidth, kHeight, 1, GL_RGBA, GL_UNSIGNED_BYTE,
4274 &clearColors[z]);
4275 }
4276
4277 for (uint32_t z = 0; z < kDepth; ++z)
4278 {
4279 glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0, z);
4280 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, clearColors[z]);
4281 }
4282 }
4283
4284 // Test that luminance alpha textures are cleared correctly with GL_EXT_clear_texture. Regression
4285 // test for emulated luma formats.
TEST_P(ClearTextureEXTTest,Luma)4286 TEST_P(ClearTextureEXTTest, Luma)
4287 {
4288 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
4289
4290 // Create a 16x16 texture with no data.
4291 GLTexture tex;
4292 glBindTexture(GL_TEXTURE_2D, tex);
4293 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4294 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4295
4296 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
4297
4298 // Clear the entire texture to transparent black and test
4299 GLubyte luminanceClearValue = 192;
4300 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, 16, 16, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE,
4301 nullptr);
4302 glClearTexImageEXT(tex, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, &luminanceClearValue);
4303 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
4304 EXPECT_PIXEL_RECT_EQ(
4305 0, 0, getWindowWidth(), getWindowHeight(),
4306 GLColor(luminanceClearValue, luminanceClearValue, luminanceClearValue, 255));
4307
4308 GLubyte lumaClearValue[2] = {128, 64};
4309 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 16, 16, 0, GL_LUMINANCE_ALPHA,
4310 GL_UNSIGNED_BYTE, nullptr);
4311 glClearTexImageEXT(tex, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, &lumaClearValue);
4312 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
4313 EXPECT_PIXEL_RECT_EQ(
4314 0, 0, getWindowWidth(), getWindowHeight(),
4315 GLColor(lumaClearValue[0], lumaClearValue[0], lumaClearValue[0], lumaClearValue[1]));
4316 }
4317
4318 // Test that luminance alpha float textures are cleared correctly with GL_EXT_clear_texture.
TEST_P(ClearTextureEXTTest,LumaAlphaFloat)4319 TEST_P(ClearTextureEXTTest, LumaAlphaFloat)
4320 {
4321 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
4322
4323 // Create a 16x16 texture with no data.
4324 GLTexture tex;
4325 glBindTexture(GL_TEXTURE_2D, tex);
4326 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4327 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4328
4329 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
4330
4331 GLfloat lumaClearValue[2] = {0.5, 0.25};
4332 glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, 16, 16, 0, GL_LUMINANCE_ALPHA, GL_FLOAT,
4333 nullptr);
4334 glClearTexImageEXT(tex, 0, GL_LUMINANCE_ALPHA, GL_FLOAT, &lumaClearValue);
4335 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
4336 EXPECT_PIXEL_COLOR_NEAR(0, 0,
4337 GLColor(lumaClearValue[0] * 255, lumaClearValue[0] * 255,
4338 lumaClearValue[0] * 255, lumaClearValue[1] * 255),
4339 1);
4340 }
4341
4342 // Test that interleaving glClearTexImageEXT and glTexSubImage2D calls produces the correct texture
4343 // data.
TEST_P(ClearTextureEXTTest,InterleavedUploads)4344 TEST_P(ClearTextureEXTTest, InterleavedUploads)
4345 {
4346 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
4347
4348 // Create a 16x16 texture with no data.
4349 GLTexture tex;
4350 glBindTexture(GL_TEXTURE_2D, tex);
4351 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4352 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4353 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4354
4355 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
4356
4357 // Clear the entire texture to transparent black and test
4358 glClearTexImageEXT(tex, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4359 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
4360 EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::transparentBlack);
4361
4362 // TexSubImage a corner
4363 std::vector<GLColor> redBlock(8 * 8, GLColor::red);
4364 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGBA, GL_UNSIGNED_BYTE, redBlock.data());
4365 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
4366 EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
4367
4368 // Clear and tex sub image together
4369 glClearTexSubImageEXT(tex, 0, 0, 0, 0, 8, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::blue);
4370 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 8, 8, GL_RGBA, GL_UNSIGNED_BYTE, redBlock.data());
4371 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
4372 EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
4373 EXPECT_PIXEL_RECT_EQ(0, getWindowHeight() / 2, getWindowWidth() / 2, getWindowHeight() / 2,
4374 GLColor::blue);
4375 }
4376
4377 // Test clearing integer textures with GL_EXT_clear_texture.
TEST_P(ClearTextureEXTTest,IntegerTexture)4378 TEST_P(ClearTextureEXTTest, IntegerTexture)
4379 {
4380 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
4381 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
4382
4383 GLTexture tex;
4384 glBindTexture(GL_TEXTURE_2D, tex);
4385
4386 GLFramebuffer fbo;
4387 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4388 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
4389
4390 GLColor32I rgba32iTestValue(-128, 256, -512, 1024);
4391 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32I, 16, 16, 0, GL_RGBA_INTEGER, GL_INT, nullptr);
4392 glClearTexImageEXT(tex, 0, GL_RGBA_INTEGER, GL_INT, &rgba32iTestValue);
4393 EXPECT_GL_NO_ERROR();
4394 EXPECT_PIXEL_32I_COLOR(0, 0, rgba32iTestValue);
4395
4396 GLColor32UI rgba32uiTestValue(128, 256, 512, 1024);
4397 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32UI, 16, 16, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT,
4398 nullptr);
4399 glClearTexImageEXT(tex, 0, GL_RGBA_INTEGER, GL_UNSIGNED_INT, &rgba32uiTestValue);
4400 EXPECT_GL_NO_ERROR();
4401 EXPECT_PIXEL_32UI_COLOR(0, 0, rgba32uiTestValue);
4402 }
4403
4404 // Test clearing float32 textures with GL_EXT_clear_texture.
TEST_P(ClearTextureEXTTest,Float32Texture)4405 TEST_P(ClearTextureEXTTest, Float32Texture)
4406 {
4407 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
4408 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
4409
4410 GLTexture tex;
4411 glBindTexture(GL_TEXTURE_2D, tex);
4412
4413 GLFramebuffer fbo;
4414 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4415 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
4416
4417 GLColor32F rgba32fTestValue(0.1, 0.2, 0.3, 0.4);
4418 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 16, 16, 0, GL_RGBA, GL_FLOAT, nullptr);
4419 glClearTexImageEXT(tex, 0, GL_RGBA, GL_FLOAT, &rgba32fTestValue);
4420 EXPECT_GL_NO_ERROR();
4421 EXPECT_PIXEL_32F_EQ(0, 0, rgba32fTestValue.R, rgba32fTestValue.G, rgba32fTestValue.B,
4422 rgba32fTestValue.A);
4423 }
4424
4425 // Test clearing depth textures with GL_EXT_clear_texture.
TEST_P(ClearTextureEXTTest,DepthTexture)4426 TEST_P(ClearTextureEXTTest, DepthTexture)
4427 {
4428 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
4429 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
4430
4431 GLTexture colorTex;
4432 glBindTexture(GL_TEXTURE_2D, colorTex);
4433 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4434 glClearTexImageEXT(colorTex, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
4435
4436 GLTexture depthTex;
4437 glBindTexture(GL_TEXTURE_2D, depthTex);
4438 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 16, 16, 0, GL_DEPTH_COMPONENT,
4439 GL_UNSIGNED_INT, nullptr);
4440
4441 GLFramebuffer fbo;
4442 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4443 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
4444 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTex, 0);
4445
4446 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Blue());
4447 glEnable(GL_DEPTH_TEST);
4448 glDepthFunc(GL_LESS);
4449
4450 const GLuint depthClearZero = 0;
4451 const GLuint depthClearOne = std::numeric_limits<GLuint>::max();
4452
4453 // Draw doesn't pass the depth test. Texture has 0.0.
4454 glClearTexImageEXT(depthTex, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, &depthClearZero);
4455 drawQuad(program, essl1_shaders::PositionAttrib(), 0);
4456 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::red);
4457
4458 // Draw passes the depth test. Texture has 1.0.
4459 glClearTexImageEXT(depthTex, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, &depthClearOne);
4460 drawQuad(program, essl1_shaders::PositionAttrib(), 0);
4461 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::blue);
4462
4463 // Left side passes, right side fails
4464 glClearTexImageEXT(colorTex, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
4465 glClearTexSubImageEXT(depthTex, 0, 0, 0, 0, 8, 16, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
4466 &depthClearZero);
4467 glClearTexSubImageEXT(depthTex, 0, 8, 0, 0, 8, 16, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
4468 &depthClearOne);
4469 drawQuad(program, essl1_shaders::PositionAttrib(), 0);
4470 EXPECT_PIXEL_RECT_EQ(0, 0, 8, 16, GLColor::red);
4471 EXPECT_PIXEL_RECT_EQ(8, 0, 8, 16, GLColor::blue);
4472 }
4473
4474 // Test clearing float depth textures (32-bit) with GL_EXT_clear_texture
TEST_P(ClearTextureEXTTest,Depth32FTexture)4475 TEST_P(ClearTextureEXTTest, Depth32FTexture)
4476 {
4477 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
4478 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
4479
4480 GLTexture colorTex;
4481 glBindTexture(GL_TEXTURE_2D, colorTex);
4482 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4483 glClearTexImageEXT(colorTex, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
4484
4485 GLTexture depthTex;
4486 glBindTexture(GL_TEXTURE_2D, depthTex);
4487 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, 16, 16, 0, GL_DEPTH_COMPONENT, GL_FLOAT,
4488 nullptr);
4489
4490 GLFramebuffer fbo;
4491 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4492 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
4493 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTex, 0);
4494
4495 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Blue());
4496 glEnable(GL_DEPTH_TEST);
4497 glDepthFunc(GL_LESS);
4498
4499 const GLfloat depthClearZero = 0.0;
4500 const GLfloat depthClearOne = 1.0;
4501
4502 // Draw doesn't pass the depth test. Texture has 0.0.
4503 glClearTexImageEXT(depthTex, 0, GL_DEPTH_COMPONENT, GL_FLOAT, &depthClearZero);
4504 drawQuad(program, essl1_shaders::PositionAttrib(), 0);
4505 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::red);
4506
4507 // Draw passes the depth test. Texture has 1.0.
4508 glClearTexImageEXT(depthTex, 0, GL_DEPTH_COMPONENT, GL_FLOAT, &depthClearOne);
4509 drawQuad(program, essl1_shaders::PositionAttrib(), 0);
4510 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::blue);
4511
4512 // Left side passes, right side fails
4513 glClearTexImageEXT(colorTex, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
4514 glClearTexSubImageEXT(depthTex, 0, 0, 0, 0, 8, 16, 1, GL_DEPTH_COMPONENT, GL_FLOAT,
4515 &depthClearZero);
4516 glClearTexSubImageEXT(depthTex, 0, 8, 0, 0, 8, 16, 1, GL_DEPTH_COMPONENT, GL_FLOAT,
4517 &depthClearOne);
4518
4519 drawQuad(program, essl1_shaders::PositionAttrib(), 0);
4520 EXPECT_PIXEL_RECT_EQ(0, 0, 8, 16, GLColor::red);
4521 EXPECT_PIXEL_RECT_EQ(8, 0, 8, 16, GLColor::blue);
4522 }
4523
4524 // Test clearing 16-bit depth textures with GL_EXT_clear_texture
TEST_P(ClearTextureEXTTest,Depth16Texture)4525 TEST_P(ClearTextureEXTTest, Depth16Texture)
4526 {
4527 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
4528 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
4529
4530 GLTexture colorTex;
4531 glBindTexture(GL_TEXTURE_2D, colorTex);
4532 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4533 glClearTexImageEXT(colorTex, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
4534
4535 GLTexture depthTex;
4536 glBindTexture(GL_TEXTURE_2D, depthTex);
4537 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, 16, 16, 0, GL_DEPTH_COMPONENT,
4538 GL_UNSIGNED_SHORT, nullptr);
4539
4540 GLFramebuffer fbo;
4541 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4542 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
4543 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTex, 0);
4544
4545 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Blue());
4546 glEnable(GL_DEPTH_TEST);
4547 glDepthFunc(GL_LESS);
4548
4549 const GLushort depthClearZero = 0;
4550 const GLushort depthClearOne = std::numeric_limits<GLushort>::max();
4551
4552 // Draw doesn't pass the depth test. Texture has 0.0.
4553 glClearTexImageEXT(depthTex, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, &depthClearZero);
4554 drawQuad(program, essl1_shaders::PositionAttrib(), 0);
4555 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::red);
4556
4557 // Draw passes the depth test. Texture has 1.0.
4558 glClearTexImageEXT(depthTex, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, &depthClearOne);
4559 drawQuad(program, essl1_shaders::PositionAttrib(), 0);
4560 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::blue);
4561
4562 // Left side passes, right side fails
4563 glClearTexImageEXT(colorTex, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
4564 glClearTexSubImageEXT(depthTex, 0, 0, 0, 0, 8, 16, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
4565 &depthClearZero);
4566 glClearTexSubImageEXT(depthTex, 0, 8, 0, 0, 8, 16, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
4567 &depthClearOne);
4568 drawQuad(program, essl1_shaders::PositionAttrib(), 0);
4569 EXPECT_PIXEL_RECT_EQ(0, 0, 8, 16, GLColor::red);
4570 EXPECT_PIXEL_RECT_EQ(8, 0, 8, 16, GLColor::blue);
4571 }
4572
4573 // Test clearing stencil textures with GL_EXT_clear_texture
TEST_P(ClearTextureEXTTest,StencilTexture)4574 TEST_P(ClearTextureEXTTest, StencilTexture)
4575 {
4576 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
4577 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
4578 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_texture_stencil8"));
4579
4580 GLTexture colorTex;
4581 glBindTexture(GL_TEXTURE_2D, colorTex);
4582 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4583 glClearTexImageEXT(colorTex, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
4584
4585 GLTexture stencilTex;
4586 glBindTexture(GL_TEXTURE_2D, stencilTex);
4587 glTexStorage2D(GL_TEXTURE_2D, 1, GL_STENCIL_INDEX8, 16, 16);
4588
4589 GLFramebuffer fbo;
4590 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4591 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
4592 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, stencilTex, 0);
4593
4594 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Blue());
4595 glEnable(GL_STENCIL_TEST);
4596 glStencilFunc(GL_LESS, 0xCC, 0xFF);
4597
4598 const GLint stencilClearAA = 0xAA;
4599 const GLint stencilClearEE = 0xEE;
4600
4601 // Draw doesn't pass the stencil test.
4602 glClearTexImageEXT(stencilTex, 0, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, &stencilClearAA);
4603 drawQuad(program, essl1_shaders::PositionAttrib(), 0);
4604 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::red);
4605
4606 // Draw passes the stencil test.
4607 glClearTexImageEXT(stencilTex, 0, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, &stencilClearEE);
4608 drawQuad(program, essl1_shaders::PositionAttrib(), 0);
4609 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::blue);
4610
4611 // Left side passes, right side fails
4612 glClearTexImageEXT(colorTex, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
4613 glClearTexSubImageEXT(stencilTex, 0, 0, 0, 0, 8, 16, 1, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE,
4614 &stencilClearAA);
4615 glClearTexSubImageEXT(stencilTex, 0, 8, 0, 0, 8, 16, 1, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE,
4616 &stencilClearEE);
4617 drawQuad(program, essl1_shaders::PositionAttrib(), 0);
4618 EXPECT_PIXEL_RECT_EQ(0, 0, 8, 16, GLColor::red);
4619 EXPECT_PIXEL_RECT_EQ(8, 0, 8, 16, GLColor::blue);
4620 }
4621
4622 // Test clearing depth24/stencil8 textures with GL_EXT_clear_texture.
TEST_P(ClearTextureEXTTest,Depth24Stencil8Texture)4623 TEST_P(ClearTextureEXTTest, Depth24Stencil8Texture)
4624 {
4625 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
4626 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
4627
4628 GLTexture colorTex;
4629 glBindTexture(GL_TEXTURE_2D, colorTex);
4630 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4631 glClearTexImageEXT(colorTex, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
4632
4633 GLTexture dsTex;
4634 glBindTexture(GL_TEXTURE_2D, dsTex);
4635 glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, 16, 16);
4636
4637 GLFramebuffer fbo;
4638 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4639 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
4640 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, dsTex, 0);
4641
4642 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Blue());
4643 glEnable(GL_DEPTH_TEST);
4644 glDepthFunc(GL_LESS);
4645 glEnable(GL_STENCIL_TEST);
4646 glStencilFunc(GL_LESS, 0xCC, 0xFF);
4647
4648 GLuint dsValue0 = 0x000000AA;
4649 GLuint dsValue1 = 0x000000EE;
4650 GLuint dsValue2 = 0xFFFFFFAA;
4651 GLuint dsValue3 = 0xFFFFFFEE;
4652
4653 // Draw doesn't pass the test.
4654 glClearTexImageEXT(dsTex, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, &dsValue0);
4655 drawQuad(program, essl1_shaders::PositionAttrib(), 0);
4656 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::red);
4657
4658 // Draw passes the stencil test.
4659 glClearTexImageEXT(dsTex, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, &dsValue3);
4660 drawQuad(program, essl1_shaders::PositionAttrib(), 0);
4661 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::blue);
4662
4663 // Left side fails the depth test. Top side fails the stencil test.
4664 glClearTexImageEXT(colorTex, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
4665
4666 glClearTexSubImageEXT(dsTex, 0, 0, 0, 0, 8, 8, 1, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
4667 &dsValue0);
4668 glClearTexSubImageEXT(dsTex, 0, 0, 8, 0, 8, 8, 1, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
4669 &dsValue1);
4670 glClearTexSubImageEXT(dsTex, 0, 8, 0, 0, 8, 8, 1, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
4671 &dsValue2);
4672 glClearTexSubImageEXT(dsTex, 0, 8, 8, 0, 8, 8, 1, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
4673 &dsValue3);
4674 drawQuad(program, essl1_shaders::PositionAttrib(), 0);
4675 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 8, GLColor::red);
4676 EXPECT_PIXEL_RECT_EQ(0, 0, 8, 16, GLColor::red);
4677 EXPECT_PIXEL_RECT_EQ(8, 8, 8, 8, GLColor::blue);
4678 }
4679
4680 // Test clearing depth32/stencil textures with GL_EXT_clear_texture.
TEST_P(ClearTextureEXTTest,Depth32FStencilTexture)4681 TEST_P(ClearTextureEXTTest, Depth32FStencilTexture)
4682 {
4683 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
4684 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
4685
4686 GLTexture colorTex;
4687 glBindTexture(GL_TEXTURE_2D, colorTex);
4688 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4689 glClearTexImageEXT(colorTex, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
4690
4691 GLTexture dsTex;
4692 glBindTexture(GL_TEXTURE_2D, dsTex);
4693 glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH32F_STENCIL8, 16, 16);
4694
4695 GLFramebuffer fbo;
4696 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4697 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
4698 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, dsTex, 0);
4699
4700 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Blue());
4701 glEnable(GL_DEPTH_TEST);
4702 glDepthFunc(GL_LESS);
4703 glEnable(GL_STENCIL_TEST);
4704 glStencilFunc(GL_LESS, 0xCC, 0xFF);
4705
4706 struct DSClearValue
4707 {
4708 GLfloat depth;
4709 GLuint stencil;
4710 };
4711
4712 DSClearValue dsValue0 = {0, 0xAA};
4713 DSClearValue dsValue1 = {0, 0xEE};
4714 DSClearValue dsValue2 = {1, 0xAA};
4715 DSClearValue dsValue3 = {1, 0xEE};
4716
4717 // Draw doesn't pass the test.
4718 glClearTexImageEXT(dsTex, 0, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, &dsValue0);
4719 drawQuad(program, essl1_shaders::PositionAttrib(), 0);
4720 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::red);
4721
4722 // Draw passes the stencil test.
4723 glClearTexImageEXT(dsTex, 0, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, &dsValue3);
4724 drawQuad(program, essl1_shaders::PositionAttrib(), 0);
4725 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::blue);
4726
4727 // Left side fails the depth test. Top side fails the stencil test.
4728 glClearTexImageEXT(colorTex, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
4729
4730 glClearTexSubImageEXT(dsTex, 0, 0, 0, 0, 8, 8, 1, GL_DEPTH_STENCIL,
4731 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, &dsValue0);
4732 glClearTexSubImageEXT(dsTex, 0, 0, 8, 0, 8, 8, 1, GL_DEPTH_STENCIL,
4733 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, &dsValue1);
4734 glClearTexSubImageEXT(dsTex, 0, 8, 0, 0, 8, 8, 1, GL_DEPTH_STENCIL,
4735 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, &dsValue2);
4736 glClearTexSubImageEXT(dsTex, 0, 8, 8, 0, 8, 8, 1, GL_DEPTH_STENCIL,
4737 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, &dsValue3);
4738 drawQuad(program, essl1_shaders::PositionAttrib(), 0);
4739 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 8, GLColor::red);
4740 EXPECT_PIXEL_RECT_EQ(0, 0, 8, 16, GLColor::red);
4741 EXPECT_PIXEL_RECT_EQ(8, 8, 8, 8, GLColor::blue);
4742 }
4743
4744 // Test clearing different sets of cube map texture faces with GL_EXT_clear_texture.
TEST_P(ClearTextureEXTTest,ClearCubeFaces)4745 TEST_P(ClearTextureEXTTest, ClearCubeFaces)
4746 {
4747 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
4748
4749 // Create a 16x16 texture with no data.
4750 GLTexture tex;
4751 glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
4752 for (size_t i = 0; i < 6; i++)
4753 {
4754 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
4755 GL_UNSIGNED_BYTE, nullptr);
4756 }
4757
4758 GLFramebuffer fbo;
4759 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4760
4761 // Clear the entire texture
4762 glClearTexImageEXT(tex, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
4763 for (size_t i = 0; i < 6; i++)
4764 {
4765 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
4766 GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, tex, 0);
4767 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::red);
4768 }
4769
4770 // Clear different ranges of faces to different colors:
4771
4772 // [0, 1] -> green
4773 glClearTexSubImageEXT(tex, 0, 0, 0, 0, 16, 16, 2, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
4774
4775 // [1, 2] -> blue (partially overlaps previous clear)
4776 glClearTexSubImageEXT(tex, 0, 0, 0, 1, 16, 16, 2, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::blue);
4777
4778 // [3, 5] -> cyan
4779 glClearTexSubImageEXT(tex, 0, 0, 0, 3, 16, 16, 3, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::cyan);
4780
4781 // Test the colors
4782 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + 0,
4783 tex, 0);
4784 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::green);
4785
4786 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + 1,
4787 tex, 0);
4788 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::blue);
4789
4790 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + 2,
4791 tex, 0);
4792 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::blue);
4793
4794 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + 3,
4795 tex, 0);
4796 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::cyan);
4797
4798 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + 4,
4799 tex, 0);
4800 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::cyan);
4801
4802 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X + 5,
4803 tex, 0);
4804 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::cyan);
4805 }
4806
4807 // Test clearing different sets of cube map array texture layer-faces with GL_EXT_clear_texture.
TEST_P(ClearTextureEXTTest,ClearCubeMapArray)4808 TEST_P(ClearTextureEXTTest, ClearCubeMapArray)
4809 {
4810 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
4811 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_cube_map_array"));
4812
4813 // Create a 16x16 texture with no data.
4814 GLTexture tex;
4815 glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex);
4816 glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, 16, 16, 24, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4817 nullptr);
4818
4819 GLFramebuffer fbo;
4820 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4821
4822 // Clear the entire texture
4823 glClearTexImageEXT(tex, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
4824 for (size_t i = 0; i < 24; i++)
4825 {
4826 glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, i);
4827 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::red);
4828 }
4829
4830 // Clear different ranges of faces to different colors:
4831
4832 // [0, 4] -> green
4833 glClearTexSubImageEXT(tex, 0, 0, 0, 0, 16, 16, 5, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
4834
4835 // [4, 6] -> blue (partially overlaps previous clear)
4836 glClearTexSubImageEXT(tex, 0, 0, 0, 4, 16, 16, 3, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::blue);
4837
4838 // [12, 17] -> cyan
4839 glClearTexSubImageEXT(tex, 0, 0, 0, 12, 16, 16, 6, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::cyan);
4840
4841 // Test the colors
4842 for (size_t i = 0; i < 4; i++)
4843 {
4844 glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, i);
4845 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::green);
4846 }
4847 for (size_t i = 4; i < 7; i++)
4848 {
4849 glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, i);
4850 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::blue);
4851 }
4852 for (size_t i = 12; i < 18; i++)
4853 {
4854 glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, i);
4855 EXPECT_PIXEL_RECT_EQ(0, 0, 16, 16, GLColor::cyan);
4856 }
4857 }
4858
4859 // Test clearing one level, then uploading an update to the same level and then drawing.
TEST_P(ClearTextureEXTTest,ClearOneLevelThenPartialUpdateAndDraw)4860 TEST_P(ClearTextureEXTTest, ClearOneLevelThenPartialUpdateAndDraw)
4861 {
4862 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
4863
4864 // Create a 16x16 texture with prior data.
4865 std::vector<GLColor> redBlock(16 * 16, GLColor::red);
4866 std::vector<GLColor> greenBlock(16 * 16, GLColor::green);
4867 GLTexture tex;
4868 glBindTexture(GL_TEXTURE_2D, tex);
4869 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4870 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4871 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, redBlock.data());
4872 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, redBlock.data());
4873
4874 // Clear one level and add another update on top of it.
4875 glClearTexImageEXT(tex, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::blue);
4876 glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 4, 4, GL_RGBA, GL_UNSIGNED_BYTE, greenBlock.data());
4877
4878 // Draw.
4879 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
4880 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
4881 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
4882 EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, GLColor::green);
4883 EXPECT_PIXEL_RECT_EQ(getWindowWidth() / 2, 0, getWindowWidth() / 2, getWindowHeight(),
4884 GLColor::blue);
4885 EXPECT_PIXEL_RECT_EQ(0, getWindowHeight() / 2, getWindowWidth(), getWindowHeight() / 2,
4886 GLColor::blue);
4887 }
4888
4889 // Test drawing, then partially clearing the texture and drawing again.
TEST_P(ClearTextureEXTTest,DrawThenClearPartiallyThenDraw)4890 TEST_P(ClearTextureEXTTest, DrawThenClearPartiallyThenDraw)
4891 {
4892 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
4893
4894 // Create a 16x16 texture with prior data.
4895 std::vector<GLColor> redBlock(16 * 16, GLColor::red);
4896 GLTexture tex;
4897 glBindTexture(GL_TEXTURE_2D, tex);
4898 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4899 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4900 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, redBlock.data());
4901
4902 // Draw.
4903 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
4904 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
4905 EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);
4906
4907 // Clear a portion of the texture and draw again.
4908 glClearTexSubImageEXT(tex, 0, 0, 0, 0, 8, 8, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::yellow);
4909
4910 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
4911 EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, GLColor::yellow);
4912 EXPECT_PIXEL_RECT_EQ(getWindowWidth() / 2, 0, getWindowWidth() / 2, getWindowHeight(),
4913 GLColor::red);
4914 EXPECT_PIXEL_RECT_EQ(0, getWindowHeight() / 2, getWindowWidth(), getWindowHeight() / 2,
4915 GLColor::red);
4916 }
4917
4918 // Test partially clearing a mip level, applying an overlapping update and then drawing with it.
TEST_P(ClearTextureEXTTest,PartialClearThenOverlappingUploadThenDraw)4919 TEST_P(ClearTextureEXTTest, PartialClearThenOverlappingUploadThenDraw)
4920 {
4921 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
4922
4923 // Create a 16x16 texture with prior data.
4924 std::vector<GLColor> redBlock(16 * 16, GLColor::red);
4925 std::vector<GLColor> greenBlock(16 * 16, GLColor::green);
4926 std::vector<GLColor> blueBlock(16 * 16, GLColor::blue);
4927 GLTexture tex;
4928 glBindTexture(GL_TEXTURE_2D, tex);
4929 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4930 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4931 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, blueBlock.data());
4932 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, redBlock.data());
4933
4934 // Clear one level and add another update on top of it.
4935 glClearTexSubImageEXT(tex, 1, 2, 2, 0, 4, 4, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::yellow);
4936 glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 4, 4, GL_RGBA, GL_UNSIGNED_BYTE, greenBlock.data());
4937
4938 // Draw and verify.
4939 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
4940 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
4941 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
4942
4943 EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, GLColor::green);
4944 EXPECT_PIXEL_RECT_EQ(getWindowWidth() / 4, getWindowWidth() / 2, getWindowWidth() / 2,
4945 getWindowHeight() / 4, GLColor::yellow);
4946 EXPECT_PIXEL_RECT_EQ(getWindowWidth() / 2, getWindowWidth() / 4, getWindowWidth() / 4,
4947 getWindowHeight() / 2, GLColor::yellow);
4948 EXPECT_PIXEL_RECT_EQ((3 * getWindowWidth()) / 4, 0, getWindowWidth() / 4, getWindowHeight(),
4949 GLColor::red);
4950 EXPECT_PIXEL_RECT_EQ(0, (3 * getWindowHeight()) / 4, getWindowWidth(), getWindowHeight() / 4,
4951 GLColor::red);
4952 EXPECT_PIXEL_RECT_EQ(getWindowWidth() / 2, 0, getWindowWidth() / 2, getWindowHeight() / 4,
4953 GLColor::red);
4954 EXPECT_PIXEL_RECT_EQ(0, getWindowHeight() / 2, getWindowWidth() / 4, getWindowHeight() / 2,
4955 GLColor::red);
4956 }
4957
4958 // Test clearing a mip level and generating mipmap based on its previous level and draw.
TEST_P(ClearTextureEXTTest,ClearLevelThenGenerateMipmapOnBaseThenDraw)4959 TEST_P(ClearTextureEXTTest, ClearLevelThenGenerateMipmapOnBaseThenDraw)
4960 {
4961 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
4962
4963 // Create a 16x16 texture with prior data.
4964 std::vector<GLColor> redBlock(16 * 16, GLColor::red);
4965 std::vector<GLColor> greenBlock(16 * 16, GLColor::green);
4966 std::vector<GLColor> blueBlock(16 * 16, GLColor::blue);
4967 GLTexture tex;
4968 glBindTexture(GL_TEXTURE_2D, tex);
4969 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4970 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4971 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, redBlock.data());
4972 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, greenBlock.data());
4973 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, blueBlock.data());
4974
4975 // Clear level 1 and then generate mipmap for the texture.
4976 glClearTexImageEXT(tex, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::yellow);
4977 glGenerateMipmap(GL_TEXTURE_2D);
4978
4979 // Draw.
4980 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
4981 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
4982 EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);
4983 }
4984
4985 // Test clearing a mip level and generating mipmap based on that level and draw.
TEST_P(ClearTextureEXTTest,ClearLevelThenGenerateMipmapOnLevelThenDraw)4986 TEST_P(ClearTextureEXTTest, ClearLevelThenGenerateMipmapOnLevelThenDraw)
4987 {
4988 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
4989
4990 // Create a 16x16 texture with prior data.
4991 std::vector<GLColor> redBlock(16 * 16, GLColor::red);
4992 std::vector<GLColor> greenBlock(16 * 16, GLColor::green);
4993 std::vector<GLColor> blueBlock(16 * 16, GLColor::blue);
4994 GLTexture tex;
4995 glBindTexture(GL_TEXTURE_2D, tex);
4996 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4997 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4998 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, redBlock.data());
4999 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, greenBlock.data());
5000 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, blueBlock.data());
5001
5002 // Clear level 1 and then generate mipmap for the texture based on level 1.
5003 glClearTexImageEXT(tex, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::yellow);
5004 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
5005 glGenerateMipmap(GL_TEXTURE_2D);
5006
5007 // Draw.
5008 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
5009 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
5010 EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::yellow);
5011 }
5012
5013 // Test clearing a large 2D texture.
TEST_P(ClearTextureEXTTest,LargeTexture)5014 TEST_P(ClearTextureEXTTest, LargeTexture)
5015 {
5016 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
5017
5018 constexpr GLsizei kTexWidth = 2048;
5019 constexpr GLsizei kTexHeight = 2048;
5020 GLTexture tex;
5021 glBindTexture(GL_TEXTURE_2D, tex);
5022 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTexWidth, kTexHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5023 nullptr);
5024
5025 GLFramebuffer fbo;
5026 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
5027 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
5028 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
5029
5030 glClearTexImageEXT(tex, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
5031 EXPECT_PIXEL_RECT_EQ(0, 0, kTexWidth, kTexHeight, GLColor::red);
5032 }
5033
5034 // Test that clearing works correctly after swizzling the texture components.
TEST_P(ClearTextureEXTTest,ClearDrawSwizzleClearDraw)5035 TEST_P(ClearTextureEXTTest, ClearDrawSwizzleClearDraw)
5036 {
5037 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
5038
5039 // Initialize texture and draw.
5040 GLTexture tex;
5041 glBindTexture(GL_TEXTURE_2D, tex);
5042 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5043 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5044 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5045 glClearTexImageEXT(tex, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::cyan);
5046
5047 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
5048 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
5049 EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::cyan);
5050
5051 // Change swizzling; left rotation of the RGB components.
5052 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_GREEN);
5053 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_BLUE);
5054 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED);
5055 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);
5056
5057 // Clear again and draw.
5058 glClearTexImageEXT(tex, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::yellow);
5059 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
5060 EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::magenta);
5061 }
5062
5063 // Test validation of GL_EXT_clear_texture.
TEST_P(ClearTextureEXTTest,Validation)5064 TEST_P(ClearTextureEXTTest, Validation)
5065 {
5066 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
5067
5068 // Texture 0 is invalid
5069 glClearTexImageEXT(0, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
5070 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5071
5072 GLTexture tex2D;
5073 glBindTexture(GL_TEXTURE_2D, tex2D);
5074 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5075
5076 // Out of bounds
5077 glClearTexSubImageEXT(tex2D, 0, 1, 0, 0, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
5078 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5079
5080 glClearTexSubImageEXT(tex2D, 0, 0, 1, 0, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
5081 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5082
5083 glClearTexSubImageEXT(tex2D, 1, 0, 0, 0, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
5084 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5085
5086 glClearTexSubImageEXT(tex2D, 0, 0, 0, 1, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
5087 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5088
5089 glClearTexSubImageEXT(tex2D, 0, 0, 0, 0, 16, 16, 2, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
5090 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5091
5092 // Negative offsets
5093 glClearTexSubImageEXT(tex2D, 0, 4, 4, 0, -2, -2, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
5094 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5095
5096 GLTexture texCube;
5097 glBindTexture(GL_TEXTURE_CUBE_MAP, texCube);
5098
5099 // First and third cube faces are specified
5100 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + 0, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
5101 GL_UNSIGNED_BYTE, nullptr);
5102 glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + 2, 0, GL_RGBA, 16, 16, 0, GL_RGBA,
5103 GL_UNSIGNED_BYTE, nullptr);
5104
5105 // Unspecified cube face
5106 glClearTexSubImageEXT(texCube, 0, 0, 0, 1, 16, 16, 1, GL_RGBA, GL_UNSIGNED_BYTE,
5107 &GLColor::green);
5108 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5109
5110 // Cube range with an unspecified face
5111 glClearTexSubImageEXT(texCube, 0, 0, 0, 0, 16, 16, 3, GL_RGBA, GL_UNSIGNED_BYTE,
5112 &GLColor::green);
5113 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5114
5115 // Undefined level
5116 GLTexture tex1Level;
5117 glBindTexture(GL_TEXTURE_2D, tex1Level);
5118 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5119 glClearTexImageEXT(tex1Level, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5120 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5121
5122 // Compressed texture
5123 GLTexture tex2DCompressed;
5124 glBindTexture(GL_TEXTURE_2D, tex2DCompressed);
5125 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, 16, 16, 0, 128, nullptr);
5126 glClearTexImageEXT(tex2DCompressed, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5127 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5128 }
5129
5130 // Covers a driver bug that leaks color mask state into clear texture ops.
TEST_P(ClearTextureEXTTest,ClearTextureAfterMaskedClearBug)5131 TEST_P(ClearTextureEXTTest, ClearTextureAfterMaskedClearBug)
5132 {
5133 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_clear_texture"));
5134
5135 // Perform a masked clear
5136 {
5137 glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
5138 glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE);
5139 glClear(GL_COLOR_BUFFER_BIT);
5140 glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
5141 }
5142
5143 // Create a new texture with data, clear it, and sample
5144 {
5145 constexpr uint32_t kSize = 16;
5146 std::vector<unsigned char> pixelData(kSize * kSize * 4, 255);
5147
5148 GLTexture tex;
5149 glBindTexture(GL_TEXTURE_2D, tex);
5150 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5151 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5152 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5153 pixelData.data());
5154 glClearTexImageEXT(tex, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5155
5156 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
5157 drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
5158 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);
5159 }
5160 }
5161
5162 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND(
5163 ClearTest,
5164 ES3_VULKAN().enable(Feature::ForceFallbackFormat),
5165 ES3_VULKAN().enable(Feature::PreferDrawClearOverVkCmdClearAttachments),
5166 ES2_WEBGPU());
5167
5168 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ClearTestES3);
5169 ANGLE_INSTANTIATE_TEST_ES3_AND(
5170 ClearTestES3,
5171 ES3_VULKAN().enable(Feature::ForceFallbackFormat),
5172 ES3_VULKAN().enable(Feature::PreferDrawClearOverVkCmdClearAttachments));
5173
5174 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ClearTestES31);
5175 ANGLE_INSTANTIATE_TEST_ES31_AND(
5176 ClearTestES31,
5177 ES31_VULKAN().enable(Feature::ForceFallbackFormat),
5178 ES31_VULKAN().enable(Feature::PreferDrawClearOverVkCmdClearAttachments));
5179
5180 ANGLE_INSTANTIATE_TEST_COMBINE_4(MaskedScissoredClearTest,
5181 MaskedScissoredClearVariationsTestPrint,
5182 testing::Range(0, 3),
5183 testing::Range(0, 3),
5184 testing::Range(0, 3),
5185 testing::Bool(),
5186 ANGLE_ALL_TEST_PLATFORMS_ES2,
5187 ANGLE_ALL_TEST_PLATFORMS_ES3,
5188 ES3_VULKAN()
5189 .disable(Feature::SupportsExtendedDynamicState)
5190 .disable(Feature::SupportsExtendedDynamicState2),
5191 ES3_VULKAN().disable(Feature::SupportsExtendedDynamicState2));
5192
5193 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VulkanClearTest);
5194 ANGLE_INSTANTIATE_TEST_COMBINE_4(VulkanClearTest,
5195 MaskedScissoredClearVariationsTestPrint,
5196 testing::Range(0, 3),
5197 testing::Range(0, 3),
5198 testing::Range(0, 3),
5199 testing::Bool(),
5200 ES2_VULKAN().enable(Feature::ForceFallbackFormat),
5201 ES2_VULKAN_SWIFTSHADER().enable(Feature::ForceFallbackFormat),
5202 ES3_VULKAN().enable(Feature::ForceFallbackFormat),
5203 ES3_VULKAN_SWIFTSHADER().enable(Feature::ForceFallbackFormat));
5204
5205 // Not all ANGLE backends support RGB backbuffers
5206 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ClearTestRGB);
5207 ANGLE_INSTANTIATE_TEST(ClearTestRGB,
5208 ES2_D3D11(),
5209 ES3_D3D11(),
5210 ES2_VULKAN(),
5211 ES3_VULKAN(),
5212 ES2_METAL(),
5213 ES3_METAL());
5214
5215 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ClearTestRGB_ES3);
5216 ANGLE_INSTANTIATE_TEST(ClearTestRGB_ES3, ES3_D3D11(), ES3_VULKAN(), ES3_METAL());
5217
5218 ANGLE_INSTANTIATE_TEST_ES3(ClearTextureEXTTest);
5219
5220 } // anonymous namespace
5221