• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // StateChangeTest:
7 //   Specifically designed for an ANGLE implementation of GL, these tests validate that
8 //   ANGLE's dirty bits systems don't get confused by certain sequences of state changes.
9 //
10 
11 #include "test_utils/ANGLETest.h"
12 #include "test_utils/gl_raii.h"
13 #include "util/random_utils.h"
14 
15 #include <thread>
16 
17 using namespace angle;
18 
19 namespace
20 {
21 
22 class StateChangeTest : public ANGLETest<>
23 {
24   protected:
StateChangeTest()25     StateChangeTest()
26     {
27         setWindowWidth(64);
28         setWindowHeight(64);
29         setConfigRedBits(8);
30         setConfigGreenBits(8);
31         setConfigBlueBits(8);
32         setConfigAlphaBits(8);
33         setConfigDepthBits(24);
34         setConfigStencilBits(8);
35 
36         // Enable the no error extension to avoid syncing the FBO state on validation.
37         setNoErrorEnabled(true);
38     }
39 
testSetUp()40     void testSetUp() override
41     {
42         glGenFramebuffers(1, &mFramebuffer);
43         glGenTextures(2, mTextures.data());
44         glGenRenderbuffers(1, &mRenderbuffer);
45 
46         ASSERT_GL_NO_ERROR();
47     }
48 
testTearDown()49     void testTearDown() override
50     {
51         if (mFramebuffer != 0)
52         {
53             glDeleteFramebuffers(1, &mFramebuffer);
54             mFramebuffer = 0;
55         }
56 
57         if (!mTextures.empty())
58         {
59             glDeleteTextures(static_cast<GLsizei>(mTextures.size()), mTextures.data());
60             mTextures.clear();
61         }
62 
63         glDeleteRenderbuffers(1, &mRenderbuffer);
64     }
65 
66     GLuint mFramebuffer           = 0;
67     GLuint mRenderbuffer          = 0;
68     std::vector<GLuint> mTextures = {0, 0};
69 };
70 
71 class StateChangeTestES3 : public StateChangeTest
72 {
73   protected:
StateChangeTestES3()74     StateChangeTestES3() {}
75 };
76 
77 class StateChangeTestES31 : public StateChangeTest
78 {
79   protected:
StateChangeTestES31()80     StateChangeTestES31() {}
81 };
82 
83 // Ensure that CopyTexImage2D syncs framebuffer changes.
TEST_P(StateChangeTest,CopyTexImage2DSync)84 TEST_P(StateChangeTest, CopyTexImage2DSync)
85 {
86     // TODO(geofflang): Fix on Linux AMD drivers (http://anglebug.com/1291)
87     ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
88 
89     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
90 
91     // Init first texture to red
92     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
93     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
94     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0);
95     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
96     glClear(GL_COLOR_BUFFER_BIT);
97     EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
98 
99     // Init second texture to green
100     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
101     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
102     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1], 0);
103     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
104     glClear(GL_COLOR_BUFFER_BIT);
105     EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
106 
107     // Copy in the red texture to the green one.
108     // CopyTexImage should sync the framebuffer attachment change.
109     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0);
110     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 16, 16, 0);
111     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1], 0);
112     EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
113 
114     ASSERT_GL_NO_ERROR();
115 }
116 
117 // Ensure that CopyTexSubImage2D syncs framebuffer changes.
TEST_P(StateChangeTest,CopyTexSubImage2DSync)118 TEST_P(StateChangeTest, CopyTexSubImage2DSync)
119 {
120     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
121 
122     // Init first texture to red
123     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
124     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
125     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0);
126     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
127     glClear(GL_COLOR_BUFFER_BIT);
128     EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
129 
130     // Init second texture to green
131     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
132     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
133     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1], 0);
134     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
135     glClear(GL_COLOR_BUFFER_BIT);
136     EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
137 
138     // Copy in the red texture to the green one.
139     // CopyTexImage should sync the framebuffer attachment change.
140     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0);
141     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 16, 16);
142     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1], 0);
143     EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
144 
145     ASSERT_GL_NO_ERROR();
146 }
147 
148 // Test that Framebuffer completeness caching works when color attachments change.
TEST_P(StateChangeTest,FramebufferIncompleteColorAttachment)149 TEST_P(StateChangeTest, FramebufferIncompleteColorAttachment)
150 {
151     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
152     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
153     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
154     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0);
155     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
156 
157     // Change the texture at color attachment 0 to be non-color-renderable.
158     glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, 16, 16, 0, GL_ALPHA, GL_UNSIGNED_BYTE, nullptr);
159     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
160                      glCheckFramebufferStatus(GL_FRAMEBUFFER));
161 
162     ASSERT_GL_NO_ERROR();
163 }
164 
165 // Test that caching works when color attachments change with TexStorage.
TEST_P(StateChangeTest,FramebufferIncompleteWithTexStorage)166 TEST_P(StateChangeTest, FramebufferIncompleteWithTexStorage)
167 {
168     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
169 
170     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
171     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
172     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
173     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0);
174     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
175 
176     // Change the texture at color attachment 0 to be non-color-renderable.
177     glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_ALPHA8_EXT, 16, 16);
178     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
179                      glCheckFramebufferStatus(GL_FRAMEBUFFER));
180 
181     ASSERT_GL_NO_ERROR();
182 }
183 
184 // Test that caching works when color attachments change with CompressedTexImage2D.
TEST_P(StateChangeTestES3,FramebufferIncompleteWithCompressedTex)185 TEST_P(StateChangeTestES3, FramebufferIncompleteWithCompressedTex)
186 {
187     // ETC texture formats are not supported on Mac OpenGL. http://anglebug.com/3853
188     ANGLE_SKIP_TEST_IF(IsMac() && IsDesktopOpenGL());
189 
190     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
191     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
192     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
193     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0);
194     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
195 
196     // Change the texture at color attachment 0 to be non-color-renderable.
197     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB8_ETC2, 16, 16, 0, 128, nullptr);
198     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
199                      glCheckFramebufferStatus(GL_FRAMEBUFFER));
200 
201     ASSERT_GL_NO_ERROR();
202 }
203 
204 // Test that caching works when color attachments are deleted.
TEST_P(StateChangeTestES3,FramebufferIncompleteWhenAttachmentDeleted)205 TEST_P(StateChangeTestES3, FramebufferIncompleteWhenAttachmentDeleted)
206 {
207     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
208     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
209     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
210     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0);
211     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
212 
213     // Delete the texture at color attachment 0.
214     glDeleteTextures(1, &mTextures[0]);
215     mTextures[0] = 0;
216     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT,
217                      glCheckFramebufferStatus(GL_FRAMEBUFFER));
218 
219     ASSERT_GL_NO_ERROR();
220 }
221 
222 // Test that Framebuffer completeness caching works when depth attachments change.
TEST_P(StateChangeTest,FramebufferIncompleteDepthAttachment)223 TEST_P(StateChangeTest, FramebufferIncompleteDepthAttachment)
224 {
225     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
226     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
227     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
228     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0);
229     glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
230     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 16, 16);
231     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mRenderbuffer);
232     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
233 
234     // Change the texture at color attachment 0 to be non-depth-renderable.
235     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 16, 16);
236     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
237                      glCheckFramebufferStatus(GL_FRAMEBUFFER));
238 
239     ASSERT_GL_NO_ERROR();
240 }
241 
242 // Test that Framebuffer completeness caching works when stencil attachments change.
TEST_P(StateChangeTest,FramebufferIncompleteStencilAttachment)243 TEST_P(StateChangeTest, FramebufferIncompleteStencilAttachment)
244 {
245     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
246     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
247     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
248     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0);
249     glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
250     glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, 16, 16);
251     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
252                               mRenderbuffer);
253     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
254 
255     // Change the texture at the stencil attachment to be non-stencil-renderable.
256     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 16, 16);
257     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
258                      glCheckFramebufferStatus(GL_FRAMEBUFFER));
259 
260     ASSERT_GL_NO_ERROR();
261 }
262 
263 // Test that Framebuffer completeness caching works when depth-stencil attachments change.
TEST_P(StateChangeTestES3,FramebufferIncompleteDepthStencilAttachment)264 TEST_P(StateChangeTestES3, FramebufferIncompleteDepthStencilAttachment)
265 {
266     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
267     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
268     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
269     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0);
270     glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
271     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 16, 16);
272     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
273                               mRenderbuffer);
274     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
275 
276     // Change the texture the depth-stencil attachment to be non-depth-stencil-renderable.
277     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 16, 16);
278     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
279                      glCheckFramebufferStatus(GL_FRAMEBUFFER));
280 
281     ASSERT_GL_NO_ERROR();
282 }
283 
284 // Test that enabling GL_SAMPLE_ALPHA_TO_COVERAGE doesn't generate errors.
TEST_P(StateChangeTest,AlphaToCoverageEnable)285 TEST_P(StateChangeTest, AlphaToCoverageEnable)
286 {
287     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
288 
289     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
290     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
291     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
292     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
293     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0);
294     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
295 
296     ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
297 
298     // We don't actually care that this does anything, just that it can be enabled without causing
299     // an error.
300     glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
301 
302     glUseProgram(greenProgram);
303     drawQuad(greenProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
304     ASSERT_GL_NO_ERROR();
305     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
306 }
307 
308 const char kSimpleAttributeVS[] = R"(attribute vec2 position;
309 attribute vec4 testAttrib;
310 varying vec4 testVarying;
311 void main()
312 {
313     gl_Position = vec4(position, 0, 1);
314     testVarying = testAttrib;
315 })";
316 
317 const char kSimpleAttributeFS[] = R"(precision mediump float;
318 varying vec4 testVarying;
319 void main()
320 {
321     gl_FragColor = testVarying;
322 })";
323 
324 // Tests that using a buffered attribute, then disabling it and using current value, works.
TEST_P(StateChangeTest,DisablingBufferedVertexAttribute)325 TEST_P(StateChangeTest, DisablingBufferedVertexAttribute)
326 {
327     ANGLE_GL_PROGRAM(program, kSimpleAttributeVS, kSimpleAttributeFS);
328     glUseProgram(program);
329     GLint attribLoc   = glGetAttribLocation(program, "testAttrib");
330     GLint positionLoc = glGetAttribLocation(program, "position");
331     ASSERT_NE(-1, attribLoc);
332     ASSERT_NE(-1, positionLoc);
333 
334     // Set up the buffered attribute.
335     std::vector<GLColor> red(6, GLColor::red);
336     GLBuffer attribBuffer;
337     glBindBuffer(GL_ARRAY_BUFFER, attribBuffer);
338     glBufferData(GL_ARRAY_BUFFER, red.size() * sizeof(GLColor), red.data(), GL_STATIC_DRAW);
339     glEnableVertexAttribArray(attribLoc);
340     glVertexAttribPointer(attribLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, nullptr);
341 
342     // Also set the current value to green now.
343     glVertexAttrib4f(attribLoc, 0.0f, 1.0f, 0.0f, 1.0f);
344 
345     // Set up the position attribute as well.
346     setupQuadVertexBuffer(0.5f, 1.0f);
347     glEnableVertexAttribArray(positionLoc);
348     glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
349 
350     // Draw with the buffered attribute. Verify red.
351     glDrawArrays(GL_TRIANGLES, 0, 6);
352     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
353 
354     // Draw with the disabled "current value attribute". Verify green.
355     glDisableVertexAttribArray(attribLoc);
356     glDrawArrays(GL_TRIANGLES, 0, 6);
357     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
358 
359     // Verify setting buffer data on the disabled buffer doesn't change anything.
360     std::vector<GLColor> blue(128, GLColor::blue);
361     glBindBuffer(GL_ARRAY_BUFFER, attribBuffer);
362     glBufferData(GL_ARRAY_BUFFER, blue.size() * sizeof(GLColor), blue.data(), GL_STATIC_DRAW);
363     glDrawArrays(GL_TRIANGLES, 0, 6);
364     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
365 }
366 
367 // Tests that setting value for a subset of default attributes doesn't affect others.
TEST_P(StateChangeTest,SetCurrentAttribute)368 TEST_P(StateChangeTest, SetCurrentAttribute)
369 {
370     constexpr char kVS[] = R"(attribute vec4 position;
371 attribute mat4 testAttrib;  // Note that this generates 4 attributes
372 varying vec4 testVarying;
373 void main (void)
374 {
375     gl_Position = position;
376 
377     testVarying = position.y < 0.0 ?
378                     position.x < 0.0 ? testAttrib[0] : testAttrib[1] :
379                     position.x < 0.0 ? testAttrib[2] : testAttrib[3];
380 })";
381 
382     ANGLE_GL_PROGRAM(program, kVS, kSimpleAttributeFS);
383     glUseProgram(program);
384     GLint attribLoc   = glGetAttribLocation(program, "testAttrib");
385     GLint positionLoc = glGetAttribLocation(program, "position");
386     ASSERT_NE(-1, attribLoc);
387     ASSERT_NE(-1, positionLoc);
388 
389     // Set the current value of two of the test attributes, while leaving the other two as default.
390     glVertexAttrib4f(attribLoc + 1, 0.0f, 1.0f, 0.0f, 1.0f);
391     glVertexAttrib4f(attribLoc + 2, 0.0f, 0.0f, 1.0f, 1.0f);
392 
393     // Set up the position attribute.
394     setupQuadVertexBuffer(0.5f, 1.0f);
395     glEnableVertexAttribArray(positionLoc);
396     glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
397 
398     // Draw and verify the four section in the output:
399     //
400     //  +---------------+
401     //  | Black | Green |
402     //  +-------+-------+
403     //  | Blue  | Black |
404     //  +---------------+
405     //
406     glDrawArrays(GL_TRIANGLES, 0, 6);
407 
408     const int w                            = getWindowWidth();
409     const int h                            = getWindowHeight();
410     constexpr unsigned int kPixelTolerance = 5u;
411     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::black, kPixelTolerance);
412     EXPECT_PIXEL_COLOR_NEAR(w - 1, 0, GLColor::green, kPixelTolerance);
413     EXPECT_PIXEL_COLOR_NEAR(0, h - 1, GLColor::blue, kPixelTolerance);
414     EXPECT_PIXEL_COLOR_NEAR(w - 1, h - 1, GLColor::black, kPixelTolerance);
415 }
416 
417 // Tests that drawing with transform feedback paused, then lines without transform feedback works
418 // without Vulkan validation errors.
TEST_P(StateChangeTestES3,DrawPausedXfbThenNonXfbLines)419 TEST_P(StateChangeTestES3, DrawPausedXfbThenNonXfbLines)
420 {
421     // glTransformFeedbackVaryings for program2 returns GL_INVALID_OPERATION on both Linux and
422     // windows.  http://anglebug.com/4265
423     ANGLE_SKIP_TEST_IF(IsIntel() && IsOpenGL());
424     // http://anglebug.com/5388
425     ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsDesktopOpenGL());
426 
427     std::vector<std::string> tfVaryings = {"gl_Position"};
428     ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(program1, essl1_shaders::vs::Simple(),
429                                         essl1_shaders::fs::Blue(), tfVaryings, GL_SEPARATE_ATTRIBS);
430 
431     GLBuffer xfbBuffer;
432     glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfbBuffer);
433     glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 6 * sizeof(float[4]), nullptr, GL_STATIC_DRAW);
434 
435     GLTransformFeedback xfb;
436     glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, xfb);
437     glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfbBuffer);
438 
439     glUseProgram(program1);
440     glBeginTransformFeedback(GL_TRIANGLES);
441     glPauseTransformFeedback();
442     glDrawArrays(GL_TRIANGLES, 0, 6);
443 
444     ANGLE_GL_PROGRAM(program2, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
445     glUseProgram(program2);
446     glDrawArrays(GL_LINES, 0, 6);
447     glEndTransformFeedback();
448 
449     ASSERT_GL_NO_ERROR();
450 }
451 
452 // Tests that vertex attribute value is preserved across context switches.
TEST_P(StateChangeTest,MultiContextVertexAttribute)453 TEST_P(StateChangeTest, MultiContextVertexAttribute)
454 {
455     EGLWindow *window   = getEGLWindow();
456     EGLDisplay display  = window->getDisplay();
457     EGLConfig config    = window->getConfig();
458     EGLSurface surface  = window->getSurface();
459     EGLContext context1 = window->getContext();
460 
461     // Set up program in primary context
462     ANGLE_GL_PROGRAM(program1, kSimpleAttributeVS, kSimpleAttributeFS);
463     glUseProgram(program1);
464     GLint attribLoc   = glGetAttribLocation(program1, "testAttrib");
465     GLint positionLoc = glGetAttribLocation(program1, "position");
466     ASSERT_NE(-1, attribLoc);
467     ASSERT_NE(-1, positionLoc);
468 
469     // Set up the position attribute in primary context
470     setupQuadVertexBuffer(0.5f, 1.0f);
471     glEnableVertexAttribArray(positionLoc);
472     glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
473 
474     // Set primary context attribute to green and draw quad
475     glVertexAttrib4f(attribLoc, 0.0f, 1.0f, 0.0f, 1.0f);
476     glDrawArrays(GL_TRIANGLES, 0, 6);
477     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
478 
479     // Set up and switch to secondary context
480     EGLint contextAttributes[] = {
481         EGL_CONTEXT_MAJOR_VERSION_KHR,
482         GetParam().majorVersion,
483         EGL_CONTEXT_MINOR_VERSION_KHR,
484         GetParam().minorVersion,
485         EGL_NONE,
486     };
487     EGLContext context2 = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttributes);
488     ASSERT_NE(context2, EGL_NO_CONTEXT);
489     eglMakeCurrent(display, surface, surface, context2);
490 
491     // Set up program in secondary context
492     ANGLE_GL_PROGRAM(program2, kSimpleAttributeVS, kSimpleAttributeFS);
493     glUseProgram(program2);
494     ASSERT_EQ(attribLoc, glGetAttribLocation(program2, "testAttrib"));
495     ASSERT_EQ(positionLoc, glGetAttribLocation(program2, "position"));
496 
497     // Set up the position attribute in secondary context
498     setupQuadVertexBuffer(0.5f, 1.0f);
499     glEnableVertexAttribArray(positionLoc);
500     glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
501 
502     // attribLoc current value should be default - (0,0,0,1)
503     glDrawArrays(GL_TRIANGLES, 0, 6);
504     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
505 
506     // Restore primary context
507     eglMakeCurrent(display, surface, surface, context1);
508     // ReadPixels to ensure context is switched
509     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
510 
511     // Switch to secondary context second time
512     eglMakeCurrent(display, surface, surface, context2);
513     // Check that it still draws black
514     glDrawArrays(GL_TRIANGLES, 0, 6);
515     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
516 
517     // Restore primary context second time
518     eglMakeCurrent(display, surface, surface, context1);
519     // Check if it still draws green
520     glDrawArrays(GL_TRIANGLES, 0, 6);
521     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
522 
523     // Clean up
524     eglDestroyContext(display, context2);
525 }
526 
527 // Ensure that CopyTexSubImage3D syncs framebuffer changes.
TEST_P(StateChangeTestES3,CopyTexSubImage3DSync)528 TEST_P(StateChangeTestES3, CopyTexSubImage3DSync)
529 {
530     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
531 
532     // Init first texture to red
533     glBindTexture(GL_TEXTURE_3D, mTextures[0]);
534     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 16, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
535     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTextures[0], 0, 0);
536     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
537     glClear(GL_COLOR_BUFFER_BIT);
538     EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
539 
540     // Init second texture to green
541     glBindTexture(GL_TEXTURE_3D, mTextures[1]);
542     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, 16, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
543     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTextures[1], 0, 0);
544     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
545     glClear(GL_COLOR_BUFFER_BIT);
546     EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
547 
548     // Copy in the red texture to the green one.
549     // CopyTexImage should sync the framebuffer attachment change.
550     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTextures[0], 0, 0);
551     glCopyTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 0, 0, 16, 16);
552     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTextures[1], 0, 0);
553     EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
554 
555     ASSERT_GL_NO_ERROR();
556 }
557 
558 // Ensure that BlitFramebuffer syncs framebuffer changes.
TEST_P(StateChangeTestES3,BlitFramebufferSync)559 TEST_P(StateChangeTestES3, BlitFramebufferSync)
560 {
561     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
562 
563     // Init first texture to red
564     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
565     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
566     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0);
567     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
568     glClear(GL_COLOR_BUFFER_BIT);
569     EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
570 
571     // Init second texture to green
572     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
573     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
574     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[1], 0);
575     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
576     glClear(GL_COLOR_BUFFER_BIT);
577     EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
578 
579     // Change to the red textures and blit.
580     // BlitFramebuffer should sync the framebuffer attachment change.
581     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
582     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0],
583                            0);
584     glBlitFramebuffer(0, 0, 16, 16, 0, 0, 16, 16, GL_COLOR_BUFFER_BIT, GL_NEAREST);
585     glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
586     EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
587 
588     ASSERT_GL_NO_ERROR();
589 }
590 
591 // Ensure that ReadBuffer and DrawBuffers sync framebuffer changes.
TEST_P(StateChangeTestES3,ReadBufferAndDrawBuffersSync)592 TEST_P(StateChangeTestES3, ReadBufferAndDrawBuffersSync)
593 {
594     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
595 
596     // Initialize two FBO attachments
597     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
598     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
599     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0);
600     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
601     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
602     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, mTextures[1], 0);
603 
604     // Clear first attachment to red
605     GLenum bufs1[] = {GL_COLOR_ATTACHMENT0, GL_NONE};
606     glDrawBuffers(2, bufs1);
607     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
608     glClear(GL_COLOR_BUFFER_BIT);
609 
610     // Clear second texture to green
611     GLenum bufs2[] = {GL_NONE, GL_COLOR_ATTACHMENT1};
612     glDrawBuffers(2, bufs2);
613     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
614     glClear(GL_COLOR_BUFFER_BIT);
615 
616     // Verify first attachment is red and second is green
617     glReadBuffer(GL_COLOR_ATTACHMENT1);
618     EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
619 
620     glReadBuffer(GL_COLOR_ATTACHMENT0);
621     EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
622 
623     ASSERT_GL_NO_ERROR();
624 }
625 
626 // Tests calling invalidate on incomplete framebuffers after switching attachments.
627 // Adapted partially from WebGL 2 test "renderbuffers/invalidate-framebuffer"
TEST_P(StateChangeTestES3,IncompleteRenderbufferAttachmentInvalidateSync)628 TEST_P(StateChangeTestES3, IncompleteRenderbufferAttachmentInvalidateSync)
629 {
630     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
631     glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
632     GLint samples = 0;
633     glGetInternalformativ(GL_RENDERBUFFER, GL_RGBA8, GL_SAMPLES, 1, &samples);
634     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mRenderbuffer);
635     ASSERT_GL_NO_ERROR();
636 
637     // invalidate the framebuffer when the attachment is incomplete: no storage allocated to the
638     // attached renderbuffer
639     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT,
640                      glCheckFramebufferStatus(GL_FRAMEBUFFER));
641     GLenum attachments1[] = {GL_COLOR_ATTACHMENT0};
642     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments1);
643     ASSERT_GL_NO_ERROR();
644 
645     glRenderbufferStorageMultisample(GL_RENDERBUFFER, static_cast<GLsizei>(samples), GL_RGBA8,
646                                      getWindowWidth(), getWindowHeight());
647     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
648     glClear(GL_COLOR_BUFFER_BIT);
649     ASSERT_GL_NO_ERROR();
650 
651     GLRenderbuffer renderbuf;
652 
653     glBindRenderbuffer(GL_RENDERBUFFER, renderbuf.get());
654     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
655                               renderbuf.get());
656     ASSERT_GL_NO_ERROR();
657 
658     // invalidate the framebuffer when the attachment is incomplete: no storage allocated to the
659     // attached renderbuffer
660     // Note: the bug will only repro *without* a call to checkStatus before the invalidate.
661     GLenum attachments2[] = {GL_DEPTH_ATTACHMENT};
662     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments2);
663 
664     glRenderbufferStorageMultisample(GL_RENDERBUFFER, static_cast<GLsizei>(samples),
665                                      GL_DEPTH_COMPONENT16, getWindowWidth(), getWindowHeight());
666     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
667     glClear(GL_DEPTH_BUFFER_BIT);
668     ASSERT_GL_NO_ERROR();
669 }
670 
671 class StateChangeRenderTest : public StateChangeTest
672 {
673   protected:
StateChangeRenderTest()674     StateChangeRenderTest() : mProgram(0), mRenderbuffer(0) {}
675 
testSetUp()676     void testSetUp() override
677     {
678         StateChangeTest::testSetUp();
679 
680         constexpr char kVS[] =
681             "attribute vec2 position;\n"
682             "void main() {\n"
683             "    gl_Position = vec4(position, 0, 1);\n"
684             "}";
685         constexpr char kFS[] =
686             "uniform highp vec4 uniformColor;\n"
687             "void main() {\n"
688             "    gl_FragColor = uniformColor;\n"
689             "}";
690 
691         mProgram = CompileProgram(kVS, kFS);
692         ASSERT_NE(0u, mProgram);
693 
694         glGenRenderbuffers(1, &mRenderbuffer);
695     }
696 
testTearDown()697     void testTearDown() override
698     {
699         glDeleteProgram(mProgram);
700         glDeleteRenderbuffers(1, &mRenderbuffer);
701 
702         StateChangeTest::testTearDown();
703     }
704 
setUniformColor(const GLColor & color)705     void setUniformColor(const GLColor &color)
706     {
707         glUseProgram(mProgram);
708         const Vector4 &normalizedColor = color.toNormalizedVector();
709         GLint uniformLocation          = glGetUniformLocation(mProgram, "uniformColor");
710         ASSERT_NE(-1, uniformLocation);
711         glUniform4fv(uniformLocation, 1, normalizedColor.data());
712     }
713 
714     GLuint mProgram;
715     GLuint mRenderbuffer;
716 };
717 
718 // Test that re-creating a currently attached texture works as expected.
TEST_P(StateChangeRenderTest,RecreateTexture)719 TEST_P(StateChangeRenderTest, RecreateTexture)
720 {
721     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
722 
723     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
724     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
725     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0);
726 
727     // Explictly check FBO status sync in some versions of ANGLE no_error skips FBO checks.
728     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
729 
730     // Draw with red to the FBO.
731     GLColor red(255, 0, 0, 255);
732     setUniformColor(red);
733     drawQuad(mProgram, "position", 0.5f);
734     EXPECT_PIXEL_COLOR_EQ(0, 0, red);
735 
736     // Recreate the texture with green.
737     GLColor green(0, 255, 0, 255);
738     std::vector<GLColor> greenPixels(32 * 32, green);
739     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE,
740                  greenPixels.data());
741     EXPECT_PIXEL_COLOR_EQ(0, 0, green);
742 
743     // Explictly check FBO status sync in some versions of ANGLE no_error skips FBO checks.
744     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
745 
746     // Verify drawing blue gives blue. This covers the FBO sync with D3D dirty bits.
747     GLColor blue(0, 0, 255, 255);
748     setUniformColor(blue);
749     drawQuad(mProgram, "position", 0.5f);
750     EXPECT_PIXEL_COLOR_EQ(0, 0, blue);
751 
752     EXPECT_GL_NO_ERROR();
753 }
754 
755 // Test that re-creating a currently attached renderbuffer works as expected.
TEST_P(StateChangeRenderTest,RecreateRenderbuffer)756 TEST_P(StateChangeRenderTest, RecreateRenderbuffer)
757 {
758     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
759 
760     glBindRenderbuffer(GL_RENDERBUFFER, mRenderbuffer);
761     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 16, 16);
762     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mRenderbuffer);
763 
764     // Explictly check FBO status sync in some versions of ANGLE no_error skips FBO checks.
765     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
766 
767     // Draw with red to the FBO.
768     setUniformColor(GLColor::red);
769     drawQuad(mProgram, "position", 0.5f);
770     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
771 
772     // Recreate the renderbuffer and clear to green.
773     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 32, 32);
774     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
775     glClear(GL_COLOR_BUFFER_BIT);
776     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
777 
778     // Explictly check FBO status sync in some versions of ANGLE no_error skips FBO checks.
779     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
780 
781     // Verify drawing blue gives blue. This covers the FBO sync with D3D dirty bits.
782     setUniformColor(GLColor::blue);
783     drawQuad(mProgram, "position", 0.5f);
784     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
785 
786     EXPECT_GL_NO_ERROR();
787 }
788 
789 // Test that recreating a texture with GenerateMipmaps signals the FBO is dirty.
TEST_P(StateChangeRenderTest,GenerateMipmap)790 TEST_P(StateChangeRenderTest, GenerateMipmap)
791 {
792     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
793 
794     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
795     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
796     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
797     glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
798     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0);
799 
800     // Explictly check FBO status sync in some versions of ANGLE no_error skips FBO checks.
801     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
802 
803     // Draw once to set the RenderTarget in D3D11
804     GLColor red(255, 0, 0, 255);
805     setUniformColor(red);
806     drawQuad(mProgram, "position", 0.5f);
807     EXPECT_PIXEL_COLOR_EQ(0, 0, red);
808 
809     // This may trigger the texture to be re-created internally.
810     glGenerateMipmap(GL_TEXTURE_2D);
811 
812     // Explictly check FBO status sync in some versions of ANGLE no_error skips FBO checks.
813     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
814 
815     // Now ensure we don't have a stale render target.
816     GLColor blue(0, 0, 255, 255);
817     setUniformColor(blue);
818     drawQuad(mProgram, "position", 0.5f);
819     EXPECT_PIXEL_COLOR_EQ(0, 0, blue);
820 
821     EXPECT_GL_NO_ERROR();
822 }
823 
824 // Tests that gl_DepthRange syncs correctly after a change.
TEST_P(StateChangeRenderTest,DepthRangeUpdates)825 TEST_P(StateChangeRenderTest, DepthRangeUpdates)
826 {
827     constexpr char kFragCoordShader[] = R"(void main()
828 {
829     if (gl_DepthRange.near == 0.2)
830     {
831         gl_FragColor = vec4(1, 0, 0, 1);
832     }
833     else if (gl_DepthRange.near == 0.5)
834     {
835         gl_FragColor = vec4(0, 1, 0, 1);
836     }
837     else
838     {
839         gl_FragColor = vec4(0, 0, 1, 1);
840     }
841 })";
842 
843     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), kFragCoordShader);
844     glUseProgram(program);
845 
846     const auto &quadVertices = GetQuadVertices();
847 
848     ASSERT_EQ(0, glGetAttribLocation(program, essl1_shaders::PositionAttrib()));
849 
850     GLBuffer vertexBuffer;
851     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
852     glBufferData(GL_ARRAY_BUFFER, quadVertices.size() * sizeof(quadVertices[0]),
853                  quadVertices.data(), GL_STATIC_DRAW);
854     glVertexAttribPointer(0u, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
855     glEnableVertexAttribArray(0u);
856 
857     // First, clear.
858     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
859     glClear(GL_COLOR_BUFFER_BIT);
860 
861     // Draw to left half viewport with a first depth range.
862     glDepthRangef(0.2f, 1.0f);
863     glViewport(0, 0, getWindowWidth() / 2, getWindowHeight());
864     glDrawArrays(GL_TRIANGLES, 0, 6);
865     ASSERT_GL_NO_ERROR();
866 
867     // Draw to right half viewport with a second depth range.
868     glDepthRangef(0.5f, 1.0f);
869     glViewport(getWindowWidth() / 2, 0, getWindowWidth() / 2, getWindowHeight());
870     glDrawArrays(GL_TRIANGLES, 0, 6);
871     ASSERT_GL_NO_ERROR();
872 
873     // Verify left half of the framebuffer is red and right half is green.
874     EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth() / 2, getWindowHeight(), GLColor::red);
875     EXPECT_PIXEL_RECT_EQ(getWindowWidth() / 2, 0, getWindowWidth() / 2, getWindowHeight(),
876                          GLColor::green);
877 }
878 
879 class StateChangeRenderTestES3 : public StateChangeRenderTest
880 {};
881 
TEST_P(StateChangeRenderTestES3,InvalidateNonCurrentFramebuffer)882 TEST_P(StateChangeRenderTestES3, InvalidateNonCurrentFramebuffer)
883 {
884     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
885     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
886     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
887     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
888     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTextures[0], 0);
889     glBindTexture(GL_TEXTURE_2D, 0);
890     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
891     ASSERT_GL_NO_ERROR();
892 
893     // Draw with red to the FBO.
894     GLColor red(255, 0, 0, 255);
895     setUniformColor(red);
896     drawQuad(mProgram, "position", 0.5f);
897     EXPECT_PIXEL_COLOR_EQ(0, 0, red);
898 
899     // Go back to default framebuffer, draw green
900     glBindFramebuffer(GL_FRAMEBUFFER, 0);
901     GLColor green(0, 255, 0, 255);
902     setUniformColor(green);
903     drawQuad(mProgram, "position", 0.5f);
904     EXPECT_PIXEL_COLOR_EQ(0, 0, green);
905 
906     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
907 
908     // Invalidate color buffer of FBO
909     GLenum attachments1[] = {GL_COLOR_ATTACHMENT0};
910     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, attachments1);
911     ASSERT_GL_NO_ERROR();
912 
913     // Verify drawing blue gives blue.
914     GLColor blue(0, 0, 255, 255);
915     setUniformColor(blue);
916     drawQuad(mProgram, "position", 0.5f);
917     EXPECT_PIXEL_COLOR_EQ(0, 0, blue);
918 }
919 
920 // Tests that D3D11 dirty bit updates don't forget about BufferSubData attrib updates.
TEST_P(StateChangeTest,VertexBufferUpdatedAfterDraw)921 TEST_P(StateChangeTest, VertexBufferUpdatedAfterDraw)
922 {
923     constexpr char kVS[] =
924         "attribute vec2 position;\n"
925         "attribute vec4 color;\n"
926         "varying vec4 outcolor;\n"
927         "void main()\n"
928         "{\n"
929         "    gl_Position = vec4(position, 0, 1);\n"
930         "    outcolor = color;\n"
931         "}";
932     constexpr char kFS[] =
933         "varying mediump vec4 outcolor;\n"
934         "void main()\n"
935         "{\n"
936         "    gl_FragColor = outcolor;\n"
937         "}";
938 
939     ANGLE_GL_PROGRAM(program, kVS, kFS);
940     glUseProgram(program);
941 
942     GLint colorLoc = glGetAttribLocation(program, "color");
943     ASSERT_NE(-1, colorLoc);
944     GLint positionLoc = glGetAttribLocation(program, "position");
945     ASSERT_NE(-1, positionLoc);
946 
947     setupQuadVertexBuffer(0.5f, 1.0f);
948     glEnableVertexAttribArray(positionLoc);
949     glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
950 
951     GLBuffer colorBuf;
952     glBindBuffer(GL_ARRAY_BUFFER, colorBuf);
953     glVertexAttribPointer(colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, nullptr);
954     glEnableVertexAttribArray(colorLoc);
955 
956     // Fill with green.
957     std::vector<GLColor> colorData(6, GLColor::green);
958     glBufferData(GL_ARRAY_BUFFER, colorData.size() * sizeof(GLColor), colorData.data(),
959                  GL_STATIC_DRAW);
960 
961     // Draw, expect green.
962     glDrawArrays(GL_TRIANGLES, 0, 6);
963     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
964     ASSERT_GL_NO_ERROR();
965 
966     // Update buffer with red.
967     std::fill(colorData.begin(), colorData.end(), GLColor::red);
968     glBufferSubData(GL_ARRAY_BUFFER, 0, colorData.size() * sizeof(GLColor), colorData.data());
969 
970     // Draw, expect red.
971     glDrawArrays(GL_TRIANGLES, 0, 6);
972     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
973     ASSERT_GL_NO_ERROR();
974 }
975 
976 // Tests that drawing after flush without any state change works.
TEST_P(StateChangeTestES3,DrawAfterFlushWithNoStateChange)977 TEST_P(StateChangeTestES3, DrawAfterFlushWithNoStateChange)
978 {
979     // Draw (0.125, 0.25, 0.5, 0.5) once, using additive blend
980     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
981     glUseProgram(drawColor);
982 
983     GLint colorUniformLocation =
984         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
985     ASSERT_NE(colorUniformLocation, -1);
986 
987     GLint positionLocation = glGetAttribLocation(drawColor, essl1_shaders::PositionAttrib());
988     ASSERT_NE(-1, positionLocation);
989 
990     // Setup VAO
991     const auto &quadVertices = GetQuadVertices();
992 
993     GLBuffer vertexBuffer;
994     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
995     glBufferData(GL_ARRAY_BUFFER, sizeof(Vector3) * 6, quadVertices.data(), GL_STATIC_DRAW);
996 
997     GLVertexArray vertexArray;
998     glBindVertexArray(vertexArray);
999     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
1000     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
1001     glEnableVertexAttribArray(positionLocation);
1002     ASSERT_GL_NO_ERROR();
1003 
1004     // Clear and draw
1005     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
1006     glClear(GL_COLOR_BUFFER_BIT);
1007 
1008     glEnable(GL_BLEND);
1009     glBlendFunc(GL_ONE, GL_ONE);
1010 
1011     glUniform4f(colorUniformLocation, 0.125f, 0.25f, 0.5f, 0.5f);
1012     glDrawArrays(GL_TRIANGLES, 0, 6);
1013     ASSERT_GL_NO_ERROR();
1014 
1015     // Make sure the work is submitted.
1016     glFinish();
1017 
1018     // Draw again with no state change
1019     glDrawArrays(GL_TRIANGLES, 0, 6);
1020     ASSERT_GL_NO_ERROR();
1021 
1022     // Make sure the pixels have the correct colors.
1023     const int h = getWindowHeight() - 1;
1024     const int w = getWindowWidth() - 1;
1025     const GLColor kExpected(63, 127, 255, 255);
1026 
1027     EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpected, 1);
1028     EXPECT_PIXEL_COLOR_NEAR(w - 1, 0, kExpected, 1);
1029     EXPECT_PIXEL_COLOR_NEAR(0, h - 1, kExpected, 1);
1030     EXPECT_PIXEL_COLOR_NEAR(w - 1, h - 1, kExpected, 1);
1031 }
1032 
1033 // Test that switching VAOs keeps the disabled "current value" attributes up-to-date.
TEST_P(StateChangeTestES3,VertexArrayObjectAndDisabledAttributes)1034 TEST_P(StateChangeTestES3, VertexArrayObjectAndDisabledAttributes)
1035 {
1036     constexpr char kSingleVS[] = "attribute vec4 position; void main() { gl_Position = position; }";
1037     constexpr char kSingleFS[] = "void main() { gl_FragColor = vec4(1, 0, 0, 1); }";
1038     ANGLE_GL_PROGRAM(singleProgram, kSingleVS, kSingleFS);
1039 
1040     constexpr char kDualVS[] =
1041         "#version 300 es\n"
1042         "in vec4 position;\n"
1043         "in vec4 color;\n"
1044         "out vec4 varyColor;\n"
1045         "void main()\n"
1046         "{\n"
1047         "    gl_Position = position;\n"
1048         "    varyColor = color;\n"
1049         "}";
1050     constexpr char kDualFS[] =
1051         "#version 300 es\n"
1052         "precision mediump float;\n"
1053         "in vec4 varyColor;\n"
1054         "out vec4 colorOut;\n"
1055         "void main()\n"
1056         "{\n"
1057         "    colorOut = varyColor;\n"
1058         "}";
1059 
1060     ANGLE_GL_PROGRAM(dualProgram, kDualVS, kDualFS);
1061 
1062     // Force consistent attribute locations
1063     constexpr GLint positionLocation = 0;
1064     constexpr GLint colorLocation    = 1;
1065 
1066     glBindAttribLocation(singleProgram, positionLocation, "position");
1067     glBindAttribLocation(dualProgram, positionLocation, "position");
1068     glBindAttribLocation(dualProgram, colorLocation, "color");
1069 
1070     {
1071         glLinkProgram(singleProgram);
1072         GLint linkStatus;
1073         glGetProgramiv(singleProgram, GL_LINK_STATUS, &linkStatus);
1074         ASSERT_NE(linkStatus, 0);
1075     }
1076 
1077     {
1078         glLinkProgram(dualProgram);
1079         GLint linkStatus;
1080         glGetProgramiv(dualProgram, GL_LINK_STATUS, &linkStatus);
1081         ASSERT_NE(linkStatus, 0);
1082     }
1083 
1084     glUseProgram(singleProgram);
1085 
1086     // Initialize position vertex buffer.
1087     const auto &quadVertices = GetQuadVertices();
1088 
1089     GLBuffer vertexBuffer;
1090     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
1091     glBufferData(GL_ARRAY_BUFFER, sizeof(Vector3) * 6, quadVertices.data(), GL_STATIC_DRAW);
1092 
1093     // Initialize a VAO. Draw with single program.
1094     GLVertexArray vertexArray;
1095     glBindVertexArray(vertexArray);
1096     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
1097     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
1098     glEnableVertexAttribArray(positionLocation);
1099 
1100     // Should draw red.
1101     glDrawArrays(GL_TRIANGLES, 0, 6);
1102     ASSERT_GL_NO_ERROR();
1103     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
1104 
1105     // Draw with a green buffer attribute, without the VAO.
1106     glBindVertexArray(0);
1107     glUseProgram(dualProgram);
1108     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
1109     glEnableVertexAttribArray(positionLocation);
1110 
1111     std::vector<GLColor> greenColors(6, GLColor::green);
1112     GLBuffer greenBuffer;
1113     glBindBuffer(GL_ARRAY_BUFFER, greenBuffer);
1114     glBufferData(GL_ARRAY_BUFFER, sizeof(GLColor) * 6, greenColors.data(), GL_STATIC_DRAW);
1115 
1116     glVertexAttribPointer(colorLocation, 4, GL_UNSIGNED_BYTE, GL_FALSE, 4, nullptr);
1117     glEnableVertexAttribArray(colorLocation);
1118 
1119     glDrawArrays(GL_TRIANGLES, 0, 6);
1120     ASSERT_GL_NO_ERROR();
1121     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1122 
1123     // Re-bind VAO and try to draw with different program, without changing state.
1124     // Should draw black since current value is not initialized.
1125     glBindVertexArray(vertexArray);
1126     glDrawArrays(GL_TRIANGLES, 0, 6);
1127     ASSERT_GL_NO_ERROR();
1128     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
1129 }
1130 
1131 const char kSamplerMetadataVertexShader0[] = R"(#version 300 es
1132 precision mediump float;
1133 out vec4 color;
1134 uniform sampler2D texture;
1135 void main()
1136 {
1137     vec2 size = vec2(textureSize(texture, 0));
1138     color = size.x != 0.0 ? vec4(0.0, 1.0, 0.0, 1.0) : vec4(1.0, 0.0, 0.0, 0.0);
1139     vec2 pos = vec2(0.0);
1140     switch (gl_VertexID) {
1141         case 0: pos = vec2(-1.0, -1.0); break;
1142         case 1: pos = vec2(3.0, -1.0); break;
1143         case 2: pos = vec2(-1.0, 3.0); break;
1144     };
1145     gl_Position = vec4(pos, 0.0, 1.0);
1146 })";
1147 
1148 const char kSamplerMetadataVertexShader1[] = R"(#version 300 es
1149 precision mediump float;
1150 out vec4 color;
1151 uniform sampler2D texture1;
1152 uniform sampler2D texture2;
1153 void main()
1154 {
1155     vec2 size1 = vec2(textureSize(texture1, 0));
1156     vec2 size2 = vec2(textureSize(texture2, 0));
1157     color = size1.x * size2.x != 0.0 ? vec4(0.0, 1.0, 0.0, 1.0) : vec4(1.0, 0.0, 0.0, 0.0);
1158     vec2 pos = vec2(0.0);
1159     switch (gl_VertexID) {
1160         case 0: pos = vec2(-1.0, -1.0); break;
1161         case 1: pos = vec2(3.0, -1.0); break;
1162         case 2: pos = vec2(-1.0, 3.0); break;
1163     };
1164     gl_Position = vec4(pos, 0.0, 1.0);
1165 })";
1166 
1167 const char kSamplerMetadataFragmentShader[] = R"(#version 300 es
1168 precision mediump float;
1169 in vec4 color;
1170 out vec4 result;
1171 void main()
1172 {
1173     result = color;
1174 })";
1175 
1176 // Tests that changing an active program invalidates the sampler metadata properly.
TEST_P(StateChangeTestES3,SamplerMetadataUpdateOnSetProgram)1177 TEST_P(StateChangeTestES3, SamplerMetadataUpdateOnSetProgram)
1178 {
1179     // http://anglebug.com/4092
1180     ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());
1181     // TODO(anglebug.com/5491) Appears as though there's something wrong with textureSize on iOS
1182     // unrelated to switching programs.
1183     ANGLE_SKIP_TEST_IF(IsIOS() && IsOpenGLES());
1184     GLVertexArray vertexArray;
1185     glBindVertexArray(vertexArray);
1186 
1187     // Create a simple framebuffer.
1188     GLTexture texture1, texture2;
1189     glActiveTexture(GL_TEXTURE0);
1190     glBindTexture(GL_TEXTURE_2D, texture1);
1191     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1192     glActiveTexture(GL_TEXTURE1);
1193     glBindTexture(GL_TEXTURE_2D, texture2);
1194     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1195 
1196     // Create 2 shader programs differing only in the number of active samplers.
1197     ANGLE_GL_PROGRAM(program1, kSamplerMetadataVertexShader0, kSamplerMetadataFragmentShader);
1198     glUseProgram(program1);
1199     glUniform1i(glGetUniformLocation(program1, "texture"), 0);
1200     ANGLE_GL_PROGRAM(program2, kSamplerMetadataVertexShader1, kSamplerMetadataFragmentShader);
1201     glUseProgram(program2);
1202     glUniform1i(glGetUniformLocation(program2, "texture1"), 0);
1203     glUniform1i(glGetUniformLocation(program2, "texture2"), 0);
1204 
1205     // Draw a solid green color to the framebuffer.
1206     glUseProgram(program1);
1207     glDrawArrays(GL_TRIANGLES, 0, 3);
1208     // Test that our first program is good.
1209     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1210 
1211     // Bind a different program that uses more samplers.
1212     // Draw another quad that depends on the sampler metadata.
1213     glUseProgram(program2);
1214     glDrawArrays(GL_TRIANGLES, 0, 3);
1215     // Flush via ReadPixels and check that it's still green.
1216     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1217 
1218     ASSERT_GL_NO_ERROR();
1219 }
1220 
1221 // Tests that redefining Buffer storage syncs with the Transform Feedback object.
TEST_P(StateChangeTestES3,RedefineTransformFeedbackBuffer)1222 TEST_P(StateChangeTestES3, RedefineTransformFeedbackBuffer)
1223 {
1224     // Create the most simple program possible - simple a passthrough for a float attribute.
1225     constexpr char kVertexShader[] = R"(#version 300 es
1226 in float valueIn;
1227 out float valueOut;
1228 void main()
1229 {
1230     gl_Position = vec4(0, 0, 0, 0);
1231     valueOut = valueIn;
1232 })";
1233 
1234     constexpr char kFragmentShader[] = R"(#version 300 es
1235 out mediump float unused;
1236 void main()
1237 {
1238     unused = 1.0;
1239 })";
1240 
1241     std::vector<std::string> tfVaryings = {"valueOut"};
1242     ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(program, kVertexShader, kFragmentShader, tfVaryings,
1243                                         GL_SEPARATE_ATTRIBS);
1244     glUseProgram(program);
1245 
1246     GLint attribLoc = glGetAttribLocation(program, "valueIn");
1247     ASSERT_NE(-1, attribLoc);
1248 
1249     // Disable rasterization - we're not interested in the framebuffer.
1250     glEnable(GL_RASTERIZER_DISCARD);
1251 
1252     // Initialize a float vertex buffer with 1.0.
1253     std::vector<GLfloat> data1(16, 1.0);
1254     GLsizei size1 = static_cast<GLsizei>(sizeof(GLfloat) * data1.size());
1255 
1256     GLBuffer vertexBuffer;
1257     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
1258     glBufferData(GL_ARRAY_BUFFER, size1, data1.data(), GL_STATIC_DRAW);
1259     glVertexAttribPointer(attribLoc, 1, GL_FLOAT, GL_FALSE, 0, nullptr);
1260     glEnableVertexAttribArray(attribLoc);
1261 
1262     ASSERT_GL_NO_ERROR();
1263 
1264     // Initialize a same-sized XFB buffer.
1265     GLBuffer xfbBuffer;
1266     glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfbBuffer);
1267     glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, size1, nullptr, GL_STATIC_DRAW);
1268 
1269     // Draw with XFB enabled.
1270     GLTransformFeedback xfb;
1271     glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, xfb);
1272     glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfbBuffer);
1273 
1274     glBeginTransformFeedback(GL_POINTS);
1275     glDrawArrays(GL_POINTS, 0, 16);
1276     glEndTransformFeedback();
1277 
1278     ASSERT_GL_NO_ERROR();
1279 
1280     // Verify the XFB stage caught the 1.0 attribute values.
1281     void *mapped1     = glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, size1, GL_MAP_READ_BIT);
1282     GLfloat *asFloat1 = reinterpret_cast<GLfloat *>(mapped1);
1283     std::vector<GLfloat> actualData1(asFloat1, asFloat1 + data1.size());
1284     EXPECT_EQ(data1, actualData1);
1285     glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
1286 
1287     // Now, reinitialize the XFB buffer to a larger size, and draw with 2.0.
1288     std::vector<GLfloat> data2(128, 2.0);
1289     const GLsizei size2 = static_cast<GLsizei>(sizeof(GLfloat) * data2.size());
1290     glBufferData(GL_ARRAY_BUFFER, size2, data2.data(), GL_STATIC_DRAW);
1291     glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, size2, nullptr, GL_STATIC_DRAW);
1292 
1293     glBeginTransformFeedback(GL_POINTS);
1294     glDrawArrays(GL_POINTS, 0, 128);
1295     glEndTransformFeedback();
1296 
1297     ASSERT_GL_NO_ERROR();
1298 
1299     // Verify the XFB stage caught the 2.0 attribute values.
1300     void *mapped2     = glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, size2, GL_MAP_READ_BIT);
1301     GLfloat *asFloat2 = reinterpret_cast<GLfloat *>(mapped2);
1302     std::vector<GLfloat> actualData2(asFloat2, asFloat2 + data2.size());
1303     EXPECT_EQ(data2, actualData2);
1304     glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
1305 }
1306 
1307 // Variations:
1308 //
1309 // - bool: whether to use WebGL compatibility mode.
1310 using StateChangeTestWebGL2Params = std::tuple<angle::PlatformParameters, bool>;
1311 
StateChangeTestWebGL2Print(const::testing::TestParamInfo<StateChangeTestWebGL2Params> & paramsInfo)1312 std::string StateChangeTestWebGL2Print(
1313     const ::testing::TestParamInfo<StateChangeTestWebGL2Params> &paramsInfo)
1314 {
1315     const StateChangeTestWebGL2Params &params = paramsInfo.param;
1316     std::ostringstream out;
1317 
1318     out << std::get<0>(params);
1319 
1320     if (std::get<1>(params))
1321     {
1322         out << "__WebGLCompatibility";
1323     }
1324 
1325     return out.str();
1326 }
1327 
1328 // State change test verifying both ES3 and WebGL2 specific behaviors.
1329 // Test is parameterized to allow execution with and without WebGL validation.
1330 // Note that this can not inherit from StateChangeTest due to the need to use ANGLETestWithParam.
1331 class StateChangeTestWebGL2 : public ANGLETest<StateChangeTestWebGL2Params>
1332 {
1333   protected:
StateChangeTestWebGL2()1334     StateChangeTestWebGL2()
1335     {
1336         setWindowWidth(kWidth);
1337         setWindowHeight(kHeight);
1338         setConfigRedBits(8);
1339         setConfigGreenBits(8);
1340         setConfigBlueBits(8);
1341         setConfigAlphaBits(8);
1342         if (testing::get<1>(GetParam()))
1343             setWebGLCompatibilityEnabled(true);
1344     }
1345 
1346     struct TestResources
1347     {
1348         GLTexture colorTexture;
1349         GLFramebuffer framebuffer;
1350     };
1351 
setupResources(TestResources & resources)1352     void setupResources(TestResources &resources)
1353     {
1354         glBindTexture(GL_TEXTURE_2D, resources.colorTexture);
1355         glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kWidth, kHeight);
1356         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1357         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1358         EXPECT_GL_NO_ERROR();
1359 
1360         glBindFramebuffer(GL_FRAMEBUFFER, resources.framebuffer);
1361         EXPECT_GL_NO_ERROR();
1362         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
1363                                resources.colorTexture, 0);
1364         EXPECT_GL_NO_ERROR();
1365     }
1366 
1367     // Use a larger window/framebuffer size than 1x1 (though not much larger) to
1368     // increase the chances that random garbage will appear.
1369     static constexpr GLsizei kWidth  = 4;
1370     static constexpr GLsizei kHeight = 4;
1371 };
1372 
1373 // Note: tested multiple other combinations:
1374 //
1375 // - Clearing/drawing to the framebuffer after invalidating, without using a
1376 //   secondary FBO
1377 // - Clearing the framebuffer after invalidating, using a secondary FBO
1378 // - Invalidating after clearing/drawing to the FBO, to verify WebGL's behavior
1379 //   that after invalidation, the framebuffer is either unmodified, or cleared
1380 //   to transparent black
1381 //
1382 // This combination, drawing after invalidating plus copying from the drawn-to
1383 // texture, was the only one which provoked the original bug in the Metal
1384 // backend with the following command line arguments:
1385 //
1386 // MTL_DEBUG_LAYER=1 MTL_DEBUG_LAYER_VALIDATE_LOAD_ACTIONS=1 \
1387 //    MTL_DEBUG_LAYER_VALIDATE_STORE_ACTIONS=1 \
1388 //    MTL_DEBUG_LAYER_VALIDATE_UNRETAINED_RESOURCES=4 \
1389 //    angle_end2end_tests ...
1390 //
1391 // See anglebug.com/6923.
1392 
TEST_P(StateChangeTestWebGL2,InvalidateThenDrawFBO)1393 TEST_P(StateChangeTestWebGL2, InvalidateThenDrawFBO)
1394 {
1395     GLint origFramebuffer = 0;
1396     glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &origFramebuffer);
1397 
1398     TestResources resources;
1399     setupResources(resources);
1400 
1401     ANGLE_GL_PROGRAM(drawGreen, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());
1402 
1403     const GLenum attachment = GL_COLOR_ATTACHMENT0;
1404 
1405     glBindFramebuffer(GL_FRAMEBUFFER, resources.framebuffer);
1406     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1407 
1408     // Clear to red to start.
1409     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
1410     glClear(GL_COLOR_BUFFER_BIT);
1411 
1412     // Invalidate framebuffer.
1413     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, &attachment);
1414     EXPECT_GL_NO_ERROR();
1415 
1416     // Draw green.
1417     // Important to use a vertex buffer because WebGL doesn't support client-side arrays.
1418     constexpr bool useVertexBuffer = true;
1419     drawQuad(drawGreen.get(), essl3_shaders::PositionAttrib(), 0.5f, 1.0f, useVertexBuffer);
1420     EXPECT_GL_NO_ERROR();
1421 
1422     // Bind original framebuffer.
1423     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, origFramebuffer);
1424     glBindFramebuffer(GL_READ_FRAMEBUFFER, resources.framebuffer);
1425     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
1426     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
1427     EXPECT_GL_NO_ERROR();
1428 
1429     // Blit from user's framebuffer to the window.
1430     //
1431     // This step is crucial to catch bugs in the Metal backend's use of no-op load/store actions.
1432     glBlitFramebuffer(0, 0, kWidth, kHeight, 0, 0, kWidth, kHeight, GL_COLOR_BUFFER_BIT,
1433                       GL_NEAREST);
1434     EXPECT_GL_NO_ERROR();
1435 
1436     // Verify results.
1437     glBindFramebuffer(GL_READ_FRAMEBUFFER, origFramebuffer);
1438     EXPECT_GL_NO_ERROR();
1439     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
1440 }
1441 
1442 // Simple state change tests for line loop drawing. There is some very specific handling of line
1443 // line loops in Vulkan and we need to test switching between drawElements and drawArrays calls to
1444 // validate every edge cases.
1445 class LineLoopStateChangeTest : public StateChangeTest
1446 {
1447   protected:
LineLoopStateChangeTest()1448     LineLoopStateChangeTest()
1449     {
1450         setWindowWidth(32);
1451         setWindowHeight(32);
1452         setConfigRedBits(8);
1453         setConfigGreenBits(8);
1454         setConfigBlueBits(8);
1455         setConfigAlphaBits(8);
1456     }
1457 
validateSquareAndHourglass() const1458     void validateSquareAndHourglass() const
1459     {
1460         ASSERT_GL_NO_ERROR();
1461 
1462         int quarterWidth  = getWindowWidth() / 4;
1463         int quarterHeight = getWindowHeight() / 4;
1464 
1465         // Bottom left
1466         EXPECT_PIXEL_COLOR_EQ(quarterWidth, quarterHeight, GLColor::blue);
1467 
1468         // Top left
1469         EXPECT_PIXEL_COLOR_EQ(quarterWidth, (quarterHeight * 3), GLColor::blue);
1470 
1471         // Top right
1472         // The last pixel isn't filled on a line loop so we check the pixel right before.
1473         EXPECT_PIXEL_COLOR_EQ((quarterWidth * 3), (quarterHeight * 3) - 1, GLColor::blue);
1474 
1475         // dead center to validate the hourglass.
1476         EXPECT_PIXEL_COLOR_EQ((quarterWidth * 2), quarterHeight * 2, GLColor::blue);
1477 
1478         // Verify line is closed between the 2 last vertices
1479         EXPECT_PIXEL_COLOR_EQ((quarterWidth * 2), quarterHeight, GLColor::blue);
1480     }
1481 };
1482 
1483 // Draw an hourglass with a drawElements call followed by a square with drawArrays.
TEST_P(LineLoopStateChangeTest,DrawElementsThenDrawArrays)1484 TEST_P(LineLoopStateChangeTest, DrawElementsThenDrawArrays)
1485 {
1486     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
1487     glUseProgram(program);
1488 
1489     // We expect to draw a square with these 4 vertices with a drawArray call.
1490     std::vector<Vector3> vertices;
1491     CreatePixelCenterWindowCoords({{8, 8}, {8, 24}, {24, 24}, {24, 8}}, getWindowWidth(),
1492                                   getWindowHeight(), &vertices);
1493 
1494     // If we use these indices to draw however, we should be drawing an hourglass.
1495     auto indices = std::vector<GLushort>{0, 2, 1, 3};
1496 
1497     GLint mPositionLocation = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
1498     ASSERT_NE(-1, mPositionLocation);
1499 
1500     GLBuffer vertexBuffer;
1501     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
1502     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
1503                  GL_STATIC_DRAW);
1504 
1505     GLBuffer indexBuffer;
1506     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
1507     glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLushort), &indices[0],
1508                  GL_STATIC_DRAW);
1509 
1510     glVertexAttribPointer(mPositionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
1511     glEnableVertexAttribArray(mPositionLocation);
1512     glClear(GL_COLOR_BUFFER_BIT);
1513     glDrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, nullptr);  // hourglass
1514     glDrawArrays(GL_LINE_LOOP, 0, 4);                             // square
1515     glDisableVertexAttribArray(mPositionLocation);
1516 
1517     validateSquareAndHourglass();
1518 }
1519 
1520 // Draw line loop using a drawArrays followed by an hourglass with drawElements.
TEST_P(LineLoopStateChangeTest,DrawArraysThenDrawElements)1521 TEST_P(LineLoopStateChangeTest, DrawArraysThenDrawElements)
1522 {
1523     // http://anglebug.com/2856: Seems to fail on older drivers and pass on newer.
1524     // Tested failing on 18.3.3 and passing on 18.9.2.
1525     ANGLE_SKIP_TEST_IF(IsAMD() && IsVulkan() && IsWindows());
1526 
1527     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
1528     glUseProgram(program);
1529 
1530     // We expect to draw a square with these 4 vertices with a drawArray call.
1531     std::vector<Vector3> vertices;
1532     CreatePixelCenterWindowCoords({{8, 8}, {8, 24}, {24, 24}, {24, 8}}, getWindowWidth(),
1533                                   getWindowHeight(), &vertices);
1534 
1535     // If we use these indices to draw however, we should be drawing an hourglass.
1536     auto indices = std::vector<GLushort>{0, 2, 1, 3};
1537 
1538     GLint mPositionLocation = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
1539     ASSERT_NE(-1, mPositionLocation);
1540 
1541     GLBuffer vertexBuffer;
1542     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
1543     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
1544                  GL_STATIC_DRAW);
1545 
1546     GLBuffer indexBuffer;
1547     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
1548     glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLushort), &indices[0],
1549                  GL_STATIC_DRAW);
1550 
1551     glVertexAttribPointer(mPositionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
1552     glEnableVertexAttribArray(mPositionLocation);
1553     glClear(GL_COLOR_BUFFER_BIT);
1554     glDrawArrays(GL_LINE_LOOP, 0, 4);                             // square
1555     glDrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_SHORT, nullptr);  // hourglass
1556     glDisableVertexAttribArray(mPositionLocation);
1557 
1558     validateSquareAndHourglass();
1559 }
1560 
1561 // Draw a triangle with a drawElements call and a non-zero offset and draw the same
1562 // triangle with the same offset again followed by a line loop with drawElements.
TEST_P(LineLoopStateChangeTest,DrawElementsThenDrawElements)1563 TEST_P(LineLoopStateChangeTest, DrawElementsThenDrawElements)
1564 {
1565     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
1566 
1567     glUseProgram(program);
1568 
1569     // Background Red color
1570     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
1571     glClear(GL_COLOR_BUFFER_BIT);
1572 
1573     // We expect to draw a triangle with the last three points on the bottom right,
1574     // draw with LineLoop, and then draw a triangle with the same non-zero offset.
1575     auto vertices = std::vector<Vector3>{
1576         {-1.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, {1.0f, -1.0f, 0.0f}, {-1.0f, -1.0f, 0.0f}};
1577 
1578     auto indices = std::vector<GLushort>{0, 1, 2, 1, 2, 3};
1579 
1580     GLint positionLocation = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
1581     ASSERT_NE(-1, positionLocation);
1582 
1583     GLBuffer indexBuffer;
1584     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
1585     glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLushort), &indices[0],
1586                  GL_STATIC_DRAW);
1587 
1588     GLBuffer vertexBuffer;
1589     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
1590     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
1591                  GL_STATIC_DRAW);
1592 
1593     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
1594     glEnableVertexAttribArray(positionLocation);
1595 
1596     // Draw a triangle with a non-zero offset on the bottom right.
1597     glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, (void *)(3 * sizeof(GLushort)));
1598 
1599     // Draw with LineLoop.
1600     glDrawElements(GL_LINE_LOOP, 3, GL_UNSIGNED_SHORT, nullptr);
1601 
1602     // Draw the triangle again with the same offset.
1603     glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, (void *)(3 * sizeof(GLushort)));
1604 
1605     glDisableVertexAttribArray(positionLocation);
1606 
1607     ASSERT_GL_NO_ERROR();
1608 
1609     int quarterWidth  = getWindowWidth() / 4;
1610     int quarterHeight = getWindowHeight() / 4;
1611 
1612     // Validate the top left point's color.
1613     EXPECT_PIXEL_COLOR_EQ(0, getWindowHeight() - 1, GLColor::blue);
1614 
1615     // Validate the triangle is drawn on the bottom right.
1616     EXPECT_PIXEL_COLOR_EQ(quarterWidth * 2, quarterHeight, GLColor::blue);
1617 
1618     // Validate the triangle is NOT on the top left part.
1619     EXPECT_PIXEL_COLOR_EQ(quarterWidth * 2, quarterHeight * 3, GLColor::red);
1620     EXPECT_PIXEL_COLOR_EQ(quarterWidth, quarterHeight * 2, GLColor::red);
1621 }
1622 
1623 // Simple state change tests, primarily focused on basic object lifetime and dependency management
1624 // with back-ends that don't support that automatically (i.e. Vulkan).
1625 class SimpleStateChangeTest : public ANGLETest<>
1626 {
1627   protected:
1628     static constexpr int kWindowSize = 64;
1629 
SimpleStateChangeTest()1630     SimpleStateChangeTest()
1631     {
1632         setWindowWidth(kWindowSize);
1633         setWindowHeight(kWindowSize);
1634         setConfigRedBits(8);
1635         setConfigGreenBits(8);
1636         setConfigBlueBits(8);
1637         setConfigAlphaBits(8);
1638     }
1639 
1640     void simpleDrawWithBuffer(GLBuffer *buffer);
1641     void simpleDrawWithColor(const GLColor &color);
1642 
1643     using UpdateFunc = std::function<void(GLenum, GLTexture *, GLint, GLint, const GLColor &)>;
1644     void updateTextureBoundToFramebufferHelper(UpdateFunc updateFunc);
1645     void bindTextureToFbo(GLFramebuffer &fbo, GLTexture &texture);
1646     void drawToFboWithCulling(const GLenum frontFace, bool earlyFrontFaceDirty);
1647 };
1648 
1649 class SimpleStateChangeTestES3 : public SimpleStateChangeTest
1650 {
1651   protected:
blendAndVerifyColor(const GLColor32F blendColor,const GLColor expectedColor)1652     void blendAndVerifyColor(const GLColor32F blendColor, const GLColor expectedColor)
1653     {
1654         glEnable(GL_BLEND);
1655         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1656         EXPECT_GL_NO_ERROR();
1657 
1658         ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
1659         glUseProgram(program);
1660 
1661         GLint colorUniformLocation =
1662             glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
1663         ASSERT_NE(colorUniformLocation, -1);
1664 
1665         glUniform4f(colorUniformLocation, blendColor.R, blendColor.G, blendColor.B, blendColor.A);
1666         EXPECT_GL_NO_ERROR();
1667 
1668         drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
1669         EXPECT_GL_NO_ERROR();
1670         EXPECT_PIXEL_COLOR_NEAR(0, 0, expectedColor, 1);
1671     }
1672 };
1673 
1674 class SimpleStateChangeTestES31 : public SimpleStateChangeTestES3
1675 {};
1676 
1677 class SimpleStateChangeTestComputeES31 : public SimpleStateChangeTest
1678 {
1679   protected:
testSetUp()1680     void testSetUp() override
1681     {
1682         glGenFramebuffers(1, &mFramebuffer);
1683         glGenTextures(1, &mTexture);
1684 
1685         glBindTexture(GL_TEXTURE_2D, mTexture);
1686         glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2);
1687         EXPECT_GL_NO_ERROR();
1688 
1689         constexpr char kCS[] = R"(#version 310 es
1690 layout(local_size_x=2, local_size_y=2) in;
1691 layout (rgba8, binding = 0) readonly uniform highp image2D srcImage;
1692 layout (rgba8, binding = 1) writeonly uniform highp image2D dstImage;
1693 void main()
1694 {
1695     imageStore(dstImage, ivec2(gl_LocalInvocationID.xy),
1696                imageLoad(srcImage, ivec2(gl_LocalInvocationID.xy)));
1697 })";
1698 
1699         mProgram = CompileComputeProgram(kCS);
1700         ASSERT_NE(mProgram, 0u);
1701 
1702         glBindImageTexture(1, mTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8);
1703 
1704         glBindFramebuffer(GL_READ_FRAMEBUFFER, mFramebuffer);
1705         glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture,
1706                                0);
1707 
1708         ASSERT_GL_NO_ERROR();
1709     }
1710 
testTearDown()1711     void testTearDown() override
1712     {
1713         if (mFramebuffer != 0)
1714         {
1715             glDeleteFramebuffers(1, &mFramebuffer);
1716             mFramebuffer = 0;
1717         }
1718 
1719         if (mTexture != 0)
1720         {
1721             glDeleteTextures(1, &mTexture);
1722             mTexture = 0;
1723         }
1724         glDeleteProgram(mProgram);
1725     }
1726 
1727     GLuint mProgram;
1728     GLuint mFramebuffer = 0;
1729     GLuint mTexture     = 0;
1730 };
1731 
1732 class ImageES31PPO
1733 {
1734   protected:
ImageES31PPO()1735     ImageES31PPO() : mComputeProg(0), mPipeline(0) {}
1736 
bindProgramPipeline(const GLchar * computeString)1737     void bindProgramPipeline(const GLchar *computeString)
1738     {
1739         mComputeProg = glCreateShaderProgramv(GL_COMPUTE_SHADER, 1, &computeString);
1740         ASSERT_NE(mComputeProg, 0u);
1741 
1742         // Generate a program pipeline and attach the programs to their respective stages
1743         glGenProgramPipelines(1, &mPipeline);
1744         EXPECT_GL_NO_ERROR();
1745         glUseProgramStages(mPipeline, GL_COMPUTE_SHADER_BIT, mComputeProg);
1746         EXPECT_GL_NO_ERROR();
1747         glBindProgramPipeline(mPipeline);
1748         EXPECT_GL_NO_ERROR();
1749         glActiveShaderProgram(mPipeline, mComputeProg);
1750         EXPECT_GL_NO_ERROR();
1751     }
1752 
1753     GLuint mComputeProg;
1754     GLuint mPipeline;
1755 };
1756 
1757 class SimpleStateChangeTestComputeES31PPO : public ImageES31PPO, public SimpleStateChangeTest
1758 {
1759   protected:
SimpleStateChangeTestComputeES31PPO()1760     SimpleStateChangeTestComputeES31PPO() : ImageES31PPO(), SimpleStateChangeTest() {}
1761 
testTearDown()1762     void testTearDown() override
1763     {
1764         if (mFramebuffer != 0)
1765         {
1766             glDeleteFramebuffers(1, &mFramebuffer);
1767             mFramebuffer = 0;
1768         }
1769 
1770         if (mTexture != 0)
1771         {
1772             glDeleteTextures(1, &mTexture);
1773             mTexture = 0;
1774         }
1775         glDeleteProgramPipelines(1, &mPipeline);
1776     }
1777 
1778     GLuint mFramebuffer = 0;
1779     GLuint mTexture     = 0;
1780 };
1781 
1782 constexpr char kSimpleVertexShader[] = R"(attribute vec2 position;
1783 attribute vec4 color;
1784 varying vec4 vColor;
1785 void main()
1786 {
1787     gl_Position = vec4(position, 0, 1);
1788     vColor = color;
1789 }
1790 )";
1791 
1792 constexpr char kSimpleFragmentShader[] = R"(precision mediump float;
1793 varying vec4 vColor;
1794 void main()
1795 {
1796     gl_FragColor = vColor;
1797 }
1798 )";
1799 
simpleDrawWithBuffer(GLBuffer * buffer)1800 void SimpleStateChangeTest::simpleDrawWithBuffer(GLBuffer *buffer)
1801 {
1802     ANGLE_GL_PROGRAM(program, kSimpleVertexShader, kSimpleFragmentShader);
1803     glUseProgram(program);
1804 
1805     GLint colorLoc = glGetAttribLocation(program, "color");
1806     ASSERT_NE(-1, colorLoc);
1807 
1808     glBindBuffer(GL_ARRAY_BUFFER, *buffer);
1809     glVertexAttribPointer(colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, nullptr);
1810     glEnableVertexAttribArray(colorLoc);
1811 
1812     drawQuad(program, "position", 0.5f, 1.0f, true);
1813     ASSERT_GL_NO_ERROR();
1814 }
1815 
simpleDrawWithColor(const GLColor & color)1816 void SimpleStateChangeTest::simpleDrawWithColor(const GLColor &color)
1817 {
1818     std::vector<GLColor> colors(6, color);
1819     GLBuffer colorBuffer;
1820     glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
1821     glBufferData(GL_ARRAY_BUFFER, colors.size() * sizeof(GLColor), colors.data(), GL_STATIC_DRAW);
1822     simpleDrawWithBuffer(&colorBuffer);
1823 }
1824 
1825 // Test that we can do a drawElements call successfully after making a drawArrays call in the same
1826 // frame.
TEST_P(SimpleStateChangeTest,DrawArraysThenDrawElements)1827 TEST_P(SimpleStateChangeTest, DrawArraysThenDrawElements)
1828 {
1829     // http://anglebug.com/4121
1830     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGLES());
1831 
1832     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
1833     glUseProgram(program);
1834 
1835     // We expect to draw a triangle with the first 3 points to the left, then another triangle with
1836     // the last 3 vertices using a drawElements call.
1837     auto vertices = std::vector<Vector3>{{-1.0f, -1.0f, 0.0f},
1838                                          {-1.0f, 1.0f, 0.0f},
1839                                          {0.0f, 0.0f, 0.0f},
1840                                          {1.0f, 1.0f, 0.0f},
1841                                          {1.0f, -1.0f, 0.0f}};
1842 
1843     // If we use these indices to draw we'll be using the last 2 vertex only to draw.
1844     auto indices = std::vector<GLushort>{2, 3, 4};
1845 
1846     GLint positionLocation = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
1847     ASSERT_NE(-1, positionLocation);
1848 
1849     GLBuffer vertexBuffer;
1850     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
1851     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
1852                  GL_STATIC_DRAW);
1853 
1854     GLBuffer indexBuffer;
1855     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
1856     glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLushort), &indices[0],
1857                  GL_STATIC_DRAW);
1858 
1859     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
1860     glEnableVertexAttribArray(positionLocation);
1861 
1862     for (int i = 0; i < 10; i++)
1863     {
1864         glClear(GL_COLOR_BUFFER_BIT);
1865         glDrawArrays(GL_TRIANGLES, 0, 3);                             // triangle to the left
1866         glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, nullptr);  // triangle to the right
1867         glFinish();
1868     }
1869     glDisableVertexAttribArray(positionLocation);
1870 
1871     ASSERT_GL_NO_ERROR();
1872 
1873     int quarterWidth = getWindowWidth() / 4;
1874     int halfHeight   = getWindowHeight() / 2;
1875 
1876     // Validate triangle to the left
1877     EXPECT_PIXEL_COLOR_EQ(quarterWidth, halfHeight, GLColor::blue);
1878 
1879     // Validate triangle to the right
1880     EXPECT_PIXEL_COLOR_EQ((quarterWidth * 3), halfHeight, GLColor::blue);
1881 }
1882 
1883 // Draw a triangle with drawElements and a non-zero offset and draw the same
1884 // triangle with the same offset followed by binding the same element buffer.
TEST_P(SimpleStateChangeTest,DrawElementsThenDrawElements)1885 TEST_P(SimpleStateChangeTest, DrawElementsThenDrawElements)
1886 {
1887     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
1888 
1889     glUseProgram(program);
1890 
1891     // Background Red color
1892     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
1893     glClear(GL_COLOR_BUFFER_BIT);
1894 
1895     // We expect to draw the triangle with the last three points on the bottom right, and
1896     // rebind the same element buffer and draw with the same indices.
1897     auto vertices = std::vector<Vector3>{
1898         {-1.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, {1.0f, -1.0f, 0.0f}, {-1.0f, -1.0f, 0.0f}};
1899 
1900     auto indices = std::vector<GLushort>{0, 1, 2, 1, 2, 3};
1901 
1902     GLint positionLocation = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
1903     ASSERT_NE(-1, positionLocation);
1904 
1905     GLBuffer indexBuffer;
1906     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
1907     glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLushort), &indices[0],
1908                  GL_STATIC_DRAW);
1909 
1910     GLBuffer vertexBuffer;
1911     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
1912     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
1913                  GL_STATIC_DRAW);
1914 
1915     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
1916     glEnableVertexAttribArray(positionLocation);
1917 
1918     glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, (void *)(3 * sizeof(GLushort)));
1919 
1920     // Rebind the same element buffer.
1921     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
1922 
1923     // Draw the triangle again with the same offset.
1924     glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, (void *)(3 * sizeof(GLushort)));
1925 
1926     glDisableVertexAttribArray(positionLocation);
1927 
1928     ASSERT_GL_NO_ERROR();
1929 
1930     int quarterWidth  = getWindowWidth() / 4;
1931     int quarterHeight = getWindowHeight() / 4;
1932 
1933     // Validate the triangle is drawn on the bottom right.
1934     EXPECT_PIXEL_COLOR_EQ(quarterWidth * 2, quarterHeight, GLColor::blue);
1935 
1936     // Validate the triangle is NOT on the top left part.
1937     EXPECT_PIXEL_COLOR_EQ(quarterWidth * 2, quarterHeight * 3, GLColor::red);
1938     EXPECT_PIXEL_COLOR_EQ(quarterWidth, quarterHeight * 2, GLColor::red);
1939 }
1940 
1941 // Draw a triangle with drawElements then change the index buffer and draw again.
TEST_P(SimpleStateChangeTest,DrawElementsThenDrawElementsNewIndexBuffer)1942 TEST_P(SimpleStateChangeTest, DrawElementsThenDrawElementsNewIndexBuffer)
1943 {
1944     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
1945 
1946     glUseProgram(program);
1947 
1948     // Background Red color
1949     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
1950     glClear(GL_COLOR_BUFFER_BIT);
1951 
1952     // We expect to draw the triangle with the last three points on the bottom right, and
1953     // rebind the same element buffer and draw with the same indices.
1954     auto vertices = std::vector<Vector3>{
1955         {-1.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, {1.0f, -1.0f, 0.0f}, {-1.0f, -1.0f, 0.0f}};
1956 
1957     auto indices8 = std::vector<GLubyte>{0, 1, 2, 1, 2, 3};
1958 
1959     GLint positionLocation = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
1960     ASSERT_NE(-1, positionLocation);
1961 
1962     GLint colorUniformLocation =
1963         glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
1964     ASSERT_NE(colorUniformLocation, -1);
1965 
1966     glUniform4f(colorUniformLocation, 1.0f, 1.0f, 1.0f, 1.0f);
1967 
1968     GLBuffer indexBuffer8;
1969     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer8);
1970     glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices8.size() * sizeof(GLubyte), &indices8[0],
1971                  GL_STATIC_DRAW);
1972 
1973     GLBuffer vertexBuffer;
1974     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
1975     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
1976                  GL_STATIC_DRAW);
1977 
1978     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
1979     glEnableVertexAttribArray(positionLocation);
1980 
1981     glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, (void *)(0 * sizeof(GLubyte)));
1982 
1983     auto indices2nd8 = std::vector<GLubyte>{2, 3, 0, 0, 1, 2};
1984 
1985     glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices2nd8.size() * sizeof(GLubyte), &indices2nd8[0],
1986                  GL_STATIC_DRAW);
1987 
1988     glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
1989 
1990     // Draw the triangle again with the same offset.
1991     glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, (void *)(0 * sizeof(GLubyte)));
1992 
1993     glDisableVertexAttribArray(positionLocation);
1994 
1995     ASSERT_GL_NO_ERROR();
1996 
1997     int quarterWidth  = getWindowWidth() / 4;
1998     int quarterHeight = getWindowHeight() / 4;
1999 
2000     // Validate the triangle is drawn on the bottom left.
2001     EXPECT_PIXEL_COLOR_EQ(quarterWidth * 2, quarterHeight, GLColor::blue);
2002     EXPECT_PIXEL_COLOR_EQ(quarterWidth, quarterHeight * 2, GLColor::blue);
2003 
2004     // Validate the triangle is NOT on the top right part.
2005     EXPECT_PIXEL_COLOR_EQ(quarterWidth * 2, quarterHeight * 3, GLColor::white);
2006 }
2007 
2008 // Draw a triangle with drawElements then change the indices and draw again.
TEST_P(SimpleStateChangeTest,DrawElementsThenDrawElementsNewIndices)2009 TEST_P(SimpleStateChangeTest, DrawElementsThenDrawElementsNewIndices)
2010 {
2011     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
2012 
2013     glUseProgram(program);
2014 
2015     // Background Red color
2016     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
2017     glClear(GL_COLOR_BUFFER_BIT);
2018 
2019     // We expect to draw the triangle with the last three points on the bottom right, and
2020     // rebind the same element buffer and draw with the same indices.
2021     std::vector<Vector3> vertices = {
2022         {-1.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, {1.0f, -1.0f, 0.0f}, {-1.0f, -1.0f, 0.0f}};
2023 
2024     std::vector<GLubyte> indices8 = {0, 1, 2, 2, 3, 0};
2025 
2026     GLint positionLocation = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
2027     ASSERT_NE(-1, positionLocation);
2028 
2029     GLint colorUniformLocation =
2030         glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
2031     ASSERT_NE(colorUniformLocation, -1);
2032 
2033     glUniform4f(colorUniformLocation, 1.0f, 1.0f, 1.0f, 1.0f);
2034 
2035     GLBuffer indexBuffer8;
2036     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer8);
2037     glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices8.size() * sizeof(GLubyte), &indices8[0],
2038                  GL_DYNAMIC_DRAW);
2039 
2040     GLBuffer vertexBuffer;
2041     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
2042     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
2043                  GL_STATIC_DRAW);
2044 
2045     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
2046     glEnableVertexAttribArray(positionLocation);
2047 
2048     glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, (void *)(0 * sizeof(GLubyte)));
2049 
2050     std::vector<GLubyte> newIndices8 = {2, 3, 0};
2051 
2052     glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, newIndices8.size() * sizeof(GLubyte),
2053                     &newIndices8[0]);
2054 
2055     glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
2056 
2057     // Draw the triangle again with the same offset.
2058     glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, (void *)(0 * sizeof(GLubyte)));
2059 
2060     glDisableVertexAttribArray(positionLocation);
2061 
2062     ASSERT_GL_NO_ERROR();
2063 
2064     int quarterWidth  = getWindowWidth() / 4;
2065     int quarterHeight = getWindowHeight() / 4;
2066 
2067     // Validate the triangle is drawn on the bottom left.
2068     EXPECT_PIXEL_COLOR_EQ(quarterWidth * 2, quarterHeight, GLColor::blue);
2069     EXPECT_PIXEL_COLOR_EQ(quarterWidth, quarterHeight * 2, GLColor::blue);
2070 
2071     // Validate the triangle is NOT on the top right part.
2072     EXPECT_PIXEL_COLOR_EQ(quarterWidth * 2, quarterHeight * 3, GLColor::white);
2073 }
2074 
2075 // Draw a triangle with drawElements then change the indices and draw again.  Similar to
2076 // DrawElementsThenDrawElementsNewIndices, but changes the whole index buffer (not just half).  This
2077 // triggers a different path in the Vulkan backend based on the fact that the majority of the buffer
2078 // is being updated.
TEST_P(SimpleStateChangeTest,DrawElementsThenDrawElementsWholeNewIndices)2079 TEST_P(SimpleStateChangeTest, DrawElementsThenDrawElementsWholeNewIndices)
2080 {
2081     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
2082 
2083     glUseProgram(program);
2084 
2085     // Background Red color
2086     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
2087     glClear(GL_COLOR_BUFFER_BIT);
2088 
2089     // We expect to draw the triangle with the last three points on the bottom right, and
2090     // rebind the same element buffer and draw with the same indices.
2091     std::vector<Vector3> vertices = {
2092         {-1.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, {1.0f, -1.0f, 0.0f}, {-1.0f, -1.0f, 0.0f}};
2093 
2094     std::vector<GLubyte> indices8 = {0, 1, 2, 2, 3, 0};
2095 
2096     GLint positionLocation = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
2097     ASSERT_NE(-1, positionLocation);
2098 
2099     GLint colorUniformLocation =
2100         glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
2101     ASSERT_NE(colorUniformLocation, -1);
2102 
2103     glUniform4f(colorUniformLocation, 1.0f, 1.0f, 1.0f, 1.0f);
2104 
2105     GLBuffer indexBuffer8;
2106     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer8);
2107     glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices8.size() * sizeof(GLubyte), &indices8[0],
2108                  GL_DYNAMIC_DRAW);
2109 
2110     GLBuffer vertexBuffer;
2111     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
2112     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
2113                  GL_STATIC_DRAW);
2114 
2115     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
2116     glEnableVertexAttribArray(positionLocation);
2117 
2118     glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, (void *)(0 * sizeof(GLubyte)));
2119 
2120     std::vector<GLubyte> newIndices8 = {2, 3, 0, 0, 0, 0};
2121 
2122     glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, newIndices8.size() * sizeof(GLubyte),
2123                     &newIndices8[0]);
2124 
2125     glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
2126 
2127     // Draw the triangle again with the same offset.
2128     glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, (void *)(0 * sizeof(GLubyte)));
2129 
2130     glDisableVertexAttribArray(positionLocation);
2131 
2132     ASSERT_GL_NO_ERROR();
2133 
2134     int quarterWidth  = getWindowWidth() / 4;
2135     int quarterHeight = getWindowHeight() / 4;
2136 
2137     // Validate the triangle is drawn on the bottom left.
2138     EXPECT_PIXEL_COLOR_EQ(quarterWidth * 2, quarterHeight, GLColor::blue);
2139     EXPECT_PIXEL_COLOR_EQ(quarterWidth, quarterHeight * 2, GLColor::blue);
2140 
2141     // Validate the triangle is NOT on the top right part.
2142     EXPECT_PIXEL_COLOR_EQ(quarterWidth * 2, quarterHeight * 3, GLColor::white);
2143 }
2144 
2145 // Draw a triangle with drawElements and a non-zero offset and draw the same
2146 // triangle with the same offset followed by binding a USHORT element buffer.
TEST_P(SimpleStateChangeTest,DrawElementsUBYTEX2ThenDrawElementsUSHORT)2147 TEST_P(SimpleStateChangeTest, DrawElementsUBYTEX2ThenDrawElementsUSHORT)
2148 {
2149     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
2150 
2151     glUseProgram(program);
2152 
2153     // Background Red color
2154     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
2155     glClear(GL_COLOR_BUFFER_BIT);
2156 
2157     // We expect to draw the triangle with the last three points on the bottom right, and
2158     // rebind the same element buffer and draw with the same indices.
2159     auto vertices = std::vector<Vector3>{
2160         {-1.0f, 1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, {1.0f, -1.0f, 0.0f}, {-1.0f, -1.0f, 0.0f}};
2161 
2162     auto indices8 = std::vector<GLubyte>{0, 1, 2, 1, 2, 3};
2163 
2164     GLint positionLocation = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
2165     ASSERT_NE(-1, positionLocation);
2166 
2167     GLint colorUniformLocation =
2168         glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
2169     ASSERT_NE(colorUniformLocation, -1);
2170 
2171     glUniform4f(colorUniformLocation, 1.0f, 1.0f, 1.0f, 1.0f);
2172 
2173     GLBuffer indexBuffer8;
2174     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer8);
2175     glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices8.size() * sizeof(GLubyte), &indices8[0],
2176                  GL_STATIC_DRAW);
2177 
2178     GLBuffer vertexBuffer;
2179     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
2180     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
2181                  GL_STATIC_DRAW);
2182 
2183     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
2184     glEnableVertexAttribArray(positionLocation);
2185 
2186     glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, (void *)(0 * sizeof(GLubyte)));
2187 
2188     auto indices2nd8 = std::vector<GLubyte>{2, 3, 0, 0, 1, 2};
2189     GLBuffer indexBuffer2nd8;
2190     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer2nd8);
2191     glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices2nd8.size() * sizeof(GLubyte), &indices2nd8[0],
2192                  GL_STATIC_DRAW);
2193     glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
2194 
2195     glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, (void *)(0 * sizeof(GLubyte)));
2196 
2197     // Bind the 16bit element buffer.
2198     auto indices16 = std::vector<GLushort>{0, 1, 3, 1, 2, 3};
2199     GLBuffer indexBuffer16;
2200     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer16);
2201     glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices16.size() * sizeof(GLushort), &indices16[0],
2202                  GL_STATIC_DRAW);
2203 
2204     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer16);
2205 
2206     glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
2207 
2208     // Draw the triangle again with the same offset.
2209     glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, (void *)(0 * sizeof(GLushort)));
2210 
2211     glDisableVertexAttribArray(positionLocation);
2212 
2213     ASSERT_GL_NO_ERROR();
2214 
2215     int quarterWidth  = getWindowWidth() / 4;
2216     int quarterHeight = getWindowHeight() / 4;
2217 
2218     // Validate green triangle is drawn on the bottom.
2219     EXPECT_PIXEL_COLOR_EQ(quarterWidth * 2, quarterHeight, GLColor::green);
2220 
2221     // Validate white triangle is drawn on the right.
2222     EXPECT_PIXEL_COLOR_EQ(quarterWidth * 3, quarterHeight * 2, GLColor::white);
2223 
2224     // Validate blue triangle is on the top left part.
2225     EXPECT_PIXEL_COLOR_EQ(quarterWidth * 2, quarterHeight * 3, GLColor::blue);
2226     EXPECT_PIXEL_COLOR_EQ(quarterWidth, quarterHeight * 2, GLColor::blue);
2227 }
2228 
2229 // Draw a points use multiple unaligned vertex buffer with same data,
2230 // verify all the rendering results are the same.
TEST_P(SimpleStateChangeTest,DrawRepeatUnalignedVboChange)2231 TEST_P(SimpleStateChangeTest, DrawRepeatUnalignedVboChange)
2232 {
2233     // http://anglebug.com/4470
2234     ANGLE_SKIP_TEST_IF(isSwiftshader() && (IsWindows() || IsLinux()));
2235 
2236     const int kRepeat = 2;
2237 
2238     // set up VBO, colorVBO is unaligned
2239     GLBuffer positionBuffer;
2240     constexpr size_t posOffset = 0;
2241     const GLfloat posData[]    = {0.5f, 0.5f};
2242     glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
2243     glBufferData(GL_ARRAY_BUFFER, sizeof(posData), posData, GL_STATIC_DRAW);
2244 
2245     GLBuffer colorBuffers[kRepeat];
2246     constexpr size_t colorOffset                = 1;
2247     const GLfloat colorData[]                   = {0.515f, 0.515f, 0.515f, 1.0f};
2248     constexpr size_t colorBufferSize            = colorOffset + sizeof(colorData);
2249     uint8_t colorDataUnaligned[colorBufferSize] = {0};
2250     memcpy(reinterpret_cast<void *>(colorDataUnaligned + colorOffset), colorData,
2251            sizeof(colorData));
2252     for (uint32_t i = 0; i < kRepeat; i++)
2253     {
2254         glBindBuffer(GL_ARRAY_BUFFER, colorBuffers[i]);
2255         glBufferData(GL_ARRAY_BUFFER, colorBufferSize, colorDataUnaligned, GL_STATIC_DRAW);
2256     }
2257 
2258     // set up frame buffer
2259     GLFramebuffer framebuffer;
2260     GLTexture framebufferTexture;
2261     bindTextureToFbo(framebuffer, framebufferTexture);
2262 
2263     // set up program
2264     ANGLE_GL_PROGRAM(program, kSimpleVertexShader, kSimpleFragmentShader);
2265     glUseProgram(program);
2266     GLuint colorAttrLocation = glGetAttribLocation(program, "color");
2267     glEnableVertexAttribArray(colorAttrLocation);
2268     GLuint posAttrLocation = glGetAttribLocation(program, "position");
2269     glEnableVertexAttribArray(posAttrLocation);
2270     EXPECT_GL_NO_ERROR();
2271 
2272     // draw and get drawing results
2273     constexpr size_t kRenderSize = kWindowSize * kWindowSize;
2274     std::array<GLColor, kRenderSize> pixelBufs[kRepeat];
2275 
2276     for (uint32_t i = 0; i < kRepeat; i++)
2277     {
2278         glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
2279         glClear(GL_COLOR_BUFFER_BIT);
2280 
2281         glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
2282         glVertexAttribPointer(posAttrLocation, 2, GL_FLOAT, GL_FALSE, 0,
2283                               reinterpret_cast<const void *>(posOffset));
2284         glBindBuffer(GL_ARRAY_BUFFER, colorBuffers[i]);
2285         glVertexAttribPointer(colorAttrLocation, 4, GL_FLOAT, GL_FALSE, 0,
2286                               reinterpret_cast<const void *>(colorOffset));
2287 
2288         glDrawArrays(GL_POINTS, 0, 1);
2289 
2290         // read drawing results
2291         glReadPixels(0, 0, kWindowSize, kWindowSize, GL_RGBA, GL_UNSIGNED_BYTE,
2292                      pixelBufs[i].data());
2293         EXPECT_GL_NO_ERROR();
2294     }
2295 
2296     // verify something is drawn
2297     static_assert(kRepeat >= 2, "More than one repetition required");
2298     std::array<GLColor, kRenderSize> pixelAllBlack{0};
2299     EXPECT_NE(pixelBufs[0], pixelAllBlack);
2300     // verify drawing results are all identical
2301     for (uint32_t i = 1; i < kRepeat; i++)
2302     {
2303         EXPECT_EQ(pixelBufs[i - 1], pixelBufs[i]);
2304     }
2305 }
2306 
2307 // Handles deleting a Buffer when it's being used.
TEST_P(SimpleStateChangeTest,DeleteBufferInUse)2308 TEST_P(SimpleStateChangeTest, DeleteBufferInUse)
2309 {
2310     std::vector<GLColor> colorData(6, GLColor::red);
2311 
2312     GLBuffer buffer;
2313     glBindBuffer(GL_ARRAY_BUFFER, buffer);
2314     glBufferData(GL_ARRAY_BUFFER, sizeof(GLColor) * colorData.size(), colorData.data(),
2315                  GL_STATIC_DRAW);
2316 
2317     simpleDrawWithBuffer(&buffer);
2318 
2319     buffer.reset();
2320     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2321 }
2322 
2323 // Tests that resizing a Buffer during a draw works as expected.
TEST_P(SimpleStateChangeTest,RedefineBufferInUse)2324 TEST_P(SimpleStateChangeTest, RedefineBufferInUse)
2325 {
2326     std::vector<GLColor> redColorData(6, GLColor::red);
2327 
2328     GLBuffer buffer;
2329     glBindBuffer(GL_ARRAY_BUFFER, buffer);
2330     glBufferData(GL_ARRAY_BUFFER, sizeof(GLColor) * redColorData.size(), redColorData.data(),
2331                  GL_STATIC_DRAW);
2332 
2333     // Trigger a pull from the buffer.
2334     simpleDrawWithBuffer(&buffer);
2335 
2336     // Redefine the buffer that's in-flight.
2337     std::vector<GLColor> greenColorData(1024, GLColor::green);
2338     glBufferData(GL_ARRAY_BUFFER, sizeof(GLColor) * greenColorData.size(), greenColorData.data(),
2339                  GL_STATIC_DRAW);
2340 
2341     // Trigger the flush and verify the first draw worked.
2342     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2343 
2344     // Draw again and verify the new data is correct.
2345     simpleDrawWithBuffer(&buffer);
2346     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2347 }
2348 
2349 // Tests updating a buffer's contents while in use, without redefining it.
TEST_P(SimpleStateChangeTest,UpdateBufferInUse)2350 TEST_P(SimpleStateChangeTest, UpdateBufferInUse)
2351 {
2352     std::vector<GLColor> redColorData(6, GLColor::red);
2353 
2354     GLBuffer buffer;
2355     glBindBuffer(GL_ARRAY_BUFFER, buffer);
2356     glBufferData(GL_ARRAY_BUFFER, sizeof(GLColor) * redColorData.size(), redColorData.data(),
2357                  GL_STATIC_DRAW);
2358 
2359     // Trigger a pull from the buffer.
2360     simpleDrawWithBuffer(&buffer);
2361 
2362     // Update the buffer that's in-flight.
2363     std::vector<GLColor> greenColorData(6, GLColor::green);
2364     glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GLColor) * greenColorData.size(),
2365                     greenColorData.data());
2366 
2367     // Trigger the flush and verify the first draw worked.
2368     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2369 
2370     // Draw again and verify the new data is correct.
2371     simpleDrawWithBuffer(&buffer);
2372     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2373 }
2374 
2375 // Tests that deleting an in-flight Texture does not immediately delete the resource.
TEST_P(SimpleStateChangeTest,DeleteTextureInUse)2376 TEST_P(SimpleStateChangeTest, DeleteTextureInUse)
2377 {
2378     std::array<GLColor, 4> colors = {
2379         {GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow}};
2380 
2381     GLTexture tex;
2382     glBindTexture(GL_TEXTURE_2D, tex);
2383     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
2384     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2385     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2386 
2387     draw2DTexturedQuad(0.5f, 1.0f, true);
2388     tex.reset();
2389     EXPECT_GL_NO_ERROR();
2390 
2391     int w = getWindowWidth() - 2;
2392     int h = getWindowHeight() - 2;
2393 
2394     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2395     EXPECT_PIXEL_COLOR_EQ(w, 0, GLColor::green);
2396     EXPECT_PIXEL_COLOR_EQ(0, h, GLColor::blue);
2397     EXPECT_PIXEL_COLOR_EQ(w, h, GLColor::yellow);
2398 }
2399 
2400 // Tests that modifying a texture parameter in-flight does not cause problems.
TEST_P(SimpleStateChangeTest,ChangeTextureFilterModeBetweenTwoDraws)2401 TEST_P(SimpleStateChangeTest, ChangeTextureFilterModeBetweenTwoDraws)
2402 {
2403     std::array<GLColor, 4> colors = {
2404         {GLColor::black, GLColor::white, GLColor::black, GLColor::white}};
2405 
2406     GLTexture tex;
2407     glBindTexture(GL_TEXTURE_2D, tex);
2408     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
2409 
2410     glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
2411     glClear(GL_COLOR_BUFFER_BIT);
2412 
2413     // Draw to the left side of the window only with NEAREST.
2414     glViewport(0, 0, getWindowWidth() / 2, getWindowHeight());
2415     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2416     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2417     draw2DTexturedQuad(0.5f, 1.0f, true);
2418 
2419     // Draw to the right side of the window only with LINEAR.
2420     glViewport(getWindowWidth() / 2, 0, getWindowWidth() / 2, getWindowHeight());
2421     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2422     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2423     draw2DTexturedQuad(0.5f, 1.0f, true);
2424     EXPECT_GL_NO_ERROR();
2425 
2426     glViewport(0, 0, getWindowWidth(), getWindowHeight());
2427 
2428     // The first half (left) should be only black followed by plain white.
2429     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
2430     EXPECT_PIXEL_COLOR_EQ(1, 0, GLColor::black);
2431     EXPECT_PIXEL_COLOR_EQ((getWindowWidth() / 2) - 3, 0, GLColor::white);
2432     EXPECT_PIXEL_COLOR_EQ((getWindowWidth() / 2) - 4, 0, GLColor::white);
2433 
2434     // The second half (right) should be a gradient so we shouldn't find plain black/white in the
2435     // middle.
2436     EXPECT_NE(angle::ReadColor((getWindowWidth() / 4) * 3, 0), GLColor::black);
2437     EXPECT_NE(angle::ReadColor((getWindowWidth() / 4) * 3, 0), GLColor::white);
2438 }
2439 
2440 // Tests that bind the same texture all the time between different draw calls.
TEST_P(SimpleStateChangeTest,RebindTextureDrawAgain)2441 TEST_P(SimpleStateChangeTest, RebindTextureDrawAgain)
2442 {
2443     GLuint program = get2DTexturedQuadProgram();
2444     glUseProgram(program);
2445 
2446     std::array<GLColor, 4> colors = {{GLColor::cyan, GLColor::cyan, GLColor::cyan, GLColor::cyan}};
2447 
2448     // Setup the texture
2449     GLTexture tex;
2450     glBindTexture(GL_TEXTURE_2D, tex);
2451     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
2452     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2453     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2454 
2455     // Setup the vertex array to draw a quad.
2456     GLint positionLocation = glGetAttribLocation(program, "position");
2457     setupQuadVertexBuffer(1.0f, 1.0f);
2458     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
2459     glEnableVertexAttribArray(positionLocation);
2460 
2461     // Draw quad
2462     glDrawArrays(GL_TRIANGLES, 0, 6);
2463     ASSERT_GL_NO_ERROR();
2464 
2465     // Bind again
2466     glBindTexture(GL_TEXTURE_2D, tex);
2467     ASSERT_GL_NO_ERROR();
2468 
2469     // Draw again, should still work.
2470     glDrawArrays(GL_TRIANGLES, 0, 6);
2471     ASSERT_GL_NO_ERROR();
2472 
2473     // Validate whole surface is filled with cyan.
2474     int h = getWindowHeight() - 1;
2475     int w = getWindowWidth() - 1;
2476 
2477     EXPECT_PIXEL_RECT_EQ(0, 0, w, h, GLColor::cyan);
2478 }
2479 
2480 // Tests that we can draw with a texture, modify the texture with a texSubImage, and then draw again
2481 // correctly.
TEST_P(SimpleStateChangeTest,DrawWithTextureTexSubImageThenDrawAgain)2482 TEST_P(SimpleStateChangeTest, DrawWithTextureTexSubImageThenDrawAgain)
2483 {
2484     GLuint program = get2DTexturedQuadProgram();
2485     ASSERT_NE(0u, program);
2486     glUseProgram(program);
2487 
2488     std::array<GLColor, 4> colors    = {{GLColor::red, GLColor::red, GLColor::red, GLColor::red}};
2489     std::array<GLColor, 4> subColors = {
2490         {GLColor::green, GLColor::green, GLColor::green, GLColor::green}};
2491 
2492     // Setup the texture
2493     GLTexture tex;
2494     glBindTexture(GL_TEXTURE_2D, tex);
2495     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
2496     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2497     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2498 
2499     // Setup the vertex array to draw a quad.
2500     GLint positionLocation = glGetAttribLocation(program, "position");
2501     setupQuadVertexBuffer(1.0f, 1.0f);
2502     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
2503     glEnableVertexAttribArray(positionLocation);
2504 
2505     // Draw quad
2506     glDrawArrays(GL_TRIANGLES, 0, 6);
2507     ASSERT_GL_NO_ERROR();
2508 
2509     // Update bottom-half of texture with green.
2510     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 1, GL_RGBA, GL_UNSIGNED_BYTE, subColors.data());
2511     ASSERT_GL_NO_ERROR();
2512 
2513     // Draw again, should still work.
2514     glDrawArrays(GL_TRIANGLES, 0, 6);
2515     ASSERT_GL_NO_ERROR();
2516 
2517     // Validate first half of the screen is red and the bottom is green.
2518     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2519     EXPECT_PIXEL_COLOR_EQ(0, getWindowHeight() / 4 * 3, GLColor::red);
2520 }
2521 
2522 // Test that we can alternate between textures between different draws.
TEST_P(SimpleStateChangeTest,DrawTextureAThenTextureBThenTextureA)2523 TEST_P(SimpleStateChangeTest, DrawTextureAThenTextureBThenTextureA)
2524 {
2525     GLuint program = get2DTexturedQuadProgram();
2526     glUseProgram(program);
2527 
2528     std::array<GLColor, 4> colorsTex1 = {
2529         {GLColor::cyan, GLColor::cyan, GLColor::cyan, GLColor::cyan}};
2530 
2531     std::array<GLColor, 4> colorsTex2 = {
2532         {GLColor::magenta, GLColor::magenta, GLColor::magenta, GLColor::magenta}};
2533 
2534     // Setup the texture
2535     GLTexture tex1;
2536     glBindTexture(GL_TEXTURE_2D, tex1);
2537     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, colorsTex1.data());
2538     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2539     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2540 
2541     GLTexture tex2;
2542     glBindTexture(GL_TEXTURE_2D, tex2);
2543     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, colorsTex2.data());
2544     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
2545     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
2546 
2547     // Setup the vertex array to draw a quad.
2548     GLint positionLocation = glGetAttribLocation(program, "position");
2549     setupQuadVertexBuffer(1.0f, 1.0f);
2550     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
2551     glEnableVertexAttribArray(positionLocation);
2552 
2553     // Draw quad
2554     glBindTexture(GL_TEXTURE_2D, tex1);
2555     glDrawArrays(GL_TRIANGLES, 0, 6);
2556     ASSERT_GL_NO_ERROR();
2557 
2558     // Bind again, draw again
2559     glBindTexture(GL_TEXTURE_2D, tex2);
2560     glDrawArrays(GL_TRIANGLES, 0, 6);
2561     ASSERT_GL_NO_ERROR();
2562 
2563     // Bind again, draw again
2564     glBindTexture(GL_TEXTURE_2D, tex1);
2565     glDrawArrays(GL_TRIANGLES, 0, 6);
2566 
2567     // Validate whole surface is filled with cyan.
2568     int h = getWindowHeight() - 1;
2569     int w = getWindowWidth() - 1;
2570 
2571     EXPECT_PIXEL_RECT_EQ(0, 0, w, h, GLColor::cyan);
2572 }
2573 
2574 // Tests that redefining an in-flight Texture does not affect the in-flight resource.
TEST_P(SimpleStateChangeTest,RedefineTextureInUse)2575 TEST_P(SimpleStateChangeTest, RedefineTextureInUse)
2576 {
2577     std::array<GLColor, 4> colors = {
2578         {GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow}};
2579 
2580     GLTexture tex;
2581     glBindTexture(GL_TEXTURE_2D, tex);
2582     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
2583     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2584     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2585 
2586     // Draw with the first texture.
2587     draw2DTexturedQuad(0.5f, 1.0f, true);
2588 
2589     // Redefine the in-flight texture.
2590     constexpr int kBigSize = 32;
2591     std::vector<GLColor> bigColors;
2592     for (int y = 0; y < kBigSize; ++y)
2593     {
2594         for (int x = 0; x < kBigSize; ++x)
2595         {
2596             bool xComp = x < kBigSize / 2;
2597             bool yComp = y < kBigSize / 2;
2598             if (yComp)
2599             {
2600                 bigColors.push_back(xComp ? GLColor::cyan : GLColor::magenta);
2601             }
2602             else
2603             {
2604                 bigColors.push_back(xComp ? GLColor::yellow : GLColor::white);
2605             }
2606         }
2607     }
2608 
2609     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, bigColors.data());
2610     EXPECT_GL_NO_ERROR();
2611 
2612     // Verify the first draw had the correct data via ReadPixels.
2613     int w = getWindowWidth() - 2;
2614     int h = getWindowHeight() - 2;
2615 
2616     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2617     EXPECT_PIXEL_COLOR_EQ(w, 0, GLColor::green);
2618     EXPECT_PIXEL_COLOR_EQ(0, h, GLColor::blue);
2619     EXPECT_PIXEL_COLOR_EQ(w, h, GLColor::yellow);
2620 
2621     // Draw and verify with the redefined data.
2622     draw2DTexturedQuad(0.5f, 1.0f, true);
2623     EXPECT_GL_NO_ERROR();
2624 
2625     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
2626     EXPECT_PIXEL_COLOR_EQ(w, 0, GLColor::magenta);
2627     EXPECT_PIXEL_COLOR_EQ(0, h, GLColor::yellow);
2628     EXPECT_PIXEL_COLOR_EQ(w, h, GLColor::white);
2629 }
2630 
2631 // Test updating a Texture's contents while in use by GL works as expected.
TEST_P(SimpleStateChangeTest,UpdateTextureInUse)2632 TEST_P(SimpleStateChangeTest, UpdateTextureInUse)
2633 {
2634     std::array<GLColor, 4> rgby = {{GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow}};
2635 
2636     // Set up 2D quad resources.
2637     GLuint program = get2DTexturedQuadProgram();
2638     glUseProgram(program);
2639     ASSERT_EQ(0, glGetAttribLocation(program, "position"));
2640 
2641     const auto &quadVerts = GetQuadVertices();
2642 
2643     GLBuffer vbo;
2644     glBindBuffer(GL_ARRAY_BUFFER, vbo);
2645     glBufferData(GL_ARRAY_BUFFER, quadVerts.size() * sizeof(quadVerts[0]), quadVerts.data(),
2646                  GL_STATIC_DRAW);
2647     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
2648     glEnableVertexAttribArray(0);
2649 
2650     GLTexture tex;
2651     glBindTexture(GL_TEXTURE_2D, tex);
2652     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgby.data());
2653     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2654     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2655 
2656     // Draw RGBY to the Framebuffer. The texture is now in-use by GL.
2657     const int w  = getWindowWidth() - 2;
2658     const int h  = getWindowHeight() - 2;
2659     const int w2 = w >> 1;
2660 
2661     glViewport(0, 0, w2, h);
2662     glDrawArrays(GL_TRIANGLES, 0, 6);
2663 
2664     // Update the texture to be YBGR, while the Texture is in-use. Should not affect the draw.
2665     std::array<GLColor, 4> ybgr = {{GLColor::yellow, GLColor::blue, GLColor::green, GLColor::red}};
2666     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, ybgr.data());
2667     ASSERT_GL_NO_ERROR();
2668 
2669     // Draw again to the Framebuffer. The second draw call should use the updated YBGR data.
2670     glViewport(w2, 0, w2, h);
2671     glDrawArrays(GL_TRIANGLES, 0, 6);
2672 
2673     // Check the Framebuffer. Both draws should have completed.
2674     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
2675     EXPECT_PIXEL_COLOR_EQ(w2 - 1, 0, GLColor::green);
2676     EXPECT_PIXEL_COLOR_EQ(0, h - 1, GLColor::blue);
2677     EXPECT_PIXEL_COLOR_EQ(w2 - 1, h - 1, GLColor::yellow);
2678 
2679     EXPECT_PIXEL_COLOR_EQ(w2 + 1, 0, GLColor::yellow);
2680     EXPECT_PIXEL_COLOR_EQ(w - 1, 0, GLColor::blue);
2681     EXPECT_PIXEL_COLOR_EQ(w2 + 1, h - 1, GLColor::green);
2682     EXPECT_PIXEL_COLOR_EQ(w - 1, h - 1, GLColor::red);
2683     ASSERT_GL_NO_ERROR();
2684 }
2685 
updateTextureBoundToFramebufferHelper(UpdateFunc updateFunc)2686 void SimpleStateChangeTest::updateTextureBoundToFramebufferHelper(UpdateFunc updateFunc)
2687 {
2688     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
2689 
2690     std::vector<GLColor> red(4, GLColor::red);
2691     std::vector<GLColor> green(4, GLColor::green);
2692 
2693     GLTexture renderTarget;
2694     glBindTexture(GL_TEXTURE_2D, renderTarget);
2695     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, red.data());
2696 
2697     GLFramebuffer fbo;
2698     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
2699     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderTarget,
2700                            0);
2701     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
2702     glViewport(0, 0, 2, 2);
2703     ASSERT_GL_NO_ERROR();
2704 
2705     GLTexture tex;
2706     glBindTexture(GL_TEXTURE_2D, tex);
2707     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, red.data());
2708     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
2709     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
2710 
2711     // Draw once to flush dirty state bits.
2712     draw2DTexturedQuad(0.5f, 1.0f, true);
2713 
2714     ASSERT_GL_NO_ERROR();
2715 
2716     // Update the (0, 1) pixel to be blue
2717     updateFunc(GL_TEXTURE_2D, &renderTarget, 0, 1, GLColor::blue);
2718 
2719     // Draw green to the right half of the Framebuffer.
2720     glBindTexture(GL_TEXTURE_2D, tex);
2721     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, green.data());
2722     glViewport(1, 0, 1, 2);
2723     draw2DTexturedQuad(0.5f, 1.0f, true);
2724 
2725     // Update the (1, 1) pixel to be yellow
2726     updateFunc(GL_TEXTURE_2D, &renderTarget, 1, 1, GLColor::yellow);
2727 
2728     ASSERT_GL_NO_ERROR();
2729 
2730     // Verify we have a quad with the right colors in the FBO.
2731     std::vector<GLColor> expected = {
2732         {GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow}};
2733     std::vector<GLColor> actual(4);
2734     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
2735     glReadPixels(0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, actual.data());
2736     EXPECT_EQ(expected, actual);
2737 }
2738 
2739 // Tests that TexSubImage updates are flushed before rendering.
TEST_P(SimpleStateChangeTest,TexSubImageOnTextureBoundToFrambuffer)2740 TEST_P(SimpleStateChangeTest, TexSubImageOnTextureBoundToFrambuffer)
2741 {
2742     // http://anglebug.com/4092
2743     ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());
2744     auto updateFunc = [](GLenum textureBinding, GLTexture *tex, GLint x, GLint y,
2745                          const GLColor &color) {
2746         glBindTexture(textureBinding, *tex);
2747         glTexSubImage2D(textureBinding, 0, x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, color.data());
2748     };
2749 
2750     updateTextureBoundToFramebufferHelper(updateFunc);
2751 }
2752 
2753 // Tests that CopyTexSubImage updates are flushed before rendering.
TEST_P(SimpleStateChangeTest,CopyTexSubImageOnTextureBoundToFrambuffer)2754 TEST_P(SimpleStateChangeTest, CopyTexSubImageOnTextureBoundToFrambuffer)
2755 {
2756     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_framebuffer_blit"));
2757 
2758     GLTexture copySource;
2759     glBindTexture(GL_TEXTURE_2D, copySource);
2760     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2761 
2762     GLFramebuffer copyFBO;
2763     glBindFramebuffer(GL_READ_FRAMEBUFFER, copyFBO);
2764     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, copySource, 0);
2765 
2766     ASSERT_GL_NO_ERROR();
2767     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
2768 
2769     auto updateFunc = [&copySource](GLenum textureBinding, GLTexture *tex, GLint x, GLint y,
2770                                     const GLColor &color) {
2771         glBindTexture(GL_TEXTURE_2D, copySource);
2772         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, color.data());
2773 
2774         glBindTexture(textureBinding, *tex);
2775         glCopyTexSubImage2D(textureBinding, 0, x, y, 0, 0, 1, 1);
2776     };
2777 
2778     updateTextureBoundToFramebufferHelper(updateFunc);
2779 }
2780 
2781 // Tests that the read framebuffer doesn't affect what the draw call thinks the attachments are
2782 // (which is what the draw framebuffer dictates) when a command is issued with the GL_FRAMEBUFFER
2783 // target.
TEST_P(SimpleStateChangeTestES3,ReadFramebufferDrawFramebufferDifferentAttachments)2784 TEST_P(SimpleStateChangeTestES3, ReadFramebufferDrawFramebufferDifferentAttachments)
2785 {
2786     // http://anglebug.com/4092
2787     ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());
2788 
2789     GLRenderbuffer drawColorBuffer;
2790     glBindRenderbuffer(GL_RENDERBUFFER, drawColorBuffer);
2791     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
2792 
2793     GLRenderbuffer drawDepthBuffer;
2794     glBindRenderbuffer(GL_RENDERBUFFER, drawDepthBuffer);
2795     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 1, 1);
2796 
2797     GLRenderbuffer readColorBuffer;
2798     glBindRenderbuffer(GL_RENDERBUFFER, readColorBuffer);
2799     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
2800 
2801     GLFramebuffer drawFBO;
2802     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFBO);
2803     glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
2804                               drawColorBuffer);
2805     glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
2806                               drawDepthBuffer);
2807     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
2808 
2809     GLFramebuffer readFBO;
2810     glBindFramebuffer(GL_READ_FRAMEBUFFER, readFBO);
2811     glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
2812                               readColorBuffer);
2813     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
2814 
2815     EXPECT_GL_NO_ERROR();
2816 
2817     glClearDepthf(1.0f);
2818     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
2819 
2820     // A handful of non-draw calls can sync framebuffer state, such as discard, invalidate,
2821     // invalidateSub and multisamplefv.
2822     GLenum invalidateAttachment = GL_COLOR_ATTACHMENT0;
2823     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, &invalidateAttachment);
2824     EXPECT_GL_NO_ERROR();
2825 
2826     glEnable(GL_DEPTH_TEST);
2827     glDepthFunc(GL_EQUAL);
2828 
2829     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Blue());
2830 
2831     drawQuad(program, essl1_shaders::PositionAttrib(), 1.0f);
2832     EXPECT_GL_NO_ERROR();
2833 
2834     glBindFramebuffer(GL_READ_FRAMEBUFFER, drawFBO);
2835     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
2836 }
2837 
2838 // Tests that invalidate then copy then blend works.
TEST_P(SimpleStateChangeTestES3,InvalidateThenCopyThenBlend)2839 TEST_P(SimpleStateChangeTestES3, InvalidateThenCopyThenBlend)
2840 {
2841     // Create a framebuffer as the source of copy
2842     const GLColor kSrcData = GLColor::cyan;
2843     GLTexture copySrc;
2844     glBindTexture(GL_TEXTURE_2D, copySrc);
2845     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &kSrcData);
2846 
2847     GLFramebuffer readFBO;
2848     glBindFramebuffer(GL_READ_FRAMEBUFFER, readFBO);
2849     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, copySrc, 0);
2850     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
2851 
2852     // Create the framebuffer that will be invalidated
2853     GLTexture renderTarget;
2854     glBindTexture(GL_TEXTURE_2D, renderTarget);
2855     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2856 
2857     GLFramebuffer drawFBO;
2858     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFBO);
2859     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderTarget,
2860                            0);
2861     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
2862 
2863     EXPECT_GL_NO_ERROR();
2864 
2865     // Clear the framebuffer and invalidate it.
2866     glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
2867     glClear(GL_COLOR_BUFFER_BIT);
2868 
2869     GLenum invalidateAttachment = GL_COLOR_ATTACHMENT0;
2870     glInvalidateFramebuffer(GL_DRAW_FRAMEBUFFER, 1, &invalidateAttachment);
2871     EXPECT_GL_NO_ERROR();
2872 
2873     // Copy into the framebuffer's texture.  The framebuffer should now be cyan.
2874     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 1, 1);
2875     EXPECT_GL_NO_ERROR();
2876 
2877     // Blend into the framebuffer, then verify that the framebuffer should have had cyan.
2878     glBindFramebuffer(GL_READ_FRAMEBUFFER, drawFBO);
2879     blendAndVerifyColor(GLColor32F(1.0f, 0.0f, 0.0f, 0.5f), GLColor(127, 127, 127, 191));
2880 }
2881 
2882 // Tests that invalidate then blit then blend works.
TEST_P(SimpleStateChangeTestES3,InvalidateThenBlitThenBlend)2883 TEST_P(SimpleStateChangeTestES3, InvalidateThenBlitThenBlend)
2884 {
2885     // Create a framebuffer as the source of blit
2886     const GLColor kSrcData = GLColor::cyan;
2887     GLTexture blitSrc;
2888     glBindTexture(GL_TEXTURE_2D, blitSrc);
2889     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &kSrcData);
2890 
2891     GLFramebuffer readFBO;
2892     glBindFramebuffer(GL_READ_FRAMEBUFFER, readFBO);
2893     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, blitSrc, 0);
2894     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
2895 
2896     // Create the framebuffer that will be invalidated
2897     GLTexture renderTarget;
2898     glBindTexture(GL_TEXTURE_2D, renderTarget);
2899     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2900 
2901     GLFramebuffer drawFBO;
2902     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFBO);
2903     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderTarget,
2904                            0);
2905     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
2906 
2907     EXPECT_GL_NO_ERROR();
2908 
2909     // Clear the framebuffer and invalidate it.
2910     glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
2911     glClear(GL_COLOR_BUFFER_BIT);
2912 
2913     GLenum invalidateAttachment = GL_COLOR_ATTACHMENT0;
2914     glInvalidateFramebuffer(GL_DRAW_FRAMEBUFFER, 1, &invalidateAttachment);
2915     EXPECT_GL_NO_ERROR();
2916 
2917     // Blit into the framebuffer.  The framebuffer should now be cyan.
2918     glBlitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
2919     EXPECT_GL_NO_ERROR();
2920 
2921     // Blend into the framebuffer, then verify that the framebuffer should have had cyan.
2922     glBindFramebuffer(GL_READ_FRAMEBUFFER, drawFBO);
2923     blendAndVerifyColor(GLColor32F(1.0f, 0.0f, 0.0f, 0.5f), GLColor(127, 127, 127, 191));
2924 }
2925 
2926 // Tests that invalidate then generate mipmaps works
TEST_P(SimpleStateChangeTestES3,InvalidateThenGenerateMipmapsThenBlend)2927 TEST_P(SimpleStateChangeTestES3, InvalidateThenGenerateMipmapsThenBlend)
2928 {
2929     // Create a texture on which generate mipmaps would be called
2930     const GLColor kMip0Data[4] = {GLColor::cyan, GLColor::cyan, GLColor::cyan, GLColor::cyan};
2931     const GLColor kMip1Data    = GLColor::blue;
2932     GLTexture texture;
2933     glBindTexture(GL_TEXTURE_2D, texture);
2934     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, kMip0Data);
2935     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &kMip1Data);
2936 
2937     // Create the framebuffer that will be invalidated
2938     GLFramebuffer drawFBO;
2939     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFBO);
2940     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 1);
2941     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
2942 
2943     EXPECT_GL_NO_ERROR();
2944 
2945     // Clear the framebuffer and invalidate it.
2946     glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
2947     glClear(GL_COLOR_BUFFER_BIT);
2948 
2949     GLenum invalidateAttachment = GL_COLOR_ATTACHMENT0;
2950     glInvalidateFramebuffer(GL_DRAW_FRAMEBUFFER, 1, &invalidateAttachment);
2951     EXPECT_GL_NO_ERROR();
2952 
2953     // Generate mipmaps
2954     glGenerateMipmap(GL_TEXTURE_2D);
2955 
2956     // Blend into the framebuffer, then verify that the framebuffer should have had cyan.
2957     glBindFramebuffer(GL_READ_FRAMEBUFFER, drawFBO);
2958     blendAndVerifyColor(GLColor32F(1.0f, 0.0f, 0.0f, 0.5f), GLColor(127, 127, 127, 191));
2959 }
2960 
2961 // Tests that invalidate then upload works
TEST_P(SimpleStateChangeTestES3,InvalidateThenUploadThenBlend)2962 TEST_P(SimpleStateChangeTestES3, InvalidateThenUploadThenBlend)
2963 {
2964     // http://anglebug.com/4870
2965     ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());
2966 
2967     // Create the framebuffer that will be invalidated
2968     GLTexture renderTarget;
2969     glBindTexture(GL_TEXTURE_2D, renderTarget);
2970     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
2971 
2972     GLFramebuffer drawFBO;
2973     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFBO);
2974     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderTarget,
2975                            0);
2976     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
2977 
2978     EXPECT_GL_NO_ERROR();
2979 
2980     // Clear the framebuffer and invalidate it.
2981     glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
2982     glClear(GL_COLOR_BUFFER_BIT);
2983 
2984     GLenum invalidateAttachment = GL_COLOR_ATTACHMENT0;
2985     glInvalidateFramebuffer(GL_DRAW_FRAMEBUFFER, 1, &invalidateAttachment);
2986     EXPECT_GL_NO_ERROR();
2987 
2988     // Upload data to it
2989     const GLColor kUploadColor = GLColor::cyan;
2990     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &kUploadColor);
2991 
2992     // Blend into the framebuffer, then verify that the framebuffer should have had cyan.
2993     glBindFramebuffer(GL_READ_FRAMEBUFFER, drawFBO);
2994     blendAndVerifyColor(GLColor32F(1.0f, 0.0f, 0.0f, 0.5f), GLColor(127, 127, 127, 191));
2995 }
2996 
2997 // Tests that invalidate then sub upload works
TEST_P(SimpleStateChangeTestES3,InvalidateThenSubUploadThenBlend)2998 TEST_P(SimpleStateChangeTestES3, InvalidateThenSubUploadThenBlend)
2999 {
3000     // http://anglebug.com/4870
3001     ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());
3002 
3003     // Create the framebuffer that will be invalidated
3004     GLTexture renderTarget;
3005     glBindTexture(GL_TEXTURE_2D, renderTarget);
3006     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3007 
3008     GLFramebuffer drawFBO;
3009     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFBO);
3010     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderTarget,
3011                            0);
3012     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
3013 
3014     EXPECT_GL_NO_ERROR();
3015 
3016     // Clear the framebuffer and invalidate it.
3017     glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
3018     glClear(GL_COLOR_BUFFER_BIT);
3019 
3020     GLenum invalidateAttachment = GL_COLOR_ATTACHMENT0;
3021     glInvalidateFramebuffer(GL_DRAW_FRAMEBUFFER, 1, &invalidateAttachment);
3022     EXPECT_GL_NO_ERROR();
3023 
3024     // Upload data to it
3025     const GLColor kUploadColor = GLColor::cyan;
3026     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &kUploadColor);
3027 
3028     // Blend into the framebuffer, then verify that the framebuffer should have had cyan.
3029     glBindFramebuffer(GL_READ_FRAMEBUFFER, drawFBO);
3030     blendAndVerifyColor(GLColor32F(1.0f, 0.0f, 0.0f, 0.5f), GLColor(127, 127, 127, 191));
3031 }
3032 
3033 // Tests that invalidate then compute write works
TEST_P(SimpleStateChangeTestES31,InvalidateThenStorageWriteThenBlend)3034 TEST_P(SimpleStateChangeTestES31, InvalidateThenStorageWriteThenBlend)
3035 {
3036     // Fails on AMD OpenGL Windows. This configuration isn't maintained.
3037     ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsOpenGL());
3038     // http://anglebug.com/5387
3039     ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsDesktopOpenGL());
3040 
3041     constexpr char kCS[] = R"(#version 310 es
3042 layout(local_size_x=1, local_size_y=1) in;
3043 layout (rgba8, binding = 1) writeonly uniform highp image2D dstImage;
3044 void main()
3045 {
3046     imageStore(dstImage, ivec2(gl_GlobalInvocationID.xy), vec4(0.0f, 1.0f, 1.0f, 1.0f));
3047 })";
3048 
3049     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
3050     glUseProgram(program);
3051     EXPECT_GL_NO_ERROR();
3052 
3053     // Create the framebuffer texture
3054     GLTexture renderTarget;
3055     glBindTexture(GL_TEXTURE_2D, renderTarget);
3056     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
3057     glBindImageTexture(1, renderTarget, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8);
3058 
3059     // Write to the texture with compute once.  In the Vulkan backend, this will make sure the image
3060     // is already created with STORAGE usage and avoids recreate later.
3061     glDispatchCompute(1, 1, 1);
3062     EXPECT_GL_NO_ERROR();
3063 
3064     // Create the framebuffer that will be invalidated
3065     GLFramebuffer drawFBO;
3066     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFBO);
3067     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderTarget,
3068                            0);
3069     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
3070 
3071     EXPECT_GL_NO_ERROR();
3072 
3073     // Clear the framebuffer and invalidate it.
3074     glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
3075     glClear(GL_COLOR_BUFFER_BIT);
3076 
3077     GLenum invalidateAttachment = GL_COLOR_ATTACHMENT0;
3078     glInvalidateFramebuffer(GL_DRAW_FRAMEBUFFER, 1, &invalidateAttachment);
3079     EXPECT_GL_NO_ERROR();
3080 
3081     // Write to it with a compute shader
3082     glDispatchCompute(1, 1, 1);
3083     EXPECT_GL_NO_ERROR();
3084 
3085     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
3086 
3087     // Blend into the framebuffer, then verify that the framebuffer should have had cyan.
3088     glBindFramebuffer(GL_READ_FRAMEBUFFER, drawFBO);
3089     blendAndVerifyColor(GLColor32F(1.0f, 0.0f, 0.0f, 0.5f), GLColor(127, 127, 127, 191));
3090 }
3091 
3092 // Tests that invalidate then compute write works inside PPO
TEST_P(SimpleStateChangeTestES31,InvalidateThenStorageWriteThenBlendPpo)3093 TEST_P(SimpleStateChangeTestES31, InvalidateThenStorageWriteThenBlendPpo)
3094 {
3095     // Fails on AMD OpenGL Windows. This configuration isn't maintained.
3096     ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsOpenGL());
3097     // PPOs are only supported in the Vulkan backend
3098     ANGLE_SKIP_TEST_IF(!isVulkanRenderer());
3099 
3100     constexpr char kCS[] = R"(#version 310 es
3101 layout(local_size_x=1, local_size_y=1) in;
3102 layout (rgba8, binding = 1) writeonly uniform highp image2D dstImage;
3103 void main()
3104 {
3105     imageStore(dstImage, ivec2(gl_GlobalInvocationID.xy), vec4(0.0f, 1.0f, 1.0f, 1.0f));
3106 })";
3107 
3108     GLProgramPipeline pipeline;
3109     ANGLE_GL_COMPUTE_PROGRAM(program, kCS);
3110     glProgramParameteri(program, GL_PROGRAM_SEPARABLE, GL_TRUE);
3111     glUseProgramStages(pipeline, GL_COMPUTE_SHADER_BIT, program);
3112     EXPECT_GL_NO_ERROR();
3113     glBindProgramPipeline(pipeline);
3114     EXPECT_GL_NO_ERROR();
3115     glUseProgram(0);
3116 
3117     // Create the framebuffer texture
3118     GLTexture renderTarget;
3119     glBindTexture(GL_TEXTURE_2D, renderTarget);
3120     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
3121     glBindImageTexture(1, renderTarget, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8);
3122 
3123     // Write to the texture with compute once.  In the Vulkan backend, this will make sure the image
3124     // is already created with STORAGE usage and avoids recreate later.
3125     glDispatchCompute(1, 1, 1);
3126     EXPECT_GL_NO_ERROR();
3127 
3128     // Create the framebuffer that will be invalidated
3129     GLFramebuffer drawFBO;
3130     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFBO);
3131     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderTarget,
3132                            0);
3133     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
3134 
3135     EXPECT_GL_NO_ERROR();
3136 
3137     // Clear the framebuffer and invalidate it.
3138     glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
3139     glClear(GL_COLOR_BUFFER_BIT);
3140 
3141     GLenum invalidateAttachment = GL_COLOR_ATTACHMENT0;
3142     glInvalidateFramebuffer(GL_DRAW_FRAMEBUFFER, 1, &invalidateAttachment);
3143     EXPECT_GL_NO_ERROR();
3144 
3145     // Write to it with a compute shader
3146     glDispatchCompute(1, 1, 1);
3147     EXPECT_GL_NO_ERROR();
3148 
3149     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
3150 
3151     // Blend into the framebuffer, then verify that the framebuffer should have had cyan.
3152     glBindFramebuffer(GL_READ_FRAMEBUFFER, drawFBO);
3153     blendAndVerifyColor(GLColor32F(1.0f, 0.0f, 0.0f, 0.5f), GLColor(127, 127, 127, 191));
3154 }
3155 
3156 // Tests that sub-invalidate then draw works.
TEST_P(SimpleStateChangeTestES3,SubInvalidateThenDraw)3157 TEST_P(SimpleStateChangeTestES3, SubInvalidateThenDraw)
3158 {
3159     // Fails on AMD OpenGL Windows. This configuration isn't maintained.
3160     ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsOpenGL());
3161 
3162     // Create the framebuffer that will be invalidated
3163     GLTexture renderTarget;
3164     glBindTexture(GL_TEXTURE_2D, renderTarget);
3165     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3166 
3167     GLFramebuffer drawFBO;
3168     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFBO);
3169     glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderTarget,
3170                            0);
3171     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_DRAW_FRAMEBUFFER);
3172 
3173     EXPECT_GL_NO_ERROR();
3174 
3175     // Clear the framebuffer.
3176     glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
3177     glClear(GL_COLOR_BUFFER_BIT);
3178 
3179     // Draw into a quarter of the framebuffer, then invalidate that same region.
3180     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
3181     glEnable(GL_SCISSOR_TEST);
3182     glScissor(1, 1, 1, 1);
3183     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
3184 
3185     // Only invalidate a quarter of the framebuffer.
3186     GLenum invalidateAttachment = GL_COLOR_ATTACHMENT0;
3187     glInvalidateSubFramebuffer(GL_DRAW_FRAMEBUFFER, 1, &invalidateAttachment, 1, 1, 1, 1);
3188     EXPECT_GL_NO_ERROR();
3189 
3190     glDisable(GL_SCISSOR_TEST);
3191 
3192     // Blend into the framebuffer, then verify that the framebuffer should have had cyan.
3193     glBindFramebuffer(GL_READ_FRAMEBUFFER, drawFBO);
3194     blendAndVerifyColor(GLColor32F(0.0f, 0.0f, 1.0f, 0.5f), GLColor(127, 127, 127, 191));
3195 }
3196 
3197 // Tests that mid-render-pass invalidate then clear works for color buffers.  This test ensures that
3198 // the invalidate is undone on draw.
TEST_P(SimpleStateChangeTestES3,ColorInvalidateThenClear)3199 TEST_P(SimpleStateChangeTestES3, ColorInvalidateThenClear)
3200 {
3201     // Create the framebuffer that will be invalidated
3202     GLTexture color;
3203     glBindTexture(GL_TEXTURE_2D, color);
3204     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2);
3205 
3206     GLFramebuffer fbo;
3207     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3208     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
3209     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3210 
3211     EXPECT_GL_NO_ERROR();
3212 
3213     // Initialize the framebuffer with a draw call.
3214     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
3215     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
3216 
3217     // Invalidate it.
3218     GLenum invalidateAttachment = GL_COLOR_ATTACHMENT0;
3219     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, &invalidateAttachment);
3220 
3221     // Clear the framebuffer.
3222     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
3223     glClear(GL_COLOR_BUFFER_BIT);
3224 
3225     // Expect the clear color, ensuring that invalidate wasn't applied after clear.
3226     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3227 }
3228 
3229 // Tests that mid-render-pass invalidate then clear works for depth buffers.  This test ensures that
3230 // the invalidate is undone on draw.
TEST_P(SimpleStateChangeTestES3,DepthInvalidateThenClear)3231 TEST_P(SimpleStateChangeTestES3, DepthInvalidateThenClear)
3232 {
3233     // Create the framebuffer that will be invalidated
3234     GLTexture color;
3235     glBindTexture(GL_TEXTURE_2D, color);
3236     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2);
3237 
3238     GLRenderbuffer depth;
3239     glBindRenderbuffer(GL_RENDERBUFFER, depth);
3240     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, 2, 2);
3241 
3242     GLFramebuffer fbo;
3243     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3244     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
3245     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depth);
3246     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3247 
3248     EXPECT_GL_NO_ERROR();
3249 
3250     // Initialize the framebuffer with a draw call.
3251     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
3252     glUseProgram(drawColor);
3253     GLint colorUniformLocation =
3254         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
3255     ASSERT_NE(colorUniformLocation, -1);
3256 
3257     glEnable(GL_DEPTH_TEST);
3258     glDepthFunc(GL_ALWAYS);
3259 
3260     glUniform4f(colorUniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
3261     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.0f);
3262 
3263     // Invalidate depth.
3264     GLenum invalidateAttachment = GL_DEPTH_ATTACHMENT;
3265     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, &invalidateAttachment);
3266 
3267     // Clear the framebuffer.
3268     glClearDepthf(0.8f);
3269     glClear(GL_DEPTH_BUFFER_BIT);
3270 
3271     // Expect the draw color.  This breaks the render pass.  Later, the test ensures that invalidate
3272     // of depth wasn't applied after clear.
3273     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3274 
3275     // Blend with depth test and make sure depth is as expected.
3276     glEnable(GL_BLEND);
3277     glBlendFunc(GL_ONE, GL_ONE);
3278 
3279     glDepthFunc(GL_LESS);
3280     glUniform4f(colorUniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
3281     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.59f);
3282 
3283     glDepthFunc(GL_GREATER);
3284     glUniform4f(colorUniformLocation, 0.0f, 0.0f, 1.0f, 1.0f);
3285     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.61f);
3286 
3287     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);
3288 }
3289 
3290 // Invalidate an RGB framebuffer and verify that the alpha channel is not destroyed and remains
3291 // valid after a draw call.
TEST_P(SimpleStateChangeTestES3,InvalidateRGBThenDraw)3292 TEST_P(SimpleStateChangeTestES3, InvalidateRGBThenDraw)
3293 {
3294     ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
3295 
3296     GLTexture texture;
3297     glBindTexture(GL_TEXTURE_2D, texture);
3298     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, getWindowWidth(), getWindowHeight(), 0, GL_RGB,
3299                  GL_UNSIGNED_BYTE, nullptr);
3300 
3301     GLFramebuffer fbo;
3302     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3303     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
3304     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3305     ASSERT_GL_NO_ERROR();
3306 
3307     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
3308     glClear(GL_COLOR_BUFFER_BIT);
3309     // Verify that clearing alpha is ineffective on an RGB format.
3310     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
3311 
3312     // Invalidate the framebuffer contents.
3313     const GLenum discards[] = {GL_COLOR_ATTACHMENT0};
3314     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, discards);
3315 
3316     // Without an explicit clear, draw blue and make sure alpha is unaffected.  If RGB is emulated
3317     // with RGBA, the previous invalidate shouldn't affect the alpha value.
3318     drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);
3319     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
3320 }
3321 
3322 // Invalidate an RGB framebuffer and verify that the alpha channel is not destroyed, even if the
3323 // color channels may be garbage.
TEST_P(SimpleStateChangeTestES3,DrawAndInvalidateRGBThenVerifyAlpha)3324 TEST_P(SimpleStateChangeTestES3, DrawAndInvalidateRGBThenVerifyAlpha)
3325 {
3326     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
3327     glUseProgram(drawColor);
3328     GLint uniformLocation = glGetUniformLocation(drawColor, essl1_shaders::ColorUniform());
3329     ASSERT_NE(uniformLocation, -1);
3330 
3331     const int w = getWindowWidth();
3332     const int h = getWindowHeight();
3333 
3334     GLTexture texture;
3335     glBindTexture(GL_TEXTURE_2D, texture);
3336     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
3337 
3338     GLFramebuffer fbo;
3339     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3340     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
3341     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3342     ASSERT_GL_NO_ERROR();
3343 
3344     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
3345     glClear(GL_COLOR_BUFFER_BIT);
3346 
3347     glUniform4f(uniformLocation, 0.1f, 0.2f, 0.3f, 0.4f);
3348     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
3349 
3350     // Invalidate the framebuffer contents.
3351     const GLenum discards[] = {GL_COLOR_ATTACHMENT0};
3352     glInvalidateFramebuffer(GL_FRAMEBUFFER, 1, discards);
3353 
3354     // Read back the contents of the framebuffer.  The color channels are invalid, but as an RGB
3355     // format, readback should always return 1 in alpha.
3356     std::vector<GLColor> readback(w * h);
3357     glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, readback.data());
3358     for (int y = 0; y < h; ++y)
3359     {
3360         for (int x = 0; x < w; ++x)
3361         {
3362             EXPECT_EQ(readback[y * w + x].A, 255) << x << " " << y;
3363         }
3364     }
3365 }
3366 
3367 // Tests deleting a Framebuffer that is in use.
TEST_P(SimpleStateChangeTest,DeleteFramebufferInUse)3368 TEST_P(SimpleStateChangeTest, DeleteFramebufferInUse)
3369 {
3370     constexpr int kSize = 16;
3371 
3372     // Create a simple framebuffer.
3373     GLTexture texture;
3374     glBindTexture(GL_TEXTURE_2D, texture);
3375     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3376 
3377     GLFramebuffer framebuffer;
3378     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
3379     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
3380     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
3381 
3382     glViewport(0, 0, kSize, kSize);
3383 
3384     // Draw a solid red color to the framebuffer.
3385     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
3386     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f, 1.0f, true);
3387 
3388     // Delete the framebuffer while the call is in flight.
3389     framebuffer.reset();
3390 
3391     // Make a new framebuffer so we can read back the texture.
3392     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
3393     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
3394     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
3395 
3396     // Flush via ReadPixels and check red was drawn.
3397     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3398     ASSERT_GL_NO_ERROR();
3399 }
3400 
3401 // This test was made to reproduce a specific issue with our Vulkan backend where were releasing
3402 // buffers too early. The test has 2 textures, we first create a texture and update it with
3403 // multiple updates, but we don't use it right away, we instead draw using another texture
3404 // then we bind the first texture and draw with it.
TEST_P(SimpleStateChangeTest,DynamicAllocationOfMemoryForTextures)3405 TEST_P(SimpleStateChangeTest, DynamicAllocationOfMemoryForTextures)
3406 {
3407     constexpr int kSize = 64;
3408 
3409     GLuint program = get2DTexturedQuadProgram();
3410     glUseProgram(program);
3411 
3412     std::vector<GLColor> greenPixels(kSize * kSize, GLColor::green);
3413     std::vector<GLColor> redPixels(kSize * kSize, GLColor::red);
3414     GLTexture texture1;
3415     glBindTexture(GL_TEXTURE_2D, texture1);
3416     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3417 
3418     for (int i = 0; i < 100; i++)
3419     {
3420         // We do this a lot of time to make sure we use multiple buffers in the vulkan backend.
3421         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGBA, GL_UNSIGNED_BYTE,
3422                         greenPixels.data());
3423     }
3424     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3425     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3426 
3427     ASSERT_GL_NO_ERROR();
3428 
3429     GLTexture texture2;
3430     glBindTexture(GL_TEXTURE_2D, texture2);
3431     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, redPixels.data());
3432     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
3433     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
3434 
3435     // Setup the vertex array to draw a quad.
3436     GLint positionLocation = glGetAttribLocation(program, "position");
3437     setupQuadVertexBuffer(1.0f, 1.0f);
3438     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
3439     glEnableVertexAttribArray(positionLocation);
3440 
3441     // Draw quad with texture 2 while texture 1 has "staged" changes that have not been flushed yet.
3442     glBindTexture(GL_TEXTURE_2D, texture2);
3443     glDrawArrays(GL_TRIANGLES, 0, 6);
3444     ASSERT_GL_NO_ERROR();
3445     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3446 
3447     // If we now try to draw with texture1, we should trigger the issue.
3448     glBindTexture(GL_TEXTURE_2D, texture1);
3449     glDrawArrays(GL_TRIANGLES, 0, 6);
3450     ASSERT_GL_NO_ERROR();
3451 
3452     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3453 }
3454 
3455 // Tests deleting a Framebuffer that is in use.
TEST_P(SimpleStateChangeTest,RedefineFramebufferInUse)3456 TEST_P(SimpleStateChangeTest, RedefineFramebufferInUse)
3457 {
3458     constexpr int kSize = 16;
3459 
3460     // Create a simple framebuffer.
3461     GLTexture texture;
3462     glBindTexture(GL_TEXTURE_2D, texture);
3463     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3464 
3465     GLFramebuffer framebuffer;
3466     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
3467     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
3468     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
3469 
3470     glViewport(0, 0, kSize, kSize);
3471 
3472     // Draw red to the framebuffer.
3473     simpleDrawWithColor(GLColor::red);
3474 
3475     // Change the framebuffer while the call is in flight to a new texture.
3476     GLTexture otherTexture;
3477     glBindTexture(GL_TEXTURE_2D, otherTexture);
3478     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3479 
3480     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, otherTexture, 0);
3481     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
3482 
3483     // Draw green to the framebuffer. Verify the color.
3484     simpleDrawWithColor(GLColor::green);
3485     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3486 
3487     // Make a new framebuffer so we can read back the first texture and verify red.
3488     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
3489     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
3490     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
3491 
3492     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3493     ASSERT_GL_NO_ERROR();
3494 }
3495 
3496 // Tests that redefining a Framebuffer Texture Attachment works as expected.
TEST_P(SimpleStateChangeTest,RedefineFramebufferTexture)3497 TEST_P(SimpleStateChangeTest, RedefineFramebufferTexture)
3498 {
3499     GLFramebuffer framebuffer;
3500     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
3501 
3502     // Bind a simple 8x8 texture to the framebuffer, draw red.
3503     GLTexture texture;
3504     glBindTexture(GL_TEXTURE_2D, texture);
3505     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3506     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
3507 
3508     glViewport(0, 0, 8, 8);
3509     simpleDrawWithColor(GLColor::red);
3510     ASSERT_GL_NO_ERROR();
3511     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red) << "first draw should be red";
3512 
3513     // Redefine the texture to 32x32, draw green. Verify we get what we expect.
3514     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3515     glViewport(0, 0, 32, 32);
3516     simpleDrawWithColor(GLColor::green);
3517     ASSERT_GL_NO_ERROR();
3518     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green) << "second draw should be green";
3519 }
3520 
3521 // Trips a bug in the Vulkan back-end where a Texture wouldn't transition correctly.
TEST_P(SimpleStateChangeTest,DrawAndClearTextureRepeatedly)3522 TEST_P(SimpleStateChangeTest, DrawAndClearTextureRepeatedly)
3523 {
3524     // Fails on 431.02 driver. http://anglebug.com/3748
3525     ANGLE_SKIP_TEST_IF(IsWindows() && IsNVIDIA() && IsVulkan());
3526 
3527     // Fails on AMD OpenGL Windows. This configuration isn't maintained.
3528     ANGLE_SKIP_TEST_IF(IsWindows() && IsAMD() && IsOpenGL());
3529 
3530     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
3531 
3532     GLTexture tex;
3533     glBindTexture(GL_TEXTURE_2D, tex);
3534     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
3535     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3536     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3537     ASSERT_GL_NO_ERROR();
3538 
3539     GLFramebuffer fbo;
3540     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3541     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
3542     ASSERT_GL_NO_ERROR();
3543     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3544 
3545     glUseProgram(program);
3546 
3547     GLint uniLoc = glGetUniformLocation(program, essl1_shaders::Texture2DUniform());
3548     ASSERT_NE(-1, uniLoc);
3549     glUniform1i(uniLoc, 0);
3550 
3551     const int numRowsCols = 2;
3552     const int cellSize    = getWindowWidth() / 2;
3553 
3554     for (int cellY = 0; cellY < numRowsCols; cellY++)
3555     {
3556         for (int cellX = 0; cellX < numRowsCols; cellX++)
3557         {
3558             int seed            = cellX + cellY * numRowsCols;
3559             const Vector4 color = RandomVec4(seed, 0.0f, 1.0f);
3560 
3561             // Set the texture to a constant color using glClear and a user FBO.
3562             glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3563             glClearColor(color[0], color[1], color[2], color[3]);
3564             glClear(GL_COLOR_BUFFER_BIT);
3565 
3566             // Draw a small colored quad to the default FBO using the viewport.
3567             glBindFramebuffer(GL_FRAMEBUFFER, 0);
3568             glViewport(cellX * cellSize, cellY * cellSize, cellSize, cellSize);
3569             drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
3570         }
3571     }
3572 
3573     // Verify the colored quads were drawn correctly despite no flushing.
3574     std::vector<GLColor> pixelData(getWindowWidth() * getWindowHeight());
3575     glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
3576                  pixelData.data());
3577 
3578     ASSERT_GL_NO_ERROR();
3579 
3580     for (int cellY = 0; cellY < numRowsCols; cellY++)
3581     {
3582         for (int cellX = 0; cellX < numRowsCols; cellX++)
3583         {
3584             int seed            = cellX + cellY * numRowsCols;
3585             const Vector4 color = RandomVec4(seed, 0.0f, 1.0f);
3586 
3587             GLColor expectedColor(color);
3588 
3589             int testN =
3590                 cellX * cellSize + cellY * getWindowWidth() * cellSize + getWindowWidth() + 1;
3591             GLColor actualColor = pixelData[testN];
3592             EXPECT_COLOR_NEAR(expectedColor, actualColor, 1);
3593         }
3594     }
3595 }
3596 
3597 // Test that clear followed by rebind of framebuffer attachment works (with noop clear in between).
TEST_P(SimpleStateChangeTestES3,ClearThenNoopClearThenRebindAttachment)3598 TEST_P(SimpleStateChangeTestES3, ClearThenNoopClearThenRebindAttachment)
3599 {
3600     // Create a texture with red
3601     const GLColor kInitColor1 = GLColor::red;
3602     GLTexture texture1;
3603     glBindTexture(GL_TEXTURE_2D, texture1);
3604     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &kInitColor1);
3605 
3606     // Create a framebuffer to be cleared
3607     GLTexture texture2;
3608     glBindTexture(GL_TEXTURE_2D, texture2);
3609     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3610 
3611     GLFramebuffer drawFBO;
3612     glBindFramebuffer(GL_FRAMEBUFFER, drawFBO);
3613     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture2, 0);
3614     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3615 
3616     EXPECT_GL_NO_ERROR();
3617 
3618     // Clear the framebuffer to green
3619     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
3620     glClear(GL_COLOR_BUFFER_BIT);
3621 
3622     // Clear again, but in a way that would be a no-op.  In the Vulkan backend, this will result in
3623     // a framebuffer sync state, which extracts deferred clears.  However, as the clear is actually
3624     // a noop, the deferred clears will remain unflushed.
3625     glClear(0);
3626 
3627     // Change framebuffer's attachment to the other texture.
3628     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture1, 0);
3629     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3630 
3631     // A bogus draw to make sure the render pass is cleared in the Vulkan backend.
3632     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
3633     glUseProgram(program);
3634 
3635     glEnable(GL_BLEND);
3636     glBlendFunc(GL_ZERO, GL_ONE);
3637     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5);
3638     EXPECT_GL_NO_ERROR();
3639 
3640     // Expect red, which is the original contents of texture1.  If the clear is mistakenly applied
3641     // to the new attachment, green will be read back.
3642     EXPECT_PIXEL_COLOR_EQ(0, 0, kInitColor1);
3643 
3644     // Attach back to texture2.  It should be cleared to green.
3645     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture2, 0);
3646     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3647 }
3648 
3649 // Test that clear followed by rebind of framebuffer attachment works (with 0-sized scissor clear in
3650 // between).
TEST_P(SimpleStateChangeTestES3,ClearThenZeroSizeScissoredClearThenRebindAttachment)3651 TEST_P(SimpleStateChangeTestES3, ClearThenZeroSizeScissoredClearThenRebindAttachment)
3652 {
3653     // Create a texture with red
3654     const GLColor kInitColor1 = GLColor::red;
3655     GLTexture texture1;
3656     glBindTexture(GL_TEXTURE_2D, texture1);
3657     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &kInitColor1);
3658 
3659     // Create a framebuffer to be cleared
3660     GLTexture texture2;
3661     glBindTexture(GL_TEXTURE_2D, texture2);
3662     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3663 
3664     GLFramebuffer drawFBO;
3665     glBindFramebuffer(GL_FRAMEBUFFER, drawFBO);
3666     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture2, 0);
3667     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3668 
3669     EXPECT_GL_NO_ERROR();
3670 
3671     // Clear the framebuffer to green
3672     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
3673     glClear(GL_COLOR_BUFFER_BIT);
3674 
3675     // Clear again, but in a way that would be a no-op.  In the Vulkan backend, this will result in
3676     // a framebuffer sync state, which extracts deferred clears.  However, as the clear is actually
3677     // a noop, the deferred clears will remain unflushed.
3678     glEnable(GL_SCISSOR_TEST);
3679     glScissor(0, 0, 0, 0);
3680     glClear(GL_COLOR_BUFFER_BIT);
3681     glDisable(GL_SCISSOR_TEST);
3682 
3683     // Change framebuffer's attachment to the other texture.
3684     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture1, 0);
3685     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3686 
3687     // A bogus draw to make sure the render pass is cleared in the Vulkan backend.
3688     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
3689     glUseProgram(program);
3690 
3691     glEnable(GL_BLEND);
3692     glBlendFunc(GL_ZERO, GL_ONE);
3693     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5);
3694     EXPECT_GL_NO_ERROR();
3695 
3696     // Expect red, which is the original contents of texture1.  If the clear is mistakenly applied
3697     // to the new attachment, green will be read back.
3698     EXPECT_PIXEL_COLOR_EQ(0, 0, kInitColor1);
3699 
3700     // Attach back to texture2.  It should be cleared to green.
3701     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture2, 0);
3702     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3703 }
3704 
3705 // Test that clear followed by rebind of framebuffer attachment works (with noop blit in between).
TEST_P(SimpleStateChangeTestES3,ClearThenNoopBlitThenRebindAttachment)3706 TEST_P(SimpleStateChangeTestES3, ClearThenNoopBlitThenRebindAttachment)
3707 {
3708     // Create a texture with red
3709     const GLColor kInitColor1 = GLColor::red;
3710     GLTexture texture1;
3711     glBindTexture(GL_TEXTURE_2D, texture1);
3712     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &kInitColor1);
3713 
3714     // Create a framebuffer to be cleared
3715     GLTexture texture2;
3716     glBindTexture(GL_TEXTURE_2D, texture2);
3717     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3718 
3719     GLFramebuffer drawFBO;
3720     glBindFramebuffer(GL_FRAMEBUFFER, drawFBO);
3721     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture2, 0);
3722     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3723 
3724     EXPECT_GL_NO_ERROR();
3725 
3726     // Clear the framebuffer to green
3727     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
3728     glClear(GL_COLOR_BUFFER_BIT);
3729 
3730     // Issue noop blit.  In the Vulkan backend, this will result in a framebuffer sync state, which
3731     // extracts deferred clears.  However, as the blit is actually a noop, the deferred clears will
3732     // remain unflushed.
3733     GLTexture blitSrc;
3734     glBindTexture(GL_TEXTURE_2D, blitSrc);
3735     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
3736 
3737     GLFramebuffer readFBO;
3738     glBindFramebuffer(GL_READ_FRAMEBUFFER, readFBO);
3739     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, blitSrc, 0);
3740     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
3741 
3742     glBlitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
3743     EXPECT_GL_NO_ERROR();
3744 
3745     // Change framebuffer's attachment to the other texture.
3746     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture1, 0);
3747     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3748 
3749     // A bogus draw to make sure the render pass is cleared in the Vulkan backend.
3750     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
3751     glUseProgram(program);
3752 
3753     glEnable(GL_BLEND);
3754     glBlendFunc(GL_ZERO, GL_ONE);
3755     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5);
3756     EXPECT_GL_NO_ERROR();
3757 
3758     // Expect red, which is the original contents of texture1.  If the clear is mistakenly applied
3759     // to the new attachment, green will be read back.
3760     glBindFramebuffer(GL_READ_FRAMEBUFFER, drawFBO);
3761     EXPECT_PIXEL_COLOR_EQ(0, 0, kInitColor1);
3762 
3763     // Attach back to texture2.  It should be cleared to green.
3764     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture2, 0);
3765     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3766 }
3767 
3768 // Validates disabling cull face really disables it.
TEST_P(SimpleStateChangeTest,EnableAndDisableCullFace)3769 TEST_P(SimpleStateChangeTest, EnableAndDisableCullFace)
3770 {
3771     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
3772     glUseProgram(program);
3773 
3774     glClear(GL_COLOR_BUFFER_BIT);
3775     glEnable(GL_CULL_FACE);
3776 
3777     glCullFace(GL_FRONT);
3778 
3779     drawQuad(program.get(), essl1_shaders::PositionAttrib(), 0.0f, 1.0f, true);
3780 
3781     ASSERT_GL_NO_ERROR();
3782 
3783     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);
3784 
3785     // Disable cull face and redraw, then make sure we have the quad drawn.
3786     glDisable(GL_CULL_FACE);
3787 
3788     drawQuad(program.get(), essl1_shaders::PositionAttrib(), 0.0f, 1.0f, true);
3789 
3790     ASSERT_GL_NO_ERROR();
3791 
3792     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3793 }
3794 
TEST_P(SimpleStateChangeTest,ScissorTest)3795 TEST_P(SimpleStateChangeTest, ScissorTest)
3796 {
3797     // This test validates this order of state changes:
3798     // 1- Set scissor but don't enable it, validate its not used.
3799     // 2- Enable it and validate its working.
3800     // 3- Disable the scissor validate its not used anymore.
3801 
3802     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
3803 
3804     glClear(GL_COLOR_BUFFER_BIT);
3805 
3806     // Set the scissor region, but don't enable it yet.
3807     glScissor(getWindowWidth() / 4, getWindowHeight() / 4, getWindowWidth() / 2,
3808               getWindowHeight() / 2);
3809 
3810     // Fill the whole screen with a quad.
3811     drawQuad(program.get(), essl1_shaders::PositionAttrib(), 0.0f, 1.0f, true);
3812 
3813     ASSERT_GL_NO_ERROR();
3814 
3815     // Test outside, scissor isnt enabled so its red.
3816     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3817 
3818     // Test inside, red of the fragment shader.
3819     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3820 
3821     // Clear everything and start over with the test enabled.
3822     glClear(GL_COLOR_BUFFER_BIT);
3823     glEnable(GL_SCISSOR_TEST);
3824 
3825     drawQuad(program.get(), essl1_shaders::PositionAttrib(), 0.0f, 1.0f, true);
3826 
3827     ASSERT_GL_NO_ERROR();
3828 
3829     // Test outside the scissor test, pitch black.
3830     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);
3831 
3832     // Test inside, red of the fragment shader.
3833     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3834 
3835     // Now disable the scissor test, do it again, and verify the region isn't used
3836     // for the scissor test.
3837     glDisable(GL_SCISSOR_TEST);
3838 
3839     // Clear everything and start over with the test enabled.
3840     glClear(GL_COLOR_BUFFER_BIT);
3841 
3842     drawQuad(program.get(), essl1_shaders::PositionAttrib(), 0.0f, 1.0f, true);
3843 
3844     ASSERT_GL_NO_ERROR();
3845 
3846     // Test outside, scissor isnt enabled so its red.
3847     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3848 
3849     // Test inside, red of the fragment shader.
3850     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);
3851 }
3852 
3853 // This test validates we are able to change the valid of a uniform dynamically.
TEST_P(SimpleStateChangeTest,UniformUpdateTest)3854 TEST_P(SimpleStateChangeTest, UniformUpdateTest)
3855 {
3856     constexpr char kPositionUniformVertexShader[] = R"(
3857 precision mediump float;
3858 attribute vec2 position;
3859 uniform vec2 uniPosModifier;
3860 void main()
3861 {
3862     gl_Position = vec4(position + uniPosModifier, 0, 1);
3863 })";
3864 
3865     ANGLE_GL_PROGRAM(program, kPositionUniformVertexShader, essl1_shaders::fs::UniformColor());
3866     glUseProgram(program);
3867 
3868     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
3869     glClear(GL_COLOR_BUFFER_BIT);
3870 
3871     GLint posUniformLocation = glGetUniformLocation(program, "uniPosModifier");
3872     ASSERT_NE(posUniformLocation, -1);
3873     GLint colorUniformLocation = glGetUniformLocation(program, essl1_shaders::ColorUniform());
3874     ASSERT_NE(colorUniformLocation, -1);
3875 
3876     // draw a red quad to the left side.
3877     glUniform2f(posUniformLocation, -0.5, 0.0);
3878     glUniform4f(colorUniformLocation, 1.0, 0.0, 0.0, 1.0);
3879     drawQuad(program.get(), "position", 0.0f, 0.5f, true);
3880 
3881     // draw a green quad to the right side.
3882     glUniform2f(posUniformLocation, 0.5, 0.0);
3883     glUniform4f(colorUniformLocation, 0.0, 1.0, 0.0, 1.0);
3884     drawQuad(program.get(), "position", 0.0f, 0.5f, true);
3885 
3886     ASSERT_GL_NO_ERROR();
3887 
3888     // Test the center of the left quad. Should be red.
3889     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4, getWindowHeight() / 2, GLColor::red);
3890 
3891     // Test the center of the right quad. Should be green.
3892     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 4 * 3, getWindowHeight() / 2, GLColor::green);
3893 }
3894 
3895 // Tests that changing the storage of a Renderbuffer currently in use by GL works as expected.
TEST_P(SimpleStateChangeTest,RedefineRenderbufferInUse)3896 TEST_P(SimpleStateChangeTest, RedefineRenderbufferInUse)
3897 {
3898     GLRenderbuffer renderbuffer;
3899     glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
3900     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 16, 16);
3901 
3902     GLFramebuffer framebuffer;
3903     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
3904     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
3905 
3906     ASSERT_GL_NO_ERROR();
3907     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
3908 
3909     ANGLE_GL_PROGRAM(program, kSimpleVertexShader, kSimpleFragmentShader);
3910     GLint colorLoc = glGetAttribLocation(program, "color");
3911     ASSERT_NE(-1, colorLoc);
3912 
3913     // Set up and draw red to the left half the screen.
3914     std::vector<GLColor> redData(6, GLColor::red);
3915     GLBuffer vertexBufferRed;
3916     glBindBuffer(GL_ARRAY_BUFFER, vertexBufferRed);
3917     glBufferData(GL_ARRAY_BUFFER, redData.size() * sizeof(GLColor), redData.data(), GL_STATIC_DRAW);
3918     glVertexAttribPointer(colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, nullptr);
3919     glEnableVertexAttribArray(colorLoc);
3920 
3921     glViewport(0, 0, 16, 16);
3922     drawQuad(program, "position", 0.5f, 1.0f, true);
3923 
3924     // Immediately redefine the Renderbuffer.
3925     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 64, 64);
3926 
3927     // Set up and draw green to the right half of the screen.
3928     std::vector<GLColor> greenData(6, GLColor::green);
3929     GLBuffer vertexBufferGreen;
3930     glBindBuffer(GL_ARRAY_BUFFER, vertexBufferGreen);
3931     glBufferData(GL_ARRAY_BUFFER, greenData.size() * sizeof(GLColor), greenData.data(),
3932                  GL_STATIC_DRAW);
3933     glVertexAttribPointer(colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, nullptr);
3934     glEnableVertexAttribArray(colorLoc);
3935 
3936     glViewport(0, 0, 64, 64);
3937     drawQuad(program, "position", 0.5f, 1.0f, true);
3938 
3939     ASSERT_GL_NO_ERROR();
3940     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3941 }
3942 
3943 // Validate that we can draw -> change frame buffer size -> draw and we'll be rendering
3944 // at the full size of the new framebuffer.
TEST_P(SimpleStateChangeTest,ChangeFramebufferSizeBetweenTwoDraws)3945 TEST_P(SimpleStateChangeTest, ChangeFramebufferSizeBetweenTwoDraws)
3946 {
3947     constexpr size_t kSmallTextureSize = 2;
3948     constexpr size_t kBigTextureSize   = 4;
3949 
3950     // Create 2 textures, one of 2x2 and the other 4x4
3951     GLTexture texture1;
3952     glBindTexture(GL_TEXTURE_2D, texture1);
3953     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSmallTextureSize, kSmallTextureSize, 0, GL_RGBA,
3954                  GL_UNSIGNED_BYTE, nullptr);
3955     ASSERT_GL_NO_ERROR();
3956 
3957     GLTexture texture2;
3958     glBindTexture(GL_TEXTURE_2D, texture2);
3959     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kBigTextureSize, kBigTextureSize, 0, GL_RGBA,
3960                  GL_UNSIGNED_BYTE, nullptr);
3961     ASSERT_GL_NO_ERROR();
3962 
3963     // A framebuffer for each texture to draw on.
3964     GLFramebuffer framebuffer1;
3965     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer1);
3966     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture1, 0);
3967     ASSERT_GL_NO_ERROR();
3968     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
3969 
3970     GLFramebuffer framebuffer2;
3971     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer2);
3972     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture2, 0);
3973     ASSERT_GL_NO_ERROR();
3974     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
3975 
3976     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
3977     glUseProgram(program);
3978     GLint uniformLocation = glGetUniformLocation(program, essl1_shaders::ColorUniform());
3979     ASSERT_NE(uniformLocation, -1);
3980 
3981     // Bind to the first framebuffer for drawing.
3982     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer1);
3983 
3984     // Set a scissor, that will trigger setting the internal scissor state in Vulkan to
3985     // (0,0,framebuffer.width, framebuffer.height) size since the scissor isn't enabled.
3986     glScissor(0, 0, 16, 16);
3987     ASSERT_GL_NO_ERROR();
3988 
3989     // Set color to red.
3990     glUniform4f(uniformLocation, 1.0f, 0.0f, 0.0f, 1.0f);
3991     glViewport(0, 0, kSmallTextureSize, kSmallTextureSize);
3992 
3993     // Draw a full sized red quad
3994     drawQuad(program, essl1_shaders::PositionAttrib(), 1.0f, 1.0f, true);
3995     ASSERT_GL_NO_ERROR();
3996 
3997     // Bind to the second (bigger) framebuffer
3998     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer2);
3999     glViewport(0, 0, kBigTextureSize, kBigTextureSize);
4000 
4001     ASSERT_GL_NO_ERROR();
4002 
4003     // Set color to green.
4004     glUniform4f(uniformLocation, 0.0f, 1.0f, 0.0f, 1.0f);
4005 
4006     // Draw again and we should fill everything with green and expect everything to be green.
4007     drawQuad(program, essl1_shaders::PositionAttrib(), 1.0f, 1.0f, true);
4008     ASSERT_GL_NO_ERROR();
4009 
4010     EXPECT_PIXEL_RECT_EQ(0, 0, kBigTextureSize, kBigTextureSize, GLColor::green);
4011 }
4012 
4013 // Tries to relink a program in use and use it again to draw something else.
TEST_P(SimpleStateChangeTest,RelinkProgram)4014 TEST_P(SimpleStateChangeTest, RelinkProgram)
4015 {
4016     // http://anglebug.com/4121
4017     ANGLE_SKIP_TEST_IF(IsIntel() && IsLinux() && IsOpenGLES());
4018     const GLuint program = glCreateProgram();
4019 
4020     GLuint vs     = CompileShader(GL_VERTEX_SHADER, essl1_shaders::vs::Simple());
4021     GLuint blueFs = CompileShader(GL_FRAGMENT_SHADER, essl1_shaders::fs::Blue());
4022     GLuint redFs  = CompileShader(GL_FRAGMENT_SHADER, essl1_shaders::fs::Red());
4023 
4024     glAttachShader(program, vs);
4025     glAttachShader(program, blueFs);
4026 
4027     glLinkProgram(program);
4028     CheckLinkStatusAndReturnProgram(program, true);
4029 
4030     glClear(GL_COLOR_BUFFER_BIT);
4031     std::vector<Vector3> vertices = {{-1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, {1.0f, -1.0f, 0.0f},
4032                                      {-1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, {-1.0, 1.0f, 0.0f}};
4033     GLBuffer vertexBuffer;
4034     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
4035     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
4036                  GL_STATIC_DRAW);
4037     const GLint positionLocation = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
4038     ASSERT_NE(-1, positionLocation);
4039     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
4040     glEnableVertexAttribArray(positionLocation);
4041 
4042     // Draw a blue triangle to the right
4043     glUseProgram(program);
4044     glDrawArrays(GL_TRIANGLES, 0, 3);
4045 
4046     // Relink to draw red to the left
4047     glDetachShader(program, blueFs);
4048     glAttachShader(program, redFs);
4049 
4050     glLinkProgram(program);
4051     CheckLinkStatusAndReturnProgram(program, true);
4052 
4053     glDrawArrays(GL_TRIANGLES, 3, 3);
4054 
4055     ASSERT_GL_NO_ERROR();
4056 
4057     glDisableVertexAttribArray(positionLocation);
4058 
4059     // Verify we drew red and green in the right places.
4060     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, 0, GLColor::blue);
4061     EXPECT_PIXEL_COLOR_EQ(0, getWindowHeight() / 2, GLColor::red);
4062 
4063     glDeleteShader(vs);
4064     glDeleteShader(blueFs);
4065     glDeleteShader(redFs);
4066     glDeleteProgram(program);
4067 }
4068 
4069 // Creates a program that uses uniforms and then immediately release it and then use it. Should be
4070 // valid.
TEST_P(SimpleStateChangeTest,ReleaseShaderInUseThatReadsFromUniforms)4071 TEST_P(SimpleStateChangeTest, ReleaseShaderInUseThatReadsFromUniforms)
4072 {
4073     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
4074     glUseProgram(program);
4075 
4076     const GLint uniformLoc = glGetUniformLocation(program, essl1_shaders::ColorUniform());
4077     EXPECT_NE(-1, uniformLoc);
4078 
4079     // Set color to red.
4080     glUniform4f(uniformLoc, 1.0f, 0.0f, 0.0f, 1.0f);
4081 
4082     glClear(GL_COLOR_BUFFER_BIT);
4083     std::vector<Vector3> vertices = {{-1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, {1.0f, -1.0f, 0.0f}};
4084     GLBuffer vertexBuffer;
4085     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
4086     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
4087                  GL_STATIC_DRAW);
4088     const GLint positionLocation = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
4089     ASSERT_NE(-1, positionLocation);
4090     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
4091     glEnableVertexAttribArray(positionLocation);
4092 
4093     // Release program while its in use.
4094     glDeleteProgram(program);
4095 
4096     // Draw a red triangle
4097     glDrawArrays(GL_TRIANGLES, 0, 3);
4098 
4099     // Set color to green
4100     glUniform4f(uniformLoc, 1.0f, 0.0f, 0.0f, 1.0f);
4101 
4102     // Draw a green triangle
4103     glDrawArrays(GL_TRIANGLES, 0, 3);
4104 
4105     ASSERT_GL_NO_ERROR();
4106 
4107     glDisableVertexAttribArray(positionLocation);
4108 
4109     glUseProgram(0);
4110 
4111     // Verify we drew red in the end since thats the last draw.
4112     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, 0, GLColor::red);
4113 }
4114 
4115 // Tests that sampler sync isn't masked by program textures.
TEST_P(SimpleStateChangeTestES3,SamplerSyncNotTiedToProgram)4116 TEST_P(SimpleStateChangeTestES3, SamplerSyncNotTiedToProgram)
4117 {
4118     // Create a sampler with NEAREST filtering.
4119     GLSampler sampler;
4120     glBindSampler(0, sampler);
4121     glSamplerParameteri(sampler, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
4122     glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
4123     glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
4124     glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4125     glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4126     ASSERT_GL_NO_ERROR();
4127 
4128     // Draw with a program that uses no textures.
4129     ANGLE_GL_PROGRAM(program1, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
4130     drawQuad(program1, essl1_shaders::PositionAttrib(), 0.5f);
4131     ASSERT_GL_NO_ERROR();
4132     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
4133 
4134     // Create a simple texture with four colors and linear filtering.
4135     constexpr GLsizei kSize       = 2;
4136     std::array<GLColor, 4> pixels = {
4137         {GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow}};
4138     GLTexture redTex;
4139     glBindTexture(GL_TEXTURE_2D, redTex);
4140     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4141                  pixels.data());
4142     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
4143     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
4144     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
4145     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4146     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4147 
4148     // Create a program that uses the texture.
4149     constexpr char kVS[] = R"(attribute vec4 position;
4150 varying vec2 texCoord;
4151 void main()
4152 {
4153     gl_Position = position;
4154     texCoord = position.xy * 0.5 + vec2(0.5);
4155 })";
4156 
4157     constexpr char kFS[] = R"(precision mediump float;
4158 varying vec2 texCoord;
4159 uniform sampler2D tex;
4160 void main()
4161 {
4162     gl_FragColor = texture2D(tex, texCoord);
4163 })";
4164 
4165     // Draw. The sampler should override the clamp wrap mode with nearest.
4166     ANGLE_GL_PROGRAM(program2, kVS, kFS);
4167     ASSERT_EQ(0, glGetUniformLocation(program2, "tex"));
4168     drawQuad(program2, "position", 0.5f);
4169     ASSERT_GL_NO_ERROR();
4170 
4171     constexpr int kHalfSize = kWindowSize / 2;
4172 
4173     EXPECT_PIXEL_RECT_EQ(0, 0, kHalfSize, kHalfSize, GLColor::red);
4174     EXPECT_PIXEL_RECT_EQ(kHalfSize, 0, kHalfSize, kHalfSize, GLColor::green);
4175     EXPECT_PIXEL_RECT_EQ(0, kHalfSize, kHalfSize, kHalfSize, GLColor::blue);
4176     EXPECT_PIXEL_RECT_EQ(kHalfSize, kHalfSize, kHalfSize, kHalfSize, GLColor::yellow);
4177 }
4178 
4179 // Tests different samplers can be used with same texture obj on different tex units.
TEST_P(SimpleStateChangeTestES3,MultipleSamplersWithSingleTextureObject)4180 TEST_P(SimpleStateChangeTestES3, MultipleSamplersWithSingleTextureObject)
4181 {
4182     // Test overview - Create two separate sampler objects, initially with the same
4183     // sampling args (NEAREST). Bind the same texture object to separate texture units.
4184     // FS samples from two samplers and blends result.
4185     // Bind separate sampler objects to the same texture units as the texture object.
4186     // Render & verify initial results
4187     // Next modify sampler0 to have LINEAR filtering instead of NEAREST
4188     // Render and save results
4189     // Now restore sampler0 to NEAREST filtering and make sampler1 LINEAR
4190     // Render and verify results are the same as previous
4191 
4192     // Create 2 samplers with NEAREST filtering.
4193     constexpr GLsizei kNumSamplers = 2;
4194     // We create/bind an extra sampler w/o bound tex object for testing purposes
4195     GLSampler samplers[kNumSamplers + 1];
4196     // Set samplers to initially have same state w/ NEAREST filter mode
4197     for (uint32_t i = 0; i < kNumSamplers + 1; ++i)
4198     {
4199         glSamplerParameteri(samplers[i], GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
4200         glSamplerParameteri(samplers[i], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
4201         glSamplerParameteri(samplers[i], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
4202         glSamplerParameteri(samplers[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4203         glSamplerParameteri(samplers[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4204         glSamplerParameterf(samplers[i], GL_TEXTURE_MAX_LOD, 1000);
4205         glSamplerParameterf(samplers[i], GL_TEXTURE_MIN_LOD, -1000);
4206         glBindSampler(i, samplers[i]);
4207         ASSERT_GL_NO_ERROR();
4208     }
4209 
4210     // Create a simple texture with four colors
4211     constexpr GLsizei kSize       = 2;
4212     std::array<GLColor, 4> pixels = {
4213         {GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow}};
4214     GLTexture rgbyTex;
4215     // Bind same texture object to tex units 0 & 1
4216     glActiveTexture(GL_TEXTURE0);
4217     glBindTexture(GL_TEXTURE_2D, rgbyTex);
4218     glActiveTexture(GL_TEXTURE1);
4219     glBindTexture(GL_TEXTURE_2D, rgbyTex);
4220     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
4221                  pixels.data());
4222 
4223     // Create a program that uses the texture with 2 separate samplers.
4224     constexpr char kFS[] = R"(precision mediump float;
4225 varying vec2 v_texCoord;
4226 uniform sampler2D samp1;
4227 uniform sampler2D samp2;
4228 void main()
4229 {
4230     gl_FragColor = mix(texture2D(samp1, v_texCoord), texture2D(samp2, v_texCoord), 0.5);
4231 })";
4232 
4233     // Create program and bind samplers to tex units 0 & 1
4234     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), kFS);
4235     GLint s1loc = glGetUniformLocation(program, "samp1");
4236     GLint s2loc = glGetUniformLocation(program, "samp2");
4237     glUseProgram(program);
4238     glUniform1i(s1loc, 0);
4239     glUniform1i(s2loc, 1);
4240     // Draw. This first draw is a confidence check and not really necessary for the test
4241     drawQuad(program, std::string(essl1_shaders::PositionAttrib()), 0.5f);
4242     ASSERT_GL_NO_ERROR();
4243 
4244     constexpr int kHalfSize = kWindowSize / 2;
4245 
4246     // When rendering w/ NEAREST, colors are all maxed out so should still be solid
4247     EXPECT_PIXEL_RECT_EQ(0, 0, kHalfSize, kHalfSize, GLColor::red);
4248     EXPECT_PIXEL_RECT_EQ(kHalfSize, 0, kHalfSize, kHalfSize, GLColor::green);
4249     EXPECT_PIXEL_RECT_EQ(0, kHalfSize, kHalfSize, kHalfSize, GLColor::blue);
4250     EXPECT_PIXEL_RECT_EQ(kHalfSize, kHalfSize, kHalfSize, kHalfSize, GLColor::yellow);
4251 
4252     // Make first sampler use linear filtering
4253     glSamplerParameteri(samplers[0], GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4254     glSamplerParameteri(samplers[0], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4255 
4256     drawQuad(program, std::string(essl1_shaders::PositionAttrib()), 0.5f);
4257     ASSERT_GL_NO_ERROR();
4258     // Capture rendered pixel color with s0 linear
4259     std::vector<GLColor> s0LinearColors(kWindowSize * kWindowSize);
4260     glReadPixels(0, 0, kWindowSize, kWindowSize, GL_RGBA, GL_UNSIGNED_BYTE, s0LinearColors.data());
4261 
4262     // Now restore first sampler & update second sampler
4263     glSamplerParameteri(samplers[0], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4264     glSamplerParameteri(samplers[0], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4265     glSamplerParameteri(samplers[1], GL_TEXTURE_MIN_FILTER, GL_LINEAR);
4266     glSamplerParameteri(samplers[1], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
4267 
4268     drawQuad(program, std::string(essl1_shaders::PositionAttrib()), 0.5f);
4269     ASSERT_GL_NO_ERROR();
4270     // Capture rendered pixel color w/ s1 linear
4271     std::vector<GLColor> s1LinearColors(kWindowSize * kWindowSize);
4272     glReadPixels(0, 0, kWindowSize, kWindowSize, GL_RGBA, GL_UNSIGNED_BYTE, s1LinearColors.data());
4273     // Results should be the same regardless of if s0 or s1 is linear
4274     EXPECT_EQ(s0LinearColors, s1LinearColors);
4275 }
4276 
4277 // Tests that rendering works as expected with multiple VAOs.
TEST_P(SimpleStateChangeTestES31,MultipleVertexArrayObjectRendering)4278 TEST_P(SimpleStateChangeTestES31, MultipleVertexArrayObjectRendering)
4279 {
4280     constexpr char kVertexShader[] = R"(attribute vec4 a_position;
4281 attribute vec4 a_color;
4282 varying vec4 v_color;
4283 void main()
4284 {
4285     gl_Position = a_position;
4286     v_color = a_color;
4287 })";
4288 
4289     constexpr char kFragmentShader[] = R"(precision mediump float;
4290 varying vec4 v_color;
4291 void main()
4292 {
4293     gl_FragColor = v_color;
4294 })";
4295 
4296     ANGLE_GL_PROGRAM(mProgram, kVertexShader, kFragmentShader);
4297     GLint positionLoc = glGetAttribLocation(mProgram, "a_position");
4298     ASSERT_NE(-1, positionLoc);
4299     GLint colorLoc = glGetAttribLocation(mProgram, "a_color");
4300     ASSERT_NE(-1, colorLoc);
4301 
4302     GLVertexArray VAOS[2];
4303     GLBuffer positionBuffer;
4304     GLBuffer colorBuffer;
4305     const auto quadVertices = GetQuadVertices();
4306 
4307     glBindVertexArray(VAOS[0]);
4308     glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
4309     glBufferData(GL_ARRAY_BUFFER, quadVertices.size() * sizeof(Vector3), quadVertices.data(),
4310                  GL_STATIC_DRAW);
4311     glEnableVertexAttribArray(positionLoc);
4312     glVertexAttribPointer(positionLoc, 3, GL_BYTE, GL_FALSE, 0, 0);
4313 
4314     glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
4315     std::vector<GLColor32F> blueColor(6, kFloatBlue);
4316     glBufferData(GL_ARRAY_BUFFER, blueColor.size() * sizeof(GLColor32F), blueColor.data(),
4317                  GL_STATIC_DRAW);
4318     glEnableVertexAttribArray(colorLoc);
4319     glVertexAttribPointer(colorLoc, 4, GL_BYTE, GL_FALSE, 0, 0);
4320 
4321     glBindVertexArray(0);
4322     glBindBuffer(GL_ARRAY_BUFFER, 0);
4323 
4324     glBindVertexArray(VAOS[1]);
4325     glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
4326     glBufferData(GL_ARRAY_BUFFER, quadVertices.size() * sizeof(Vector3), quadVertices.data(),
4327                  GL_STATIC_DRAW);
4328     glEnableVertexAttribArray(positionLoc);
4329     glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);
4330 
4331     glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
4332     std::vector<GLColor32F> greenColor(6, kFloatGreen);
4333     glBufferData(GL_ARRAY_BUFFER, greenColor.size() * sizeof(GLColor32F), greenColor.data(),
4334                  GL_STATIC_DRAW);
4335     glEnableVertexAttribArray(colorLoc);
4336     glVertexAttribPointer(colorLoc, 4, GL_FLOAT, GL_FALSE, 0, 0);
4337 
4338     glBindVertexArray(0);
4339     glBindBuffer(GL_ARRAY_BUFFER, 0);
4340 
4341     glUseProgram(mProgram);
4342     ASSERT_GL_NO_ERROR();
4343 
4344     glBindVertexArray(VAOS[1]);
4345     glClear(GL_COLOR_BUFFER_BIT);
4346     glDrawArrays(GL_TRIANGLES, 0, 6);
4347 
4348     // This drawing should not affect the next drawing.
4349     glBindVertexArray(VAOS[0]);
4350     glClear(GL_COLOR_BUFFER_BIT);
4351     glDrawArrays(GL_TRIANGLES, 0, 6);
4352 
4353     glBindVertexArray(VAOS[1]);
4354     glClear(GL_COLOR_BUFFER_BIT);
4355     glDrawArrays(GL_TRIANGLES, 0, 6);
4356 
4357     EXPECT_GL_NO_ERROR();
4358     EXPECT_PIXEL_COLOR_EQ(0, getWindowHeight() / 2, GLColor::green);
4359     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::green);
4360     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4361     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, 0, GLColor::green);
4362 
4363     ASSERT_GL_NO_ERROR();
4364 }
4365 
4366 // Tests that consecutive identical draw calls that write to an image in the fragment shader work
4367 // correctly.  This requires a memory barrier in between the draw calls which should not be
4368 // reordered w.r.t the calls.
TEST_P(SimpleStateChangeTestES31,DrawWithImageTextureThenDrawAgain)4369 TEST_P(SimpleStateChangeTestES31, DrawWithImageTextureThenDrawAgain)
4370 {
4371     // http://anglebug.com/5593
4372     ANGLE_SKIP_TEST_IF(IsD3D11());
4373 
4374     GLint maxFragmentImageUniforms;
4375     glGetIntegerv(GL_MAX_FRAGMENT_IMAGE_UNIFORMS, &maxFragmentImageUniforms);
4376 
4377     ANGLE_SKIP_TEST_IF(maxFragmentImageUniforms < 1);
4378 
4379     // The test uses a GL_R32F framebuffer.
4380     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_color_buffer_float"));
4381 
4382     constexpr GLsizei kSize = 1;
4383 
4384     GLTexture color;
4385     glBindTexture(GL_TEXTURE_2D, color);
4386     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
4387     EXPECT_GL_NO_ERROR();
4388 
4389     GLFramebuffer fbo;
4390     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4391     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
4392     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4393     EXPECT_GL_NO_ERROR();
4394 
4395     const float kInitialValue = 0.125f;
4396 
4397     GLTexture texture;
4398     glBindTexture(GL_TEXTURE_2D, texture);
4399     glTexStorage2D(GL_TEXTURE_2D, 1, GL_R32F, kSize, kSize);
4400     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RED, GL_FLOAT, &kInitialValue);
4401     EXPECT_GL_NO_ERROR();
4402 
4403     GLFramebuffer readbackFbo;
4404     glBindFramebuffer(GL_READ_FRAMEBUFFER, readbackFbo);
4405     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
4406     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_READ_FRAMEBUFFER);
4407     EXPECT_GL_NO_ERROR();
4408 
4409     // Create a program that outputs to the image in the fragment shader.
4410     constexpr char kFS[] = R"(#version 310 es
4411 precision mediump float;
4412 layout(r32f, binding = 0) uniform highp image2D dst;
4413 out vec4 colorOut;
4414 void main()
4415 {
4416     vec4 result = imageLoad(dst, ivec2(gl_FragCoord.xy));
4417     colorOut = result;
4418 
4419     result.x += 0.193;
4420     imageStore(dst, ivec2(gl_FragCoord.xy), result);
4421 })";
4422 
4423     ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Simple(), kFS);
4424     glUseProgram(program);
4425 
4426     GLint positionLoc = glGetAttribLocation(program, essl31_shaders::PositionAttrib());
4427     ASSERT_NE(-1, positionLoc);
4428 
4429     glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R32F);
4430     EXPECT_GL_NO_ERROR();
4431 
4432     // Setup the draw so that there's no state change between the draw calls.
4433     const std::array<Vector3, 6> &quadVertices = GetQuadVertices();
4434     const size_t posBufferSize                 = quadVertices.size() * sizeof(Vector3);
4435 
4436     GLBuffer posBuffer;
4437     glBindBuffer(GL_ARRAY_BUFFER, posBuffer);
4438     glBufferData(GL_ARRAY_BUFFER, posBufferSize, quadVertices.data(), GL_STATIC_DRAW);
4439     glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
4440     glEnableVertexAttribArray(positionLoc);
4441     EXPECT_GL_NO_ERROR();
4442 
4443     glDrawArrays(GL_TRIANGLES, 0, 6);
4444     glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
4445     glDrawArrays(GL_TRIANGLES, 0, 6);
4446     EXPECT_GL_NO_ERROR();
4447 
4448     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
4449     EXPECT_GL_NO_ERROR();
4450 
4451     // Verify the output of the two draw calls through the image is correct
4452     EXPECT_PIXEL_COLOR32F_NEAR(0, 0, GLColor32F(kInitialValue + 0.193f * 2, 0.0f, 0.0f, 1.0f),
4453                                0.001f);
4454 
4455     // Verify the output of rendering as well
4456     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
4457     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(81, 0, 0, 255), 1);
4458 }
4459 
4460 // Tests that sampling from a texture in one draw call followed by writing to its image in another
4461 // draw call works correctly.  This requires a barrier in between the draw calls.
TEST_P(SimpleStateChangeTestES31,DrawWithTextureThenDrawWithImage)4462 TEST_P(SimpleStateChangeTestES31, DrawWithTextureThenDrawWithImage)
4463 {
4464     // http://anglebug.com/5593
4465     ANGLE_SKIP_TEST_IF(IsD3D11());
4466     // http://anglebug.com/5686
4467     ANGLE_SKIP_TEST_IF(IsWindows() && IsIntel() && IsDesktopOpenGL());
4468 
4469     GLint maxFragmentImageUniforms;
4470     glGetIntegerv(GL_MAX_FRAGMENT_IMAGE_UNIFORMS, &maxFragmentImageUniforms);
4471 
4472     ANGLE_SKIP_TEST_IF(maxFragmentImageUniforms < 1);
4473 
4474     constexpr GLsizei kSize = 1;
4475 
4476     GLTexture color;
4477     glBindTexture(GL_TEXTURE_2D, color);
4478     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
4479     EXPECT_GL_NO_ERROR();
4480 
4481     GLFramebuffer fbo;
4482     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4483     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
4484     EXPECT_GL_NO_ERROR();
4485 
4486     const GLColor kInitialColor = GLColor::red;
4487 
4488     GLTexture texture;
4489     glBindTexture(GL_TEXTURE_2D, texture);
4490     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
4491     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGBA, GL_UNSIGNED_BYTE,
4492                     &kInitialColor);
4493     EXPECT_GL_NO_ERROR();
4494 
4495     GLFramebuffer readbackFbo;
4496     glBindFramebuffer(GL_READ_FRAMEBUFFER, readbackFbo);
4497     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
4498     EXPECT_GL_NO_ERROR();
4499 
4500     // Create a program that samples from the texture in the fragment shader.
4501     constexpr char kFSSample[] = R"(#version 310 es
4502 precision mediump float;
4503 uniform sampler2D tex;
4504 out vec4 colorOut;
4505 void main()
4506 {
4507     colorOut = texture(tex, vec2(0));
4508 })";
4509     ANGLE_GL_PROGRAM(sampleProgram, essl31_shaders::vs::Simple(), kFSSample);
4510 
4511     // Create a program that outputs to the image in the fragment shader.
4512     constexpr char kFSWrite[] = R"(#version 310 es
4513 precision mediump float;
4514 layout(rgba8, binding = 0) uniform highp writeonly image2D dst;
4515 out vec4 colorOut;
4516 void main()
4517 {
4518     colorOut = vec4(0, 0, 1.0, 0);
4519     imageStore(dst, ivec2(gl_FragCoord.xy), vec4(0.0, 1.0, 0.0, 1.0));
4520 })";
4521 
4522     ANGLE_GL_PROGRAM(writeProgram, essl31_shaders::vs::Simple(), kFSWrite);
4523 
4524     glUseProgram(sampleProgram);
4525     GLint positionLocSample = glGetAttribLocation(sampleProgram, essl31_shaders::PositionAttrib());
4526     ASSERT_NE(-1, positionLocSample);
4527 
4528     glUseProgram(writeProgram);
4529     GLint positionLocWrite = glGetAttribLocation(writeProgram, essl31_shaders::PositionAttrib());
4530     ASSERT_NE(-1, positionLocWrite);
4531 
4532     glBindImageTexture(0, texture, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
4533 
4534     // Setup the draw so that there's no state change between the draw calls.
4535     const std::array<Vector3, 6> &quadVertices = GetQuadVertices();
4536     const size_t posBufferSize                 = quadVertices.size() * sizeof(Vector3);
4537 
4538     GLBuffer posBuffer;
4539     glBindBuffer(GL_ARRAY_BUFFER, posBuffer);
4540     glBufferData(GL_ARRAY_BUFFER, posBufferSize, quadVertices.data(), GL_STATIC_DRAW);
4541     glVertexAttribPointer(positionLocSample, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
4542     glVertexAttribPointer(positionLocWrite, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
4543     glEnableVertexAttribArray(positionLocSample);
4544     glEnableVertexAttribArray(positionLocWrite);
4545 
4546     glUseProgram(sampleProgram);
4547     glDrawArrays(GL_TRIANGLES, 0, 6);
4548 
4549     glEnable(GL_BLEND);
4550     glBlendFunc(GL_ONE, GL_ONE);
4551     glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
4552 
4553     glUseProgram(writeProgram);
4554     glDrawArrays(GL_TRIANGLES, 0, 6);
4555 
4556     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
4557     EXPECT_GL_NO_ERROR();
4558 
4559     // Verify the output of the two draw calls through the image is correct
4560     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
4561 
4562     // Verify the output of rendering as well
4563     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
4564     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);
4565 }
4566 
4567 // Tests that reading from a ubo in one draw call followed by writing to it as SSBO in another draw
4568 // call works correctly.  This requires a barrier in between the draw calls.
TEST_P(SimpleStateChangeTestES31,DrawWithUBOThenDrawWithSSBO)4569 TEST_P(SimpleStateChangeTestES31, DrawWithUBOThenDrawWithSSBO)
4570 {
4571     GLint maxFragmentShaderStorageBlocks;
4572     glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &maxFragmentShaderStorageBlocks);
4573 
4574     ANGLE_SKIP_TEST_IF(maxFragmentShaderStorageBlocks < 1);
4575 
4576     constexpr GLsizei kSize = 1;
4577 
4578     GLTexture color;
4579     glBindTexture(GL_TEXTURE_2D, color);
4580     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
4581     EXPECT_GL_NO_ERROR();
4582 
4583     GLFramebuffer fbo;
4584     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4585     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
4586     EXPECT_GL_NO_ERROR();
4587 
4588     constexpr std::array<float, 4> kBufferInitValue = {0.125f, 0.25f, 0.5f, 1.0f};
4589     GLBuffer buffer;
4590     glBindBuffer(GL_UNIFORM_BUFFER, buffer);
4591     glBufferData(GL_UNIFORM_BUFFER, sizeof(kBufferInitValue), kBufferInitValue.data(),
4592                  GL_STATIC_DRAW);
4593     glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);
4594 
4595     glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
4596     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffer);
4597 
4598     // Create a program that reads from the ubo in the fragment shader.
4599     constexpr char kFSRead[] = R"(#version 310 es
4600 precision mediump float;
4601 uniform block { vec4 vec; } b;
4602 out vec4 colorOut;
4603 void main()
4604 {
4605     colorOut = b.vec;
4606 })";
4607     ANGLE_GL_PROGRAM(readProgram, essl31_shaders::vs::Simple(), kFSRead);
4608 
4609     // Create a program that outputs to the image in the fragment shader.
4610     constexpr char kFSWrite[] = R"(#version 310 es
4611 precision mediump float;
4612 layout(binding = 0, std430) buffer Output {
4613     vec4 vec;
4614 } b;
4615 out vec4 colorOut;
4616 void main()
4617 {
4618     b.vec = vec4(0.7, 0.6, 0.4, 0.3);
4619     colorOut = vec4(0.125, 0.125, 0.125, 0);
4620 })";
4621 
4622     ANGLE_GL_PROGRAM(writeProgram, essl31_shaders::vs::Simple(), kFSWrite);
4623 
4624     glUseProgram(readProgram);
4625     GLint positionLocRead = glGetAttribLocation(readProgram, essl31_shaders::PositionAttrib());
4626     ASSERT_NE(-1, positionLocRead);
4627 
4628     glUseProgram(writeProgram);
4629     GLint positionLocWrite = glGetAttribLocation(writeProgram, essl31_shaders::PositionAttrib());
4630     ASSERT_NE(-1, positionLocWrite);
4631 
4632     // Setup the draw so that there's no state change between the draw calls.
4633     const std::array<Vector3, 6> &quadVertices = GetQuadVertices();
4634     const size_t posBufferSize                 = quadVertices.size() * sizeof(Vector3);
4635 
4636     GLBuffer posBuffer;
4637     glBindBuffer(GL_ARRAY_BUFFER, posBuffer);
4638     glBufferData(GL_ARRAY_BUFFER, posBufferSize, quadVertices.data(), GL_STATIC_DRAW);
4639     glVertexAttribPointer(positionLocRead, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
4640     glVertexAttribPointer(positionLocWrite, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
4641     glEnableVertexAttribArray(positionLocRead);
4642     glEnableVertexAttribArray(positionLocWrite);
4643 
4644     glUseProgram(readProgram);
4645     glDrawArrays(GL_TRIANGLES, 0, 6);
4646 
4647     glEnable(GL_BLEND);
4648     glBlendFunc(GL_ONE, GL_ONE);
4649     glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
4650 
4651     glUseProgram(writeProgram);
4652     glDrawArrays(GL_TRIANGLES, 0, 6);
4653 
4654     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
4655     EXPECT_GL_NO_ERROR();
4656 
4657     // Verify the output of rendering
4658     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(63, 95, 159, 255), 1);
4659 
4660     // Verify the output from the second draw call
4661     const float *ptr = reinterpret_cast<const float *>(
4662         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(kBufferInitValue), GL_MAP_READ_BIT));
4663 
4664     EXPECT_NEAR(ptr[0], 0.7f, 0.001);
4665     EXPECT_NEAR(ptr[1], 0.6f, 0.001);
4666     EXPECT_NEAR(ptr[2], 0.4f, 0.001);
4667     EXPECT_NEAR(ptr[3], 0.3f, 0.001);
4668 
4669     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
4670 }
4671 
4672 // Tests that writing to an SSBO in the fragment shader before and after a change to the drawbuffers
4673 // still works
TEST_P(SimpleStateChangeTestES31,FragWriteSSBOThenChangeDrawbuffersThenWriteSSBO)4674 TEST_P(SimpleStateChangeTestES31, FragWriteSSBOThenChangeDrawbuffersThenWriteSSBO)
4675 {
4676     GLint maxFragmentShaderStorageBlocks;
4677     glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &maxFragmentShaderStorageBlocks);
4678 
4679     ANGLE_SKIP_TEST_IF(maxFragmentShaderStorageBlocks < 1);
4680 
4681     constexpr GLsizei kSize = 1;
4682 
4683     GLTexture color;
4684     glBindTexture(GL_TEXTURE_2D, color);
4685     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
4686     EXPECT_GL_NO_ERROR();
4687 
4688     GLFramebuffer fbo;
4689     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4690     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
4691     EXPECT_GL_NO_ERROR();
4692 
4693     constexpr std::array<float, 4> kBufferInitValue = {0.125f, 0.25f, 0.5f, 1.0f};
4694     GLBuffer buffer;
4695     glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
4696     glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(kBufferInitValue), kBufferInitValue.data(),
4697                  GL_STATIC_DRAW);
4698     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffer);
4699 
4700     // Create a program that writes to the SSBO in the fragment shader.
4701     constexpr char kFS[] = R"(#version 310 es
4702 precision mediump float;
4703 layout(binding = 0, std430) buffer Output {
4704     vec4 value;
4705 } b;
4706 out vec4 colorOut;
4707 uniform vec4 value;
4708 void main()
4709 {
4710     b.value = value;
4711     colorOut = vec4(1, 1, 1, 0);
4712 })";
4713 
4714     GLuint vs = CompileShader(GL_VERTEX_SHADER, essl31_shaders::vs::Simple());
4715     GLuint fs = CompileShader(GL_FRAGMENT_SHADER, kFS);
4716 
4717     const GLuint program = glCreateProgram();
4718     glAttachShader(program, vs);
4719     glAttachShader(program, fs);
4720     glLinkProgram(program);
4721     CheckLinkStatusAndReturnProgram(program, true);
4722 
4723     // Detach the shaders, so any draw-time shader rewriting won't be able to use them.
4724     glDetachShader(program, vs);
4725     glDetachShader(program, fs);
4726 
4727     glUseProgram(program);
4728     GLint positionLoc = glGetAttribLocation(program, essl31_shaders::PositionAttrib());
4729     ASSERT_NE(-1, positionLoc);
4730     GLint valueLoc = glGetUniformLocation(program, "value");
4731     ASSERT_NE(-1, valueLoc);
4732 
4733     const std::array<Vector3, 6> &quadVertices = GetQuadVertices();
4734     const size_t posBufferSize                 = quadVertices.size() * sizeof(Vector3);
4735 
4736     GLBuffer posBuffer;
4737     glBindBuffer(GL_ARRAY_BUFFER, posBuffer);
4738     glBufferData(GL_ARRAY_BUFFER, posBufferSize, quadVertices.data(), GL_STATIC_DRAW);
4739     glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
4740     glEnableVertexAttribArray(positionLoc);
4741 
4742     glUseProgram(program);
4743     constexpr float kValue1[4] = {0.1f, 0.2f, 0.3f, 0.4f};
4744 
4745     glUniform4fv(valueLoc, 1, kValue1);
4746     glDrawArrays(GL_TRIANGLES, 0, 6);
4747     glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
4748     EXPECT_GL_NO_ERROR();
4749 
4750     // Verify that the program wrote the SSBO correctly.
4751     const float *ptr = reinterpret_cast<const float *>(
4752         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(kBufferInitValue), GL_MAP_READ_BIT));
4753 
4754     for (int i = 0; i < 4; ++i)
4755     {
4756         EXPECT_NEAR(ptr[i], kValue1[i], 0.001);
4757     }
4758 
4759     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
4760 
4761     GLenum drawBuffers[] = {GL_NONE};
4762     glDrawBuffers(1, drawBuffers);
4763 
4764     constexpr float kValue2[4] = {0.5f, 0.6f, 0.7f, 0.9f};
4765     glUniform4fv(valueLoc, 1, kValue2);
4766     glDrawArrays(GL_TRIANGLES, 0, 6);
4767     glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
4768     EXPECT_GL_NO_ERROR();
4769     // Verify that the program wrote the SSBO correctly.
4770     ptr = reinterpret_cast<const float *>(
4771         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(kBufferInitValue), GL_MAP_READ_BIT));
4772 
4773     for (int i = 0; i < 4; ++i)
4774     {
4775         EXPECT_NEAR(ptr[i], kValue2[i], 0.001);
4776     }
4777 
4778     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
4779 }
4780 
4781 // Tests that writing to an SSBO in the vertex shader before and after a change to the drawbuffers
4782 // still works
TEST_P(SimpleStateChangeTestES31,VertWriteSSBOThenChangeDrawbuffersThenWriteSSBO)4783 TEST_P(SimpleStateChangeTestES31, VertWriteSSBOThenChangeDrawbuffersThenWriteSSBO)
4784 {
4785     GLint maxVertexShaderStorageBlocks;
4786     glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &maxVertexShaderStorageBlocks);
4787 
4788     ANGLE_SKIP_TEST_IF(maxVertexShaderStorageBlocks < 1);
4789 
4790     constexpr GLsizei kSize = 1;
4791 
4792     GLTexture color;
4793     glBindTexture(GL_TEXTURE_2D, color);
4794     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
4795     EXPECT_GL_NO_ERROR();
4796 
4797     GLFramebuffer fbo;
4798     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4799     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
4800     EXPECT_GL_NO_ERROR();
4801 
4802     constexpr std::array<float, 4> kBufferInitValue = {0.125f, 0.25f, 0.5f, 1.0f};
4803     GLBuffer buffer;
4804     glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
4805     glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(kBufferInitValue), kBufferInitValue.data(),
4806                  GL_STATIC_DRAW);
4807     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffer);
4808 
4809     // Create a program that writes to the SSBO in the vertex shader.
4810     constexpr char kVS[] = R"(#version 310 es
4811 in vec4 a_position;
4812 uniform vec4 value;
4813 layout(binding = 0, std430) buffer Output {
4814     vec4 value;
4815 } b;
4816 void main()
4817 {
4818     b.value = value;
4819     gl_Position = a_position;
4820 })";
4821 
4822     GLuint vs = CompileShader(GL_VERTEX_SHADER, kVS);
4823     GLuint fs = CompileShader(GL_FRAGMENT_SHADER, essl31_shaders::fs::Green());
4824 
4825     const GLuint program = glCreateProgram();
4826     glAttachShader(program, vs);
4827     glAttachShader(program, fs);
4828     glLinkProgram(program);
4829     CheckLinkStatusAndReturnProgram(program, true);
4830 
4831     // Detach the shaders, so any draw-time shader rewriting won't be able to use them.
4832     glDetachShader(program, vs);
4833     glDetachShader(program, fs);
4834 
4835     glUseProgram(program);
4836     GLint positionLoc = glGetAttribLocation(program, essl31_shaders::PositionAttrib());
4837     ASSERT_NE(-1, positionLoc);
4838     GLint valueLoc = glGetUniformLocation(program, "value");
4839     ASSERT_NE(-1, valueLoc);
4840 
4841     const std::array<Vector3, 6> &quadVertices = GetQuadVertices();
4842     const size_t posBufferSize                 = quadVertices.size() * sizeof(Vector3);
4843 
4844     GLBuffer posBuffer;
4845     glBindBuffer(GL_ARRAY_BUFFER, posBuffer);
4846     glBufferData(GL_ARRAY_BUFFER, posBufferSize, quadVertices.data(), GL_STATIC_DRAW);
4847     glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
4848     glEnableVertexAttribArray(positionLoc);
4849 
4850     glUseProgram(program);
4851     constexpr float kValue1[4] = {0.1f, 0.2f, 0.3f, 0.4f};
4852 
4853     glUniform4fv(valueLoc, 1, kValue1);
4854     glDrawArrays(GL_TRIANGLES, 0, 6);
4855     glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
4856     EXPECT_GL_NO_ERROR();
4857 
4858     // Verify that the program wrote the SSBO correctly.
4859     const float *ptr = reinterpret_cast<const float *>(
4860         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(kBufferInitValue), GL_MAP_READ_BIT));
4861 
4862     for (int i = 0; i < 4; ++i)
4863     {
4864         EXPECT_NEAR(ptr[i], kValue1[i], 0.001);
4865     }
4866 
4867     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
4868 
4869     GLenum drawBuffers[] = {GL_NONE};
4870     glDrawBuffers(1, drawBuffers);
4871 
4872     constexpr float kValue2[4] = {0.5f, 0.6f, 0.7f, 0.9f};
4873     glUniform4fv(valueLoc, 1, kValue2);
4874     glDrawArrays(GL_TRIANGLES, 0, 6);
4875     glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
4876     EXPECT_GL_NO_ERROR();
4877     // Verify that the program wrote the SSBO correctly.
4878     ptr = reinterpret_cast<const float *>(
4879         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(kBufferInitValue), GL_MAP_READ_BIT));
4880 
4881     for (int i = 0; i < 4; ++i)
4882     {
4883         EXPECT_NEAR(ptr[i], kValue2[i], 0.001);
4884     }
4885 
4886     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
4887 }
4888 
4889 // Tests that rendering to a texture in one draw call followed by sampling from it in a dispatch
4890 // call works correctly.  This requires an implicit barrier in between the calls.
TEST_P(SimpleStateChangeTestES31,DrawThenSampleWithCompute)4891 TEST_P(SimpleStateChangeTestES31, DrawThenSampleWithCompute)
4892 {
4893     // TODO(anglebug.com/5649): Test is failing since it was introduced on Linux AMD GLES
4894     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsAMD() && IsLinux());
4895 
4896     constexpr GLsizei kSize = 1;
4897     const GLColor kInitColor(111, 222, 33, 44);
4898 
4899     GLTexture color;
4900     glBindTexture(GL_TEXTURE_2D, color);
4901     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
4902     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4903     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4904     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGBA, GL_UNSIGNED_BYTE, &kInitColor);
4905     EXPECT_GL_NO_ERROR();
4906 
4907     GLFramebuffer fbo;
4908     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4909     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
4910     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4911     EXPECT_GL_NO_ERROR();
4912 
4913     constexpr std::array<float, 4> kBufferInitValue = {0.123f, 0.456f, 0.789f, 0.852f};
4914     GLBuffer buffer;
4915     glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
4916     glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(kBufferInitValue), kBufferInitValue.data(),
4917                  GL_STATIC_DRAW);
4918     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffer);
4919     EXPECT_GL_NO_ERROR();
4920 
4921     ANGLE_GL_PROGRAM(drawProgram, essl31_shaders::vs::Simple(), essl31_shaders::fs::Red());
4922 
4923     constexpr char kCS[] = R"(#version 310 es
4924 layout(local_size_x=1, local_size_y=1) in;
4925 uniform sampler2D tex;
4926 layout(binding = 0, std430) buffer Output {
4927     vec4 vec;
4928 } b;
4929 void main()
4930 {
4931     b.vec = texelFetch(tex, ivec2(gl_LocalInvocationID.xy), 0);
4932 })";
4933 
4934     ANGLE_GL_COMPUTE_PROGRAM(readProgram, kCS);
4935     glUseProgram(readProgram);
4936 
4937     glActiveTexture(GL_TEXTURE0);
4938     glUniform1i(glGetUniformLocation(readProgram, "tex"), 0);
4939 
4940     drawQuad(drawProgram, essl31_shaders::PositionAttrib(), 0.5f);
4941     EXPECT_GL_NO_ERROR();
4942 
4943     glUseProgram(readProgram);
4944     glDispatchCompute(1, 1, 1);
4945 
4946     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
4947     EXPECT_GL_NO_ERROR();
4948 
4949     // Verify the output of rendering
4950     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
4951 
4952     // Verify the output from the compute shader
4953     const float *ptr = reinterpret_cast<const float *>(
4954         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(kBufferInitValue), GL_MAP_READ_BIT));
4955 
4956     EXPECT_EQ(ptr[0], 1.0f);
4957     EXPECT_EQ(ptr[1], 0.0f);
4958     EXPECT_EQ(ptr[2], 0.0f);
4959     EXPECT_EQ(ptr[3], 1.0f);
4960 
4961     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
4962 }
4963 
4964 // Tests that clearing a texture followed by sampling from it in a dispatch call works correctly.
4965 // In the Vulkan backend, the clear is deferred and should be flushed correctly.
TEST_P(SimpleStateChangeTestES31,ClearThenSampleWithCompute)4966 TEST_P(SimpleStateChangeTestES31, ClearThenSampleWithCompute)
4967 {
4968     // http://anglebug.com/5687
4969     ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsDesktopOpenGL());
4970 
4971     constexpr GLsizei kSize = 1;
4972 
4973     GLTexture color;
4974     glBindTexture(GL_TEXTURE_2D, color);
4975     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
4976     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
4977     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
4978     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
4979     EXPECT_GL_NO_ERROR();
4980 
4981     GLFramebuffer fbo;
4982     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
4983     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
4984     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
4985     EXPECT_GL_NO_ERROR();
4986 
4987     // Make sure the update to the texture is effective.
4988     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
4989 
4990     // Clear the texture through the framebuffer
4991     glClearColor(0, 1.0f, 0, 1.0f);
4992     glClear(GL_COLOR_BUFFER_BIT);
4993 
4994     constexpr std::array<float, 4> kBufferInitValue = {0.123f, 0.456f, 0.789f, 0.852f};
4995     GLBuffer buffer;
4996     glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
4997     glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(kBufferInitValue), kBufferInitValue.data(),
4998                  GL_STATIC_DRAW);
4999     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, buffer);
5000     EXPECT_GL_NO_ERROR();
5001 
5002     constexpr char kCS[] = R"(#version 310 es
5003 layout(local_size_x=1, local_size_y=1) in;
5004 uniform sampler2D tex;
5005 layout(binding = 0, std430) buffer Output {
5006     vec4 vec;
5007 } b;
5008 void main()
5009 {
5010     b.vec = texelFetch(tex, ivec2(gl_LocalInvocationID.xy), 0);
5011 })";
5012 
5013     ANGLE_GL_COMPUTE_PROGRAM(readProgram, kCS);
5014     glUseProgram(readProgram);
5015 
5016     glActiveTexture(GL_TEXTURE0);
5017     glUniform1i(glGetUniformLocation(readProgram, "tex"), 0);
5018 
5019     glUseProgram(readProgram);
5020     glDispatchCompute(1, 1, 1);
5021 
5022     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
5023     EXPECT_GL_NO_ERROR();
5024 
5025     // Verify the clear
5026     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5027 
5028     // Verify the output from the compute shader
5029     const float *ptr = reinterpret_cast<const float *>(
5030         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(kBufferInitValue), GL_MAP_READ_BIT));
5031 
5032     EXPECT_EQ(ptr[0], 0.0f);
5033     EXPECT_EQ(ptr[1], 1.0f);
5034     EXPECT_EQ(ptr[2], 0.0f);
5035     EXPECT_EQ(ptr[3], 1.0f);
5036 
5037     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
5038 }
5039 
5040 // Tests that writing to a buffer with transform feedback in one draw call followed by reading from
5041 // it in a dispatch call works correctly.  This requires an implicit barrier in between the calls.
TEST_P(SimpleStateChangeTestES31,TransformFeedbackThenReadWithCompute)5042 TEST_P(SimpleStateChangeTestES31, TransformFeedbackThenReadWithCompute)
5043 {
5044     // http://anglebug.com/5687
5045     ANGLE_SKIP_TEST_IF(IsAMD() && IsVulkan());
5046 
5047     constexpr GLsizei kBufferSize = sizeof(float) * 4 * 6;
5048     GLBuffer buffer;
5049     glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buffer);
5050     glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, kBufferSize, nullptr, GL_STATIC_DRAW);
5051     glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buffer);
5052 
5053     std::vector<std::string> tfVaryings = {"gl_Position"};
5054     ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(program, essl3_shaders::vs::Simple(),
5055                                         essl3_shaders::fs::Green(), tfVaryings,
5056                                         GL_INTERLEAVED_ATTRIBS);
5057     glUseProgram(program);
5058 
5059     glBeginTransformFeedback(GL_TRIANGLES);
5060     drawQuad(program, essl3_shaders::PositionAttrib(), 0.0f);
5061     glEndTransformFeedback();
5062 
5063     constexpr char kCS[] = R"(#version 310 es
5064 layout(local_size_x=1, local_size_y=1) in;
5065 layout(binding = 0) uniform Input
5066 {
5067     vec4 data[3];
5068 };
5069 layout(binding = 0, std430) buffer Output {
5070     bool pass;
5071 };
5072 void main()
5073 {
5074     pass = data[0] == vec4(-1, 1, 0, 1) &&
5075            data[1] == vec4(-1, -1, 0, 1) &&
5076            data[2] == vec4(1, -1, 0, 1);
5077 })";
5078 
5079     ANGLE_GL_COMPUTE_PROGRAM(readProgram, kCS);
5080     glUseProgram(readProgram);
5081 
5082     glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);
5083 
5084     constexpr GLsizei kResultSize = sizeof(uint32_t);
5085     GLBuffer resultBuffer;
5086     glBindBuffer(GL_SHADER_STORAGE_BUFFER, resultBuffer);
5087     glBufferData(GL_SHADER_STORAGE_BUFFER, kResultSize, nullptr, GL_STATIC_DRAW);
5088     glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, resultBuffer);
5089 
5090     glDispatchCompute(1, 1, 1);
5091 
5092     glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
5093     EXPECT_GL_NO_ERROR();
5094 
5095     // Verify the output of rendering
5096     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5097 
5098     // Verify the output from the compute shader
5099     const uint32_t *ptr = reinterpret_cast<const uint32_t *>(
5100         glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, kResultSize, GL_MAP_READ_BIT));
5101 
5102     EXPECT_EQ(ptr[0], 1u);
5103 
5104     glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
5105 }
5106 
5107 // Tests that deleting an in-flight image texture does not immediately delete the resource.
TEST_P(SimpleStateChangeTestComputeES31,DeleteImageTextureInUse)5108 TEST_P(SimpleStateChangeTestComputeES31, DeleteImageTextureInUse)
5109 {
5110     std::array<GLColor, 4> colors = {
5111         {GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow}};
5112     GLTexture texRead;
5113     glBindTexture(GL_TEXTURE_2D, texRead);
5114     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2);
5115     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
5116     EXPECT_GL_NO_ERROR();
5117 
5118     glUseProgram(mProgram);
5119 
5120     glBindImageTexture(0, texRead, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
5121     glDispatchCompute(1, 1, 1);
5122     texRead.reset();
5123 
5124     std::array<GLColor, 4> results;
5125     glReadPixels(0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, results.data());
5126     EXPECT_GL_NO_ERROR();
5127 
5128     for (int i = 0; i < 4; i++)
5129     {
5130         EXPECT_EQ(colors[i], results[i]);
5131     }
5132 }
5133 
5134 // Tests that bind the same image texture all the time between different dispatch calls.
TEST_P(SimpleStateChangeTestComputeES31,RebindImageTextureDispatchAgain)5135 TEST_P(SimpleStateChangeTestComputeES31, RebindImageTextureDispatchAgain)
5136 {
5137     std::array<GLColor, 4> colors = {{GLColor::cyan, GLColor::cyan, GLColor::cyan, GLColor::cyan}};
5138     GLTexture texRead;
5139     glBindTexture(GL_TEXTURE_2D, texRead);
5140     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2);
5141     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
5142 
5143     glUseProgram(mProgram);
5144 
5145     glBindImageTexture(0, texRead, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
5146     glDispatchCompute(1, 1, 1);
5147 
5148     // Bind again
5149     glBindImageTexture(0, texRead, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
5150     glDispatchCompute(1, 1, 1);
5151     EXPECT_GL_NO_ERROR();
5152 
5153     EXPECT_PIXEL_RECT_EQ(0, 0, 2, 2, GLColor::cyan);
5154 }
5155 
5156 // Tests that we can dispatch with an image texture, modify the image texture with a texSubImage,
5157 // and then dispatch again correctly.
TEST_P(SimpleStateChangeTestComputeES31,DispatchWithImageTextureTexSubImageThenDispatchAgain)5158 TEST_P(SimpleStateChangeTestComputeES31, DispatchWithImageTextureTexSubImageThenDispatchAgain)
5159 {
5160     std::array<GLColor, 4> colors    = {{GLColor::red, GLColor::red, GLColor::red, GLColor::red}};
5161     std::array<GLColor, 4> subColors = {
5162         {GLColor::green, GLColor::green, GLColor::green, GLColor::green}};
5163 
5164     GLTexture texRead;
5165     glBindTexture(GL_TEXTURE_2D, texRead);
5166     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2);
5167     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
5168 
5169     glUseProgram(mProgram);
5170 
5171     glBindImageTexture(0, texRead, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
5172     glDispatchCompute(1, 1, 1);
5173 
5174     // Update bottom-half of image texture with green.
5175     glBindTexture(GL_TEXTURE_2D, texRead);
5176     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 1, GL_RGBA, GL_UNSIGNED_BYTE, subColors.data());
5177     ASSERT_GL_NO_ERROR();
5178 
5179     // Dispatch again, should still work.
5180     glDispatchCompute(1, 1, 1);
5181     ASSERT_GL_NO_ERROR();
5182 
5183     // Validate first half of the image is red and the bottom is green.
5184     std::array<GLColor, 4> results;
5185     glReadPixels(0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, results.data());
5186     EXPECT_GL_NO_ERROR();
5187 
5188     EXPECT_EQ(GLColor::green, results[0]);
5189     EXPECT_EQ(GLColor::green, results[1]);
5190     EXPECT_EQ(GLColor::red, results[2]);
5191     EXPECT_EQ(GLColor::red, results[3]);
5192 }
5193 
5194 // Test updating an image texture's contents while in use by GL works as expected.
TEST_P(SimpleStateChangeTestComputeES31,UpdateImageTextureInUse)5195 TEST_P(SimpleStateChangeTestComputeES31, UpdateImageTextureInUse)
5196 {
5197     std::array<GLColor, 4> rgby = {{GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow}};
5198 
5199     GLTexture texRead;
5200     glBindTexture(GL_TEXTURE_2D, texRead);
5201     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2);
5202     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, rgby.data());
5203 
5204     glUseProgram(mProgram);
5205 
5206     glBindImageTexture(0, texRead, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
5207     glDispatchCompute(1, 1, 1);
5208 
5209     // Update the texture to be YBGR, while the Texture is in-use. Should not affect the dispatch.
5210     std::array<GLColor, 4> ybgr = {{GLColor::yellow, GLColor::blue, GLColor::green, GLColor::red}};
5211     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, ybgr.data());
5212     ASSERT_GL_NO_ERROR();
5213 
5214     // Check the Framebuffer. The dispatch call should have completed with the original RGBY data.
5215     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
5216     EXPECT_PIXEL_COLOR_EQ(1, 0, GLColor::green);
5217     EXPECT_PIXEL_COLOR_EQ(0, 1, GLColor::blue);
5218     EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::yellow);
5219 
5220     // Dispatch again. The second dispatch call should use the updated YBGR data.
5221     glDispatchCompute(1, 1, 1);
5222 
5223     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
5224     EXPECT_PIXEL_COLOR_EQ(1, 0, GLColor::blue);
5225     EXPECT_PIXEL_COLOR_EQ(0, 1, GLColor::green);
5226     EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::red);
5227     ASSERT_GL_NO_ERROR();
5228 }
5229 
5230 // Test that we can alternate between image textures between different dispatchs.
TEST_P(SimpleStateChangeTestComputeES31,DispatchImageTextureAThenTextureBThenTextureA)5231 TEST_P(SimpleStateChangeTestComputeES31, DispatchImageTextureAThenTextureBThenTextureA)
5232 {
5233     std::array<GLColor, 4> colorsTexA = {
5234         {GLColor::cyan, GLColor::cyan, GLColor::cyan, GLColor::cyan}};
5235 
5236     std::array<GLColor, 4> colorsTexB = {
5237         {GLColor::magenta, GLColor::magenta, GLColor::magenta, GLColor::magenta}};
5238 
5239     GLTexture texA;
5240     glBindTexture(GL_TEXTURE_2D, texA);
5241     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2);
5242     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, colorsTexA.data());
5243     GLTexture texB;
5244     glBindTexture(GL_TEXTURE_2D, texB);
5245     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2);
5246     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, colorsTexB.data());
5247 
5248     glUseProgram(mProgram);
5249 
5250     glBindImageTexture(0, texA, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
5251     glDispatchCompute(1, 1, 1);
5252 
5253     glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
5254     glBindImageTexture(0, texB, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
5255     glDispatchCompute(1, 1, 1);
5256 
5257     glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
5258     glBindImageTexture(0, texA, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
5259     glDispatchCompute(1, 1, 1);
5260 
5261     glMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT);
5262     EXPECT_PIXEL_RECT_EQ(0, 0, 2, 2, GLColor::cyan);
5263     ASSERT_GL_NO_ERROR();
5264 }
5265 
5266 // Copied from SimpleStateChangeTestComputeES31::DeleteImageTextureInUse
5267 // Tests that deleting an in-flight image texture does not immediately delete the resource.
TEST_P(SimpleStateChangeTestComputeES31PPO,DeleteImageTextureInUse)5268 TEST_P(SimpleStateChangeTestComputeES31PPO, DeleteImageTextureInUse)
5269 {
5270     ANGLE_SKIP_TEST_IF(!IsVulkan());
5271 
5272     glGenFramebuffers(1, &mFramebuffer);
5273     glGenTextures(1, &mTexture);
5274 
5275     glBindTexture(GL_TEXTURE_2D, mTexture);
5276     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2);
5277     EXPECT_GL_NO_ERROR();
5278 
5279     constexpr char kCS[] = R"(#version 310 es
5280 layout(local_size_x=2, local_size_y=2) in;
5281 layout (rgba8, binding = 0) readonly uniform highp image2D srcImage;
5282 layout (rgba8, binding = 1) writeonly uniform highp image2D dstImage;
5283 void main()
5284 {
5285 imageStore(dstImage, ivec2(gl_LocalInvocationID.xy),
5286            imageLoad(srcImage, ivec2(gl_LocalInvocationID.xy)));
5287 })";
5288 
5289     bindProgramPipeline(kCS);
5290 
5291     glBindImageTexture(1, mTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8);
5292 
5293     glBindFramebuffer(GL_READ_FRAMEBUFFER, mFramebuffer);
5294     glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
5295 
5296     ASSERT_GL_NO_ERROR();
5297 
5298     std::array<GLColor, 4> colors = {
5299         {GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow}};
5300     GLTexture texRead;
5301     glBindTexture(GL_TEXTURE_2D, texRead);
5302     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2);
5303     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
5304     EXPECT_GL_NO_ERROR();
5305 
5306     glBindImageTexture(0, texRead, 0, GL_FALSE, 0, GL_READ_ONLY, GL_RGBA8);
5307     glDispatchCompute(1, 1, 1);
5308     texRead.reset();
5309 
5310     std::array<GLColor, 4> results;
5311     glReadPixels(0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, results.data());
5312     EXPECT_GL_NO_ERROR();
5313 
5314     for (int i = 0; i < 4; i++)
5315     {
5316         EXPECT_EQ(colors[i], results[i]);
5317     }
5318 }
5319 
5320 static constexpr char kColorVS[] = R"(attribute vec2 position;
5321 attribute vec4 color;
5322 varying vec4 vColor;
5323 void main()
5324 {
5325     gl_Position = vec4(position, 0, 1);
5326     vColor = color;
5327 })";
5328 
5329 static constexpr char kColorFS[] = R"(precision mediump float;
5330 varying vec4 vColor;
5331 void main()
5332 {
5333     gl_FragColor = vColor;
5334 })";
5335 
5336 class ValidationStateChangeTest : public ANGLETest<>
5337 {
5338   protected:
ValidationStateChangeTest()5339     ValidationStateChangeTest()
5340     {
5341         setWindowWidth(64);
5342         setWindowHeight(64);
5343         setConfigRedBits(8);
5344         setConfigGreenBits(8);
5345         setConfigBlueBits(8);
5346         setConfigAlphaBits(8);
5347     }
5348 };
5349 
5350 class WebGL2ValidationStateChangeTest : public ValidationStateChangeTest
5351 {
5352   protected:
WebGL2ValidationStateChangeTest()5353     WebGL2ValidationStateChangeTest() { setWebGLCompatibilityEnabled(true); }
5354 };
5355 
5356 class ValidationStateChangeTestES31 : public ANGLETest<>
5357 {};
5358 
5359 class WebGLComputeValidationStateChangeTest : public ANGLETest<>
5360 {
5361   public:
WebGLComputeValidationStateChangeTest()5362     WebGLComputeValidationStateChangeTest() { setWebGLCompatibilityEnabled(true); }
5363 };
5364 
5365 class RobustBufferAccessWebGL2ValidationStateChangeTest : public WebGL2ValidationStateChangeTest
5366 {
5367   protected:
RobustBufferAccessWebGL2ValidationStateChangeTest()5368     RobustBufferAccessWebGL2ValidationStateChangeTest()
5369     {
5370         // SwS/OSX GL do not support robustness. Mali does not support it.
5371         if (!isSwiftshader() && !IsMac() && !IsIOS() && !IsARM())
5372         {
5373             setRobustAccess(true);
5374         }
5375     }
5376 };
5377 
5378 // Tests that mapping and unmapping an array buffer in various ways causes rendering to fail.
5379 // This isn't guaranteed to produce an error by GL. But we assume ANGLE always errors.
TEST_P(ValidationStateChangeTest,MapBufferAndDraw)5380 TEST_P(ValidationStateChangeTest, MapBufferAndDraw)
5381 {
5382     // Initialize program and set up state.
5383     ANGLE_GL_PROGRAM(program, kColorVS, kColorFS);
5384 
5385     glUseProgram(program);
5386     GLint positionLoc = glGetAttribLocation(program, "position");
5387     ASSERT_NE(-1, positionLoc);
5388     GLint colorLoc = glGetAttribLocation(program, "color");
5389     ASSERT_NE(-1, colorLoc);
5390 
5391     const std::array<Vector3, 6> &quadVertices = GetQuadVertices();
5392     const size_t posBufferSize                 = quadVertices.size() * sizeof(Vector3);
5393 
5394     GLBuffer posBuffer;
5395     glBindBuffer(GL_ARRAY_BUFFER, posBuffer);
5396     glBufferData(GL_ARRAY_BUFFER, posBufferSize, quadVertices.data(), GL_STATIC_DRAW);
5397 
5398     // Start with position enabled.
5399     glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
5400     glEnableVertexAttribArray(positionLoc);
5401 
5402     std::vector<GLColor> colorVertices(6, GLColor::blue);
5403     const size_t colorBufferSize = sizeof(GLColor) * 6;
5404 
5405     GLBuffer colorBuffer;
5406     glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
5407     glBufferData(GL_ARRAY_BUFFER, colorBufferSize, colorVertices.data(), GL_STATIC_DRAW);
5408 
5409     // Start with color disabled.
5410     glVertexAttribPointer(colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, nullptr);
5411     glDisableVertexAttribArray(colorLoc);
5412 
5413     ASSERT_GL_NO_ERROR();
5414 
5415     // Draw without a mapped buffer. Should succeed.
5416     glVertexAttrib4f(colorLoc, 0, 1, 0, 1);
5417     glDrawArrays(GL_TRIANGLES, 0, 6);
5418     ASSERT_GL_NO_ERROR();
5419     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5420 
5421     // Map position buffer and draw. Should fail.
5422     glBindBuffer(GL_ARRAY_BUFFER, posBuffer);
5423     glMapBufferRange(GL_ARRAY_BUFFER, 0, posBufferSize, GL_MAP_READ_BIT);
5424     ASSERT_GL_NO_ERROR();
5425 
5426     glDrawArrays(GL_TRIANGLES, 0, 6);
5427     EXPECT_GL_ERROR(GL_INVALID_OPERATION) << "Map position buffer and draw should fail.";
5428     glUnmapBuffer(GL_ARRAY_BUFFER);
5429 
5430     // Map then enable color buffer. Should fail.
5431     glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
5432     glMapBufferRange(GL_ARRAY_BUFFER, 0, colorBufferSize, GL_MAP_READ_BIT);
5433     glEnableVertexAttribArray(colorLoc);
5434     ASSERT_GL_NO_ERROR();
5435 
5436     glDrawArrays(GL_TRIANGLES, 0, 6);
5437     EXPECT_GL_ERROR(GL_INVALID_OPERATION) << "Map then enable color buffer should fail.";
5438 
5439     // Unmap then draw. Should succeed.
5440     glUnmapBuffer(GL_ARRAY_BUFFER);
5441     ASSERT_GL_NO_ERROR();
5442 
5443     glDrawArrays(GL_TRIANGLES, 0, 6);
5444     ASSERT_GL_NO_ERROR();
5445     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
5446 }
5447 
5448 // Tests that mapping an immutable and persistent buffer after calling glVertexAttribPointer()
5449 // allows rendering to succeed.
TEST_P(ValidationStateChangeTest,MapImmutablePersistentBufferAndDraw)5450 TEST_P(ValidationStateChangeTest, MapImmutablePersistentBufferAndDraw)
5451 {
5452     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_buffer_storage"));
5453 
5454     // Initialize program and set up state.
5455     ANGLE_GL_PROGRAM(program, kColorVS, kColorFS);
5456 
5457     glUseProgram(program);
5458     GLint positionLoc = glGetAttribLocation(program, "position");
5459     ASSERT_NE(-1, positionLoc);
5460     GLint colorLoc = glGetAttribLocation(program, "color");
5461     ASSERT_NE(-1, colorLoc);
5462 
5463     const std::array<Vector3, 6> &quadVertices = GetQuadVertices();
5464     const size_t posBufferSize                 = quadVertices.size() * sizeof(Vector3);
5465 
5466     GLBuffer posBuffer;
5467     glBindBuffer(GL_ARRAY_BUFFER, posBuffer);
5468     glBufferStorageEXT(GL_ARRAY_BUFFER, posBufferSize, quadVertices.data(),
5469                        GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT_EXT);
5470 
5471     // Start with position enabled.
5472     glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
5473     glEnableVertexAttribArray(positionLoc);
5474 
5475     std::vector<GLColor> colorVertices(6, GLColor::blue);
5476     const size_t colorBufferSize = sizeof(GLColor) * 6;
5477 
5478     GLBuffer colorBuffer;
5479     glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
5480     glBufferStorageEXT(GL_ARRAY_BUFFER, colorBufferSize, colorVertices.data(),
5481                        GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT_EXT);
5482 
5483     // Start with color disabled.
5484     glVertexAttribPointer(colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, nullptr);
5485     glDisableVertexAttribArray(colorLoc);
5486 
5487     ASSERT_GL_NO_ERROR();
5488 
5489     // Draw without a mapped buffer. Should succeed.
5490     glVertexAttrib4f(colorLoc, 0, 1, 0, 1);
5491     glDrawArrays(GL_TRIANGLES, 0, 6);
5492     ASSERT_GL_NO_ERROR();
5493     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5494 
5495     // Map position buffer and draw. Should succeed.
5496     glBindBuffer(GL_ARRAY_BUFFER, posBuffer);
5497     glMapBufferRange(GL_ARRAY_BUFFER, 0, posBufferSize,
5498                      GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT_EXT);
5499     ASSERT_GL_NO_ERROR();
5500 
5501     glDrawArrays(GL_TRIANGLES, 0, 6);
5502     ASSERT_GL_NO_ERROR();
5503     glUnmapBuffer(GL_ARRAY_BUFFER);
5504 
5505     // Map then enable color buffer. Should succeed.
5506     glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
5507     glMapBufferRange(GL_ARRAY_BUFFER, 0, colorBufferSize,
5508                      GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT_EXT);
5509     glEnableVertexAttribArray(colorLoc);
5510     ASSERT_GL_NO_ERROR();
5511 
5512     glDrawArrays(GL_TRIANGLES, 0, 6);
5513     ASSERT_GL_NO_ERROR();
5514 
5515     // Unmap then draw. Should succeed.
5516     glUnmapBuffer(GL_ARRAY_BUFFER);
5517     ASSERT_GL_NO_ERROR();
5518 
5519     glDrawArrays(GL_TRIANGLES, 0, 6);
5520     ASSERT_GL_NO_ERROR();
5521     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
5522 }
5523 
5524 // Tests that mapping an immutable and persistent buffer before calling glVertexAttribPointer()
5525 // allows rendering to succeed. This case is special in that the VertexArray is not observing the
5526 // buffer yet, so it's various cached buffer states aren't updated when the buffer is mapped.
TEST_P(ValidationStateChangeTest,MapImmutablePersistentBufferThenVAPAndDraw)5527 TEST_P(ValidationStateChangeTest, MapImmutablePersistentBufferThenVAPAndDraw)
5528 {
5529     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_buffer_storage"));
5530 
5531     // Initialize program and set up state.
5532     ANGLE_GL_PROGRAM(program, kColorVS, kColorFS);
5533 
5534     glUseProgram(program);
5535     GLint positionLoc = glGetAttribLocation(program, "position");
5536     ASSERT_NE(-1, positionLoc);
5537     GLint colorLoc = glGetAttribLocation(program, "color");
5538     ASSERT_NE(-1, colorLoc);
5539 
5540     const std::array<Vector3, 6> &quadVertices = GetQuadVertices();
5541     const size_t posBufferSize                 = quadVertices.size() * sizeof(Vector3);
5542 
5543     GLBuffer posBuffer;
5544     glBindBuffer(GL_ARRAY_BUFFER, posBuffer);
5545     glBufferStorageEXT(GL_ARRAY_BUFFER, posBufferSize, quadVertices.data(),
5546                        GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT_EXT);
5547 
5548     glMapBufferRange(GL_ARRAY_BUFFER, 0, posBufferSize,
5549                      GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT_EXT);
5550 
5551     // Start with position enabled.
5552     glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
5553     glEnableVertexAttribArray(positionLoc);
5554 
5555     std::vector<GLColor> colorVertices(6, GLColor::blue);
5556     const size_t colorBufferSize = sizeof(GLColor) * 6;
5557 
5558     GLBuffer colorBuffer;
5559     glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
5560     glBufferStorageEXT(GL_ARRAY_BUFFER, colorBufferSize, colorVertices.data(),
5561                        GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT_EXT);
5562 
5563     glMapBufferRange(GL_ARRAY_BUFFER, 0, colorBufferSize,
5564                      GL_MAP_READ_BIT | GL_MAP_PERSISTENT_BIT_EXT);
5565     ASSERT_GL_NO_ERROR();
5566 
5567     // Start with color disabled.
5568     glVertexAttribPointer(colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, nullptr);
5569     glDisableVertexAttribArray(colorLoc);
5570 
5571     ASSERT_GL_NO_ERROR();
5572 
5573     // Draw without a mapped buffer. Should succeed.
5574     glVertexAttrib4f(colorLoc, 0, 1, 0, 1);
5575     glDrawArrays(GL_TRIANGLES, 0, 6);
5576     ASSERT_GL_NO_ERROR();
5577     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5578 
5579     // Unmap then draw. Should succeed.
5580     glUnmapBuffer(GL_ARRAY_BUFFER);
5581     glEnableVertexAttribArray(colorLoc);
5582     ASSERT_GL_NO_ERROR();
5583     glDrawArrays(GL_TRIANGLES, 0, 6);
5584     ASSERT_GL_NO_ERROR();
5585     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
5586 }
5587 
5588 // Tests that changing a vertex binding with glVertexAttribDivisor updates the mapped buffer check.
TEST_P(ValidationStateChangeTestES31,MapBufferAndDrawWithDivisor)5589 TEST_P(ValidationStateChangeTestES31, MapBufferAndDrawWithDivisor)
5590 {
5591     // Seems to trigger a GL error in some edge cases. http://anglebug.com/2755
5592     ANGLE_SKIP_TEST_IF(IsOpenGL() && IsNVIDIA());
5593 
5594     // Initialize program and set up state.
5595     ANGLE_GL_PROGRAM(program, kColorVS, kColorFS);
5596 
5597     glUseProgram(program);
5598     GLint positionLoc = glGetAttribLocation(program, "position");
5599     ASSERT_NE(-1, positionLoc);
5600     GLint colorLoc = glGetAttribLocation(program, "color");
5601     ASSERT_NE(-1, colorLoc);
5602 
5603     // Create a user vertex array.
5604     GLVertexArray vao;
5605     glBindVertexArray(vao);
5606 
5607     const std::array<Vector3, 6> &quadVertices = GetQuadVertices();
5608     const size_t posBufferSize                 = quadVertices.size() * sizeof(Vector3);
5609 
5610     GLBuffer posBuffer;
5611     glBindBuffer(GL_ARRAY_BUFFER, posBuffer);
5612     glBufferData(GL_ARRAY_BUFFER, posBufferSize, quadVertices.data(), GL_STATIC_DRAW);
5613 
5614     // Start with position enabled.
5615     glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
5616     glEnableVertexAttribArray(positionLoc);
5617 
5618     std::vector<GLColor> blueVertices(6, GLColor::blue);
5619     const size_t blueBufferSize = sizeof(GLColor) * 6;
5620 
5621     GLBuffer blueBuffer;
5622     glBindBuffer(GL_ARRAY_BUFFER, blueBuffer);
5623     glBufferData(GL_ARRAY_BUFFER, blueBufferSize, blueVertices.data(), GL_STATIC_DRAW);
5624 
5625     // Start with color enabled at an unused binding.
5626     constexpr GLint kUnusedBinding = 3;
5627     ASSERT_NE(colorLoc, kUnusedBinding);
5628     ASSERT_NE(positionLoc, kUnusedBinding);
5629     glVertexAttribFormat(colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0);
5630     glVertexAttribBinding(colorLoc, kUnusedBinding);
5631     glBindVertexBuffer(kUnusedBinding, blueBuffer, 0, sizeof(GLColor));
5632     glEnableVertexAttribArray(colorLoc);
5633 
5634     // Make binding 'colorLoc' use a mapped buffer.
5635     std::vector<GLColor> greenVertices(6, GLColor::green);
5636     const size_t greenBufferSize = sizeof(GLColor) * 6;
5637     GLBuffer greenBuffer;
5638     glBindBuffer(GL_ARRAY_BUFFER, greenBuffer);
5639     glBufferData(GL_ARRAY_BUFFER, greenBufferSize, greenVertices.data(), GL_STATIC_DRAW);
5640     glMapBufferRange(GL_ARRAY_BUFFER, 0, greenBufferSize, GL_MAP_READ_BIT);
5641     glBindVertexBuffer(colorLoc, greenBuffer, 0, sizeof(GLColor));
5642 
5643     ASSERT_GL_NO_ERROR();
5644 
5645     // Draw without a mapped buffer. Should succeed.
5646     glDrawArrays(GL_TRIANGLES, 0, 6);
5647     ASSERT_GL_NO_ERROR();
5648     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
5649 
5650     // Change divisor with VertexAttribDivisor. Should fail.
5651     glVertexAttribDivisor(colorLoc, 0);
5652     ASSERT_GL_NO_ERROR();
5653     glDrawArrays(GL_TRIANGLES, 0, 6);
5654     EXPECT_GL_ERROR(GL_INVALID_OPERATION) << "draw with mapped buffer should fail.";
5655 
5656     // Unmap the buffer. Should succeed.
5657     glUnmapBuffer(GL_ARRAY_BUFFER);
5658     glDrawArrays(GL_TRIANGLES, 0, 6);
5659     ASSERT_GL_NO_ERROR();
5660     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5661 }
5662 
5663 // Tests that changing a vertex binding with glVertexAttribDivisor updates the buffer size check.
TEST_P(WebGLComputeValidationStateChangeTest,DrawPastEndOfBufferWithDivisor)5664 TEST_P(WebGLComputeValidationStateChangeTest, DrawPastEndOfBufferWithDivisor)
5665 {
5666     // Initialize program and set up state.
5667     ANGLE_GL_PROGRAM(program, kColorVS, kColorFS);
5668 
5669     glUseProgram(program);
5670     GLint positionLoc = glGetAttribLocation(program, "position");
5671     ASSERT_NE(-1, positionLoc);
5672     GLint colorLoc = glGetAttribLocation(program, "color");
5673     ASSERT_NE(-1, colorLoc);
5674 
5675     // Create a user vertex array.
5676     GLVertexArray vao;
5677     glBindVertexArray(vao);
5678 
5679     const std::array<Vector3, 6> &quadVertices = GetQuadVertices();
5680     const size_t posBufferSize                 = quadVertices.size() * sizeof(Vector3);
5681 
5682     GLBuffer posBuffer;
5683     glBindBuffer(GL_ARRAY_BUFFER, posBuffer);
5684     glBufferData(GL_ARRAY_BUFFER, posBufferSize, quadVertices.data(), GL_STATIC_DRAW);
5685 
5686     // Start with position enabled.
5687     glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
5688     glEnableVertexAttribArray(positionLoc);
5689 
5690     std::vector<GLColor> blueVertices(6, GLColor::blue);
5691     const size_t blueBufferSize = sizeof(GLColor) * 6;
5692 
5693     GLBuffer blueBuffer;
5694     glBindBuffer(GL_ARRAY_BUFFER, blueBuffer);
5695     glBufferData(GL_ARRAY_BUFFER, blueBufferSize, blueVertices.data(), GL_STATIC_DRAW);
5696 
5697     // Start with color enabled at an unused binding.
5698     constexpr GLint kUnusedBinding = 3;
5699     ASSERT_NE(colorLoc, kUnusedBinding);
5700     ASSERT_NE(positionLoc, kUnusedBinding);
5701     glVertexAttribFormat(colorLoc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0);
5702     glVertexAttribBinding(colorLoc, kUnusedBinding);
5703     glBindVertexBuffer(kUnusedBinding, blueBuffer, 0, sizeof(GLColor));
5704     glEnableVertexAttribArray(colorLoc);
5705 
5706     // Make binding 'colorLoc' use a small buffer.
5707     std::vector<GLColor> greenVertices(6, GLColor::green);
5708     const size_t greenBufferSize = sizeof(GLColor) * 3;
5709     GLBuffer greenBuffer;
5710     glBindBuffer(GL_ARRAY_BUFFER, greenBuffer);
5711     glBufferData(GL_ARRAY_BUFFER, greenBufferSize, greenVertices.data(), GL_STATIC_DRAW);
5712     glBindVertexBuffer(colorLoc, greenBuffer, 0, sizeof(GLColor));
5713 
5714     ASSERT_GL_NO_ERROR();
5715 
5716     // Draw without a mapped buffer. Should succeed.
5717     glDrawArrays(GL_TRIANGLES, 0, 6);
5718     ASSERT_GL_NO_ERROR();
5719     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
5720 
5721     // Change divisor with VertexAttribDivisor. Should fail.
5722     glVertexAttribDivisor(colorLoc, 0);
5723     ASSERT_GL_NO_ERROR();
5724     glDrawArrays(GL_TRIANGLES, 0, 6);
5725     EXPECT_GL_ERROR(GL_INVALID_OPERATION) << "draw with small buffer should fail.";
5726 
5727     // Do a small draw. Should succeed.
5728     glDrawArrays(GL_TRIANGLES, 0, 3);
5729     ASSERT_GL_NO_ERROR();
5730     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5731 }
5732 
5733 // Tests state changes with uniform block validation.
TEST_P(WebGL2ValidationStateChangeTest,UniformBlockNegativeAPI)5734 TEST_P(WebGL2ValidationStateChangeTest, UniformBlockNegativeAPI)
5735 {
5736     constexpr char kVS[] = R"(#version 300 es
5737 in vec2 position;
5738 void main()
5739 {
5740     gl_Position = vec4(position, 0, 1);
5741 })";
5742 
5743     constexpr char kFS[] = R"(#version 300 es
5744 precision mediump float;
5745 uniform uni { vec4 vec; };
5746 out vec4 color;
5747 void main()
5748 {
5749     color = vec;
5750 })";
5751 
5752     ANGLE_GL_PROGRAM(program, kVS, kFS);
5753     glUseProgram(program);
5754 
5755     GLuint blockIndex = glGetUniformBlockIndex(program, "uni");
5756     ASSERT_NE(GL_INVALID_INDEX, blockIndex);
5757 
5758     glUniformBlockBinding(program, blockIndex, 0);
5759 
5760     GLBuffer uniformBuffer;
5761     glBindBuffer(GL_UNIFORM_BUFFER, uniformBuffer);
5762     glBufferData(GL_UNIFORM_BUFFER, sizeof(GLColor32F), &kFloatGreen.R, GL_STATIC_DRAW);
5763     glBindBufferBase(GL_UNIFORM_BUFFER, 0, uniformBuffer);
5764 
5765     const auto &quadVertices = GetQuadVertices();
5766 
5767     GLBuffer positionBuffer;
5768     glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
5769     glBufferData(GL_ARRAY_BUFFER, quadVertices.size() * sizeof(Vector3), quadVertices.data(),
5770                  GL_STATIC_DRAW);
5771 
5772     GLint positionLocation = glGetAttribLocation(program, "position");
5773     ASSERT_NE(-1, positionLocation);
5774 
5775     glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
5776     glEnableVertexAttribArray(positionLocation);
5777     ASSERT_GL_NO_ERROR();
5778 
5779     // First draw should succeed.
5780     glDrawArrays(GL_TRIANGLES, 0, 6);
5781     ASSERT_GL_NO_ERROR();
5782     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5783 
5784     // Change the uniform block binding. Should fail.
5785     glUniformBlockBinding(program, blockIndex, 1);
5786     ASSERT_GL_NO_ERROR();
5787     glDrawArrays(GL_TRIANGLES, 0, 6);
5788     ASSERT_GL_ERROR(GL_INVALID_OPERATION) << "Invalid uniform block binding should fail";
5789 
5790     // Reset to a correct state.
5791     glUniformBlockBinding(program, blockIndex, 0);
5792     glDrawArrays(GL_TRIANGLES, 0, 6);
5793     ASSERT_GL_NO_ERROR();
5794     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5795 
5796     // Change the buffer binding. Should fail.
5797     glBindBufferBase(GL_UNIFORM_BUFFER, 0, 0);
5798     ASSERT_GL_NO_ERROR();
5799     glDrawArrays(GL_TRIANGLES, 0, 6);
5800     ASSERT_GL_ERROR(GL_INVALID_OPERATION) << "Setting invalid uniform buffer should fail";
5801 
5802     // Reset to a correct state.
5803     glBindBufferBase(GL_UNIFORM_BUFFER, 0, uniformBuffer);
5804     glDrawArrays(GL_TRIANGLES, 0, 6);
5805     ASSERT_GL_NO_ERROR();
5806     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5807 
5808     // Resize the buffer to be too small. Should fail.
5809     glBufferData(GL_UNIFORM_BUFFER, 1, nullptr, GL_STATIC_DRAW);
5810     glDrawArrays(GL_TRIANGLES, 0, 6);
5811     EXPECT_GL_ERROR(GL_INVALID_OPERATION) << "Invalid buffer size should fail";
5812 }
5813 
5814 // Tests various state change effects on draw framebuffer validation.
TEST_P(WebGL2ValidationStateChangeTest,DrawFramebufferNegativeAPI)5815 TEST_P(WebGL2ValidationStateChangeTest, DrawFramebufferNegativeAPI)
5816 {
5817     // Set up a simple draw from a Texture to a user Framebuffer.
5818     GLuint program = get2DTexturedQuadProgram();
5819     ASSERT_NE(0u, program);
5820     glUseProgram(program);
5821 
5822     GLint posLoc = glGetAttribLocation(program, "position");
5823     ASSERT_NE(-1, posLoc);
5824 
5825     const auto &quadVertices = GetQuadVertices();
5826 
5827     GLBuffer positionBuffer;
5828     glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
5829     glBufferData(GL_ARRAY_BUFFER, sizeof(Vector3) * quadVertices.size(), quadVertices.data(),
5830                  GL_STATIC_DRAW);
5831 
5832     glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
5833     glEnableVertexAttribArray(posLoc);
5834 
5835     constexpr size_t kSize = 2;
5836 
5837     GLTexture colorBufferTexture;
5838     glBindTexture(GL_TEXTURE_2D, colorBufferTexture);
5839     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
5840     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5841     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5842 
5843     GLFramebuffer framebuffer;
5844     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
5845     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTexture,
5846                            0);
5847     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
5848 
5849     std::vector<GLColor> greenColor(kSize * kSize, GLColor::green);
5850 
5851     GLTexture greenTexture;
5852     glBindTexture(GL_TEXTURE_2D, greenTexture);
5853     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5854                  greenColor.data());
5855     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
5856     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
5857 
5858     // Second framebuffer with a feedback loop. Initially unbound.
5859     GLFramebuffer loopedFramebuffer;
5860     glBindFramebuffer(GL_FRAMEBUFFER, loopedFramebuffer);
5861     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, greenTexture, 0);
5862     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
5863     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
5864 
5865     ASSERT_GL_NO_ERROR();
5866 
5867     glDrawArrays(GL_TRIANGLES, 0, 6);
5868     ASSERT_GL_NO_ERROR();
5869     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5870 
5871     // Create a rendering feedback loop. Should fail.
5872     glBindTexture(GL_TEXTURE_2D, colorBufferTexture);
5873     ASSERT_GL_NO_ERROR();
5874     glDrawArrays(GL_TRIANGLES, 0, 6);
5875     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5876 
5877     // Reset to a valid state.
5878     glBindTexture(GL_TEXTURE_2D, greenTexture);
5879     glDrawArrays(GL_TRIANGLES, 0, 6);
5880     ASSERT_GL_NO_ERROR();
5881     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5882 
5883     // Bind a second framebuffer with a feedback loop.
5884     glBindFramebuffer(GL_FRAMEBUFFER, loopedFramebuffer);
5885     ASSERT_GL_NO_ERROR();
5886     glDrawArrays(GL_TRIANGLES, 0, 6);
5887     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5888 
5889     // Update the framebuffer texture attachment. Should succeed.
5890     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorBufferTexture,
5891                            0);
5892     glDrawArrays(GL_TRIANGLES, 0, 6);
5893     ASSERT_GL_NO_ERROR();
5894     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5895 }
5896 
5897 // Tests various state change effects on draw framebuffer validation with MRT.
TEST_P(WebGL2ValidationStateChangeTest,MultiAttachmentDrawFramebufferNegativeAPI)5898 TEST_P(WebGL2ValidationStateChangeTest, MultiAttachmentDrawFramebufferNegativeAPI)
5899 {
5900     // Crashes on 64-bit Android.  http://anglebug.com/3878
5901     ANGLE_SKIP_TEST_IF(IsVulkan() && IsAndroid());
5902 
5903     // Set up a program that writes to two outputs: one int and one float.
5904     constexpr char kVS[] = R"(#version 300 es
5905 layout(location = 0) in vec2 position;
5906 out vec2 texCoord;
5907 void main()
5908 {
5909     gl_Position = vec4(position, 0, 1);
5910     texCoord = position * 0.5 + vec2(0.5);
5911 })";
5912 
5913     constexpr char kFS[] = R"(#version 300 es
5914 precision mediump float;
5915 in vec2 texCoord;
5916 layout(location = 0) out vec4 outFloat;
5917 layout(location = 1) out uvec4 outInt;
5918 void main()
5919 {
5920     outFloat = vec4(0, 1, 0, 1);
5921     outInt = uvec4(0, 1, 0, 1);
5922 })";
5923 
5924     ANGLE_GL_PROGRAM(program, kVS, kFS);
5925     glUseProgram(program);
5926 
5927     constexpr GLint kPosLoc = 0;
5928 
5929     const auto &quadVertices = GetQuadVertices();
5930 
5931     GLBuffer positionBuffer;
5932     glBindBuffer(GL_ARRAY_BUFFER, positionBuffer);
5933     glBufferData(GL_ARRAY_BUFFER, sizeof(Vector3) * quadVertices.size(), quadVertices.data(),
5934                  GL_STATIC_DRAW);
5935 
5936     glVertexAttribPointer(kPosLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
5937     glEnableVertexAttribArray(kPosLoc);
5938 
5939     constexpr size_t kSize = 2;
5940 
5941     GLFramebuffer floatFramebuffer;
5942     glBindFramebuffer(GL_FRAMEBUFFER, floatFramebuffer);
5943 
5944     GLTexture floatTextures[2];
5945     for (int i = 0; i < 2; ++i)
5946     {
5947         glBindTexture(GL_TEXTURE_2D, floatTextures[i]);
5948         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
5949                      nullptr);
5950         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D,
5951                                floatTextures[i], 0);
5952         ASSERT_GL_NO_ERROR();
5953     }
5954 
5955     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
5956 
5957     GLFramebuffer intFramebuffer;
5958     glBindFramebuffer(GL_FRAMEBUFFER, intFramebuffer);
5959 
5960     GLTexture intTextures[2];
5961     for (int i = 0; i < 2; ++i)
5962     {
5963         glBindTexture(GL_TEXTURE_2D, intTextures[i]);
5964         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, kSize, kSize, 0, GL_RGBA_INTEGER,
5965                      GL_UNSIGNED_BYTE, nullptr);
5966         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D,
5967                                intTextures[i], 0);
5968         ASSERT_GL_NO_ERROR();
5969     }
5970 
5971     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
5972 
5973     ASSERT_GL_NO_ERROR();
5974 
5975     constexpr GLenum kColor0Enabled[]     = {GL_COLOR_ATTACHMENT0, GL_NONE};
5976     constexpr GLenum kColor1Enabled[]     = {GL_NONE, GL_COLOR_ATTACHMENT1};
5977     constexpr GLenum kColor0And1Enabled[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
5978 
5979     // Draw float. Should work.
5980     glBindFramebuffer(GL_FRAMEBUFFER, floatFramebuffer);
5981     glDrawBuffers(2, kColor0Enabled);
5982 
5983     glDrawArrays(GL_TRIANGLES, 0, 6);
5984     ASSERT_GL_NO_ERROR() << "Draw to float texture with correct mask";
5985     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
5986 
5987     // Set an invalid component write.
5988     glDrawBuffers(2, kColor0And1Enabled);
5989     ASSERT_GL_NO_ERROR() << "Draw to float texture with invalid mask";
5990     glDrawArrays(GL_TRIANGLES, 0, 6);
5991     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5992     // Set all 4 channels of color mask to false. Validate success.
5993     glColorMask(false, false, false, false);
5994     glDrawArrays(GL_TRIANGLES, 0, 6);
5995     EXPECT_GL_NO_ERROR();
5996     glColorMask(false, true, false, false);
5997     glDrawArrays(GL_TRIANGLES, 0, 6);
5998     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
5999     glColorMask(true, true, true, true);
6000     glDrawArrays(GL_TRIANGLES, 0, 6);
6001     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
6002 
6003     // Restore state.
6004     glDrawBuffers(2, kColor0Enabled);
6005     glDrawArrays(GL_TRIANGLES, 0, 6);
6006     ASSERT_GL_NO_ERROR() << "Draw to float texture with correct mask";
6007     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6008 
6009     // Bind an invalid framebuffer. Validate failure.
6010     glBindFramebuffer(GL_FRAMEBUFFER, intFramebuffer);
6011     ASSERT_GL_NO_ERROR();
6012     glDrawArrays(GL_TRIANGLES, 0, 6);
6013     EXPECT_GL_ERROR(GL_INVALID_OPERATION) << "Draw to int texture with default mask";
6014 
6015     // Set draw mask to a valid mask. Validate success.
6016     glDrawBuffers(2, kColor1Enabled);
6017     glDrawArrays(GL_TRIANGLES, 0, 6);
6018     ASSERT_GL_NO_ERROR() << "Draw to int texture with correct mask";
6019 }
6020 
6021 // Tests negative API state change cases with Transform Feedback bindings.
TEST_P(WebGL2ValidationStateChangeTest,TransformFeedbackNegativeAPI)6022 TEST_P(WebGL2ValidationStateChangeTest, TransformFeedbackNegativeAPI)
6023 {
6024     ANGLE_SKIP_TEST_IF(IsAMD() && IsMac());
6025 
6026     // TODO(anglebug.com/4533) This fails after the upgrade to the 26.20.100.7870 driver.
6027     ANGLE_SKIP_TEST_IF(IsWindows() && IsIntel() && IsVulkan());
6028 
6029     constexpr char kFS[] = R"(#version 300 es
6030 precision mediump float;
6031 uniform block { vec4 color; };
6032 out vec4 colorOut;
6033 void main()
6034 {
6035     colorOut = color;
6036 })";
6037 
6038     std::vector<std::string> tfVaryings = {"gl_Position"};
6039     ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(program, essl3_shaders::vs::Simple(), kFS, tfVaryings,
6040                                         GL_INTERLEAVED_ATTRIBS);
6041     glUseProgram(program);
6042 
6043     std::vector<Vector4> positionData;
6044     for (const Vector3 &quadVertex : GetQuadVertices())
6045     {
6046         positionData.emplace_back(quadVertex.x(), quadVertex.y(), quadVertex.z(), 1.0f);
6047     }
6048 
6049     GLBuffer arrayBuffer;
6050     glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer);
6051     glBufferData(GL_ARRAY_BUFFER, positionData.size() * sizeof(Vector4), positionData.data(),
6052                  GL_STATIC_DRAW);
6053 
6054     GLint positionLoc = glGetAttribLocation(program, essl3_shaders::PositionAttrib());
6055     ASSERT_NE(-1, positionLoc);
6056 
6057     glVertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, nullptr);
6058     glEnableVertexAttribArray(positionLoc);
6059 
6060     EXPECT_GL_NO_ERROR();
6061 
6062     // Set up transform feedback.
6063     GLTransformFeedback transformFeedback;
6064     glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedback);
6065 
6066     constexpr size_t kTransformFeedbackSize = 6 * sizeof(Vector4);
6067 
6068     GLBuffer transformFeedbackBuffer;
6069     glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, transformFeedbackBuffer);
6070     glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, kTransformFeedbackSize * 2, nullptr, GL_STATIC_DRAW);
6071     glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, transformFeedbackBuffer);
6072 
6073     // Set up uniform buffer.
6074     GLBuffer uniformBuffer;
6075     glBindBuffer(GL_UNIFORM_BUFFER, uniformBuffer);
6076     glBufferData(GL_UNIFORM_BUFFER, sizeof(GLColor32F), &kFloatGreen.R, GL_STATIC_DRAW);
6077     glBindBufferBase(GL_UNIFORM_BUFFER, 0, uniformBuffer);
6078 
6079     ASSERT_GL_NO_ERROR();
6080 
6081     // Do the draw operation. Should succeed.
6082     glBeginTransformFeedback(GL_TRIANGLES);
6083     glDrawArrays(GL_TRIANGLES, 0, 6);
6084     glEndTransformFeedback();
6085 
6086     ASSERT_GL_NO_ERROR();
6087     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6088 
6089     const GLvoid *mapPointer =
6090         glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0, kTransformFeedbackSize, GL_MAP_READ_BIT);
6091     ASSERT_GL_NO_ERROR();
6092     ASSERT_NE(nullptr, mapPointer);
6093     const Vector4 *typedMapPointer = reinterpret_cast<const Vector4 *>(mapPointer);
6094     std::vector<Vector4> actualData(typedMapPointer, typedMapPointer + 6);
6095     EXPECT_EQ(positionData, actualData);
6096     glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);
6097 
6098     // Draw once to update validation cache.
6099     glBeginTransformFeedback(GL_TRIANGLES);
6100     glDrawArrays(GL_TRIANGLES, 0, 6);
6101 
6102     // Bind transform feedback buffer to another binding point. Should cause a conflict.
6103     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, transformFeedbackBuffer);
6104     ASSERT_GL_NO_ERROR();
6105     glDrawArrays(GL_TRIANGLES, 0, 6);
6106     glEndTransformFeedback();
6107     EXPECT_GL_ERROR(GL_INVALID_OPERATION) << "Simultaneous element buffer binding should fail";
6108 
6109     // Reset to valid state.
6110     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
6111     glBeginTransformFeedback(GL_TRIANGLES);
6112     glDrawArrays(GL_TRIANGLES, 0, 6);
6113     glEndTransformFeedback();
6114     ASSERT_GL_NO_ERROR();
6115 
6116     // Simultaneous non-vertex-array binding. Should fail.
6117     glBeginTransformFeedback(GL_TRIANGLES);
6118     glDrawArrays(GL_TRIANGLES, 0, 6);
6119     ASSERT_GL_NO_ERROR();
6120     glBindBuffer(GL_PIXEL_PACK_BUFFER, transformFeedbackBuffer);
6121     ASSERT_GL_NO_ERROR();
6122     glDrawArrays(GL_TRIANGLES, 0, 6);
6123     glEndTransformFeedback();
6124     EXPECT_GL_ERROR(GL_INVALID_OPERATION) << "Simultaneous pack buffer binding should fail";
6125 }
6126 
6127 // Test sampler format validation caching works.
TEST_P(WebGL2ValidationStateChangeTest,SamplerFormatCache)6128 TEST_P(WebGL2ValidationStateChangeTest, SamplerFormatCache)
6129 {
6130     // Crashes in depth data upload due to lack of support for GL_UNSIGNED_INT data when
6131     // DEPTH_COMPONENT24 is emulated with D32_S8X24.  http://anglebug.com/3880
6132     ANGLE_SKIP_TEST_IF(IsVulkan() && IsWindows() && IsAMD());
6133 
6134     constexpr char kFS[] = R"(#version 300 es
6135 precision mediump float;
6136 uniform sampler2D sampler;
6137 out vec4 colorOut;
6138 void main()
6139 {
6140     colorOut = texture(sampler, vec2(0));
6141 })";
6142 
6143     std::vector<std::string> tfVaryings = {"gl_Position"};
6144     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
6145     glUseProgram(program);
6146 
6147     std::array<GLColor, 4> colors = {
6148         {GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow}};
6149 
6150     GLTexture tex;
6151     glBindTexture(GL_TEXTURE_2D, tex);
6152     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
6153 
6154     const auto &quadVertices = GetQuadVertices();
6155 
6156     GLBuffer arrayBuffer;
6157     glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer);
6158     glBufferData(GL_ARRAY_BUFFER, quadVertices.size() * sizeof(Vector3), quadVertices.data(),
6159                  GL_STATIC_DRAW);
6160 
6161     GLint samplerLoc = glGetUniformLocation(program, "sampler");
6162     ASSERT_NE(-1, samplerLoc);
6163     glUniform1i(samplerLoc, 0);
6164 
6165     GLint positionLoc = glGetAttribLocation(program, essl3_shaders::PositionAttrib());
6166     ASSERT_NE(-1, positionLoc);
6167     glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
6168     glEnableVertexAttribArray(positionLoc);
6169 
6170     ASSERT_GL_NO_ERROR();
6171 
6172     glDrawArrays(GL_TRIANGLES, 0, 6);
6173     ASSERT_GL_NO_ERROR();
6174 
6175     // TexImage2D should update the sampler format cache.
6176     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 2, 2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE,
6177                  colors.data());
6178     glDrawArrays(GL_TRIANGLES, 0, 6);
6179     EXPECT_GL_ERROR(GL_INVALID_OPERATION) << "Sampling integer texture with a float sampler.";
6180 
6181     glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 2, 2, 0, GL_DEPTH_COMPONENT,
6182                  GL_UNSIGNED_INT, colors.data());
6183     glDrawArrays(GL_TRIANGLES, 0, 6);
6184     ASSERT_GL_NO_ERROR() << "Depth texture with no compare mode.";
6185 
6186     // TexParameteri should update the sampler format cache.
6187     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
6188     glDrawArrays(GL_TRIANGLES, 0, 6);
6189     EXPECT_GL_ERROR(GL_INVALID_OPERATION) << "Depth texture with compare mode set.";
6190 }
6191 
6192 // Tests that we retain the correct draw mode settings with transform feedback changes.
TEST_P(ValidationStateChangeTest,TransformFeedbackDrawModes)6193 TEST_P(ValidationStateChangeTest, TransformFeedbackDrawModes)
6194 {
6195     ANGLE_SKIP_TEST_IF(IsAMD() && IsMac());
6196 
6197     std::vector<std::string> tfVaryings = {"gl_Position"};
6198     ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(program, essl3_shaders::vs::Simple(),
6199                                         essl3_shaders::fs::Red(), tfVaryings,
6200                                         GL_INTERLEAVED_ATTRIBS);
6201     glUseProgram(program);
6202 
6203     std::vector<Vector4> positionData;
6204     for (const Vector3 &quadVertex : GetQuadVertices())
6205     {
6206         positionData.emplace_back(quadVertex.x(), quadVertex.y(), quadVertex.z(), 1.0f);
6207     }
6208 
6209     GLBuffer arrayBuffer;
6210     glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer);
6211     glBufferData(GL_ARRAY_BUFFER, positionData.size() * sizeof(Vector4), positionData.data(),
6212                  GL_STATIC_DRAW);
6213 
6214     GLint positionLoc = glGetAttribLocation(program, essl3_shaders::PositionAttrib());
6215     ASSERT_NE(-1, positionLoc);
6216 
6217     glVertexAttribPointer(positionLoc, 4, GL_FLOAT, GL_FALSE, 0, nullptr);
6218     glEnableVertexAttribArray(positionLoc);
6219 
6220     // Set up transform feedback.
6221     GLTransformFeedback transformFeedback;
6222     glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedback);
6223 
6224     constexpr size_t kTransformFeedbackSize = 6 * sizeof(Vector4);
6225 
6226     GLBuffer transformFeedbackBuffer;
6227     glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, transformFeedbackBuffer);
6228     glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, kTransformFeedbackSize * 2, nullptr, GL_STATIC_DRAW);
6229     glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, transformFeedbackBuffer);
6230 
6231     GLTransformFeedback pointsXFB;
6232     glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, pointsXFB);
6233     GLBuffer pointsXFBBuffer;
6234     glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, pointsXFBBuffer);
6235     glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 1024, nullptr, GL_STREAM_DRAW);
6236     glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, pointsXFBBuffer);
6237 
6238     // Begin TRIANGLES, switch to paused POINTS, should be valid.
6239     glBeginTransformFeedback(GL_POINTS);
6240     glPauseTransformFeedback();
6241     ASSERT_GL_NO_ERROR() << "Starting point transform feedback should succeed";
6242 
6243     glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedback);
6244     glBeginTransformFeedback(GL_TRIANGLES);
6245     glDrawArrays(GL_TRIANGLES, 0, 6);
6246     EXPECT_GL_NO_ERROR() << "Triangle rendering should succeed";
6247     glDrawArrays(GL_POINTS, 0, 6);
6248     EXPECT_GL_ERROR(GL_INVALID_OPERATION) << "Point rendering should fail";
6249     glDrawArrays(GL_LINES, 0, 6);
6250     EXPECT_GL_ERROR(GL_INVALID_OPERATION) << "Lines rendering should fail";
6251     glPauseTransformFeedback();
6252     glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, pointsXFB);
6253     glResumeTransformFeedback();
6254     glDrawArrays(GL_POINTS, 0, 6);
6255     EXPECT_GL_NO_ERROR() << "Point rendering should succeed";
6256     glDrawArrays(GL_TRIANGLES, 0, 6);
6257     EXPECT_GL_ERROR(GL_INVALID_OPERATION) << "Triangle rendering should fail";
6258     glDrawArrays(GL_LINES, 0, 6);
6259     EXPECT_GL_ERROR(GL_INVALID_OPERATION) << "Lines rendering should fail";
6260 
6261     glEndTransformFeedback();
6262     glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedback);
6263     glEndTransformFeedback();
6264     ASSERT_GL_NO_ERROR() << "Ending transform feeback should pass";
6265 
6266     glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
6267 
6268     glDrawArrays(GL_POINTS, 0, 6);
6269     EXPECT_GL_NO_ERROR() << "Point rendering should succeed";
6270     glDrawArrays(GL_TRIANGLES, 0, 6);
6271     EXPECT_GL_NO_ERROR() << "Triangle rendering should succeed";
6272     glDrawArrays(GL_LINES, 0, 6);
6273     EXPECT_GL_NO_ERROR() << "Line rendering should succeed";
6274 }
6275 
6276 // Tests a valid rendering setup with two textures. Followed by a draw with conflicting samplers.
TEST_P(ValidationStateChangeTest,TextureConflict)6277 TEST_P(ValidationStateChangeTest, TextureConflict)
6278 {
6279     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_storage"));
6280 
6281     GLint maxTextures = 0;
6282     glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextures);
6283     ANGLE_SKIP_TEST_IF(maxTextures < 2);
6284 
6285     // Set up state.
6286     constexpr GLint kSize = 2;
6287 
6288     std::vector<GLColor> greenData(4, GLColor::green);
6289 
6290     GLTexture textureA;
6291     glBindTexture(GL_TEXTURE_2D, textureA);
6292     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
6293                  greenData.data());
6294     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6295     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6296 
6297     glActiveTexture(GL_TEXTURE1);
6298 
6299     GLTexture textureB;
6300     glBindTexture(GL_TEXTURE_CUBE_MAP, textureB);
6301     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA8, kSize, kSize, 0, GL_RGBA,
6302                  GL_UNSIGNED_BYTE, greenData.data());
6303     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA8, kSize, kSize, 0, GL_RGBA,
6304                  GL_UNSIGNED_BYTE, greenData.data());
6305     glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA8, kSize, kSize, 0, GL_RGBA,
6306                  GL_UNSIGNED_BYTE, greenData.data());
6307     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA8, kSize, kSize, 0, GL_RGBA,
6308                  GL_UNSIGNED_BYTE, greenData.data());
6309     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA8, kSize, kSize, 0, GL_RGBA,
6310                  GL_UNSIGNED_BYTE, greenData.data());
6311     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA8, kSize, kSize, 0, GL_RGBA,
6312                  GL_UNSIGNED_BYTE, greenData.data());
6313     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6314     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6315 
6316     constexpr char kVS[] = R"(attribute vec2 position;
6317 varying mediump vec2 texCoord;
6318 void main()
6319 {
6320     gl_Position = vec4(position, 0, 1);
6321     texCoord = position * 0.5 + vec2(0.5);
6322 })";
6323 
6324     constexpr char kFS[] = R"(varying mediump vec2 texCoord;
6325 uniform sampler2D texA;
6326 uniform samplerCube texB;
6327 void main()
6328 {
6329     gl_FragColor = texture2D(texA, texCoord) + textureCube(texB, vec3(1, 0, 0));
6330 })";
6331 
6332     ANGLE_GL_PROGRAM(program, kVS, kFS);
6333     glUseProgram(program);
6334 
6335     const auto &quadVertices = GetQuadVertices();
6336 
6337     GLBuffer arrayBuffer;
6338     glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer);
6339     glBufferData(GL_ARRAY_BUFFER, quadVertices.size() * sizeof(Vector3), quadVertices.data(),
6340                  GL_STATIC_DRAW);
6341 
6342     GLint positionLoc = glGetAttribLocation(program, "position");
6343     ASSERT_NE(-1, positionLoc);
6344 
6345     GLint texALoc = glGetUniformLocation(program, "texA");
6346     ASSERT_NE(-1, texALoc);
6347 
6348     GLint texBLoc = glGetUniformLocation(program, "texB");
6349     ASSERT_NE(-1, texBLoc);
6350 
6351     glUniform1i(texALoc, 0);
6352     glUniform1i(texBLoc, 1);
6353 
6354     glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
6355     glEnableVertexAttribArray(positionLoc);
6356 
6357     ASSERT_GL_NO_ERROR();
6358 
6359     // First draw. Should succeed.
6360     glDrawArrays(GL_TRIANGLES, 0, 6);
6361     ASSERT_GL_NO_ERROR();
6362     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6363 
6364     // Second draw to ensure all state changes are flushed.
6365     glDrawArrays(GL_TRIANGLES, 0, 6);
6366     ASSERT_GL_NO_ERROR();
6367 
6368     // Make the uniform use an invalid texture binding.
6369     glUniform1i(texBLoc, 0);
6370     glDrawArrays(GL_TRIANGLES, 0, 6);
6371     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
6372 }
6373 
6374 // Tests that mapping the element array buffer triggers errors.
TEST_P(ValidationStateChangeTest,MapElementArrayBuffer)6375 TEST_P(ValidationStateChangeTest, MapElementArrayBuffer)
6376 {
6377     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
6378     glUseProgram(program);
6379 
6380     std::array<GLushort, 6> quadIndices = GetQuadIndices();
6381     std::array<Vector3, 4> quadVertices = GetIndexedQuadVertices();
6382 
6383     GLsizei elementBufferSize = sizeof(quadIndices[0]) * quadIndices.size();
6384 
6385     GLBuffer elementArrayBuffer;
6386     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayBuffer);
6387     glBufferData(GL_ELEMENT_ARRAY_BUFFER, elementBufferSize, quadIndices.data(), GL_STATIC_DRAW);
6388 
6389     GLBuffer arrayBuffer;
6390     glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer);
6391     glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices[0]) * quadVertices.size(),
6392                  quadVertices.data(), GL_STATIC_DRAW);
6393 
6394     GLint positionLoc = glGetAttribLocation(program, essl3_shaders::PositionAttrib());
6395     ASSERT_NE(-1, positionLoc);
6396     glVertexAttribPointer(positionLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
6397     glEnableVertexAttribArray(positionLoc);
6398 
6399     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
6400     ASSERT_GL_NO_ERROR();
6401 
6402     void *ptr = glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, elementBufferSize, GL_MAP_READ_BIT);
6403     ASSERT_NE(nullptr, ptr);
6404 
6405     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
6406     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
6407 
6408     glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
6409 
6410     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
6411     ASSERT_GL_NO_ERROR();
6412     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
6413 }
6414 
6415 // Tests that deleting a non-active texture does not reset the current texture cache.
TEST_P(SimpleStateChangeTest,DeleteNonActiveTextureThenDraw)6416 TEST_P(SimpleStateChangeTest, DeleteNonActiveTextureThenDraw)
6417 {
6418     constexpr char kFS[] =
6419         "uniform sampler2D us; void main() { gl_FragColor = texture2D(us, vec2(0)); }";
6420     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), kFS);
6421     glUseProgram(program);
6422     GLint loc = glGetUniformLocation(program, "us");
6423     ASSERT_EQ(0, loc);
6424 
6425     auto quadVertices = GetQuadVertices();
6426     GLint posLoc      = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
6427     ASSERT_EQ(0, posLoc);
6428 
6429     GLBuffer buffer;
6430     glBindBuffer(GL_ARRAY_BUFFER, buffer);
6431     glBufferData(GL_ARRAY_BUFFER, quadVertices.size() * sizeof(quadVertices[0]),
6432                  quadVertices.data(), GL_STATIC_DRAW);
6433     glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
6434     glEnableVertexAttribArray(posLoc);
6435 
6436     constexpr size_t kSize = 2;
6437     std::vector<GLColor> red(kSize * kSize, GLColor::red);
6438 
6439     GLTexture tex;
6440     glBindTexture(GL_TEXTURE_2D, tex);
6441     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, red.data());
6442     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6443     glUniform1i(loc, 0);
6444 
6445     glDrawArrays(GL_TRIANGLES, 0, 3);
6446     ASSERT_GL_NO_ERROR();
6447     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
6448 
6449     // Deleting TEXTURE_CUBE_MAP[0] should not affect TEXTURE_2D[0].
6450     GLTexture tex2;
6451     glBindTexture(GL_TEXTURE_CUBE_MAP, tex2);
6452     tex2.reset();
6453 
6454     glDrawArrays(GL_TRIANGLES, 0, 3);
6455     ASSERT_GL_NO_ERROR();
6456     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
6457 
6458     // Deleting TEXTURE_2D[0] should start "sampling" from the default/zero texture.
6459     tex.reset();
6460 
6461     glDrawArrays(GL_TRIANGLES, 0, 3);
6462     ASSERT_GL_NO_ERROR();
6463     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
6464 }
6465 
6466 // Tests that deleting a texture successfully binds the zero texture.
TEST_P(SimpleStateChangeTest,DeleteTextureThenDraw)6467 TEST_P(SimpleStateChangeTest, DeleteTextureThenDraw)
6468 {
6469     constexpr char kFS[] =
6470         "uniform sampler2D us; void main() { gl_FragColor = texture2D(us, vec2(0)); }";
6471     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), kFS);
6472     glUseProgram(program);
6473     GLint loc = glGetUniformLocation(program, "us");
6474     ASSERT_EQ(0, loc);
6475 
6476     auto quadVertices = GetQuadVertices();
6477     GLint posLoc      = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
6478     ASSERT_EQ(0, posLoc);
6479 
6480     GLBuffer buffer;
6481     glBindBuffer(GL_ARRAY_BUFFER, buffer);
6482     glBufferData(GL_ARRAY_BUFFER, quadVertices.size() * sizeof(quadVertices[0]),
6483                  quadVertices.data(), GL_STATIC_DRAW);
6484     glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
6485     glEnableVertexAttribArray(posLoc);
6486 
6487     constexpr size_t kSize = 2;
6488     std::vector<GLColor> red(kSize * kSize, GLColor::red);
6489 
6490     GLTexture tex;
6491     glBindTexture(GL_TEXTURE_2D, tex);
6492     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, red.data());
6493     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6494     glUniform1i(loc, 1);
6495     tex.reset();
6496 
6497     glDrawArrays(GL_TRIANGLES, 0, 3);
6498     ASSERT_GL_NO_ERROR();
6499     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
6500 }
6501 
bindTextureToFbo(GLFramebuffer & fbo,GLTexture & texture)6502 void SimpleStateChangeTest::bindTextureToFbo(GLFramebuffer &fbo, GLTexture &texture)
6503 {
6504     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
6505     glBindTexture(GL_TEXTURE_2D, texture);
6506     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
6507                  GL_UNSIGNED_BYTE, nullptr);
6508     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6509     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6510     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
6511     ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
6512 }
6513 
drawToFboWithCulling(const GLenum frontFace,bool earlyFrontFaceDirty)6514 void SimpleStateChangeTest::drawToFboWithCulling(const GLenum frontFace, bool earlyFrontFaceDirty)
6515 {
6516     // Render to an FBO
6517     GLFramebuffer fbo1;
6518     GLTexture texture1;
6519 
6520     ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
6521     ANGLE_GL_PROGRAM(textureProgram, essl1_shaders::vs::Texture2D(),
6522                      essl1_shaders::fs::Texture2D());
6523 
6524     bindTextureToFbo(fbo1, texture1);
6525 
6526     // Clear the surface FBO to initialize it to a known value
6527     glBindFramebuffer(GL_FRAMEBUFFER, 0);
6528     glClearColor(kFloatRed.R, kFloatRed.G, kFloatRed.B, kFloatRed.A);
6529     glClear(GL_COLOR_BUFFER_BIT);
6530     ASSERT_GL_NO_ERROR();
6531     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
6532     glFlush();
6533 
6534     // Draw to FBO 1 to initialize it to a known value
6535     glBindFramebuffer(GL_FRAMEBUFFER, fbo1);
6536 
6537     if (earlyFrontFaceDirty)
6538     {
6539         glEnable(GL_CULL_FACE);
6540         // Make sure we don't cull
6541         glCullFace(frontFace == GL_CCW ? GL_BACK : GL_FRONT);
6542         glFrontFace(frontFace);
6543     }
6544     else
6545     {
6546         glDisable(GL_CULL_FACE);
6547     }
6548 
6549     glUseProgram(greenProgram);
6550     drawQuad(greenProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
6551     ASSERT_GL_NO_ERROR();
6552     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6553 
6554     // Draw into FBO 0 using FBO 1's texture to determine if culling is working or not
6555     glBindFramebuffer(GL_FRAMEBUFFER, 0);
6556     glBindTexture(GL_TEXTURE_2D, texture1);
6557 
6558     glCullFace(GL_BACK);
6559     if (!earlyFrontFaceDirty)
6560     {
6561         // Set the culling we want to test
6562         glEnable(GL_CULL_FACE);
6563         glFrontFace(frontFace);
6564     }
6565 
6566     glUseProgram(textureProgram);
6567     drawQuad(textureProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
6568     ASSERT_GL_NO_ERROR();
6569 
6570     if (frontFace == GL_CCW)
6571     {
6572         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6573     }
6574     else
6575     {
6576         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
6577     }
6578 
6579     glBindFramebuffer(GL_FRAMEBUFFER, 0);
6580     glBindTexture(GL_TEXTURE_2D, 0);
6581 }
6582 
6583 // Validates if culling rasterization states work with FBOs using CCW winding.
TEST_P(SimpleStateChangeTest,FboEarlyCullFaceBackCCWState)6584 TEST_P(SimpleStateChangeTest, FboEarlyCullFaceBackCCWState)
6585 {
6586     drawToFboWithCulling(GL_CCW, true);
6587 }
6588 
6589 // Validates if culling rasterization states work with FBOs using CW winding.
TEST_P(SimpleStateChangeTest,FboEarlyCullFaceBackCWState)6590 TEST_P(SimpleStateChangeTest, FboEarlyCullFaceBackCWState)
6591 {
6592     drawToFboWithCulling(GL_CW, true);
6593 }
6594 
TEST_P(SimpleStateChangeTest,FboLateCullFaceBackCCWState)6595 TEST_P(SimpleStateChangeTest, FboLateCullFaceBackCCWState)
6596 {
6597     drawToFboWithCulling(GL_CCW, false);
6598 }
6599 
6600 // Validates if culling rasterization states work with FBOs using CW winding.
TEST_P(SimpleStateChangeTest,FboLateCullFaceBackCWState)6601 TEST_P(SimpleStateChangeTest, FboLateCullFaceBackCWState)
6602 {
6603     drawToFboWithCulling(GL_CW, false);
6604 }
6605 
6606 // Test that vertex attribute translation is still kept after binding it to another buffer then
6607 // binding back to the previous buffer.
TEST_P(SimpleStateChangeTest,RebindTranslatedAttribute)6608 TEST_P(SimpleStateChangeTest, RebindTranslatedAttribute)
6609 {
6610     // http://anglebug.com/5379
6611     ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsVulkan());
6612 
6613     constexpr char kVS[] = R"(attribute vec4 a_position;
6614 attribute float a_attrib;
6615 varying float v_attrib;
6616 void main()
6617 {
6618     v_attrib = a_attrib;
6619     gl_Position = a_position;
6620 })";
6621 
6622     constexpr char kFS[] = R"(precision mediump float;
6623 varying float v_attrib;
6624 void main()
6625 {
6626     gl_FragColor = vec4(v_attrib, 0, 0, 1);
6627 })";
6628 
6629     ANGLE_GL_PROGRAM(program, kVS, kFS);
6630     glBindAttribLocation(program, 0, "a_position");
6631     glBindAttribLocation(program, 1, "a_attrib");
6632     glLinkProgram(program);
6633     glUseProgram(program);
6634     ASSERT_GL_NO_ERROR();
6635 
6636     // Set up color data so red is drawn
6637     std::vector<GLushort> data(1000, 0xffff);
6638 
6639     GLBuffer redBuffer;
6640     glBindBuffer(GL_ARRAY_BUFFER, redBuffer);
6641     glBufferData(GL_ARRAY_BUFFER, sizeof(GLushort) * data.size(), data.data(), GL_STATIC_DRAW);
6642     // Use offset not multiple of 4 GLushorts, this could force vertex translation in Metal backend.
6643     glVertexAttribPointer(1, 4, GL_UNSIGNED_SHORT, GL_TRUE, 0,
6644                           reinterpret_cast<const void *>(sizeof(GLushort) * 97));
6645     glBindBuffer(GL_ARRAY_BUFFER, 0);
6646     glEnableVertexAttribArray(1);
6647 
6648     drawQuad(program, "a_position", 0.5f);
6649     // Verify red was drawn
6650     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
6651 
6652     glClearColor(0, 1, 0, 1);
6653     glClear(GL_COLOR_BUFFER_BIT);
6654     // Verify that green was drawn
6655     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6656 
6657     // Bind black color buffer to the same attribute with zero offset
6658     std::vector<GLfloat> black(6, 0.0f);
6659     GLBuffer blackBuffer;
6660     glBindBuffer(GL_ARRAY_BUFFER, blackBuffer);
6661     glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * black.size(), black.data(), GL_STATIC_DRAW);
6662     glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, 0);
6663 
6664     drawQuad(program, "a_position", 0.5f);
6665     // Verify black was drawn
6666     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
6667 
6668     // Rebind the old buffer & offset
6669     glBindBuffer(GL_ARRAY_BUFFER, redBuffer);
6670     // Use offset not multiple of 4 GLushorts
6671     glVertexAttribPointer(1, 4, GL_UNSIGNED_SHORT, GL_TRUE, 0,
6672                           reinterpret_cast<const void *>(sizeof(GLushort) * 97));
6673 
6674     drawQuad(program, "a_position", 0.5f);
6675     // Verify red was drawn
6676     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
6677 }
6678 
6679 // Test that switching between programs that only contain default uniforms is correct.
TEST_P(SimpleStateChangeTest,TwoProgramsWithOnlyDefaultUniforms)6680 TEST_P(SimpleStateChangeTest, TwoProgramsWithOnlyDefaultUniforms)
6681 {
6682     constexpr char kVS[] = R"(attribute vec4 a_position;
6683 varying float v_attrib;
6684 uniform float u_value;
6685 void main()
6686 {
6687     v_attrib = u_value;
6688     gl_Position = a_position;
6689 })";
6690 
6691     constexpr char kFS[] = R"(precision mediump float;
6692 varying float v_attrib;
6693 void main()
6694 {
6695     gl_FragColor = vec4(v_attrib, 0, 0, 1);
6696 })";
6697 
6698     ANGLE_GL_PROGRAM(program1, kVS, kFS);
6699     ANGLE_GL_PROGRAM(program2, kVS, kFS);
6700 
6701     // Don't use drawQuad so there's no state changes between the draw calls other than the program
6702     // binding.
6703 
6704     constexpr size_t kProgramCount = 2;
6705     GLuint programs[kProgramCount] = {program1, program2};
6706     for (size_t i = 0; i < kProgramCount; ++i)
6707     {
6708         glUseProgram(programs[i]);
6709         GLint uniformLoc = glGetUniformLocation(programs[i], "u_value");
6710         ASSERT_NE(uniformLoc, -1);
6711 
6712         glUniform1f(uniformLoc, static_cast<float>(i + 1) / static_cast<float>(kProgramCount));
6713 
6714         // Ensure position is at location 0 in both programs.
6715         GLint positionLocation = glGetAttribLocation(programs[i], "a_position");
6716         ASSERT_EQ(positionLocation, 0);
6717     }
6718     ASSERT_GL_NO_ERROR();
6719 
6720     std::array<Vector3, 6> quadVertices = GetQuadVertices();
6721     glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, quadVertices.data());
6722     glEnableVertexAttribArray(0);
6723 
6724     // Draw once with each so their uniforms are updated.
6725     // The first draw will clear the screen to 255, 0, 0, 255
6726     glUseProgram(program2);
6727     glDrawArrays(GL_TRIANGLES, 0, 6);
6728     // The second draw will clear the screen to 127, 0, 0, 255
6729     glUseProgram(program1);
6730     glDrawArrays(GL_TRIANGLES, 0, 6);
6731 
6732     // Draw with the previous program again, to make sure its default uniforms are bound again.
6733     glUseProgram(program2);
6734     glDrawArrays(GL_TRIANGLES, 0, 6);
6735 
6736     // Verify red was drawn
6737     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
6738 }
6739 
6740 // Test that glDrawArrays when an empty-sized element array buffer is bound doesn't crash.
6741 // Regression test for crbug.com/1172577.
TEST_P(SimpleStateChangeTest,DrawArraysWithZeroSizedElementArrayBuffer)6742 TEST_P(SimpleStateChangeTest, DrawArraysWithZeroSizedElementArrayBuffer)
6743 {
6744     ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
6745 
6746     GLBuffer indexBuffer;
6747     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
6748     glBufferData(GL_ELEMENT_ARRAY_BUFFER, 0, nullptr, GL_DYNAMIC_DRAW);
6749     drawQuad(greenProgram, essl1_shaders::PositionAttrib(), 0.0f);
6750     ASSERT_GL_NO_ERROR();
6751 
6752     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6753 }
6754 
6755 // Validates GL_RASTERIZER_DISCARD state is tracked correctly
TEST_P(SimpleStateChangeTestES3,RasterizerDiscardState)6756 TEST_P(SimpleStateChangeTestES3, RasterizerDiscardState)
6757 {
6758     glClearColor(kFloatRed.R, kFloatRed.G, kFloatRed.B, kFloatRed.A);
6759     glClear(GL_COLOR_BUFFER_BIT);
6760     ASSERT_GL_NO_ERROR();
6761     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
6762 
6763     ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
6764     ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
6765 
6766     // The drawQuad() should have no effect with GL_RASTERIZER_DISCARD enabled
6767     glEnable(GL_RASTERIZER_DISCARD);
6768     glUseProgram(greenProgram);
6769     drawQuad(greenProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
6770     ASSERT_GL_NO_ERROR();
6771     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
6772 
6773     // The drawQuad() should draw something with GL_RASTERIZER_DISCARD disabled
6774     glDisable(GL_RASTERIZER_DISCARD);
6775     glUseProgram(greenProgram);
6776     drawQuad(greenProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
6777     ASSERT_GL_NO_ERROR();
6778     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6779 
6780     // The drawQuad() should have no effect with GL_RASTERIZER_DISCARD enabled
6781     glEnable(GL_RASTERIZER_DISCARD);
6782     glUseProgram(blueProgram);
6783     drawQuad(blueProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
6784     ASSERT_GL_NO_ERROR();
6785     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
6786 }
6787 
6788 // Test that early return on binding the same texture is functional
TEST_P(SimpleStateChangeTestES3,BindingSameTexture)6789 TEST_P(SimpleStateChangeTestES3, BindingSameTexture)
6790 {
6791     // Create two 1x1 textures
6792     constexpr GLsizei kSize           = 2;
6793     std::array<GLColor, kSize> colors = {GLColor::yellow, GLColor::cyan};
6794 
6795     GLTexture tex[kSize];
6796     // Bind texture 0 and 1 to active textures 0 and 1 and set data
6797     glActiveTexture(GL_TEXTURE0);
6798     glBindTexture(GL_TEXTURE_2D, tex[0]);
6799     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors[0].data());
6800 
6801     glActiveTexture(GL_TEXTURE1);
6802     glBindTexture(GL_TEXTURE_2D, tex[1]);
6803     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors[1].data());
6804 
6805     // Create simple program and query sampler location
6806     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
6807     ASSERT(program.valid());
6808     glUseProgram(program);
6809     GLint textureLocation = glGetUniformLocation(program, essl1_shaders::Texture2DUniform());
6810     ASSERT_NE(-1, textureLocation);
6811 
6812     // Draw using active texture 0.
6813     glActiveTexture(GL_TEXTURE0);
6814     glUniform1i(textureLocation, 0);
6815     glBindTexture(GL_TEXTURE_2D, tex[0]);
6816     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
6817     ASSERT_GL_NO_ERROR();
6818     EXPECT_PIXEL_COLOR_EQ(0, 0, colors[0]);
6819 
6820     // Draw using active texture 1.
6821     glActiveTexture(GL_TEXTURE1);
6822     glUniform1i(textureLocation, 1);
6823     glBindTexture(GL_TEXTURE_2D, tex[1]);
6824     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
6825     ASSERT_GL_NO_ERROR();
6826     EXPECT_PIXEL_COLOR_EQ(0, 0, colors[1]);
6827 
6828     // Rebind the same texture to texture unit 1 and expect same color
6829     glBindTexture(GL_TEXTURE_2D, tex[1]);
6830     glUniform1i(textureLocation, 1);
6831     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
6832     ASSERT_GL_NO_ERROR();
6833     EXPECT_PIXEL_COLOR_EQ(0, 0, colors[1]);
6834 
6835     // Rebind the same texture to texture unit 0 and expect same color
6836     glActiveTexture(GL_TEXTURE0);
6837     glUniform1i(textureLocation, 0);
6838     glBindTexture(GL_TEXTURE_2D, tex[0]);
6839     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
6840     ASSERT_GL_NO_ERROR();
6841     EXPECT_PIXEL_COLOR_EQ(0, 0, colors[0]);
6842 }
6843 
6844 // Test that early return on binding the same sampler is functional
TEST_P(SimpleStateChangeTestES3,BindingSameSampler)6845 TEST_P(SimpleStateChangeTestES3, BindingSameSampler)
6846 {
6847     // Create 2 samplers with different filtering.
6848     constexpr GLsizei kNumSamplers = 2;
6849     GLSampler samplers[kNumSamplers];
6850 
6851     // Init sampler0
6852     glBindSampler(0, samplers[0]);
6853     glSamplerParameteri(samplers[0], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
6854     glSamplerParameteri(samplers[0], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
6855     ASSERT_GL_NO_ERROR();
6856 
6857     // Init sampler1
6858     glBindSampler(1, samplers[1]);
6859     glSamplerParameteri(samplers[1], GL_TEXTURE_MIN_FILTER, GL_LINEAR);
6860     glSamplerParameteri(samplers[1], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
6861     ASSERT_GL_NO_ERROR();
6862 
6863     // Create a simple 2x1 texture with black and white colors
6864     std::array<GLColor, 2> colors = {{GLColor::black, GLColor::white}};
6865 
6866     GLTexture tex;
6867     // Bind the same texture to texture units 0 and 1
6868     glActiveTexture(GL_TEXTURE0);
6869     glBindTexture(GL_TEXTURE_2D, tex);
6870     glActiveTexture(GL_TEXTURE1);
6871     glBindTexture(GL_TEXTURE_2D, tex);
6872     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
6873 
6874     // Create a program that uses 2 samplers.
6875     constexpr char kFS[] = R"(precision mediump float;
6876 varying vec2 v_texCoord;
6877 uniform sampler2D baseSampler;
6878 uniform sampler2D overrideSampler;
6879 void main()
6880 {
6881     gl_FragColor = texture2D(baseSampler, v_texCoord);
6882     gl_FragColor = texture2D(overrideSampler, v_texCoord);
6883 })";
6884     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), kFS);
6885     glUseProgram(program);
6886     GLint baseSamplerLoc     = glGetUniformLocation(program, "baseSampler");
6887     GLint overrideSamplerLoc = glGetUniformLocation(program, "overrideSampler");
6888 
6889     // Bind samplers to texture units 0 and 1
6890     glBindSampler(0, samplers[0]);
6891     glBindSampler(1, samplers[1]);
6892     glUniform1i(baseSamplerLoc, 0);
6893     glUniform1i(overrideSamplerLoc, 1);
6894     drawQuad(program, std::string(essl1_shaders::PositionAttrib()), 0.5f);
6895     ASSERT_GL_NO_ERROR();
6896     // A gradient should have been rendered since "overrideSampler" has linear filter,
6897     // we should not expect a solid black or white color.
6898     EXPECT_NE(angle::ReadColor(getWindowWidth() / 2, getWindowHeight() / 2), GLColor::black);
6899     EXPECT_NE(angle::ReadColor(getWindowWidth() / 2, getWindowHeight() / 2), GLColor::white);
6900 
6901     // Switch sampler bindings
6902     glBindSampler(1, samplers[0]);
6903     glBindSampler(0, samplers[1]);
6904     drawQuad(program, std::string(essl1_shaders::PositionAttrib()), 0.5f);
6905     ASSERT_GL_NO_ERROR();
6906     // Now that "overrideSampler" has nearest filter expect solid colors.
6907     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
6908     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, 0, GLColor::white);
6909 
6910     // Rebind the same samplers again and expect same output
6911     glBindSampler(1, samplers[0]);
6912     glBindSampler(0, samplers[1]);
6913     drawQuad(program, std::string(essl1_shaders::PositionAttrib()), 0.5f);
6914     ASSERT_GL_NO_ERROR();
6915     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
6916     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, 0, GLColor::white);
6917 }
6918 
6919 // Test that early return on binding the same buffer is functional
TEST_P(SimpleStateChangeTestES3,BindingSameBuffer)6920 TEST_P(SimpleStateChangeTestES3, BindingSameBuffer)
6921 {
6922     GLushort indexData[] = {0, 1, 2, 3};
6923 
6924     GLBuffer elementArrayBuffer;
6925     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayBuffer);
6926     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexData), indexData, GL_STATIC_DRAW);
6927 
6928     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Zero(), essl1_shaders::fs::Red());
6929     glUseProgram(program);
6930 
6931     glDrawElements(GL_POINTS, 4, GL_UNSIGNED_SHORT, 0);
6932 
6933     std::vector<GLColor> colors0(kWindowSize * kWindowSize);
6934     glReadPixels(0, 0, kWindowSize, kWindowSize, GL_RGBA, GL_UNSIGNED_BYTE, colors0.data());
6935 
6936     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayBuffer);
6937     glDrawElements(GL_POINTS, 4, GL_UNSIGNED_SHORT, 0);
6938     std::vector<GLColor> colors1(kWindowSize * kWindowSize);
6939     glReadPixels(0, 0, kWindowSize, kWindowSize, GL_RGBA, GL_UNSIGNED_BYTE, colors1.data());
6940 
6941     EXPECT_EQ(colors0, colors1);
6942 }
6943 
6944 class ImageRespecificationTest : public ANGLETest<>
6945 {
6946   protected:
ImageRespecificationTest()6947     ImageRespecificationTest()
6948     {
6949         setWindowWidth(128);
6950         setWindowHeight(128);
6951         setConfigRedBits(8);
6952         setConfigGreenBits(8);
6953         setConfigBlueBits(8);
6954         setConfigAlphaBits(8);
6955         setConfigDepthBits(24);
6956     }
6957 
testSetUp()6958     void testSetUp() override
6959     {
6960         constexpr char kVS[] = R"(precision highp float;
6961 attribute vec4 position;
6962 varying vec2 texcoord;
6963 
6964 void main()
6965 {
6966     gl_Position = position;
6967     texcoord = (position.xy * 0.5) + 0.5;
6968 })";
6969 
6970         constexpr char kFS[] = R"(precision highp float;
6971 uniform sampler2D tex;
6972 varying vec2 texcoord;
6973 
6974 void main()
6975 {
6976     gl_FragColor = texture2D(tex, texcoord);
6977 })";
6978 
6979         mProgram = CompileProgram(kVS, kFS);
6980         ASSERT_NE(0u, mProgram);
6981 
6982         mTextureUniformLocation = glGetUniformLocation(mProgram, "tex");
6983         ASSERT_NE(-1, mTextureUniformLocation);
6984 
6985         glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
6986         ASSERT_GL_NO_ERROR();
6987     }
6988 
testTearDown()6989     void testTearDown() override
6990     {
6991         if (mProgram != 0)
6992         {
6993             glDeleteProgram(mProgram);
6994         }
6995     }
6996 
6997     template <typename T>
init2DSourceTexture(GLenum internalFormat,GLenum dataFormat,GLenum dataType,const T * data)6998     void init2DSourceTexture(GLenum internalFormat,
6999                              GLenum dataFormat,
7000                              GLenum dataType,
7001                              const T *data)
7002     {
7003         glBindTexture(GL_TEXTURE_2D, mSourceTexture);
7004         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
7005 
7006         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7007         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7008 
7009         glBindTexture(GL_TEXTURE_2D, 0);
7010     }
7011 
attachTargetTextureToFramebuffer()7012     void attachTargetTextureToFramebuffer()
7013     {
7014         glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
7015         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTargetTexture,
7016                                0);
7017 
7018         ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
7019         ASSERT_GL_NO_ERROR();
7020 
7021         glBindFramebuffer(GL_FRAMEBUFFER, 0);
7022     }
7023 
renderToTargetTexture()7024     void renderToTargetTexture()
7025     {
7026         glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
7027 
7028         glActiveTexture(GL_TEXTURE0);
7029         glBindTexture(GL_TEXTURE_2D, mSourceTexture);
7030 
7031         glUseProgram(mProgram);
7032         glUniform1i(mTextureUniformLocation, 0);
7033 
7034         drawQuad(mProgram, "position", 0.5f);
7035         ASSERT_GL_NO_ERROR();
7036 
7037         glBindFramebuffer(GL_FRAMEBUFFER, 0);
7038         glBindTexture(GL_TEXTURE_2D, 0);
7039         glUseProgram(0);
7040     }
7041 
renderToDefaultFramebuffer(GLColor * expectedData)7042     void renderToDefaultFramebuffer(GLColor *expectedData)
7043     {
7044         glBindFramebuffer(GL_FRAMEBUFFER, 0);
7045         glUseProgram(mProgram);
7046         glBindTexture(GL_TEXTURE_2D, mTargetTexture);
7047         glUniform1i(mTextureUniformLocation, 0);
7048 
7049         glClear(GL_COLOR_BUFFER_BIT);
7050         drawQuad(mProgram, "position", 0.5f);
7051         ASSERT_GL_NO_ERROR();
7052 
7053         EXPECT_PIXEL_COLOR_EQ(0, 0, *expectedData);
7054 
7055         glBindTexture(GL_TEXTURE_2D, 0);
7056         glUseProgram(0);
7057     }
7058 
7059     GLuint mProgram;
7060     GLint mTextureUniformLocation;
7061 
7062     GLTexture mSourceTexture;
7063     GLTexture mTargetTexture;
7064 
7065     GLFramebuffer mFramebuffer;
7066 };
7067 
7068 // Verify that a swizzle on an active sampler is handled appropriately
TEST_P(ImageRespecificationTest,Swizzle)7069 TEST_P(ImageRespecificationTest, Swizzle)
7070 {
7071     GLubyte data[] = {1, 64, 128, 200};
7072     GLColor expectedData(data[0], data[1], data[2], data[3]);
7073 
7074     // Create the source and target texture
7075     init2DSourceTexture(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, data);
7076 
7077     glBindTexture(GL_TEXTURE_2D, mTargetTexture);
7078     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
7079 
7080     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7081     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7082 
7083     glBindTexture(GL_TEXTURE_2D, 0);
7084 
7085     // Create a framebuffer and the target texture is attached to the framebuffer.
7086     attachTargetTextureToFramebuffer();
7087 
7088     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
7089     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
7090     glClear(GL_COLOR_BUFFER_BIT);
7091     glBindFramebuffer(GL_FRAMEBUFFER, 0);
7092 
7093     // Render content of source texture to target texture
7094     // This command triggers the creation of -
7095     //     - draw imageviews of the texture
7096     //     - VkFramebuffer object of the framebuffer
7097     renderToTargetTexture();
7098 
7099     // This swizzle operation should cause the read imageviews of the texture to be released
7100     glBindTexture(GL_TEXTURE_2D, mTargetTexture);
7101     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_RED);
7102     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN);
7103     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_BLUE);
7104     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA);
7105     glBindTexture(GL_TEXTURE_2D, 0);
7106 
7107     // Draw using the newly created read imageviews
7108     renderToDefaultFramebuffer(&expectedData);
7109 
7110     // Render content of source texture to target texture, again
7111     renderToTargetTexture();
7112 
7113     // Make sure the content rendered to target texture is correct
7114     renderToDefaultFramebuffer(&expectedData);
7115 }
7116 
7117 // Verify that when a texture is respecified through glEGLImageTargetTexture2DOES,
7118 // the Framebuffer that has the texture as a color attachment is recreated before next use.
TEST_P(ImageRespecificationTest,ImageTarget2DOESSwitch)7119 TEST_P(ImageRespecificationTest, ImageTarget2DOESSwitch)
7120 {
7121     // This is the specific problem on the Vulkan backend and needs some extensions
7122     ANGLE_SKIP_TEST_IF(
7123         !IsGLExtensionEnabled("GL_OES_EGL_image_external") ||
7124         !IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(), "EGL_KHR_gl_texture_2D_image"));
7125 
7126     GLubyte data[] = {1, 64, 128, 200};
7127     GLColor expectedData(data[0], data[1], data[2], data[3]);
7128 
7129     // Create the source texture
7130     init2DSourceTexture(GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, data);
7131 
7132     // Create the first EGL image to attach the framebuffer through the texture
7133     GLTexture firstTexture;
7134 
7135     glBindTexture(GL_TEXTURE_2D, firstTexture);
7136     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
7137 
7138     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7139     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7140 
7141     glBindTexture(GL_TEXTURE_2D, 0);
7142 
7143     EGLWindow *window = getEGLWindow();
7144     EGLint attribs[]  = {
7145         EGL_IMAGE_PRESERVED,
7146         EGL_TRUE,
7147         EGL_NONE,
7148     };
7149     EGLImageKHR firstEGLImage = eglCreateImageKHR(
7150         window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_2D_KHR,
7151         reinterpret_cast<EGLClientBuffer>(static_cast<uintptr_t>(firstTexture.get())), attribs);
7152     ASSERT_EGL_SUCCESS();
7153 
7154     // Create the target texture and attach it to the framebuffer
7155     glBindTexture(GL_TEXTURE_2D, mTargetTexture);
7156     glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, firstEGLImage);
7157 
7158     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7159     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7160 
7161     glBindTexture(GL_TEXTURE_2D, 0);
7162 
7163     attachTargetTextureToFramebuffer();
7164 
7165     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
7166 
7167     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
7168     glClear(GL_COLOR_BUFFER_BIT);
7169 
7170     glBindFramebuffer(GL_FRAMEBUFFER, 0);
7171 
7172     // Render content of source texture to target texture
7173     // This command triggers the creation of -
7174     //     - draw imageviews of the texture
7175     //     - VkFramebuffer object of the framebuffer
7176     renderToTargetTexture();
7177 
7178     // Make sure the content rendered to target texture is correct
7179     renderToDefaultFramebuffer(&expectedData);
7180 
7181     // Create the second EGL image
7182     GLTexture secondTexture;
7183 
7184     glBindTexture(GL_TEXTURE_2D, secondTexture);
7185     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
7186 
7187     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7188     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7189 
7190     glBindTexture(GL_TEXTURE_2D, 0);
7191 
7192     EGLImageKHR secondEGLImage = eglCreateImageKHR(
7193         window->getDisplay(), window->getContext(), EGL_GL_TEXTURE_2D_KHR,
7194         reinterpret_cast<EGLClientBuffer>(static_cast<uintptr_t>(secondTexture.get())), attribs);
7195     ASSERT_EGL_SUCCESS();
7196 
7197     glBindTexture(GL_TEXTURE_2D, mTargetTexture);
7198     // This will release all the imageviews related to the first EGL image
7199     glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, secondEGLImage);
7200 
7201     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7202     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7203 
7204     glBindTexture(GL_TEXTURE_2D, 0);
7205 
7206     // Attach the first EGL image to the target texture again
7207     glBindTexture(GL_TEXTURE_2D, mTargetTexture);
7208     glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, firstEGLImage);
7209 
7210     // This is for checking this code can deal with the problem even if both ORPHAN and
7211     // COLOR_ATTACHMENT dirty bits are set.
7212     GLTexture tempTexture;
7213 
7214     glBindTexture(GL_TEXTURE_2D, tempTexture);
7215     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
7216 
7217     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
7218     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
7219 
7220     glBindTexture(GL_TEXTURE_2D, 0);
7221 
7222     // This sets COLOR_ATTACHMENT dirty bit
7223     glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
7224     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tempTexture, 0);
7225     glBindFramebuffer(GL_FRAMEBUFFER, 0);
7226 
7227     // The released imageviews related to "secondEGLImage" will be garbage collected
7228     renderToDefaultFramebuffer(&expectedData);
7229 
7230     // Process both OPPHAN and COLOR_ATTACHMENT dirty bits
7231     renderToTargetTexture();
7232 
7233     // Make sure the content rendered to target texture is correct
7234     renderToDefaultFramebuffer(&expectedData);
7235 
7236     // Render content of source texture to target texture
7237     attachTargetTextureToFramebuffer();
7238     renderToTargetTexture();
7239 
7240     // Make sure the content rendered to target texture is correct
7241     renderToDefaultFramebuffer(&expectedData);
7242 
7243     eglDestroyImageKHR(window->getDisplay(), firstEGLImage);
7244     eglDestroyImageKHR(window->getDisplay(), secondEGLImage);
7245 }
7246 
7247 // Covers a bug where sometimes we wouldn't catch invalid element buffer sizes.
TEST_P(WebGL2ValidationStateChangeTest,DeleteElementArrayBufferValidation)7248 TEST_P(WebGL2ValidationStateChangeTest, DeleteElementArrayBufferValidation)
7249 {
7250     GLushort indexData[] = {0, 1, 2, 3};
7251 
7252     GLBuffer elementArrayBuffer;
7253     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayBuffer);
7254     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexData), indexData, GL_STATIC_DRAW);
7255 
7256     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Zero(), essl1_shaders::fs::Red());
7257     glUseProgram(program);
7258 
7259     glDrawElements(GL_POINTS, 4, GL_UNSIGNED_SHORT, 0);
7260 
7261     elementArrayBuffer.reset();
7262 
7263     // Must use a non-0 offset and a multiple of the type size.
7264     glDrawElements(GL_POINTS, 4, GL_UNSIGNED_SHORT, reinterpret_cast<const void *>(0x4));
7265     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
7266 }
7267 
7268 // Covers a bug in the D3D11 back-end related to how buffers are translated.
TEST_P(RobustBufferAccessWebGL2ValidationStateChangeTest,BindZeroSizeBufferThenDeleteBufferBug)7269 TEST_P(RobustBufferAccessWebGL2ValidationStateChangeTest, BindZeroSizeBufferThenDeleteBufferBug)
7270 {
7271     // SwiftShader does not currently support robustness.
7272     ANGLE_SKIP_TEST_IF(isSwiftshader());
7273 
7274     // http://anglebug.com/4872
7275     ANGLE_SKIP_TEST_IF(IsAndroid() && IsVulkan());
7276 
7277     // no intent to follow up on this failure.
7278     ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGL());
7279 
7280     // no intent to follow up on this failure.
7281     ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
7282 
7283     // no intent to follow up on this failure.
7284     ANGLE_SKIP_TEST_IF(IsMac());
7285 
7286     // Mali does not support robustness now.
7287     ANGLE_SKIP_TEST_IF(IsARM());
7288 
7289     // TODO(anglebug.com/5491)
7290     ANGLE_SKIP_TEST_IF(IsIOS() && IsOpenGLES());
7291 
7292     std::vector<GLubyte> data(48, 1);
7293 
7294     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Red());
7295     glUseProgram(program);
7296 
7297     // First bind and draw with a buffer with a format we know to be "Direct" in D3D11.
7298     GLBuffer arrayBuffer;
7299     glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer);
7300     glBufferData(GL_ARRAY_BUFFER, 48, data.data(), GL_STATIC_DRAW);
7301     glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
7302     glEnableVertexAttribArray(0);
7303     glDrawArrays(GL_TRIANGLES, 0, 3);
7304 
7305     // Then bind a zero size buffer and draw.
7306     GLBuffer secondBuffer;
7307     glBindBuffer(GL_ARRAY_BUFFER, secondBuffer);
7308     glVertexAttribPointer(0, 4, GL_UNSIGNED_BYTE, GL_FALSE, 1, 0);
7309     glDrawArrays(GL_TRIANGLES, 0, 3);
7310 
7311     // Finally delete the original buffer. This triggers the bug.
7312     arrayBuffer.reset();
7313     glDrawArrays(GL_TRIANGLES, 0, 3);
7314     ASSERT_GL_NO_ERROR();
7315 }
7316 
7317 // Tests DrawElements with an empty buffer using a VAO.
TEST_P(WebGL2ValidationStateChangeTest,DrawElementsEmptyVertexArray)7318 TEST_P(WebGL2ValidationStateChangeTest, DrawElementsEmptyVertexArray)
7319 {
7320     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
7321 
7322     glUseProgram(program);
7323 
7324     // Draw with empty buffer. Out of range but valid.
7325     GLBuffer buffer;
7326     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
7327     glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_SHORT, reinterpret_cast<const GLvoid *>(0x1000));
7328 
7329     // Switch VAO. No buffer bound, should be an error.
7330     GLVertexArray vao;
7331     glBindVertexArray(vao);
7332     glDrawElements(GL_LINE_STRIP, 0x1000, GL_UNSIGNED_SHORT,
7333                    reinterpret_cast<const GLvoid *>(0x1000));
7334     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
7335 }
7336 
7337 // Test that closing the render pass due to an update to UBO data then drawing non-indexed followed
7338 // by indexed works.
TEST_P(SimpleStateChangeTestES31,DrawThenUpdateUBOThenDrawThenDrawIndexed)7339 TEST_P(SimpleStateChangeTestES31, DrawThenUpdateUBOThenDrawThenDrawIndexed)
7340 {
7341     // First, create the index buffer and issue an indexed draw call.  This clears the index dirty
7342     // bit.
7343     GLBuffer indexBuffer;
7344     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
7345 
7346     const std::array<GLuint, 4> kIndexData = {0, 1, 2, 0};
7347     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(kIndexData), kIndexData.data(), GL_STATIC_DRAW);
7348 
7349     // Setup vertices.
7350     const std::array<GLfloat, 6> kVertices = {
7351         -1, -1, 3, -1, -1, 3,
7352     };
7353     GLBuffer vertexBuffer;
7354     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
7355     glBufferData(GL_ARRAY_BUFFER, sizeof(kVertices), kVertices.data(), GL_STATIC_DRAW);
7356     glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
7357     glEnableVertexAttribArray(0);
7358 
7359     // Create a uniform buffer that will get modified.  This is used to break the render pass.
7360     const std::array<GLuint, 4> kUboData1 = {0x12345678u, 0, 0, 0};
7361 
7362     GLBuffer ubo;
7363     glBindBuffer(GL_UNIFORM_BUFFER, ubo);
7364     glBindBufferBase(GL_UNIFORM_BUFFER, 0, ubo);
7365     glBufferData(GL_UNIFORM_BUFFER, sizeof(kUboData1), kUboData1.data(), GL_DYNAMIC_DRAW);
7366 
7367     // Set up a program.  The same program is used for all draw calls to avoid state change due to
7368     // program change.
7369     constexpr char kFS[] = R"(#version 300 es
7370 precision mediump float;
7371 uniform block { uint data; } ubo;
7372 uniform uint expect;
7373 uniform vec4 successColor;
7374 out vec4 colorOut;
7375 void main()
7376 {
7377     colorOut = ubo.data == expect ? successColor : colorOut = vec4(0, 0, 0, 0);
7378 })";
7379 
7380     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
7381     glUseProgram(program);
7382 
7383     const GLint positionLoc = glGetAttribLocation(program, essl3_shaders::PositionAttrib());
7384     const GLint expectLoc   = glGetUniformLocation(program, "expect");
7385     const GLint successLoc  = glGetUniformLocation(program, "successColor");
7386     ASSERT_NE(-1, positionLoc);
7387     ASSERT_NE(-1, expectLoc);
7388     ASSERT_NE(-1, successLoc);
7389 
7390     glVertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
7391     glEnableVertexAttribArray(positionLoc);
7392 
7393     glUniform1ui(expectLoc, kUboData1[0]);
7394     glUniform4f(successLoc, 0, 0, 0, 1);
7395     glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);
7396     EXPECT_GL_NO_ERROR();
7397 
7398     // Then upload data to the UBO so on next use the render pass has to break.  This draw call is
7399     // not indexed.
7400     constexpr GLuint kUboData2 = 0x87654321u;
7401     glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(kUboData2), &kUboData2);
7402 
7403     glEnable(GL_BLEND);
7404     glBlendFunc(GL_ONE, GL_ONE);
7405     glUniform1ui(expectLoc, kUboData2);
7406     glUniform4f(successLoc, 0, 1, 0, 0);
7407     glDrawArrays(GL_TRIANGLES, 0, 3);
7408 
7409     // Issue another draw call that is indexed.  The index buffer should be bound correctly on the
7410     // new render pass.
7411     glUniform4f(successLoc, 0, 0, 1, 0);
7412     glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);
7413     EXPECT_GL_NO_ERROR();
7414 
7415     // Ensure correct rendering.
7416     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
7417 }
7418 
7419 // Test that switching framebuffers then a non-indexed draw followed by an indexed one works.
TEST_P(SimpleStateChangeTestES31,DrawThenChangeFBOThenDrawThenDrawIndexed)7420 TEST_P(SimpleStateChangeTestES31, DrawThenChangeFBOThenDrawThenDrawIndexed)
7421 {
7422     // Create a framebuffer, and make sure it and the default framebuffer are fully synced.
7423     glClearColor(0, 0, 0, 1);
7424     glClear(GL_COLOR_BUFFER_BIT);
7425     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
7426 
7427     GLFramebuffer fbo;
7428     GLTexture texture;
7429 
7430     glBindTexture(GL_TEXTURE_2D, texture);
7431     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
7432     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 16, 16);
7433     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
7434 
7435     glClear(GL_COLOR_BUFFER_BIT);
7436     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
7437 
7438     glBindFramebuffer(GL_FRAMEBUFFER, 0);
7439 
7440     // First, create the index buffer and issue an indexed draw call.  This clears the index dirty
7441     // bit.
7442     GLBuffer indexBuffer;
7443     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
7444 
7445     const std::array<GLuint, 4> kIndexData = {0, 1, 2, 0};
7446     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(kIndexData), kIndexData.data(), GL_STATIC_DRAW);
7447 
7448     // Setup vertices.
7449     const std::array<GLfloat, 6> kVertices = {
7450         -1, -1, 3, -1, -1, 3,
7451     };
7452     GLBuffer vertexBuffer;
7453     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
7454     glBufferData(GL_ARRAY_BUFFER, sizeof(kVertices), kVertices.data(), GL_STATIC_DRAW);
7455     glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
7456     glEnableVertexAttribArray(0);
7457 
7458     // Set up a program.  The same program is used for all draw calls to avoid state change due to
7459     // program change.
7460     constexpr char kFS[] = R"(#version 300 es
7461 precision mediump float;
7462 uniform vec4 colorIn;
7463 out vec4 colorOut;
7464 void main()
7465 {
7466     colorOut = colorIn;
7467 })";
7468 
7469     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
7470     glUseProgram(program);
7471 
7472     const GLint positionLoc = glGetAttribLocation(program, essl3_shaders::PositionAttrib());
7473     const GLint colorLoc    = glGetUniformLocation(program, "colorIn");
7474     ASSERT_NE(-1, positionLoc);
7475     ASSERT_NE(-1, colorLoc);
7476 
7477     glVertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
7478     glEnableVertexAttribArray(positionLoc);
7479 
7480     glUniform4f(colorLoc, 1, 0, 0, 1);
7481     glEnable(GL_BLEND);
7482     glBlendFunc(GL_ONE, GL_ONE);
7483     glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);
7484     EXPECT_GL_NO_ERROR();
7485 
7486     // Then switch to fbo and issue a non-indexed draw call followed by an indexed one.
7487     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
7488     glUniform4f(colorLoc, 0, 1, 0, 0);
7489     glDrawArrays(GL_TRIANGLES, 0, 3);
7490 
7491     glUniform4f(colorLoc, 0, 0, 1, 0);
7492     glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);
7493     EXPECT_GL_NO_ERROR();
7494 
7495     // Ensure correct rendering.
7496     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
7497 
7498     glBindFramebuffer(GL_FRAMEBUFFER, 0);
7499     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
7500 }
7501 
7502 // Test that switching framebuffers then a non-indexed draw followed by an indexed one works, with
7503 // another context flushing work in between the two draw calls.
TEST_P(SimpleStateChangeTestES31,DrawThenChangeFBOThenDrawThenFlushInAnotherThreadThenDrawIndexed)7504 TEST_P(SimpleStateChangeTestES31, DrawThenChangeFBOThenDrawThenFlushInAnotherThreadThenDrawIndexed)
7505 {
7506     // Create a framebuffer, and make sure it and the default framebuffer are fully synced.
7507     glClearColor(0, 0, 0, 1);
7508     glClear(GL_COLOR_BUFFER_BIT);
7509     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
7510 
7511     GLFramebuffer fbo;
7512     GLTexture texture;
7513 
7514     glBindTexture(GL_TEXTURE_2D, texture);
7515     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
7516     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 16, 16);
7517     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
7518 
7519     glClear(GL_COLOR_BUFFER_BIT);
7520     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
7521 
7522     glBindFramebuffer(GL_FRAMEBUFFER, 0);
7523 
7524     // First, create the index buffer and issue an indexed draw call.  This clears the index dirty
7525     // bit.
7526     GLBuffer indexBuffer;
7527     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
7528 
7529     const std::array<GLuint, 4> kIndexData = {0, 1, 2, 0};
7530     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(kIndexData), kIndexData.data(), GL_STATIC_DRAW);
7531 
7532     // Setup vertices.
7533     const std::array<GLfloat, 6> kVertices = {
7534         -1, -1, 3, -1, -1, 3,
7535     };
7536     GLBuffer vertexBuffer;
7537     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
7538     glBufferData(GL_ARRAY_BUFFER, sizeof(kVertices), kVertices.data(), GL_STATIC_DRAW);
7539     glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
7540     glEnableVertexAttribArray(0);
7541 
7542     // Set up a program.  The same program is used for all draw calls to avoid state change due to
7543     // program change.
7544     constexpr char kFS[] = R"(#version 300 es
7545 precision mediump float;
7546 uniform vec4 colorIn;
7547 out vec4 colorOut;
7548 void main()
7549 {
7550     colorOut = colorIn;
7551 })";
7552 
7553     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);
7554     glUseProgram(program);
7555 
7556     const GLint positionLoc = glGetAttribLocation(program, essl3_shaders::PositionAttrib());
7557     const GLint colorLoc    = glGetUniformLocation(program, "colorIn");
7558     ASSERT_NE(-1, positionLoc);
7559     ASSERT_NE(-1, colorLoc);
7560 
7561     glVertexAttribPointer(positionLoc, 2, GL_FLOAT, GL_FALSE, 0, 0);
7562     glEnableVertexAttribArray(positionLoc);
7563 
7564     glUniform4f(colorLoc, 0, 0, 0, 1);
7565     glEnable(GL_BLEND);
7566     glBlendFunc(GL_ONE, GL_ONE);
7567     glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);
7568     EXPECT_GL_NO_ERROR();
7569 
7570     // Then switch to fbo and issue a non-indexed draw call followed by an indexed one.
7571     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
7572     glUniform4f(colorLoc, 0, 1, 0, 0);
7573     glDrawArrays(GL_TRIANGLES, 0, 3);
7574 
7575     // In between the two calls, make sure the first render pass is submitted, so the primary
7576     // command buffer is reset.
7577     {
7578         EGLWindow *window          = getEGLWindow();
7579         EGLDisplay dpy             = window->getDisplay();
7580         EGLConfig config           = window->getConfig();
7581         EGLint pbufferAttributes[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE, EGL_NONE};
7582         EGLSurface surface         = eglCreatePbufferSurface(dpy, config, pbufferAttributes);
7583         EGLContext ctx             = window->createContext(EGL_NO_CONTEXT, nullptr);
7584         EXPECT_EGL_SUCCESS();
7585         std::thread flushThread = std::thread([&]() {
7586             EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, ctx));
7587             EXPECT_EGL_SUCCESS();
7588 
7589             glClearColor(1, 0, 0, 1);
7590             glClear(GL_COLOR_BUFFER_BIT);
7591             EXPECT_GL_NO_ERROR();
7592 
7593             EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
7594         });
7595         flushThread.join();
7596 
7597         eglDestroySurface(dpy, surface);
7598         eglDestroyContext(dpy, ctx);
7599     }
7600 
7601     glUniform4f(colorLoc, 0, 0, 1, 0);
7602     glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);
7603     EXPECT_GL_NO_ERROR();
7604 
7605     // Ensure correct rendering.
7606     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::cyan);
7607 }
7608 
7609 // Negative test for EXT_primitive_bounding_box
TEST_P(SimpleStateChangeTestES31,PrimitiveBoundingBoxEXTNegativeTest)7610 TEST_P(SimpleStateChangeTestES31, PrimitiveBoundingBoxEXTNegativeTest)
7611 {
7612     ANGLE_SKIP_TEST_IF(IsGLExtensionEnabled("GL_EXT_primitive_bounding_box"));
7613 
7614     glPrimitiveBoundingBoxEXT(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
7615     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
7616 
7617     GLfloat boundingBox[8] = {0};
7618     glGetFloatv(GL_PRIMITIVE_BOUNDING_BOX_EXT, boundingBox);
7619     EXPECT_GL_ERROR(GL_INVALID_ENUM);
7620 }
7621 
7622 // Negative test for OES_primitive_bounding_box
TEST_P(SimpleStateChangeTestES31,PrimitiveBoundingBoxOESNegativeTest)7623 TEST_P(SimpleStateChangeTestES31, PrimitiveBoundingBoxOESNegativeTest)
7624 {
7625     ANGLE_SKIP_TEST_IF(IsGLExtensionEnabled("GL_OES_primitive_bounding_box"));
7626 
7627     glPrimitiveBoundingBoxEXT(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
7628     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
7629 
7630     GLfloat boundingBox[8] = {0};
7631     glGetFloatv(GL_PRIMITIVE_BOUNDING_BOX_OES, boundingBox);
7632     EXPECT_GL_ERROR(GL_INVALID_ENUM);
7633 }
7634 
7635 // Update an element array buffer that is already in use.
TEST_P(SimpleStateChangeTest,UpdateBoundElementArrayBuffer)7636 TEST_P(SimpleStateChangeTest, UpdateBoundElementArrayBuffer)
7637 {
7638     constexpr char kVS[] = R"(attribute vec4 position;
7639 attribute float color;
7640 varying float colorVarying;
7641 void main()
7642 {
7643     gl_Position = position;
7644     colorVarying = color;
7645 })";
7646 
7647     constexpr char kFS[] = R"(precision mediump float;
7648 varying float colorVarying;
7649 void main()
7650 {
7651     if (colorVarying == 1.0)
7652     {
7653         gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
7654     }
7655     else
7656     {
7657         gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
7658     }
7659 })";
7660 
7661     ANGLE_GL_PROGRAM(testProgram, kVS, kFS);
7662     glUseProgram(testProgram);
7663 
7664     GLint posLoc = glGetAttribLocation(testProgram, "position");
7665     ASSERT_NE(-1, posLoc);
7666     GLint colorLoc = glGetAttribLocation(testProgram, "color");
7667     ASSERT_NE(-1, colorLoc);
7668 
7669     std::array<GLushort, 6> quadIndices = GetQuadIndices();
7670 
7671     std::vector<GLubyte> indices;
7672     for (GLushort index : quadIndices)
7673     {
7674         indices.push_back(static_cast<GLubyte>(index));
7675     }
7676 
7677     GLBuffer indexBuffer;
7678     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
7679     glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(indices[0]), indices.data(),
7680                  GL_STATIC_DRAW);
7681 
7682     std::array<Vector3, 4> quadVertices = GetIndexedQuadVertices();
7683 
7684     std::vector<Vector3> positionVertices;
7685     for (Vector3 vertex : quadVertices)
7686     {
7687         positionVertices.push_back(vertex);
7688     }
7689     for (Vector3 vertex : quadVertices)
7690     {
7691         positionVertices.push_back(vertex);
7692     }
7693 
7694     GLBuffer positionVertexBuffer;
7695     glBindBuffer(GL_ARRAY_BUFFER, positionVertexBuffer);
7696     glBufferData(GL_ARRAY_BUFFER, positionVertices.size() * sizeof(positionVertices[0]),
7697                  positionVertices.data(), GL_STATIC_DRAW);
7698     glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
7699     glEnableVertexAttribArray(posLoc);
7700 
7701     std::vector<float> colorVertices = {1, 1, 1, 1, 0, 0, 0, 0};
7702 
7703     GLBuffer colorVertexBuffer;
7704     glBindBuffer(GL_ARRAY_BUFFER, colorVertexBuffer);
7705     glBufferData(GL_ARRAY_BUFFER, colorVertices.size() * sizeof(colorVertices[0]),
7706                  colorVertices.data(), GL_STATIC_DRAW);
7707     glVertexAttribPointer(colorLoc, 1, GL_FLOAT, GL_FALSE, 0, nullptr);
7708     glEnableVertexAttribArray(colorLoc);
7709 
7710     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, nullptr);
7711     ASSERT_GL_NO_ERROR();
7712     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
7713 
7714     indices.clear();
7715     for (GLushort index : quadIndices)
7716     {
7717         indices.push_back(static_cast<GLubyte>(index + 4));
7718     }
7719     glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, indices.size() * sizeof(indices[0]),
7720                     indices.data());
7721 
7722     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, nullptr);
7723     ASSERT_GL_NO_ERROR();
7724     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
7725 }
7726 
7727 // Covers a bug where we would use a stale cache variable in the Vulkan back-end.
TEST_P(SimpleStateChangeTestES3,DeleteFramebufferBeforeQuery)7728 TEST_P(SimpleStateChangeTestES3, DeleteFramebufferBeforeQuery)
7729 {
7730     ANGLE_GL_PROGRAM(testProgram, essl1_shaders::vs::Zero(), essl1_shaders::fs::Red());
7731     glUseProgram(testProgram);
7732 
7733     GLFramebuffer fbo;
7734     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
7735 
7736     GLRenderbuffer rbo;
7737     glBindRenderbuffer(GL_RENDERBUFFER, rbo);
7738 
7739     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH32F_STENCIL8, 16, 16);
7740     glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo);
7741 
7742     GLfloat floatArray[] = {1, 2, 3, 4};
7743 
7744     GLBuffer buffer;
7745     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
7746     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLfloat) * 4, floatArray, GL_DYNAMIC_COPY);
7747     glDrawElements(GL_TRIANGLE_FAN, 5, GL_UNSIGNED_SHORT, 0);
7748 
7749     fbo.reset();
7750 
7751     GLQuery query2;
7752     glBeginQuery(GL_ANY_SAMPLES_PASSED_CONSERVATIVE, query2);
7753 
7754     ASSERT_GL_NO_ERROR();
7755 }
7756 
7757 // Covers an edge case
TEST_P(SimpleStateChangeTestES3,TextureTypeConflictAfterDraw)7758 TEST_P(SimpleStateChangeTestES3, TextureTypeConflictAfterDraw)
7759 {
7760     constexpr char kVS[] = R"(precision highp float;
7761 attribute vec4 a_position;
7762 void main()
7763 {
7764     gl_Position = a_position;
7765 }
7766 )";
7767 
7768     constexpr char kFS[] = R"(precision highp float;
7769 uniform sampler2D u_2d1;
7770 uniform samplerCube u_Cube1;
7771 void main()
7772 {
7773     gl_FragColor = texture2D(u_2d1, vec2(0.0, 0.0)) + textureCube(u_Cube1, vec3(0.0, 0.0, 0.0));
7774 }
7775 )";
7776 
7777     ANGLE_GL_PROGRAM(testProgram, kVS, kFS);
7778     glUseProgram(testProgram);
7779 
7780     GLTexture texture;
7781     glBindTexture(GL_TEXTURE_2D, texture);
7782     glTexStorage2D(GL_TEXTURE_2D, 4, GL_SRGB8, 1268, 614);
7783 
7784     GLint uniformloc = glGetUniformLocation(testProgram, "u_Cube1");
7785     ASSERT_NE(-1, uniformloc);
7786     glUniform1i(uniformloc, 1);
7787 
7788     glDrawArrays(GL_POINTS, 0, 1);
7789     ASSERT_GL_NO_ERROR();
7790 
7791     // Trigger the state update.
7792     glLinkProgram(testProgram);
7793     texture.reset();
7794 
7795     // The texture types are now conflicting, and draws should fail.
7796     glDrawArrays(GL_POINTS, 0, 1);
7797     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
7798 }
7799 
7800 // Regression test for a bug where a mutable texture is used with non-zero base level then rebased
7801 // to zero but made incomplete and attached to the framebuffer.  The texture's image is not
7802 // recreated with level 0, leading to errors when drawing to the framebuffer.
TEST_P(SimpleStateChangeTestES3,NonZeroBaseMutableTextureThenZeroBaseButIncompleteBug)7803 TEST_P(SimpleStateChangeTestES3, NonZeroBaseMutableTextureThenZeroBaseButIncompleteBug)
7804 {
7805     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
7806     glUseProgram(program);
7807 
7808     const std::array<GLColor, 4> kMip0Data = {GLColor::red, GLColor::red, GLColor::red,
7809                                               GLColor::red};
7810     const std::array<GLColor, 2> kMip1Data = {GLColor::green, GLColor::green};
7811 
7812     // Create two textures.
7813     GLTexture immutableTex;
7814     glBindTexture(GL_TEXTURE_2D, immutableTex);
7815     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
7816     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kMip0Data.data());
7817 
7818     GLTexture mutableTex;
7819     glBindTexture(GL_TEXTURE_2D, mutableTex);
7820     for (uint32_t mip = 0; mip < 2; ++mip)
7821     {
7822         const uint32_t size = 4 >> mip;
7823         glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA8, size, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
7824                      mip == 0 ? kMip0Data.data() : kMip1Data.data());
7825     }
7826 
7827     GLFramebuffer fbo;
7828     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
7829 
7830     // Sample from the mutable texture at non-zero base level.
7831     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
7832     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
7833 
7834     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, immutableTex, 0);
7835     drawQuad(program, std::string(essl1_shaders::PositionAttrib()), 0.0f);
7836     EXPECT_PIXEL_COLOR_EQ(0, 0, kMip1Data[0]);
7837 
7838     // Rebase the mutable texture to zero, but enable mipmapping which makes it incomplete.
7839     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
7840     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
7841 
7842     // Remove feedback loop for good measure.
7843     glBindTexture(GL_TEXTURE_2D, immutableTex);
7844 
7845     // Draw into base zero of the texture.
7846     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mutableTex, 0);
7847     drawQuad(program, std::string(essl1_shaders::PositionAttrib()), 0.0f);
7848 
7849     EXPECT_PIXEL_COLOR_EQ(0, 0, kMip1Data[1]);
7850     ASSERT_GL_NO_ERROR();
7851 }
7852 
7853 // Regression test for a bug where the framebuffer binding was not synced during invalidate when a
7854 // clear operation was deferred.
TEST_P(SimpleStateChangeTestES3,ChangeFramebufferThenInvalidateWithClear)7855 TEST_P(SimpleStateChangeTestES3, ChangeFramebufferThenInvalidateWithClear)
7856 {
7857     // Clear the default framebuffer.
7858     glClear(GL_COLOR_BUFFER_BIT);
7859 
7860     // Start rendering to another framebuffer
7861     GLFramebuffer fbo;
7862     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
7863 
7864     GLRenderbuffer rbo;
7865     glBindRenderbuffer(GL_RENDERBUFFER, rbo);
7866     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 16, 16);
7867     glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
7868 
7869     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Red());
7870     glUseProgram(program);
7871     glDrawArrays(GL_TRIANGLES, 0, 3);
7872 
7873     // Switch back to the default framebuffer
7874     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
7875 
7876     // Invalidate it.  Don't invalidate color, as that's the one being cleared.
7877     constexpr GLenum kAttachment = GL_DEPTH;
7878     glInvalidateFramebuffer(GL_DRAW_FRAMEBUFFER, 1, &kAttachment);
7879     EXPECT_GL_NO_ERROR();
7880 }
7881 
7882 // Test that clear / invalidate / clear works.  The invalidate is for a target that's not cleared.
7883 // Regression test for a bug where invalidate() would start a render pass to perform the first
7884 // clear, while the second clear didn't expect a render pass opened without any draw calls in it.
TEST_P(SimpleStateChangeTestES3,ClearColorInvalidateDepthClearColor)7885 TEST_P(SimpleStateChangeTestES3, ClearColorInvalidateDepthClearColor)
7886 {
7887     // Clear color.
7888     glClear(GL_COLOR_BUFFER_BIT);
7889 
7890     // Invalidate depth.
7891     constexpr GLenum kAttachment = GL_DEPTH;
7892     glInvalidateFramebuffer(GL_DRAW_FRAMEBUFFER, 1, &kAttachment);
7893     EXPECT_GL_NO_ERROR();
7894 
7895     // Clear color again.
7896     glClear(GL_COLOR_BUFFER_BIT);
7897     ASSERT_GL_NO_ERROR();
7898 }
7899 
7900 // Regression test for a bug where glInvalidateFramebuffer(GL_FRAMEBUFFER, ...) was invalidating
7901 // both the draw and read framebuffers.
TEST_P(SimpleStateChangeTestES3,InvalidateFramebufferShouldntInvalidateReadFramebuffer)7902 TEST_P(SimpleStateChangeTestES3, InvalidateFramebufferShouldntInvalidateReadFramebuffer)
7903 {
7904     // Create an invalid read framebuffer.
7905     GLFramebuffer fbo;
7906     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
7907 
7908     GLTexture tex;
7909     glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
7910     glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_R8, 1, 1, 1);
7911     glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, tex, 0, 5);
7912 
7913     // Invalidate using GL_FRAMEBUFFER.  If GL_READ_FRAMEBUFFER was used, validation would fail due
7914     // to the framebuffer not being complete.  A bug here was attempting to invalidate the read
7915     // framebuffer given GL_FRAMEBUFFER anyway.
7916     constexpr std::array<GLenum, 2> kAttachments = {GL_DEPTH, GL_STENCIL};
7917     glInvalidateFramebuffer(GL_FRAMEBUFFER, 2, kAttachments.data());
7918     EXPECT_GL_NO_ERROR();
7919 }
7920 
7921 // Covers situations where vertex conversion could read out of bounds.
TEST_P(SimpleStateChangeTestES3,OutOfBoundsByteAttribute)7922 TEST_P(SimpleStateChangeTestES3, OutOfBoundsByteAttribute)
7923 {
7924     ANGLE_GL_PROGRAM(testProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
7925     glUseProgram(testProgram);
7926 
7927     GLBuffer buffer;
7928     glBindBuffer(GL_ARRAY_BUFFER, buffer);
7929     glBufferData(GL_ARRAY_BUFFER, 2, nullptr, GL_STREAM_COPY);
7930 
7931     glEnableVertexAttribArray(0);
7932     glVertexAttribPointer(0, 4, GL_BYTE, false, 0xff, reinterpret_cast<const void *>(0xfe));
7933 
7934     glDrawArraysInstanced(GL_TRIANGLE_STRIP, 1, 10, 1000);
7935 }
7936 
7937 // Test that respecifies a buffer after we start XFB.
TEST_P(SimpleStateChangeTestES3,RespecifyBufferAfterBeginTransformFeedback)7938 TEST_P(SimpleStateChangeTestES3, RespecifyBufferAfterBeginTransformFeedback)
7939 {
7940     std::vector<std::string> tfVaryings = {"gl_Position"};
7941     ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(testProgram, essl3_shaders::vs::Simple(),
7942                                         essl3_shaders::fs::Green(), tfVaryings,
7943                                         GL_INTERLEAVED_ATTRIBS);
7944 
7945     glUseProgram(testProgram);
7946     GLBuffer buffer;
7947     glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buffer);
7948     glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(float) * 3 * 2 * 7, nullptr, GL_STREAM_DRAW);
7949     glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buffer);
7950     glBeginTransformFeedback(GL_TRIANGLES);
7951     glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(float) * 3 * 4 * 6, nullptr, GL_STREAM_DRAW);
7952     glDrawArrays(GL_TRIANGLES, 0, 6);
7953     glEndTransformFeedback();
7954 }
7955 
7956 // Test a bug angleproject:6998 in TransformFeedback code path by allocating paddingBuffer first and
7957 // then allocate another buffer and then deallocate paddingBuffer and then allocate buffer again.
7958 // This new buffer will be allocated in the space where paddingBuffer was allocated which causing
7959 // XFB generate VVL error.
TEST_P(SimpleStateChangeTestES3,RespecifyBufferAfterBeginTransformFeedbackInDeletedPaddingBuffer)7960 TEST_P(SimpleStateChangeTestES3, RespecifyBufferAfterBeginTransformFeedbackInDeletedPaddingBuffer)
7961 {
7962     std::vector<std::string> tfVaryings = {"gl_Position"};
7963     ANGLE_GL_PROGRAM_TRANSFORM_FEEDBACK(testProgram, essl3_shaders::vs::Simple(),
7964                                         essl3_shaders::fs::Green(), tfVaryings,
7965                                         GL_INTERLEAVED_ATTRIBS);
7966     glUseProgram(testProgram);
7967 
7968     GLuint paddingBuffer;
7969     glGenBuffers(1, &paddingBuffer);
7970     glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, paddingBuffer);
7971     glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 256, nullptr, GL_STREAM_DRAW);
7972 
7973     GLBuffer buffer;
7974     glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buffer);
7975     glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(float) * 3 * 2 * 7, nullptr, GL_STREAM_DRAW);
7976     glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buffer);
7977     // Delete padding buffer, expecting the next bufferData call will reuse the space of
7978     // paddingBuffer whose offset is smaller than buffer's offset, which triggers the bug.
7979     glDeleteBuffers(1, &paddingBuffer);
7980     glBeginTransformFeedback(GL_TRIANGLES);
7981     glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(float) * 3 * 4 * 6, nullptr, GL_STREAM_DRAW);
7982     glDrawArrays(GL_TRIANGLES, 0, 6);
7983     glEndTransformFeedback();
7984 }
7985 
7986 // Regression test for a bug in the Vulkan backend where a draw-based copy after a deferred flush
7987 // would lead to an image view being destroyed too early.
TEST_P(SimpleStateChangeTestES3,DrawFlushThenCopyTexImage)7988 TEST_P(SimpleStateChangeTestES3, DrawFlushThenCopyTexImage)
7989 {
7990     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());
7991 
7992     // Issue a cheap draw call and a flush
7993     glEnable(GL_SCISSOR_TEST);
7994     glScissor(0, 0, 1, 1);
7995     drawQuad(program, essl3_shaders::PositionAttrib(), 0.0f);
7996     glDisable(GL_SCISSOR_TEST);
7997     glFlush();
7998 
7999     constexpr GLsizei kSize = 32;
8000 
8001     // Then an expensive copy tex image
8002     GLTexture texture;
8003     glBindTexture(GL_TEXTURE_3D, texture);
8004     glTexStorage3D(GL_TEXTURE_3D, 1, GL_RGB8, kSize, kSize, kSize);
8005     glCopyTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, 0, 0, kSize, kSize);
8006     glFlush();
8007     ASSERT_GL_NO_ERROR();
8008 }
8009 
TEST_P(SimpleStateChangeTestES3,DrawFlushThenBlit)8010 TEST_P(SimpleStateChangeTestES3, DrawFlushThenBlit)
8011 {
8012     constexpr GLsizei kSize = 256;
8013     const std::vector<GLColor> data(kSize * kSize, GLColor::red);
8014 
8015     ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());
8016 
8017     GLFramebuffer fbo;
8018     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
8019 
8020     GLTexture readColor;
8021     glBindTexture(GL_TEXTURE_2D, readColor);
8022     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
8023                  data.data());
8024     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, readColor, 0);
8025 
8026     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
8027 
8028     // Issue a cheap draw call and a flush
8029     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
8030     glEnable(GL_SCISSOR_TEST);
8031     glScissor(0, 0, 1, 1);
8032     drawQuad(program, essl3_shaders::PositionAttrib(), 0.0f);
8033     glDisable(GL_SCISSOR_TEST);
8034     glFlush();
8035 
8036     // Then an expensive blit
8037     glBlitFramebuffer(0, 0, kSize, kSize, kSize + 2, kSize, 0, 0, GL_COLOR_BUFFER_BIT, GL_NEAREST);
8038     glFlush();
8039     ASSERT_GL_NO_ERROR();
8040 }
8041 
8042 class VertexAttribArrayStateChangeTest : public ANGLETest<>
8043 {
8044   protected:
VertexAttribArrayStateChangeTest()8045     VertexAttribArrayStateChangeTest()
8046     {
8047         setWindowWidth(128);
8048         setWindowHeight(128);
8049         setConfigRedBits(8);
8050         setConfigGreenBits(8);
8051         setConfigBlueBits(8);
8052         setConfigAlphaBits(8);
8053         setConfigDepthBits(24);
8054     }
8055 
testSetUp()8056     void testSetUp() override
8057     {
8058         constexpr char kVS[] = R"(precision highp float;
8059 attribute vec4 position;
8060 attribute vec4 color;
8061 varying vec4 colorOut;
8062 
8063 void main()
8064 {
8065     gl_Position = position;
8066     colorOut = color;
8067 })";
8068 
8069         constexpr char kFS[] = R"(precision highp float;
8070 varying vec4 colorOut;
8071 
8072 void main()
8073 {
8074     gl_FragColor = colorOut;
8075 })";
8076 
8077         mProgram = CompileProgram(kVS, kFS);
8078         ASSERT_NE(0u, mProgram);
8079 
8080         mPosAttribLocation = glGetAttribLocation(mProgram, "position");
8081         ASSERT_NE(-1, mPosAttribLocation);
8082         mColorAttribLocation = glGetAttribLocation(mProgram, "color");
8083         ASSERT_NE(-1, mColorAttribLocation);
8084 
8085         glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
8086         ASSERT_GL_NO_ERROR();
8087 
8088         glGenBuffers(1, &mVertexBuffer);
8089         glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
8090 
8091         const float posAttribData[] = {
8092             -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f,
8093         };
8094         glBufferData(GL_ARRAY_BUFFER, sizeof(posAttribData), posAttribData, GL_STATIC_DRAW);
8095 
8096         glBindBuffer(GL_ARRAY_BUFFER, 0);
8097     }
8098 
testTearDown()8099     void testTearDown() override
8100     {
8101         if (mVertexBuffer != 0)
8102         {
8103             glDeleteBuffers(1, &mVertexBuffer);
8104         }
8105 
8106         if (mProgram != 0)
8107         {
8108             glDeleteProgram(mProgram);
8109         }
8110     }
8111 
8112     GLuint mProgram;
8113     GLint mPosAttribLocation;
8114     GLint mColorAttribLocation;
8115     GLuint mVertexBuffer;
8116 };
8117 
TEST_P(VertexAttribArrayStateChangeTest,Basic)8118 TEST_P(VertexAttribArrayStateChangeTest, Basic)
8119 {
8120     glUseProgram(mProgram);
8121     glClear(GL_COLOR_BUFFER_BIT);
8122     glDisable(GL_DEPTH_TEST);
8123     glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
8124 
8125     glVertexAttribPointer(mPosAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
8126     glEnableVertexAttribArray(mPosAttribLocation);
8127     glDisableVertexAttribArray(mColorAttribLocation);
8128     glVertexAttrib4f(mColorAttribLocation, 1.0f, 0.0f, 0.0f, 1.0f);
8129     // Don't try to verify the color of this draw as red here because it might
8130     // hide the bug
8131     glDrawArrays(GL_TRIANGLES, 0, 6);
8132     glVertexAttrib4f(mColorAttribLocation, 0.0f, 1.0f, 0.0f, 1.0f);
8133     glDrawArrays(GL_TRIANGLES, 0, 6);
8134     ASSERT_GL_NO_ERROR();
8135     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
8136 
8137     glUseProgram(0);
8138     glBindBuffer(GL_ARRAY_BUFFER, 0);
8139 }
8140 
TEST_P(SimpleStateChangeTestES3,DepthOnlyToColorAttachmentPreservesBlendState)8141 TEST_P(SimpleStateChangeTestES3, DepthOnlyToColorAttachmentPreservesBlendState)
8142 {
8143 
8144     constexpr char kVS[] = R"(precision highp float;
8145 attribute vec4 position;
8146 attribute vec4 color;
8147 varying vec4 colorOut;
8148 
8149 void main()
8150 {
8151     gl_Position = position;
8152     colorOut = color;
8153 })";
8154 
8155     constexpr char kFS[] = R"(precision highp float;
8156 varying vec4 colorOut;
8157 
8158 void main()
8159 {
8160     gl_FragColor = colorOut;
8161 })";
8162 
8163     ANGLE_GL_PROGRAM(program, kVS, kFS);
8164 
8165     GLint posAttribLocation = glGetAttribLocation(program, "position");
8166     ASSERT_NE(-1, posAttribLocation);
8167     GLint colorAttribLocation = glGetAttribLocation(program, "color");
8168     ASSERT_NE(-1, colorAttribLocation);
8169 
8170     GLBuffer vertexBuffer;
8171     GLTexture texture;
8172     GLFramebuffer framebuffer;
8173     GLRenderbuffer depthRenderbuffer;
8174     GLFramebuffer depthFramebuffer;
8175 
8176     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
8177 
8178     const float posAttribData[] = {
8179         -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f,
8180     };
8181     glBufferData(GL_ARRAY_BUFFER, sizeof(posAttribData), posAttribData, GL_STATIC_DRAW);
8182 
8183     glBindBuffer(GL_ARRAY_BUFFER, 0);
8184 
8185     constexpr int kWidth  = 1;
8186     constexpr int kHeight = 1;
8187 
8188     glBindTexture(GL_TEXTURE_2D, texture);
8189     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
8190     glBindTexture(GL_TEXTURE_2D, 0);
8191 
8192     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
8193     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
8194     glBindFramebuffer(GL_FRAMEBUFFER, 0);
8195 
8196     glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
8197     glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, kWidth, kHeight);
8198     glBindRenderbuffer(GL_RENDERBUFFER, 0);
8199 
8200     glBindFramebuffer(GL_FRAMEBUFFER, depthFramebuffer);
8201     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER,
8202                               depthRenderbuffer);
8203     glBindFramebuffer(GL_FRAMEBUFFER, 0);
8204 
8205     glDisable(GL_DEPTH_TEST);
8206     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
8207     glVertexAttribPointer(posAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
8208     glEnableVertexAttribArray(posAttribLocation);
8209     glDisableVertexAttribArray(colorAttribLocation);
8210     glVertexAttrib4f(colorAttribLocation, 1.0f, 0.0f, 0.0f, 1.0f);
8211 
8212     glUseProgram(program);
8213     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
8214     glEnable(GL_BLEND);
8215     glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE, GL_ONE);
8216     glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
8217     glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
8218     glClear(GL_COLOR_BUFFER_BIT);
8219     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
8220 
8221     glBindFramebuffer(GL_FRAMEBUFFER, depthFramebuffer);
8222     glDrawArrays(GL_TRIANGLES, 0, 6);
8223 
8224     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
8225     glDrawArrays(GL_TRIANGLES, 0, 6);
8226     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
8227 
8228     glBindBuffer(GL_ARRAY_BUFFER, 0);
8229     glBindFramebuffer(GL_FRAMEBUFFER, 0);
8230     glUseProgram(0);
8231 }
8232 
8233 // Tests a bug where we wouldn't update our cached base/max levels in Vulkan.
TEST_P(SimpleStateChangeTestES3,MaxLevelChange)8234 TEST_P(SimpleStateChangeTestES3, MaxLevelChange)
8235 {
8236     // Initialize an immutable texture with 2 levels.
8237     std::vector<GLColor> bluePixels(4, GLColor::blue);
8238 
8239     GLTexture tex;
8240     glBindTexture(GL_TEXTURE_2D, tex);
8241     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
8242     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
8243     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
8244     glTexStorage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2);
8245     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, bluePixels.data());
8246     glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::yellow);
8247 
8248     // Set up draw resources.
8249     ANGLE_GL_PROGRAM(testProgram, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
8250     glUseProgram(testProgram);
8251 
8252     GLint posLoc = glGetAttribLocation(testProgram, essl1_shaders::PositionAttrib());
8253     ASSERT_NE(-1, posLoc);
8254 
8255     std::array<Vector3, 6> quadVerts = GetQuadVertices();
8256 
8257     GLBuffer vao;
8258     glBindBuffer(GL_ARRAY_BUFFER, vao);
8259     glBufferData(GL_ARRAY_BUFFER, quadVerts.size() * sizeof(quadVerts[0]), quadVerts.data(),
8260                  GL_STATIC_DRAW);
8261     glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
8262     glEnableVertexAttribArray(posLoc);
8263 
8264     ASSERT_GL_NO_ERROR();
8265 
8266     // Draw with the 2x2 mip / max level 1.
8267     glViewport(0, 0, 2, 2);
8268     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
8269     glDrawArrays(GL_TRIANGLES, 0, 6);
8270 
8271     // Draw with the 1x1 mip / max level 2.
8272     glViewport(2, 0, 1, 1);
8273     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
8274     glDrawArrays(GL_TRIANGLES, 0, 6);
8275 
8276     // Draw with the 2x2 mip / max level 1.
8277     glViewport(0, 2, 2, 2);
8278     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
8279     glDrawArrays(GL_TRIANGLES, 0, 6);
8280 
8281     // Draw with the 1x1 mip / max level 2.
8282     glViewport(2, 2, 1, 1);
8283     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
8284     glDrawArrays(GL_TRIANGLES, 0, 6);
8285 
8286     ASSERT_GL_NO_ERROR();
8287 
8288     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
8289     EXPECT_PIXEL_COLOR_EQ(2, 0, GLColor::yellow);
8290     EXPECT_PIXEL_COLOR_EQ(0, 2, GLColor::blue);
8291     EXPECT_PIXEL_COLOR_EQ(2, 2, GLColor::yellow);
8292 }
8293 
8294 // Tests a bug when removing an element array buffer bound to two vertex arrays.
TEST_P(SimpleStateChangeTestES3,DeleteDoubleBoundBufferAndVertexArray)8295 TEST_P(SimpleStateChangeTestES3, DeleteDoubleBoundBufferAndVertexArray)
8296 {
8297     std::vector<uint8_t> bufData(100, 0);
8298     GLBuffer buffer;
8299     GLVertexArray vao;
8300 
8301     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
8302     glBindVertexArray(vao);
8303     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
8304     buffer.reset();
8305     vao.reset();
8306 
8307     glBufferData(GL_ELEMENT_ARRAY_BUFFER, bufData.size(), bufData.data(), GL_STATIC_DRAW);
8308     glBufferData(GL_ELEMENT_ARRAY_BUFFER, bufData.size(), bufData.data(), GL_STATIC_DRAW);
8309     ASSERT_GL_NO_ERROR();
8310 }
8311 
8312 // Tests state change for glLineWidth.
TEST_P(StateChangeTestES3,LineWidth)8313 TEST_P(StateChangeTestES3, LineWidth)
8314 {
8315     GLfloat range[2] = {1};
8316     glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, range);
8317     EXPECT_GL_NO_ERROR();
8318 
8319     ANGLE_SKIP_TEST_IF(range[1] < 5.0);
8320 
8321     constexpr char kVS[] = R"(#version 300 es
8322 precision highp float;
8323 uniform float height;
8324 void main()
8325 {
8326     gl_Position = vec4(gl_VertexID == 0 ? -1 : 1, height * 2. - 1., 0, 1);
8327 })";
8328 
8329     constexpr char kFS[] = R"(#version 300 es
8330 precision highp float;
8331 out vec4 colorOut;
8332 uniform vec4 color;
8333 void main()
8334 {
8335     colorOut = color;
8336 })";
8337 
8338     ANGLE_GL_PROGRAM(program, kVS, kFS);
8339     glUseProgram(program);
8340 
8341     GLint heightLoc = glGetUniformLocation(program, "height");
8342     GLint colorLoc  = glGetUniformLocation(program, "color");
8343     ASSERT_NE(-1, heightLoc);
8344     ASSERT_NE(-1, colorLoc);
8345 
8346     glClearColor(0, 0, 0, 1);
8347     glClear(GL_COLOR_BUFFER_BIT);
8348 
8349     const int w                 = getWindowWidth();
8350     const int h                 = getWindowHeight();
8351     const float halfPixelHeight = 0.5 / h;
8352 
8353     glUniform1f(heightLoc, 0.25f + halfPixelHeight);
8354     glUniform4f(colorLoc, 1, 0, 0, 1);
8355     glLineWidth(3);
8356     glDrawArrays(GL_LINES, 0, 2);
8357 
8358     glUniform1f(heightLoc, 0.5f + halfPixelHeight);
8359     glUniform4f(colorLoc, 0, 1, 0, 1);
8360     glLineWidth(5);
8361     glDrawArrays(GL_LINES, 0, 2);
8362 
8363     glUniform1f(heightLoc, 0.75f + halfPixelHeight);
8364     glUniform4f(colorLoc, 0, 0, 1, 1);
8365     glLineWidth(1);
8366     glDrawArrays(GL_LINES, 0, 2);
8367 
8368     EXPECT_PIXEL_RECT_EQ(0, h / 4 - 2, w, 1, GLColor::black);
8369     EXPECT_PIXEL_RECT_EQ(0, h / 4 - 1, w, 3, GLColor::red);
8370     EXPECT_PIXEL_RECT_EQ(0, h / 4 + 2, w, 1, GLColor::black);
8371 
8372     EXPECT_PIXEL_RECT_EQ(0, h / 2 - 3, w, 1, GLColor::black);
8373     EXPECT_PIXEL_RECT_EQ(0, h / 2 - 2, w, 5, GLColor::green);
8374     EXPECT_PIXEL_RECT_EQ(0, h / 2 + 3, w, 1, GLColor::black);
8375 
8376     EXPECT_PIXEL_RECT_EQ(0, 3 * h / 4 - 1, w, 1, GLColor::black);
8377     EXPECT_PIXEL_RECT_EQ(0, 3 * h / 4, w, 1, GLColor::blue);
8378     EXPECT_PIXEL_RECT_EQ(0, 3 * h / 4 + 1, w, 1, GLColor::black);
8379 
8380     ASSERT_GL_NO_ERROR();
8381 }
8382 
8383 // Tests state change for out-of-range value for glLineWidth. The expectation
8384 // here is primarily that rendering backends do not crash with invalid line
8385 // width values.
TEST_P(StateChangeTestES3,LineWidthOutOfRangeDoesntCrash)8386 TEST_P(StateChangeTestES3, LineWidthOutOfRangeDoesntCrash)
8387 {
8388     GLfloat range[2] = {1};
8389     glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, range);
8390     EXPECT_GL_NO_ERROR();
8391 
8392     constexpr char kVS[] = R"(#version 300 es
8393 precision highp float;
8394 void main()
8395 {
8396     gl_Position = vec4(gl_VertexID == 0 ? -1.0 : 1.0, -1.0, 0.0, 1.0);
8397 })";
8398 
8399     constexpr char kFS[] = R"(#version 300 es
8400 precision highp float;
8401 out vec4 colorOut;
8402 void main()
8403 {
8404     colorOut = vec4(1.0);
8405 })";
8406 
8407     ANGLE_GL_PROGRAM(program, kVS, kFS);
8408     glUseProgram(program);
8409 
8410     glClearColor(0, 0, 0, 1);
8411     glClear(GL_COLOR_BUFFER_BIT);
8412 
8413     glLineWidth(range[1] + 1.0f);
8414     glDrawArrays(GL_LINES, 0, 2);
8415 
8416     glFinish();
8417 
8418     ASSERT_GL_NO_ERROR();
8419 }
8420 
8421 // Tests state change for glPolygonOffset.
TEST_P(StateChangeTestES3,PolygonOffset)8422 TEST_P(StateChangeTestES3, PolygonOffset)
8423 {
8424     constexpr char kVS[] = R"(#version 300 es
8425 precision highp float;
8426 uniform float height;
8427 void main()
8428 {
8429     // gl_VertexID    x    y
8430     //      0        -1   -1
8431     //      1         1   -1
8432     //      2        -1    1
8433     //      3         1    1
8434     int bit0 = gl_VertexID & 1;
8435     int bit1 = gl_VertexID >> 1;
8436     gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, gl_VertexID % 2 == 0 ? -1 : 1, 1);
8437 })";
8438 
8439     constexpr char kFS[] = R"(#version 300 es
8440 precision highp float;
8441 out vec4 colorOut;
8442 uniform vec4 color;
8443 void main()
8444 {
8445     colorOut = color;
8446 })";
8447 
8448     glEnable(GL_POLYGON_OFFSET_FILL);
8449 
8450     ANGLE_GL_PROGRAM(program, kVS, kFS);
8451     glUseProgram(program);
8452 
8453     GLint colorLoc = glGetUniformLocation(program, "color");
8454     ASSERT_NE(-1, colorLoc);
8455 
8456     glClearColor(0, 0, 0, 1);
8457     glClearDepthf(0);
8458     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
8459 
8460     glEnable(GL_DEPTH_TEST);
8461     glDepthFunc(GL_ALWAYS);
8462 
8463     // The shader creates a depth slope from left (0) to right (1).
8464     //
8465     // This test issues three draw calls:
8466     //
8467     //           Draw 2 (green): factor width/2, offset 0, depth test: Greater
8468     //          ^     |       __________________
8469     //          |     |    __/__/   __/
8470     //          |     V __/__/   __/  <--- Draw 1 (red): factor width/4, offset 0
8471     //          |    __/__/ ^ __/
8472     //          | __/__/   _|/
8473     //          |/__/   __/ |
8474     //          |/   __/    |
8475     //          | __/    Draw 3 (blue): factor width/2, offset -2, depth test: Less
8476     //          |/
8477     //          |
8478     //          |
8479     //          +------------------------------->
8480     //
8481     // Result:  <----blue-----><-green-><--red-->
8482 
8483     const int w = getWindowWidth();
8484     const int h = getWindowHeight();
8485 
8486     glUniform4f(colorLoc, 1, 0, 0, 1);
8487     glPolygonOffset(getWindowWidth() / 4, 0);
8488     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
8489 
8490     glUniform4f(colorLoc, 0, 1, 0, 1);
8491     glPolygonOffset(getWindowWidth() / 2, 0);
8492     glDepthFunc(GL_GREATER);
8493     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
8494 
8495     glUniform4f(colorLoc, 0, 0, 1, 1);
8496     glPolygonOffset(getWindowWidth() / 2, -2);
8497     glDepthFunc(GL_LESS);
8498     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
8499 
8500     EXPECT_PIXEL_RECT_EQ(0, 0, w / 2 - 1, h, GLColor::blue);
8501     EXPECT_PIXEL_RECT_EQ(w / 2 + 1, 0, w / 4 - 1, h, GLColor::green);
8502     EXPECT_PIXEL_RECT_EQ(3 * w / 4 + 1, 0, w / 4 - 1, h, GLColor::red);
8503 
8504     ASSERT_GL_NO_ERROR();
8505 }
8506 
8507 // Tests state change for glPolygonOffsetClampEXT.
TEST_P(StateChangeTestES3,PolygonOffsetClamp)8508 TEST_P(StateChangeTestES3, PolygonOffsetClamp)
8509 {
8510     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_polygon_offset_clamp"));
8511 
8512     constexpr char kVS[] = R"(#version 300 es
8513 precision highp float;
8514 uniform float height;
8515 void main()
8516 {
8517     // gl_VertexID    x    y
8518     //      0        -1   -1
8519     //      1         1   -1
8520     //      2        -1    1
8521     //      3         1    1
8522     int bit0 = gl_VertexID & 1;
8523     int bit1 = gl_VertexID >> 1;
8524     gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, gl_VertexID % 2 == 0 ? -1 : 1, 1);
8525 })";
8526 
8527     constexpr char kFS[] = R"(#version 300 es
8528 precision highp float;
8529 out vec4 colorOut;
8530 uniform vec4 color;
8531 void main()
8532 {
8533     colorOut = color;
8534 })";
8535 
8536     glEnable(GL_POLYGON_OFFSET_FILL);
8537 
8538     ANGLE_GL_PROGRAM(program, kVS, kFS);
8539     glUseProgram(program);
8540 
8541     GLint colorLoc = glGetUniformLocation(program, "color");
8542     ASSERT_NE(-1, colorLoc);
8543 
8544     glClearColor(0, 0, 0, 1);
8545     glClearDepthf(0);
8546     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
8547 
8548     glEnable(GL_DEPTH_TEST);
8549     glDepthFunc(GL_ALWAYS);
8550 
8551     // The shader creates a depth slope from left (0) to right (1).
8552     //
8553     // This test issues two draw calls:
8554     //
8555     //           Draw 2 (green): factor width, offset 0, clamp 0.5, depth test: Greater
8556     //          ^     |       __________________
8557     //          |     |    __/      __/
8558     //          |     V __/      __/  <--- Draw 1 (red): factor width, offset 0, clamp 0.25
8559     //          |    __/      __/
8560     //          | __/      __/
8561     //          |/      __/
8562     //          |    __/
8563     //          | __/
8564     //          |/
8565     //          |
8566     //          |
8567     //          +------------------------------->
8568     //
8569     // Result:  <---------green--------><--red-->
8570 
8571     const int w = getWindowWidth();
8572     const int h = getWindowHeight();
8573 
8574     glUniform4f(colorLoc, 1, 0, 0, 1);
8575     glPolygonOffsetClampEXT(getWindowWidth(), 0, 0.25);
8576     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
8577 
8578     glUniform4f(colorLoc, 0, 1, 0, 1);
8579     glPolygonOffsetClampEXT(getWindowWidth(), 0, 0.5);
8580     glDepthFunc(GL_GREATER);
8581     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
8582 
8583     EXPECT_PIXEL_RECT_EQ(0, 0, 3 * w / 4 - 1, h, GLColor::green);
8584     EXPECT_PIXEL_RECT_EQ(3 * w / 4 + 1, 0, w / 4 - 1, h, GLColor::red);
8585 
8586     ASSERT_GL_NO_ERROR();
8587 }
8588 
8589 // Tests state change for glBlendColor.
TEST_P(StateChangeTestES3,BlendColor)8590 TEST_P(StateChangeTestES3, BlendColor)
8591 {
8592     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
8593     glUseProgram(program);
8594 
8595     GLint colorLoc = glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
8596     ASSERT_NE(colorLoc, -1);
8597 
8598     glEnable(GL_BLEND);
8599     glBlendFunc(GL_CONSTANT_COLOR, GL_ZERO);
8600     glBlendColor(0.498, 0.498, 0, 1);
8601     glUniform4f(colorLoc, 1, 1, 1, 1);
8602     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
8603 
8604     const int w = getWindowWidth();
8605     const int h = getWindowHeight();
8606 
8607     glEnable(GL_SCISSOR_TEST);
8608     glScissor(0, 0, w / 2, h);
8609     glBlendColor(0, 1, 0.498, 1);
8610     glUniform4f(colorLoc, 1, 0.247, 1, 1);
8611     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
8612 
8613     EXPECT_PIXEL_RECT_EQ(0, 0, w / 2, h, GLColor(0, 63, 127, 255));
8614     EXPECT_PIXEL_RECT_EQ(w / 2, 0, w / 2, h, GLColor(127, 127, 0, 255));
8615 
8616     ASSERT_GL_NO_ERROR();
8617 }
8618 
8619 // Tests state change for ref and mask in glStencilFuncSeparate.
TEST_P(StateChangeTestES3,StencilReferenceAndCompareMask)8620 TEST_P(StateChangeTestES3, StencilReferenceAndCompareMask)
8621 {
8622     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
8623     glUseProgram(program);
8624 
8625     GLint colorLoc = glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
8626     ASSERT_NE(colorLoc, -1);
8627 
8628     glClearColor(0, 0, 0, 1);
8629     glClearStencil(0x3A);
8630     glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
8631 
8632     glEnable(GL_STENCIL_TEST);
8633 
8634     glStencilMaskSeparate(GL_FRONT, 0xF0);
8635     glStencilMaskSeparate(GL_BACK, 0x0F);
8636 
8637     glStencilFuncSeparate(GL_FRONT, GL_EQUAL, 0xB9, 0x7C);
8638     glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_REPLACE);
8639 
8640     glStencilFuncSeparate(GL_BACK, GL_EQUAL, 0x99, 0xAC);
8641     glStencilOpSeparate(GL_BACK, GL_REPLACE, GL_KEEP, GL_KEEP);
8642 
8643     const int w = getWindowWidth();
8644     const int h = getWindowHeight();
8645 
8646     // Draw front-facing.  Front stencil test should pass, replacing the top bits with 0xB:
8647     //
8648     // Current value of stencil buffer: 0x3A, mask: 0x7C, writing 0xB9
8649     //
8650     //     B9 & 7C == 38 == 3A & 7C
8651     glUniform4f(colorLoc, 1, 0, 0, 1);
8652     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
8653 
8654     // Draw back-facing.  Back stencil test should fail, replacing the bottom bits with 0x9:
8655     //
8656     // Current value of stencil buffer: 0xBA, mask: 0xAC, writing 0x99
8657     //
8658     //     99 & AC == 88 != A8 == BA & AC
8659     glFrontFace(GL_CW);
8660     glDisable(GL_CULL_FACE);
8661     glEnable(GL_SCISSOR_TEST);
8662     glScissor(0, 0, w / 2, h);
8663     glUniform4f(colorLoc, 0, 1, 0, 1);
8664     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
8665 
8666     // The left half of image should now have a value of B9, the right half should have BA
8667     //
8668     // Change the masks such that if the old masks are used, stencil test would fail, but if the new
8669     // mask is used it would pass.
8670     //
8671     //    Left:  B9 & 7C == 38 != 3C == 3D & 7C
8672     //           B9 & 33 == 31 == 3D & 33
8673     //
8674     //    Right: BA & AC == A8 != 28 == 3A & AC
8675     //           BA & 59 == 18 == 3A & 59
8676     //
8677     glStencilFuncSeparate(GL_FRONT, GL_EQUAL, 0x3D, 0x33);
8678     glStencilFuncSeparate(GL_BACK, GL_EQUAL, 0x3A, 0x59);
8679     glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_KEEP);
8680     glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_KEEP);
8681 
8682     glScissor(0, 0, w, h / 2);
8683 
8684     // Draw front-facing, coloring the top-left
8685     glUniform4f(colorLoc, 1, 1, 0, 1);
8686     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
8687     glFrontFace(GL_CCW);
8688     glUniform4f(colorLoc, 0, 0, 1, 1);
8689     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
8690 
8691     // Verify results
8692     EXPECT_PIXEL_RECT_EQ(0, 0, w / 2, h / 2, GLColor::blue);
8693     EXPECT_PIXEL_RECT_EQ(w / 2, 0, w / 2, h / 2, GLColor::yellow);
8694     EXPECT_PIXEL_RECT_EQ(0, h / 2, w / 2, h / 2, GLColor::red);
8695     EXPECT_PIXEL_RECT_EQ(w / 2, h / 2, w / 2, h / 2, GLColor::red);
8696 
8697     // Verify stencil exactly
8698     glDisable(GL_SCISSOR_TEST);
8699     glStencilFunc(GL_EQUAL, 0xB9, 0xFF);
8700     glUniform4f(colorLoc, 0, 1, 1, 1);
8701     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
8702 
8703     glStencilFunc(GL_EQUAL, 0xBA, 0xFF);
8704     glUniform4f(colorLoc, 1, 0, 1, 1);
8705     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
8706 
8707     EXPECT_PIXEL_RECT_EQ(0, 0, w / 2, h, GLColor::cyan);
8708     EXPECT_PIXEL_RECT_EQ(w / 2, 0, w / 2, h, GLColor::magenta);
8709 
8710     ASSERT_GL_NO_ERROR();
8711 }
8712 
8713 // Tests state change for mask in glStencilMaskSeparate.
TEST_P(StateChangeTestES3,StencilWriteMask)8714 TEST_P(StateChangeTestES3, StencilWriteMask)
8715 {
8716     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
8717     glUseProgram(program);
8718 
8719     GLint colorLoc = glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
8720     ASSERT_NE(colorLoc, -1);
8721 
8722     glClearColor(0, 0, 0, 1);
8723     glClearStencil(0x00);
8724     glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
8725 
8726     glEnable(GL_STENCIL_TEST);
8727 
8728     glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_REPLACE);
8729     glStencilOpSeparate(GL_BACK, GL_REPLACE, GL_KEEP, GL_REPLACE);
8730 
8731     const int w = getWindowWidth();
8732     const int h = getWindowHeight();
8733 
8734     // Draw front-facing to the left half, replacing the top four bits, and back-facing to the right
8735     // half, replacing the bottom four bits.
8736     glStencilMaskSeparate(GL_FRONT, 0xF0);
8737     glStencilFuncSeparate(GL_FRONT, GL_ALWAYS, 0x39, 0xFF);
8738     glStencilMaskSeparate(GL_BACK, 0x0F);
8739     glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 0x2A, 0xFF);
8740 
8741     glEnable(GL_SCISSOR_TEST);
8742     glScissor(0, 0, w / 2, h);
8743     glUniform4f(colorLoc, 1, 0, 0, 1);
8744     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
8745 
8746     glDisable(GL_CULL_FACE);
8747     glFrontFace(GL_CW);
8748     glScissor(w / 2, 0, w / 2, h);
8749     glUniform4f(colorLoc, 0, 1, 0, 1);
8750     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
8751 
8752     // Draw back-facing to the top-left quarter, replacing the top two bits, and front-facing to the
8753     // top-right quarter, replacing the bottom two bits.
8754     glStencilMaskSeparate(GL_FRONT, 0xC0);
8755     glStencilFuncSeparate(GL_FRONT, GL_ALWAYS, 0x81, 0xFF);
8756     glStencilMaskSeparate(GL_BACK, 0x03);
8757     glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 0x53, 0xFF);
8758 
8759     glScissor(0, 0, w / 2, h / 2);
8760     glUniform4f(colorLoc, 0, 0, 1, 1);
8761     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
8762 
8763     glFrontFace(GL_CCW);
8764     glScissor(w / 2, 0, w / 2, h / 2);
8765     glUniform4f(colorLoc, 1, 1, 0, 1);
8766     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
8767 
8768     // Verify results
8769     EXPECT_PIXEL_RECT_EQ(0, 0, w / 2, h / 2, GLColor::blue);
8770     EXPECT_PIXEL_RECT_EQ(w / 2, 0, w / 2, h / 2, GLColor::yellow);
8771     EXPECT_PIXEL_RECT_EQ(0, h / 2, w / 2, h / 2, GLColor::red);
8772     EXPECT_PIXEL_RECT_EQ(w / 2, h / 2, w / 2, h / 2, GLColor::green);
8773 
8774     // Verify stencil exactly.  Stencil has the following values:
8775     //
8776     //    +------+------+
8777     //    |      |      |
8778     //    |  33  |  8A  |
8779     //    |      |      |
8780     //    +------+------+
8781     //    |      |      |
8782     //    |  30  |  0A  |
8783     //    |      |      |
8784     //    +------+------+
8785     //
8786     glDisable(GL_SCISSOR_TEST);
8787     glStencilFunc(GL_EQUAL, 0x33, 0xFF);
8788     glUniform4f(colorLoc, 0, 1, 1, 1);
8789     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
8790 
8791     glStencilFunc(GL_EQUAL, 0x8A, 0xFF);
8792     glUniform4f(colorLoc, 1, 0, 1, 1);
8793     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
8794 
8795     glStencilFunc(GL_EQUAL, 0x30, 0xFF);
8796     glUniform4f(colorLoc, 1, 1, 1, 1);
8797     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
8798 
8799     glStencilFunc(GL_EQUAL, 0x0A, 0xFF);
8800     glUniform4f(colorLoc, 0, 0, 0, 1);
8801     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
8802 
8803     EXPECT_PIXEL_RECT_EQ(0, 0, w / 2, h / 2, GLColor::cyan);
8804     EXPECT_PIXEL_RECT_EQ(w / 2, 0, w / 2, h / 2, GLColor::magenta);
8805     EXPECT_PIXEL_RECT_EQ(0, h / 2, w / 2, h / 2, GLColor::white);
8806     EXPECT_PIXEL_RECT_EQ(w / 2, h / 2, w / 2, h / 2, GLColor::black);
8807 
8808     ASSERT_GL_NO_ERROR();
8809 }
8810 
8811 // Tests that |discard| works with stencil write mask
TEST_P(StateChangeTestES3,StencilWriteMaskVsDiscard)8812 TEST_P(StateChangeTestES3, StencilWriteMaskVsDiscard)
8813 {
8814     constexpr char kVS[] = R"(#version 300 es
8815 precision highp float;
8816 uniform float height;
8817 void main()
8818 {
8819     // gl_VertexID    x    y
8820     //      0        -1   -1
8821     //      1         1   -1
8822     //      2        -1    1
8823     //      3         1    1
8824     int bit0 = gl_VertexID & 1;
8825     int bit1 = gl_VertexID >> 1;
8826     gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, gl_VertexID % 2 == 0 ? -1 : 1, 1);
8827 })";
8828 
8829     constexpr char kFS[] = R"(#version 300 es
8830 precision highp float;
8831 out vec4 colorOut;
8832 uniform vec4 color;
8833 uniform int flag;
8834 void main()
8835 {
8836     if (flag > 0)
8837     {
8838         discard;
8839     }
8840     colorOut = color;
8841 })";
8842 
8843     ANGLE_GL_PROGRAM(program, kVS, kFS);
8844     glUseProgram(program);
8845 
8846     GLint colorLoc = glGetUniformLocation(program, "color");
8847     ASSERT_NE(colorLoc, -1);
8848 
8849     GLint flagLoc = glGetUniformLocation(program, "flag");
8850     ASSERT_NE(flagLoc, -1);
8851 
8852     glEnable(GL_DEPTH_TEST);
8853 
8854     glClearColor(0, 0, 0, 1);
8855     glClearDepthf(1);
8856     glClearStencil(0x00);
8857     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
8858 
8859     glDepthFunc(GL_LEQUAL);
8860     glDepthMask(GL_FALSE);
8861     glEnable(GL_STENCIL_TEST);
8862 
8863     // Enable stencil write, but issue a draw call where all fragments are discarded.
8864     glStencilFunc(GL_ALWAYS, 128, 128);
8865     glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
8866     glStencilMask(128);
8867 
8868     glUniform4f(colorLoc, 1, 0, 0, 1);
8869     glUniform1i(flagLoc, 1);
8870     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
8871 
8872     // At this point, the stencil buffer should be unmodified.  Verify it with another draw call.
8873     glStencilFunc(GL_NOTEQUAL, 128, 128);
8874     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
8875     glStencilMask(128);
8876 
8877     glUniform4f(colorLoc, 0, 1, 0, 1);
8878     glUniform1i(flagLoc, 0);
8879     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
8880 
8881     const int w = getWindowWidth();
8882     const int h = getWindowHeight();
8883 
8884     EXPECT_PIXEL_RECT_EQ(0, 0, w, h, GLColor::green);
8885 
8886     ASSERT_GL_NO_ERROR();
8887 }
8888 
8889 // Tests state change for glCullFace and glEnable(GL_CULL_FACE) as well as glFrontFace
TEST_P(StateChangeTestES3,CullFaceAndFrontFace)8890 TEST_P(StateChangeTestES3, CullFaceAndFrontFace)
8891 {
8892     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
8893     glUseProgram(program);
8894 
8895     GLint colorLoc = glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
8896     ASSERT_NE(colorLoc, -1);
8897 
8898     glClearColor(0, 0, 0, 1);
8899     glClear(GL_COLOR_BUFFER_BIT);
8900 
8901     const int w = getWindowWidth();
8902     const int h = getWindowHeight();
8903 
8904     // Draw red back-facing.  Face culling is initially disabled
8905     glFrontFace(GL_CW);
8906     glUniform4f(colorLoc, 1, 0, 0, 1);
8907     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
8908 
8909     // Draw green back-facing, but enable face culling.  Default cull face is back.
8910     glEnable(GL_CULL_FACE);
8911     glEnable(GL_SCISSOR_TEST);
8912     glScissor(0, 0, w / 2, h / 2);
8913     glUniform4f(colorLoc, 0, 1, 0, 1);
8914     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
8915 
8916     // Draw blue front-facing.
8917     glFrontFace(GL_CCW);
8918     glScissor(w / 2, 0, w / 2, h / 2);
8919     glUniform4f(colorLoc, 0, 0, 1, 1);
8920     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
8921 
8922     // Draw magenta front-facing, but change cull face to front
8923     glCullFace(GL_FRONT);
8924     glScissor(0, h / 2, w / 2, h / 2);
8925     glUniform4f(colorLoc, 1, 0, 1, 1);
8926     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
8927 
8928     // Draw cyan front-facing, with face culling disabled
8929     glDisable(GL_CULL_FACE);
8930     glScissor(w / 2, h / 2, w / 2, h / 2);
8931     glUniform4f(colorLoc, 0, 1, 1, 1);
8932     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
8933 
8934     // Draw yellow front-facing, with cull face set to front and back
8935     glEnable(GL_CULL_FACE);
8936     glCullFace(GL_FRONT_AND_BACK);
8937     glDisable(GL_SCISSOR_TEST);
8938     glUniform4f(colorLoc, 1, 1, 0, 1);
8939     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
8940 
8941     // Verify results
8942     EXPECT_PIXEL_RECT_EQ(0, 0, w / 2, h / 2, GLColor::red);
8943     EXPECT_PIXEL_RECT_EQ(w / 2, 0, w / 2, h / 2, GLColor::blue);
8944     EXPECT_PIXEL_RECT_EQ(0, h / 2, w / 2, h / 2, GLColor::red);
8945     EXPECT_PIXEL_RECT_EQ(w / 2, h / 2, w / 2, h / 2, GLColor::cyan);
8946 
8947     ASSERT_GL_NO_ERROR();
8948 }
8949 
8950 // Tests state change for draw primitive mode
TEST_P(StateChangeTestES3,PrimitiveMode)8951 TEST_P(StateChangeTestES3, PrimitiveMode)
8952 {
8953     constexpr char kVS[] = R"(#version 300 es
8954 precision highp float;
8955 uniform float height;
8956 
8957 // Hardcoded positions for a number of draw modes, using different vertex offsets.
8958 const vec2 kVertices[35] = vec2[35](
8959     // Two triangle
8960     vec2(-1, -1), vec2(1, -1), vec2(-1, 1),
8961     vec2(-1,  1), vec2(1, -1), vec2( 1, 1),
8962     // A triangle strip with 8 triangles
8963     vec2(   -1, -0.5), vec2(   -1,  0.5),
8964     vec2(-0.75, -0.5), vec2(-0.75,  0.5),
8965     vec2( -0.5, -0.5), vec2( -0.5,  0.5),
8966     vec2(-0.25, -0.5), vec2(-0.25,  0.5),
8967     vec2(    0, -0.5), vec2(    0,  0.5),
8968     // A triangle fan with 4 triangles
8969     vec2(0.5, 0), vec2(1, -0.5), vec2(1, 0.5), vec2(0, 0.5), vec2(0, -0.5), vec2(1, -0.5),
8970     // One line
8971     vec2(-1, -0.49), vec2(1, -0.49),
8972     // One line strip
8973     vec2(-1, 0.51), vec2(0, 0.51), vec2(1, 0.51),
8974     // One line loop
8975     vec2(-.99, -.99), vec2(0.99, -.99), vec2(0.99, 0.99), vec2(-.99, 0.99),
8976     // Four points
8977     vec2(-.99, -.99), vec2(0.99, -.99), vec2(0.99, 0.99), vec2(-.99, 0.99)
8978 );
8979 
8980 void main()
8981 {
8982     gl_Position = vec4(kVertices[gl_VertexID], 0, 1);
8983     gl_PointSize = 1.;
8984 })";
8985 
8986     constexpr char kFS[] = R"(#version 300 es
8987 precision highp float;
8988 out vec4 colorOut;
8989 uniform vec4 color;
8990 void main()
8991 {
8992     colorOut = color;
8993 })";
8994 
8995     ANGLE_GL_PROGRAM(program, kVS, kFS);
8996     glUseProgram(program);
8997 
8998     GLint colorLoc = glGetUniformLocation(program, "color");
8999     ASSERT_NE(colorLoc, -1);
9000 
9001     glClearColor(0, 0, 0, 1);
9002     glClear(GL_COLOR_BUFFER_BIT);
9003 
9004     // Draw the following:
9005     //
9006     // 1. Red with two triangles
9007     // 2. Green with a triangle strip
9008     // 3. Blue with a triangle fan
9009     // 4. Yellow with a line
9010     // 5. Cyan with a line strip
9011     // 6. Magenta with a line loop
9012     // 7. White with four points
9013     //
9014     //
9015     //     +---------------------------+  <-- 7: corners
9016     //     |                           |
9017     //     |             1             |
9018     //     |                           |
9019     //     +-------------+-------------+  <-- 5: horizontal line
9020     //     |             |             |
9021     //     |             |             |
9022     //     |             |             |
9023     //     |      2      |      3      |  <-- 6: border around image
9024     //     |             |             |
9025     //     |             |             |
9026     //     |             |             |
9027     //     +-------------+-------------+  <-- 4: horizontal line
9028     //     |                           |
9029     //     |             1             |
9030     //     |                           |
9031     //     +---------------------------+
9032 
9033     glUniform4f(colorLoc, 1, 0, 0, 1);
9034     glDrawArrays(GL_TRIANGLES, 0, 6);
9035 
9036     glUniform4f(colorLoc, 0, 1, 0, 1);
9037     glDrawArrays(GL_TRIANGLE_STRIP, 6, 10);
9038 
9039     glUniform4f(colorLoc, 0, 0, 1, 1);
9040     glDrawArrays(GL_TRIANGLE_FAN, 16, 6);
9041 
9042     glUniform4f(colorLoc, 1, 1, 0, 1);
9043     glDrawArrays(GL_LINES, 22, 2);
9044 
9045     glUniform4f(colorLoc, 0, 1, 1, 1);
9046     glDrawArrays(GL_LINE_STRIP, 24, 3);
9047 
9048     glUniform4f(colorLoc, 1, 0, 1, 1);
9049     glDrawArrays(GL_LINE_LOOP, 27, 4);
9050 
9051     glUniform4f(colorLoc, 1, 1, 1, 1);
9052     glDrawArrays(GL_POINTS, 31, 4);
9053 
9054     const int w = getWindowWidth();
9055     const int h = getWindowHeight();
9056 
9057     // Verify results
9058     EXPECT_PIXEL_RECT_EQ(1, 1, w - 2, h / 4 - 2, GLColor::red);
9059     EXPECT_PIXEL_RECT_EQ(1, 3 * h / 4 + 1, w - 2, h / 4 - 2, GLColor::red);
9060 
9061     EXPECT_PIXEL_RECT_EQ(1, h / 4 + 1, w / 2 - 2, h / 2 - 2, GLColor::green);
9062 
9063     EXPECT_PIXEL_RECT_EQ(w / 2 + 1, h / 4 + 1, w / 2 - 2, h / 2 - 2, GLColor::blue);
9064 
9065     EXPECT_PIXEL_RECT_EQ(1, h / 4, w / 2 - 2, 1, GLColor::yellow);
9066 
9067     EXPECT_PIXEL_RECT_EQ(1, 3 * h / 4, w / 2 - 2, 1, GLColor::cyan);
9068 
9069     EXPECT_PIXEL_RECT_EQ(1, 0, w - 2, 1, GLColor::magenta);
9070     EXPECT_PIXEL_RECT_EQ(0, 1, 1, h - 2, GLColor::magenta);
9071     EXPECT_PIXEL_RECT_EQ(w - 1, 1, 1, h - 2, GLColor::magenta);
9072     EXPECT_PIXEL_RECT_EQ(1, h - 1, w - 2, 1, GLColor::magenta);
9073 
9074     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white);
9075     EXPECT_PIXEL_COLOR_EQ(w - 1, 0, GLColor::white);
9076     EXPECT_PIXEL_COLOR_EQ(0, h - 1, GLColor::white);
9077     EXPECT_PIXEL_COLOR_EQ(w - 1, h - 1, GLColor::white);
9078 
9079     ASSERT_GL_NO_ERROR();
9080 }
9081 
9082 // Tests that vertex attributes are correctly bound after a masked clear.  In the Vulkan backend,
9083 // the masked clear is done with an internal shader that doesn't use vertex attributes.
TEST_P(StateChangeTestES3,DrawMaskedClearDraw)9084 TEST_P(StateChangeTestES3, DrawMaskedClearDraw)
9085 {
9086     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
9087     glUseProgram(program);
9088 
9089     GLint colorLoc = glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
9090     ASSERT_NE(colorLoc, -1);
9091 
9092     GLint posAttrib = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
9093     ASSERT_EQ(0, posAttrib);
9094 
9095     std::array<GLfloat, 3 * 4> positionData = {
9096         -1, -1, 0, 1, -1, 0, -1, 1, 0, 1, 1, 0,
9097     };
9098 
9099     GLBuffer posBuffer;
9100     glBindBuffer(GL_ARRAY_BUFFER, posBuffer);
9101     glBufferData(GL_ARRAY_BUFFER, sizeof(positionData), positionData.data(), GL_STATIC_DRAW);
9102     glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
9103     glEnableVertexAttribArray(posAttrib);
9104 
9105     const int w = getWindowWidth();
9106     const int h = getWindowHeight();
9107 
9108     glClearColor(0, 0, 0, 1);
9109     glClear(GL_COLOR_BUFFER_BIT);
9110 
9111     glEnable(GL_BLEND);
9112     glBlendFunc(GL_ONE, GL_ONE);
9113 
9114     // Draw to red and alpha channels, with garbage in green and blue
9115     glUniform4f(colorLoc, 1, 0.123f, 0.456f, 0.5f);
9116     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
9117 
9118     // Clear the green and blue channels
9119     glColorMask(GL_FALSE, GL_TRUE, GL_TRUE, GL_FALSE);
9120     glClearColor(0.333f, 0.5, 0, 0.888f);
9121     glClear(GL_COLOR_BUFFER_BIT);
9122 
9123     // Blend in to saturate green and alpha
9124     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
9125     glUniform4f(colorLoc, 0, 0.6f, 0, 0.6f);
9126     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
9127 
9128     // Verify results
9129     EXPECT_PIXEL_RECT_EQ(0, 0, w, h, GLColor::yellow);
9130 
9131     ASSERT_GL_NO_ERROR();
9132 }
9133 
9134 // Tests state change for vertex attribute stride
TEST_P(StateChangeTestES3,VertexStride)9135 TEST_P(StateChangeTestES3, VertexStride)
9136 {
9137     constexpr char kVS[] =
9138         R"(#version 300 es
9139 precision mediump float;
9140 in vec4 position;
9141 layout(location = 1) in vec4 test;
9142 layout(location = 5) in vec4 expected;
9143 out vec4 result;
9144 void main(void)
9145 {
9146     gl_Position = position;
9147     if (any(equal(test, vec4(0))) || any(equal(expected, vec4(0))))
9148     {
9149         result = vec4(0);
9150     }
9151     else
9152     {
9153         vec4 threshold = max(abs(expected) * 0.01, 1.0 / 64.0);
9154         result = vec4(lessThanEqual(abs(test - expected), threshold));
9155     }
9156 })";
9157 
9158     constexpr char kFS[] =
9159         R"(#version 300 es
9160 precision mediump float;
9161 in vec4 result;
9162 out vec4 colorOut;
9163 void main()
9164 {
9165     colorOut = vec4(greaterThanEqual(result, vec4(0.999)));
9166 })";
9167 
9168     ANGLE_GL_PROGRAM(program, kVS, kFS);
9169     glUseProgram(program);
9170 
9171     // Every draw call consists of 4 vertices.  The vertex attributes are laid out as follows:
9172     //
9173     // Position: No gaps
9174     // test: 4 unorm vertices with stride 20, simultaneously 4 vertices with stride 16
9175     // expected: 4 float vertices with stride 80, simultaneously 4 vertices with stride 48
9176 
9177     const std::array<GLubyte, 7 * 4> kData = {{1,   2,   3,   4,   5,   6,   7,  8,  125, 126,
9178                                                127, 128, 129, 250, 251, 252, 78, 79, 80,  81,
9179                                                155, 156, 157, 158, 20,  21,  22, 23}};
9180 
9181     constexpr size_t kTestStride1     = 20;
9182     constexpr size_t kTestStride2     = 16;
9183     constexpr size_t kExpectedStride1 = 20;
9184     constexpr size_t kExpectedStride2 = 12;
9185 
9186     std::array<GLubyte, kTestStride1 * 3 + 4> testInitData         = {};
9187     std::array<GLfloat, kExpectedStride1 * 3 + 4> expectedInitData = {};
9188 
9189     for (uint32_t vertex = 0; vertex < 7; ++vertex)
9190     {
9191         size_t testOffset     = vertex * kTestStride1;
9192         size_t expectedOffset = vertex * kExpectedStride1;
9193         if (vertex >= 4)
9194         {
9195             testOffset     = (vertex - 3) * kTestStride2;
9196             expectedOffset = (vertex - 3) * kExpectedStride2;
9197         }
9198 
9199         for (uint32_t channel = 0; channel < 4; ++channel)
9200         {
9201             // The strides are chosen such that the two streams don't collide
9202             ASSERT_EQ(testInitData[testOffset + channel], 0);
9203             ASSERT_EQ(expectedInitData[expectedOffset + channel], 0);
9204 
9205             GLubyte data                               = kData[vertex * 4 + channel];
9206             testInitData[testOffset + channel]         = data;
9207             expectedInitData[expectedOffset + channel] = data;
9208         }
9209 
9210         // For the first 4 vertices, expect perfect match (i.e. get white).  For the last 3
9211         // vertices, expect the green channel test to fail (i.e. get magenta).
9212         if (vertex >= 4)
9213         {
9214             expectedInitData[expectedOffset + 1] += 2;
9215         }
9216     }
9217 
9218     std::array<GLfloat, 3 * 4> positionData = {
9219         -1, -1, 0, 1, -1, 0, -1, 1, 0, 1, 1, 0,
9220     };
9221 
9222     GLBuffer posBuffer;
9223     glBindBuffer(GL_ARRAY_BUFFER, posBuffer);
9224     glBufferData(GL_ARRAY_BUFFER, sizeof(positionData), positionData.data(), GL_STATIC_DRAW);
9225 
9226     GLBuffer testBuffer;
9227     glBindBuffer(GL_ARRAY_BUFFER, testBuffer);
9228     glBufferData(GL_ARRAY_BUFFER, sizeof(testInitData), testInitData.data(), GL_STATIC_DRAW);
9229 
9230     GLBuffer expectedBuffer;
9231     glBindBuffer(GL_ARRAY_BUFFER, expectedBuffer);
9232     glBufferData(GL_ARRAY_BUFFER, sizeof(expectedInitData), expectedInitData.data(),
9233                  GL_STATIC_DRAW);
9234 
9235     GLint posAttrib = glGetAttribLocation(program, "position");
9236     ASSERT_EQ(0, posAttrib);
9237     GLint testAttrib = glGetAttribLocation(program, "test");
9238     ASSERT_EQ(1, testAttrib);
9239     GLint expectedAttrib = glGetAttribLocation(program, "expected");
9240     ASSERT_EQ(5, expectedAttrib);
9241 
9242     const int w = getWindowWidth();
9243     const int h = getWindowHeight();
9244 
9245     glClearColor(0, 0, 0, 1);
9246     glClear(GL_COLOR_BUFFER_BIT);
9247 
9248     glEnableVertexAttribArray(posAttrib);
9249     glEnableVertexAttribArray(testAttrib);
9250     glEnableVertexAttribArray(expectedAttrib);
9251 
9252     glBindBuffer(GL_ARRAY_BUFFER, posBuffer);
9253     glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
9254     glBindBuffer(GL_ARRAY_BUFFER, testBuffer);
9255     glVertexAttribPointer(testAttrib, 4, GL_UNSIGNED_BYTE, GL_FALSE, kTestStride1 * sizeof(GLubyte),
9256                           nullptr);
9257     glBindBuffer(GL_ARRAY_BUFFER, expectedBuffer);
9258     glVertexAttribPointer(expectedAttrib, 4, GL_FLOAT, GL_FALSE, kExpectedStride1 * sizeof(GLfloat),
9259                           nullptr);
9260 
9261     glEnable(GL_SCISSOR_TEST);
9262     glScissor(0, 0, w / 2, h);
9263     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
9264 
9265     glBindBuffer(GL_ARRAY_BUFFER, testBuffer);
9266     glVertexAttribPointer(testAttrib, 4, GL_UNSIGNED_BYTE, GL_FALSE, kTestStride2 * sizeof(GLubyte),
9267                           nullptr);
9268     glBindBuffer(GL_ARRAY_BUFFER, expectedBuffer);
9269     glVertexAttribPointer(expectedAttrib, 4, GL_FLOAT, GL_FALSE, kExpectedStride2 * sizeof(GLfloat),
9270                           nullptr);
9271 
9272     glScissor(w / 2, 0, w / 2, h);
9273     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
9274 
9275     // Verify results
9276     EXPECT_PIXEL_RECT_EQ(0, 0, w / 2, h, GLColor::white);
9277     EXPECT_PIXEL_RECT_EQ(w / 2, 0, w / 2, h, GLColor::magenta);
9278 
9279     ASSERT_GL_NO_ERROR();
9280 }
9281 
9282 // Tests state change for depth test, write and function
TEST_P(StateChangeTestES3,DepthTestWriteAndFunc)9283 TEST_P(StateChangeTestES3, DepthTestWriteAndFunc)
9284 {
9285     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
9286     glUseProgram(program);
9287 
9288     GLint colorLoc = glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
9289     ASSERT_NE(colorLoc, -1);
9290 
9291     const int w = getWindowWidth();
9292     const int h = getWindowHeight();
9293 
9294     glClearColor(0, 0, 0, 1);
9295     glClearDepthf(0.5);
9296     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
9297 
9298     // Initialize the depth buffer:
9299     glEnable(GL_DEPTH_TEST);
9300     glDepthMask(GL_TRUE);
9301     glDepthFunc(GL_ALWAYS);
9302 
9303     glEnable(GL_SCISSOR_TEST);
9304     glScissor(0, 0, w / 2, h / 2);
9305     glUniform4f(colorLoc, 0, 0, 0, 1);
9306     drawQuad(program, essl1_shaders::PositionAttrib(), -0.8f);
9307     glScissor(w / 2, 0, w / 2, h / 2);
9308     drawQuad(program, essl1_shaders::PositionAttrib(), -0.2f);
9309     glScissor(0, h / 2, w / 2, h / 2);
9310     drawQuad(program, essl1_shaders::PositionAttrib(), 0.4f);
9311     glScissor(w / 2, h / 2, w / 2, h / 2);
9312     drawQuad(program, essl1_shaders::PositionAttrib(), 0.6f);
9313 
9314     glDisable(GL_SCISSOR_TEST);
9315     glDisable(GL_DEPTH_TEST);
9316     glDepthMask(GL_FALSE);
9317     glUniform4f(colorLoc, 1, 0, 0, 1);
9318     drawQuad(program, essl1_shaders::PositionAttrib(), 0);
9319 
9320     EXPECT_PIXEL_RECT_EQ(0, 0, w, h, GLColor::red);
9321 
9322     // Make draw calls that test depth or not, write depth or not, and use different functions
9323 
9324     // Write green to one half
9325     glEnable(GL_DEPTH_TEST);
9326     glDepthFunc(GL_LESS);
9327     glUniform4f(colorLoc, 0, 1, 0, 1);
9328     drawQuad(program, essl1_shaders::PositionAttrib(), 0.35f);
9329 
9330     // Write blue to another half
9331     glDepthFunc(GL_GREATER);
9332     glUniform4f(colorLoc, 0, 0, 1, 1);
9333     drawQuad(program, essl1_shaders::PositionAttrib(), -0.15f);
9334 
9335     // Write yellow to a corner, overriding depth
9336     glDepthMask(GL_TRUE);
9337     glUniform4f(colorLoc, 1, 1, 0, 1);
9338     drawQuad(program, essl1_shaders::PositionAttrib(), -0.6f);
9339 
9340     // Write magenta to another corner, overriding depth
9341     glDepthFunc(GL_LESS);
9342     glUniform4f(colorLoc, 1, 0, 1, 1);
9343     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
9344 
9345     // No-op write
9346     glDepthFunc(GL_NEVER);
9347     glUniform4f(colorLoc, 0, 1, 1, 1);
9348     drawQuad(program, essl1_shaders::PositionAttrib(), 0);
9349 
9350     // Verify results
9351     EXPECT_PIXEL_RECT_EQ(0, 0, w / 2, h / 2, GLColor::yellow);
9352     EXPECT_PIXEL_RECT_EQ(w / 2, 0, w / 2, h / 2, GLColor::blue);
9353     EXPECT_PIXEL_RECT_EQ(0, h / 2, w / 2, h / 2, GLColor::green);
9354     EXPECT_PIXEL_RECT_EQ(w / 2, h / 2, w / 2, h / 2, GLColor::magenta);
9355 
9356     // Verify the depth buffer
9357     glDepthMask(GL_FALSE);
9358     glDepthFunc(GL_LESS);
9359     glUniform4f(colorLoc, 1, 0, 0, 1);
9360     drawQuad(program, essl1_shaders::PositionAttrib(), -0.61f);
9361     glUniform4f(colorLoc, 0, 0, 0, 1);
9362     drawQuad(program, essl1_shaders::PositionAttrib(), -0.59f);
9363 
9364     EXPECT_PIXEL_RECT_EQ(0, 0, w / 2, h / 2, GLColor::red);
9365     EXPECT_PIXEL_RECT_EQ(w / 2, 0, w / 2, h / 2, GLColor::black);
9366     EXPECT_PIXEL_RECT_EQ(0, h / 2, w / 2, h / 2, GLColor::black);
9367     EXPECT_PIXEL_RECT_EQ(w / 2, h / 2, w / 2, h / 2, GLColor::black);
9368 
9369     glDepthFunc(GL_GREATER);
9370     glUniform4f(colorLoc, 0, 1, 1, 1);
9371     drawQuad(program, essl1_shaders::PositionAttrib(), 0.51f);
9372     glUniform4f(colorLoc, 0, 0, 0, 1);
9373     drawQuad(program, essl1_shaders::PositionAttrib(), 0.49f);
9374 
9375     EXPECT_PIXEL_RECT_EQ(0, 0, w / 2, h / 2, GLColor::black);
9376     EXPECT_PIXEL_RECT_EQ(w / 2, 0, w / 2, h / 2, GLColor::black);
9377     EXPECT_PIXEL_RECT_EQ(0, h / 2, w / 2, h / 2, GLColor::black);
9378     EXPECT_PIXEL_RECT_EQ(w / 2, h / 2, w / 2, h / 2, GLColor::cyan);
9379 
9380     glDepthFunc(GL_LESS);
9381     glUniform4f(colorLoc, 0, 1, 0, 1);
9382     drawQuad(program, essl1_shaders::PositionAttrib(), -0.21f);
9383     glUniform4f(colorLoc, 1, 1, 1, 1);
9384     drawQuad(program, essl1_shaders::PositionAttrib(), -0.19f);
9385 
9386     EXPECT_PIXEL_RECT_EQ(0, 0, w / 2, h / 2, GLColor::black);
9387     EXPECT_PIXEL_RECT_EQ(w / 2, 0, w / 2, h / 2, GLColor::green);
9388     EXPECT_PIXEL_RECT_EQ(0, h / 2, w / 2, h / 2, GLColor::white);
9389     EXPECT_PIXEL_RECT_EQ(w / 2, h / 2, w / 2, h / 2, GLColor::white);
9390 
9391     glDepthFunc(GL_GREATER);
9392     glUniform4f(colorLoc, 0, 0, 1, 1);
9393     drawQuad(program, essl1_shaders::PositionAttrib(), 0.41f);
9394     glUniform4f(colorLoc, 1, 0, 1, 1);
9395     drawQuad(program, essl1_shaders::PositionAttrib(), 0.39f);
9396 
9397     EXPECT_PIXEL_RECT_EQ(0, 0, w / 2, h / 2, GLColor::magenta);
9398     EXPECT_PIXEL_RECT_EQ(w / 2, 0, w / 2, h / 2, GLColor::magenta);
9399     EXPECT_PIXEL_RECT_EQ(0, h / 2, w / 2, h / 2, GLColor::blue);
9400     EXPECT_PIXEL_RECT_EQ(w / 2, h / 2, w / 2, h / 2, GLColor::white);
9401 
9402     ASSERT_GL_NO_ERROR();
9403 }
9404 
9405 // Tests state change for stencil test and function
TEST_P(StateChangeTestES3,StencilTestAndFunc)9406 TEST_P(StateChangeTestES3, StencilTestAndFunc)
9407 {
9408     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
9409     glUseProgram(program);
9410 
9411     GLint colorLoc = glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
9412     ASSERT_NE(colorLoc, -1);
9413 
9414     const int w = getWindowWidth();
9415     const int h = getWindowHeight();
9416 
9417     glClearColor(0, 0, 0, 1);
9418     glClearDepthf(0.5);
9419     glClearStencil(0x55);
9420     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
9421 
9422     // Initialize the depth and stencil buffers
9423     glEnable(GL_DEPTH_TEST);
9424     glDepthMask(GL_TRUE);
9425     glDepthFunc(GL_ALWAYS);
9426 
9427     glEnable(GL_STENCIL_TEST);
9428     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
9429 
9430     glEnable(GL_SCISSOR_TEST);
9431     glScissor(0, 0, w / 2, h / 2);
9432     glUniform4f(colorLoc, 0, 0, 0, 1);
9433     glStencilFunc(GL_ALWAYS, 0x3E, 0xFF);
9434     drawQuad(program, essl1_shaders::PositionAttrib(), -0.8f);
9435     glScissor(w / 2, 0, w / 2, h / 2);
9436     glStencilFunc(GL_ALWAYS, 0xA7, 0xFF);
9437     drawQuad(program, essl1_shaders::PositionAttrib(), -0.2f);
9438     glScissor(0, h / 2, w / 2, h / 2);
9439     glStencilFunc(GL_ALWAYS, 0x6C, 0xFF);
9440     drawQuad(program, essl1_shaders::PositionAttrib(), 0.4f);
9441     glScissor(w / 2, h / 2, w / 2, h / 2);
9442     glStencilFunc(GL_ALWAYS, 0x5B, 0xFF);
9443     drawQuad(program, essl1_shaders::PositionAttrib(), 0.6f);
9444 
9445     glDisable(GL_SCISSOR_TEST);
9446     glDisable(GL_DEPTH_TEST);
9447     glDisable(GL_STENCIL_TEST);
9448     glDepthMask(GL_FALSE);
9449     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
9450     glUniform4f(colorLoc, 1, 0, 0, 1);
9451     drawQuad(program, essl1_shaders::PositionAttrib(), 0);
9452 
9453     EXPECT_PIXEL_RECT_EQ(0, 0, w, h, GLColor::red);
9454 
9455     // Make draw calls that manipulate stencil and use different functions and ops.
9456 
9457     // Current color/depth/stencil in the four sections of the image:
9458     //
9459     //     red/-0.8/3E    red/-0.2/A7
9460     //     red/ 0.4/6C    red/0.6/5B
9461     //
9462     glEnable(GL_DEPTH_TEST);
9463     glDepthFunc(GL_LESS);
9464     glEnable(GL_STENCIL_TEST);
9465     glStencilFuncSeparate(GL_FRONT, GL_EQUAL, 0x2C, 0x2C);
9466     glStencilOpSeparate(GL_FRONT, GL_INCR, GL_DECR, GL_INVERT);
9467     glStencilFuncSeparate(GL_BACK, GL_GREATER, 0x7B, 0xFF);
9468     glStencilOpSeparate(GL_BACK, GL_INCR, GL_ZERO, GL_REPLACE);
9469 
9470     // Draw green front-facing to get:
9471     //
9472     //       red/-0.8/3D    red/-0.2/A8
9473     //     green/ 0.4/93    red/ 0.6/5C
9474     //
9475     glUniform4f(colorLoc, 0, 1, 0, 1);
9476     drawQuad(program, essl1_shaders::PositionAttrib(), 0);
9477 
9478     // Draw blue back-facing to get:
9479     //
9480     //       red/-0.8/00    red/-0.2/A9
9481     //     green/ 0.4/94   blue/ 0.6/7B
9482     //
9483     glFrontFace(GL_CW);
9484     glUniform4f(colorLoc, 0, 0, 1, 1);
9485     drawQuad(program, essl1_shaders::PositionAttrib(), 0);
9486 
9487     glStencilFuncSeparate(GL_FRONT, GL_LEQUAL, 0x42, 0x42);
9488     glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_DECR, GL_INCR_WRAP);
9489     glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 0x00, 0x00);
9490     glStencilOpSeparate(GL_BACK, GL_KEEP, GL_INCR, GL_INVERT);
9491 
9492     // Draw yellow back-facing to get:
9493     //
9494     //    yellow/-0.8/FF yellow/-0.2/56
9495     //     green/ 0.4/95   blue/ 0.6/7C
9496     //
9497     glDepthFunc(GL_GREATER);
9498     glUniform4f(colorLoc, 1, 1, 0, 1);
9499     drawQuad(program, essl1_shaders::PositionAttrib(), 0);
9500 
9501     // Draw cyan front-facing to get:
9502     //
9503     //      cyan/-0.8/00 yellow/-0.2/55
9504     //     green/ 0.4/95   blue/ 0.6/7C
9505     //
9506     glFrontFace(GL_CCW);
9507     glUniform4f(colorLoc, 0, 1, 1, 1);
9508     drawQuad(program, essl1_shaders::PositionAttrib(), -0.5);
9509 
9510     // No-op draw
9511     glStencilFuncSeparate(GL_FRONT, GL_NEVER, 0x00, 0x00);
9512     glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INVERT, GL_INVERT);
9513     glUniform4f(colorLoc, 1, 0, 1, 1);
9514     drawQuad(program, essl1_shaders::PositionAttrib(), 0);
9515 
9516     // Verify results
9517     EXPECT_PIXEL_RECT_EQ(0, 0, w / 2, h / 2, GLColor::cyan);
9518     EXPECT_PIXEL_RECT_EQ(w / 2, 0, w / 2, h / 2, GLColor::yellow);
9519     EXPECT_PIXEL_RECT_EQ(0, h / 2, w / 2, h / 2, GLColor::green);
9520     EXPECT_PIXEL_RECT_EQ(w / 2, h / 2, w / 2, h / 2, GLColor::blue);
9521 
9522     // Verify the stencil buffer
9523     glDisable(GL_DEPTH_TEST);
9524     glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_KEEP);
9525     glStencilFuncSeparate(GL_FRONT, GL_EQUAL, 0x00, 0xFF);
9526     glUniform4f(colorLoc, 1, 0, 0, 1);
9527     drawQuad(program, essl1_shaders::PositionAttrib(), 0);
9528 
9529     EXPECT_PIXEL_RECT_EQ(0, 0, w / 2, h / 2, GLColor::red);
9530     EXPECT_PIXEL_RECT_EQ(w / 2, 0, w / 2, h / 2, GLColor::yellow);
9531     EXPECT_PIXEL_RECT_EQ(0, h / 2, w / 2, h / 2, GLColor::green);
9532     EXPECT_PIXEL_RECT_EQ(w / 2, h / 2, w / 2, h / 2, GLColor::blue);
9533 
9534     glStencilFuncSeparate(GL_FRONT, GL_EQUAL, 0x55, 0xFF);
9535     glUniform4f(colorLoc, 1, 0, 1, 1);
9536     drawQuad(program, essl1_shaders::PositionAttrib(), 0);
9537 
9538     EXPECT_PIXEL_RECT_EQ(0, 0, w / 2, h / 2, GLColor::red);
9539     EXPECT_PIXEL_RECT_EQ(w / 2, 0, w / 2, h / 2, GLColor::magenta);
9540     EXPECT_PIXEL_RECT_EQ(0, h / 2, w / 2, h / 2, GLColor::green);
9541     EXPECT_PIXEL_RECT_EQ(w / 2, h / 2, w / 2, h / 2, GLColor::blue);
9542 
9543     glStencilFuncSeparate(GL_FRONT, GL_EQUAL, 0x95, 0xFF);
9544     glUniform4f(colorLoc, 1, 1, 1, 1);
9545     drawQuad(program, essl1_shaders::PositionAttrib(), 0);
9546 
9547     EXPECT_PIXEL_RECT_EQ(0, 0, w / 2, h / 2, GLColor::red);
9548     EXPECT_PIXEL_RECT_EQ(w / 2, 0, w / 2, h / 2, GLColor::magenta);
9549     EXPECT_PIXEL_RECT_EQ(0, h / 2, w / 2, h / 2, GLColor::white);
9550     EXPECT_PIXEL_RECT_EQ(w / 2, h / 2, w / 2, h / 2, GLColor::blue);
9551 
9552     glStencilFuncSeparate(GL_FRONT, GL_EQUAL, 0x7C, 0xFF);
9553     glUniform4f(colorLoc, 0, 0, 0, 1);
9554     drawQuad(program, essl1_shaders::PositionAttrib(), 0);
9555 
9556     EXPECT_PIXEL_RECT_EQ(0, 0, w / 2, h / 2, GLColor::red);
9557     EXPECT_PIXEL_RECT_EQ(w / 2, 0, w / 2, h / 2, GLColor::magenta);
9558     EXPECT_PIXEL_RECT_EQ(0, h / 2, w / 2, h / 2, GLColor::white);
9559     EXPECT_PIXEL_RECT_EQ(w / 2, h / 2, w / 2, h / 2, GLColor::black);
9560 
9561     ASSERT_GL_NO_ERROR();
9562 }
9563 
9564 // Tests state change for rasterizer discard
TEST_P(StateChangeTestES3,RasterizerDiscard)9565 TEST_P(StateChangeTestES3, RasterizerDiscard)
9566 {
9567     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
9568     glUseProgram(program);
9569 
9570     GLint colorLoc = glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
9571     ASSERT_NE(colorLoc, -1);
9572 
9573     const int w = getWindowWidth();
9574     const int h = getWindowHeight();
9575 
9576     glClearColor(0, 0, 0, 0);
9577     glClear(GL_COLOR_BUFFER_BIT);
9578 
9579     glEnable(GL_BLEND);
9580     glBlendFunc(GL_ONE, GL_ONE);
9581 
9582     // Start a render pass and issue three draw calls with the middle one having rasterizer discard
9583     // enabled.
9584     glUniform4f(colorLoc, 1, 0, 0, 0);
9585     drawQuad(program, essl1_shaders::PositionAttrib(), 0);
9586 
9587     glEnable(GL_RASTERIZER_DISCARD);
9588 
9589     glUniform4f(colorLoc, 0, 1, 1, 0);
9590     drawQuad(program, essl1_shaders::PositionAttrib(), 0);
9591 
9592     glDisable(GL_RASTERIZER_DISCARD);
9593 
9594     glUniform4f(colorLoc, 0, 0, 0, 1);
9595     drawQuad(program, essl1_shaders::PositionAttrib(), 0);
9596 
9597     EXPECT_PIXEL_RECT_EQ(0, 0, w, h, GLColor::red);
9598 
9599     // Enable rasterizer discard and make sure the state is effective.
9600     glEnable(GL_RASTERIZER_DISCARD);
9601 
9602     glUniform4f(colorLoc, 0, 1, 0, 1);
9603     drawQuad(program, essl1_shaders::PositionAttrib(), 0);
9604 
9605     EXPECT_PIXEL_RECT_EQ(0, 0, w, h, GLColor::red);
9606 
9607     // Start a render pass and issue three draw calls with the first and last ones having rasterizer
9608     // discard enabled.
9609     glUniform4f(colorLoc, 0, 1, 0, 0);
9610     drawQuad(program, essl1_shaders::PositionAttrib(), 0);
9611 
9612     glDisable(GL_RASTERIZER_DISCARD);
9613 
9614     glUniform4f(colorLoc, 0, 0, 1, 0);
9615     drawQuad(program, essl1_shaders::PositionAttrib(), 0);
9616 
9617     glEnable(GL_RASTERIZER_DISCARD);
9618 
9619     glUniform4f(colorLoc, 0, 1, 0, 1);
9620     drawQuad(program, essl1_shaders::PositionAttrib(), 0);
9621 
9622     EXPECT_PIXEL_RECT_EQ(0, 0, w, h, GLColor::magenta);
9623 
9624     ASSERT_GL_NO_ERROR();
9625 }
9626 
9627 // Tests state change for GL_POLYGON_OFFSET_FILL.
TEST_P(StateChangeTestES3,PolygonOffsetFill)9628 TEST_P(StateChangeTestES3, PolygonOffsetFill)
9629 {
9630     constexpr char kVS[] = R"(#version 300 es
9631 precision highp float;
9632 uniform float height;
9633 void main()
9634 {
9635     // gl_VertexID    x    y
9636     //      0        -1   -1
9637     //      1         1   -1
9638     //      2        -1    1
9639     //      3         1    1
9640     int bit0 = gl_VertexID & 1;
9641     int bit1 = gl_VertexID >> 1;
9642     gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, gl_VertexID % 2 == 0 ? -1 : 1, 1);
9643 })";
9644 
9645     constexpr char kFS[] = R"(#version 300 es
9646 precision highp float;
9647 out vec4 colorOut;
9648 uniform vec4 color;
9649 void main()
9650 {
9651     colorOut = color;
9652 })";
9653 
9654     ANGLE_GL_PROGRAM(program, kVS, kFS);
9655     glUseProgram(program);
9656 
9657     GLint colorLoc = glGetUniformLocation(program, "color");
9658     ASSERT_NE(-1, colorLoc);
9659 
9660     glClearColor(0, 0, 0, 1);
9661     glClearDepthf(0);
9662     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
9663 
9664     // The shader creates a depth slope from left (0) to right (1).
9665     //
9666     // This test issues three draw calls:
9667     //
9668     //
9669     //           Draw 3 (blue): factor width/2, enabled, depth test: Greater
9670     //          ^     |       __________________
9671     //          |     |    __/      __/      __/
9672     //          |     V __/      __/      __/
9673     //          |    __/      __/      __/
9674     //          | __/      __/      __/
9675     //          |/      __/^     __/
9676     //          |    __/   |  __/   <--- Draw 2: factor width/2, disabled, depth test: Greater
9677     //          | __/      _\/
9678     //          |/      __/  \
9679     //          |    __/      Draw 1 (red): factor width/4, enabled
9680     //          | __/
9681     //          +/------------------------------>
9682     //
9683     // Result:  <-------magenta-------><--red-->
9684 
9685     glEnable(GL_BLEND);
9686     glBlendFunc(GL_ONE, GL_ONE);
9687 
9688     glEnable(GL_DEPTH_TEST);
9689     glDepthFunc(GL_ALWAYS);
9690 
9691     glEnable(GL_POLYGON_OFFSET_FILL);
9692 
9693     const int w = getWindowWidth();
9694     const int h = getWindowHeight();
9695 
9696     glUniform4f(colorLoc, 1, 0, 0, 1);
9697     glPolygonOffset(getWindowWidth() / 4, 0);
9698     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
9699 
9700     glUniform4f(colorLoc, 0, 1, 0, 1);
9701     glPolygonOffset(getWindowWidth() / 2, 0);
9702     glDepthFunc(GL_GREATER);
9703     glDisable(GL_POLYGON_OFFSET_FILL);
9704     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
9705 
9706     glUniform4f(colorLoc, 0, 0, 1, 1);
9707     glEnable(GL_POLYGON_OFFSET_FILL);
9708     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
9709 
9710     EXPECT_PIXEL_RECT_EQ(0, 0, 3 * w / 4 - 1, h, GLColor::magenta);
9711     EXPECT_PIXEL_RECT_EQ(3 * w / 4 + 1, 0, w / 4 - 1, h, GLColor::red);
9712 
9713     ASSERT_GL_NO_ERROR();
9714 }
9715 
9716 // Tests state change for GL_PRIMITIVE_RESTART.
TEST_P(StateChangeTestES3,PrimitiveRestart)9717 TEST_P(StateChangeTestES3, PrimitiveRestart)
9718 {
9719     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
9720     glUseProgram(program);
9721 
9722     GLint colorLoc = glGetUniformLocation(program, angle::essl1_shaders::ColorUniform());
9723     ASSERT_NE(colorLoc, -1);
9724 
9725     GLint posAttrib = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
9726     ASSERT_EQ(0, posAttrib);
9727 
9728     // Arrange the vertices as such:
9729     //
9730     //     1      3      4
9731     //      +-----+-----+
9732     //      |     |     |
9733     //      |     |     |
9734     //      |     |     |
9735     //      |     |     |
9736     //      |     |     |
9737     //      |     |     |
9738     //      +-----+-----+
9739     //     0      2     FF
9740     //
9741     // Drawing a triangle strip, without primitive restart, the whole framebuffer is rendered, while
9742     // with primitive restart only the left half is.
9743     std::vector<Vector3> positionData(256, {0, 0, 0});
9744 
9745     positionData[0]    = Vector3(-1, -1, 0);
9746     positionData[1]    = Vector3(-1, 1, 0);
9747     positionData[2]    = Vector3(0, -1, 0);
9748     positionData[3]    = Vector3(0, 1, 0);
9749     positionData[0xFF] = Vector3(1, -1, 0);
9750     positionData[4]    = Vector3(1, 1, 0);
9751 
9752     constexpr std::array<GLubyte, 6> indices = {0, 1, 2, 3, 0xFF, 4};
9753 
9754     GLBuffer posBuffer;
9755     glBindBuffer(GL_ARRAY_BUFFER, posBuffer);
9756     glBufferData(GL_ARRAY_BUFFER, positionData.size() * sizeof(positionData[0]),
9757                  positionData.data(), GL_STATIC_DRAW);
9758     glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
9759     glEnableVertexAttribArray(posAttrib);
9760 
9761     GLBuffer indexBuffer;
9762     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
9763     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices.data(), GL_STATIC_DRAW);
9764 
9765     const int w = getWindowWidth();
9766     const int h = getWindowHeight();
9767 
9768     glClearColor(0, 0, 0, 1);
9769     glClear(GL_COLOR_BUFFER_BIT);
9770 
9771     glEnable(GL_BLEND);
9772     glBlendFunc(GL_ONE, GL_ONE);
9773 
9774     // Draw red with primitive restart enabled
9775     glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
9776     glUniform4f(colorLoc, 1, 0, 0, 0);
9777     glDrawElements(GL_TRIANGLE_STRIP, 6, GL_UNSIGNED_BYTE, nullptr);
9778 
9779     // Draw green with primitive restart disabled
9780     glDisable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
9781     glUniform4f(colorLoc, 0, 1, 0, 1);
9782     glDrawElements(GL_TRIANGLE_STRIP, 6, GL_UNSIGNED_BYTE, nullptr);
9783 
9784     // Draw blue with primitive restart enabled again
9785     glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
9786     glUniform4f(colorLoc, 0, 0, 1, 0);
9787     glDrawElements(GL_TRIANGLE_STRIP, 6, GL_UNSIGNED_BYTE, nullptr);
9788 
9789     // Verify results
9790     EXPECT_PIXEL_RECT_EQ(0, 0, w / 2 - 1, h, GLColor::white);
9791     EXPECT_PIXEL_RECT_EQ(w / 2 + 1, 0, w / 2 - 1, h, GLColor::green);
9792 
9793     ASSERT_GL_NO_ERROR();
9794 }
9795 
9796 // Tests state change for GL_COLOR_LOGIC_OP and glLogicOp.
TEST_P(StateChangeTestES3,LogicOp)9797 TEST_P(StateChangeTestES3, LogicOp)
9798 {
9799     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_logic_op"));
9800 
9801     constexpr char kVS[] = R"(#version 300 es
9802 precision highp float;
9803 uniform float height;
9804 void main()
9805 {
9806     // gl_VertexID    x    y
9807     //      0        -1   -1
9808     //      1         1   -1
9809     //      2        -1    1
9810     //      3         1    1
9811     int bit0 = gl_VertexID & 1;
9812     int bit1 = gl_VertexID >> 1;
9813     gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, gl_VertexID % 2 == 0 ? -1 : 1, 1);
9814 })";
9815 
9816     constexpr char kFS[] = R"(#version 300 es
9817 precision highp float;
9818 out vec4 colorOut;
9819 uniform vec4 color;
9820 void main()
9821 {
9822     colorOut = color;
9823 })";
9824 
9825     ANGLE_GL_PROGRAM(program, kVS, kFS);
9826     glUseProgram(program);
9827 
9828     GLint colorLoc = glGetUniformLocation(program, "color");
9829     ASSERT_NE(-1, colorLoc);
9830 
9831     glClearColor(0, 0, 0, 1);
9832     glClearDepthf(0);
9833     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
9834 
9835     auto unorm8 = [](uint8_t value) { return (value + 0.1f) / 255.0f; };
9836 
9837     constexpr uint8_t kInitRed   = 0xA4;
9838     constexpr uint8_t kInitGreen = 0x1E;
9839     constexpr uint8_t kInitBlue  = 0x97;
9840     constexpr uint8_t kInitAlpha = 0x65;
9841 
9842     // Initialize with logic op enabled, but using the default GL_COPY op.
9843     glEnable(GL_COLOR_LOGIC_OP_ANGLE);
9844 
9845     glUniform4f(colorLoc, unorm8(kInitRed), unorm8(kInitGreen), unorm8(kInitBlue),
9846                 unorm8(kInitAlpha));
9847     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
9848 
9849     // Set logic op to GL_XOR and draw again.
9850     glLogicOpANGLE(GL_LOGIC_OP_XOR_ANGLE);
9851 
9852     constexpr uint8_t kXorRed   = 0x4C;
9853     constexpr uint8_t kXorGreen = 0x7D;
9854     constexpr uint8_t kXorBlue  = 0xB3;
9855     constexpr uint8_t kXorAlpha = 0x0F;
9856 
9857     glUniform4f(colorLoc, unorm8(kXorRed), unorm8(kXorGreen), unorm8(kXorBlue), unorm8(kXorAlpha));
9858     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
9859 
9860     // Set logic op to GL_INVERT and draw again.
9861     glLogicOpANGLE(GL_LOGIC_OP_INVERT_ANGLE);
9862     glUniform4f(colorLoc, 0.123f, 0.234f, 0.345f, 0.456f);
9863     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
9864 
9865     const int w = getWindowWidth();
9866     const int h = getWindowHeight();
9867 
9868     // Verify results
9869     const GLColor kExpect(static_cast<uint8_t>(~(kInitRed ^ kXorRed)),
9870                           static_cast<uint8_t>(~(kInitGreen ^ kXorGreen)),
9871                           static_cast<uint8_t>(~(kInitBlue ^ kXorBlue)),
9872                           static_cast<uint8_t>(~(kInitAlpha ^ kXorAlpha)));
9873     EXPECT_PIXEL_RECT_EQ(0, 0, w, h, kExpect);
9874 
9875     // Render again with logic op enabled, this time with GL_COPY_INVERTED
9876     glLogicOpANGLE(GL_LOGIC_OP_COPY_INVERTED_ANGLE);
9877     glUniform4f(colorLoc, 0.123f, 0.234f, 0.345f, 0.456f);
9878     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
9879 
9880     // Disable logic op and render again
9881     glDisable(GL_COLOR_LOGIC_OP_ANGLE);
9882     glUniform4f(colorLoc, 0, 1, 0, 1);
9883     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
9884 
9885     EXPECT_PIXEL_RECT_EQ(0, 0, w, h, GLColor::green);
9886     ASSERT_GL_NO_ERROR();
9887 }
9888 
9889 // Test for a bug with the VK_EXT_graphics_pipeline_library implementation in a scenario such as
9890 // this:
9891 //
9892 // - Use blend function A, draw  <-- a new pipeline is created
9893 // - Use blend function B, draw  <-- a new pipeline is created,
9894 //                                   new transition from A to B
9895 // - Switch to program 2
9896 // - Use blend function A, draw  <-- a new pipeline is created
9897 // - Switch to program 1
9898 // -                       draw  <-- the first pipeline is retrieved from cache,
9899 //                                   new transition from B to A
9900 // - Use blend function B, draw  <-- the second pipeline is retrieved from transition
9901 // - Switch to program 3
9902 // -                       draw  <-- a new pipeline is created
9903 //
9904 // With graphics pipeline library, the fragment output partial pipeline changes as follows:
9905 //
9906 // - Use blend function A, draw  <-- a new fragment output pipeline is created
9907 // - Use blend function B, draw  <-- a new fragment output pipeline is created,
9908 //                                   new transition from A to B
9909 // - Switch to program 2
9910 // - Use blend function A, draw  <-- the first fragment output pipeline is retrieved from cache
9911 // - Switch to program 1
9912 // -                       draw  <-- the first monolithic pipeline is retrieved from cache
9913 // - Use blend function B, draw  <-- the second monolithic pipeline is retrieved from transition
9914 // - Switch to program 3
9915 // -                       draw  <-- the second fragment output pipeline is retrieved from cache
9916 //
9917 // The bug was that the dirty blend state was discarded when the monolithic pipeline was retrieved
9918 // through the transition graph, and the last draw call used a stale fragment output pipeline (from
9919 // the last draw call with function A)
9920 //
TEST_P(StateChangeTestES3,FragmentOutputStateChangeAfterCachedPipelineTransition)9921 TEST_P(StateChangeTestES3, FragmentOutputStateChangeAfterCachedPipelineTransition)
9922 {
9923     // Program 1
9924     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
9925     // Program 2
9926     ANGLE_GL_PROGRAM(drawColor2, essl3_shaders::vs::Simple(), R"(#version 300 es
9927 precision mediump float;
9928 out vec4 colorOut;
9929 uniform vec4 colorIn;
9930 void main()
9931 {
9932     colorOut = colorIn;
9933 }
9934 )");
9935     // Program 3
9936     ANGLE_GL_PROGRAM(drawGreen, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
9937 
9938     glUseProgram(drawColor2);
9939     GLint color2UniformLocation = glGetUniformLocation(drawColor2, "colorIn");
9940     ASSERT_NE(color2UniformLocation, -1);
9941 
9942     glUseProgram(drawColor);
9943     GLint colorUniformLocation =
9944         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
9945     ASSERT_NE(colorUniformLocation, -1);
9946 
9947     glEnable(GL_BLEND);
9948     glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
9949     glClearColor(0, 0, 0, 0);
9950     glClear(GL_COLOR_BUFFER_BIT);
9951     // Framebuffer color is now (0, 0, 0, 0)
9952 
9953     glUniform4f(colorUniformLocation, 0, 0, 1, 0.25f);
9954     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
9955     // Framebuffer color is now (0, 0, 0.25, 0.25*0.25)
9956 
9957     glBlendFunc(GL_ONE, GL_ONE);
9958     glUniform4f(colorUniformLocation, 0, 0, 0.25, 0.5 - 0.0625);
9959     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
9960     // Framebuffer color is now (0, 0, 0.5, 0.5)
9961 
9962     // Draw with a different program, but same fragment output state.  The fragment output pipeline
9963     // is retrieved from cache.
9964     glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
9965     glUseProgram(drawColor2);
9966     glUniform4f(color2UniformLocation, 1, 0, 0, 0.5);
9967     drawQuad(drawColor2, essl1_shaders::PositionAttrib(), 0.5f);
9968     // Framebuffer color is now (0.5, 0, 0.25, 0.5)
9969 
9970     // Draw with the original program and the first fragment output state, so it's retrieved from
9971     // cache.
9972     glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
9973     glUseProgram(drawColor);
9974     glUniform4f(colorUniformLocation, 0, 0, 0.5, 0.25);
9975     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
9976     // Framebuffer color is now (0.25, 0, 0.25, 0.25+0.25*0.25)
9977 
9978     // Change to the second fragment output state, so it's retrieved through the transition graph.
9979     glBlendFunc(GL_ONE, GL_ONE);
9980     glUniform4f(colorUniformLocation, 0, 0, 0.5, 0.25 - 0.25 * 0.25);
9981     drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0.5f);
9982     // Framebuffer color is now (0.25, 0, 0.75, 0.5)
9983 
9984     // Draw with the third program, not changing the fragment output state.
9985     drawQuad(drawGreen, essl1_shaders::PositionAttrib(), 0.5f);
9986     // Framebuffer color is now (0.25, 1, 0.75, 1)
9987 
9988     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(64, 255, 192, 255), 1);
9989     ASSERT_GL_NO_ERROR();
9990 }
9991 
9992 // Tests a specific case for multiview and queries.
TEST_P(SimpleStateChangeTestES3,MultiviewAndQueries)9993 TEST_P(SimpleStateChangeTestES3, MultiviewAndQueries)
9994 {
9995     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_OVR_multiview"));
9996 
9997     ANGLE_GL_PROGRAM(prog, essl1_shaders::vs::Zero(), essl1_shaders::fs::Red());
9998     glUseProgram(prog);
9999 
10000     const int PRE_QUERY_CNT = 63;
10001 
10002     GLQuery qry;
10003     GLTexture tex;
10004     GLFramebuffer fb;
10005     GLFramebuffer fb2;
10006     glBeginQuery(GL_ANY_SAMPLES_PASSED, qry);
10007     for (int i = 0; i < PRE_QUERY_CNT; i++)
10008     {
10009         glDrawArrays(GL_POINTS, 0, 1);
10010 
10011         GLColor color;
10012         glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &color);
10013     }
10014     glEndQuery(GL_ANY_SAMPLES_PASSED);
10015     glColorMask(GL_TRUE, GL_FALSE, GL_FALSE, GL_FALSE);
10016     glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
10017     glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 2, 2, 2);
10018     glBindFramebuffer(GL_FRAMEBUFFER, fb);
10019     glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0, 0, 2);
10020     glClear(GL_COLOR_BUFFER_BIT);
10021     glBindFramebuffer(GL_FRAMEBUFFER, fb2);
10022     glBeginQuery(GL_ANY_SAMPLES_PASSED, qry);
10023 }
10024 
10025 // Tests a bug related to an ordering of certain commands.
TEST_P(SimpleStateChangeTestES3,ClearQuerySwapClear)10026 TEST_P(SimpleStateChangeTestES3, ClearQuerySwapClear)
10027 {
10028     glClear(GL_COLOR_BUFFER_BIT);
10029     {
10030         GLQuery query;
10031         glBeginQuery(GL_ANY_SAMPLES_PASSED, query);
10032         glEndQuery(GL_ANY_SAMPLES_PASSED);
10033     }
10034     swapBuffers();
10035     glClear(GL_COLOR_BUFFER_BIT);
10036 }
10037 
10038 // Tests a bug around sampler2D swap and uniform locations.
TEST_P(StateChangeTestES3,SamplerSwap)10039 TEST_P(StateChangeTestES3, SamplerSwap)
10040 {
10041     constexpr char kVS[] = R"(#version 300 es
10042 precision highp float;
10043 uniform float height;
10044 void main()
10045 {
10046     // gl_VertexID    x    y
10047     //      0        -1   -1
10048     //      1         1   -1
10049     //      2        -1    1
10050     //      3         1    1
10051     int bit0 = gl_VertexID & 1;
10052     int bit1 = gl_VertexID >> 1;
10053     gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, gl_VertexID % 2 == 0 ? -1 : 1, 1);
10054 })";
10055 
10056     constexpr char kFS1[] = R"(#version 300 es
10057 precision highp float;
10058 uniform sampler2D A;
10059 uniform sampler2D B;
10060 out vec4 colorOut;
10061 void main()
10062 {
10063     float a = texture(A, vec2(0)).x;
10064     float b = texture(B, vec2(0)).x;
10065     colorOut = vec4(a, b, 0, 1);
10066 })";
10067 
10068     constexpr char kFS2[] = R"(#version 300 es
10069 precision highp float;
10070 uniform sampler2D B;
10071 uniform sampler2D A;
10072 const vec2 multiplier = vec2(0.5, 0.5);
10073 out vec4 colorOut;
10074 void main()
10075 {
10076     float a = texture(A, vec2(0)).x;
10077     float b = texture(B, vec2(0)).x;
10078     colorOut = vec4(a, b, 0, 1);
10079 })";
10080 
10081     ANGLE_GL_PROGRAM(prog1, kVS, kFS1);
10082     ANGLE_GL_PROGRAM(prog2, kVS, kFS2);
10083 
10084     const GLColor kColorA(123, 0, 0, 0);
10085     const GLColor kColorB(157, 0, 0, 0);
10086 
10087     GLTexture texA;
10088     glActiveTexture(GL_TEXTURE0);
10089     glBindTexture(GL_TEXTURE_2D, texA);
10090     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
10091     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &kColorA);
10092 
10093     GLTexture texB;
10094     glActiveTexture(GL_TEXTURE1);
10095     glBindTexture(GL_TEXTURE_2D, texB);
10096     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
10097     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &kColorB);
10098     EXPECT_GL_NO_ERROR();
10099 
10100     glUseProgram(prog1);
10101     glUniform1i(glGetUniformLocation(prog1, "A"), 0);
10102     glUniform1i(glGetUniformLocation(prog1, "B"), 1);
10103 
10104     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
10105 
10106     const GLColor kExpect(kColorA.R, kColorB.R, 0, 255);
10107 
10108     EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpect, 1);
10109     ASSERT_GL_NO_ERROR();
10110 
10111     // The same with the second program that has sampler2D (definitions) swapped which should have
10112     // no effect on the result.
10113     glUseProgram(prog2);
10114     glUniform1i(glGetUniformLocation(prog2, "A"), 0);
10115     glUniform1i(glGetUniformLocation(prog2, "B"), 1);
10116 
10117     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
10118 
10119     EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpect, 1);
10120     ASSERT_GL_NO_ERROR();
10121 }
10122 
10123 // Tests a bug around sampler2D reordering and uniform locations.
TEST_P(StateChangeTestES3,SamplerReordering)10124 TEST_P(StateChangeTestES3, SamplerReordering)
10125 {
10126     constexpr char kVS[] = R"(#version 300 es
10127 precision highp float;
10128 uniform float height;
10129 void main()
10130 {
10131     // gl_VertexID    x    y
10132     //      0        -1   -1
10133     //      1         1   -1
10134     //      2        -1    1
10135     //      3         1    1
10136     int bit0 = gl_VertexID & 1;
10137     int bit1 = gl_VertexID >> 1;
10138     gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, gl_VertexID % 2 == 0 ? -1 : 1, 1);
10139 })";
10140 
10141     constexpr char kFS1[] = R"(#version 300 es
10142 precision highp float;
10143 uniform sampler2D A;
10144 uniform sampler2D B;
10145 //uniform vec2 multiplier;
10146 const vec2 multiplier = vec2(0.5, 0.5);
10147 out vec4 colorOut;
10148 void main()
10149 {
10150     float a = texture(A, vec2(0)).x;
10151     float b = texture(B, vec2(0)).x;
10152     colorOut = vec4(vec2(a, b) * multiplier, 0, 1);
10153 })";
10154 
10155     constexpr char kFS2[] = R"(#version 300 es
10156 precision highp float;
10157 uniform sampler2D S;
10158 uniform sampler2D P;
10159 //uniform vec2 multiplier;
10160 const vec2 multiplier = vec2(0.5, 0.5);
10161 out vec4 colorOut;
10162 void main()
10163 {
10164     float a = texture(P, vec2(0)).x;
10165     float b = texture(S, vec2(0)).x;
10166     colorOut = vec4(vec2(a, b) * multiplier, 0, 1);
10167 })";
10168 
10169     constexpr char kFS3[] = R"(#version 300 es
10170 precision highp float;
10171 uniform sampler2D R;
10172 uniform sampler2D S;
10173 //uniform vec2 multiplier;
10174 const vec2 multiplier = vec2(0.5, 0.5);
10175 out vec4 colorOut;
10176 void main()
10177 {
10178     float a = texture(R, vec2(0)).x;
10179     float b = texture(S, vec2(0)).x;
10180     colorOut = vec4(vec2(a, b) * multiplier, 0, 1);
10181 })";
10182 
10183     ANGLE_GL_PROGRAM(prog1, kVS, kFS1);
10184     ANGLE_GL_PROGRAM(prog2, kVS, kFS2);
10185     ANGLE_GL_PROGRAM(prog3, kVS, kFS3);
10186 
10187     const GLColor kColorA(123, 0, 0, 0);
10188     const GLColor kColorB(157, 0, 0, 0);
10189 
10190     GLTexture texA;
10191     glActiveTexture(GL_TEXTURE0);
10192     glBindTexture(GL_TEXTURE_2D, texA);
10193     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
10194     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &kColorA);
10195 
10196     GLTexture texB;
10197     glActiveTexture(GL_TEXTURE1);
10198     glBindTexture(GL_TEXTURE_2D, texB);
10199     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
10200     glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &kColorB);
10201     EXPECT_GL_NO_ERROR();
10202 
10203     glUseProgram(prog1);
10204     glUniform1i(glGetUniformLocation(prog1, "A"), 0);
10205     glUniform1i(glGetUniformLocation(prog1, "B"), 1);
10206 
10207     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
10208 
10209     glUseProgram(prog2);
10210     glUniform1i(glGetUniformLocation(prog2, "S"), 0);
10211     glUniform1i(glGetUniformLocation(prog2, "P"), 1);
10212 
10213     glEnable(GL_BLEND);
10214     glBlendFunc(GL_ONE, GL_ONE);
10215     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
10216 
10217     constexpr float kXMultiplier = 0.5;
10218     constexpr float kYMultiplier = 0.5;
10219 
10220     const GLColor kExpect(static_cast<uint8_t>((kColorA.R + kColorB.R) * kXMultiplier),
10221                           static_cast<uint8_t>((kColorA.R + kColorB.R) * kYMultiplier), 0, 255);
10222 
10223     EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpect, 1);
10224     ASSERT_GL_NO_ERROR();
10225 
10226     // Do the same thing again, but with the second shader having its samplers specified in the
10227     // opposite order.  The difference between kFS2 and kFS3 is that S is now the second
10228     // declaration, and P is renamed to R.  The reason for the rename is that even if the samplers
10229     // get sorted by name, they would still result in the two shaders declaring them in different
10230     // orders.
10231     glDisable(GL_BLEND);
10232 
10233     glUseProgram(prog1);
10234     glUniform1i(glGetUniformLocation(prog1, "A"), 0);
10235     glUniform1i(glGetUniformLocation(prog1, "B"), 1);
10236 
10237     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
10238 
10239     glUseProgram(prog3);
10240     glUniform1i(glGetUniformLocation(prog3, "S"), 0);
10241     glUniform1i(glGetUniformLocation(prog3, "R"), 1);
10242 
10243     glEnable(GL_BLEND);
10244     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
10245 
10246     EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpect, 1);
10247     ASSERT_GL_NO_ERROR();
10248 }
10249 
10250 // Test that switching FBO attachments affects sample coverage
TEST_P(StateChangeTestES3,SampleCoverageFramebufferAttachmentSwitch)10251 TEST_P(StateChangeTestES3, SampleCoverageFramebufferAttachmentSwitch)
10252 {
10253     // Keep this state unchanged during the test
10254     glEnable(GL_SAMPLE_COVERAGE);
10255     glSampleCoverage(0.0f, false);
10256 
10257     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
10258 
10259     GLFramebuffer fbo;
10260     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
10261 
10262     GLRenderbuffer rbo;
10263     glBindRenderbuffer(GL_RENDERBUFFER, rbo);
10264     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 0, GL_RGBA8, 1, 1);
10265 
10266     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
10267     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
10268 
10269     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0);
10270     ASSERT_GL_NO_ERROR();
10271 
10272     // Sample coverage must have no effect
10273     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
10274 
10275     GLRenderbuffer rboMS;
10276     glBindRenderbuffer(GL_RENDERBUFFER, rboMS);
10277     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, 1, 1);
10278 
10279     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rboMS);
10280     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
10281 
10282     glClearColor(1, 0, 0, 1);
10283     glClear(GL_COLOR_BUFFER_BIT);
10284     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0);
10285     ASSERT_GL_NO_ERROR();
10286 
10287     // Use a temporary FBO to resolve
10288     {
10289         GLFramebuffer fboResolve;
10290         glBindFramebuffer(GL_FRAMEBUFFER, fboResolve);
10291 
10292         GLRenderbuffer rboResolve;
10293         glBindRenderbuffer(GL_RENDERBUFFER, rboResolve);
10294         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
10295 
10296         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
10297                                   rboResolve);
10298         ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
10299 
10300         glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
10301         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboResolve);
10302         glBlitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
10303         ASSERT_GL_NO_ERROR();
10304 
10305         // Nothing was drawn because of zero coverage
10306         glBindFramebuffer(GL_READ_FRAMEBUFFER, fboResolve);
10307         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
10308     }
10309 
10310     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
10311 
10312     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
10313     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
10314 
10315     glClearColor(0, 0, 1, 1);
10316     glClear(GL_COLOR_BUFFER_BIT);
10317     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
10318 
10319     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0);
10320     ASSERT_GL_NO_ERROR();
10321 
10322     // Sample coverage must have no effect
10323     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
10324 }
10325 
10326 // Test that switching FBO attachments affects alpha-to-coverage
TEST_P(StateChangeTestES3,AlphaToCoverageFramebufferAttachmentSwitch)10327 TEST_P(StateChangeTestES3, AlphaToCoverageFramebufferAttachmentSwitch)
10328 {
10329     // Keep this state unchanged during the test
10330     glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
10331 
10332     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
10333     glUseProgram(program);
10334     glUniform4f(glGetUniformLocation(program, essl1_shaders::ColorUniform()), 0, 1, 0, 0);
10335 
10336     GLFramebuffer fbo;
10337     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
10338 
10339     GLRenderbuffer rbo;
10340     glBindRenderbuffer(GL_RENDERBUFFER, rbo);
10341     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 0, GL_RGBA8, 1, 1);
10342 
10343     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
10344     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
10345 
10346     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0);
10347     ASSERT_GL_NO_ERROR();
10348 
10349     // A2C must have no effect
10350     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(0, 255, 0, 0));
10351 
10352     GLRenderbuffer rboMS;
10353     glBindRenderbuffer(GL_RENDERBUFFER, rboMS);
10354     glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA8, 1, 1);
10355 
10356     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rboMS);
10357     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
10358 
10359     glClearColor(1, 0, 0, 1);
10360     glClear(GL_COLOR_BUFFER_BIT);
10361     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0);
10362     ASSERT_GL_NO_ERROR();
10363 
10364     // Use a temporary FBO to resolve
10365     {
10366         GLFramebuffer fboResolve;
10367         glBindFramebuffer(GL_FRAMEBUFFER, fboResolve);
10368 
10369         GLRenderbuffer rboResolve;
10370         glBindRenderbuffer(GL_RENDERBUFFER, rboResolve);
10371         glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 1, 1);
10372 
10373         glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
10374                                   rboResolve);
10375         ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
10376 
10377         glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
10378         glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fboResolve);
10379         glBlitFramebuffer(0, 0, 1, 1, 0, 0, 1, 1, GL_COLOR_BUFFER_BIT, GL_NEAREST);
10380         ASSERT_GL_NO_ERROR();
10381 
10382         // Nothing was drawn because of zero alpha
10383         glBindFramebuffer(GL_READ_FRAMEBUFFER, fboResolve);
10384         EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
10385     }
10386 
10387     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
10388 
10389     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
10390     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
10391 
10392     glClearColor(0, 0, 1, 1);
10393     glClear(GL_COLOR_BUFFER_BIT);
10394     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
10395 
10396     drawQuad(program, essl1_shaders::PositionAttrib(), 0.0);
10397     ASSERT_GL_NO_ERROR();
10398 
10399     // A2C must have no effect
10400     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(0, 255, 0, 0));
10401 }
10402 
10403 // Tests state change for sample shading.
TEST_P(StateChangeTestES31,SampleShading)10404 TEST_P(StateChangeTestES31, SampleShading)
10405 {
10406     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_sample_shading"));
10407     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_sample_variables"));
10408 
10409     constexpr GLsizei kSize        = 1;
10410     constexpr GLsizei kSampleCount = 4;
10411 
10412     // Create a single sampled texture and framebuffer for verifying results
10413     GLFramebuffer fbo;
10414     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
10415 
10416     GLTexture texture;
10417     glBindTexture(GL_TEXTURE_2D, texture);
10418     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
10419     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
10420     ASSERT_GL_NO_ERROR();
10421     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
10422 
10423     // Create a multisampled texture and framebuffer.
10424     GLFramebuffer msaaFBO;
10425     glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO);
10426 
10427     GLTexture msaaTexture;
10428     glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, msaaTexture);
10429     glTexStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, kSampleCount, GL_RGBA8, kSize, kSize,
10430                               false);
10431     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE,
10432                            msaaTexture, 0);
10433     ASSERT_GL_NO_ERROR();
10434     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
10435 
10436     // Create a fragment shader whose _resolved_ output is different based on whether sample shading
10437     // is enabled or not, but which doesn't use gl_SampleID (which implicitly enables sample
10438     // shading).
10439     //
10440     // This is done by non-linearly transforming a varying, resulting in a different color average
10441     // based on the location in which the varying is sampled.  The framebuffer is 1x1 and the vertex
10442     // shader outputs the following triangle:
10443     //
10444     //      (-3, 3)
10445     //        |\
10446     //        |  \
10447     //        |    \
10448     //        |      \
10449     //        |        \
10450     //        |          \
10451     //        +-----------+ <----- position evaluates as (1, 1)
10452     //        |       X   | \
10453     //        |  W        |   \
10454     //        |     C     |     \
10455     //        |        Z  |       \
10456     //        |   Y       |         \
10457     //        +-----------+-----------\
10458     //      (-1, -1)                (3, -1)
10459     //
10460     // The varying |gradient| is output as position.  This means that:
10461     //
10462     // - At the center of the pixel (C), the |gradient| value is (0,0)
10463     // - At sample positions W, X, Y and Z, the |gradient| has 0.75 and 0.25 (positive or negative)
10464     //   in its components.  Most importantly, its length^2 (i.e. gradient.gradient) is:
10465     //
10466     //       0.25^2 + 0.75^2 = 0.625
10467     //
10468     // The fragment shader outputs gradient.gradient + (0.1, 0) as color.  Without sample shading,
10469     // this outputs (0.1, 0, 0, 1) in the color.  With sample shading, it outputs
10470     // (0.725, 0.625, 0, 1) (for all samples).  By using additive blending, we can verify that when
10471     // only sample shading state is modified, that sample shading is indeed toggled.
10472     //
10473     constexpr char kVS[] = R"(#version 300 es
10474 
10475 out mediump vec2 gradient;
10476 
10477 void main()
10478 {
10479     vec2 position = vec2(-1, -1);
10480     if (gl_VertexID == 1)
10481         position = vec2(3, -1);
10482     else if (gl_VertexID == 2)
10483         position = vec2(-1, 3);
10484 
10485     gradient = position;
10486     gl_Position = vec4(position, 0, 1);
10487 })";
10488 
10489     constexpr char kFS[] = R"(#version 300 es
10490 
10491 in mediump vec2 gradient;
10492 out mediump vec4 color;
10493 
10494 uniform mediump vec2 offset;
10495 
10496 void main()
10497 {
10498     mediump float len = dot(gradient, gradient);
10499     color = vec4(vec2(len, len) + offset, 0, 1);
10500 })";
10501 
10502     ANGLE_GL_PROGRAM(program, kVS, kFS);
10503     glUseProgram(program);
10504     GLint offsetLoc = glGetUniformLocation(program, "offset");
10505     ASSERT_NE(offsetLoc, -1);
10506 
10507     glClearColor(0, 0, 0, 0);
10508     glClear(GL_COLOR_BUFFER_BIT);
10509 
10510     glEnable(GL_BLEND);
10511     glBlendFunc(GL_ONE, GL_ONE);
10512 
10513     glViewport(0, 0, kSize, kSize);
10514 
10515     // Issue 2 draw calls, with sample shading enabled then disabled.
10516     glUniform2f(offsetLoc, 0.1f, 0);
10517 
10518     glEnable(GL_SAMPLE_SHADING_OES);
10519     glMinSampleShadingOES(1.0f);
10520     glDrawArrays(GL_TRIANGLES, 0, 3);
10521     glDisable(GL_SAMPLE_SHADING_OES);
10522     glDrawArrays(GL_TRIANGLES, 0, 3);
10523 
10524     // Verify results
10525     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
10526     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_LINEAR);
10527     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
10528     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(210, 159, 0, 255), 1);
10529 
10530     // Do the same test in opposite order (sample shading disabled first, then enabled).
10531     glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO);
10532 
10533     glUniform2f(offsetLoc, 0, 0.1f);
10534 
10535     glClear(GL_COLOR_BUFFER_BIT);
10536     glDrawArrays(GL_TRIANGLES, 0, 3);
10537     glEnable(GL_SAMPLE_SHADING_OES);
10538     glDrawArrays(GL_TRIANGLES, 0, 3);
10539 
10540     // Verify results
10541     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
10542     glBlitFramebuffer(0, 0, kSize, kSize, 0, 0, kSize, kSize, GL_COLOR_BUFFER_BIT, GL_LINEAR);
10543     glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
10544     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor(159, 210, 0, 255), 1);
10545 
10546     ASSERT_GL_NO_ERROR();
10547 }
10548 
10549 }  // anonymous namespace
10550 
10551 ANGLE_INSTANTIATE_TEST_ES2(StateChangeTest);
10552 ANGLE_INSTANTIATE_TEST_ES2(LineLoopStateChangeTest);
10553 ANGLE_INSTANTIATE_TEST_ES2(StateChangeRenderTest);
10554 
10555 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(StateChangeTestES3);
10556 ANGLE_INSTANTIATE_TEST_ES3_AND(
10557     StateChangeTestES3,
10558     ES3_VULKAN().disable(Feature::SupportsIndexTypeUint8),
10559     ES3_VULKAN()
10560         .disable(Feature::SupportsExtendedDynamicState)
10561         .disable(Feature::SupportsExtendedDynamicState2),
10562     ES3_VULKAN().disable(Feature::SupportsExtendedDynamicState2),
10563     ES3_VULKAN().disable(Feature::UseVertexInputBindingStrideDynamicState),
10564     ES3_VULKAN().disable(Feature::UsePrimitiveRestartEnableDynamicState));
10565 
10566 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(StateChangeTestES31);
10567 ANGLE_INSTANTIATE_TEST_ES31_AND(
10568     StateChangeTestES31,
10569     ES31_VULKAN().disable(Feature::SupportsIndexTypeUint8),
10570     ES31_VULKAN()
10571         .disable(Feature::SupportsExtendedDynamicState)
10572         .disable(Feature::SupportsExtendedDynamicState2),
10573     ES31_VULKAN().disable(Feature::SupportsExtendedDynamicState2),
10574     ES31_VULKAN().disable(Feature::UseVertexInputBindingStrideDynamicState),
10575     ES31_VULKAN().disable(Feature::UsePrimitiveRestartEnableDynamicState));
10576 
10577 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(StateChangeTestWebGL2);
10578 ANGLE_INSTANTIATE_TEST_COMBINE_1(StateChangeTestWebGL2,
10579                                  StateChangeTestWebGL2Print,
10580                                  testing::Bool(),
10581                                  ANGLE_ALL_TEST_PLATFORMS_ES3);
10582 
10583 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(StateChangeRenderTestES3);
10584 ANGLE_INSTANTIATE_TEST_ES3(StateChangeRenderTestES3);
10585 
10586 ANGLE_INSTANTIATE_TEST_ES2(SimpleStateChangeTest);
10587 
10588 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SimpleStateChangeTestES3);
10589 ANGLE_INSTANTIATE_TEST_ES3_AND(SimpleStateChangeTestES3,
10590                                ES3_VULKAN().enable(Feature::AllocateNonZeroMemory));
10591 
10592 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ImageRespecificationTest);
10593 ANGLE_INSTANTIATE_TEST_ES3(ImageRespecificationTest);
10594 
10595 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SimpleStateChangeTestES31);
10596 ANGLE_INSTANTIATE_TEST_ES31(SimpleStateChangeTestES31);
10597 
10598 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SimpleStateChangeTestComputeES31);
10599 ANGLE_INSTANTIATE_TEST_ES31(SimpleStateChangeTestComputeES31);
10600 
10601 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(SimpleStateChangeTestComputeES31PPO);
10602 ANGLE_INSTANTIATE_TEST_ES31(SimpleStateChangeTestComputeES31PPO);
10603 
10604 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ValidationStateChangeTest);
10605 ANGLE_INSTANTIATE_TEST_ES3(ValidationStateChangeTest);
10606 
10607 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WebGL2ValidationStateChangeTest);
10608 ANGLE_INSTANTIATE_TEST_ES3(WebGL2ValidationStateChangeTest);
10609 
10610 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RobustBufferAccessWebGL2ValidationStateChangeTest);
10611 ANGLE_INSTANTIATE_TEST_ES3(RobustBufferAccessWebGL2ValidationStateChangeTest);
10612 
10613 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ValidationStateChangeTestES31);
10614 ANGLE_INSTANTIATE_TEST_ES31(ValidationStateChangeTestES31);
10615 
10616 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(WebGLComputeValidationStateChangeTest);
10617 ANGLE_INSTANTIATE_TEST_ES31(WebGLComputeValidationStateChangeTest);
10618 
10619 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VertexAttribArrayStateChangeTest);
10620 ANGLE_INSTANTIATE_TEST_ES3(VertexAttribArrayStateChangeTest);
10621