xref: /aosp_15_r20/external/angle/src/tests/gl_tests/MultisampleCompatibilityTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2015 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 // MultisampleCompatibilityTest.cpp:
7*8975f5c5SAndroid Build Coastguard Worker //   Tests for the EXT_multisample_compatibility extension.
8*8975f5c5SAndroid Build Coastguard Worker //
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.h"
11*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/gl_raii.h"
12*8975f5c5SAndroid Build Coastguard Worker 
13*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
14*8975f5c5SAndroid Build Coastguard Worker 
15*8975f5c5SAndroid Build Coastguard Worker namespace
16*8975f5c5SAndroid Build Coastguard Worker {
17*8975f5c5SAndroid Build Coastguard Worker 
18*8975f5c5SAndroid Build Coastguard Worker const GLint kWidth  = 64;
19*8975f5c5SAndroid Build Coastguard Worker const GLint kHeight = 64;
20*8975f5c5SAndroid Build Coastguard Worker 
21*8975f5c5SAndroid Build Coastguard Worker // test drawing with GL_MULTISAMPLE_EXT enabled/disabled.
22*8975f5c5SAndroid Build Coastguard Worker class EXTMultisampleCompatibilityTest : public ANGLETest<>
23*8975f5c5SAndroid Build Coastguard Worker {
24*8975f5c5SAndroid Build Coastguard Worker 
25*8975f5c5SAndroid Build Coastguard Worker   protected:
EXTMultisampleCompatibilityTest()26*8975f5c5SAndroid Build Coastguard Worker     EXTMultisampleCompatibilityTest()
27*8975f5c5SAndroid Build Coastguard Worker     {
28*8975f5c5SAndroid Build Coastguard Worker         setWindowWidth(64);
29*8975f5c5SAndroid Build Coastguard Worker         setWindowHeight(64);
30*8975f5c5SAndroid Build Coastguard Worker         setConfigRedBits(8);
31*8975f5c5SAndroid Build Coastguard Worker         setConfigBlueBits(8);
32*8975f5c5SAndroid Build Coastguard Worker         setConfigAlphaBits(8);
33*8975f5c5SAndroid Build Coastguard Worker     }
34*8975f5c5SAndroid Build Coastguard Worker 
testSetUp()35*8975f5c5SAndroid Build Coastguard Worker     void testSetUp() override
36*8975f5c5SAndroid Build Coastguard Worker     {
37*8975f5c5SAndroid Build Coastguard Worker         mProgram = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
38*8975f5c5SAndroid Build Coastguard Worker 
39*8975f5c5SAndroid Build Coastguard Worker         GLuint position_loc = glGetAttribLocation(mProgram, essl1_shaders::PositionAttrib());
40*8975f5c5SAndroid Build Coastguard Worker         mColorLoc           = glGetUniformLocation(mProgram, essl1_shaders::ColorUniform());
41*8975f5c5SAndroid Build Coastguard Worker 
42*8975f5c5SAndroid Build Coastguard Worker         glGenBuffers(1, &mVBO);
43*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_ARRAY_BUFFER, mVBO);
44*8975f5c5SAndroid Build Coastguard Worker         static float vertices[] = {
45*8975f5c5SAndroid Build Coastguard Worker             1.0f,  1.0f, -1.0f, 1.0f,  -1.0f, -1.0f, -1.0f, 1.0f, -1.0f,
46*8975f5c5SAndroid Build Coastguard Worker             -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f,  -1.0f, 1.0f, 1.0f,
47*8975f5c5SAndroid Build Coastguard Worker         };
48*8975f5c5SAndroid Build Coastguard Worker         glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
49*8975f5c5SAndroid Build Coastguard Worker         glEnableVertexAttribArray(position_loc);
50*8975f5c5SAndroid Build Coastguard Worker         glVertexAttribPointer(position_loc, 2, GL_FLOAT, GL_FALSE, 0, 0);
51*8975f5c5SAndroid Build Coastguard Worker     }
52*8975f5c5SAndroid Build Coastguard Worker 
testTearDown()53*8975f5c5SAndroid Build Coastguard Worker     void testTearDown() override
54*8975f5c5SAndroid Build Coastguard Worker     {
55*8975f5c5SAndroid Build Coastguard Worker         glDeleteBuffers(1, &mVBO);
56*8975f5c5SAndroid Build Coastguard Worker         glDeleteProgram(mProgram);
57*8975f5c5SAndroid Build Coastguard Worker     }
58*8975f5c5SAndroid Build Coastguard Worker 
prepareForDraw()59*8975f5c5SAndroid Build Coastguard Worker     void prepareForDraw()
60*8975f5c5SAndroid Build Coastguard Worker     {
61*8975f5c5SAndroid Build Coastguard Worker         // Create a sample buffer.
62*8975f5c5SAndroid Build Coastguard Worker         GLsizei num_samples = 4, max_samples = 0;
63*8975f5c5SAndroid Build Coastguard Worker         glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
64*8975f5c5SAndroid Build Coastguard Worker         num_samples = std::min(num_samples, max_samples);
65*8975f5c5SAndroid Build Coastguard Worker 
66*8975f5c5SAndroid Build Coastguard Worker         glGenRenderbuffers(1, &mSampleRB);
67*8975f5c5SAndroid Build Coastguard Worker         glBindRenderbuffer(GL_RENDERBUFFER, mSampleRB);
68*8975f5c5SAndroid Build Coastguard Worker         glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, num_samples, GL_RGBA8_OES, kWidth,
69*8975f5c5SAndroid Build Coastguard Worker                                               kHeight);
70*8975f5c5SAndroid Build Coastguard Worker         GLint param = 0;
71*8975f5c5SAndroid Build Coastguard Worker         glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &param);
72*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GE(param, num_samples);
73*8975f5c5SAndroid Build Coastguard Worker 
74*8975f5c5SAndroid Build Coastguard Worker         glGenFramebuffers(1, &mSampleFBO);
75*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, mSampleFBO);
76*8975f5c5SAndroid Build Coastguard Worker         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mSampleRB);
77*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
78*8975f5c5SAndroid Build Coastguard Worker                   glCheckFramebufferStatus(GL_FRAMEBUFFER));
79*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, 0);
80*8975f5c5SAndroid Build Coastguard Worker 
81*8975f5c5SAndroid Build Coastguard Worker         // Create another FBO to resolve the multisample buffer into.
82*8975f5c5SAndroid Build Coastguard Worker         glGenTextures(1, &mResolveTex);
83*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, mResolveTex);
84*8975f5c5SAndroid Build Coastguard Worker         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
85*8975f5c5SAndroid Build Coastguard Worker                      nullptr);
86*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
87*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
88*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
89*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
90*8975f5c5SAndroid Build Coastguard Worker         glGenFramebuffers(1, &mResolveFBO);
91*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, mResolveFBO);
92*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mResolveTex, 0);
93*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
94*8975f5c5SAndroid Build Coastguard Worker                   glCheckFramebufferStatus(GL_FRAMEBUFFER));
95*8975f5c5SAndroid Build Coastguard Worker 
96*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(mProgram);
97*8975f5c5SAndroid Build Coastguard Worker         glViewport(0, 0, kWidth, kHeight);
98*8975f5c5SAndroid Build Coastguard Worker         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
99*8975f5c5SAndroid Build Coastguard Worker         glEnable(GL_BLEND);
100*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, mSampleFBO);
101*8975f5c5SAndroid Build Coastguard Worker         glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
102*8975f5c5SAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
103*8975f5c5SAndroid Build Coastguard Worker     }
104*8975f5c5SAndroid Build Coastguard Worker 
prepareForVerify()105*8975f5c5SAndroid Build Coastguard Worker     void prepareForVerify()
106*8975f5c5SAndroid Build Coastguard Worker     {
107*8975f5c5SAndroid Build Coastguard Worker         // Resolve.
108*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_READ_FRAMEBUFFER, mSampleFBO);
109*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mResolveFBO);
110*8975f5c5SAndroid Build Coastguard Worker         glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
111*8975f5c5SAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
112*8975f5c5SAndroid Build Coastguard Worker         glBlitFramebufferANGLE(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_COLOR_BUFFER_BIT,
113*8975f5c5SAndroid Build Coastguard Worker                                GL_NEAREST);
114*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_READ_FRAMEBUFFER, mResolveFBO);
115*8975f5c5SAndroid Build Coastguard Worker 
116*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
117*8975f5c5SAndroid Build Coastguard Worker     }
118*8975f5c5SAndroid Build Coastguard Worker 
cleanup()119*8975f5c5SAndroid Build Coastguard Worker     void cleanup()
120*8975f5c5SAndroid Build Coastguard Worker     {
121*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, 0);
122*8975f5c5SAndroid Build Coastguard Worker         glDeleteFramebuffers(1, &mResolveFBO);
123*8975f5c5SAndroid Build Coastguard Worker         glDeleteFramebuffers(1, &mSampleFBO);
124*8975f5c5SAndroid Build Coastguard Worker         glDeleteTextures(1, &mResolveTex);
125*8975f5c5SAndroid Build Coastguard Worker         glDeleteRenderbuffers(1, &mSampleRB);
126*8975f5c5SAndroid Build Coastguard Worker 
127*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
128*8975f5c5SAndroid Build Coastguard Worker     }
129*8975f5c5SAndroid Build Coastguard Worker 
isApplicable() const130*8975f5c5SAndroid Build Coastguard Worker     bool isApplicable() const
131*8975f5c5SAndroid Build Coastguard Worker     {
132*8975f5c5SAndroid Build Coastguard Worker         return IsGLExtensionEnabled("GL_EXT_multisample_compatibility") &&
133*8975f5c5SAndroid Build Coastguard Worker                IsGLExtensionEnabled("GL_ANGLE_framebuffer_multisample") &&
134*8975f5c5SAndroid Build Coastguard Worker                IsGLExtensionEnabled("GL_OES_rgb8_rgba8") && !IsAMD();
135*8975f5c5SAndroid Build Coastguard Worker     }
136*8975f5c5SAndroid Build Coastguard Worker     GLuint mSampleFBO;
137*8975f5c5SAndroid Build Coastguard Worker     GLuint mResolveFBO;
138*8975f5c5SAndroid Build Coastguard Worker     GLuint mSampleRB;
139*8975f5c5SAndroid Build Coastguard Worker     GLuint mResolveTex;
140*8975f5c5SAndroid Build Coastguard Worker 
141*8975f5c5SAndroid Build Coastguard Worker     GLuint mColorLoc;
142*8975f5c5SAndroid Build Coastguard Worker     GLuint mProgram;
143*8975f5c5SAndroid Build Coastguard Worker     GLuint mVBO;
144*8975f5c5SAndroid Build Coastguard Worker };
145*8975f5c5SAndroid Build Coastguard Worker 
146*8975f5c5SAndroid Build Coastguard Worker }  // namespace
147*8975f5c5SAndroid Build Coastguard Worker 
148*8975f5c5SAndroid Build Coastguard Worker // Test simple state tracking
TEST_P(EXTMultisampleCompatibilityTest,TestStateTracking)149*8975f5c5SAndroid Build Coastguard Worker TEST_P(EXTMultisampleCompatibilityTest, TestStateTracking)
150*8975f5c5SAndroid Build Coastguard Worker {
151*8975f5c5SAndroid Build Coastguard Worker     if (!isApplicable())
152*8975f5c5SAndroid Build Coastguard Worker         return;
153*8975f5c5SAndroid Build Coastguard Worker 
154*8975f5c5SAndroid Build Coastguard Worker     EXPECT_TRUE(glIsEnabled(GL_MULTISAMPLE_EXT));
155*8975f5c5SAndroid Build Coastguard Worker     glDisable(GL_MULTISAMPLE_EXT);
156*8975f5c5SAndroid Build Coastguard Worker     EXPECT_FALSE(glIsEnabled(GL_MULTISAMPLE_EXT));
157*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_MULTISAMPLE_EXT);
158*8975f5c5SAndroid Build Coastguard Worker     EXPECT_TRUE(glIsEnabled(GL_MULTISAMPLE_EXT));
159*8975f5c5SAndroid Build Coastguard Worker 
160*8975f5c5SAndroid Build Coastguard Worker     EXPECT_FALSE(glIsEnabled(GL_SAMPLE_ALPHA_TO_ONE_EXT));
161*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_SAMPLE_ALPHA_TO_ONE_EXT);
162*8975f5c5SAndroid Build Coastguard Worker     EXPECT_TRUE(glIsEnabled(GL_SAMPLE_ALPHA_TO_ONE_EXT));
163*8975f5c5SAndroid Build Coastguard Worker     glDisable(GL_SAMPLE_ALPHA_TO_ONE_EXT);
164*8975f5c5SAndroid Build Coastguard Worker     EXPECT_FALSE(glIsEnabled(GL_SAMPLE_ALPHA_TO_ONE_EXT));
165*8975f5c5SAndroid Build Coastguard Worker 
166*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
167*8975f5c5SAndroid Build Coastguard Worker }
168*8975f5c5SAndroid Build Coastguard Worker 
169*8975f5c5SAndroid Build Coastguard Worker // Test that disabling GL_MULTISAMPLE_EXT is handled correctly.
TEST_P(EXTMultisampleCompatibilityTest,DrawAndResolve)170*8975f5c5SAndroid Build Coastguard Worker TEST_P(EXTMultisampleCompatibilityTest, DrawAndResolve)
171*8975f5c5SAndroid Build Coastguard Worker {
172*8975f5c5SAndroid Build Coastguard Worker     if (!isApplicable())
173*8975f5c5SAndroid Build Coastguard Worker         return;
174*8975f5c5SAndroid Build Coastguard Worker 
175*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/40644773
176*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsMac() && IsIntelUHD630Mobile() && IsDesktopOpenGL());
177*8975f5c5SAndroid Build Coastguard Worker 
178*8975f5c5SAndroid Build Coastguard Worker     static const float kBlue[]  = {0.0f, 0.0f, 1.0f, 1.0f};
179*8975f5c5SAndroid Build Coastguard Worker     static const float kGreen[] = {0.0f, 1.0f, 0.0f, 1.0f};
180*8975f5c5SAndroid Build Coastguard Worker     static const float kRed[]   = {1.0f, 0.0f, 0.0f, 1.0f};
181*8975f5c5SAndroid Build Coastguard Worker 
182*8975f5c5SAndroid Build Coastguard Worker     // Different drivers seem to behave differently with respect to resulting
183*8975f5c5SAndroid Build Coastguard Worker     // values. These might be due to different MSAA sample counts causing
184*8975f5c5SAndroid Build Coastguard Worker     // different samples to hit.  Other option is driver bugs. Just test that
185*8975f5c5SAndroid Build Coastguard Worker     // disabling multisample causes a difference.
186*8975f5c5SAndroid Build Coastguard Worker     std::unique_ptr<uint8_t[]> results[3];
187*8975f5c5SAndroid Build Coastguard Worker     const GLint kResultSize = kWidth * kHeight * 4;
188*8975f5c5SAndroid Build Coastguard Worker     for (int pass = 0; pass < 3; pass++)
189*8975f5c5SAndroid Build Coastguard Worker     {
190*8975f5c5SAndroid Build Coastguard Worker         prepareForDraw();
191*8975f5c5SAndroid Build Coastguard Worker         // Green: from top right to bottom left.
192*8975f5c5SAndroid Build Coastguard Worker         glUniform4fv(mColorLoc, 1, kGreen);
193*8975f5c5SAndroid Build Coastguard Worker         glDrawArrays(GL_TRIANGLES, 0, 3);
194*8975f5c5SAndroid Build Coastguard Worker 
195*8975f5c5SAndroid Build Coastguard Worker         // Blue: from top left to bottom right.
196*8975f5c5SAndroid Build Coastguard Worker         glUniform4fv(mColorLoc, 1, kBlue);
197*8975f5c5SAndroid Build Coastguard Worker         glDrawArrays(GL_TRIANGLES, 3, 3);
198*8975f5c5SAndroid Build Coastguard Worker 
199*8975f5c5SAndroid Build Coastguard Worker         // Red, with and without MSAA: from bottom left to top right.
200*8975f5c5SAndroid Build Coastguard Worker         if (pass == 1)
201*8975f5c5SAndroid Build Coastguard Worker         {
202*8975f5c5SAndroid Build Coastguard Worker             glDisable(GL_MULTISAMPLE_EXT);
203*8975f5c5SAndroid Build Coastguard Worker         }
204*8975f5c5SAndroid Build Coastguard Worker         glUniform4fv(mColorLoc, 1, kRed);
205*8975f5c5SAndroid Build Coastguard Worker         glDrawArrays(GL_TRIANGLES, 6, 3);
206*8975f5c5SAndroid Build Coastguard Worker         if (pass == 1)
207*8975f5c5SAndroid Build Coastguard Worker         {
208*8975f5c5SAndroid Build Coastguard Worker             glEnable(GL_MULTISAMPLE_EXT);
209*8975f5c5SAndroid Build Coastguard Worker         }
210*8975f5c5SAndroid Build Coastguard Worker         prepareForVerify();
211*8975f5c5SAndroid Build Coastguard Worker         results[pass].reset(new uint8_t[kResultSize]);
212*8975f5c5SAndroid Build Coastguard Worker         memset(results[pass].get(), 123u, kResultSize);
213*8975f5c5SAndroid Build Coastguard Worker         glReadPixels(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, results[pass].get());
214*8975f5c5SAndroid Build Coastguard Worker 
215*8975f5c5SAndroid Build Coastguard Worker         cleanup();
216*8975f5c5SAndroid Build Coastguard Worker     }
217*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(0, memcmp(results[0].get(), results[1].get(), kResultSize));
218*8975f5c5SAndroid Build Coastguard Worker     // Verify that rendering is deterministic, so that the pass above does not
219*8975f5c5SAndroid Build Coastguard Worker     // come from non-deterministic rendering.
220*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(0, memcmp(results[0].get(), results[2].get(), kResultSize));
221*8975f5c5SAndroid Build Coastguard Worker }
222*8975f5c5SAndroid Build Coastguard Worker 
223*8975f5c5SAndroid Build Coastguard Worker // Test that enabling GL_SAMPLE_ALPHA_TO_ONE_EXT affects rendering.
TEST_P(EXTMultisampleCompatibilityTest,DrawAlphaOneAndResolve)224*8975f5c5SAndroid Build Coastguard Worker TEST_P(EXTMultisampleCompatibilityTest, DrawAlphaOneAndResolve)
225*8975f5c5SAndroid Build Coastguard Worker {
226*8975f5c5SAndroid Build Coastguard Worker     if (!isApplicable())
227*8975f5c5SAndroid Build Coastguard Worker         return;
228*8975f5c5SAndroid Build Coastguard Worker 
229*8975f5c5SAndroid Build Coastguard Worker     // SAMPLE_ALPHA_TO_ONE is specified to transform alpha values of
230*8975f5c5SAndroid Build Coastguard Worker     // covered samples to 1.0. In order to detect it, we use non-1.0
231*8975f5c5SAndroid Build Coastguard Worker     // alpha.
232*8975f5c5SAndroid Build Coastguard Worker     static const float kBlue[]  = {0.0f, 0.0f, 1.0f, 0.5f};
233*8975f5c5SAndroid Build Coastguard Worker     static const float kGreen[] = {0.0f, 1.0f, 0.0f, 0.5f};
234*8975f5c5SAndroid Build Coastguard Worker     static const float kRed[]   = {1.0f, 0.0f, 0.0f, 0.5f};
235*8975f5c5SAndroid Build Coastguard Worker 
236*8975f5c5SAndroid Build Coastguard Worker     // Different drivers seem to behave differently with respect to resulting
237*8975f5c5SAndroid Build Coastguard Worker     // alpha value. These might be due to different MSAA sample counts causing
238*8975f5c5SAndroid Build Coastguard Worker     // different samples to hit.  Other option is driver bugs. Testing exact or
239*8975f5c5SAndroid Build Coastguard Worker     // even approximate sample values is not that easy.  Thus, just test
240*8975f5c5SAndroid Build Coastguard Worker     // representative positions which have fractional pixels, inspecting that
241*8975f5c5SAndroid Build Coastguard Worker     // normal rendering is different to SAMPLE_ALPHA_TO_ONE rendering.
242*8975f5c5SAndroid Build Coastguard Worker     std::unique_ptr<uint8_t[]> results[3];
243*8975f5c5SAndroid Build Coastguard Worker     const GLint kResultSize = kWidth * kHeight * 4;
244*8975f5c5SAndroid Build Coastguard Worker 
245*8975f5c5SAndroid Build Coastguard Worker     for (int pass = 0; pass < 3; ++pass)
246*8975f5c5SAndroid Build Coastguard Worker     {
247*8975f5c5SAndroid Build Coastguard Worker         prepareForDraw();
248*8975f5c5SAndroid Build Coastguard Worker         if (pass == 1)
249*8975f5c5SAndroid Build Coastguard Worker         {
250*8975f5c5SAndroid Build Coastguard Worker             glEnable(GL_SAMPLE_ALPHA_TO_ONE_EXT);
251*8975f5c5SAndroid Build Coastguard Worker         }
252*8975f5c5SAndroid Build Coastguard Worker         glEnable(GL_MULTISAMPLE_EXT);
253*8975f5c5SAndroid Build Coastguard Worker         glUniform4fv(mColorLoc, 1, kGreen);
254*8975f5c5SAndroid Build Coastguard Worker         glDrawArrays(GL_TRIANGLES, 0, 3);
255*8975f5c5SAndroid Build Coastguard Worker 
256*8975f5c5SAndroid Build Coastguard Worker         glUniform4fv(mColorLoc, 1, kBlue);
257*8975f5c5SAndroid Build Coastguard Worker         glDrawArrays(GL_TRIANGLES, 3, 3);
258*8975f5c5SAndroid Build Coastguard Worker 
259*8975f5c5SAndroid Build Coastguard Worker         glDisable(GL_MULTISAMPLE_EXT);
260*8975f5c5SAndroid Build Coastguard Worker         glUniform4fv(mColorLoc, 1, kRed);
261*8975f5c5SAndroid Build Coastguard Worker         glDrawArrays(GL_TRIANGLES, 6, 3);
262*8975f5c5SAndroid Build Coastguard Worker 
263*8975f5c5SAndroid Build Coastguard Worker         prepareForVerify();
264*8975f5c5SAndroid Build Coastguard Worker         results[pass].reset(new uint8_t[kResultSize]);
265*8975f5c5SAndroid Build Coastguard Worker         memset(results[pass].get(), 123u, kResultSize);
266*8975f5c5SAndroid Build Coastguard Worker         glReadPixels(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, results[pass].get());
267*8975f5c5SAndroid Build Coastguard Worker         if (pass == 1)
268*8975f5c5SAndroid Build Coastguard Worker         {
269*8975f5c5SAndroid Build Coastguard Worker             glDisable(GL_SAMPLE_ALPHA_TO_ONE_EXT);
270*8975f5c5SAndroid Build Coastguard Worker         }
271*8975f5c5SAndroid Build Coastguard Worker 
272*8975f5c5SAndroid Build Coastguard Worker         cleanup();
273*8975f5c5SAndroid Build Coastguard Worker     }
274*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(0, memcmp(results[0].get(), results[1].get(), kResultSize));
275*8975f5c5SAndroid Build Coastguard Worker     // Verify that rendering is deterministic, so that the pass above does not
276*8975f5c5SAndroid Build Coastguard Worker     // come from non-deterministic rendering.
277*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(0, memcmp(results[0].get(), results[2].get(), kResultSize));
278*8975f5c5SAndroid Build Coastguard Worker }
279*8975f5c5SAndroid Build Coastguard Worker 
280*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(EXTMultisampleCompatibilityTest);
281*8975f5c5SAndroid Build Coastguard Worker 
282*8975f5c5SAndroid Build Coastguard Worker class MultisampleCompatibilityTest : public ANGLETest<>
283*8975f5c5SAndroid Build Coastguard Worker {
284*8975f5c5SAndroid Build Coastguard Worker 
285*8975f5c5SAndroid Build Coastguard Worker   protected:
MultisampleCompatibilityTest()286*8975f5c5SAndroid Build Coastguard Worker     MultisampleCompatibilityTest()
287*8975f5c5SAndroid Build Coastguard Worker     {
288*8975f5c5SAndroid Build Coastguard Worker         setWindowWidth(64);
289*8975f5c5SAndroid Build Coastguard Worker         setWindowHeight(64);
290*8975f5c5SAndroid Build Coastguard Worker         setConfigRedBits(8);
291*8975f5c5SAndroid Build Coastguard Worker         setConfigBlueBits(8);
292*8975f5c5SAndroid Build Coastguard Worker         setConfigAlphaBits(8);
293*8975f5c5SAndroid Build Coastguard Worker     }
294*8975f5c5SAndroid Build Coastguard Worker 
prepareForDraw(GLsizei numSamples)295*8975f5c5SAndroid Build Coastguard Worker     void prepareForDraw(GLsizei numSamples)
296*8975f5c5SAndroid Build Coastguard Worker     {
297*8975f5c5SAndroid Build Coastguard Worker         // Create a sample buffer.
298*8975f5c5SAndroid Build Coastguard Worker         glGenRenderbuffers(1, &mSampleRB);
299*8975f5c5SAndroid Build Coastguard Worker         glBindRenderbuffer(GL_RENDERBUFFER, mSampleRB);
300*8975f5c5SAndroid Build Coastguard Worker         glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, numSamples, GL_RGBA8, kWidth,
301*8975f5c5SAndroid Build Coastguard Worker                                               kHeight);
302*8975f5c5SAndroid Build Coastguard Worker         GLint param = 0;
303*8975f5c5SAndroid Build Coastguard Worker         glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &param);
304*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GE(param, numSamples);
305*8975f5c5SAndroid Build Coastguard Worker         glGenFramebuffers(1, &mSampleFBO);
306*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, mSampleFBO);
307*8975f5c5SAndroid Build Coastguard Worker         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mSampleRB);
308*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
309*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, 0);
310*8975f5c5SAndroid Build Coastguard Worker         // Create another FBO to resolve the multisample buffer into.
311*8975f5c5SAndroid Build Coastguard Worker         glGenTextures(1, &mResolveTex);
312*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, mResolveTex);
313*8975f5c5SAndroid Build Coastguard Worker         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
314*8975f5c5SAndroid Build Coastguard Worker                      nullptr);
315*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
316*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
317*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
318*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
319*8975f5c5SAndroid Build Coastguard Worker         glGenFramebuffers(1, &mResolveFBO);
320*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, mResolveFBO);
321*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mResolveTex, 0);
322*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
323*8975f5c5SAndroid Build Coastguard Worker         glViewport(0, 0, kWidth, kHeight);
324*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, mSampleFBO);
325*8975f5c5SAndroid Build Coastguard Worker         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
326*8975f5c5SAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
327*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
328*8975f5c5SAndroid Build Coastguard Worker     }
329*8975f5c5SAndroid Build Coastguard Worker 
prepareForVerify()330*8975f5c5SAndroid Build Coastguard Worker     void prepareForVerify()
331*8975f5c5SAndroid Build Coastguard Worker     {
332*8975f5c5SAndroid Build Coastguard Worker         // Resolve.
333*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_READ_FRAMEBUFFER, mSampleFBO);
334*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mResolveFBO);
335*8975f5c5SAndroid Build Coastguard Worker         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
336*8975f5c5SAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
337*8975f5c5SAndroid Build Coastguard Worker         glBlitFramebufferANGLE(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_COLOR_BUFFER_BIT,
338*8975f5c5SAndroid Build Coastguard Worker                                GL_NEAREST);
339*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_READ_FRAMEBUFFER, mResolveFBO);
340*8975f5c5SAndroid Build Coastguard Worker 
341*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
342*8975f5c5SAndroid Build Coastguard Worker     }
343*8975f5c5SAndroid Build Coastguard Worker 
cleanup()344*8975f5c5SAndroid Build Coastguard Worker     void cleanup()
345*8975f5c5SAndroid Build Coastguard Worker     {
346*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, 0);
347*8975f5c5SAndroid Build Coastguard Worker         glDeleteFramebuffers(1, &mResolveFBO);
348*8975f5c5SAndroid Build Coastguard Worker         glDeleteFramebuffers(1, &mSampleFBO);
349*8975f5c5SAndroid Build Coastguard Worker         glDeleteTextures(1, &mResolveTex);
350*8975f5c5SAndroid Build Coastguard Worker         glDeleteRenderbuffers(1, &mSampleRB);
351*8975f5c5SAndroid Build Coastguard Worker 
352*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
353*8975f5c5SAndroid Build Coastguard Worker     }
354*8975f5c5SAndroid Build Coastguard Worker 
isApplicable() const355*8975f5c5SAndroid Build Coastguard Worker     bool isApplicable() const
356*8975f5c5SAndroid Build Coastguard Worker     {
357*8975f5c5SAndroid Build Coastguard Worker         return IsGLExtensionEnabled("GL_ANGLE_framebuffer_multisample") &&
358*8975f5c5SAndroid Build Coastguard Worker                IsGLExtensionEnabled("GL_OES_rgb8_rgba8");
359*8975f5c5SAndroid Build Coastguard Worker     }
360*8975f5c5SAndroid Build Coastguard Worker 
361*8975f5c5SAndroid Build Coastguard Worker     GLuint mSampleFBO;
362*8975f5c5SAndroid Build Coastguard Worker     GLuint mResolveFBO;
363*8975f5c5SAndroid Build Coastguard Worker     GLuint mSampleRB;
364*8975f5c5SAndroid Build Coastguard Worker     GLuint mResolveTex;
365*8975f5c5SAndroid Build Coastguard Worker };
366*8975f5c5SAndroid Build Coastguard Worker 
367*8975f5c5SAndroid Build Coastguard Worker // Test that enabling GL_SAMPLE_COVERAGE affects rendering.
TEST_P(MultisampleCompatibilityTest,DrawCoverageAndResolve)368*8975f5c5SAndroid Build Coastguard Worker TEST_P(MultisampleCompatibilityTest, DrawCoverageAndResolve)
369*8975f5c5SAndroid Build Coastguard Worker {
370*8975f5c5SAndroid Build Coastguard Worker     if (!isApplicable())
371*8975f5c5SAndroid Build Coastguard Worker         return;
372*8975f5c5SAndroid Build Coastguard Worker 
373*8975f5c5SAndroid Build Coastguard Worker     // TODO: Figure out why this fails on Android.
374*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());
375*8975f5c5SAndroid Build Coastguard Worker 
376*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
377*8975f5c5SAndroid Build Coastguard Worker 
378*8975f5c5SAndroid Build Coastguard Worker     GLsizei maxSamples = 0;
379*8975f5c5SAndroid Build Coastguard Worker     glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
380*8975f5c5SAndroid Build Coastguard Worker     int iterationCount = maxSamples + 1;
381*8975f5c5SAndroid Build Coastguard Worker     for (int samples = 1; samples < iterationCount; samples++)
382*8975f5c5SAndroid Build Coastguard Worker     {
383*8975f5c5SAndroid Build Coastguard Worker         prepareForDraw(samples);
384*8975f5c5SAndroid Build Coastguard Worker         glEnable(GL_SAMPLE_COVERAGE);
385*8975f5c5SAndroid Build Coastguard Worker         glSampleCoverage(1.0, false);
386*8975f5c5SAndroid Build Coastguard Worker         drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.5f);
387*8975f5c5SAndroid Build Coastguard Worker 
388*8975f5c5SAndroid Build Coastguard Worker         prepareForVerify();
389*8975f5c5SAndroid Build Coastguard Worker         GLsizei pixelCount = kWidth * kHeight;
390*8975f5c5SAndroid Build Coastguard Worker         std::vector<GLColor> actual(pixelCount, GLColor::black);
391*8975f5c5SAndroid Build Coastguard Worker         glReadPixels(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, actual.data());
392*8975f5c5SAndroid Build Coastguard Worker         glDisable(GL_SAMPLE_COVERAGE);
393*8975f5c5SAndroid Build Coastguard Worker         cleanup();
394*8975f5c5SAndroid Build Coastguard Worker 
395*8975f5c5SAndroid Build Coastguard Worker         std::vector<GLColor> expected(pixelCount, GLColor::red);
396*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expected, actual);
397*8975f5c5SAndroid Build Coastguard Worker     }
398*8975f5c5SAndroid Build Coastguard Worker }
399*8975f5c5SAndroid Build Coastguard Worker 
400*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(MultisampleCompatibilityTest);
401