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