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