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