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