• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 #include "test_utils/ANGLETest.h"
8 #include "test_utils/gl_raii.h"
9 
10 using namespace angle;
11 
12 namespace
13 {
14 class BlitFramebufferANGLETest : public ANGLETest<>
15 {
16   protected:
BlitFramebufferANGLETest()17     BlitFramebufferANGLETest()
18     {
19         setWindowWidth(64);
20         setWindowHeight(32);
21         setConfigRedBits(8);
22         setConfigGreenBits(8);
23         setConfigBlueBits(8);
24         setConfigAlphaBits(8);
25         setConfigDepthBits(24);
26         setConfigStencilBits(8);
27 
28         mCheckerProgram = 0;
29         mBlueProgram    = 0;
30         mRedProgram     = 0;
31 
32         mOriginalFBO = 0;
33 
34         mUserFBO                = 0;
35         mUserColorBuffer        = 0;
36         mUserDepthStencilBuffer = 0;
37 
38         mSmallFBO                = 0;
39         mSmallColorBuffer        = 0;
40         mSmallDepthStencilBuffer = 0;
41 
42         mColorOnlyFBO         = 0;
43         mColorOnlyColorBuffer = 0;
44 
45         mDiffFormatFBO         = 0;
46         mDiffFormatColorBuffer = 0;
47 
48         mDiffSizeFBO         = 0;
49         mDiffSizeColorBuffer = 0;
50 
51         mMRTFBO          = 0;
52         mMRTColorBuffer0 = 0;
53         mMRTColorBuffer1 = 0;
54 
55         mRGBAColorbuffer              = 0;
56         mRGBAFBO                      = 0;
57         mRGBAMultisampledRenderbuffer = 0;
58         mRGBAMultisampledFBO          = 0;
59 
60         mBGRAColorbuffer              = 0;
61         mBGRAFBO                      = 0;
62         mBGRAMultisampledRenderbuffer = 0;
63         mBGRAMultisampledFBO          = 0;
64     }
65 
testSetUp()66     void testSetUp() override
67     {
68         mCheckerProgram =
69             CompileProgram(essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Checkered());
70         mBlueProgram = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
71         mRedProgram  = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
72         if (mCheckerProgram == 0 || mBlueProgram == 0 || mRedProgram == 0)
73         {
74             FAIL() << "shader compilation failed.";
75         }
76 
77         EXPECT_GL_NO_ERROR();
78 
79         GLint originalFBO;
80         glGetIntegerv(GL_FRAMEBUFFER_BINDING, &originalFBO);
81         if (originalFBO >= 0)
82         {
83             mOriginalFBO = (GLuint)originalFBO;
84         }
85 
86         GLenum format = GL_RGBA;
87 
88         glGenFramebuffers(1, &mUserFBO);
89         glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
90         glGenTextures(1, &mUserColorBuffer);
91         glGenRenderbuffers(1, &mUserDepthStencilBuffer);
92         glBindTexture(GL_TEXTURE_2D, mUserColorBuffer);
93         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
94                                mUserColorBuffer, 0);
95         glTexImage2D(GL_TEXTURE_2D, 0, format, getWindowWidth(), getWindowHeight(), 0, format,
96                      GL_UNSIGNED_BYTE, nullptr);
97         glBindRenderbuffer(GL_RENDERBUFFER, mUserDepthStencilBuffer);
98         glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, getWindowWidth(),
99                               getWindowHeight());
100         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
101                                   mUserDepthStencilBuffer);
102         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
103                                   mUserDepthStencilBuffer);
104 
105         ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
106         ASSERT_GL_NO_ERROR();
107 
108         glGenFramebuffers(1, &mSmallFBO);
109         glBindFramebuffer(GL_FRAMEBUFFER, mSmallFBO);
110         glGenTextures(1, &mSmallColorBuffer);
111         glGenRenderbuffers(1, &mSmallDepthStencilBuffer);
112         glBindTexture(GL_TEXTURE_2D, mSmallColorBuffer);
113         glTexImage2D(GL_TEXTURE_2D, 0, format, getWindowWidth() / 2, getWindowHeight() / 2, 0,
114                      format, GL_UNSIGNED_BYTE, nullptr);
115         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
116                                mSmallColorBuffer, 0);
117         glBindRenderbuffer(GL_RENDERBUFFER, mSmallDepthStencilBuffer);
118         glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, getWindowWidth() / 2,
119                               getWindowHeight() / 2);
120         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
121                                   mSmallDepthStencilBuffer);
122         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
123                                   mSmallDepthStencilBuffer);
124 
125         ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
126         ASSERT_GL_NO_ERROR();
127 
128         glGenFramebuffers(1, &mColorOnlyFBO);
129         glBindFramebuffer(GL_FRAMEBUFFER, mColorOnlyFBO);
130         glGenTextures(1, &mColorOnlyColorBuffer);
131         glBindTexture(GL_TEXTURE_2D, mColorOnlyColorBuffer);
132         glTexImage2D(GL_TEXTURE_2D, 0, format, getWindowWidth(), getWindowHeight(), 0, format,
133                      GL_UNSIGNED_BYTE, nullptr);
134         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
135                                mColorOnlyColorBuffer, 0);
136 
137         ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
138         ASSERT_GL_NO_ERROR();
139 
140         glGenFramebuffers(1, &mDiffFormatFBO);
141         glBindFramebuffer(GL_FRAMEBUFFER, mDiffFormatFBO);
142         glGenTextures(1, &mDiffFormatColorBuffer);
143         glBindTexture(GL_TEXTURE_2D, mDiffFormatColorBuffer);
144         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, getWindowWidth(), getWindowHeight(), 0, GL_RGB,
145                      GL_UNSIGNED_SHORT_5_6_5, nullptr);
146         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
147                                mDiffFormatColorBuffer, 0);
148 
149         ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
150         ASSERT_GL_NO_ERROR();
151 
152         glGenFramebuffers(1, &mDiffSizeFBO);
153         glBindFramebuffer(GL_FRAMEBUFFER, mDiffSizeFBO);
154         glGenTextures(1, &mDiffSizeColorBuffer);
155         glBindTexture(GL_TEXTURE_2D, mDiffSizeColorBuffer);
156         glTexImage2D(GL_TEXTURE_2D, 0, format, getWindowWidth() * 2, getWindowHeight() * 2, 0,
157                      format, GL_UNSIGNED_BYTE, nullptr);
158         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
159                                mDiffSizeColorBuffer, 0);
160 
161         ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
162         ASSERT_GL_NO_ERROR();
163 
164         if (IsGLExtensionEnabled("GL_EXT_draw_buffers"))
165         {
166             glGenFramebuffers(1, &mMRTFBO);
167             glBindFramebuffer(GL_FRAMEBUFFER, mMRTFBO);
168             glGenTextures(1, &mMRTColorBuffer0);
169             glGenTextures(1, &mMRTColorBuffer1);
170             glBindTexture(GL_TEXTURE_2D, mMRTColorBuffer0);
171             glTexImage2D(GL_TEXTURE_2D, 0, format, getWindowWidth(), getWindowHeight(), 0, format,
172                          GL_UNSIGNED_BYTE, nullptr);
173             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D,
174                                    mMRTColorBuffer0, 0);
175             glBindTexture(GL_TEXTURE_2D, mMRTColorBuffer1);
176             glTexImage2D(GL_TEXTURE_2D, 0, format, getWindowWidth(), getWindowHeight(), 0, format,
177                          GL_UNSIGNED_BYTE, nullptr);
178             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D,
179                                    mMRTColorBuffer1, 0);
180 
181             ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
182             ASSERT_GL_NO_ERROR();
183         }
184 
185         if (IsGLExtensionEnabled("GL_ANGLE_framebuffer_multisample") &&
186             IsGLExtensionEnabled("GL_OES_rgb8_rgba8"))
187         {
188             // RGBA single-sampled framebuffer
189             glGenTextures(1, &mRGBAColorbuffer);
190             glBindTexture(GL_TEXTURE_2D, mRGBAColorbuffer);
191             glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
192                          GL_UNSIGNED_BYTE, nullptr);
193 
194             glGenFramebuffers(1, &mRGBAFBO);
195             glBindFramebuffer(GL_FRAMEBUFFER, mRGBAFBO);
196             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
197                                    mRGBAColorbuffer, 0);
198 
199             ASSERT_GL_NO_ERROR();
200             ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
201 
202             // RGBA multisampled framebuffer
203             glGenRenderbuffers(1, &mRGBAMultisampledRenderbuffer);
204             glBindRenderbuffer(GL_RENDERBUFFER, mRGBAMultisampledRenderbuffer);
205             glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 1, GL_RGBA8, getWindowWidth(),
206                                                   getWindowHeight());
207 
208             glGenFramebuffers(1, &mRGBAMultisampledFBO);
209             glBindFramebuffer(GL_FRAMEBUFFER, mRGBAMultisampledFBO);
210             glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
211                                       mRGBAMultisampledRenderbuffer);
212 
213             ASSERT_GL_NO_ERROR();
214             ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
215 
216             if (IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"))
217             {
218                 // BGRA single-sampled framebuffer
219                 glGenTextures(1, &mBGRAColorbuffer);
220                 glBindTexture(GL_TEXTURE_2D, mBGRAColorbuffer);
221                 glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, getWindowWidth(), getWindowHeight(), 0,
222                              GL_BGRA_EXT, GL_UNSIGNED_BYTE, nullptr);
223 
224                 glGenFramebuffers(1, &mBGRAFBO);
225                 glBindFramebuffer(GL_FRAMEBUFFER, mBGRAFBO);
226                 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
227                                        mBGRAColorbuffer, 0);
228 
229                 ASSERT_GL_NO_ERROR();
230                 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
231 
232                 // BGRA multisampled framebuffer
233                 glGenRenderbuffers(1, &mBGRAMultisampledRenderbuffer);
234                 glBindRenderbuffer(GL_RENDERBUFFER, mBGRAMultisampledRenderbuffer);
235                 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 1, GL_BGRA8_EXT,
236                                                       getWindowWidth(), getWindowHeight());
237 
238                 glGenFramebuffers(1, &mBGRAMultisampledFBO);
239                 glBindFramebuffer(GL_FRAMEBUFFER, mBGRAMultisampledFBO);
240                 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
241                                           mBGRAMultisampledRenderbuffer);
242 
243                 ASSERT_GL_NO_ERROR();
244                 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
245             }
246         }
247 
248         glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
249     }
250 
testTearDown()251     void testTearDown() override
252     {
253         glDeleteProgram(mCheckerProgram);
254         glDeleteProgram(mBlueProgram);
255         glDeleteProgram(mRedProgram);
256 
257         glDeleteFramebuffers(1, &mUserFBO);
258         glDeleteTextures(1, &mUserColorBuffer);
259         glDeleteRenderbuffers(1, &mUserDepthStencilBuffer);
260 
261         glDeleteFramebuffers(1, &mSmallFBO);
262         glDeleteTextures(1, &mSmallColorBuffer);
263         glDeleteRenderbuffers(1, &mSmallDepthStencilBuffer);
264 
265         glDeleteFramebuffers(1, &mColorOnlyFBO);
266         glDeleteTextures(1, &mSmallDepthStencilBuffer);
267 
268         glDeleteFramebuffers(1, &mDiffFormatFBO);
269         glDeleteTextures(1, &mDiffFormatColorBuffer);
270 
271         glDeleteFramebuffers(1, &mDiffSizeFBO);
272         glDeleteTextures(1, &mDiffSizeColorBuffer);
273 
274         if (IsGLExtensionEnabled("GL_EXT_draw_buffers"))
275         {
276             glDeleteFramebuffers(1, &mMRTFBO);
277             glDeleteTextures(1, &mMRTColorBuffer0);
278             glDeleteTextures(1, &mMRTColorBuffer1);
279         }
280 
281         if (mRGBAColorbuffer != 0)
282         {
283             glDeleteTextures(1, &mRGBAColorbuffer);
284         }
285 
286         if (mRGBAFBO != 0)
287         {
288             glDeleteFramebuffers(1, &mRGBAFBO);
289         }
290 
291         if (mRGBAMultisampledRenderbuffer != 0)
292         {
293             glDeleteRenderbuffers(1, &mRGBAMultisampledRenderbuffer);
294         }
295 
296         if (mRGBAMultisampledFBO != 0)
297         {
298             glDeleteFramebuffers(1, &mRGBAMultisampledFBO);
299         }
300 
301         if (mBGRAColorbuffer != 0)
302         {
303             glDeleteTextures(1, &mBGRAColorbuffer);
304         }
305 
306         if (mBGRAFBO != 0)
307         {
308             glDeleteFramebuffers(1, &mBGRAFBO);
309         }
310 
311         if (mBGRAMultisampledRenderbuffer != 0)
312         {
313             glDeleteRenderbuffers(1, &mBGRAMultisampledRenderbuffer);
314         }
315 
316         if (mBGRAMultisampledFBO != 0)
317         {
318             glDeleteFramebuffers(1, &mBGRAMultisampledFBO);
319         }
320     }
321 
multisampleTestHelper(GLuint readFramebuffer,GLuint drawFramebuffer)322     void multisampleTestHelper(GLuint readFramebuffer, GLuint drawFramebuffer)
323     {
324         glClearColor(0.0, 1.0, 0.0, 1.0);
325         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, readFramebuffer);
326         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
327         EXPECT_GL_NO_ERROR();
328 
329         glBindFramebuffer(GL_READ_FRAMEBUFFER, readFramebuffer);
330         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFramebuffer);
331         glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
332                                getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
333         EXPECT_GL_NO_ERROR();
334 
335         glBindFramebuffer(GL_READ_FRAMEBUFFER, drawFramebuffer);
336         EXPECT_PIXEL_EQ(getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255);
337         EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255);
338         EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255);
339         EXPECT_PIXEL_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255);
340     }
341 
checkExtension(const std::string & extension)342     bool checkExtension(const std::string &extension)
343     {
344         if (!IsGLExtensionEnabled(extension))
345         {
346             std::cout << "Test skipped because " << extension << " not supported." << std::endl;
347             return false;
348         }
349 
350         return true;
351     }
352 
BlitStencilTestHelper(bool mesaYFlip)353     void BlitStencilTestHelper(bool mesaYFlip)
354     {
355         glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
356 
357         if (mesaYFlip)
358         {
359             ASSERT_TRUE(IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
360             glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
361         }
362 
363         glClearColor(0.0, 1.0, 0.0, 1.0);
364         glClearStencil(0x0);
365         glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
366 
367         // Scissor half the screen so we fill the stencil only halfway
368         glScissor(0, 0, getWindowWidth(), getWindowHeight() / 2);
369         glEnable(GL_SCISSOR_TEST);
370 
371         // fill the stencil buffer with 0x1
372         glStencilFunc(GL_ALWAYS, 0x1, 0xFF);
373         glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
374         glEnable(GL_STENCIL_TEST);
375         drawQuad(mRedProgram, essl1_shaders::PositionAttrib(), 0.3f);
376 
377         glDisable(GL_SCISSOR_TEST);
378 
379         glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
380         glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
381 
382         // These clears are not useful in theory because we're copying over them, but its
383         // helpful in debugging if we see white in any result.
384         glClearColor(1.0, 1.0, 1.0, 1.0);
385         glClearStencil(0x0);
386         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
387 
388         glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
389                                getWindowHeight(), GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
390                                GL_NEAREST);
391 
392         EXPECT_GL_NO_ERROR();
393 
394         glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
395 
396         EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
397         EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);
398         EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
399         EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);
400 
401         glStencilFunc(GL_EQUAL, 0x1, 0xFF);  // only pass if stencil buffer at pixel reads 0x1
402 
403         drawQuad(mBlueProgram, essl1_shaders::PositionAttrib(),
404                  0.8f);  // blue quad will draw if stencil buffer was copied
405 
406         glDisable(GL_STENCIL_TEST);
407 
408         EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
409         EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);
410         EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
411         EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);
412     }
413 
414     GLuint mCheckerProgram;
415     GLuint mBlueProgram;
416     GLuint mRedProgram;
417 
418     GLuint mOriginalFBO;
419 
420     GLuint mUserFBO;
421     GLuint mUserColorBuffer;
422     GLuint mUserDepthStencilBuffer;
423 
424     GLuint mSmallFBO;
425     GLuint mSmallColorBuffer;
426     GLuint mSmallDepthStencilBuffer;
427 
428     GLuint mColorOnlyFBO;
429     GLuint mColorOnlyColorBuffer;
430 
431     GLuint mDiffFormatFBO;
432     GLuint mDiffFormatColorBuffer;
433 
434     GLuint mDiffSizeFBO;
435     GLuint mDiffSizeColorBuffer;
436 
437     GLuint mMRTFBO;
438     GLuint mMRTColorBuffer0;
439     GLuint mMRTColorBuffer1;
440 
441     GLuint mRGBAColorbuffer;
442     GLuint mRGBAFBO;
443     GLuint mRGBAMultisampledRenderbuffer;
444     GLuint mRGBAMultisampledFBO;
445 
446     GLuint mBGRAColorbuffer;
447     GLuint mBGRAFBO;
448     GLuint mBGRAMultisampledRenderbuffer;
449     GLuint mBGRAMultisampledFBO;
450 };
451 
452 // Draw to user-created framebuffer, blit whole-buffer color to original framebuffer.
TEST_P(BlitFramebufferANGLETest,BlitColorToDefault)453 TEST_P(BlitFramebufferANGLETest, BlitColorToDefault)
454 {
455     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
456 
457     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
458 
459     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
460 
461     drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);
462 
463     EXPECT_GL_NO_ERROR();
464 
465     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
466     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
467 
468     glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
469                            getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
470 
471     EXPECT_GL_NO_ERROR();
472 
473     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
474 
475     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
476     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);
477     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
478     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);
479 }
480 
481 // Blit color to/from default framebuffer with Flip-X/Flip-Y.
TEST_P(BlitFramebufferANGLETest,BlitColorWithFlip)482 TEST_P(BlitFramebufferANGLETest, BlitColorWithFlip)
483 {
484     // OpenGL ES 3.0 / GL_NV_framebuffer_blit required for flip.
485     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
486                        !IsGLExtensionEnabled("GL_NV_framebuffer_blit"));
487 
488     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
489 
490     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
491 
492     drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);
493 
494     EXPECT_GL_NO_ERROR();
495 
496     // Blit to default with x-flip.
497     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
498     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
499 
500     glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), getWindowWidth(), 0, 0,
501                       getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
502 
503     EXPECT_GL_NO_ERROR();
504 
505     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
506 
507     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
508     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);
509     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
510     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);
511 
512     // Blit to default with y-flip.
513     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
514     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
515 
516     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
517     glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), 0, getWindowHeight(),
518                       getWindowWidth(), 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
519 
520     EXPECT_GL_NO_ERROR();
521 
522     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
523 
524     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::green);
525     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::red);
526     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::yellow);
527     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::blue);
528 
529     // Blit from default with x-flip.
530 
531     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO);
532     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO);
533 
534     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
535     glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), getWindowWidth(), 0, 0,
536                       getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
537 
538     EXPECT_GL_NO_ERROR();
539 
540     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
541 
542     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::yellow);
543     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::blue);
544     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::green);
545     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::red);
546 
547     // Blit from default with y-flip.
548     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO);
549     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO);
550 
551     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
552     glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), 0, getWindowHeight(),
553                       getWindowWidth(), 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
554 
555     EXPECT_GL_NO_ERROR();
556 
557     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
558 
559     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
560     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);
561     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
562     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);
563 }
564 
565 // Blit color to default framebuffer from another framebuffer with GL_MESA_framebuffer_flip_y.
TEST_P(BlitFramebufferANGLETest,BlitColorWithMesaYFlipSrc)566 TEST_P(BlitFramebufferANGLETest, BlitColorWithMesaYFlipSrc)
567 {
568     // OpenGL ES 3.0 / GL_NV_framebuffer_blit required for flip.
569     ANGLE_SKIP_TEST_IF(
570         (getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_NV_framebuffer_blit")) ||
571         !IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
572 
573     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
574 
575     glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
576 
577     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
578 
579     EXPECT_GL_NO_ERROR();
580 
581     drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);
582 
583     EXPECT_GL_NO_ERROR();
584 
585     // Blit to default from y-flipped.
586     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
587     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
588 
589     const int fboTargetWidth  = getWindowHeight() / 2;
590     const int fboTargetHeight = getWindowHeight() / 2;
591 
592     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
593     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
594 
595     glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, fboTargetWidth,
596                       fboTargetHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
597 
598     EXPECT_GL_NO_ERROR();
599 
600     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
601 
602     EXPECT_PIXEL_COLOR_EQ(fboTargetWidth / 4, fboTargetHeight / 4, GLColor::red);
603     EXPECT_PIXEL_COLOR_EQ(fboTargetWidth / 4, 3 * fboTargetHeight / 4, GLColor::green);
604     EXPECT_PIXEL_COLOR_EQ(3 * fboTargetWidth / 4, fboTargetHeight / 4, GLColor::blue);
605     EXPECT_PIXEL_COLOR_EQ(3 * fboTargetWidth / 4, 3 * fboTargetHeight / 4, GLColor::yellow);
606 }
607 
608 // Blit color to y-flipped with GL_MESA_framebuffer_flip_y framebuffer from normal framebuffer.
TEST_P(BlitFramebufferANGLETest,BlitColorWithMesaYFlipDst)609 TEST_P(BlitFramebufferANGLETest, BlitColorWithMesaYFlipDst)
610 {
611     // OpenGL ES 3.0 / GL_NV_framebuffer_blit required for flip.
612     ANGLE_SKIP_TEST_IF(
613         (getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_NV_framebuffer_blit")) ||
614         !IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
615 
616     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
617 
618     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
619 
620     drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);
621 
622     EXPECT_GL_NO_ERROR();
623 
624     // Blit to default from y-flipped.
625     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO);
626     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO);
627 
628     glFramebufferParameteriMESA(GL_DRAW_FRAMEBUFFER_ANGLE, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
629 
630     const int fboTargetWidth  = getWindowWidth() / 2;
631     const int fboTargetHeight = getWindowHeight();
632 
633     glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
634     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
635 
636     glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, fboTargetWidth,
637                       fboTargetHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
638     glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), getWindowWidth() / 2, 0,
639                       getWindowWidth(), getWindowHeight() / 2, GL_COLOR_BUFFER_BIT, GL_NEAREST);
640 
641     glFramebufferParameteriMESA(GL_DRAW_FRAMEBUFFER_ANGLE, GL_FRAMEBUFFER_FLIP_Y_MESA, 0);
642 
643     EXPECT_GL_NO_ERROR();
644 
645     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
646 
647     // Left side have inverted checker pattern.
648     EXPECT_PIXEL_COLOR_EQ(fboTargetWidth / 4, fboTargetHeight / 4, GLColor::green);
649     EXPECT_PIXEL_COLOR_EQ(fboTargetWidth / 4, 3 * fboTargetHeight / 4, GLColor::red);
650     EXPECT_PIXEL_COLOR_EQ(3 * fboTargetWidth / 4, fboTargetHeight / 4, GLColor::yellow);
651     EXPECT_PIXEL_COLOR_EQ(3 * fboTargetWidth / 4, 3 * fboTargetHeight / 4, GLColor::blue);
652 
653     // Right side is split to 2 parts where upper part have non y-flipped checker pattern and the
654     // bottom one has white color.
655     EXPECT_PIXEL_COLOR_EQ(5 * getWindowWidth() / 8, 5 * getWindowHeight() / 8, GLColor::green);
656     EXPECT_PIXEL_COLOR_EQ(5 * getWindowWidth() / 8, 7 * getWindowHeight() / 8, GLColor::red);
657     EXPECT_PIXEL_COLOR_EQ(7 * getWindowWidth() / 8, 5 * getWindowHeight() / 8, GLColor::yellow);
658     EXPECT_PIXEL_COLOR_EQ(7 * getWindowWidth() / 8, 7 * getWindowHeight() / 8, GLColor::blue);
659 
660     EXPECT_PIXEL_RECT_EQ(4 * getWindowWidth() / 8, 0, getWindowWidth() / 4, getWindowHeight() / 2,
661                          GLColor::white);
662 }
663 
664 // Blit color to/from y-flipped with GL_MESA_framebuffer_flip_y framebuffers where dst framebuffer
665 // have different size.
TEST_P(BlitFramebufferANGLETest,BlitColorWithMesaYFlipSrcDst)666 TEST_P(BlitFramebufferANGLETest, BlitColorWithMesaYFlipSrcDst)
667 {
668     // OpenGL ES 3.0 / GL_NV_framebuffer_blit required for flip.
669     ANGLE_SKIP_TEST_IF(
670         (getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_NV_framebuffer_blit")) ||
671         !IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
672 
673     // Create a custom framebuffer as the default one cannot be flipped.
674     GLTexture tex0;
675     glBindTexture(GL_TEXTURE_2D, tex0);
676     const int fb0Width  = getWindowWidth() / 2;
677     const int fb0Height = getWindowHeight() / 2;
678     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, fb0Width, fb0Height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
679                  nullptr);
680 
681     GLFramebuffer fb0;
682     glBindFramebuffer(GL_FRAMEBUFFER, fb0);
683     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex0, 0);
684     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
685 
686     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
687 
688     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
689 
690     drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);
691 
692     EXPECT_GL_NO_ERROR();
693 
694     // Blit to default from y-flipped.
695     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
696     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, fb0);
697 
698     glFramebufferParameteriMESA(GL_DRAW_FRAMEBUFFER_ANGLE, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
699     glFramebufferParameteriMESA(GL_READ_FRAMEBUFFER_ANGLE, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
700 
701     const int fboTargetWidth  = fb0Width / 2;
702     const int fboTargetHeight = fb0Height;
703 
704     glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
705     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
706 
707     glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, fboTargetWidth,
708                       fboTargetHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
709     glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), fb0Width / 2, 0, fb0Width,
710                       fb0Height / 2, GL_COLOR_BUFFER_BIT, GL_NEAREST);
711 
712     EXPECT_GL_NO_ERROR();
713 
714     glBindFramebuffer(GL_FRAMEBUFFER, fb0);
715 
716     glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 0);
717 
718     // Left side have inverted checker pattern.
719     EXPECT_PIXEL_COLOR_EQ(fboTargetWidth / 4, fboTargetHeight / 4, GLColor::red);
720     EXPECT_PIXEL_COLOR_EQ(fboTargetWidth / 4, 3 * fboTargetHeight / 4, GLColor::green);
721     EXPECT_PIXEL_COLOR_EQ(3 * fboTargetWidth / 4, fboTargetHeight / 4, GLColor::blue);
722     EXPECT_PIXEL_COLOR_EQ(3 * fboTargetWidth / 4, 3 * fboTargetHeight / 4, GLColor::yellow);
723 
724     // Right side is split to 2 parts where upper part have y-flipped checker pattern and the
725     // bottom one has white color.
726     EXPECT_PIXEL_COLOR_EQ(5 * fb0Width / 8, 5 * fb0Height / 8, GLColor::red);
727     EXPECT_PIXEL_COLOR_EQ(5 * fb0Width / 8, 7 * fb0Height / 8, GLColor::green);
728     EXPECT_PIXEL_COLOR_EQ(7 * fb0Width / 8, 5 * fb0Height / 8, GLColor::blue);
729     EXPECT_PIXEL_COLOR_EQ(7 * fb0Width / 8, 7 * fb0Height / 8, GLColor::yellow);
730 
731     EXPECT_PIXEL_RECT_EQ(4 * fb0Width / 8, 0, fb0Width / 4, fb0Height / 2, GLColor::white);
732 }
733 
734 // Same as BlitColorWithMesaYFlip but uses an integer buffer format.
TEST_P(BlitFramebufferANGLETest,BlitColorWithMesaYFlipInteger)735 TEST_P(BlitFramebufferANGLETest, BlitColorWithMesaYFlipInteger)
736 {
737     // OpenGL ES 3.0 / GL_NV_framebuffer_blit required for flip.
738     ANGLE_SKIP_TEST_IF(
739         (getClientMajorVersion() < 3 || !IsGLExtensionEnabled("GL_NV_framebuffer_blit")) ||
740         !IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
741 
742     GLTexture tex0;
743     glBindTexture(GL_TEXTURE_2D, tex0);
744     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8I, getWindowWidth(), getWindowHeight(), 0,
745                  GL_RGBA_INTEGER, GL_BYTE, nullptr);
746 
747     GLFramebuffer fb0;
748     glBindFramebuffer(GL_FRAMEBUFFER, fb0);
749     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex0, 0);
750     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
751 
752     glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
753 
754     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
755 
756     drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);
757 
758     EXPECT_GL_NO_ERROR();
759 
760     GLTexture tex1;
761     glBindTexture(GL_TEXTURE_2D, tex1);
762     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8I, getWindowWidth(), getWindowHeight(), 0,
763                  GL_RGBA_INTEGER, GL_BYTE, nullptr);
764 
765     GLFramebuffer fb1;
766     glBindFramebuffer(GL_FRAMEBUFFER, fb1);
767     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex1, 0);
768 
769     // Blit to default from y-flipped.
770     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, fb0);
771     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, fb1);
772 
773     const int fb1_target_width  = getWindowHeight() / 3;
774     const int fb1_target_height = getWindowHeight() / 3;
775 
776     glClearColor(0.0f, 1.0f, 1.0f, 1.0f);
777     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
778 
779     glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, fb1_target_width,
780                       fb1_target_height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
781 
782     EXPECT_GL_NO_ERROR();
783 
784     glBindFramebuffer(GL_FRAMEBUFFER, fb1);
785 
786     // The colors outside the target must remain the same.
787     EXPECT_PIXEL_8I(getWindowWidth() - 1, getWindowHeight() - 1, 0, 127, 127, 127);
788     EXPECT_PIXEL_8I(getWindowWidth() - 1, 0, 0, 127, 127, 127);
789     EXPECT_PIXEL_8I(0, getWindowHeight() - 1, 0, 127, 127, 127);
790     EXPECT_PIXEL_8I(fb1_target_width, fb1_target_height, 0, 127, 127, 127);
791 
792     // While inside must change.
793     EXPECT_PIXEL_8I(fb1_target_width / 4, fb1_target_height / 4, 127, 0, 0, 127);
794     EXPECT_PIXEL_8I(fb1_target_width / 4, 3 * fb1_target_height / 4, 0, 127, 0, 127);
795     EXPECT_PIXEL_8I(3 * fb1_target_width / 4, fb1_target_height / 4, 0, 0, 127, 127);
796     EXPECT_PIXEL_8I(3 * fb1_target_width / 4, 3 * fb1_target_height / 4, 127, 127, 0, 127);
797 
798     // Blit from y-flipped to default.
799     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, fb1);
800     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, fb0);
801 
802     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
803     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
804 
805     // Set y-flip flag so that y-flipped frame buffer blit to the original fbo in reverse. This
806     // should result in flipping y back.
807     glFramebufferParameteriMESA(GL_DRAW_FRAMEBUFFER_ANGLE, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
808 
809     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
810     glBlitFramebuffer(0, 0, fb1_target_width, fb1_target_height, 0, 0, getWindowWidth(),
811                       getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
812 
813     // And explicitly disable y-flip so that read does not implicitly use this flag.
814     glFramebufferParameteriMESA(GL_DRAW_FRAMEBUFFER_ANGLE, GL_FRAMEBUFFER_FLIP_Y_MESA, 0);
815 
816     EXPECT_GL_NO_ERROR();
817 
818     glBindFramebuffer(GL_FRAMEBUFFER, fb0);
819 
820     EXPECT_PIXEL_8I(getWindowWidth() / 4, getWindowHeight() / 4, 0, 127, 0, 127);
821     EXPECT_PIXEL_8I(getWindowWidth() / 4, 3 * getWindowHeight() / 4, 127, 0, 0, 127);
822     EXPECT_PIXEL_8I(3 * getWindowWidth() / 4, getWindowHeight() / 4, 127, 127, 0, 127);
823     EXPECT_PIXEL_8I(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 0, 127, 127);
824 }
825 
826 // Draw to system framebuffer, blit whole-buffer color to user-created framebuffer.
TEST_P(BlitFramebufferANGLETest,ReverseColorBlit)827 TEST_P(BlitFramebufferANGLETest, ReverseColorBlit)
828 {
829     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
830 
831     // TODO(jmadill): Fix this. http://anglebug.com/2743
832     ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
833 
834     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
835 
836     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
837 
838     drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);
839 
840     EXPECT_GL_NO_ERROR();
841 
842     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO);
843     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO);
844 
845     glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
846                            getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
847 
848     EXPECT_GL_NO_ERROR();
849 
850     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
851 
852     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
853     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);
854     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
855     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);
856 }
857 
858 // blit from user-created FBO to system framebuffer, with the scissor test enabled.
TEST_P(BlitFramebufferANGLETest,ScissoredBlit)859 TEST_P(BlitFramebufferANGLETest, ScissoredBlit)
860 {
861     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
862 
863     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
864 
865     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
866 
867     drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);
868 
869     EXPECT_GL_NO_ERROR();
870 
871     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
872     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
873 
874     glClearColor(1.0, 1.0, 1.0, 1.0);
875     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
876 
877     glScissor(getWindowWidth() / 2, 0, getWindowWidth() / 2, getWindowHeight());
878     glEnable(GL_SCISSOR_TEST);
879 
880     glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
881                            getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
882 
883     EXPECT_GL_NO_ERROR();
884 
885     glDisable(GL_SCISSOR_TEST);
886 
887     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
888 
889     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::white);
890     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::white);
891     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
892     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);
893 }
894 
895 // blit from system FBO to user-created framebuffer, with the scissor test enabled.
TEST_P(BlitFramebufferANGLETest,ReverseScissoredBlit)896 TEST_P(BlitFramebufferANGLETest, ReverseScissoredBlit)
897 {
898     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
899 
900     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
901 
902     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
903 
904     drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);
905 
906     EXPECT_GL_NO_ERROR();
907 
908     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO);
909     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO);
910 
911     glClearColor(1.0, 1.0, 1.0, 1.0);
912     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
913 
914     glScissor(getWindowWidth() / 2, 0, getWindowWidth() / 2, getWindowHeight());
915     glEnable(GL_SCISSOR_TEST);
916 
917     glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
918                            getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
919 
920     EXPECT_GL_NO_ERROR();
921 
922     glDisable(GL_SCISSOR_TEST);
923 
924     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
925 
926     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::white);
927     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::white);
928     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
929     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);
930 }
931 
932 // blit from user-created FBO to system framebuffer, using region larger than buffer.
TEST_P(BlitFramebufferANGLETest,OversizedBlit)933 TEST_P(BlitFramebufferANGLETest, OversizedBlit)
934 {
935     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
936 
937     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
938 
939     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
940 
941     drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);
942 
943     EXPECT_GL_NO_ERROR();
944 
945     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
946     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
947 
948     glClearColor(1.0, 1.0, 1.0, 1.0);
949     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
950 
951     glBlitFramebufferANGLE(0, 0, getWindowWidth() * 2, getWindowHeight() * 2, 0, 0,
952                            getWindowWidth() * 2, getWindowHeight() * 2, GL_COLOR_BUFFER_BIT,
953                            GL_NEAREST);
954 
955     EXPECT_GL_NO_ERROR();
956 
957     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
958 
959     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
960     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);
961     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
962     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);
963 }
964 
965 // blit from system FBO to user-created framebuffer, using region larger than buffer.
TEST_P(BlitFramebufferANGLETest,ReverseOversizedBlit)966 TEST_P(BlitFramebufferANGLETest, ReverseOversizedBlit)
967 {
968     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
969 
970     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
971 
972     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
973 
974     drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);
975 
976     EXPECT_GL_NO_ERROR();
977 
978     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO);
979     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO);
980 
981     glClearColor(1.0, 1.0, 1.0, 1.0);
982     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
983 
984     glBlitFramebufferANGLE(0, 0, getWindowWidth() * 2, getWindowHeight() * 2, 0, 0,
985                            getWindowWidth() * 2, getWindowHeight() * 2, GL_COLOR_BUFFER_BIT,
986                            GL_NEAREST);
987     EXPECT_GL_NO_ERROR();
988 
989     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
990 
991     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
992     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);
993     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
994     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);
995 }
996 
997 // blit from user-created FBO to system framebuffer, with depth buffer.
TEST_P(BlitFramebufferANGLETest,BlitWithDepthUserToDefault)998 TEST_P(BlitFramebufferANGLETest, BlitWithDepthUserToDefault)
999 {
1000     // TODO(http://anglebug.com/6154): glBlitFramebufferANGLE() generates GL_INVALID_OPERATION for
1001     // the ES2_OpenGL backend.
1002     ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsOpenGL());
1003 
1004     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1005 
1006     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
1007 
1008     glDepthMask(GL_TRUE);
1009     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1010 
1011     glEnable(GL_DEPTH_TEST);
1012 
1013     EXPECT_GL_NO_ERROR();
1014 
1015     // Clear the first half of the screen
1016     glEnable(GL_SCISSOR_TEST);
1017     glScissor(0, 0, getWindowWidth(), getWindowHeight() / 2);
1018 
1019     glClearDepthf(0.1f);
1020     glClearColor(1.0, 0.0, 0.0, 1.0);
1021     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1022 
1023     // Scissor the second half of the screen
1024     glScissor(0, getWindowHeight() / 2, getWindowWidth(), getWindowHeight() / 2);
1025 
1026     glClearDepthf(0.9f);
1027     glClearColor(0.0, 1.0, 0.0, 1.0);
1028     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1029 
1030     glDisable(GL_SCISSOR_TEST);
1031 
1032     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
1033     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
1034 
1035     glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
1036                            getWindowHeight(), GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
1037                            GL_NEAREST);
1038     EXPECT_GL_NO_ERROR();
1039 
1040     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
1041 
1042     // if blit is happening correctly, this quad will draw only on the bottom half since it will
1043     // be behind on the first half and in front on the second half.
1044     drawQuad(mBlueProgram, essl1_shaders::PositionAttrib(), 0.5f);
1045 
1046     glDisable(GL_DEPTH_TEST);
1047 
1048     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
1049     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::blue);
1050     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
1051     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::blue);
1052 }
1053 
1054 // blit from system FBO to user-created framebuffer, with depth buffer.
TEST_P(BlitFramebufferANGLETest,BlitWithDepthDefaultToUser)1055 TEST_P(BlitFramebufferANGLETest, BlitWithDepthDefaultToUser)
1056 {
1057     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1058 
1059     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
1060 
1061     glDepthMask(GL_TRUE);
1062     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1063 
1064     glEnable(GL_DEPTH_TEST);
1065 
1066     EXPECT_GL_NO_ERROR();
1067 
1068     // Clear the first half of the screen
1069     glEnable(GL_SCISSOR_TEST);
1070     glScissor(0, 0, getWindowWidth(), getWindowHeight() / 2);
1071 
1072     glClearDepthf(0.1f);
1073     glClearColor(1.0, 0.0, 0.0, 1.0);
1074     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1075 
1076     // Scissor the second half of the screen
1077     glScissor(0, getWindowHeight() / 2, getWindowWidth(), getWindowHeight() / 2);
1078 
1079     glClearDepthf(0.9f);
1080     glClearColor(0.0, 1.0, 0.0, 1.0);
1081     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1082 
1083     glDisable(GL_SCISSOR_TEST);
1084 
1085     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO);
1086     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO);
1087 
1088     glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
1089                            getWindowHeight(), GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
1090                            GL_NEAREST);
1091     EXPECT_GL_NO_ERROR();
1092 
1093     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
1094 
1095     // if blit is happening correctly, this quad will draw only on the bottom half since it will be
1096     // behind on the first half and in front on the second half.
1097     drawQuad(mBlueProgram, essl1_shaders::PositionAttrib(), 0.5f);
1098 
1099     glDisable(GL_DEPTH_TEST);
1100 
1101     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
1102     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::blue);
1103     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
1104     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::blue);
1105 }
1106 
1107 // blit from one region of the system fbo to another-- this should fail.
TEST_P(BlitFramebufferANGLETest,BlitSameBufferOriginal)1108 TEST_P(BlitFramebufferANGLETest, BlitSameBufferOriginal)
1109 {
1110     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1111 
1112     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
1113 
1114     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1115 
1116     drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.3f);
1117 
1118     EXPECT_GL_NO_ERROR();
1119 
1120     glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight(), getWindowWidth() / 2, 0,
1121                            getWindowWidth(), getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
1122     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1123 }
1124 
1125 // blit from one region of the system fbo to another.
TEST_P(BlitFramebufferANGLETest,BlitSameBufferUser)1126 TEST_P(BlitFramebufferANGLETest, BlitSameBufferUser)
1127 {
1128     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1129 
1130     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
1131 
1132     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1133 
1134     drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.3f);
1135 
1136     EXPECT_GL_NO_ERROR();
1137 
1138     glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight(), getWindowWidth() / 2, 0,
1139                            getWindowWidth(), getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
1140     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1141 }
1142 
TEST_P(BlitFramebufferANGLETest,BlitPartialColor)1143 TEST_P(BlitFramebufferANGLETest, BlitPartialColor)
1144 {
1145     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1146 
1147     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
1148 
1149     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1150 
1151     drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.5f);
1152 
1153     EXPECT_GL_NO_ERROR();
1154 
1155     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
1156     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
1157 
1158     glClearColor(1.0, 1.0, 1.0, 1.0);
1159     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1160 
1161     glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, 0,
1162                            getWindowHeight() / 2, getWindowWidth() / 2, getWindowHeight(),
1163                            GL_COLOR_BUFFER_BIT, GL_NEAREST);
1164 
1165     EXPECT_GL_NO_ERROR();
1166 
1167     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
1168 
1169     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::white);
1170     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::red);
1171     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::white);
1172     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::white);
1173 }
1174 
TEST_P(BlitFramebufferANGLETest,BlitDifferentSizes)1175 TEST_P(BlitFramebufferANGLETest, BlitDifferentSizes)
1176 {
1177     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1178 
1179     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
1180 
1181     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1182 
1183     drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.5f);
1184 
1185     EXPECT_GL_NO_ERROR();
1186 
1187     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mSmallFBO);
1188     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
1189 
1190     glClearColor(1.0, 1.0, 1.0, 1.0);
1191     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1192 
1193     glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
1194                            getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
1195 
1196     EXPECT_GL_NO_ERROR();
1197 
1198     glBindFramebuffer(GL_FRAMEBUFFER, mSmallFBO);
1199 
1200     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
1201 
1202     EXPECT_GL_NO_ERROR();
1203 }
1204 
TEST_P(BlitFramebufferANGLETest,BlitWithMissingAttachments)1205 TEST_P(BlitFramebufferANGLETest, BlitWithMissingAttachments)
1206 {
1207     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1208 
1209     glBindFramebuffer(GL_FRAMEBUFFER, mColorOnlyFBO);
1210 
1211     glClear(GL_COLOR_BUFFER_BIT);
1212     drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.3f);
1213 
1214     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
1215     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mColorOnlyFBO);
1216 
1217     glClearColor(1.0, 1.0, 1.0, 1.0);
1218     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1219 
1220     // generate INVALID_OPERATION if the read FBO has no depth attachment
1221     glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
1222                            getWindowHeight(), GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
1223                            GL_NEAREST);
1224 
1225     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1226 
1227     // generate INVALID_OPERATION if the read FBO has no stencil attachment
1228     glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
1229                            getWindowHeight(), GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
1230                            GL_NEAREST);
1231 
1232     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1233 
1234     // generate INVALID_OPERATION if we read from a missing color attachment
1235     glReadBuffer(GL_COLOR_ATTACHMENT1);
1236     glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
1237                            getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
1238 
1239     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1240 }
1241 
TEST_P(BlitFramebufferANGLETest,BlitStencil)1242 TEST_P(BlitFramebufferANGLETest, BlitStencil)
1243 {
1244     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1245 
1246     // http://anglebug.com/2205
1247     ANGLE_SKIP_TEST_IF(IsIntel() && IsD3D9());
1248 
1249     // http://anglebug.com/5396
1250     ANGLE_SKIP_TEST_IF(IsAMD() && IsD3D9());
1251 
1252     BlitStencilTestHelper(false /* mesaFlipY */);
1253 }
1254 
1255 // Same as BlitStencil, but with y-flip flag set.
TEST_P(BlitFramebufferANGLETest,BlitStencilWithMesaYFlip)1256 TEST_P(BlitFramebufferANGLETest, BlitStencilWithMesaYFlip)
1257 {
1258     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit") ||
1259                        !IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
1260 
1261     // http://anglebug.com/2205
1262     ANGLE_SKIP_TEST_IF(IsIntel() && IsD3D9());
1263 
1264     // http://anglebug.com/5396
1265     ANGLE_SKIP_TEST_IF(IsAMD() && IsD3D9());
1266 
1267     BlitStencilTestHelper(true /* mesaFlipY */);
1268 }
1269 
1270 // make sure that attempting to blit a partial depth buffer issues an error
TEST_P(BlitFramebufferANGLETest,BlitPartialDepthStencil)1271 TEST_P(BlitFramebufferANGLETest, BlitPartialDepthStencil)
1272 {
1273     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1274 
1275     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
1276 
1277     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1278 
1279     drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.5f);
1280 
1281     EXPECT_GL_NO_ERROR();
1282 
1283     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
1284     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
1285 
1286     glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, 0, 0,
1287                            getWindowWidth() / 2, getWindowHeight() / 2, GL_DEPTH_BUFFER_BIT,
1288                            GL_NEAREST);
1289     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1290 }
1291 
1292 // Test blit with MRT framebuffers
TEST_P(BlitFramebufferANGLETest,BlitMRT)1293 TEST_P(BlitFramebufferANGLETest, BlitMRT)
1294 {
1295     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1296 
1297     if (!IsGLExtensionEnabled("GL_EXT_draw_buffers"))
1298     {
1299         return;
1300     }
1301 
1302     GLenum drawBuffers[] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT};
1303 
1304     glBindFramebuffer(GL_FRAMEBUFFER, mMRTFBO);
1305     glDrawBuffersEXT(2, drawBuffers);
1306 
1307     glBindFramebuffer(GL_FRAMEBUFFER, mColorOnlyFBO);
1308 
1309     glClear(GL_COLOR_BUFFER_BIT);
1310 
1311     drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);
1312 
1313     EXPECT_GL_NO_ERROR();
1314 
1315     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mColorOnlyFBO);
1316     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mMRTFBO);
1317 
1318     glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
1319                            getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
1320 
1321     EXPECT_GL_NO_ERROR();
1322 
1323     glBindFramebuffer(GL_FRAMEBUFFER, mMRTFBO);
1324 
1325     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
1326     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);
1327     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
1328     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);
1329 
1330     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, 0, 0);
1331     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mMRTColorBuffer0,
1332                            0);
1333 
1334     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
1335     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);
1336     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
1337     EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);
1338 
1339     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mMRTColorBuffer0,
1340                            0);
1341     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D,
1342                            mMRTColorBuffer1, 0);
1343 }
1344 
1345 // Test multisampled framebuffer blits if supported
TEST_P(BlitFramebufferANGLETest,MultisampledRGBAToRGBA)1346 TEST_P(BlitFramebufferANGLETest, MultisampledRGBAToRGBA)
1347 {
1348     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1349 
1350     if (!checkExtension("GL_ANGLE_framebuffer_multisample"))
1351         return;
1352 
1353     if (!checkExtension("GL_OES_rgb8_rgba8"))
1354         return;
1355 
1356     multisampleTestHelper(mRGBAMultisampledFBO, mRGBAFBO);
1357 }
1358 
TEST_P(BlitFramebufferANGLETest,MultisampledRGBAToBGRA)1359 TEST_P(BlitFramebufferANGLETest, MultisampledRGBAToBGRA)
1360 {
1361     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1362 
1363     if (!checkExtension("GL_ANGLE_framebuffer_multisample"))
1364         return;
1365 
1366     if (!checkExtension("GL_OES_rgb8_rgba8"))
1367         return;
1368 
1369     if (!checkExtension("GL_EXT_texture_format_BGRA8888"))
1370         return;
1371 
1372     multisampleTestHelper(mRGBAMultisampledFBO, mBGRAFBO);
1373 }
1374 
TEST_P(BlitFramebufferANGLETest,MultisampledBGRAToRGBA)1375 TEST_P(BlitFramebufferANGLETest, MultisampledBGRAToRGBA)
1376 {
1377     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1378 
1379     if (!checkExtension("GL_ANGLE_framebuffer_multisample"))
1380         return;
1381 
1382     if (!checkExtension("GL_OES_rgb8_rgba8"))
1383         return;
1384 
1385     if (!checkExtension("GL_EXT_texture_format_BGRA8888"))
1386         return;
1387 
1388     multisampleTestHelper(mBGRAMultisampledFBO, mRGBAFBO);
1389 }
1390 
TEST_P(BlitFramebufferANGLETest,MultisampledBGRAToBGRA)1391 TEST_P(BlitFramebufferANGLETest, MultisampledBGRAToBGRA)
1392 {
1393     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1394 
1395     if (!checkExtension("GL_ANGLE_framebuffer_multisample"))
1396         return;
1397 
1398     if (!checkExtension("GL_OES_rgb8_rgba8"))
1399         return;
1400 
1401     if (!checkExtension("GL_EXT_texture_format_BGRA8888"))
1402         return;
1403 
1404     multisampleTestHelper(mBGRAMultisampledFBO, mBGRAFBO);
1405 }
1406 
1407 // Make sure that attempts to stretch in a blit call issue an error
TEST_P(BlitFramebufferANGLETest,ErrorStretching)1408 TEST_P(BlitFramebufferANGLETest, ErrorStretching)
1409 {
1410     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1411 
1412     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
1413 
1414     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1415 
1416     drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.5f);
1417 
1418     EXPECT_GL_NO_ERROR();
1419 
1420     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
1421     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
1422 
1423     glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, 0, 0,
1424                            getWindowWidth(), getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
1425     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1426 }
1427 
1428 // Make sure that attempts to flip in a blit call issue an error
TEST_P(BlitFramebufferANGLETest,ErrorFlipping)1429 TEST_P(BlitFramebufferANGLETest, ErrorFlipping)
1430 {
1431     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1432 
1433     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
1434 
1435     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1436 
1437     drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.5f);
1438 
1439     EXPECT_GL_NO_ERROR();
1440 
1441     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
1442     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
1443 
1444     glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, getWindowWidth() / 2,
1445                            getWindowHeight() / 2, 0, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1446     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1447 }
1448 
TEST_P(BlitFramebufferANGLETest,Errors)1449 TEST_P(BlitFramebufferANGLETest, Errors)
1450 {
1451     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1452 
1453     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
1454 
1455     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1456 
1457     drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.5f);
1458 
1459     EXPECT_GL_NO_ERROR();
1460 
1461     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
1462     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
1463 
1464     glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
1465                            getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_LINEAR);
1466     EXPECT_GL_ERROR(GL_INVALID_ENUM);
1467 
1468     glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
1469                            getWindowHeight(), GL_COLOR_BUFFER_BIT | 234, GL_NEAREST);
1470     EXPECT_GL_ERROR(GL_INVALID_VALUE);
1471 
1472     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mDiffFormatFBO);
1473 
1474     glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
1475                            getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
1476     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1477 }
1478 
1479 // TODO(geofflang): Fix the dependence on glBlitFramebufferANGLE without checks and assuming the
1480 // default framebuffer is BGRA to enable the GL and GLES backends. (http://anglebug.com/1289)
1481 
1482 class BlitFramebufferTest : public ANGLETest<>
1483 {
1484   protected:
BlitFramebufferTest()1485     BlitFramebufferTest()
1486     {
1487         setWindowWidth(256);
1488         setWindowHeight(256);
1489         setConfigRedBits(8);
1490         setConfigGreenBits(8);
1491         setConfigBlueBits(8);
1492         setConfigAlphaBits(8);
1493         setConfigDepthBits(24);
1494         setConfigStencilBits(8);
1495     }
1496 
initColorFBO(GLFramebuffer * fbo,GLRenderbuffer * rbo,GLenum rboFormat,GLsizei width,GLsizei height)1497     void initColorFBO(GLFramebuffer *fbo,
1498                       GLRenderbuffer *rbo,
1499                       GLenum rboFormat,
1500                       GLsizei width,
1501                       GLsizei height)
1502     {
1503         glBindRenderbuffer(GL_RENDERBUFFER, *rbo);
1504         glRenderbufferStorage(GL_RENDERBUFFER, rboFormat, width, height);
1505 
1506         glBindFramebuffer(GL_FRAMEBUFFER, *fbo);
1507         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *rbo);
1508     }
1509 
initColorFBOWithCheckerPattern(GLFramebuffer * fbo,GLRenderbuffer * rbo,GLenum rboFormat,GLsizei width,GLsizei height)1510     void initColorFBOWithCheckerPattern(GLFramebuffer *fbo,
1511                                         GLRenderbuffer *rbo,
1512                                         GLenum rboFormat,
1513                                         GLsizei width,
1514                                         GLsizei height)
1515     {
1516         initColorFBO(fbo, rbo, rboFormat, width, height);
1517 
1518         ANGLE_GL_PROGRAM(checkerProgram, essl1_shaders::vs::Passthrough(),
1519                          essl1_shaders::fs::Checkered());
1520         glViewport(0, 0, width, height);
1521         glBindFramebuffer(GL_FRAMEBUFFER, *fbo);
1522         drawQuad(checkerProgram, essl1_shaders::PositionAttrib(), 0.5f);
1523     }
1524 
BlitDepthStencilPixelByPixelTestHelper(bool mesaYFlip)1525     void BlitDepthStencilPixelByPixelTestHelper(bool mesaYFlip)
1526     {
1527         if (mesaYFlip)
1528             ASSERT_TRUE(IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
1529 
1530         ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
1531 
1532         glViewport(0, 0, 128, 1);
1533         glEnable(GL_DEPTH_TEST);
1534 
1535         GLFramebuffer srcFramebuffer;
1536         GLRenderbuffer srcRenderbuffer;
1537         glBindFramebuffer(GL_FRAMEBUFFER, srcFramebuffer);
1538         if (mesaYFlip)
1539             glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
1540         glBindRenderbuffer(GL_RENDERBUFFER, srcRenderbuffer);
1541         glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 128, 1);
1542         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
1543                                   srcRenderbuffer);
1544         glClearDepthf(1.0f);
1545         glClear(GL_DEPTH_BUFFER_BIT);
1546 
1547         drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.0f, 0.5f);
1548         glViewport(0, 0, 256, 2);
1549 
1550         GLFramebuffer dstFramebuffer;
1551         GLRenderbuffer dstRenderbuffer;
1552         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dstFramebuffer);
1553         glBindRenderbuffer(GL_RENDERBUFFER, dstRenderbuffer);
1554         glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 256, 2);
1555         glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
1556                                   dstRenderbuffer);
1557 
1558         GLTexture dstColor;
1559         glBindTexture(GL_TEXTURE_2D, dstColor);
1560         glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 2);
1561         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dstColor, 0);
1562 
1563         glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFramebuffer);
1564         glBlitFramebuffer(0, 0, 128, 1, 0, 0, 256, 2, GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
1565                           GL_NEAREST);
1566 
1567         glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
1568         glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
1569         glClear(GL_COLOR_BUFFER_BIT);
1570         glDepthMask(false);
1571         glDepthFunc(GL_LESS);
1572         drawQuad(drawRed, essl1_shaders::PositionAttrib(), -0.01f, 0.5f);
1573         EXPECT_PIXEL_RECT_EQ(64, 0, 128, 1, GLColor::red);
1574 
1575         ANGLE_GL_PROGRAM(drawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());
1576         glEnable(GL_DEPTH_TEST);
1577         glDepthMask(false);
1578         glDepthFunc(GL_GREATER);
1579         if (mesaYFlip)
1580             glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
1581         drawQuad(drawBlue, essl1_shaders::PositionAttrib(), 0.01f, 0.5f);
1582         if (mesaYFlip)
1583             EXPECT_PIXEL_RECT_EQ(64, 0, 128, 1, GLColor::green);
1584         else
1585             EXPECT_PIXEL_RECT_EQ(64, 0, 128, 1, GLColor::blue);
1586     }
1587 
1588     // Test blitting between 3D textures and 2D array textures
test3DBlit(GLenum sourceTarget,GLenum destTarget)1589     void test3DBlit(GLenum sourceTarget, GLenum destTarget)
1590     {
1591 
1592         constexpr int kTexWidth  = 4;
1593         constexpr int kTexHeight = 3;
1594         constexpr int kTexDepth  = 2;
1595         glViewport(0, 0, kTexWidth, kTexHeight);
1596 
1597         size_t size = kTexWidth * kTexHeight * kTexDepth;
1598         std::vector<uint32_t> sourceData(size);
1599         std::vector<uint32_t> destData(size);
1600         for (size_t i = 0; i < size; ++i)
1601         {
1602             sourceData[i] = i;
1603             destData[i]   = size - i;
1604         }
1605 
1606         // Create a source 3D texture and FBO.
1607         GLTexture sourceTexture;
1608         glBindTexture(sourceTarget, sourceTexture);
1609         glTexImage3D(sourceTarget, 0, GL_RGBA8, kTexWidth, kTexHeight, kTexDepth, 0, GL_RGBA,
1610                      GL_UNSIGNED_BYTE, sourceData.data());
1611 
1612         // Create a dest texture and FBO.
1613         GLTexture destTexture;
1614         glBindTexture(destTarget, destTexture);
1615         glTexImage3D(destTarget, 0, GL_RGBA8, kTexWidth, kTexHeight, kTexDepth, 0, GL_RGBA,
1616                      GL_UNSIGNED_BYTE, destData.data());
1617 
1618         for (int z = 0; z < kTexDepth; ++z)
1619         {
1620             ASSERT_GL_NO_ERROR();
1621             GLFramebuffer sourceFBO;
1622             glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
1623             glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, sourceTexture, 0,
1624                                       z);
1625             ASSERT_GL_NO_ERROR();
1626 
1627             GLFramebuffer destFBO;
1628             glBindFramebuffer(GL_DRAW_FRAMEBUFFER, destFBO);
1629             glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, destTexture, 0, z);
1630             ASSERT_GL_NO_ERROR();
1631 
1632             glBlitFramebuffer(0, 0, kTexWidth, kTexHeight, 0, 0, kTexWidth, kTexHeight,
1633                               GL_COLOR_BUFFER_BIT, GL_NEAREST);
1634             ASSERT_GL_NO_ERROR();
1635         }
1636 
1637         for (int z = 0; z < kTexDepth; ++z)
1638         {
1639             GLFramebuffer readFBO;
1640             glBindFramebuffer(GL_READ_FRAMEBUFFER, readFBO);
1641             glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, destTexture, 0, z);
1642             ASSERT_GL_NO_ERROR();
1643 
1644             glReadBuffer(GL_COLOR_ATTACHMENT0);
1645             for (int y = 0; y < kTexHeight; ++y)
1646             {
1647                 for (int x = 0; x < kTexWidth; ++x)
1648                 {
1649                     int index = x + kTexWidth * (y + z * kTexHeight);
1650                     EXPECT_PIXEL_COLOR_EQ(x, y, index);
1651                 }
1652             }
1653         }
1654     }
1655 
initFBOWithProgramAndDepth(GLFramebuffer * fbo,GLRenderbuffer * colorRenderBuffer,GLenum colorFormat,GLRenderbuffer * depthRenderBuffer,GLenum depthFormat,GLsizei width,GLsizei height,GLuint program,float depthValue)1656     void initFBOWithProgramAndDepth(GLFramebuffer *fbo,
1657                                     GLRenderbuffer *colorRenderBuffer,
1658                                     GLenum colorFormat,
1659                                     GLRenderbuffer *depthRenderBuffer,
1660                                     GLenum depthFormat,
1661                                     GLsizei width,
1662                                     GLsizei height,
1663                                     GLuint program,
1664                                     float depthValue)
1665     {
1666         if (fbo != nullptr)
1667         {
1668             // Create renderbuffer
1669             glBindRenderbuffer(GL_RENDERBUFFER, *colorRenderBuffer);
1670             glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, width, height);
1671             glBindRenderbuffer(GL_RENDERBUFFER, *depthRenderBuffer);
1672             glRenderbufferStorage(GL_RENDERBUFFER, depthFormat, width, height);
1673 
1674             // Create fbo
1675             glBindFramebuffer(GL_FRAMEBUFFER, *fbo);
1676             glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
1677                                       *colorRenderBuffer);
1678             glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
1679                                       *depthRenderBuffer);
1680         }
1681         else
1682         {
1683             glBindFramebuffer(GL_FRAMEBUFFER, 0);
1684         }
1685 
1686         // draw with program
1687         glUseProgram(program);
1688         glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
1689         glClearDepthf(1.0f);
1690         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1691         glEnable(GL_DEPTH_TEST);
1692         glDepthMask(true);
1693         drawQuad(program, essl1_shaders::PositionAttrib(), depthValue);
1694     }
1695 
drawWithDepthValue(std::array<Vector3,6> & quadVertices,float depth)1696     void drawWithDepthValue(std::array<Vector3, 6> &quadVertices, float depth)
1697     {
1698         for (Vector3 &vertice : quadVertices)
1699         {
1700             vertice[2] = depth;
1701         }
1702         glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(quadVertices[0]) * quadVertices.size(),
1703                         quadVertices.data());
1704         glDrawArrays(GL_TRIANGLES, 0, 6);
1705     }
1706 };
1707 
1708 class BlitFramebufferTestES31 : public BlitFramebufferTest
1709 {};
1710 
1711 // Tests resolving a multisample depth buffer.
TEST_P(BlitFramebufferTest,MultisampleDepth)1712 TEST_P(BlitFramebufferTest, MultisampleDepth)
1713 {
1714     // TODO(oetuaho@nvidia.com): http://crbug.com/837717
1715     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsMac());
1716 
1717     GLRenderbuffer renderbuf;
1718     glBindRenderbuffer(GL_RENDERBUFFER, renderbuf);
1719     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_DEPTH_COMPONENT24, 256, 256);
1720 
1721     GLFramebuffer framebuffer;
1722     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1723     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuf);
1724 
1725     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1726 
1727     glClearDepthf(0.5f);
1728     glClear(GL_DEPTH_BUFFER_BIT);
1729 
1730     GLRenderbuffer destRenderbuf;
1731     glBindRenderbuffer(GL_RENDERBUFFER, destRenderbuf);
1732     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 256, 256);
1733 
1734     GLFramebuffer resolved;
1735     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolved);
1736     glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
1737                               destRenderbuf);
1738 
1739     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
1740     glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
1741 
1742     glBindFramebuffer(GL_FRAMEBUFFER, resolved);
1743 
1744     // Immediately destroy the framebuffer and the associated textures for additional cleanup
1745     // ordering testing.
1746     framebuffer.reset();
1747     renderbuf.reset();
1748 
1749     GLTexture colorbuf;
1750     glBindTexture(GL_TEXTURE_2D, colorbuf);
1751     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);
1752     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuf, 0);
1753 
1754     ASSERT_GL_NO_ERROR();
1755 
1756     // Clear to green
1757     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
1758     glClear(GL_COLOR_BUFFER_BIT);
1759     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1760 
1761     // Make sure resulting depth is near 0.5f.
1762     ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
1763     glEnable(GL_DEPTH_TEST);
1764     glDepthMask(false);
1765     glDepthFunc(GL_LESS);
1766     drawQuad(drawRed, essl3_shaders::PositionAttrib(), -0.01f);
1767     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1768     EXPECT_PIXEL_COLOR_EQ(255, 0, GLColor::red);
1769     EXPECT_PIXEL_COLOR_EQ(0, 255, GLColor::red);
1770     EXPECT_PIXEL_COLOR_EQ(255, 255, GLColor::red);
1771     EXPECT_PIXEL_COLOR_EQ(127, 127, GLColor::red);
1772 
1773     ANGLE_GL_PROGRAM(drawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());
1774     glEnable(GL_DEPTH_TEST);
1775     glDepthMask(false);
1776     glDepthFunc(GL_GREATER);
1777     drawQuad(drawBlue, essl3_shaders::PositionAttrib(), 0.01f);
1778     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
1779     EXPECT_PIXEL_COLOR_EQ(255, 0, GLColor::blue);
1780     EXPECT_PIXEL_COLOR_EQ(0, 255, GLColor::blue);
1781     EXPECT_PIXEL_COLOR_EQ(255, 255, GLColor::blue);
1782     EXPECT_PIXEL_COLOR_EQ(127, 127, GLColor::blue);
1783 
1784     ASSERT_GL_NO_ERROR();
1785 }
1786 
1787 // Blit multisample stencil buffer to default framebuffer without prerotaion.
TEST_P(BlitFramebufferTest,BlitMultisampleStencilToDefault)1788 TEST_P(BlitFramebufferTest, BlitMultisampleStencilToDefault)
1789 {
1790     // http://anglebug.com/3496
1791     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsMac());
1792 
1793     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1794     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1795 
1796     GLRenderbuffer colorbuf;
1797     glBindRenderbuffer(GL_RENDERBUFFER, colorbuf);
1798     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, 128, 128);
1799 
1800     GLRenderbuffer depthstencilbuf;
1801     glBindRenderbuffer(GL_RENDERBUFFER, depthstencilbuf);
1802     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, 128, 128);
1803 
1804     GLFramebuffer framebuffer;
1805     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1806     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuf);
1807     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
1808                               depthstencilbuf);
1809     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
1810                               depthstencilbuf);
1811     glCheckFramebufferStatus(GL_FRAMEBUFFER);
1812 
1813     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1814     glFlush();
1815 
1816     // Replace stencil to 1.
1817     ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
1818     glEnable(GL_STENCIL_TEST);
1819     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
1820     glStencilFunc(GL_ALWAYS, 1, 255);
1821     drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.8f);
1822 
1823     // Blit multisample stencil buffer to default frambuffer.
1824     GLenum attachments1[] = {GL_COLOR_ATTACHMENT0};
1825     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments1);
1826     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1827     glBlitFramebuffer(0, 0, 128, 128, 0, 0, 128, 128, GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
1828                       GL_NEAREST);
1829     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1830 
1831     // Disable stencil and draw full_screen green color.
1832     ANGLE_GL_PROGRAM(drawGreen, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());
1833     glDisable(GL_STENCIL_TEST);
1834     drawQuad(drawGreen, essl3_shaders::PositionAttrib(), 0.5f);
1835 
1836     // Draw blue color if the stencil is equal to 1.
1837     // If the blit finished successfully, the stencil test should all pass.
1838     ANGLE_GL_PROGRAM(drawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());
1839     glEnable(GL_STENCIL_TEST);
1840     glStencilFunc(GL_EQUAL, 1, 255);
1841     drawQuad(drawBlue, essl3_shaders::PositionAttrib(), 0.2f);
1842 
1843     // Check the result, especially the boundaries.
1844     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
1845     EXPECT_PIXEL_COLOR_EQ(127, 0, GLColor::blue);
1846     EXPECT_PIXEL_COLOR_EQ(50, 0, GLColor::blue);
1847     EXPECT_PIXEL_COLOR_EQ(127, 1, GLColor::blue);
1848     EXPECT_PIXEL_COLOR_EQ(0, 127, GLColor::blue);
1849     EXPECT_PIXEL_COLOR_EQ(127, 127, GLColor::blue);
1850     EXPECT_PIXEL_COLOR_EQ(64, 64, GLColor::blue);
1851 
1852     ASSERT_GL_NO_ERROR();
1853 }
1854 
1855 // Tests clearing a multisampled depth buffer.
TEST_P(BlitFramebufferTest,MultisampleDepthClear)1856 TEST_P(BlitFramebufferTest, MultisampleDepthClear)
1857 {
1858     // http://anglebug.com/4092
1859     ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());
1860 
1861     GLRenderbuffer depthMS;
1862     glBindRenderbuffer(GL_RENDERBUFFER, depthMS);
1863     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_DEPTH_COMPONENT24, 256, 256);
1864 
1865     GLRenderbuffer colorMS;
1866     glBindRenderbuffer(GL_RENDERBUFFER, colorMS);
1867     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_RGBA8, 256, 256);
1868 
1869     GLRenderbuffer colorResolved;
1870     glBindRenderbuffer(GL_RENDERBUFFER, colorResolved);
1871     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 256, 256);
1872 
1873     GLFramebuffer framebufferMS;
1874     glBindFramebuffer(GL_FRAMEBUFFER, framebufferMS);
1875     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthMS);
1876     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorMS);
1877 
1878     // Clear depth buffer to 0.5 and color to green.
1879     glClearDepthf(0.5f);
1880     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
1881     glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
1882 
1883     glFlush();
1884 
1885     // Draw red into the multisampled color buffer.
1886     ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
1887     glEnable(GL_DEPTH_TEST);
1888     glDepthFunc(GL_EQUAL);
1889     drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.0f);
1890 
1891     // Resolve the color buffer to make sure the above draw worked correctly, which in turn implies
1892     // that the multisampled depth clear worked.
1893     GLFramebuffer framebufferResolved;
1894     glBindFramebuffer(GL_FRAMEBUFFER, framebufferResolved);
1895     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorResolved);
1896     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferMS);
1897     glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1898 
1899     glBindFramebuffer(GL_FRAMEBUFFER, framebufferResolved);
1900 
1901     ASSERT_GL_NO_ERROR();
1902 
1903     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1904     EXPECT_PIXEL_COLOR_EQ(255, 0, GLColor::red);
1905     EXPECT_PIXEL_COLOR_EQ(0, 255, GLColor::red);
1906     EXPECT_PIXEL_COLOR_EQ(255, 255, GLColor::red);
1907     EXPECT_PIXEL_COLOR_EQ(127, 127, GLColor::red);
1908 
1909     ASSERT_GL_NO_ERROR();
1910 }
1911 
1912 // Tests clearing a multisampled depth buffer with a glFenceSync in between.
TEST_P(BlitFramebufferTest,MultisampleDepthClearWithFenceSync)1913 TEST_P(BlitFramebufferTest, MultisampleDepthClearWithFenceSync)
1914 {
1915     // http://anglebug.com/4092
1916     ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());
1917 
1918     GLRenderbuffer depthMS;
1919     glBindRenderbuffer(GL_RENDERBUFFER, depthMS);
1920     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_DEPTH_COMPONENT24, 256, 256);
1921 
1922     GLRenderbuffer colorMS;
1923     glBindRenderbuffer(GL_RENDERBUFFER, colorMS);
1924     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_RGBA8, 256, 256);
1925 
1926     GLRenderbuffer colorResolved;
1927     glBindRenderbuffer(GL_RENDERBUFFER, colorResolved);
1928     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 256, 256);
1929 
1930     GLFramebuffer framebufferMS;
1931     glBindFramebuffer(GL_FRAMEBUFFER, framebufferMS);
1932     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthMS);
1933     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorMS);
1934 
1935     // Clear depth buffer to 0.5 and color to green.
1936     glClearDepthf(0.5f);
1937     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
1938     glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
1939 
1940     glFlush();
1941 
1942     // Draw red into the multisampled color buffer.
1943     ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
1944     glEnable(GL_DEPTH_TEST);
1945     glDepthFunc(GL_EQUAL);
1946     drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.0f);
1947 
1948     // This should trigger a deferred renderPass end
1949     GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
1950     EXPECT_GL_NO_ERROR();
1951 
1952     // Resolve the color buffer to make sure the above draw worked correctly, which in turn implies
1953     // that the multisampled depth clear worked.
1954     GLFramebuffer framebufferResolved;
1955     glBindFramebuffer(GL_FRAMEBUFFER, framebufferResolved);
1956     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorResolved);
1957     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferMS);
1958     glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1959 
1960     glBindFramebuffer(GL_FRAMEBUFFER, framebufferResolved);
1961 
1962     ASSERT_GL_NO_ERROR();
1963 
1964     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1965     EXPECT_PIXEL_COLOR_EQ(255, 0, GLColor::red);
1966     EXPECT_PIXEL_COLOR_EQ(0, 255, GLColor::red);
1967     EXPECT_PIXEL_COLOR_EQ(255, 255, GLColor::red);
1968     EXPECT_PIXEL_COLOR_EQ(127, 127, GLColor::red);
1969 
1970     glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED);
1971     ASSERT_GL_NO_ERROR();
1972 }
1973 
1974 // Test resolving a multisampled stencil buffer.
TEST_P(BlitFramebufferTest,MultisampleStencil)1975 TEST_P(BlitFramebufferTest, MultisampleStencil)
1976 {
1977     GLRenderbuffer renderbuf;
1978     glBindRenderbuffer(GL_RENDERBUFFER, renderbuf);
1979     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_STENCIL_INDEX8, 256, 256);
1980 
1981     ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
1982 
1983     GLFramebuffer framebuffer;
1984     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1985     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuf);
1986 
1987     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1988 
1989     // fill the stencil buffer with 0x1
1990     glStencilFunc(GL_ALWAYS, 0x1, 0xFF);
1991     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
1992     glEnable(GL_STENCIL_TEST);
1993     drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.5f);
1994 
1995     GLTexture destColorbuf;
1996     glBindTexture(GL_TEXTURE_2D, destColorbuf);
1997     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);
1998 
1999     GLRenderbuffer destRenderbuf;
2000     glBindRenderbuffer(GL_RENDERBUFFER, destRenderbuf);
2001     glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, 256, 256);
2002 
2003     GLFramebuffer resolved;
2004     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolved);
2005     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, destColorbuf,
2006                            0);
2007     glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2008                               destRenderbuf);
2009 
2010     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
2011     glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_STENCIL_BUFFER_BIT, GL_NEAREST);
2012 
2013     // Immediately destroy the framebuffer and the associated textures for additional cleanup
2014     // ordering testing.
2015     framebuffer.reset();
2016     renderbuf.reset();
2017 
2018     glBindFramebuffer(GL_FRAMEBUFFER, resolved);
2019 
2020     ASSERT_GL_NO_ERROR();
2021 
2022     // Clear to green
2023     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
2024     glClear(GL_COLOR_BUFFER_BIT);
2025     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2026 
2027     // Draw red if the stencil is 0x1, which should be true after the resolve.
2028     glStencilFunc(GL_EQUAL, 0x1, 0xFF);
2029     drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.5f);
2030     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2031 
2032     ASSERT_GL_NO_ERROR();
2033 }
2034 
2035 // Test resolving a multisampled stencil buffer with scissor.
TEST_P(BlitFramebufferTest,ScissoredMultisampleStencil)2036 TEST_P(BlitFramebufferTest, ScissoredMultisampleStencil)
2037 {
2038     constexpr GLuint kSize = 256;
2039 
2040     // Create the resolve framebuffer.
2041     GLTexture destColorbuf;
2042     glBindTexture(GL_TEXTURE_2D, destColorbuf);
2043     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
2044 
2045     GLRenderbuffer destRenderbuf;
2046     glBindRenderbuffer(GL_RENDERBUFFER, destRenderbuf);
2047     glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, kSize, kSize);
2048 
2049     GLFramebuffer resolved;
2050     glBindFramebuffer(GL_FRAMEBUFFER, resolved);
2051     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, destColorbuf,
2052                            0);
2053     glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2054                               destRenderbuf);
2055 
2056     // Clear the resolved buffer with gray and 0x10 stencil.
2057     GLColor gray(127, 127, 127, 255);
2058     glClearStencil(0x10);
2059     glClearColor(0.499f, 0.499f, 0.499f, 1.0f);
2060     glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2061     EXPECT_PIXEL_COLOR_EQ(0, 0, gray);
2062     EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, gray);
2063 
2064     // Create the multisampled framebuffer.
2065     GLRenderbuffer renderbuf;
2066     glBindRenderbuffer(GL_RENDERBUFFER, renderbuf);
2067     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_STENCIL_INDEX8, kSize, kSize);
2068 
2069     ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
2070     ANGLE_GL_PROGRAM(drawGreen, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());
2071     ANGLE_GL_PROGRAM(drawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());
2072 
2073     GLFramebuffer framebuffer;
2074     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
2075     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuf);
2076 
2077     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
2078 
2079     // Fill the stencil buffer with 0x1.
2080     glClearStencil(0x1);
2081     glClear(GL_STENCIL_BUFFER_BIT);
2082 
2083     // Fill a smaller region of the buffer with 0x2.
2084     glEnable(GL_SCISSOR_TEST);
2085     glEnable(GL_STENCIL_TEST);
2086     glScissor(kSize / 4, kSize / 4, kSize / 2, kSize / 2);
2087     glStencilFunc(GL_ALWAYS, 0x2, 0xFF);
2088     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
2089     drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.5f);
2090 
2091     // Blit into the resolved framebuffer (with scissor still enabled).
2092     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolved);
2093     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_STENCIL_BUFFER_BIT, GL_NEAREST);
2094 
2095     glBindFramebuffer(GL_FRAMEBUFFER, resolved);
2096 
2097     ASSERT_GL_NO_ERROR();
2098 
2099     // Draw blue if the stencil is 0x1, which should never be true.
2100     glDisable(GL_SCISSOR_TEST);
2101     glStencilMask(0);
2102     glStencilFunc(GL_EQUAL, 0x1, 0xFF);
2103     drawQuad(drawBlue, essl3_shaders::PositionAttrib(), 0.5f);
2104     EXPECT_PIXEL_COLOR_EQ(0, 0, gray);
2105     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, gray);
2106     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, gray);
2107     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, gray);
2108     EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, gray);
2109 
2110     // Draw red if the stencil is 0x2, which should be true in the middle after the blit/resolve.
2111     glStencilFunc(GL_EQUAL, 0x2, 0xFF);
2112     drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.5f);
2113     EXPECT_PIXEL_COLOR_EQ(0, 0, gray);
2114     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, gray);
2115     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, gray);
2116     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, gray);
2117     EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::red);
2118 
2119     // Draw green if the stencil is 0x10, which should be left untouched in the outer regions.
2120     glStencilFunc(GL_EQUAL, 0x10, 0xFF);
2121     drawQuad(drawGreen, essl3_shaders::PositionAttrib(), 0.5f);
2122     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2123     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::green);
2124     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::green);
2125     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::green);
2126     EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::red);
2127 
2128     ASSERT_GL_NO_ERROR();
2129 }
2130 
2131 // Test blitting from a texture with non-zero base.  The blit is non-stretching and between
2132 // identical formats so that the path that uses vkCmdBlitImage is taken.
TEST_P(BlitFramebufferTest,NonZeroBaseSource)2133 TEST_P(BlitFramebufferTest, NonZeroBaseSource)
2134 {
2135     // http://anglebug.com/5001
2136     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsMac());
2137 
2138     ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
2139 
2140     // Create a framebuffer for source data.  It usea a non-zero base.
2141     GLTexture srcColor;
2142     glBindTexture(GL_TEXTURE_2D, srcColor);
2143     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2144     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2145     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2146 
2147     GLFramebuffer srcFramebuffer;
2148     glBindFramebuffer(GL_FRAMEBUFFER, srcFramebuffer);
2149     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcColor, 1);
2150     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2151 
2152     // fill the color buffer with red.
2153     drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.5f);
2154 
2155     // Create a framebuffer for blit destination.
2156     GLTexture dstColor;
2157     glBindTexture(GL_TEXTURE_2D, dstColor);
2158     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2159 
2160     GLFramebuffer dstFramebuffer;
2161     glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
2162     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dstColor, 0);
2163     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2164 
2165     // Blit.  Note: no stretching is done so that vkCmdBlitImage can be used.
2166     glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFramebuffer);
2167     glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2168 
2169     glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
2170 
2171     ASSERT_GL_NO_ERROR();
2172 
2173     // Make sure the blit is done.
2174     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2175 
2176     ASSERT_GL_NO_ERROR();
2177 }
2178 
2179 // Test blitting to a texture with non-zero base.  The blit is non-stretching and between
2180 // identical formats so that the path that uses vkCmdBlitImage is taken.
TEST_P(BlitFramebufferTest,NonZeroBaseDestination)2181 TEST_P(BlitFramebufferTest, NonZeroBaseDestination)
2182 {
2183     ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
2184 
2185     // Create a framebuffer for source data.  It usea a non-zero base.
2186     GLTexture srcColor;
2187     glBindTexture(GL_TEXTURE_2D, srcColor);
2188     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2189 
2190     GLFramebuffer srcFramebuffer;
2191     glBindFramebuffer(GL_FRAMEBUFFER, srcFramebuffer);
2192     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcColor, 0);
2193     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2194 
2195     // fill the color buffer with red.
2196     drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.5f);
2197 
2198     // Create a framebuffer for blit destination.
2199     GLTexture dstColor;
2200     glBindTexture(GL_TEXTURE_2D, dstColor);
2201     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2202     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2203     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2204 
2205     GLFramebuffer dstFramebuffer;
2206     glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
2207     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dstColor, 1);
2208     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2209 
2210     // Blit.  Note: no stretching is done so that vkCmdBlitImage can be used.
2211     glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFramebuffer);
2212     glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2213 
2214     glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
2215 
2216     ASSERT_GL_NO_ERROR();
2217 
2218     // Make sure the blit is done.
2219     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2220 
2221     ASSERT_GL_NO_ERROR();
2222 }
2223 
2224 // Test blitting from a stencil buffer with non-zero base.
TEST_P(BlitFramebufferTest,NonZeroBaseSourceStencil)2225 TEST_P(BlitFramebufferTest, NonZeroBaseSourceStencil)
2226 {
2227     // http://anglebug.com/5001
2228     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsMac());
2229 
2230     ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
2231 
2232     // Create a framebuffer with an attachment that has non-zero base
2233     GLTexture stencilTexture;
2234     glBindTexture(GL_TEXTURE_2D, stencilTexture);
2235     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 256, 256, 0, GL_DEPTH_STENCIL,
2236                  GL_UNSIGNED_INT_24_8, nullptr);
2237     glTexImage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, 256, 256, 0, GL_DEPTH_STENCIL,
2238                  GL_UNSIGNED_INT_24_8, nullptr);
2239     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2240 
2241     GLFramebuffer srcFramebuffer;
2242     glBindFramebuffer(GL_FRAMEBUFFER, srcFramebuffer);
2243     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, stencilTexture, 1);
2244     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2245 
2246     // fill the stencil buffer with 0x1
2247     glStencilFunc(GL_ALWAYS, 0x1, 0xFF);
2248     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
2249     glEnable(GL_STENCIL_TEST);
2250     drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.5f);
2251 
2252     // Create a framebuffer with an attachment that has non-zero base
2253     GLTexture colorTexture;
2254     glBindTexture(GL_TEXTURE_2D, colorTexture);
2255     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);
2256 
2257     GLRenderbuffer renderbuf;
2258     glBindRenderbuffer(GL_RENDERBUFFER, renderbuf);
2259     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 256, 256);
2260 
2261     GLFramebuffer dstFramebuffer;
2262     glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
2263     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
2264     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuf);
2265     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2266 
2267     // Blit stencil.
2268     glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFramebuffer);
2269     glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_STENCIL_BUFFER_BIT, GL_NEAREST);
2270 
2271     glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
2272 
2273     ASSERT_GL_NO_ERROR();
2274 
2275     // Clear to green
2276     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
2277     glClear(GL_COLOR_BUFFER_BIT);
2278     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2279 
2280     // Draw red if the stencil is 0x1, which should be true after the blit.
2281     glStencilFunc(GL_EQUAL, 0x1, 0xFF);
2282     drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.5f);
2283     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2284 
2285     ASSERT_GL_NO_ERROR();
2286 }
2287 
2288 // Test blitting to a stencil buffer with non-zero base.
TEST_P(BlitFramebufferTest,NonZeroBaseDestinationStencil)2289 TEST_P(BlitFramebufferTest, NonZeroBaseDestinationStencil)
2290 {
2291     // http://anglebug.com/5001
2292     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsMac());
2293 
2294     // http://anglebug.com/5003
2295     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsWindows());
2296 
2297     ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
2298 
2299     // Create a framebuffer for source data.
2300     GLRenderbuffer renderbuf;
2301     glBindRenderbuffer(GL_RENDERBUFFER, renderbuf);
2302     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 256, 256);
2303 
2304     GLFramebuffer srcFramebuffer;
2305     glBindFramebuffer(GL_FRAMEBUFFER, srcFramebuffer);
2306     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuf);
2307     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2308 
2309     // fill the stencil buffer with 0x1
2310     glStencilFunc(GL_ALWAYS, 0x1, 0xFF);
2311     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
2312     glEnable(GL_STENCIL_TEST);
2313     drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.5f);
2314 
2315     // Create a framebuffer with an attachment that has non-zero base
2316     GLTexture colorTexture;
2317     glBindTexture(GL_TEXTURE_2D, colorTexture);
2318     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);
2319 
2320     GLTexture stencilTexture;
2321     glBindTexture(GL_TEXTURE_2D, stencilTexture);
2322     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 256, 256, 0, GL_DEPTH_STENCIL,
2323                  GL_UNSIGNED_INT_24_8, nullptr);
2324     glTexImage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, 256, 256, 0, GL_DEPTH_STENCIL,
2325                  GL_UNSIGNED_INT_24_8, nullptr);
2326     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2327 
2328     GLFramebuffer dstFramebuffer;
2329     glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
2330     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
2331     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, stencilTexture, 1);
2332     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2333 
2334     // Blit stencil.
2335     glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFramebuffer);
2336     glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_STENCIL_BUFFER_BIT, GL_NEAREST);
2337 
2338     glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
2339 
2340     ASSERT_GL_NO_ERROR();
2341 
2342     // Clear to green
2343     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
2344     glClear(GL_COLOR_BUFFER_BIT);
2345     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2346 
2347     // Draw red if the stencil is 0x1, which should be true after the blit.
2348     glStencilFunc(GL_EQUAL, 0x1, 0xFF);
2349     drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.5f);
2350     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2351 
2352     ASSERT_GL_NO_ERROR();
2353 }
2354 
2355 // Test blitting to a stencil buffer with non-zero base.  Exercises the compute path in the Vulkan
2356 // backend if stencil export is not supported.  The blit is not 1-to-1 for this path to be taken.
TEST_P(BlitFramebufferTest,NonZeroBaseDestinationStencilStretch)2357 TEST_P(BlitFramebufferTest, NonZeroBaseDestinationStencilStretch)
2358 {
2359     // http://anglebug.com/5000
2360     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsWindows());
2361 
2362     // http://anglebug.com/5001
2363     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsMac());
2364 
2365     ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
2366 
2367     // Create a framebuffer for source data.
2368     GLRenderbuffer renderbuf;
2369     glBindRenderbuffer(GL_RENDERBUFFER, renderbuf);
2370     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 256, 256);
2371 
2372     GLFramebuffer srcFramebuffer;
2373     glBindFramebuffer(GL_FRAMEBUFFER, srcFramebuffer);
2374     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuf);
2375     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2376 
2377     // fill the stencil buffer with 0x1
2378     glStencilFunc(GL_ALWAYS, 0x1, 0xFF);
2379     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
2380     glEnable(GL_STENCIL_TEST);
2381     drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.5f);
2382 
2383     // Create a framebuffer with an attachment that has non-zero base
2384     GLTexture colorTexture;
2385     glBindTexture(GL_TEXTURE_2D, colorTexture);
2386     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);
2387 
2388     GLTexture stencilTexture;
2389     glBindTexture(GL_TEXTURE_2D, stencilTexture);
2390     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 256, 256, 0, GL_DEPTH_STENCIL,
2391                  GL_UNSIGNED_INT_24_8, nullptr);
2392     glTexImage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, 256, 256, 0, GL_DEPTH_STENCIL,
2393                  GL_UNSIGNED_INT_24_8, nullptr);
2394     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2395 
2396     GLFramebuffer dstFramebuffer;
2397     glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
2398     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
2399     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, stencilTexture, 1);
2400     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2401 
2402     // Blit stencil.  Note: stretch is intentional so vkCmdBlitImage cannot be used in the Vulkan
2403     // backend.
2404     glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFramebuffer);
2405     glBlitFramebuffer(0, 0, 256, 256, -256, -256, 512, 512, GL_STENCIL_BUFFER_BIT, GL_NEAREST);
2406 
2407     glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
2408 
2409     ASSERT_GL_NO_ERROR();
2410 
2411     // Clear to green
2412     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
2413     glClear(GL_COLOR_BUFFER_BIT);
2414     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2415 
2416     // Draw red if the stencil is 0x1, which should be true after the blit.
2417     glStencilFunc(GL_EQUAL, 0x1, 0xFF);
2418     drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.5f);
2419     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2420 
2421     ASSERT_GL_NO_ERROR();
2422 }
2423 
2424 // Blit an SRGB framebuffer and scale it.
TEST_P(BlitFramebufferTest,BlitSRGBToRGBAndScale)2425 TEST_P(BlitFramebufferTest, BlitSRGBToRGBAndScale)
2426 {
2427     constexpr const GLsizei kWidth  = 256;
2428     constexpr const GLsizei kHeight = 256;
2429 
2430     GLRenderbuffer sourceRBO, targetRBO;
2431     GLFramebuffer sourceFBO, targetFBO;
2432     initColorFBOWithCheckerPattern(&sourceFBO, &sourceRBO, GL_SRGB8_ALPHA8, kWidth * 2,
2433                                    kHeight * 2);
2434     initColorFBO(&targetFBO, &targetRBO, GL_RGBA8, kWidth, kHeight);
2435 
2436     EXPECT_GL_NO_ERROR();
2437 
2438     glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
2439     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
2440 
2441     glViewport(0, 0, kWidth, kHeight);
2442 
2443     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
2444     glClear(GL_COLOR_BUFFER_BIT);
2445 
2446     // Scale down without flipping.
2447     glBlitFramebuffer(0, 0, kWidth * 2, kHeight * 2, 0, 0, kWidth, kHeight, GL_COLOR_BUFFER_BIT,
2448                       GL_NEAREST);
2449 
2450     EXPECT_GL_NO_ERROR();
2451 
2452     glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
2453 
2454     EXPECT_PIXEL_COLOR_EQ(kWidth / 4, kHeight / 4, GLColor::red);
2455     EXPECT_PIXEL_COLOR_EQ(kWidth / 4, 3 * kHeight / 4, GLColor::green);
2456     EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, kHeight / 4, GLColor::blue);
2457     EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, 3 * kHeight / 4, GLColor::yellow);
2458 
2459     glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
2460     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
2461 
2462     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
2463     glClear(GL_COLOR_BUFFER_BIT);
2464 
2465     // Scale down and flip in the X direction.
2466     glBlitFramebuffer(0, 0, kWidth * 2, kHeight * 2, kWidth, 0, 0, kHeight, GL_COLOR_BUFFER_BIT,
2467                       GL_NEAREST);
2468 
2469     EXPECT_GL_NO_ERROR();
2470 
2471     glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
2472 
2473     EXPECT_PIXEL_COLOR_EQ(kWidth / 4, kHeight / 4, GLColor::blue);
2474     EXPECT_PIXEL_COLOR_EQ(kWidth / 4, 3 * kHeight / 4, GLColor::yellow);
2475     EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, kHeight / 4, GLColor::red);
2476     EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, 3 * kHeight / 4, GLColor::green);
2477 }
2478 
2479 // Blit stencil, with scissor and scale it.
TEST_P(BlitFramebufferTest,BlitStencilScissoredScaled)2480 TEST_P(BlitFramebufferTest, BlitStencilScissoredScaled)
2481 {
2482     constexpr GLint kSize = 256;
2483 
2484     // Create the destination framebuffer.
2485     GLTexture destColorbuf;
2486     glBindTexture(GL_TEXTURE_2D, destColorbuf);
2487     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
2488 
2489     GLRenderbuffer destRenderbuf;
2490     glBindRenderbuffer(GL_RENDERBUFFER, destRenderbuf);
2491     glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, kSize, kSize);
2492 
2493     GLFramebuffer destFBO;
2494     glBindFramebuffer(GL_FRAMEBUFFER, destFBO);
2495     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, destColorbuf,
2496                            0);
2497     glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2498                               destRenderbuf);
2499 
2500     // Clear the destination buffer with gray and 0x10 stencil.
2501     GLColor gray(127, 127, 127, 255);
2502     glClearStencil(0x10);
2503     glClearColor(0.499f, 0.499f, 0.499f, 1.0f);
2504     glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2505     EXPECT_PIXEL_COLOR_EQ(0, 0, gray);
2506     EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, gray);
2507 
2508     // Create the source framebuffer.
2509     GLRenderbuffer renderbuf;
2510     glBindRenderbuffer(GL_RENDERBUFFER, renderbuf);
2511     glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, kSize, kSize);
2512 
2513     ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
2514     ANGLE_GL_PROGRAM(drawGreen, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());
2515     ANGLE_GL_PROGRAM(drawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());
2516 
2517     GLFramebuffer sourceFBO;
2518     glBindFramebuffer(GL_FRAMEBUFFER, sourceFBO);
2519     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuf);
2520 
2521     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
2522 
2523     // Fill the stencil buffer with 0x1.
2524     glClearStencil(0x1);
2525     glClear(GL_STENCIL_BUFFER_BIT);
2526 
2527     // Fill a smaller region of the buffer with 0x2.
2528     glEnable(GL_SCISSOR_TEST);
2529     glEnable(GL_STENCIL_TEST);
2530     glScissor(kSize / 4, kSize / 4, kSize / 2, kSize / 2);
2531     glStencilFunc(GL_ALWAYS, 0x2, 0xFF);
2532     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
2533     drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.5f);
2534 
2535     // Blit and scale down into the destination framebuffer (with scissor still enabled).
2536     //
2537     // Source looks like this:
2538     //
2539     //     +----|----|----|----+
2540     //     |                   |
2541     //     |       0x1         |
2542     //     -    +---------+    -
2543     //     |    |         |    |
2544     //     |    |         |    |
2545     //     -    |   0x2   |    -
2546     //     |    |         |    |
2547     //     |    |         |    |
2548     //     -    +---------+    -
2549     //     |                   |
2550     //     |                   |
2551     //     +----|----|----|----+
2552     //
2553     // We want the destination to look like this:
2554     //
2555     //     +----|----|----|----+
2556     //     |                   |
2557     //     |       0x10        |
2558     //     -    +---------+    -
2559     //     |    |  0x1    |    |
2560     //     |    |  +------+    |
2561     //     -    |  |      |    -
2562     //     |    |  | 0x2  |    |
2563     //     |    |  |      |    |
2564     //     -    +--+------+    -
2565     //     |                   |
2566     //     |                   |
2567     //     +----|----|----|----+
2568     //
2569     // The corresponding blit would be: (0, 0, 3/4, 3/4) -> (1/4, 1/4, 3/4, 3/4).  For testing, we
2570     // would like to avoid having the destination area and scissor to match.  Using destination
2571     // area as (0, 0, 1, 1), and keeping the same scaling, the source area should be
2572     // (-3/8, -3/8, 9/8, 9/8).
2573     //
2574     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, destFBO);
2575     constexpr GLint kBlitSrc[2] = {-3 * kSize / 8, 9 * kSize / 8};
2576     glBlitFramebuffer(kBlitSrc[0], kBlitSrc[0], kBlitSrc[1], kBlitSrc[1], 0, 0, kSize, kSize,
2577                       GL_STENCIL_BUFFER_BIT, GL_NEAREST);
2578 
2579     glBindFramebuffer(GL_FRAMEBUFFER, destFBO);
2580 
2581     ASSERT_GL_NO_ERROR();
2582 
2583     // Draw blue if the stencil is 0x1, which should be true only in the top and left of the inner
2584     // square.
2585     glDisable(GL_SCISSOR_TEST);
2586     glStencilMask(0);
2587     glStencilFunc(GL_EQUAL, 0x1, 0xFF);
2588     drawQuad(drawBlue, essl3_shaders::PositionAttrib(), 0.5f);
2589     EXPECT_PIXEL_COLOR_EQ(0, 0, gray);
2590     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, gray);
2591     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, gray);
2592     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, gray);
2593 
2594     EXPECT_PIXEL_COLOR_EQ(kSize / 4, kSize / 4, GLColor::blue);
2595     EXPECT_PIXEL_COLOR_EQ(kSize / 4, 3 * kSize / 4 - 1, GLColor::blue);
2596     EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, kSize / 4, GLColor::blue);
2597 
2598     EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, gray);
2599     EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, 3 * kSize / 4 - 1, gray);
2600 
2601     // Draw red if the stencil is 0x2, which should be true in the bottom/right of the middle
2602     // square after the blit.
2603     glStencilFunc(GL_EQUAL, 0x2, 0xFF);
2604     drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.5f);
2605     EXPECT_PIXEL_COLOR_EQ(0, 0, gray);
2606     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, gray);
2607     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, gray);
2608     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, gray);
2609 
2610     EXPECT_PIXEL_COLOR_EQ(kSize / 4, kSize / 4, GLColor::blue);
2611     EXPECT_PIXEL_COLOR_EQ(kSize / 4, 3 * kSize / 4 - 1, GLColor::blue);
2612     EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, kSize / 4, GLColor::blue);
2613 
2614     EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::red);
2615     EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, 3 * kSize / 4 - 1, GLColor::red);
2616 
2617     // Draw green if the stencil is 0x10, which should be left untouched in the outer regions.
2618     glStencilFunc(GL_EQUAL, 0x10, 0xFF);
2619     drawQuad(drawGreen, essl3_shaders::PositionAttrib(), 0.5f);
2620     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2621     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::green);
2622     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::green);
2623     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::green);
2624 
2625     EXPECT_PIXEL_COLOR_EQ(kSize / 4, kSize / 4, GLColor::blue);
2626     EXPECT_PIXEL_COLOR_EQ(kSize / 4, 3 * kSize / 4 - 1, GLColor::blue);
2627     EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, kSize / 4, GLColor::blue);
2628 
2629     EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::red);
2630     EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, 3 * kSize / 4 - 1, GLColor::red);
2631 
2632     ASSERT_GL_NO_ERROR();
2633 }
2634 
2635 // Blit a subregion of an SRGB framebuffer to an RGB framebuffer.
TEST_P(BlitFramebufferTest,PartialBlitSRGBToRGB)2636 TEST_P(BlitFramebufferTest, PartialBlitSRGBToRGB)
2637 {
2638     constexpr const GLsizei kWidth  = 256;
2639     constexpr const GLsizei kHeight = 256;
2640 
2641     GLRenderbuffer sourceRBO, targetRBO;
2642     GLFramebuffer sourceFBO, targetFBO;
2643     initColorFBOWithCheckerPattern(&sourceFBO, &sourceRBO, GL_SRGB8_ALPHA8, kWidth * 2,
2644                                    kHeight * 2);
2645     initColorFBO(&targetFBO, &targetRBO, GL_RGBA8, kWidth, kHeight);
2646 
2647     EXPECT_GL_NO_ERROR();
2648 
2649     glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
2650     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
2651 
2652     glViewport(0, 0, kWidth, kHeight);
2653 
2654     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
2655     glClear(GL_COLOR_BUFFER_BIT);
2656 
2657     // Blit a part of the source FBO without flipping.
2658     glBlitFramebuffer(kWidth, kHeight, kWidth * 2, kHeight * 2, 0, 0, kWidth, kHeight,
2659                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
2660 
2661     EXPECT_GL_NO_ERROR();
2662 
2663     glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
2664 
2665     EXPECT_PIXEL_COLOR_EQ(kWidth / 4, kHeight / 4, GLColor::yellow);
2666     EXPECT_PIXEL_COLOR_EQ(kWidth / 4, 3 * kHeight / 4, GLColor::yellow);
2667     EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, kHeight / 4, GLColor::yellow);
2668     EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, 3 * kHeight / 4, GLColor::yellow);
2669 
2670     glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
2671     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
2672 
2673     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
2674     glClear(GL_COLOR_BUFFER_BIT);
2675 
2676     // Blit a part of the source FBO and flip in the X direction.
2677     glBlitFramebuffer(kWidth * 2, 0, kWidth, kHeight, kWidth, 0, 0, kHeight, GL_COLOR_BUFFER_BIT,
2678                       GL_NEAREST);
2679 
2680     EXPECT_GL_NO_ERROR();
2681 
2682     glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
2683 
2684     EXPECT_PIXEL_COLOR_EQ(kWidth / 4, kHeight / 4, GLColor::blue);
2685     EXPECT_PIXEL_COLOR_EQ(kWidth / 4, 3 * kHeight / 4, GLColor::blue);
2686     EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, kHeight / 4, GLColor::blue);
2687     EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, 3 * kHeight / 4, GLColor::blue);
2688 }
2689 
2690 // Blit an SRGB framebuffer with an oversized source area (parts outside the source area should be
2691 // clipped out).
TEST_P(BlitFramebufferTest,BlitSRGBToRGBOversizedSourceArea)2692 TEST_P(BlitFramebufferTest, BlitSRGBToRGBOversizedSourceArea)
2693 {
2694     constexpr const GLsizei kWidth  = 256;
2695     constexpr const GLsizei kHeight = 256;
2696 
2697     GLRenderbuffer sourceRBO, targetRBO;
2698     GLFramebuffer sourceFBO, targetFBO;
2699     initColorFBOWithCheckerPattern(&sourceFBO, &sourceRBO, GL_SRGB8_ALPHA8, kWidth, kHeight);
2700     initColorFBO(&targetFBO, &targetRBO, GL_RGBA8, kWidth, kHeight);
2701 
2702     EXPECT_GL_NO_ERROR();
2703 
2704     glViewport(0, 0, kWidth, kHeight);
2705 
2706     glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
2707     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
2708 
2709     glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
2710     glClear(GL_COLOR_BUFFER_BIT);
2711 
2712     // Blit so that the source area gets placed at the center of the target FBO.
2713     // The width of the source area is 1/4 of the width of the target FBO.
2714     glBlitFramebuffer(-3 * kWidth / 2, -3 * kHeight / 2, 5 * kWidth / 2, 5 * kHeight / 2, 0, 0,
2715                       kWidth, kHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2716 
2717     EXPECT_GL_NO_ERROR();
2718 
2719     glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
2720 
2721     // Source FBO colors can be found in the middle of the target FBO.
2722     EXPECT_PIXEL_COLOR_EQ(7 * kWidth / 16, 7 * kHeight / 16, GLColor::red);
2723     EXPECT_PIXEL_COLOR_EQ(7 * kWidth / 16, 9 * kHeight / 16, GLColor::green);
2724     EXPECT_PIXEL_COLOR_EQ(9 * kWidth / 16, 7 * kHeight / 16, GLColor::blue);
2725     EXPECT_PIXEL_COLOR_EQ(9 * kWidth / 16, 9 * kHeight / 16, GLColor::yellow);
2726 
2727     // Clear color should remain around the edges of the target FBO (WebGL 2.0 spec explicitly
2728     // requires this and ANGLE is expected to follow that).
2729     EXPECT_PIXEL_COLOR_EQ(kWidth / 4, kHeight / 4, GLColor::blue);
2730     EXPECT_PIXEL_COLOR_EQ(kWidth / 4, 3 * kHeight / 4, GLColor::blue);
2731     EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, kHeight / 4, GLColor::blue);
2732     EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, 3 * kHeight / 4, GLColor::blue);
2733 }
2734 
2735 // Blit an SRGB framebuffer with an oversized dest area (even though the result is clipped, it
2736 // should be scaled as if the whole dest area was used).
TEST_P(BlitFramebufferTest,BlitSRGBToRGBOversizedDestArea)2737 TEST_P(BlitFramebufferTest, BlitSRGBToRGBOversizedDestArea)
2738 {
2739     constexpr const GLsizei kWidth  = 256;
2740     constexpr const GLsizei kHeight = 256;
2741 
2742     GLRenderbuffer sourceRBO, targetRBO;
2743     GLFramebuffer sourceFBO, targetFBO;
2744     initColorFBOWithCheckerPattern(&sourceFBO, &sourceRBO, GL_SRGB8_ALPHA8, kWidth, kHeight);
2745     initColorFBO(&targetFBO, &targetRBO, GL_RGBA8, kWidth, kHeight);
2746 
2747     EXPECT_GL_NO_ERROR();
2748 
2749     glViewport(0, 0, kWidth, kHeight);
2750 
2751     glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
2752     glClear(GL_COLOR_BUFFER_BIT);
2753 
2754     // Dest is oversized but centered the same as source
2755     glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
2756     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
2757 
2758     glBlitFramebuffer(0, 0, kWidth, kHeight, -kWidth / 2, -kHeight / 2, 3 * kWidth / 2,
2759                       3 * kHeight / 2, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2760 
2761     EXPECT_GL_NO_ERROR();
2762 
2763     glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
2764 
2765     // Expected result:
2766     //
2767     //     +-------+-------+
2768     //     |       |       |
2769     //     |   R   |   B   |
2770     //     |       |       |
2771     //     +-------+-------+
2772     //     |       |       |
2773     //     |   G   |   Y   |
2774     //     |       |       |
2775     //     +-------+-------+
2776     //
2777     EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::red);
2778     EXPECT_PIXEL_COLOR_EQ(kWidth / 4, kHeight / 4, GLColor::red);
2779     EXPECT_PIXEL_COLOR_EQ(kWidth / 2 - 1, kHeight / 2 - 1, GLColor::red);
2780 
2781     EXPECT_PIXEL_COLOR_EQ(1, kWidth - 1, GLColor::green);
2782     EXPECT_PIXEL_COLOR_EQ(kWidth / 4, 3 * kHeight / 4, GLColor::green);
2783     EXPECT_PIXEL_COLOR_EQ(kWidth / 2 - 1, kHeight / 2 + 1, GLColor::green);
2784 
2785     EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 1, GLColor::blue);
2786     EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, kHeight / 4, GLColor::blue);
2787     EXPECT_PIXEL_COLOR_EQ(kWidth / 2 + 1, kHeight / 2 - 1, GLColor::blue);
2788 
2789     EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::yellow);
2790     EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, 3 * kHeight / 4, GLColor::yellow);
2791     EXPECT_PIXEL_COLOR_EQ(kWidth / 2 + 1, kHeight / 2 + 1, GLColor::yellow);
2792 
2793     // Dest is oversized in the negative direction
2794     glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
2795     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
2796 
2797     glBlitFramebuffer(0, 0, kWidth, kHeight, -kWidth / 2, -kHeight / 2, kWidth, kHeight,
2798                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
2799 
2800     EXPECT_GL_NO_ERROR();
2801 
2802     glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
2803 
2804     // Expected result:
2805     //
2806     //     Width / 4
2807     //         |
2808     //         V
2809     //     +---+-----------+
2810     //     | R |     B     |
2811     //     +---+-----------+ <- Height / 4
2812     //     |   |           |
2813     //     |   |           |
2814     //     | G |     Y     |
2815     //     |   |           |
2816     //     |   |           |
2817     //     +---+-----------+
2818     //
2819     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2820     EXPECT_PIXEL_COLOR_EQ(0, kHeight / 4 - 1, GLColor::red);
2821     EXPECT_PIXEL_COLOR_EQ(kWidth / 4 - 1, 0, GLColor::red);
2822     EXPECT_PIXEL_COLOR_EQ(kWidth / 4 - 1, kHeight / 4 - 1, GLColor::red);
2823     EXPECT_PIXEL_COLOR_EQ(kWidth / 8, kHeight / 8, GLColor::red);
2824 
2825     EXPECT_PIXEL_COLOR_EQ(0, kHeight / 4 + 1, GLColor::green);
2826     EXPECT_PIXEL_COLOR_EQ(0, kHeight - 1, GLColor::green);
2827     EXPECT_PIXEL_COLOR_EQ(kWidth / 4 - 1, kHeight / 4 + 1, GLColor::green);
2828     EXPECT_PIXEL_COLOR_EQ(kWidth / 4 - 1, kHeight - 1, GLColor::green);
2829     EXPECT_PIXEL_COLOR_EQ(kWidth / 8, kHeight / 2, GLColor::green);
2830 
2831     EXPECT_PIXEL_COLOR_EQ(kWidth / 4 + 1, 0, GLColor::blue);
2832     EXPECT_PIXEL_COLOR_EQ(kWidth / 4 + 1, kHeight / 4 - 1, GLColor::blue);
2833     EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 0, GLColor::blue);
2834     EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight / 4 - 1, GLColor::blue);
2835     EXPECT_PIXEL_COLOR_EQ(kWidth / 2, kHeight / 8, GLColor::blue);
2836 
2837     EXPECT_PIXEL_COLOR_EQ(kWidth / 4 + 1, kHeight / 4 + 1, GLColor::yellow);
2838     EXPECT_PIXEL_COLOR_EQ(kWidth / 4 + 1, kHeight - 1, GLColor::yellow);
2839     EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight / 4 + 1, GLColor::yellow);
2840     EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::yellow);
2841     EXPECT_PIXEL_COLOR_EQ(kWidth / 2, kHeight / 2, GLColor::yellow);
2842 
2843     // Dest is oversized in the positive direction
2844     glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
2845     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
2846 
2847     glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, 3 * kWidth / 2, 3 * kHeight / 2,
2848                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
2849 
2850     EXPECT_GL_NO_ERROR();
2851 
2852     glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
2853 
2854     // Expected result:
2855     //
2856     //           3 * Width / 4
2857     //                 |
2858     //                 V
2859     //     +-----------+---+
2860     //     |           |   |
2861     //     |           |   |
2862     //     |     R     | B |
2863     //     |           |   |
2864     //     |           |   |
2865     //     +-----------+---+ <- 3 * Height / 4
2866     //     |     G     | Y |
2867     //     +-----------+---+
2868     //
2869     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2870     EXPECT_PIXEL_COLOR_EQ(0, 3 * kHeight / 4 - 1, GLColor::red);
2871     EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 - 1, 0, GLColor::red);
2872     EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 - 1, 3 * kHeight / 4 - 1, GLColor::red);
2873     EXPECT_PIXEL_COLOR_EQ(kWidth / 2, kHeight / 2, GLColor::red);
2874 
2875     EXPECT_PIXEL_COLOR_EQ(0, 3 * kHeight / 4 + 1, GLColor::green);
2876     EXPECT_PIXEL_COLOR_EQ(0, kHeight - 1, GLColor::green);
2877     EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 - 1, 3 * kHeight / 4 + 1, GLColor::green);
2878     EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 - 1, kHeight - 1, GLColor::green);
2879     EXPECT_PIXEL_COLOR_EQ(kWidth / 2, 7 * kHeight / 8, GLColor::green);
2880 
2881     EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 + 1, 0, GLColor::blue);
2882     EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 + 1, 3 * kHeight / 4 - 1, GLColor::blue);
2883     EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 0, GLColor::blue);
2884     EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 3 * kHeight / 4 - 1, GLColor::blue);
2885     EXPECT_PIXEL_COLOR_EQ(7 * kWidth / 8, kHeight / 2, GLColor::blue);
2886 
2887     EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 + 1, 3 * kHeight / 4 + 1, GLColor::yellow);
2888     EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 + 1, kHeight - 1, GLColor::yellow);
2889     EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 3 * kHeight / 4 + 1, GLColor::yellow);
2890     EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::yellow);
2891     EXPECT_PIXEL_COLOR_EQ(7 * kWidth / 8, 7 * kHeight / 8, GLColor::yellow);
2892 }
2893 
2894 // This test is to demonstrate a bug that when a program is created and used and then destroyed, we
2895 // should not have a dangling PipelineHelper pointer in the context point to the already destroyed
2896 // object.
TEST_P(BlitFramebufferTest,useAndDestroyProgramThenBlit)2897 TEST_P(BlitFramebufferTest, useAndDestroyProgramThenBlit)
2898 {
2899     constexpr const GLsizei kWidth  = 256;
2900     constexpr const GLsizei kHeight = 256;
2901 
2902     GLRenderbuffer sourceRBO, targetRBO;
2903     GLFramebuffer sourceFBO, targetFBO;
2904 
2905     {
2906         initColorFBO(&sourceFBO, &sourceRBO, GL_SRGB8_ALPHA8, kWidth, kHeight);
2907         // checkerProgram will be created and destroyed in this code block
2908         ANGLE_GL_PROGRAM(checkerProgram, essl1_shaders::vs::Passthrough(),
2909                          essl1_shaders::fs::Checkered());
2910         glViewport(0, 0, kWidth, kHeight);
2911         glBindFramebuffer(GL_FRAMEBUFFER, sourceFBO);
2912         drawQuad(checkerProgram, essl1_shaders::PositionAttrib(), 0.5f);
2913         EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::red);
2914     }
2915     initColorFBO(&targetFBO, &targetRBO, GL_RGBA8, kWidth, kHeight);
2916     EXPECT_GL_NO_ERROR();
2917 
2918     glViewport(0, 0, kWidth, kHeight);
2919     glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
2920     glClear(GL_COLOR_BUFFER_BIT);
2921 
2922     // Blit call should not crash or assert
2923     glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
2924     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
2925     glBlitFramebuffer(0, 0, kWidth, kHeight, -kWidth / 2, -kHeight / 2, 3 * kWidth / 2,
2926                       3 * kHeight / 2, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2927     EXPECT_GL_NO_ERROR();
2928 }
2929 
2930 // This test is to ensure the draw after blit without any state change works properly
TEST_P(BlitFramebufferTest,drawBlitAndDrawAgain)2931 TEST_P(BlitFramebufferTest, drawBlitAndDrawAgain)
2932 {
2933     constexpr const GLsizei kWidth  = 256;
2934     constexpr const GLsizei kHeight = 256;
2935 
2936     GLRenderbuffer srcColorRB, srcDepthRB;
2937     GLFramebuffer srcFBO;
2938 
2939     ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Red());
2940     ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Green());
2941     ANGLE_GL_PROGRAM(drawBlue, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Blue());
2942 
2943     // Initialize source FBO with red color and depth==0.8f
2944     initFBOWithProgramAndDepth(&srcFBO, &srcColorRB, GL_RGBA8, &srcDepthRB, GL_DEPTH24_STENCIL8_OES,
2945                                kWidth, kHeight, drawRed, 0.8f);
2946     EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::red);
2947 
2948     // Initialize destination FBO and initialize to green and depth==0.7
2949     initFBOWithProgramAndDepth(nullptr, nullptr, 0, nullptr, 0, kWidth, kHeight, drawGreen, 0.7f);
2950     EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::green);
2951 
2952     // Setup for draw-blit-draw use pattern
2953     glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFBO);
2954     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
2955     std::array<Vector3, 6> quadVertices = GetQuadVertices();
2956     constexpr size_t kBufferSize        = sizeof(quadVertices[0]) * quadVertices.size();
2957     GLBuffer vertexBuffer;
2958     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
2959     glBufferData(GL_ARRAY_BUFFER, kBufferSize, nullptr, GL_STATIC_DRAW);
2960     glUseProgram(drawBlue);
2961     const GLint positionLocation = glGetAttribLocation(drawBlue, essl1_shaders::PositionAttrib());
2962     ASSERT_NE(-1, positionLocation);
2963     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
2964     glEnableVertexAttribArray(positionLocation);
2965 
2966     // Draw with depth=0.75, should fail depth test
2967     drawWithDepthValue(quadVertices, 0.75f);
2968     // Now blit  depth buffer from source FBO to the right half of destination FBO, so left half has
2969     // depth 0.7f and right half has 0.8f
2970     glBlitFramebuffer(kWidth / 2, 0, kWidth, kHeight, kWidth / 2, 0, kWidth, kHeight,
2971                       GL_DEPTH_BUFFER_BIT, GL_NEAREST);
2972     // Continue draw without state change and depth==0.75f, now it should pass depth test on right
2973     // half
2974     glDrawArrays(GL_TRIANGLES, 0, 6);
2975 
2976     // Now verify dstFBO
2977     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
2978     EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::green);
2979     EXPECT_PIXEL_COLOR_EQ(kWidth / 2 + 1, 1, GLColor::blue);
2980     EXPECT_GL_NO_ERROR();
2981 }
2982 
2983 // This test is to ensure the scissored draw after blit without any state change works properly
TEST_P(BlitFramebufferTest,scissorDrawBlitAndDrawAgain)2984 TEST_P(BlitFramebufferTest, scissorDrawBlitAndDrawAgain)
2985 {
2986     constexpr const GLsizei kWidth  = 256;
2987     constexpr const GLsizei kHeight = 256;
2988 
2989     GLRenderbuffer srcColorRB, srcDepthRB;
2990     GLFramebuffer srcFBO;
2991 
2992     ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Red());
2993     ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Green());
2994     ANGLE_GL_PROGRAM(drawBlue, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Blue());
2995 
2996     // Initialize source FBO with red color and depth==0.8f
2997     initFBOWithProgramAndDepth(&srcFBO, &srcColorRB, GL_RGBA8, &srcDepthRB, GL_DEPTH24_STENCIL8_OES,
2998                                kWidth, kHeight, drawRed, 0.8f);
2999     EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::red);
3000 
3001     // Initialize destination FBO and initialize to green and depth==0.7
3002     initFBOWithProgramAndDepth(nullptr, nullptr, 0, nullptr, 0, kWidth, kHeight, drawGreen, 0.7f);
3003     EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::green);
3004 
3005     // Setup for draw-blit-draw use pattern
3006     glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFBO);
3007     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
3008     std::array<Vector3, 6> quadVertices = GetQuadVertices();
3009     constexpr size_t kBufferSize        = sizeof(quadVertices[0]) * quadVertices.size();
3010     GLBuffer vertexBuffer;
3011     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
3012     glBufferData(GL_ARRAY_BUFFER, kBufferSize, nullptr, GL_STATIC_DRAW);
3013     glUseProgram(drawBlue);
3014     const GLint positionLocation = glGetAttribLocation(drawBlue, essl1_shaders::PositionAttrib());
3015     ASSERT_NE(-1, positionLocation);
3016     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
3017     glEnableVertexAttribArray(positionLocation);
3018 
3019     // Scissored draw with depth=0.75, should fail depth test
3020     glEnable(GL_SCISSOR_TEST);
3021     glScissor(0, 0, kWidth, kHeight / 2);
3022     drawWithDepthValue(quadVertices, 0.75f);
3023     // Now blit  depth buffer from source FBO to the right half of destination FBO, so left half has
3024     // depth 0.7f and right half has 0.8f
3025     glBlitFramebuffer(kWidth / 2, 0, kWidth, kHeight, kWidth / 2, 0, kWidth, kHeight,
3026                       GL_DEPTH_BUFFER_BIT, GL_NEAREST);
3027     // Continue draw without state change and depth==0.75f, now it should pass depth test on right
3028     // half
3029     glDrawArrays(GL_TRIANGLES, 0, 6);
3030 
3031     // Now verify dstFBO
3032     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
3033     EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::green);
3034     EXPECT_PIXEL_COLOR_EQ(kWidth / 2 + 1, 1, GLColor::blue);
3035     EXPECT_PIXEL_COLOR_EQ(1, kHeight - 1, GLColor::green);
3036     EXPECT_PIXEL_COLOR_EQ(kWidth / 2 + 1, kHeight - 1, GLColor::green);
3037     EXPECT_GL_NO_ERROR();
3038 }
3039 
3040 // Test blitFramebuffer size overflow checks. WebGL 2.0 spec section 5.41. We do validation for
3041 // overflows also in non-WebGL mode to avoid triggering driver bugs.
TEST_P(BlitFramebufferTest,BlitFramebufferSizeOverflow)3042 TEST_P(BlitFramebufferTest, BlitFramebufferSizeOverflow)
3043 {
3044     GLTexture textures[2];
3045     glBindTexture(GL_TEXTURE_2D, textures[0]);
3046     glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, 4, 4);
3047     glBindTexture(GL_TEXTURE_2D, textures[1]);
3048     glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, 4, 4);
3049 
3050     GLFramebuffer framebuffers[2];
3051     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffers[0]);
3052     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffers[1]);
3053 
3054     ASSERT_GL_NO_ERROR();
3055 
3056     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0],
3057                            0);
3058     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1],
3059                            0);
3060     ASSERT_GL_NO_ERROR();
3061 
3062     // srcX
3063     glBlitFramebuffer(-1, 0, std::numeric_limits<GLint>::max(), 4, 0, 0, 4, 4, GL_COLOR_BUFFER_BIT,
3064                       GL_NEAREST);
3065     EXPECT_GL_ERROR(GL_INVALID_VALUE);
3066     glBlitFramebuffer(std::numeric_limits<GLint>::max(), 0, -1, 4, 0, 0, 4, 4, GL_COLOR_BUFFER_BIT,
3067                       GL_NEAREST);
3068     EXPECT_GL_ERROR(GL_INVALID_VALUE);
3069 
3070     // srcY
3071     glBlitFramebuffer(0, -1, 4, std::numeric_limits<GLint>::max(), 0, 0, 4, 4, GL_COLOR_BUFFER_BIT,
3072                       GL_NEAREST);
3073     EXPECT_GL_ERROR(GL_INVALID_VALUE);
3074     glBlitFramebuffer(0, std::numeric_limits<GLint>::max(), 4, -1, 0, 0, 4, 4, GL_COLOR_BUFFER_BIT,
3075                       GL_NEAREST);
3076     EXPECT_GL_ERROR(GL_INVALID_VALUE);
3077 
3078     // dstX
3079     glBlitFramebuffer(0, 0, 4, 4, -1, 0, std::numeric_limits<GLint>::max(), 4, GL_COLOR_BUFFER_BIT,
3080                       GL_NEAREST);
3081     EXPECT_GL_ERROR(GL_INVALID_VALUE);
3082     glBlitFramebuffer(0, 0, 4, 4, std::numeric_limits<GLint>::max(), 0, -1, 4, GL_COLOR_BUFFER_BIT,
3083                       GL_NEAREST);
3084     EXPECT_GL_ERROR(GL_INVALID_VALUE);
3085 
3086     // dstY
3087     glBlitFramebuffer(0, 0, 4, 4, 0, -1, 4, std::numeric_limits<GLint>::max(), GL_COLOR_BUFFER_BIT,
3088                       GL_NEAREST);
3089     EXPECT_GL_ERROR(GL_INVALID_VALUE);
3090     glBlitFramebuffer(0, 0, 4, 4, 0, std::numeric_limits<GLint>::max(), 4, -1, GL_COLOR_BUFFER_BIT,
3091                       GL_NEAREST);
3092     EXPECT_GL_ERROR(GL_INVALID_VALUE);
3093 }
3094 
3095 // Test blitFramebuffer size overflow checks. WebGL 2.0 spec section 5.41. Similar to above test,
3096 // but this test more accurately duplicates the behavior of the WebGL test
3097 // conformance2/rendering/blitframebuffer-size-overflow.html, which covers a few more edge cases.
TEST_P(BlitFramebufferTest,BlitFramebufferSizeOverflow2)3098 TEST_P(BlitFramebufferTest, BlitFramebufferSizeOverflow2)
3099 {
3100     GLTexture textures[2];
3101     glBindTexture(GL_TEXTURE_2D, textures[0]);
3102     glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, 4, 4);
3103     glBindTexture(GL_TEXTURE_2D, textures[1]);
3104     glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, 4, 4);
3105 
3106     GLFramebuffer framebuffers[2];
3107     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffers[0]);
3108     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffers[1]);
3109 
3110     ASSERT_GL_NO_ERROR();
3111 
3112     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0],
3113                            0);
3114     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1],
3115                            0);
3116     ASSERT_GL_NO_ERROR();
3117 
3118     GLint width  = 8;
3119     GLint height = 8;
3120 
3121     GLTexture tex0;
3122     glBindTexture(GL_TEXTURE_2D, tex0);
3123     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
3124 
3125     GLFramebuffer fb0;
3126     glBindFramebuffer(GL_READ_FRAMEBUFFER, fb0);
3127     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex0, 0);
3128 
3129     GLTexture tex1;
3130     glBindTexture(GL_TEXTURE_2D, tex1);
3131     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
3132 
3133     GLFramebuffer fb1;
3134     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb1);
3135     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex1, 0);
3136 
3137     GLint max = std::numeric_limits<GLint>::max();
3138     // Using max 32-bit integer as blitFramebuffer parameter should succeed.
3139     glBlitFramebuffer(0, 0, max, max, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3140     glBlitFramebuffer(0, 0, width, height, 0, 0, max, max, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3141     glBlitFramebuffer(0, 0, max, max, 0, 0, max, max, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3142     EXPECT_GL_NO_ERROR();
3143 
3144     // Using blitFramebuffer parameters where calculated width/height matches max 32-bit integer
3145     // should succeed
3146     glBlitFramebuffer(-1, -1, max - 1, max - 1, 0, 0, width, height, GL_COLOR_BUFFER_BIT,
3147                       GL_NEAREST);
3148     glBlitFramebuffer(0, 0, width, height, -1, -1, max - 1, max - 1, GL_COLOR_BUFFER_BIT,
3149                       GL_NEAREST);
3150     glBlitFramebuffer(-1, -1, max - 1, max - 1, -1, -1, max - 1, max - 1, GL_COLOR_BUFFER_BIT,
3151                       GL_NEAREST);
3152     EXPECT_GL_NO_ERROR();
3153 
3154     // Using source width/height greater than max 32-bit integer should fail.
3155     glBlitFramebuffer(-1, -1, max, max, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3156     EXPECT_GL_ERROR(GL_INVALID_VALUE);
3157 
3158     // Using source width/height greater than max 32-bit integer should fail.
3159     glBlitFramebuffer(max, max, -1, -1, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3160     EXPECT_GL_ERROR(GL_INVALID_VALUE);
3161 
3162     // Using destination width/height greater than max 32-bit integer should fail.
3163     glBlitFramebuffer(0, 0, width, height, -1, -1, max, max, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3164     EXPECT_GL_ERROR(GL_INVALID_VALUE);
3165 
3166     // Using destination width/height greater than max 32-bit integer should fail.
3167     glBlitFramebuffer(0, 0, width, height, max, max, -1, -1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3168     EXPECT_GL_ERROR(GL_INVALID_VALUE);
3169 
3170     // Using both source and destination width/height greater than max 32-bit integer should fail.
3171     glBlitFramebuffer(-1, -1, max, max, -1, -1, max, max, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3172     EXPECT_GL_ERROR(GL_INVALID_VALUE);
3173 
3174     // Using minimum and maximum integers for all boundaries should fail.
3175     glBlitFramebuffer(-max - 1, -max - 1, max, max, -max - 1, -max - 1, max, max,
3176                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
3177     EXPECT_GL_ERROR(GL_INVALID_VALUE);
3178 }
3179 
3180 // Test an edge case in D3D11 stencil blitting on the CPU that does not properly clip the
3181 // destination regions
TEST_P(BlitFramebufferTest,BlitFramebufferStencilClipNoIntersection)3182 TEST_P(BlitFramebufferTest, BlitFramebufferStencilClipNoIntersection)
3183 {
3184     GLFramebuffer framebuffers[2];
3185     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffers[0]);
3186     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffers[1]);
3187 
3188     GLRenderbuffer renderbuffers[2];
3189     glBindRenderbuffer(GL_RENDERBUFFER, renderbuffers[0]);
3190     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 4, 4);
3191     glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
3192                               renderbuffers[0]);
3193 
3194     glBindRenderbuffer(GL_RENDERBUFFER, renderbuffers[1]);
3195     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 4, 4);
3196     glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
3197                               renderbuffers[1]);
3198 
3199     glBlitFramebuffer(0, 0, 4, 4, 1 << 24, 1 << 24, 1 << 25, 1 << 25, GL_STENCIL_BUFFER_BIT,
3200                       GL_NEAREST);
3201     EXPECT_GL_NO_ERROR();
3202 }
3203 
3204 // Covers an edge case with blitting borderline values.
TEST_P(BlitFramebufferTest,OOBWrite)3205 TEST_P(BlitFramebufferTest, OOBWrite)
3206 {
3207     constexpr size_t length = 0x100000;
3208     GLFramebuffer rfb;
3209     GLFramebuffer dfb;
3210     GLRenderbuffer rb1;
3211     GLRenderbuffer rb2;
3212     glBindFramebuffer(GL_READ_FRAMEBUFFER, rfb);
3213     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dfb);
3214     glBindRenderbuffer(GL_RENDERBUFFER, rb1);
3215     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 0x1000, 2);
3216     glBindRenderbuffer(GL_RENDERBUFFER, rb2);
3217     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 2, 2);
3218     glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
3219                               rb1);
3220     glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
3221                               rb2);
3222     glBlitFramebuffer(1, 0, 0, 1, 1, 0, (2147483648 / 2) - (length / 4) + 1, 1,
3223                       GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
3224     ASSERT_GL_NO_ERROR();
3225 }
3226 
3227 // Test that flipped blits don't have off-by-one errors
TEST_P(BlitFramebufferTest,FlippedBlits)3228 TEST_P(BlitFramebufferTest, FlippedBlits)
3229 {
3230     constexpr const GLsizei kWidth  = 11;
3231     constexpr const GLsizei kHeight = 19;
3232     glViewport(0, 0, kWidth, kHeight);
3233 
3234     GLRenderbuffer srcColorRB, srcDepthRB, dstColorRB, dstDepthRB;
3235     GLFramebuffer srcFBO, dstFBO;
3236 
3237     ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Red());
3238     ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Green());
3239     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
3240     glUseProgram(drawColor);
3241     GLint colorLoc = glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
3242     ASSERT_NE(colorLoc, -1);
3243 
3244     // Create source and dest FBOs
3245     glBindRenderbuffer(GL_RENDERBUFFER, srcColorRB);
3246     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kWidth, kHeight);
3247     glBindRenderbuffer(GL_RENDERBUFFER, srcDepthRB);
3248     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, kWidth, kHeight);
3249 
3250     glBindFramebuffer(GL_FRAMEBUFFER, srcFBO);
3251     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, srcColorRB);
3252     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
3253                               srcDepthRB);
3254 
3255     glBindRenderbuffer(GL_RENDERBUFFER, dstColorRB);
3256     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kWidth, kHeight);
3257     glBindRenderbuffer(GL_RENDERBUFFER, dstDepthRB);
3258     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, kWidth, kHeight);
3259 
3260     glBindFramebuffer(GL_FRAMEBUFFER, dstFBO);
3261     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, dstColorRB);
3262     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
3263                               dstDepthRB);
3264 
3265     // Fill the source framebuffer with differring values per pixel, so off-by-one errors are more
3266     // easily found.
3267     glEnable(GL_SCISSOR_TEST);
3268     glEnable(GL_DEPTH_TEST);
3269     glDepthFunc(GL_ALWAYS);
3270     glDepthMask(GL_TRUE);
3271     glEnable(GL_STENCIL_TEST);
3272     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
3273     glStencilMask(0xFF);
3274 
3275     auto makeColor = [](GLsizei row, GLsizei col) -> GLColor {
3276         return GLColor(row * 255 / kHeight, col * 255 / kWidth, (row * 7 + col * 11) % 256, 255);
3277     };
3278     auto makeDepth = [](GLsizei row, GLsizei col) -> float {
3279         return 1.8f * ((row * kWidth + col) % 33 / 32.0f) - 0.9f;
3280     };
3281     auto makeStencil = [](GLsizei row, GLsizei col) -> uint8_t {
3282         return (col * kHeight + row) & 0xFF;
3283     };
3284 
3285     glBindFramebuffer(GL_FRAMEBUFFER, srcFBO);
3286     glUseProgram(drawColor);
3287     for (GLsizei row = 0; row < kHeight; ++row)
3288     {
3289         for (GLsizei col = 0; col < kWidth; ++col)
3290         {
3291             glScissor(col, row, 1, 1);
3292 
3293             glUniform4fv(colorLoc, 1, makeColor(row, col).toNormalizedVector().data());
3294             glStencilFunc(GL_ALWAYS, makeStencil(row, col), 0xFF);
3295             drawQuad(drawColor, essl1_shaders::PositionAttrib(), makeDepth(row, col));
3296         }
3297     }
3298 
3299     glDepthFunc(GL_LESS);
3300     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
3301 
3302     auto test = [&](int testIndex, bool flipX, bool flipY, GLint srcOffsetX, GLint srcOffsetY,
3303                     GLint dstOffsetX, GLint dstOffsetY, GLint width, GLint height) {
3304         glDisable(GL_SCISSOR_TEST);
3305         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dstFBO);
3306         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3307 
3308         glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFBO);
3309 
3310         const GLint srcX0 = srcOffsetX;
3311         const GLint srcY0 = srcOffsetY;
3312         const GLint srcX1 = srcOffsetX + width;
3313         const GLint srcY1 = srcOffsetY + height;
3314 
3315         const GLint dstX0 = flipX ? dstOffsetX + width : dstOffsetX;
3316         const GLint dstY0 = flipY ? dstOffsetY + height : dstOffsetY;
3317         const GLint dstX1 = flipX ? dstOffsetX : dstOffsetX + width;
3318         const GLint dstY1 = flipY ? dstOffsetY : dstOffsetY + height;
3319 
3320         glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
3321                           GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
3322                           GL_NEAREST);
3323 
3324         // Verify results
3325         glBindFramebuffer(GL_READ_FRAMEBUFFER, dstFBO);
3326 
3327         for (GLsizei row = 0; row < height; ++row)
3328         {
3329             for (GLsizei col = 0; col < width; ++col)
3330             {
3331                 const GLint srcPixelX = col + srcOffsetX;
3332                 const GLint srcPixelY = row + srcOffsetY;
3333                 const GLint dstPixelX = dstOffsetX + (flipX ? width - 1 - col : col);
3334                 const GLint dstPixelY = dstOffsetY + (flipY ? height - 1 - row : row);
3335 
3336                 const GLColor expectColor   = makeColor(srcPixelY, srcPixelX);
3337                 const float expectDepth     = makeDepth(srcPixelY, srcPixelX);
3338                 const uint8_t expectStencil = makeStencil(srcPixelY, srcPixelX);
3339 
3340                 // Verify color
3341                 EXPECT_PIXEL_COLOR_EQ(dstPixelX, dstPixelY, expectColor)
3342                     << testIndex << " " << flipX << " " << flipY << " " << row << " " << col;
3343 
3344                 glEnable(GL_SCISSOR_TEST);
3345                 glScissor(dstPixelX, dstPixelY, 1, 1);
3346 
3347                 // Verify depth and stencil
3348                 glStencilFunc(GL_EQUAL, expectStencil, 0xFF);
3349                 drawQuad(drawRed, essl1_shaders::PositionAttrib(), expectDepth - 0.05);
3350                 drawQuad(drawGreen, essl1_shaders::PositionAttrib(), expectDepth + 0.05);
3351 
3352                 EXPECT_PIXEL_COLOR_EQ(dstPixelX, dstPixelY, GLColor::red)
3353                     << testIndex << " " << flipX << " " << flipY << " " << row << " " << col;
3354             }
3355         }
3356     };
3357 
3358     for (int flipX = 0; flipX < 2; ++flipX)
3359     {
3360         for (int flipY = 0; flipY < 2; ++flipY)
3361         {
3362             // Test 0, full sized blit
3363             test(0, flipX != 0, flipY != 0, 0, 0, 0, 0, kWidth, kHeight);
3364             // Test 1, blit only one pixel
3365             test(1, flipX != 0, flipY != 0, kWidth / 3, kHeight / 7, 2 * kWidth / 5,
3366                  3 * kHeight / 4, 1, 1);
3367             // Test 2, random region
3368             test(2, flipX != 0, flipY != 0, kWidth / 5, 2 * kHeight / 7, kWidth / 6, kHeight / 4,
3369                  kWidth / 2, kHeight / 2);
3370         }
3371     }
3372 }
3373 
3374 // Test blitting a depthStencil buffer with multiple depth values to a larger size.
TEST_P(BlitFramebufferTest,BlitDepthStencilPixelByPixel)3375 TEST_P(BlitFramebufferTest, BlitDepthStencilPixelByPixel)
3376 {
3377     BlitDepthStencilPixelByPixelTestHelper(false /* mesaYFlip */);
3378 }
3379 
3380 // Same as BlitDepthStencilPixelByPixel, but with y-flip flag set.
TEST_P(BlitFramebufferTest,BlitDepthStencilPixelByPixelMesaYFlip)3381 TEST_P(BlitFramebufferTest, BlitDepthStencilPixelByPixelMesaYFlip)
3382 {
3383     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
3384 
3385     BlitDepthStencilPixelByPixelTestHelper(true /* mesaYFlip */);
3386 }
3387 
3388 // Regression test for a bug in the Vulkan backend where vkCmdResolveImage was used with
3389 // out-of-bounds regions.
TEST_P(BlitFramebufferTestES31,OOBResolve)3390 TEST_P(BlitFramebufferTestES31, OOBResolve)
3391 {
3392     constexpr GLint kWidth  = 16;
3393     constexpr GLint kHeight = 32;
3394 
3395     // Read framebuffer is multisampled.
3396     GLTexture readTexture;
3397     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, readTexture);
3398     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kWidth, kHeight, GL_TRUE);
3399 
3400     GLFramebuffer readFbo;
3401     glBindFramebuffer(GL_FRAMEBUFFER, readFbo);
3402     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
3403                            readTexture, 0);
3404     ASSERT_GL_NO_ERROR();
3405     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3406 
3407     glClearColor(1, 0, 0, 1);
3408     glClear(GL_COLOR_BUFFER_BIT);
3409 
3410     // Draw framebuffer is single sampled.
3411     GLTexture drawTexture;
3412     glBindTexture(GL_TEXTURE_2D, drawTexture);
3413     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3414                  nullptr);
3415     glGenerateMipmap(GL_TEXTURE_2D);
3416 
3417     GLFramebuffer drawFbo;
3418     glBindFramebuffer(GL_FRAMEBUFFER, drawFbo);
3419     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, drawTexture, 0);
3420     ASSERT_GL_NO_ERROR();
3421     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3422 
3423     glClearColor(0, 1, 0, 1);
3424     glClear(GL_COLOR_BUFFER_BIT);
3425     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
3426 
3427     // Resolve the read framebuffer, using bounds that are outside the size of the image.
3428     glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
3429     glBlitFramebuffer(-kWidth * 2, -kHeight * 3, kWidth * 11, kHeight * 8, -kWidth * 2,
3430                       -kHeight * 3, kWidth * 11, kHeight * 8, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3431     ASSERT_GL_NO_ERROR();
3432 
3433     glBindFramebuffer(GL_READ_FRAMEBUFFER, drawFbo);
3434     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);
3435 }
3436 
3437 // Regression test for a bug in the Vulkan backend where vkCmdResolveImage was using the src extents
3438 // as the resolve area instead of the area passed to glBlitFramebuffer.
TEST_P(BlitFramebufferTestES31,PartialResolve)3439 TEST_P(BlitFramebufferTestES31, PartialResolve)
3440 {
3441     constexpr GLint kWidth  = 16;
3442     constexpr GLint kHeight = 32;
3443 
3444     // Read framebuffer is multisampled.
3445     GLTexture readTexture;
3446     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, readTexture);
3447     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kWidth, kHeight, GL_TRUE);
3448 
3449     GLFramebuffer readFbo;
3450     glBindFramebuffer(GL_FRAMEBUFFER, readFbo);
3451     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
3452                            readTexture, 0);
3453     ASSERT_GL_NO_ERROR();
3454     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3455 
3456     glClearColor(1, 0, 0, 1);
3457     glClear(GL_COLOR_BUFFER_BIT);
3458 
3459     // Draw framebuffer is single sampled.  It's bound to a texture with base level the same size as
3460     // the read framebuffer, but it's bound to mip 1.
3461     GLTexture drawTexture;
3462     glBindTexture(GL_TEXTURE_2D, drawTexture);
3463     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3464                  nullptr);
3465     glGenerateMipmap(GL_TEXTURE_2D);
3466 
3467     GLFramebuffer drawFbo;
3468     glBindFramebuffer(GL_FRAMEBUFFER, drawFbo);
3469     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, drawTexture, 1);
3470     ASSERT_GL_NO_ERROR();
3471     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3472 
3473     glClearColor(0, 1, 0, 1);
3474     glClear(GL_COLOR_BUFFER_BIT);
3475     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth / 2, kHeight / 2, GLColor::green);
3476 
3477     constexpr GLint kResolveX0 = 1;
3478     constexpr GLint kResolveY0 = 2;
3479     constexpr GLint kResolveX1 = 4;
3480     constexpr GLint kResolveY1 = 6;
3481 
3482     // Resolve only a portion of the read framebuffer.
3483     glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
3484     glBlitFramebuffer(kResolveX0, kResolveY0, kResolveX1, kResolveY1, kResolveX0, kResolveY0,
3485                       kResolveX1, kResolveY1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3486     ASSERT_GL_NO_ERROR();
3487 
3488     glBindFramebuffer(GL_READ_FRAMEBUFFER, drawFbo);
3489     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth / 2, kResolveY0, GLColor::green);
3490     EXPECT_PIXEL_RECT_EQ(0, 0, kResolveX0, kHeight / 2, GLColor::green);
3491     EXPECT_PIXEL_RECT_EQ(kResolveX1, 0, kWidth / 2 - kResolveX1, kHeight / 2, GLColor::green);
3492     EXPECT_PIXEL_RECT_EQ(0, kResolveY1, kWidth / 2, kHeight / 2 - kResolveY1, GLColor::green);
3493 
3494     EXPECT_PIXEL_RECT_EQ(kResolveX0, kResolveY0, kResolveX1 - kResolveX0, kResolveY1 - kResolveY0,
3495                          GLColor::red);
3496 }
3497 
3498 // Test that a draw call to a small FBO followed by a resolve of a large FBO works.
TEST_P(BlitFramebufferTestES31,DrawToSmallFBOThenResolveLargeFBO)3499 TEST_P(BlitFramebufferTestES31, DrawToSmallFBOThenResolveLargeFBO)
3500 {
3501     GLFramebuffer fboMS[2];
3502     GLTexture textureMS[2];
3503     GLFramebuffer fboSS;
3504     GLTexture textureSS;
3505 
3506     // A bug in the Vulkan backend grew the render area of the previous render pass on blit, even
3507     // though the previous render pass belonged to an unrelated framebuffer.  This test only needs
3508     // to make sure that the FBO being resolved is not strictly smaller than the previous FBO which
3509     // was drawn to.
3510     constexpr GLsizei kLargeWidth  = 127;
3511     constexpr GLsizei kLargeHeight = 54;
3512     constexpr GLsizei kSmallWidth  = 37;
3513     constexpr GLsizei kSmallHeight = 79;
3514 
3515     ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
3516 
3517     // Create resolve target.
3518     glBindTexture(GL_TEXTURE_2D, textureSS);
3519     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kLargeWidth, kLargeHeight);
3520 
3521     glBindFramebuffer(GL_FRAMEBUFFER, fboSS);
3522     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureSS, 0);
3523     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3524 
3525     // Create multisampled framebuffers and draw into them one by one.
3526     for (size_t fboIndex = 0; fboIndex < 2; ++fboIndex)
3527     {
3528         const GLsizei width  = fboIndex == 0 ? kLargeWidth : kSmallWidth;
3529         const GLsizei height = fboIndex == 0 ? kLargeHeight : kSmallHeight;
3530 
3531         glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textureMS[fboIndex]);
3532         glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, width, height, GL_TRUE);
3533 
3534         glBindFramebuffer(GL_FRAMEBUFFER, fboMS[fboIndex]);
3535         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
3536                                textureMS[fboIndex], 0);
3537         ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3538 
3539         glViewport(0, 0, width, height);
3540         drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.8f);
3541         EXPECT_GL_NO_ERROR();
3542     }
3543 
3544     // Resolve the first FBO
3545     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboSS);
3546     glBindFramebuffer(GL_READ_FRAMEBUFFER, fboMS[0]);
3547 
3548     glViewport(0, 0, kLargeWidth, kLargeHeight);
3549     glBlitFramebuffer(0, 0, kLargeWidth, kLargeHeight, 0, 0, kLargeWidth, kLargeHeight,
3550                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
3551     EXPECT_GL_NO_ERROR();
3552 
3553     // Verify the resolve
3554     glBindFramebuffer(GL_READ_FRAMEBUFFER, fboSS);
3555     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3556     EXPECT_PIXEL_COLOR_EQ(kLargeWidth - 1, kLargeHeight - 1, GLColor::red);
3557 }
3558 
3559 // Blit a multisampled RGBX8 framebuffer to an RGB8 framebuffer.
TEST_P(BlitFramebufferTestES31,BlitMultisampledRGBX8ToRGB8)3560 TEST_P(BlitFramebufferTestES31, BlitMultisampledRGBX8ToRGB8)
3561 {
3562     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_rgbx_internal_format"));
3563 
3564     constexpr const GLsizei kWidth  = 256;
3565     constexpr const GLsizei kHeight = 256;
3566 
3567     GLTexture textureMS;
3568     GLRenderbuffer targetRBO;
3569     GLFramebuffer sourceFBO, targetFBO;
3570 
3571     // Initialize a source multisampled FBO with checker pattern
3572     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textureMS);
3573     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBX8_ANGLE, kWidth, kHeight,
3574                               GL_TRUE);
3575     EXPECT_GL_NO_ERROR();
3576     glBindFramebuffer(GL_FRAMEBUFFER, sourceFBO);
3577     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
3578                            textureMS, 0);
3579     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3580     ANGLE_GL_PROGRAM(checkerProgram, essl1_shaders::vs::Passthrough(),
3581                      essl1_shaders::fs::Checkered());
3582     glViewport(0, 0, kWidth, kHeight);
3583     glBindFramebuffer(GL_FRAMEBUFFER, sourceFBO);
3584     drawQuad(checkerProgram, essl1_shaders::PositionAttrib(), 0.5f);
3585     EXPECT_GL_NO_ERROR();
3586 
3587     // Initialize the destination FBO
3588     initColorFBO(&targetFBO, &targetRBO, GL_RGB8, kWidth, kHeight);
3589     EXPECT_GL_NO_ERROR();
3590 
3591     glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
3592     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
3593     EXPECT_GL_NO_ERROR();
3594 
3595     glViewport(0, 0, kWidth, kHeight);
3596 
3597     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
3598     glClear(GL_COLOR_BUFFER_BIT);
3599 
3600     // Scale down without flipping.
3601     glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_COLOR_BUFFER_BIT,
3602                       GL_NEAREST);
3603     EXPECT_GL_NO_ERROR();
3604 
3605     glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
3606 
3607     EXPECT_PIXEL_COLOR_EQ(kWidth / 4, kHeight / 4, GLColor::red);
3608     EXPECT_PIXEL_COLOR_EQ(kWidth / 4, 3 * kHeight / 4, GLColor::green);
3609     EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, kHeight / 4, GLColor::blue);
3610     EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, 3 * kHeight / 4, GLColor::yellow);
3611 }
3612 
3613 // Test resolving a multisampled texture with blit. Draw flipped, resolve with read fbo flipped.
TEST_P(BlitFramebufferTestES31,MultisampleFlippedResolveReadWithBlitAndFlippedDraw)3614 TEST_P(BlitFramebufferTestES31, MultisampleFlippedResolveReadWithBlitAndFlippedDraw)
3615 {
3616     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
3617 
3618     constexpr int kSize = 16;
3619     glViewport(0, 0, kSize, kSize);
3620 
3621     GLFramebuffer msaaFBO;
3622     glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO);
3623 
3624     glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
3625 
3626     GLTexture texture;
3627     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture);
3628     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
3629     ASSERT_GL_NO_ERROR();
3630     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, texture,
3631                            0);
3632     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3633 
3634     ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),
3635                      essl31_shaders::fs::RedGreenGradient());
3636     drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
3637     ASSERT_GL_NO_ERROR();
3638 
3639     // Create another FBO to resolve the multisample buffer into.
3640     GLTexture resolveTexture;
3641     GLFramebuffer resolveFBO;
3642     glBindTexture(GL_TEXTURE_2D, resolveTexture);
3643     constexpr int kResolveFBOWidth  = kSize - 3;
3644     constexpr int kResolveFBOHeight = kSize - 2;
3645     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kResolveFBOWidth, kResolveFBOHeight, 0, GL_RGBA,
3646                  GL_UNSIGNED_BYTE, nullptr);
3647     glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
3648     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 0);
3649     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3650 
3651     glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBO);
3652     glFramebufferParameteriMESA(GL_READ_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
3653     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO);
3654     glBlitFramebuffer(0, 0, kResolveFBOWidth, kResolveFBOHeight, 0, 0, kResolveFBOWidth,
3655                       kResolveFBOHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3656     ASSERT_GL_NO_ERROR();
3657 
3658     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO);
3659     constexpr uint8_t kHalfPixelGradient = 256 / kSize / 2;
3660     EXPECT_PIXEL_NEAR(0, 0, kHalfPixelGradient, kHalfPixelGradient, 0, 255, 1.0);
3661     EXPECT_PIXEL_NEAR(kResolveFBOWidth - 1, 0, 199, kHalfPixelGradient, 0, 255, 1.0);
3662     EXPECT_PIXEL_NEAR(0, kResolveFBOHeight - 1, kHalfPixelGradient, 215, 0, 255, 1.0);
3663     EXPECT_PIXEL_NEAR(kResolveFBOWidth - 1, kResolveFBOHeight - 1, 199, 215, 0, 255, 1.0);
3664 }
3665 
3666 // Test resolving a multisampled texture with blit. Draw non-flipped, resolve with read fbo flipped.
TEST_P(BlitFramebufferTestES31,MultisampleFlippedResolveReadWithBlitAndNonFlippedDraw)3667 TEST_P(BlitFramebufferTestES31, MultisampleFlippedResolveReadWithBlitAndNonFlippedDraw)
3668 {
3669     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
3670 
3671     constexpr int kSize = 16;
3672     glViewport(0, 0, kSize, kSize);
3673 
3674     GLFramebuffer msaaFBO;
3675     glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO);
3676 
3677     // Draw non-flipped - explicitly set y-flip to 0.
3678     glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 0);
3679 
3680     GLTexture texture;
3681     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture);
3682     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
3683     ASSERT_GL_NO_ERROR();
3684     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, texture,
3685                            0);
3686     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3687 
3688     ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),
3689                      essl31_shaders::fs::RedGreenGradient());
3690     drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
3691     ASSERT_GL_NO_ERROR();
3692 
3693     // Create another FBO to resolve the multisample buffer into.
3694     GLTexture resolveTexture;
3695     GLFramebuffer resolveFBO;
3696     glBindTexture(GL_TEXTURE_2D, resolveTexture);
3697     constexpr int kResolveFBOWidth  = kSize - 3;
3698     constexpr int kResolveFBOHeight = kSize - 2;
3699     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kResolveFBOWidth, kResolveFBOHeight, 0, GL_RGBA,
3700                  GL_UNSIGNED_BYTE, nullptr);
3701     glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
3702     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 0);
3703     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3704 
3705     glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBO);
3706     // Resolve with read fbo flipped and draw fbo non-flipped
3707     glFramebufferParameteriMESA(GL_READ_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
3708     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO);
3709     glBlitFramebuffer(0, 0, kResolveFBOWidth, kResolveFBOHeight, 0, 0, kResolveFBOWidth,
3710                       kResolveFBOHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3711     ASSERT_GL_NO_ERROR();
3712 
3713     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO);
3714     constexpr uint8_t kHalfPixelGradient = 256 / kSize / 2;
3715     EXPECT_PIXEL_NEAR(0, 0, kHalfPixelGradient, 255 - kHalfPixelGradient, 0, 255, 1.0);
3716     EXPECT_PIXEL_NEAR(kResolveFBOWidth - 1, 0, 199, 255 - kHalfPixelGradient, 0, 255, 1.0);
3717     EXPECT_PIXEL_NEAR(0, kResolveFBOHeight - 1, kHalfPixelGradient, 40, 0, 255, 1.0);
3718     EXPECT_PIXEL_NEAR(kResolveFBOWidth - 1, kResolveFBOHeight - 1, 199, 40, 0, 255, 1.0);
3719 }
3720 
3721 // Test resolving a multisampled texture with blit. Draw non-flipped, resolve with draw fbo flipped
TEST_P(BlitFramebufferTestES31,MultisampleFlippedResolveDrawWithBlitAndNonFlippedDraw)3722 TEST_P(BlitFramebufferTestES31, MultisampleFlippedResolveDrawWithBlitAndNonFlippedDraw)
3723 {
3724     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
3725 
3726     constexpr int kSize = 16;
3727     glViewport(0, 0, kSize, kSize);
3728 
3729     GLFramebuffer msaaFBO;
3730     glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO);
3731 
3732     // Draw non-flipped - explicitly set y-flip to 0.
3733     glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 0);
3734 
3735     GLTexture texture;
3736     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture);
3737     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
3738     ASSERT_GL_NO_ERROR();
3739     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, texture,
3740                            0);
3741     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3742 
3743     ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),
3744                      essl31_shaders::fs::RedGreenGradient());
3745     drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
3746     ASSERT_GL_NO_ERROR();
3747 
3748     // Create another FBO to resolve the multisample buffer into.
3749     GLTexture resolveTexture;
3750     GLFramebuffer resolveFBO;
3751     glBindTexture(GL_TEXTURE_2D, resolveTexture);
3752     constexpr int kResolveFBOWidth  = kSize - 3;
3753     constexpr int kResolveFBOHeight = kSize - 2;
3754     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kResolveFBOWidth, kResolveFBOHeight, 0, GL_RGBA,
3755                  GL_UNSIGNED_BYTE, nullptr);
3756     glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
3757     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 0);
3758     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3759 
3760     glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBO);
3761     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO);
3762     // Resolve with draw fbo flipped and read fbo non-flipped.
3763     glFramebufferParameteriMESA(GL_READ_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 0);
3764     glFramebufferParameteriMESA(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
3765     glBlitFramebuffer(0, 0, kResolveFBOWidth, kResolveFBOHeight, 0, 0, kResolveFBOWidth,
3766                       kResolveFBOHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3767     ASSERT_GL_NO_ERROR();
3768 
3769     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO);
3770     constexpr uint8_t kHalfPixelGradient = 256 / kSize / 2;
3771     EXPECT_PIXEL_NEAR(0, 0, kHalfPixelGradient, kHalfPixelGradient, 0, 255, 1.0);
3772     EXPECT_PIXEL_NEAR(kResolveFBOWidth - 1, 0, 199, kHalfPixelGradient, 0, 255, 1.0);
3773     EXPECT_PIXEL_NEAR(0, kResolveFBOHeight - 1, kHalfPixelGradient, 215, 0, 255, 1.0);
3774     EXPECT_PIXEL_NEAR(kResolveFBOWidth - 1, kResolveFBOHeight - 1, 199, 215, 0, 255, 1.0);
3775 }
3776 
3777 // Test resolving a multisampled texture with blit. Draw non-flipped, resolve with both read and
3778 // draw fbos flipped
TEST_P(BlitFramebufferTestES31,MultisampleFlippedResolveWithBlitAndNonFlippedDraw)3779 TEST_P(BlitFramebufferTestES31, MultisampleFlippedResolveWithBlitAndNonFlippedDraw)
3780 {
3781     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
3782 
3783     constexpr int kSize = 16;
3784     glViewport(0, 0, kSize, kSize);
3785 
3786     GLFramebuffer msaaFBO;
3787     glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO);
3788 
3789     // Draw non-flipped - explicitly set y-flip to 0.
3790     glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 0);
3791 
3792     GLTexture texture;
3793     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture);
3794     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
3795     ASSERT_GL_NO_ERROR();
3796     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, texture,
3797                            0);
3798     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3799 
3800     ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),
3801                      essl31_shaders::fs::RedGreenGradient());
3802     drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
3803     ASSERT_GL_NO_ERROR();
3804 
3805     // Create another FBO to resolve the multisample buffer into.
3806     GLTexture resolveTexture;
3807     GLFramebuffer resolveFBO;
3808     constexpr int kResolveFBOWidth  = kSize - 3;
3809     constexpr int kResolveFBOHeight = kSize - 2;
3810     glBindTexture(GL_TEXTURE_2D, resolveTexture);
3811     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kResolveFBOWidth, kResolveFBOHeight, 0, GL_RGBA,
3812                  GL_UNSIGNED_BYTE, nullptr);
3813     glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
3814     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 0);
3815     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3816 
3817     glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBO);
3818     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO);
3819     // Resolve with draw and read fbo flipped.
3820     glFramebufferParameteriMESA(GL_READ_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
3821     glFramebufferParameteriMESA(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
3822     glBlitFramebuffer(0, 0, kResolveFBOWidth, kResolveFBOHeight, 0, 0, kResolveFBOWidth,
3823                       kResolveFBOHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3824     ASSERT_GL_NO_ERROR();
3825 
3826     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO);
3827     constexpr uint8_t kHalfPixelGradient = 256 / kSize / 2;
3828     EXPECT_PIXEL_NEAR(0, 0, kHalfPixelGradient, 255 - kHalfPixelGradient, 0, 255, 1.0);
3829     EXPECT_PIXEL_NEAR(kResolveFBOWidth - 1, 0, 199, 255 - kHalfPixelGradient, 0, 255, 1.0);
3830     EXPECT_PIXEL_NEAR(0, kResolveFBOHeight - 1, kHalfPixelGradient, 40, 0, 255, 1.0);
3831     EXPECT_PIXEL_NEAR(kResolveFBOWidth - 1, kResolveFBOHeight - 1, 199, 40, 0, 255, 1.0);
3832 }
3833 
3834 // Test resolving into smaller framebuffer.
TEST_P(BlitFramebufferTest,ResolveIntoSmallerFramebuffer)3835 TEST_P(BlitFramebufferTest, ResolveIntoSmallerFramebuffer)
3836 {
3837     constexpr GLuint kSize[2] = {40, 32};
3838     glViewport(0, 0, kSize[0], kSize[0]);
3839 
3840     GLRenderbuffer rbo[2];
3841     GLFramebuffer fbo[2];
3842 
3843     for (int i = 0; i < 2; ++i)
3844     {
3845         glBindRenderbuffer(GL_RENDERBUFFER, rbo[i]);
3846         if (i == 0)
3847         {
3848             glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, kSize[i], kSize[i]);
3849         }
3850         else
3851         {
3852             glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize[i], kSize[i]);
3853         }
3854         glBindFramebuffer(GL_FRAMEBUFFER, fbo[i]);
3855         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo[i]);
3856     }
3857 
3858     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
3859     glUseProgram(program);
3860 
3861     glBindFramebuffer(GL_FRAMEBUFFER, fbo[0]);
3862     drawQuad(program, essl1_shaders::PositionAttrib(), 0.3f);
3863 
3864     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[1]);
3865     glBlitFramebuffer(0, 0, kSize[1], kSize[1], 0, 0, kSize[1], kSize[1], GL_COLOR_BUFFER_BIT,
3866                       GL_NEAREST);
3867 
3868     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo[1]);
3869     EXPECT_PIXEL_RECT_EQ(0, 0, kSize[1], kSize[1], GLColor::red);
3870 }
3871 
3872 // Test resolving into bigger framebuffer.
TEST_P(BlitFramebufferTest,ResolveIntoBiggerFramebuffer)3873 TEST_P(BlitFramebufferTest, ResolveIntoBiggerFramebuffer)
3874 {
3875     constexpr GLuint kSize[2] = {32, 40};
3876     glViewport(0, 0, kSize[0], kSize[0]);
3877 
3878     GLRenderbuffer rbo[2];
3879     GLFramebuffer fbo[2];
3880 
3881     for (int i = 0; i < 2; ++i)
3882     {
3883         glBindRenderbuffer(GL_RENDERBUFFER, rbo[i]);
3884         if (i == 0)
3885         {
3886             glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, kSize[i], kSize[i]);
3887         }
3888         else
3889         {
3890             glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize[i], kSize[i]);
3891         }
3892         glBindFramebuffer(GL_FRAMEBUFFER, fbo[i]);
3893         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo[i]);
3894     }
3895 
3896     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
3897     glUseProgram(program);
3898 
3899     glBindFramebuffer(GL_FRAMEBUFFER, fbo[0]);
3900     drawQuad(program, essl1_shaders::PositionAttrib(), 0.3f);
3901 
3902     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[1]);
3903     glBlitFramebuffer(0, 0, kSize[1], kSize[1], 0, 0, kSize[1], kSize[1], GL_COLOR_BUFFER_BIT,
3904                       GL_NEAREST);
3905 
3906     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo[1]);
3907     EXPECT_PIXEL_RECT_EQ(0, 0, kSize[0], kSize[0], GLColor::red);
3908 }
3909 
3910 // Test resolving into a rotated framebuffer
TEST_P(BlitFramebufferTest,ResolveWithRotation)3911 TEST_P(BlitFramebufferTest, ResolveWithRotation)
3912 {
3913     const GLint w = getWindowWidth();
3914     const GLint h = getWindowHeight();
3915 
3916     glViewport(0, 0, w, h);
3917 
3918     GLRenderbuffer rbo;
3919     GLFramebuffer fbo;
3920 
3921     glBindRenderbuffer(GL_RENDERBUFFER, rbo);
3922     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, w, h);
3923     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3924     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
3925 
3926     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Checkered());
3927     glUseProgram(program);
3928 
3929     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3930     drawQuad(program, essl1_shaders::PositionAttrib(), 0.3f);
3931 
3932     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
3933     glBlitFramebuffer(0, 0, w, h, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3934 
3935     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
3936     EXPECT_PIXEL_RECT_EQ(0, 0, w / 2, h / 2, GLColor::red);
3937     EXPECT_PIXEL_RECT_EQ(w / 2, 0, w / 2, h / 2, GLColor::blue);
3938     EXPECT_PIXEL_RECT_EQ(0, h / 2, w / 2, h / 2, GLColor::green);
3939     EXPECT_PIXEL_RECT_EQ(w / 2, h / 2, w / 2, h / 2, GLColor::yellow);
3940 }
3941 
3942 // Test blitting a 3D texture to a 3D texture
TEST_P(BlitFramebufferTest,Blit3D)3943 TEST_P(BlitFramebufferTest, Blit3D)
3944 {
3945     test3DBlit(GL_TEXTURE_3D, GL_TEXTURE_3D);
3946 }
3947 
3948 // Test blitting a 2D array texture to a 2D array texture
TEST_P(BlitFramebufferTest,Blit2DArray)3949 TEST_P(BlitFramebufferTest, Blit2DArray)
3950 {
3951     test3DBlit(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_2D_ARRAY);
3952 }
3953 
3954 // Test blitting a 3D texture to a 2D array texture
TEST_P(BlitFramebufferTest,Blit3DTo2DArray)3955 TEST_P(BlitFramebufferTest, Blit3DTo2DArray)
3956 {
3957     test3DBlit(GL_TEXTURE_3D, GL_TEXTURE_2D_ARRAY);
3958 }
3959 
3960 // Test blitting a 2D array texture to a 3D texture
TEST_P(BlitFramebufferTest,Blit2DArrayTo3D)3961 TEST_P(BlitFramebufferTest, Blit2DArrayTo3D)
3962 {
3963     test3DBlit(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_3D);
3964 }
3965 
3966 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
3967 // tests should be run against.
3968 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BlitFramebufferANGLETest);
3969 ANGLE_INSTANTIATE_TEST(BlitFramebufferANGLETest,
3970                        ES2_D3D9(),
3971                        ES2_D3D11(),
3972                        ES2_D3D11_PRESENT_PATH_FAST(),
3973                        ES2_OPENGL(),
3974                        ES3_OPENGL(),
3975                        ES2_VULKAN(),
3976                        ES3_VULKAN(),
3977                        ES3_VULKAN().enable(Feature::EmulatedPrerotation90),
3978                        ES3_VULKAN().enable(Feature::EmulatedPrerotation180),
3979                        ES3_VULKAN().enable(Feature::EmulatedPrerotation270),
3980                        ES3_VULKAN()
3981                            .disable(Feature::SupportsExtendedDynamicState)
3982                            .disable(Feature::SupportsExtendedDynamicState2),
3983                        ES3_VULKAN().disable(Feature::SupportsExtendedDynamicState2),
3984                        ES2_METAL(),
3985                        ES2_METAL().disable(Feature::HasShaderStencilOutput));
3986 
3987 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BlitFramebufferTest);
3988 ANGLE_INSTANTIATE_TEST_ES3_AND(BlitFramebufferTest,
3989                                ES3_VULKAN().enable(Feature::EmulatedPrerotation90),
3990                                ES3_VULKAN().enable(Feature::EmulatedPrerotation180),
3991                                ES3_VULKAN().enable(Feature::EmulatedPrerotation270),
3992                                ES3_VULKAN()
3993                                    .disable(Feature::SupportsExtendedDynamicState)
3994                                    .disable(Feature::SupportsExtendedDynamicState2),
3995                                ES3_VULKAN().disable(Feature::SupportsExtendedDynamicState2),
3996                                ES3_VULKAN().enable(Feature::DisableFlippingBlitWithCommand),
3997                                ES3_METAL().disable(Feature::HasShaderStencilOutput));
3998 
3999 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BlitFramebufferTestES31);
4000 ANGLE_INSTANTIATE_TEST_ES31(BlitFramebufferTestES31);
4001 }  // namespace
4002