• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2019 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 // MultisampledRenderToTextureTest: Tests of EXT_multisampled_render_to_texture extension
8 
9 #include "test_utils/ANGLETest.h"
10 #include "test_utils/gl_raii.h"
11 
12 using namespace angle;
13 
14 namespace
15 {
16 class MultisampledRenderToTextureTest : public ANGLETest
17 {
18   protected:
MultisampledRenderToTextureTest()19     MultisampledRenderToTextureTest()
20     {
21         setWindowWidth(64);
22         setWindowHeight(64);
23         setConfigRedBits(8);
24         setConfigGreenBits(8);
25         setConfigBlueBits(8);
26         setConfigAlphaBits(8);
27     }
28 
testSetUp()29     void testSetUp() override
30     {
31         if (getClientMajorVersion() >= 3 && getClientMinorVersion() >= 1)
32         {
33             glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &mMaxIntegerSamples);
34         }
35     }
36 
testTearDown()37     void testTearDown() override {}
38 
assertErrorIfNotMSRTT2(GLenum error)39     void assertErrorIfNotMSRTT2(GLenum error)
40     {
41         if (EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture2"))
42         {
43             ASSERT_GL_NO_ERROR();
44         }
45         else
46         {
47             ASSERT_GL_ERROR(error);
48         }
49     }
50 
setupCopyTexProgram()51     void setupCopyTexProgram()
52     {
53         mCopyTextureProgram.makeRaster(essl1_shaders::vs::Texture2D(),
54                                        essl1_shaders::fs::Texture2D());
55         ASSERT_GL_TRUE(mCopyTextureProgram.valid());
56 
57         mCopyTextureUniformLocation =
58             glGetUniformLocation(mCopyTextureProgram, essl1_shaders::Texture2DUniform());
59 
60         ASSERT_GL_NO_ERROR();
61     }
62 
setupUniformColorProgramMultiRenderTarget(const bool bufferEnabled[8],GLuint * programOut)63     void setupUniformColorProgramMultiRenderTarget(const bool bufferEnabled[8], GLuint *programOut)
64     {
65         std::stringstream fs;
66 
67         fs << "#extension GL_EXT_draw_buffers : enable\n"
68               "precision highp float;\n"
69               "uniform mediump vec4 "
70            << essl1_shaders::ColorUniform()
71            << ";\n"
72               "void main()\n"
73               "{\n";
74 
75         for (unsigned int index = 0; index < 8; index++)
76         {
77             if (bufferEnabled[index])
78             {
79                 fs << "    gl_FragData[" << index << "] = " << essl1_shaders::ColorUniform()
80                    << ";\n";
81             }
82         }
83 
84         fs << "}\n";
85 
86         *programOut = CompileProgram(essl1_shaders::vs::Simple(), fs.str().c_str());
87         ASSERT_NE(*programOut, 0u);
88     }
89 
verifyResults(GLuint texture,const GLColor expected,GLint fboSize,GLint xs,GLint ys,GLint xe,GLint ye)90     void verifyResults(GLuint texture,
91                        const GLColor expected,
92                        GLint fboSize,
93                        GLint xs,
94                        GLint ys,
95                        GLint xe,
96                        GLint ye)
97     {
98         glViewport(0, 0, fboSize, fboSize);
99 
100         glBindFramebuffer(GL_FRAMEBUFFER, 0);
101 
102         // Draw a quad with the target texture
103         glUseProgram(mCopyTextureProgram);
104         glBindTexture(GL_TEXTURE_2D, texture);
105         glUniform1i(mCopyTextureUniformLocation, 0);
106 
107         glDisable(GL_DEPTH_TEST);
108         glDisable(GL_STENCIL_TEST);
109         glDisable(GL_BLEND);
110         glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
111         drawQuad(mCopyTextureProgram, essl1_shaders::PositionAttrib(), 0.5f);
112 
113         // Expect that the rendered quad has the same color as the source texture
114         EXPECT_PIXEL_COLOR_NEAR(xs, ys, expected, 1.0);
115         EXPECT_PIXEL_COLOR_NEAR(xs, ye - 1, expected, 1.0);
116         EXPECT_PIXEL_COLOR_NEAR(xe - 1, ys, expected, 1.0);
117         EXPECT_PIXEL_COLOR_NEAR(xe - 1, ye - 1, expected, 1.0);
118         EXPECT_PIXEL_COLOR_NEAR((xs + xe) / 2, (ys + ye) / 2, expected, 1.0);
119     }
120 
clearAndDrawQuad(GLuint program,GLsizei viewportWidth,GLsizei viewportHeight)121     void clearAndDrawQuad(GLuint program, GLsizei viewportWidth, GLsizei viewportHeight)
122     {
123         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
124         glClear(GL_COLOR_BUFFER_BIT);
125         glViewport(0, 0, viewportWidth, viewportHeight);
126         ASSERT_GL_NO_ERROR();
127 
128         drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
129         ASSERT_GL_NO_ERROR();
130     }
131 
132     struct GLType
133     {
134         GLenum internalFormat;
135         GLenum format;
136         GLenum type;
137     };
138 
139     void createAndAttachColorAttachment(bool useRenderbuffer,
140                                         GLsizei size,
141                                         GLenum renderbufferTarget,
142                                         const GLType *glType,
143                                         GLint samples,
144                                         GLTexture *textureOut,
145                                         GLRenderbuffer *renderbufferOut);
146     void createAndAttachDepthStencilAttachment(bool useRenderbuffer,
147                                                GLsizei size,
148                                                GLTexture *textureOut,
149                                                GLRenderbuffer *renderbufferOut);
150     void colorAttachmentMultisampleDrawTestCommon(bool useRenderbuffer);
151     void copyTexImageTestCommon(bool useRenderbuffer);
152     void copyTexSubImageTestCommon(bool useRenderbuffer);
153     void drawCopyThenBlendCommon(bool useRenderbuffer);
154     void clearDrawCopyThenBlendSameProgramCommon(bool useRenderbuffer);
155     void drawCopyDrawThenMaskedClearCommon(bool useRenderbuffer);
156     void clearThenBlendCommon(bool useRenderbuffer);
157 
158     GLProgram mCopyTextureProgram;
159     GLint mCopyTextureUniformLocation = -1;
160 
161     const GLint mTestSampleCount = 4;
162     GLint mMaxIntegerSamples     = 0;
163 };
164 
165 class MultisampledRenderToTextureES3Test : public MultisampledRenderToTextureTest
166 {
167   protected:
168     void readPixelsTestCommon(bool useRenderbuffer);
169     void blitFramebufferTestCommon(bool useRenderbuffer);
170     void drawCopyDrawAttachInvalidatedThenDrawCommon(bool useRenderbuffer);
171     void drawCopyDrawAttachDepthStencilClearThenDrawCommon(bool useRenderbuffer);
172     void depthStencilClearThenDrawCommon(bool useRenderbuffer);
173     void colorAttachment1Common(bool useRenderbuffer);
174     void colorAttachments0And3Common(bool useRenderbuffer);
175     void blitFramebufferMixedColorAndDepthCommon(bool useRenderbuffer);
176     void renderbufferUnresolveColorAndDepthStencilThenTwoColors(bool withDepth, bool withStencil);
177 };
178 
179 class MultisampledRenderToTextureES31Test : public MultisampledRenderToTextureTest
180 {
181   protected:
182     void blitFramebufferAttachment1Common(bool useRenderbuffer);
183     void drawCopyThenBlendAllAttachmentsMixed(bool useRenderbuffer);
184 };
185 
186 // Checking against invalid parameters for RenderbufferStorageMultisampleEXT.
TEST_P(MultisampledRenderToTextureTest,RenderbufferParameterCheck)187 TEST_P(MultisampledRenderToTextureTest, RenderbufferParameterCheck)
188 {
189     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
190 
191     // Linux Intel Vulkan returns 0 for GL_MAX_INTEGER_SAMPLES http://anglebug.com/5988
192     ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsVulkan());
193 
194     GLRenderbuffer renderbuffer;
195     glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
196 
197     // Positive test case.  Formats required by the spec (GLES2.0 Table 4.5)
198     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_DEPTH_COMPONENT16, 64, 64);
199     ASSERT_GL_NO_ERROR();
200     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_STENCIL_INDEX8, 64, 64);
201     ASSERT_GL_NO_ERROR();
202     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_RGBA4, 64, 64);
203     ASSERT_GL_NO_ERROR();
204     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_RGB5_A1, 64, 64);
205     ASSERT_GL_NO_ERROR();
206     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_RGB565, 64, 64);
207     ASSERT_GL_NO_ERROR();
208 
209     // Positive test case.  A few of the ES3 formats
210     if (getClientMajorVersion() >= 3)
211     {
212         glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, 64, 64);
213         ASSERT_GL_NO_ERROR();
214         glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_RGBA8, 64, 64);
215         ASSERT_GL_NO_ERROR();
216 
217         if (getClientMinorVersion() >= 1)
218         {
219             glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, mMaxIntegerSamples, GL_RGBA32I, 64,
220                                                 64);
221             ASSERT_GL_NO_ERROR();
222             glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, mMaxIntegerSamples, GL_RGBA32UI,
223                                                 64, 64);
224             ASSERT_GL_NO_ERROR();
225         }
226     }
227 
228     GLint samples;
229     glGetIntegerv(GL_MAX_SAMPLES_EXT, &samples);
230     ASSERT_GL_NO_ERROR();
231     EXPECT_GE(samples, 1);
232 
233     // Samples too large
234     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples + 1, GL_DEPTH_COMPONENT16, 64, 64);
235     ASSERT_GL_ERROR(GL_INVALID_VALUE);
236 
237     // Renderbuffer size too large
238     GLint maxSize;
239     glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE, &maxSize);
240     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 2, GL_RGBA4, maxSize + 1, maxSize);
241     ASSERT_GL_ERROR(GL_INVALID_VALUE);
242     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 2, GL_DEPTH_COMPONENT16, maxSize,
243                                         maxSize + 1);
244     ASSERT_GL_ERROR(GL_INVALID_VALUE);
245 
246     // Retrieving samples
247     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_DEPTH_COMPONENT16, 64, 64);
248     GLint param = 0;
249     glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES_EXT, &param);
250     // GE because samples may vary base on implementation. Spec says "the resulting value for
251     // RENDERBUFFER_SAMPLES_EXT is guaranteed to be greater than or equal to samples and no more
252     // than the next larger sample count supported by the implementation"
253     EXPECT_GE(param, 4);
254 }
255 
256 // Checking against invalid parameters for FramebufferTexture2DMultisampleEXT.
TEST_P(MultisampledRenderToTextureTest,Texture2DParameterCheck)257 TEST_P(MultisampledRenderToTextureTest, Texture2DParameterCheck)
258 {
259     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
260     bool isES3 = getClientMajorVersion() >= 3;
261 
262     GLTexture texture;
263     glBindTexture(GL_TEXTURE_2D, texture);
264     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
265     ASSERT_GL_NO_ERROR();
266 
267     GLTexture depthTexture;
268     if (isES3)
269     {
270         glBindTexture(GL_TEXTURE_2D, depthTexture);
271         glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 64, 64, 0, GL_DEPTH_STENCIL,
272                      GL_UNSIGNED_INT_24_8_OES, nullptr);
273     }
274 
275     GLFramebuffer fbo;
276     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
277     // Positive test case
278     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
279                                          texture, 0, 4);
280     ASSERT_GL_NO_ERROR();
281     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
282 
283     if (EnsureGLExtensionEnabled("GL_EXT_draw_buffers") || isES3)
284     {
285         // Attachment not COLOR_ATTACHMENT0.  Allowed only in EXT_multisampled_render_to_texture2
286         glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D,
287                                              texture, 0, 4);
288         assertErrorIfNotMSRTT2(GL_INVALID_ENUM);
289     }
290 
291     // Depth/stencil attachment.  Allowed only in EXT_multisampled_render_to_texture2
292     if (isES3)
293     {
294         glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
295                                              depthTexture, 0, 4);
296         assertErrorIfNotMSRTT2(GL_INVALID_ENUM);
297 
298         glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
299                                              depthTexture, 0, 4);
300         assertErrorIfNotMSRTT2(GL_INVALID_ENUM);
301 
302         glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
303                                              GL_TEXTURE_2D, depthTexture, 0, 4);
304         assertErrorIfNotMSRTT2(GL_INVALID_ENUM);
305 
306         glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D,
307                                              depthTexture, 0, 4);
308         assertErrorIfNotMSRTT2(GL_INVALID_ENUM);
309     }
310 
311     // Target not framebuffer
312     glFramebufferTexture2DMultisampleEXT(GL_RENDERBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
313                                          texture, 0, 4);
314     ASSERT_GL_ERROR(GL_INVALID_ENUM);
315 
316     GLint samples;
317     glGetIntegerv(GL_MAX_SAMPLES_EXT, &samples);
318     ASSERT_GL_NO_ERROR();
319     EXPECT_GE(samples, 1);
320 
321     // Samples too large
322     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
323                                          texture, 0, samples + 1);
324     ASSERT_GL_ERROR(GL_INVALID_VALUE);
325 
326     // Retrieving samples
327     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
328                                          texture, 0, 4);
329     GLint param = 0;
330     glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
331                                           GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT, &param);
332     // GE because samples may vary base on implementation. Spec says "the resulting value for
333     // TEXTURE_SAMPLES_EXT is guaranteed to be greater than or equal to samples and no more than the
334     // next larger sample count supported by the implementation"
335     EXPECT_GE(param, 4);
336 }
337 
338 // Checking against invalid parameters for FramebufferTexture2DMultisampleEXT (cubemap).
TEST_P(MultisampledRenderToTextureTest,TextureCubeMapParameterCheck)339 TEST_P(MultisampledRenderToTextureTest, TextureCubeMapParameterCheck)
340 {
341     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
342     bool isES3 = getClientMajorVersion() >= 3;
343 
344     GLTexture texture;
345     glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
346     for (GLenum face = 0; face < 6; face++)
347     {
348         glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, 64, 64, 0, GL_RGBA,
349                      GL_UNSIGNED_BYTE, nullptr);
350         ASSERT_GL_NO_ERROR();
351     }
352 
353     GLint samples;
354     glGetIntegerv(GL_MAX_SAMPLES_EXT, &samples);
355     ASSERT_GL_NO_ERROR();
356     EXPECT_GE(samples, 1);
357 
358     GLFramebuffer FBO;
359     glBindFramebuffer(GL_FRAMEBUFFER, FBO);
360     for (GLenum face = 0; face < 6; face++)
361     {
362         // Positive test case
363         glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
364                                              GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, texture, 0, 4);
365         ASSERT_GL_NO_ERROR();
366         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
367 
368         if (EnsureGLExtensionEnabled("GL_EXT_draw_buffers") || isES3)
369         {
370             // Attachment not COLOR_ATTACHMENT0.  Allowed only in
371             // EXT_multisampled_render_to_texture2
372             glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,
373                                                  GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, texture, 0,
374                                                  4);
375             assertErrorIfNotMSRTT2(GL_INVALID_ENUM);
376         }
377 
378         // Target not framebuffer
379         glFramebufferTexture2DMultisampleEXT(GL_RENDERBUFFER, GL_COLOR_ATTACHMENT0,
380                                              GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, texture, 0, 4);
381         ASSERT_GL_ERROR(GL_INVALID_ENUM);
382 
383         // Samples too large
384         glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
385                                              GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, texture, 0,
386                                              samples + 1);
387         ASSERT_GL_ERROR(GL_INVALID_VALUE);
388 
389         // Retrieving samples
390         glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
391                                              GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, texture, 0, 4);
392         GLint param = 0;
393         glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
394                                               GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT,
395                                               &param);
396         // GE because samples may vary base on implementation. Spec says "the resulting value for
397         // TEXTURE_SAMPLES_EXT is guaranteed to be greater than or equal to samples and no more than
398         // the next larger sample count supported by the implementation"
399         EXPECT_GE(param, 4);
400     }
401 }
402 
403 // Checking for framebuffer completeness using extension methods.
TEST_P(MultisampledRenderToTextureTest,FramebufferCompleteness)404 TEST_P(MultisampledRenderToTextureTest, FramebufferCompleteness)
405 {
406     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
407 
408     // Checking that Renderbuffer and texture2d having different number of samples results
409     // in a FRAMEBUFFER_INCOMPLETE_MULTISAMPLE
410     GLTexture texture;
411     glBindTexture(GL_TEXTURE_2D, texture);
412     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
413     ASSERT_GL_NO_ERROR();
414 
415     // Texture attachment for color attachment 0.  Framebuffer should be complete.
416     GLFramebuffer FBO;
417     glBindFramebuffer(GL_FRAMEBUFFER, FBO);
418     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
419                                          texture, 0, 4);
420     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
421 
422     GLsizei maxSamples = 0;
423     glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
424 
425     // Depth/stencil renderbuffer, potentially with a different sample count.
426     GLRenderbuffer dsRenderbuffer;
427     glBindRenderbuffer(GL_RENDERBUFFER, dsRenderbuffer);
428     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, maxSamples, GL_DEPTH_COMPONENT16, 64, 64);
429     ASSERT_GL_NO_ERROR();
430     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, dsRenderbuffer);
431 
432     if (maxSamples > 4)
433     {
434         EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
435                          glCheckFramebufferStatus(GL_FRAMEBUFFER));
436     }
437     else
438     {
439         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
440     }
441 
442     // Color renderbuffer for color attachment 0.
443     GLRenderbuffer colorRenderbuffer;
444     glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
445     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, maxSamples, GL_RGBA4, 64, 64);
446     ASSERT_GL_NO_ERROR();
447     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
448                               colorRenderbuffer);
449     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
450 
451     // D3D backend doesn't implement multisampled render to texture renderbuffers correctly.
452     // http://anglebug.com/3107
453     ANGLE_SKIP_TEST_IF(IsD3D());
454 
455     if (getClientMajorVersion() >= 3)
456     {
457         // Texture attachment for color attachment 1.
458         GLTexture texture2;
459         glBindTexture(GL_TEXTURE_2D, texture2);
460         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
461         ASSERT_GL_NO_ERROR();
462 
463         // Attach with a potentially different number of samples.
464         glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D,
465                                              texture, 0, 4);
466 
467         if (maxSamples > 4)
468         {
469             EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE,
470                              glCheckFramebufferStatus(GL_FRAMEBUFFER));
471         }
472         else
473         {
474             EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
475         }
476 
477         // Attach with same number of samples.
478         glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D,
479                                              texture, 0, maxSamples);
480         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
481     }
482 }
483 
484 // Checking for framebuffer completeness using extension methods.
TEST_P(MultisampledRenderToTextureTest,FramebufferCompletenessSmallSampleCount)485 TEST_P(MultisampledRenderToTextureTest, FramebufferCompletenessSmallSampleCount)
486 {
487     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
488 
489     // A sample count of '2' can be rounded up to '4' on some systems (e.g., ARM+Android).
490     GLsizei samples = 2;
491 
492     // Checking that Renderbuffer and texture2d having different number of samples results
493     // in a FRAMEBUFFER_INCOMPLETE_MULTISAMPLE
494     GLTexture texture;
495     glBindTexture(GL_TEXTURE_2D, texture);
496     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
497     ASSERT_GL_NO_ERROR();
498 
499     // Texture attachment for color attachment 0.  Framebuffer should be complete.
500     GLFramebuffer FBO;
501     glBindFramebuffer(GL_FRAMEBUFFER, FBO);
502     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
503                                          texture, 0, samples);
504     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
505 
506     // Depth/stencil renderbuffer, potentially with a different sample count.
507     GLRenderbuffer dsRenderbuffer;
508     glBindRenderbuffer(GL_RENDERBUFFER, dsRenderbuffer);
509     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, GL_DEPTH_COMPONENT16, 64, 64);
510     ASSERT_GL_NO_ERROR();
511     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, dsRenderbuffer);
512     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
513 
514     // Color renderbuffer for color attachment 0.
515     GLRenderbuffer colorRenderbuffer;
516     glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
517     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, GL_RGBA4, 64, 64);
518     ASSERT_GL_NO_ERROR();
519     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
520                               colorRenderbuffer);
521     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
522 }
523 
524 // Test mixing unsized and sized formats with multisampling. Regression test for
525 // http://crbug.com/1238327
TEST_P(MultisampledRenderToTextureTest,UnsizedTextureFormatSampleMissmatch)526 TEST_P(MultisampledRenderToTextureTest, UnsizedTextureFormatSampleMissmatch)
527 {
528     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
529     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_texture_rg"));
530 
531     // Test failure introduced by Apple's changes (anglebug.com/5505)
532     ANGLE_SKIP_TEST_IF(IsMetal() && IsAMD());
533 
534     GLsizei samples = 0;
535     glGetIntegerv(GL_MAX_SAMPLES, &samples);
536 
537     GLTexture texture;
538     glBindTexture(GL_TEXTURE_2D, texture);
539     glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 64, 64, 0, GL_RED, GL_UNSIGNED_BYTE, nullptr);
540     ASSERT_GL_NO_ERROR();
541 
542     // Texture attachment for color attachment 0.  Framebuffer should be complete.
543     GLFramebuffer FBO;
544     glBindFramebuffer(GL_FRAMEBUFFER, FBO);
545     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
546                                          texture, 0, samples);
547     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
548 
549     // Depth/stencil renderbuffer, potentially with a different sample count.
550     GLRenderbuffer dsRenderbuffer;
551     glBindRenderbuffer(GL_RENDERBUFFER, dsRenderbuffer);
552     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, GL_STENCIL_INDEX8, 64, 64);
553     ASSERT_GL_NO_ERROR();
554     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
555                               dsRenderbuffer);
556     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
557 }
558 
createAndAttachColorAttachment(bool useRenderbuffer,GLsizei size,GLenum renderbufferTarget,const GLType * glType,GLint samples,GLTexture * textureOut,GLRenderbuffer * renderbufferOut)559 void MultisampledRenderToTextureTest::createAndAttachColorAttachment(
560     bool useRenderbuffer,
561     GLsizei size,
562     GLenum renderbufferTarget,
563     const GLType *glType,
564     GLint samples,
565     GLTexture *textureOut,
566     GLRenderbuffer *renderbufferOut)
567 {
568     GLenum internalFormat = glType ? glType->internalFormat : GL_RGBA;
569     GLenum format         = glType ? glType->format : GL_RGBA;
570     GLenum type           = glType ? glType->type : GL_UNSIGNED_BYTE;
571 
572     if (useRenderbuffer)
573     {
574         if (internalFormat == GL_RGBA)
575         {
576             internalFormat = GL_RGBA8;
577         }
578         glBindRenderbuffer(GL_RENDERBUFFER, *renderbufferOut);
579         glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples, internalFormat, size, size);
580         glFramebufferRenderbuffer(GL_FRAMEBUFFER, renderbufferTarget, GL_RENDERBUFFER,
581                                   *renderbufferOut);
582     }
583     else
584     {
585         glBindTexture(GL_TEXTURE_2D, *textureOut);
586         glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, size, size, 0, format, type, nullptr);
587         glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, renderbufferTarget, GL_TEXTURE_2D,
588                                              *textureOut, 0, samples);
589     }
590     ASSERT_GL_NO_ERROR();
591 }
592 
createAndAttachDepthStencilAttachment(bool useRenderbuffer,GLsizei size,GLTexture * textureOut,GLRenderbuffer * renderbufferOut)593 void MultisampledRenderToTextureTest::createAndAttachDepthStencilAttachment(
594     bool useRenderbuffer,
595     GLsizei size,
596     GLTexture *textureOut,
597     GLRenderbuffer *renderbufferOut)
598 {
599     if (useRenderbuffer)
600     {
601         glBindRenderbuffer(GL_RENDERBUFFER, *renderbufferOut);
602         glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, mTestSampleCount, GL_DEPTH24_STENCIL8,
603                                             size, size);
604         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
605                                   *renderbufferOut);
606     }
607     else
608     {
609         glBindTexture(GL_TEXTURE_2D, *textureOut);
610         glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, size, size, 0, GL_DEPTH_STENCIL,
611                      GL_UNSIGNED_INT_24_8_OES, nullptr);
612         glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
613                                              GL_TEXTURE_2D, *textureOut, 0, mTestSampleCount);
614     }
615     ASSERT_GL_NO_ERROR();
616 }
617 
colorAttachmentMultisampleDrawTestCommon(bool useRenderbuffer)618 void MultisampledRenderToTextureTest::colorAttachmentMultisampleDrawTestCommon(bool useRenderbuffer)
619 {
620     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
621 
622     GLFramebuffer FBO;
623     glBindFramebuffer(GL_FRAMEBUFFER, FBO);
624 
625     // Set up color attachment and bind to FBO
626     constexpr GLsizei kSize = 6;
627     GLTexture texture;
628     GLRenderbuffer renderbuffer;
629     createAndAttachColorAttachment(useRenderbuffer, kSize, GL_COLOR_ATTACHMENT0, nullptr,
630                                    mTestSampleCount, &texture, &renderbuffer);
631     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
632 
633     // Set viewport and clear to black
634     glViewport(0, 0, kSize, kSize);
635     glClearColor(0.0, 0.0, 0.0, 1.0);
636     glClear(GL_COLOR_BUFFER_BIT);
637 
638     // Set up Green square program
639     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
640     glUseProgram(program);
641     GLint positionLocation = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
642     ASSERT_NE(-1, positionLocation);
643 
644     setupQuadVertexBuffer(0.5f, 0.5f);
645     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
646     glEnableVertexAttribArray(positionLocation);
647 
648     // Draw green square
649     glDrawArrays(GL_TRIANGLES, 0, 6);
650     ASSERT_GL_NO_ERROR();
651 
652     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
653     EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::green);
654 
655     // Set up Red square program
656     ANGLE_GL_PROGRAM(program2, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
657     glUseProgram(program2);
658     GLint positionLocation2 = glGetAttribLocation(program2, essl1_shaders::PositionAttrib());
659     ASSERT_NE(-1, positionLocation2);
660 
661     setupQuadVertexBuffer(0.5f, 0.75f);
662     glVertexAttribPointer(positionLocation2, 3, GL_FLOAT, GL_FALSE, 0, 0);
663 
664     // Draw red square
665     glDrawArrays(GL_TRIANGLES, 0, 6);
666     ASSERT_GL_NO_ERROR();
667 
668     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
669     EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::red);
670 
671     glDisableVertexAttribArray(0);
672     glBindBuffer(GL_ARRAY_BUFFER, 0);
673 }
674 
675 // Draw test with color attachment only.
676 TEST_P(MultisampledRenderToTextureTest, 2DColorAttachmentMultisampleDrawTest)
677 {
678     colorAttachmentMultisampleDrawTestCommon(false);
679 }
680 
681 // Draw test with renderbuffer color attachment only
TEST_P(MultisampledRenderToTextureTest,RenderbufferColorAttachmentMultisampleDrawTest)682 TEST_P(MultisampledRenderToTextureTest, RenderbufferColorAttachmentMultisampleDrawTest)
683 {
684     colorAttachmentMultisampleDrawTestCommon(true);
685 }
686 
687 // Test draw with a scissored region.
TEST_P(MultisampledRenderToTextureTest,ScissoredDrawTest)688 TEST_P(MultisampledRenderToTextureTest, ScissoredDrawTest)
689 {
690     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
691 
692     GLFramebuffer FBO;
693     glBindFramebuffer(GL_FRAMEBUFFER, FBO);
694 
695     // Set up color attachment and bind to FBO
696     constexpr GLsizei kSize = 1024;
697     GLTexture texture;
698     GLRenderbuffer renderbuffer;
699     createAndAttachColorAttachment(false, kSize, GL_COLOR_ATTACHMENT0, nullptr, mTestSampleCount,
700                                    &texture, &renderbuffer);
701     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
702 
703     // Set viewport and clear to black
704     glViewport(0, 0, kSize, kSize);
705     glClearColor(0.0, 0.0, 0.0, 1.0);
706     glClear(GL_COLOR_BUFFER_BIT);
707 
708     // Set up Green square program
709     ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
710     glUseProgram(drawGreen);
711 
712     // Draw green square
713     drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.0f);
714     ASSERT_GL_NO_ERROR();
715 
716     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
717     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::green);
718     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::green);
719     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::green);
720     EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::green);
721 
722     // Set up Red square program
723     ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
724     glUseProgram(drawRed);
725 
726     // Draw a scissored red square
727 
728     constexpr GLint kScissorStartX = 1;
729     constexpr GLint kScissorStartY = 103;
730     constexpr GLint kScissorEndX   = 285;
731     constexpr GLint kScissorEndY   = 402;
732 
733     glEnable(GL_SCISSOR_TEST);
734     glScissor(kScissorStartX, kScissorStartY, kScissorEndX - kScissorStartX + 1,
735               kScissorEndY - kScissorStartY + 1);
736     drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.0f);
737     ASSERT_GL_NO_ERROR();
738 
739     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
740     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::green);
741     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::green);
742     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::green);
743     EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::green);
744 
745     EXPECT_PIXEL_COLOR_EQ(kScissorStartX, kScissorStartY, GLColor::red);
746     EXPECT_PIXEL_COLOR_EQ(kScissorEndX, kScissorStartY, GLColor::red);
747     EXPECT_PIXEL_COLOR_EQ(kScissorStartX, kScissorEndY, GLColor::red);
748     EXPECT_PIXEL_COLOR_EQ(kScissorEndX, kScissorEndY, GLColor::red);
749 
750     EXPECT_PIXEL_COLOR_EQ(kScissorStartX - 1, kScissorStartY, GLColor::green);
751     EXPECT_PIXEL_COLOR_EQ(kScissorStartX, kScissorStartY - 1, GLColor::green);
752     EXPECT_PIXEL_COLOR_EQ(kScissorEndX + 1, kScissorStartY, GLColor::green);
753     EXPECT_PIXEL_COLOR_EQ(kScissorEndX, kScissorStartY - 1, GLColor::green);
754     EXPECT_PIXEL_COLOR_EQ(kScissorStartX - 1, kScissorEndY, GLColor::green);
755     EXPECT_PIXEL_COLOR_EQ(kScissorStartX, kScissorEndY + 1, GLColor::green);
756     EXPECT_PIXEL_COLOR_EQ(kScissorEndX + 1, kScissorEndY, GLColor::green);
757     EXPECT_PIXEL_COLOR_EQ(kScissorEndX, kScissorEndY + 1, GLColor::green);
758 }
759 
760 // Test transform feedback with state change.  In the Vulkan backend, this results in an implicit
761 // break of the render pass, and must work correctly with respect to the subpass index that's used.
TEST_P(MultisampledRenderToTextureES3Test,TransformFeedbackTest)762 TEST_P(MultisampledRenderToTextureES3Test, TransformFeedbackTest)
763 {
764     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
765 
766     GLFramebuffer FBO;
767     glBindFramebuffer(GL_FRAMEBUFFER, FBO);
768 
769     // Set up color attachment and bind to FBO
770     constexpr GLsizei kSize = 1024;
771     GLTexture texture;
772     GLRenderbuffer renderbuffer;
773     createAndAttachColorAttachment(false, kSize, GL_COLOR_ATTACHMENT0, nullptr, mTestSampleCount,
774                                    &texture, &renderbuffer);
775     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
776 
777     // Set up transform feedback.
778     GLTransformFeedback xfb;
779     glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, xfb);
780 
781     constexpr size_t kXfbBufferSize = 1024;  // arbitrary number
782     GLBuffer xfbBuffer;
783     glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfbBuffer);
784     glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, kXfbBufferSize, nullptr, GL_STATIC_DRAW);
785     glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfbBuffer);
786 
787     // Set up program with transform feedback
788     std::vector<std::string> tfVaryings = {"gl_Position"};
789     ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(drawColor, essl1_shaders::vs::Simple(),
790                                         essl1_shaders::fs::UniformColor(), tfVaryings,
791                                         GL_INTERLEAVED_ATTRIBS);
792     glUseProgram(drawColor);
793     GLint colorUniformLocation =
794         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
795     ASSERT_NE(colorUniformLocation, -1);
796 
797     // Start transform feedback
798     glBeginTransformFeedback(GL_TRIANGLES);
799 
800     // Set viewport and clear to black
801     glViewport(0, 0, kSize, kSize);
802     glClearColor(0.0, 0.0, 0.0, 1.0);
803     glClear(GL_COLOR_BUFFER_BIT);
804 
805     // Draw green.  There's no unresolve operation as the framebuffer has just been cleared.
806     glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
807     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.0f);
808     ASSERT_GL_NO_ERROR();
809 
810     // Incur a state change while transform feedback is active.  This will result in a pipeline
811     // rebind in the Vulkan backend, which should necessarily break the render pass when
812     // VK_EXT_transform_feedback is used.
813     glEnable(GL_BLEND);
814     glBlendFunc(GL_ONE, GL_ONE);
815 
816     // Draw red.  The implicit render pass break means that there's an unresolve operation.
817     glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
818     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.0f);
819 
820     // End transform feedback
821     glEndTransformFeedback();
822 
823     // Expect yellow.
824     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
825     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::yellow);
826     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::yellow);
827     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::yellow);
828     EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::yellow);
829 }
830 
831 // Draw test using both color and depth attachments.
832 TEST_P(MultisampledRenderToTextureTest, 2DColorDepthMultisampleDrawTest)
833 {
834     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
835 
836     // http://anglebug.com/5380
837     ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsVulkan());
838 
839     constexpr GLsizei kSize = 6;
840     // create complete framebuffer with depth buffer
841     GLTexture texture;
842     glBindTexture(GL_TEXTURE_2D, texture);
843     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
844     ASSERT_GL_NO_ERROR();
845 
846     GLFramebuffer FBO;
847     glBindFramebuffer(GL_FRAMEBUFFER, FBO);
848     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
849                                          texture, 0, 4);
850 
851     GLRenderbuffer renderbuffer;
852     glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
853     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_DEPTH_COMPONENT16, kSize, kSize);
854     ASSERT_GL_NO_ERROR();
855     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderbuffer);
856     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
857 
858     // Set viewport and clear framebuffer
859     glViewport(0, 0, kSize, kSize);
860     glClearColor(0.0, 0.0, 0.0, 1.0);
861     glClearDepthf(0.5f);
862     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
863 
864     // Draw first green square
865     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
866     glEnable(GL_DEPTH_TEST);
867     glDepthFunc(GL_GREATER);
868     glUseProgram(program);
869     GLint positionLocation = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
870     ASSERT_NE(-1, positionLocation);
871 
872     setupQuadVertexBuffer(0.8f, 0.5f);
873     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
874     glEnableVertexAttribArray(positionLocation);
875 
876     // Tests that TRIANGLES works.
877     glDrawArrays(GL_TRIANGLES, 0, 6);
878     ASSERT_GL_NO_ERROR();
879 
880     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
881     EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::green);
882 
883     // Draw red square behind green square
884     ANGLE_GL_PROGRAM(program2, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
885     glUseProgram(program2);
886     GLint positionLocation2 = glGetAttribLocation(program2, essl1_shaders::PositionAttrib());
887     ASSERT_NE(-1, positionLocation2);
888 
889     setupQuadVertexBuffer(0.7f, 1.0f);
890     glVertexAttribPointer(positionLocation2, 3, GL_FLOAT, GL_FALSE, 0, 0);
891 
892     glDrawArrays(GL_TRIANGLES, 0, 6);
893     ASSERT_GL_NO_ERROR();
894     glDisable(GL_DEPTH_TEST);
895 
896     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
897     EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::green);
898 
899     glDisableVertexAttribArray(0);
900     glBindBuffer(GL_ARRAY_BUFFER, 0);
901 }
902 
readPixelsTestCommon(bool useRenderbuffer)903 void MultisampledRenderToTextureES3Test::readPixelsTestCommon(bool useRenderbuffer)
904 {
905     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
906 
907     GLFramebuffer FBO;
908     glBindFramebuffer(GL_FRAMEBUFFER, FBO);
909 
910     constexpr GLsizei kSize = 6;
911     GLTexture texture;
912     GLRenderbuffer renderbuffer;
913     createAndAttachColorAttachment(useRenderbuffer, kSize, GL_COLOR_ATTACHMENT0, nullptr,
914                                    mTestSampleCount, &texture, &renderbuffer);
915     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
916 
917     // Set viewport and clear to red
918     glViewport(0, 0, kSize, kSize);
919     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
920     glClear(GL_COLOR_BUFFER_BIT);
921     ASSERT_GL_NO_ERROR();
922 
923     // Bind Pack Pixel Buffer and read to it
924     GLBuffer PBO;
925     glBindBuffer(GL_PIXEL_PACK_BUFFER, PBO);
926     glBufferData(GL_PIXEL_PACK_BUFFER, 4 * kSize * kSize, nullptr, GL_STATIC_DRAW);
927     glReadPixels(0, 0, kSize, kSize, GL_RGBA, GL_UNSIGNED_BYTE, 0);
928     ASSERT_GL_NO_ERROR();
929 
930     // Retrieving pixel color
931     void *mappedPtr    = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, 32, GL_MAP_READ_BIT);
932     GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
933     EXPECT_GL_NO_ERROR();
934 
935     EXPECT_EQ(GLColor::red, dataColor[0]);
936 
937     glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
938     EXPECT_GL_NO_ERROR();
939 }
940 
941 // Read pixels with pack buffer. ES3+.
TEST_P(MultisampledRenderToTextureES3Test,ReadPixelsTest)942 TEST_P(MultisampledRenderToTextureES3Test, ReadPixelsTest)
943 {
944     readPixelsTestCommon(false);
945 }
946 
947 // Read pixels with pack buffer from renderbuffer. ES3+.
TEST_P(MultisampledRenderToTextureES3Test,RenderbufferReadPixelsTest)948 TEST_P(MultisampledRenderToTextureES3Test, RenderbufferReadPixelsTest)
949 {
950     // D3D backend doesn't implement multisampled render to texture renderbuffers correctly.
951     // http://anglebug.com/3107
952     ANGLE_SKIP_TEST_IF(IsD3D());
953 
954     readPixelsTestCommon(true);
955 }
956 
copyTexImageTestCommon(bool useRenderbuffer)957 void MultisampledRenderToTextureTest::copyTexImageTestCommon(bool useRenderbuffer)
958 {
959     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
960     constexpr GLsizei kSize = 16;
961 
962     setupCopyTexProgram();
963 
964     GLFramebuffer FBO;
965     glBindFramebuffer(GL_FRAMEBUFFER, FBO);
966 
967     GLTexture texture;
968     GLRenderbuffer renderbuffer;
969     createAndAttachColorAttachment(useRenderbuffer, kSize, GL_COLOR_ATTACHMENT0, nullptr,
970                                    mTestSampleCount, &texture, &renderbuffer);
971     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
972 
973     // Set color for framebuffer
974     glClearColor(0.25f, 1.0f, 0.75f, 0.5f);
975     glClear(GL_COLOR_BUFFER_BIT);
976     ASSERT_GL_NO_ERROR();
977 
978     GLTexture copyToTex;
979     glBindTexture(GL_TEXTURE_2D, copyToTex);
980 
981     // Disable mipmapping
982     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
983     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
984 
985     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, kSize, kSize, 0);
986     ASSERT_GL_NO_ERROR();
987 
988     verifyResults(copyToTex, {64, 255, 191, 255}, kSize, 0, 0, kSize, kSize);
989 }
990 
991 // CopyTexImage from a multisampled texture functionality test.
TEST_P(MultisampledRenderToTextureTest,CopyTexImageTest)992 TEST_P(MultisampledRenderToTextureTest, CopyTexImageTest)
993 {
994     copyTexImageTestCommon(false);
995 }
996 
997 // CopyTexImage from a multisampled texture functionality test using renderbuffer.
TEST_P(MultisampledRenderToTextureTest,RenderbufferCopyTexImageTest)998 TEST_P(MultisampledRenderToTextureTest, RenderbufferCopyTexImageTest)
999 {
1000     copyTexImageTestCommon(true);
1001 }
1002 
copyTexSubImageTestCommon(bool useRenderbuffer)1003 void MultisampledRenderToTextureTest::copyTexSubImageTestCommon(bool useRenderbuffer)
1004 {
1005     // Fails on Pixel 2. http://anglebug.com/4906
1006     ANGLE_SKIP_TEST_IF(IsAndroid());
1007 
1008     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
1009     constexpr GLsizei kSize = 16;
1010 
1011     setupCopyTexProgram();
1012 
1013     GLFramebuffer copyFBO0;
1014     glBindFramebuffer(GL_FRAMEBUFFER, copyFBO0);
1015 
1016     // Create color attachment for copyFBO0
1017     GLTexture texture;
1018     GLRenderbuffer renderbuffer;
1019     createAndAttachColorAttachment(useRenderbuffer, kSize, GL_COLOR_ATTACHMENT0, nullptr,
1020                                    mTestSampleCount, &texture, &renderbuffer);
1021     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1022 
1023     GLFramebuffer copyFBO1;
1024     glBindFramebuffer(GL_FRAMEBUFFER, copyFBO1);
1025 
1026     // Create color attachment for copyFBO1
1027     GLTexture texture1;
1028     GLRenderbuffer renderbuffer1;
1029     createAndAttachColorAttachment(useRenderbuffer, kSize, GL_COLOR_ATTACHMENT0, nullptr,
1030                                    mTestSampleCount, &texture1, &renderbuffer1);
1031     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1032 
1033     // Set color for copyFBO0
1034     glBindFramebuffer(GL_FRAMEBUFFER, copyFBO0);
1035     glClearColor(0.25f, 1.0f, 0.75f, 0.5f);
1036     glClear(GL_COLOR_BUFFER_BIT);
1037     ASSERT_GL_NO_ERROR();
1038 
1039     // Set color for copyFBO1
1040     glBindFramebuffer(GL_FRAMEBUFFER, copyFBO1);
1041     glClearColor(1.0f, 0.75f, 0.5f, 0.25f);
1042     glClear(GL_COLOR_BUFFER_BIT);
1043     ASSERT_GL_NO_ERROR();
1044 
1045     GLTexture copyToTex;
1046     glBindTexture(GL_TEXTURE_2D, copyToTex);
1047 
1048     // Disable mipmapping
1049     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1050     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1051 
1052     // copyFBO0 -> copyToTex
1053     // copyToTex should hold what was originally in copyFBO0 : (.25, 1, .75, .5)
1054     glBindFramebuffer(GL_FRAMEBUFFER, copyFBO0);
1055     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, kSize, kSize, 0);
1056     ASSERT_GL_NO_ERROR();
1057 
1058     const GLColor expected0(64, 255, 191, 255);
1059     verifyResults(copyToTex, expected0, kSize, 0, 0, kSize, kSize);
1060 
1061     // copyFBO[1] - copySubImage -> copyToTex
1062     // copyToTex should have subportion what was in copyFBO[1] : (1, .75, .5, .25)
1063     // The rest should still be untouched: (.25, 1, .75, .5)
1064     GLint half = kSize / 2;
1065     glBindFramebuffer(GL_FRAMEBUFFER, copyFBO1);
1066     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, half, half, half, half, half, half);
1067     ASSERT_GL_NO_ERROR();
1068 
1069     const GLColor expected1(255, 191, 127, 255);
1070     verifyResults(copyToTex, expected1, kSize, half, half, kSize, kSize);
1071 
1072     // Verify rest is untouched
1073     verifyResults(copyToTex, expected0, kSize, 0, 0, half, half);
1074     verifyResults(copyToTex, expected0, kSize, 0, half, half, kSize);
1075     verifyResults(copyToTex, expected0, kSize, half, 0, kSize, half);
1076 }
1077 
1078 // CopyTexSubImage from a multisampled texture functionality test.
TEST_P(MultisampledRenderToTextureTest,CopyTexSubImageTest)1079 TEST_P(MultisampledRenderToTextureTest, CopyTexSubImageTest)
1080 {
1081     copyTexSubImageTestCommon(false);
1082 }
1083 
1084 // CopyTexSubImage from a multisampled texture functionality test with renderbuffers
TEST_P(MultisampledRenderToTextureTest,RenderbufferCopyTexSubImageTest)1085 TEST_P(MultisampledRenderToTextureTest, RenderbufferCopyTexSubImageTest)
1086 {
1087     copyTexSubImageTestCommon(true);
1088 }
1089 
blitFramebufferTestCommon(bool useRenderbuffer)1090 void MultisampledRenderToTextureES3Test::blitFramebufferTestCommon(bool useRenderbuffer)
1091 {
1092     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
1093 
1094     // Some draws are not executed before the blitframebuffer on Pixel2.
1095     // http://anglebug.com/2894
1096     ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGL() && IsPixel2());
1097 
1098     constexpr GLsizei kSize = 16;
1099 
1100     GLFramebuffer fboMS;
1101     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
1102 
1103     // Create multisampled framebuffer to use as source.
1104     GLRenderbuffer depthMS;
1105     glBindRenderbuffer(GL_RENDERBUFFER, depthMS);
1106     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_DEPTH_COMPONENT24, kSize, kSize);
1107     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthMS);
1108     ASSERT_GL_NO_ERROR();
1109 
1110     GLTexture textureMS;
1111     GLRenderbuffer renderbufferMS;
1112     createAndAttachColorAttachment(useRenderbuffer, kSize, GL_COLOR_ATTACHMENT0, nullptr,
1113                                    mTestSampleCount, &textureMS, &renderbufferMS);
1114     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1115 
1116     // Clear depth to 0.5 and color to green.
1117     glClearDepthf(0.5f);
1118     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
1119     glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
1120     glFlush();
1121     ASSERT_GL_NO_ERROR();
1122 
1123     // Draw red into the multisampled color buffer.
1124     ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
1125     glEnable(GL_DEPTH_TEST);
1126     glDepthFunc(GL_EQUAL);
1127     drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.0f);
1128     ASSERT_GL_NO_ERROR();
1129 
1130     // Create single sampled framebuffer to use as dest.
1131     GLFramebuffer fboSS;
1132     glBindFramebuffer(GL_FRAMEBUFFER, fboSS);
1133     GLTexture colorSS;
1134     glBindTexture(GL_TEXTURE_2D, colorSS);
1135     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1136     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorSS, 0);
1137     ASSERT_GL_NO_ERROR();
1138 
1139     // Bind MS to READ as SS is already bound to DRAW.
1140     glBindFramebuffer(GL_READ_FRAMEBUFFER, fboMS);
1141     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1142     ASSERT_GL_NO_ERROR();
1143 
1144     // Bind SS to READ so we can readPixels from it
1145     glBindFramebuffer(GL_FRAMEBUFFER, fboSS);
1146 
1147     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1148     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::red);
1149     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::red);
1150     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::red);
1151     EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::red);
1152     ASSERT_GL_NO_ERROR();
1153 }
1154 
1155 // BlitFramebuffer functionality test. ES3+.
TEST_P(MultisampledRenderToTextureES3Test,BlitFramebufferTest)1156 TEST_P(MultisampledRenderToTextureES3Test, BlitFramebufferTest)
1157 {
1158     blitFramebufferTestCommon(false);
1159 }
1160 
1161 // BlitFramebuffer functionality test with renderbuffer. ES3+.
TEST_P(MultisampledRenderToTextureES3Test,RenderbufferBlitFramebufferTest)1162 TEST_P(MultisampledRenderToTextureES3Test, RenderbufferBlitFramebufferTest)
1163 {
1164     blitFramebufferTestCommon(true);
1165 }
1166 
1167 // GenerateMipmap functionality test
TEST_P(MultisampledRenderToTextureTest,GenerateMipmapTest)1168 TEST_P(MultisampledRenderToTextureTest, GenerateMipmapTest)
1169 {
1170     // Fails on Pixel 2. http://anglebug.com/4906
1171     ANGLE_SKIP_TEST_IF(IsAndroid());
1172 
1173     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
1174     constexpr GLsizei kSize = 64;
1175 
1176     setupCopyTexProgram();
1177     glUseProgram(mCopyTextureProgram);
1178 
1179     // Initialize texture with blue
1180     GLTexture texture;
1181     glBindTexture(GL_TEXTURE_2D, texture);
1182     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, kSize, kSize, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
1183     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1184     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1185 
1186     GLFramebuffer FBO;
1187     glBindFramebuffer(GL_FRAMEBUFFER, FBO);
1188     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
1189                                          texture, 0, 4);
1190     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
1191     glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
1192     glClear(GL_COLOR_BUFFER_BIT);
1193     glViewport(0, 0, kSize, kSize);
1194     glBindFramebuffer(GL_FRAMEBUFFER, 0);
1195     ASSERT_GL_NO_ERROR();
1196 
1197     // Generate mipmap
1198     glGenerateMipmap(GL_TEXTURE_2D);
1199     ASSERT_GL_NO_ERROR();
1200 
1201     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1202 
1203     // Now draw the texture to various different sized areas.
1204     clearAndDrawQuad(mCopyTextureProgram, kSize, kSize);
1205     EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::blue);
1206 
1207     // Use mip level 1
1208     clearAndDrawQuad(mCopyTextureProgram, kSize / 2, kSize / 2);
1209     EXPECT_PIXEL_COLOR_EQ(kSize / 4, kSize / 4, GLColor::blue);
1210 
1211     // Use mip level 2
1212     clearAndDrawQuad(mCopyTextureProgram, kSize / 4, kSize / 4);
1213     EXPECT_PIXEL_COLOR_EQ(kSize / 8, kSize / 8, GLColor::blue);
1214 
1215     ASSERT_GL_NO_ERROR();
1216 }
1217 
drawCopyThenBlendCommon(bool useRenderbuffer)1218 void MultisampledRenderToTextureTest::drawCopyThenBlendCommon(bool useRenderbuffer)
1219 {
1220     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
1221     constexpr GLsizei kSize = 64;
1222 
1223     setupCopyTexProgram();
1224 
1225     GLFramebuffer fboMS;
1226     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
1227 
1228     // Create multisampled framebuffer to draw into
1229     GLTexture textureMS;
1230     GLRenderbuffer renderbufferMS;
1231     createAndAttachColorAttachment(useRenderbuffer, kSize, GL_COLOR_ATTACHMENT0, nullptr,
1232                                    mTestSampleCount, &textureMS, &renderbufferMS);
1233     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1234 
1235     // Draw red into the multisampled color buffer.
1236     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
1237     glUseProgram(drawColor);
1238     GLint colorUniformLocation =
1239         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
1240     ASSERT_NE(colorUniformLocation, -1);
1241 
1242     glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
1243     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
1244     ASSERT_GL_NO_ERROR();
1245 
1246     // Create a texture and copy into it.
1247     GLTexture texture;
1248     glBindTexture(GL_TEXTURE_2D, texture);
1249     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, kSize, kSize, 0);
1250     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1251     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1252 
1253     // Draw again into the framebuffer, this time blending.  This tests that the framebuffer's data,
1254     // residing in the single-sampled texture, is available to the multisampled intermediate image
1255     // for blending.
1256 
1257     // Blend half-transparent green into the multisampled color buffer.
1258     glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 0.5f);
1259     glEnable(GL_BLEND);
1260     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1261     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
1262     ASSERT_GL_NO_ERROR();
1263 
1264     // Verify that the texture is now yellow
1265     const GLColor kExpected(127, 127, 0, 191);
1266     EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpected, 1);
1267     EXPECT_PIXEL_COLOR_NEAR(kSize - 1, 0, kExpected, 1);
1268     EXPECT_PIXEL_COLOR_NEAR(0, kSize - 1, kExpected, 1);
1269     EXPECT_PIXEL_COLOR_NEAR(kSize - 1, kSize - 1, kExpected, 1);
1270 
1271     // For completeness, verify that the texture used as copy target is red.
1272     ASSERT_GL_NO_ERROR();
1273     verifyResults(texture, GLColor::red, kSize, 0, 0, kSize, kSize);
1274 
1275     ASSERT_GL_NO_ERROR();
1276 }
1277 
1278 // Draw, copy, then blend.  The copy will make sure an implicit resolve happens.  Regardless, the
1279 // following draw should retain the data written by the first draw command.
TEST_P(MultisampledRenderToTextureTest,DrawCopyThenBlend)1280 TEST_P(MultisampledRenderToTextureTest, DrawCopyThenBlend)
1281 {
1282     drawCopyThenBlendCommon(false);
1283 }
1284 
1285 // Draw, copy, then blend.  The copy will make sure an implicit resolve happens.  Regardless, the
1286 // following draw should retain the data written by the first draw command.  Uses renderbuffer.
TEST_P(MultisampledRenderToTextureTest,RenderbufferDrawCopyThenBlend)1287 TEST_P(MultisampledRenderToTextureTest, RenderbufferDrawCopyThenBlend)
1288 {
1289     drawCopyThenBlendCommon(true);
1290 }
1291 
clearDrawCopyThenBlendSameProgramCommon(bool useRenderbuffer)1292 void MultisampledRenderToTextureTest::clearDrawCopyThenBlendSameProgramCommon(bool useRenderbuffer)
1293 {
1294     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
1295     constexpr GLsizei kSize = 64;
1296 
1297     setupCopyTexProgram();
1298 
1299     GLFramebuffer fboMS;
1300     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
1301 
1302     // Create multisampled framebuffer to draw into
1303     GLTexture textureMS;
1304     GLRenderbuffer renderbufferMS;
1305     createAndAttachColorAttachment(useRenderbuffer, kSize, GL_COLOR_ATTACHMENT0, nullptr,
1306                                    mTestSampleCount, &textureMS, &renderbufferMS);
1307     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1308 
1309     // Draw red into the multisampled color buffer.
1310     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
1311     glUseProgram(drawColor);
1312     GLint colorUniformLocation =
1313         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
1314     ASSERT_NE(colorUniformLocation, -1);
1315 
1316     // Clear the framebuffer.
1317     glClearColor(0.1f, 0.9f, 0.2f, 0.8f);
1318     glClear(GL_COLOR_BUFFER_BIT);
1319 
1320     // Then draw into it.
1321     glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
1322     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
1323     ASSERT_GL_NO_ERROR();
1324 
1325     // Blend green into it.  This makes sure that the blend after the resolve doesn't have different
1326     // state from the one used here.
1327     glEnable(GL_BLEND);
1328     glBlendFunc(GL_ONE, GL_ONE);
1329     glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
1330     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
1331     ASSERT_GL_NO_ERROR();
1332 
1333     // Create a texture and copy into it.
1334     GLTexture texture;
1335     glBindTexture(GL_TEXTURE_2D, texture);
1336     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, kSize, kSize, 0);
1337     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1338     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1339 
1340     // Draw again into the framebuffer, this time blending.  This tests that the framebuffer's data,
1341     // residing in the single-sampled texture, is available to the multisampled intermediate image
1342     // for blending.
1343 
1344     // Blend blue into the multisampled color buffer.
1345     glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
1346     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
1347     ASSERT_GL_NO_ERROR();
1348 
1349     // Verify that the texture is now white
1350     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);
1351     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::white);
1352     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::white);
1353     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::white);
1354 
1355     // Once again, clear and draw so the program is used again in the way it was first used.
1356     glClear(GL_COLOR_BUFFER_BIT);
1357     glDisable(GL_BLEND);
1358     glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
1359     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
1360 
1361     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
1362     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::blue);
1363     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::blue);
1364     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::blue);
1365 
1366     // For completeness, verify that the texture used as copy target is yellow.
1367     ASSERT_GL_NO_ERROR();
1368     verifyResults(texture, GLColor::yellow, kSize, 0, 0, kSize, kSize);
1369 
1370     ASSERT_GL_NO_ERROR();
1371 }
1372 
1373 // Clear&Draw, copy, then blend with same program.  The copy will make sure an implicit resolve
1374 // happens.  The second draw should retain the data written by the first draw command ("unresolve"
1375 // operation).  The same program is used for the first and second draw calls, and the fact that the
1376 // attachment is cleared or unresolved should not cause issues.  In the Vulkan backend, the program
1377 // will be used in different subpass indices, so two graphics pipelines should be created for it.
TEST_P(MultisampledRenderToTextureTest,ClearDrawCopyThenBlendSameProgram)1378 TEST_P(MultisampledRenderToTextureTest, ClearDrawCopyThenBlendSameProgram)
1379 {
1380     clearDrawCopyThenBlendSameProgramCommon(false);
1381 }
1382 
1383 // Same as ClearDrawCopyThenBlendSameProgram but with renderbuffers
TEST_P(MultisampledRenderToTextureTest,RenderbufferClearDrawCopyThenBlendSameProgram)1384 TEST_P(MultisampledRenderToTextureTest, RenderbufferClearDrawCopyThenBlendSameProgram)
1385 {
1386     clearDrawCopyThenBlendSameProgramCommon(true);
1387 }
1388 
1389 // Similar to RenderbufferClearDrawCopyThenBlendSameProgram, but with the depth/stencil attachment
1390 // being unresolved only.
TEST_P(MultisampledRenderToTextureES3Test,RenderbufferClearDrawCopyThenBlendWithDepthStencilSameProgram)1391 TEST_P(MultisampledRenderToTextureES3Test,
1392        RenderbufferClearDrawCopyThenBlendWithDepthStencilSameProgram)
1393 {
1394     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
1395 
1396     // http://anglebug.com/5380
1397     ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsVulkan());
1398 
1399     constexpr GLsizei kSize = 64;
1400 
1401     setupCopyTexProgram();
1402 
1403     GLFramebuffer fboMS;
1404     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
1405 
1406     // Create multisampled framebuffer to draw into
1407     GLTexture color;
1408     glBindTexture(GL_TEXTURE_2D, color);
1409     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1410     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color,
1411                                          0, 4);
1412 
1413     GLRenderbuffer depthStencil;
1414     glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
1415     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, kSize, kSize);
1416     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
1417                               depthStencil);
1418     ASSERT_GL_NO_ERROR();
1419     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1420 
1421     // Draw red into the multisampled color buffer.
1422     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
1423     glUseProgram(drawColor);
1424     GLint colorUniformLocation =
1425         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
1426     ASSERT_NE(colorUniformLocation, -1);
1427 
1428     // Enable write to depth/stencil so the attachment has valid contents, but always pass the test.
1429     glEnable(GL_DEPTH_TEST);
1430     glDepthFunc(GL_ALWAYS);
1431 
1432     glEnable(GL_STENCIL_TEST);
1433     glStencilFunc(GL_ALWAYS, 0x55, 0xFF);
1434     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
1435     glStencilMask(0xFF);
1436 
1437     // Clear the framebuffer.
1438     glClearColor(0.1f, 0.9f, 0.2f, 0.8f);
1439     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1440 
1441     // Then draw into it.
1442     glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
1443     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 1.0f);
1444     ASSERT_GL_NO_ERROR();
1445 
1446     // Blend green into it.  This makes sure that the blend after the resolve doesn't have different
1447     // state from the one used here.  Additionally, test that the previous draw output the correct
1448     // depth/stencil data.  Again, this makes sure that the draw call after the resolve doesn't have
1449     // different has depth/stencil test state.
1450 
1451     // If depth is not set to 1, rendering would fail.
1452     glDepthFunc(GL_LESS);
1453 
1454     // If stencil is not set to 0x55, rendering would fail.
1455     glStencilFunc(GL_EQUAL, 0x55, 0xFF);
1456     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
1457 
1458     glEnable(GL_BLEND);
1459     glBlendFunc(GL_ONE, GL_ONE);
1460     glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
1461     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.95f);
1462     ASSERT_GL_NO_ERROR();
1463 
1464     // Create a texture and copy into it.
1465     GLTexture texture;
1466     glBindTexture(GL_TEXTURE_2D, texture);
1467     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, kSize, kSize, 0);
1468     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1469     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1470 
1471     // Clear color (but not depth/stencil), and draw again into the framebuffer, this time blending.
1472     // Additionally, make sure the depth/stencil data are retained.
1473 
1474     // Clear color (to blue), but not depth/stencil.
1475     glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
1476     glClear(GL_COLOR_BUFFER_BIT);
1477 
1478     // Blend green into the multisampled color buffer.
1479     glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
1480     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.9f);
1481     ASSERT_GL_NO_ERROR();
1482 
1483     // Verify that the texture is now cyan
1484     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
1485     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::cyan);
1486     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::cyan);
1487     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::cyan);
1488 
1489     // Once again, clear and draw so the program is used again in the way it was first used.
1490     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1491     glDisable(GL_BLEND);
1492     glDepthFunc(GL_ALWAYS);
1493     glStencilFunc(GL_ALWAYS, 0x55, 0xFF);
1494     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
1495     glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
1496     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
1497 
1498     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
1499     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::blue);
1500     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::blue);
1501     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::blue);
1502 
1503     // For completeness, verify that the texture used as copy target is yellow.
1504     ASSERT_GL_NO_ERROR();
1505     verifyResults(texture, GLColor::yellow, kSize, 0, 0, kSize, kSize);
1506 
1507     ASSERT_GL_NO_ERROR();
1508 }
1509 
drawCopyDrawThenMaskedClearCommon(bool useRenderbuffer)1510 void MultisampledRenderToTextureTest::drawCopyDrawThenMaskedClearCommon(bool useRenderbuffer)
1511 {
1512     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
1513     constexpr GLsizei kSize = 64;
1514 
1515     setupCopyTexProgram();
1516 
1517     GLFramebuffer fboMS;
1518     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
1519 
1520     // Create multisampled framebuffer to draw into
1521     GLTexture textureMS;
1522     GLRenderbuffer renderbufferMS;
1523     createAndAttachColorAttachment(useRenderbuffer, kSize, GL_COLOR_ATTACHMENT0, nullptr,
1524                                    mTestSampleCount, &textureMS, &renderbufferMS);
1525     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1526 
1527     // Draw red into the multisampled color buffer.
1528     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
1529     glUseProgram(drawColor);
1530     GLint colorUniformLocation =
1531         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
1532     ASSERT_NE(colorUniformLocation, -1);
1533 
1534     // Draw into framebuffer.
1535     glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
1536     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
1537     ASSERT_GL_NO_ERROR();
1538 
1539     // Create a texture and copy into it.
1540     GLTexture texture;
1541     glBindTexture(GL_TEXTURE_2D, texture);
1542     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, kSize, kSize, 0);
1543     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1544     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1545 
1546     // Draw again into the framebuffer, this time blending.  Afterwards, issue a masked clear.  This
1547     // ensures that previous resolved data is unresolved, and mid-render-pass clears work correctly.
1548 
1549     // Draw green into the multisampled color buffer.
1550     glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
1551     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
1552     ASSERT_GL_NO_ERROR();
1553 
1554     // Issue a masked clear.
1555     glClearColor(0.1f, 0.9f, 1.0f, 0.8f);
1556     glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_FALSE);
1557     glClear(GL_COLOR_BUFFER_BIT);
1558 
1559     // Verify that the texture is now cyan
1560     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
1561     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::cyan);
1562     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::cyan);
1563     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::cyan);
1564 
1565     // For completeness, verify that the texture used as copy target is red.
1566     ASSERT_GL_NO_ERROR();
1567     verifyResults(texture, GLColor::red, kSize, 0, 0, kSize, kSize);
1568 
1569     ASSERT_GL_NO_ERROR();
1570 }
1571 
1572 // Draw, copy, draw then issue a masked clear.  The copy will make sure an implicit resolve
1573 // happens.  The second draw should retain the data written by the first draw command ("unresolve"
1574 // operation).  The final clear uses a draw call to perform the clear in the Vulkan backend, and it
1575 // should use the correct subpass index.
TEST_P(MultisampledRenderToTextureTest,DrawCopyDrawThenMaskedClear)1576 TEST_P(MultisampledRenderToTextureTest, DrawCopyDrawThenMaskedClear)
1577 {
1578     drawCopyDrawThenMaskedClearCommon(false);
1579 }
1580 
1581 // Same as DrawCopyDrawThenMaskedClearCommon but with renderbuffers
TEST_P(MultisampledRenderToTextureTest,RenderbufferDrawCopyDrawThenMaskedClear)1582 TEST_P(MultisampledRenderToTextureTest, RenderbufferDrawCopyDrawThenMaskedClear)
1583 {
1584     drawCopyDrawThenMaskedClearCommon(true);
1585 }
1586 
drawCopyDrawAttachInvalidatedThenDrawCommon(bool useRenderbuffer)1587 void MultisampledRenderToTextureES3Test::drawCopyDrawAttachInvalidatedThenDrawCommon(
1588     bool useRenderbuffer)
1589 {
1590     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
1591     constexpr GLsizei kSize = 64;
1592 
1593     setupCopyTexProgram();
1594 
1595     GLFramebuffer fboMS;
1596     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
1597 
1598     // Create multisampled framebuffer to draw into
1599     GLTexture textureMS;
1600     GLRenderbuffer renderbufferMS;
1601     createAndAttachColorAttachment(useRenderbuffer, kSize, GL_COLOR_ATTACHMENT0, nullptr,
1602                                    mTestSampleCount, &textureMS, &renderbufferMS);
1603     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1604 
1605     // Draw red into the multisampled color buffer.
1606     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
1607     glUseProgram(drawColor);
1608     GLint colorUniformLocation =
1609         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
1610     ASSERT_NE(colorUniformLocation, -1);
1611 
1612     // Clear and draw into framebuffer.
1613     glClear(GL_COLOR_BUFFER_BIT);
1614     glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
1615     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
1616     ASSERT_GL_NO_ERROR();
1617 
1618     // Create a texture and copy into it.
1619     GLTexture texture;
1620     glBindTexture(GL_TEXTURE_2D, texture);
1621     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, kSize, kSize, 0);
1622     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1623     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1624 
1625     // Draw green into framebuffer.  This will unresolve color.
1626     glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
1627     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
1628     ASSERT_GL_NO_ERROR();
1629 
1630     // Create multisampled framebuffer and invalidate its attachment.
1631     GLFramebuffer invalidateFboMS;
1632     glBindFramebuffer(GL_FRAMEBUFFER, invalidateFboMS);
1633 
1634     // Create multisampled framebuffer to draw into
1635     GLTexture invalidateTextureMS;
1636     GLRenderbuffer invalidateRenderbufferMS;
1637     createAndAttachColorAttachment(useRenderbuffer, kSize, GL_COLOR_ATTACHMENT0, nullptr,
1638                                    mTestSampleCount, &invalidateTextureMS,
1639                                    &invalidateRenderbufferMS);
1640     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1641 
1642     // Invalidate the attachment.
1643     GLenum invalidateAttachments[] = {GL_COLOR_ATTACHMENT0};
1644     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, invalidateAttachments);
1645 
1646     // Replace the original framebuffer's attachment with the invalidated one.
1647     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
1648     if (useRenderbuffer)
1649     {
1650         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
1651                                   invalidateRenderbufferMS);
1652     }
1653     else
1654     {
1655         glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
1656                                              invalidateTextureMS, 0, 4);
1657     }
1658     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1659 
1660     // Draw blue into the multisampled color buffer.
1661     glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
1662     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
1663     ASSERT_GL_NO_ERROR();
1664 
1665     // Verify that the texture is now blue
1666     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
1667     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::blue);
1668     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::blue);
1669     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::blue);
1670 
1671     // For completeness, verify that the texture used as copy target is red.
1672     ASSERT_GL_NO_ERROR();
1673     verifyResults(texture, GLColor::red, kSize, 0, 0, kSize, kSize);
1674 
1675     ASSERT_GL_NO_ERROR();
1676 }
1677 
1678 // Draw, copy, draw, attach an invalidated image then draw.  The second draw will need to unresolve
1679 // color.  Attaching an invalidated image changes the framebuffer, and the following draw doesn't
1680 // require an unresolve.  In the Vulkan backend, mismatches in unresolve state between framebuffer
1681 // and render pass will result in an ASSERT.
TEST_P(MultisampledRenderToTextureES3Test,DrawCopyDrawAttachInvalidatedThenDraw)1682 TEST_P(MultisampledRenderToTextureES3Test, DrawCopyDrawAttachInvalidatedThenDraw)
1683 {
1684     drawCopyDrawAttachInvalidatedThenDrawCommon(false);
1685 }
1686 
1687 // Same as DrawCopyDrawAttachInvalidatedThenDraw but with renderbuffers
TEST_P(MultisampledRenderToTextureES3Test,RenderbufferDrawCopyDrawAttachInvalidatedThenDraw)1688 TEST_P(MultisampledRenderToTextureES3Test, RenderbufferDrawCopyDrawAttachInvalidatedThenDraw)
1689 {
1690     drawCopyDrawAttachInvalidatedThenDrawCommon(true);
1691 }
1692 
drawCopyDrawAttachDepthStencilClearThenDrawCommon(bool useRenderbuffer)1693 void MultisampledRenderToTextureES3Test::drawCopyDrawAttachDepthStencilClearThenDrawCommon(
1694     bool useRenderbuffer)
1695 {
1696     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
1697     constexpr GLsizei kSize = 64;
1698 
1699     // http://anglebug.com/4935
1700     ANGLE_SKIP_TEST_IF(IsD3D11());
1701 
1702     setupCopyTexProgram();
1703 
1704     GLFramebuffer fboMS;
1705     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
1706 
1707     // Create multisampled framebuffer to draw into
1708     GLTexture textureMS;
1709     GLRenderbuffer renderbufferMS;
1710     createAndAttachColorAttachment(useRenderbuffer, kSize, GL_COLOR_ATTACHMENT0, nullptr,
1711                                    mTestSampleCount, &textureMS, &renderbufferMS);
1712     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1713 
1714     // Draw red into the multisampled color buffer.
1715     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
1716     glUseProgram(drawColor);
1717     GLint colorUniformLocation =
1718         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
1719     ASSERT_NE(colorUniformLocation, -1);
1720 
1721     // Clear and draw into framebuffer.  There is no unresolve due to clear.  The clear value is
1722     // irrelevant as the contents are immediately overdrawn with the draw call.
1723     glClear(GL_COLOR_BUFFER_BIT);
1724     glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
1725     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
1726     ASSERT_GL_NO_ERROR();
1727 
1728     // Create a texture and copy into it.
1729     GLTexture texture;
1730     glBindTexture(GL_TEXTURE_2D, texture);
1731     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, kSize, kSize, 0);
1732     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1733     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1734 
1735     // Draw green into framebuffer.  This will unresolve color.
1736     glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
1737     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
1738     ASSERT_GL_NO_ERROR();
1739 
1740     // Attach a depth/stencil attachment.
1741     GLTexture dsTextureMS;
1742     GLRenderbuffer dsRenderbufferMS;
1743     createAndAttachDepthStencilAttachment(useRenderbuffer, kSize, &dsTextureMS, &dsRenderbufferMS);
1744     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1745 
1746     // Clear all attachments, so no unresolve would be necessary.
1747     glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
1748     glClearDepthf(1);
1749     glClearStencil(0x55);
1750     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1751 
1752     // If depth is not cleared to 1, rendering would fail.
1753     glEnable(GL_DEPTH_TEST);
1754     glDepthFunc(GL_LESS);
1755 
1756     // If stencil is not cleared to 0x55, rendering would fail.
1757     glEnable(GL_STENCIL_TEST);
1758     glStencilFunc(GL_EQUAL, 0x55, 0xFF);
1759     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
1760     glStencilMask(0xFF);
1761 
1762     // Blend half-transparent green into the multisampled color buffer.
1763     glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 0.5f);
1764     glEnable(GL_BLEND);
1765     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1766     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.95f);
1767     ASSERT_GL_NO_ERROR();
1768 
1769     // Verify that the texture is now cyan
1770     const GLColor kExpected2(0, 127, 127, 191);
1771     EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpected2, 1);
1772     EXPECT_PIXEL_COLOR_NEAR(kSize - 1, 0, kExpected2, 1);
1773     EXPECT_PIXEL_COLOR_NEAR(0, kSize - 1, kExpected2, 1);
1774     EXPECT_PIXEL_COLOR_NEAR(kSize - 1, kSize - 1, kExpected2, 1);
1775 
1776     // For completeness, verify that the texture used as copy target is red.
1777     ASSERT_GL_NO_ERROR();
1778     verifyResults(texture, GLColor::red, kSize, 0, 0, kSize, kSize);
1779 
1780     ASSERT_GL_NO_ERROR();
1781 }
1782 
1783 // Draw, copy, draw, attach depth/stencil, clear then draw.  The second draw will need to unresolve
1784 // color.  Attaching depth/stencil changes the framebuffer, and the following clear ensures no
1785 // unresolve is necessary.  In the Vulkan backend, mismatches in unresolve state between framebuffer
1786 // and render pass will result in an ASSERT.
TEST_P(MultisampledRenderToTextureES3Test,DrawCopyDrawAttachDepthStencilClearThenDraw)1787 TEST_P(MultisampledRenderToTextureES3Test, DrawCopyDrawAttachDepthStencilClearThenDraw)
1788 {
1789     drawCopyDrawAttachDepthStencilClearThenDrawCommon(false);
1790 }
1791 
1792 // Same as DrawCopyDrawAttachDepthStencilClearThenDraw but with renderbuffers
TEST_P(MultisampledRenderToTextureES3Test,RenderbufferDrawCopyDrawAttachDepthStencilClearThenDraw)1793 TEST_P(MultisampledRenderToTextureES3Test, RenderbufferDrawCopyDrawAttachDepthStencilClearThenDraw)
1794 {
1795     drawCopyDrawAttachDepthStencilClearThenDrawCommon(true);
1796 }
1797 
1798 // Draw, copy, redefine the color attachment with a different format, clear, copy then draw.  The
1799 // initial draw will need to unresolve color as the color attachment is preinitilized with data.
1800 // Redefining the color attachment forces framebuffer to recreate when the clear is called.  The
1801 // second copy resolves the clear and the final draw unresolves again.  In the Vulkan backend,
1802 // mismatches in unresolve state between framebuffer and render pass will result in an ASSERT and a
1803 // validation error (if ASSERT is removed).
TEST_P(MultisampledRenderToTextureES3Test,DrawCopyRedefineClearCopyThenDraw)1804 TEST_P(MultisampledRenderToTextureES3Test, DrawCopyRedefineClearCopyThenDraw)
1805 {
1806     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
1807     constexpr GLsizei kSize = 64;
1808 
1809     setupCopyTexProgram();
1810 
1811     GLFramebuffer fboMS;
1812     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
1813 
1814     std::vector<GLColor> initialColorData(kSize * kSize, GLColor::black);
1815 
1816     // Create multisampled framebuffer to draw into
1817     GLTexture colorMS;
1818     glBindTexture(GL_TEXTURE_2D, colorMS);
1819     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1820                  initialColorData.data());
1821     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
1822                                          colorMS, 0, 4);
1823     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1824 
1825     // Draw red into the multisampled color buffer.
1826     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
1827     glUseProgram(drawColor);
1828     GLint colorUniformLocation =
1829         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
1830     ASSERT_NE(colorUniformLocation, -1);
1831 
1832     // Draw into framebuffer.  This will unresolve color.
1833     glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
1834     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
1835     ASSERT_GL_NO_ERROR();
1836 
1837     // Create a texture and copy into it.
1838     GLTexture texture;
1839     glBindTexture(GL_TEXTURE_2D, texture);
1840     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, kSize, kSize, 0);
1841     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1842     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1843 
1844     // Incompatibly redefine the texture, forcing its image to be recreated.
1845     glBindTexture(GL_TEXTURE_2D, colorMS);
1846     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, kSize, kSize, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
1847     ASSERT_GL_NO_ERROR();
1848     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1849 
1850     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
1851     glClear(GL_COLOR_BUFFER_BIT);
1852 
1853     // Create another texture and copy into it.
1854     GLTexture texture2;
1855     glBindTexture(GL_TEXTURE_2D, texture2);
1856     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, kSize, kSize, 0);
1857 
1858     // Clear to green and blend blue into the multisampled color buffer.
1859     glUseProgram(drawColor);
1860     glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
1861     glEnable(GL_BLEND);
1862     glBlendFunc(GL_ONE, GL_ONE);
1863     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
1864     ASSERT_GL_NO_ERROR();
1865 
1866     // Verify that the texture is now cyan
1867     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
1868     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::cyan);
1869     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::cyan);
1870     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::cyan);
1871 
1872     // For completeness, verify that the texture used as copy target is red.
1873     ASSERT_GL_NO_ERROR();
1874     verifyResults(texture, GLColor::red, kSize, 0, 0, kSize, kSize);
1875 
1876     ASSERT_GL_NO_ERROR();
1877 }
1878 
1879 // Draw, copy, rebind the attachment, clear then draw.  The initial draw will need to unresolve
1880 // color.  The framebuffer attachment is temporary changed and then reset back to the original.
1881 // This causes the framebuffer to be recreated on the following clear and draw.  The clear prevents
1882 // the final draw from doing an unresolve.  In the Vulkan backend, mismatches in unresolve state
1883 // between framebuffer and render pass will result in an ASSERT and a validation error (if ASSERT is
1884 // removed).
TEST_P(MultisampledRenderToTextureES3Test,DrawCopyRebindAttachmentClearThenDraw)1885 TEST_P(MultisampledRenderToTextureES3Test, DrawCopyRebindAttachmentClearThenDraw)
1886 {
1887     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
1888     constexpr GLsizei kSize = 64;
1889 
1890     setupCopyTexProgram();
1891 
1892     GLFramebuffer fboMS;
1893     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
1894 
1895     std::vector<GLColor> initialColorData(kSize * kSize, GLColor::black);
1896 
1897     // Create multisampled framebuffer to draw into
1898     GLTexture colorMS;
1899     glBindTexture(GL_TEXTURE_2D, colorMS);
1900     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1901                  initialColorData.data());
1902     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
1903                                          colorMS, 0, 4);
1904     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1905 
1906     // Draw red into the multisampled color buffer.
1907     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
1908     glUseProgram(drawColor);
1909     GLint colorUniformLocation =
1910         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
1911     ASSERT_NE(colorUniformLocation, -1);
1912 
1913     // Draw into framebuffer.  This will unresolve color.
1914     glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
1915     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
1916     ASSERT_GL_NO_ERROR();
1917 
1918     // Create a texture and copy into it.
1919     GLTexture texture;
1920     glBindTexture(GL_TEXTURE_2D, texture);
1921     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, kSize, kSize, 0);
1922     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1923     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1924 
1925     // Bind the framebuffer to another texture.
1926     GLTexture color;
1927     glBindTexture(GL_TEXTURE_2D, color);
1928     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1929     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
1930     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1931 
1932     // Do whatever.
1933     glClear(GL_COLOR_BUFFER_BIT);
1934 
1935     // Rebind the framebuffer back to the original texture.
1936     glBindTexture(GL_TEXTURE_2D, colorMS);
1937     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
1938                                          colorMS, 0, 4);
1939 
1940     // Clear to green and blend blue into the multisampled color buffer.
1941     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
1942     glClear(GL_COLOR_BUFFER_BIT);
1943     glUseProgram(drawColor);
1944     glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
1945     glEnable(GL_BLEND);
1946     glBlendFunc(GL_ONE, GL_ONE);
1947     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
1948     ASSERT_GL_NO_ERROR();
1949 
1950     // Verify that the texture is now cyan
1951     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
1952     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::cyan);
1953     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::cyan);
1954     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::cyan);
1955 
1956     // For completeness, verify that the texture used as copy target is red.
1957     ASSERT_GL_NO_ERROR();
1958     verifyResults(texture, GLColor::red, kSize, 0, 0, kSize, kSize);
1959 
1960     ASSERT_GL_NO_ERROR();
1961 }
1962 
clearThenBlendCommon(bool useRenderbuffer)1963 void MultisampledRenderToTextureTest::clearThenBlendCommon(bool useRenderbuffer)
1964 {
1965     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
1966     constexpr GLsizei kSize = 64;
1967 
1968     setupCopyTexProgram();
1969 
1970     GLFramebuffer fboMS;
1971     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
1972 
1973     // Create multisampled framebuffer to draw into
1974     GLTexture textureMS;
1975     GLRenderbuffer renderbufferMS;
1976     createAndAttachColorAttachment(useRenderbuffer, kSize, GL_COLOR_ATTACHMENT0, nullptr,
1977                                    mTestSampleCount, &textureMS, &renderbufferMS);
1978     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1979 
1980     // Clear the framebuffer.
1981     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
1982     glClear(GL_COLOR_BUFFER_BIT);
1983 
1984     // Blend half-transparent green into the multisampled color buffer.
1985     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
1986     glUseProgram(drawColor);
1987     GLint colorUniformLocation =
1988         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
1989     ASSERT_NE(colorUniformLocation, -1);
1990 
1991     glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 0.5f);
1992     glEnable(GL_BLEND);
1993     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1994     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
1995     ASSERT_GL_NO_ERROR();
1996 
1997     // Verify that the texture is now yellow
1998     const GLColor kExpected(127, 127, 0, 191);
1999     EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpected, 1);
2000     EXPECT_PIXEL_COLOR_NEAR(kSize - 1, 0, kExpected, 1);
2001     EXPECT_PIXEL_COLOR_NEAR(0, kSize - 1, kExpected, 1);
2002     EXPECT_PIXEL_COLOR_NEAR(kSize - 1, kSize - 1, kExpected, 1);
2003 }
2004 
2005 // Clear then blend.  The clear should be applied correctly.
TEST_P(MultisampledRenderToTextureTest,ClearThenBlend)2006 TEST_P(MultisampledRenderToTextureTest, ClearThenBlend)
2007 {
2008     clearThenBlendCommon(false);
2009 }
2010 
2011 // Clear then blend.  The clear should be applied correctly.  Uses renderbuffer.
TEST_P(MultisampledRenderToTextureTest,RenderbufferClearThenBlend)2012 TEST_P(MultisampledRenderToTextureTest, RenderbufferClearThenBlend)
2013 {
2014     clearThenBlendCommon(true);
2015 }
2016 
depthStencilClearThenDrawCommon(bool useRenderbuffer)2017 void MultisampledRenderToTextureES3Test::depthStencilClearThenDrawCommon(bool useRenderbuffer)
2018 {
2019     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
2020     if (!useRenderbuffer)
2021     {
2022         ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture2"));
2023     }
2024 
2025     // http://anglebug.com/5083
2026     ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsVulkan());
2027 
2028     constexpr GLsizei kSize = 64;
2029 
2030     setupCopyTexProgram();
2031 
2032     GLFramebuffer fboMS;
2033     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
2034 
2035     // Create framebuffer to draw into, with both color and depth attachments.
2036     GLTexture textureMS;
2037     GLRenderbuffer renderbufferMS;
2038     createAndAttachColorAttachment(useRenderbuffer, kSize, GL_COLOR_ATTACHMENT0, nullptr,
2039                                    mTestSampleCount, &textureMS, &renderbufferMS);
2040 
2041     GLTexture dsTextureMS;
2042     GLRenderbuffer dsRenderbufferMS;
2043     createAndAttachDepthStencilAttachment(useRenderbuffer, kSize, &dsTextureMS, &dsRenderbufferMS);
2044     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2045 
2046     // Set viewport and clear depth/stencil
2047     glViewport(0, 0, kSize, kSize);
2048     glClearDepthf(1);
2049     glClearStencil(0x55);
2050     glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2051 
2052     // If depth is not cleared to 1, rendering would fail.
2053     glEnable(GL_DEPTH_TEST);
2054     glDepthFunc(GL_LESS);
2055 
2056     // If stencil is not cleared to 0x55, rendering would fail.
2057     glEnable(GL_STENCIL_TEST);
2058     glStencilFunc(GL_EQUAL, 0x55, 0xFF);
2059     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
2060     glStencilMask(0xFF);
2061 
2062     // Set up program
2063     ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
2064 
2065     // Draw red
2066     drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.0f);
2067     ASSERT_GL_NO_ERROR();
2068 
2069     // Create a texture and copy into it.
2070     GLTexture texture;
2071     glBindTexture(GL_TEXTURE_2D, texture);
2072     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, kSize, kSize, 0);
2073     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2074     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2075     ASSERT_GL_NO_ERROR();
2076 
2077     // Verify.
2078     verifyResults(texture, GLColor::red, kSize, 0, 0, kSize, kSize);
2079 }
2080 
2081 // Clear depth stencil, then draw.  The clear should be applied correctly.
TEST_P(MultisampledRenderToTextureES3Test,DepthStencilClearThenDraw)2082 TEST_P(MultisampledRenderToTextureES3Test, DepthStencilClearThenDraw)
2083 {
2084     depthStencilClearThenDrawCommon(false);
2085 }
2086 
2087 // Clear depth stencil, then draw.  The clear should be applied correctly.  Uses renderbuffer.
TEST_P(MultisampledRenderToTextureES3Test,RenderbufferDepthStencilClearThenDraw)2088 TEST_P(MultisampledRenderToTextureES3Test, RenderbufferDepthStencilClearThenDraw)
2089 {
2090     depthStencilClearThenDrawCommon(true);
2091 }
2092 
2093 // Clear&Draw, copy, then blend similarly to RenderbufferClearDrawCopyThenBlendSameProgram.  This
2094 // tests uses a depth/stencil buffer and makes sure the second draw (in the second render pass)
2095 // succeeds (i.e. depth/stencil data is not lost).  Note that this test doesn't apply to
2096 // depth/stencil textures as they are explicitly autoinvalidated between render passes.
TEST_P(MultisampledRenderToTextureES3Test,RenderbufferDepthStencilClearDrawCopyThenBlend)2097 TEST_P(MultisampledRenderToTextureES3Test, RenderbufferDepthStencilClearDrawCopyThenBlend)
2098 {
2099     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
2100 
2101     // http://anglebug.com/5083
2102     ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsVulkan());
2103 
2104     // http://anglebug.com/5096
2105     ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsVulkan());
2106 
2107     // http://anglebug.com/5380
2108     ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsVulkan());
2109 
2110     constexpr GLsizei kSize = 64;
2111 
2112     setupCopyTexProgram();
2113 
2114     GLFramebuffer fbo;
2115     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2116 
2117     // Create framebuffer to draw into, with both color and depth/stencil attachments.
2118     GLTexture color;
2119     glBindTexture(GL_TEXTURE_2D, color);
2120     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2121     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color,
2122                                          0, 4);
2123 
2124     GLRenderbuffer depthStencil;
2125     glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
2126     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, kSize, kSize);
2127     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2128                               depthStencil);
2129     ASSERT_GL_NO_ERROR();
2130     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2131 
2132     // Set viewport and clear depth/stencil
2133     glViewport(0, 0, kSize, kSize);
2134     glClearDepthf(1);
2135     glClearStencil(0x55);
2136     glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2137 
2138     // If depth is not cleared to 1, rendering would fail.
2139     glEnable(GL_DEPTH_TEST);
2140     glDepthFunc(GL_LESS);
2141 
2142     // If stencil is not cleared to 0x55, rendering would fail.
2143     glEnable(GL_STENCIL_TEST);
2144     glStencilFunc(GL_EQUAL, 0x55, 0xFF);
2145     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
2146     glStencilMask(0xFF);
2147 
2148     // Set up program
2149     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
2150     glUseProgram(drawColor);
2151     GLint colorUniformLocation =
2152         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
2153     ASSERT_NE(colorUniformLocation, -1);
2154 
2155     // Draw red
2156     glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
2157     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.25f);
2158     ASSERT_GL_NO_ERROR();
2159 
2160     // Create a texture and copy into it.
2161     GLTexture texture;
2162     glBindTexture(GL_TEXTURE_2D, texture);
2163     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, kSize, kSize, 0);
2164     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2165     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2166     ASSERT_GL_NO_ERROR();
2167 
2168     // Draw again into the framebuffer, this time blending.  This tests that both the color and
2169     // depth/stencil data are preserved after the resolve incurred by the copy above.
2170     glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 0.5f);
2171     glEnable(GL_BLEND);
2172     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2173     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.0f);
2174     ASSERT_GL_NO_ERROR();
2175 
2176     // Verify that the texture is now yellow
2177     const GLColor kExpected(127, 127, 0, 191);
2178     EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpected, 1);
2179     EXPECT_PIXEL_COLOR_NEAR(kSize - 1, 0, kExpected, 1);
2180     EXPECT_PIXEL_COLOR_NEAR(0, kSize - 1, kExpected, 1);
2181     EXPECT_PIXEL_COLOR_NEAR(kSize - 1, kSize - 1, kExpected, 1);
2182 
2183     // For completeness, verify that the texture used as copy target is red.
2184     verifyResults(texture, GLColor::red, kSize, 0, 0, kSize, kSize);
2185 }
2186 
2187 // Draw, copy, then clear&blend.  This tests uses a depth/stencil buffer and makes sure the second
2188 // draw (in the second render pass) succeeds (i.e.  depth/stencil data is not lost).  The difference
2189 // with RenderbufferDepthStencilClearDrawCopyThenBlend is that color is cleared in the second render
2190 // pass, so only depth/stencil data is unresolved.  This test doesn't apply to depth/stencil
2191 // textures as they are explicitly autoinvalidated between render passes.
TEST_P(MultisampledRenderToTextureES3Test,RenderbufferDepthStencilDrawCopyClearThenBlend)2192 TEST_P(MultisampledRenderToTextureES3Test, RenderbufferDepthStencilDrawCopyClearThenBlend)
2193 {
2194     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
2195 
2196     // http://anglebug.com/5083
2197     ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsVulkan());
2198 
2199     // http://anglebug.com/5096
2200     ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsVulkan());
2201 
2202     // http://anglebug.com/5380
2203     ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsVulkan());
2204 
2205     constexpr GLsizei kSize = 64;
2206 
2207     setupCopyTexProgram();
2208 
2209     GLFramebuffer fbo;
2210     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
2211 
2212     // Create framebuffer to draw into, with both color and depth/stencil attachments.
2213     GLTexture color;
2214     glBindTexture(GL_TEXTURE_2D, color);
2215     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2216     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color,
2217                                          0, 4);
2218 
2219     GLRenderbuffer depthStencil;
2220     glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
2221     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, kSize, kSize);
2222     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2223                               depthStencil);
2224     ASSERT_GL_NO_ERROR();
2225     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2226 
2227     // Set viewport and clear depth/stencil through draw
2228     glViewport(0, 0, kSize, kSize);
2229 
2230     glEnable(GL_DEPTH_TEST);
2231     glDepthFunc(GL_ALWAYS);
2232 
2233     glEnable(GL_STENCIL_TEST);
2234     glStencilFunc(GL_ALWAYS, 0x55, 0xFF);
2235     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
2236     glStencilMask(0xFF);
2237 
2238     // Set up program
2239     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
2240     glUseProgram(drawColor);
2241     GLint colorUniformLocation =
2242         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
2243     ASSERT_NE(colorUniformLocation, -1);
2244 
2245     // Draw red
2246     glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
2247     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 1.0f);
2248     ASSERT_GL_NO_ERROR();
2249 
2250     // Create a texture and copy into it.
2251     GLTexture texture;
2252     glBindTexture(GL_TEXTURE_2D, texture);
2253     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, kSize, kSize, 0);
2254     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2255     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2256     ASSERT_GL_NO_ERROR();
2257 
2258     // Clear color to blue
2259     glClearColor(0.0, 0.0, 1.0, 1.0);
2260     glClear(GL_COLOR_BUFFER_BIT);
2261 
2262     // If depth is not cleared to 1, rendering would fail.
2263     glEnable(GL_DEPTH_TEST);
2264     glDepthFunc(GL_LESS);
2265 
2266     // If stencil is not cleared to 0x55, rendering would fail.
2267     glEnable(GL_STENCIL_TEST);
2268     glStencilFunc(GL_EQUAL, 0x55, 0xFF);
2269     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
2270     glStencilMask(0xFF);
2271 
2272     // Draw again into the framebuffer, this time blending.  This tests that depth/stencil data are
2273     // preserved after the resolve incurred by the copy above and color is cleared correctly.
2274     glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 0.5f);
2275     glEnable(GL_BLEND);
2276     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2277     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.0f);
2278     ASSERT_GL_NO_ERROR();
2279 
2280     // Copy into the texture again.
2281     glBindTexture(GL_TEXTURE_2D, texture);
2282     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, kSize, kSize, 0);
2283     ASSERT_GL_NO_ERROR();
2284 
2285     // Verify that the texture is now cyan
2286     const GLColor kExpected(0, 127, 127, 191);
2287     EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpected, 1);
2288     EXPECT_PIXEL_COLOR_NEAR(kSize - 1, 0, kExpected, 1);
2289     EXPECT_PIXEL_COLOR_NEAR(0, kSize - 1, kExpected, 1);
2290     EXPECT_PIXEL_COLOR_NEAR(kSize - 1, kSize - 1, kExpected, 1);
2291 
2292     // For completeness, verify that the texture used as copy target is also cyan.
2293     const GLColor expectedCopyResult(0, 127, 127, 191);
2294     verifyResults(texture, expectedCopyResult, kSize, 0, 0, kSize, kSize);
2295 }
2296 
2297 // Clear, then blit depth/stencil with renderbuffers.  This test makes sure depth/stencil blit uses
2298 // the correct image.  Note that this test doesn't apply to depth/stencil textures as they are
2299 // explicitly autoinvalidated between render passes.
TEST_P(MultisampledRenderToTextureES3Test,RenderbufferClearThenBlitDepthStencil)2300 TEST_P(MultisampledRenderToTextureES3Test, RenderbufferClearThenBlitDepthStencil)
2301 {
2302     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
2303 
2304     // D3D backend doesn't implement multisampled render to texture renderbuffers correctly.
2305     // http://anglebug.com/3107
2306     ANGLE_SKIP_TEST_IF(IsD3D());
2307 
2308     // The following trybot configurations don't support VK_KHR_depth_stencil_resolve.  ANGLE is not
2309     // conformant without this extension, but it's allowed as users commonly invalidate
2310     // depth/stencil.
2311     //
2312     //  - SwifthShader
2313     //  - Android
2314     //  - AMD
2315     //  - Nvidia on Windows7
2316     ANGLE_SKIP_TEST_IF(IsVulkan() &&
2317                        (isSwiftshader() || IsAndroid() || IsAMD() || (IsWindows7() && IsNVIDIA())));
2318 
2319     constexpr GLsizei kSize = 64;
2320 
2321     setupCopyTexProgram();
2322 
2323     GLFramebuffer fboMS;
2324     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
2325 
2326     // Create framebuffer to draw into, with both color and depth/stencil attachments.
2327     GLTexture color;
2328     glBindTexture(GL_TEXTURE_2D, color);
2329     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2330     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color,
2331                                          0, 4);
2332 
2333     GLRenderbuffer depthStencilMS;
2334     glBindRenderbuffer(GL_RENDERBUFFER, depthStencilMS);
2335     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, kSize, kSize);
2336     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2337                               depthStencilMS);
2338     ASSERT_GL_NO_ERROR();
2339     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2340 
2341     // Clear depth/stencil
2342     glClearDepthf(1);
2343     glClearStencil(0x55);
2344     glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2345 
2346     // Create framebuffer as blit target.
2347     GLFramebuffer fbo;
2348     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
2349 
2350     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
2351 
2352     GLRenderbuffer depthStencil;
2353     glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
2354     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);
2355     glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2356                               depthStencil);
2357     ASSERT_GL_NO_ERROR();
2358     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
2359 
2360     // Blit depth/stencil
2361     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize,
2362                       GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
2363 
2364     // Draw into the framebuffer that was the destination of blit, verifying that depth and stencil
2365     // values are correct.
2366 
2367     // If depth is not 1, rendering would fail.
2368     glEnable(GL_DEPTH_TEST);
2369     glDepthFunc(GL_LESS);
2370 
2371     // If stencil is not 0x55, rendering would fail.
2372     glEnable(GL_STENCIL_TEST);
2373     glStencilFunc(GL_EQUAL, 0x55, 0xFF);
2374     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
2375     glStencilMask(0xFF);
2376 
2377     // Set up program
2378     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
2379     glUseProgram(drawColor);
2380     GLint colorUniformLocation =
2381         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
2382     ASSERT_NE(colorUniformLocation, -1);
2383 
2384     // Draw red
2385     glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
2386     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.0f);
2387     ASSERT_GL_NO_ERROR();
2388 
2389     // Verify that the texture is now red
2390     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2391     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::red);
2392     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::red);
2393     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::red);
2394 
2395     // Clear depth/stencil to a different value, and blit again but this time flipped.
2396     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboMS);
2397     glClearDepthf(0);
2398     glClearStencil(0x3E);
2399     glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
2400 
2401     // Blit
2402     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
2403     glBlitFramebuffer(0, 0, kSize, kSize, kSize, kSize, 0, 0,
2404                       GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
2405 
2406     // Draw green
2407     glDepthFunc(GL_GREATER);
2408     glStencilFunc(GL_EQUAL, 0x3E, 0xFF);
2409     glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
2410     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.0f);
2411     ASSERT_GL_NO_ERROR();
2412 
2413     // Verify that the texture is now green
2414     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2415     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::green);
2416     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::green);
2417     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::green);
2418 }
2419 
2420 // Draw, then blit depth/stencil with renderbuffers.  This test makes sure depth/stencil resolve is
2421 // correctly implemented.  Note that this test doesn't apply to depth/stencil textures as they are
2422 // explicitly autoinvalidated between render passes.
TEST_P(MultisampledRenderToTextureES3Test,RenderbufferDrawThenBlitDepthStencil)2423 TEST_P(MultisampledRenderToTextureES3Test, RenderbufferDrawThenBlitDepthStencil)
2424 {
2425     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
2426 
2427     // Skip on configurations that don't support VK_KHR_depth_stencil_resolve.  See comment
2428     // in RenderbufferClearThenBlitDepthStencil.
2429     ANGLE_SKIP_TEST_IF(IsVulkan() &&
2430                        (isSwiftshader() || IsAndroid() || IsAMD() || (IsWindows7() && IsNVIDIA())));
2431 
2432     // http://anglebug.com/5096
2433     ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsVulkan());
2434 
2435     constexpr GLsizei kSize = 64;
2436 
2437     GLFramebuffer fboMS;
2438     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
2439 
2440     // Create framebuffer to draw into, with both color and depth/stencil attachments.
2441     GLTexture color;
2442     glBindTexture(GL_TEXTURE_2D, color);
2443     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2444     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color,
2445                                          0, 4);
2446 
2447     GLRenderbuffer depthStencilMS;
2448     glBindRenderbuffer(GL_RENDERBUFFER, depthStencilMS);
2449     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, kSize, kSize);
2450     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2451                               depthStencilMS);
2452     ASSERT_GL_NO_ERROR();
2453     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2454 
2455     // Set up program
2456     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
2457     glUseProgram(drawColor);
2458     GLint colorUniformLocation =
2459         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
2460     ASSERT_NE(colorUniformLocation, -1);
2461 
2462     // Output depth/stencil through draw
2463     glEnable(GL_DEPTH_TEST);
2464     glDepthFunc(GL_ALWAYS);
2465 
2466     glEnable(GL_STENCIL_TEST);
2467     glStencilFunc(GL_ALWAYS, 0x55, 0xFF);
2468     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
2469     glStencilMask(0xFF);
2470 
2471     // Draw blue
2472     glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
2473     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 1.0f);
2474     ASSERT_GL_NO_ERROR();
2475 
2476     // Create framebuffer as blit target.
2477     GLFramebuffer fbo;
2478     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
2479 
2480     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
2481 
2482     GLRenderbuffer depthStencil;
2483     glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
2484     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);
2485     glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2486                               depthStencil);
2487     ASSERT_GL_NO_ERROR();
2488     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
2489 
2490     // Blit depth/stencil
2491     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize,
2492                       GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
2493 
2494     // Draw into the framebuffer that was the destination of blit, verifying that depth and stencil
2495     // values are correct.
2496 
2497     // If depth is not 1, rendering would fail.
2498     glDepthFunc(GL_LESS);
2499 
2500     // If stencil is not 0x55, rendering would fail.
2501     glStencilFunc(GL_EQUAL, 0x55, 0xFF);
2502     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
2503     glStencilMask(0xFF);
2504 
2505     // Draw red
2506     glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
2507     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.0f);
2508     ASSERT_GL_NO_ERROR();
2509 
2510     // Verify that the texture is now red
2511     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2512     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::red);
2513     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::red);
2514     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::red);
2515 }
2516 
2517 // Draw, then blit depth/stencil with renderbuffers, without a color attachment. Note that this test
2518 // doesn't apply to depth/stencil textures as they are explicitly autoinvalidated between render
2519 // passes.
2520 //
2521 // This test first uses a draw call to fill in the depth/stencil buffer, then blits it to force a
2522 // resolve.  Then it uses a no-op draw call to start a "fullscreen" render pass followed by a
2523 // scissored draw to modify parts of the depth buffer:
2524 //
2525 // +--------------------+
2526 // |     D=1, S=0x55    |
2527 // |                    |
2528 // |     +--------+     |
2529 // |     |  D=0   |     |
2530 // |     | S=0xAA |     |
2531 // |     +--------+     |
2532 // |                    |
2533 // |                    |
2534 // +--------------------+
2535 //
2536 // Blit is used again to copy the depth/stencil attachment data, and the result is verified.
TEST_P(MultisampledRenderToTextureES3Test,RenderbufferDrawThenBlitDepthStencilOnly)2537 TEST_P(MultisampledRenderToTextureES3Test, RenderbufferDrawThenBlitDepthStencilOnly)
2538 {
2539     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
2540 
2541     // Skip on configurations that don't support VK_KHR_depth_stencil_resolve.  See comment
2542     // in RenderbufferClearThenBlitDepthStencil.
2543     ANGLE_SKIP_TEST_IF(IsVulkan() &&
2544                        (isSwiftshader() || IsAndroid() || IsAMD() || (IsWindows7() && IsNVIDIA())));
2545 
2546     // http://anglebug.com/5096
2547     ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsVulkan());
2548 
2549     // http://anglebug.com/5110
2550     ANGLE_SKIP_TEST_IF(IsD3D());
2551 
2552     constexpr GLsizei kSize = 64;
2553 
2554     GLFramebuffer fboMS;
2555     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
2556 
2557     // Create framebuffer to draw into, with depth/stencil attachment only.
2558     GLRenderbuffer depthStencilMS;
2559     glBindRenderbuffer(GL_RENDERBUFFER, depthStencilMS);
2560     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_DEPTH24_STENCIL8, kSize, kSize);
2561     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2562                               depthStencilMS);
2563     ASSERT_GL_NO_ERROR();
2564     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2565 
2566     // Set up program
2567     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
2568     glUseProgram(drawColor);
2569     GLint colorUniformLocation =
2570         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
2571     ASSERT_NE(colorUniformLocation, -1);
2572     glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
2573 
2574     // Output depth/stencil through draw
2575     glEnable(GL_DEPTH_TEST);
2576     glDepthFunc(GL_ALWAYS);
2577 
2578     glEnable(GL_STENCIL_TEST);
2579     glStencilFunc(GL_ALWAYS, 0x55, 0xFF);
2580     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
2581     glStencilMask(0xFF);
2582 
2583     // Draw.  Depth/stencil is now:
2584     //
2585     // +--------------------+
2586     // |     D=1, S=0x55    |
2587     // |                    |
2588     // |                    |
2589     // |                    |
2590     // |                    |
2591     // |                    |
2592     // |                    |
2593     // |                    |
2594     // +--------------------+
2595     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 1.0f);
2596     ASSERT_GL_NO_ERROR();
2597 
2598     // Create framebuffer as blit target.
2599     GLFramebuffer fbo;
2600     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
2601 
2602     GLRenderbuffer depthStencil;
2603     glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
2604     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, kSize, kSize);
2605     glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
2606                               depthStencil);
2607     ASSERT_GL_NO_ERROR();
2608     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
2609 
2610     // Blit depth/stencil
2611     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize,
2612                       GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
2613 
2614     // Disable depth/stencil and draw again.  Depth/stencil is not modified.
2615     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboMS);
2616     glDisable(GL_DEPTH_TEST);
2617     glDisable(GL_STENCIL_TEST);
2618     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.0f);
2619     ASSERT_GL_NO_ERROR();
2620 
2621     // Enable depth/stencil and do a scissored draw.  Depth/stencil is now:
2622     //
2623     // +--------------------+
2624     // |     D=1, S=0x55    |
2625     // |                    |
2626     // |     +--------+     |
2627     // |     |  D=0   |     |
2628     // |     | S=0xAA |     |
2629     // |     +--------+     |
2630     // |                    |
2631     // |                    |
2632     // +--------------------+
2633     glEnable(GL_DEPTH_TEST);
2634     glEnable(GL_STENCIL_TEST);
2635     glStencilFunc(GL_ALWAYS, 0xAA, 0xFF);
2636     glEnable(GL_SCISSOR_TEST);
2637     glScissor(kSize / 4, kSize / 4, kSize / 2, kSize / 2);
2638     drawQuad(drawColor, essl1_shaders::PositionAttrib(), -1.0f);
2639     glDisable(GL_SCISSOR_TEST);
2640     ASSERT_GL_NO_ERROR();
2641 
2642     // Blit depth/stencil again.
2643     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
2644     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize,
2645                       GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
2646     ASSERT_GL_NO_ERROR();
2647 
2648     // Draw into the framebuffer that was the destination of blit, verifying that depth and stencil
2649     // values are correct.
2650     GLTexture color;
2651     glBindTexture(GL_TEXTURE_2D, color);
2652     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2653     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
2654     ASSERT_GL_NO_ERROR();
2655     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
2656 
2657     // First, verify the outside border, where D=1 and S=0x55
2658     glDepthFunc(GL_LESS);
2659     glStencilFunc(GL_EQUAL, 0x55, 0xFF);
2660     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
2661     glStencilMask(0xFF);
2662     ASSERT_GL_NO_ERROR();
2663 
2664     // Draw green
2665     glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
2666     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.95f);
2667     ASSERT_GL_NO_ERROR();
2668 
2669     // Then, verify the center, where D=0 and S=0xAA
2670     glDepthFunc(GL_GREATER);
2671     glStencilFunc(GL_EQUAL, 0xAA, 0xFF);
2672     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
2673     glStencilMask(0xFF);
2674 
2675     // Draw blue
2676     glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
2677     drawQuad(drawColor, essl1_shaders::PositionAttrib(), -0.95f);
2678     ASSERT_GL_NO_ERROR();
2679 
2680     // Verify that the border is now green
2681     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
2682     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2683     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::green);
2684     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::green);
2685     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::green);
2686 
2687     // Verify that the center is now blue
2688     EXPECT_PIXEL_COLOR_EQ(kSize / 4, kSize / 4, GLColor::blue);
2689     EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, kSize / 4, GLColor::blue);
2690     EXPECT_PIXEL_COLOR_EQ(kSize / 4, 3 * kSize / 4 - 1, GLColor::blue);
2691     EXPECT_PIXEL_COLOR_EQ(3 * kSize / 4 - 1, 3 * kSize / 4 - 1, GLColor::blue);
2692     EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::blue);
2693 }
2694 
2695 // Test the depth read/write mode change within the renderpass while there is color unresolve
2696 // attachment
TEST_P(MultisampledRenderToTextureTest,DepthReadWriteToggleWithStartedRenderPass)2697 TEST_P(MultisampledRenderToTextureTest, DepthReadWriteToggleWithStartedRenderPass)
2698 {
2699     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
2700 
2701     // http://anglebug.com/5380
2702     ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsVulkan());
2703 
2704     constexpr GLsizei kSize = 64;
2705 
2706     setupCopyTexProgram();
2707 
2708     GLFramebuffer fboMS;
2709     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
2710 
2711     // Create framebuffer to draw into, with both color and depth attachments.
2712     GLTexture textureMS;
2713     GLRenderbuffer renderbufferMS;
2714     createAndAttachColorAttachment(true, kSize, GL_COLOR_ATTACHMENT0, nullptr, mTestSampleCount,
2715                                    &textureMS, &renderbufferMS);
2716 
2717     GLTexture dsTextureMS;
2718     GLRenderbuffer dsRenderbufferMS;
2719     glBindRenderbuffer(GL_RENDERBUFFER, dsRenderbufferMS);
2720     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_DEPTH_COMPONENT16, kSize, kSize);
2721     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
2722                               dsRenderbufferMS);
2723     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2724 
2725     // First renderpass: draw with depth value 0.5f
2726     glViewport(0, 0, kSize, kSize);
2727     glEnable(GL_DEPTH_TEST);
2728     glDepthFunc(GL_ALWAYS);
2729     glDepthMask(GL_TRUE);
2730     glClearColor(0.0, 0.0, 0.0, 1.0);
2731     glClear(GL_COLOR_BUFFER_BIT);
2732     glEnable(GL_BLEND);
2733     glBlendFunc(GL_ONE, GL_ZERO);
2734     ANGLE_GL_PROGRAM(drawBlue, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
2735     drawQuad(drawBlue, essl1_shaders::PositionAttrib(), 0.5f);
2736     ASSERT_GL_NO_ERROR();
2737     // The color check should end the renderpass
2738     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
2739 
2740     // Create another FBO and render, jus so try to clear rendering cache. At least on pixel4,
2741     // the test now properly fail if I force the loadOP to DontCare in the next renderpass.
2742     constexpr bool clearRenderingCacheWithFBO = true;
2743     if (clearRenderingCacheWithFBO)
2744     {
2745         GLFramebuffer fboMS2;
2746         glBindFramebuffer(GL_FRAMEBUFFER, fboMS2);
2747         GLTexture textureMS2;
2748         GLRenderbuffer renderbufferMS2;
2749         createAndAttachColorAttachment(true, 2048, GL_COLOR_ATTACHMENT0, nullptr, mTestSampleCount,
2750                                        &textureMS2, &renderbufferMS2);
2751         GLTexture dsTextureMS2;
2752         GLRenderbuffer dsRenderbufferMS2;
2753         glBindRenderbuffer(GL_RENDERBUFFER, dsRenderbufferMS2);
2754         glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_DEPTH_COMPONENT16, 2048, 2048);
2755         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
2756                                   dsRenderbufferMS2);
2757         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2758         ASSERT_GL_NO_ERROR();
2759         glViewport(0, 0, 2048, 2048);
2760         ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
2761         glUseProgram(drawColor);
2762         GLint colorUniformLocation =
2763             glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
2764         ASSERT_NE(colorUniformLocation, -1);
2765         glUniform4f(colorUniformLocation, 0.0f, 0.0f, 0.0f, 0.0f);
2766         drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
2767         ASSERT_GL_NO_ERROR();
2768     }
2769 
2770     // Second renderpass: Start with depth read only and then switch to depth write
2771     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
2772     glViewport(0, 0, kSize, kSize);
2773     glDepthFunc(GL_LESS);
2774     // Draw red with depth read only. pass depth test, Result: color=Red, depth=0.5
2775     glDepthMask(GL_FALSE);
2776     glBlendFunc(GL_ONE, GL_ONE);
2777     ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
2778     glUseProgram(drawRed);
2779     drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.1f);
2780     ASSERT_GL_NO_ERROR();
2781 
2782     // Draw green with depth write. Pass depth test. Result: color=Green, depth=0.3
2783     glDepthMask(GL_TRUE);
2784     glBlendFunc(GL_ONE, GL_ONE);
2785     ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
2786     glUseProgram(drawGreen);
2787     drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.3f);
2788     ASSERT_GL_NO_ERROR();
2789 
2790     // Create a texture and copy into it.
2791     GLTexture texture;
2792     glBindTexture(GL_TEXTURE_2D, texture);
2793     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, kSize, kSize, 0);
2794     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2795     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2796     ASSERT_GL_NO_ERROR();
2797 
2798     // Verify the color has all three color in it.
2799     EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::white);
2800 }
2801 
colorAttachment1Common(bool useRenderbuffer)2802 void MultisampledRenderToTextureES3Test::colorAttachment1Common(bool useRenderbuffer)
2803 {
2804     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
2805     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture2"));
2806     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_draw_buffers"));
2807 
2808     // Qualcomm driver crashes in the presence of VK_ATTACHMENT_UNUSED.
2809     // http://anglebug.com/3423
2810     ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
2811 
2812     // Fails on Intel Ubuntu 19.04 Mesa 19.0.2 Vulkan. http://anglebug.com/3616
2813     ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsVulkan());
2814 
2815     constexpr GLsizei kSize = 64;
2816 
2817     setupCopyTexProgram();
2818 
2819     GLFramebuffer fboMS;
2820     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
2821 
2822     // Create multisampled framebuffer to draw into, use color attachment 1
2823     GLTexture textureMS;
2824     GLRenderbuffer renderbufferMS;
2825     createAndAttachColorAttachment(useRenderbuffer, kSize, GL_COLOR_ATTACHMENT1, nullptr,
2826                                    mTestSampleCount, &textureMS, &renderbufferMS);
2827     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2828 
2829     // Setup program to render into attachment 1.
2830     constexpr bool kBuffersEnabled[8] = {false, true};
2831 
2832     GLuint drawColor;
2833     setupUniformColorProgramMultiRenderTarget(kBuffersEnabled, &drawColor);
2834     glUseProgram(drawColor);
2835     GLint colorUniformLocation =
2836         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
2837     ASSERT_NE(colorUniformLocation, -1);
2838 
2839     constexpr GLenum kDrawBuffers[] = {GL_NONE, GL_COLOR_ATTACHMENT1};
2840     glDrawBuffers(2, kDrawBuffers);
2841     glReadBuffer(GL_COLOR_ATTACHMENT1);
2842     ASSERT_GL_NO_ERROR();
2843 
2844     // Draw red into the multisampled color buffer.
2845     glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
2846     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
2847     ASSERT_GL_NO_ERROR();
2848 
2849     // Create a texture and copy into it.
2850     GLTexture texture;
2851     glBindTexture(GL_TEXTURE_2D, texture);
2852     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, kSize, kSize, 0);
2853     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2854     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2855     ASSERT_GL_NO_ERROR();
2856 
2857     // Blend half-transparent green into the multisampled color buffer.
2858     glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 0.5f);
2859     glEnable(GL_BLEND);
2860     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2861     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
2862     ASSERT_GL_NO_ERROR();
2863 
2864     // Verify that the texture is now yellow
2865     const GLColor kExpected(127, 127, 0, 191);
2866     EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpected, 1);
2867     EXPECT_PIXEL_COLOR_NEAR(kSize - 1, 0, kExpected, 1);
2868     EXPECT_PIXEL_COLOR_NEAR(0, kSize - 1, kExpected, 1);
2869     EXPECT_PIXEL_COLOR_NEAR(kSize - 1, kSize - 1, kExpected, 1);
2870 
2871     // For completeness, verify that the texture used as copy target is red.
2872     verifyResults(texture, GLColor::red, kSize, 0, 0, kSize, kSize);
2873 
2874     ASSERT_GL_NO_ERROR();
2875 
2876     glDeleteProgram(drawColor);
2877 }
2878 
2879 // Draw, copy, then blend.  The copy will make sure an implicit resolve happens.  Regardless, the
2880 // following draw should retain the data written by the first draw command.
2881 // Uses color attachment 1.
TEST_P(MultisampledRenderToTextureES3Test,ColorAttachment1)2882 TEST_P(MultisampledRenderToTextureES3Test, ColorAttachment1)
2883 {
2884     colorAttachment1Common(false);
2885 }
2886 
2887 // Draw, copy, then blend.  The copy will make sure an implicit resolve happens.  Regardless, the
2888 // following draw should retain the data written by the first draw command.
2889 // Uses color attachment 1.  Uses renderbuffer.
TEST_P(MultisampledRenderToTextureES3Test,RenderbufferColorAttachment1)2890 TEST_P(MultisampledRenderToTextureES3Test, RenderbufferColorAttachment1)
2891 {
2892     colorAttachment1Common(true);
2893 }
2894 
colorAttachments0And3Common(bool useRenderbuffer)2895 void MultisampledRenderToTextureES3Test::colorAttachments0And3Common(bool useRenderbuffer)
2896 {
2897     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
2898     ANGLE_SKIP_TEST_IF(!useRenderbuffer &&
2899                        !EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture2"));
2900     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_draw_buffers"));
2901 
2902     // Qualcomm driver crashes in the presence of VK_ATTACHMENT_UNUSED.
2903     // http://anglebug.com/3423
2904     ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
2905 
2906     constexpr GLsizei kSize = 64;
2907 
2908     setupCopyTexProgram();
2909 
2910     GLFramebuffer fboMS;
2911     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
2912 
2913     // Create multisampled framebuffer to draw into, use color attachment 1
2914     GLTexture textureMS0;
2915     GLRenderbuffer renderbufferMS0;
2916     createAndAttachColorAttachment(useRenderbuffer, kSize, GL_COLOR_ATTACHMENT0, nullptr,
2917                                    mTestSampleCount, &textureMS0, &renderbufferMS0);
2918 
2919     GLTexture textureMS3;
2920     GLRenderbuffer renderbufferMS3;
2921     createAndAttachColorAttachment(useRenderbuffer, kSize, GL_COLOR_ATTACHMENT3, nullptr,
2922                                    mTestSampleCount, &textureMS3, &renderbufferMS3);
2923 
2924     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
2925 
2926     // Setup program to render into attachments 0 and 3.
2927     constexpr bool kBuffersEnabled[8] = {true, false, false, true};
2928 
2929     GLuint drawColor;
2930     setupUniformColorProgramMultiRenderTarget(kBuffersEnabled, &drawColor);
2931     glUseProgram(drawColor);
2932     GLint colorUniformLocation =
2933         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
2934     ASSERT_NE(colorUniformLocation, -1);
2935 
2936     constexpr GLenum kDrawBuffers[] = {GL_COLOR_ATTACHMENT0, GL_NONE, GL_NONE,
2937                                        GL_COLOR_ATTACHMENT3};
2938     glDrawBuffers(4, kDrawBuffers);
2939     glReadBuffer(GL_COLOR_ATTACHMENT3);
2940     ASSERT_GL_NO_ERROR();
2941 
2942     // Draw red into the multisampled color buffers.
2943     glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
2944     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
2945     ASSERT_GL_NO_ERROR();
2946 
2947     // Create a texture and copy from one of them.
2948     GLTexture texture;
2949     glBindTexture(GL_TEXTURE_2D, texture);
2950     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, kSize, kSize, 0);
2951     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2952     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2953     ASSERT_GL_NO_ERROR();
2954 
2955     // Blend half-transparent green into the multisampled color buffers.
2956     glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 0.5f);
2957     glEnable(GL_BLEND);
2958     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2959     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
2960     ASSERT_GL_NO_ERROR();
2961 
2962     // Verify that the textures are now yellow
2963     const GLColor kExpected(127, 127, 0, 191);
2964     EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpected, 1);
2965     EXPECT_PIXEL_COLOR_NEAR(kSize - 1, 0, kExpected, 1);
2966     EXPECT_PIXEL_COLOR_NEAR(0, kSize - 1, kExpected, 1);
2967     EXPECT_PIXEL_COLOR_NEAR(kSize - 1, kSize - 1, kExpected, 1);
2968 
2969     glReadBuffer(GL_COLOR_ATTACHMENT0);
2970     EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpected, 1);
2971     EXPECT_PIXEL_COLOR_NEAR(kSize - 1, 0, kExpected, 1);
2972     EXPECT_PIXEL_COLOR_NEAR(0, kSize - 1, kExpected, 1);
2973     EXPECT_PIXEL_COLOR_NEAR(kSize - 1, kSize - 1, kExpected, 1);
2974 
2975     // For completeness, verify that the texture used as copy target is red.
2976     verifyResults(texture, GLColor::red, kSize, 0, 0, kSize, kSize);
2977 
2978     ASSERT_GL_NO_ERROR();
2979 
2980     glDeleteProgram(drawColor);
2981 }
2982 
2983 // Draw, copy, then blend.  The copy will make sure an implicit resolve happens.  Regardless, the
2984 // following draw should retain the data written by the first draw command.
2985 // Uses color attachments 0 and 3.
TEST_P(MultisampledRenderToTextureES3Test,ColorAttachments0And3)2986 TEST_P(MultisampledRenderToTextureES3Test, ColorAttachments0And3)
2987 {
2988     colorAttachments0And3Common(false);
2989 }
2990 
2991 // Draw, copy, then blend.  The copy will make sure an implicit resolve happens.  Regardless, the
2992 // following draw should retain the data written by the first draw command.
2993 // Uses color attachments 0 and 3.  Uses renderbuffer.
TEST_P(MultisampledRenderToTextureES3Test,RenderbufferColorAttachments0And3)2994 TEST_P(MultisampledRenderToTextureES3Test, RenderbufferColorAttachments0And3)
2995 {
2996     colorAttachments0And3Common(true);
2997 }
2998 
2999 // Draw with depth buffer.  Uses EXT_multisampled_render_to_texture2.
3000 // The test works with a 64x1 texture.  The first draw call will render geometry whose depth is
3001 // different between top and bottom.  The second draw call will enable depth test and draw with the
3002 // average of the two depths.  Only half of the samples will take the new color.  Once resolved, the
3003 // expected color would be the average of the two draw colors.
TEST_P(MultisampledRenderToTextureES3Test,DepthStencilAttachment)3004 TEST_P(MultisampledRenderToTextureES3Test, DepthStencilAttachment)
3005 {
3006     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
3007     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture2"));
3008 
3009     constexpr GLsizei kWidth = 64;
3010 
3011     // Create multisampled framebuffer to draw into, with both color and depth attachments.
3012     GLTexture colorMS;
3013     glBindTexture(GL_TEXTURE_2D, colorMS);
3014     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3015 
3016     GLTexture depthMS;
3017     glBindTexture(GL_TEXTURE_2D, depthMS);
3018     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, kWidth, 1, 0, GL_DEPTH_STENCIL,
3019                  GL_UNSIGNED_INT_24_8_OES, nullptr);
3020 
3021     GLFramebuffer fboMS;
3022     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
3023     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
3024                                          colorMS, 0, 4);
3025     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
3026                                          depthMS, 0, 4);
3027     ASSERT_GL_NO_ERROR();
3028 
3029     // Setup draw program
3030     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
3031     glUseProgram(drawColor);
3032     GLint colorUniformLocation =
3033         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
3034     ASSERT_NE(colorUniformLocation, -1);
3035     GLint positionLocation = glGetAttribLocation(drawColor, essl1_shaders::PositionAttrib());
3036     ASSERT_NE(-1, positionLocation);
3037 
3038     // Setup vertices such that depth is varied from top to bottom.
3039     std::array<Vector3, 6> quadVertices = {
3040         Vector3(-1.0f, 1.0f, 0.8f), Vector3(-1.0f, -1.0f, 0.2f), Vector3(1.0f, -1.0f, 0.2f),
3041         Vector3(-1.0f, 1.0f, 0.8f), Vector3(1.0f, -1.0f, 0.2f),  Vector3(1.0f, 1.0f, 0.8f),
3042     };
3043     GLBuffer quadVertexBuffer;
3044     glBindBuffer(GL_ARRAY_BUFFER, quadVertexBuffer);
3045     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * 6, quadVertices.data(), GL_STATIC_DRAW);
3046     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
3047     glEnableVertexAttribArray(positionLocation);
3048 
3049     // Draw red into the framebuffer.
3050     glViewport(0, 0, kWidth, 1);
3051     glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
3052     glEnable(GL_DEPTH_TEST);
3053     glDepthFunc(GL_ALWAYS);
3054     glDrawArrays(GL_TRIANGLES, 0, 6);
3055     ASSERT_GL_NO_ERROR();
3056 
3057     // Draw green such that half the samples of each pixel pass the depth test.
3058     glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
3059     glDepthFunc(GL_GREATER);
3060     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
3061     ASSERT_GL_NO_ERROR();
3062 
3063     const GLColor kExpected(127, 127, 0, 255);
3064     EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpected, 1);
3065     EXPECT_PIXEL_COLOR_NEAR(kWidth - 1, 0, kExpected, 1);
3066     EXPECT_PIXEL_COLOR_NEAR(kWidth / 2, 0, kExpected, 1);
3067 
3068     glDisableVertexAttribArray(0);
3069     glBindBuffer(GL_ARRAY_BUFFER, 0);
3070 }
3071 
3072 // Draw, copy, then blend.  The copy will make sure an implicit resolve happens.  Regardless, the
3073 // following draw should retain the data written by the first draw command.
3074 // Uses color attachments 0 and 1.  Attachment 0 is a normal multisampled texture, while attachment
3075 // 1 is a multisampled-render-to-texture texture.
TEST_P(MultisampledRenderToTextureES31Test,MixedMultisampledAndMultisampledRenderToTexture)3076 TEST_P(MultisampledRenderToTextureES31Test, MixedMultisampledAndMultisampledRenderToTexture)
3077 {
3078     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
3079     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture2"));
3080     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_draw_buffers"));
3081 
3082     constexpr GLsizei kSize = 64;
3083 
3084     setupCopyTexProgram();
3085 
3086     // Create multisampled framebuffer to draw into, use color attachment 1
3087     GLTexture colorMS0;
3088     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, colorMS0);
3089     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, true);
3090 
3091     GLTexture colorMS1;
3092     glBindTexture(GL_TEXTURE_2D, colorMS1);
3093     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3094 
3095     GLFramebuffer fboMS;
3096     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
3097     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
3098                            colorMS0, 0);
3099     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D,
3100                                          colorMS1, 0, 4);
3101     ASSERT_GL_NO_ERROR();
3102 
3103     // Setup program to render into attachments 0 and 1.
3104     constexpr bool kBuffersEnabled[8] = {true, true};
3105 
3106     GLuint drawColor;
3107     setupUniformColorProgramMultiRenderTarget(kBuffersEnabled, &drawColor);
3108     glUseProgram(drawColor);
3109     GLint colorUniformLocation =
3110         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
3111     ASSERT_NE(colorUniformLocation, -1);
3112 
3113     constexpr GLenum kDrawBuffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
3114     glDrawBuffers(2, kDrawBuffers);
3115     glReadBuffer(GL_COLOR_ATTACHMENT1);
3116     ASSERT_GL_NO_ERROR();
3117 
3118     // Draw red into the multisampled color buffers.
3119     glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
3120     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
3121     ASSERT_GL_NO_ERROR();
3122 
3123     // Create a texture and copy from one of them.
3124     GLTexture texture;
3125     glBindTexture(GL_TEXTURE_2D, texture);
3126     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, kSize, kSize, 0);
3127     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3128     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3129     ASSERT_GL_NO_ERROR();
3130 
3131     // Blend half-transparent green into the multisampled color buffers.
3132     glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 0.5f);
3133     glEnable(GL_BLEND);
3134     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
3135     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
3136     ASSERT_GL_NO_ERROR();
3137 
3138     // Verify that the textures are now yellow
3139     const GLColor kExpected(127, 127, 0, 191);
3140     EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpected, 1);
3141     EXPECT_PIXEL_COLOR_NEAR(kSize - 1, 0, kExpected, 1);
3142     EXPECT_PIXEL_COLOR_NEAR(0, kSize - 1, kExpected, 1);
3143     EXPECT_PIXEL_COLOR_NEAR(kSize - 1, kSize - 1, kExpected, 1);
3144 
3145     // For completeness, verify that the texture used as copy target is red.
3146     verifyResults(texture, GLColor::red, kSize, 0, 0, kSize, kSize);
3147 
3148     ASSERT_GL_NO_ERROR();
3149 
3150     glDeleteProgram(drawColor);
3151 }
3152 
blitFramebufferAttachment1Common(bool useRenderbuffer)3153 void MultisampledRenderToTextureES31Test::blitFramebufferAttachment1Common(bool useRenderbuffer)
3154 {
3155     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
3156     ANGLE_SKIP_TEST_IF(!useRenderbuffer &&
3157                        !EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture2"));
3158     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_draw_buffers"));
3159 
3160     constexpr GLsizei kSize = 16;
3161 
3162     GLFramebuffer fboMS;
3163     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
3164 
3165     // Create multisampled framebuffer to draw into, use color attachment 1
3166     GLTexture colorMS0;
3167     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, colorMS0);
3168     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 4, GL_RGBA8, kSize, kSize, true);
3169     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
3170                            colorMS0, 0);
3171 
3172     GLTexture textureMS1;
3173     GLRenderbuffer renderbufferMS1;
3174     createAndAttachColorAttachment(useRenderbuffer, kSize, GL_COLOR_ATTACHMENT1, nullptr,
3175                                    mTestSampleCount, &textureMS1, &renderbufferMS1);
3176     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3177 
3178     // Setup program to render into attachments 0 and 1.
3179     constexpr bool kBuffersEnabled[8] = {true, true};
3180 
3181     GLuint drawColor;
3182     setupUniformColorProgramMultiRenderTarget(kBuffersEnabled, &drawColor);
3183     glUseProgram(drawColor);
3184     GLint colorUniformLocation =
3185         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
3186     ASSERT_NE(colorUniformLocation, -1);
3187 
3188     constexpr GLenum kDrawBuffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
3189     glDrawBuffers(2, kDrawBuffers);
3190     glReadBuffer(GL_COLOR_ATTACHMENT1);
3191     ASSERT_GL_NO_ERROR();
3192 
3193     // Draw red into the multisampled color buffers.
3194     glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
3195     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
3196     ASSERT_GL_NO_ERROR();
3197 
3198     // Create single sampled framebuffer to use as dest.
3199     GLFramebuffer fboSS;
3200     glBindFramebuffer(GL_FRAMEBUFFER, fboSS);
3201     GLTexture colorSS;
3202     glBindTexture(GL_TEXTURE_2D, colorSS);
3203     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3204     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorSS, 0);
3205     ASSERT_GL_NO_ERROR();
3206 
3207     // Bind MS to READ as SS is already bound to DRAW.
3208     glBindFramebuffer(GL_READ_FRAMEBUFFER, fboMS);
3209     glReadBuffer(GL_COLOR_ATTACHMENT1);
3210     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3211     ASSERT_GL_NO_ERROR();
3212 
3213     // Bind SS to READ so we can readPixels from it
3214     glBindFramebuffer(GL_FRAMEBUFFER, fboSS);
3215 
3216     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3217     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::red);
3218     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::red);
3219     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::red);
3220     EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::red);
3221     ASSERT_GL_NO_ERROR();
3222 }
3223 
3224 // BlitFramebuffer functionality test with mixed color attachments where multisampled render to
3225 // texture as attachment 1 and is the read buffer.  This test makes sure the fact that attachment 0
3226 // is a true multisampled texture doesn't cause issues.
3227 // Uses EXT_multisampled_render_to_texture2.
TEST_P(MultisampledRenderToTextureES31Test,BlitFramebufferAttachment1)3228 TEST_P(MultisampledRenderToTextureES31Test, BlitFramebufferAttachment1)
3229 {
3230     blitFramebufferAttachment1Common(false);
3231 }
3232 
3233 // BlitFramebuffer functionality test with mixed color attachments where multisampled render to
3234 // texture as attachment 1 and is the read buffer.  This test makes sure the fact that attachment 0
3235 // is a true multisampled texture doesn't cause issues.
3236 // Uses renderbuffer.
TEST_P(MultisampledRenderToTextureES31Test,RenderbufferBlitFramebufferAttachment1)3237 TEST_P(MultisampledRenderToTextureES31Test, RenderbufferBlitFramebufferAttachment1)
3238 {
3239     blitFramebufferAttachment1Common(true);
3240 }
3241 
blitFramebufferMixedColorAndDepthCommon(bool useRenderbuffer)3242 void MultisampledRenderToTextureES3Test::blitFramebufferMixedColorAndDepthCommon(
3243     bool useRenderbuffer)
3244 {
3245     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
3246 
3247     constexpr GLsizei kSize = 16;
3248 
3249     GLFramebuffer fboMS;
3250     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
3251 
3252     // Create multisampled framebuffer to use as source.
3253     GLRenderbuffer depthMS;
3254     glBindRenderbuffer(GL_RENDERBUFFER, depthMS);
3255     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_DEPTH_COMPONENT24, kSize, kSize);
3256     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthMS);
3257 
3258     GLTexture textureMS;
3259     GLRenderbuffer renderbufferMS;
3260     createAndAttachColorAttachment(useRenderbuffer, kSize, GL_COLOR_ATTACHMENT0, nullptr,
3261                                    mTestSampleCount, &textureMS, &renderbufferMS);
3262     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3263 
3264     // Clear depth to 0.5 and color to red.
3265     glClearDepthf(0.5f);
3266     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
3267     glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
3268     ASSERT_GL_NO_ERROR();
3269 
3270     // Create single sampled framebuffer to use as dest.
3271     GLRenderbuffer depthSS;
3272     glBindRenderbuffer(GL_RENDERBUFFER, depthSS);
3273     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, kSize, kSize);
3274 
3275     GLTexture colorSS;
3276     glBindTexture(GL_TEXTURE_2D, colorSS);
3277     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3278 
3279     GLFramebuffer fboSS;
3280     glBindFramebuffer(GL_FRAMEBUFFER, fboSS);
3281     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthSS);
3282     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorSS, 0);
3283     ASSERT_GL_NO_ERROR();
3284 
3285     // Bind MS to READ as SS is already bound to DRAW.
3286     glBindFramebuffer(GL_READ_FRAMEBUFFER, fboMS);
3287     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize,
3288                       GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
3289     ASSERT_GL_NO_ERROR();
3290 
3291     // Bind SS to READ so we can readPixels from it
3292     glBindFramebuffer(GL_FRAMEBUFFER, fboSS);
3293 
3294     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3295     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::red);
3296     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::red);
3297     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::red);
3298     EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::red);
3299     ASSERT_GL_NO_ERROR();
3300 
3301     // Use a small shader to verify depth.
3302     ANGLE_GL_PROGRAM(depthTestProgram, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Blue());
3303     ANGLE_GL_PROGRAM(depthTestProgramFail, essl1_shaders::vs::Passthrough(),
3304                      essl1_shaders::fs::Green());
3305     glEnable(GL_DEPTH_TEST);
3306     glDepthFunc(GL_LESS);
3307     drawQuad(depthTestProgram, essl1_shaders::PositionAttrib(), -0.01f);
3308     drawQuad(depthTestProgramFail, essl1_shaders::PositionAttrib(), 0.01f);
3309     glDisable(GL_DEPTH_TEST);
3310     ASSERT_GL_NO_ERROR();
3311 
3312     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
3313     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::blue);
3314     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::blue);
3315     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::blue);
3316     EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::blue);
3317     ASSERT_GL_NO_ERROR();
3318 }
3319 
3320 // BlitFramebuffer functionality test with mixed multisampled-render-to-texture color attachment and
3321 // multisampled depth buffer.  This test makes sure that the color attachment is blitted, while
3322 // the depth/stencil attachment is resolved.
TEST_P(MultisampledRenderToTextureES3Test,BlitFramebufferMixedColorAndDepth)3323 TEST_P(MultisampledRenderToTextureES3Test, BlitFramebufferMixedColorAndDepth)
3324 {
3325     blitFramebufferMixedColorAndDepthCommon(false);
3326 }
3327 
3328 // BlitFramebuffer functionality test with mixed multisampled-render-to-texture color attachment and
3329 // multisampled depth buffer.  This test makes sure that the color attachment is blitted, while
3330 // the depth/stencil attachment is resolved.  Uses renderbuffer.
TEST_P(MultisampledRenderToTextureES3Test,RenderbufferBlitFramebufferMixedColorAndDepth)3331 TEST_P(MultisampledRenderToTextureES3Test, RenderbufferBlitFramebufferMixedColorAndDepth)
3332 {
3333     blitFramebufferMixedColorAndDepthCommon(true);
3334 }
3335 
3336 // Draw non-multisampled, draw multisampled, repeat.  This tests the same texture being bound
3337 // differently to two FBOs.
TEST_P(MultisampledRenderToTextureTest,DrawNonMultisampledThenMultisampled)3338 TEST_P(MultisampledRenderToTextureTest, DrawNonMultisampledThenMultisampled)
3339 {
3340     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
3341     constexpr GLsizei kSize = 64;
3342 
3343     // http://anglebug.com/4935
3344     ANGLE_SKIP_TEST_IF(IsD3D11());
3345 
3346     // Texture attachment to the two framebuffers.
3347     GLTexture color;
3348     glBindTexture(GL_TEXTURE_2D, color);
3349     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3350 
3351     // Create singlesampled framebuffer.
3352     GLFramebuffer fboSS;
3353     glBindFramebuffer(GL_FRAMEBUFFER, fboSS);
3354     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
3355     ASSERT_GL_NO_ERROR();
3356 
3357     // Create multisampled framebuffer.
3358     GLFramebuffer fboMS;
3359     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
3360     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color,
3361                                          0, 4);
3362     ASSERT_GL_NO_ERROR();
3363 
3364     // Draw red into the multisampled color buffer.
3365     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
3366     glUseProgram(drawColor);
3367     GLint colorUniformLocation =
3368         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
3369     ASSERT_NE(colorUniformLocation, -1);
3370 
3371     glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
3372     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
3373     ASSERT_GL_NO_ERROR();
3374 
3375     // Draw green into the singlesampled color buffer
3376     glBindFramebuffer(GL_FRAMEBUFFER, fboSS);
3377     glEnable(GL_SCISSOR_TEST);
3378     glScissor(kSize / 8, kSize / 8, 3 * kSize / 4, 3 * kSize / 4);
3379     glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
3380     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
3381     ASSERT_GL_NO_ERROR();
3382 
3383     // Draw blue into the multisampled color buffer
3384     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
3385     glScissor(kSize / 4, kSize / 4, kSize / 2, kSize / 2);
3386     glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
3387     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
3388     ASSERT_GL_NO_ERROR();
3389 
3390     // Verify that the texture is red on the border, blue in the middle and green in between.
3391     glBindFramebuffer(GL_READ_FRAMEBUFFER, fboSS);
3392 
3393     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3394     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::red);
3395     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::red);
3396     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::red);
3397 
3398     EXPECT_PIXEL_COLOR_EQ(3 * kSize / 16, 3 * kSize / 16, GLColor::green);
3399     EXPECT_PIXEL_COLOR_EQ(13 * kSize / 16, 3 * kSize / 16, GLColor::green);
3400     EXPECT_PIXEL_COLOR_EQ(3 * kSize / 16, 13 * kSize / 16, GLColor::green);
3401     EXPECT_PIXEL_COLOR_EQ(13 * kSize / 16, 13 * kSize / 16, GLColor::green);
3402 
3403     EXPECT_PIXEL_COLOR_EQ(3 * kSize / 8, 3 * kSize / 8, GLColor::blue);
3404     EXPECT_PIXEL_COLOR_EQ(5 * kSize / 8, 3 * kSize / 8, GLColor::blue);
3405     EXPECT_PIXEL_COLOR_EQ(3 * kSize / 8, 5 * kSize / 8, GLColor::blue);
3406     EXPECT_PIXEL_COLOR_EQ(5 * kSize / 8, 5 * kSize / 8, GLColor::blue);
3407     EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::blue);
3408 
3409     ASSERT_GL_NO_ERROR();
3410 }
3411 
3412 // Draw multisampled, draw multisampled with another sample count, repeat.  This tests the same
3413 // texture being bound as multisampled-render-to-texture with different sample counts to two FBOs.
TEST_P(MultisampledRenderToTextureTest,DrawMultisampledDifferentSamples)3414 TEST_P(MultisampledRenderToTextureTest, DrawMultisampledDifferentSamples)
3415 {
3416     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
3417     constexpr GLsizei kSize = 64;
3418 
3419     GLsizei maxSamples = 0;
3420     glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
3421     ASSERT_GE(maxSamples, 4);
3422 
3423     // Texture attachment to the two framebuffers.
3424     GLTexture color;
3425     glBindTexture(GL_TEXTURE_2D, color);
3426     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3427 
3428     // Create two multisampled framebuffers.
3429     GLFramebuffer fboMS1;
3430     glBindFramebuffer(GL_FRAMEBUFFER, fboMS1);
3431     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color,
3432                                          0, 4);
3433 
3434     GLFramebuffer fboMS2;
3435     glBindFramebuffer(GL_FRAMEBUFFER, fboMS2);
3436     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color,
3437                                          0, maxSamples);
3438     ASSERT_GL_NO_ERROR();
3439 
3440     // Draw red into the first multisampled color buffer.
3441     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
3442     glUseProgram(drawColor);
3443     GLint colorUniformLocation =
3444         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
3445     ASSERT_NE(colorUniformLocation, -1);
3446 
3447     glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
3448     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
3449     ASSERT_GL_NO_ERROR();
3450 
3451     // Draw green into the second multisampled color buffer
3452     glBindFramebuffer(GL_FRAMEBUFFER, fboMS1);
3453     glEnable(GL_SCISSOR_TEST);
3454     glScissor(kSize / 8, kSize / 8, 3 * kSize / 4, 3 * kSize / 4);
3455     glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
3456     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
3457     ASSERT_GL_NO_ERROR();
3458 
3459     // Draw blue into the first multisampled color buffer
3460     glBindFramebuffer(GL_FRAMEBUFFER, fboMS2);
3461     glScissor(kSize / 4, kSize / 4, kSize / 2, kSize / 2);
3462     glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
3463     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
3464     ASSERT_GL_NO_ERROR();
3465 
3466     // Verify that the texture is red on the border, blue in the middle and green in between.
3467     GLFramebuffer fboSS;
3468     glBindFramebuffer(GL_FRAMEBUFFER, fboSS);
3469     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
3470     ASSERT_GL_NO_ERROR();
3471 
3472     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3473     EXPECT_PIXEL_COLOR_EQ(kSize - 1, 0, GLColor::red);
3474     EXPECT_PIXEL_COLOR_EQ(0, kSize - 1, GLColor::red);
3475     EXPECT_PIXEL_COLOR_EQ(kSize - 1, kSize - 1, GLColor::red);
3476 
3477     EXPECT_PIXEL_COLOR_EQ(3 * kSize / 16, 3 * kSize / 16, GLColor::green);
3478     EXPECT_PIXEL_COLOR_EQ(13 * kSize / 16, 3 * kSize / 16, GLColor::green);
3479     EXPECT_PIXEL_COLOR_EQ(3 * kSize / 16, 13 * kSize / 16, GLColor::green);
3480     EXPECT_PIXEL_COLOR_EQ(13 * kSize / 16, 13 * kSize / 16, GLColor::green);
3481 
3482     EXPECT_PIXEL_COLOR_EQ(3 * kSize / 8, 3 * kSize / 8, GLColor::blue);
3483     EXPECT_PIXEL_COLOR_EQ(5 * kSize / 8, 3 * kSize / 8, GLColor::blue);
3484     EXPECT_PIXEL_COLOR_EQ(3 * kSize / 8, 5 * kSize / 8, GLColor::blue);
3485     EXPECT_PIXEL_COLOR_EQ(5 * kSize / 8, 5 * kSize / 8, GLColor::blue);
3486     EXPECT_PIXEL_COLOR_EQ(kSize / 2, kSize / 2, GLColor::blue);
3487 
3488     ASSERT_GL_NO_ERROR();
3489 }
3490 
drawCopyThenBlendAllAttachmentsMixed(bool useRenderbuffer)3491 void MultisampledRenderToTextureES31Test::drawCopyThenBlendAllAttachmentsMixed(bool useRenderbuffer)
3492 {
3493     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
3494     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture2"));
3495 
3496     GLint maxDrawBuffers = 0;
3497     glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
3498 
3499     // At least 4 draw buffers per GLES3.0 spec.
3500     ASSERT_GE(maxDrawBuffers, 4);
3501 
3502     // Maximum 8 draw buffers exposed by ANGLE.
3503     constexpr GLint kImplMaxDrawBuffers = 8;
3504     maxDrawBuffers                      = std::min(maxDrawBuffers, kImplMaxDrawBuffers);
3505 
3506     // Integer formats are mixed in which have different sample count limits. A framebuffer must
3507     // have the same sample count for all attachments.
3508     const GLint sampleCount = std::min(mTestSampleCount, mMaxIntegerSamples);
3509 
3510     constexpr const char *kDecl[kImplMaxDrawBuffers] = {
3511         "layout(location = 0) out vec4 out0;",  "layout(location = 1) out ivec4 out1;",
3512         "layout(location = 2) out uvec4 out2;", "layout(location = 3) out vec4 out3;",
3513         "layout(location = 4) out uvec4 out4;", "layout(location = 5) out ivec4 out5;",
3514         "layout(location = 6) out ivec4 out6;", "layout(location = 7) out vec4 out7;",
3515     };
3516 
3517     constexpr GLType kGLType[kImplMaxDrawBuffers] = {
3518         {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE},           {GL_RGBA32I, GL_RGBA_INTEGER, GL_INT},
3519         {GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT}, {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE},
3520         {GL_RGBA32UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT}, {GL_RGBA32I, GL_RGBA_INTEGER, GL_INT},
3521         {GL_RGBA32I, GL_RGBA_INTEGER, GL_INT},           {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE},
3522     };
3523 
3524     constexpr const char *kAssign1[kImplMaxDrawBuffers] = {
3525         "out0 = vec4(1.0f, 0.0f, 0.0f, 1.0f);",
3526         "out1 = ivec4(-19, 13, 123456, -654321);",
3527         "out2 = uvec4(98765, 43210, 2, 0);",
3528         "out3 = vec4(0.0f, 1.0f, 0.0f, 1.0f);",
3529         "out4 = uvec4(10101010, 2345, 0, 991);",
3530         "out5 = ivec4(615243, -948576, -222, 111);",
3531         "out6 = ivec4(-8127931, -1392781, 246810, 1214161820);",
3532         "out7 = vec4(0.0f, 0.0f, 1.0f, 1.0f);",
3533     };
3534 
3535     constexpr const char *kAssign2[kImplMaxDrawBuffers] = {
3536         "out0 = vec4(0.0f, 1.0f, 0.0f, 0.5f);",
3537         "out1 = ivec4(0, 0, 0, 0);",
3538         "out2 = uvec4(0, 0, 0, 0);",
3539         "out3 = vec4(0.0f, 0.0f, 1.0f, 0.5f);",
3540         "out4 = uvec4(0, 0, 0, 0);",
3541         "out5 = ivec4(0, 0, 0, 0);",
3542         "out6 = ivec4(0, 0, 0, 0);",
3543         "out7 = vec4(1.0f, 0.0f, 0.0f, 0.5f);",
3544     };
3545 
3546     // Generate the shaders, [0] for first draw and [1] for second.
3547     std::stringstream fsStr[2];
3548     for (unsigned int index = 0; index < 2; ++index)
3549     {
3550         fsStr[index] << R"(#version 300 es
3551 precision highp float;
3552 )";
3553 
3554         for (GLint drawBuffer = 0; drawBuffer < maxDrawBuffers; ++drawBuffer)
3555         {
3556             fsStr[index] << kDecl[drawBuffer] << "\n";
3557         }
3558 
3559         fsStr[index] << R"(void main()
3560 {
3561 )";
3562 
3563         const char *const *assign = index == 0 ? kAssign1 : kAssign2;
3564         for (GLint drawBuffer = 0; drawBuffer < maxDrawBuffers; ++drawBuffer)
3565         {
3566             fsStr[index] << assign[drawBuffer] << "\n";
3567         }
3568 
3569         fsStr[index] << "}\n";
3570     }
3571 
3572     constexpr GLsizei kSize = 64;
3573 
3574     setupCopyTexProgram();
3575 
3576     // Create multisampled framebuffer to draw into
3577     GLFramebuffer fboMS;
3578     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
3579 
3580     GLTexture textureMS[kImplMaxDrawBuffers];
3581     GLRenderbuffer renderbufferMS[kImplMaxDrawBuffers];
3582     for (GLint drawBuffer = 0; drawBuffer < maxDrawBuffers; ++drawBuffer)
3583     {
3584         createAndAttachColorAttachment(useRenderbuffer, kSize, GL_COLOR_ATTACHMENT0 + drawBuffer,
3585                                        &kGLType[drawBuffer], sampleCount, &textureMS[drawBuffer],
3586                                        &renderbufferMS[drawBuffer]);
3587     }
3588     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3589 
3590     // Setup programs
3591     ANGLE_GL_PROGRAM(drawProg, essl3_shaders::vs::Simple(), fsStr[0].str().c_str());
3592     ANGLE_GL_PROGRAM(blendProg, essl3_shaders::vs::Simple(), fsStr[1].str().c_str());
3593 
3594     constexpr GLenum kDrawBuffers[] = {
3595         GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3,
3596         GL_COLOR_ATTACHMENT4, GL_COLOR_ATTACHMENT5, GL_COLOR_ATTACHMENT6, GL_COLOR_ATTACHMENT7};
3597     glDrawBuffers(maxDrawBuffers, kDrawBuffers);
3598     ASSERT_GL_NO_ERROR();
3599 
3600     // Draw into the multisampled color buffers.
3601     glUseProgram(drawProg);
3602     drawQuad(drawProg, essl3_shaders::PositionAttrib(), 0.5f);
3603     ASSERT_GL_NO_ERROR();
3604 
3605     // Create a texture and copy from one of them.
3606     GLTexture texture;
3607     glBindTexture(GL_TEXTURE_2D, texture);
3608     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, kSize, kSize, 0);
3609     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3610     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3611     ASSERT_GL_NO_ERROR();
3612 
3613     // Blend color buffers.
3614     glUseProgram(blendProg);
3615     glEnable(GL_BLEND);
3616     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
3617     drawQuad(blendProg, essl3_shaders::PositionAttrib(), 0.5f);
3618     ASSERT_GL_NO_ERROR();
3619 
3620     // Verify texture colors.
3621     glReadBuffer(GL_COLOR_ATTACHMENT0);
3622     const GLColor kExpected0(127, 127, 0, 191);
3623     EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpected0, 1);
3624     EXPECT_PIXEL_COLOR_NEAR(kSize - 1, 0, kExpected0, 1);
3625     EXPECT_PIXEL_COLOR_NEAR(0, kSize - 1, kExpected0, 1);
3626     EXPECT_PIXEL_COLOR_NEAR(kSize - 1, kSize - 1, kExpected0, 1);
3627 
3628     glReadBuffer(GL_COLOR_ATTACHMENT3);
3629     const GLColor kExpected3(0, 127, 127, 191);
3630     EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpected3, 1);
3631     EXPECT_PIXEL_COLOR_NEAR(kSize - 1, 0, kExpected3, 1);
3632     EXPECT_PIXEL_COLOR_NEAR(0, kSize - 1, kExpected3, 1);
3633     EXPECT_PIXEL_COLOR_NEAR(kSize - 1, kSize - 1, kExpected3, 1);
3634 
3635     if (maxDrawBuffers > 7)
3636     {
3637         glReadBuffer(GL_COLOR_ATTACHMENT7);
3638         const GLColor kExpected7(127, 0, 127, 191);
3639         EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpected7, 1);
3640         EXPECT_PIXEL_COLOR_NEAR(kSize - 1, 0, kExpected7, 1);
3641         EXPECT_PIXEL_COLOR_NEAR(0, kSize - 1, kExpected7, 1);
3642         EXPECT_PIXEL_COLOR_NEAR(kSize - 1, kSize - 1, kExpected7, 1);
3643     }
3644 
3645     // For completeness, verify that the texture used as copy target is red.
3646     verifyResults(texture, GLColor::red, kSize, 0, 0, kSize, kSize);
3647 
3648     ASSERT_GL_NO_ERROR();
3649 }
3650 
3651 // Draw, copy, then blend with 8 mixed format attachments.  The copy will make sure an implicit
3652 // resolve happens.  Regardless, the following draw should retain the data written by the first draw
3653 // command.
TEST_P(MultisampledRenderToTextureES31Test,DrawCopyThenBlendAllAttachmentsMixed)3654 TEST_P(MultisampledRenderToTextureES31Test, DrawCopyThenBlendAllAttachmentsMixed)
3655 {
3656     drawCopyThenBlendAllAttachmentsMixed(false);
3657 }
3658 
3659 // Same as DrawCopyThenBlendAllAttachmentsMixed but with renderbuffers.
TEST_P(MultisampledRenderToTextureES31Test,RenderbufferDrawCopyThenBlendAllAttachmentsMixed)3660 TEST_P(MultisampledRenderToTextureES31Test, RenderbufferDrawCopyThenBlendAllAttachmentsMixed)
3661 {
3662     // Linux Intel Vulkan returns 0 for GL_MAX_INTEGER_SAMPLES http://anglebug.com/5988
3663     ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsVulkan());
3664 
3665     drawCopyThenBlendAllAttachmentsMixed(true);
3666 }
3667 
renderbufferUnresolveColorAndDepthStencilThenTwoColors(bool withDepth,bool withStencil)3668 void MultisampledRenderToTextureES3Test::renderbufferUnresolveColorAndDepthStencilThenTwoColors(
3669     bool withDepth,
3670     bool withStencil)
3671 {
3672     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
3673     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture2"));
3674     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_draw_buffers"));
3675 
3676     // http://anglebug.com/5083
3677     ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsVulkan());
3678 
3679     // http://anglebug.com/5096
3680     ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsVulkan());
3681 
3682     // http://anglebug.com/5380
3683     ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsVulkan());
3684 
3685     constexpr GLsizei kSize = 64;
3686 
3687     setupCopyTexProgram();
3688 
3689     GLFramebuffer fboColorAndDepthStencil;
3690     glBindFramebuffer(GL_FRAMEBUFFER, fboColorAndDepthStencil);
3691 
3692     // Create framebuffer to draw into, with both color and depth/stencil attachments.
3693     GLTexture color1;
3694     glBindTexture(GL_TEXTURE_2D, color1);
3695     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3696     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
3697                                          color1, 0, 4);
3698 
3699     GLenum depthStencilFormat = GL_DEPTH24_STENCIL8;
3700     GLenum depthStencilTarget = GL_DEPTH_STENCIL_ATTACHMENT;
3701 
3702     ASSERT_TRUE(withDepth || withStencil);
3703     if (withDepth && !withStencil)
3704     {
3705         depthStencilFormat = GL_DEPTH_COMPONENT24;
3706         depthStencilTarget = GL_DEPTH_ATTACHMENT;
3707     }
3708     if (!withDepth && withStencil)
3709     {
3710         depthStencilFormat = GL_STENCIL_INDEX8;
3711         depthStencilTarget = GL_STENCIL_ATTACHMENT;
3712     }
3713 
3714     GLRenderbuffer depthStencil;
3715     glBindRenderbuffer(GL_RENDERBUFFER, depthStencil);
3716     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, depthStencilFormat, kSize, kSize);
3717     glFramebufferRenderbuffer(GL_FRAMEBUFFER, depthStencilTarget, GL_RENDERBUFFER, depthStencil);
3718     ASSERT_GL_NO_ERROR();
3719     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3720 
3721     // Set viewport and clear depth/stencil
3722     glViewport(0, 0, kSize, kSize);
3723     glClearDepthf(1);
3724     glClearStencil(0x55);
3725     glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
3726 
3727     // If depth is not cleared to 1, rendering would fail.
3728     if (withDepth)
3729     {
3730         glEnable(GL_DEPTH_TEST);
3731         glDepthFunc(GL_LESS);
3732     }
3733 
3734     // If stencil is not cleared to 0x55, rendering would fail.
3735     if (withStencil)
3736     {
3737         glEnable(GL_STENCIL_TEST);
3738         glStencilFunc(GL_EQUAL, 0x55, 0xFF);
3739         glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
3740         glStencilMask(0xFF);
3741     }
3742 
3743     // Set up program
3744     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
3745     glUseProgram(drawColor);
3746     GLint colorUniformLocation =
3747         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
3748     ASSERT_NE(colorUniformLocation, -1);
3749 
3750     // Draw red
3751     glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
3752     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.25f);
3753     ASSERT_GL_NO_ERROR();
3754 
3755     // Create a texture and copy into it.
3756     GLTexture texture;
3757     glBindTexture(GL_TEXTURE_2D, texture);
3758     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, kSize, kSize, 0);
3759     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3760     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3761     ASSERT_GL_NO_ERROR();
3762 
3763     // Draw again into the framebuffer, this time blending.  This tests that both the color and
3764     // depth/stencil data are preserved after the resolve incurred by the copy above.
3765     glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 0.5f);
3766     glEnable(GL_BLEND);
3767     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
3768     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.0f);
3769     ASSERT_GL_NO_ERROR();
3770 
3771     // Verify that the texture is now yellow
3772     const GLColor kExpected(127, 127, 0, 191);
3773     EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpected, 1);
3774     EXPECT_PIXEL_COLOR_NEAR(kSize - 1, 0, kExpected, 1);
3775     EXPECT_PIXEL_COLOR_NEAR(0, kSize - 1, kExpected, 1);
3776     EXPECT_PIXEL_COLOR_NEAR(kSize - 1, kSize - 1, kExpected, 1);
3777 
3778     // For completeness, verify that the texture used as copy target is red.
3779     verifyResults(texture, GLColor::red, kSize, 0, 0, kSize, kSize);
3780 
3781     // Now create a framebuffer with two color attachments and do something similar.  This makes
3782     // sure that the fact that both these framebuffers have 2 attachments does not cause confusion,
3783     // for example by having the unresolve shader generated for the first framebuffer used for the
3784     // second framebuffer.
3785     GLFramebuffer fboTwoColors;
3786     glBindFramebuffer(GL_FRAMEBUFFER, fboTwoColors);
3787 
3788     GLTexture color2;
3789     glBindTexture(GL_TEXTURE_2D, color2);
3790     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3791     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
3792                                          color2, 0, 4);
3793 
3794     GLTexture color3;
3795     glBindTexture(GL_TEXTURE_2D, color3);
3796     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3797     glFramebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D,
3798                                          color3, 0, 4);
3799 
3800     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3801 
3802     glDisable(GL_DEPTH_TEST);
3803     glDisable(GL_STENCIL_TEST);
3804     glDisable(GL_BLEND);
3805 
3806     constexpr GLenum kDrawBuffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
3807     glDrawBuffers(2, kDrawBuffers);
3808     glReadBuffer(GL_COLOR_ATTACHMENT1);
3809 
3810     // Setup program
3811     constexpr bool kBuffersEnabled[8] = {true, true};
3812 
3813     GLuint drawColorMRT;
3814     setupUniformColorProgramMultiRenderTarget(kBuffersEnabled, &drawColorMRT);
3815     glUseProgram(drawColorMRT);
3816     GLint colorUniformLocationMRT =
3817         glGetUniformLocation(drawColorMRT, angle::essl1_shaders::ColorUniform());
3818     ASSERT_NE(colorUniformLocationMRT, -1);
3819 
3820     // Draw blue
3821     glUniform4f(colorUniformLocationMRT, 0.0f, 0.0f, 1.0f, 1.0f);
3822     drawQuad(drawColorMRT, essl1_shaders::PositionAttrib(), 0.5f);
3823     ASSERT_GL_NO_ERROR();
3824 
3825     // Copy into texture
3826     glBindTexture(GL_TEXTURE_2D, texture);
3827     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, kSize, kSize, 0);
3828 
3829     // Blend.
3830     glUniform4f(colorUniformLocationMRT, 0.0f, 1.0f, 0.0f, 0.5f);
3831     glEnable(GL_BLEND);
3832     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
3833     drawQuad(drawColorMRT, essl1_shaders::PositionAttrib(), 0.0f);
3834     ASSERT_GL_NO_ERROR();
3835 
3836     // Verify that the texture is now cyan
3837     const GLColor kExpected2(0, 127, 127, 191);
3838     EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpected2, 1);
3839     EXPECT_PIXEL_COLOR_NEAR(kSize - 1, 0, kExpected2, 1);
3840     EXPECT_PIXEL_COLOR_NEAR(0, kSize - 1, kExpected2, 1);
3841     EXPECT_PIXEL_COLOR_NEAR(kSize - 1, kSize - 1, kExpected2, 1);
3842 
3843     // For completeness, verify that the texture used as copy target is blue.
3844     verifyResults(texture, GLColor::blue, kSize, 0, 0, kSize, kSize);
3845 }
3846 
3847 // Draw, copy, then blend once on a framebuffer with color and depth attachments, and once with two
3848 // color attachments.  Tests that unresolve is done correctly on two framebuffers with the same
3849 // number of attachments, but differing in depth being there.  Note that this test doesn't apply to
3850 // depth/stencil textures as they are explicitly autoinvalidated between render passes.
TEST_P(MultisampledRenderToTextureES3Test,RenderbufferUnresolveColorAndDepthThenTwoColors)3851 TEST_P(MultisampledRenderToTextureES3Test, RenderbufferUnresolveColorAndDepthThenTwoColors)
3852 {
3853     renderbufferUnresolveColorAndDepthStencilThenTwoColors(true, false);
3854 }
3855 
3856 // Similar to RenderbufferUnresolveColorAndDepthThenTwoColors, but with stencil.
TEST_P(MultisampledRenderToTextureES3Test,RenderbufferUnresolveColorAndStencilThenTwoColors)3857 TEST_P(MultisampledRenderToTextureES3Test, RenderbufferUnresolveColorAndStencilThenTwoColors)
3858 {
3859     renderbufferUnresolveColorAndDepthStencilThenTwoColors(false, true);
3860 }
3861 
3862 // Similar to RenderbufferUnresolveColorAndDepthThenTwoColors, but with depth and stencil.
TEST_P(MultisampledRenderToTextureES3Test,RenderbufferUnresolveColorAndDepthStencilThenTwoColors)3863 TEST_P(MultisampledRenderToTextureES3Test, RenderbufferUnresolveColorAndDepthStencilThenTwoColors)
3864 {
3865     renderbufferUnresolveColorAndDepthStencilThenTwoColors(true, true);
3866 }
3867 
3868 // Make sure deferred clears are flushed correctly when the framebuffer switches between
3869 // needing unresolve and not needing it.
TEST_P(MultisampledRenderToTextureES3Test,ClearThenMaskedClearFramebufferTest)3870 TEST_P(MultisampledRenderToTextureES3Test, ClearThenMaskedClearFramebufferTest)
3871 {
3872     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_multisampled_render_to_texture"));
3873 
3874     // TODO(anglebug:5655): This test is failing on Linux AMD Vulkan since it was added.
3875     ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsVulkan());
3876 
3877     // TODO(geofflang) http://anglebug.com/2894
3878     ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGL() && IsPixel2());
3879 
3880     constexpr GLsizei kSize = 16;
3881 
3882     GLFramebuffer fboMS;
3883     glBindFramebuffer(GL_FRAMEBUFFER, fboMS);
3884 
3885     // Create multisampled framebuffer to use as source.
3886     GLRenderbuffer depthMS;
3887     glBindRenderbuffer(GL_RENDERBUFFER, depthMS);
3888     glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, 4, GL_DEPTH_COMPONENT24, kSize, kSize);
3889     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthMS);
3890     ASSERT_GL_NO_ERROR();
3891 
3892     GLTexture textureMS;
3893     GLRenderbuffer renderbufferMS;
3894     createAndAttachColorAttachment(false, kSize, GL_COLOR_ATTACHMENT0, nullptr, mTestSampleCount,
3895                                    &textureMS, &renderbufferMS);
3896     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3897 
3898     // Clear depth to 0.5 and color to green.
3899     glClearDepthf(0.5f);
3900     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
3901     glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
3902     ASSERT_GL_NO_ERROR();
3903 
3904     // Break the render pass.
3905     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3906 
3907     // Draw red into the multisampled color buffer.  An unresolve operation is needed.
3908     ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
3909     glEnable(GL_DEPTH_TEST);
3910     glDepthFunc(GL_EQUAL);
3911     drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.0f);
3912     ASSERT_GL_NO_ERROR();
3913 
3914     // Break the render pass.
3915     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3916 
3917     // Clear color to transparent blue.
3918     glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
3919     glClear(GL_COLOR_BUFFER_BIT);
3920 
3921     // Clear both color and depth, with color masked.
3922     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
3923     glColorMask(GL_FALSE, GL_TRUE, GL_FALSE, GL_TRUE);
3924     glClearDepthf(0.3f);
3925     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
3926 
3927     // Make sure the result is blue.
3928     EXPECT_PIXEL_RECT_EQ(0, 0, kSize - 1, kSize - 1, GLColor::blue);
3929     ASSERT_GL_NO_ERROR();
3930 }
3931 
3932 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND_ES31(MultisampledRenderToTextureTest);
3933 
3934 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MultisampledRenderToTextureES3Test);
3935 ANGLE_INSTANTIATE_TEST_ES3(MultisampledRenderToTextureES3Test);
3936 
3937 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MultisampledRenderToTextureES31Test);
3938 ANGLE_INSTANTIATE_TEST_ES31(MultisampledRenderToTextureES31Test);
3939 }  // namespace
3940