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