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