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/42261451
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/42264679): glBlitFramebufferANGLE() generates GL_INVALID_OPERATION
1001 // for 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
1205 // Test that blit with missing attachments is ignored.
TEST_P(BlitFramebufferANGLETest,BlitWithMissingAttachments)1206 TEST_P(BlitFramebufferANGLETest, BlitWithMissingAttachments)
1207 {
1208 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1209
1210 glBindFramebuffer(GL_FRAMEBUFFER, mColorOnlyFBO);
1211
1212 glClear(GL_COLOR_BUFFER_BIT);
1213 drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.3f);
1214
1215 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
1216 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mColorOnlyFBO);
1217
1218 glClearColor(1.0, 1.0, 1.0, 1.0);
1219 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1220
1221 // No error if the read FBO has no depth attachment
1222 glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
1223 getWindowHeight(), GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
1224 GL_NEAREST);
1225 EXPECT_GL_NO_ERROR();
1226
1227 // No error 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 EXPECT_GL_NO_ERROR();
1232
1233 // No error if we read from a missing color attachment. Create a temp attachment as
1234 // attachment1, then remove attachment 0.
1235 //
1236 // The same could be done with glReadBuffer, which requires ES3 (this test runs on ES2).
1237 GLTexture tempColor;
1238 glBindTexture(GL_TEXTURE_2D, tempColor);
1239 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
1240 GL_UNSIGNED_BYTE, nullptr);
1241 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, tempColor, 0);
1242 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
1243 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
1244 EXPECT_GL_NO_ERROR();
1245
1246 glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
1247 getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
1248 EXPECT_GL_NO_ERROR();
1249 }
1250
TEST_P(BlitFramebufferANGLETest,BlitStencil)1251 TEST_P(BlitFramebufferANGLETest, BlitStencil)
1252 {
1253 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1254
1255 // http://anglebug.com/40096473
1256 ANGLE_SKIP_TEST_IF(IsIntel() && IsD3D9());
1257
1258 // http://anglebug.com/42263934
1259 ANGLE_SKIP_TEST_IF(IsAMD() && IsD3D9());
1260
1261 BlitStencilTestHelper(false /* mesaFlipY */);
1262 }
1263
1264 // Same as BlitStencil, but with y-flip flag set.
TEST_P(BlitFramebufferANGLETest,BlitStencilWithMesaYFlip)1265 TEST_P(BlitFramebufferANGLETest, BlitStencilWithMesaYFlip)
1266 {
1267 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit") ||
1268 !IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
1269
1270 // http://anglebug.com/40096473
1271 ANGLE_SKIP_TEST_IF(IsIntel() && IsD3D9());
1272
1273 // http://anglebug.com/42263934
1274 ANGLE_SKIP_TEST_IF(IsAMD() && IsD3D9());
1275
1276 BlitStencilTestHelper(true /* mesaFlipY */);
1277 }
1278
1279 // make sure that attempting to blit a partial depth buffer issues an error
TEST_P(BlitFramebufferANGLETest,BlitPartialDepthStencil)1280 TEST_P(BlitFramebufferANGLETest, BlitPartialDepthStencil)
1281 {
1282 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1283
1284 glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
1285
1286 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1287
1288 drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.5f);
1289
1290 EXPECT_GL_NO_ERROR();
1291
1292 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
1293 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
1294
1295 glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, 0, 0,
1296 getWindowWidth() / 2, getWindowHeight() / 2, GL_DEPTH_BUFFER_BIT,
1297 GL_NEAREST);
1298 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1299 }
1300
1301 // Test blit with MRT framebuffers
TEST_P(BlitFramebufferANGLETest,BlitMRT)1302 TEST_P(BlitFramebufferANGLETest, BlitMRT)
1303 {
1304 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1305
1306 if (!IsGLExtensionEnabled("GL_EXT_draw_buffers"))
1307 {
1308 return;
1309 }
1310
1311 GLenum drawBuffers[] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT};
1312
1313 glBindFramebuffer(GL_FRAMEBUFFER, mMRTFBO);
1314 glDrawBuffersEXT(2, drawBuffers);
1315
1316 glBindFramebuffer(GL_FRAMEBUFFER, mColorOnlyFBO);
1317
1318 glClear(GL_COLOR_BUFFER_BIT);
1319
1320 drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);
1321
1322 EXPECT_GL_NO_ERROR();
1323
1324 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mColorOnlyFBO);
1325 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mMRTFBO);
1326
1327 glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
1328 getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
1329
1330 EXPECT_GL_NO_ERROR();
1331
1332 glBindFramebuffer(GL_FRAMEBUFFER, mMRTFBO);
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_ATTACHMENT1_EXT, GL_TEXTURE_2D, 0, 0);
1340 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mMRTColorBuffer0,
1341 0);
1342
1343 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
1344 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);
1345 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
1346 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);
1347
1348 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mMRTColorBuffer0,
1349 0);
1350 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D,
1351 mMRTColorBuffer1, 0);
1352 }
1353
1354 // Test multisampled framebuffer blits if supported
TEST_P(BlitFramebufferANGLETest,MultisampledRGBAToRGBA)1355 TEST_P(BlitFramebufferANGLETest, MultisampledRGBAToRGBA)
1356 {
1357 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1358
1359 if (!checkExtension("GL_ANGLE_framebuffer_multisample"))
1360 return;
1361
1362 if (!checkExtension("GL_OES_rgb8_rgba8"))
1363 return;
1364
1365 multisampleTestHelper(mRGBAMultisampledFBO, mRGBAFBO);
1366 }
1367
TEST_P(BlitFramebufferANGLETest,MultisampledRGBAToBGRA)1368 TEST_P(BlitFramebufferANGLETest, MultisampledRGBAToBGRA)
1369 {
1370 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1371
1372 if (!checkExtension("GL_ANGLE_framebuffer_multisample"))
1373 return;
1374
1375 if (!checkExtension("GL_OES_rgb8_rgba8"))
1376 return;
1377
1378 if (!checkExtension("GL_EXT_texture_format_BGRA8888"))
1379 return;
1380
1381 multisampleTestHelper(mRGBAMultisampledFBO, mBGRAFBO);
1382 }
1383
TEST_P(BlitFramebufferANGLETest,MultisampledBGRAToRGBA)1384 TEST_P(BlitFramebufferANGLETest, MultisampledBGRAToRGBA)
1385 {
1386 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1387
1388 if (!checkExtension("GL_ANGLE_framebuffer_multisample"))
1389 return;
1390
1391 if (!checkExtension("GL_OES_rgb8_rgba8"))
1392 return;
1393
1394 if (!checkExtension("GL_EXT_texture_format_BGRA8888"))
1395 return;
1396
1397 multisampleTestHelper(mBGRAMultisampledFBO, mRGBAFBO);
1398 }
1399
TEST_P(BlitFramebufferANGLETest,MultisampledBGRAToBGRA)1400 TEST_P(BlitFramebufferANGLETest, MultisampledBGRAToBGRA)
1401 {
1402 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1403
1404 if (!checkExtension("GL_ANGLE_framebuffer_multisample"))
1405 return;
1406
1407 if (!checkExtension("GL_OES_rgb8_rgba8"))
1408 return;
1409
1410 if (!checkExtension("GL_EXT_texture_format_BGRA8888"))
1411 return;
1412
1413 multisampleTestHelper(mBGRAMultisampledFBO, mBGRAFBO);
1414 }
1415
1416 // Make sure that attempts to stretch in a blit call issue an error
TEST_P(BlitFramebufferANGLETest,ErrorStretching)1417 TEST_P(BlitFramebufferANGLETest, ErrorStretching)
1418 {
1419 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1420
1421 glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
1422
1423 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1424
1425 drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.5f);
1426
1427 EXPECT_GL_NO_ERROR();
1428
1429 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
1430 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
1431
1432 glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, 0, 0,
1433 getWindowWidth(), getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
1434 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1435 }
1436
1437 // Make sure that attempts to flip in a blit call issue an error
TEST_P(BlitFramebufferANGLETest,ErrorFlipping)1438 TEST_P(BlitFramebufferANGLETest, ErrorFlipping)
1439 {
1440 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1441
1442 glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
1443
1444 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1445
1446 drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.5f);
1447
1448 EXPECT_GL_NO_ERROR();
1449
1450 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
1451 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
1452
1453 glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, getWindowWidth() / 2,
1454 getWindowHeight() / 2, 0, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1455 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1456 }
1457
TEST_P(BlitFramebufferANGLETest,Errors)1458 TEST_P(BlitFramebufferANGLETest, Errors)
1459 {
1460 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1461
1462 glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
1463
1464 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1465
1466 drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.5f);
1467
1468 EXPECT_GL_NO_ERROR();
1469
1470 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
1471 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
1472
1473 glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
1474 getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_LINEAR);
1475 EXPECT_GL_ERROR(GL_INVALID_ENUM);
1476
1477 glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
1478 getWindowHeight(), GL_COLOR_BUFFER_BIT | 234, GL_NEAREST);
1479 EXPECT_GL_ERROR(GL_INVALID_VALUE);
1480
1481 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mDiffFormatFBO);
1482
1483 glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
1484 getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
1485 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1486 }
1487
1488 // TODO(geofflang): Fix the dependence on glBlitFramebufferANGLE without checks and assuming the
1489 // default framebuffer is BGRA to enable the GL and GLES backends. (http://anglebug.com/42260299)
1490
1491 class BlitFramebufferTest : public ANGLETest<>
1492 {
1493 protected:
BlitFramebufferTest()1494 BlitFramebufferTest()
1495 {
1496 setWindowWidth(256);
1497 setWindowHeight(256);
1498 setConfigRedBits(8);
1499 setConfigGreenBits(8);
1500 setConfigBlueBits(8);
1501 setConfigAlphaBits(8);
1502 setConfigDepthBits(24);
1503 setConfigStencilBits(8);
1504 }
1505
initColorFBO(GLFramebuffer * fbo,GLRenderbuffer * rbo,GLenum rboFormat,GLsizei width,GLsizei height)1506 void initColorFBO(GLFramebuffer *fbo,
1507 GLRenderbuffer *rbo,
1508 GLenum rboFormat,
1509 GLsizei width,
1510 GLsizei height)
1511 {
1512 glBindRenderbuffer(GL_RENDERBUFFER, *rbo);
1513 glRenderbufferStorage(GL_RENDERBUFFER, rboFormat, width, height);
1514
1515 glBindFramebuffer(GL_FRAMEBUFFER, *fbo);
1516 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *rbo);
1517 }
1518
initColorFBOWithCheckerPattern(GLFramebuffer * fbo,GLRenderbuffer * rbo,GLenum rboFormat,GLsizei width,GLsizei height)1519 void initColorFBOWithCheckerPattern(GLFramebuffer *fbo,
1520 GLRenderbuffer *rbo,
1521 GLenum rboFormat,
1522 GLsizei width,
1523 GLsizei height)
1524 {
1525 initColorFBO(fbo, rbo, rboFormat, width, height);
1526
1527 ANGLE_GL_PROGRAM(checkerProgram, essl1_shaders::vs::Passthrough(),
1528 essl1_shaders::fs::Checkered());
1529 glViewport(0, 0, width, height);
1530 glBindFramebuffer(GL_FRAMEBUFFER, *fbo);
1531 drawQuad(checkerProgram, essl1_shaders::PositionAttrib(), 0.5f);
1532 }
1533
BlitDepthStencilPixelByPixelTestHelper(bool mesaYFlip)1534 void BlitDepthStencilPixelByPixelTestHelper(bool mesaYFlip)
1535 {
1536 if (mesaYFlip)
1537 ASSERT_TRUE(IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
1538
1539 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
1540
1541 glViewport(0, 0, 128, 1);
1542 glEnable(GL_DEPTH_TEST);
1543
1544 GLFramebuffer srcFramebuffer;
1545 GLRenderbuffer srcRenderbuffer;
1546 glBindFramebuffer(GL_FRAMEBUFFER, srcFramebuffer);
1547 if (mesaYFlip)
1548 glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
1549 glBindRenderbuffer(GL_RENDERBUFFER, srcRenderbuffer);
1550 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 128, 1);
1551 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
1552 srcRenderbuffer);
1553 glClearDepthf(1.0f);
1554 glClear(GL_DEPTH_BUFFER_BIT);
1555
1556 drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.0f, 0.5f);
1557 glViewport(0, 0, 256, 2);
1558
1559 GLFramebuffer dstFramebuffer;
1560 GLRenderbuffer dstRenderbuffer;
1561 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dstFramebuffer);
1562 glBindRenderbuffer(GL_RENDERBUFFER, dstRenderbuffer);
1563 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 256, 2);
1564 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
1565 dstRenderbuffer);
1566
1567 GLTexture dstColor;
1568 glBindTexture(GL_TEXTURE_2D, dstColor);
1569 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 2);
1570 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dstColor, 0);
1571
1572 glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFramebuffer);
1573 glBlitFramebuffer(0, 0, 128, 1, 0, 0, 256, 2, GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
1574 GL_NEAREST);
1575
1576 glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
1577 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
1578 glClear(GL_COLOR_BUFFER_BIT);
1579 glDepthMask(false);
1580 glDepthFunc(GL_LESS);
1581 drawQuad(drawRed, essl1_shaders::PositionAttrib(), -0.01f, 0.5f);
1582 EXPECT_PIXEL_RECT_EQ(64, 0, 128, 1, GLColor::red);
1583
1584 ANGLE_GL_PROGRAM(drawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());
1585 glEnable(GL_DEPTH_TEST);
1586 glDepthMask(false);
1587 glDepthFunc(GL_GREATER);
1588 if (mesaYFlip)
1589 glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
1590 drawQuad(drawBlue, essl1_shaders::PositionAttrib(), 0.01f, 0.5f);
1591 if (mesaYFlip)
1592 EXPECT_PIXEL_RECT_EQ(64, 0, 128, 1, GLColor::green);
1593 else
1594 EXPECT_PIXEL_RECT_EQ(64, 0, 128, 1, GLColor::blue);
1595 }
1596
1597 // Test blitting between 3D textures and 2D array textures
test3DBlit(GLenum sourceTarget,GLenum destTarget)1598 void test3DBlit(GLenum sourceTarget, GLenum destTarget)
1599 {
1600
1601 constexpr int kTexWidth = 4;
1602 constexpr int kTexHeight = 3;
1603 constexpr int kTexDepth = 2;
1604 glViewport(0, 0, kTexWidth, kTexHeight);
1605
1606 size_t size = kTexWidth * kTexHeight * kTexDepth;
1607 std::vector<uint32_t> sourceData(size);
1608 std::vector<uint32_t> destData(size);
1609 for (size_t i = 0; i < size; ++i)
1610 {
1611 sourceData[i] = i;
1612 destData[i] = size - i;
1613 }
1614
1615 // Create a source 3D texture and FBO.
1616 GLTexture sourceTexture;
1617 glBindTexture(sourceTarget, sourceTexture);
1618 glTexImage3D(sourceTarget, 0, GL_RGBA8, kTexWidth, kTexHeight, kTexDepth, 0, GL_RGBA,
1619 GL_UNSIGNED_BYTE, sourceData.data());
1620
1621 // Create a dest texture and FBO.
1622 GLTexture destTexture;
1623 glBindTexture(destTarget, destTexture);
1624 glTexImage3D(destTarget, 0, GL_RGBA8, kTexWidth, kTexHeight, kTexDepth, 0, GL_RGBA,
1625 GL_UNSIGNED_BYTE, destData.data());
1626
1627 for (int z = 0; z < kTexDepth; ++z)
1628 {
1629 ASSERT_GL_NO_ERROR();
1630 GLFramebuffer sourceFBO;
1631 glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
1632 glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, sourceTexture, 0,
1633 z);
1634 ASSERT_GL_NO_ERROR();
1635
1636 GLFramebuffer destFBO;
1637 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, destFBO);
1638 glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, destTexture, 0, z);
1639 ASSERT_GL_NO_ERROR();
1640
1641 glBlitFramebuffer(0, 0, kTexWidth, kTexHeight, 0, 0, kTexWidth, kTexHeight,
1642 GL_COLOR_BUFFER_BIT, GL_NEAREST);
1643 ASSERT_GL_NO_ERROR();
1644 }
1645
1646 for (int z = 0; z < kTexDepth; ++z)
1647 {
1648 GLFramebuffer readFBO;
1649 glBindFramebuffer(GL_READ_FRAMEBUFFER, readFBO);
1650 glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, destTexture, 0, z);
1651 ASSERT_GL_NO_ERROR();
1652
1653 glReadBuffer(GL_COLOR_ATTACHMENT0);
1654 for (int y = 0; y < kTexHeight; ++y)
1655 {
1656 for (int x = 0; x < kTexWidth; ++x)
1657 {
1658 int index = x + kTexWidth * (y + z * kTexHeight);
1659 EXPECT_PIXEL_COLOR_EQ(x, y, index);
1660 }
1661 }
1662 }
1663 }
1664
initFBOWithProgramAndDepth(GLFramebuffer * fbo,GLRenderbuffer * colorRenderBuffer,GLenum colorFormat,GLRenderbuffer * depthRenderBuffer,GLenum depthFormat,GLsizei width,GLsizei height,GLuint program,float depthValue)1665 void initFBOWithProgramAndDepth(GLFramebuffer *fbo,
1666 GLRenderbuffer *colorRenderBuffer,
1667 GLenum colorFormat,
1668 GLRenderbuffer *depthRenderBuffer,
1669 GLenum depthFormat,
1670 GLsizei width,
1671 GLsizei height,
1672 GLuint program,
1673 float depthValue)
1674 {
1675 if (fbo != nullptr)
1676 {
1677 // Create renderbuffer
1678 glBindRenderbuffer(GL_RENDERBUFFER, *colorRenderBuffer);
1679 glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, width, height);
1680 glBindRenderbuffer(GL_RENDERBUFFER, *depthRenderBuffer);
1681 glRenderbufferStorage(GL_RENDERBUFFER, depthFormat, width, height);
1682
1683 // Create fbo
1684 glBindFramebuffer(GL_FRAMEBUFFER, *fbo);
1685 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
1686 *colorRenderBuffer);
1687 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
1688 *depthRenderBuffer);
1689 }
1690 else
1691 {
1692 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1693 }
1694
1695 // draw with program
1696 glUseProgram(program);
1697 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
1698 glClearDepthf(1.0f);
1699 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1700 glEnable(GL_DEPTH_TEST);
1701 glDepthMask(true);
1702 drawQuad(program, essl1_shaders::PositionAttrib(), depthValue);
1703 }
1704
drawWithDepthValue(std::array<Vector3,6> & quadVertices,float depth)1705 void drawWithDepthValue(std::array<Vector3, 6> &quadVertices, float depth)
1706 {
1707 for (Vector3 &vertice : quadVertices)
1708 {
1709 vertice[2] = depth;
1710 }
1711 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(quadVertices[0]) * quadVertices.size(),
1712 quadVertices.data());
1713 glDrawArrays(GL_TRIANGLES, 0, 6);
1714 }
1715 };
1716
1717 class BlitFramebufferTestES31 : public BlitFramebufferTest
1718 {};
1719
1720 // Tests resolving a multisample depth buffer.
TEST_P(BlitFramebufferTest,MultisampleDepth)1721 TEST_P(BlitFramebufferTest, MultisampleDepth)
1722 {
1723 // TODO([email protected]): http://crbug.com/837717
1724 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsMac());
1725
1726 GLRenderbuffer renderbuf;
1727 glBindRenderbuffer(GL_RENDERBUFFER, renderbuf);
1728 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_DEPTH_COMPONENT24, 256, 256);
1729
1730 GLFramebuffer framebuffer;
1731 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1732 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuf);
1733
1734 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1735
1736 glClearDepthf(0.5f);
1737 glClear(GL_DEPTH_BUFFER_BIT);
1738
1739 GLRenderbuffer destRenderbuf;
1740 glBindRenderbuffer(GL_RENDERBUFFER, destRenderbuf);
1741 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 256, 256);
1742
1743 GLFramebuffer resolved;
1744 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolved);
1745 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
1746 destRenderbuf);
1747
1748 glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
1749 glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
1750
1751 glBindFramebuffer(GL_FRAMEBUFFER, resolved);
1752
1753 // Immediately destroy the framebuffer and the associated textures for additional cleanup
1754 // ordering testing.
1755 framebuffer.reset();
1756 renderbuf.reset();
1757
1758 GLTexture colorbuf;
1759 glBindTexture(GL_TEXTURE_2D, colorbuf);
1760 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);
1761 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuf, 0);
1762
1763 ASSERT_GL_NO_ERROR();
1764
1765 // Clear to green
1766 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
1767 glClear(GL_COLOR_BUFFER_BIT);
1768 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1769
1770 // Make sure resulting depth is near 0.5f.
1771 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
1772 glEnable(GL_DEPTH_TEST);
1773 glDepthMask(false);
1774 glDepthFunc(GL_LESS);
1775 drawQuad(drawRed, essl3_shaders::PositionAttrib(), -0.01f);
1776 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1777 EXPECT_PIXEL_COLOR_EQ(255, 0, GLColor::red);
1778 EXPECT_PIXEL_COLOR_EQ(0, 255, GLColor::red);
1779 EXPECT_PIXEL_COLOR_EQ(255, 255, GLColor::red);
1780 EXPECT_PIXEL_COLOR_EQ(127, 127, GLColor::red);
1781
1782 ANGLE_GL_PROGRAM(drawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());
1783 glEnable(GL_DEPTH_TEST);
1784 glDepthMask(false);
1785 glDepthFunc(GL_GREATER);
1786 drawQuad(drawBlue, essl3_shaders::PositionAttrib(), 0.01f);
1787 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
1788 EXPECT_PIXEL_COLOR_EQ(255, 0, GLColor::blue);
1789 EXPECT_PIXEL_COLOR_EQ(0, 255, GLColor::blue);
1790 EXPECT_PIXEL_COLOR_EQ(255, 255, GLColor::blue);
1791 EXPECT_PIXEL_COLOR_EQ(127, 127, GLColor::blue);
1792
1793 ASSERT_GL_NO_ERROR();
1794 }
1795
1796 // Blit multisample stencil buffer to default framebuffer without prerotaion.
TEST_P(BlitFramebufferTest,BlitMultisampleStencilToDefault)1797 TEST_P(BlitFramebufferTest, BlitMultisampleStencilToDefault)
1798 {
1799 // http://anglebug.com/42262159
1800 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsMac());
1801
1802 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1803 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1804
1805 GLRenderbuffer colorbuf;
1806 glBindRenderbuffer(GL_RENDERBUFFER, colorbuf);
1807 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, 128, 128);
1808
1809 GLRenderbuffer depthstencilbuf;
1810 glBindRenderbuffer(GL_RENDERBUFFER, depthstencilbuf);
1811 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, 128, 128);
1812
1813 GLFramebuffer framebuffer;
1814 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1815 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuf);
1816 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
1817 depthstencilbuf);
1818 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
1819 depthstencilbuf);
1820 glCheckFramebufferStatus(GL_FRAMEBUFFER);
1821
1822 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1823 glFlush();
1824
1825 // Replace stencil to 1.
1826 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
1827 glEnable(GL_STENCIL_TEST);
1828 glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
1829 glStencilFunc(GL_ALWAYS, 1, 255);
1830 drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.8f);
1831
1832 // Blit multisample stencil buffer to default frambuffer.
1833 GLenum attachments1[] = {GL_COLOR_ATTACHMENT0};
1834 glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments1);
1835 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1836 glBlitFramebuffer(0, 0, 128, 128, 0, 0, 128, 128, GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
1837 GL_NEAREST);
1838 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1839
1840 // Disable stencil and draw full_screen green color.
1841 ANGLE_GL_PROGRAM(drawGreen, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());
1842 glDisable(GL_STENCIL_TEST);
1843 drawQuad(drawGreen, essl3_shaders::PositionAttrib(), 0.5f);
1844
1845 // Draw blue color if the stencil is equal to 1.
1846 // If the blit finished successfully, the stencil test should all pass.
1847 ANGLE_GL_PROGRAM(drawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());
1848 glEnable(GL_STENCIL_TEST);
1849 glStencilFunc(GL_EQUAL, 1, 255);
1850 drawQuad(drawBlue, essl3_shaders::PositionAttrib(), 0.2f);
1851
1852 // Check the result, especially the boundaries.
1853 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
1854 EXPECT_PIXEL_COLOR_EQ(127, 0, GLColor::blue);
1855 EXPECT_PIXEL_COLOR_EQ(50, 0, GLColor::blue);
1856 EXPECT_PIXEL_COLOR_EQ(127, 1, GLColor::blue);
1857 EXPECT_PIXEL_COLOR_EQ(0, 127, GLColor::blue);
1858 EXPECT_PIXEL_COLOR_EQ(127, 127, GLColor::blue);
1859 EXPECT_PIXEL_COLOR_EQ(64, 64, GLColor::blue);
1860
1861 ASSERT_GL_NO_ERROR();
1862 }
1863
1864 // Test blit multisampled framebuffer to MRT framebuffer
TEST_P(BlitFramebufferTest,BlitMultisampledFramebufferToMRT)1865 TEST_P(BlitFramebufferTest, BlitMultisampledFramebufferToMRT)
1866 {
1867 // https://issues.angleproject.org/issues/361369302
1868
1869 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1870 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1871
1872 // Prepare multisampled framebuffer to blit from.
1873 GLRenderbuffer multiSampleColorbuf;
1874 glBindRenderbuffer(GL_RENDERBUFFER, multiSampleColorbuf);
1875 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, getWindowWidth(),
1876 getWindowHeight());
1877
1878 GLFramebuffer multiSampleFramebuffer;
1879 glBindFramebuffer(GL_FRAMEBUFFER, multiSampleFramebuffer);
1880 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
1881 multiSampleColorbuf);
1882 glCheckFramebufferStatus(GL_FRAMEBUFFER);
1883
1884 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
1885 drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.8f);
1886 EXPECT_GL_NO_ERROR();
1887
1888 // Prepare mrt framebuffer with two attachments to blit to.
1889 GLFramebuffer MRTFBO;
1890 glBindFramebuffer(GL_FRAMEBUFFER, MRTFBO);
1891 GLTexture MRTColorBuffer0;
1892 GLTexture MRTColorBuffer1;
1893 glBindTexture(GL_TEXTURE_2D, MRTColorBuffer0);
1894 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
1895 GL_UNSIGNED_BYTE, nullptr);
1896 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, MRTColorBuffer0, 0);
1897 glBindTexture(GL_TEXTURE_2D, MRTColorBuffer1);
1898 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
1899 GL_UNSIGNED_BYTE, nullptr);
1900 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, MRTColorBuffer1, 0);
1901
1902 glBindFramebuffer(GL_READ_FRAMEBUFFER, multiSampleFramebuffer);
1903 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, MRTFBO);
1904
1905 glReadBuffer(GL_COLOR_ATTACHMENT0);
1906 GLenum drawBuffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
1907 glDrawBuffers(2, drawBuffers);
1908
1909 glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
1910 getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
1911 EXPECT_GL_NO_ERROR();
1912
1913 // Check results
1914 glBindFramebuffer(GL_FRAMEBUFFER, MRTFBO);
1915 glReadBuffer(GL_COLOR_ATTACHMENT0);
1916 EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);
1917
1918 glReadBuffer(GL_COLOR_ATTACHMENT1);
1919 EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);
1920 }
1921
1922 // Tests clearing a multisampled depth buffer.
TEST_P(BlitFramebufferTest,MultisampleDepthClear)1923 TEST_P(BlitFramebufferTest, MultisampleDepthClear)
1924 {
1925 // http://anglebug.com/40096654
1926 ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());
1927
1928 GLRenderbuffer depthMS;
1929 glBindRenderbuffer(GL_RENDERBUFFER, depthMS);
1930 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_DEPTH_COMPONENT24, 256, 256);
1931
1932 GLRenderbuffer colorMS;
1933 glBindRenderbuffer(GL_RENDERBUFFER, colorMS);
1934 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_RGBA8, 256, 256);
1935
1936 GLRenderbuffer colorResolved;
1937 glBindRenderbuffer(GL_RENDERBUFFER, colorResolved);
1938 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 256, 256);
1939
1940 GLFramebuffer framebufferMS;
1941 glBindFramebuffer(GL_FRAMEBUFFER, framebufferMS);
1942 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthMS);
1943 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorMS);
1944
1945 // Clear depth buffer to 0.5 and color to green.
1946 glClearDepthf(0.5f);
1947 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
1948 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
1949
1950 glFlush();
1951
1952 // Draw red into the multisampled color buffer.
1953 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
1954 glEnable(GL_DEPTH_TEST);
1955 glDepthFunc(GL_EQUAL);
1956 drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.0f);
1957
1958 // Resolve the color buffer to make sure the above draw worked correctly, which in turn implies
1959 // that the multisampled depth clear worked.
1960 GLFramebuffer framebufferResolved;
1961 glBindFramebuffer(GL_FRAMEBUFFER, framebufferResolved);
1962 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorResolved);
1963 glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferMS);
1964 glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1965
1966 glBindFramebuffer(GL_FRAMEBUFFER, framebufferResolved);
1967
1968 ASSERT_GL_NO_ERROR();
1969
1970 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1971 EXPECT_PIXEL_COLOR_EQ(255, 0, GLColor::red);
1972 EXPECT_PIXEL_COLOR_EQ(0, 255, GLColor::red);
1973 EXPECT_PIXEL_COLOR_EQ(255, 255, GLColor::red);
1974 EXPECT_PIXEL_COLOR_EQ(127, 127, GLColor::red);
1975
1976 ASSERT_GL_NO_ERROR();
1977 }
1978
1979 // Tests clearing a multisampled depth buffer with a glFenceSync in between.
TEST_P(BlitFramebufferTest,MultisampleDepthClearWithFenceSync)1980 TEST_P(BlitFramebufferTest, MultisampleDepthClearWithFenceSync)
1981 {
1982 // http://anglebug.com/40096654
1983 ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());
1984
1985 GLRenderbuffer depthMS;
1986 glBindRenderbuffer(GL_RENDERBUFFER, depthMS);
1987 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_DEPTH_COMPONENT24, 256, 256);
1988
1989 GLRenderbuffer colorMS;
1990 glBindRenderbuffer(GL_RENDERBUFFER, colorMS);
1991 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_RGBA8, 256, 256);
1992
1993 GLRenderbuffer colorResolved;
1994 glBindRenderbuffer(GL_RENDERBUFFER, colorResolved);
1995 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 256, 256);
1996
1997 GLFramebuffer framebufferMS;
1998 glBindFramebuffer(GL_FRAMEBUFFER, framebufferMS);
1999 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthMS);
2000 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorMS);
2001
2002 // Clear depth buffer to 0.5 and color to green.
2003 glClearDepthf(0.5f);
2004 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
2005 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
2006
2007 glFlush();
2008
2009 // Draw red into the multisampled color buffer.
2010 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
2011 glEnable(GL_DEPTH_TEST);
2012 glDepthFunc(GL_EQUAL);
2013 drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.0f);
2014
2015 // This should trigger a deferred renderPass end
2016 GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
2017 EXPECT_GL_NO_ERROR();
2018
2019 // Resolve the color buffer to make sure the above draw worked correctly, which in turn implies
2020 // that the multisampled depth clear worked.
2021 GLFramebuffer framebufferResolved;
2022 glBindFramebuffer(GL_FRAMEBUFFER, framebufferResolved);
2023 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorResolved);
2024 glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferMS);
2025 glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2026
2027 glBindFramebuffer(GL_FRAMEBUFFER, framebufferResolved);
2028
2029 ASSERT_GL_NO_ERROR();
2030
2031 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2032 EXPECT_PIXEL_COLOR_EQ(255, 0, GLColor::red);
2033 EXPECT_PIXEL_COLOR_EQ(0, 255, GLColor::red);
2034 EXPECT_PIXEL_COLOR_EQ(255, 255, GLColor::red);
2035 EXPECT_PIXEL_COLOR_EQ(127, 127, GLColor::red);
2036
2037 glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED);
2038 ASSERT_GL_NO_ERROR();
2039 }
2040
2041 // Test resolving a multisampled stencil buffer.
TEST_P(BlitFramebufferTest,MultisampleStencil)2042 TEST_P(BlitFramebufferTest, MultisampleStencil)
2043 {
2044 GLRenderbuffer renderbuf;
2045 glBindRenderbuffer(GL_RENDERBUFFER, renderbuf);
2046 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_STENCIL_INDEX8, 256, 256);
2047
2048 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
2049
2050 GLFramebuffer framebuffer;
2051 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
2052 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuf);
2053
2054 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
2055
2056 // fill the stencil buffer with 0x1
2057 glStencilFunc(GL_ALWAYS, 0x1, 0xFF);
2058 glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
2059 glEnable(GL_STENCIL_TEST);
2060 drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.5f);
2061
2062 GLTexture destColorbuf;
2063 glBindTexture(GL_TEXTURE_2D, destColorbuf);
2064 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);
2065
2066 GLRenderbuffer destRenderbuf;
2067 glBindRenderbuffer(GL_RENDERBUFFER, destRenderbuf);
2068 glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, 256, 256);
2069
2070 GLFramebuffer resolved;
2071 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolved);
2072 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, destColorbuf,
2073 0);
2074 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2075 destRenderbuf);
2076
2077 glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
2078 glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_STENCIL_BUFFER_BIT, GL_NEAREST);
2079
2080 // Immediately destroy the framebuffer and the associated textures for additional cleanup
2081 // ordering testing.
2082 framebuffer.reset();
2083 renderbuf.reset();
2084
2085 glBindFramebuffer(GL_FRAMEBUFFER, resolved);
2086
2087 ASSERT_GL_NO_ERROR();
2088
2089 // Clear to green
2090 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
2091 glClear(GL_COLOR_BUFFER_BIT);
2092 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2093
2094 // Draw red if the stencil is 0x1, which should be true after the resolve.
2095 glStencilFunc(GL_EQUAL, 0x1, 0xFF);
2096 drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.5f);
2097 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2098
2099 ASSERT_GL_NO_ERROR();
2100 }
2101
2102 // Test resolving a multisampled stencil buffer with scissor.
TEST_P(BlitFramebufferTest,ScissoredMultisampleStencil)2103 TEST_P(BlitFramebufferTest, ScissoredMultisampleStencil)
2104 {
2105 constexpr GLuint kSize = 256;
2106
2107 // Create the resolve framebuffer.
2108 GLTexture destColorbuf;
2109 glBindTexture(GL_TEXTURE_2D, destColorbuf);
2110 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
2111
2112 GLRenderbuffer destRenderbuf;
2113 glBindRenderbuffer(GL_RENDERBUFFER, destRenderbuf);
2114 glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, kSize, kSize);
2115
2116 GLFramebuffer resolved;
2117 glBindFramebuffer(GL_FRAMEBUFFER, resolved);
2118 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, destColorbuf,
2119 0);
2120 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2121 destRenderbuf);
2122
2123 // Clear the resolved buffer with gray and 0x10 stencil.
2124 GLColor gray(127, 127, 127, 255);
2125 glClearStencil(0x10);
2126 glClearColor(0.499f, 0.499f, 0.499f, 1.0f);
2127 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2128 EXPECT_PIXEL_COLOR_EQ(0, 0, gray);
2129 EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, gray);
2130
2131 // Create the multisampled framebuffer.
2132 GLRenderbuffer renderbuf;
2133 glBindRenderbuffer(GL_RENDERBUFFER, renderbuf);
2134 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_STENCIL_INDEX8, kSize, kSize);
2135
2136 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
2137 ANGLE_GL_PROGRAM(drawGreen, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());
2138 ANGLE_GL_PROGRAM(drawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());
2139
2140 GLFramebuffer framebuffer;
2141 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
2142 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuf);
2143
2144 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
2145
2146 // Fill the stencil buffer with 0x1.
2147 glClearStencil(0x1);
2148 glClear(GL_STENCIL_BUFFER_BIT);
2149
2150 // Fill a smaller region of the buffer with 0x2.
2151 glEnable(GL_SCISSOR_TEST);
2152 glEnable(GL_STENCIL_TEST);
2153 glScissor(kSize / 4, kSize / 4, kSize / 2, kSize / 2);
2154 glStencilFunc(GL_ALWAYS, 0x2, 0xFF);
2155 glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
2156 drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.5f);
2157
2158 // Blit into the resolved framebuffer (with scissor still enabled).
2159 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolved);
2160 glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_STENCIL_BUFFER_BIT, GL_NEAREST);
2161
2162 glBindFramebuffer(GL_FRAMEBUFFER, resolved);
2163
2164 ASSERT_GL_NO_ERROR();
2165
2166 // Draw blue if the stencil is 0x1, which should never be true.
2167 glDisable(GL_SCISSOR_TEST);
2168 glStencilMask(0);
2169 glStencilFunc(GL_EQUAL, 0x1, 0xFF);
2170 drawQuad(drawBlue, essl3_shaders::PositionAttrib(), 0.5f);
2171 EXPECT_PIXEL_COLOR_EQ(0, 0, gray);
2172 EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, gray);
2173 EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, gray);
2174 EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, gray);
2175 EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, gray);
2176
2177 // Draw red if the stencil is 0x2, which should be true in the middle after the blit/resolve.
2178 glStencilFunc(GL_EQUAL, 0x2, 0xFF);
2179 drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.5f);
2180 EXPECT_PIXEL_COLOR_EQ(0, 0, gray);
2181 EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, gray);
2182 EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, gray);
2183 EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, gray);
2184 EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::red);
2185
2186 // Draw green if the stencil is 0x10, which should be left untouched in the outer regions.
2187 glStencilFunc(GL_EQUAL, 0x10, 0xFF);
2188 drawQuad(drawGreen, essl3_shaders::PositionAttrib(), 0.5f);
2189 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2190 EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::green);
2191 EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::green);
2192 EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::green);
2193 EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::red);
2194
2195 ASSERT_GL_NO_ERROR();
2196 }
2197
2198 // Test blitting from a texture with non-zero base. The blit is non-stretching and between
2199 // identical formats so that the path that uses vkCmdBlitImage is taken.
TEST_P(BlitFramebufferTest,NonZeroBaseSource)2200 TEST_P(BlitFramebufferTest, NonZeroBaseSource)
2201 {
2202 // http://anglebug.com/40644751
2203 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsMac());
2204
2205 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
2206
2207 // Create a framebuffer for source data. It usea a non-zero base.
2208 GLTexture srcColor;
2209 glBindTexture(GL_TEXTURE_2D, srcColor);
2210 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2211 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2212 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2213
2214 GLFramebuffer srcFramebuffer;
2215 glBindFramebuffer(GL_FRAMEBUFFER, srcFramebuffer);
2216 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcColor, 1);
2217 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2218
2219 // fill the color buffer with red.
2220 drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.5f);
2221
2222 // Create a framebuffer for blit destination.
2223 GLTexture dstColor;
2224 glBindTexture(GL_TEXTURE_2D, dstColor);
2225 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2226
2227 GLFramebuffer dstFramebuffer;
2228 glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
2229 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dstColor, 0);
2230 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2231
2232 // Blit. Note: no stretching is done so that vkCmdBlitImage can be used.
2233 glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFramebuffer);
2234 glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2235
2236 glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
2237
2238 ASSERT_GL_NO_ERROR();
2239
2240 // Make sure the blit is done.
2241 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2242
2243 ASSERT_GL_NO_ERROR();
2244 }
2245
2246 // Test blitting to a texture with non-zero base. The blit is non-stretching and between
2247 // identical formats so that the path that uses vkCmdBlitImage is taken.
TEST_P(BlitFramebufferTest,NonZeroBaseDestination)2248 TEST_P(BlitFramebufferTest, NonZeroBaseDestination)
2249 {
2250 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
2251
2252 // Create a framebuffer for source data. It usea a non-zero base.
2253 GLTexture srcColor;
2254 glBindTexture(GL_TEXTURE_2D, srcColor);
2255 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2256
2257 GLFramebuffer srcFramebuffer;
2258 glBindFramebuffer(GL_FRAMEBUFFER, srcFramebuffer);
2259 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcColor, 0);
2260 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2261
2262 // fill the color buffer with red.
2263 drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.5f);
2264
2265 // Create a framebuffer for blit destination.
2266 GLTexture dstColor;
2267 glBindTexture(GL_TEXTURE_2D, dstColor);
2268 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2269 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2270 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2271
2272 GLFramebuffer dstFramebuffer;
2273 glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
2274 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dstColor, 1);
2275 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2276
2277 // Blit. Note: no stretching is done so that vkCmdBlitImage can be used.
2278 glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFramebuffer);
2279 glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2280
2281 glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
2282
2283 ASSERT_GL_NO_ERROR();
2284
2285 // Make sure the blit is done.
2286 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2287
2288 ASSERT_GL_NO_ERROR();
2289 }
2290
2291 // Test blitting from a stencil buffer with non-zero base.
TEST_P(BlitFramebufferTest,NonZeroBaseSourceStencil)2292 TEST_P(BlitFramebufferTest, NonZeroBaseSourceStencil)
2293 {
2294 // http://anglebug.com/40644751
2295 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsMac());
2296
2297 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
2298
2299 // Create a framebuffer with an attachment that has non-zero base
2300 GLTexture stencilTexture;
2301 glBindTexture(GL_TEXTURE_2D, stencilTexture);
2302 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 256, 256, 0, GL_DEPTH_STENCIL,
2303 GL_UNSIGNED_INT_24_8, nullptr);
2304 glTexImage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, 256, 256, 0, GL_DEPTH_STENCIL,
2305 GL_UNSIGNED_INT_24_8, nullptr);
2306 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2307
2308 GLFramebuffer srcFramebuffer;
2309 glBindFramebuffer(GL_FRAMEBUFFER, srcFramebuffer);
2310 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, stencilTexture, 1);
2311 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2312
2313 // fill the stencil buffer with 0x1
2314 glStencilFunc(GL_ALWAYS, 0x1, 0xFF);
2315 glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
2316 glEnable(GL_STENCIL_TEST);
2317 drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.5f);
2318
2319 // Create a framebuffer with an attachment that has non-zero base
2320 GLTexture colorTexture;
2321 glBindTexture(GL_TEXTURE_2D, colorTexture);
2322 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);
2323
2324 GLRenderbuffer renderbuf;
2325 glBindRenderbuffer(GL_RENDERBUFFER, renderbuf);
2326 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 256, 256);
2327
2328 GLFramebuffer dstFramebuffer;
2329 glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
2330 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
2331 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuf);
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.
TEST_P(BlitFramebufferTest,NonZeroBaseDestinationStencil)2356 TEST_P(BlitFramebufferTest, NonZeroBaseDestinationStencil)
2357 {
2358 // http://anglebug.com/40644751
2359 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsMac());
2360
2361 // http://anglebug.com/42263576
2362 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsWindows());
2363
2364 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
2365
2366 // Create a framebuffer for source data.
2367 GLRenderbuffer renderbuf;
2368 glBindRenderbuffer(GL_RENDERBUFFER, renderbuf);
2369 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 256, 256);
2370
2371 GLFramebuffer srcFramebuffer;
2372 glBindFramebuffer(GL_FRAMEBUFFER, srcFramebuffer);
2373 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuf);
2374 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2375
2376 // fill the stencil buffer with 0x1
2377 glStencilFunc(GL_ALWAYS, 0x1, 0xFF);
2378 glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
2379 glEnable(GL_STENCIL_TEST);
2380 drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.5f);
2381
2382 // Create a framebuffer with an attachment that has non-zero base
2383 GLTexture colorTexture;
2384 glBindTexture(GL_TEXTURE_2D, colorTexture);
2385 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);
2386
2387 GLTexture stencilTexture;
2388 glBindTexture(GL_TEXTURE_2D, stencilTexture);
2389 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 256, 256, 0, GL_DEPTH_STENCIL,
2390 GL_UNSIGNED_INT_24_8, nullptr);
2391 glTexImage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, 256, 256, 0, GL_DEPTH_STENCIL,
2392 GL_UNSIGNED_INT_24_8, nullptr);
2393 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2394
2395 GLFramebuffer dstFramebuffer;
2396 glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
2397 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
2398 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, stencilTexture, 1);
2399 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2400
2401 // Blit stencil.
2402 glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFramebuffer);
2403 glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_STENCIL_BUFFER_BIT, GL_NEAREST);
2404
2405 glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
2406
2407 ASSERT_GL_NO_ERROR();
2408
2409 // Clear to green
2410 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
2411 glClear(GL_COLOR_BUFFER_BIT);
2412 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2413
2414 // Draw red if the stencil is 0x1, which should be true after the blit.
2415 glStencilFunc(GL_EQUAL, 0x1, 0xFF);
2416 drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.5f);
2417 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2418
2419 ASSERT_GL_NO_ERROR();
2420 }
2421
2422 // Test blitting to a stencil buffer with non-zero base. Exercises the compute path in the Vulkan
2423 // backend if stencil export is not supported. The blit is not 1-to-1 for this path to be taken.
TEST_P(BlitFramebufferTest,NonZeroBaseDestinationStencilStretch)2424 TEST_P(BlitFramebufferTest, NonZeroBaseDestinationStencilStretch)
2425 {
2426 // http://anglebug.com/40644750
2427 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsWindows());
2428
2429 // http://anglebug.com/40644751
2430 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsMac());
2431
2432 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
2433
2434 // Create a framebuffer for source data.
2435 GLRenderbuffer renderbuf;
2436 glBindRenderbuffer(GL_RENDERBUFFER, renderbuf);
2437 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 256, 256);
2438
2439 GLFramebuffer srcFramebuffer;
2440 glBindFramebuffer(GL_FRAMEBUFFER, srcFramebuffer);
2441 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuf);
2442 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2443
2444 // fill the stencil buffer with 0x1
2445 glStencilFunc(GL_ALWAYS, 0x1, 0xFF);
2446 glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
2447 glEnable(GL_STENCIL_TEST);
2448 drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.5f);
2449
2450 // Create a framebuffer with an attachment that has non-zero base
2451 GLTexture colorTexture;
2452 glBindTexture(GL_TEXTURE_2D, colorTexture);
2453 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);
2454
2455 GLTexture stencilTexture;
2456 glBindTexture(GL_TEXTURE_2D, stencilTexture);
2457 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 256, 256, 0, GL_DEPTH_STENCIL,
2458 GL_UNSIGNED_INT_24_8, nullptr);
2459 glTexImage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, 256, 256, 0, GL_DEPTH_STENCIL,
2460 GL_UNSIGNED_INT_24_8, nullptr);
2461 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
2462
2463 GLFramebuffer dstFramebuffer;
2464 glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
2465 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
2466 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, stencilTexture, 1);
2467 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2468
2469 // Blit stencil. Note: stretch is intentional so vkCmdBlitImage cannot be used in the Vulkan
2470 // backend.
2471 glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFramebuffer);
2472 glBlitFramebuffer(0, 0, 256, 256, -256, -256, 512, 512, GL_STENCIL_BUFFER_BIT, GL_NEAREST);
2473
2474 glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
2475
2476 ASSERT_GL_NO_ERROR();
2477
2478 // Clear to green
2479 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
2480 glClear(GL_COLOR_BUFFER_BIT);
2481 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2482
2483 // Draw red if the stencil is 0x1, which should be true after the blit.
2484 glStencilFunc(GL_EQUAL, 0x1, 0xFF);
2485 drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.5f);
2486 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2487
2488 ASSERT_GL_NO_ERROR();
2489 }
2490
2491 // Blit an SRGB framebuffer and scale it.
TEST_P(BlitFramebufferTest,BlitSRGBToRGBAndScale)2492 TEST_P(BlitFramebufferTest, BlitSRGBToRGBAndScale)
2493 {
2494 constexpr const GLsizei kWidth = 256;
2495 constexpr const GLsizei kHeight = 256;
2496
2497 GLRenderbuffer sourceRBO, targetRBO;
2498 GLFramebuffer sourceFBO, targetFBO;
2499 initColorFBOWithCheckerPattern(&sourceFBO, &sourceRBO, GL_SRGB8_ALPHA8, kWidth * 2,
2500 kHeight * 2);
2501 initColorFBO(&targetFBO, &targetRBO, GL_RGBA8, kWidth, kHeight);
2502
2503 EXPECT_GL_NO_ERROR();
2504
2505 glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
2506 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
2507
2508 glViewport(0, 0, kWidth, kHeight);
2509
2510 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
2511 glClear(GL_COLOR_BUFFER_BIT);
2512
2513 // Scale down without flipping.
2514 glBlitFramebuffer(0, 0, kWidth * 2, kHeight * 2, 0, 0, kWidth, kHeight, GL_COLOR_BUFFER_BIT,
2515 GL_NEAREST);
2516
2517 EXPECT_GL_NO_ERROR();
2518
2519 glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
2520
2521 EXPECT_PIXEL_COLOR_EQ(kWidth / 4, kHeight / 4, GLColor::red);
2522 EXPECT_PIXEL_COLOR_EQ(kWidth / 4, 3 * kHeight / 4, GLColor::green);
2523 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, kHeight / 4, GLColor::blue);
2524 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, 3 * kHeight / 4, GLColor::yellow);
2525
2526 glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
2527 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
2528
2529 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
2530 glClear(GL_COLOR_BUFFER_BIT);
2531
2532 // Scale down and flip in the X direction.
2533 glBlitFramebuffer(0, 0, kWidth * 2, kHeight * 2, kWidth, 0, 0, kHeight, GL_COLOR_BUFFER_BIT,
2534 GL_NEAREST);
2535
2536 EXPECT_GL_NO_ERROR();
2537
2538 glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
2539
2540 EXPECT_PIXEL_COLOR_EQ(kWidth / 4, kHeight / 4, GLColor::blue);
2541 EXPECT_PIXEL_COLOR_EQ(kWidth / 4, 3 * kHeight / 4, GLColor::yellow);
2542 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, kHeight / 4, GLColor::red);
2543 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, 3 * kHeight / 4, GLColor::green);
2544 }
2545
2546 // Blit stencil, with scissor and scale it.
TEST_P(BlitFramebufferTest,BlitStencilScissoredScaled)2547 TEST_P(BlitFramebufferTest, BlitStencilScissoredScaled)
2548 {
2549 constexpr GLint kSize = 256;
2550
2551 // Create the destination framebuffer.
2552 GLTexture destColorbuf;
2553 glBindTexture(GL_TEXTURE_2D, destColorbuf);
2554 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
2555
2556 GLRenderbuffer destRenderbuf;
2557 glBindRenderbuffer(GL_RENDERBUFFER, destRenderbuf);
2558 glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, kSize, kSize);
2559
2560 GLFramebuffer destFBO;
2561 glBindFramebuffer(GL_FRAMEBUFFER, destFBO);
2562 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, destColorbuf,
2563 0);
2564 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2565 destRenderbuf);
2566
2567 // Clear the destination buffer with gray and 0x10 stencil.
2568 GLColor gray(127, 127, 127, 255);
2569 glClearStencil(0x10);
2570 glClearColor(0.499f, 0.499f, 0.499f, 1.0f);
2571 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2572 EXPECT_PIXEL_COLOR_EQ(0, 0, gray);
2573 EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, gray);
2574
2575 // Create the source framebuffer.
2576 GLRenderbuffer renderbuf;
2577 glBindRenderbuffer(GL_RENDERBUFFER, renderbuf);
2578 glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, kSize, kSize);
2579
2580 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
2581 ANGLE_GL_PROGRAM(drawGreen, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());
2582 ANGLE_GL_PROGRAM(drawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());
2583
2584 GLFramebuffer sourceFBO;
2585 glBindFramebuffer(GL_FRAMEBUFFER, sourceFBO);
2586 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuf);
2587
2588 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
2589
2590 // Fill the stencil buffer with 0x1.
2591 glClearStencil(0x1);
2592 glClear(GL_STENCIL_BUFFER_BIT);
2593
2594 // Fill a smaller region of the buffer with 0x2.
2595 glEnable(GL_SCISSOR_TEST);
2596 glEnable(GL_STENCIL_TEST);
2597 glScissor(kSize / 4, kSize / 4, kSize / 2, kSize / 2);
2598 glStencilFunc(GL_ALWAYS, 0x2, 0xFF);
2599 glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
2600 drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.5f);
2601
2602 // Blit and scale down into the destination framebuffer (with scissor still enabled).
2603 //
2604 // Source looks like this:
2605 //
2606 // +----|----|----|----+
2607 // | |
2608 // | 0x1 |
2609 // - +---------+ -
2610 // | | | |
2611 // | | | |
2612 // - | 0x2 | -
2613 // | | | |
2614 // | | | |
2615 // - +---------+ -
2616 // | |
2617 // | |
2618 // +----|----|----|----+
2619 //
2620 // We want the destination to look like this:
2621 //
2622 // +----|----|----|----+
2623 // | |
2624 // | 0x10 |
2625 // - +---------+ -
2626 // | | 0x1 | |
2627 // | | +------+ |
2628 // - | | | -
2629 // | | | 0x2 | |
2630 // | | | | |
2631 // - +--+------+ -
2632 // | |
2633 // | |
2634 // +----|----|----|----+
2635 //
2636 // The corresponding blit would be: (0, 0, 3/4, 3/4) -> (1/4, 1/4, 3/4, 3/4). For testing, we
2637 // would like to avoid having the destination area and scissor to match. Using destination
2638 // area as (0, 0, 1, 1), and keeping the same scaling, the source area should be
2639 // (-3/8, -3/8, 9/8, 9/8).
2640 //
2641 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, destFBO);
2642 constexpr GLint kBlitSrc[2] = {-3 * kSize / 8, 9 * kSize / 8};
2643 glBlitFramebuffer(kBlitSrc[0], kBlitSrc[0], kBlitSrc[1], kBlitSrc[1], 0, 0, kSize, kSize,
2644 GL_STENCIL_BUFFER_BIT, GL_NEAREST);
2645
2646 glBindFramebuffer(GL_FRAMEBUFFER, destFBO);
2647
2648 ASSERT_GL_NO_ERROR();
2649
2650 // Draw blue if the stencil is 0x1, which should be true only in the top and left of the inner
2651 // square.
2652 glDisable(GL_SCISSOR_TEST);
2653 glStencilMask(0);
2654 glStencilFunc(GL_EQUAL, 0x1, 0xFF);
2655 drawQuad(drawBlue, essl3_shaders::PositionAttrib(), 0.5f);
2656 EXPECT_PIXEL_COLOR_EQ(0, 0, gray);
2657 EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, gray);
2658 EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, gray);
2659 EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, gray);
2660
2661 EXPECT_PIXEL_COLOR_EQ(kSize / 4, kSize / 4, GLColor::blue);
2662 EXPECT_PIXEL_COLOR_EQ(kSize / 4, 3 * kSize / 4 - 1, GLColor::blue);
2663 EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, kSize / 4, GLColor::blue);
2664
2665 EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, gray);
2666 EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, 3 * kSize / 4 - 1, gray);
2667
2668 // Draw red if the stencil is 0x2, which should be true in the bottom/right of the middle
2669 // square after the blit.
2670 glStencilFunc(GL_EQUAL, 0x2, 0xFF);
2671 drawQuad(drawRed, essl3_shaders::PositionAttrib(), 0.5f);
2672 EXPECT_PIXEL_COLOR_EQ(0, 0, gray);
2673 EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, gray);
2674 EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, gray);
2675 EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, gray);
2676
2677 EXPECT_PIXEL_COLOR_EQ(kSize / 4, kSize / 4, GLColor::blue);
2678 EXPECT_PIXEL_COLOR_EQ(kSize / 4, 3 * kSize / 4 - 1, GLColor::blue);
2679 EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, kSize / 4, GLColor::blue);
2680
2681 EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::red);
2682 EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, 3 * kSize / 4 - 1, GLColor::red);
2683
2684 // Draw green if the stencil is 0x10, which should be left untouched in the outer regions.
2685 glStencilFunc(GL_EQUAL, 0x10, 0xFF);
2686 drawQuad(drawGreen, essl3_shaders::PositionAttrib(), 0.5f);
2687 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2688 EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::green);
2689 EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::green);
2690 EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::green);
2691
2692 EXPECT_PIXEL_COLOR_EQ(kSize / 4, kSize / 4, GLColor::blue);
2693 EXPECT_PIXEL_COLOR_EQ(kSize / 4, 3 * kSize / 4 - 1, GLColor::blue);
2694 EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, kSize / 4, GLColor::blue);
2695
2696 EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::red);
2697 EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, 3 * kSize / 4 - 1, GLColor::red);
2698
2699 ASSERT_GL_NO_ERROR();
2700 }
2701
2702 // Blit a subregion of an SRGB framebuffer to an RGB framebuffer.
TEST_P(BlitFramebufferTest,PartialBlitSRGBToRGB)2703 TEST_P(BlitFramebufferTest, PartialBlitSRGBToRGB)
2704 {
2705 constexpr const GLsizei kWidth = 256;
2706 constexpr const GLsizei kHeight = 256;
2707
2708 GLRenderbuffer sourceRBO, targetRBO;
2709 GLFramebuffer sourceFBO, targetFBO;
2710 initColorFBOWithCheckerPattern(&sourceFBO, &sourceRBO, GL_SRGB8_ALPHA8, kWidth * 2,
2711 kHeight * 2);
2712 initColorFBO(&targetFBO, &targetRBO, GL_RGBA8, kWidth, kHeight);
2713
2714 EXPECT_GL_NO_ERROR();
2715
2716 glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
2717 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
2718
2719 glViewport(0, 0, kWidth, kHeight);
2720
2721 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
2722 glClear(GL_COLOR_BUFFER_BIT);
2723
2724 // Blit a part of the source FBO without flipping.
2725 glBlitFramebuffer(kWidth, kHeight, kWidth * 2, kHeight * 2, 0, 0, kWidth, kHeight,
2726 GL_COLOR_BUFFER_BIT, GL_NEAREST);
2727
2728 EXPECT_GL_NO_ERROR();
2729
2730 glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
2731
2732 EXPECT_PIXEL_COLOR_EQ(kWidth / 4, kHeight / 4, GLColor::yellow);
2733 EXPECT_PIXEL_COLOR_EQ(kWidth / 4, 3 * kHeight / 4, GLColor::yellow);
2734 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, kHeight / 4, GLColor::yellow);
2735 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, 3 * kHeight / 4, GLColor::yellow);
2736
2737 glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
2738 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
2739
2740 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
2741 glClear(GL_COLOR_BUFFER_BIT);
2742
2743 // Blit a part of the source FBO and flip in the X direction.
2744 glBlitFramebuffer(kWidth * 2, 0, kWidth, kHeight, kWidth, 0, 0, kHeight, GL_COLOR_BUFFER_BIT,
2745 GL_NEAREST);
2746
2747 EXPECT_GL_NO_ERROR();
2748
2749 glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
2750
2751 EXPECT_PIXEL_COLOR_EQ(kWidth / 4, kHeight / 4, GLColor::blue);
2752 EXPECT_PIXEL_COLOR_EQ(kWidth / 4, 3 * kHeight / 4, GLColor::blue);
2753 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, kHeight / 4, GLColor::blue);
2754 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, 3 * kHeight / 4, GLColor::blue);
2755 }
2756
2757 // Blit an SRGB framebuffer with an oversized source area (parts outside the source area should be
2758 // clipped out).
TEST_P(BlitFramebufferTest,BlitSRGBToRGBOversizedSourceArea)2759 TEST_P(BlitFramebufferTest, BlitSRGBToRGBOversizedSourceArea)
2760 {
2761 constexpr const GLsizei kWidth = 256;
2762 constexpr const GLsizei kHeight = 256;
2763
2764 GLRenderbuffer sourceRBO, targetRBO;
2765 GLFramebuffer sourceFBO, targetFBO;
2766 initColorFBOWithCheckerPattern(&sourceFBO, &sourceRBO, GL_SRGB8_ALPHA8, kWidth, kHeight);
2767 initColorFBO(&targetFBO, &targetRBO, GL_RGBA8, kWidth, kHeight);
2768
2769 EXPECT_GL_NO_ERROR();
2770
2771 glViewport(0, 0, kWidth, kHeight);
2772
2773 glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
2774 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
2775
2776 glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
2777 glClear(GL_COLOR_BUFFER_BIT);
2778
2779 // Blit so that the source area gets placed at the center of the target FBO.
2780 // The width of the source area is 1/4 of the width of the target FBO.
2781 glBlitFramebuffer(-3 * kWidth / 2, -3 * kHeight / 2, 5 * kWidth / 2, 5 * kHeight / 2, 0, 0,
2782 kWidth, kHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2783
2784 EXPECT_GL_NO_ERROR();
2785
2786 glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
2787
2788 // Source FBO colors can be found in the middle of the target FBO.
2789 EXPECT_PIXEL_COLOR_EQ(7 * kWidth / 16, 7 * kHeight / 16, GLColor::red);
2790 EXPECT_PIXEL_COLOR_EQ(7 * kWidth / 16, 9 * kHeight / 16, GLColor::green);
2791 EXPECT_PIXEL_COLOR_EQ(9 * kWidth / 16, 7 * kHeight / 16, GLColor::blue);
2792 EXPECT_PIXEL_COLOR_EQ(9 * kWidth / 16, 9 * kHeight / 16, GLColor::yellow);
2793
2794 // Clear color should remain around the edges of the target FBO (WebGL 2.0 spec explicitly
2795 // requires this and ANGLE is expected to follow that).
2796 EXPECT_PIXEL_COLOR_EQ(kWidth / 4, kHeight / 4, GLColor::blue);
2797 EXPECT_PIXEL_COLOR_EQ(kWidth / 4, 3 * kHeight / 4, GLColor::blue);
2798 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, kHeight / 4, GLColor::blue);
2799 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, 3 * kHeight / 4, GLColor::blue);
2800 }
2801
2802 // Blit an SRGB framebuffer with an oversized dest area (even though the result is clipped, it
2803 // should be scaled as if the whole dest area was used).
TEST_P(BlitFramebufferTest,BlitSRGBToRGBOversizedDestArea)2804 TEST_P(BlitFramebufferTest, BlitSRGBToRGBOversizedDestArea)
2805 {
2806 constexpr const GLsizei kWidth = 256;
2807 constexpr const GLsizei kHeight = 256;
2808
2809 GLRenderbuffer sourceRBO, targetRBO;
2810 GLFramebuffer sourceFBO, targetFBO;
2811 initColorFBOWithCheckerPattern(&sourceFBO, &sourceRBO, GL_SRGB8_ALPHA8, kWidth, kHeight);
2812 initColorFBO(&targetFBO, &targetRBO, GL_RGBA8, kWidth, kHeight);
2813
2814 EXPECT_GL_NO_ERROR();
2815
2816 glViewport(0, 0, kWidth, kHeight);
2817
2818 glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
2819 glClear(GL_COLOR_BUFFER_BIT);
2820
2821 // Dest is oversized but centered the same as source
2822 glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
2823 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
2824
2825 glBlitFramebuffer(0, 0, kWidth, kHeight, -kWidth / 2, -kHeight / 2, 3 * kWidth / 2,
2826 3 * kHeight / 2, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2827
2828 EXPECT_GL_NO_ERROR();
2829
2830 glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
2831
2832 // Expected result:
2833 //
2834 // +-------+-------+
2835 // | | |
2836 // | R | B |
2837 // | | |
2838 // +-------+-------+
2839 // | | |
2840 // | G | Y |
2841 // | | |
2842 // +-------+-------+
2843 //
2844 EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::red);
2845 EXPECT_PIXEL_COLOR_EQ(kWidth / 4, kHeight / 4, GLColor::red);
2846 EXPECT_PIXEL_COLOR_EQ(kWidth / 2 - 1, kHeight / 2 - 1, GLColor::red);
2847
2848 EXPECT_PIXEL_COLOR_EQ(1, kWidth - 1, GLColor::green);
2849 EXPECT_PIXEL_COLOR_EQ(kWidth / 4, 3 * kHeight / 4, GLColor::green);
2850 EXPECT_PIXEL_COLOR_EQ(kWidth / 2 - 1, kHeight / 2 + 1, GLColor::green);
2851
2852 EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 1, GLColor::blue);
2853 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, kHeight / 4, GLColor::blue);
2854 EXPECT_PIXEL_COLOR_EQ(kWidth / 2 + 1, kHeight / 2 - 1, GLColor::blue);
2855
2856 EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::yellow);
2857 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, 3 * kHeight / 4, GLColor::yellow);
2858 EXPECT_PIXEL_COLOR_EQ(kWidth / 2 + 1, kHeight / 2 + 1, GLColor::yellow);
2859
2860 // Dest is oversized in the negative direction
2861 glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
2862 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
2863
2864 glBlitFramebuffer(0, 0, kWidth, kHeight, -kWidth / 2, -kHeight / 2, kWidth, kHeight,
2865 GL_COLOR_BUFFER_BIT, GL_NEAREST);
2866
2867 EXPECT_GL_NO_ERROR();
2868
2869 glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
2870
2871 // Expected result:
2872 //
2873 // Width / 4
2874 // |
2875 // V
2876 // +---+-----------+
2877 // | R | B |
2878 // +---+-----------+ <- Height / 4
2879 // | | |
2880 // | | |
2881 // | G | Y |
2882 // | | |
2883 // | | |
2884 // +---+-----------+
2885 //
2886 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2887 EXPECT_PIXEL_COLOR_EQ(0, kHeight / 4 - 1, GLColor::red);
2888 EXPECT_PIXEL_COLOR_EQ(kWidth / 4 - 1, 0, GLColor::red);
2889 EXPECT_PIXEL_COLOR_EQ(kWidth / 4 - 1, kHeight / 4 - 1, GLColor::red);
2890 EXPECT_PIXEL_COLOR_EQ(kWidth / 8, kHeight / 8, GLColor::red);
2891
2892 EXPECT_PIXEL_COLOR_EQ(0, kHeight / 4 + 1, GLColor::green);
2893 EXPECT_PIXEL_COLOR_EQ(0, kHeight - 1, GLColor::green);
2894 EXPECT_PIXEL_COLOR_EQ(kWidth / 4 - 1, kHeight / 4 + 1, GLColor::green);
2895 EXPECT_PIXEL_COLOR_EQ(kWidth / 4 - 1, kHeight - 1, GLColor::green);
2896 EXPECT_PIXEL_COLOR_EQ(kWidth / 8, kHeight / 2, GLColor::green);
2897
2898 EXPECT_PIXEL_COLOR_EQ(kWidth / 4 + 1, 0, GLColor::blue);
2899 EXPECT_PIXEL_COLOR_EQ(kWidth / 4 + 1, kHeight / 4 - 1, GLColor::blue);
2900 EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 0, GLColor::blue);
2901 EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight / 4 - 1, GLColor::blue);
2902 EXPECT_PIXEL_COLOR_EQ(kWidth / 2, kHeight / 8, GLColor::blue);
2903
2904 EXPECT_PIXEL_COLOR_EQ(kWidth / 4 + 1, kHeight / 4 + 1, GLColor::yellow);
2905 EXPECT_PIXEL_COLOR_EQ(kWidth / 4 + 1, kHeight - 1, GLColor::yellow);
2906 EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight / 4 + 1, GLColor::yellow);
2907 EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::yellow);
2908 EXPECT_PIXEL_COLOR_EQ(kWidth / 2, kHeight / 2, GLColor::yellow);
2909
2910 // Dest is oversized in the positive direction
2911 glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
2912 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
2913
2914 glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, 3 * kWidth / 2, 3 * kHeight / 2,
2915 GL_COLOR_BUFFER_BIT, GL_NEAREST);
2916
2917 EXPECT_GL_NO_ERROR();
2918
2919 glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
2920
2921 // Expected result:
2922 //
2923 // 3 * Width / 4
2924 // |
2925 // V
2926 // +-----------+---+
2927 // | | |
2928 // | | |
2929 // | R | B |
2930 // | | |
2931 // | | |
2932 // +-----------+---+ <- 3 * Height / 4
2933 // | G | Y |
2934 // +-----------+---+
2935 //
2936 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2937 EXPECT_PIXEL_COLOR_EQ(0, 3 * kHeight / 4 - 1, GLColor::red);
2938 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 - 1, 0, GLColor::red);
2939 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 - 1, 3 * kHeight / 4 - 1, GLColor::red);
2940 EXPECT_PIXEL_COLOR_EQ(kWidth / 2, kHeight / 2, GLColor::red);
2941
2942 EXPECT_PIXEL_COLOR_EQ(0, 3 * kHeight / 4 + 1, GLColor::green);
2943 EXPECT_PIXEL_COLOR_EQ(0, kHeight - 1, GLColor::green);
2944 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 - 1, 3 * kHeight / 4 + 1, GLColor::green);
2945 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 - 1, kHeight - 1, GLColor::green);
2946 EXPECT_PIXEL_COLOR_EQ(kWidth / 2, 7 * kHeight / 8, GLColor::green);
2947
2948 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 + 1, 0, GLColor::blue);
2949 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 + 1, 3 * kHeight / 4 - 1, GLColor::blue);
2950 EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 0, GLColor::blue);
2951 EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 3 * kHeight / 4 - 1, GLColor::blue);
2952 EXPECT_PIXEL_COLOR_EQ(7 * kWidth / 8, kHeight / 2, GLColor::blue);
2953
2954 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 + 1, 3 * kHeight / 4 + 1, GLColor::yellow);
2955 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 + 1, kHeight - 1, GLColor::yellow);
2956 EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 3 * kHeight / 4 + 1, GLColor::yellow);
2957 EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::yellow);
2958 EXPECT_PIXEL_COLOR_EQ(7 * kWidth / 8, 7 * kHeight / 8, GLColor::yellow);
2959 }
2960
2961 // This test is to demonstrate a bug that when a program is created and used and then destroyed, we
2962 // should not have a dangling PipelineHelper pointer in the context point to the already destroyed
2963 // object.
TEST_P(BlitFramebufferTest,useAndDestroyProgramThenBlit)2964 TEST_P(BlitFramebufferTest, useAndDestroyProgramThenBlit)
2965 {
2966 constexpr const GLsizei kWidth = 256;
2967 constexpr const GLsizei kHeight = 256;
2968
2969 GLRenderbuffer sourceRBO, targetRBO;
2970 GLFramebuffer sourceFBO, targetFBO;
2971
2972 {
2973 initColorFBO(&sourceFBO, &sourceRBO, GL_SRGB8_ALPHA8, kWidth, kHeight);
2974 // checkerProgram will be created and destroyed in this code block
2975 ANGLE_GL_PROGRAM(checkerProgram, essl1_shaders::vs::Passthrough(),
2976 essl1_shaders::fs::Checkered());
2977 glViewport(0, 0, kWidth, kHeight);
2978 glBindFramebuffer(GL_FRAMEBUFFER, sourceFBO);
2979 drawQuad(checkerProgram, essl1_shaders::PositionAttrib(), 0.5f);
2980 EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::red);
2981 }
2982 initColorFBO(&targetFBO, &targetRBO, GL_RGBA8, kWidth, kHeight);
2983 EXPECT_GL_NO_ERROR();
2984
2985 glViewport(0, 0, kWidth, kHeight);
2986 glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
2987 glClear(GL_COLOR_BUFFER_BIT);
2988
2989 // Blit call should not crash or assert
2990 glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
2991 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
2992 glBlitFramebuffer(0, 0, kWidth, kHeight, -kWidth / 2, -kHeight / 2, 3 * kWidth / 2,
2993 3 * kHeight / 2, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2994 EXPECT_GL_NO_ERROR();
2995 }
2996
2997 // This test is to ensure the draw after blit without any state change works properly
TEST_P(BlitFramebufferTest,drawBlitAndDrawAgain)2998 TEST_P(BlitFramebufferTest, drawBlitAndDrawAgain)
2999 {
3000 constexpr const GLsizei kWidth = 256;
3001 constexpr const GLsizei kHeight = 256;
3002
3003 GLRenderbuffer srcColorRB, srcDepthRB;
3004 GLFramebuffer srcFBO;
3005
3006 ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Red());
3007 ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Green());
3008 ANGLE_GL_PROGRAM(drawBlue, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Blue());
3009
3010 // Initialize source FBO with red color and depth==0.8f
3011 initFBOWithProgramAndDepth(&srcFBO, &srcColorRB, GL_RGBA8, &srcDepthRB, GL_DEPTH24_STENCIL8_OES,
3012 kWidth, kHeight, drawRed, 0.8f);
3013 EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::red);
3014
3015 // Initialize destination FBO and initialize to green and depth==0.7
3016 initFBOWithProgramAndDepth(nullptr, nullptr, 0, nullptr, 0, kWidth, kHeight, drawGreen, 0.7f);
3017 EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::green);
3018
3019 // Setup for draw-blit-draw use pattern
3020 glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFBO);
3021 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
3022 std::array<Vector3, 6> quadVertices = GetQuadVertices();
3023 constexpr size_t kBufferSize = sizeof(quadVertices[0]) * quadVertices.size();
3024 GLBuffer vertexBuffer;
3025 glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
3026 glBufferData(GL_ARRAY_BUFFER, kBufferSize, nullptr, GL_STATIC_DRAW);
3027 glUseProgram(drawBlue);
3028 const GLint positionLocation = glGetAttribLocation(drawBlue, essl1_shaders::PositionAttrib());
3029 ASSERT_NE(-1, positionLocation);
3030 glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
3031 glEnableVertexAttribArray(positionLocation);
3032
3033 // Draw with depth=0.75, should fail depth test
3034 drawWithDepthValue(quadVertices, 0.75f);
3035 // Now blit depth buffer from source FBO to the right half of destination FBO, so left half has
3036 // depth 0.7f and right half has 0.8f
3037 glBlitFramebuffer(kWidth / 2, 0, kWidth, kHeight, kWidth / 2, 0, kWidth, kHeight,
3038 GL_DEPTH_BUFFER_BIT, GL_NEAREST);
3039 // Continue draw without state change and depth==0.75f, now it should pass depth test on right
3040 // half
3041 glDrawArrays(GL_TRIANGLES, 0, 6);
3042
3043 // Now verify dstFBO
3044 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
3045 EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::green);
3046 EXPECT_PIXEL_COLOR_EQ(kWidth / 2 + 1, 1, GLColor::blue);
3047 EXPECT_GL_NO_ERROR();
3048 }
3049
3050 // This test is to ensure the scissored draw after blit without any state change works properly
TEST_P(BlitFramebufferTest,scissorDrawBlitAndDrawAgain)3051 TEST_P(BlitFramebufferTest, scissorDrawBlitAndDrawAgain)
3052 {
3053 constexpr const GLsizei kWidth = 256;
3054 constexpr const GLsizei kHeight = 256;
3055
3056 GLRenderbuffer srcColorRB, srcDepthRB;
3057 GLFramebuffer srcFBO;
3058
3059 ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Red());
3060 ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Green());
3061 ANGLE_GL_PROGRAM(drawBlue, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Blue());
3062
3063 // Initialize source FBO with red color and depth==0.8f
3064 initFBOWithProgramAndDepth(&srcFBO, &srcColorRB, GL_RGBA8, &srcDepthRB, GL_DEPTH24_STENCIL8_OES,
3065 kWidth, kHeight, drawRed, 0.8f);
3066 EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::red);
3067
3068 // Initialize destination FBO and initialize to green and depth==0.7
3069 initFBOWithProgramAndDepth(nullptr, nullptr, 0, nullptr, 0, kWidth, kHeight, drawGreen, 0.7f);
3070 EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::green);
3071
3072 // Setup for draw-blit-draw use pattern
3073 glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFBO);
3074 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
3075 std::array<Vector3, 6> quadVertices = GetQuadVertices();
3076 constexpr size_t kBufferSize = sizeof(quadVertices[0]) * quadVertices.size();
3077 GLBuffer vertexBuffer;
3078 glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
3079 glBufferData(GL_ARRAY_BUFFER, kBufferSize, nullptr, GL_STATIC_DRAW);
3080 glUseProgram(drawBlue);
3081 const GLint positionLocation = glGetAttribLocation(drawBlue, essl1_shaders::PositionAttrib());
3082 ASSERT_NE(-1, positionLocation);
3083 glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
3084 glEnableVertexAttribArray(positionLocation);
3085
3086 // Scissored draw with depth=0.75, should fail depth test
3087 glEnable(GL_SCISSOR_TEST);
3088 glScissor(0, 0, kWidth, kHeight / 2);
3089 drawWithDepthValue(quadVertices, 0.75f);
3090 // Now blit depth buffer from source FBO to the right half of destination FBO, so left half has
3091 // depth 0.7f and right half has 0.8f
3092 glBlitFramebuffer(kWidth / 2, 0, kWidth, kHeight, kWidth / 2, 0, kWidth, kHeight,
3093 GL_DEPTH_BUFFER_BIT, GL_NEAREST);
3094 // Continue draw without state change and depth==0.75f, now it should pass depth test on right
3095 // half
3096 glDrawArrays(GL_TRIANGLES, 0, 6);
3097
3098 // Now verify dstFBO
3099 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
3100 EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::green);
3101 EXPECT_PIXEL_COLOR_EQ(kWidth / 2 + 1, 1, GLColor::blue);
3102 EXPECT_PIXEL_COLOR_EQ(1, kHeight - 1, GLColor::green);
3103 EXPECT_PIXEL_COLOR_EQ(kWidth / 2 + 1, kHeight - 1, GLColor::green);
3104 EXPECT_GL_NO_ERROR();
3105 }
3106
3107 // Test blitFramebuffer size overflow checks. WebGL 2.0 spec section 5.41. We do validation for
3108 // overflows also in non-WebGL mode to avoid triggering driver bugs.
TEST_P(BlitFramebufferTest,BlitFramebufferSizeOverflow)3109 TEST_P(BlitFramebufferTest, BlitFramebufferSizeOverflow)
3110 {
3111 GLTexture textures[2];
3112 glBindTexture(GL_TEXTURE_2D, textures[0]);
3113 glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, 4, 4);
3114 glBindTexture(GL_TEXTURE_2D, textures[1]);
3115 glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, 4, 4);
3116
3117 GLFramebuffer framebuffers[2];
3118 glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffers[0]);
3119 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffers[1]);
3120
3121 ASSERT_GL_NO_ERROR();
3122
3123 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0],
3124 0);
3125 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1],
3126 0);
3127 ASSERT_GL_NO_ERROR();
3128
3129 // srcX
3130 glBlitFramebuffer(-1, 0, std::numeric_limits<GLint>::max(), 4, 0, 0, 4, 4, GL_COLOR_BUFFER_BIT,
3131 GL_NEAREST);
3132 EXPECT_GL_ERROR(GL_INVALID_VALUE);
3133 glBlitFramebuffer(std::numeric_limits<GLint>::max(), 0, -1, 4, 0, 0, 4, 4, GL_COLOR_BUFFER_BIT,
3134 GL_NEAREST);
3135 EXPECT_GL_ERROR(GL_INVALID_VALUE);
3136
3137 // srcY
3138 glBlitFramebuffer(0, -1, 4, std::numeric_limits<GLint>::max(), 0, 0, 4, 4, GL_COLOR_BUFFER_BIT,
3139 GL_NEAREST);
3140 EXPECT_GL_ERROR(GL_INVALID_VALUE);
3141 glBlitFramebuffer(0, std::numeric_limits<GLint>::max(), 4, -1, 0, 0, 4, 4, GL_COLOR_BUFFER_BIT,
3142 GL_NEAREST);
3143 EXPECT_GL_ERROR(GL_INVALID_VALUE);
3144
3145 // dstX
3146 glBlitFramebuffer(0, 0, 4, 4, -1, 0, std::numeric_limits<GLint>::max(), 4, GL_COLOR_BUFFER_BIT,
3147 GL_NEAREST);
3148 EXPECT_GL_ERROR(GL_INVALID_VALUE);
3149 glBlitFramebuffer(0, 0, 4, 4, std::numeric_limits<GLint>::max(), 0, -1, 4, GL_COLOR_BUFFER_BIT,
3150 GL_NEAREST);
3151 EXPECT_GL_ERROR(GL_INVALID_VALUE);
3152
3153 // dstY
3154 glBlitFramebuffer(0, 0, 4, 4, 0, -1, 4, std::numeric_limits<GLint>::max(), GL_COLOR_BUFFER_BIT,
3155 GL_NEAREST);
3156 EXPECT_GL_ERROR(GL_INVALID_VALUE);
3157 glBlitFramebuffer(0, 0, 4, 4, 0, std::numeric_limits<GLint>::max(), 4, -1, GL_COLOR_BUFFER_BIT,
3158 GL_NEAREST);
3159 EXPECT_GL_ERROR(GL_INVALID_VALUE);
3160 }
3161
3162 // Test blitFramebuffer size overflow checks. WebGL 2.0 spec section 5.41. Similar to above test,
3163 // but this test more accurately duplicates the behavior of the WebGL test
3164 // conformance2/rendering/blitframebuffer-size-overflow.html, which covers a few more edge cases.
TEST_P(BlitFramebufferTest,BlitFramebufferSizeOverflow2)3165 TEST_P(BlitFramebufferTest, BlitFramebufferSizeOverflow2)
3166 {
3167 GLTexture textures[2];
3168 glBindTexture(GL_TEXTURE_2D, textures[0]);
3169 glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, 4, 4);
3170 glBindTexture(GL_TEXTURE_2D, textures[1]);
3171 glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, 4, 4);
3172
3173 GLFramebuffer framebuffers[2];
3174 glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffers[0]);
3175 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffers[1]);
3176
3177 ASSERT_GL_NO_ERROR();
3178
3179 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0],
3180 0);
3181 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1],
3182 0);
3183 ASSERT_GL_NO_ERROR();
3184
3185 GLint width = 8;
3186 GLint height = 8;
3187
3188 GLTexture tex0;
3189 glBindTexture(GL_TEXTURE_2D, tex0);
3190 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
3191
3192 GLFramebuffer fb0;
3193 glBindFramebuffer(GL_READ_FRAMEBUFFER, fb0);
3194 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex0, 0);
3195
3196 GLTexture tex1;
3197 glBindTexture(GL_TEXTURE_2D, tex1);
3198 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
3199
3200 GLFramebuffer fb1;
3201 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb1);
3202 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex1, 0);
3203
3204 GLint max = std::numeric_limits<GLint>::max();
3205 // Using max 32-bit integer as blitFramebuffer parameter should succeed.
3206 glBlitFramebuffer(0, 0, max, max, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3207 glBlitFramebuffer(0, 0, width, height, 0, 0, max, max, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3208 glBlitFramebuffer(0, 0, max, max, 0, 0, max, max, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3209 EXPECT_GL_NO_ERROR();
3210
3211 // Using blitFramebuffer parameters where calculated width/height matches max 32-bit integer
3212 // should succeed
3213 glBlitFramebuffer(-1, -1, max - 1, max - 1, 0, 0, width, height, GL_COLOR_BUFFER_BIT,
3214 GL_NEAREST);
3215 glBlitFramebuffer(0, 0, width, height, -1, -1, max - 1, max - 1, GL_COLOR_BUFFER_BIT,
3216 GL_NEAREST);
3217 glBlitFramebuffer(-1, -1, max - 1, max - 1, -1, -1, max - 1, max - 1, GL_COLOR_BUFFER_BIT,
3218 GL_NEAREST);
3219 EXPECT_GL_NO_ERROR();
3220
3221 // Using source width/height greater than max 32-bit integer should fail.
3222 glBlitFramebuffer(-1, -1, max, max, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3223 EXPECT_GL_ERROR(GL_INVALID_VALUE);
3224
3225 // Using source width/height greater than max 32-bit integer should fail.
3226 glBlitFramebuffer(max, max, -1, -1, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3227 EXPECT_GL_ERROR(GL_INVALID_VALUE);
3228
3229 // Using destination width/height greater than max 32-bit integer should fail.
3230 glBlitFramebuffer(0, 0, width, height, -1, -1, max, max, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3231 EXPECT_GL_ERROR(GL_INVALID_VALUE);
3232
3233 // Using destination width/height greater than max 32-bit integer should fail.
3234 glBlitFramebuffer(0, 0, width, height, max, max, -1, -1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3235 EXPECT_GL_ERROR(GL_INVALID_VALUE);
3236
3237 // Using both source and destination width/height greater than max 32-bit integer should fail.
3238 glBlitFramebuffer(-1, -1, max, max, -1, -1, max, max, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3239 EXPECT_GL_ERROR(GL_INVALID_VALUE);
3240
3241 // Using minimum and maximum integers for all boundaries should fail.
3242 glBlitFramebuffer(-max - 1, -max - 1, max, max, -max - 1, -max - 1, max, max,
3243 GL_COLOR_BUFFER_BIT, GL_NEAREST);
3244 EXPECT_GL_ERROR(GL_INVALID_VALUE);
3245 }
3246
3247 // Test an edge case in D3D11 stencil blitting on the CPU that does not properly clip the
3248 // destination regions
TEST_P(BlitFramebufferTest,BlitFramebufferStencilClipNoIntersection)3249 TEST_P(BlitFramebufferTest, BlitFramebufferStencilClipNoIntersection)
3250 {
3251 GLFramebuffer framebuffers[2];
3252 glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffers[0]);
3253 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffers[1]);
3254
3255 GLRenderbuffer renderbuffers[2];
3256 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffers[0]);
3257 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 4, 4);
3258 glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
3259 renderbuffers[0]);
3260
3261 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffers[1]);
3262 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 4, 4);
3263 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
3264 renderbuffers[1]);
3265
3266 glBlitFramebuffer(0, 0, 4, 4, 1 << 24, 1 << 24, 1 << 25, 1 << 25, GL_STENCIL_BUFFER_BIT,
3267 GL_NEAREST);
3268 EXPECT_GL_NO_ERROR();
3269 }
3270
3271 // Covers an edge case with blitting borderline values.
TEST_P(BlitFramebufferTest,OOBWrite)3272 TEST_P(BlitFramebufferTest, OOBWrite)
3273 {
3274 constexpr size_t length = 0x100000;
3275 GLFramebuffer rfb;
3276 GLFramebuffer dfb;
3277 GLRenderbuffer rb1;
3278 GLRenderbuffer rb2;
3279 glBindFramebuffer(GL_READ_FRAMEBUFFER, rfb);
3280 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dfb);
3281 glBindRenderbuffer(GL_RENDERBUFFER, rb1);
3282 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 0x1000, 2);
3283 glBindRenderbuffer(GL_RENDERBUFFER, rb2);
3284 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 2, 2);
3285 glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
3286 rb1);
3287 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
3288 rb2);
3289 glBlitFramebuffer(1, 0, 0, 1, 1, 0, (2147483648 / 2) - (length / 4) + 1, 1,
3290 GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
3291 ASSERT_GL_NO_ERROR();
3292 }
3293
3294 // Test that flipped blits don't have off-by-one errors
TEST_P(BlitFramebufferTest,FlippedBlits)3295 TEST_P(BlitFramebufferTest, FlippedBlits)
3296 {
3297 constexpr const GLsizei kWidth = 11;
3298 constexpr const GLsizei kHeight = 19;
3299 glViewport(0, 0, kWidth, kHeight);
3300
3301 GLRenderbuffer srcColorRB, srcDepthRB, dstColorRB, dstDepthRB;
3302 GLFramebuffer srcFBO, dstFBO;
3303
3304 ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Red());
3305 ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Green());
3306 ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
3307 glUseProgram(drawColor);
3308 GLint colorLoc = glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
3309 ASSERT_NE(colorLoc, -1);
3310
3311 // Create source and dest FBOs
3312 glBindRenderbuffer(GL_RENDERBUFFER, srcColorRB);
3313 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kWidth, kHeight);
3314 glBindRenderbuffer(GL_RENDERBUFFER, srcDepthRB);
3315 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, kWidth, kHeight);
3316
3317 glBindFramebuffer(GL_FRAMEBUFFER, srcFBO);
3318 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, srcColorRB);
3319 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
3320 srcDepthRB);
3321
3322 glBindRenderbuffer(GL_RENDERBUFFER, dstColorRB);
3323 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kWidth, kHeight);
3324 glBindRenderbuffer(GL_RENDERBUFFER, dstDepthRB);
3325 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, kWidth, kHeight);
3326
3327 glBindFramebuffer(GL_FRAMEBUFFER, dstFBO);
3328 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, dstColorRB);
3329 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
3330 dstDepthRB);
3331
3332 // Fill the source framebuffer with differring values per pixel, so off-by-one errors are more
3333 // easily found.
3334 glEnable(GL_SCISSOR_TEST);
3335 glEnable(GL_DEPTH_TEST);
3336 glDepthFunc(GL_ALWAYS);
3337 glDepthMask(GL_TRUE);
3338 glEnable(GL_STENCIL_TEST);
3339 glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
3340 glStencilMask(0xFF);
3341
3342 auto makeColor = [](GLsizei row, GLsizei col) -> GLColor {
3343 return GLColor(row * 255 / kHeight, col * 255 / kWidth, (row * 7 + col * 11) % 256, 255);
3344 };
3345 auto makeDepth = [](GLsizei row, GLsizei col) -> float {
3346 return 1.8f * ((row * kWidth + col) % 33 / 32.0f) - 0.9f;
3347 };
3348 auto makeStencil = [](GLsizei row, GLsizei col) -> uint8_t {
3349 return (col * kHeight + row) & 0xFF;
3350 };
3351
3352 glBindFramebuffer(GL_FRAMEBUFFER, srcFBO);
3353 glUseProgram(drawColor);
3354 for (GLsizei row = 0; row < kHeight; ++row)
3355 {
3356 for (GLsizei col = 0; col < kWidth; ++col)
3357 {
3358 glScissor(col, row, 1, 1);
3359
3360 glUniform4fv(colorLoc, 1, makeColor(row, col).toNormalizedVector().data());
3361 glStencilFunc(GL_ALWAYS, makeStencil(row, col), 0xFF);
3362 drawQuad(drawColor, essl1_shaders::PositionAttrib(), makeDepth(row, col));
3363 }
3364 }
3365
3366 glDepthFunc(GL_LESS);
3367 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
3368
3369 auto test = [&](int testIndex, bool flipX, bool flipY, GLint srcOffsetX, GLint srcOffsetY,
3370 GLint dstOffsetX, GLint dstOffsetY, GLint width, GLint height) {
3371 glDisable(GL_SCISSOR_TEST);
3372 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dstFBO);
3373 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3374
3375 glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFBO);
3376
3377 const GLint srcX0 = srcOffsetX;
3378 const GLint srcY0 = srcOffsetY;
3379 const GLint srcX1 = srcOffsetX + width;
3380 const GLint srcY1 = srcOffsetY + height;
3381
3382 const GLint dstX0 = flipX ? dstOffsetX + width : dstOffsetX;
3383 const GLint dstY0 = flipY ? dstOffsetY + height : dstOffsetY;
3384 const GLint dstX1 = flipX ? dstOffsetX : dstOffsetX + width;
3385 const GLint dstY1 = flipY ? dstOffsetY : dstOffsetY + height;
3386
3387 glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1,
3388 GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
3389 GL_NEAREST);
3390
3391 // Verify results
3392 glBindFramebuffer(GL_READ_FRAMEBUFFER, dstFBO);
3393
3394 for (GLsizei row = 0; row < height; ++row)
3395 {
3396 for (GLsizei col = 0; col < width; ++col)
3397 {
3398 const GLint srcPixelX = col + srcOffsetX;
3399 const GLint srcPixelY = row + srcOffsetY;
3400 const GLint dstPixelX = dstOffsetX + (flipX ? width - 1 - col : col);
3401 const GLint dstPixelY = dstOffsetY + (flipY ? height - 1 - row : row);
3402
3403 const GLColor expectColor = makeColor(srcPixelY, srcPixelX);
3404 const float expectDepth = makeDepth(srcPixelY, srcPixelX);
3405 const uint8_t expectStencil = makeStencil(srcPixelY, srcPixelX);
3406
3407 // Verify color
3408 EXPECT_PIXEL_COLOR_EQ(dstPixelX, dstPixelY, expectColor)
3409 << testIndex << " " << flipX << " " << flipY << " " << row << " " << col;
3410
3411 glEnable(GL_SCISSOR_TEST);
3412 glScissor(dstPixelX, dstPixelY, 1, 1);
3413
3414 // Verify depth and stencil
3415 glStencilFunc(GL_EQUAL, expectStencil, 0xFF);
3416 drawQuad(drawRed, essl1_shaders::PositionAttrib(), expectDepth - 0.05);
3417 drawQuad(drawGreen, essl1_shaders::PositionAttrib(), expectDepth + 0.05);
3418
3419 EXPECT_PIXEL_COLOR_EQ(dstPixelX, dstPixelY, GLColor::red)
3420 << testIndex << " " << flipX << " " << flipY << " " << row << " " << col;
3421 }
3422 }
3423 };
3424
3425 for (int flipX = 0; flipX < 2; ++flipX)
3426 {
3427 for (int flipY = 0; flipY < 2; ++flipY)
3428 {
3429 // Test 0, full sized blit
3430 test(0, flipX != 0, flipY != 0, 0, 0, 0, 0, kWidth, kHeight);
3431 // Test 1, blit only one pixel
3432 test(1, flipX != 0, flipY != 0, kWidth / 3, kHeight / 7, 2 * kWidth / 5,
3433 3 * kHeight / 4, 1, 1);
3434 // Test 2, random region
3435 test(2, flipX != 0, flipY != 0, kWidth / 5, 2 * kHeight / 7, kWidth / 6, kHeight / 4,
3436 kWidth / 2, kHeight / 2);
3437 }
3438 }
3439 }
3440
3441 // Test blitting a depthStencil buffer with multiple depth values to a larger size.
TEST_P(BlitFramebufferTest,BlitDepthStencilPixelByPixel)3442 TEST_P(BlitFramebufferTest, BlitDepthStencilPixelByPixel)
3443 {
3444 BlitDepthStencilPixelByPixelTestHelper(false /* mesaYFlip */);
3445 }
3446
3447 // Same as BlitDepthStencilPixelByPixel, but with y-flip flag set.
TEST_P(BlitFramebufferTest,BlitDepthStencilPixelByPixelMesaYFlip)3448 TEST_P(BlitFramebufferTest, BlitDepthStencilPixelByPixelMesaYFlip)
3449 {
3450 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
3451
3452 BlitDepthStencilPixelByPixelTestHelper(true /* mesaYFlip */);
3453 }
3454
3455 // Regression test for a bug in the Vulkan backend where vkCmdResolveImage was used with
3456 // out-of-bounds regions.
TEST_P(BlitFramebufferTestES31,OOBResolve)3457 TEST_P(BlitFramebufferTestES31, OOBResolve)
3458 {
3459 constexpr GLint kWidth = 16;
3460 constexpr GLint kHeight = 32;
3461
3462 // Read framebuffer is multisampled.
3463 GLTexture readTexture;
3464 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, readTexture);
3465 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kWidth, kHeight, GL_TRUE);
3466
3467 GLFramebuffer readFbo;
3468 glBindFramebuffer(GL_FRAMEBUFFER, readFbo);
3469 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
3470 readTexture, 0);
3471 ASSERT_GL_NO_ERROR();
3472 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3473
3474 glClearColor(1, 0, 0, 1);
3475 glClear(GL_COLOR_BUFFER_BIT);
3476
3477 // Draw framebuffer is single sampled.
3478 GLTexture drawTexture;
3479 glBindTexture(GL_TEXTURE_2D, drawTexture);
3480 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3481 nullptr);
3482 glGenerateMipmap(GL_TEXTURE_2D);
3483
3484 GLFramebuffer drawFbo;
3485 glBindFramebuffer(GL_FRAMEBUFFER, drawFbo);
3486 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, drawTexture, 0);
3487 ASSERT_GL_NO_ERROR();
3488 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3489
3490 glClearColor(0, 1, 0, 1);
3491 glClear(GL_COLOR_BUFFER_BIT);
3492 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
3493
3494 // Resolve the read framebuffer, using bounds that are outside the size of the image.
3495 glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
3496 glBlitFramebuffer(-kWidth * 2, -kHeight * 3, kWidth * 11, kHeight * 8, -kWidth * 2,
3497 -kHeight * 3, kWidth * 11, kHeight * 8, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3498 ASSERT_GL_NO_ERROR();
3499
3500 glBindFramebuffer(GL_READ_FRAMEBUFFER, drawFbo);
3501 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);
3502 }
3503
3504 // Regression test for a bug in the Vulkan backend where vkCmdResolveImage was using the src extents
3505 // as the resolve area instead of the area passed to glBlitFramebuffer.
TEST_P(BlitFramebufferTestES31,PartialResolve)3506 TEST_P(BlitFramebufferTestES31, PartialResolve)
3507 {
3508 constexpr GLint kWidth = 16;
3509 constexpr GLint kHeight = 32;
3510
3511 // Read framebuffer is multisampled.
3512 GLTexture readTexture;
3513 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, readTexture);
3514 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kWidth, kHeight, GL_TRUE);
3515
3516 GLFramebuffer readFbo;
3517 glBindFramebuffer(GL_FRAMEBUFFER, readFbo);
3518 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
3519 readTexture, 0);
3520 ASSERT_GL_NO_ERROR();
3521 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3522
3523 glClearColor(1, 0, 0, 1);
3524 glClear(GL_COLOR_BUFFER_BIT);
3525
3526 // Draw framebuffer is single sampled. It's bound to a texture with base level the same size as
3527 // the read framebuffer, but it's bound to mip 1.
3528 GLTexture drawTexture;
3529 glBindTexture(GL_TEXTURE_2D, drawTexture);
3530 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
3531 nullptr);
3532 glGenerateMipmap(GL_TEXTURE_2D);
3533
3534 GLFramebuffer drawFbo;
3535 glBindFramebuffer(GL_FRAMEBUFFER, drawFbo);
3536 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, drawTexture, 1);
3537 ASSERT_GL_NO_ERROR();
3538 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3539
3540 glClearColor(0, 1, 0, 1);
3541 glClear(GL_COLOR_BUFFER_BIT);
3542 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth / 2, kHeight / 2, GLColor::green);
3543
3544 constexpr GLint kResolveX0 = 1;
3545 constexpr GLint kResolveY0 = 2;
3546 constexpr GLint kResolveX1 = 4;
3547 constexpr GLint kResolveY1 = 6;
3548
3549 // Resolve only a portion of the read framebuffer.
3550 glBindFramebuffer(GL_READ_FRAMEBUFFER, readFbo);
3551 glBlitFramebuffer(kResolveX0, kResolveY0, kResolveX1, kResolveY1, kResolveX0, kResolveY0,
3552 kResolveX1, kResolveY1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3553 ASSERT_GL_NO_ERROR();
3554
3555 glBindFramebuffer(GL_READ_FRAMEBUFFER, drawFbo);
3556 EXPECT_PIXEL_RECT_EQ(0, 0, kWidth / 2, kResolveY0, GLColor::green);
3557 EXPECT_PIXEL_RECT_EQ(0, 0, kResolveX0, kHeight / 2, GLColor::green);
3558 EXPECT_PIXEL_RECT_EQ(kResolveX1, 0, kWidth / 2 - kResolveX1, kHeight / 2, GLColor::green);
3559 EXPECT_PIXEL_RECT_EQ(0, kResolveY1, kWidth / 2, kHeight / 2 - kResolveY1, GLColor::green);
3560
3561 EXPECT_PIXEL_RECT_EQ(kResolveX0, kResolveY0, kResolveX1 - kResolveX0, kResolveY1 - kResolveY0,
3562 GLColor::red);
3563 }
3564
3565 // Test that a draw call to a small FBO followed by a resolve of a large FBO works.
TEST_P(BlitFramebufferTestES31,DrawToSmallFBOThenResolveLargeFBO)3566 TEST_P(BlitFramebufferTestES31, DrawToSmallFBOThenResolveLargeFBO)
3567 {
3568 GLFramebuffer fboMS[2];
3569 GLTexture textureMS[2];
3570 GLFramebuffer fboSS;
3571 GLTexture textureSS;
3572
3573 // A bug in the Vulkan backend grew the render area of the previous render pass on blit, even
3574 // though the previous render pass belonged to an unrelated framebuffer. This test only needs
3575 // to make sure that the FBO being resolved is not strictly smaller than the previous FBO which
3576 // was drawn to.
3577 constexpr GLsizei kLargeWidth = 127;
3578 constexpr GLsizei kLargeHeight = 54;
3579 constexpr GLsizei kSmallWidth = 37;
3580 constexpr GLsizei kSmallHeight = 79;
3581
3582 ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
3583
3584 // Create resolve target.
3585 glBindTexture(GL_TEXTURE_2D, textureSS);
3586 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kLargeWidth, kLargeHeight);
3587
3588 glBindFramebuffer(GL_FRAMEBUFFER, fboSS);
3589 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureSS, 0);
3590 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3591
3592 // Create multisampled framebuffers and draw into them one by one.
3593 for (size_t fboIndex = 0; fboIndex < 2; ++fboIndex)
3594 {
3595 const GLsizei width = fboIndex == 0 ? kLargeWidth : kSmallWidth;
3596 const GLsizei height = fboIndex == 0 ? kLargeHeight : kSmallHeight;
3597
3598 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textureMS[fboIndex]);
3599 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, width, height, GL_TRUE);
3600
3601 glBindFramebuffer(GL_FRAMEBUFFER, fboMS[fboIndex]);
3602 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
3603 textureMS[fboIndex], 0);
3604 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3605
3606 glViewport(0, 0, width, height);
3607 drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.8f);
3608 EXPECT_GL_NO_ERROR();
3609 }
3610
3611 // Resolve the first FBO
3612 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboSS);
3613 glBindFramebuffer(GL_READ_FRAMEBUFFER, fboMS[0]);
3614
3615 glViewport(0, 0, kLargeWidth, kLargeHeight);
3616 glBlitFramebuffer(0, 0, kLargeWidth, kLargeHeight, 0, 0, kLargeWidth, kLargeHeight,
3617 GL_COLOR_BUFFER_BIT, GL_NEAREST);
3618 EXPECT_GL_NO_ERROR();
3619
3620 // Verify the resolve
3621 glBindFramebuffer(GL_READ_FRAMEBUFFER, fboSS);
3622 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3623 EXPECT_PIXEL_COLOR_EQ(kLargeWidth - 1, kLargeHeight - 1, GLColor::red);
3624 }
3625
3626 // Blit a multisampled RGBX8 framebuffer to an RGB8 framebuffer.
TEST_P(BlitFramebufferTestES31,BlitMultisampledRGBX8ToRGB8)3627 TEST_P(BlitFramebufferTestES31, BlitMultisampledRGBX8ToRGB8)
3628 {
3629 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_rgbx_internal_format"));
3630
3631 constexpr const GLsizei kWidth = 256;
3632 constexpr const GLsizei kHeight = 256;
3633
3634 GLTexture textureMS;
3635 GLRenderbuffer targetRBO;
3636 GLFramebuffer sourceFBO, targetFBO;
3637
3638 // Initialize a source multisampled FBO with checker pattern
3639 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, textureMS);
3640 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBX8_ANGLE, kWidth, kHeight,
3641 GL_TRUE);
3642 EXPECT_GL_NO_ERROR();
3643 glBindFramebuffer(GL_FRAMEBUFFER, sourceFBO);
3644 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
3645 textureMS, 0);
3646 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3647 ANGLE_GL_PROGRAM(checkerProgram, essl1_shaders::vs::Passthrough(),
3648 essl1_shaders::fs::Checkered());
3649 glViewport(0, 0, kWidth, kHeight);
3650 glBindFramebuffer(GL_FRAMEBUFFER, sourceFBO);
3651 drawQuad(checkerProgram, essl1_shaders::PositionAttrib(), 0.5f);
3652 EXPECT_GL_NO_ERROR();
3653
3654 // Initialize the destination FBO
3655 initColorFBO(&targetFBO, &targetRBO, GL_RGB8, kWidth, kHeight);
3656 EXPECT_GL_NO_ERROR();
3657
3658 glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
3659 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
3660 EXPECT_GL_NO_ERROR();
3661
3662 glViewport(0, 0, kWidth, kHeight);
3663
3664 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
3665 glClear(GL_COLOR_BUFFER_BIT);
3666
3667 // Scale down without flipping.
3668 glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_COLOR_BUFFER_BIT,
3669 GL_NEAREST);
3670 EXPECT_GL_NO_ERROR();
3671
3672 glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
3673
3674 EXPECT_PIXEL_COLOR_EQ(kWidth / 4, kHeight / 4, GLColor::red);
3675 EXPECT_PIXEL_COLOR_EQ(kWidth / 4, 3 * kHeight / 4, GLColor::green);
3676 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, kHeight / 4, GLColor::blue);
3677 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, 3 * kHeight / 4, GLColor::yellow);
3678 }
3679
3680 // Test resolving a multisampled texture with blit. Draw flipped, resolve with read fbo flipped.
TEST_P(BlitFramebufferTestES31,MultisampleFlippedResolveReadWithBlitAndFlippedDraw)3681 TEST_P(BlitFramebufferTestES31, MultisampleFlippedResolveReadWithBlitAndFlippedDraw)
3682 {
3683 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
3684
3685 constexpr int kSize = 16;
3686 glViewport(0, 0, kSize, kSize);
3687
3688 GLFramebuffer msaaFBO;
3689 glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO);
3690
3691 glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
3692
3693 GLTexture texture;
3694 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture);
3695 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
3696 ASSERT_GL_NO_ERROR();
3697 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, texture,
3698 0);
3699 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3700
3701 ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),
3702 essl31_shaders::fs::RedGreenGradient());
3703 drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
3704 ASSERT_GL_NO_ERROR();
3705
3706 // Create another FBO to resolve the multisample buffer into.
3707 GLTexture resolveTexture;
3708 GLFramebuffer resolveFBO;
3709 glBindTexture(GL_TEXTURE_2D, resolveTexture);
3710 constexpr int kResolveFBOWidth = kSize - 3;
3711 constexpr int kResolveFBOHeight = kSize - 2;
3712 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kResolveFBOWidth, kResolveFBOHeight, 0, GL_RGBA,
3713 GL_UNSIGNED_BYTE, nullptr);
3714 glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
3715 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 0);
3716 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3717
3718 glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBO);
3719 glFramebufferParameteriMESA(GL_READ_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
3720 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO);
3721 glBlitFramebuffer(0, 0, kResolveFBOWidth, kResolveFBOHeight, 0, 0, kResolveFBOWidth,
3722 kResolveFBOHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3723 ASSERT_GL_NO_ERROR();
3724
3725 glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO);
3726 constexpr uint8_t kHalfPixelGradient = 256 / kSize / 2;
3727 EXPECT_PIXEL_NEAR(0, 0, kHalfPixelGradient, kHalfPixelGradient, 0, 255, 1.0);
3728 EXPECT_PIXEL_NEAR(kResolveFBOWidth - 1, 0, 199, kHalfPixelGradient, 0, 255, 1.0);
3729 EXPECT_PIXEL_NEAR(0, kResolveFBOHeight - 1, kHalfPixelGradient, 215, 0, 255, 1.0);
3730 EXPECT_PIXEL_NEAR(kResolveFBOWidth - 1, kResolveFBOHeight - 1, 199, 215, 0, 255, 1.0);
3731 }
3732
3733 // Test resolving a multisampled texture with blit. Draw non-flipped, resolve with read fbo flipped.
TEST_P(BlitFramebufferTestES31,MultisampleFlippedResolveReadWithBlitAndNonFlippedDraw)3734 TEST_P(BlitFramebufferTestES31, MultisampleFlippedResolveReadWithBlitAndNonFlippedDraw)
3735 {
3736 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
3737
3738 constexpr int kSize = 16;
3739 glViewport(0, 0, kSize, kSize);
3740
3741 GLFramebuffer msaaFBO;
3742 glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO);
3743
3744 // Draw non-flipped - explicitly set y-flip to 0.
3745 glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 0);
3746
3747 GLTexture texture;
3748 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture);
3749 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
3750 ASSERT_GL_NO_ERROR();
3751 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, texture,
3752 0);
3753 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3754
3755 ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),
3756 essl31_shaders::fs::RedGreenGradient());
3757 drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
3758 ASSERT_GL_NO_ERROR();
3759
3760 // Create another FBO to resolve the multisample buffer into.
3761 GLTexture resolveTexture;
3762 GLFramebuffer resolveFBO;
3763 glBindTexture(GL_TEXTURE_2D, resolveTexture);
3764 constexpr int kResolveFBOWidth = kSize - 3;
3765 constexpr int kResolveFBOHeight = kSize - 2;
3766 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kResolveFBOWidth, kResolveFBOHeight, 0, GL_RGBA,
3767 GL_UNSIGNED_BYTE, nullptr);
3768 glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
3769 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 0);
3770 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3771
3772 glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBO);
3773 // Resolve with read fbo flipped and draw fbo non-flipped
3774 glFramebufferParameteriMESA(GL_READ_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
3775 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO);
3776 glBlitFramebuffer(0, 0, kResolveFBOWidth, kResolveFBOHeight, 0, 0, kResolveFBOWidth,
3777 kResolveFBOHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3778 ASSERT_GL_NO_ERROR();
3779
3780 glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO);
3781 constexpr uint8_t kHalfPixelGradient = 256 / kSize / 2;
3782 EXPECT_PIXEL_NEAR(0, 0, kHalfPixelGradient, 255 - kHalfPixelGradient, 0, 255, 1.0);
3783 EXPECT_PIXEL_NEAR(kResolveFBOWidth - 1, 0, 199, 255 - kHalfPixelGradient, 0, 255, 1.0);
3784 EXPECT_PIXEL_NEAR(0, kResolveFBOHeight - 1, kHalfPixelGradient, 40, 0, 255, 1.0);
3785 EXPECT_PIXEL_NEAR(kResolveFBOWidth - 1, kResolveFBOHeight - 1, 199, 40, 0, 255, 1.0);
3786 }
3787
3788 // Test resolving a multisampled texture with blit. Draw non-flipped, resolve with draw fbo flipped
TEST_P(BlitFramebufferTestES31,MultisampleFlippedResolveDrawWithBlitAndNonFlippedDraw)3789 TEST_P(BlitFramebufferTestES31, MultisampleFlippedResolveDrawWithBlitAndNonFlippedDraw)
3790 {
3791 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
3792
3793 constexpr int kSize = 16;
3794 glViewport(0, 0, kSize, kSize);
3795
3796 GLFramebuffer msaaFBO;
3797 glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO);
3798
3799 // Draw non-flipped - explicitly set y-flip to 0.
3800 glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 0);
3801
3802 GLTexture texture;
3803 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture);
3804 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
3805 ASSERT_GL_NO_ERROR();
3806 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, texture,
3807 0);
3808 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3809
3810 ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),
3811 essl31_shaders::fs::RedGreenGradient());
3812 drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
3813 ASSERT_GL_NO_ERROR();
3814
3815 // Create another FBO to resolve the multisample buffer into.
3816 GLTexture resolveTexture;
3817 GLFramebuffer resolveFBO;
3818 glBindTexture(GL_TEXTURE_2D, resolveTexture);
3819 constexpr int kResolveFBOWidth = kSize - 3;
3820 constexpr int kResolveFBOHeight = kSize - 2;
3821 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kResolveFBOWidth, kResolveFBOHeight, 0, GL_RGBA,
3822 GL_UNSIGNED_BYTE, nullptr);
3823 glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
3824 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 0);
3825 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3826
3827 glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBO);
3828 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO);
3829 // Resolve with draw fbo flipped and read fbo non-flipped.
3830 glFramebufferParameteriMESA(GL_READ_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 0);
3831 glFramebufferParameteriMESA(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
3832 glBlitFramebuffer(0, 0, kResolveFBOWidth, kResolveFBOHeight, 0, 0, kResolveFBOWidth,
3833 kResolveFBOHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3834 ASSERT_GL_NO_ERROR();
3835
3836 glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO);
3837 constexpr uint8_t kHalfPixelGradient = 256 / kSize / 2;
3838 EXPECT_PIXEL_NEAR(0, 0, kHalfPixelGradient, kHalfPixelGradient, 0, 255, 1.0);
3839 EXPECT_PIXEL_NEAR(kResolveFBOWidth - 1, 0, 199, kHalfPixelGradient, 0, 255, 1.0);
3840 EXPECT_PIXEL_NEAR(0, kResolveFBOHeight - 1, kHalfPixelGradient, 215, 0, 255, 1.0);
3841 EXPECT_PIXEL_NEAR(kResolveFBOWidth - 1, kResolveFBOHeight - 1, 199, 215, 0, 255, 1.0);
3842 }
3843
3844 // Test resolving a multisampled texture with blit. Draw non-flipped, resolve with both read and
3845 // draw fbos flipped
TEST_P(BlitFramebufferTestES31,MultisampleFlippedResolveWithBlitAndNonFlippedDraw)3846 TEST_P(BlitFramebufferTestES31, MultisampleFlippedResolveWithBlitAndNonFlippedDraw)
3847 {
3848 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"));
3849
3850 constexpr int kSize = 16;
3851 glViewport(0, 0, kSize, kSize);
3852
3853 GLFramebuffer msaaFBO;
3854 glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO);
3855
3856 // Draw non-flipped - explicitly set y-flip to 0.
3857 glFramebufferParameteriMESA(GL_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 0);
3858
3859 GLTexture texture;
3860 glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, texture);
3861 glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, false);
3862 ASSERT_GL_NO_ERROR();
3863 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, texture,
3864 0);
3865 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3866
3867 ANGLE_GL_PROGRAM(gradientProgram, essl31_shaders::vs::Passthrough(),
3868 essl31_shaders::fs::RedGreenGradient());
3869 drawQuad(gradientProgram, essl31_shaders::PositionAttrib(), 0.5f, 1.0f, true);
3870 ASSERT_GL_NO_ERROR();
3871
3872 // Create another FBO to resolve the multisample buffer into.
3873 GLTexture resolveTexture;
3874 GLFramebuffer resolveFBO;
3875 constexpr int kResolveFBOWidth = kSize - 3;
3876 constexpr int kResolveFBOHeight = kSize - 2;
3877 glBindTexture(GL_TEXTURE_2D, resolveTexture);
3878 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kResolveFBOWidth, kResolveFBOHeight, 0, GL_RGBA,
3879 GL_UNSIGNED_BYTE, nullptr);
3880 glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
3881 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 0);
3882 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3883
3884 glBindFramebuffer(GL_READ_FRAMEBUFFER, msaaFBO);
3885 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO);
3886 // Resolve with draw and read fbo flipped.
3887 glFramebufferParameteriMESA(GL_READ_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
3888 glFramebufferParameteriMESA(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
3889 glBlitFramebuffer(0, 0, kResolveFBOWidth, kResolveFBOHeight, 0, 0, kResolveFBOWidth,
3890 kResolveFBOHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3891 ASSERT_GL_NO_ERROR();
3892
3893 glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO);
3894 constexpr uint8_t kHalfPixelGradient = 256 / kSize / 2;
3895 EXPECT_PIXEL_NEAR(0, 0, kHalfPixelGradient, 255 - kHalfPixelGradient, 0, 255, 1.0);
3896 EXPECT_PIXEL_NEAR(kResolveFBOWidth - 1, 0, 199, 255 - kHalfPixelGradient, 0, 255, 1.0);
3897 EXPECT_PIXEL_NEAR(0, kResolveFBOHeight - 1, kHalfPixelGradient, 40, 0, 255, 1.0);
3898 EXPECT_PIXEL_NEAR(kResolveFBOWidth - 1, kResolveFBOHeight - 1, 199, 40, 0, 255, 1.0);
3899 }
3900
3901 // Test resolving into smaller framebuffer.
TEST_P(BlitFramebufferTest,ResolveIntoSmallerFramebuffer)3902 TEST_P(BlitFramebufferTest, ResolveIntoSmallerFramebuffer)
3903 {
3904 constexpr GLuint kSize[2] = {40, 32};
3905 glViewport(0, 0, kSize[0], kSize[0]);
3906
3907 GLRenderbuffer rbo[2];
3908 GLFramebuffer fbo[2];
3909
3910 for (int i = 0; i < 2; ++i)
3911 {
3912 glBindRenderbuffer(GL_RENDERBUFFER, rbo[i]);
3913 if (i == 0)
3914 {
3915 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, kSize[i], kSize[i]);
3916 }
3917 else
3918 {
3919 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize[i], kSize[i]);
3920 }
3921 glBindFramebuffer(GL_FRAMEBUFFER, fbo[i]);
3922 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo[i]);
3923 }
3924
3925 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
3926 glUseProgram(program);
3927
3928 glBindFramebuffer(GL_FRAMEBUFFER, fbo[0]);
3929 drawQuad(program, essl1_shaders::PositionAttrib(), 0.3f);
3930
3931 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[1]);
3932 glBlitFramebuffer(0, 0, kSize[1], kSize[1], 0, 0, kSize[1], kSize[1], GL_COLOR_BUFFER_BIT,
3933 GL_NEAREST);
3934
3935 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo[1]);
3936 EXPECT_PIXEL_RECT_EQ(0, 0, kSize[1], kSize[1], GLColor::red);
3937 }
3938
3939 // Test resolving into bigger framebuffer.
TEST_P(BlitFramebufferTest,ResolveIntoBiggerFramebuffer)3940 TEST_P(BlitFramebufferTest, ResolveIntoBiggerFramebuffer)
3941 {
3942 constexpr GLuint kSize[2] = {32, 40};
3943 glViewport(0, 0, kSize[0], kSize[0]);
3944
3945 GLRenderbuffer rbo[2];
3946 GLFramebuffer fbo[2];
3947
3948 for (int i = 0; i < 2; ++i)
3949 {
3950 glBindRenderbuffer(GL_RENDERBUFFER, rbo[i]);
3951 if (i == 0)
3952 {
3953 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, kSize[i], kSize[i]);
3954 }
3955 else
3956 {
3957 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kSize[i], kSize[i]);
3958 }
3959 glBindFramebuffer(GL_FRAMEBUFFER, fbo[i]);
3960 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo[i]);
3961 }
3962
3963 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
3964 glUseProgram(program);
3965
3966 glBindFramebuffer(GL_FRAMEBUFFER, fbo[0]);
3967 drawQuad(program, essl1_shaders::PositionAttrib(), 0.3f);
3968
3969 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo[1]);
3970 glBlitFramebuffer(0, 0, kSize[1], kSize[1], 0, 0, kSize[1], kSize[1], GL_COLOR_BUFFER_BIT,
3971 GL_NEAREST);
3972
3973 glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo[1]);
3974 EXPECT_PIXEL_RECT_EQ(0, 0, kSize[0], kSize[0], GLColor::red);
3975 }
3976
3977 // Test resolving into a rotated framebuffer
TEST_P(BlitFramebufferTest,ResolveWithRotation)3978 TEST_P(BlitFramebufferTest, ResolveWithRotation)
3979 {
3980 const GLint w = getWindowWidth();
3981 const GLint h = getWindowHeight();
3982
3983 glViewport(0, 0, w, h);
3984
3985 GLRenderbuffer rbo;
3986 GLFramebuffer fbo;
3987
3988 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
3989 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, w, h);
3990 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3991 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
3992
3993 ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Checkered());
3994 glUseProgram(program);
3995
3996 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3997 drawQuad(program, essl1_shaders::PositionAttrib(), 0.3f);
3998
3999 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
4000 glBlitFramebuffer(0, 0, w, h, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_NEAREST);
4001
4002 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
4003 EXPECT_PIXEL_RECT_EQ(0, 0, w / 2, h / 2, GLColor::red);
4004 EXPECT_PIXEL_RECT_EQ(w / 2, 0, w / 2, h / 2, GLColor::blue);
4005 EXPECT_PIXEL_RECT_EQ(0, h / 2, w / 2, h / 2, GLColor::green);
4006 EXPECT_PIXEL_RECT_EQ(w / 2, h / 2, w / 2, h / 2, GLColor::yellow);
4007 }
4008
4009 // Test blitting a 3D texture to a 3D texture
TEST_P(BlitFramebufferTest,Blit3D)4010 TEST_P(BlitFramebufferTest, Blit3D)
4011 {
4012 test3DBlit(GL_TEXTURE_3D, GL_TEXTURE_3D);
4013 }
4014
4015 // Test blitting a 2D array texture to a 2D array texture
TEST_P(BlitFramebufferTest,Blit2DArray)4016 TEST_P(BlitFramebufferTest, Blit2DArray)
4017 {
4018 test3DBlit(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_2D_ARRAY);
4019 }
4020
4021 // Test blitting a 3D texture to a 2D array texture
TEST_P(BlitFramebufferTest,Blit3DTo2DArray)4022 TEST_P(BlitFramebufferTest, Blit3DTo2DArray)
4023 {
4024 test3DBlit(GL_TEXTURE_3D, GL_TEXTURE_2D_ARRAY);
4025 }
4026
4027 // Test blitting a 2D array texture to a 3D texture
TEST_P(BlitFramebufferTest,Blit2DArrayTo3D)4028 TEST_P(BlitFramebufferTest, Blit2DArrayTo3D)
4029 {
4030 test3DBlit(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_3D);
4031 }
4032
4033 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
4034 // tests should be run against.
4035 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BlitFramebufferANGLETest);
4036 ANGLE_INSTANTIATE_TEST(BlitFramebufferANGLETest,
4037 ES2_D3D9(),
4038 ES2_D3D11(),
4039 ES2_D3D11_PRESENT_PATH_FAST(),
4040 ES2_OPENGL(),
4041 ES3_OPENGL(),
4042 ES2_VULKAN(),
4043 ES3_VULKAN(),
4044 ES3_VULKAN().enable(Feature::EmulatedPrerotation90),
4045 ES3_VULKAN().enable(Feature::EmulatedPrerotation180),
4046 ES3_VULKAN().enable(Feature::EmulatedPrerotation270),
4047 ES3_VULKAN()
4048 .disable(Feature::SupportsExtendedDynamicState)
4049 .disable(Feature::SupportsExtendedDynamicState2),
4050 ES3_VULKAN().disable(Feature::SupportsExtendedDynamicState2),
4051 ES2_METAL(),
4052 ES2_METAL().disable(Feature::HasShaderStencilOutput));
4053
4054 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BlitFramebufferTest);
4055 ANGLE_INSTANTIATE_TEST_ES3_AND(BlitFramebufferTest,
4056 ES3_VULKAN().enable(Feature::EmulatedPrerotation90),
4057 ES3_VULKAN().enable(Feature::EmulatedPrerotation180),
4058 ES3_VULKAN().enable(Feature::EmulatedPrerotation270),
4059 ES3_VULKAN()
4060 .disable(Feature::SupportsExtendedDynamicState)
4061 .disable(Feature::SupportsExtendedDynamicState2),
4062 ES3_VULKAN().disable(Feature::SupportsExtendedDynamicState2),
4063 ES3_VULKAN().enable(Feature::DisableFlippingBlitWithCommand),
4064 ES3_METAL().disable(Feature::HasShaderStencilOutput));
4065
4066 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BlitFramebufferTestES31);
4067 ANGLE_INSTANTIATE_TEST_ES31(BlitFramebufferTestES31);
4068 } // namespace
4069