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 class BlitFramebufferANGLETest : public ANGLETest
13 {
14 protected:
BlitFramebufferANGLETest()15 BlitFramebufferANGLETest()
16 {
17 setWindowWidth(64);
18 setWindowHeight(32);
19 setConfigRedBits(8);
20 setConfigGreenBits(8);
21 setConfigBlueBits(8);
22 setConfigAlphaBits(8);
23 setConfigDepthBits(24);
24 setConfigStencilBits(8);
25
26 mCheckerProgram = 0;
27 mBlueProgram = 0;
28 mRedProgram = 0;
29
30 mOriginalFBO = 0;
31
32 mUserFBO = 0;
33 mUserColorBuffer = 0;
34 mUserDepthStencilBuffer = 0;
35
36 mSmallFBO = 0;
37 mSmallColorBuffer = 0;
38 mSmallDepthStencilBuffer = 0;
39
40 mColorOnlyFBO = 0;
41 mColorOnlyColorBuffer = 0;
42
43 mDiffFormatFBO = 0;
44 mDiffFormatColorBuffer = 0;
45
46 mDiffSizeFBO = 0;
47 mDiffSizeColorBuffer = 0;
48
49 mMRTFBO = 0;
50 mMRTColorBuffer0 = 0;
51 mMRTColorBuffer1 = 0;
52
53 mRGBAColorbuffer = 0;
54 mRGBAFBO = 0;
55 mRGBAMultisampledRenderbuffer = 0;
56 mRGBAMultisampledFBO = 0;
57
58 mBGRAColorbuffer = 0;
59 mBGRAFBO = 0;
60 mBGRAMultisampledRenderbuffer = 0;
61 mBGRAMultisampledFBO = 0;
62 }
63
testSetUp()64 void testSetUp() override
65 {
66 mCheckerProgram =
67 CompileProgram(essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Checkered());
68 mBlueProgram = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
69 mRedProgram = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
70 if (mCheckerProgram == 0 || mBlueProgram == 0 || mRedProgram == 0)
71 {
72 FAIL() << "shader compilation failed.";
73 }
74
75 EXPECT_GL_NO_ERROR();
76
77 GLint originalFBO;
78 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &originalFBO);
79 if (originalFBO >= 0)
80 {
81 mOriginalFBO = (GLuint)originalFBO;
82 }
83
84 GLenum format = GL_RGBA;
85
86 glGenFramebuffers(1, &mUserFBO);
87 glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
88 glGenTextures(1, &mUserColorBuffer);
89 glGenRenderbuffers(1, &mUserDepthStencilBuffer);
90 glBindTexture(GL_TEXTURE_2D, mUserColorBuffer);
91 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
92 mUserColorBuffer, 0);
93 glTexImage2D(GL_TEXTURE_2D, 0, format, getWindowWidth(), getWindowHeight(), 0, format,
94 GL_UNSIGNED_BYTE, nullptr);
95 glBindRenderbuffer(GL_RENDERBUFFER, mUserDepthStencilBuffer);
96 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, getWindowWidth(),
97 getWindowHeight());
98 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
99 mUserDepthStencilBuffer);
100 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
101 mUserDepthStencilBuffer);
102
103 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
104 ASSERT_GL_NO_ERROR();
105
106 glGenFramebuffers(1, &mSmallFBO);
107 glBindFramebuffer(GL_FRAMEBUFFER, mSmallFBO);
108 glGenTextures(1, &mSmallColorBuffer);
109 glGenRenderbuffers(1, &mSmallDepthStencilBuffer);
110 glBindTexture(GL_TEXTURE_2D, mSmallColorBuffer);
111 glTexImage2D(GL_TEXTURE_2D, 0, format, getWindowWidth() / 2, getWindowHeight() / 2, 0,
112 format, GL_UNSIGNED_BYTE, nullptr);
113 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
114 mSmallColorBuffer, 0);
115 glBindRenderbuffer(GL_RENDERBUFFER, mSmallDepthStencilBuffer);
116 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, getWindowWidth() / 2,
117 getWindowHeight() / 2);
118 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
119 mSmallDepthStencilBuffer);
120 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
121 mSmallDepthStencilBuffer);
122
123 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
124 ASSERT_GL_NO_ERROR();
125
126 glGenFramebuffers(1, &mColorOnlyFBO);
127 glBindFramebuffer(GL_FRAMEBUFFER, mColorOnlyFBO);
128 glGenTextures(1, &mColorOnlyColorBuffer);
129 glBindTexture(GL_TEXTURE_2D, mColorOnlyColorBuffer);
130 glTexImage2D(GL_TEXTURE_2D, 0, format, getWindowWidth(), getWindowHeight(), 0, format,
131 GL_UNSIGNED_BYTE, nullptr);
132 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
133 mColorOnlyColorBuffer, 0);
134
135 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
136 ASSERT_GL_NO_ERROR();
137
138 glGenFramebuffers(1, &mDiffFormatFBO);
139 glBindFramebuffer(GL_FRAMEBUFFER, mDiffFormatFBO);
140 glGenTextures(1, &mDiffFormatColorBuffer);
141 glBindTexture(GL_TEXTURE_2D, mDiffFormatColorBuffer);
142 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, getWindowWidth(), getWindowHeight(), 0, GL_RGB,
143 GL_UNSIGNED_SHORT_5_6_5, nullptr);
144 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
145 mDiffFormatColorBuffer, 0);
146
147 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
148 ASSERT_GL_NO_ERROR();
149
150 glGenFramebuffers(1, &mDiffSizeFBO);
151 glBindFramebuffer(GL_FRAMEBUFFER, mDiffSizeFBO);
152 glGenTextures(1, &mDiffSizeColorBuffer);
153 glBindTexture(GL_TEXTURE_2D, mDiffSizeColorBuffer);
154 glTexImage2D(GL_TEXTURE_2D, 0, format, getWindowWidth() * 2, getWindowHeight() * 2, 0,
155 format, GL_UNSIGNED_BYTE, nullptr);
156 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
157 mDiffSizeColorBuffer, 0);
158
159 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
160 ASSERT_GL_NO_ERROR();
161
162 if (IsGLExtensionEnabled("GL_EXT_draw_buffers"))
163 {
164 glGenFramebuffers(1, &mMRTFBO);
165 glBindFramebuffer(GL_FRAMEBUFFER, mMRTFBO);
166 glGenTextures(1, &mMRTColorBuffer0);
167 glGenTextures(1, &mMRTColorBuffer1);
168 glBindTexture(GL_TEXTURE_2D, mMRTColorBuffer0);
169 glTexImage2D(GL_TEXTURE_2D, 0, format, getWindowWidth(), getWindowHeight(), 0, format,
170 GL_UNSIGNED_BYTE, nullptr);
171 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D,
172 mMRTColorBuffer0, 0);
173 glBindTexture(GL_TEXTURE_2D, mMRTColorBuffer1);
174 glTexImage2D(GL_TEXTURE_2D, 0, format, getWindowWidth(), getWindowHeight(), 0, format,
175 GL_UNSIGNED_BYTE, nullptr);
176 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D,
177 mMRTColorBuffer1, 0);
178
179 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
180 ASSERT_GL_NO_ERROR();
181 }
182
183 if (IsGLExtensionEnabled("GL_ANGLE_framebuffer_multisample") &&
184 IsGLExtensionEnabled("GL_OES_rgb8_rgba8"))
185 {
186 // RGBA single-sampled framebuffer
187 glGenTextures(1, &mRGBAColorbuffer);
188 glBindTexture(GL_TEXTURE_2D, mRGBAColorbuffer);
189 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
190 GL_UNSIGNED_BYTE, nullptr);
191
192 glGenFramebuffers(1, &mRGBAFBO);
193 glBindFramebuffer(GL_FRAMEBUFFER, mRGBAFBO);
194 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
195 mRGBAColorbuffer, 0);
196
197 ASSERT_GL_NO_ERROR();
198 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
199
200 // RGBA multisampled framebuffer
201 glGenRenderbuffers(1, &mRGBAMultisampledRenderbuffer);
202 glBindRenderbuffer(GL_RENDERBUFFER, mRGBAMultisampledRenderbuffer);
203 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 1, GL_RGBA8, getWindowWidth(),
204 getWindowHeight());
205
206 glGenFramebuffers(1, &mRGBAMultisampledFBO);
207 glBindFramebuffer(GL_FRAMEBUFFER, mRGBAMultisampledFBO);
208 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
209 mRGBAMultisampledRenderbuffer);
210
211 ASSERT_GL_NO_ERROR();
212 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
213
214 if (IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"))
215 {
216 // BGRA single-sampled framebuffer
217 glGenTextures(1, &mBGRAColorbuffer);
218 glBindTexture(GL_TEXTURE_2D, mBGRAColorbuffer);
219 glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, getWindowWidth(), getWindowHeight(), 0,
220 GL_BGRA_EXT, GL_UNSIGNED_BYTE, nullptr);
221
222 glGenFramebuffers(1, &mBGRAFBO);
223 glBindFramebuffer(GL_FRAMEBUFFER, mBGRAFBO);
224 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
225 mBGRAColorbuffer, 0);
226
227 ASSERT_GL_NO_ERROR();
228 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
229
230 // BGRA multisampled framebuffer
231 glGenRenderbuffers(1, &mBGRAMultisampledRenderbuffer);
232 glBindRenderbuffer(GL_RENDERBUFFER, mBGRAMultisampledRenderbuffer);
233 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 1, GL_BGRA8_EXT,
234 getWindowWidth(), getWindowHeight());
235
236 glGenFramebuffers(1, &mBGRAMultisampledFBO);
237 glBindFramebuffer(GL_FRAMEBUFFER, mBGRAMultisampledFBO);
238 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
239 mBGRAMultisampledRenderbuffer);
240
241 ASSERT_GL_NO_ERROR();
242 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
243 }
244 }
245
246 glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
247 }
248
testTearDown()249 void testTearDown() override
250 {
251 glDeleteProgram(mCheckerProgram);
252 glDeleteProgram(mBlueProgram);
253 glDeleteProgram(mRedProgram);
254
255 glDeleteFramebuffers(1, &mUserFBO);
256 glDeleteTextures(1, &mUserColorBuffer);
257 glDeleteRenderbuffers(1, &mUserDepthStencilBuffer);
258
259 glDeleteFramebuffers(1, &mSmallFBO);
260 glDeleteTextures(1, &mSmallColorBuffer);
261 glDeleteRenderbuffers(1, &mSmallDepthStencilBuffer);
262
263 glDeleteFramebuffers(1, &mColorOnlyFBO);
264 glDeleteTextures(1, &mSmallDepthStencilBuffer);
265
266 glDeleteFramebuffers(1, &mDiffFormatFBO);
267 glDeleteTextures(1, &mDiffFormatColorBuffer);
268
269 glDeleteFramebuffers(1, &mDiffSizeFBO);
270 glDeleteTextures(1, &mDiffSizeColorBuffer);
271
272 if (IsGLExtensionEnabled("GL_EXT_draw_buffers"))
273 {
274 glDeleteFramebuffers(1, &mMRTFBO);
275 glDeleteTextures(1, &mMRTColorBuffer0);
276 glDeleteTextures(1, &mMRTColorBuffer1);
277 }
278
279 if (mRGBAColorbuffer != 0)
280 {
281 glDeleteTextures(1, &mRGBAColorbuffer);
282 }
283
284 if (mRGBAFBO != 0)
285 {
286 glDeleteFramebuffers(1, &mRGBAFBO);
287 }
288
289 if (mRGBAMultisampledRenderbuffer != 0)
290 {
291 glDeleteRenderbuffers(1, &mRGBAMultisampledRenderbuffer);
292 }
293
294 if (mRGBAMultisampledFBO != 0)
295 {
296 glDeleteFramebuffers(1, &mRGBAMultisampledFBO);
297 }
298
299 if (mBGRAColorbuffer != 0)
300 {
301 glDeleteTextures(1, &mBGRAColorbuffer);
302 }
303
304 if (mBGRAFBO != 0)
305 {
306 glDeleteFramebuffers(1, &mBGRAFBO);
307 }
308
309 if (mBGRAMultisampledRenderbuffer != 0)
310 {
311 glDeleteRenderbuffers(1, &mBGRAMultisampledRenderbuffer);
312 }
313
314 if (mBGRAMultisampledFBO != 0)
315 {
316 glDeleteFramebuffers(1, &mBGRAMultisampledFBO);
317 }
318 }
319
multisampleTestHelper(GLuint readFramebuffer,GLuint drawFramebuffer)320 void multisampleTestHelper(GLuint readFramebuffer, GLuint drawFramebuffer)
321 {
322 glClearColor(0.0, 1.0, 0.0, 1.0);
323 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, readFramebuffer);
324 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
325 EXPECT_GL_NO_ERROR();
326
327 glBindFramebuffer(GL_READ_FRAMEBUFFER, readFramebuffer);
328 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFramebuffer);
329 glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
330 getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
331 EXPECT_GL_NO_ERROR();
332
333 glBindFramebuffer(GL_READ_FRAMEBUFFER, drawFramebuffer);
334 EXPECT_PIXEL_EQ(getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255);
335 EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, 0, 255, 0, 255);
336 EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255);
337 EXPECT_PIXEL_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, 0, 255, 0, 255);
338 }
339
checkExtension(const std::string & extension)340 bool checkExtension(const std::string &extension)
341 {
342 if (!IsGLExtensionEnabled(extension))
343 {
344 std::cout << "Test skipped because " << extension << " not supported." << std::endl;
345 return false;
346 }
347
348 return true;
349 }
350
351 GLuint mCheckerProgram;
352 GLuint mBlueProgram;
353 GLuint mRedProgram;
354
355 GLuint mOriginalFBO;
356
357 GLuint mUserFBO;
358 GLuint mUserColorBuffer;
359 GLuint mUserDepthStencilBuffer;
360
361 GLuint mSmallFBO;
362 GLuint mSmallColorBuffer;
363 GLuint mSmallDepthStencilBuffer;
364
365 GLuint mColorOnlyFBO;
366 GLuint mColorOnlyColorBuffer;
367
368 GLuint mDiffFormatFBO;
369 GLuint mDiffFormatColorBuffer;
370
371 GLuint mDiffSizeFBO;
372 GLuint mDiffSizeColorBuffer;
373
374 GLuint mMRTFBO;
375 GLuint mMRTColorBuffer0;
376 GLuint mMRTColorBuffer1;
377
378 GLuint mRGBAColorbuffer;
379 GLuint mRGBAFBO;
380 GLuint mRGBAMultisampledRenderbuffer;
381 GLuint mRGBAMultisampledFBO;
382
383 GLuint mBGRAColorbuffer;
384 GLuint mBGRAFBO;
385 GLuint mBGRAMultisampledRenderbuffer;
386 GLuint mBGRAMultisampledFBO;
387 };
388
389 // Draw to user-created framebuffer, blit whole-buffer color to original framebuffer.
TEST_P(BlitFramebufferANGLETest,BlitColorToDefault)390 TEST_P(BlitFramebufferANGLETest, BlitColorToDefault)
391 {
392 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
393
394 glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
395
396 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
397
398 drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);
399
400 EXPECT_GL_NO_ERROR();
401
402 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
403 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
404
405 glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
406 getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
407
408 EXPECT_GL_NO_ERROR();
409
410 glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
411
412 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
413 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);
414 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
415 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);
416 }
417
418 // Blit color to/from default framebuffer with Flip-X/Flip-Y.
TEST_P(BlitFramebufferANGLETest,BlitColorWithFlip)419 TEST_P(BlitFramebufferANGLETest, BlitColorWithFlip)
420 {
421 // OpenGL ES 3.0 / GL_NV_framebuffer_blit required for flip.
422 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
423 !IsGLExtensionEnabled("GL_NV_framebuffer_blit"));
424
425 glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
426
427 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
428
429 drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);
430
431 EXPECT_GL_NO_ERROR();
432
433 // Blit to default with x-flip.
434 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
435 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
436
437 glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), getWindowWidth(), 0, 0,
438 getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
439
440 EXPECT_GL_NO_ERROR();
441
442 glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
443
444 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
445 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);
446 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
447 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);
448
449 // Blit to default with y-flip.
450 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
451 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
452
453 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
454 glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), 0, getWindowHeight(),
455 getWindowWidth(), 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
456
457 EXPECT_GL_NO_ERROR();
458
459 glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
460
461 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::green);
462 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::red);
463 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::yellow);
464 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::blue);
465
466 // Blit from default with x-flip.
467
468 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO);
469 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO);
470
471 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
472 glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), getWindowWidth(), 0, 0,
473 getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
474
475 EXPECT_GL_NO_ERROR();
476
477 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
478
479 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::yellow);
480 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::blue);
481 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::green);
482 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::red);
483
484 // Blit from default with y-flip.
485 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO);
486 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO);
487
488 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
489 glBlitFramebuffer(0, 0, getWindowWidth(), getWindowHeight(), 0, getWindowHeight(),
490 getWindowWidth(), 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
491
492 EXPECT_GL_NO_ERROR();
493
494 glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
495
496 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
497 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);
498 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
499 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);
500 }
501
502 // Draw to system framebuffer, blit whole-buffer color to user-created framebuffer.
TEST_P(BlitFramebufferANGLETest,ReverseColorBlit)503 TEST_P(BlitFramebufferANGLETest, ReverseColorBlit)
504 {
505 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
506
507 // TODO(jmadill): Fix this. http://anglebug.com/2743
508 ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
509
510 glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
511
512 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
513
514 drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);
515
516 EXPECT_GL_NO_ERROR();
517
518 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO);
519 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO);
520
521 glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
522 getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
523
524 EXPECT_GL_NO_ERROR();
525
526 glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
527
528 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
529 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);
530 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
531 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);
532 }
533
534 // blit from user-created FBO to system framebuffer, with the scissor test enabled.
TEST_P(BlitFramebufferANGLETest,ScissoredBlit)535 TEST_P(BlitFramebufferANGLETest, ScissoredBlit)
536 {
537 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
538
539 glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
540
541 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
542
543 drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);
544
545 EXPECT_GL_NO_ERROR();
546
547 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
548 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
549
550 glClearColor(1.0, 1.0, 1.0, 1.0);
551 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
552
553 glScissor(getWindowWidth() / 2, 0, getWindowWidth() / 2, getWindowHeight());
554 glEnable(GL_SCISSOR_TEST);
555
556 glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
557 getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
558
559 EXPECT_GL_NO_ERROR();
560
561 glDisable(GL_SCISSOR_TEST);
562
563 glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
564
565 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::white);
566 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::white);
567 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
568 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);
569 }
570
571 // blit from system FBO to user-created framebuffer, with the scissor test enabled.
TEST_P(BlitFramebufferANGLETest,ReverseScissoredBlit)572 TEST_P(BlitFramebufferANGLETest, ReverseScissoredBlit)
573 {
574 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
575
576 glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
577
578 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
579
580 drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);
581
582 EXPECT_GL_NO_ERROR();
583
584 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO);
585 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO);
586
587 glClearColor(1.0, 1.0, 1.0, 1.0);
588 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
589
590 glScissor(getWindowWidth() / 2, 0, getWindowWidth() / 2, getWindowHeight());
591 glEnable(GL_SCISSOR_TEST);
592
593 glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
594 getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
595
596 EXPECT_GL_NO_ERROR();
597
598 glDisable(GL_SCISSOR_TEST);
599
600 glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
601
602 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::white);
603 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::white);
604 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
605 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);
606 }
607
608 // blit from user-created FBO to system framebuffer, using region larger than buffer.
TEST_P(BlitFramebufferANGLETest,OversizedBlit)609 TEST_P(BlitFramebufferANGLETest, OversizedBlit)
610 {
611 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
612
613 glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
614
615 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
616
617 drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);
618
619 EXPECT_GL_NO_ERROR();
620
621 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
622 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
623
624 glClearColor(1.0, 1.0, 1.0, 1.0);
625 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
626
627 glBlitFramebufferANGLE(0, 0, getWindowWidth() * 2, getWindowHeight() * 2, 0, 0,
628 getWindowWidth() * 2, getWindowHeight() * 2, GL_COLOR_BUFFER_BIT,
629 GL_NEAREST);
630
631 EXPECT_GL_NO_ERROR();
632
633 glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
634
635 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
636 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);
637 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
638 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);
639 }
640
641 // blit from system FBO to user-created framebuffer, using region larger than buffer.
TEST_P(BlitFramebufferANGLETest,ReverseOversizedBlit)642 TEST_P(BlitFramebufferANGLETest, ReverseOversizedBlit)
643 {
644 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
645
646 glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
647
648 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
649
650 drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);
651
652 EXPECT_GL_NO_ERROR();
653
654 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO);
655 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO);
656
657 glClearColor(1.0, 1.0, 1.0, 1.0);
658 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
659
660 glBlitFramebufferANGLE(0, 0, getWindowWidth() * 2, getWindowHeight() * 2, 0, 0,
661 getWindowWidth() * 2, getWindowHeight() * 2, GL_COLOR_BUFFER_BIT,
662 GL_NEAREST);
663 EXPECT_GL_NO_ERROR();
664
665 glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
666
667 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
668 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);
669 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
670 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);
671 }
672
673 // blit from user-created FBO to system framebuffer, with depth buffer.
TEST_P(BlitFramebufferANGLETest,BlitWithDepthUserToDefault)674 TEST_P(BlitFramebufferANGLETest, BlitWithDepthUserToDefault)
675 {
676 // TODO(http://anglebug.com/6154): glBlitFramebufferANGLE() generates GL_INVALID_OPERATION for
677 // the ES2_OpenGL backend.
678 ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsOpenGL());
679
680 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
681
682 glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
683
684 glDepthMask(GL_TRUE);
685 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
686
687 glEnable(GL_DEPTH_TEST);
688
689 EXPECT_GL_NO_ERROR();
690
691 // Clear the first half of the screen
692 glEnable(GL_SCISSOR_TEST);
693 glScissor(0, 0, getWindowWidth(), getWindowHeight() / 2);
694
695 glClearDepthf(0.1f);
696 glClearColor(1.0, 0.0, 0.0, 1.0);
697 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
698
699 // Scissor the second half of the screen
700 glScissor(0, getWindowHeight() / 2, getWindowWidth(), getWindowHeight() / 2);
701
702 glClearDepthf(0.9f);
703 glClearColor(0.0, 1.0, 0.0, 1.0);
704 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
705
706 glDisable(GL_SCISSOR_TEST);
707
708 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
709 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
710
711 glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
712 getWindowHeight(), GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
713 GL_NEAREST);
714 EXPECT_GL_NO_ERROR();
715
716 glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
717
718 // if blit is happening correctly, this quad will draw only on the bottom half since it will
719 // be behind on the first half and in front on the second half.
720 drawQuad(mBlueProgram, essl1_shaders::PositionAttrib(), 0.5f);
721
722 glDisable(GL_DEPTH_TEST);
723
724 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
725 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::blue);
726 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
727 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::blue);
728 }
729
730 // blit from system FBO to user-created framebuffer, with depth buffer.
TEST_P(BlitFramebufferANGLETest,BlitWithDepthDefaultToUser)731 TEST_P(BlitFramebufferANGLETest, BlitWithDepthDefaultToUser)
732 {
733 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
734
735 glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
736
737 glDepthMask(GL_TRUE);
738 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
739
740 glEnable(GL_DEPTH_TEST);
741
742 EXPECT_GL_NO_ERROR();
743
744 // Clear the first half of the screen
745 glEnable(GL_SCISSOR_TEST);
746 glScissor(0, 0, getWindowWidth(), getWindowHeight() / 2);
747
748 glClearDepthf(0.1f);
749 glClearColor(1.0, 0.0, 0.0, 1.0);
750 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
751
752 // Scissor the second half of the screen
753 glScissor(0, getWindowHeight() / 2, getWindowWidth(), getWindowHeight() / 2);
754
755 glClearDepthf(0.9f);
756 glClearColor(0.0, 1.0, 0.0, 1.0);
757 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
758
759 glDisable(GL_SCISSOR_TEST);
760
761 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO);
762 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO);
763
764 glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
765 getWindowHeight(), GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
766 GL_NEAREST);
767 EXPECT_GL_NO_ERROR();
768
769 glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
770
771 // if blit is happening correctly, this quad will draw only on the bottom half since it will be
772 // behind on the first half and in front on the second half.
773 drawQuad(mBlueProgram, essl1_shaders::PositionAttrib(), 0.5f);
774
775 glDisable(GL_DEPTH_TEST);
776
777 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
778 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::blue);
779 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
780 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::blue);
781 }
782
783 // blit from one region of the system fbo to another-- this should fail.
TEST_P(BlitFramebufferANGLETest,BlitSameBufferOriginal)784 TEST_P(BlitFramebufferANGLETest, BlitSameBufferOriginal)
785 {
786 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
787
788 glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
789
790 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
791
792 drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.3f);
793
794 EXPECT_GL_NO_ERROR();
795
796 glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight(), getWindowWidth() / 2, 0,
797 getWindowWidth(), getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
798 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
799 }
800
801 // blit from one region of the system fbo to another.
TEST_P(BlitFramebufferANGLETest,BlitSameBufferUser)802 TEST_P(BlitFramebufferANGLETest, BlitSameBufferUser)
803 {
804 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
805
806 glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
807
808 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
809
810 drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.3f);
811
812 EXPECT_GL_NO_ERROR();
813
814 glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight(), getWindowWidth() / 2, 0,
815 getWindowWidth(), getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
816 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
817 }
818
TEST_P(BlitFramebufferANGLETest,BlitPartialColor)819 TEST_P(BlitFramebufferANGLETest, BlitPartialColor)
820 {
821 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
822
823 glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
824
825 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
826
827 drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.5f);
828
829 EXPECT_GL_NO_ERROR();
830
831 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
832 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
833
834 glClearColor(1.0, 1.0, 1.0, 1.0);
835 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
836
837 glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, 0,
838 getWindowHeight() / 2, getWindowWidth() / 2, getWindowHeight(),
839 GL_COLOR_BUFFER_BIT, GL_NEAREST);
840
841 EXPECT_GL_NO_ERROR();
842
843 glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
844
845 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::white);
846 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::red);
847 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::white);
848 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::white);
849 }
850
TEST_P(BlitFramebufferANGLETest,BlitDifferentSizes)851 TEST_P(BlitFramebufferANGLETest, BlitDifferentSizes)
852 {
853 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
854
855 glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
856
857 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
858
859 drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.5f);
860
861 EXPECT_GL_NO_ERROR();
862
863 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mSmallFBO);
864 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
865
866 glClearColor(1.0, 1.0, 1.0, 1.0);
867 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
868
869 glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
870 getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
871
872 EXPECT_GL_NO_ERROR();
873
874 glBindFramebuffer(GL_FRAMEBUFFER, mSmallFBO);
875
876 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
877
878 EXPECT_GL_NO_ERROR();
879 }
880
TEST_P(BlitFramebufferANGLETest,BlitWithMissingAttachments)881 TEST_P(BlitFramebufferANGLETest, BlitWithMissingAttachments)
882 {
883 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
884
885 glBindFramebuffer(GL_FRAMEBUFFER, mColorOnlyFBO);
886
887 glClear(GL_COLOR_BUFFER_BIT);
888 drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.3f);
889
890 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
891 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mColorOnlyFBO);
892
893 glClearColor(1.0, 1.0, 1.0, 1.0);
894 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
895
896 // generate INVALID_OPERATION if the read FBO has no depth attachment
897 glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
898 getWindowHeight(), GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
899 GL_NEAREST);
900
901 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
902
903 // generate INVALID_OPERATION if the read FBO has no stencil attachment
904 glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
905 getWindowHeight(), GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
906 GL_NEAREST);
907
908 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
909
910 // generate INVALID_OPERATION if we read from a missing color attachment
911 glReadBuffer(GL_COLOR_ATTACHMENT1);
912 glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
913 getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
914
915 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
916 }
917
TEST_P(BlitFramebufferANGLETest,BlitStencil)918 TEST_P(BlitFramebufferANGLETest, BlitStencil)
919 {
920 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
921
922 // http://anglebug.com/2205
923 ANGLE_SKIP_TEST_IF(IsIntel() && IsD3D9());
924
925 // http://anglebug.com/4919
926 ANGLE_SKIP_TEST_IF(IsIntel() && IsMetal());
927
928 // http://anglebug.com/5396
929 ANGLE_SKIP_TEST_IF(IsAMD() && IsD3D9());
930
931 glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
932
933 glClearColor(0.0, 1.0, 0.0, 1.0);
934 glClearStencil(0x0);
935 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
936
937 // Scissor half the screen so we fill the stencil only halfway
938 glScissor(0, 0, getWindowWidth(), getWindowHeight() / 2);
939 glEnable(GL_SCISSOR_TEST);
940
941 // fill the stencil buffer with 0x1
942 glStencilFunc(GL_ALWAYS, 0x1, 0xFF);
943 glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
944 glEnable(GL_STENCIL_TEST);
945 drawQuad(mRedProgram, essl1_shaders::PositionAttrib(), 0.3f);
946
947 glDisable(GL_SCISSOR_TEST);
948
949 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
950 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
951
952 // These clears are not useful in theory because we're copying over them, but its
953 // helpful in debugging if we see white in any result.
954 glClearColor(1.0, 1.0, 1.0, 1.0);
955 glClearStencil(0x0);
956 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
957
958 // depth blit request should be silently ignored, because the read FBO has no depth attachment
959 glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
960 getWindowHeight(), GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
961 GL_NEAREST);
962
963 EXPECT_GL_NO_ERROR();
964
965 glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
966
967 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
968 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);
969 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
970 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);
971
972 glStencilFunc(GL_EQUAL, 0x1, 0xFF); // only pass if stencil buffer at pixel reads 0x1
973
974 drawQuad(mBlueProgram, essl1_shaders::PositionAttrib(),
975 0.8f); // blue quad will draw if stencil buffer was copied
976
977 glDisable(GL_STENCIL_TEST);
978
979 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
980 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);
981 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
982 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);
983 }
984
985 // make sure that attempting to blit a partial depth buffer issues an error
TEST_P(BlitFramebufferANGLETest,BlitPartialDepthStencil)986 TEST_P(BlitFramebufferANGLETest, BlitPartialDepthStencil)
987 {
988 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
989
990 glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
991
992 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
993
994 drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.5f);
995
996 EXPECT_GL_NO_ERROR();
997
998 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
999 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
1000
1001 glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, 0, 0,
1002 getWindowWidth() / 2, getWindowHeight() / 2, GL_DEPTH_BUFFER_BIT,
1003 GL_NEAREST);
1004 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1005 }
1006
1007 // Test blit with MRT framebuffers
TEST_P(BlitFramebufferANGLETest,BlitMRT)1008 TEST_P(BlitFramebufferANGLETest, BlitMRT)
1009 {
1010 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1011
1012 if (!IsGLExtensionEnabled("GL_EXT_draw_buffers"))
1013 {
1014 return;
1015 }
1016
1017 GLenum drawBuffers[] = {GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT};
1018
1019 glBindFramebuffer(GL_FRAMEBUFFER, mMRTFBO);
1020 glDrawBuffersEXT(2, drawBuffers);
1021
1022 glBindFramebuffer(GL_FRAMEBUFFER, mColorOnlyFBO);
1023
1024 glClear(GL_COLOR_BUFFER_BIT);
1025
1026 drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.8f);
1027
1028 EXPECT_GL_NO_ERROR();
1029
1030 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mColorOnlyFBO);
1031 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mMRTFBO);
1032
1033 glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
1034 getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
1035
1036 EXPECT_GL_NO_ERROR();
1037
1038 glBindFramebuffer(GL_FRAMEBUFFER, mMRTFBO);
1039
1040 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
1041 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);
1042 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
1043 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);
1044
1045 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, 0, 0);
1046 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mMRTColorBuffer0,
1047 0);
1048
1049 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 4, GLColor::red);
1050 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::green);
1051 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, getWindowHeight() / 4, GLColor::blue);
1052 EXPECT_PIXEL_COLOR_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, GLColor::yellow);
1053
1054 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mMRTColorBuffer0,
1055 0);
1056 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D,
1057 mMRTColorBuffer1, 0);
1058 }
1059
1060 // Test multisampled framebuffer blits if supported
TEST_P(BlitFramebufferANGLETest,MultisampledRGBAToRGBA)1061 TEST_P(BlitFramebufferANGLETest, MultisampledRGBAToRGBA)
1062 {
1063 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1064
1065 if (!checkExtension("GL_ANGLE_framebuffer_multisample"))
1066 return;
1067
1068 if (!checkExtension("GL_OES_rgb8_rgba8"))
1069 return;
1070
1071 multisampleTestHelper(mRGBAMultisampledFBO, mRGBAFBO);
1072 }
1073
TEST_P(BlitFramebufferANGLETest,MultisampledRGBAToBGRA)1074 TEST_P(BlitFramebufferANGLETest, MultisampledRGBAToBGRA)
1075 {
1076 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1077
1078 // VVL report error http://anglebug.com/4694
1079 ANGLE_SKIP_TEST_IF(IsVulkan());
1080
1081 if (!checkExtension("GL_ANGLE_framebuffer_multisample"))
1082 return;
1083
1084 if (!checkExtension("GL_OES_rgb8_rgba8"))
1085 return;
1086
1087 if (!checkExtension("GL_EXT_texture_format_BGRA8888"))
1088 return;
1089
1090 multisampleTestHelper(mRGBAMultisampledFBO, mBGRAFBO);
1091 }
1092
TEST_P(BlitFramebufferANGLETest,MultisampledBGRAToRGBA)1093 TEST_P(BlitFramebufferANGLETest, MultisampledBGRAToRGBA)
1094 {
1095 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1096
1097 // VVL report error http://anglebug.com/4694
1098 ANGLE_SKIP_TEST_IF(IsVulkan());
1099
1100 if (!checkExtension("GL_ANGLE_framebuffer_multisample"))
1101 return;
1102
1103 if (!checkExtension("GL_OES_rgb8_rgba8"))
1104 return;
1105
1106 if (!checkExtension("GL_EXT_texture_format_BGRA8888"))
1107 return;
1108
1109 multisampleTestHelper(mBGRAMultisampledFBO, mRGBAFBO);
1110 }
1111
TEST_P(BlitFramebufferANGLETest,MultisampledBGRAToBGRA)1112 TEST_P(BlitFramebufferANGLETest, MultisampledBGRAToBGRA)
1113 {
1114 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1115
1116 if (!checkExtension("GL_ANGLE_framebuffer_multisample"))
1117 return;
1118
1119 if (!checkExtension("GL_OES_rgb8_rgba8"))
1120 return;
1121
1122 if (!checkExtension("GL_EXT_texture_format_BGRA8888"))
1123 return;
1124
1125 multisampleTestHelper(mBGRAMultisampledFBO, mBGRAFBO);
1126 }
1127
1128 // Make sure that attempts to stretch in a blit call issue an error
TEST_P(BlitFramebufferANGLETest,ErrorStretching)1129 TEST_P(BlitFramebufferANGLETest, ErrorStretching)
1130 {
1131 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1132
1133 glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
1134
1135 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1136
1137 drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.5f);
1138
1139 EXPECT_GL_NO_ERROR();
1140
1141 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
1142 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
1143
1144 glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, 0, 0,
1145 getWindowWidth(), getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
1146 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1147 }
1148
1149 // Make sure that attempts to flip in a blit call issue an error
TEST_P(BlitFramebufferANGLETest,ErrorFlipping)1150 TEST_P(BlitFramebufferANGLETest, ErrorFlipping)
1151 {
1152 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1153
1154 glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
1155
1156 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1157
1158 drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.5f);
1159
1160 EXPECT_GL_NO_ERROR();
1161
1162 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
1163 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
1164
1165 glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, getWindowWidth() / 2,
1166 getWindowHeight() / 2, 0, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1167 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1168 }
1169
TEST_P(BlitFramebufferANGLETest,Errors)1170 TEST_P(BlitFramebufferANGLETest, Errors)
1171 {
1172 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
1173
1174 glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
1175
1176 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1177
1178 drawQuad(mCheckerProgram, essl1_shaders::PositionAttrib(), 0.5f);
1179
1180 EXPECT_GL_NO_ERROR();
1181
1182 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
1183 glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
1184
1185 glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
1186 getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_LINEAR);
1187 EXPECT_GL_ERROR(GL_INVALID_ENUM);
1188
1189 glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
1190 getWindowHeight(), GL_COLOR_BUFFER_BIT | 234, GL_NEAREST);
1191 EXPECT_GL_ERROR(GL_INVALID_VALUE);
1192
1193 glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mDiffFormatFBO);
1194
1195 glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(),
1196 getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
1197 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1198 }
1199
1200 // TODO(geofflang): Fix the dependence on glBlitFramebufferANGLE without checks and assuming the
1201 // default framebuffer is BGRA to enable the GL and GLES backends. (http://anglebug.com/1289)
1202
1203 class BlitFramebufferTest : public ANGLETest
1204 {
1205 protected:
BlitFramebufferTest()1206 BlitFramebufferTest()
1207 {
1208 setWindowWidth(256);
1209 setWindowHeight(256);
1210 setConfigRedBits(8);
1211 setConfigGreenBits(8);
1212 setConfigBlueBits(8);
1213 setConfigAlphaBits(8);
1214 setConfigDepthBits(24);
1215 setConfigStencilBits(8);
1216 }
1217
initColorFBO(GLFramebuffer * fbo,GLRenderbuffer * rbo,GLenum rboFormat,GLsizei width,GLsizei height)1218 void initColorFBO(GLFramebuffer *fbo,
1219 GLRenderbuffer *rbo,
1220 GLenum rboFormat,
1221 GLsizei width,
1222 GLsizei height)
1223 {
1224 glBindRenderbuffer(GL_RENDERBUFFER, *rbo);
1225 glRenderbufferStorage(GL_RENDERBUFFER, rboFormat, width, height);
1226
1227 glBindFramebuffer(GL_FRAMEBUFFER, *fbo);
1228 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, *rbo);
1229 }
1230
initColorFBOWithCheckerPattern(GLFramebuffer * fbo,GLRenderbuffer * rbo,GLenum rboFormat,GLsizei width,GLsizei height)1231 void initColorFBOWithCheckerPattern(GLFramebuffer *fbo,
1232 GLRenderbuffer *rbo,
1233 GLenum rboFormat,
1234 GLsizei width,
1235 GLsizei height)
1236 {
1237 initColorFBO(fbo, rbo, rboFormat, width, height);
1238
1239 ANGLE_GL_PROGRAM(checkerProgram, essl1_shaders::vs::Passthrough(),
1240 essl1_shaders::fs::Checkered());
1241 glViewport(0, 0, width, height);
1242 glBindFramebuffer(GL_FRAMEBUFFER, *fbo);
1243 drawQuad(checkerProgram.get(), essl1_shaders::PositionAttrib(), 0.5f);
1244 }
1245 };
1246
1247 // Tests resolving a multisample depth buffer.
TEST_P(BlitFramebufferTest,MultisampleDepth)1248 TEST_P(BlitFramebufferTest, MultisampleDepth)
1249 {
1250 // Test failure introduced by Apple's changes (anglebug.com/5505)
1251 ANGLE_SKIP_TEST_IF(IsMetal());
1252
1253 // TODO(oetuaho@nvidia.com): http://crbug.com/837717
1254 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsOSX());
1255
1256 GLRenderbuffer renderbuf;
1257 glBindRenderbuffer(GL_RENDERBUFFER, renderbuf.get());
1258 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_DEPTH_COMPONENT24, 256, 256);
1259
1260 GLFramebuffer framebuffer;
1261 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
1262 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
1263 renderbuf.get());
1264
1265 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1266
1267 glClearDepthf(0.5f);
1268 glClear(GL_DEPTH_BUFFER_BIT);
1269
1270 GLRenderbuffer destRenderbuf;
1271 glBindRenderbuffer(GL_RENDERBUFFER, destRenderbuf.get());
1272 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 256, 256);
1273
1274 GLFramebuffer resolved;
1275 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolved.get());
1276 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
1277 destRenderbuf.get());
1278
1279 glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer.get());
1280 glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
1281
1282 glBindFramebuffer(GL_FRAMEBUFFER, resolved.get());
1283
1284 GLTexture colorbuf;
1285 glBindTexture(GL_TEXTURE_2D, colorbuf.get());
1286 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);
1287 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuf.get(), 0);
1288
1289 ASSERT_GL_NO_ERROR();
1290
1291 // Clear to green
1292 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
1293 glClear(GL_COLOR_BUFFER_BIT);
1294 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1295
1296 // Make sure resulting depth is near 0.5f.
1297 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
1298 glEnable(GL_DEPTH_TEST);
1299 glDepthMask(false);
1300 glDepthFunc(GL_LESS);
1301 drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), -0.01f);
1302 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1303 EXPECT_PIXEL_COLOR_EQ(255, 0, GLColor::red);
1304 EXPECT_PIXEL_COLOR_EQ(0, 255, GLColor::red);
1305 EXPECT_PIXEL_COLOR_EQ(255, 255, GLColor::red);
1306 EXPECT_PIXEL_COLOR_EQ(127, 127, GLColor::red);
1307
1308 ANGLE_GL_PROGRAM(drawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());
1309 glEnable(GL_DEPTH_TEST);
1310 glDepthMask(false);
1311 glDepthFunc(GL_GREATER);
1312 drawQuad(drawBlue.get(), essl3_shaders::PositionAttrib(), 0.01f);
1313 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
1314 EXPECT_PIXEL_COLOR_EQ(255, 0, GLColor::blue);
1315 EXPECT_PIXEL_COLOR_EQ(0, 255, GLColor::blue);
1316 EXPECT_PIXEL_COLOR_EQ(255, 255, GLColor::blue);
1317 EXPECT_PIXEL_COLOR_EQ(127, 127, GLColor::blue);
1318
1319 ASSERT_GL_NO_ERROR();
1320 }
1321
1322 // Blit multisample stencil buffer to default framebuffer without prerotaion.
TEST_P(BlitFramebufferTest,BlitMultisampleStencilToDefault)1323 TEST_P(BlitFramebufferTest, BlitMultisampleStencilToDefault)
1324 {
1325 // http://anglebug.com/3496
1326 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsOSX());
1327
1328 // http://anglebug.com/5106
1329 ANGLE_SKIP_TEST_IF(IsMetal() && IsIntel() && IsOSX());
1330
1331 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
1332 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1333
1334 GLRenderbuffer colorbuf;
1335 glBindRenderbuffer(GL_RENDERBUFFER, colorbuf.get());
1336 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, 128, 128);
1337
1338 GLRenderbuffer depthstencilbuf;
1339 glBindRenderbuffer(GL_RENDERBUFFER, depthstencilbuf.get());
1340 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, 128, 128);
1341
1342 GLFramebuffer framebuffer;
1343 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
1344 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuf);
1345 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
1346 depthstencilbuf);
1347 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
1348 depthstencilbuf);
1349 glCheckFramebufferStatus(GL_FRAMEBUFFER);
1350
1351 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1352 glFlush();
1353
1354 // Replace stencil to 1.
1355 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
1356 glEnable(GL_STENCIL_TEST);
1357 glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
1358 glStencilFunc(GL_ALWAYS, 1, 255);
1359 drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.8f);
1360
1361 // Blit multisample stencil buffer to default frambuffer.
1362 GLenum attachments1[] = {GL_COLOR_ATTACHMENT0};
1363 glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments1);
1364 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1365 glBlitFramebuffer(0, 0, 128, 128, 0, 0, 128, 128, GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
1366 GL_NEAREST);
1367 glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1368
1369 // Disable stencil and draw full_screen green color.
1370 ANGLE_GL_PROGRAM(drawGreen, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());
1371 glDisable(GL_STENCIL_TEST);
1372 drawQuad(drawGreen.get(), essl3_shaders::PositionAttrib(), 0.5f);
1373
1374 // Draw blue color if the stencil is equal to 1.
1375 // If the blit finished successfully, the stencil test should all pass.
1376 ANGLE_GL_PROGRAM(drawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());
1377 glEnable(GL_STENCIL_TEST);
1378 glStencilFunc(GL_EQUAL, 1, 255);
1379 drawQuad(drawBlue.get(), essl3_shaders::PositionAttrib(), 0.2f);
1380
1381 // Check the result, especially the boundaries.
1382 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
1383 EXPECT_PIXEL_COLOR_EQ(127, 0, GLColor::blue);
1384 EXPECT_PIXEL_COLOR_EQ(50, 0, GLColor::blue);
1385 EXPECT_PIXEL_COLOR_EQ(127, 1, GLColor::blue);
1386 EXPECT_PIXEL_COLOR_EQ(0, 127, GLColor::blue);
1387 EXPECT_PIXEL_COLOR_EQ(127, 127, GLColor::blue);
1388 EXPECT_PIXEL_COLOR_EQ(64, 64, GLColor::blue);
1389
1390 ASSERT_GL_NO_ERROR();
1391 }
1392
1393 // Tests clearing a multisampled depth buffer.
TEST_P(BlitFramebufferTest,MultisampleDepthClear)1394 TEST_P(BlitFramebufferTest, MultisampleDepthClear)
1395 {
1396 // clearDepth && !maskDepth fails on Intel Ubuntu 19.04 Mesa 19.0.2 GL. http://anglebug.com/3614
1397 ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsDesktopOpenGL());
1398
1399 // http://anglebug.com/4092
1400 ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());
1401
1402 GLRenderbuffer depthMS;
1403 glBindRenderbuffer(GL_RENDERBUFFER, depthMS.get());
1404 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_DEPTH_COMPONENT24, 256, 256);
1405
1406 GLRenderbuffer colorMS;
1407 glBindRenderbuffer(GL_RENDERBUFFER, colorMS.get());
1408 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_RGBA8, 256, 256);
1409
1410 GLRenderbuffer colorResolved;
1411 glBindRenderbuffer(GL_RENDERBUFFER, colorResolved.get());
1412 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 256, 256);
1413
1414 GLFramebuffer framebufferMS;
1415 glBindFramebuffer(GL_FRAMEBUFFER, framebufferMS.get());
1416 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthMS.get());
1417 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorMS.get());
1418
1419 // Clear depth buffer to 0.5 and color to green.
1420 glClearDepthf(0.5f);
1421 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
1422 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
1423
1424 glFlush();
1425
1426 // Draw red into the multisampled color buffer.
1427 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
1428 glEnable(GL_DEPTH_TEST);
1429 glDepthFunc(GL_EQUAL);
1430 drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.0f);
1431
1432 // Resolve the color buffer to make sure the above draw worked correctly, which in turn implies
1433 // that the multisampled depth clear worked.
1434 GLFramebuffer framebufferResolved;
1435 glBindFramebuffer(GL_FRAMEBUFFER, framebufferResolved.get());
1436 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
1437 colorResolved.get());
1438 glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferMS.get());
1439 glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1440
1441 glBindFramebuffer(GL_FRAMEBUFFER, framebufferResolved.get());
1442
1443 ASSERT_GL_NO_ERROR();
1444
1445 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1446 EXPECT_PIXEL_COLOR_EQ(255, 0, GLColor::red);
1447 EXPECT_PIXEL_COLOR_EQ(0, 255, GLColor::red);
1448 EXPECT_PIXEL_COLOR_EQ(255, 255, GLColor::red);
1449 EXPECT_PIXEL_COLOR_EQ(127, 127, GLColor::red);
1450
1451 ASSERT_GL_NO_ERROR();
1452 }
1453
1454 // Test resolving a multisampled stencil buffer.
TEST_P(BlitFramebufferTest,MultisampleStencil)1455 TEST_P(BlitFramebufferTest, MultisampleStencil)
1456 {
1457 // Incorrect rendering results seen on AMD Windows OpenGL. http://anglebug.com/2486
1458 ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL() && IsWindows());
1459
1460 // http://anglebug.com/5106
1461 ANGLE_SKIP_TEST_IF(IsMetal() && IsIntel() && IsOSX());
1462
1463 GLRenderbuffer renderbuf;
1464 glBindRenderbuffer(GL_RENDERBUFFER, renderbuf.get());
1465 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_STENCIL_INDEX8, 256, 256);
1466
1467 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
1468
1469 GLFramebuffer framebuffer;
1470 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
1471 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
1472 renderbuf.get());
1473
1474 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1475
1476 // fill the stencil buffer with 0x1
1477 glStencilFunc(GL_ALWAYS, 0x1, 0xFF);
1478 glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
1479 glEnable(GL_STENCIL_TEST);
1480 drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);
1481
1482 GLTexture destColorbuf;
1483 glBindTexture(GL_TEXTURE_2D, destColorbuf.get());
1484 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);
1485
1486 GLRenderbuffer destRenderbuf;
1487 glBindRenderbuffer(GL_RENDERBUFFER, destRenderbuf.get());
1488 glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, 256, 256);
1489
1490 GLFramebuffer resolved;
1491 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolved.get());
1492 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
1493 destColorbuf.get(), 0);
1494 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
1495 destRenderbuf.get());
1496
1497 glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer.get());
1498 glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_STENCIL_BUFFER_BIT, GL_NEAREST);
1499
1500 glBindFramebuffer(GL_FRAMEBUFFER, resolved.get());
1501
1502 ASSERT_GL_NO_ERROR();
1503
1504 // Clear to green
1505 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
1506 glClear(GL_COLOR_BUFFER_BIT);
1507 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1508
1509 // Draw red if the stencil is 0x1, which should be true after the resolve.
1510 glStencilFunc(GL_EQUAL, 0x1, 0xFF);
1511 drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);
1512 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1513
1514 ASSERT_GL_NO_ERROR();
1515 }
1516
1517 // Test resolving a multisampled stencil buffer with scissor.
TEST_P(BlitFramebufferTest,ScissoredMultisampleStencil)1518 TEST_P(BlitFramebufferTest, ScissoredMultisampleStencil)
1519 {
1520 // Incorrect rendering results seen on AMD Windows OpenGL. http://anglebug.com/2486
1521 ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL() && IsWindows());
1522
1523 // Fails verifying that the middle pixel is red. http://anglebug.com/3496
1524 ANGLE_SKIP_TEST_IF((IsIntel() || IsAMD()) && IsOSX());
1525
1526 constexpr GLuint kSize = 256;
1527
1528 // Create the resolve framebuffer.
1529 GLTexture destColorbuf;
1530 glBindTexture(GL_TEXTURE_2D, destColorbuf.get());
1531 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
1532
1533 GLRenderbuffer destRenderbuf;
1534 glBindRenderbuffer(GL_RENDERBUFFER, destRenderbuf.get());
1535 glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, kSize, kSize);
1536
1537 GLFramebuffer resolved;
1538 glBindFramebuffer(GL_FRAMEBUFFER, resolved.get());
1539 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
1540 destColorbuf.get(), 0);
1541 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
1542 destRenderbuf.get());
1543
1544 // Clear the resolved buffer with gray and 0x10 stencil.
1545 GLColor gray(127, 127, 127, 255);
1546 glClearStencil(0x10);
1547 glClearColor(0.499f, 0.499f, 0.499f, 1.0f);
1548 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1549 EXPECT_PIXEL_COLOR_EQ(0, 0, gray);
1550 EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, gray);
1551
1552 // Create the multisampled framebuffer.
1553 GLRenderbuffer renderbuf;
1554 glBindRenderbuffer(GL_RENDERBUFFER, renderbuf.get());
1555 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_STENCIL_INDEX8, kSize, kSize);
1556
1557 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
1558 ANGLE_GL_PROGRAM(drawGreen, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());
1559 ANGLE_GL_PROGRAM(drawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());
1560
1561 GLFramebuffer framebuffer;
1562 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
1563 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
1564 renderbuf.get());
1565
1566 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1567
1568 // Fill the stencil buffer with 0x1.
1569 glClearStencil(0x1);
1570 glClear(GL_STENCIL_BUFFER_BIT);
1571
1572 // Fill a smaller region of the buffer with 0x2.
1573 glEnable(GL_SCISSOR_TEST);
1574 glEnable(GL_STENCIL_TEST);
1575 glScissor(kSize / 4, kSize / 4, kSize / 2, kSize / 2);
1576 glStencilFunc(GL_ALWAYS, 0x2, 0xFF);
1577 glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
1578 drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);
1579
1580 // Blit into the resolved framebuffer (with scissor still enabled).
1581 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolved.get());
1582 glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_STENCIL_BUFFER_BIT, GL_NEAREST);
1583
1584 glBindFramebuffer(GL_FRAMEBUFFER, resolved.get());
1585
1586 ASSERT_GL_NO_ERROR();
1587
1588 // Draw blue if the stencil is 0x1, which should never be true.
1589 glDisable(GL_SCISSOR_TEST);
1590 glStencilMask(0);
1591 glStencilFunc(GL_EQUAL, 0x1, 0xFF);
1592 drawQuad(drawBlue.get(), essl3_shaders::PositionAttrib(), 0.5f);
1593 EXPECT_PIXEL_COLOR_EQ(0, 0, gray);
1594 EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, gray);
1595 EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, gray);
1596 EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, gray);
1597 EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, gray);
1598
1599 // Draw red if the stencil is 0x2, which should be true in the middle after the blit/resolve.
1600 glStencilFunc(GL_EQUAL, 0x2, 0xFF);
1601 drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);
1602 EXPECT_PIXEL_COLOR_EQ(0, 0, gray);
1603 EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, gray);
1604 EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, gray);
1605 EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, gray);
1606 EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::red);
1607
1608 // Draw green if the stencil is 0x10, which should be left untouched in the outer regions.
1609 glStencilFunc(GL_EQUAL, 0x10, 0xFF);
1610 drawQuad(drawGreen.get(), essl3_shaders::PositionAttrib(), 0.5f);
1611 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1612 EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::green);
1613 EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::green);
1614 EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::green);
1615 EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::red);
1616
1617 ASSERT_GL_NO_ERROR();
1618 }
1619
1620 // Test blitting from a texture with non-zero base. The blit is non-stretching and between
1621 // identical formats so that the path that uses vkCmdBlitImage is taken.
TEST_P(BlitFramebufferTest,NonZeroBaseSource)1622 TEST_P(BlitFramebufferTest, NonZeroBaseSource)
1623 {
1624 // http://anglebug.com/5001
1625 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsOSX());
1626
1627 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
1628
1629 // Create a framebuffer for source data. It usea a non-zero base.
1630 GLTexture srcColor;
1631 glBindTexture(GL_TEXTURE_2D, srcColor);
1632 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1633 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1634 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1635
1636 GLFramebuffer srcFramebuffer;
1637 glBindFramebuffer(GL_FRAMEBUFFER, srcFramebuffer);
1638 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcColor, 1);
1639 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1640
1641 // fill the color buffer with red.
1642 drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);
1643
1644 // Create a framebuffer for blit destination.
1645 GLTexture dstColor;
1646 glBindTexture(GL_TEXTURE_2D, dstColor);
1647 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1648
1649 GLFramebuffer dstFramebuffer;
1650 glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
1651 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dstColor, 0);
1652 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1653
1654 // Blit. Note: no stretching is done so that vkCmdBlitImage can be used.
1655 glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFramebuffer);
1656 glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1657
1658 glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
1659
1660 ASSERT_GL_NO_ERROR();
1661
1662 // Make sure the blit is done.
1663 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1664
1665 ASSERT_GL_NO_ERROR();
1666 }
1667
1668 // Test blitting to a texture with non-zero base. The blit is non-stretching and between
1669 // identical formats so that the path that uses vkCmdBlitImage is taken.
TEST_P(BlitFramebufferTest,NonZeroBaseDestination)1670 TEST_P(BlitFramebufferTest, NonZeroBaseDestination)
1671 {
1672 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
1673
1674 // Create a framebuffer for source data. It usea a non-zero base.
1675 GLTexture srcColor;
1676 glBindTexture(GL_TEXTURE_2D, srcColor);
1677 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1678
1679 GLFramebuffer srcFramebuffer;
1680 glBindFramebuffer(GL_FRAMEBUFFER, srcFramebuffer);
1681 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, srcColor, 0);
1682 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1683
1684 // fill the color buffer with red.
1685 drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);
1686
1687 // Create a framebuffer for blit destination.
1688 GLTexture dstColor;
1689 glBindTexture(GL_TEXTURE_2D, dstColor);
1690 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1691 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1692 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1693
1694 GLFramebuffer dstFramebuffer;
1695 glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
1696 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dstColor, 1);
1697 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1698
1699 // Blit. Note: no stretching is done so that vkCmdBlitImage can be used.
1700 glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFramebuffer);
1701 glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1702
1703 glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
1704
1705 ASSERT_GL_NO_ERROR();
1706
1707 // Make sure the blit is done.
1708 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1709
1710 ASSERT_GL_NO_ERROR();
1711 }
1712
1713 // Test blitting from a stencil buffer with non-zero base.
TEST_P(BlitFramebufferTest,NonZeroBaseSourceStencil)1714 TEST_P(BlitFramebufferTest, NonZeroBaseSourceStencil)
1715 {
1716 // http://anglebug.com/5001
1717 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsOSX());
1718
1719 // http://anglebug.com/5106
1720 ANGLE_SKIP_TEST_IF(IsMetal() && IsIntel() && IsOSX());
1721
1722 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
1723
1724 // Create a framebuffer with an attachment that has non-zero base
1725 GLTexture stencilTexture;
1726 glBindTexture(GL_TEXTURE_2D, stencilTexture);
1727 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 256, 256, 0, GL_DEPTH_STENCIL,
1728 GL_UNSIGNED_INT_24_8, nullptr);
1729 glTexImage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, 256, 256, 0, GL_DEPTH_STENCIL,
1730 GL_UNSIGNED_INT_24_8, nullptr);
1731 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1732
1733 GLFramebuffer srcFramebuffer;
1734 glBindFramebuffer(GL_FRAMEBUFFER, srcFramebuffer);
1735 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, stencilTexture, 1);
1736 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1737
1738 // fill the stencil buffer with 0x1
1739 glStencilFunc(GL_ALWAYS, 0x1, 0xFF);
1740 glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
1741 glEnable(GL_STENCIL_TEST);
1742 drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);
1743
1744 // Create a framebuffer with an attachment that has non-zero base
1745 GLTexture colorTexture;
1746 glBindTexture(GL_TEXTURE_2D, colorTexture);
1747 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);
1748
1749 GLRenderbuffer renderbuf;
1750 glBindRenderbuffer(GL_RENDERBUFFER, renderbuf);
1751 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 256, 256);
1752
1753 GLFramebuffer dstFramebuffer;
1754 glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
1755 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
1756 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuf);
1757 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1758
1759 // Blit stencil.
1760 glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFramebuffer);
1761 glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_STENCIL_BUFFER_BIT, GL_NEAREST);
1762
1763 glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
1764
1765 ASSERT_GL_NO_ERROR();
1766
1767 // Clear to green
1768 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
1769 glClear(GL_COLOR_BUFFER_BIT);
1770 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1771
1772 // Draw red if the stencil is 0x1, which should be true after the blit.
1773 glStencilFunc(GL_EQUAL, 0x1, 0xFF);
1774 drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);
1775 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1776
1777 ASSERT_GL_NO_ERROR();
1778 }
1779
1780 // Test blitting to a stencil buffer with non-zero base.
TEST_P(BlitFramebufferTest,NonZeroBaseDestinationStencil)1781 TEST_P(BlitFramebufferTest, NonZeroBaseDestinationStencil)
1782 {
1783 // http://anglebug.com/5001
1784 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsOSX());
1785 // http://anglebug.com/5106
1786 ANGLE_SKIP_TEST_IF(IsMetal() && (IsAMD() || IsIntel()));
1787 // http://anglebug.com/5003
1788 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsWindows());
1789
1790 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
1791
1792 // Create a framebuffer for source data.
1793 GLRenderbuffer renderbuf;
1794 glBindRenderbuffer(GL_RENDERBUFFER, renderbuf);
1795 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 256, 256);
1796
1797 GLFramebuffer srcFramebuffer;
1798 glBindFramebuffer(GL_FRAMEBUFFER, srcFramebuffer);
1799 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuf);
1800 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1801
1802 // fill the stencil buffer with 0x1
1803 glStencilFunc(GL_ALWAYS, 0x1, 0xFF);
1804 glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
1805 glEnable(GL_STENCIL_TEST);
1806 drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);
1807
1808 // Create a framebuffer with an attachment that has non-zero base
1809 GLTexture colorTexture;
1810 glBindTexture(GL_TEXTURE_2D, colorTexture);
1811 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);
1812
1813 GLTexture stencilTexture;
1814 glBindTexture(GL_TEXTURE_2D, stencilTexture);
1815 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 256, 256, 0, GL_DEPTH_STENCIL,
1816 GL_UNSIGNED_INT_24_8, nullptr);
1817 glTexImage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, 256, 256, 0, GL_DEPTH_STENCIL,
1818 GL_UNSIGNED_INT_24_8, nullptr);
1819 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1820
1821 GLFramebuffer dstFramebuffer;
1822 glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
1823 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
1824 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, stencilTexture, 1);
1825 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1826
1827 // Blit stencil.
1828 glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFramebuffer);
1829 glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_STENCIL_BUFFER_BIT, GL_NEAREST);
1830
1831 glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
1832
1833 ASSERT_GL_NO_ERROR();
1834
1835 // Clear to green
1836 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
1837 glClear(GL_COLOR_BUFFER_BIT);
1838 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1839
1840 // Draw red if the stencil is 0x1, which should be true after the blit.
1841 glStencilFunc(GL_EQUAL, 0x1, 0xFF);
1842 drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);
1843 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1844
1845 ASSERT_GL_NO_ERROR();
1846 }
1847
1848 // Test blitting to a stencil buffer with non-zero base. Exercises the compute path in the Vulkan
1849 // backend if stencil export is not supported. The blit is not 1-to-1 for this path to be taken.
TEST_P(BlitFramebufferTest,NonZeroBaseDestinationStencilStretch)1850 TEST_P(BlitFramebufferTest, NonZeroBaseDestinationStencilStretch)
1851 {
1852 // http://anglebug.com/5000
1853 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsWindows());
1854
1855 // http://anglebug.com/5001
1856 ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsOSX());
1857
1858 // http://anglebug.com/5106
1859 ANGLE_SKIP_TEST_IF(IsMetal() && (IsAMD() || IsIntel()));
1860
1861 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
1862
1863 // Create a framebuffer for source data.
1864 GLRenderbuffer renderbuf;
1865 glBindRenderbuffer(GL_RENDERBUFFER, renderbuf);
1866 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 256, 256);
1867
1868 GLFramebuffer srcFramebuffer;
1869 glBindFramebuffer(GL_FRAMEBUFFER, srcFramebuffer);
1870 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderbuf);
1871 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1872
1873 // fill the stencil buffer with 0x1
1874 glStencilFunc(GL_ALWAYS, 0x1, 0xFF);
1875 glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
1876 glEnable(GL_STENCIL_TEST);
1877 drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);
1878
1879 // Create a framebuffer with an attachment that has non-zero base
1880 GLTexture colorTexture;
1881 glBindTexture(GL_TEXTURE_2D, colorTexture);
1882 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);
1883
1884 GLTexture stencilTexture;
1885 glBindTexture(GL_TEXTURE_2D, stencilTexture);
1886 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 256, 256, 0, GL_DEPTH_STENCIL,
1887 GL_UNSIGNED_INT_24_8, nullptr);
1888 glTexImage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, 256, 256, 0, GL_DEPTH_STENCIL,
1889 GL_UNSIGNED_INT_24_8, nullptr);
1890 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
1891
1892 GLFramebuffer dstFramebuffer;
1893 glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
1894 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0);
1895 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, stencilTexture, 1);
1896 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1897
1898 // Blit stencil. Note: stretch is intentional so vkCmdBlitImage cannot be used in the Vulkan
1899 // backend.
1900 glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFramebuffer);
1901 glBlitFramebuffer(0, 0, 256, 256, -256, -256, 512, 512, GL_STENCIL_BUFFER_BIT, GL_NEAREST);
1902
1903 glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
1904
1905 ASSERT_GL_NO_ERROR();
1906
1907 // Clear to green
1908 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
1909 glClear(GL_COLOR_BUFFER_BIT);
1910 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1911
1912 // Draw red if the stencil is 0x1, which should be true after the blit.
1913 glStencilFunc(GL_EQUAL, 0x1, 0xFF);
1914 drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);
1915 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1916
1917 ASSERT_GL_NO_ERROR();
1918 }
1919
1920 // Blit an SRGB framebuffer and scale it.
TEST_P(BlitFramebufferTest,BlitSRGBToRGBAndScale)1921 TEST_P(BlitFramebufferTest, BlitSRGBToRGBAndScale)
1922 {
1923 constexpr const GLsizei kWidth = 256;
1924 constexpr const GLsizei kHeight = 256;
1925
1926 GLRenderbuffer sourceRBO, targetRBO;
1927 GLFramebuffer sourceFBO, targetFBO;
1928 initColorFBOWithCheckerPattern(&sourceFBO, &sourceRBO, GL_SRGB8_ALPHA8, kWidth * 2,
1929 kHeight * 2);
1930 initColorFBO(&targetFBO, &targetRBO, GL_RGBA8, kWidth, kHeight);
1931
1932 EXPECT_GL_NO_ERROR();
1933
1934 glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
1935 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
1936
1937 glViewport(0, 0, kWidth, kHeight);
1938
1939 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
1940 glClear(GL_COLOR_BUFFER_BIT);
1941
1942 // Scale down without flipping.
1943 glBlitFramebuffer(0, 0, kWidth * 2, kHeight * 2, 0, 0, kWidth, kHeight, GL_COLOR_BUFFER_BIT,
1944 GL_NEAREST);
1945
1946 EXPECT_GL_NO_ERROR();
1947
1948 glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
1949
1950 EXPECT_PIXEL_COLOR_EQ(kWidth / 4, kHeight / 4, GLColor::red);
1951 EXPECT_PIXEL_COLOR_EQ(kWidth / 4, 3 * kHeight / 4, GLColor::green);
1952 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, kHeight / 4, GLColor::blue);
1953 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, 3 * kHeight / 4, GLColor::yellow);
1954
1955 glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
1956 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
1957
1958 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
1959 glClear(GL_COLOR_BUFFER_BIT);
1960
1961 // Scale down and flip in the X direction.
1962 glBlitFramebuffer(0, 0, kWidth * 2, kHeight * 2, kWidth, 0, 0, kHeight, GL_COLOR_BUFFER_BIT,
1963 GL_NEAREST);
1964
1965 EXPECT_GL_NO_ERROR();
1966
1967 glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
1968
1969 EXPECT_PIXEL_COLOR_EQ(kWidth / 4, kHeight / 4, GLColor::blue);
1970 EXPECT_PIXEL_COLOR_EQ(kWidth / 4, 3 * kHeight / 4, GLColor::yellow);
1971 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, kHeight / 4, GLColor::red);
1972 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, 3 * kHeight / 4, GLColor::green);
1973 }
1974
1975 // Blit stencil, with scissor and scale it.
TEST_P(BlitFramebufferTest,BlitStencilScissoredScaled)1976 TEST_P(BlitFramebufferTest, BlitStencilScissoredScaled)
1977 {
1978 // http://anglebug.com/5106
1979 ANGLE_SKIP_TEST_IF(IsMetal() && IsIntel() && IsOSX());
1980
1981 constexpr GLint kSize = 256;
1982
1983 // Create the destination framebuffer.
1984 GLTexture destColorbuf;
1985 glBindTexture(GL_TEXTURE_2D, destColorbuf.get());
1986 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
1987
1988 GLRenderbuffer destRenderbuf;
1989 glBindRenderbuffer(GL_RENDERBUFFER, destRenderbuf.get());
1990 glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, kSize, kSize);
1991
1992 GLFramebuffer destFBO;
1993 glBindFramebuffer(GL_FRAMEBUFFER, destFBO.get());
1994 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
1995 destColorbuf.get(), 0);
1996 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
1997 destRenderbuf.get());
1998
1999 // Clear the destination buffer with gray and 0x10 stencil.
2000 GLColor gray(127, 127, 127, 255);
2001 glClearStencil(0x10);
2002 glClearColor(0.499f, 0.499f, 0.499f, 1.0f);
2003 glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2004 EXPECT_PIXEL_COLOR_EQ(0, 0, gray);
2005 EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, gray);
2006
2007 // Create the source framebuffer.
2008 GLRenderbuffer renderbuf;
2009 glBindRenderbuffer(GL_RENDERBUFFER, renderbuf.get());
2010 glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, kSize, kSize);
2011
2012 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
2013 ANGLE_GL_PROGRAM(drawGreen, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());
2014 ANGLE_GL_PROGRAM(drawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());
2015
2016 GLFramebuffer sourceFBO;
2017 glBindFramebuffer(GL_FRAMEBUFFER, sourceFBO.get());
2018 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2019 renderbuf.get());
2020
2021 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
2022
2023 // Fill the stencil buffer with 0x1.
2024 glClearStencil(0x1);
2025 glClear(GL_STENCIL_BUFFER_BIT);
2026
2027 // Fill a smaller region of the buffer with 0x2.
2028 glEnable(GL_SCISSOR_TEST);
2029 glEnable(GL_STENCIL_TEST);
2030 glScissor(kSize / 4, kSize / 4, kSize / 2, kSize / 2);
2031 glStencilFunc(GL_ALWAYS, 0x2, 0xFF);
2032 glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
2033 drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);
2034
2035 // Blit and scale down into the destination framebuffer (with scissor still enabled).
2036 //
2037 // Source looks like this:
2038 //
2039 // +----|----|----|----+
2040 // | |
2041 // | 0x1 |
2042 // - +---------+ -
2043 // | | | |
2044 // | | | |
2045 // - | 0x2 | -
2046 // | | | |
2047 // | | | |
2048 // - +---------+ -
2049 // | |
2050 // | |
2051 // +----|----|----|----+
2052 //
2053 // We want the destination to look like this:
2054 //
2055 // +----|----|----|----+
2056 // | |
2057 // | 0x10 |
2058 // - +---------+ -
2059 // | | 0x1 | |
2060 // | | +------+ |
2061 // - | | | -
2062 // | | | 0x2 | |
2063 // | | | | |
2064 // - +--+------+ -
2065 // | |
2066 // | |
2067 // +----|----|----|----+
2068 //
2069 // The corresponding blit would be: (0, 0, 3/4, 3/4) -> (1/4, 1/4, 3/4, 3/4). For testing, we
2070 // would like to avoid having the destination area and scissor to match. Using destination
2071 // area as (0, 0, 1, 1), and keeping the same scaling, the source area should be
2072 // (-3/8, -3/8, 9/8, 9/8).
2073 //
2074 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, destFBO.get());
2075 constexpr GLint kBlitSrc[2] = {-3 * kSize / 8, 9 * kSize / 8};
2076 glBlitFramebuffer(kBlitSrc[0], kBlitSrc[0], kBlitSrc[1], kBlitSrc[1], 0, 0, kSize, kSize,
2077 GL_STENCIL_BUFFER_BIT, GL_NEAREST);
2078
2079 glBindFramebuffer(GL_FRAMEBUFFER, destFBO.get());
2080
2081 ASSERT_GL_NO_ERROR();
2082
2083 // Draw blue if the stencil is 0x1, which should be true only in the top and left of the inner
2084 // square.
2085 glDisable(GL_SCISSOR_TEST);
2086 glStencilMask(0);
2087 glStencilFunc(GL_EQUAL, 0x1, 0xFF);
2088 drawQuad(drawBlue.get(), essl3_shaders::PositionAttrib(), 0.5f);
2089 EXPECT_PIXEL_COLOR_EQ(0, 0, gray);
2090 EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, gray);
2091 EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, gray);
2092 EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, gray);
2093
2094 EXPECT_PIXEL_COLOR_EQ(kSize / 4, kSize / 4, GLColor::blue);
2095 EXPECT_PIXEL_COLOR_EQ(kSize / 4, 3 * kSize / 4 - 1, GLColor::blue);
2096 EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, kSize / 4, GLColor::blue);
2097
2098 EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, gray);
2099 EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, 3 * kSize / 4 - 1, gray);
2100
2101 // Draw red if the stencil is 0x2, which should be true in the bottom/right of the middle
2102 // square after the blit.
2103 glStencilFunc(GL_EQUAL, 0x2, 0xFF);
2104 drawQuad(drawRed.get(), essl3_shaders::PositionAttrib(), 0.5f);
2105 EXPECT_PIXEL_COLOR_EQ(0, 0, gray);
2106 EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, gray);
2107 EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, gray);
2108 EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, gray);
2109
2110 EXPECT_PIXEL_COLOR_EQ(kSize / 4, kSize / 4, GLColor::blue);
2111 EXPECT_PIXEL_COLOR_EQ(kSize / 4, 3 * kSize / 4 - 1, GLColor::blue);
2112 EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, kSize / 4, GLColor::blue);
2113
2114 EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::red);
2115 EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, 3 * kSize / 4 - 1, GLColor::red);
2116
2117 // Draw green if the stencil is 0x10, which should be left untouched in the outer regions.
2118 glStencilFunc(GL_EQUAL, 0x10, 0xFF);
2119 drawQuad(drawGreen.get(), essl3_shaders::PositionAttrib(), 0.5f);
2120 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2121 EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::green);
2122 EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::green);
2123 EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::green);
2124
2125 EXPECT_PIXEL_COLOR_EQ(kSize / 4, kSize / 4, GLColor::blue);
2126 EXPECT_PIXEL_COLOR_EQ(kSize / 4, 3 * kSize / 4 - 1, GLColor::blue);
2127 EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, kSize / 4, GLColor::blue);
2128
2129 EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::red);
2130 EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, 3 * kSize / 4 - 1, GLColor::red);
2131
2132 ASSERT_GL_NO_ERROR();
2133 }
2134
2135 // Blit a subregion of an SRGB framebuffer to an RGB framebuffer.
TEST_P(BlitFramebufferTest,PartialBlitSRGBToRGB)2136 TEST_P(BlitFramebufferTest, PartialBlitSRGBToRGB)
2137 {
2138 constexpr const GLsizei kWidth = 256;
2139 constexpr const GLsizei kHeight = 256;
2140
2141 GLRenderbuffer sourceRBO, targetRBO;
2142 GLFramebuffer sourceFBO, targetFBO;
2143 initColorFBOWithCheckerPattern(&sourceFBO, &sourceRBO, GL_SRGB8_ALPHA8, kWidth * 2,
2144 kHeight * 2);
2145 initColorFBO(&targetFBO, &targetRBO, GL_RGBA8, kWidth, kHeight);
2146
2147 EXPECT_GL_NO_ERROR();
2148
2149 glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
2150 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
2151
2152 glViewport(0, 0, kWidth, kHeight);
2153
2154 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
2155 glClear(GL_COLOR_BUFFER_BIT);
2156
2157 // Blit a part of the source FBO without flipping.
2158 glBlitFramebuffer(kWidth, kHeight, kWidth * 2, kHeight * 2, 0, 0, kWidth, kHeight,
2159 GL_COLOR_BUFFER_BIT, GL_NEAREST);
2160
2161 EXPECT_GL_NO_ERROR();
2162
2163 glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
2164
2165 EXPECT_PIXEL_COLOR_EQ(kWidth / 4, kHeight / 4, GLColor::yellow);
2166 EXPECT_PIXEL_COLOR_EQ(kWidth / 4, 3 * kHeight / 4, GLColor::yellow);
2167 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, kHeight / 4, GLColor::yellow);
2168 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, 3 * kHeight / 4, GLColor::yellow);
2169
2170 glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
2171 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
2172
2173 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
2174 glClear(GL_COLOR_BUFFER_BIT);
2175
2176 // Blit a part of the source FBO and flip in the X direction.
2177 glBlitFramebuffer(kWidth * 2, 0, kWidth, kHeight, kWidth, 0, 0, kHeight, GL_COLOR_BUFFER_BIT,
2178 GL_NEAREST);
2179
2180 EXPECT_GL_NO_ERROR();
2181
2182 glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
2183
2184 EXPECT_PIXEL_COLOR_EQ(kWidth / 4, kHeight / 4, GLColor::blue);
2185 EXPECT_PIXEL_COLOR_EQ(kWidth / 4, 3 * kHeight / 4, GLColor::blue);
2186 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, kHeight / 4, GLColor::blue);
2187 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, 3 * kHeight / 4, GLColor::blue);
2188 }
2189
2190 // Blit an SRGB framebuffer with an oversized source area (parts outside the source area should be
2191 // clipped out).
TEST_P(BlitFramebufferTest,BlitSRGBToRGBOversizedSourceArea)2192 TEST_P(BlitFramebufferTest, BlitSRGBToRGBOversizedSourceArea)
2193 {
2194 constexpr const GLsizei kWidth = 256;
2195 constexpr const GLsizei kHeight = 256;
2196
2197 GLRenderbuffer sourceRBO, targetRBO;
2198 GLFramebuffer sourceFBO, targetFBO;
2199 initColorFBOWithCheckerPattern(&sourceFBO, &sourceRBO, GL_SRGB8_ALPHA8, kWidth, kHeight);
2200 initColorFBO(&targetFBO, &targetRBO, GL_RGBA8, kWidth, kHeight);
2201
2202 EXPECT_GL_NO_ERROR();
2203
2204 glViewport(0, 0, kWidth, kHeight);
2205
2206 glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
2207 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
2208
2209 glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
2210 glClear(GL_COLOR_BUFFER_BIT);
2211
2212 // Blit so that the source area gets placed at the center of the target FBO.
2213 // The width of the source area is 1/4 of the width of the target FBO.
2214 glBlitFramebuffer(-3 * kWidth / 2, -3 * kHeight / 2, 5 * kWidth / 2, 5 * kHeight / 2, 0, 0,
2215 kWidth, kHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2216
2217 EXPECT_GL_NO_ERROR();
2218
2219 glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
2220
2221 // Source FBO colors can be found in the middle of the target FBO.
2222 EXPECT_PIXEL_COLOR_EQ(7 * kWidth / 16, 7 * kHeight / 16, GLColor::red);
2223 EXPECT_PIXEL_COLOR_EQ(7 * kWidth / 16, 9 * kHeight / 16, GLColor::green);
2224 EXPECT_PIXEL_COLOR_EQ(9 * kWidth / 16, 7 * kHeight / 16, GLColor::blue);
2225 EXPECT_PIXEL_COLOR_EQ(9 * kWidth / 16, 9 * kHeight / 16, GLColor::yellow);
2226
2227 // Clear color should remain around the edges of the target FBO (WebGL 2.0 spec explicitly
2228 // requires this and ANGLE is expected to follow that).
2229 EXPECT_PIXEL_COLOR_EQ(kWidth / 4, kHeight / 4, GLColor::blue);
2230 EXPECT_PIXEL_COLOR_EQ(kWidth / 4, 3 * kHeight / 4, GLColor::blue);
2231 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, kHeight / 4, GLColor::blue);
2232 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, 3 * kHeight / 4, GLColor::blue);
2233 }
2234
2235 // Blit an SRGB framebuffer with an oversized dest area (even though the result is clipped, it
2236 // should be scaled as if the whole dest area was used).
TEST_P(BlitFramebufferTest,BlitSRGBToRGBOversizedDestArea)2237 TEST_P(BlitFramebufferTest, BlitSRGBToRGBOversizedDestArea)
2238 {
2239 constexpr const GLsizei kWidth = 256;
2240 constexpr const GLsizei kHeight = 256;
2241
2242 GLRenderbuffer sourceRBO, targetRBO;
2243 GLFramebuffer sourceFBO, targetFBO;
2244 initColorFBOWithCheckerPattern(&sourceFBO, &sourceRBO, GL_SRGB8_ALPHA8, kWidth, kHeight);
2245 initColorFBO(&targetFBO, &targetRBO, GL_RGBA8, kWidth, kHeight);
2246
2247 EXPECT_GL_NO_ERROR();
2248
2249 glViewport(0, 0, kWidth, kHeight);
2250
2251 glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
2252 glClear(GL_COLOR_BUFFER_BIT);
2253
2254 // Dest is oversized but centered the same as source
2255 glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
2256 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
2257
2258 glBlitFramebuffer(0, 0, kWidth, kHeight, -kWidth / 2, -kHeight / 2, 3 * kWidth / 2,
2259 3 * kHeight / 2, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2260
2261 EXPECT_GL_NO_ERROR();
2262
2263 glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
2264
2265 // Expected result:
2266 //
2267 // +-------+-------+
2268 // | | |
2269 // | R | B |
2270 // | | |
2271 // +-------+-------+
2272 // | | |
2273 // | G | Y |
2274 // | | |
2275 // +-------+-------+
2276 //
2277 EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::red);
2278 EXPECT_PIXEL_COLOR_EQ(kWidth / 4, kHeight / 4, GLColor::red);
2279 EXPECT_PIXEL_COLOR_EQ(kWidth / 2 - 1, kHeight / 2 - 1, GLColor::red);
2280
2281 EXPECT_PIXEL_COLOR_EQ(1, kWidth - 1, GLColor::green);
2282 EXPECT_PIXEL_COLOR_EQ(kWidth / 4, 3 * kHeight / 4, GLColor::green);
2283 EXPECT_PIXEL_COLOR_EQ(kWidth / 2 - 1, kHeight / 2 + 1, GLColor::green);
2284
2285 EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 1, GLColor::blue);
2286 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, kHeight / 4, GLColor::blue);
2287 EXPECT_PIXEL_COLOR_EQ(kWidth / 2 + 1, kHeight / 2 - 1, GLColor::blue);
2288
2289 EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::yellow);
2290 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4, 3 * kHeight / 4, GLColor::yellow);
2291 EXPECT_PIXEL_COLOR_EQ(kWidth / 2 + 1, kHeight / 2 + 1, GLColor::yellow);
2292
2293 // Dest is oversized in the negative direction
2294 glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
2295 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
2296
2297 glBlitFramebuffer(0, 0, kWidth, kHeight, -kWidth / 2, -kHeight / 2, kWidth, kHeight,
2298 GL_COLOR_BUFFER_BIT, GL_NEAREST);
2299
2300 EXPECT_GL_NO_ERROR();
2301
2302 glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
2303
2304 // Expected result:
2305 //
2306 // Width / 4
2307 // |
2308 // V
2309 // +---+-----------+
2310 // | R | B |
2311 // +---+-----------+ <- Height / 4
2312 // | | |
2313 // | | |
2314 // | G | Y |
2315 // | | |
2316 // | | |
2317 // +---+-----------+
2318 //
2319 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2320 EXPECT_PIXEL_COLOR_EQ(0, kHeight / 4 - 1, GLColor::red);
2321 EXPECT_PIXEL_COLOR_EQ(kWidth / 4 - 1, 0, GLColor::red);
2322 EXPECT_PIXEL_COLOR_EQ(kWidth / 4 - 1, kHeight / 4 - 1, GLColor::red);
2323 EXPECT_PIXEL_COLOR_EQ(kWidth / 8, kHeight / 8, GLColor::red);
2324
2325 EXPECT_PIXEL_COLOR_EQ(0, kHeight / 4 + 1, GLColor::green);
2326 EXPECT_PIXEL_COLOR_EQ(0, kHeight - 1, GLColor::green);
2327 EXPECT_PIXEL_COLOR_EQ(kWidth / 4 - 1, kHeight / 4 + 1, GLColor::green);
2328 EXPECT_PIXEL_COLOR_EQ(kWidth / 4 - 1, kHeight - 1, GLColor::green);
2329 EXPECT_PIXEL_COLOR_EQ(kWidth / 8, kHeight / 2, GLColor::green);
2330
2331 EXPECT_PIXEL_COLOR_EQ(kWidth / 4 + 1, 0, GLColor::blue);
2332 EXPECT_PIXEL_COLOR_EQ(kWidth / 4 + 1, kHeight / 4 - 1, GLColor::blue);
2333 EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 0, GLColor::blue);
2334 EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight / 4 - 1, GLColor::blue);
2335 EXPECT_PIXEL_COLOR_EQ(kWidth / 2, kHeight / 8, GLColor::blue);
2336
2337 EXPECT_PIXEL_COLOR_EQ(kWidth / 4 + 1, kHeight / 4 + 1, GLColor::yellow);
2338 EXPECT_PIXEL_COLOR_EQ(kWidth / 4 + 1, kHeight - 1, GLColor::yellow);
2339 EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight / 4 + 1, GLColor::yellow);
2340 EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::yellow);
2341 EXPECT_PIXEL_COLOR_EQ(kWidth / 2, kHeight / 2, GLColor::yellow);
2342
2343 // Dest is oversized in the positive direction
2344 glBindFramebuffer(GL_READ_FRAMEBUFFER, sourceFBO);
2345 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, targetFBO);
2346
2347 glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, 3 * kWidth / 2, 3 * kHeight / 2,
2348 GL_COLOR_BUFFER_BIT, GL_NEAREST);
2349
2350 EXPECT_GL_NO_ERROR();
2351
2352 glBindFramebuffer(GL_FRAMEBUFFER, targetFBO);
2353
2354 // Expected result:
2355 //
2356 // 3 * Width / 4
2357 // |
2358 // V
2359 // +-----------+---+
2360 // | | |
2361 // | | |
2362 // | R | B |
2363 // | | |
2364 // | | |
2365 // +-----------+---+ <- 3 * Height / 4
2366 // | G | Y |
2367 // +-----------+---+
2368 //
2369 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2370 EXPECT_PIXEL_COLOR_EQ(0, 3 * kHeight / 4 - 1, GLColor::red);
2371 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 - 1, 0, GLColor::red);
2372 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 - 1, 3 * kHeight / 4 - 1, GLColor::red);
2373 EXPECT_PIXEL_COLOR_EQ(kWidth / 2, kHeight / 2, GLColor::red);
2374
2375 EXPECT_PIXEL_COLOR_EQ(0, 3 * kHeight / 4 + 1, GLColor::green);
2376 EXPECT_PIXEL_COLOR_EQ(0, kHeight - 1, GLColor::green);
2377 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 - 1, 3 * kHeight / 4 + 1, GLColor::green);
2378 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 - 1, kHeight - 1, GLColor::green);
2379 EXPECT_PIXEL_COLOR_EQ(kWidth / 2, 7 * kHeight / 8, GLColor::green);
2380
2381 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 + 1, 0, GLColor::blue);
2382 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 + 1, 3 * kHeight / 4 - 1, GLColor::blue);
2383 EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 0, GLColor::blue);
2384 EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 3 * kHeight / 4 - 1, GLColor::blue);
2385 EXPECT_PIXEL_COLOR_EQ(7 * kWidth / 8, kHeight / 2, GLColor::blue);
2386
2387 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 + 1, 3 * kHeight / 4 + 1, GLColor::yellow);
2388 EXPECT_PIXEL_COLOR_EQ(3 * kWidth / 4 + 1, kHeight - 1, GLColor::yellow);
2389 EXPECT_PIXEL_COLOR_EQ(kWidth - 1, 3 * kHeight / 4 + 1, GLColor::yellow);
2390 EXPECT_PIXEL_COLOR_EQ(kWidth - 1, kHeight - 1, GLColor::yellow);
2391 EXPECT_PIXEL_COLOR_EQ(7 * kWidth / 8, 7 * kHeight / 8, GLColor::yellow);
2392 }
2393
2394 // Test blitFramebuffer size overflow checks. WebGL 2.0 spec section 5.41. We do validation for
2395 // overflows also in non-WebGL mode to avoid triggering driver bugs.
TEST_P(BlitFramebufferTest,BlitFramebufferSizeOverflow)2396 TEST_P(BlitFramebufferTest, BlitFramebufferSizeOverflow)
2397 {
2398 GLTexture textures[2];
2399 glBindTexture(GL_TEXTURE_2D, textures[0]);
2400 glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, 4, 4);
2401 glBindTexture(GL_TEXTURE_2D, textures[1]);
2402 glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, 4, 4);
2403
2404 GLFramebuffer framebuffers[2];
2405 glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffers[0]);
2406 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffers[1]);
2407
2408 ASSERT_GL_NO_ERROR();
2409
2410 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0],
2411 0);
2412 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1],
2413 0);
2414 ASSERT_GL_NO_ERROR();
2415
2416 // srcX
2417 glBlitFramebuffer(-1, 0, std::numeric_limits<GLint>::max(), 4, 0, 0, 4, 4, GL_COLOR_BUFFER_BIT,
2418 GL_NEAREST);
2419 EXPECT_GL_ERROR(GL_INVALID_VALUE);
2420 glBlitFramebuffer(std::numeric_limits<GLint>::max(), 0, -1, 4, 0, 0, 4, 4, GL_COLOR_BUFFER_BIT,
2421 GL_NEAREST);
2422 EXPECT_GL_ERROR(GL_INVALID_VALUE);
2423
2424 // srcY
2425 glBlitFramebuffer(0, -1, 4, std::numeric_limits<GLint>::max(), 0, 0, 4, 4, GL_COLOR_BUFFER_BIT,
2426 GL_NEAREST);
2427 EXPECT_GL_ERROR(GL_INVALID_VALUE);
2428 glBlitFramebuffer(0, std::numeric_limits<GLint>::max(), 4, -1, 0, 0, 4, 4, GL_COLOR_BUFFER_BIT,
2429 GL_NEAREST);
2430 EXPECT_GL_ERROR(GL_INVALID_VALUE);
2431
2432 // dstX
2433 glBlitFramebuffer(0, 0, 4, 4, -1, 0, std::numeric_limits<GLint>::max(), 4, GL_COLOR_BUFFER_BIT,
2434 GL_NEAREST);
2435 EXPECT_GL_ERROR(GL_INVALID_VALUE);
2436 glBlitFramebuffer(0, 0, 4, 4, std::numeric_limits<GLint>::max(), 0, -1, 4, GL_COLOR_BUFFER_BIT,
2437 GL_NEAREST);
2438 EXPECT_GL_ERROR(GL_INVALID_VALUE);
2439
2440 // dstY
2441 glBlitFramebuffer(0, 0, 4, 4, 0, -1, 4, std::numeric_limits<GLint>::max(), GL_COLOR_BUFFER_BIT,
2442 GL_NEAREST);
2443 EXPECT_GL_ERROR(GL_INVALID_VALUE);
2444 glBlitFramebuffer(0, 0, 4, 4, 0, std::numeric_limits<GLint>::max(), 4, -1, GL_COLOR_BUFFER_BIT,
2445 GL_NEAREST);
2446 EXPECT_GL_ERROR(GL_INVALID_VALUE);
2447 }
2448
2449 // Test blitFramebuffer size overflow checks. WebGL 2.0 spec section 5.41. Similar to above test,
2450 // but this test more accurately duplicates the behavior of the WebGL test
2451 // conformance2/rendering/blitframebuffer-size-overflow.html, which covers a few more edge cases.
TEST_P(BlitFramebufferTest,BlitFramebufferSizeOverflow2)2452 TEST_P(BlitFramebufferTest, BlitFramebufferSizeOverflow2)
2453 {
2454 GLTexture textures[2];
2455 glBindTexture(GL_TEXTURE_2D, textures[0]);
2456 glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, 4, 4);
2457 glBindTexture(GL_TEXTURE_2D, textures[1]);
2458 glTexStorage2D(GL_TEXTURE_2D, 3, GL_RGBA8, 4, 4);
2459
2460 GLFramebuffer framebuffers[2];
2461 glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffers[0]);
2462 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffers[1]);
2463
2464 ASSERT_GL_NO_ERROR();
2465
2466 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[0],
2467 0);
2468 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textures[1],
2469 0);
2470 ASSERT_GL_NO_ERROR();
2471
2472 GLint width = 8;
2473 GLint height = 8;
2474
2475 GLTexture tex0;
2476 glBindTexture(GL_TEXTURE_2D, tex0);
2477 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
2478
2479 GLFramebuffer fb0;
2480 glBindFramebuffer(GL_READ_FRAMEBUFFER, fb0);
2481 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex0, 0);
2482
2483 GLTexture tex1;
2484 glBindTexture(GL_TEXTURE_2D, tex1);
2485 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
2486
2487 GLFramebuffer fb1;
2488 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb1);
2489 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex1, 0);
2490
2491 GLint max = std::numeric_limits<GLint>::max();
2492 // Using max 32-bit integer as blitFramebuffer parameter should succeed.
2493 glBlitFramebuffer(0, 0, max, max, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2494 glBlitFramebuffer(0, 0, width, height, 0, 0, max, max, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2495 glBlitFramebuffer(0, 0, max, max, 0, 0, max, max, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2496 EXPECT_GL_NO_ERROR();
2497
2498 // Using blitFramebuffer parameters where calculated width/height matches max 32-bit integer
2499 // should succeed
2500 glBlitFramebuffer(-1, -1, max - 1, max - 1, 0, 0, width, height, GL_COLOR_BUFFER_BIT,
2501 GL_NEAREST);
2502 glBlitFramebuffer(0, 0, width, height, -1, -1, max - 1, max - 1, GL_COLOR_BUFFER_BIT,
2503 GL_NEAREST);
2504 glBlitFramebuffer(-1, -1, max - 1, max - 1, -1, -1, max - 1, max - 1, GL_COLOR_BUFFER_BIT,
2505 GL_NEAREST);
2506 EXPECT_GL_NO_ERROR();
2507
2508 // Using source width/height greater than max 32-bit integer should fail.
2509 glBlitFramebuffer(-1, -1, max, max, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2510 EXPECT_GL_ERROR(GL_INVALID_VALUE);
2511
2512 // Using source width/height greater than max 32-bit integer should fail.
2513 glBlitFramebuffer(max, max, -1, -1, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2514 EXPECT_GL_ERROR(GL_INVALID_VALUE);
2515
2516 // Using destination width/height greater than max 32-bit integer should fail.
2517 glBlitFramebuffer(0, 0, width, height, -1, -1, max, max, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2518 EXPECT_GL_ERROR(GL_INVALID_VALUE);
2519
2520 // Using destination width/height greater than max 32-bit integer should fail.
2521 glBlitFramebuffer(0, 0, width, height, max, max, -1, -1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2522 EXPECT_GL_ERROR(GL_INVALID_VALUE);
2523
2524 // Using both source and destination width/height greater than max 32-bit integer should fail.
2525 glBlitFramebuffer(-1, -1, max, max, -1, -1, max, max, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2526 EXPECT_GL_ERROR(GL_INVALID_VALUE);
2527
2528 // Using minimum and maximum integers for all boundaries should fail.
2529 glBlitFramebuffer(-max - 1, -max - 1, max, max, -max - 1, -max - 1, max, max,
2530 GL_COLOR_BUFFER_BIT, GL_NEAREST);
2531 EXPECT_GL_ERROR(GL_INVALID_VALUE);
2532 }
2533
2534 // Test an edge case in D3D11 stencil blitting on the CPU that does not properly clip the
2535 // destination regions
TEST_P(BlitFramebufferTest,BlitFramebufferStencilClipNoIntersection)2536 TEST_P(BlitFramebufferTest, BlitFramebufferStencilClipNoIntersection)
2537 {
2538 GLFramebuffer framebuffers[2];
2539 glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffers[0]);
2540 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffers[1]);
2541
2542 GLRenderbuffer renderbuffers[2];
2543 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffers[0]);
2544 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 4, 4);
2545 glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2546 renderbuffers[0]);
2547
2548 glBindRenderbuffer(GL_RENDERBUFFER, renderbuffers[1]);
2549 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 4, 4);
2550 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2551 renderbuffers[1]);
2552
2553 glBlitFramebuffer(0, 0, 4, 4, 1 << 24, 1 << 24, 1 << 25, 1 << 25, GL_STENCIL_BUFFER_BIT,
2554 GL_NEAREST);
2555 EXPECT_GL_NO_ERROR();
2556 }
2557
2558 // Covers an edge case with blitting borderline values.
TEST_P(BlitFramebufferTest,OOBWrite)2559 TEST_P(BlitFramebufferTest, OOBWrite)
2560 {
2561 constexpr size_t length = 0x100000;
2562 GLFramebuffer rfb;
2563 GLFramebuffer dfb;
2564 GLRenderbuffer rb1;
2565 GLRenderbuffer rb2;
2566 glBindFramebuffer(GL_READ_FRAMEBUFFER, rfb);
2567 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dfb);
2568 glBindRenderbuffer(GL_RENDERBUFFER, rb1);
2569 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 0x1000, 2);
2570 glBindRenderbuffer(GL_RENDERBUFFER, rb2);
2571 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 2, 2);
2572 glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2573 rb1);
2574 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2575 rb2);
2576 glBlitFramebuffer(1, 0, 0, 1, 1, 0, (2147483648 / 2) - (length / 4) + 1, 1,
2577 GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
2578 ASSERT_GL_NO_ERROR();
2579 }
2580
2581 // Test blitting a depthStencil buffer with multiple depth values to a larger size.
TEST_P(BlitFramebufferTest,BlitDepthStencilPixelByPixel)2582 TEST_P(BlitFramebufferTest, BlitDepthStencilPixelByPixel)
2583 {
2584 ANGLE_GL_PROGRAM(drawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
2585
2586 glViewport(0, 0, 128, 1);
2587 glEnable(GL_DEPTH_TEST);
2588
2589 GLFramebuffer srcFramebuffer;
2590 GLRenderbuffer srcRenderbuffer;
2591 glBindFramebuffer(GL_FRAMEBUFFER, srcFramebuffer);
2592 glBindRenderbuffer(GL_RENDERBUFFER, srcRenderbuffer);
2593 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 128, 1);
2594 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2595 srcRenderbuffer);
2596 glClearDepthf(1.0f);
2597 glClear(GL_DEPTH_BUFFER_BIT);
2598
2599 drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.0f, 0.5f);
2600 glViewport(0, 0, 256, 2);
2601
2602 GLFramebuffer dstFramebuffer;
2603 GLRenderbuffer dstRenderbuffer;
2604 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dstFramebuffer);
2605 glBindRenderbuffer(GL_RENDERBUFFER, dstRenderbuffer);
2606 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 256, 2);
2607 glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2608 dstRenderbuffer);
2609
2610 GLTexture dstColor;
2611 glBindTexture(GL_TEXTURE_2D, dstColor);
2612 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 2);
2613 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, dstColor, 0);
2614
2615 glBindFramebuffer(GL_READ_FRAMEBUFFER, srcFramebuffer);
2616 glBlitFramebuffer(0, 0, 128, 1, 0, 0, 256, 2, GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
2617 GL_NEAREST);
2618
2619 glBindFramebuffer(GL_FRAMEBUFFER, dstFramebuffer);
2620 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
2621 glClear(GL_COLOR_BUFFER_BIT);
2622 glDepthMask(false);
2623 glDepthFunc(GL_LESS);
2624 drawQuad(drawRed, essl1_shaders::PositionAttrib(), -0.01f, 0.5f);
2625 EXPECT_PIXEL_RECT_EQ(64, 0, 128, 1, GLColor::red);
2626
2627 ANGLE_GL_PROGRAM(drawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());
2628 glEnable(GL_DEPTH_TEST);
2629 glDepthMask(false);
2630 glDepthFunc(GL_GREATER);
2631 drawQuad(drawBlue, essl1_shaders::PositionAttrib(), 0.01f, 0.5f);
2632 EXPECT_PIXEL_RECT_EQ(64, 0, 128, 1, GLColor::blue);
2633 }
2634
2635 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
2636 // tests should be run against.
2637 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BlitFramebufferANGLETest);
2638 ANGLE_INSTANTIATE_TEST(BlitFramebufferANGLETest,
2639 ES2_D3D9(),
2640 ES2_D3D11(),
2641 ES2_D3D11_PRESENT_PATH_FAST(),
2642 ES2_OPENGL(),
2643 ES3_OPENGL(),
2644 ES2_VULKAN(),
2645 ES3_VULKAN(),
2646 WithEmulatedPrerotation(ES3_VULKAN(), 90),
2647 WithEmulatedPrerotation(ES3_VULKAN(), 180),
2648 WithEmulatedPrerotation(ES3_VULKAN(), 270),
2649 ES2_METAL(),
2650 WithNoShaderStencilOutput(ES2_METAL()));
2651
2652 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BlitFramebufferTest);
2653 ANGLE_INSTANTIATE_TEST_ES3_AND(BlitFramebufferTest, WithNoShaderStencilOutput(ES3_METAL()));
2654