xref: /aosp_15_r20/external/angle/src/tests/gl_tests/MultisampleTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2019 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker 
7*8975f5c5SAndroid Build Coastguard Worker // MultisampleTest: Tests of multisampled default framebuffer
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.h"
10*8975f5c5SAndroid Build Coastguard Worker 
11*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/gl_raii.h"
12*8975f5c5SAndroid Build Coastguard Worker #include "util/OSWindow.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "util/shader_utils.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "util/test_utils.h"
15*8975f5c5SAndroid Build Coastguard Worker 
16*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
17*8975f5c5SAndroid Build Coastguard Worker 
18*8975f5c5SAndroid Build Coastguard Worker namespace
19*8975f5c5SAndroid Build Coastguard Worker {
20*8975f5c5SAndroid Build Coastguard Worker 
21*8975f5c5SAndroid Build Coastguard Worker class MultisampleTest : public ANGLETest<>
22*8975f5c5SAndroid Build Coastguard Worker {
23*8975f5c5SAndroid Build Coastguard Worker   protected:
MultisampleTest()24*8975f5c5SAndroid Build Coastguard Worker     MultisampleTest()
25*8975f5c5SAndroid Build Coastguard Worker     {
26*8975f5c5SAndroid Build Coastguard Worker         setWindowWidth(kWindowWidth);
27*8975f5c5SAndroid Build Coastguard Worker         setWindowHeight(kWindowHeight);
28*8975f5c5SAndroid Build Coastguard Worker         setConfigRedBits(8);
29*8975f5c5SAndroid Build Coastguard Worker         setConfigGreenBits(8);
30*8975f5c5SAndroid Build Coastguard Worker         setConfigBlueBits(8);
31*8975f5c5SAndroid Build Coastguard Worker         setConfigAlphaBits(8);
32*8975f5c5SAndroid Build Coastguard Worker         setConfigDepthBits(24);
33*8975f5c5SAndroid Build Coastguard Worker         setConfigStencilBits(8);
34*8975f5c5SAndroid Build Coastguard Worker         setSamples(4);
35*8975f5c5SAndroid Build Coastguard Worker         setMultisampleEnabled(true);
36*8975f5c5SAndroid Build Coastguard Worker     }
37*8975f5c5SAndroid Build Coastguard Worker 
prepareVertexBuffer(GLBuffer & vertexBuffer,const Vector3 * vertices,size_t vertexCount,GLint positionLocation)38*8975f5c5SAndroid Build Coastguard Worker     void prepareVertexBuffer(GLBuffer &vertexBuffer,
39*8975f5c5SAndroid Build Coastguard Worker                              const Vector3 *vertices,
40*8975f5c5SAndroid Build Coastguard Worker                              size_t vertexCount,
41*8975f5c5SAndroid Build Coastguard Worker                              GLint positionLocation)
42*8975f5c5SAndroid Build Coastguard Worker     {
43*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
44*8975f5c5SAndroid Build Coastguard Worker         glBufferData(GL_ARRAY_BUFFER, sizeof(*vertices) * vertexCount, vertices, GL_STATIC_DRAW);
45*8975f5c5SAndroid Build Coastguard Worker         glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
46*8975f5c5SAndroid Build Coastguard Worker         glEnableVertexAttribArray(positionLocation);
47*8975f5c5SAndroid Build Coastguard Worker     }
48*8975f5c5SAndroid Build Coastguard Worker 
49*8975f5c5SAndroid Build Coastguard Worker   protected:
50*8975f5c5SAndroid Build Coastguard Worker     static constexpr int kWindowWidth  = 16;
51*8975f5c5SAndroid Build Coastguard Worker     static constexpr int kWindowHeight = 8;
52*8975f5c5SAndroid Build Coastguard Worker };
53*8975f5c5SAndroid Build Coastguard Worker 
54*8975f5c5SAndroid Build Coastguard Worker class MultisampleTestES3 : public MultisampleTest
55*8975f5c5SAndroid Build Coastguard Worker {};
56*8975f5c5SAndroid Build Coastguard Worker 
57*8975f5c5SAndroid Build Coastguard Worker class MultisampleTestES32 : public MultisampleTest
58*8975f5c5SAndroid Build Coastguard Worker {};
59*8975f5c5SAndroid Build Coastguard Worker 
60*8975f5c5SAndroid Build Coastguard Worker // Test point rendering on a multisampled surface.  GLES2 section 3.3.1.
TEST_P(MultisampleTest,Point)61*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleTest, Point)
62*8975f5c5SAndroid Build Coastguard Worker {
63*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42262135
64*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsAndroid() && IsNVIDIAShield() && IsOpenGLES());
65*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42264264
66*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsOzone());
67*8975f5c5SAndroid Build Coastguard Worker 
68*8975f5c5SAndroid Build Coastguard Worker     constexpr char kPointsVS[] = R"(precision highp float;
69*8975f5c5SAndroid Build Coastguard Worker attribute vec4 a_position;
70*8975f5c5SAndroid Build Coastguard Worker 
71*8975f5c5SAndroid Build Coastguard Worker void main()
72*8975f5c5SAndroid Build Coastguard Worker {
73*8975f5c5SAndroid Build Coastguard Worker     gl_PointSize = 3.0;
74*8975f5c5SAndroid Build Coastguard Worker     gl_Position = a_position;
75*8975f5c5SAndroid Build Coastguard Worker })";
76*8975f5c5SAndroid Build Coastguard Worker 
77*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, kPointsVS, essl1_shaders::fs::Red());
78*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
79*8975f5c5SAndroid Build Coastguard Worker     const GLint positionLocation = glGetAttribLocation(program, "a_position");
80*8975f5c5SAndroid Build Coastguard Worker 
81*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexBuffer;
82*8975f5c5SAndroid Build Coastguard Worker     const Vector3 vertices[1] = {{0.0f, 0.0f, 0.0f}};
83*8975f5c5SAndroid Build Coastguard Worker     prepareVertexBuffer(vertexBuffer, vertices, 1, positionLocation);
84*8975f5c5SAndroid Build Coastguard Worker 
85*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
86*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_POINTS, 0, 1);
87*8975f5c5SAndroid Build Coastguard Worker 
88*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
89*8975f5c5SAndroid Build Coastguard Worker 
90*8975f5c5SAndroid Build Coastguard Worker     // The center pixels should be all red.
91*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(kWindowWidth / 2, kWindowHeight / 2, GLColor::red);
92*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(kWindowWidth / 2 - 1, kWindowHeight / 2, GLColor::red);
93*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(kWindowWidth / 2, kWindowHeight / 2 - 1, GLColor::red);
94*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(kWindowWidth / 2 - 1, kWindowHeight / 2 - 1, GLColor::red);
95*8975f5c5SAndroid Build Coastguard Worker 
96*8975f5c5SAndroid Build Coastguard Worker     // Border pixels should be between red and black, and not exactly either; corners are darker and
97*8975f5c5SAndroid Build Coastguard Worker     // sides are brighter.
98*8975f5c5SAndroid Build Coastguard Worker     const GLColor kSideColor   = {128, 0, 0, 128};
99*8975f5c5SAndroid Build Coastguard Worker     const GLColor kCornerColor = {64, 0, 0, 64};
100*8975f5c5SAndroid Build Coastguard Worker     constexpr int kErrorMargin = 16;
101*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(kWindowWidth / 2 - 2, kWindowHeight / 2 - 2, kCornerColor,
102*8975f5c5SAndroid Build Coastguard Worker                             kErrorMargin);
103*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(kWindowWidth / 2 - 2, kWindowHeight / 2 + 1, kCornerColor,
104*8975f5c5SAndroid Build Coastguard Worker                             kErrorMargin);
105*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(kWindowWidth / 2 + 1, kWindowHeight / 2 - 2, kCornerColor,
106*8975f5c5SAndroid Build Coastguard Worker                             kErrorMargin);
107*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(kWindowWidth / 2 + 1, kWindowHeight / 2 + 1, kCornerColor,
108*8975f5c5SAndroid Build Coastguard Worker                             kErrorMargin);
109*8975f5c5SAndroid Build Coastguard Worker 
110*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(kWindowWidth / 2 - 2, kWindowHeight / 2 - 1, kSideColor, kErrorMargin);
111*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(kWindowWidth / 2 - 2, kWindowHeight / 2, kSideColor, kErrorMargin);
112*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(kWindowWidth / 2 - 1, kWindowHeight / 2 - 2, kSideColor, kErrorMargin);
113*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(kWindowWidth / 2 - 1, kWindowHeight / 2 + 1, kSideColor, kErrorMargin);
114*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(kWindowWidth / 2, kWindowHeight / 2 - 2, kSideColor, kErrorMargin);
115*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(kWindowWidth / 2, kWindowHeight / 2 + 1, kSideColor, kErrorMargin);
116*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(kWindowWidth / 2 + 1, kWindowHeight / 2 - 1, kSideColor, kErrorMargin);
117*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(kWindowWidth / 2 + 1, kWindowHeight / 2, kSideColor, kErrorMargin);
118*8975f5c5SAndroid Build Coastguard Worker }
119*8975f5c5SAndroid Build Coastguard Worker 
120*8975f5c5SAndroid Build Coastguard Worker // Test line rendering on a multisampled surface.  GLES2 section 3.4.4.
TEST_P(MultisampleTest,Line)121*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleTest, Line)
122*8975f5c5SAndroid Build Coastguard Worker {
123*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsARM64() && IsWindows() && IsD3D());
124*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42264264
125*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsOzone());
126*8975f5c5SAndroid Build Coastguard Worker 
127*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
128*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
129*8975f5c5SAndroid Build Coastguard Worker     const GLint positionLocation = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
130*8975f5c5SAndroid Build Coastguard Worker 
131*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexBuffer;
132*8975f5c5SAndroid Build Coastguard Worker     const Vector3 vertices[2] = {{-1.0f, -0.3f, 0.0f}, {1.0f, 0.3f, 0.0f}};
133*8975f5c5SAndroid Build Coastguard Worker     prepareVertexBuffer(vertexBuffer, vertices, 2, positionLocation);
134*8975f5c5SAndroid Build Coastguard Worker 
135*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
136*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_LINES, 0, 2);
137*8975f5c5SAndroid Build Coastguard Worker 
138*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
139*8975f5c5SAndroid Build Coastguard Worker 
140*8975f5c5SAndroid Build Coastguard Worker     // The line goes from left to right at about -17 degrees slope.  It renders as such (captured
141*8975f5c5SAndroid Build Coastguard Worker     // with renderdoc):
142*8975f5c5SAndroid Build Coastguard Worker     //
143*8975f5c5SAndroid Build Coastguard Worker     // D                    D = Dark Red (0.25) or (0.5)
144*8975f5c5SAndroid Build Coastguard Worker     //  BRA                 R = Red (1.0)
145*8975f5c5SAndroid Build Coastguard Worker     //     ARB              M = Middle Red (0.75)
146*8975f5c5SAndroid Build Coastguard Worker     //        D             B = Bright Red (1.0 or 0.75)
147*8975f5c5SAndroid Build Coastguard Worker     //                      A = Any red (0.5, 0.75 or 1.0)
148*8975f5c5SAndroid Build Coastguard Worker     //
149*8975f5c5SAndroid Build Coastguard Worker     // Verify that rendering is done as above.
150*8975f5c5SAndroid Build Coastguard Worker 
151*8975f5c5SAndroid Build Coastguard Worker     const GLColor kDarkRed     = {128, 0, 0, 128};
152*8975f5c5SAndroid Build Coastguard Worker     const GLColor kMidRed      = {192, 0, 0, 192};
153*8975f5c5SAndroid Build Coastguard Worker     constexpr int kErrorMargin = 16;
154*8975f5c5SAndroid Build Coastguard Worker     constexpr int kLargeMargin = 80;
155*8975f5c5SAndroid Build Coastguard Worker 
156*8975f5c5SAndroid Build Coastguard Worker     static_assert(kWindowWidth == 16, "Verification code written for 16x8 window");
157*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(0, 2, kDarkRed, kLargeMargin);
158*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(3, 3, GLColor::red, kLargeMargin);
159*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(4, 3, GLColor::red, kErrorMargin);
160*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(6, 3, kMidRed, kLargeMargin);
161*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(8, 4, kMidRed, kLargeMargin);
162*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(11, 4, GLColor::red, kErrorMargin);
163*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(12, 4, GLColor::red, kLargeMargin);
164*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(15, 5, kDarkRed, kLargeMargin);
165*8975f5c5SAndroid Build Coastguard Worker }
166*8975f5c5SAndroid Build Coastguard Worker 
167*8975f5c5SAndroid Build Coastguard Worker // Test polygon rendering on a multisampled surface.  GLES2 section 3.5.3.
TEST_P(MultisampleTest,Triangle)168*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleTest, Triangle)
169*8975f5c5SAndroid Build Coastguard Worker {
170*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42262135
171*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsAndroid() && IsNVIDIAShield() && IsOpenGLES());
172*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42264264
173*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsOzone());
174*8975f5c5SAndroid Build Coastguard Worker 
175*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
176*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
177*8975f5c5SAndroid Build Coastguard Worker     const GLint positionLocation = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
178*8975f5c5SAndroid Build Coastguard Worker 
179*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexBuffer;
180*8975f5c5SAndroid Build Coastguard Worker     const Vector3 vertices[3] = {{-1.0f, -1.0f, 0.0f}, {-1.0f, 1.0f, 0.0f}, {1.0f, -1.0f, 0.0f}};
181*8975f5c5SAndroid Build Coastguard Worker     prepareVertexBuffer(vertexBuffer, vertices, 3, positionLocation);
182*8975f5c5SAndroid Build Coastguard Worker 
183*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
184*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLES, 0, 3);
185*8975f5c5SAndroid Build Coastguard Worker 
186*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
187*8975f5c5SAndroid Build Coastguard Worker 
188*8975f5c5SAndroid Build Coastguard Worker     // Top-left pixels should be all red.
189*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
190*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(kWindowWidth / 4, kWindowHeight / 4, GLColor::red);
191*8975f5c5SAndroid Build Coastguard Worker 
192*8975f5c5SAndroid Build Coastguard Worker     // Diagonal pixels from bottom-left to top-right are between red and black.  Pixels above the
193*8975f5c5SAndroid Build Coastguard Worker     // diagonal are red and pixels below it are black.
194*8975f5c5SAndroid Build Coastguard Worker     const GLColor kMidRed = {128, 0, 0, 128};
195*8975f5c5SAndroid Build Coastguard Worker     // D3D11 is off by 63 for red (191 instead of 128), where other back-ends get 128
196*8975f5c5SAndroid Build Coastguard Worker     constexpr int kErrorMargin = 64;
197*8975f5c5SAndroid Build Coastguard Worker 
198*8975f5c5SAndroid Build Coastguard Worker     for (int i = 2; i + 2 < kWindowWidth; i += 2)
199*8975f5c5SAndroid Build Coastguard Worker     {
200*8975f5c5SAndroid Build Coastguard Worker         int j = kWindowHeight - 1 - (i / 2);
201*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_COLOR_NEAR(i, j, kMidRed, kErrorMargin);
202*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_COLOR_EQ(i, j - 1, GLColor::red);
203*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_COLOR_EQ(i, j + 1, GLColor::transparentBlack);
204*8975f5c5SAndroid Build Coastguard Worker     }
205*8975f5c5SAndroid Build Coastguard Worker }
206*8975f5c5SAndroid Build Coastguard Worker 
207*8975f5c5SAndroid Build Coastguard Worker // Test polygon rendering on a multisampled surface. And rendering is interrupted by a compute pass
208*8975f5c5SAndroid Build Coastguard Worker // that converts the index buffer. Make sure the rendering's multisample result is preserved after
209*8975f5c5SAndroid Build Coastguard Worker // interruption.
TEST_P(MultisampleTest,ContentPresevedAfterInterruption)210*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleTest, ContentPresevedAfterInterruption)
211*8975f5c5SAndroid Build Coastguard Worker {
212*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_rgb8_rgba8"));
213*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42262135
214*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsAndroid() && IsNVIDIAShield() && IsOpenGLES());
215*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42263216
216*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsD3D11());
217*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42264264
218*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsOzone());
219*8975f5c5SAndroid Build Coastguard Worker 
220*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
221*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
222*8975f5c5SAndroid Build Coastguard Worker     const GLint positionLocation = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
223*8975f5c5SAndroid Build Coastguard Worker 
224*8975f5c5SAndroid Build Coastguard Worker     if (IsGLExtensionEnabled("GL_EXT_discard_framebuffer"))
225*8975f5c5SAndroid Build Coastguard Worker     {
226*8975f5c5SAndroid Build Coastguard Worker         GLenum attachments[] = {GL_COLOR_EXT, GL_DEPTH_EXT, GL_STENCIL_EXT};
227*8975f5c5SAndroid Build Coastguard Worker         glDiscardFramebufferEXT(GL_FRAMEBUFFER, 3, attachments);
228*8975f5c5SAndroid Build Coastguard Worker     }
229*8975f5c5SAndroid Build Coastguard Worker     // Draw triangle
230*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexBuffer;
231*8975f5c5SAndroid Build Coastguard Worker     const Vector3 vertices[3] = {{-1.0f, -1.0f, 0.0f}, {-1.0f, 1.0f, 0.0f}, {1.0f, -1.0f, 0.0f}};
232*8975f5c5SAndroid Build Coastguard Worker     prepareVertexBuffer(vertexBuffer, vertices, 3, positionLocation);
233*8975f5c5SAndroid Build Coastguard Worker 
234*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
235*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLES, 0, 3);
236*8975f5c5SAndroid Build Coastguard Worker 
237*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
238*8975f5c5SAndroid Build Coastguard Worker 
239*8975f5c5SAndroid Build Coastguard Worker     // Draw a line
240*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexBuffer2;
241*8975f5c5SAndroid Build Coastguard Worker     GLBuffer indexBuffer2;
242*8975f5c5SAndroid Build Coastguard Worker     const Vector3 vertices2[2] = {{-1.0f, -0.3f, 0.0f}, {1.0f, 0.3f, 0.0f}};
243*8975f5c5SAndroid Build Coastguard Worker     const GLubyte indices2[]   = {0, 1};
244*8975f5c5SAndroid Build Coastguard Worker     prepareVertexBuffer(vertexBuffer2, vertices2, 2, positionLocation);
245*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer2);
246*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices2), indices2, GL_STATIC_DRAW);
247*8975f5c5SAndroid Build Coastguard Worker 
248*8975f5c5SAndroid Build Coastguard Worker     glDrawElements(GL_LINES, 2, GL_UNSIGNED_BYTE, 0);
249*8975f5c5SAndroid Build Coastguard Worker 
250*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
251*8975f5c5SAndroid Build Coastguard Worker 
252*8975f5c5SAndroid Build Coastguard Worker     // Top-left pixels should be all red.
253*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
254*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(kWindowWidth / 4, kWindowHeight / 4, GLColor::red);
255*8975f5c5SAndroid Build Coastguard Worker 
256*8975f5c5SAndroid Build Coastguard Worker     // Triangle edge:
257*8975f5c5SAndroid Build Coastguard Worker     // Diagonal pixels from bottom-left to top-right are between red and black.  Pixels above the
258*8975f5c5SAndroid Build Coastguard Worker     // diagonal are red and pixels below it are black.
259*8975f5c5SAndroid Build Coastguard Worker     {
260*8975f5c5SAndroid Build Coastguard Worker         const GLColor kMidRed      = {128, 0, 0, 128};
261*8975f5c5SAndroid Build Coastguard Worker         constexpr int kErrorMargin = 16;
262*8975f5c5SAndroid Build Coastguard Worker 
263*8975f5c5SAndroid Build Coastguard Worker         for (int i = 2; i + 2 < kWindowWidth; i += 2)
264*8975f5c5SAndroid Build Coastguard Worker         {
265*8975f5c5SAndroid Build Coastguard Worker             // Exclude the middle pixel where the triangle and line cross each other.
266*8975f5c5SAndroid Build Coastguard Worker             if (abs(kWindowHeight / 2 - (i / 2)) <= 1)
267*8975f5c5SAndroid Build Coastguard Worker             {
268*8975f5c5SAndroid Build Coastguard Worker                 continue;
269*8975f5c5SAndroid Build Coastguard Worker             }
270*8975f5c5SAndroid Build Coastguard Worker             int j = kWindowHeight - 1 - (i / 2);
271*8975f5c5SAndroid Build Coastguard Worker             EXPECT_PIXEL_COLOR_NEAR(i, j, kMidRed, kErrorMargin);
272*8975f5c5SAndroid Build Coastguard Worker             EXPECT_PIXEL_COLOR_EQ(i, j - 1, GLColor::red);
273*8975f5c5SAndroid Build Coastguard Worker             EXPECT_PIXEL_COLOR_EQ(i, j + 1, GLColor::transparentBlack);
274*8975f5c5SAndroid Build Coastguard Worker         }
275*8975f5c5SAndroid Build Coastguard Worker     }
276*8975f5c5SAndroid Build Coastguard Worker 
277*8975f5c5SAndroid Build Coastguard Worker     // Line edge:
278*8975f5c5SAndroid Build Coastguard Worker     {
279*8975f5c5SAndroid Build Coastguard Worker         const GLColor kDarkRed     = {128, 0, 0, 128};
280*8975f5c5SAndroid Build Coastguard Worker         constexpr int kErrorMargin = 16;
281*8975f5c5SAndroid Build Coastguard Worker         constexpr int kLargeMargin = 80;
282*8975f5c5SAndroid Build Coastguard Worker 
283*8975f5c5SAndroid Build Coastguard Worker         static_assert(kWindowWidth == 16, "Verification code written for 16x8 window");
284*8975f5c5SAndroid Build Coastguard Worker         // Exclude the triangle region.
285*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_COLOR_NEAR(11, 4, GLColor::red, kErrorMargin);
286*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_COLOR_NEAR(12, 4, GLColor::red, kLargeMargin);
287*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_COLOR_NEAR(15, 5, kDarkRed, kLargeMargin);
288*8975f5c5SAndroid Build Coastguard Worker     }
289*8975f5c5SAndroid Build Coastguard Worker }
290*8975f5c5SAndroid Build Coastguard Worker 
291*8975f5c5SAndroid Build Coastguard Worker // Test that alpha to coverage is enabled works properly along with early fragment test.
TEST_P(MultisampleTest,AlphaToSampleCoverage)292*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleTest, AlphaToSampleCoverage)
293*8975f5c5SAndroid Build Coastguard Worker {
294*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42264264
295*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsOzone());
296*8975f5c5SAndroid Build Coastguard Worker 
297*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] =
298*8975f5c5SAndroid Build Coastguard Worker         "precision highp float;\n"
299*8975f5c5SAndroid Build Coastguard Worker         "void main()\n"
300*8975f5c5SAndroid Build Coastguard Worker         "{\n"
301*8975f5c5SAndroid Build Coastguard Worker         "    gl_FragColor = vec4(1.0, 0.0, 0.0, 0.0);\n"
302*8975f5c5SAndroid Build Coastguard Worker         "}\n";
303*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(transparentRedProgram, essl1_shaders::vs::Simple(), kFS);
304*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(transparentRedProgram);
305*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_DEPTH_TEST);
306*8975f5c5SAndroid Build Coastguard Worker     glDepthFunc(GL_LESS);
307*8975f5c5SAndroid Build Coastguard Worker     glClearDepthf(1.0f);
308*8975f5c5SAndroid Build Coastguard Worker     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);  // clear to green
309*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
310*8975f5c5SAndroid Build Coastguard Worker     // This should pass depth test, but because of the alpha to coverage enabled, and alpha is 0,
311*8975f5c5SAndroid Build Coastguard Worker     // the fragment should be discarded. If early fragment test is disabled, no depth will be
312*8975f5c5SAndroid Build Coastguard Worker     // written. depth buffer should be 1.0.
313*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
314*8975f5c5SAndroid Build Coastguard Worker     // There was a bug in ANGLE that we are checking sampler coverage enabled or not instead of
315*8975f5c5SAndroid Build Coastguard Worker     // alpha to sample coverage enabled or not. This is specically try to trick ANGLE so that it
316*8975f5c5SAndroid Build Coastguard Worker     // will enable early fragment test. When early fragment test is accidentally enabled, then the
317*8975f5c5SAndroid Build Coastguard Worker     // depth test will occur before fragment shader, and depth buffer maybe written with value
318*8975f5c5SAndroid Build Coastguard Worker     // (0.0+1.0)/2.0=0.5.
319*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_SAMPLE_COVERAGE);
320*8975f5c5SAndroid Build Coastguard Worker     drawQuad(transparentRedProgram, essl1_shaders::PositionAttrib(), 0.0f);
321*8975f5c5SAndroid Build Coastguard Worker 
322*8975f5c5SAndroid Build Coastguard Worker     // Now draw with blue color but to test against 0.0f. This should fail depth test
323*8975f5c5SAndroid Build Coastguard Worker     glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
324*8975f5c5SAndroid Build Coastguard Worker     glDisable(GL_SAMPLE_COVERAGE);
325*8975f5c5SAndroid Build Coastguard Worker     glDepthFunc(GL_GREATER);
326*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
327*8975f5c5SAndroid Build Coastguard Worker     // Zd = 0.5f means (0.5+1.0)/2.0=0.75. Depends on early fragment on or off this will pass or
328*8975f5c5SAndroid Build Coastguard Worker     // fail depth test.
329*8975f5c5SAndroid Build Coastguard Worker     drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);
330*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::green);
331*8975f5c5SAndroid Build Coastguard Worker 
332*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
333*8975f5c5SAndroid Build Coastguard Worker }
334*8975f5c5SAndroid Build Coastguard Worker 
335*8975f5c5SAndroid Build Coastguard Worker // Test that resolve from multisample default framebuffer works.
TEST_P(MultisampleTestES3,ResolveToFBO)336*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleTestES3, ResolveToFBO)
337*8975f5c5SAndroid Build Coastguard Worker {
338*8975f5c5SAndroid Build Coastguard Worker     GLTexture resolveTexture;
339*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, resolveTexture);
340*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWindowWidth, kWindowHeight, 0, GL_RGBA,
341*8975f5c5SAndroid Build Coastguard Worker                  GL_UNSIGNED_BYTE, nullptr);
342*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
343*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
344*8975f5c5SAndroid Build Coastguard Worker 
345*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer resolveFBO;
346*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
347*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 0);
348*8975f5c5SAndroid Build Coastguard Worker 
349*8975f5c5SAndroid Build Coastguard Worker     // Clear the default framebuffer
350*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, 0);
351*8975f5c5SAndroid Build Coastguard Worker     glClearColor(0.25, 0.5, 0.75, 0.25);
352*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
353*8975f5c5SAndroid Build Coastguard Worker 
354*8975f5c5SAndroid Build Coastguard Worker     // Resolve into FBO
355*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO);
356*8975f5c5SAndroid Build Coastguard Worker     glClearColor(1, 0, 0, 1);
357*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
358*8975f5c5SAndroid Build Coastguard Worker     glBlitFramebuffer(0, 0, kWindowWidth, kWindowHeight, 0, 0, kWindowWidth, kWindowHeight,
359*8975f5c5SAndroid Build Coastguard Worker                       GL_COLOR_BUFFER_BIT, GL_NEAREST);
360*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
361*8975f5c5SAndroid Build Coastguard Worker 
362*8975f5c5SAndroid Build Coastguard Worker     const GLColor kResult = GLColor(63, 127, 191, 63);
363*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO);
364*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(0, 0, kResult, 1);
365*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(kWindowWidth - 1, 0, kResult, 1);
366*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(0, kWindowHeight - 1, kResult, 1);
367*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(kWindowWidth - 1, kWindowHeight - 1, kResult, 1);
368*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(kWindowWidth / 2, kWindowHeight / 2, kResult, 1);
369*8975f5c5SAndroid Build Coastguard Worker }
370*8975f5c5SAndroid Build Coastguard Worker 
371*8975f5c5SAndroid Build Coastguard Worker // Test that resolve from multisample default framebuffer after an open render pass works when the
372*8975f5c5SAndroid Build Coastguard Worker // framebuffer is also immediately implicitly resolved due to swap afterwards.
TEST_P(MultisampleTestES3,RenderPassResolveToFBOThenSwap)373*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleTestES3, RenderPassResolveToFBOThenSwap)
374*8975f5c5SAndroid Build Coastguard Worker {
375*8975f5c5SAndroid Build Coastguard Worker     GLTexture resolveTexture;
376*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, resolveTexture);
377*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWindowWidth, kWindowHeight, 0, GL_RGBA,
378*8975f5c5SAndroid Build Coastguard Worker                  GL_UNSIGNED_BYTE, nullptr);
379*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
380*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
381*8975f5c5SAndroid Build Coastguard Worker 
382*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer resolveFBO;
383*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, resolveFBO);
384*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, resolveTexture, 0);
385*8975f5c5SAndroid Build Coastguard Worker 
386*8975f5c5SAndroid Build Coastguard Worker     auto runTest = [&](bool flipY) {
387*8975f5c5SAndroid Build Coastguard Worker         // Open a render pass by drawing to the default framebuffer
388*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, 0);
389*8975f5c5SAndroid Build Coastguard Worker         ANGLE_GL_PROGRAM(red, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
390*8975f5c5SAndroid Build Coastguard Worker         drawQuad(red, essl1_shaders::PositionAttrib(), 0.5f);
391*8975f5c5SAndroid Build Coastguard Worker 
392*8975f5c5SAndroid Build Coastguard Worker         // Resolve into FBO
393*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO);
394*8975f5c5SAndroid Build Coastguard Worker         if (flipY)
395*8975f5c5SAndroid Build Coastguard Worker         {
396*8975f5c5SAndroid Build Coastguard Worker             glFramebufferParameteriMESA(GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER_FLIP_Y_MESA, 1);
397*8975f5c5SAndroid Build Coastguard Worker         }
398*8975f5c5SAndroid Build Coastguard Worker         glBlitFramebuffer(0, 0, kWindowWidth, kWindowHeight, 0, 0, kWindowWidth, kWindowHeight,
399*8975f5c5SAndroid Build Coastguard Worker                           GL_COLOR_BUFFER_BIT, GL_NEAREST);
400*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
401*8975f5c5SAndroid Build Coastguard Worker 
402*8975f5c5SAndroid Build Coastguard Worker         // Immediately swap so that an implicit resolve to the backbuffer happens right away.
403*8975f5c5SAndroid Build Coastguard Worker         swapBuffers();
404*8975f5c5SAndroid Build Coastguard Worker 
405*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO);
406*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_RECT_EQ(0, 0, kWindowWidth, kWindowHeight, GLColor::red);
407*8975f5c5SAndroid Build Coastguard Worker     };
408*8975f5c5SAndroid Build Coastguard Worker 
409*8975f5c5SAndroid Build Coastguard Worker     runTest(false);
410*8975f5c5SAndroid Build Coastguard Worker     if (IsGLExtensionEnabled("GL_MESA_framebuffer_flip_y"))
411*8975f5c5SAndroid Build Coastguard Worker     {
412*8975f5c5SAndroid Build Coastguard Worker         // With multiple backends, the default framebuffer is flipped w.r.t GL's coordinates.  As a
413*8975f5c5SAndroid Build Coastguard Worker         // result, the glBlitFramebuffer may need to take a different path from a direct multisample
414*8975f5c5SAndroid Build Coastguard Worker         // resolve.  This test ensures a direct resolve is also tested where possible.
415*8975f5c5SAndroid Build Coastguard Worker         runTest(true);
416*8975f5c5SAndroid Build Coastguard Worker     }
417*8975f5c5SAndroid Build Coastguard Worker }
418*8975f5c5SAndroid Build Coastguard Worker 
419*8975f5c5SAndroid Build Coastguard Worker // Test that CopyTexImage2D from an MSAA default fbo works
TEST_P(MultisampleTestES3,CopyTexImage2DFromMsaaDefaultFbo)420*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleTestES3, CopyTexImage2DFromMsaaDefaultFbo)
421*8975f5c5SAndroid Build Coastguard Worker {
422*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] = R"(#version 300 es
423*8975f5c5SAndroid Build Coastguard Worker #extension GL_OES_sample_variables : require
424*8975f5c5SAndroid Build Coastguard Worker precision highp float;
425*8975f5c5SAndroid Build Coastguard Worker out vec4 my_FragColor;
426*8975f5c5SAndroid Build Coastguard Worker 
427*8975f5c5SAndroid Build Coastguard Worker void main()
428*8975f5c5SAndroid Build Coastguard Worker {
429*8975f5c5SAndroid Build Coastguard Worker     switch (uint(gl_SampleID))
430*8975f5c5SAndroid Build Coastguard Worker     {
431*8975f5c5SAndroid Build Coastguard Worker         case 0u:
432*8975f5c5SAndroid Build Coastguard Worker             my_FragColor = vec4(1.0, 0.9, 0.8, 0.7);
433*8975f5c5SAndroid Build Coastguard Worker             break;
434*8975f5c5SAndroid Build Coastguard Worker         case 1u:
435*8975f5c5SAndroid Build Coastguard Worker             my_FragColor = vec4(0.0, 0.1, 0.2, 0.3);
436*8975f5c5SAndroid Build Coastguard Worker             break;
437*8975f5c5SAndroid Build Coastguard Worker         case 2u:
438*8975f5c5SAndroid Build Coastguard Worker             my_FragColor = vec4(0.5, 0.25, 0.75, 1.0);
439*8975f5c5SAndroid Build Coastguard Worker             break;
440*8975f5c5SAndroid Build Coastguard Worker         case 3u:
441*8975f5c5SAndroid Build Coastguard Worker             my_FragColor = vec4(0.4, 0.6, 0.2, 0.8);
442*8975f5c5SAndroid Build Coastguard Worker             break;
443*8975f5c5SAndroid Build Coastguard Worker         default:
444*8975f5c5SAndroid Build Coastguard Worker             my_FragColor = vec4(0.0);
445*8975f5c5SAndroid Build Coastguard Worker             break;
446*8975f5c5SAndroid Build Coastguard Worker     }
447*8975f5c5SAndroid Build Coastguard Worker }
448*8975f5c5SAndroid Build Coastguard Worker )";
449*8975f5c5SAndroid Build Coastguard Worker 
450*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(programMs, essl3_shaders::vs::Simple(), kFS);
451*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(programMs);
452*8975f5c5SAndroid Build Coastguard Worker 
453*8975f5c5SAndroid Build Coastguard Worker     // Clear the default framebuffer and draw
454*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, 0);
455*8975f5c5SAndroid Build Coastguard Worker     glClearColor(0.25, 0.5, 0.75, 0.25);
456*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
457*8975f5c5SAndroid Build Coastguard Worker     drawQuad(programMs, essl3_shaders::PositionAttrib(), 0.0);
458*8975f5c5SAndroid Build Coastguard Worker 
459*8975f5c5SAndroid Build Coastguard Worker     // Create a texture for copy
460*8975f5c5SAndroid Build Coastguard Worker     GLTexture copyTexture;
461*8975f5c5SAndroid Build Coastguard Worker     glBindTexture(GL_TEXTURE_2D, copyTexture);
462*8975f5c5SAndroid Build Coastguard Worker     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWindowWidth, kWindowHeight, 0, GL_RGBA,
463*8975f5c5SAndroid Build Coastguard Worker                  GL_UNSIGNED_BYTE, nullptr);
464*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
465*8975f5c5SAndroid Build Coastguard Worker     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
466*8975f5c5SAndroid Build Coastguard Worker 
467*8975f5c5SAndroid Build Coastguard Worker     constexpr int kCopyWidth  = 10;
468*8975f5c5SAndroid Build Coastguard Worker     constexpr int kCopyHeight = 5;
469*8975f5c5SAndroid Build Coastguard Worker     // Copy MSAA default framebuffer into the texture
470*8975f5c5SAndroid Build Coastguard Worker     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, kCopyWidth, kCopyHeight, 0);
471*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
472*8975f5c5SAndroid Build Coastguard Worker 
473*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer readFbo;
474*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, readFbo);
475*8975f5c5SAndroid Build Coastguard Worker     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, copyTexture, 0);
476*8975f5c5SAndroid Build Coastguard Worker 
477*8975f5c5SAndroid Build Coastguard Worker     const GLColor kResult = GLColor(121, 118, 124, 178);
478*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(0, 0, kResult, 1);
479*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(kCopyWidth - 1, 0, kResult, 1);
480*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(0, kCopyHeight - 1, kResult, 1);
481*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(kCopyWidth - 1, kCopyHeight - 1, kResult, 1);
482*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(kCopyWidth / 2, kCopyHeight / 2, kResult, 1);
483*8975f5c5SAndroid Build Coastguard Worker }
484*8975f5c5SAndroid Build Coastguard Worker 
485*8975f5c5SAndroid Build Coastguard Worker class MultisampleResolveTest : public ANGLETest<>
486*8975f5c5SAndroid Build Coastguard Worker {
487*8975f5c5SAndroid Build Coastguard Worker   protected:
488*8975f5c5SAndroid Build Coastguard Worker     static const GLColor kEXPECTED_R8;
489*8975f5c5SAndroid Build Coastguard Worker     static const GLColor kEXPECTED_RG8;
490*8975f5c5SAndroid Build Coastguard Worker     static const GLColor kEXPECTED_RGB8;
491*8975f5c5SAndroid Build Coastguard Worker     static const GLColor kEXPECTED_RGBA8;
492*8975f5c5SAndroid Build Coastguard Worker     static const GLColor32F kEXPECTED_RF;
493*8975f5c5SAndroid Build Coastguard Worker     static const GLColor32F kEXPECTED_RGF;
494*8975f5c5SAndroid Build Coastguard Worker     static const GLColor32F kEXPECTED_RGBF;
495*8975f5c5SAndroid Build Coastguard Worker     static const GLColor32F kEXPECTED_RGBAF;
496*8975f5c5SAndroid Build Coastguard Worker     static constexpr GLint kWidth  = 13;
497*8975f5c5SAndroid Build Coastguard Worker     static constexpr GLint kHeight = 11;
498*8975f5c5SAndroid Build Coastguard Worker 
MultisampleResolveTest()499*8975f5c5SAndroid Build Coastguard Worker     MultisampleResolveTest() {}
500*8975f5c5SAndroid Build Coastguard Worker 
501*8975f5c5SAndroid Build Coastguard Worker     struct GLResources
502*8975f5c5SAndroid Build Coastguard Worker     {
503*8975f5c5SAndroid Build Coastguard Worker         GLFramebuffer fb;
504*8975f5c5SAndroid Build Coastguard Worker         GLRenderbuffer rb;
505*8975f5c5SAndroid Build Coastguard Worker     };
506*8975f5c5SAndroid Build Coastguard Worker 
resolveToFBO(GLenum format,GLint samples,GLint width,GLint height,GLResources & resources)507*8975f5c5SAndroid Build Coastguard Worker     void resolveToFBO(GLenum format,
508*8975f5c5SAndroid Build Coastguard Worker                       GLint samples,
509*8975f5c5SAndroid Build Coastguard Worker                       GLint width,
510*8975f5c5SAndroid Build Coastguard Worker                       GLint height,
511*8975f5c5SAndroid Build Coastguard Worker                       GLResources &resources)
512*8975f5c5SAndroid Build Coastguard Worker     {
513*8975f5c5SAndroid Build Coastguard Worker         constexpr char kVS[] = R"(#version 300 es
514*8975f5c5SAndroid Build Coastguard Worker         layout(location = 0) in vec4 position;
515*8975f5c5SAndroid Build Coastguard Worker         void main() {
516*8975f5c5SAndroid Build Coastguard Worker            gl_Position = position;
517*8975f5c5SAndroid Build Coastguard Worker         }
518*8975f5c5SAndroid Build Coastguard Worker         )";
519*8975f5c5SAndroid Build Coastguard Worker 
520*8975f5c5SAndroid Build Coastguard Worker         constexpr char kFS[] = R"(#version 300 es
521*8975f5c5SAndroid Build Coastguard Worker         precision highp float;
522*8975f5c5SAndroid Build Coastguard Worker         out vec4 color;
523*8975f5c5SAndroid Build Coastguard Worker         void main() {
524*8975f5c5SAndroid Build Coastguard Worker            color = vec4(0.5, 0.6, 0.7, 0.8);
525*8975f5c5SAndroid Build Coastguard Worker         }
526*8975f5c5SAndroid Build Coastguard Worker         )";
527*8975f5c5SAndroid Build Coastguard Worker 
528*8975f5c5SAndroid Build Coastguard Worker         ANGLE_GL_PROGRAM(program, kVS, kFS);
529*8975f5c5SAndroid Build Coastguard Worker 
530*8975f5c5SAndroid Build Coastguard Worker         // Make samples = 4 multi-sample framebuffer.
531*8975f5c5SAndroid Build Coastguard Worker         GLFramebuffer fb0;
532*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, fb0);
533*8975f5c5SAndroid Build Coastguard Worker 
534*8975f5c5SAndroid Build Coastguard Worker         GLRenderbuffer rb0;
535*8975f5c5SAndroid Build Coastguard Worker         glBindRenderbuffer(GL_RENDERBUFFER, rb0);
536*8975f5c5SAndroid Build Coastguard Worker         glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, format, width, height);
537*8975f5c5SAndroid Build Coastguard Worker         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb0);
538*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
539*8975f5c5SAndroid Build Coastguard Worker 
540*8975f5c5SAndroid Build Coastguard Worker         // Make samples = 0 multi-sample framebuffer.
541*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, resources.fb);
542*8975f5c5SAndroid Build Coastguard Worker 
543*8975f5c5SAndroid Build Coastguard Worker         glBindRenderbuffer(GL_RENDERBUFFER, resources.rb);
544*8975f5c5SAndroid Build Coastguard Worker         glRenderbufferStorageMultisample(GL_RENDERBUFFER, 0, format, width, height);
545*8975f5c5SAndroid Build Coastguard Worker         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
546*8975f5c5SAndroid Build Coastguard Worker                                   resources.rb);
547*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
548*8975f5c5SAndroid Build Coastguard Worker 
549*8975f5c5SAndroid Build Coastguard Worker         // Draw quad to fb0.
550*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, fb0);
551*8975f5c5SAndroid Build Coastguard Worker         glViewport(0, 0, width, height);
552*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(program);
553*8975f5c5SAndroid Build Coastguard Worker         GLBuffer buf;
554*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_ARRAY_BUFFER, buf);
555*8975f5c5SAndroid Build Coastguard Worker 
556*8975f5c5SAndroid Build Coastguard Worker         constexpr float vertices[] = {
557*8975f5c5SAndroid Build Coastguard Worker             -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f,
558*8975f5c5SAndroid Build Coastguard Worker         };
559*8975f5c5SAndroid Build Coastguard Worker         glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
560*8975f5c5SAndroid Build Coastguard Worker         glEnableVertexAttribArray(0);
561*8975f5c5SAndroid Build Coastguard Worker         glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
562*8975f5c5SAndroid Build Coastguard Worker         glDrawArrays(GL_TRIANGLES, 0, 6);
563*8975f5c5SAndroid Build Coastguard Worker 
564*8975f5c5SAndroid Build Coastguard Worker         // Blit fb0 to fb1.
565*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_READ_FRAMEBUFFER, fb0);
566*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resources.fb);
567*8975f5c5SAndroid Build Coastguard Worker         glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT,
568*8975f5c5SAndroid Build Coastguard Worker                           GL_NEAREST);
569*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
570*8975f5c5SAndroid Build Coastguard Worker 
571*8975f5c5SAndroid Build Coastguard Worker         // Prep for read pixels.
572*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_READ_FRAMEBUFFER, resources.fb);
573*8975f5c5SAndroid Build Coastguard Worker     }
574*8975f5c5SAndroid Build Coastguard Worker 
testResolveToUNormFBO(GLenum format,const GLColor & expected_color,GLint samples,GLint width,GLint height)575*8975f5c5SAndroid Build Coastguard Worker     void testResolveToUNormFBO(GLenum format,
576*8975f5c5SAndroid Build Coastguard Worker                                const GLColor &expected_color,
577*8975f5c5SAndroid Build Coastguard Worker                                GLint samples,
578*8975f5c5SAndroid Build Coastguard Worker                                GLint width,
579*8975f5c5SAndroid Build Coastguard Worker                                GLint height)
580*8975f5c5SAndroid Build Coastguard Worker     {
581*8975f5c5SAndroid Build Coastguard Worker         GLResources resources;
582*8975f5c5SAndroid Build Coastguard Worker         resolveToFBO(format, samples, width, height, resources);
583*8975f5c5SAndroid Build Coastguard Worker 
584*8975f5c5SAndroid Build Coastguard Worker         // Check the results
585*8975f5c5SAndroid Build Coastguard Worker         for (GLint y = 0; y < kHeight; ++y)
586*8975f5c5SAndroid Build Coastguard Worker         {
587*8975f5c5SAndroid Build Coastguard Worker             for (GLint x = 0; x < kWidth; ++x)
588*8975f5c5SAndroid Build Coastguard Worker             {
589*8975f5c5SAndroid Build Coastguard Worker                 EXPECT_PIXEL_COLOR_NEAR(x, y, expected_color, 2);
590*8975f5c5SAndroid Build Coastguard Worker             }
591*8975f5c5SAndroid Build Coastguard Worker         }
592*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
593*8975f5c5SAndroid Build Coastguard Worker     }
594*8975f5c5SAndroid Build Coastguard Worker 
testResolveToHalfFBO(GLenum format,const GLColor32F & expected_color,GLint samples,GLint width,GLint height)595*8975f5c5SAndroid Build Coastguard Worker     void testResolveToHalfFBO(GLenum format,
596*8975f5c5SAndroid Build Coastguard Worker                               const GLColor32F &expected_color,
597*8975f5c5SAndroid Build Coastguard Worker                               GLint samples,
598*8975f5c5SAndroid Build Coastguard Worker                               GLint width,
599*8975f5c5SAndroid Build Coastguard Worker                               GLint height)
600*8975f5c5SAndroid Build Coastguard Worker     {
601*8975f5c5SAndroid Build Coastguard Worker         if (!IsGLExtensionEnabled("GL_EXT_color_buffer_half_float"))
602*8975f5c5SAndroid Build Coastguard Worker         {
603*8975f5c5SAndroid Build Coastguard Worker             return;
604*8975f5c5SAndroid Build Coastguard Worker         }
605*8975f5c5SAndroid Build Coastguard Worker 
606*8975f5c5SAndroid Build Coastguard Worker         GLResources resources;
607*8975f5c5SAndroid Build Coastguard Worker         resolveToFBO(format, samples, width, height, resources);
608*8975f5c5SAndroid Build Coastguard Worker 
609*8975f5c5SAndroid Build Coastguard Worker         // Check the results
610*8975f5c5SAndroid Build Coastguard Worker         for (GLint y = 0; y < kHeight; ++y)
611*8975f5c5SAndroid Build Coastguard Worker         {
612*8975f5c5SAndroid Build Coastguard Worker             for (GLint x = 0; x < kWidth; ++x)
613*8975f5c5SAndroid Build Coastguard Worker             {
614*8975f5c5SAndroid Build Coastguard Worker                 EXPECT_PIXEL_COLOR32F_NEAR(x, y, expected_color, 2.0f / 255.0f);
615*8975f5c5SAndroid Build Coastguard Worker             }
616*8975f5c5SAndroid Build Coastguard Worker         }
617*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
618*8975f5c5SAndroid Build Coastguard Worker     }
619*8975f5c5SAndroid Build Coastguard Worker 
testResolveToFloatFBO(GLenum format,const GLColor32F & expected_color,GLint samples,GLint width,GLint height)620*8975f5c5SAndroid Build Coastguard Worker     void testResolveToFloatFBO(GLenum format,
621*8975f5c5SAndroid Build Coastguard Worker                                const GLColor32F &expected_color,
622*8975f5c5SAndroid Build Coastguard Worker                                GLint samples,
623*8975f5c5SAndroid Build Coastguard Worker                                GLint width,
624*8975f5c5SAndroid Build Coastguard Worker                                GLint height)
625*8975f5c5SAndroid Build Coastguard Worker     {
626*8975f5c5SAndroid Build Coastguard Worker         if (!IsGLExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgba"))
627*8975f5c5SAndroid Build Coastguard Worker         {
628*8975f5c5SAndroid Build Coastguard Worker             return;
629*8975f5c5SAndroid Build Coastguard Worker         }
630*8975f5c5SAndroid Build Coastguard Worker 
631*8975f5c5SAndroid Build Coastguard Worker         GLResources resources;
632*8975f5c5SAndroid Build Coastguard Worker         resolveToFBO(format, samples, width, height, resources);
633*8975f5c5SAndroid Build Coastguard Worker 
634*8975f5c5SAndroid Build Coastguard Worker         // Check the results
635*8975f5c5SAndroid Build Coastguard Worker         for (GLint y = 0; y < kHeight; ++y)
636*8975f5c5SAndroid Build Coastguard Worker         {
637*8975f5c5SAndroid Build Coastguard Worker             for (GLint x = 0; x < kWidth; ++x)
638*8975f5c5SAndroid Build Coastguard Worker             {
639*8975f5c5SAndroid Build Coastguard Worker                 EXPECT_PIXEL_COLOR32F_NEAR(x, y, expected_color, 2.0f / 255.0f);
640*8975f5c5SAndroid Build Coastguard Worker             }
641*8975f5c5SAndroid Build Coastguard Worker         }
642*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
643*8975f5c5SAndroid Build Coastguard Worker     }
644*8975f5c5SAndroid Build Coastguard Worker 
testResolveToRGBFloatFBO(GLenum format,const GLColor32F & expected_color,GLint samples,GLint width,GLint height)645*8975f5c5SAndroid Build Coastguard Worker     void testResolveToRGBFloatFBO(GLenum format,
646*8975f5c5SAndroid Build Coastguard Worker                                   const GLColor32F &expected_color,
647*8975f5c5SAndroid Build Coastguard Worker                                   GLint samples,
648*8975f5c5SAndroid Build Coastguard Worker                                   GLint width,
649*8975f5c5SAndroid Build Coastguard Worker                                   GLint height)
650*8975f5c5SAndroid Build Coastguard Worker     {
651*8975f5c5SAndroid Build Coastguard Worker         if (!IsGLExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgb"))
652*8975f5c5SAndroid Build Coastguard Worker         {
653*8975f5c5SAndroid Build Coastguard Worker             return;
654*8975f5c5SAndroid Build Coastguard Worker         }
655*8975f5c5SAndroid Build Coastguard Worker 
656*8975f5c5SAndroid Build Coastguard Worker         GLResources resources;
657*8975f5c5SAndroid Build Coastguard Worker         resolveToFBO(format, samples, width, height, resources);
658*8975f5c5SAndroid Build Coastguard Worker 
659*8975f5c5SAndroid Build Coastguard Worker         // Check the results
660*8975f5c5SAndroid Build Coastguard Worker         for (GLint y = 0; y < kHeight; ++y)
661*8975f5c5SAndroid Build Coastguard Worker         {
662*8975f5c5SAndroid Build Coastguard Worker             for (GLint x = 0; x < kWidth; ++x)
663*8975f5c5SAndroid Build Coastguard Worker             {
664*8975f5c5SAndroid Build Coastguard Worker                 EXPECT_PIXEL_COLOR32F_NEAR(x, y, expected_color, 2.0f / 255.0f);
665*8975f5c5SAndroid Build Coastguard Worker             }
666*8975f5c5SAndroid Build Coastguard Worker         }
667*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
668*8975f5c5SAndroid Build Coastguard Worker     }
669*8975f5c5SAndroid Build Coastguard Worker 
peelDepth(GLint colorLoc)670*8975f5c5SAndroid Build Coastguard Worker     void peelDepth(GLint colorLoc)
671*8975f5c5SAndroid Build Coastguard Worker     {
672*8975f5c5SAndroid Build Coastguard Worker         // Draw full quads from front to back and increasing depths
673*8975f5c5SAndroid Build Coastguard Worker         // with depth test = less.
674*8975f5c5SAndroid Build Coastguard Worker         glDepthMask(GL_FALSE);
675*8975f5c5SAndroid Build Coastguard Worker         constexpr int steps = 64;
676*8975f5c5SAndroid Build Coastguard Worker         for (int i = 0; i < steps; ++i)
677*8975f5c5SAndroid Build Coastguard Worker         {
678*8975f5c5SAndroid Build Coastguard Worker             float l = float(i) / float(steps);
679*8975f5c5SAndroid Build Coastguard Worker             float c = l;
680*8975f5c5SAndroid Build Coastguard Worker             float z = c * 2.0f - 1.0f;
681*8975f5c5SAndroid Build Coastguard Worker             glVertexAttrib4f(1, 0, 0, z, 0);
682*8975f5c5SAndroid Build Coastguard Worker             glUniform4f(colorLoc, c, c, c, c);
683*8975f5c5SAndroid Build Coastguard Worker             glDrawArrays(GL_TRIANGLES, 0, 6);
684*8975f5c5SAndroid Build Coastguard Worker         }
685*8975f5c5SAndroid Build Coastguard Worker         glDepthMask(GL_TRUE);
686*8975f5c5SAndroid Build Coastguard Worker     }
687*8975f5c5SAndroid Build Coastguard Worker 
testResolveDepthToFBO(GLenum format,GLenum attachment,GLint samples,GLint width,GLint height)688*8975f5c5SAndroid Build Coastguard Worker     void testResolveDepthToFBO(GLenum format,
689*8975f5c5SAndroid Build Coastguard Worker                                GLenum attachment,
690*8975f5c5SAndroid Build Coastguard Worker                                GLint samples,
691*8975f5c5SAndroid Build Coastguard Worker                                GLint width,
692*8975f5c5SAndroid Build Coastguard Worker                                GLint height)
693*8975f5c5SAndroid Build Coastguard Worker     {
694*8975f5c5SAndroid Build Coastguard Worker         constexpr char kVS[] = R"(#version 300 es
695*8975f5c5SAndroid Build Coastguard Worker         layout(location = 0) in vec4 position;
696*8975f5c5SAndroid Build Coastguard Worker         void main() {
697*8975f5c5SAndroid Build Coastguard Worker            gl_Position = position;
698*8975f5c5SAndroid Build Coastguard Worker         }
699*8975f5c5SAndroid Build Coastguard Worker         )";
700*8975f5c5SAndroid Build Coastguard Worker 
701*8975f5c5SAndroid Build Coastguard Worker         constexpr char kFS[] = R"(#version 300 es
702*8975f5c5SAndroid Build Coastguard Worker         precision highp float;
703*8975f5c5SAndroid Build Coastguard Worker         out vec4 color;
704*8975f5c5SAndroid Build Coastguard Worker         void main() {
705*8975f5c5SAndroid Build Coastguard Worker            color = vec4(0.5, 0.6, 0.7, 0.8);
706*8975f5c5SAndroid Build Coastguard Worker         }
707*8975f5c5SAndroid Build Coastguard Worker         )";
708*8975f5c5SAndroid Build Coastguard Worker 
709*8975f5c5SAndroid Build Coastguard Worker         constexpr char kDepthVS[] = R"(#version 300 es
710*8975f5c5SAndroid Build Coastguard Worker         layout(location = 0) in vec4 position;
711*8975f5c5SAndroid Build Coastguard Worker         layout(location = 1) in vec4 offset;
712*8975f5c5SAndroid Build Coastguard Worker         void main() {
713*8975f5c5SAndroid Build Coastguard Worker            gl_Position = position + offset;
714*8975f5c5SAndroid Build Coastguard Worker         }
715*8975f5c5SAndroid Build Coastguard Worker         )";
716*8975f5c5SAndroid Build Coastguard Worker 
717*8975f5c5SAndroid Build Coastguard Worker         constexpr char kDepthFS[] = R"(#version 300 es
718*8975f5c5SAndroid Build Coastguard Worker         precision highp float;
719*8975f5c5SAndroid Build Coastguard Worker         uniform vec4 color;
720*8975f5c5SAndroid Build Coastguard Worker         out vec4 outColor;
721*8975f5c5SAndroid Build Coastguard Worker         void main() {
722*8975f5c5SAndroid Build Coastguard Worker            outColor = color;
723*8975f5c5SAndroid Build Coastguard Worker         }
724*8975f5c5SAndroid Build Coastguard Worker         )";
725*8975f5c5SAndroid Build Coastguard Worker 
726*8975f5c5SAndroid Build Coastguard Worker         ANGLE_GL_PROGRAM(program, kVS, kFS);
727*8975f5c5SAndroid Build Coastguard Worker         ANGLE_GL_PROGRAM(depthProgram, kDepthVS, kDepthFS);
728*8975f5c5SAndroid Build Coastguard Worker 
729*8975f5c5SAndroid Build Coastguard Worker         // Make samples = 4 multi-sample framebuffer.
730*8975f5c5SAndroid Build Coastguard Worker         GLFramebuffer fb0;
731*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, fb0);
732*8975f5c5SAndroid Build Coastguard Worker 
733*8975f5c5SAndroid Build Coastguard Worker         GLRenderbuffer rb0;
734*8975f5c5SAndroid Build Coastguard Worker         glBindRenderbuffer(GL_RENDERBUFFER, rb0);
735*8975f5c5SAndroid Build Coastguard Worker         glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_RGBA8, width, height);
736*8975f5c5SAndroid Build Coastguard Worker         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb0);
737*8975f5c5SAndroid Build Coastguard Worker 
738*8975f5c5SAndroid Build Coastguard Worker         GLRenderbuffer db0;
739*8975f5c5SAndroid Build Coastguard Worker         glBindRenderbuffer(GL_RENDERBUFFER, db0);
740*8975f5c5SAndroid Build Coastguard Worker         glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, format, width, height);
741*8975f5c5SAndroid Build Coastguard Worker         glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, db0);
742*8975f5c5SAndroid Build Coastguard Worker 
743*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
744*8975f5c5SAndroid Build Coastguard Worker 
745*8975f5c5SAndroid Build Coastguard Worker         // Make samples = 0 multi-sample framebuffer.
746*8975f5c5SAndroid Build Coastguard Worker         GLFramebuffer fb1;
747*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, fb1);
748*8975f5c5SAndroid Build Coastguard Worker 
749*8975f5c5SAndroid Build Coastguard Worker         GLRenderbuffer rb1;
750*8975f5c5SAndroid Build Coastguard Worker         glBindRenderbuffer(GL_RENDERBUFFER, rb1);
751*8975f5c5SAndroid Build Coastguard Worker         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, width, height);
752*8975f5c5SAndroid Build Coastguard Worker         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rb1);
753*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
754*8975f5c5SAndroid Build Coastguard Worker 
755*8975f5c5SAndroid Build Coastguard Worker         GLRenderbuffer db1;
756*8975f5c5SAndroid Build Coastguard Worker         glBindRenderbuffer(GL_RENDERBUFFER, db1);
757*8975f5c5SAndroid Build Coastguard Worker         glRenderbufferStorage(GL_RENDERBUFFER, format, width, height);
758*8975f5c5SAndroid Build Coastguard Worker         glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, db1);
759*8975f5c5SAndroid Build Coastguard Worker 
760*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
761*8975f5c5SAndroid Build Coastguard Worker 
762*8975f5c5SAndroid Build Coastguard Worker         // Draw quad to fb0.
763*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, fb0);
764*8975f5c5SAndroid Build Coastguard Worker         glViewport(0, 0, width, height);
765*8975f5c5SAndroid Build Coastguard Worker         glClearColor(1, 1, 1, 1);
766*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(program);
767*8975f5c5SAndroid Build Coastguard Worker 
768*8975f5c5SAndroid Build Coastguard Worker         GLVertexArray va0;
769*8975f5c5SAndroid Build Coastguard Worker         glBindVertexArray(va0);
770*8975f5c5SAndroid Build Coastguard Worker 
771*8975f5c5SAndroid Build Coastguard Worker         GLBuffer buf0;
772*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_ARRAY_BUFFER, buf0);
773*8975f5c5SAndroid Build Coastguard Worker 
774*8975f5c5SAndroid Build Coastguard Worker         // clang-format off
775*8975f5c5SAndroid Build Coastguard Worker         constexpr float vertices[] = {
776*8975f5c5SAndroid Build Coastguard Worker             -1.0f, -1.0f, -1.0,
777*8975f5c5SAndroid Build Coastguard Worker              1.0f, -1.0f,  0.0,
778*8975f5c5SAndroid Build Coastguard Worker             -1.0f,  1.0f,  0.0,
779*8975f5c5SAndroid Build Coastguard Worker             -1.0f,  1.0f,  0.0,
780*8975f5c5SAndroid Build Coastguard Worker              1.0f, -1.0f,  0.0,
781*8975f5c5SAndroid Build Coastguard Worker              1.0f,  1.0f,  1.0,
782*8975f5c5SAndroid Build Coastguard Worker         };
783*8975f5c5SAndroid Build Coastguard Worker         // clang-format on
784*8975f5c5SAndroid Build Coastguard Worker 
785*8975f5c5SAndroid Build Coastguard Worker         glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
786*8975f5c5SAndroid Build Coastguard Worker         glEnableVertexAttribArray(0);
787*8975f5c5SAndroid Build Coastguard Worker         glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
788*8975f5c5SAndroid Build Coastguard Worker         glEnable(GL_DEPTH_TEST);
789*8975f5c5SAndroid Build Coastguard Worker         glDepthFunc(GL_ALWAYS);
790*8975f5c5SAndroid Build Coastguard Worker         glDrawArrays(GL_TRIANGLES, 0, 6);
791*8975f5c5SAndroid Build Coastguard Worker 
792*8975f5c5SAndroid Build Coastguard Worker         // Blit fb0 to fb1.
793*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_READ_FRAMEBUFFER, fb0);
794*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb1);
795*8975f5c5SAndroid Build Coastguard Worker         glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_DEPTH_BUFFER_BIT,
796*8975f5c5SAndroid Build Coastguard Worker                           GL_NEAREST);
797*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
798*8975f5c5SAndroid Build Coastguard Worker 
799*8975f5c5SAndroid Build Coastguard Worker         GLVertexArray va1;
800*8975f5c5SAndroid Build Coastguard Worker         glBindVertexArray(va1);
801*8975f5c5SAndroid Build Coastguard Worker 
802*8975f5c5SAndroid Build Coastguard Worker         // clang-format off
803*8975f5c5SAndroid Build Coastguard Worker         constexpr float depthVertices[] = {
804*8975f5c5SAndroid Build Coastguard Worker             -1.0f, -1.0f,
805*8975f5c5SAndroid Build Coastguard Worker              1.0f, -1.0f,
806*8975f5c5SAndroid Build Coastguard Worker             -1.0f,  1.0f,
807*8975f5c5SAndroid Build Coastguard Worker             -1.0f,  1.0f,
808*8975f5c5SAndroid Build Coastguard Worker              1.0f, -1.0f,
809*8975f5c5SAndroid Build Coastguard Worker              1.0f,  1.0f,
810*8975f5c5SAndroid Build Coastguard Worker         };
811*8975f5c5SAndroid Build Coastguard Worker         // clang-format on
812*8975f5c5SAndroid Build Coastguard Worker 
813*8975f5c5SAndroid Build Coastguard Worker         GLBuffer buf1;
814*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_ARRAY_BUFFER, buf1);
815*8975f5c5SAndroid Build Coastguard Worker         glBufferData(GL_ARRAY_BUFFER, sizeof(depthVertices), depthVertices, GL_STATIC_DRAW);
816*8975f5c5SAndroid Build Coastguard Worker         glEnableVertexAttribArray(0);
817*8975f5c5SAndroid Build Coastguard Worker         glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
818*8975f5c5SAndroid Build Coastguard Worker 
819*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(depthProgram);
820*8975f5c5SAndroid Build Coastguard Worker         GLint colorLoc = glGetUniformLocation(depthProgram, "color");
821*8975f5c5SAndroid Build Coastguard Worker 
822*8975f5c5SAndroid Build Coastguard Worker         // Extract the depth results.
823*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, fb1);
824*8975f5c5SAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
825*8975f5c5SAndroid Build Coastguard Worker         glDepthFunc(GL_LESS);
826*8975f5c5SAndroid Build Coastguard Worker         peelDepth(colorLoc);
827*8975f5c5SAndroid Build Coastguard Worker         std::vector<GLColor> actual(width * height);
828*8975f5c5SAndroid Build Coastguard Worker         glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, actual.data());
829*8975f5c5SAndroid Build Coastguard Worker 
830*8975f5c5SAndroid Build Coastguard Worker         // Render what should be a similar result to the non-multi-sampled fb
831*8975f5c5SAndroid Build Coastguard Worker         glBindVertexArray(va0);
832*8975f5c5SAndroid Build Coastguard Worker         glDepthFunc(GL_ALWAYS);
833*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(program);
834*8975f5c5SAndroid Build Coastguard Worker         glDrawArrays(GL_TRIANGLES, 0, 6);
835*8975f5c5SAndroid Build Coastguard Worker 
836*8975f5c5SAndroid Build Coastguard Worker         // Extract the expected depth results.
837*8975f5c5SAndroid Build Coastguard Worker         glBindVertexArray(va1);
838*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(depthProgram);
839*8975f5c5SAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
840*8975f5c5SAndroid Build Coastguard Worker         glDepthFunc(GL_LESS);
841*8975f5c5SAndroid Build Coastguard Worker         peelDepth(colorLoc);
842*8975f5c5SAndroid Build Coastguard Worker         std::vector<GLColor> expected(width * height);
843*8975f5c5SAndroid Build Coastguard Worker         glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, expected.data());
844*8975f5c5SAndroid Build Coastguard Worker 
845*8975f5c5SAndroid Build Coastguard Worker         for (size_t i = 0; i < expected.size(); ++i)
846*8975f5c5SAndroid Build Coastguard Worker         {
847*8975f5c5SAndroid Build Coastguard Worker             EXPECT_NEAR(expected[i].R, actual[i].R, 8)
848*8975f5c5SAndroid Build Coastguard Worker                 << "at " << (i % width) << "," << (i / width);
849*8975f5c5SAndroid Build Coastguard Worker         }
850*8975f5c5SAndroid Build Coastguard Worker 
851*8975f5c5SAndroid Build Coastguard Worker         // Verify we read the depth buffer.
852*8975f5c5SAndroid Build Coastguard Worker         const GLint minDimension = std::min(width, height);
853*8975f5c5SAndroid Build Coastguard Worker         for (GLint i = 1; i < minDimension; ++i)
854*8975f5c5SAndroid Build Coastguard Worker         {
855*8975f5c5SAndroid Build Coastguard Worker             const GLColor &c1 = expected[i - 1];
856*8975f5c5SAndroid Build Coastguard Worker             const GLColor &c2 = expected[i * width + i];
857*8975f5c5SAndroid Build Coastguard Worker             EXPECT_LT(c1.R, c2.R);
858*8975f5c5SAndroid Build Coastguard Worker         }
859*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
860*8975f5c5SAndroid Build Coastguard Worker     }
861*8975f5c5SAndroid Build Coastguard Worker };
862*8975f5c5SAndroid Build Coastguard Worker 
863*8975f5c5SAndroid Build Coastguard Worker // Test the multisampled optimized resolve subpass
TEST_P(MultisampleResolveTest,DISABLED_ResolveSubpassMSImage)864*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleResolveTest, DISABLED_ResolveSubpassMSImage)
865*8975f5c5SAndroid Build Coastguard Worker {
866*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
867*8975f5c5SAndroid Build Coastguard Worker 
868*8975f5c5SAndroid Build Coastguard Worker     // Draw green.
869*8975f5c5SAndroid Build Coastguard Worker     drawQuad(greenProgram, essl1_shaders::PositionAttrib(), 0.5f);
870*8975f5c5SAndroid Build Coastguard Worker     swapBuffers();
871*8975f5c5SAndroid Build Coastguard Worker 
872*8975f5c5SAndroid Build Coastguard Worker     // Wait for visual verification.
873*8975f5c5SAndroid Build Coastguard Worker     angle::Sleep(2000);
874*8975f5c5SAndroid Build Coastguard Worker }
875*8975f5c5SAndroid Build Coastguard Worker 
876*8975f5c5SAndroid Build Coastguard Worker // This is a test that must be verified visually.
877*8975f5c5SAndroid Build Coastguard Worker //
878*8975f5c5SAndroid Build Coastguard Worker // Tests that clear of the default framebuffer with multisample applies to the window.
TEST_P(MultisampleTestES3,DISABLED_ClearMSAAReachesWindow)879*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleTestES3, DISABLED_ClearMSAAReachesWindow)
880*8975f5c5SAndroid Build Coastguard Worker {
881*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
882*8975f5c5SAndroid Build Coastguard Worker 
883*8975f5c5SAndroid Build Coastguard Worker     // Draw blue.
884*8975f5c5SAndroid Build Coastguard Worker     drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);
885*8975f5c5SAndroid Build Coastguard Worker     swapBuffers();
886*8975f5c5SAndroid Build Coastguard Worker 
887*8975f5c5SAndroid Build Coastguard Worker     // Use glClear to clear to red.  Regression test for the Vulkan backend where this clear
888*8975f5c5SAndroid Build Coastguard Worker     // remained "deferred" and didn't make it to the window on swap.
889*8975f5c5SAndroid Build Coastguard Worker     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
890*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
891*8975f5c5SAndroid Build Coastguard Worker     swapBuffers();
892*8975f5c5SAndroid Build Coastguard Worker 
893*8975f5c5SAndroid Build Coastguard Worker     // Wait for visual verification.
894*8975f5c5SAndroid Build Coastguard Worker     angle::Sleep(2000);
895*8975f5c5SAndroid Build Coastguard Worker }
896*8975f5c5SAndroid Build Coastguard Worker 
897*8975f5c5SAndroid Build Coastguard Worker // According to the spec, the minimum value for the multisample line width range limits is one.
TEST_P(MultisampleTestES32,MultisampleLineWidthRangeCheck)898*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleTestES32, MultisampleLineWidthRangeCheck)
899*8975f5c5SAndroid Build Coastguard Worker {
900*8975f5c5SAndroid Build Coastguard Worker     GLfloat range[2] = {0, 0};
901*8975f5c5SAndroid Build Coastguard Worker     glGetFloatv(GL_MULTISAMPLE_LINE_WIDTH_RANGE, range);
902*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
903*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GE(range[0], 1.0f);
904*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GE(range[1], 1.0f);
905*8975f5c5SAndroid Build Coastguard Worker }
906*8975f5c5SAndroid Build Coastguard Worker 
907*8975f5c5SAndroid Build Coastguard Worker // The multisample line width granularity should not be negative.
TEST_P(MultisampleTestES32,MultisampleLineWidthGranularityCheck)908*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleTestES32, MultisampleLineWidthGranularityCheck)
909*8975f5c5SAndroid Build Coastguard Worker {
910*8975f5c5SAndroid Build Coastguard Worker     GLfloat granularity = -1.0f;
911*8975f5c5SAndroid Build Coastguard Worker     glGetFloatv(GL_MULTISAMPLE_LINE_WIDTH_GRANULARITY, &granularity);
912*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
913*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GE(granularity, 0.0f);
914*8975f5c5SAndroid Build Coastguard Worker }
915*8975f5c5SAndroid Build Coastguard Worker 
916*8975f5c5SAndroid Build Coastguard Worker // These colors match the shader in resolveToFBO which returns (0.5, 0.6, 0.7, 0.8).
917*8975f5c5SAndroid Build Coastguard Worker const GLColor MultisampleResolveTest::kEXPECTED_R8(128, 0, 0, 255);
918*8975f5c5SAndroid Build Coastguard Worker const GLColor MultisampleResolveTest::kEXPECTED_RG8(128, 153, 0, 255);
919*8975f5c5SAndroid Build Coastguard Worker const GLColor MultisampleResolveTest::kEXPECTED_RGB8(128, 153, 178, 255);
920*8975f5c5SAndroid Build Coastguard Worker const GLColor MultisampleResolveTest::kEXPECTED_RGBA8(128, 153, 178, 204);
921*8975f5c5SAndroid Build Coastguard Worker const GLColor32F MultisampleResolveTest::kEXPECTED_RF(0.5f, 0.0f, 0.0f, 1.0f);
922*8975f5c5SAndroid Build Coastguard Worker const GLColor32F MultisampleResolveTest::kEXPECTED_RGF(0.5f, 0.6f, 0.0f, 1.0f);
923*8975f5c5SAndroid Build Coastguard Worker const GLColor32F MultisampleResolveTest::kEXPECTED_RGBF(0.5f, 0.6f, 0.7f, 1.0f);
924*8975f5c5SAndroid Build Coastguard Worker const GLColor32F MultisampleResolveTest::kEXPECTED_RGBAF(0.5f, 0.6f, 0.7f, 0.8f);
925*8975f5c5SAndroid Build Coastguard Worker 
926*8975f5c5SAndroid Build Coastguard Worker // Test we can render to and resolve an RGBA8 renderbuffer
TEST_P(MultisampleResolveTest,ResolveRGBA8ToFBO4Samples)927*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleResolveTest, ResolveRGBA8ToFBO4Samples)
928*8975f5c5SAndroid Build Coastguard Worker {
929*8975f5c5SAndroid Build Coastguard Worker     testResolveToUNormFBO(GL_RGBA8, kEXPECTED_RGBA8, 4, kWidth, kHeight);
930*8975f5c5SAndroid Build Coastguard Worker }
931*8975f5c5SAndroid Build Coastguard Worker 
932*8975f5c5SAndroid Build Coastguard Worker // Test we can render to and resolve an RGB8 renderbuffer
TEST_P(MultisampleResolveTest,ResolveRGB8ToFBO4Samples)933*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleResolveTest, ResolveRGB8ToFBO4Samples)
934*8975f5c5SAndroid Build Coastguard Worker {
935*8975f5c5SAndroid Build Coastguard Worker     testResolveToUNormFBO(GL_RGB8, kEXPECTED_RGB8, 4, kWidth, kHeight);
936*8975f5c5SAndroid Build Coastguard Worker }
937*8975f5c5SAndroid Build Coastguard Worker 
938*8975f5c5SAndroid Build Coastguard Worker // Test we can render to and resolve an RG8 renderbuffer
TEST_P(MultisampleResolveTest,ResolveRG8ToFBO4Samples)939*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleResolveTest, ResolveRG8ToFBO4Samples)
940*8975f5c5SAndroid Build Coastguard Worker {
941*8975f5c5SAndroid Build Coastguard Worker     testResolveToUNormFBO(GL_RG8, kEXPECTED_RG8, 4, kWidth, kHeight);
942*8975f5c5SAndroid Build Coastguard Worker }
943*8975f5c5SAndroid Build Coastguard Worker 
944*8975f5c5SAndroid Build Coastguard Worker // Test we can render to and resolve an R8 renderbuffer
TEST_P(MultisampleResolveTest,ResolveR8ToFBO4Samples)945*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleResolveTest, ResolveR8ToFBO4Samples)
946*8975f5c5SAndroid Build Coastguard Worker {
947*8975f5c5SAndroid Build Coastguard Worker     testResolveToUNormFBO(GL_R8, kEXPECTED_R8, 4, kWidth, kHeight);
948*8975f5c5SAndroid Build Coastguard Worker }
949*8975f5c5SAndroid Build Coastguard Worker 
950*8975f5c5SAndroid Build Coastguard Worker // Test we can render to and resolve an R16F renderbuffer
TEST_P(MultisampleResolveTest,ResolveR16FToFBO4Samples)951*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleResolveTest, ResolveR16FToFBO4Samples)
952*8975f5c5SAndroid Build Coastguard Worker {
953*8975f5c5SAndroid Build Coastguard Worker     testResolveToHalfFBO(GL_R16F, kEXPECTED_RF, 4, kWidth, kHeight);
954*8975f5c5SAndroid Build Coastguard Worker }
955*8975f5c5SAndroid Build Coastguard Worker 
956*8975f5c5SAndroid Build Coastguard Worker // Test we can render to and resolve an RG16F renderbuffer
TEST_P(MultisampleResolveTest,ResolveRG16FToFBO4Samples)957*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleResolveTest, ResolveRG16FToFBO4Samples)
958*8975f5c5SAndroid Build Coastguard Worker {
959*8975f5c5SAndroid Build Coastguard Worker     testResolveToHalfFBO(GL_RG16F, kEXPECTED_RGF, 4, kWidth, kHeight);
960*8975f5c5SAndroid Build Coastguard Worker }
961*8975f5c5SAndroid Build Coastguard Worker 
962*8975f5c5SAndroid Build Coastguard Worker // Test we can render to and resolve an RGB16F renderbuffer
TEST_P(MultisampleResolveTest,ResolveRGB16FToFBO4Samples)963*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleResolveTest, ResolveRGB16FToFBO4Samples)
964*8975f5c5SAndroid Build Coastguard Worker {
965*8975f5c5SAndroid Build Coastguard Worker     testResolveToHalfFBO(GL_RGB16F, kEXPECTED_RGBF, 4, kWidth, kHeight);
966*8975f5c5SAndroid Build Coastguard Worker }
967*8975f5c5SAndroid Build Coastguard Worker 
968*8975f5c5SAndroid Build Coastguard Worker // Test we can render to and resolve an RGBA16F renderbuffer
TEST_P(MultisampleResolveTest,ResolveRGBA16FToFBO4Samples)969*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleResolveTest, ResolveRGBA16FToFBO4Samples)
970*8975f5c5SAndroid Build Coastguard Worker {
971*8975f5c5SAndroid Build Coastguard Worker     testResolveToHalfFBO(GL_RGBA16F, kEXPECTED_RGBAF, 4, kWidth, kHeight);
972*8975f5c5SAndroid Build Coastguard Worker }
973*8975f5c5SAndroid Build Coastguard Worker 
974*8975f5c5SAndroid Build Coastguard Worker // Test we can render to and resolve an R32F renderbuffer
TEST_P(MultisampleResolveTest,ResolveR32FToFBO4Samples)975*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleResolveTest, ResolveR32FToFBO4Samples)
976*8975f5c5SAndroid Build Coastguard Worker {
977*8975f5c5SAndroid Build Coastguard Worker     testResolveToFloatFBO(GL_R32F, kEXPECTED_RF, 4, kWidth, kHeight);
978*8975f5c5SAndroid Build Coastguard Worker }
979*8975f5c5SAndroid Build Coastguard Worker 
980*8975f5c5SAndroid Build Coastguard Worker // Test we can render to and resolve an RG32F renderbuffer
TEST_P(MultisampleResolveTest,ResolveRG32FToFBO4Samples)981*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleResolveTest, ResolveRG32FToFBO4Samples)
982*8975f5c5SAndroid Build Coastguard Worker {
983*8975f5c5SAndroid Build Coastguard Worker     testResolveToFloatFBO(GL_RG32F, kEXPECTED_RGF, 4, kWidth, kHeight);
984*8975f5c5SAndroid Build Coastguard Worker }
985*8975f5c5SAndroid Build Coastguard Worker 
986*8975f5c5SAndroid Build Coastguard Worker // Test we can render to and resolve an RGB32F renderbuffer
TEST_P(MultisampleResolveTest,ResolveRGB32FToFBO4Samples)987*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleResolveTest, ResolveRGB32FToFBO4Samples)
988*8975f5c5SAndroid Build Coastguard Worker {
989*8975f5c5SAndroid Build Coastguard Worker     testResolveToRGBFloatFBO(GL_RGB32F, kEXPECTED_RGBF, 4, kWidth, kHeight);
990*8975f5c5SAndroid Build Coastguard Worker }
991*8975f5c5SAndroid Build Coastguard Worker 
992*8975f5c5SAndroid Build Coastguard Worker // Test we can render to and resolve an RGBA32F renderbuffer
TEST_P(MultisampleResolveTest,ResolveRGBA32FToFBO4Samples)993*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleResolveTest, ResolveRGBA32FToFBO4Samples)
994*8975f5c5SAndroid Build Coastguard Worker {
995*8975f5c5SAndroid Build Coastguard Worker     testResolveToFloatFBO(GL_RGBA32F, kEXPECTED_RGBAF, 4, kWidth, kHeight);
996*8975f5c5SAndroid Build Coastguard Worker }
997*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(MultisampleResolveTest,ResolveD32FS8F4Samples)998*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleResolveTest, ResolveD32FS8F4Samples)
999*8975f5c5SAndroid Build Coastguard Worker {
1000*8975f5c5SAndroid Build Coastguard Worker     testResolveDepthToFBO(GL_DEPTH32F_STENCIL8, GL_DEPTH_STENCIL_ATTACHMENT, 4, kWidth, kHeight);
1001*8975f5c5SAndroid Build Coastguard Worker }
1002*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(MultisampleResolveTest,ResolveD24S8Samples)1003*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleResolveTest, ResolveD24S8Samples)
1004*8975f5c5SAndroid Build Coastguard Worker {
1005*8975f5c5SAndroid Build Coastguard Worker     testResolveDepthToFBO(GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL_ATTACHMENT, 4, kWidth, kHeight);
1006*8975f5c5SAndroid Build Coastguard Worker }
1007*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(MultisampleResolveTest,ResolveD32FSamples)1008*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleResolveTest, ResolveD32FSamples)
1009*8975f5c5SAndroid Build Coastguard Worker {
1010*8975f5c5SAndroid Build Coastguard Worker     testResolveDepthToFBO(GL_DEPTH_COMPONENT32F, GL_DEPTH_ATTACHMENT, 4, kWidth, kHeight);
1011*8975f5c5SAndroid Build Coastguard Worker }
1012*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(MultisampleResolveTest,ResolveD24Samples)1013*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleResolveTest, ResolveD24Samples)
1014*8975f5c5SAndroid Build Coastguard Worker {
1015*8975f5c5SAndroid Build Coastguard Worker     testResolveDepthToFBO(GL_DEPTH_COMPONENT24, GL_DEPTH_ATTACHMENT, 4, kWidth, kHeight);
1016*8975f5c5SAndroid Build Coastguard Worker }
1017*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(MultisampleResolveTest,ResolveD16Samples)1018*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleResolveTest, ResolveD16Samples)
1019*8975f5c5SAndroid Build Coastguard Worker {
1020*8975f5c5SAndroid Build Coastguard Worker     testResolveDepthToFBO(GL_DEPTH_COMPONENT16, GL_DEPTH_ATTACHMENT, 4, kWidth, kHeight);
1021*8975f5c5SAndroid Build Coastguard Worker }
1022*8975f5c5SAndroid Build Coastguard Worker 
drawRectAndBlit(GLuint msFramebuffer,GLuint resolveFramebuffer,GLint width,GLint height,GLint matLoc,GLint colorLoc,float x,float y,float w,float h,const GLColor & color)1023*8975f5c5SAndroid Build Coastguard Worker void drawRectAndBlit(GLuint msFramebuffer,
1024*8975f5c5SAndroid Build Coastguard Worker                      GLuint resolveFramebuffer,
1025*8975f5c5SAndroid Build Coastguard Worker                      GLint width,
1026*8975f5c5SAndroid Build Coastguard Worker                      GLint height,
1027*8975f5c5SAndroid Build Coastguard Worker                      GLint matLoc,
1028*8975f5c5SAndroid Build Coastguard Worker                      GLint colorLoc,
1029*8975f5c5SAndroid Build Coastguard Worker                      float x,
1030*8975f5c5SAndroid Build Coastguard Worker                      float y,
1031*8975f5c5SAndroid Build Coastguard Worker                      float w,
1032*8975f5c5SAndroid Build Coastguard Worker                      float h,
1033*8975f5c5SAndroid Build Coastguard Worker                      const GLColor &color)
1034*8975f5c5SAndroid Build Coastguard Worker {
1035*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, msFramebuffer);
1036*8975f5c5SAndroid Build Coastguard Worker     float matrix[16] = {
1037*8975f5c5SAndroid Build Coastguard Worker         w, 0, 0, 0, 0, h, 0, 0, 0, 0, 1, 0, x, y, 0, 1,
1038*8975f5c5SAndroid Build Coastguard Worker     };
1039*8975f5c5SAndroid Build Coastguard Worker     glUniformMatrix4fv(matLoc, 1, false, matrix);
1040*8975f5c5SAndroid Build Coastguard Worker     angle::Vector4 c(color.toNormalizedVector());
1041*8975f5c5SAndroid Build Coastguard Worker     glUniform4f(colorLoc, c[0], c[1], c[2], c[3]);
1042*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_TRIANGLES, 0, 6);
1043*8975f5c5SAndroid Build Coastguard Worker 
1044*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFramebuffer);
1045*8975f5c5SAndroid Build Coastguard Worker     glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
1046*8975f5c5SAndroid Build Coastguard Worker }
1047*8975f5c5SAndroid Build Coastguard Worker 
1048*8975f5c5SAndroid Build Coastguard Worker // Tests if we resolve(blit) a multisample renderbuffer that it
1049*8975f5c5SAndroid Build Coastguard Worker // does not lose its contents.
TEST_P(MultisampleResolveTest,DrawAndResolveMultipleTimes)1050*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleResolveTest, DrawAndResolveMultipleTimes)
1051*8975f5c5SAndroid Build Coastguard Worker {
1052*8975f5c5SAndroid Build Coastguard Worker     constexpr GLint samples = 4;
1053*8975f5c5SAndroid Build Coastguard Worker     constexpr GLenum format = GL_RGBA8;
1054*8975f5c5SAndroid Build Coastguard Worker     constexpr GLint width   = 16;
1055*8975f5c5SAndroid Build Coastguard Worker     constexpr GLint height  = 16;
1056*8975f5c5SAndroid Build Coastguard Worker 
1057*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVS[] = R"(#version 300 es
1058*8975f5c5SAndroid Build Coastguard Worker     layout(location = 0) in vec4 position;
1059*8975f5c5SAndroid Build Coastguard Worker     uniform mat4 mat;
1060*8975f5c5SAndroid Build Coastguard Worker     void main() {
1061*8975f5c5SAndroid Build Coastguard Worker        gl_Position = mat * position;
1062*8975f5c5SAndroid Build Coastguard Worker     }
1063*8975f5c5SAndroid Build Coastguard Worker     )";
1064*8975f5c5SAndroid Build Coastguard Worker 
1065*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] = R"(#version 300 es
1066*8975f5c5SAndroid Build Coastguard Worker     precision highp float;
1067*8975f5c5SAndroid Build Coastguard Worker     uniform vec4 color;
1068*8975f5c5SAndroid Build Coastguard Worker     out vec4 outColor;
1069*8975f5c5SAndroid Build Coastguard Worker     void main() {
1070*8975f5c5SAndroid Build Coastguard Worker        outColor = color;
1071*8975f5c5SAndroid Build Coastguard Worker     }
1072*8975f5c5SAndroid Build Coastguard Worker     )";
1073*8975f5c5SAndroid Build Coastguard Worker 
1074*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, width, height);
1075*8975f5c5SAndroid Build Coastguard Worker 
1076*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, kVS, kFS);
1077*8975f5c5SAndroid Build Coastguard Worker     GLint matLoc   = glGetUniformLocation(program, "mat");
1078*8975f5c5SAndroid Build Coastguard Worker     GLint colorLoc = glGetUniformLocation(program, "color");
1079*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
1080*8975f5c5SAndroid Build Coastguard Worker 
1081*8975f5c5SAndroid Build Coastguard Worker     GLBuffer buf;
1082*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, buf);
1083*8975f5c5SAndroid Build Coastguard Worker 
1084*8975f5c5SAndroid Build Coastguard Worker     constexpr float vertices[] = {
1085*8975f5c5SAndroid Build Coastguard Worker         0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
1086*8975f5c5SAndroid Build Coastguard Worker     };
1087*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
1088*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(0);
1089*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
1090*8975f5c5SAndroid Build Coastguard Worker 
1091*8975f5c5SAndroid Build Coastguard Worker     // Make samples = 4 multi-sample framebuffer.
1092*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer msFB;
1093*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, msFB);
1094*8975f5c5SAndroid Build Coastguard Worker 
1095*8975f5c5SAndroid Build Coastguard Worker     GLRenderbuffer msRB;
1096*8975f5c5SAndroid Build Coastguard Worker     glBindRenderbuffer(GL_RENDERBUFFER, msRB);
1097*8975f5c5SAndroid Build Coastguard Worker     glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, format, width, height);
1098*8975f5c5SAndroid Build Coastguard Worker     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, msRB);
1099*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1100*8975f5c5SAndroid Build Coastguard Worker 
1101*8975f5c5SAndroid Build Coastguard Worker     // Make non-multi-sample framebuffer.
1102*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer drawFB;
1103*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, drawFB);
1104*8975f5c5SAndroid Build Coastguard Worker 
1105*8975f5c5SAndroid Build Coastguard Worker     GLRenderbuffer drawRB;
1106*8975f5c5SAndroid Build Coastguard Worker     glBindRenderbuffer(GL_RENDERBUFFER, drawRB);
1107*8975f5c5SAndroid Build Coastguard Worker     glRenderbufferStorage(GL_RENDERBUFFER, format, width, height);
1108*8975f5c5SAndroid Build Coastguard Worker     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, drawRB);
1109*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1110*8975f5c5SAndroid Build Coastguard Worker 
1111*8975f5c5SAndroid Build Coastguard Worker     drawRectAndBlit(msFB, drawFB, width, height, matLoc, colorLoc, -1, -1, 2, 2, GLColor::red);
1112*8975f5c5SAndroid Build Coastguard Worker     drawRectAndBlit(msFB, drawFB, width, height, matLoc, colorLoc, 0, -1, 1, 1, GLColor::green);
1113*8975f5c5SAndroid Build Coastguard Worker     drawRectAndBlit(msFB, drawFB, width, height, matLoc, colorLoc, -1, 0, 1, 1, GLColor::blue);
1114*8975f5c5SAndroid Build Coastguard Worker     drawRectAndBlit(msFB, drawFB, width, height, matLoc, colorLoc, 0, 0, 1, 1, GLColor::yellow);
1115*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_BLEND);
1116*8975f5c5SAndroid Build Coastguard Worker     glBlendFunc(GL_ONE, GL_ONE);
1117*8975f5c5SAndroid Build Coastguard Worker     drawRectAndBlit(msFB, drawFB, width, height, matLoc, colorLoc, -0.5, -0.5, 1, 1,
1118*8975f5c5SAndroid Build Coastguard Worker                     GLColor(0x80, 0x80, 0x80, 0x80));
1119*8975f5c5SAndroid Build Coastguard Worker     glDisable(GL_BLEND);
1120*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
1121*8975f5c5SAndroid Build Coastguard Worker 
1122*8975f5c5SAndroid Build Coastguard Worker     /*
1123*8975f5c5SAndroid Build Coastguard Worker        expected
1124*8975f5c5SAndroid Build Coastguard Worker        +-------------+--------------+
1125*8975f5c5SAndroid Build Coastguard Worker        | blue        |       yellow |
1126*8975f5c5SAndroid Build Coastguard Worker        |   +---------+----------+   |
1127*8975f5c5SAndroid Build Coastguard Worker        |   |.5,.5,1,1| 1,1,.5,1 |   |
1128*8975f5c5SAndroid Build Coastguard Worker        +---+---------+----------+---+
1129*8975f5c5SAndroid Build Coastguard Worker        |   |1,.5,.5,1| .5,1,.5,1|   |
1130*8975f5c5SAndroid Build Coastguard Worker        |   +---------+----------+   |
1131*8975f5c5SAndroid Build Coastguard Worker        | red         |        green |
1132*8975f5c5SAndroid Build Coastguard Worker        +-------------+--------------+
1133*8975f5c5SAndroid Build Coastguard Worker       0,0
1134*8975f5c5SAndroid Build Coastguard Worker     */
1135*8975f5c5SAndroid Build Coastguard Worker 
1136*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, drawFB);
1137*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_RECT_EQ(0, 0, width / 2, height / 4, GLColor::red);
1138*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_RECT_EQ(width / 2, 0, width / 2, height / 4, GLColor::green);
1139*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_RECT_EQ(0, height * 3 / 4, width / 2, height / 4, GLColor::blue);
1140*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_RECT_EQ(width / 2, height * 3 / 4, width / 2, height / 4, GLColor::yellow);
1141*8975f5c5SAndroid Build Coastguard Worker 
1142*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_RECT_EQ(width / 4, height / 4, width / 4, height / 4, GLColor(255, 128, 128, 255));
1143*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_RECT_EQ(width / 2, height / 4, width / 4, height / 4, GLColor(128, 255, 128, 255));
1144*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_RECT_EQ(width / 4, height / 2, width / 4, height / 4, GLColor(128, 128, 255, 255));
1145*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_RECT_EQ(width / 2, height / 2, width / 4, height / 4, GLColor(255, 255, 128, 255));
1146*8975f5c5SAndroid Build Coastguard Worker }
1147*8975f5c5SAndroid Build Coastguard Worker 
1148*8975f5c5SAndroid Build Coastguard Worker // Tests resolve after the read framebuffer's attachment has been swapped out.
TEST_P(MultisampleResolveTest,SwitchAttachmentsBeforeResolve)1149*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleResolveTest, SwitchAttachmentsBeforeResolve)
1150*8975f5c5SAndroid Build Coastguard Worker {
1151*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kWidth  = 16;
1152*8975f5c5SAndroid Build Coastguard Worker     constexpr GLuint kHeight = 24;
1153*8975f5c5SAndroid Build Coastguard Worker 
1154*8975f5c5SAndroid Build Coastguard Worker     GLRenderbuffer msaaColor0, msaaColor1;
1155*8975f5c5SAndroid Build Coastguard Worker     glBindRenderbuffer(GL_RENDERBUFFER, msaaColor0);
1156*8975f5c5SAndroid Build Coastguard Worker     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, kWidth, kHeight);
1157*8975f5c5SAndroid Build Coastguard Worker     glBindRenderbuffer(GL_RENDERBUFFER, msaaColor1);
1158*8975f5c5SAndroid Build Coastguard Worker     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, kWidth, kHeight);
1159*8975f5c5SAndroid Build Coastguard Worker 
1160*8975f5c5SAndroid Build Coastguard Worker     {
1161*8975f5c5SAndroid Build Coastguard Worker         // First, make one of the MSAA color buffers green.
1162*8975f5c5SAndroid Build Coastguard Worker         GLFramebuffer clearFbo;
1163*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, clearFbo);
1164*8975f5c5SAndroid Build Coastguard Worker         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
1165*8975f5c5SAndroid Build Coastguard Worker                                   msaaColor1);
1166*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1167*8975f5c5SAndroid Build Coastguard Worker 
1168*8975f5c5SAndroid Build Coastguard Worker         glClearColor(0, 1, 0, 1);
1169*8975f5c5SAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
1170*8975f5c5SAndroid Build Coastguard Worker 
1171*8975f5c5SAndroid Build Coastguard Worker         // Make sure clear is performed.
1172*8975f5c5SAndroid Build Coastguard Worker         GLTexture resolveTexture;
1173*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, resolveTexture);
1174*8975f5c5SAndroid Build Coastguard Worker         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
1175*8975f5c5SAndroid Build Coastguard Worker                      nullptr);
1176*8975f5c5SAndroid Build Coastguard Worker 
1177*8975f5c5SAndroid Build Coastguard Worker         GLFramebuffer verifyFBO;
1178*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, verifyFBO);
1179*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
1180*8975f5c5SAndroid Build Coastguard Worker                                resolveTexture, 0);
1181*8975f5c5SAndroid Build Coastguard Worker 
1182*8975f5c5SAndroid Build Coastguard Worker         glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_COLOR_BUFFER_BIT,
1183*8975f5c5SAndroid Build Coastguard Worker                           GL_NEAREST);
1184*8975f5c5SAndroid Build Coastguard Worker 
1185*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_READ_FRAMEBUFFER, verifyFBO);
1186*8975f5c5SAndroid Build Coastguard Worker         EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
1187*8975f5c5SAndroid Build Coastguard Worker     }
1188*8975f5c5SAndroid Build Coastguard Worker 
1189*8975f5c5SAndroid Build Coastguard Worker     // Set up the msaa framebuffer with the other MSAA color buffer.
1190*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer msaaFBO;
1191*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO);
1192*8975f5c5SAndroid Build Coastguard Worker     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, msaaColor0);
1193*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1194*8975f5c5SAndroid Build Coastguard Worker 
1195*8975f5c5SAndroid Build Coastguard Worker     // Draw into it to start a render pass
1196*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(red, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
1197*8975f5c5SAndroid Build Coastguard Worker     drawQuad(red, essl1_shaders::PositionAttrib(), 0.5f);
1198*8975f5c5SAndroid Build Coastguard Worker 
1199*8975f5c5SAndroid Build Coastguard Worker     // Set up the resolve framebuffer
1200*8975f5c5SAndroid Build Coastguard Worker     GLRenderbuffer resolveColor;
1201*8975f5c5SAndroid Build Coastguard Worker     glBindRenderbuffer(GL_RENDERBUFFER, resolveColor);
1202*8975f5c5SAndroid Build Coastguard Worker     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kWidth, kHeight);
1203*8975f5c5SAndroid Build Coastguard Worker 
1204*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer resolveFBO;
1205*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolveFBO);
1206*8975f5c5SAndroid Build Coastguard Worker     glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
1207*8975f5c5SAndroid Build Coastguard Worker                               resolveColor);
1208*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
1209*8975f5c5SAndroid Build Coastguard Worker 
1210*8975f5c5SAndroid Build Coastguard Worker     // Before resolve the MSAA framebuffer, switch its attachment.  Regression test for a bug where
1211*8975f5c5SAndroid Build Coastguard Worker     // the resolve used the previous attachment.
1212*8975f5c5SAndroid Build Coastguard Worker     glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
1213*8975f5c5SAndroid Build Coastguard Worker                               msaaColor1);
1214*8975f5c5SAndroid Build Coastguard Worker 
1215*8975f5c5SAndroid Build Coastguard Worker     glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_COLOR_BUFFER_BIT,
1216*8975f5c5SAndroid Build Coastguard Worker                       GL_NEAREST);
1217*8975f5c5SAndroid Build Coastguard Worker 
1218*8975f5c5SAndroid Build Coastguard Worker     // Verify that the resolve happened on the pre-cleared attachment, not the rendered one.
1219*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_READ_FRAMEBUFFER, resolveFBO);
1220*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
1221*8975f5c5SAndroid Build Coastguard Worker }
1222*8975f5c5SAndroid Build Coastguard Worker 
1223*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND_ES31_AND(
1224*8975f5c5SAndroid Build Coastguard Worker     MultisampleTest,
1225*8975f5c5SAndroid Build Coastguard Worker     ES3_VULKAN().enable(Feature::EmulatedPrerotation90),
1226*8975f5c5SAndroid Build Coastguard Worker     ES3_VULKAN().enable(Feature::EmulatedPrerotation180),
1227*8975f5c5SAndroid Build Coastguard Worker     ES3_VULKAN().enable(Feature::EmulatedPrerotation270),
1228*8975f5c5SAndroid Build Coastguard Worker     // Simulate missing msaa auto resolve feature in Metal.
1229*8975f5c5SAndroid Build Coastguard Worker     ES2_METAL().disable(Feature::AllowMultisampleStoreAndResolve));
1230*8975f5c5SAndroid Build Coastguard Worker 
1231*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MultisampleTestES3);
1232*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES3_AND_ES31_AND(MultisampleTestES3,
1233*8975f5c5SAndroid Build Coastguard Worker                                         ES3_VULKAN().enable(Feature::EmulatedPrerotation90),
1234*8975f5c5SAndroid Build Coastguard Worker                                         ES3_VULKAN().enable(Feature::EmulatedPrerotation180),
1235*8975f5c5SAndroid Build Coastguard Worker                                         ES3_VULKAN().enable(Feature::EmulatedPrerotation270));
1236*8975f5c5SAndroid Build Coastguard Worker 
1237*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MultisampleTestES32);
1238*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES32_AND(MultisampleTestES32,
1239*8975f5c5SAndroid Build Coastguard Worker                                 ES32_VULKAN().enable(Feature::EmulatedPrerotation90),
1240*8975f5c5SAndroid Build Coastguard Worker                                 ES32_VULKAN().enable(Feature::EmulatedPrerotation180),
1241*8975f5c5SAndroid Build Coastguard Worker                                 ES32_VULKAN().enable(Feature::EmulatedPrerotation270));
1242*8975f5c5SAndroid Build Coastguard Worker 
1243*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES3_AND(
1244*8975f5c5SAndroid Build Coastguard Worker     MultisampleResolveTest,
1245*8975f5c5SAndroid Build Coastguard Worker     ES3_VULKAN().enable(Feature::EmulatedPrerotation90),
1246*8975f5c5SAndroid Build Coastguard Worker     ES3_VULKAN().enable(Feature::EmulatedPrerotation180),
1247*8975f5c5SAndroid Build Coastguard Worker     ES3_VULKAN().enable(Feature::EmulatedPrerotation270),
1248*8975f5c5SAndroid Build Coastguard Worker     ES3_VULKAN().enable(Feature::PreferDrawClearOverVkCmdClearAttachments));
1249*8975f5c5SAndroid Build Coastguard Worker 
1250*8975f5c5SAndroid Build Coastguard Worker }  // anonymous namespace
1251