xref: /aosp_15_r20/external/angle/src/tests/gl_tests/FramebufferMixedSamplesTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2016 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 // CHROMIUMFramebufferMixedSamplesTest
7*8975f5c5SAndroid Build Coastguard Worker //   Test CHROMIUM subset of NV_framebuffer_mixed_samples.
8*8975f5c5SAndroid Build Coastguard Worker //   This extension allows rendering to a framebuffer that has different
9*8975f5c5SAndroid Build Coastguard Worker //   sample counts for different render buffers (stencil, depth, color)
10*8975f5c5SAndroid Build Coastguard Worker 
11*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.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 GLuint kWidth  = 100;
19*8975f5c5SAndroid Build Coastguard Worker const GLuint kHeight = 100;
20*8975f5c5SAndroid Build Coastguard Worker 
21*8975f5c5SAndroid Build Coastguard Worker class CHROMIUMFramebufferMixedSamplesTest : public ANGLETest<>
22*8975f5c5SAndroid Build Coastguard Worker {
23*8975f5c5SAndroid Build Coastguard Worker   protected:
24*8975f5c5SAndroid Build Coastguard Worker     enum SetupFBOType
25*8975f5c5SAndroid Build Coastguard Worker     {
26*8975f5c5SAndroid Build Coastguard Worker         MixedSampleFBO,   // 1 color sample, N stencil samples.
27*8975f5c5SAndroid Build Coastguard Worker         SingleSampleFBO,  // 1 color sample, 1 stencil sample.
28*8975f5c5SAndroid Build Coastguard Worker     };
29*8975f5c5SAndroid Build Coastguard Worker 
isApplicable() const30*8975f5c5SAndroid Build Coastguard Worker     bool isApplicable() const
31*8975f5c5SAndroid Build Coastguard Worker     {
32*8975f5c5SAndroid Build Coastguard Worker         return IsGLExtensionEnabled("GL_CHROMIUM_framebuffer_mixed_samples") &&
33*8975f5c5SAndroid Build Coastguard Worker                IsGLExtensionEnabled("GL_OES_rgb8_rgba8");
34*8975f5c5SAndroid Build Coastguard Worker     }
35*8975f5c5SAndroid Build Coastguard Worker 
testSetUp()36*8975f5c5SAndroid Build Coastguard Worker     void testSetUp() override
37*8975f5c5SAndroid Build Coastguard Worker     {
38*8975f5c5SAndroid Build Coastguard Worker         mProgram = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
39*8975f5c5SAndroid Build Coastguard Worker 
40*8975f5c5SAndroid Build Coastguard Worker         GLuint position_loc = glGetAttribLocation(mProgram, essl1_shaders::PositionAttrib());
41*8975f5c5SAndroid Build Coastguard Worker         mColorLoc           = glGetUniformLocation(mProgram, essl1_shaders::ColorUniform());
42*8975f5c5SAndroid Build Coastguard Worker 
43*8975f5c5SAndroid Build Coastguard Worker         glGenBuffers(1, &mVBO);
44*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_ARRAY_BUFFER, mVBO);
45*8975f5c5SAndroid Build Coastguard Worker 
46*8975f5c5SAndroid Build Coastguard Worker         static float vertices[] = {
47*8975f5c5SAndroid Build Coastguard Worker             1.0f,  1.0f, -1.0f, 1.0f,  -1.0f, -1.0f, -1.0f, 1.0f, -1.0f,
48*8975f5c5SAndroid Build Coastguard Worker             -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f,  -1.0f, 1.0f, 1.0f,
49*8975f5c5SAndroid Build Coastguard Worker         };
50*8975f5c5SAndroid Build Coastguard Worker         glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
51*8975f5c5SAndroid Build Coastguard Worker         glEnableVertexAttribArray(position_loc);
52*8975f5c5SAndroid Build Coastguard Worker         glVertexAttribPointer(position_loc, 2, GL_FLOAT, GL_FALSE, 0, 0);
53*8975f5c5SAndroid Build Coastguard Worker 
54*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
55*8975f5c5SAndroid Build Coastguard Worker     }
56*8975f5c5SAndroid Build Coastguard Worker 
testTearDown()57*8975f5c5SAndroid Build Coastguard Worker     void testTearDown() override
58*8975f5c5SAndroid Build Coastguard Worker     {
59*8975f5c5SAndroid Build Coastguard Worker         glDeleteBuffers(1, &mVBO);
60*8975f5c5SAndroid Build Coastguard Worker         glDeleteProgram(mProgram);
61*8975f5c5SAndroid Build Coastguard Worker 
62*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
63*8975f5c5SAndroid Build Coastguard Worker     }
64*8975f5c5SAndroid Build Coastguard Worker 
prepareForDraw(SetupFBOType fbo_type)65*8975f5c5SAndroid Build Coastguard Worker     void prepareForDraw(SetupFBOType fbo_type)
66*8975f5c5SAndroid Build Coastguard Worker     {
67*8975f5c5SAndroid Build Coastguard Worker         glActiveTexture(GL_TEXTURE0);
68*8975f5c5SAndroid Build Coastguard Worker         glGenTextures(1, &mTexture);
69*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, mTexture);
70*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
71*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
72*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
73*8975f5c5SAndroid Build Coastguard Worker         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
74*8975f5c5SAndroid Build Coastguard Worker         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
75*8975f5c5SAndroid Build Coastguard Worker                      nullptr);
76*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, 0);
77*8975f5c5SAndroid Build Coastguard Worker 
78*8975f5c5SAndroid Build Coastguard Worker         glGenRenderbuffers(1, &mStencilRB);
79*8975f5c5SAndroid Build Coastguard Worker         glBindRenderbuffer(GL_RENDERBUFFER, mStencilRB);
80*8975f5c5SAndroid Build Coastguard Worker 
81*8975f5c5SAndroid Build Coastguard Worker         if (fbo_type == MixedSampleFBO)
82*8975f5c5SAndroid Build Coastguard Worker         {
83*8975f5c5SAndroid Build Coastguard Worker             // Create a sample buffer.
84*8975f5c5SAndroid Build Coastguard Worker             GLsizei num_samples = 8, max_samples = 0;
85*8975f5c5SAndroid Build Coastguard Worker             glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
86*8975f5c5SAndroid Build Coastguard Worker             num_samples = std::min(num_samples, max_samples);
87*8975f5c5SAndroid Build Coastguard Worker             glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, num_samples, GL_STENCIL_INDEX8,
88*8975f5c5SAndroid Build Coastguard Worker                                                   kWidth, kHeight);
89*8975f5c5SAndroid Build Coastguard Worker             GLint param = 0;
90*8975f5c5SAndroid Build Coastguard Worker             glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &param);
91*8975f5c5SAndroid Build Coastguard Worker             EXPECT_GT(param, 1);
92*8975f5c5SAndroid Build Coastguard Worker         }
93*8975f5c5SAndroid Build Coastguard Worker         else
94*8975f5c5SAndroid Build Coastguard Worker         {
95*8975f5c5SAndroid Build Coastguard Worker             glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, kWidth, kHeight);
96*8975f5c5SAndroid Build Coastguard Worker         }
97*8975f5c5SAndroid Build Coastguard Worker         glBindRenderbuffer(GL_RENDERBUFFER, 0);
98*8975f5c5SAndroid Build Coastguard Worker 
99*8975f5c5SAndroid Build Coastguard Worker         glGenFramebuffers(1, &mSampleFBO);
100*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, mSampleFBO);
101*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
102*8975f5c5SAndroid Build Coastguard Worker         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
103*8975f5c5SAndroid Build Coastguard Worker                                   mStencilRB);
104*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(static_cast<GLenum>(GL_FRAMEBUFFER_COMPLETE),
105*8975f5c5SAndroid Build Coastguard Worker                   glCheckFramebufferStatus(GL_FRAMEBUFFER));
106*8975f5c5SAndroid Build Coastguard Worker 
107*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(mProgram);
108*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_ARRAY_BUFFER, 0);
109*8975f5c5SAndroid Build Coastguard Worker         glViewport(0, 0, kWidth, kHeight);
110*8975f5c5SAndroid Build Coastguard Worker         glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
111*8975f5c5SAndroid Build Coastguard Worker         glClearStencil(1);
112*8975f5c5SAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
113*8975f5c5SAndroid Build Coastguard Worker         glEnable(GL_STENCIL_TEST);
114*8975f5c5SAndroid Build Coastguard Worker         glEnable(GL_BLEND);
115*8975f5c5SAndroid Build Coastguard Worker         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
116*8975f5c5SAndroid Build Coastguard Worker         glStencilMask(0xffffffff);
117*8975f5c5SAndroid Build Coastguard Worker         glStencilFunc(GL_EQUAL, 1, 0xffffffff);
118*8975f5c5SAndroid Build Coastguard Worker         glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO);
119*8975f5c5SAndroid Build Coastguard Worker 
120*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
121*8975f5c5SAndroid Build Coastguard Worker     }
122*8975f5c5SAndroid Build Coastguard Worker 
cleanup()123*8975f5c5SAndroid Build Coastguard Worker     void cleanup()
124*8975f5c5SAndroid Build Coastguard Worker     {
125*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, 0);
126*8975f5c5SAndroid Build Coastguard Worker         glDeleteFramebuffers(1, &mSampleFBO);
127*8975f5c5SAndroid Build Coastguard Worker         glDeleteTextures(1, &mTexture);
128*8975f5c5SAndroid Build Coastguard Worker         glDeleteRenderbuffers(1, &mStencilRB);
129*8975f5c5SAndroid Build Coastguard Worker 
130*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
131*8975f5c5SAndroid Build Coastguard Worker     }
132*8975f5c5SAndroid Build Coastguard Worker 
133*8975f5c5SAndroid Build Coastguard Worker     GLuint mSampleFBO;
134*8975f5c5SAndroid Build Coastguard Worker     GLuint mStencilRB;
135*8975f5c5SAndroid Build Coastguard Worker     GLuint mTexture;
136*8975f5c5SAndroid Build Coastguard Worker 
137*8975f5c5SAndroid Build Coastguard Worker     GLuint mProgram;
138*8975f5c5SAndroid Build Coastguard Worker     GLuint mVBO;
139*8975f5c5SAndroid Build Coastguard Worker     GLint mColorLoc;
140*8975f5c5SAndroid Build Coastguard Worker };
141*8975f5c5SAndroid Build Coastguard Worker 
142*8975f5c5SAndroid Build Coastguard Worker }  // namespace
143*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(CHROMIUMFramebufferMixedSamplesTest,StateSettingTest)144*8975f5c5SAndroid Build Coastguard Worker TEST_P(CHROMIUMFramebufferMixedSamplesTest, StateSettingTest)
145*8975f5c5SAndroid Build Coastguard Worker {
146*8975f5c5SAndroid Build Coastguard Worker     if (!isApplicable())
147*8975f5c5SAndroid Build Coastguard Worker     {
148*8975f5c5SAndroid Build Coastguard Worker         return;
149*8975f5c5SAndroid Build Coastguard Worker     }
150*8975f5c5SAndroid Build Coastguard Worker 
151*8975f5c5SAndroid Build Coastguard Worker     GLint value = -1;
152*8975f5c5SAndroid Build Coastguard Worker     glGetIntegerv(GL_COVERAGE_MODULATION_CHROMIUM, &value);
153*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(GL_NONE, value);
154*8975f5c5SAndroid Build Coastguard Worker     GLenum kValues[] = {GL_NONE, GL_RGB, GL_RGBA, GL_ALPHA};
155*8975f5c5SAndroid Build Coastguard Worker     for (auto expect : kValues)
156*8975f5c5SAndroid Build Coastguard Worker     {
157*8975f5c5SAndroid Build Coastguard Worker         glCoverageModulationCHROMIUM(expect);
158*8975f5c5SAndroid Build Coastguard Worker         value = -1;
159*8975f5c5SAndroid Build Coastguard Worker         glGetIntegerv(GL_COVERAGE_MODULATION_CHROMIUM, &value);
160*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(expect, static_cast<GLenum>(value));
161*8975f5c5SAndroid Build Coastguard Worker         EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
162*8975f5c5SAndroid Build Coastguard Worker     }
163*8975f5c5SAndroid Build Coastguard Worker 
164*8975f5c5SAndroid Build Coastguard Worker     glCoverageModulationCHROMIUM(GL_BYTE);
165*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(static_cast<GLenum>(GL_INVALID_ENUM), glGetError());
166*8975f5c5SAndroid Build Coastguard Worker     value = -1;
167*8975f5c5SAndroid Build Coastguard Worker     glGetIntegerv(GL_COVERAGE_MODULATION_CHROMIUM, &value);
168*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(static_cast<GLenum>(GL_ALPHA), static_cast<GLenum>(value));
169*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(static_cast<GLenum>(GL_NO_ERROR), glGetError());
170*8975f5c5SAndroid Build Coastguard Worker }
171*8975f5c5SAndroid Build Coastguard Worker 
172*8975f5c5SAndroid Build Coastguard Worker // The test pattern is as follows:
173*8975f5c5SAndroid Build Coastguard Worker // A green triangle (bottom left, top right, top left).
174*8975f5c5SAndroid Build Coastguard Worker // A blue triangle (top left, bottom right, bottom left).
175*8975f5c5SAndroid Build Coastguard Worker // The triangles will overlap but overlap only contains green pixels,
176*8975f5c5SAndroid Build Coastguard Worker // due to each draw erasing its area from stencil.
177*8975f5c5SAndroid Build Coastguard Worker // The blue triangle will fill only the area (bottom left, center,
178*8975f5c5SAndroid Build Coastguard Worker // bottom right).
179*8975f5c5SAndroid Build Coastguard Worker 
180*8975f5c5SAndroid Build Coastguard Worker // The test tests that CoverageModulation call works.
181*8975f5c5SAndroid Build Coastguard Worker // The fractional pixels of both triangles end up being modulated
182*8975f5c5SAndroid Build Coastguard Worker // by the coverage of the fragment. Test that drawing with and without
183*8975f5c5SAndroid Build Coastguard Worker // CoverageModulation causes the result to be different.
TEST_P(CHROMIUMFramebufferMixedSamplesTest,CoverageModulation)184*8975f5c5SAndroid Build Coastguard Worker TEST_P(CHROMIUMFramebufferMixedSamplesTest, CoverageModulation)
185*8975f5c5SAndroid Build Coastguard Worker {
186*8975f5c5SAndroid Build Coastguard Worker     if (!isApplicable())
187*8975f5c5SAndroid Build Coastguard Worker     {
188*8975f5c5SAndroid Build Coastguard Worker         return;
189*8975f5c5SAndroid Build Coastguard Worker     }
190*8975f5c5SAndroid Build Coastguard Worker     static const float kBlue[]  = {0.0f, 0.0f, 1.0f, 1.0f};
191*8975f5c5SAndroid Build Coastguard Worker     static const float kGreen[] = {0.0f, 1.0f, 0.0f, 1.0f};
192*8975f5c5SAndroid Build Coastguard Worker     std::unique_ptr<uint8_t[]> results[3];
193*8975f5c5SAndroid Build Coastguard Worker     const GLint kResultSize = kWidth * kHeight * 4;
194*8975f5c5SAndroid Build Coastguard Worker 
195*8975f5c5SAndroid Build Coastguard Worker     for (int pass = 0; pass < 3; ++pass)
196*8975f5c5SAndroid Build Coastguard Worker     {
197*8975f5c5SAndroid Build Coastguard Worker         prepareForDraw(MixedSampleFBO);
198*8975f5c5SAndroid Build Coastguard Worker         if (pass == 1)
199*8975f5c5SAndroid Build Coastguard Worker         {
200*8975f5c5SAndroid Build Coastguard Worker             glCoverageModulationCHROMIUM(GL_RGBA);
201*8975f5c5SAndroid Build Coastguard Worker         }
202*8975f5c5SAndroid Build Coastguard Worker         glUniform4fv(mColorLoc, 1, kGreen);
203*8975f5c5SAndroid Build Coastguard Worker         glDrawArrays(GL_TRIANGLES, 0, 3);
204*8975f5c5SAndroid Build Coastguard Worker 
205*8975f5c5SAndroid Build Coastguard Worker         glUniform4fv(mColorLoc, 1, kBlue);
206*8975f5c5SAndroid Build Coastguard Worker         glDrawArrays(GL_TRIANGLES, 3, 3);
207*8975f5c5SAndroid Build Coastguard Worker         if (pass == 1)
208*8975f5c5SAndroid Build Coastguard Worker         {
209*8975f5c5SAndroid Build Coastguard Worker             glCoverageModulationCHROMIUM(GL_NONE);
210*8975f5c5SAndroid Build Coastguard Worker         }
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 
218*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(0, memcmp(results[0].get(), results[1].get(), kResultSize));
219*8975f5c5SAndroid Build Coastguard Worker     // Verify that rendering is deterministic, so that the pass above does not
220*8975f5c5SAndroid Build Coastguard Worker     // come from non-deterministic rendering.
221*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(0, memcmp(results[0].get(), results[2].get(), kResultSize));
222*8975f5c5SAndroid Build Coastguard Worker }
223*8975f5c5SAndroid Build Coastguard Worker 
224*8975f5c5SAndroid Build Coastguard Worker // The test tests that the stencil buffer can be multisampled, even though the
225*8975f5c5SAndroid Build Coastguard Worker // color buffer is single-sampled. Draws the same pattern with single-sample
226*8975f5c5SAndroid Build Coastguard Worker // stencil buffer and with multisample stencil buffer. The images should differ.
TEST_P(CHROMIUMFramebufferMixedSamplesTest,MultisampleStencilEffective)227*8975f5c5SAndroid Build Coastguard Worker TEST_P(CHROMIUMFramebufferMixedSamplesTest, MultisampleStencilEffective)
228*8975f5c5SAndroid Build Coastguard Worker {
229*8975f5c5SAndroid Build Coastguard Worker     if (!isApplicable())
230*8975f5c5SAndroid Build Coastguard Worker     {
231*8975f5c5SAndroid Build Coastguard Worker         return;
232*8975f5c5SAndroid Build Coastguard Worker     }
233*8975f5c5SAndroid Build Coastguard Worker 
234*8975f5c5SAndroid Build Coastguard Worker     static const float kBlue[]  = {0.0f, 0.0f, 1.0f, 1.0f};
235*8975f5c5SAndroid Build Coastguard Worker     static const float kGreen[] = {0.0f, 1.0f, 0.0f, 1.0f};
236*8975f5c5SAndroid Build Coastguard Worker 
237*8975f5c5SAndroid Build Coastguard Worker     std::unique_ptr<uint8_t[]> results[3];
238*8975f5c5SAndroid Build Coastguard Worker     const GLint kResultSize = kWidth * kHeight * 4;
239*8975f5c5SAndroid Build Coastguard Worker 
240*8975f5c5SAndroid Build Coastguard Worker     for (int pass = 0; pass < 3; ++pass)
241*8975f5c5SAndroid Build Coastguard Worker     {
242*8975f5c5SAndroid Build Coastguard Worker         if (pass == 1)
243*8975f5c5SAndroid Build Coastguard Worker         {
244*8975f5c5SAndroid Build Coastguard Worker             prepareForDraw(MixedSampleFBO);
245*8975f5c5SAndroid Build Coastguard Worker         }
246*8975f5c5SAndroid Build Coastguard Worker         else
247*8975f5c5SAndroid Build Coastguard Worker         {
248*8975f5c5SAndroid Build Coastguard Worker             prepareForDraw(SingleSampleFBO);
249*8975f5c5SAndroid Build Coastguard Worker         }
250*8975f5c5SAndroid Build Coastguard Worker         glUniform4fv(mColorLoc, 1, kGreen);
251*8975f5c5SAndroid Build Coastguard Worker         glDrawArrays(GL_TRIANGLES, 0, 3);
252*8975f5c5SAndroid Build Coastguard Worker 
253*8975f5c5SAndroid Build Coastguard Worker         glUniform4fv(mColorLoc, 1, kBlue);
254*8975f5c5SAndroid Build Coastguard Worker         glDrawArrays(GL_TRIANGLES, 3, 3);
255*8975f5c5SAndroid Build Coastguard Worker 
256*8975f5c5SAndroid Build Coastguard Worker         results[pass].reset(new uint8_t[kResultSize]);
257*8975f5c5SAndroid Build Coastguard Worker         memset(results[pass].get(), 12u, kResultSize);
258*8975f5c5SAndroid Build Coastguard Worker         glReadPixels(0, 0, kWidth, kHeight, GL_RGBA, GL_UNSIGNED_BYTE, results[pass].get());
259*8975f5c5SAndroid Build Coastguard Worker 
260*8975f5c5SAndroid Build Coastguard Worker         cleanup();
261*8975f5c5SAndroid Build Coastguard Worker     }
262*8975f5c5SAndroid Build Coastguard Worker 
263*8975f5c5SAndroid Build Coastguard Worker     EXPECT_NE(0, memcmp(results[0].get(), results[1].get(), kResultSize));
264*8975f5c5SAndroid Build Coastguard Worker     // Verify that rendering is deterministic, so that the pass above does not
265*8975f5c5SAndroid Build Coastguard Worker     // come from non-deterministic rendering.
266*8975f5c5SAndroid Build Coastguard Worker     EXPECT_EQ(0, memcmp(results[0].get(), results[2].get(), kResultSize));
267*8975f5c5SAndroid Build Coastguard Worker }
268*8975f5c5SAndroid Build Coastguard Worker 
269*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES2(CHROMIUMFramebufferMixedSamplesTest);
270