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