• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // Framebuffer tests:
7 //   Various tests related for Frambuffers.
8 //
9 
10 #include "common/mathutil.h"
11 #include "platform/FeaturesD3D.h"
12 #include "test_utils/ANGLETest.h"
13 #include "test_utils/gl_raii.h"
14 
15 using namespace angle;
16 
17 namespace
18 {
19 
ExpectFramebufferCompleteOrUnsupported(GLenum binding)20 void ExpectFramebufferCompleteOrUnsupported(GLenum binding)
21 {
22     GLenum status = glCheckFramebufferStatus(binding);
23     EXPECT_TRUE(status == GL_FRAMEBUFFER_COMPLETE || status == GL_FRAMEBUFFER_UNSUPPORTED);
24 }
25 
26 }  // anonymous namespace
27 
28 class FramebufferFormatsTest : public ANGLETest
29 {
30   protected:
FramebufferFormatsTest()31     FramebufferFormatsTest() : mFramebuffer(0), mTexture(0), mRenderbuffer(0), mProgram(0)
32     {
33         setWindowWidth(128);
34         setWindowHeight(128);
35         setConfigRedBits(8);
36         setConfigGreenBits(8);
37         setConfigBlueBits(8);
38         setConfigAlphaBits(8);
39     }
40 
checkBitCount(GLuint fbo,GLenum channel,GLint minBits)41     void checkBitCount(GLuint fbo, GLenum channel, GLint minBits)
42     {
43         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
44 
45         GLint bits = 0;
46         glGetIntegerv(channel, &bits);
47 
48         if (minBits == 0)
49         {
50             EXPECT_EQ(minBits, bits);
51         }
52         else
53         {
54             EXPECT_GE(bits, minBits);
55         }
56     }
57 
testBitCounts(GLuint fbo,GLint minRedBits,GLint minGreenBits,GLint minBlueBits,GLint minAlphaBits,GLint minDepthBits,GLint minStencilBits)58     void testBitCounts(GLuint fbo,
59                        GLint minRedBits,
60                        GLint minGreenBits,
61                        GLint minBlueBits,
62                        GLint minAlphaBits,
63                        GLint minDepthBits,
64                        GLint minStencilBits)
65     {
66         checkBitCount(fbo, GL_RED_BITS, minRedBits);
67         checkBitCount(fbo, GL_GREEN_BITS, minGreenBits);
68         checkBitCount(fbo, GL_BLUE_BITS, minBlueBits);
69         checkBitCount(fbo, GL_ALPHA_BITS, minAlphaBits);
70         checkBitCount(fbo, GL_DEPTH_BITS, minDepthBits);
71         checkBitCount(fbo, GL_STENCIL_BITS, minStencilBits);
72     }
73 
testTextureFormat(GLenum internalFormat,GLint minRedBits,GLint minGreenBits,GLint minBlueBits,GLint minAlphaBits)74     void testTextureFormat(GLenum internalFormat,
75                            GLint minRedBits,
76                            GLint minGreenBits,
77                            GLint minBlueBits,
78                            GLint minAlphaBits)
79     {
80         glGenTextures(1, &mTexture);
81         glBindTexture(GL_TEXTURE_2D, mTexture);
82 
83         if (getClientMajorVersion() >= 3)
84         {
85             glTexStorage2D(GL_TEXTURE_2D, 1, internalFormat, 1, 1);
86         }
87         else
88         {
89             glTexStorage2DEXT(GL_TEXTURE_2D, 1, internalFormat, 1, 1);
90         }
91 
92         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
93 
94         testBitCounts(mFramebuffer, minRedBits, minGreenBits, minBlueBits, minAlphaBits, 0, 0);
95     }
96 
testRenderbufferMultisampleFormat(int minESVersion,GLenum attachmentType,GLenum internalFormat)97     void testRenderbufferMultisampleFormat(int minESVersion,
98                                            GLenum attachmentType,
99                                            GLenum internalFormat)
100     {
101         int clientVersion = getClientMajorVersion();
102         if (clientVersion < minESVersion)
103         {
104             return;
105         }
106 
107         // Check that multisample is supported with at least two samples (minimum required is 1)
108         bool supports2Samples = false;
109 
110         if (clientVersion == 2)
111         {
112             if (IsGLExtensionEnabled("ANGLE_framebuffer_multisample"))
113             {
114                 int maxSamples;
115                 glGetIntegerv(GL_MAX_SAMPLES_ANGLE, &maxSamples);
116                 supports2Samples = maxSamples >= 2;
117             }
118         }
119         else
120         {
121             assert(clientVersion >= 3);
122             int maxSamples;
123             glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
124             supports2Samples = maxSamples >= 2;
125         }
126 
127         if (!supports2Samples)
128         {
129             return;
130         }
131 
132         glGenRenderbuffers(1, &mRenderbuffer);
133         glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
134 
135         EXPECT_GL_NO_ERROR();
136         glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 2, internalFormat, 128, 128);
137         EXPECT_GL_NO_ERROR();
138         glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachmentType, GL_RENDERBUFFER, mRenderbuffer);
139         EXPECT_GL_NO_ERROR();
140     }
141 
testZeroHeightRenderbuffer()142     void testZeroHeightRenderbuffer()
143     {
144         glGenRenderbuffers(1, &mRenderbuffer);
145         glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
146         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 0);
147         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
148                                   mRenderbuffer);
149         EXPECT_GL_NO_ERROR();
150     }
151 
testSetUp()152     void testSetUp() override
153     {
154         glGenFramebuffers(1, &mFramebuffer);
155         glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
156     }
157 
testTearDown()158     void testTearDown() override
159     {
160         if (mTexture != 0)
161         {
162             glDeleteTextures(1, &mTexture);
163             mTexture = 0;
164         }
165 
166         if (mRenderbuffer != 0)
167         {
168             glDeleteRenderbuffers(1, &mRenderbuffer);
169             mRenderbuffer = 0;
170         }
171 
172         if (mFramebuffer != 0)
173         {
174             glDeleteFramebuffers(1, &mFramebuffer);
175             mFramebuffer = 0;
176         }
177 
178         if (mProgram != 0)
179         {
180             glDeleteProgram(mProgram);
181             mProgram = 0;
182         }
183     }
184 
185     GLuint mFramebuffer;
186     GLuint mTexture;
187     GLuint mRenderbuffer;
188     GLuint mProgram;
189 };
190 
TEST_P(FramebufferFormatsTest,RGBA4)191 TEST_P(FramebufferFormatsTest, RGBA4)
192 {
193     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
194                        !IsGLExtensionEnabled("GL_EXT_texture_storage"));
195 
196     testTextureFormat(GL_RGBA4, 4, 4, 4, 4);
197 }
198 
TEST_P(FramebufferFormatsTest,RGB565)199 TEST_P(FramebufferFormatsTest, RGB565)
200 {
201     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
202                        !IsGLExtensionEnabled("GL_EXT_texture_storage"));
203 
204     testTextureFormat(GL_RGB565, 5, 6, 5, 0);
205 }
206 
TEST_P(FramebufferFormatsTest,RGB8)207 TEST_P(FramebufferFormatsTest, RGB8)
208 {
209     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
210                        (!IsGLExtensionEnabled("GL_OES_rgb8_rgba8") ||
211                         !IsGLExtensionEnabled("GL_EXT_texture_storage")));
212 
213     testTextureFormat(GL_RGB8_OES, 8, 8, 8, 0);
214 }
215 
TEST_P(FramebufferFormatsTest,BGRA8)216 TEST_P(FramebufferFormatsTest, BGRA8)
217 {
218     ANGLE_SKIP_TEST_IF(
219         !IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888") ||
220         (getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_EXT_texture_storage")));
221 
222     testTextureFormat(GL_BGRA8_EXT, 8, 8, 8, 8);
223 }
224 
TEST_P(FramebufferFormatsTest,RGBA8)225 TEST_P(FramebufferFormatsTest, RGBA8)
226 {
227     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
228                        (!IsGLExtensionEnabled("GL_OES_rgb8_rgba8") ||
229                         !IsGLExtensionEnabled("GL_EXT_texture_storage")));
230 
231     testTextureFormat(GL_RGBA8_OES, 8, 8, 8, 8);
232 }
233 
TEST_P(FramebufferFormatsTest,RenderbufferMultisample_DEPTH16)234 TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH16)
235 {
236     testRenderbufferMultisampleFormat(2, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT16);
237 }
238 
TEST_P(FramebufferFormatsTest,RenderbufferMultisample_DEPTH24)239 TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH24)
240 {
241     testRenderbufferMultisampleFormat(3, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT24);
242 }
243 
TEST_P(FramebufferFormatsTest,RenderbufferMultisample_DEPTH32F)244 TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH32F)
245 {
246     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
247 
248     testRenderbufferMultisampleFormat(3, GL_DEPTH_ATTACHMENT, GL_DEPTH_COMPONENT32F);
249 }
250 
TEST_P(FramebufferFormatsTest,RenderbufferMultisample_DEPTH24_STENCIL8)251 TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH24_STENCIL8)
252 {
253     testRenderbufferMultisampleFormat(3, GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH24_STENCIL8);
254 }
255 
TEST_P(FramebufferFormatsTest,RenderbufferMultisample_DEPTH32F_STENCIL8)256 TEST_P(FramebufferFormatsTest, RenderbufferMultisample_DEPTH32F_STENCIL8)
257 {
258     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
259 
260     testRenderbufferMultisampleFormat(3, GL_DEPTH_STENCIL_ATTACHMENT, GL_DEPTH32F_STENCIL8);
261 }
262 
TEST_P(FramebufferFormatsTest,RenderbufferMultisample_STENCIL_INDEX8)263 TEST_P(FramebufferFormatsTest, RenderbufferMultisample_STENCIL_INDEX8)
264 {
265     // TODO(geofflang): Figure out how to support GLSTENCIL_INDEX8 on desktop GL
266     ANGLE_SKIP_TEST_IF(IsDesktopOpenGL());
267 
268     testRenderbufferMultisampleFormat(2, GL_STENCIL_ATTACHMENT, GL_STENCIL_INDEX8);
269 }
270 
271 // Test that binding an incomplete cube map is rejected by ANGLE.
TEST_P(FramebufferFormatsTest,IncompleteCubeMap)272 TEST_P(FramebufferFormatsTest, IncompleteCubeMap)
273 {
274     // http://anglebug.com/3145
275     ANGLE_SKIP_TEST_IF(IsFuchsia() && IsIntel() && IsVulkan());
276 
277     // First make a complete CubeMap.
278     glGenTextures(1, &mTexture);
279     glBindTexture(GL_TEXTURE_CUBE_MAP, mTexture);
280     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
281                  nullptr);
282     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
283                  nullptr);
284     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
285                  nullptr);
286     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
287                  nullptr);
288     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
289                  nullptr);
290     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE,
291                  nullptr);
292     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
293     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
294 
295     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X,
296                            mTexture, 0);
297 
298     // Verify the framebuffer is complete.
299     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
300 
301     // Make the CubeMap cube-incomplete.
302     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE,
303                  nullptr);
304 
305     // Verify the framebuffer is incomplete.
306     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
307                      glCheckFramebufferStatus(GL_FRAMEBUFFER));
308 
309     ASSERT_GL_NO_ERROR();
310 
311     // Verify drawing with the incomplete framebuffer produces a GL error
312     mProgram = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
313     ASSERT_NE(0u, mProgram);
314     drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.5f);
315     ASSERT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
316 }
317 
318 // Test that a renderbuffer with zero height but nonzero width is handled without crashes/asserts.
TEST_P(FramebufferFormatsTest,ZeroHeightRenderbuffer)319 TEST_P(FramebufferFormatsTest, ZeroHeightRenderbuffer)
320 {
321     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
322 
323     testZeroHeightRenderbuffer();
324 }
325 
326 // Test to cover a bug where the read framebuffer affects the completeness of the draw framebuffer.
TEST_P(FramebufferFormatsTest,ReadDrawCompleteness)327 TEST_P(FramebufferFormatsTest, ReadDrawCompleteness)
328 {
329     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
330 
331     GLTexture incompleteTexture;
332     glBindTexture(GL_TEXTURE_2D, incompleteTexture);
333 
334     GLFramebuffer incompleteFBO;
335     glBindFramebuffer(GL_FRAMEBUFFER, incompleteFBO);
336     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, incompleteTexture,
337                            0);
338     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
339                      glCheckFramebufferStatus(GL_FRAMEBUFFER));
340 
341     GLTexture completeTexture;
342     glBindTexture(GL_TEXTURE_2D, completeTexture);
343     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, getWindowWidth(), getWindowHeight());
344 
345     GLFramebuffer completeFBO;
346     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, completeFBO);
347     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
348                            completeTexture, 0);
349 
350     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
351                      glCheckFramebufferStatus(GL_READ_FRAMEBUFFER));
352     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER));
353 
354     ASSERT_GL_NO_ERROR();
355 
356     // Simple draw program.
357     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
358 
359     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f, 1.0f, true);
360     EXPECT_GL_NO_ERROR();
361 
362     glBindFramebuffer(GL_READ_FRAMEBUFFER, completeFBO);
363     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
364 }
365 
366 // Test that a renderbuffer with RGB565 format works as expected. This test is intended for some
367 // back-end having no support for native RGB565 renderbuffer and thus having to emulate using RGBA
368 // format.
TEST_P(FramebufferFormatsTest,RGB565Renderbuffer)369 TEST_P(FramebufferFormatsTest, RGB565Renderbuffer)
370 {
371     GLRenderbuffer rbo;
372     glBindRenderbuffer(GL_RENDERBUFFER, rbo);
373     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB565, 1, 1);
374 
375     GLFramebuffer completeFBO;
376     glBindFramebuffer(GL_FRAMEBUFFER, completeFBO);
377     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
378 
379     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
380 
381     ASSERT_GL_NO_ERROR();
382 
383     glClearColor(1, 0, 0, 0.5f);
384     glClear(GL_COLOR_BUFFER_BIT);
385     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
386 }
387 
388 class FramebufferTest_ES3 : public ANGLETest
389 {
390   protected:
FramebufferTest_ES3()391     FramebufferTest_ES3()
392     {
393         setWindowWidth(kWidth);
394         setWindowHeight(kHeight);
395         setConfigRedBits(8);
396         setConfigGreenBits(8);
397         setConfigBlueBits(8);
398         setConfigAlphaBits(8);
399         setConfigDepthBits(24);
400         setConfigStencilBits(8);
401     }
402 
403     static constexpr GLsizei kWidth  = 64;
404     static constexpr GLsizei kHeight = 256;
405 };
406 
407 // Covers invalidating an incomplete framebuffer. This should be a no-op, but should not error.
TEST_P(FramebufferTest_ES3,InvalidateIncomplete)408 TEST_P(FramebufferTest_ES3, InvalidateIncomplete)
409 {
410     GLFramebuffer framebuffer;
411     GLRenderbuffer renderbuffer;
412 
413     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
414     glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
415     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
416     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
417                      glCheckFramebufferStatus(GL_FRAMEBUFFER));
418 
419     std::vector<GLenum> attachments;
420     attachments.push_back(GL_COLOR_ATTACHMENT0);
421 
422     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments.data());
423     EXPECT_GL_NO_ERROR();
424 }
425 
426 // Covers sub-invalidating an incomplete framebuffer. This should be a no-op, but should not error.
TEST_P(FramebufferTest_ES3,SubInvalidateIncomplete)427 TEST_P(FramebufferTest_ES3, SubInvalidateIncomplete)
428 {
429     GLFramebuffer framebuffer;
430     GLRenderbuffer renderbuffer;
431 
432     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
433     glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
434     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
435     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
436                      glCheckFramebufferStatus(GL_FRAMEBUFFER));
437 
438     std::vector<GLenum> attachments;
439     attachments.push_back(GL_COLOR_ATTACHMENT0);
440 
441     glInvalidateSubFramebuffer(GL_FRAMEBUFFER, 1, attachments.data(), 5, 5, 10, 10);
442     EXPECT_GL_NO_ERROR();
443 }
444 
445 // Test that subinvalidate with no prior command works.  Regression test for the Vulkan backend that
446 // assumed a render pass is started when sub invalidate is called.
TEST_P(FramebufferTest_ES3,SubInvalidateFirst)447 TEST_P(FramebufferTest_ES3, SubInvalidateFirst)
448 {
449     glBindFramebuffer(GL_FRAMEBUFFER, 0);
450 
451     // Invalidate half of the framebuffer using swapped dimensions.
452     std::array<GLenum, 1> attachments = {GL_COLOR};
453     glInvalidateSubFramebuffer(GL_DRAW_FRAMEBUFFER, 1, attachments.data(), 0, 0, kHeight, kWidth);
454     EXPECT_GL_NO_ERROR();
455 }
456 
457 // Test that subinvalidate doesn't discard data outside area.  Uses swapped width/height for
458 // invalidate which results in a partial invalidate, but also prevents bugs with Vulkan
459 // pre-rotation.
TEST_P(FramebufferTest_ES3,SubInvalidatePartial)460 TEST_P(FramebufferTest_ES3, SubInvalidatePartial)
461 {
462     glBindFramebuffer(GL_FRAMEBUFFER, 0);
463 
464     // Clear the attachment.
465     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
466     glClear(GL_COLOR_BUFFER_BIT);
467     EXPECT_GL_NO_ERROR();
468 
469     // Invalidate half of the framebuffer using swapped dimensions.
470     std::array<GLenum, 1> attachments = {GL_COLOR};
471     glInvalidateSubFramebuffer(GL_DRAW_FRAMEBUFFER, 1, attachments.data(), 0, 0, kHeight, kWidth);
472     EXPECT_GL_NO_ERROR();
473 
474     // Make sure the other half is correct.
475     EXPECT_PIXEL_COLOR_EQ(0, kWidth, GLColor::red);
476     EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kWidth, GLColor::red);
477     EXPECT_PIXEL_COLOR_EQ(0, kHeight - 1, GLColor::red);
478     EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::red);
479 }
480 
481 // Test that invalidating stencil of a depth-only attachment doesn't crash.
TEST_P(FramebufferTest_ES3,DepthOnlyAttachmentInvalidateStencil)482 TEST_P(FramebufferTest_ES3, DepthOnlyAttachmentInvalidateStencil)
483 {
484     // Create the framebuffer that will be invalidated
485     GLRenderbuffer depth;
486     glBindRenderbuffer(GL_RENDERBUFFER, depth);
487     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 2, 2);
488 
489     GLFramebuffer fbo;
490     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
491     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);
492     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
493 
494     EXPECT_GL_NO_ERROR();
495 
496     // Invalidate stencil only.
497     std::array<GLenum, 2> attachments = {GL_STENCIL_ATTACHMENT, GL_DEPTH_ATTACHMENT};
498     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments.data());
499     EXPECT_GL_NO_ERROR();
500 
501     // Invalidate both depth and stencil.
502     glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, attachments.data());
503     EXPECT_GL_NO_ERROR();
504 }
505 
506 // Test that invalidating depth of a stencil-only attachment doesn't crash.
TEST_P(FramebufferTest_ES3,StencilOnlyAttachmentInvalidateDepth)507 TEST_P(FramebufferTest_ES3, StencilOnlyAttachmentInvalidateDepth)
508 {
509     // Create the framebuffer that will be invalidated
510     GLRenderbuffer depth;
511     glBindRenderbuffer(GL_RENDERBUFFER, depth);
512     glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, 2, 2);
513 
514     GLFramebuffer fbo;
515     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
516     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depth);
517     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
518 
519     EXPECT_GL_NO_ERROR();
520 
521     // Invalidate depth only.
522     std::array<GLenum, 2> attachments = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
523     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments.data());
524     EXPECT_GL_NO_ERROR();
525 
526     // Invalidate both depth and stencil.
527     glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, attachments.data());
528     EXPECT_GL_NO_ERROR();
529 }
530 
531 // Test that a scissored draw followed by subinvalidate followed by a non-scissored draw retains the
532 // part that is not invalidated.  Uses swapped width/height for invalidate which results in a
533 // partial invalidate, but also prevents bugs with Vulkan pre-rotation.
TEST_P(FramebufferTest_ES3,ScissoredDrawSubInvalidateThenNonScissoredDraw)534 TEST_P(FramebufferTest_ES3, ScissoredDrawSubInvalidateThenNonScissoredDraw)
535 {
536     glBindFramebuffer(GL_FRAMEBUFFER, 0);
537 
538     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
539     glUseProgram(drawColor);
540     GLint colorUniformLocation =
541         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
542     ASSERT_NE(colorUniformLocation, -1);
543 
544     // Clear color to red and the depth/stencil buffer to 1.0 and 0x55
545     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
546     glClearDepthf(1);
547     glClearStencil(0x55);
548     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
549     EXPECT_GL_NO_ERROR();
550 
551     // Break rendering so the following draw call starts rendering with a scissored area.
552     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
553 
554     // Issue a scissored draw call that changes depth to 0.5 and stencil 0x3C
555     glScissor(0, 0, kHeight, kWidth);
556     glEnable(GL_SCISSOR_TEST);
557 
558     glEnable(GL_DEPTH_TEST);
559     glDepthFunc(GL_ALWAYS);
560 
561     glEnable(GL_STENCIL_TEST);
562     glStencilFunc(GL_ALWAYS, 0x3C, 0xFF);
563     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
564     glStencilMask(0xFF);
565 
566     glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
567     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0);
568 
569     // Invalidate the draw region (half of the framebuffer using swapped dimensions).
570     std::array<GLenum, 3> attachments = {GL_COLOR, GL_DEPTH, GL_STENCIL};
571     glInvalidateSubFramebuffer(GL_DRAW_FRAMEBUFFER, 3, attachments.data(), 0, 0, kHeight, kWidth);
572     EXPECT_GL_NO_ERROR();
573 
574     // Match the scissor to the framebuffer size and issue a draw call that blends blue, and expects
575     // depth to be 1 and stencil to be 0x55.  This is only valid for the half that was not
576     // invalidated.
577     glScissor(0, 0, kWidth, kHeight);
578     glDepthFunc(GL_LESS);
579     glStencilFunc(GL_EQUAL, 0x55, 0xFF);
580     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
581 
582     glEnable(GL_BLEND);
583     glBlendFunc(GL_ONE, GL_ONE);
584     glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
585     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.95f);
586     ASSERT_GL_NO_ERROR();
587 
588     // Make sure the half that was not invalidated is correct.
589     EXPECT_PIXEL_COLOR_EQ(0, kWidth, GLColor::magenta);
590     EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kWidth, GLColor::magenta);
591     EXPECT_PIXEL_COLOR_EQ(0, kHeight - 1, GLColor::magenta);
592     EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::magenta);
593 }
594 
595 // Test that the framebuffer state tracking robustly handles a depth-only attachment being set
596 // as a depth-stencil attachment. It is equivalent to detaching the depth-stencil attachment.
TEST_P(FramebufferTest_ES3,DepthOnlyAsDepthStencil)597 TEST_P(FramebufferTest_ES3, DepthOnlyAsDepthStencil)
598 {
599     GLFramebuffer framebuffer;
600     GLRenderbuffer renderbuffer;
601 
602     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
603     glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
604     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 4, 4);
605 
606     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
607                               renderbuffer);
608     EXPECT_GLENUM_NE(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
609 }
610 
611 // Test that the framebuffer correctly returns that it is not complete if invalid texture mip levels
612 // are bound
TEST_P(FramebufferTest_ES3,TextureAttachmentMipLevels)613 TEST_P(FramebufferTest_ES3, TextureAttachmentMipLevels)
614 {
615     GLFramebuffer framebuffer;
616     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
617 
618     GLTexture texture;
619     glBindTexture(GL_TEXTURE_2D, texture);
620 
621     // Create a complete mip chain in mips 1 to 3
622     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
623     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
624     glTexImage2D(GL_TEXTURE_2D, 3, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
625 
626     // Create another complete mip chain in mips 4 to 5
627     glTexImage2D(GL_TEXTURE_2D, 4, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
628     glTexImage2D(GL_TEXTURE_2D, 5, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
629 
630     // Create a non-complete mip chain in mip 6
631     glTexImage2D(GL_TEXTURE_2D, 6, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
632 
633     // Incomplete, mipLevel != baseLevel and texture is not mip complete
634     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 1);
635     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
636                      glCheckFramebufferStatus(GL_FRAMEBUFFER));
637 
638     // Complete, mipLevel == baseLevel
639     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
640     ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
641 
642     // Complete, mipLevel != baseLevel but texture is now mip complete
643     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 2);
644     ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
645     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 3);
646     ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
647 
648     // Incomplete, attached level below the base level
649     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 2);
650     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 1);
651     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
652                      glCheckFramebufferStatus(GL_FRAMEBUFFER));
653 
654     // Incomplete, attached level is beyond effective max level
655     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 4);
656     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
657                      glCheckFramebufferStatus(GL_FRAMEBUFFER));
658 
659     // Complete, mipLevel == baseLevel
660     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 4);
661     ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
662 
663     // Complete, mipLevel != baseLevel but texture is now mip complete
664     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 5);
665     ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
666 
667     // Complete, mipLevel == baseLevel
668     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 6);
669     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 6);
670     ExpectFramebufferCompleteOrUnsupported(GL_FRAMEBUFFER);
671 }
672 
TEST_P(FramebufferTest_ES3,TextureAttachmentMipLevelsReadBack)673 TEST_P(FramebufferTest_ES3, TextureAttachmentMipLevelsReadBack)
674 {
675     GLFramebuffer framebuffer;
676     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
677 
678     GLTexture texture;
679     glBindTexture(GL_TEXTURE_2D, texture);
680 
681     const std::array<GLColor, 4 * 4> mip0Data = {
682         GLColor::red, GLColor::red, GLColor::red, GLColor::red, GLColor::red, GLColor::red,
683         GLColor::red, GLColor::red, GLColor::red, GLColor::red, GLColor::red, GLColor::red,
684         GLColor::red, GLColor::red, GLColor::red, GLColor::red};
685     const std::array<GLColor, 2 * 2> mip1Data = {GLColor::green, GLColor::green, GLColor::green,
686                                                  GLColor::green};
687 
688     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip0Data.data());
689     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip1Data.data());
690 
691     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
692     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 1);
693     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
694 
695     glClearColor(0, 0, 1.0f, 1.0f);
696     glClear(GL_COLOR_BUFFER_BIT);
697     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
698 }
699 
700 // TextureAttachmentMipLevelsReadBackWithDraw is a copy of TextureAttachmentMipLevelsReadBack except
701 // for adding a draw after the last clear. The draw forces ANGLE's Vulkan backend to use the
702 // framebuffer that is level 1 of the texture which will trigger the mismatch use of the GL level
703 // and Vulkan level in referring to that rendertarget.
TEST_P(FramebufferTest_ES3,TextureAttachmentMipLevelsReadBackWithDraw)704 TEST_P(FramebufferTest_ES3, TextureAttachmentMipLevelsReadBackWithDraw)
705 {
706     ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
707 
708     GLFramebuffer framebuffer;
709     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
710 
711     GLTexture texture;
712     glBindTexture(GL_TEXTURE_2D, texture);
713 
714     const std::array<GLColor, 4 * 4> mip0Data = {
715         GLColor::red, GLColor::red, GLColor::red, GLColor::red, GLColor::red, GLColor::red,
716         GLColor::red, GLColor::red, GLColor::red, GLColor::red, GLColor::red, GLColor::red,
717         GLColor::red, GLColor::red, GLColor::red, GLColor::red};
718     const std::array<GLColor, 2 * 2> mip1Data = {GLColor::green, GLColor::green, GLColor::green,
719                                                  GLColor::green};
720 
721     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip0Data.data());
722     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, mip1Data.data());
723 
724     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
725     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 1);
726     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
727 
728     glClearColor(0, 0, 1.0f, 1.0f);
729     glClear(GL_COLOR_BUFFER_BIT);
730 
731     // This draw triggers the use of the framebuffer
732     glUseProgram(greenProgram);
733     drawQuad(greenProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
734     ASSERT_GL_NO_ERROR();
735     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
736 }
737 
738 // Test that passing an attachment COLOR_ATTACHMENTm where m is equal to MAX_COLOR_ATTACHMENTS
739 // generates an INVALID_OPERATION.
740 // OpenGL ES Version 3.0.5 (November 3, 2016), 4.4.2.4 Attaching Texture Images to a Framebuffer, p.
741 // 208
TEST_P(FramebufferTest_ES3,ColorAttachmentIndexOutOfBounds)742 TEST_P(FramebufferTest_ES3, ColorAttachmentIndexOutOfBounds)
743 {
744     GLFramebuffer framebuffer;
745     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
746 
747     GLint maxColorAttachments = 0;
748     glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxColorAttachments);
749     GLenum attachment = static_cast<GLenum>(maxColorAttachments + GL_COLOR_ATTACHMENT0);
750 
751     GLTexture texture;
752     glBindTexture(GL_TEXTURE_2D, texture.get());
753     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA32F, 1, 1);
754     glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, texture.get(), 0);
755     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
756 }
757 
758 // Check that depth-only attachments report the correct number of samples.
TEST_P(FramebufferTest_ES3,MultisampleDepthOnly)759 TEST_P(FramebufferTest_ES3, MultisampleDepthOnly)
760 {
761     GLRenderbuffer renderbuffer;
762     glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
763     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_DEPTH_COMPONENT24, 32, 32);
764 
765     GLFramebuffer framebuffer;
766     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
767     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer);
768     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
769     EXPECT_GL_NO_ERROR();
770 
771     GLint samples = 0;
772     glGetIntegerv(GL_SAMPLES, &samples);
773     EXPECT_GL_NO_ERROR();
774     EXPECT_GE(samples, 2);
775 }
776 
777 // Check that we only compare width and height of attachments, not depth.
TEST_P(FramebufferTest_ES3,AttachmentWith3DLayers)778 TEST_P(FramebufferTest_ES3, AttachmentWith3DLayers)
779 {
780     GLTexture texA;
781     glBindTexture(GL_TEXTURE_2D, texA);
782     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
783 
784     GLTexture texB;
785     glBindTexture(GL_TEXTURE_3D, texB);
786     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 4, 4, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
787 
788     GLFramebuffer framebuffer;
789     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
790     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texA, 0);
791     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, texB, 0, 0);
792     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
793     EXPECT_GL_NO_ERROR();
794 }
795 
796 // Check that invalid layer is detected in framebuffer completeness check.
797 TEST_P(FramebufferTest_ES3, 3DAttachmentInvalidLayer)
798 {
799     GLTexture tex;
800     glBindTexture(GL_TEXTURE_3D, tex);
801     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 4, 4, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
802 
803     GLFramebuffer framebuffer;
804     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
805     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 2);
806     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
807                      glCheckFramebufferStatus(GL_FRAMEBUFFER));
808 
809     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 1);
810     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
811     EXPECT_GL_NO_ERROR();
812 }
813 
814 // Check that invalid layer is detected in framebuffer completeness check.
815 TEST_P(FramebufferTest_ES3, 2DArrayInvalidLayer)
816 {
817     GLTexture tex;
818     glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
819     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA8, 4, 4, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
820 
821     GLFramebuffer framebuffer;
822     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
823     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 2);
824     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
825                      glCheckFramebufferStatus(GL_FRAMEBUFFER));
826 
827     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 1);
828     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
829     EXPECT_GL_NO_ERROR();
830 }
831 
832 // Test that clearing the stencil buffer when the framebuffer only has a color attachment does not
833 // crash.
TEST_P(FramebufferTest_ES3,ClearNonexistentStencil)834 TEST_P(FramebufferTest_ES3, ClearNonexistentStencil)
835 {
836     GLRenderbuffer rbo;
837     glBindRenderbuffer(GL_RENDERBUFFER, rbo);
838     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
839 
840     GLFramebuffer fbo;
841     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
842     glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
843 
844     GLint clearValue = 0;
845     glClearBufferiv(GL_STENCIL, 0, &clearValue);
846 
847     // There's no error specified for clearing nonexistent buffers, it's simply a no-op.
848     EXPECT_GL_NO_ERROR();
849 }
850 
851 // Test that clearing the depth buffer when the framebuffer only has a color attachment does not
852 // crash.
TEST_P(FramebufferTest_ES3,ClearNonexistentDepth)853 TEST_P(FramebufferTest_ES3, ClearNonexistentDepth)
854 {
855     GLRenderbuffer rbo;
856     glBindRenderbuffer(GL_RENDERBUFFER, rbo);
857     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
858 
859     GLFramebuffer fbo;
860     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
861     glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
862 
863     GLfloat clearValue = 0.0f;
864     glClearBufferfv(GL_DEPTH, 0, &clearValue);
865 
866     // There's no error specified for clearing nonexistent buffers, it's simply a no-op.
867     EXPECT_GL_NO_ERROR();
868 }
869 
870 // Test that clearing a nonexistent color attachment does not crash.
TEST_P(FramebufferTest_ES3,ClearNonexistentColor)871 TEST_P(FramebufferTest_ES3, ClearNonexistentColor)
872 {
873     GLRenderbuffer rbo;
874     glBindRenderbuffer(GL_RENDERBUFFER, rbo);
875     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
876 
877     GLFramebuffer fbo;
878     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
879     glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
880 
881     std::vector<GLfloat> clearValue = {{0.0f, 1.0f, 0.0f, 1.0f}};
882     glClearBufferfv(GL_COLOR, 1, clearValue.data());
883 
884     // There's no error specified for clearing nonexistent buffers, it's simply a no-op.
885     EXPECT_GL_NO_ERROR();
886 }
887 
888 // Test that clearing the depth and stencil buffers when the framebuffer only has a color attachment
889 // does not crash.
TEST_P(FramebufferTest_ES3,ClearNonexistentDepthStencil)890 TEST_P(FramebufferTest_ES3, ClearNonexistentDepthStencil)
891 {
892     GLRenderbuffer rbo;
893     glBindRenderbuffer(GL_RENDERBUFFER, rbo);
894     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
895 
896     GLFramebuffer fbo;
897     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
898     glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
899 
900     glClearBufferfi(GL_DEPTH_STENCIL, 0, 0.0f, 0);
901 
902     // There's no error specified for clearing nonexistent buffers, it's simply a no-op.
903     EXPECT_GL_NO_ERROR();
904 }
905 
906 // Test that clearing a color attachment that has been deleted doesn't crash.
TEST_P(FramebufferTest_ES3,ClearDeletedAttachment)907 TEST_P(FramebufferTest_ES3, ClearDeletedAttachment)
908 {
909     // An INVALID_FRAMEBUFFER_OPERATION error was seen in this test on Mac, not sure where it might
910     // be originating from. http://anglebug.com/2834
911     ANGLE_SKIP_TEST_IF(IsOSX() && IsOpenGL());
912 
913     GLFramebuffer fbo;
914     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
915 
916     // There used to be a bug where some draw buffer state used to remain set even after the
917     // attachment was detached via deletion. That's why we create, attach and delete this RBO here.
918     GLuint rbo = 0u;
919     glGenRenderbuffers(1, &rbo);
920     glBindRenderbuffer(GL_RENDERBUFFER, rbo);
921     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
922     glDeleteRenderbuffers(1, &rbo);
923 
924     // There needs to be at least one color attachment to prevent early out from the clear calls.
925     GLRenderbuffer rbo2;
926     glBindRenderbuffer(GL_RENDERBUFFER, rbo2);
927     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
928     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, rbo2);
929 
930     ASSERT_GL_NO_ERROR();
931 
932     // There's no error specified for clearing nonexistent buffers, it's simply a no-op, so we
933     // expect no GL errors below.
934     std::array<GLfloat, 4> floatClearValue = {0.0f, 0.0f, 0.0f, 0.0f};
935     glClearBufferfv(GL_COLOR, 0, floatClearValue.data());
936     EXPECT_GL_NO_ERROR();
937     std::array<GLuint, 4> uintClearValue = {0u, 0u, 0u, 0u};
938     glClearBufferuiv(GL_COLOR, 0, uintClearValue.data());
939     EXPECT_GL_NO_ERROR();
940     std::array<GLint, 4> intClearValue = {0, 0, 0, 0};
941     glClearBufferiv(GL_COLOR, 0, intClearValue.data());
942     EXPECT_GL_NO_ERROR();
943 }
944 
945 // Test that resizing the color attachment is handled correctly.
TEST_P(FramebufferTest_ES3,ResizeColorAttachmentSmallToLarge)946 TEST_P(FramebufferTest_ES3, ResizeColorAttachmentSmallToLarge)
947 {
948     GLFramebuffer fbo;
949     GLTexture smallTexture;
950     GLTexture largeTexture;
951 
952     ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
953     ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
954 
955     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
956 
957     // Bind the small texture
958     glBindTexture(GL_TEXTURE_2D, smallTexture);
959     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth() / 2, getWindowHeight() / 2, 0, GL_RGBA,
960                  GL_UNSIGNED_BYTE, nullptr);
961     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
962     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
963     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, smallTexture, 0);
964     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
965 
966     // Draw to FBO backed by the small texture
967     glUseProgram(greenProgram);
968     drawQuad(greenProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
969     ASSERT_GL_NO_ERROR();
970     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
971     EXPECT_PIXEL_COLOR_EQ((getWindowWidth() / 2) - 1, (getWindowHeight() / 2) - 1, GLColor::green);
972 
973     // Change the attachment to the larger texture that fills the window
974     glBindTexture(GL_TEXTURE_2D, largeTexture);
975     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
976                  GL_UNSIGNED_BYTE, nullptr);
977     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
978     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
979     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, largeTexture, 0);
980     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
981 
982     // Draw to FBO backed by the large texture
983     glUseProgram(blueProgram);
984     drawQuad(blueProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
985     ASSERT_GL_NO_ERROR();
986     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
987     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::blue);
988 }
989 
990 // Test that resizing the color attachment is handled correctly.
TEST_P(FramebufferTest_ES3,ResizeColorAttachmentLargeToSmall)991 TEST_P(FramebufferTest_ES3, ResizeColorAttachmentLargeToSmall)
992 {
993     GLFramebuffer fbo;
994     GLTexture smallTexture;
995     GLTexture largeTexture;
996 
997     ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
998     ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
999 
1000     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1001 
1002     // Bind the large texture
1003     glBindTexture(GL_TEXTURE_2D, largeTexture);
1004     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
1005                  GL_UNSIGNED_BYTE, nullptr);
1006     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1007     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1008     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, largeTexture, 0);
1009     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1010 
1011     // Draw to FBO backed by the large texture
1012     glUseProgram(blueProgram);
1013     drawQuad(blueProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
1014     ASSERT_GL_NO_ERROR();
1015     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
1016     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::blue);
1017 
1018     // Change the attachment to the smaller texture
1019     glBindTexture(GL_TEXTURE_2D, smallTexture);
1020     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth() / 2, getWindowHeight() / 2, 0, GL_RGBA,
1021                  GL_UNSIGNED_BYTE, nullptr);
1022     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1023     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1024     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, smallTexture, 0);
1025     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1026 
1027     // Draw to FBO backed by the small texture
1028     glUseProgram(greenProgram);
1029     drawQuad(greenProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
1030     ASSERT_GL_NO_ERROR();
1031     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1032     EXPECT_PIXEL_COLOR_EQ((getWindowWidth() / 2) - 1, (getWindowHeight() / 2) - 1, GLColor::green);
1033 }
1034 
1035 // Test that resizing the texture is handled correctly.
TEST_P(FramebufferTest_ES3,ResizeTextureLargeToSmall)1036 TEST_P(FramebufferTest_ES3, ResizeTextureLargeToSmall)
1037 {
1038     GLFramebuffer fbo;
1039     GLTexture texture;
1040 
1041     ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
1042     ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
1043 
1044     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1045 
1046     // Allocate a large texture
1047     glBindTexture(GL_TEXTURE_2D, texture);
1048     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
1049                  GL_UNSIGNED_BYTE, nullptr);
1050     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1051     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1052     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
1053     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1054 
1055     // Draw to FBO backed by the large texture
1056     glUseProgram(blueProgram);
1057     drawQuad(blueProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
1058     ASSERT_GL_NO_ERROR();
1059     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
1060     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::blue);
1061 
1062     // Shrink the texture
1063     glBindTexture(GL_TEXTURE_2D, texture);
1064     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth() / 2, getWindowHeight() / 2, 0, GL_RGBA,
1065                  GL_UNSIGNED_BYTE, nullptr);
1066     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1067     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1068     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
1069     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1070 
1071     // Draw to FBO backed by the small texture
1072     glUseProgram(greenProgram);
1073     drawQuad(greenProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
1074     ASSERT_GL_NO_ERROR();
1075     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1076     EXPECT_PIXEL_COLOR_EQ((getWindowWidth() / 2) - 1, (getWindowHeight() / 2) - 1, GLColor::green);
1077 }
1078 
1079 // Test that resizing the texture is handled correctly.
TEST_P(FramebufferTest_ES3,ResizeTextureSmallToLarge)1080 TEST_P(FramebufferTest_ES3, ResizeTextureSmallToLarge)
1081 {
1082     GLFramebuffer fbo;
1083     GLTexture texture;
1084 
1085     ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
1086     ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
1087 
1088     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1089 
1090     // Allocate a small texture
1091     glBindTexture(GL_TEXTURE_2D, texture);
1092     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth() / 2, getWindowHeight() / 2, 0, GL_RGBA,
1093                  GL_UNSIGNED_BYTE, nullptr);
1094     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1095     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1096     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
1097     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1098 
1099     // Draw to FBO backed by the large texture
1100     glUseProgram(blueProgram);
1101     drawQuad(blueProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
1102     ASSERT_GL_NO_ERROR();
1103     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
1104     EXPECT_PIXEL_COLOR_EQ((getWindowWidth() / 2) - 1, (getWindowHeight() / 2) - 1, GLColor::blue);
1105 
1106     // Grow the texture
1107     glBindTexture(GL_TEXTURE_2D, texture);
1108     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
1109                  GL_UNSIGNED_BYTE, nullptr);
1110     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1111     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1112     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
1113     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1114 
1115     // Draw to FBO backed by the small texture
1116     glUseProgram(greenProgram);
1117     drawQuad(greenProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
1118     ASSERT_GL_NO_ERROR();
1119     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1120     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
1121 }
1122 
1123 // Test that fewer outputs than framebuffer attachments doesn't crash.  This causes a Vulkan
1124 // validation warning, but should not be fatal.
TEST_P(FramebufferTest_ES3,FewerShaderOutputsThanAttachments)1125 TEST_P(FramebufferTest_ES3, FewerShaderOutputsThanAttachments)
1126 {
1127     constexpr char kFS[] = R"(#version 300 es
1128 precision highp float;
1129 
1130 layout(location = 0) out vec4 color0;
1131 layout(location = 1) out vec4 color1;
1132 layout(location = 2) out vec4 color2;
1133 
1134 void main()
1135 {
1136     color0 = vec4(1.0, 0.0, 0.0, 1.0);
1137     color1 = vec4(0.0, 1.0, 0.0, 1.0);
1138     color2 = vec4(0.0, 0.0, 1.0, 1.0);
1139 }
1140 )";
1141 
1142     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
1143 
1144     constexpr GLint kDrawBufferCount = 4;
1145 
1146     GLint maxDrawBuffers;
1147     glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
1148     ASSERT_GE(maxDrawBuffers, kDrawBufferCount);
1149 
1150     GLTexture textures[kDrawBufferCount];
1151 
1152     for (GLint texIndex = 0; texIndex < kDrawBufferCount; ++texIndex)
1153     {
1154         glBindTexture(GL_TEXTURE_2D, textures[texIndex]);
1155         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
1156                      GL_UNSIGNED_BYTE, nullptr);
1157     }
1158 
1159     GLenum allBufs[kDrawBufferCount] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
1160                                         GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
1161 
1162     GLFramebuffer fbo;
1163     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
1164 
1165     // Enable all draw buffers.
1166     for (GLint texIndex = 0; texIndex < kDrawBufferCount; ++texIndex)
1167     {
1168         glBindTexture(GL_TEXTURE_2D, textures[texIndex]);
1169         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + texIndex, GL_TEXTURE_2D,
1170                                textures[texIndex], 0);
1171     }
1172     glDrawBuffers(kDrawBufferCount, allBufs);
1173 
1174     // Draw with simple program.
1175     drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f, 1.0f, true);
1176     ASSERT_GL_NO_ERROR();
1177 }
1178 
1179 class FramebufferTestWithFormatFallback : public ANGLETest
1180 {
1181   protected:
FramebufferTestWithFormatFallback()1182     FramebufferTestWithFormatFallback()
1183     {
1184         setWindowWidth(16);
1185         setWindowHeight(16);
1186         setConfigRedBits(8);
1187         setConfigGreenBits(8);
1188         setConfigBlueBits(8);
1189         setConfigAlphaBits(8);
1190         setConfigDepthBits(24);
1191         setConfigStencilBits(8);
1192     }
1193 
1194     void texImageFollowedByFBORead(GLenum internalFormat, GLenum type);
1195     void blitCopyFollowedByFBORead(GLenum internalFormat, GLenum type);
1196     void copyTexImageFollowedBySampling(GLenum internalFormat, GLenum type);
1197     void cubeTexImageFollowedByFBORead(GLenum internalFormat, GLenum type);
1198     GLushort convertGLColorToUShort(GLenum internalFormat, const GLColor &color);
1199     static constexpr GLsizei kTexWidth  = 16;
1200     static constexpr GLsizei kTexHeight = 16;
1201     static constexpr GLsizei kMaxLevel  = 4;
1202 };
1203 
convertGLColorToUShort(GLenum internalFormat,const GLColor & color)1204 GLushort FramebufferTestWithFormatFallback::convertGLColorToUShort(GLenum internalFormat,
1205                                                                    const GLColor &color)
1206 {
1207     GLushort r, g, b, a;
1208     switch (internalFormat)
1209     {
1210         case GL_RGB5_A1:
1211             r = (color.R >> 3) << 11;
1212             g = (color.G >> 3) << 6;
1213             b = (color.B >> 3) << 1;
1214             a = color.A >> 7;
1215             break;
1216         case GL_RGBA4:
1217             r = (color.R >> 4) << 12;
1218             g = (color.G >> 4) << 8;
1219             b = (color.B >> 4) << 4;
1220             a = color.A >> 4;
1221             break;
1222         default:
1223             UNREACHABLE();
1224             r = 0;
1225             g = 0;
1226             b = 0;
1227             a = 0;
1228             break;
1229     }
1230     return r | g | b | a;
1231 }
1232 
1233 // Test texture format fallback while it has staged updates.
texImageFollowedByFBORead(GLenum internalFormat,GLenum type)1234 void FramebufferTestWithFormatFallback::texImageFollowedByFBORead(GLenum internalFormat,
1235                                                                   GLenum type)
1236 {
1237     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Texture2DLod(), essl3_shaders::fs::Texture2DLod());
1238     GLint textureLocation = glGetUniformLocation(program, essl3_shaders::Texture2DUniform());
1239     ASSERT_NE(-1, textureLocation);
1240     GLint lodLocation = glGetUniformLocation(program, essl3_shaders::LodUniform());
1241     ASSERT_NE(-1, lodLocation);
1242 
1243     const GLColor kColor = GLColor::blue;
1244 
1245     for (int loop = 0; loop < 4; loop++)
1246     {
1247         GLTexture texture;
1248         glBindTexture(GL_TEXTURE_2D, texture);
1249         const GLushort u16Color = convertGLColorToUShort(internalFormat, kColor);
1250         std::vector<GLushort> pixels(kTexWidth * kTexHeight, u16Color);
1251         if (loop == 0 || loop == 2)
1252         {
1253             glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, kTexWidth, kTexHeight, 0, GL_RGBA, type,
1254                          pixels.data());
1255         }
1256         else
1257         {
1258             glTexStorage2D(GL_TEXTURE_2D, 1, internalFormat, kTexWidth, kTexHeight);
1259             glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTexWidth, kTexHeight, GL_RGBA, type,
1260                             pixels.data());
1261         }
1262         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1263         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1264 
1265         if (loop >= 2)
1266         {
1267             // Draw quad using texture
1268             glUseProgram(program);
1269             glActiveTexture(GL_TEXTURE0);
1270             glBindTexture(GL_TEXTURE_2D, texture);
1271             glClearColor(0, 0, 0, 1);
1272             glClear(GL_COLOR_BUFFER_BIT);
1273             glUniform1f(lodLocation, 0);
1274             drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
1275             EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 255, 255);
1276             ASSERT_GL_NO_ERROR();
1277         }
1278 
1279         // attach blue texture to FBO
1280         GLFramebuffer fbo;
1281         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1282         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
1283         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1284         EXPECT_PIXEL_EQ(kTexWidth / 2, kTexHeight / 2, kColor.R, kColor.G, kColor.B, kColor.A);
1285         ASSERT_GL_NO_ERROR();
1286     }
1287 }
TEST_P(FramebufferTestWithFormatFallback,R5G5B5A1_TexImage)1288 TEST_P(FramebufferTestWithFormatFallback, R5G5B5A1_TexImage)
1289 {
1290     texImageFollowedByFBORead(GL_RGB5_A1, GL_UNSIGNED_SHORT_5_5_5_1);
1291 }
TEST_P(FramebufferTestWithFormatFallback,R4G4B4A4_TexImage)1292 TEST_P(FramebufferTestWithFormatFallback, R4G4B4A4_TexImage)
1293 {
1294     texImageFollowedByFBORead(GL_RGBA4, GL_UNSIGNED_SHORT_4_4_4_4);
1295 }
1296 
1297 // Test texture format fallback while it has staged updates and then do copyTexImage2D and followed
1298 // by sampling.
copyTexImageFollowedBySampling(GLenum internalFormat,GLenum type)1299 void FramebufferTestWithFormatFallback::copyTexImageFollowedBySampling(GLenum internalFormat,
1300                                                                        GLenum type)
1301 {
1302     const GLColor kColor = GLColor::blue;
1303     // Create blue texture
1304     GLTexture blueTex2D;
1305     glBindTexture(GL_TEXTURE_2D, blueTex2D);
1306     const GLushort u16Color = convertGLColorToUShort(internalFormat, kColor);
1307     std::vector<GLushort> bluePixels(kTexWidth * kTexHeight, u16Color);
1308     glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, kTexWidth, kTexHeight, 0, GL_RGBA, type,
1309                  bluePixels.data());
1310     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1311     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1312 
1313     // attach blue texture to FBO and read back to verify. This should trigger format conversion
1314     GLFramebuffer blueFbo;
1315     glBindFramebuffer(GL_FRAMEBUFFER, blueFbo);
1316     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, blueTex2D, 0);
1317     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1318     EXPECT_PIXEL_EQ(kTexWidth / 2, kTexHeight / 2, 0, 0, 255, 255);
1319     ASSERT_GL_NO_ERROR();
1320 
1321     // Create red texture
1322     GLTexture copyTex2D;
1323     glBindTexture(GL_TEXTURE_2D, copyTex2D);
1324     std::vector<GLushort> redPixels(kTexWidth * kTexHeight, 0xF801);
1325     glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, kTexWidth, kTexHeight, 0, GL_RGBA, type,
1326                  redPixels.data());
1327     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1328     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1329 
1330     // CopyTexImage from blue to red
1331     glCopyTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 0, 0, kTexWidth, kTexHeight, 0);
1332     ASSERT_GL_NO_ERROR();
1333 
1334     // Draw with copyTex2D
1335     glBindFramebuffer(GL_FRAMEBUFFER, 0);
1336     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Texture2DLod(), essl3_shaders::fs::Texture2DLod());
1337     glUseProgram(program);
1338     GLint textureLocation = glGetUniformLocation(program, essl3_shaders::Texture2DUniform());
1339     ASSERT_NE(-1, textureLocation);
1340     GLint lodLocation = glGetUniformLocation(program, essl3_shaders::LodUniform());
1341     ASSERT_NE(-1, lodLocation);
1342     glActiveTexture(GL_TEXTURE0);
1343     glBindTexture(GL_TEXTURE_2D, copyTex2D);
1344     glClearColor(0, 1, 0, 1);
1345     glClear(GL_COLOR_BUFFER_BIT);
1346     glUniform1f(lodLocation, 0);
1347     drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
1348     EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, kColor.R, kColor.G, kColor.B,
1349                     kColor.A);
1350     ASSERT_GL_NO_ERROR();
1351 }
TEST_P(FramebufferTestWithFormatFallback,R5G5B5A1_CopyTexImage)1352 TEST_P(FramebufferTestWithFormatFallback, R5G5B5A1_CopyTexImage)
1353 {
1354     copyTexImageFollowedBySampling(GL_RGB5_A1, GL_UNSIGNED_SHORT_5_5_5_1);
1355 }
TEST_P(FramebufferTestWithFormatFallback,R4G4B4A4_CopyTexImage)1356 TEST_P(FramebufferTestWithFormatFallback, R4G4B4A4_CopyTexImage)
1357 {
1358     copyTexImageFollowedBySampling(GL_RGBA4, GL_UNSIGNED_SHORT_4_4_4_4);
1359 }
1360 
1361 // Test texture format fallback while it has staged updates and then do FBO blit and followed by
1362 // copyTexImage2D.
blitCopyFollowedByFBORead(GLenum internalFormat,GLenum type)1363 void FramebufferTestWithFormatFallback::blitCopyFollowedByFBORead(GLenum internalFormat,
1364                                                                   GLenum type)
1365 {
1366     for (int loop = 0; loop < 2; loop++)
1367     {
1368         // Create blue texture
1369         GLTexture blueTex2D;
1370         glBindTexture(GL_TEXTURE_2D, blueTex2D);
1371         GLushort u16Color = convertGLColorToUShort(internalFormat, GLColor::blue);
1372         std::vector<GLushort> bluePixels(kTexWidth * kTexHeight, u16Color);
1373         glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, kTexWidth, kTexHeight, 0, GL_RGBA, type,
1374                      bluePixels.data());
1375         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1376         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1377 
1378         // attach blue texture to FBO
1379         GLFramebuffer readFbo;
1380         glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
1381         glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, blueTex2D,
1382                                0);
1383         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
1384 
1385         GLTexture redTex2D;
1386         GLRenderbuffer renderBuffer;
1387         GLFramebuffer drawFbo;
1388         if (loop == 0)
1389         {
1390             glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer);
1391             glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, kTexWidth, kTexHeight);
1392 
1393             glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFbo);
1394             glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
1395                                       renderBuffer);
1396             EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
1397             glClearColor(1.0, 0.0, 0.0, 1.0);
1398             glClear(GL_COLOR_BUFFER_BIT);
1399         }
1400         else
1401         {
1402             glBindTexture(GL_TEXTURE_2D, redTex2D);
1403             u16Color = convertGLColorToUShort(internalFormat, GLColor::red);
1404             std::vector<GLushort> redPixels(kTexWidth * kTexHeight, u16Color);
1405             glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, kTexWidth, kTexHeight, 0, GL_RGBA, type,
1406                          redPixels.data());
1407             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1408             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1409 
1410             glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFbo);
1411             glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
1412                                    redTex2D, 0);
1413             EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
1414         }
1415 
1416         // Blit
1417         glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
1418         glBlitFramebuffer(0, 0, kTexWidth, kTexHeight, 0, 0, kTexWidth, kTexHeight,
1419                           GL_COLOR_BUFFER_BIT, GL_NEAREST);
1420         ASSERT_GL_NO_ERROR();
1421 
1422         GLFramebuffer readFbo2;
1423         if (loop == 0)
1424         {
1425             // CopyTexImage from renderBuffer to copyTex2D
1426             glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo2);
1427             glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
1428                                       renderBuffer);
1429         }
1430         else
1431         {
1432 
1433             // CopyTexImage from redTex2D to copyTex2D
1434             glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo2);
1435             glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
1436                                    redTex2D, 0);
1437         }
1438         GLTexture copyTex2D;
1439         glBindTexture(GL_TEXTURE_2D, copyTex2D);
1440         glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, kTexWidth, kTexHeight, 0);
1441         ASSERT_GL_NO_ERROR();
1442         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1443         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1444         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1445         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1446         glBindTexture(GL_TEXTURE_2D, 0);
1447 
1448         // Read out red texture
1449         GLFramebuffer readFbo3;
1450         glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo3);
1451         glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, copyTex2D,
1452                                0);
1453         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
1454         EXPECT_PIXEL_EQ(kTexWidth / 2, kTexHeight / 2, 0, 0, 255, 255);
1455         ASSERT_GL_NO_ERROR();
1456     }
1457 }
TEST_P(FramebufferTestWithFormatFallback,R5G5B5A1_BlitCopyTexImage)1458 TEST_P(FramebufferTestWithFormatFallback, R5G5B5A1_BlitCopyTexImage)
1459 {
1460     blitCopyFollowedByFBORead(GL_RGB5_A1, GL_UNSIGNED_SHORT_5_5_5_1);
1461 }
TEST_P(FramebufferTestWithFormatFallback,RGBA4444_BlitCopyTexImage)1462 TEST_P(FramebufferTestWithFormatFallback, RGBA4444_BlitCopyTexImage)
1463 {
1464     blitCopyFollowedByFBORead(GL_RGBA4, GL_UNSIGNED_SHORT_4_4_4_4);
1465 }
1466 
1467 // Test texture format fallback while it has staged updates, specially for cubemap target.
cubeTexImageFollowedByFBORead(GLenum internalFormat,GLenum type)1468 void FramebufferTestWithFormatFallback::cubeTexImageFollowedByFBORead(GLenum internalFormat,
1469                                                                       GLenum type)
1470 {
1471     const GLColor kColors[6] = {GLColor::red,  GLColor::green,  GLColor::blue,
1472                                 GLColor::cyan, GLColor::yellow, GLColor::magenta};
1473     GLTexture cubeTex2D;
1474     glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTex2D);
1475     for (GLenum target = GL_TEXTURE_CUBE_MAP_POSITIVE_X; target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1476          target++)
1477     {
1478         int j                   = target - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
1479         const GLushort u16Color = convertGLColorToUShort(internalFormat, kColors[j]);
1480         std::vector<GLushort> pixels(kTexWidth * kTexHeight, u16Color);
1481         glTexImage2D(target, 0, internalFormat, kTexWidth, kTexHeight, 0, GL_RGBA, type,
1482                      pixels.data());
1483     }
1484     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1485     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1486 
1487     // attach blue texture to FBO
1488     GLFramebuffer fbo;
1489     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1490     for (GLenum target = GL_TEXTURE_CUBE_MAP_POSITIVE_X; target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
1491          target++)
1492     {
1493         GLint j = target - GL_TEXTURE_CUBE_MAP_POSITIVE_X;
1494         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, cubeTex2D, 0);
1495         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1496         EXPECT_PIXEL_COLOR_EQ(kTexWidth / 2, kTexHeight / 2, kColors[j]) << "face " << j;
1497     }
1498     ASSERT_GL_NO_ERROR();
1499 }
TEST_P(FramebufferTestWithFormatFallback,R5G5B5A1_CubeTexImage)1500 TEST_P(FramebufferTestWithFormatFallback, R5G5B5A1_CubeTexImage)
1501 {
1502     cubeTexImageFollowedByFBORead(GL_RGB5_A1, GL_UNSIGNED_SHORT_5_5_5_1);
1503 }
TEST_P(FramebufferTestWithFormatFallback,R4G4B4A4_CubeTexImage)1504 TEST_P(FramebufferTestWithFormatFallback, R4G4B4A4_CubeTexImage)
1505 {
1506     cubeTexImageFollowedByFBORead(GL_RGBA4, GL_UNSIGNED_SHORT_4_4_4_4);
1507 }
1508 
1509 // Tests that the out-of-range staged update is reformatted when mipmapping is enabled, but not
1510 // before it.
TEST_P(FramebufferTestWithFormatFallback,R4G4B4A4_OutOfRangeStagedUpdateReformated)1511 TEST_P(FramebufferTestWithFormatFallback, R4G4B4A4_OutOfRangeStagedUpdateReformated)
1512 {
1513     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Texture2DLod(), essl3_shaders::fs::Texture2DLod());
1514     glUseProgram(program);
1515     GLint textureLocation = glGetUniformLocation(program, essl3_shaders::Texture2DUniform());
1516     ASSERT_NE(-1, textureLocation);
1517     GLint lodLocation = glGetUniformLocation(program, essl3_shaders::LodUniform());
1518     ASSERT_NE(-1, lodLocation);
1519 
1520     GLTexture texture;
1521     glBindTexture(GL_TEXTURE_2D, texture);
1522     GLushort u16Color = convertGLColorToUShort(GL_RGBA4, GLColor::red);
1523     std::vector<GLushort> pixels(kTexWidth * kTexHeight, u16Color);
1524     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTexWidth, kTexHeight, 0, GL_RGBA,
1525                  GL_UNSIGNED_SHORT_4_4_4_4, pixels.data());
1526     u16Color = convertGLColorToUShort(GL_RGB5_A1, GLColor::green);
1527     pixels.assign(kTexWidth * kTexHeight, u16Color);
1528     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, kTexWidth / 2, kTexHeight / 2, 0, GL_RGBA,
1529                  GL_UNSIGNED_SHORT_5_5_5_1, pixels.data());
1530     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1531     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1532 
1533     // Draw quad
1534     glActiveTexture(GL_TEXTURE0);
1535     glBindTexture(GL_TEXTURE_2D, texture);
1536     glUniform1f(lodLocation, 0);
1537     drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
1538     EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 255, 0, 0, 255);
1539 
1540     // Now trigger format conversion
1541     GLFramebuffer readFbo;
1542     glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
1543     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
1544     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
1545     EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowWidth() / 2, 255, 0, 0, 255);
1546 
1547     // update level0 with compatible data and enable mipmap
1548     u16Color = convertGLColorToUShort(GL_RGB5_A1, GLColor::blue);
1549     pixels.assign(kTexWidth * kTexHeight, u16Color);
1550     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTexWidth, kTexHeight, 0, GL_RGBA,
1551                  GL_UNSIGNED_SHORT_5_5_5_1, pixels.data());
1552     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
1553     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1554     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
1555 
1556     // Draw quad with lod0 and lod1 and verify color
1557     glUniform1f(lodLocation, 0);
1558     drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
1559     EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 255, 255);
1560     glUniform1f(lodLocation, 1);
1561     drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
1562     EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 0, 0, 255, 255);
1563     ASSERT_GL_NO_ERROR();
1564 }
1565 
1566 // Tests that the texture is reformatted when the clear is done through the draw path.
TEST_P(FramebufferTestWithFormatFallback,R4G4B4A4_MaskedClear)1567 TEST_P(FramebufferTestWithFormatFallback, R4G4B4A4_MaskedClear)
1568 {
1569     for (int loop = 0; loop < 2; loop++)
1570     {
1571         GLTexture texture;
1572         glBindTexture(GL_TEXTURE_2D, texture);
1573         GLushort u16Color = convertGLColorToUShort(GL_RGBA4, GLColor::red);
1574         std::vector<GLushort> pixels(kTexWidth * kTexHeight, u16Color);
1575         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTexWidth, kTexHeight, 0, GL_RGBA,
1576                      GL_UNSIGNED_SHORT_4_4_4_4, pixels.data());
1577         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1578         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1579 
1580         if (loop == 0)
1581         {
1582             // Draw quad
1583             ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Texture2DLod(),
1584                              essl3_shaders::fs::Texture2DLod());
1585             glUseProgram(program);
1586             GLint textureLocation =
1587                 glGetUniformLocation(program, essl3_shaders::Texture2DUniform());
1588             ASSERT_NE(-1, textureLocation);
1589             GLint lodLocation = glGetUniformLocation(program, essl3_shaders::LodUniform());
1590             ASSERT_NE(-1, lodLocation);
1591             glActiveTexture(GL_TEXTURE0);
1592             glBindTexture(GL_TEXTURE_2D, texture);
1593             glClearColor(0, 0, 0, 1);
1594             glClear(GL_COLOR_BUFFER_BIT);
1595             glUniform1f(lodLocation, 0);
1596             drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
1597             EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 255, 0, 0, 255);
1598             ASSERT_GL_NO_ERROR();
1599         }
1600 
1601         // Now trigger format conversion with masked clear
1602         GLFramebuffer fbo;
1603         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1604         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
1605         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1606         glClearColor(0, 1, 1, 1);
1607         glColorMask(false, true, false, false);
1608         glClear(GL_COLOR_BUFFER_BIT);
1609         EXPECT_PIXEL_EQ(kTexWidth / 2, kTexHeight / 2, 255, 255, 0, 255);
1610         ASSERT_GL_NO_ERROR();
1611     }
1612 }
1613 
1614 // Tests that glGenerateMipmap works when the format is converted to renderable..
TEST_P(FramebufferTestWithFormatFallback,R4G4B4A4_GenerateMipmap)1615 TEST_P(FramebufferTestWithFormatFallback, R4G4B4A4_GenerateMipmap)
1616 {
1617     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Texture2DLod(), essl3_shaders::fs::Texture2DLod());
1618     glUseProgram(program);
1619     GLint textureLocation = glGetUniformLocation(program, essl3_shaders::Texture2DUniform());
1620     ASSERT_NE(-1, textureLocation);
1621     GLint lodLocation = glGetUniformLocation(program, essl3_shaders::LodUniform());
1622     ASSERT_NE(-1, lodLocation);
1623 
1624     for (int loop = 0; loop < 4; loop++)
1625     {
1626         GLTexture texture;
1627         glBindTexture(GL_TEXTURE_2D, texture);
1628         GLushort u16Color = convertGLColorToUShort(GL_RGBA4, GLColor::red);
1629         std::vector<GLushort> pixels(kTexWidth * kTexHeight, u16Color);
1630         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTexWidth, kTexHeight, 0, GL_RGBA,
1631                      GL_UNSIGNED_SHORT_4_4_4_4, pixels.data());
1632         u16Color = convertGLColorToUShort(GL_RGBA4, GLColor::green);
1633         pixels.assign(kTexWidth * kTexHeight, u16Color);
1634         glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, kTexWidth / 2, kTexHeight / 2, 0, GL_RGBA,
1635                      GL_UNSIGNED_SHORT_5_5_5_1, pixels.data());
1636         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1637         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1638 
1639         if (loop == 0 || loop == 2)
1640         {
1641             // Draw quad
1642             glUniform1f(lodLocation, 0);
1643             drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
1644             EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 255, 0, 0, 255);
1645             ASSERT_GL_NO_ERROR();
1646         }
1647 
1648         if (loop > 2)
1649         {
1650             // Now trigger format conversion
1651             GLFramebuffer readFbo;
1652             glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
1653             glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
1654                                    texture, 0);
1655             EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
1656         }
1657 
1658         // GenerateMipmap
1659         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
1660         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1661         glGenerateMipmap(GL_TEXTURE_2D);
1662 
1663         // Verify each lod
1664         for (int lod = 0; lod <= kMaxLevel; lod++)
1665         {
1666             glUniform1f(lodLocation, lod);
1667             drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
1668             EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 255, 0, 0, 255);
1669         }
1670         ASSERT_GL_NO_ERROR();
1671     }
1672 }
1673 
1674 // Tests that when reformatting the image, incompatible updates don't cause a problem.
TEST_P(FramebufferTestWithFormatFallback,R4G4B4A4_InCompatibleFormat)1675 TEST_P(FramebufferTestWithFormatFallback, R4G4B4A4_InCompatibleFormat)
1676 {
1677     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Texture2DLod(), essl3_shaders::fs::Texture2DLod());
1678     glUseProgram(program);
1679     GLint textureLocation = glGetUniformLocation(program, essl3_shaders::Texture2DUniform());
1680     ASSERT_NE(-1, textureLocation);
1681     GLint lodLocation = glGetUniformLocation(program, essl3_shaders::LodUniform());
1682     ASSERT_NE(-1, lodLocation);
1683 
1684     for (int loop = 0; loop < 4; loop++)
1685     {
1686         GLTexture texture;
1687         glBindTexture(GL_TEXTURE_2D, texture);
1688         // Define a texture with lod0 and lod1 with two different effective internal formats or size
1689         GLushort u16Color = convertGLColorToUShort(GL_RGBA4, GLColor::red);
1690         std::vector<GLushort> pixels(kTexWidth * kTexHeight, u16Color);
1691         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTexWidth, kTexHeight, 0, GL_RGBA,
1692                      GL_UNSIGNED_SHORT_4_4_4_4, pixels.data());
1693         if (loop < 2)
1694         {
1695             u16Color = convertGLColorToUShort(GL_RGB5_A1, GLColor::green);
1696             pixels.assign(kTexWidth * kTexHeight, u16Color);
1697             // bad effective internal format
1698             glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, kTexWidth / 2, kTexHeight / 2, 0, GL_RGBA,
1699                          GL_UNSIGNED_SHORT_5_5_5_1, pixels.data());
1700         }
1701         else
1702         {
1703             u16Color = convertGLColorToUShort(GL_RGBA4, GLColor::green);
1704             pixels.assign(kTexWidth * kTexHeight, u16Color);
1705             // bad size
1706             glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, kTexWidth, kTexHeight, 0, GL_RGBA,
1707                          GL_UNSIGNED_SHORT_4_4_4_4, pixels.data());
1708         }
1709         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
1710         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1711 
1712         // Now trigger format conversion and verify lod0
1713         GLFramebuffer readFbo;
1714         glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
1715         glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture,
1716                                0);
1717         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
1718         EXPECT_PIXEL_EQ(kTexWidth / 2, kTexHeight / 2, 255, 0, 0, 255);
1719 
1720         if (loop == 1 || loop == 3)
1721         {
1722             // Disable mipmap and sample from lod0 and verify
1723             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1724             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1725             glUniform1f(lodLocation, 0);
1726             drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
1727             EXPECT_PIXEL_EQ(getWindowWidth() / 2, getWindowHeight() / 2, 255, 0, 0, 255);
1728         }
1729     }
1730 }
1731 
1732 class FramebufferTest_ES31 : public ANGLETest
1733 {
1734   protected:
validateSamplePass(GLuint & query,GLuint & passedCount,GLint width,GLint height)1735     void validateSamplePass(GLuint &query, GLuint &passedCount, GLint width, GLint height)
1736     {
1737         glUniform2i(0, width - 1, height - 1);
1738         glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
1739         glDrawArrays(GL_TRIANGLES, 0, 6);
1740         glEndQuery(GL_ANY_SAMPLES_PASSED);
1741         glGetQueryObjectuiv(query, GL_QUERY_RESULT, &passedCount);
1742         EXPECT_GT(static_cast<GLint>(passedCount), 0);
1743 
1744         glUniform2i(0, width - 1, height);
1745         glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
1746         glDrawArrays(GL_TRIANGLES, 0, 6);
1747         glEndQuery(GL_ANY_SAMPLES_PASSED);
1748         glGetQueryObjectuiv(query, GL_QUERY_RESULT, &passedCount);
1749         EXPECT_EQ(static_cast<GLint>(passedCount), 0);
1750 
1751         glUniform2i(0, width, height - 1);
1752         glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
1753         glDrawArrays(GL_TRIANGLES, 0, 6);
1754         glEndQuery(GL_ANY_SAMPLES_PASSED);
1755         glGetQueryObjectuiv(query, GL_QUERY_RESULT, &passedCount);
1756         EXPECT_EQ(static_cast<GLint>(passedCount), 0);
1757     }
1758 
1759     static constexpr char kFSWriteRedGreen[] = R"(#extension GL_EXT_draw_buffers : enable
1760 precision highp float;
1761 void main()
1762 {
1763     gl_FragData[0] = vec4(1.0, 0.0, 0.0, 1.0);  // attachment 0: red
1764     gl_FragData[1] = vec4(0.0, 1.0, 0.0, 1.0);  // attachment 1: green
1765 })";
1766 };
1767 
1768 // Until C++17, need to redundantly declare the constexpr array members outside the class.
1769 constexpr char FramebufferTest_ES31::kFSWriteRedGreen[];
1770 
1771 // Test that without attachment, if either the value of FRAMEBUFFER_DEFAULT_WIDTH or
1772 // FRAMEBUFFER_DEFAULT_HEIGHT parameters is zero, the framebuffer is incomplete.
TEST_P(FramebufferTest_ES31,IncompleteMissingAttachmentDefaultParam)1773 TEST_P(FramebufferTest_ES31, IncompleteMissingAttachmentDefaultParam)
1774 {
1775     GLFramebuffer mFramebuffer;
1776     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
1777 
1778     glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 1);
1779     glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 1);
1780     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1781 
1782     glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 0);
1783     glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 0);
1784     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
1785                      glCheckFramebufferStatus(GL_FRAMEBUFFER));
1786 
1787     glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 1);
1788     glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 0);
1789     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
1790                      glCheckFramebufferStatus(GL_FRAMEBUFFER));
1791 
1792     glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 0);
1793     glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, 1);
1794     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
1795                      glCheckFramebufferStatus(GL_FRAMEBUFFER));
1796 
1797     ASSERT_GL_NO_ERROR();
1798 }
1799 
1800 // Test that the sample count of a mix of texture and renderbuffer should be same.
TEST_P(FramebufferTest_ES31,IncompleteMultisampleSampleCountMix)1801 TEST_P(FramebufferTest_ES31, IncompleteMultisampleSampleCountMix)
1802 {
1803     GLFramebuffer mFramebuffer;
1804     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
1805 
1806     // Lookup the supported number of sample counts (rely on fact that ANGLE uses the same set of
1807     // sample counts for textures and renderbuffers)
1808     GLint numSampleCounts = 0;
1809     std::vector<GLint> sampleCounts;
1810     GLsizei queryBufferSize = 1;
1811     glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_RGBA8, GL_NUM_SAMPLE_COUNTS,
1812                           queryBufferSize, &numSampleCounts);
1813     ANGLE_SKIP_TEST_IF((numSampleCounts < 2));
1814     sampleCounts.resize(numSampleCounts);
1815     queryBufferSize = numSampleCounts;
1816     glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_RGBA8, GL_SAMPLES, queryBufferSize,
1817                           sampleCounts.data());
1818 
1819     GLTexture mTexture;
1820     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture.get());
1821     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, sampleCounts[0], GL_RGBA8, 1, 1, true);
1822 
1823     GLRenderbuffer mRenderbuffer;
1824     glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer.get());
1825     glRenderbufferStorageMultisample(GL_RENDERBUFFER, sampleCounts[1], GL_RGBA8, 1, 1);
1826     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
1827                            mTexture.get(), 0);
1828     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER,
1829                               mRenderbuffer.get());
1830     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
1831                      glCheckFramebufferStatus(GL_FRAMEBUFFER));
1832 
1833     ASSERT_GL_NO_ERROR();
1834 }
1835 
1836 // Test that the sample count of texture attachments should be same.
TEST_P(FramebufferTest_ES31,IncompleteMultisampleSampleCountTex)1837 TEST_P(FramebufferTest_ES31, IncompleteMultisampleSampleCountTex)
1838 {
1839     GLFramebuffer mFramebuffer;
1840     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
1841 
1842     // Lookup the supported number of sample counts
1843     GLint numSampleCounts = 0;
1844     std::vector<GLint> sampleCounts;
1845     GLsizei queryBufferSize = 1;
1846     glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_RGBA8, GL_NUM_SAMPLE_COUNTS,
1847                           queryBufferSize, &numSampleCounts);
1848     ANGLE_SKIP_TEST_IF((numSampleCounts < 2));
1849     sampleCounts.resize(numSampleCounts);
1850     queryBufferSize = numSampleCounts;
1851     glGetInternalformativ(GL_TEXTURE_2D_MULTISAMPLE, GL_RGBA8, GL_SAMPLES, queryBufferSize,
1852                           sampleCounts.data());
1853 
1854     GLTexture mTextures[2];
1855     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTextures[0].get());
1856     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, sampleCounts[0], GL_RGBA8, 1, 1, true);
1857     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTextures[1].get());
1858     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, sampleCounts[1], GL_RGBA8, 1, 1, true);
1859     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
1860                            mTextures[0].get(), 0);
1861     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE,
1862                            mTextures[1].get(), 0);
1863     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
1864                      glCheckFramebufferStatus(GL_FRAMEBUFFER));
1865 
1866     ASSERT_GL_NO_ERROR();
1867 }
1868 
1869 // Test that if the attached images are a mix of renderbuffers and textures, the value of
1870 // TEXTURE_FIXED_SAMPLE_LOCATIONS must be TRUE for all attached textures.
TEST_P(FramebufferTest_ES31,IncompleteMultisampleFixedSampleLocationsMix)1871 TEST_P(FramebufferTest_ES31, IncompleteMultisampleFixedSampleLocationsMix)
1872 {
1873     GLFramebuffer mFramebuffer;
1874     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
1875 
1876     GLTexture mTexture;
1877     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTexture.get());
1878     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, false);
1879 
1880     GLRenderbuffer mRenderbuffer;
1881     glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer.get());
1882     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 1, GL_RGBA8, 1, 1);
1883     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
1884                            mTexture.get(), 0);
1885     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER,
1886                               mRenderbuffer.get());
1887     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
1888                      glCheckFramebufferStatus(GL_FRAMEBUFFER));
1889 
1890     ASSERT_GL_NO_ERROR();
1891 }
1892 
1893 // Test that the value of TEXTURE_FIXED_SAMPLE_LOCATIONS is the same for all attached textures.
TEST_P(FramebufferTest_ES31,IncompleteMultisampleFixedSampleLocationsTex)1894 TEST_P(FramebufferTest_ES31, IncompleteMultisampleFixedSampleLocationsTex)
1895 {
1896     GLFramebuffer mFramebuffer;
1897     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
1898 
1899     GLTexture mTextures[2];
1900     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTextures[0].get());
1901     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGBA8, 1, 1, false);
1902     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
1903                            mTextures[0].get(), 0);
1904     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, mTextures[1].get());
1905     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 1, GL_RGB8, 1, 1, true);
1906     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE,
1907                            mTextures[1].get(), 0);
1908     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
1909                      glCheckFramebufferStatus(GL_FRAMEBUFFER));
1910 
1911     ASSERT_GL_NO_ERROR();
1912 }
1913 
1914 // Tests that draw to Y-flipped FBO results in correct pixels.
TEST_P(FramebufferTest_ES31,BasicDrawToYFlippedFBO)1915 TEST_P(FramebufferTest_ES31, BasicDrawToYFlippedFBO)
1916 {
1917     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
1918 
1919     constexpr int kSize = 16;
1920     glViewport(0, 0, kSize, kSize);
1921 
1922     GLFramebuffer fbo;
1923     glBindFramebuffer(GL_FRAMEBUFFER, fbo.get());
1924 
1925     glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
1926 
1927     GLTexture texture;
1928     glBindTexture(GL_TEXTURE_2D, texture.get());
1929     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
1930     ASSERT_GL_NO_ERROR();
1931     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.get(), 0);
1932     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1933 
1934     ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),
1935                      essl31_shaders::fs::RedGreenGradient());
1936     drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
1937     ASSERT_GL_NO_ERROR();
1938 
1939     // Remove the flag so that glReadPixels do not implicitly use that.
1940     glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 0);
1941 
1942     constexpr uint8_t kHalfPixelGradient = 256 / kSize / 2;
1943     EXPECT_PIXEL_NEAR(0, 0, kHalfPixelGradient, 255 - kHalfPixelGradient, 0, 255, 1.0);
1944     EXPECT_PIXEL_NEAR(kSize - 1, 0, 255 - kHalfPixelGradient, 255 - kHalfPixelGradient, 0, 255,
1945                       1.0);
1946     EXPECT_PIXEL_NEAR(0, kSize - 1, kHalfPixelGradient, kHalfPixelGradient, 0, 255, 1.0);
1947     EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 255 - kHalfPixelGradient, kHalfPixelGradient, 0, 255,
1948                       1.0);
1949 }
1950 
1951 // Test resolving a multisampled texture with blit
TEST_P(FramebufferTest_ES31,MultisampleResolveWithBlit)1952 TEST_P(FramebufferTest_ES31, MultisampleResolveWithBlit)
1953 {
1954     constexpr int kSize = 16;
1955     glViewport(0, 0, kSize, kSize);
1956 
1957     GLFramebuffer msaaFBO;
1958     glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO.get());
1959 
1960     GLTexture texture;
1961     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture.get());
1962     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
1963     ASSERT_GL_NO_ERROR();
1964     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
1965                            texture.get(), 0);
1966     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1967 
1968     ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),
1969                      essl31_shaders::fs::RedGreenGradient());
1970     drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
1971     ASSERT_GL_NO_ERROR();
1972 
1973     // Create another FBO to resolve the multisample buffer into.
1974     GLTexture resolveTexture;
1975     GLFramebuffer resolveFBO;
1976     glBindTexture(GL_TEXTURE_2D, resolveTexture);
1977     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1978     glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
1979     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 0);
1980     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1981 
1982     glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBO);
1983     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO);
1984     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1985     ASSERT_GL_NO_ERROR();
1986 
1987     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO);
1988     constexpr uint8_t kHalfPixelGradient = 256 / kSize / 2;
1989     EXPECT_PIXEL_NEAR(0, 0, kHalfPixelGradient, kHalfPixelGradient, 0, 255, 1.0);
1990     EXPECT_PIXEL_NEAR(kSize - 1, 0, 255 - kHalfPixelGradient, kHalfPixelGradient, 0, 255, 1.0);
1991     EXPECT_PIXEL_NEAR(0, kSize - 1, kHalfPixelGradient, 255 - kHalfPixelGradient, 0, 255, 1.0);
1992     EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 255 - kHalfPixelGradient, 255 - kHalfPixelGradient, 0,
1993                       255, 1.0);
1994 }
1995 
1996 // Test resolving a multisampled texture with blit to a different format
TEST_P(FramebufferTest_ES31,MultisampleResolveWithBlitDifferentFormats)1997 TEST_P(FramebufferTest_ES31, MultisampleResolveWithBlitDifferentFormats)
1998 {
1999     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"));
2000 
2001     constexpr int kSize = 16;
2002     glViewport(0, 0, kSize, kSize);
2003 
2004     GLFramebuffer msaaFBO;
2005     glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO.get());
2006 
2007     GLTexture texture;
2008     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture.get());
2009     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
2010     ASSERT_GL_NO_ERROR();
2011     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
2012                            texture.get(), 0);
2013     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2014 
2015     ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),
2016                      essl31_shaders::fs::RedGreenGradient());
2017     drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
2018     ASSERT_GL_NO_ERROR();
2019 
2020     // Create another FBO to resolve the multisample buffer into.
2021     GLTexture resolveTexture;
2022     GLFramebuffer resolveFBO;
2023     glBindTexture(GL_TEXTURE_2D, resolveTexture);
2024     glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA8_EXT, kSize, kSize, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE,
2025                  nullptr);
2026     glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
2027     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 0);
2028     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2029 
2030     glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBO);
2031     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO);
2032     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2033     ASSERT_GL_NO_ERROR();
2034 
2035     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO);
2036     constexpr uint8_t kHalfPixelGradient = 256 / kSize / 2;
2037     EXPECT_PIXEL_NEAR(0, 0, kHalfPixelGradient, kHalfPixelGradient, 0, 255, 1.0);
2038     EXPECT_PIXEL_NEAR(kSize - 1, 0, 255 - kHalfPixelGradient, kHalfPixelGradient, 0, 255, 1.0);
2039     EXPECT_PIXEL_NEAR(0, kSize - 1, kHalfPixelGradient, 255 - kHalfPixelGradient, 0, 255, 1.0);
2040     EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 255 - kHalfPixelGradient, 255 - kHalfPixelGradient, 0,
2041                       255, 1.0);
2042 }
2043 
2044 // Test resolving a multisampled texture with blit after drawing to mulitiple FBOs.
TEST_P(FramebufferTest_ES31,MultisampleResolveWithBlitMultipleFBOs)2045 TEST_P(FramebufferTest_ES31, MultisampleResolveWithBlitMultipleFBOs)
2046 {
2047     // FBO 1 -> multisample draw (red)
2048     // FBO 2 -> multisample draw (green)
2049     // Bind FBO 1 as read
2050     // Bind FBO 3 as draw
2051     // Resolve
2052 
2053     constexpr int kSize = 16;
2054     glViewport(0, 0, kSize, kSize);
2055 
2056     GLFramebuffer msaaFBORed;
2057     glBindFramebuffer(GL_FRAMEBUFFER, msaaFBORed.get());
2058 
2059     GLTexture textureRed;
2060     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textureRed.get());
2061     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
2062     ASSERT_GL_NO_ERROR();
2063     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
2064                            textureRed.get(), 0);
2065     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2066 
2067     ANGLE_GL_PROGRAM(redProgram, essl31_shaders::vs::Simple(), essl31_shaders::fs::Red());
2068     drawQuad(redProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
2069     ASSERT_GL_NO_ERROR();
2070 
2071     GLFramebuffer msaaFBOGreen;
2072     glBindFramebuffer(GL_FRAMEBUFFER, msaaFBOGreen.get());
2073 
2074     GLTexture textureGreen;
2075     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textureGreen.get());
2076     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
2077     ASSERT_GL_NO_ERROR();
2078     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
2079                            textureGreen.get(), 0);
2080     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2081 
2082     ANGLE_GL_PROGRAM(greenProgram, essl31_shaders::vs::Simple(), essl31_shaders::fs::Green());
2083     drawQuad(greenProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
2084     ASSERT_GL_NO_ERROR();
2085 
2086     // Create another FBO to resolve the multisample buffer into.
2087     GLTexture resolveTexture;
2088     GLFramebuffer resolveFBO;
2089     glBindTexture(GL_TEXTURE_2D, resolveTexture);
2090     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2091     glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
2092     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 0);
2093     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2094 
2095     glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBORed);
2096     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO);
2097     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2098     ASSERT_GL_NO_ERROR();
2099 
2100     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO);
2101     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2102 }
2103 
2104 // Test resolving a multisampled texture with blit after drawing to mulitiple FBOs.
TEST_P(FramebufferTest_ES31,MultisampleResolveWithBlitMultipleResolves)2105 TEST_P(FramebufferTest_ES31, MultisampleResolveWithBlitMultipleResolves)
2106 {
2107     // Draw multisampled in FBO 1
2108     // Bind FBO 1 as read
2109     // Bind FBO 2 as draw
2110     // Resolve
2111     // Bind FBO 3 as draw
2112     // Resolve
2113 
2114     constexpr int kSize = 16;
2115     glViewport(0, 0, kSize, kSize);
2116 
2117     GLFramebuffer msaaFBORed;
2118     glBindFramebuffer(GL_FRAMEBUFFER, msaaFBORed.get());
2119 
2120     GLTexture textureRed;
2121     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textureRed.get());
2122     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
2123     ASSERT_GL_NO_ERROR();
2124     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
2125                            textureRed.get(), 0);
2126     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2127 
2128     ANGLE_GL_PROGRAM(redProgram, essl31_shaders::vs::Simple(), essl31_shaders::fs::Red());
2129     drawQuad(redProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
2130     ASSERT_GL_NO_ERROR();
2131 
2132     // Create another FBO to resolve the multisample buffer into.
2133     GLTexture resolveTexture1;
2134     GLFramebuffer resolveFBO1;
2135     glBindTexture(GL_TEXTURE_2D, resolveTexture1);
2136     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2137     glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO1);
2138     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture1, 0);
2139     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2140 
2141     glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBORed);
2142     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO1);
2143     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2144     ASSERT_GL_NO_ERROR();
2145 
2146     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO1);
2147     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2148 
2149     // Create another FBO to resolve the multisample buffer into.
2150     GLTexture resolveTexture2;
2151     GLFramebuffer resolveFBO2;
2152     glBindTexture(GL_TEXTURE_2D, resolveTexture2);
2153     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2154     glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO2);
2155     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture2, 0);
2156     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2157 
2158     glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBORed);
2159     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO2);
2160     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2161     ASSERT_GL_NO_ERROR();
2162 
2163     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO2);
2164     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2165 }
2166 
2167 // Test resolving a multisampled texture with blit into an FBO with different read and draw
2168 // attachments.
TEST_P(FramebufferTest_ES31,MultisampleResolveWithBlitDifferentReadDrawBuffers)2169 TEST_P(FramebufferTest_ES31, MultisampleResolveWithBlitDifferentReadDrawBuffers)
2170 {
2171     constexpr int kSize = 16;
2172     glViewport(0, 0, kSize, kSize);
2173 
2174     GLFramebuffer msaaFBO;
2175     glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO.get());
2176 
2177     GLTexture texture;
2178     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture.get());
2179     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
2180     ASSERT_GL_NO_ERROR();
2181     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
2182                            texture.get(), 0);
2183     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2184 
2185     ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),
2186                      essl31_shaders::fs::RedGreenGradient());
2187     drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
2188     ASSERT_GL_NO_ERROR();
2189 
2190     // Create another FBO to resolve the multisample buffer into.
2191     GLFramebuffer resolveFBO;
2192     glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
2193 
2194     // Bind both read and draw textures as separate attachments.
2195     const std::vector<GLColor> blueColors(kSize * kSize, GLColor::blue);
2196     GLTexture resolveReadTexture;
2197     glBindTexture(GL_TEXTURE_2D, resolveReadTexture);
2198     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
2199                  blueColors.data());
2200     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveReadTexture,
2201                            0);
2202     glReadBuffer(GL_COLOR_ATTACHMENT0);
2203     ASSERT_GL_NO_ERROR();
2204 
2205     GLTexture resolveDrawTexture;
2206     glBindTexture(GL_TEXTURE_2D, resolveDrawTexture);
2207     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2208     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, resolveDrawTexture,
2209                            0);
2210     // Only enable color attachment 1 to be drawn to, since the Vulkan back end (currently) only
2211     // supports using resolve attachments when there is a single draw attachment enabled. This
2212     // ensures that the read and draw images are treated separately, including their layouts.
2213     GLenum drawBuffers[] = {GL_NONE, GL_COLOR_ATTACHMENT1};
2214     glDrawBuffers(2, drawBuffers);
2215     ASSERT_GL_NO_ERROR();
2216     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2217 
2218     glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBO);
2219     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO);
2220     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2221     ASSERT_GL_NO_ERROR();
2222 
2223     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO);
2224     glReadBuffer(GL_COLOR_ATTACHMENT1);
2225     constexpr uint8_t kHalfPixelGradient = 256 / kSize / 2;
2226     EXPECT_PIXEL_NEAR(0, 0, kHalfPixelGradient, kHalfPixelGradient, 0, 255, 1.0);
2227     EXPECT_PIXEL_NEAR(kSize - 1, 0, 255 - kHalfPixelGradient, kHalfPixelGradient, 0, 255, 1.0);
2228     EXPECT_PIXEL_NEAR(0, kSize - 1, kHalfPixelGradient, 255 - kHalfPixelGradient, 0, 255, 1.0);
2229     EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 255 - kHalfPixelGradient, 255 - kHalfPixelGradient, 0,
2230                       255, 1.0);
2231 }
2232 
2233 // Test resolving a multisampled texture into a mipmaped texture with blit
TEST_P(FramebufferTest_ES31,MultisampleResolveIntoMipMapWithBlit)2234 TEST_P(FramebufferTest_ES31, MultisampleResolveIntoMipMapWithBlit)
2235 {
2236     // FBO 1 is attached to a 64x64 texture
2237     // FBO 2 attached to level 1 of a 128x128 texture
2238 
2239     constexpr int kSize = 64;
2240     glViewport(0, 0, kSize, kSize);
2241 
2242     // Create the textures early and call glGenerateMipmap() so it doesn't break the render pass
2243     // between the drawQuad() and glBlitFramebuffer(), so we can test the resolve with subpass path
2244     // in the Vulkan back end.
2245     GLTexture texture;
2246     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture.get());
2247     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
2248     ASSERT_GL_NO_ERROR();
2249 
2250     GLTexture resolveTexture;
2251     glBindTexture(GL_TEXTURE_2D, resolveTexture);
2252     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2253     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2254     ASSERT_GL_NO_ERROR();
2255 
2256     GLFramebuffer msaaFBO;
2257     glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO.get());
2258     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
2259                            texture.get(), 0);
2260     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2261 
2262     ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),
2263                      essl31_shaders::fs::RedGreenGradient());
2264     drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
2265     ASSERT_GL_NO_ERROR();
2266 
2267     // Create another FBO to resolve the multisample buffer into.
2268     GLFramebuffer resolveFBO;
2269     glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
2270     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 1);
2271     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2272 
2273     glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBO);
2274     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO);
2275     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2276     ASSERT_GL_NO_ERROR();
2277 
2278     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO);
2279     constexpr uint8_t kHalfPixelGradient = 256 / kSize / 2;
2280     EXPECT_PIXEL_NEAR(0, 0, kHalfPixelGradient, kHalfPixelGradient, 0, 255, 1.0);
2281     EXPECT_PIXEL_NEAR(kSize - 1, 0, 255 - kHalfPixelGradient, kHalfPixelGradient, 0, 255, 1.0);
2282     EXPECT_PIXEL_NEAR(0, kSize - 1, kHalfPixelGradient, 255 - kHalfPixelGradient, 0, 255, 1.0);
2283     EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 255 - kHalfPixelGradient, 255 - kHalfPixelGradient, 0,
2284                       255, 1.0);
2285 }
2286 
2287 // Test resolving a multisampled texture with blit after drawing to multiple FBOs.
TEST_P(FramebufferTest_ES31,MultipleTextureMultisampleResolveWithBlitMultipleResolves)2288 TEST_P(FramebufferTest_ES31, MultipleTextureMultisampleResolveWithBlitMultipleResolves)
2289 {
2290     // Attach two MSAA textures to FBO1
2291     // Set read buffer 0
2292     // Resolve into FBO2
2293     // Set read buffer 1
2294     // Resolve into FBO3
2295 
2296     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_draw_buffers"));
2297 
2298     constexpr int kSize = 16;
2299     glViewport(0, 0, kSize, kSize);
2300 
2301     GLFramebuffer msaaFBO;
2302     glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO.get());
2303 
2304     GLTexture msaaTextureRed;
2305     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, msaaTextureRed.get());
2306     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
2307     ASSERT_GL_NO_ERROR();
2308     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
2309                            msaaTextureRed.get(), 0);
2310     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2311 
2312     GLTexture msaaTextureGreen;
2313     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, msaaTextureGreen.get());
2314     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
2315     ASSERT_GL_NO_ERROR();
2316     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE,
2317                            msaaTextureGreen.get(), 0);
2318     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2319 
2320     // Setup program to render red into attachment 0 and green into attachment 1.
2321     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), kFSWriteRedGreen);
2322     glUseProgram(program);
2323     constexpr GLenum kDrawBuffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
2324     glDrawBuffers(2, kDrawBuffers);
2325 
2326     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
2327     ASSERT_GL_NO_ERROR();
2328 
2329     // Create another FBO to resolve the multisample buffer into.
2330     GLTexture resolveTexture1;
2331     GLFramebuffer resolveFBO1;
2332     glBindTexture(GL_TEXTURE_2D, resolveTexture1);
2333     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2334     glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO1);
2335     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture1, 0);
2336     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2337 
2338     glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBO);
2339     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO1);
2340     glReadBuffer(GL_COLOR_ATTACHMENT0);  // Red
2341     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2342     ASSERT_GL_NO_ERROR();
2343 
2344     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO1);
2345     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2346 
2347     // Create another FBO to resolve the multisample buffer into.
2348     GLTexture resolveTexture2;
2349     GLFramebuffer resolveFBO2;
2350     glBindTexture(GL_TEXTURE_2D, resolveTexture2);
2351     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2352     glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO2);
2353     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture2, 0);
2354     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2355 
2356     glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBO);
2357     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO2);
2358     glReadBuffer(GL_COLOR_ATTACHMENT1);  // Green
2359     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2360     ASSERT_GL_NO_ERROR();
2361 
2362     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO2);
2363     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2364 }
2365 
2366 // Test resolving a multisampled texture with blit after drawing to multiple FBOs, with color
2367 // attachment 1 resolved first.
TEST_P(FramebufferTest_ES31,MultipleTextureMultisampleResolveWithBlitMultipleResolvesAttachment1First)2368 TEST_P(FramebufferTest_ES31,
2369        MultipleTextureMultisampleResolveWithBlitMultipleResolvesAttachment1First)
2370 {
2371     // Attach two MSAA textures to FBO1
2372     // Set read buffer 1
2373     // Resolve into FBO2
2374     // Set read buffer 0
2375     // Resolve into FBO3
2376 
2377     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_draw_buffers"));
2378 
2379     constexpr int kSize = 16;
2380     glViewport(0, 0, kSize, kSize);
2381 
2382     GLFramebuffer msaaFBO;
2383     glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO.get());
2384 
2385     GLTexture msaaTextureRed;
2386     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, msaaTextureRed.get());
2387     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
2388     ASSERT_GL_NO_ERROR();
2389     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
2390                            msaaTextureRed.get(), 0);
2391     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2392 
2393     GLTexture msaaTextureGreen;
2394     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, msaaTextureGreen.get());
2395     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
2396     ASSERT_GL_NO_ERROR();
2397     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE,
2398                            msaaTextureGreen.get(), 0);
2399     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2400 
2401     // Setup program to render red into attachment 0 and green into attachment 1.
2402     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), kFSWriteRedGreen);
2403     glUseProgram(program);
2404     constexpr GLenum kDrawBuffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
2405     glDrawBuffers(2, kDrawBuffers);
2406 
2407     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
2408     ASSERT_GL_NO_ERROR();
2409 
2410     // Create another FBO to resolve the multisample buffer into.
2411     GLTexture resolveTexture1;
2412     GLFramebuffer resolveFBO1;
2413     glBindTexture(GL_TEXTURE_2D, resolveTexture1);
2414     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2415     glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO1);
2416     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture1, 0);
2417     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2418 
2419     glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBO);
2420     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO1);
2421     glReadBuffer(GL_COLOR_ATTACHMENT1);  // Green
2422     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2423     ASSERT_GL_NO_ERROR();
2424 
2425     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO1);
2426     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2427 
2428     // Create another FBO to resolve the multisample buffer into.
2429     GLTexture resolveTexture2;
2430     GLFramebuffer resolveFBO2;
2431     glBindTexture(GL_TEXTURE_2D, resolveTexture2);
2432     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2433     glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO2);
2434     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture2, 0);
2435     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2436 
2437     glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBO);
2438     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO2);
2439     glReadBuffer(GL_COLOR_ATTACHMENT0);  // Red
2440     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2441     ASSERT_GL_NO_ERROR();
2442 
2443     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO2);
2444     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2445 }
2446 
2447 // Test resolving a multisampled texture with blit, then drawing multisampled again.  The latter
2448 // should not get re-resolved automatically.
TEST_P(FramebufferTest_ES31,MultisampleResolveWithBlitThenDraw)2449 TEST_P(FramebufferTest_ES31, MultisampleResolveWithBlitThenDraw)
2450 {
2451     constexpr int kSize = 16;
2452     glViewport(0, 0, kSize, kSize);
2453 
2454     GLFramebuffer msaaFBO;
2455     glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO.get());
2456 
2457     GLTexture texture;
2458     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture.get());
2459     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
2460     ASSERT_GL_NO_ERROR();
2461     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
2462                            texture.get(), 0);
2463     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2464 
2465     ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),
2466                      essl31_shaders::fs::RedGreenGradient());
2467     drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
2468     ASSERT_GL_NO_ERROR();
2469 
2470     // Create another FBO to resolve the multisample buffer into.
2471     GLTexture resolveTexture;
2472     GLFramebuffer resolveFBO;
2473     glBindTexture(GL_TEXTURE_2D, resolveTexture);
2474     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2475     glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
2476     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 0);
2477     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2478 
2479     glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBO);
2480     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO);
2481     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2482     ASSERT_GL_NO_ERROR();
2483 
2484     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO);
2485     constexpr uint8_t kHalfPixelGradient = 256 / kSize / 2;
2486     EXPECT_PIXEL_NEAR(0, 0, kHalfPixelGradient, kHalfPixelGradient, 0, 255, 1.0);
2487     EXPECT_PIXEL_NEAR(kSize - 1, 0, 255 - kHalfPixelGradient, kHalfPixelGradient, 0, 255, 1.0);
2488     EXPECT_PIXEL_NEAR(0, kSize - 1, kHalfPixelGradient, 255 - kHalfPixelGradient, 0, 255, 1.0);
2489     EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 255 - kHalfPixelGradient, 255 - kHalfPixelGradient, 0,
2490                       255, 1.0);
2491 
2492     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, msaaFBO);
2493     ANGLE_GL_PROGRAM(blueProgram, essl3_shaders::vs::Passthrough(), essl3_shaders::fs::Blue());
2494     drawQuad(blueProgram, essl3_shaders::PositionAttrib(), 0.5f, 1.0f, true);
2495     ASSERT_GL_NO_ERROR();
2496 
2497     // The resolved FBO should be unaffected by the last draw call.
2498     EXPECT_PIXEL_NEAR(0, 0, kHalfPixelGradient, kHalfPixelGradient, 0, 255, 1.0);
2499     EXPECT_PIXEL_NEAR(kSize - 1, 0, 255 - kHalfPixelGradient, kHalfPixelGradient, 0, 255, 1.0);
2500     EXPECT_PIXEL_NEAR(0, kSize - 1, kHalfPixelGradient, 255 - kHalfPixelGradient, 0, 255, 1.0);
2501     EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 255 - kHalfPixelGradient, 255 - kHalfPixelGradient, 0,
2502                       255, 1.0);
2503 }
2504 
2505 // Test resolving a multisampled texture with blit, then drawing multisampled again.  The latter
2506 // should not get re-resolved automatically.  Resoloves color attachment 1.
TEST_P(FramebufferTest_ES31,MultisampleResolveWithBlitThenDrawAttachment1)2507 TEST_P(FramebufferTest_ES31, MultisampleResolveWithBlitThenDrawAttachment1)
2508 {
2509     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_draw_buffers"));
2510 
2511     constexpr int kSize = 16;
2512     glViewport(0, 0, kSize, kSize);
2513 
2514     GLFramebuffer msaaFBO;
2515     glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO.get());
2516 
2517     GLTexture msaaTextureRed;
2518     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, msaaTextureRed.get());
2519     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
2520     ASSERT_GL_NO_ERROR();
2521     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
2522                            msaaTextureRed.get(), 0);
2523     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2524 
2525     GLTexture msaaTextureGreen;
2526     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, msaaTextureGreen.get());
2527     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
2528     ASSERT_GL_NO_ERROR();
2529     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D_MULTISAMPLE,
2530                            msaaTextureGreen.get(), 0);
2531     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2532 
2533     // Setup program to render red into attachment 0 and green into attachment 1.
2534     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), kFSWriteRedGreen);
2535     glUseProgram(program);
2536     constexpr GLenum kDrawBuffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
2537     glDrawBuffers(2, kDrawBuffers);
2538 
2539     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
2540     ASSERT_GL_NO_ERROR();
2541 
2542     // Create another FBO to resolve the multisample buffer into.
2543     GLTexture resolveTexture;
2544     GLFramebuffer resolveFBO;
2545     glBindTexture(GL_TEXTURE_2D, resolveTexture);
2546     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2547     glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
2548     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 0);
2549     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2550 
2551     glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBO);
2552     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO);
2553     glReadBuffer(GL_COLOR_ATTACHMENT1);  // Green
2554     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2555     ASSERT_GL_NO_ERROR();
2556 
2557     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO);
2558     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2559     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::green);
2560     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::green);
2561     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::green);
2562 
2563     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, msaaFBO);
2564     ANGLE_GL_PROGRAM(blueProgram, essl3_shaders::vs::Passthrough(), essl3_shaders::fs::Blue());
2565     drawQuad(blueProgram, essl3_shaders::PositionAttrib(), 0.5f, 1.0f, true);
2566     ASSERT_GL_NO_ERROR();
2567 
2568     // The resolved FBO should be unaffected by the last draw call.
2569     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2570     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::green);
2571     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::green);
2572     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::green);
2573 }
2574 
2575 // Test resolving a multisampled texture with blit, then drawing multisampled again and resolving to
2576 // same framebuffer.
TEST_P(FramebufferTest_ES31,MultisampleResolveWithBlitThenDrawThenResolveAgain)2577 TEST_P(FramebufferTest_ES31, MultisampleResolveWithBlitThenDrawThenResolveAgain)
2578 {
2579     constexpr int kSize = 16;
2580     glViewport(0, 0, kSize, kSize);
2581 
2582     GLFramebuffer msaaFBO;
2583     glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO.get());
2584 
2585     GLTexture texture;
2586     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture.get());
2587     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
2588     ASSERT_GL_NO_ERROR();
2589     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
2590                            texture.get(), 0);
2591     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2592 
2593     ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),
2594                      essl31_shaders::fs::RedGreenGradient());
2595     drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
2596     ASSERT_GL_NO_ERROR();
2597 
2598     // Create another FBO to resolve the multisample buffer into.
2599     GLTexture resolveTexture;
2600     GLFramebuffer resolveFBO;
2601     glBindTexture(GL_TEXTURE_2D, resolveTexture);
2602     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2603     glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
2604     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 0);
2605     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2606 
2607     glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBO);
2608     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO);
2609     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2610     ASSERT_GL_NO_ERROR();
2611 
2612     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO);
2613     constexpr uint8_t kHalfPixelGradient = 256 / kSize / 2;
2614     EXPECT_PIXEL_NEAR(0, 0, kHalfPixelGradient, kHalfPixelGradient, 0, 255, 1.0);
2615     EXPECT_PIXEL_NEAR(kSize - 1, 0, 255 - kHalfPixelGradient, kHalfPixelGradient, 0, 255, 1.0);
2616     EXPECT_PIXEL_NEAR(0, kSize - 1, kHalfPixelGradient, 255 - kHalfPixelGradient, 0, 255, 1.0);
2617     EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 255 - kHalfPixelGradient, 255 - kHalfPixelGradient, 0,
2618                       255, 1.0);
2619 
2620     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, msaaFBO);
2621     ANGLE_GL_PROGRAM(blueProgram, essl3_shaders::vs::Passthrough(), essl3_shaders::fs::Blue());
2622     drawQuad(blueProgram, essl3_shaders::PositionAttrib(), 0.5f, 1.0f, true);
2623     ASSERT_GL_NO_ERROR();
2624 
2625     glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBO);
2626     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO);
2627     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2628     ASSERT_GL_NO_ERROR();
2629 
2630     // Verify that the resolve happened correctly
2631     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO);
2632     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
2633     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::blue);
2634     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::blue);
2635     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::blue);
2636 }
2637 
2638 // Test resolving a multisampled texture with blit, then drawing multisampled again and resolving to
2639 // another framebuffer.
TEST_P(FramebufferTest_ES31,MultisampleResolveWithBlitThenDrawThenResolveAgainToDifferentFBO)2640 TEST_P(FramebufferTest_ES31, MultisampleResolveWithBlitThenDrawThenResolveAgainToDifferentFBO)
2641 {
2642     constexpr int kSize = 16;
2643     glViewport(0, 0, kSize, kSize);
2644 
2645     GLFramebuffer msaaFBO;
2646     glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO.get());
2647 
2648     GLTexture texture;
2649     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture.get());
2650     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
2651     ASSERT_GL_NO_ERROR();
2652     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
2653                            texture.get(), 0);
2654     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2655 
2656     ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),
2657                      essl31_shaders::fs::RedGreenGradient());
2658     drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
2659     ASSERT_GL_NO_ERROR();
2660 
2661     // Create another FBO to resolve the multisample buffer into.
2662     GLTexture resolveTexture1;
2663     GLFramebuffer resolveFBO1;
2664     glBindTexture(GL_TEXTURE_2D, resolveTexture1);
2665     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2666     glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO1);
2667     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture1, 0);
2668     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2669 
2670     glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBO);
2671     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO1);
2672     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2673     ASSERT_GL_NO_ERROR();
2674 
2675     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO1);
2676     constexpr uint8_t kHalfPixelGradient = 256 / kSize / 2;
2677     EXPECT_PIXEL_NEAR(0, 0, kHalfPixelGradient, kHalfPixelGradient, 0, 255, 1.0);
2678     EXPECT_PIXEL_NEAR(kSize - 1, 0, 255 - kHalfPixelGradient, kHalfPixelGradient, 0, 255, 1.0);
2679     EXPECT_PIXEL_NEAR(0, kSize - 1, kHalfPixelGradient, 255 - kHalfPixelGradient, 0, 255, 1.0);
2680     EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 255 - kHalfPixelGradient, 255 - kHalfPixelGradient, 0,
2681                       255, 1.0);
2682 
2683     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, msaaFBO);
2684     ANGLE_GL_PROGRAM(blueProgram, essl3_shaders::vs::Passthrough(), essl3_shaders::fs::Blue());
2685     drawQuad(blueProgram, essl3_shaders::PositionAttrib(), 0.5f, 1.0f, true);
2686     ASSERT_GL_NO_ERROR();
2687 
2688     // Create another FBO to resolve the multisample buffer into.
2689     GLTexture resolveTexture2;
2690     GLFramebuffer resolveFBO2;
2691     glBindTexture(GL_TEXTURE_2D, resolveTexture2);
2692     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2693     glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO2);
2694     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture2, 0);
2695     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2696 
2697     glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBO);
2698     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO2);
2699     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2700     ASSERT_GL_NO_ERROR();
2701 
2702     // Verify that the resolve happened to the correct FBO
2703     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO2);
2704     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
2705     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::blue);
2706     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::blue);
2707     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::blue);
2708 
2709     // The first resolve FBO should be untouched.
2710     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO1);
2711     EXPECT_PIXEL_NEAR(0, 0, kHalfPixelGradient, kHalfPixelGradient, 0, 255, 1.0);
2712     EXPECT_PIXEL_NEAR(kSize - 1, 0, 255 - kHalfPixelGradient, kHalfPixelGradient, 0, 255, 1.0);
2713     EXPECT_PIXEL_NEAR(0, kSize - 1, kHalfPixelGradient, 255 - kHalfPixelGradient, 0, 255, 1.0);
2714     EXPECT_PIXEL_NEAR(kSize - 1, kSize - 1, 255 - kHalfPixelGradient, 255 - kHalfPixelGradient, 0,
2715                       255, 1.0);
2716 }
2717 
2718 // If there are no attachments, rendering will be limited to a rectangle having a lower left of
2719 // (0, 0) and an upper right of(width, height), where width and height are the framebuffer
2720 // object's default width and height.
TEST_P(FramebufferTest_ES31,RenderingLimitToDefaultFBOSizeWithNoAttachments)2721 TEST_P(FramebufferTest_ES31, RenderingLimitToDefaultFBOSizeWithNoAttachments)
2722 {
2723     // anglebug.com/2253
2724     ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsDesktopOpenGL());
2725     // Occlusion query reports fragments outside the render area are still rendered
2726     ANGLE_SKIP_TEST_IF(IsAndroid() || (IsWindows() && (IsIntel() || IsAMD())));
2727 
2728     constexpr char kVS1[] = R"(#version 310 es
2729 in layout(location = 0) highp vec2 a_position;
2730 void main()
2731 {
2732     gl_Position = vec4(a_position, 0.0, 1.0);
2733 })";
2734 
2735     constexpr char kFS1[] = R"(#version 310 es
2736 uniform layout(location = 0) highp ivec2 u_expectedSize;
2737 out layout(location = 3) mediump vec4 f_color;
2738 void main()
2739 {
2740     if (ivec2(gl_FragCoord.xy) != u_expectedSize) discard;
2741     f_color = vec4(1.0, 0.5, 0.25, 1.0);
2742 })";
2743 
2744     constexpr char kVS2[] = R"(#version 310 es
2745 in layout(location = 0) highp vec2 a_position;
2746 void main()
2747 {
2748     gl_Position = vec4(a_position, 0.0, 1.0);
2749 })";
2750 
2751     constexpr char kFS2[] = R"(#version 310 es
2752 uniform layout(location = 0) highp ivec2 u_expectedSize;
2753 out layout(location = 2) mediump vec4 f_color;
2754 void main()
2755 {
2756     if (ivec2(gl_FragCoord.xy) != u_expectedSize) discard;
2757     f_color = vec4(1.0, 0.5, 0.25, 1.0);
2758 })";
2759 
2760     ANGLE_GL_PROGRAM(program1, kVS1, kFS1);
2761     ANGLE_GL_PROGRAM(program2, kVS2, kFS2);
2762 
2763     glUseProgram(program1);
2764 
2765     GLFramebuffer mFramebuffer;
2766     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer);
2767     GLuint defaultWidth  = 1;
2768     GLuint defaultHeight = 1;
2769 
2770     glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, defaultWidth);
2771     glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_HEIGHT, defaultHeight);
2772     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
2773 
2774     const float data[] = {
2775         1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f,
2776     };
2777 
2778     GLuint vertexArray  = 0;
2779     GLuint vertexBuffer = 0;
2780     GLuint query        = 0;
2781     GLuint passedCount  = 0;
2782 
2783     glGenQueries(1, &query);
2784     glGenVertexArrays(1, &vertexArray);
2785     glBindVertexArray(vertexArray);
2786 
2787     glGenBuffers(1, &vertexBuffer);
2788     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
2789     glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
2790 
2791     glEnableVertexAttribArray(0);
2792     glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
2793     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
2794 
2795     validateSamplePass(query, passedCount, defaultWidth, defaultHeight);
2796 
2797     glUseProgram(program2);
2798     validateSamplePass(query, passedCount, defaultWidth, defaultHeight);
2799 
2800     glUseProgram(program1);
2801     // If fbo has attachments, the rendering size should be the same as its attachment.
2802     GLTexture mTexture;
2803     GLuint width  = 2;
2804     GLuint height = 2;
2805     glBindTexture(GL_TEXTURE_2D, mTexture.get());
2806     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width, height);
2807 
2808     const GLenum bufs[] = {GL_NONE, GL_NONE, GL_NONE, GL_COLOR_ATTACHMENT3};
2809 
2810     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, mTexture.get(),
2811                            0);
2812     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
2813     glDrawBuffers(4, bufs);
2814 
2815     validateSamplePass(query, passedCount, width, height);
2816 
2817     // If fbo's attachment has been removed, the rendering size should be the same as framebuffer
2818     // default size.
2819     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, 0, 0, 0);
2820     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
2821 
2822     validateSamplePass(query, passedCount, defaultWidth, defaultHeight);
2823 
2824     glDisableVertexAttribArray(0);
2825     glBindBuffer(GL_ARRAY_BUFFER, 0);
2826     glBindVertexArray(0);
2827     glDeleteBuffers(1, &vertexBuffer);
2828     glDeleteVertexArrays(1, &vertexArray);
2829 
2830     ASSERT_GL_NO_ERROR();
2831 }
2832 
2833 // Validates both MESA and standard functions can be used on OpenGL ES >=3.1
TEST_P(FramebufferTest_ES31,ValidateFramebufferFlipYMesaExtension)2834 TEST_P(FramebufferTest_ES31, ValidateFramebufferFlipYMesaExtension)
2835 {
2836     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
2837 
2838     GLFramebuffer mFramebuffer;
2839     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
2840 
2841     glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
2842     ASSERT_GL_NO_ERROR();
2843 
2844     GLint flip_y = -1;
2845 
2846     glGetFramebufferParameterivMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, &flip_y);
2847     ASSERT_GL_NO_ERROR();
2848     EXPECT_EQ(flip_y, 1);
2849 
2850     glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 0);
2851     ASSERT_GL_NO_ERROR();
2852 
2853     flip_y = -1;
2854     glGetFramebufferParameterivMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, &flip_y);
2855     ASSERT_GL_NO_ERROR();
2856     EXPECT_EQ(flip_y, 0);
2857 
2858     // Also using non-MESA functions should work.
2859     glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
2860     ASSERT_GL_NO_ERROR();
2861 
2862     flip_y = -1;
2863     glGetFramebufferParameteriv(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, &flip_y);
2864     ASSERT_GL_NO_ERROR();
2865     EXPECT_EQ(flip_y, 1);
2866 
2867     glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 0);
2868     ASSERT_GL_NO_ERROR();
2869 
2870     flip_y = -1;
2871     glGetFramebufferParameteriv(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, &flip_y);
2872     ASSERT_GL_NO_ERROR();
2873     EXPECT_EQ(flip_y, 0);
2874 }
2875 
2876 class AddMockTextureNoRenderTargetTest : public ANGLETest
2877 {
2878   public:
AddMockTextureNoRenderTargetTest()2879     AddMockTextureNoRenderTargetTest()
2880     {
2881         setWindowWidth(512);
2882         setWindowHeight(512);
2883         setConfigRedBits(8);
2884         setConfigGreenBits(8);
2885         setConfigBlueBits(8);
2886         setConfigAlphaBits(8);
2887     }
2888 };
2889 
2890 // Test to verify workaround succeeds when no program outputs exist http://anglebug.com/2283
TEST_P(AddMockTextureNoRenderTargetTest,NoProgramOutputWorkaround)2891 TEST_P(AddMockTextureNoRenderTargetTest, NoProgramOutputWorkaround)
2892 {
2893     constexpr char kVS[] = "void main() {}";
2894     constexpr char kFS[] = "void main() {}";
2895 
2896     ANGLE_GL_PROGRAM(drawProgram, kVS, kFS);
2897 
2898     glUseProgram(drawProgram);
2899 
2900     glDrawArrays(GL_TRIANGLES, 0, 6);
2901 
2902     ASSERT_GL_NO_ERROR();
2903 }
2904 
2905 // Covers a bug in ANGLE's Vulkan back-end framebuffer cache which ignored depth/stencil after
2906 // calls to DrawBuffers.
TEST_P(FramebufferTest_ES3,AttachmentStateChange)2907 TEST_P(FramebufferTest_ES3, AttachmentStateChange)
2908 {
2909     constexpr GLuint kSize = 2;
2910 
2911     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
2912 
2913     GLTexture colorTexture;
2914     glBindTexture(GL_TEXTURE_2D, colorTexture);
2915     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2916 
2917     GLFramebuffer fbo;
2918     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2919     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
2920 
2921     ASSERT_GL_NO_ERROR();
2922     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2923 
2924     // First draw without a depth buffer.
2925     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
2926 
2927     GLRenderbuffer depthBuffer;
2928     glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
2929     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, kSize, kSize);
2930 
2931     // Bind just a renderbuffer and draw.
2932     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer);
2933 
2934     ASSERT_GL_NO_ERROR();
2935     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2936 
2937     glDrawBuffers(0, nullptr);
2938     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
2939 
2940     // Re-enable color buffer and draw one final time. This previously triggered a crash.
2941     GLenum drawBuffs = {GL_COLOR_ATTACHMENT0};
2942     glDrawBuffers(1, &drawBuffs);
2943 
2944     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
2945     ASSERT_GL_NO_ERROR();
2946     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2947 }
2948 
2949 // Tests that we can support a feedback loop between a depth textures and the depth buffer.
2950 // The test emulates the read-only feedback loop in Manhattan.
TEST_P(FramebufferTest_ES3,ReadOnlyDepthFeedbackLoopSupported)2951 TEST_P(FramebufferTest_ES3, ReadOnlyDepthFeedbackLoopSupported)
2952 {
2953     // Feedback loops are only supported on Vulkan.
2954     // TODO(jmadill): Make GL extension. http://anglebug.com/4969
2955     ANGLE_SKIP_TEST_IF(!IsVulkan());
2956 
2957     constexpr GLuint kSize = 2;
2958     glViewport(0, 0, kSize, kSize);
2959 
2960     constexpr char kFS[] = R"(precision mediump float;
2961 varying vec2 v_texCoord;
2962 uniform sampler2D depth;
2963 void main()
2964 {
2965     if (abs(texture2D(depth, v_texCoord).x - 0.5) < 0.1)
2966     {
2967         gl_FragColor = vec4(0, 1, 0, 1);
2968     }
2969     else
2970     {
2971         gl_FragColor = vec4(1, 0, 0, 1);
2972     }
2973 })";
2974 
2975     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), kFS);
2976 
2977     GLFramebuffer framebuffer;
2978     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
2979 
2980     GLTexture colorTexture;
2981     glBindTexture(GL_TEXTURE_2D, colorTexture);
2982     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2983 
2984     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2985     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2986     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
2987 
2988     GLTexture depthTexture;
2989     glBindTexture(GL_TEXTURE_2D, depthTexture);
2990     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, kSize, kSize, 0, GL_DEPTH_COMPONENT,
2991                  GL_UNSIGNED_INT, nullptr);
2992     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2993     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2994     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
2995 
2996     ASSERT_GL_NO_ERROR();
2997     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2998 
2999     // Clear depth to 0.5.
3000     glClearDepthf(0.5f);
3001     glClear(GL_DEPTH_BUFFER_BIT);
3002 
3003     // Disable depth. Although this does not remove the feedback loop as defined by the
3004     // spec it mimics what gfxbench does in its rendering tests.
3005     glDepthMask(false);
3006     glDisable(GL_DEPTH_TEST);
3007 
3008     // Verify we can sample the depth texture and get 0.5.
3009     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5);
3010 
3011     ASSERT_GL_NO_ERROR();
3012     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3013 }
3014 
3015 // Tests corner cases with read-only depth-stencil feedback loops.
TEST_P(FramebufferTest_ES3,ReadOnlyDepthFeedbackLoopStateChanges)3016 TEST_P(FramebufferTest_ES3, ReadOnlyDepthFeedbackLoopStateChanges)
3017 {
3018     // Feedback loops are only supported on Vulkan.
3019     // TODO(jmadill): Make GL extension. http://anglebug.com/4969
3020     ANGLE_SKIP_TEST_IF(!IsVulkan());
3021 
3022     constexpr GLuint kSize = 2;
3023     glViewport(0, 0, kSize, kSize);
3024 
3025     constexpr char kFS[] = R"(precision mediump float;
3026 varying vec2 v_texCoord;
3027 uniform sampler2D depth;
3028 void main()
3029 {
3030     if (abs(texture2D(depth, v_texCoord).x - 0.5) < 0.1)
3031     {
3032         gl_FragColor = vec4(0, 1, 0, 1);
3033     }
3034     else
3035     {
3036         gl_FragColor = vec4(1, 0, 0, 1);
3037     }
3038 })";
3039 
3040     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), kFS);
3041     glUseProgram(program);
3042 
3043     setupQuadVertexBuffer(0.5f, 1.0f);
3044     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
3045     glEnableVertexAttribArray(0);
3046 
3047     GLFramebuffer framebuffer1;
3048     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer1);
3049 
3050     GLTexture colorTexture;
3051     glBindTexture(GL_TEXTURE_2D, colorTexture);
3052     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3053 
3054     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3055     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3056     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
3057 
3058     GLTexture depthTexture;
3059     glBindTexture(GL_TEXTURE_2D, depthTexture);
3060     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, kSize, kSize, 0, GL_DEPTH_COMPONENT,
3061                  GL_UNSIGNED_INT, nullptr);
3062     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3063     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3064     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
3065     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3066 
3067     GLFramebuffer framebuffer2;
3068     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer2);
3069     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
3070     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3071 
3072     ASSERT_GL_NO_ERROR();
3073 
3074     // Clear depth to 0.5.
3075     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer1);
3076     glClearDepthf(0.5f);
3077     glClear(GL_DEPTH_BUFFER_BIT);
3078     glFlush();
3079 
3080     // Disable depth. Although this does not remove the feedback loop as defined by the
3081     // spec it mimics what gfxbench does in its rendering tests.
3082     glDepthMask(false);
3083     glDisable(GL_DEPTH_TEST);
3084 
3085     // Draw with loop.
3086     glDrawArrays(GL_TRIANGLES, 0, 6);
3087     ASSERT_GL_NO_ERROR();
3088 
3089     // Draw with no loop and second FBO. Starts RP in writable mode.
3090     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer2);
3091     glBindTexture(GL_TEXTURE_2D, 0);
3092     glDrawArrays(GL_TRIANGLES, 0, 6);
3093     ASSERT_GL_NO_ERROR();
3094 
3095     // Draw with loop, restarts RP.
3096     glBindTexture(GL_TEXTURE_2D, depthTexture);
3097     glDrawArrays(GL_TRIANGLES, 0, 6);
3098     ASSERT_GL_NO_ERROR();
3099 }
3100 
3101 // Tests depth/stencil clear after read-only depth/stencil feedback loop draw.
TEST_P(FramebufferTest_ES3,ReadOnlyDepthFeedbackLoopDrawThenDepthStencilClear)3102 TEST_P(FramebufferTest_ES3, ReadOnlyDepthFeedbackLoopDrawThenDepthStencilClear)
3103 {
3104     // Feedback loops are only supported on Vulkan.
3105     // TODO(jmadill): Make GL extension. http://anglebug.com/4969
3106     ANGLE_SKIP_TEST_IF(!IsVulkan());
3107 
3108     constexpr GLuint kSize = 2;
3109     glViewport(0, 0, kSize, kSize);
3110 
3111     constexpr char kFS[] = R"(precision mediump float;
3112 varying vec2 v_texCoord;
3113 uniform sampler2D depth;
3114 void main()
3115 {
3116     if (abs(texture2D(depth, v_texCoord).x - 0.5) < 0.1)
3117     {
3118         gl_FragColor = vec4(0, 1, 0, 1);
3119     }
3120     else
3121     {
3122         gl_FragColor = vec4(1, 0, 0, 1);
3123     }
3124 })";
3125 
3126     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), kFS);
3127     glUseProgram(program);
3128 
3129     setupQuadVertexBuffer(0.5f, 1.0f);
3130     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
3131     glEnableVertexAttribArray(0);
3132 
3133     GLFramebuffer framebuffer;
3134     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
3135 
3136     GLTexture colorTexture;
3137     glBindTexture(GL_TEXTURE_2D, colorTexture);
3138     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3139 
3140     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3141     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3142     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
3143 
3144     GLTexture depthTexture;
3145     glBindTexture(GL_TEXTURE_2D, depthTexture);
3146     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, kSize, kSize, 0, GL_DEPTH_COMPONENT,
3147                  GL_UNSIGNED_INT, nullptr);
3148     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3149     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3150     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
3151 
3152     ASSERT_GL_NO_ERROR();
3153     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3154 
3155     // Clear depth to 0.5.
3156     glClearDepthf(0.5f);
3157     glClear(GL_DEPTH_BUFFER_BIT);
3158 
3159     // Disable depth to establish read-only depth/stencil feedback loop.
3160     glDepthMask(false);
3161     glDisable(GL_DEPTH_TEST);
3162 
3163     // Verify we can sample the depth texture and get 0.5.
3164     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5);
3165 
3166     // Clear depth to another value
3167     glDepthMask(true);
3168     glClearDepthf(1.0f);
3169     glClear(GL_DEPTH_BUFFER_BIT);
3170     ASSERT_GL_NO_ERROR();
3171 
3172     // Make sure the last clear and the draw are not reordered by mistake.
3173     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3174     ASSERT_GL_NO_ERROR();
3175 
3176     // Make sure depth is correctly cleared.
3177     glEnable(GL_DEPTH_TEST);
3178     glDepthFunc(GL_LESS);
3179 
3180     ANGLE_GL_PROGRAM(drawBlue, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
3181     drawQuad(drawBlue, essl1_shaders::PositionAttrib(), 0.95f);
3182 
3183     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
3184     ASSERT_GL_NO_ERROR();
3185 }
3186 
3187 // Tests scissored depth/stencil clear after read-only depth/stencil feedback loop draw.
TEST_P(FramebufferTest_ES3,ReadOnlyDepthFeedbackLoopDrawThenScissoredDepthStencilClear)3188 TEST_P(FramebufferTest_ES3, ReadOnlyDepthFeedbackLoopDrawThenScissoredDepthStencilClear)
3189 {
3190     // Feedback loops are only supported on Vulkan.
3191     // TODO(jmadill): Make GL extension. http://anglebug.com/4969
3192     ANGLE_SKIP_TEST_IF(!IsVulkan());
3193 
3194     constexpr GLuint kSize = 2;
3195     glViewport(0, 0, kSize, kSize);
3196 
3197     constexpr char kFS[] = R"(precision mediump float;
3198 varying vec2 v_texCoord;
3199 uniform sampler2D depth;
3200 void main()
3201 {
3202     if (abs(texture2D(depth, v_texCoord).x - 0.5) < 0.1)
3203     {
3204         gl_FragColor = vec4(0, 1, 0, 1);
3205     }
3206     else
3207     {
3208         gl_FragColor = vec4(1, 0, 0, 1);
3209     }
3210 })";
3211 
3212     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), kFS);
3213     glUseProgram(program);
3214 
3215     setupQuadVertexBuffer(0.5f, 1.0f);
3216     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
3217     glEnableVertexAttribArray(0);
3218 
3219     GLFramebuffer framebuffer;
3220     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
3221 
3222     GLTexture colorTexture;
3223     glBindTexture(GL_TEXTURE_2D, colorTexture);
3224     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3225 
3226     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3227     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3228     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
3229 
3230     GLTexture depthTexture;
3231     glBindTexture(GL_TEXTURE_2D, depthTexture);
3232     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, kSize, kSize, 0, GL_DEPTH_COMPONENT,
3233                  GL_UNSIGNED_INT, nullptr);
3234     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3235     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3236     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
3237 
3238     ASSERT_GL_NO_ERROR();
3239     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3240 
3241     // Clear depth to 0.5.
3242     glClearDepthf(0.5f);
3243     glClear(GL_DEPTH_BUFFER_BIT);
3244 
3245     // Disable depth to establish read-only depth/stencil feedback loop.
3246     glDepthMask(false);
3247     glDisable(GL_DEPTH_TEST);
3248 
3249     // Verify we can sample the depth texture and get 0.5.
3250     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5);
3251 
3252     // Clear depth to another value in a scissor
3253     glDepthMask(true);
3254     glEnable(GL_SCISSOR_TEST);
3255     glViewport(kSize / 2, kSize / 2, kSize / 2, kSize / 2);
3256     glClearDepthf(1.0f);
3257     glClear(GL_DEPTH_BUFFER_BIT);
3258     ASSERT_GL_NO_ERROR();
3259 
3260     // Make sure the draw worked.
3261     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3262     ASSERT_GL_NO_ERROR();
3263 
3264     // Make sure depth is correctly cleared.
3265     glEnable(GL_DEPTH_TEST);
3266     glDepthFunc(GL_LESS);
3267 
3268     ANGLE_GL_PROGRAM(drawBlue, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
3269     drawQuad(drawBlue, essl1_shaders::PositionAttrib(), 0.95f);
3270 
3271     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3272     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::blue);
3273     ASSERT_GL_NO_ERROR();
3274 }
3275 
3276 // Tests depth/stencil blit after read-only depth/stencil feedback loop draw.
TEST_P(FramebufferTest_ES3,ReadOnlyDepthFeedbackLoopDrawThenDepthStencilBlit)3277 TEST_P(FramebufferTest_ES3, ReadOnlyDepthFeedbackLoopDrawThenDepthStencilBlit)
3278 {
3279     // Feedback loops are only supported on Vulkan.
3280     // TODO(jmadill): Make GL extension. http://anglebug.com/4969
3281     ANGLE_SKIP_TEST_IF(!IsVulkan());
3282 
3283     constexpr GLuint kSize = 2;
3284     glViewport(0, 0, kSize, kSize);
3285 
3286     constexpr char kFS[] = R"(precision mediump float;
3287 varying vec2 v_texCoord;
3288 uniform sampler2D depth;
3289 void main()
3290 {
3291     if (abs(texture2D(depth, v_texCoord).x - 0.5) < 0.1)
3292     {
3293         gl_FragColor = vec4(0, 1, 0, 1);
3294     }
3295     else
3296     {
3297         gl_FragColor = vec4(1, 0, 0, 1);
3298     }
3299 })";
3300 
3301     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), kFS);
3302     glUseProgram(program);
3303 
3304     setupQuadVertexBuffer(0.5f, 1.0f);
3305     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
3306     glEnableVertexAttribArray(0);
3307 
3308     GLFramebuffer framebuffer;
3309     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
3310 
3311     GLTexture colorTexture;
3312     glBindTexture(GL_TEXTURE_2D, colorTexture);
3313     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3314 
3315     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3316     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3317     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
3318 
3319     GLTexture depthTexture;
3320     glBindTexture(GL_TEXTURE_2D, depthTexture);
3321     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, kSize, kSize, 0, GL_DEPTH_COMPONENT,
3322                  GL_UNSIGNED_INT, nullptr);
3323     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3324     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3325     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
3326 
3327     ASSERT_GL_NO_ERROR();
3328     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3329 
3330     // Clear depth to 0.5.
3331     glClearDepthf(0.5f);
3332     glClear(GL_DEPTH_BUFFER_BIT);
3333 
3334     // Disable depth to establish read-only depth/stencil feedback loop.
3335     glDepthMask(false);
3336     glDisable(GL_DEPTH_TEST);
3337 
3338     // Verify we can sample the depth texture and get 0.5.
3339     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5);
3340 
3341     // Blit depth to another framebuffer.
3342     GLFramebuffer framebuffer2;
3343     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer2);
3344 
3345     GLTexture colorTexture2;
3346     glBindTexture(GL_TEXTURE_2D, colorTexture2);
3347     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3348     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture2,
3349                            0);
3350 
3351     GLTexture depthTexture2;
3352     glBindTexture(GL_TEXTURE_2D, depthTexture2);
3353     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, kSize, kSize, 0, GL_DEPTH_COMPONENT,
3354                  GL_UNSIGNED_INT, nullptr);
3355     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture2,
3356                            0);
3357 
3358     ASSERT_GL_NO_ERROR();
3359     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
3360 
3361     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
3362 
3363     // Make sure the draw worked.
3364     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3365     ASSERT_GL_NO_ERROR();
3366 
3367     // Make sure depth is correctly blitted.
3368     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer2);
3369     glEnable(GL_DEPTH_TEST);
3370     glDepthFunc(GL_GREATER);
3371 
3372     ANGLE_GL_PROGRAM(drawBlue, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
3373     drawQuad(drawBlue, essl1_shaders::PositionAttrib(), 0.05f);
3374 
3375     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
3376     ASSERT_GL_NO_ERROR();
3377 
3378     glDepthFunc(GL_LESS);
3379     ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
3380     drawQuad(drawRed, essl1_shaders::PositionAttrib(), -0.05f);
3381 
3382     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3383     ASSERT_GL_NO_ERROR();
3384 }
3385 
3386 // Tests that if the framebuffer is cleared, a feedback loop between a depth textures and the depth
3387 // buffer is established, and a scissored clear is issued, that the clear is not mistakenly
3388 // scissored.
TEST_P(FramebufferTest_ES3,ReadOnlyDepthFeedbackLoopWithClearAndScissoredDraw)3389 TEST_P(FramebufferTest_ES3, ReadOnlyDepthFeedbackLoopWithClearAndScissoredDraw)
3390 {
3391     // Feedback loops are only supported on Vulkan.
3392     // TODO(jmadill): Make GL extension. http://anglebug.com/4969
3393     ANGLE_SKIP_TEST_IF(!IsVulkan());
3394 
3395     constexpr GLuint kSize = 16;
3396     glViewport(0, 0, kSize, kSize);
3397 
3398     constexpr char kFS[] = R"(precision mediump float;
3399 varying vec2 v_texCoord;
3400 uniform sampler2D depth;
3401 void main()
3402 {
3403     if (abs(texture2D(depth, v_texCoord).x - 0.5) < 0.1)
3404     {
3405         gl_FragColor = vec4(0, 1, 0, 1);
3406     }
3407     else
3408     {
3409         gl_FragColor = vec4(1, 0, 0, 1);
3410     }
3411 })";
3412 
3413     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), kFS);
3414 
3415     GLFramebuffer framebuffer;
3416     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
3417 
3418     GLTexture colorTexture;
3419     glBindTexture(GL_TEXTURE_2D, colorTexture);
3420     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3421 
3422     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3423     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3424     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
3425 
3426     GLTexture depthTexture;
3427     glBindTexture(GL_TEXTURE_2D, depthTexture);
3428     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, kSize, kSize, 0, GL_DEPTH_COMPONENT,
3429                  GL_UNSIGNED_INT, nullptr);
3430     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3431     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3432     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
3433 
3434     ASSERT_GL_NO_ERROR();
3435     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3436 
3437     // Clear color to blue and depth to 0.5.
3438     glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
3439     glClearDepthf(0.5f);
3440     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
3441 
3442     // Disable depth. Although this does not remove the feedback loop as defined by the
3443     // spec it mimics what gfxbench does in its rendering tests.
3444     glDepthMask(false);
3445     glDisable(GL_DEPTH_TEST);
3446 
3447     // Verify we can sample the depth texture and get 0.5.  Use a scissor.
3448     glScissor(0, 0, kSize / 2, kSize);
3449     glEnable(GL_SCISSOR_TEST);
3450     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5);
3451     ASSERT_GL_NO_ERROR();
3452 
3453     // Make sure the scissored region passes the depth test and is changed to green.
3454     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3455     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::green);
3456     EXPECT_PIXEL_COLOR_EQ(kSize / 2 - 1, 0, GLColor::green);
3457     EXPECT_PIXEL_COLOR_EQ(kSize / 2 - 1, kSize - 1, GLColor::green);
3458 
3459     // Make sure the region outside the scissor is cleared to blue.
3460     EXPECT_PIXEL_COLOR_EQ(kSize / 2, 0, GLColor::blue);
3461     EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize - 1, GLColor::blue);
3462     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::blue);
3463     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::blue);
3464 }
3465 
3466 // Tests that we can support a color texture also attached to the color attachment but
3467 // with different LOD. From GLES3.0 spec section 4.4.3.2, if min_filter is GL_NEAREST_MIPMAP_NEAREST
3468 // and the lod is within the [base_level, max_level] range, and it is possible to sample from a LOD
3469 // that is rendering to then it does form a feedback loop. But if it is using textureLOD to
3470 // explicitly fetching texture on different LOD, there is no loop and should still work. Aztec_ruins
3471 // (https://issuetracker.google.com/175584609) is doing exactly this.
TEST_P(FramebufferTest_ES3,SampleFromAttachedTextureWithDifferentLOD)3472 TEST_P(FramebufferTest_ES3, SampleFromAttachedTextureWithDifferentLOD)
3473 {
3474     // TODO: https://anglebug.com/5760
3475     ANGLE_SKIP_TEST_IF(IsD3D());
3476 
3477     constexpr GLuint kLevel0Size = 4;
3478     constexpr GLuint kLevel1Size = kLevel0Size / 2;
3479     constexpr GLuint kLevel2Size = kLevel1Size / 2;
3480     std::array<GLColor, kLevel0Size * kLevel0Size> gData;
3481 
3482     GLTexture colorTexture;
3483     glBindTexture(GL_TEXTURE_2D, colorTexture);
3484     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
3485     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3486     glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, kLevel0Size, kLevel0Size);
3487     gData.fill(GLColor::red);
3488     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kLevel0Size, kLevel0Size, GL_RGBA, GL_UNSIGNED_BYTE,
3489                     gData.data());
3490     gData.fill(GLColor::green);
3491     glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, kLevel1Size, kLevel1Size, GL_RGBA, GL_UNSIGNED_BYTE,
3492                     gData.data());
3493     gData.fill(GLColor::blue);
3494     glTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, kLevel2Size, kLevel2Size, GL_RGBA, GL_UNSIGNED_BYTE,
3495                     gData.data());
3496 
3497     // Attach level 1 to a FBO
3498     GLFramebuffer framebuffer;
3499     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
3500     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 1);
3501     ASSERT_GL_NO_ERROR();
3502     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3503 
3504     // Render to FBO with color texture level 1 and textureLod from level 0.
3505     const GLenum discard[] = {GL_COLOR_ATTACHMENT0};
3506     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, discard);
3507     glViewport(0, 0, kLevel1Size, kLevel1Size);
3508     glScissor(0, 0, kLevel1Size, kLevel1Size);
3509     glEnable(GL_CULL_FACE);
3510     glCullFace(GL_BACK);
3511     glDisable(GL_BLEND);
3512     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3513     glActiveTexture(GL_TEXTURE0);
3514     glBindTexture(GL_TEXTURE_2D, colorTexture);
3515 
3516     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Texture2DLod(), essl3_shaders::fs::Texture2DLod());
3517     glUseProgram(program);
3518     GLint textureLoc = glGetUniformLocation(program, essl3_shaders::Texture2DUniform());
3519     GLint lodLoc     = glGetUniformLocation(program, essl3_shaders::LodUniform());
3520     ASSERT_NE(-1, textureLoc);
3521     ASSERT_NE(-1, lodLoc);
3522     glUniform1i(textureLoc, 0);  // texture unit 0
3523     glUniform1f(lodLoc, 0);      // with Lod=0
3524     drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
3525 
3526     glDisable(GL_CULL_FACE);
3527     glDisable(GL_DEPTH_TEST);
3528     glDisable(GL_BLEND);
3529     glDisable(GL_SCISSOR_TEST);
3530     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3531 
3532     ASSERT_GL_NO_ERROR();
3533     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3534 }
3535 
3536 // This extends the test SampleFromAttachedTextureWithDifferentLOD by creating two renderpasses
3537 // without changing texture binding. This is to make sure that sample/render to the same texture
3538 // still function properly when transition from one renderpass to another without texture binding
3539 // change.
TEST_P(FramebufferTest_ES3,SampleFromAttachedTextureWithDifferentLODAndFBOSwitch)3540 TEST_P(FramebufferTest_ES3, SampleFromAttachedTextureWithDifferentLODAndFBOSwitch)
3541 {
3542     // TODO: https://anglebug.com/5760
3543     ANGLE_SKIP_TEST_IF(IsD3D());
3544 
3545     constexpr GLuint kLevel0Size = 4;
3546     constexpr GLuint kLevel1Size = kLevel0Size / 2;
3547     constexpr GLuint kLevel2Size = kLevel1Size / 2;
3548     std::array<GLColor, kLevel0Size * kLevel0Size> gData;
3549 
3550     GLTexture colorTexture;
3551     glBindTexture(GL_TEXTURE_2D, colorTexture);
3552     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
3553     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3554     glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, kLevel0Size, kLevel0Size);
3555     gData.fill(GLColor::red);
3556     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kLevel0Size, kLevel0Size, GL_RGBA, GL_UNSIGNED_BYTE,
3557                     gData.data());
3558     gData.fill(GLColor::green);
3559     glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, kLevel1Size, kLevel1Size, GL_RGBA, GL_UNSIGNED_BYTE,
3560                     gData.data());
3561     gData.fill(GLColor::blue);
3562     glTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, kLevel2Size, kLevel2Size, GL_RGBA, GL_UNSIGNED_BYTE,
3563                     gData.data());
3564 
3565     // Attach level 1 to two FBOs
3566     GLFramebuffer framebuffer1;
3567     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer1);
3568     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 1);
3569     ASSERT_GL_NO_ERROR();
3570     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3571     GLFramebuffer framebuffer2;
3572     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer2);
3573     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 1);
3574     ASSERT_GL_NO_ERROR();
3575     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3576 
3577     // Render to left half of FBO1 and textureLod from level 0.
3578     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer1);
3579     glViewport(0, 0, kLevel1Size / 2, kLevel1Size);
3580     glScissor(0, 0, kLevel1Size / 2, kLevel1Size);
3581     glActiveTexture(GL_TEXTURE0);
3582     glBindTexture(GL_TEXTURE_2D, colorTexture);
3583     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Texture2DLod(), essl3_shaders::fs::Texture2DLod());
3584     glUseProgram(program);
3585     GLint textureLoc = glGetUniformLocation(program, essl3_shaders::Texture2DUniform());
3586     GLint lodLoc     = glGetUniformLocation(program, essl3_shaders::LodUniform());
3587     ASSERT_NE(-1, textureLoc);
3588     ASSERT_NE(-1, lodLoc);
3589     glUniform1i(textureLoc, 0);  // texture unit 0
3590     glUniform1f(lodLoc, 0);      // with Lod=0
3591     drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
3592     ASSERT_GL_NO_ERROR();
3593 
3594     // Render to right half of FBO2 and textureLod from level 0 without trigger texture binding
3595     // change.
3596     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer2);
3597     glViewport(kLevel1Size / 2, 0, kLevel1Size / 2, kLevel1Size);
3598     glScissor(kLevel1Size / 2, 0, kLevel1Size / 2, kLevel1Size);
3599     drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
3600     ASSERT_GL_NO_ERROR();
3601     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3602     EXPECT_PIXEL_COLOR_EQ(kLevel1Size - 1, 0, GLColor::red);
3603 }
3604 
3605 // Test render to a texture level that is excluded from [base_level, max_level]. This specific test
3606 // renders to an immutable texture at the level that is bigger than GL_TEXTURE_MAX_LEVEL. The
3607 // texture itself has not been initialized with any data before rendering (TexSubImage call may
3608 // initialize a VkImage object).
TEST_P(FramebufferTest_ES3,RenderAndInvalidateImmutableTextureWithBeyondMaxLevel)3609 TEST_P(FramebufferTest_ES3, RenderAndInvalidateImmutableTextureWithBeyondMaxLevel)
3610 {
3611     constexpr GLuint kLevel0Size = 4;
3612     constexpr GLuint kLevel1Size = kLevel0Size / 2;
3613 
3614     GLTexture colorTexture;
3615     glBindTexture(GL_TEXTURE_2D, colorTexture);
3616     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
3617     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3618     glTexStorage2D(GL_TEXTURE_2D, 2, GL_RGBA8, kLevel0Size, kLevel0Size);
3619     // set max_level to 0
3620     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
3621 
3622     // Attach level 1 to a FBO
3623     GLFramebuffer framebuffer;
3624     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
3625     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 1);
3626     ASSERT_GL_NO_ERROR();
3627     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3628 
3629     // Render to FBO
3630     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
3631     const GLenum discard[] = {GL_COLOR_ATTACHMENT0};
3632     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, discard);
3633     glViewport(0, 0, kLevel1Size, kLevel1Size);
3634     glScissor(0, 0, kLevel1Size, kLevel1Size);
3635     glEnable(GL_CULL_FACE);
3636     glCullFace(GL_BACK);
3637     glDisable(GL_BLEND);
3638     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3639     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
3640     glUseProgram(program);
3641     drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
3642 
3643     glDisable(GL_CULL_FACE);
3644     glDisable(GL_DEPTH_TEST);
3645     glDisable(GL_BLEND);
3646     glDisable(GL_SCISSOR_TEST);
3647     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3648 
3649     ASSERT_GL_NO_ERROR();
3650     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3651 }
3652 
3653 // Test render to a texture level that is excluded from [base_level, max_level]. This specific test
3654 // renders to an immutable texture at the level that is bigger than GL_TEXTURE_MAX_LEVEL. The
3655 // texture itself has been initialized with data before rendering.
TEST_P(FramebufferTest_ES3,RenderAndInvalidateImmutableTextureWithSubImageWithBeyondMaxLevel)3656 TEST_P(FramebufferTest_ES3, RenderAndInvalidateImmutableTextureWithSubImageWithBeyondMaxLevel)
3657 {
3658     constexpr GLuint kLevel0Size = 4;
3659     constexpr GLuint kLevel1Size = kLevel0Size / 2;
3660     std::array<GLColor, kLevel0Size * kLevel0Size> gData;
3661 
3662     GLTexture colorTexture;
3663     glBindTexture(GL_TEXTURE_2D, colorTexture);
3664     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
3665     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3666     glTexStorage2D(GL_TEXTURE_2D, 2, GL_RGBA8, kLevel0Size, kLevel0Size);
3667     // set max_level to 0
3668     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
3669     // Initialize with TexSubImage call
3670     gData.fill(GLColor::blue);
3671     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kLevel0Size, kLevel0Size, GL_RGBA, GL_UNSIGNED_BYTE,
3672                     gData.data());
3673 
3674     // Attach level 1 to a FBO
3675     GLFramebuffer framebuffer;
3676     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
3677     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 1);
3678     ASSERT_GL_NO_ERROR();
3679     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3680 
3681     // Render to FBO
3682     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
3683     const GLenum discard[] = {GL_COLOR_ATTACHMENT0};
3684     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, discard);
3685     glViewport(0, 0, kLevel1Size, kLevel1Size);
3686     glScissor(0, 0, kLevel1Size, kLevel1Size);
3687     glEnable(GL_CULL_FACE);
3688     glCullFace(GL_BACK);
3689     glDisable(GL_BLEND);
3690     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3691     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
3692     glUseProgram(program);
3693     drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
3694 
3695     glDisable(GL_CULL_FACE);
3696     glDisable(GL_DEPTH_TEST);
3697     glDisable(GL_BLEND);
3698     glDisable(GL_SCISSOR_TEST);
3699     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3700 
3701     ASSERT_GL_NO_ERROR();
3702     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3703 }
3704 
3705 // Test render to a texture level that is excluded from [base_level, max_level]. This specific test
3706 // renders to an immutable texture at the level that is smaller than GL_TEXTURE_BASE_LEVEL. The
3707 // texture itself has been initialized with data before rendering. Filament is using it this way
TEST_P(FramebufferTest_ES3,RenderAndInvalidateImmutableTextureWithBellowBaseLevelLOD)3708 TEST_P(FramebufferTest_ES3, RenderAndInvalidateImmutableTextureWithBellowBaseLevelLOD)
3709 {
3710     constexpr GLuint kLevel0Size = 4;
3711     constexpr GLuint kLevel1Size = kLevel0Size / 2;
3712     std::array<GLColor, kLevel0Size * kLevel0Size> gData;
3713 
3714     GLTexture colorTexture;
3715     glBindTexture(GL_TEXTURE_2D, colorTexture);
3716     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
3717     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3718     glTexStorage2D(GL_TEXTURE_2D, 2, GL_RGBA8, kLevel0Size, kLevel0Size);
3719     // set base_level to 1
3720     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
3721     gData.fill(GLColor::blue);
3722     glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, kLevel1Size, kLevel1Size, GL_RGBA, GL_UNSIGNED_BYTE,
3723                     gData.data());
3724 
3725     // Attach level 0 to a FBO
3726     GLFramebuffer framebuffer;
3727     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
3728     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
3729     ASSERT_GL_NO_ERROR();
3730     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3731 
3732     // Render to FBO
3733     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
3734     const GLenum discard[] = {GL_COLOR_ATTACHMENT0};
3735     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, discard);
3736     glViewport(0, 0, kLevel0Size, kLevel0Size);
3737     glScissor(0, 0, kLevel0Size, kLevel0Size);
3738     glEnable(GL_CULL_FACE);
3739     glCullFace(GL_BACK);
3740     glDisable(GL_BLEND);
3741     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3742     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
3743     glUseProgram(program);
3744     drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
3745 
3746     glDisable(GL_CULL_FACE);
3747     glDisable(GL_DEPTH_TEST);
3748     glDisable(GL_BLEND);
3749     glDisable(GL_SCISSOR_TEST);
3750     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3751 
3752     ASSERT_GL_NO_ERROR();
3753     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3754 }
3755 
3756 // Test render to a texture level that is excluded from [base_level, max_level]. This specific test
3757 // renders to an immutable texture at the level that is bigger than GL_TEXTURE_MAX_LEVEL. The
3758 // texture level that we render to has been initialized with data before rendering. This test if
3759 // render to that level will get flush the level update even though it is outside [base, max]
3760 // levels.
TEST_P(FramebufferTest_ES3,RenderImmutableTextureWithSubImageWithBeyondMaxLevel)3761 TEST_P(FramebufferTest_ES3, RenderImmutableTextureWithSubImageWithBeyondMaxLevel)
3762 {
3763     // Set up program to sample from specific lod level.
3764     GLProgram textureLodProgram;
3765     textureLodProgram.makeRaster(essl3_shaders::vs::Texture2DLod(),
3766                                  essl3_shaders::fs::Texture2DLod());
3767     ASSERT(textureLodProgram.valid());
3768     glUseProgram(textureLodProgram);
3769 
3770     GLint textureLocation =
3771         glGetUniformLocation(textureLodProgram, essl3_shaders::Texture2DUniform());
3772     ASSERT_NE(-1, textureLocation);
3773     GLint lodLocation = glGetUniformLocation(textureLodProgram, essl3_shaders::LodUniform());
3774     ASSERT_NE(-1, lodLocation);
3775 
3776     constexpr GLuint kLevel0Size = 4;
3777     constexpr GLuint kLevel1Size = kLevel0Size / 2;
3778     std::array<GLColor, kLevel0Size * kLevel0Size> gData;
3779 
3780     GLTexture colorTexture;
3781     glBindTexture(GL_TEXTURE_2D, colorTexture);
3782     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
3783     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3784     glTexStorage2D(GL_TEXTURE_2D, 2, GL_RGBA8, kLevel0Size, kLevel0Size);
3785     // Initialize level 0 with blue
3786     gData.fill(GLColor::blue);
3787     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kLevel0Size, kLevel0Size, GL_RGBA, GL_UNSIGNED_BYTE,
3788                     gData.data());
3789     // set max_level to 0
3790     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
3791     // Draw with level 0
3792     glUniform1f(lodLocation, 0);
3793     drawQuad(textureLodProgram, essl3_shaders::PositionAttrib(), 0.5f);
3794     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
3795 
3796     // Initalize level 1 with green
3797     gData.fill(GLColor::green);
3798     glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, kLevel1Size, kLevel1Size, GL_RGBA, GL_UNSIGNED_BYTE,
3799                     gData.data());
3800     // Attach level 1 to a FBO
3801     GLFramebuffer framebuffer;
3802     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
3803     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 1);
3804     ASSERT_GL_NO_ERROR();
3805     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3806     // Render to FBO (i.e. level 1) with Red and blend with existing texture level data
3807     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
3808     glViewport(0, 0, kLevel1Size, kLevel1Size);
3809     glScissor(0, 0, kLevel1Size, kLevel1Size);
3810     glEnable(GL_CULL_FACE);
3811     glCullFace(GL_BACK);
3812     glEnable(GL_BLEND);
3813     glBlendFunc(GL_ONE, GL_ONE);
3814     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3815     ANGLE_GL_PROGRAM(redProgram, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
3816     glUseProgram(redProgram);
3817     drawQuad(redProgram, essl3_shaders::PositionAttrib(), 0.5f);
3818 
3819     glDisable(GL_CULL_FACE);
3820     glDisable(GL_DEPTH_TEST);
3821     glDisable(GL_BLEND);
3822     glDisable(GL_SCISSOR_TEST);
3823     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
3824 
3825     ASSERT_GL_NO_ERROR();
3826     // Expect to see Red + Green, which is Yellow
3827     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
3828 }
3829 
3830 // Similar to the other RenderImmutableTexture*** tests, but test on depth attachment instead of
3831 // color attachment. This tests render to a depth texture level that is less than
3832 // GL_TEXTURE_BASE_LEVEL and sample from it at the same time.
TEST_P(FramebufferTest_ES3,RenderSampleDepthTextureWithExcludedLevel)3833 TEST_P(FramebufferTest_ES3, RenderSampleDepthTextureWithExcludedLevel)
3834 {
3835     // Set up program to copy depth texture's value to color.red.
3836     constexpr char kVS[] = R"(precision mediump float;
3837 attribute vec4 a_position;
3838 varying vec2 v_texCoord;
3839 void main()
3840 {
3841     gl_Position = a_position;
3842     v_texCoord = a_position.xy * 0.5 + vec2(0.5);
3843 })";
3844     constexpr char kFS[] = R"(precision mediump float;
3845 varying vec2 v_texCoord;
3846 uniform sampler2D depth;
3847 void main()
3848 {
3849     gl_FragColor = vec4(texture2D(depth, v_texCoord).x, 1, 0, 1);
3850 })";
3851     ANGLE_GL_PROGRAM(program, kVS, kFS);
3852 
3853     constexpr GLuint kLevel0Size = 4;
3854     constexpr GLuint kLevel1Size = kLevel0Size / 2;
3855 
3856     GLTexture colorTexture;
3857     glBindTexture(GL_TEXTURE_2D, colorTexture);
3858     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
3859     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3860     glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, kLevel0Size, kLevel0Size);
3861 
3862     GLTexture depthTexture;
3863     glBindTexture(GL_TEXTURE_2D, depthTexture);
3864     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
3865     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3866     glTexStorage2D(GL_TEXTURE_2D, 3, GL_DEPTH_COMPONENT32F, kLevel0Size, kLevel0Size);
3867     // Initialize level 1 with known depth value
3868     std::array<GLfloat, kLevel1Size *kLevel1Size> gData = {0.2, 0.4, 0.6, 0.8};
3869     glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, kLevel1Size, kLevel1Size, GL_DEPTH_COMPONENT, GL_FLOAT,
3870                     gData.data());
3871     // set base_level and max_level to 1, exclude level 0
3872     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
3873     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
3874 
3875     // Attach level 0 to a FBO
3876     GLFramebuffer framebuffer;
3877     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
3878     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
3879     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
3880     ASSERT_GL_NO_ERROR();
3881     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3882 
3883     // Render to FBO (LOD 0) with depth texture LOD 1
3884     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
3885     glViewport(0, 0, kLevel0Size, kLevel0Size);
3886     glScissor(0, 0, kLevel0Size, kLevel0Size);
3887     glDepthMask(GL_TRUE);
3888     glEnable(GL_DEPTH_TEST);
3889     glDepthFunc(GL_ALWAYS);
3890     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
3891     ASSERT_GL_NO_ERROR();
3892     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(51u, 255u, 0, 255u), 1);
3893     EXPECT_PIXEL_COLOR_NEAR(kLevel0Size - 1, 0, GLColor(102u, 255u, 0, 255u), 1);
3894     EXPECT_PIXEL_COLOR_NEAR(0, kLevel0Size - 1, GLColor(153u, 255u, 0, 255u), 1);
3895     EXPECT_PIXEL_COLOR_NEAR(kLevel0Size - 1, kLevel0Size - 1, GLColor(204u, 255u, 0, 255u), 1);
3896 
3897     // Now check depth value is 0.5
3898     glDepthFunc(GL_LESS);
3899     glDepthMask(GL_FALSE);
3900     ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
3901     glUseProgram(blueProgram);
3902     // should fail depth test
3903     drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.51f);
3904     ASSERT_GL_NO_ERROR();
3905     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(51u, 255u, 0, 255u), 1);
3906     // should pass depth test
3907     drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.49f);
3908     ASSERT_GL_NO_ERROR();
3909     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
3910 }
3911 
3912 // Covers a bug in ANGLE's Vulkan back-end. Our VkFramebuffer cache would in some cases forget to
3913 // check the draw states when computing a cache key.
TEST_P(FramebufferTest_ES3,DisabledAttachmentRedefinition)3914 TEST_P(FramebufferTest_ES3, DisabledAttachmentRedefinition)
3915 {
3916     constexpr GLuint kSize = 2;
3917 
3918     // Make a Framebuffer with two attachments with one enabled and one disabled.
3919     GLTexture texA, texB;
3920     glBindTexture(GL_TEXTURE_2D, texA);
3921     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3922     glBindTexture(GL_TEXTURE_2D, texB);
3923     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3924 
3925     GLFramebuffer fbo;
3926     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3927     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texA, 0);
3928     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, texB, 0);
3929 
3930     // Mask out the second texture.
3931     constexpr GLenum kOneDrawBuf = GL_COLOR_ATTACHMENT0;
3932     glDrawBuffers(1, &kOneDrawBuf);
3933 
3934     ASSERT_GL_NO_ERROR();
3935     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3936 
3937     // Set up a very simple shader.
3938     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
3939     glViewport(0, 0, kSize, kSize);
3940 
3941     // Draw
3942     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f, 1.0f, true);
3943     ASSERT_GL_NO_ERROR();
3944     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3945 
3946     // Update the masked out attachment and draw again.
3947     std::vector<GLColor> redPixels(kSize * kSize, GLColor::red);
3948     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGBA, GL_UNSIGNED_BYTE,
3949                     redPixels.data());
3950 
3951     // Draw
3952     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f, 1.0f, true);
3953     ASSERT_GL_NO_ERROR();
3954     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3955 
3956     glReadBuffer(GL_COLOR_ATTACHMENT1);
3957     ASSERT_GL_NO_ERROR();
3958     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3959 }
3960 
3961 // Test that changing the attachment of a framebuffer then sync'ing both READ and DRAW framebuffer
3962 // (currently possible with glInvalidateFramebuffer) updates the scissor correctly.
TEST_P(FramebufferTest_ES3,ChangeAttachmentThenInvalidateAndDraw)3963 TEST_P(FramebufferTest_ES3, ChangeAttachmentThenInvalidateAndDraw)
3964 {
3965     constexpr GLsizei kSizeLarge = 32;
3966     constexpr GLsizei kSizeSmall = 16;
3967 
3968     GLTexture color1;
3969     glBindTexture(GL_TEXTURE_2D, color1);
3970     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kSizeSmall, kSizeSmall, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3971                  nullptr);
3972 
3973     GLTexture color2;
3974     glBindTexture(GL_TEXTURE_2D, color2);
3975     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kSizeLarge, kSizeLarge, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3976                  nullptr);
3977 
3978     GLFramebuffer fbo;
3979     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3980     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color1, 0);
3981 
3982     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
3983     glUseProgram(drawColor);
3984     GLint colorUniformLocation =
3985         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
3986     ASSERT_NE(colorUniformLocation, -1);
3987 
3988     glViewport(0, 0, kSizeLarge, kSizeLarge);
3989 
3990     // Draw red into the framebuffer.
3991     glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
3992     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
3993     ASSERT_GL_NO_ERROR();
3994 
3995     // Change the attachment, invalidate it and draw green.
3996     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color2, 0);
3997     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3998 
3999     std::array<GLenum, 1> attachments = {GL_COLOR_ATTACHMENT0};
4000     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments.data());
4001     ASSERT_GL_NO_ERROR();
4002 
4003     glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
4004     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
4005     ASSERT_GL_NO_ERROR();
4006 
4007     // Validate the result.
4008     EXPECT_PIXEL_RECT_EQ(0, 0, kSizeLarge, kSizeLarge, GLColor::green);
4009 
4010     // Do the same, but changing from the large to small attachment.
4011 
4012     // Draw red into the framebuffer.
4013     glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
4014     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
4015     ASSERT_GL_NO_ERROR();
4016 
4017     // Change the attachment, invalidate it and draw blue.
4018     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color1, 0);
4019     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4020     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments.data());
4021 
4022     glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
4023     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
4024     ASSERT_GL_NO_ERROR();
4025 
4026     // Validate the result.
4027     EXPECT_PIXEL_RECT_EQ(0, 0, kSizeSmall, kSizeSmall, GLColor::blue);
4028 }
4029 
4030 // Test Framebuffer object with two attachments that have unequal size. In OpenGLES3.0, this is
4031 // a supported config. The common intersection area should be correctly rendered. The contents
4032 // outside common intersection area are undefined.
TEST_P(FramebufferTest_ES3,AttachmentsWithUnequalDimensions)4033 TEST_P(FramebufferTest_ES3, AttachmentsWithUnequalDimensions)
4034 {
4035     ANGLE_SKIP_TEST_IF(IsD3D());
4036 
4037     constexpr GLsizei kSizeLarge = 32;
4038     constexpr GLsizei kSizeSmall = 16;
4039 
4040     GLTexture colorTexture;
4041     glBindTexture(GL_TEXTURE_2D, colorTexture);
4042     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kSizeLarge, kSizeSmall, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4043                  nullptr);
4044 
4045     GLRenderbuffer color;
4046     glBindRenderbuffer(GL_RENDERBUFFER, color);
4047     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSizeSmall, kSizeLarge);
4048 
4049     GLRenderbuffer depth;
4050     glBindRenderbuffer(GL_RENDERBUFFER, depth);
4051     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, kSizeSmall, kSizeLarge);
4052 
4053     GLRenderbuffer stencil;
4054     glBindRenderbuffer(GL_RENDERBUFFER, stencil);
4055     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSizeSmall, kSizeLarge);
4056 
4057     struct
4058     {
4059         GLenum attachment;
4060         GLuint renderbuffer;
4061     } attachment2[4] = {{GL_COLOR_ATTACHMENT1, 0},
4062                         {GL_COLOR_ATTACHMENT1, color},
4063                         {GL_DEPTH_ATTACHMENT, depth},
4064                         {GL_STENCIL_ATTACHMENT, stencil}};
4065     for (int i = 0; i < 4; i++)
4066     {
4067         GLFramebuffer fbo;
4068         glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4069         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture,
4070                                0);
4071         if (attachment2[i].renderbuffer)
4072         {
4073             glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment2[i].attachment, GL_RENDERBUFFER,
4074                                       attachment2[i].renderbuffer);
4075         }
4076         ASSERT_GL_NO_ERROR();
4077         ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4078 
4079         ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
4080         glUseProgram(drawColor);
4081         GLint colorUniformLocation =
4082             glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
4083         ASSERT_NE(colorUniformLocation, -1);
4084 
4085         glViewport(0, 0, kSizeLarge, kSizeLarge);
4086         const GLenum discard[] = {GL_COLOR_ATTACHMENT0};
4087         glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, discard);
4088 
4089         // Draw red into the framebuffer.
4090         glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
4091         drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
4092         ASSERT_GL_NO_ERROR();
4093 
4094         // Validate the result. The intersected common area should be red now
4095         EXPECT_PIXEL_RECT_EQ(0, 0, kSizeSmall, kSizeSmall, GLColor::red);
4096     }
4097 }
4098 
4099 // Validates only MESA functions can be used on OpenGL ES <3.1
TEST_P(FramebufferTest_ES3,ValidateFramebufferFlipYMesaExtension)4100 TEST_P(FramebufferTest_ES3, ValidateFramebufferFlipYMesaExtension)
4101 {
4102     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
4103 
4104     GLFramebuffer mFramebuffer;
4105     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
4106 
4107     glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
4108     ASSERT_GL_NO_ERROR();
4109 
4110     GLint flip_y = -1;
4111 
4112     glGetFramebufferParameterivMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, &flip_y);
4113     ASSERT_GL_NO_ERROR();
4114     EXPECT_EQ(flip_y, 1);
4115 
4116     glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 0);
4117     ASSERT_GL_NO_ERROR();
4118 
4119     flip_y = -1;
4120     glGetFramebufferParameterivMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, &flip_y);
4121     ASSERT_GL_NO_ERROR();
4122     EXPECT_EQ(flip_y, 0);
4123 
4124     // Using non-MESA function should fail.
4125     glFramebufferParameteri(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 0);
4126     ASSERT_GL_ERROR(GL_INVALID_OPERATION);
4127 
4128     glGetFramebufferParameteriv(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, &flip_y);
4129     ASSERT_GL_ERROR(GL_INVALID_OPERATION);
4130 }
4131 
TEST_P(FramebufferTest_ES3,FramebufferFlipYMesaExtensionIncorrectPname)4132 TEST_P(FramebufferTest_ES3, FramebufferFlipYMesaExtensionIncorrectPname)
4133 {
4134     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
4135 
4136     GLFramebuffer mFramebuffer;
4137     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer.get());
4138 
4139     glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_DEFAULT_WIDTH, 1);
4140     ASSERT_GL_ERROR(GL_INVALID_ENUM);
4141 }
4142 
4143 class FramebufferTest : public ANGLETest
4144 {};
4145 
4146 template <typename T>
FillTexture2D(GLuint texture,GLsizei width,GLsizei height,const T & onePixelData,GLint level,GLint internalFormat,GLenum format,GLenum type)4147 void FillTexture2D(GLuint texture,
4148                    GLsizei width,
4149                    GLsizei height,
4150                    const T &onePixelData,
4151                    GLint level,
4152                    GLint internalFormat,
4153                    GLenum format,
4154                    GLenum type)
4155 {
4156     std::vector<T> allPixelsData(width * height, onePixelData);
4157 
4158     glBindTexture(GL_TEXTURE_2D, texture);
4159     glTexImage2D(GL_TEXTURE_2D, level, internalFormat, width, height, 0, format, type,
4160                  allPixelsData.data());
4161     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4162     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4163     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
4164     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
4165 }
4166 
4167 // Multi-context uses of textures should not cause rendering feedback loops.
TEST_P(FramebufferTest,MultiContextNoRenderingFeedbackLoops)4168 TEST_P(FramebufferTest, MultiContextNoRenderingFeedbackLoops)
4169 {
4170     constexpr char kTextureVS[] =
4171         R"(attribute vec4 a_position;
4172 varying vec2 v_texCoord;
4173 void main() {
4174     gl_Position = a_position;
4175     v_texCoord = (a_position.xy * 0.5) + 0.5;
4176 })";
4177 
4178     constexpr char kTextureFS[] =
4179         R"(precision mediump float;
4180 varying vec2 v_texCoord;
4181 uniform sampler2D u_texture;
4182 void main() {
4183     gl_FragColor = texture2D(u_texture, v_texCoord).rgba;
4184 })";
4185 
4186     ANGLE_GL_PROGRAM(textureProgram, kTextureVS, kTextureFS);
4187 
4188     glUseProgram(textureProgram.get());
4189     GLint uniformLoc = glGetUniformLocation(textureProgram.get(), "u_texture");
4190     ASSERT_NE(-1, uniformLoc);
4191     glUniform1i(uniformLoc, 0);
4192 
4193     GLTexture texture;
4194     FillTexture2D(texture.get(), 1, 1, GLColor::red, 0, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE);
4195     glBindTexture(GL_TEXTURE_2D, texture.get());
4196     // Note that _texture_ is still bound to GL_TEXTURE_2D in this context at this point.
4197 
4198     EGLWindow *window          = getEGLWindow();
4199     EGLDisplay display         = window->getDisplay();
4200     EGLConfig config           = window->getConfig();
4201     EGLSurface surface         = window->getSurface();
4202     EGLint contextAttributes[] = {
4203         EGL_CONTEXT_MAJOR_VERSION_KHR,
4204         GetParam().majorVersion,
4205         EGL_CONTEXT_MINOR_VERSION_KHR,
4206         GetParam().minorVersion,
4207         EGL_NONE,
4208     };
4209     EGLContext context1 = eglGetCurrentContext();
4210     // Create context2, sharing resources with context1.
4211     EGLContext context2 = eglCreateContext(display, config, context1, contextAttributes);
4212     ASSERT_NE(context2, EGL_NO_CONTEXT);
4213     eglMakeCurrent(display, surface, surface, context2);
4214 
4215     constexpr char kVS[] =
4216         R"(attribute vec4 a_position;
4217 void main() {
4218     gl_Position = a_position;
4219 })";
4220 
4221     constexpr char kFS[] =
4222         R"(precision mediump float;
4223 void main() {
4224     gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
4225 })";
4226 
4227     ANGLE_GL_PROGRAM(program, kVS, kFS);
4228     glUseProgram(program.get());
4229 
4230     ASSERT_GL_NO_ERROR();
4231 
4232     // Render to the texture in context2.
4233     GLFramebuffer framebuffer;
4234     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
4235     // Texture is still a valid name in context2.
4236     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture.get(), 0);
4237     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4238     // There is no rendering feedback loop at this point.
4239 
4240     glDisable(GL_BLEND);
4241     glDisable(GL_DEPTH_TEST);
4242     ASSERT_GL_NO_ERROR();
4243 
4244     // If draw is no-op'ed, texture will not be filled appropriately.
4245     drawQuad(program.get(), "a_position", 0.5f, 1.0f, true);
4246     ASSERT_GL_NO_ERROR();
4247     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4248 
4249     // Make context1 current again.
4250     eglMakeCurrent(display, surface, surface, context1);
4251 
4252     // Render texture to screen.
4253     drawQuad(textureProgram.get(), "a_position", 0.5f, 1.0f, true);
4254     ASSERT_GL_NO_ERROR();
4255     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4256 
4257     eglDestroyContext(display, context2);
4258 }
4259 
4260 // Ensure cube-incomplete attachments cause incomplete Framebuffers.
TEST_P(FramebufferTest,IncompleteCubeMap)4261 TEST_P(FramebufferTest, IncompleteCubeMap)
4262 {
4263     constexpr GLuint kSize = 2;
4264 
4265     GLTexture srcTex;
4266     glBindTexture(GL_TEXTURE_CUBE_MAP, srcTex);
4267     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA,
4268                  GL_UNSIGNED_BYTE, nullptr);
4269 
4270     GLFramebuffer fbo;
4271     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4272     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X,
4273                            srcTex, 0);
4274 
4275     ASSERT_GL_NO_ERROR();
4276     ASSERT_GLENUM_EQ(glCheckFramebufferStatus(GL_FRAMEBUFFER),
4277                      GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
4278 }
4279 
4280 // Test FBOs with different sizes are drawn correctly
TEST_P(FramebufferTest,BindAndDrawDifferentSizedFBOs)4281 TEST_P(FramebufferTest, BindAndDrawDifferentSizedFBOs)
4282 {
4283     // 1. Create FBO 1 with dimensions 16x16
4284     // 2. Draw red into FBO 1 (note, FramebufferVk::syncState is called)
4285     // 3. Create FBO 2 with dimensions 8x8
4286     // 4. Draw green into FBO 2 (note, FramebufferVk::syncState is called)
4287     // 5. Bind FBO 1 (note, it's not dirty)
4288     // 6. Draw blue into FBO 1
4289     // 7. Verify FBO 1 is entirely blue
4290 
4291     GLFramebuffer smallFbo;
4292     GLFramebuffer largeFbo;
4293     GLTexture smallTexture;
4294     GLTexture largeTexture;
4295     constexpr GLsizei kLargeWidth  = 16;
4296     constexpr GLsizei kLargeHeight = 16;
4297     constexpr GLsizei kSmallWidth  = 8;
4298     constexpr GLsizei kSmallHeight = 8;
4299 
4300     ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
4301     ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
4302     ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
4303 
4304     // 1. Create FBO 1 with dimensions 16x16
4305     glBindFramebuffer(GL_FRAMEBUFFER, largeFbo);
4306     glBindTexture(GL_TEXTURE_2D, largeTexture);
4307     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kLargeWidth, kLargeHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4308                  nullptr);
4309     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4310     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4311     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, largeTexture, 0);
4312     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4313 
4314     // 2. Draw red into FBO 1 (note, FramebufferVk::syncState is called)
4315     glUseProgram(redProgram);
4316     drawQuad(redProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
4317     ASSERT_GL_NO_ERROR();
4318 
4319     // 3. Create FBO 2 with dimensions 8x8
4320     glBindFramebuffer(GL_FRAMEBUFFER, smallFbo);
4321     glBindTexture(GL_TEXTURE_2D, smallTexture);
4322     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSmallWidth, kSmallHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4323                  nullptr);
4324     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4325     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4326     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, smallTexture, 0);
4327     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4328 
4329     // 4. Draw green into FBO 2 (note, FramebufferVk::syncState is called)
4330     glUseProgram(greenProgram);
4331     drawQuad(greenProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
4332     ASSERT_GL_NO_ERROR();
4333 
4334     // 5. Bind FBO 1 (note, it's not dirty)
4335     glBindFramebuffer(GL_FRAMEBUFFER, largeFbo);
4336 
4337     // 6. Draw blue into FBO 1
4338     glUseProgram(blueProgram);
4339     drawQuad(blueProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
4340     ASSERT_GL_NO_ERROR();
4341 
4342     // 7. Verify FBO 1 is entirely blue
4343     EXPECT_PIXEL_RECT_EQ(0, 0, kLargeWidth, kLargeHeight, GLColor::blue);
4344 }
4345 
4346 // Regression test based on a fuzzer failure.  A crash was encountered in the following situation:
4347 //
4348 // - Texture bound as sampler with MAX_LEVEL 0
4349 // - Framebuffer bound to level 0
4350 // - Draw
4351 // - Texture MAX_LEVEL changed to 1
4352 // - Framebuffer bound to level 1
4353 // - Draw
4354 //
4355 // Notes: Removing the first half removed the crash.  MIN_FILTERING of LINEAR vs
4356 // LINEAR_MIPMAP_LINEAR did not make any changes.
TEST_P(FramebufferTest_ES3,FramebufferBindToNewLevelAfterMaxIncreaseShouldntCrash)4357 TEST_P(FramebufferTest_ES3, FramebufferBindToNewLevelAfterMaxIncreaseShouldntCrash)
4358 {
4359     constexpr char kFS[] = R"(precision mediump float;
4360 uniform sampler2D u_tex0;
4361 void main() {
4362     gl_FragColor = texture2D(u_tex0, vec2(0));
4363 })";
4364 
4365     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), kFS);
4366     glUseProgram(program);
4367 
4368     GLTexture mutTex;
4369     glBindTexture(GL_TEXTURE_2D, mutTex);
4370     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 10, 10, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4371     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 5, 5, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4372 
4373     GLFramebuffer fb;
4374     glBindFramebuffer(GL_FRAMEBUFFER, fb);
4375 
4376     // Attempt a draw with level 0 (feedback loop)
4377     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
4378     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4379 
4380     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mutTex, 0);
4381     glDrawArrays(GL_POINTS, 0, 1);
4382 
4383     // Attempt another draw with level 1.
4384     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
4385 
4386     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mutTex, 1);
4387 
4388     // This shouldn't crash.
4389     glDrawArrays(GL_POINTS, 0, 1);
4390     ASSERT_GL_NO_ERROR();
4391 }
4392 
4393 // Modify renderbuffer attachment samples after bind
TEST_P(FramebufferTest_ES3,BindRenderbufferThenModifySamples)4394 TEST_P(FramebufferTest_ES3, BindRenderbufferThenModifySamples)
4395 {
4396     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
4397     glUseProgram(program);
4398     GLint colorUniformLocation =
4399         glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
4400     ASSERT_NE(colorUniformLocation, -1);
4401 
4402     GLFramebuffer fbo;
4403     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4404 
4405     GLsizei size = 16;
4406     glViewport(0, 0, size, size);
4407 
4408     GLRenderbuffer color;
4409     glBindRenderbuffer(GL_RENDERBUFFER, color);
4410 
4411     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, size, size);
4412     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color);
4413     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, size, size);
4414 
4415     glUniform4f(colorUniformLocation, 1, 0, 0, 1);
4416     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
4417 
4418     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
4419     ASSERT_GL_NO_ERROR();
4420 }
4421 
4422 // Modify renderbuffer attachment size after bind
TEST_P(FramebufferTest_ES3,BindRenderbufferThenModifySize)4423 TEST_P(FramebufferTest_ES3, BindRenderbufferThenModifySize)
4424 {
4425     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
4426     glUseProgram(program);
4427     GLint colorUniformLocation =
4428         glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
4429     ASSERT_NE(colorUniformLocation, -1);
4430 
4431     GLFramebuffer fbo;
4432     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4433 
4434     GLsizei size = 16;
4435     glViewport(0, 0, size, size);
4436 
4437     GLRenderbuffer color;
4438     glBindRenderbuffer(GL_RENDERBUFFER, color);
4439 
4440     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, size, size);
4441     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, color);
4442     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, size / 2, size * 2);
4443 
4444     glUniform4f(colorUniformLocation, 1, 0, 0, 1);
4445     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
4446 
4447     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
4448     ASSERT_GL_NO_ERROR();
4449 }
4450 
4451 // Tests redefining a layered framebuffer attachment.
TEST_P(FramebufferTest_ES3,RedefineLayerAttachment)4452 TEST_P(FramebufferTest_ES3, RedefineLayerAttachment)
4453 {
4454     GLTexture texture;
4455     glBindTexture(GL_TEXTURE_3D, texture);
4456     std::vector<uint8_t> imgData(20480, 0);
4457     glTexImage3D(GL_TEXTURE_3D, 0, GL_R8, 8, 8, 8, 0, GL_RED, GL_UNSIGNED_BYTE, imgData.data());
4458 
4459     GLFramebuffer fbo;
4460     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4461     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0, 8);
4462     glGenerateMipmap(GL_TEXTURE_3D);
4463 
4464     glTexImage3D(GL_TEXTURE_3D, 0, GL_R8UI, 16, 16, 16, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE,
4465                  imgData.data());
4466     glCopyTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 2, 2, 15, 16, 16);
4467     ASSERT_GL_NO_ERROR();
4468 }
4469 
4470 // Covers a bug when changing a base level of a texture bound to a FBO.
TEST_P(FramebufferTest_ES3,ReattachToInvalidBaseLevel)4471 TEST_P(FramebufferTest_ES3, ReattachToInvalidBaseLevel)
4472 {
4473     ANGLE_GL_PROGRAM(testProgram, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
4474     glUseProgram(testProgram);
4475 
4476     GLTexture tex;
4477     glBindTexture(GL_TEXTURE_2D, tex);
4478     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4479 
4480     for (int mip = 0; mip <= 2; ++mip)
4481     {
4482         int size = 10 >> mip;
4483         glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA8, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4484                      nullptr);
4485     }
4486 
4487     GLFramebuffer fb;
4488     glBindFramebuffer(GL_FRAMEBUFFER, fb);
4489     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 1);
4490     EXPECT_GL_NO_ERROR();
4491 
4492     // Set base level 1 and draw.
4493     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
4494     glDrawArrays(GL_POINTS, 0, 1);
4495     EXPECT_GL_NO_ERROR();
4496     // Set base level 0. The FBO is incomplete because the FBO attachment binds to level 1.
4497     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
4498     glDrawArrays(GL_POINTS, 0, 1);
4499     EXPECT_GL_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION);
4500 }
4501 
4502 // Ensure that clear color is correctly applied after invalidate
TEST_P(FramebufferTest_ES3,InvalidateClearDraw)4503 TEST_P(FramebufferTest_ES3, InvalidateClearDraw)
4504 {
4505     constexpr GLsizei kSize = 2;
4506 
4507     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
4508 
4509     GLTexture tex;
4510     glBindTexture(GL_TEXTURE_2D, tex);
4511     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
4512 
4513     GLFramebuffer fbo;
4514     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4515     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
4516 
4517     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4518 
4519     // Clear the image, and make sure the clear is flushed outside the render pass.
4520     glClearColor(1, 0, 0, 1);
4521     glClear(GL_COLOR_BUFFER_BIT);
4522     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
4523 
4524     // Invalidate it such that the contents are marked as undefined. Note that
4525     // regardless of the marking, the image is cleared nevertheless.
4526     const GLenum discards[] = {GL_COLOR_ATTACHMENT0};
4527     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, discards);
4528 
4529     // Clear it again to the same color, and make sure the clear is flushed outside the render pass,
4530     // which may be optimized out.
4531     glClear(GL_COLOR_BUFFER_BIT);
4532     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
4533 
4534     // Draw with blend.  If the second clear is dropped and the image continues to be marked as
4535     // invalidated, loadOp=DONT_CARE would be used instead of loadOp=LOAD.
4536     glEnable(GL_BLEND);
4537     glBlendFunc(GL_ONE, GL_ONE);
4538 
4539     drawQuad(program, essl1_shaders::PositionAttrib(), 0);
4540     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);
4541 }
4542 
4543 ANGLE_INSTANTIATE_TEST_ES2_AND(AddMockTextureNoRenderTargetTest,
4544                                ES2_D3D9().enable(Feature::AddMockTextureNoRenderTarget),
4545                                ES2_D3D11().enable(Feature::AddMockTextureNoRenderTarget));
4546 
4547 ANGLE_INSTANTIATE_TEST_ES2(FramebufferTest);
4548 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(FramebufferFormatsTest);
4549 
4550 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FramebufferTest_ES3);
4551 ANGLE_INSTANTIATE_TEST_ES3_AND(FramebufferTest_ES3,
4552                                ES3_VULKAN().enable(Feature::EmulatedPrerotation90),
4553                                ES3_VULKAN().enable(Feature::EmulatedPrerotation180),
4554                                ES3_VULKAN().enable(Feature::EmulatedPrerotation270));
4555 
4556 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FramebufferTest_ES31);
4557 ANGLE_INSTANTIATE_TEST_ES31(FramebufferTest_ES31);
4558 ANGLE_INSTANTIATE_TEST_ES3(FramebufferTestWithFormatFallback);
4559