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, ¶m);
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, ¶m);
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 ¶m);
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