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 
9 #include "test_utils/gl_raii.h"
10 
11 using namespace angle;
12 
13 class BlitFramebufferANGLETest : public ANGLETest
14 {
15   protected:
BlitFramebufferANGLETest()16     BlitFramebufferANGLETest()
17     {
18         setWindowWidth(256);
19         setWindowHeight(256);
20         setConfigRedBits(8);
21         setConfigGreenBits(8);
22         setConfigBlueBits(8);
23         setConfigAlphaBits(8);
24         setConfigDepthBits(24);
25         setConfigStencilBits(8);
26 
27         mCheckerProgram = 0;
28         mBlueProgram = 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 
56         mBGRAMultisampledRenderbuffer = 0;
57         mBGRAMultisampledFBO = 0;
58     }
59 
SetUp()60     virtual void SetUp()
61     {
62         ANGLETest::SetUp();
63 
64         const std::string passthroughVS = SHADER_SOURCE
65         (
66             precision highp float;
67             attribute vec4 position;
68             varying vec4 pos;
69 
70             void main()
71             {
72                 gl_Position = position;
73                 pos = position;
74             }
75         );
76 
77         const std::string checkeredFS = SHADER_SOURCE
78         (
79             precision highp float;
80             varying vec4 pos;
81 
82             void main()
83             {
84                 if (pos.x * pos.y > 0.0)
85                 {
86                     gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
87                 }
88                 else
89                 {
90                     gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
91                 }
92             }
93         );
94 
95         const std::string blueFS = SHADER_SOURCE
96         (
97             precision highp float;
98             varying vec4 pos;
99 
100             void main()
101             {
102                 gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
103             }
104         );
105 
106         mCheckerProgram = CompileProgram(passthroughVS, checkeredFS);
107         mBlueProgram = CompileProgram(passthroughVS, blueFS);
108         if (mCheckerProgram == 0 || mBlueProgram == 0)
109         {
110             FAIL() << "shader compilation failed.";
111         }
112 
113         EXPECT_GL_NO_ERROR();
114 
115         GLint originalFBO;
116         glGetIntegerv(GL_FRAMEBUFFER_BINDING, &originalFBO);
117         if (originalFBO >= 0)
118         {
119             mOriginalFBO = (GLuint)originalFBO;
120         }
121 
122         GLenum format = GL_BGRA8_EXT;
123 
124         glGenFramebuffers(1, &mUserFBO);
125         glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
126         glGenTextures(1, &mUserColorBuffer);
127         glGenRenderbuffers(1, &mUserDepthStencilBuffer);
128         glBindTexture(GL_TEXTURE_2D, mUserColorBuffer);
129         glTexStorage2DEXT(GL_TEXTURE_2D, 1, format, getWindowWidth(), getWindowHeight());
130         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mUserColorBuffer, 0);
131         glBindRenderbuffer(GL_RENDERBUFFER, mUserDepthStencilBuffer);
132         glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, getWindowWidth(), getWindowHeight());
133         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mUserDepthStencilBuffer);
134         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mUserDepthStencilBuffer);
135 
136         ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
137         ASSERT_GL_NO_ERROR();
138 
139         glGenFramebuffers(1, &mSmallFBO);
140         glBindFramebuffer(GL_FRAMEBUFFER, mSmallFBO);
141         glGenTextures(1, &mSmallColorBuffer);
142         glGenRenderbuffers(1, &mSmallDepthStencilBuffer);
143         glBindTexture(GL_TEXTURE_2D, mSmallColorBuffer);
144         glTexStorage2DEXT(GL_TEXTURE_2D, 1, format, getWindowWidth() / 2, getWindowHeight() / 2);
145         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mSmallColorBuffer, 0);
146         glBindRenderbuffer(GL_RENDERBUFFER, mSmallDepthStencilBuffer);
147         glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, getWindowWidth() / 2, getWindowHeight() / 2);
148         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mSmallDepthStencilBuffer);
149         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mSmallDepthStencilBuffer);
150 
151         ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
152         ASSERT_GL_NO_ERROR();
153 
154         glGenFramebuffers(1, &mColorOnlyFBO);
155         glBindFramebuffer(GL_FRAMEBUFFER, mColorOnlyFBO);
156         glGenTextures(1, &mColorOnlyColorBuffer);
157         glBindTexture(GL_TEXTURE_2D, mColorOnlyColorBuffer);
158         glTexStorage2DEXT(GL_TEXTURE_2D, 1, format, getWindowWidth(), getWindowHeight());
159         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mColorOnlyColorBuffer, 0);
160 
161         ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
162         ASSERT_GL_NO_ERROR();
163 
164         glGenFramebuffers(1, &mDiffFormatFBO);
165         glBindFramebuffer(GL_FRAMEBUFFER, mDiffFormatFBO);
166         glGenTextures(1, &mDiffFormatColorBuffer);
167         glBindTexture(GL_TEXTURE_2D, mDiffFormatColorBuffer);
168         glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGB565, getWindowWidth(), getWindowHeight());
169         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mDiffFormatColorBuffer, 0);
170 
171         ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
172         ASSERT_GL_NO_ERROR();
173 
174         glGenFramebuffers(1, &mDiffSizeFBO);
175         glBindFramebuffer(GL_FRAMEBUFFER, mDiffSizeFBO);
176         glGenTextures(1, &mDiffSizeColorBuffer);
177         glBindTexture(GL_TEXTURE_2D, mDiffSizeColorBuffer);
178         glTexStorage2DEXT(GL_TEXTURE_2D, 1, format, getWindowWidth()*2, getWindowHeight()*2);
179         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mDiffSizeColorBuffer, 0);
180 
181         ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
182         ASSERT_GL_NO_ERROR();
183 
184         if (extensionEnabled("GL_EXT_draw_buffers"))
185         {
186             glGenFramebuffers(1, &mMRTFBO);
187             glBindFramebuffer(GL_FRAMEBUFFER, mMRTFBO);
188             glGenTextures(1, &mMRTColorBuffer0);
189             glGenTextures(1, &mMRTColorBuffer1);
190             glBindTexture(GL_TEXTURE_2D, mMRTColorBuffer0);
191             glTexStorage2DEXT(GL_TEXTURE_2D, 1, format, getWindowWidth(), getWindowHeight());
192             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, mMRTColorBuffer0, 0);
193             glBindTexture(GL_TEXTURE_2D, mMRTColorBuffer1);
194             glTexStorage2DEXT(GL_TEXTURE_2D, 1, format, getWindowWidth(), getWindowHeight());
195             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, mMRTColorBuffer1, 0);
196 
197             ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
198             ASSERT_GL_NO_ERROR();
199         }
200 
201         if (extensionEnabled("GL_ANGLE_framebuffer_multisample"))
202         {
203             // Test blit between RGBA and multisampled BGRA
204             glGenTextures(1, &mRGBAColorbuffer);
205             glBindTexture(GL_TEXTURE_2D, mRGBAColorbuffer);
206             glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8_OES, getWindowWidth(), getWindowHeight());
207 
208             glGenFramebuffers(1, &mRGBAFBO);
209             glBindFramebuffer(GL_FRAMEBUFFER, mRGBAFBO);
210             glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mRGBAColorbuffer, 0);
211 
212             ASSERT_GL_NO_ERROR();
213             ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
214 
215             glGenRenderbuffers(1, &mBGRAMultisampledRenderbuffer);
216             glBindRenderbuffer(GL_RENDERBUFFER, mBGRAMultisampledRenderbuffer);
217             glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 1, GL_BGRA8_EXT, getWindowWidth(), getWindowHeight());
218 
219             glGenFramebuffers(1, &mBGRAMultisampledFBO);
220             glBindFramebuffer(GL_FRAMEBUFFER, mBGRAMultisampledFBO);
221             glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mBGRAMultisampledRenderbuffer);
222 
223             ASSERT_GL_NO_ERROR();
224             ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
225         }
226 
227         glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
228     }
229 
TearDown()230     virtual void TearDown()
231     {
232         glDeleteProgram(mCheckerProgram);
233         glDeleteProgram(mBlueProgram);
234 
235         glDeleteFramebuffers(1, &mUserFBO);
236         glDeleteTextures(1, &mUserColorBuffer);
237         glDeleteRenderbuffers(1, &mUserDepthStencilBuffer);
238 
239         glDeleteFramebuffers(1, &mSmallFBO);
240         glDeleteTextures(1, &mSmallColorBuffer);
241         glDeleteRenderbuffers(1, &mSmallDepthStencilBuffer);
242 
243         glDeleteFramebuffers(1, &mColorOnlyFBO);
244         glDeleteTextures(1, &mSmallDepthStencilBuffer);
245 
246         glDeleteFramebuffers(1, &mDiffFormatFBO);
247         glDeleteTextures(1, &mDiffFormatColorBuffer);
248 
249         glDeleteFramebuffers(1, &mDiffSizeFBO);
250         glDeleteTextures(1, &mDiffSizeColorBuffer);
251 
252         if (extensionEnabled("GL_EXT_draw_buffers"))
253         {
254             glDeleteFramebuffers(1, &mMRTFBO);
255             glDeleteTextures(1, &mMRTColorBuffer0);
256             glDeleteTextures(1, &mMRTColorBuffer1);
257         }
258 
259         if (mRGBAColorbuffer != 0)
260         {
261             glDeleteTextures(1, &mRGBAColorbuffer);
262         }
263 
264         if (mRGBAFBO != 0)
265         {
266             glDeleteFramebuffers(1, &mBGRAMultisampledFBO);
267         }
268 
269         if (mBGRAMultisampledRenderbuffer != 0)
270         {
271             glDeleteRenderbuffers(1, &mBGRAMultisampledRenderbuffer);
272         }
273 
274         if (mBGRAMultisampledFBO != 0)
275         {
276             glDeleteFramebuffers(1, &mBGRAMultisampledFBO);
277         }
278 
279         ANGLETest::TearDown();
280     }
281 
282     GLuint mCheckerProgram;
283     GLuint mBlueProgram;
284 
285     GLuint mOriginalFBO;
286 
287     GLuint mUserFBO;
288     GLuint mUserColorBuffer;
289     GLuint mUserDepthStencilBuffer;
290 
291     GLuint mSmallFBO;
292     GLuint mSmallColorBuffer;
293     GLuint mSmallDepthStencilBuffer;
294 
295     GLuint mColorOnlyFBO;
296     GLuint mColorOnlyColorBuffer;
297 
298     GLuint mDiffFormatFBO;
299     GLuint mDiffFormatColorBuffer;
300 
301     GLuint mDiffSizeFBO;
302     GLuint mDiffSizeColorBuffer;
303 
304     GLuint mMRTFBO;
305     GLuint mMRTColorBuffer0;
306     GLuint mMRTColorBuffer1;
307 
308     GLuint mRGBAColorbuffer;
309     GLuint mRGBAFBO;
310 
311     GLuint mBGRAMultisampledRenderbuffer;
312     GLuint mBGRAMultisampledFBO;
313 };
314 
315 // Draw to user-created framebuffer, blit whole-buffer color to original framebuffer.
TEST_P(BlitFramebufferANGLETest,BlitColorToDefault)316 TEST_P(BlitFramebufferANGLETest, BlitColorToDefault)
317 {
318     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
319 
320     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
321 
322     drawQuad(mCheckerProgram, "position", 0.8f);
323 
324     EXPECT_GL_NO_ERROR();
325 
326     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
327     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
328 
329     glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
330                            GL_COLOR_BUFFER_BIT, GL_NEAREST);
331 
332     EXPECT_GL_NO_ERROR();
333 
334     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
335 
336     EXPECT_PIXEL_EQ(    getWindowWidth() / 4,     getWindowHeight() / 4, 255,   0,   0, 255);
337     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4,     getWindowHeight() / 4,   0, 255,   0, 255);
338     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255,   0,   0, 255);
339     EXPECT_PIXEL_EQ(    getWindowWidth() / 4, 3 * getWindowHeight() / 4,   0, 255,   0, 255);
340 }
341 
342 // Draw to system framebuffer, blit whole-buffer color to user-created framebuffer.
TEST_P(BlitFramebufferANGLETest,ReverseColorBlit)343 TEST_P(BlitFramebufferANGLETest, ReverseColorBlit)
344 {
345     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
346 
347     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
348 
349     drawQuad(mCheckerProgram, "position", 0.8f);
350 
351     EXPECT_GL_NO_ERROR();
352 
353     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO);
354     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO);
355 
356     glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
357                            GL_COLOR_BUFFER_BIT, GL_NEAREST);
358 
359     EXPECT_GL_NO_ERROR();
360 
361     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
362 
363     EXPECT_PIXEL_EQ(    getWindowWidth() / 4,     getWindowHeight() / 4, 255,   0,   0, 255);
364     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4,     getWindowHeight() / 4,   0, 255,   0, 255);
365     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255,   0,   0, 255);
366     EXPECT_PIXEL_EQ(    getWindowWidth() / 4, 3 * getWindowHeight() / 4,   0, 255,   0, 255);
367 }
368 
369 // blit from user-created FBO to system framebuffer, with the scissor test enabled.
TEST_P(BlitFramebufferANGLETest,ScissoredBlit)370 TEST_P(BlitFramebufferANGLETest, ScissoredBlit)
371 {
372     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
373 
374     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
375 
376     drawQuad(mCheckerProgram, "position", 0.8f);
377 
378     EXPECT_GL_NO_ERROR();
379 
380     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
381     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
382 
383     glClearColor(1.0, 1.0, 1.0, 1.0);
384     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
385 
386     glScissor(getWindowWidth() / 2, 0, getWindowWidth() / 2, getWindowHeight());
387     glEnable(GL_SCISSOR_TEST);
388 
389     glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
390                            GL_COLOR_BUFFER_BIT, GL_NEAREST);
391 
392     EXPECT_GL_NO_ERROR();
393 
394     glDisable(GL_SCISSOR_TEST);
395 
396     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
397 
398     EXPECT_PIXEL_EQ(    getWindowWidth() / 4,     getWindowHeight() / 4, 255, 255, 255, 255);
399     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4,     getWindowHeight() / 4,   0, 255,   0, 255);
400     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255,   0,   0, 255);
401     EXPECT_PIXEL_EQ(    getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 255, 255, 255);
402 }
403 
404 // blit from system FBO to user-created framebuffer, with the scissor test enabled.
TEST_P(BlitFramebufferANGLETest,ReverseScissoredBlit)405 TEST_P(BlitFramebufferANGLETest, ReverseScissoredBlit)
406 {
407     // TODO(jmadill): Triage this driver bug.
408     if (IsAMD() && IsD3D11())
409     {
410         std::cout << "Test skipped on AMD D3D11." << std::endl;
411         return;
412     }
413 
414     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
415 
416     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
417 
418     drawQuad(mCheckerProgram, "position", 0.8f);
419 
420     EXPECT_GL_NO_ERROR();
421 
422     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO);
423     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO);
424 
425     glClearColor(1.0, 1.0, 1.0, 1.0);
426     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
427 
428     glScissor(getWindowWidth() / 2, 0, getWindowWidth() / 2, getWindowHeight());
429     glEnable(GL_SCISSOR_TEST);
430 
431     glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
432                            GL_COLOR_BUFFER_BIT, GL_NEAREST);
433 
434     EXPECT_GL_NO_ERROR();
435 
436     glDisable(GL_SCISSOR_TEST);
437 
438     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
439 
440     EXPECT_PIXEL_EQ(    getWindowWidth() / 4,     getWindowHeight() / 4, 255, 255, 255, 255);
441     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4,     getWindowHeight() / 4,   0, 255,   0, 255);
442     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255,   0,   0, 255);
443     EXPECT_PIXEL_EQ(    getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 255, 255, 255);
444 }
445 
446 // blit from user-created FBO to system framebuffer, using region larger than buffer.
TEST_P(BlitFramebufferANGLETest,OversizedBlit)447 TEST_P(BlitFramebufferANGLETest, OversizedBlit)
448 {
449     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
450 
451     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
452 
453     drawQuad(mCheckerProgram, "position", 0.8f);
454 
455     EXPECT_GL_NO_ERROR();
456 
457     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
458     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
459 
460     glClearColor(1.0, 1.0, 1.0, 1.0);
461     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
462 
463     glBlitFramebufferANGLE(0, 0, getWindowWidth() * 2, getWindowHeight() * 2, 0, 0, getWindowWidth() * 2, getWindowHeight() * 2,
464                            GL_COLOR_BUFFER_BIT, GL_NEAREST);
465 
466     EXPECT_GL_NO_ERROR();
467 
468     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
469 
470     EXPECT_PIXEL_EQ(    getWindowWidth() / 4,     getWindowHeight() / 4, 255,   0,   0, 255);
471     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4,     getWindowHeight() / 4,   0, 255,   0, 255);
472     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255,   0,   0, 255);
473     EXPECT_PIXEL_EQ(    getWindowWidth() / 4, 3 * getWindowHeight() / 4,   0, 255,   0, 255);
474 }
475 
476 // blit from system FBO to user-created framebuffer, using region larger than buffer.
TEST_P(BlitFramebufferANGLETest,ReverseOversizedBlit)477 TEST_P(BlitFramebufferANGLETest, ReverseOversizedBlit)
478 {
479     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
480 
481     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
482 
483     drawQuad(mCheckerProgram, "position", 0.8f);
484 
485     EXPECT_GL_NO_ERROR();
486 
487     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO);
488     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO);
489 
490     glClearColor(1.0, 1.0, 1.0, 1.0);
491     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
492 
493     glBlitFramebufferANGLE(0, 0, getWindowWidth() * 2, getWindowHeight() * 2, 0, 0, getWindowWidth() * 2, getWindowHeight() * 2,
494                            GL_COLOR_BUFFER_BIT, GL_NEAREST);
495     EXPECT_GL_NO_ERROR();
496 
497     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
498 
499     EXPECT_PIXEL_EQ(    getWindowWidth() / 4,     getWindowHeight() / 4, 255,   0,   0, 255);
500     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4,     getWindowHeight() / 4,   0, 255,   0, 255);
501     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255,   0,   0, 255);
502     EXPECT_PIXEL_EQ(    getWindowWidth() / 4, 3 * getWindowHeight() / 4,   0, 255,   0, 255);
503 }
504 
505 // blit from user-created FBO to system framebuffer, with depth buffer.
TEST_P(BlitFramebufferANGLETest,BlitWithDepth)506 TEST_P(BlitFramebufferANGLETest, BlitWithDepth)
507 {
508     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
509 
510     glDepthMask(GL_TRUE);
511     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
512 
513     glEnable(GL_DEPTH_TEST);
514 
515     drawQuad(mCheckerProgram, "position", 0.3f);
516 
517     EXPECT_GL_NO_ERROR();
518 
519     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
520     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
521 
522     glClearColor(1.0, 1.0, 1.0, 1.0);
523     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
524 
525     glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
526                            GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
527     EXPECT_GL_NO_ERROR();
528 
529     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
530 
531     // if blit is happening correctly, this quad will not draw, because it is behind the blitted one
532     drawQuad(mBlueProgram, "position", 0.8f);
533 
534     glDisable(GL_DEPTH_TEST);
535 
536     EXPECT_PIXEL_EQ(    getWindowWidth() / 4,     getWindowHeight() / 4, 255,   0,   0, 255);
537     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4,     getWindowHeight() / 4,   0, 255,   0, 255);
538     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255,   0,   0, 255);
539     EXPECT_PIXEL_EQ(    getWindowWidth() / 4, 3 * getWindowHeight() / 4,   0, 255,   0, 255);
540 }
541 
542 // blit from system FBO to user-created framebuffer, with depth buffer.
TEST_P(BlitFramebufferANGLETest,ReverseBlitWithDepth)543 TEST_P(BlitFramebufferANGLETest, ReverseBlitWithDepth)
544 {
545     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
546 
547     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
548 
549     glEnable(GL_DEPTH_TEST);
550 
551     drawQuad(mCheckerProgram, "position", 0.3f);
552 
553     EXPECT_GL_NO_ERROR();
554 
555     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mUserFBO);
556     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mOriginalFBO);
557 
558     glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
559     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
560 
561     glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
562                            GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
563     EXPECT_GL_NO_ERROR();
564 
565     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
566 
567     // if blit is happening correctly, this quad will not draw, because it is behind the blitted one
568 
569     drawQuad(mBlueProgram, "position", 0.8f);
570 
571     glDisable(GL_DEPTH_TEST);
572 
573     EXPECT_PIXEL_EQ(    getWindowWidth() / 4,     getWindowHeight() / 4, 255,   0,   0, 255);
574     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4,     getWindowHeight() / 4,   0, 255,   0, 255);
575     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255,   0,   0, 255);
576     EXPECT_PIXEL_EQ(    getWindowWidth() / 4, 3 * getWindowHeight() / 4,   0, 255,   0, 255);
577 }
578 
579 // blit from one region of the system fbo to another-- this should fail.
TEST_P(BlitFramebufferANGLETest,BlitSameBufferOriginal)580 TEST_P(BlitFramebufferANGLETest, BlitSameBufferOriginal)
581 {
582     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
583 
584     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
585 
586     drawQuad(mCheckerProgram, "position", 0.3f);
587 
588     EXPECT_GL_NO_ERROR();
589 
590     glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight(), getWindowWidth() / 2, 0, getWindowWidth(), getWindowHeight(),
591                            GL_COLOR_BUFFER_BIT, GL_NEAREST);
592     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
593 }
594 
595 // blit from one region of the system fbo to another.
TEST_P(BlitFramebufferANGLETest,BlitSameBufferUser)596 TEST_P(BlitFramebufferANGLETest, BlitSameBufferUser)
597 {
598     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
599 
600     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
601 
602     drawQuad(mCheckerProgram, "position", 0.3f);
603 
604     EXPECT_GL_NO_ERROR();
605 
606     glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight(), getWindowWidth() / 2, 0, getWindowWidth(), getWindowHeight(),
607                            GL_COLOR_BUFFER_BIT, GL_NEAREST);
608     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
609 }
610 
TEST_P(BlitFramebufferANGLETest,BlitPartialColor)611 TEST_P(BlitFramebufferANGLETest, BlitPartialColor)
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, "position", 0.5f);
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, getWindowHeight() / 2, getWindowWidth() / 2, getWindowHeight(),
628                            GL_COLOR_BUFFER_BIT, GL_NEAREST);
629 
630     EXPECT_GL_NO_ERROR();
631 
632     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
633 
634     EXPECT_PIXEL_EQ(    getWindowWidth() / 4,     getWindowHeight() / 4, 255, 255, 255, 255);
635     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4,     getWindowHeight() / 4, 255, 255, 255, 255);
636     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255, 255, 255, 255);
637     EXPECT_PIXEL_EQ(    getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255,   0,   0, 255);
638 }
639 
TEST_P(BlitFramebufferANGLETest,BlitDifferentSizes)640 TEST_P(BlitFramebufferANGLETest, BlitDifferentSizes)
641 {
642     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
643 
644     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
645 
646     drawQuad(mCheckerProgram, "position", 0.5f);
647 
648     EXPECT_GL_NO_ERROR();
649 
650     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mSmallFBO);
651     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
652 
653     glClearColor(1.0, 1.0, 1.0, 1.0);
654     glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
655 
656     glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
657                            GL_COLOR_BUFFER_BIT, GL_NEAREST);
658 
659     EXPECT_GL_NO_ERROR();
660 
661     glBindFramebuffer(GL_FRAMEBUFFER, mSmallFBO);
662 
663     EXPECT_PIXEL_EQ(    getWindowWidth() / 4,     getWindowHeight() / 4, 255,   0,   0, 255);
664 
665     EXPECT_GL_NO_ERROR();
666 }
667 
TEST_P(BlitFramebufferANGLETest,BlitWithMissingAttachments)668 TEST_P(BlitFramebufferANGLETest, BlitWithMissingAttachments)
669 {
670     glBindFramebuffer(GL_FRAMEBUFFER, mColorOnlyFBO);
671 
672     glClear(GL_COLOR_BUFFER_BIT);
673     drawQuad(mCheckerProgram, "position", 0.3f);
674 
675     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
676     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mColorOnlyFBO);
677 
678     glClearColor(1.0, 1.0, 1.0, 1.0);
679     glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
680 
681     // depth blit request should be silently ignored, because the read FBO has no depth attachment
682     glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
683                            GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
684 
685     EXPECT_GL_NO_ERROR();
686 
687     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
688 
689     EXPECT_PIXEL_EQ(    getWindowWidth() / 4,     getWindowHeight() / 4, 255,   0,   0, 255);
690     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4,     getWindowHeight() / 4,   0, 255,   0, 255);
691     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255,   0,   0, 255);
692     EXPECT_PIXEL_EQ(    getWindowWidth() / 4, 3 * getWindowHeight() / 4,   0, 255,   0, 255);
693 
694     // unlike in the depth blit tests, this *should* draw a blue quad, because depth info
695     // has not been copied
696     glEnable(GL_DEPTH_TEST);
697     drawQuad(mBlueProgram, "position", 0.8f);
698     glDisable(GL_DEPTH_TEST);
699 
700     EXPECT_PIXEL_EQ(    getWindowWidth() / 4,     getWindowHeight() / 4,   0,   0, 255, 255);
701     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4,     getWindowHeight() / 4,   0,   0, 255, 255);
702     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4,   0,   0, 255, 255);
703     EXPECT_PIXEL_EQ(    getWindowWidth() / 4, 3 * getWindowHeight() / 4,   0,   0, 255, 255);
704 }
705 
TEST_P(BlitFramebufferANGLETest,BlitStencil)706 TEST_P(BlitFramebufferANGLETest, BlitStencil)
707 {
708     // TODO(jmadill): Figure out if we can fix this on D3D9.
709     // https://code.google.com/p/angleproject/issues/detail?id=809
710     if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE)
711     {
712         std::cout << "Test skipped on Intel D3D9." << std::endl;
713         return;
714     }
715 
716     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
717 
718     glClear(GL_COLOR_BUFFER_BIT);
719     // fill the stencil buffer with 0x1
720     glStencilFunc(GL_ALWAYS, 0x1, 0xFF);
721     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
722     glEnable(GL_STENCIL_TEST);
723     drawQuad(mCheckerProgram, "position", 0.3f);
724 
725     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
726     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
727 
728     glClearColor(1.0, 1.0, 1.0, 1.0);
729     glClearStencil(0x0);
730     glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
731 
732     // depth blit request should be silently ignored, because the read FBO has no depth attachment
733     glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
734                            GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
735 
736     EXPECT_GL_NO_ERROR();
737 
738     glBindFramebuffer(GL_FRAMEBUFFER, mOriginalFBO);
739 
740     EXPECT_PIXEL_EQ(    getWindowWidth() / 4,     getWindowHeight() / 4, 255,   0,   0, 255);
741     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4,     getWindowHeight() / 4,   0, 255,   0, 255);
742     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255,   0,   0, 255);
743     EXPECT_PIXEL_EQ(    getWindowWidth() / 4, 3 * getWindowHeight() / 4,   0, 255,   0, 255);
744 
745     glStencilFunc(GL_EQUAL, 0x1, 0xFF); // only pass if stencil buffer at pixel reads 0x1
746     drawQuad(mBlueProgram, "position", 0.8f); // blue quad will draw if stencil buffer was copied
747     glDisable(GL_STENCIL_TEST);
748 
749     EXPECT_PIXEL_EQ(    getWindowWidth() / 4,     getWindowHeight() / 4,   0,   0, 255, 255);
750     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4,     getWindowHeight() / 4,   0,   0, 255, 255);
751     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4,   0,   0, 255, 255);
752     EXPECT_PIXEL_EQ(    getWindowWidth() / 4, 3 * getWindowHeight() / 4,   0,   0, 255, 255);
753 }
754 
755 // make sure that attempting to blit a partial depth buffer issues an error
TEST_P(BlitFramebufferANGLETest,BlitPartialDepthStencil)756 TEST_P(BlitFramebufferANGLETest, BlitPartialDepthStencil)
757 {
758     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
759 
760     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
761 
762     drawQuad(mCheckerProgram, "position", 0.5f);
763 
764     EXPECT_GL_NO_ERROR();
765 
766     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
767     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
768 
769     glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, 0, 0,
770                            getWindowWidth() / 2, getWindowHeight() / 2, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
771     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
772 }
773 
774 // Test blit with MRT framebuffers
TEST_P(BlitFramebufferANGLETest,BlitMRT)775 TEST_P(BlitFramebufferANGLETest, BlitMRT)
776 {
777     if (!extensionEnabled("GL_EXT_draw_buffers"))
778     {
779         return;
780     }
781 
782     GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT };
783 
784     glBindFramebuffer(GL_FRAMEBUFFER, mMRTFBO);
785     glDrawBuffersEXT(2, drawBuffers);
786 
787     glBindFramebuffer(GL_FRAMEBUFFER, mColorOnlyFBO);
788 
789     glClear(GL_COLOR_BUFFER_BIT);
790 
791     drawQuad(mCheckerProgram, "position", 0.8f);
792 
793     EXPECT_GL_NO_ERROR();
794 
795     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mColorOnlyFBO);
796     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mMRTFBO);
797 
798     glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
799                            GL_COLOR_BUFFER_BIT, GL_NEAREST);
800 
801     EXPECT_GL_NO_ERROR();
802 
803     glBindFramebuffer(GL_FRAMEBUFFER, mMRTFBO);
804 
805     EXPECT_PIXEL_EQ(    getWindowWidth() / 4,     getWindowHeight() / 4, 255,   0,   0, 255);
806     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4,     getWindowHeight() / 4,   0, 255,   0, 255);
807     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255,   0,   0, 255);
808     EXPECT_PIXEL_EQ(    getWindowWidth() / 4, 3 * getWindowHeight() / 4,   0, 255,   0, 255);
809 
810     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, 0, 0);
811     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mMRTColorBuffer0, 0);
812 
813     EXPECT_PIXEL_EQ(    getWindowWidth() / 4,     getWindowHeight() / 4, 255,   0,   0, 255);
814     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4,     getWindowHeight() / 4,   0, 255,   0, 255);
815     EXPECT_PIXEL_EQ(3 * getWindowWidth() / 4, 3 * getWindowHeight() / 4, 255,   0,   0, 255);
816     EXPECT_PIXEL_EQ(    getWindowWidth() / 4, 3 * getWindowHeight() / 4,   0, 255,   0, 255);
817 
818     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mMRTColorBuffer0, 0);
819     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, mMRTColorBuffer1, 0);
820 }
821 
822 // Make sure that attempts to stretch in a blit call issue an error
TEST_P(BlitFramebufferANGLETest,ErrorStretching)823 TEST_P(BlitFramebufferANGLETest, ErrorStretching)
824 {
825     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
826 
827     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
828 
829     drawQuad(mCheckerProgram, "position", 0.5f);
830 
831     EXPECT_GL_NO_ERROR();
832 
833     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
834     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
835 
836     glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, 0, 0,
837                            getWindowWidth(), getWindowHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
838     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
839 }
840 
841 // Make sure that attempts to flip in a blit call issue an error
TEST_P(BlitFramebufferANGLETest,ErrorFlipping)842 TEST_P(BlitFramebufferANGLETest, ErrorFlipping)
843 {
844     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
845 
846     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
847 
848     drawQuad(mCheckerProgram, "position", 0.5f);
849 
850     EXPECT_GL_NO_ERROR();
851 
852     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
853     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
854 
855     glBlitFramebufferANGLE(0, 0, getWindowWidth() / 2, getWindowHeight() / 2, getWindowWidth() / 2, getWindowHeight() / 2,
856                            0, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
857     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
858 }
859 
TEST_P(BlitFramebufferANGLETest,Errors)860 TEST_P(BlitFramebufferANGLETest, Errors)
861 {
862     glBindFramebuffer(GL_FRAMEBUFFER, mUserFBO);
863 
864     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
865 
866     drawQuad(mCheckerProgram, "position", 0.5f);
867 
868     EXPECT_GL_NO_ERROR();
869 
870     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mOriginalFBO);
871     glBindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, mUserFBO);
872 
873     glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
874                            GL_COLOR_BUFFER_BIT, GL_LINEAR);
875     EXPECT_GL_ERROR(GL_INVALID_ENUM);
876 
877     glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
878                            GL_COLOR_BUFFER_BIT | 234, GL_NEAREST);
879     EXPECT_GL_ERROR(GL_INVALID_VALUE);
880 
881     glBindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, mDiffFormatFBO);
882 
883     glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
884                            GL_COLOR_BUFFER_BIT, GL_NEAREST);
885     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
886 
887     if (extensionEnabled("GL_ANGLE_framebuffer_multisample"))
888     {
889         glBindFramebuffer(GL_READ_FRAMEBUFFER, mBGRAMultisampledFBO);
890         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mRGBAFBO);
891         EXPECT_GL_NO_ERROR();
892 
893         glBlitFramebufferANGLE(0, 0, getWindowWidth(), getWindowHeight(), 0, 0, getWindowWidth(), getWindowHeight(),
894                                GL_COLOR_BUFFER_BIT, GL_NEAREST);
895         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
896     }
897 
898 }
899 
900 // TODO(geofflang): Fix the dependence on glBlitFramebufferANGLE without checks and assuming the
901 // default framebuffer is BGRA to enable the GL and GLES backends. (http://anglebug.com/1289)
902 
903 class BlitFramebufferTest : public ANGLETest
904 {
905   protected:
BlitFramebufferTest()906     BlitFramebufferTest()
907     {
908         setWindowWidth(256);
909         setWindowHeight(256);
910         setConfigRedBits(8);
911         setConfigGreenBits(8);
912         setConfigBlueBits(8);
913         setConfigAlphaBits(8);
914         setConfigDepthBits(24);
915         setConfigStencilBits(8);
916     }
917 };
918 
919 // Tests resolving a multisample depth buffer.
TEST_P(BlitFramebufferTest,MultisampleDepth)920 TEST_P(BlitFramebufferTest, MultisampleDepth)
921 {
922     // TODO(jmadill): Triage this driver bug.
923     if (IsAMD() && IsD3D11())
924     {
925         std::cout << "Test skipped on AMD D3D11." << std::endl;
926         return;
927     }
928 
929     GLRenderbuffer renderbuf;
930     glBindRenderbuffer(GL_RENDERBUFFER, renderbuf.get());
931     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_DEPTH_COMPONENT24, 256, 256);
932 
933     const std::string &vertex =
934         "#version 300 es\n"
935         "in vec2 position;\n"
936         "void main() {\n"
937         "  gl_Position = vec4(position, 0.0, 0.5);\n"
938         "}";
939     const std::string &fragment =
940         "#version 300 es\n"
941         "out mediump vec4 red;\n"
942         "void main() {\n"
943         "   red = vec4(1.0, 0.0, 0.0, 1.0);\n"
944         "   gl_FragDepth = 0.5;\n"
945         "}";
946 
947     ANGLE_GL_PROGRAM(drawRed, vertex, fragment);
948 
949     GLFramebuffer framebuffer;
950     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
951     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
952                               renderbuf.get());
953 
954     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
955 
956     glClearDepthf(0.5f);
957     glClear(GL_DEPTH_BUFFER_BIT);
958 
959     GLRenderbuffer destRenderbuf;
960     glBindRenderbuffer(GL_RENDERBUFFER, destRenderbuf.get());
961     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 256, 256);
962 
963     GLFramebuffer resolved;
964     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolved.get());
965     glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
966                               destRenderbuf.get());
967 
968     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer.get());
969     glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
970 
971     glBindFramebuffer(GL_FRAMEBUFFER, resolved.get());
972 
973     GLTexture colorbuf;
974     glBindTexture(GL_TEXTURE_2D, colorbuf.get());
975     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);
976     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorbuf.get(), 0);
977 
978     ASSERT_GL_NO_ERROR();
979 
980     // Clear to green
981     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
982     glClear(GL_COLOR_BUFFER_BIT);
983     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
984 
985     // Draw with 0.5f test and the test should pass.
986     glEnable(GL_DEPTH_TEST);
987     glDepthFunc(GL_EQUAL);
988     drawQuad(drawRed.get(), "position", 0.5f);
989     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
990 
991     ASSERT_GL_NO_ERROR();
992 }
993 
994 // Test resolving a multisampled stencil buffer.
TEST_P(BlitFramebufferTest,MultisampleStencil)995 TEST_P(BlitFramebufferTest, MultisampleStencil)
996 {
997     GLRenderbuffer renderbuf;
998     glBindRenderbuffer(GL_RENDERBUFFER, renderbuf.get());
999     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_STENCIL_INDEX8, 256, 256);
1000 
1001     const std::string &vertex =
1002         "#version 300 es\n"
1003         "in vec2 position;\n"
1004         "void main() {\n"
1005         "  gl_Position = vec4(position, 0.0, 1.0);\n"
1006         "}";
1007     const std::string &fragment =
1008         "#version 300 es\n"
1009         "out mediump vec4 red;\n"
1010         "void main() {\n"
1011         "   red = vec4(1.0, 0.0, 0.0, 1.0);\n"
1012         "}";
1013 
1014     ANGLE_GL_PROGRAM(drawRed, vertex, fragment);
1015 
1016     GLFramebuffer framebuffer;
1017     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer.get());
1018     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
1019                               renderbuf.get());
1020 
1021     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1022 
1023     // fill the stencil buffer with 0x1
1024     glStencilFunc(GL_ALWAYS, 0x1, 0xFF);
1025     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
1026     glEnable(GL_STENCIL_TEST);
1027     drawQuad(drawRed.get(), "position", 0.5f);
1028 
1029     GLTexture destColorbuf;
1030     glBindTexture(GL_TEXTURE_2D, destColorbuf.get());
1031     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 256, 256);
1032 
1033     GLRenderbuffer destRenderbuf;
1034     glBindRenderbuffer(GL_RENDERBUFFER, destRenderbuf.get());
1035     glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, 256, 256);
1036 
1037     GLFramebuffer resolved;
1038     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolved.get());
1039     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
1040                            destColorbuf.get(), 0);
1041     glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
1042                               destRenderbuf.get());
1043 
1044     glBindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer.get());
1045     glBlitFramebuffer(0, 0, 256, 256, 0, 0, 256, 256, GL_STENCIL_BUFFER_BIT, GL_NEAREST);
1046 
1047     glBindFramebuffer(GL_FRAMEBUFFER, resolved.get());
1048 
1049     ASSERT_GL_NO_ERROR();
1050 
1051     // Clear to green
1052     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
1053     glClear(GL_COLOR_BUFFER_BIT);
1054     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1055 
1056     // Draw red if the stencil is 0x1, which should be true after the blit/resolve.
1057     glStencilFunc(GL_EQUAL, 0x1, 0xFF);
1058     drawQuad(drawRed.get(), "position", 0.5f);
1059     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1060 
1061     ASSERT_GL_NO_ERROR();
1062 }
1063 
1064 // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
1065 ANGLE_INSTANTIATE_TEST(BlitFramebufferANGLETest,
1066                        ES2_D3D9(),
1067                        ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE),
1068                        ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE));
1069 
1070 ANGLE_INSTANTIATE_TEST(BlitFramebufferTest, ES3_D3D11());