xref: /aosp_15_r20/external/angle/src/tests/gl_tests/LineLoopTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker 
7*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.h"
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/gl_raii.h"
10*8975f5c5SAndroid Build Coastguard Worker 
11*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
12*8975f5c5SAndroid Build Coastguard Worker 
13*8975f5c5SAndroid Build Coastguard Worker class LineLoopTest : public ANGLETest<>
14*8975f5c5SAndroid Build Coastguard Worker {
15*8975f5c5SAndroid Build Coastguard Worker   protected:
LineLoopTest()16*8975f5c5SAndroid Build Coastguard Worker     LineLoopTest()
17*8975f5c5SAndroid Build Coastguard Worker     {
18*8975f5c5SAndroid Build Coastguard Worker         setWindowWidth(256);
19*8975f5c5SAndroid Build Coastguard Worker         setWindowHeight(256);
20*8975f5c5SAndroid Build Coastguard Worker         setConfigRedBits(8);
21*8975f5c5SAndroid Build Coastguard Worker         setConfigGreenBits(8);
22*8975f5c5SAndroid Build Coastguard Worker         setConfigBlueBits(8);
23*8975f5c5SAndroid Build Coastguard Worker         setConfigAlphaBits(8);
24*8975f5c5SAndroid Build Coastguard Worker     }
25*8975f5c5SAndroid Build Coastguard Worker 
testSetUp()26*8975f5c5SAndroid Build Coastguard Worker     void testSetUp() override
27*8975f5c5SAndroid Build Coastguard Worker     {
28*8975f5c5SAndroid Build Coastguard Worker         mProgram = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
29*8975f5c5SAndroid Build Coastguard Worker         if (mProgram == 0)
30*8975f5c5SAndroid Build Coastguard Worker         {
31*8975f5c5SAndroid Build Coastguard Worker             FAIL() << "shader compilation failed.";
32*8975f5c5SAndroid Build Coastguard Worker         }
33*8975f5c5SAndroid Build Coastguard Worker 
34*8975f5c5SAndroid Build Coastguard Worker         mPositionLocation = glGetAttribLocation(mProgram, essl1_shaders::PositionAttrib());
35*8975f5c5SAndroid Build Coastguard Worker         mColorLocation    = glGetUniformLocation(mProgram, essl1_shaders::ColorUniform());
36*8975f5c5SAndroid Build Coastguard Worker 
37*8975f5c5SAndroid Build Coastguard Worker         glBlendFunc(GL_ONE, GL_ONE);
38*8975f5c5SAndroid Build Coastguard Worker         glEnable(GL_BLEND);
39*8975f5c5SAndroid Build Coastguard Worker         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
40*8975f5c5SAndroid Build Coastguard Worker 
41*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
42*8975f5c5SAndroid Build Coastguard Worker     }
43*8975f5c5SAndroid Build Coastguard Worker 
testTearDown()44*8975f5c5SAndroid Build Coastguard Worker     void testTearDown() override { glDeleteProgram(mProgram); }
45*8975f5c5SAndroid Build Coastguard Worker 
checkPixels()46*8975f5c5SAndroid Build Coastguard Worker     void checkPixels()
47*8975f5c5SAndroid Build Coastguard Worker     {
48*8975f5c5SAndroid Build Coastguard Worker         std::vector<GLubyte> pixels(getWindowWidth() * getWindowHeight() * 4);
49*8975f5c5SAndroid Build Coastguard Worker         glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
50*8975f5c5SAndroid Build Coastguard Worker                      &pixels[0]);
51*8975f5c5SAndroid Build Coastguard Worker 
52*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
53*8975f5c5SAndroid Build Coastguard Worker 
54*8975f5c5SAndroid Build Coastguard Worker         for (int y = 0; y < getWindowHeight(); y++)
55*8975f5c5SAndroid Build Coastguard Worker         {
56*8975f5c5SAndroid Build Coastguard Worker             for (int x = 0; x < getWindowWidth(); x++)
57*8975f5c5SAndroid Build Coastguard Worker             {
58*8975f5c5SAndroid Build Coastguard Worker                 const GLubyte *pixel = &pixels[0] + ((y * getWindowWidth() + x) * 4);
59*8975f5c5SAndroid Build Coastguard Worker 
60*8975f5c5SAndroid Build Coastguard Worker                 EXPECT_EQ(pixel[0], 0) << "Failed at " << x << ", " << y << std::endl;
61*8975f5c5SAndroid Build Coastguard Worker                 EXPECT_EQ(pixel[1], pixel[2]) << "Failed at " << x << ", " << y << std::endl;
62*8975f5c5SAndroid Build Coastguard Worker                 ASSERT_EQ(pixel[3], 255) << "Failed at " << x << ", " << y << std::endl;
63*8975f5c5SAndroid Build Coastguard Worker             }
64*8975f5c5SAndroid Build Coastguard Worker         }
65*8975f5c5SAndroid Build Coastguard Worker     }
66*8975f5c5SAndroid Build Coastguard Worker 
preTestUpdateBuffer(GLuint framebuffer,GLuint texture,GLuint buffer,GLsizei size)67*8975f5c5SAndroid Build Coastguard Worker     void preTestUpdateBuffer(GLuint framebuffer, GLuint texture, GLuint buffer, GLsizei size)
68*8975f5c5SAndroid Build Coastguard Worker     {
69*8975f5c5SAndroid Build Coastguard Worker         GLsizei uboSize = std::max(size, 16);
70*8975f5c5SAndroid Build Coastguard Worker         const std::vector<uint32_t> initialData((uboSize + 3) / 4, 0x1234567u);
71*8975f5c5SAndroid Build Coastguard Worker 
72*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, texture);
73*8975f5c5SAndroid Build Coastguard Worker         glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
74*8975f5c5SAndroid Build Coastguard Worker 
75*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
76*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture,
77*8975f5c5SAndroid Build Coastguard Worker                                0);
78*8975f5c5SAndroid Build Coastguard Worker 
79*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_UNIFORM_BUFFER, buffer);
80*8975f5c5SAndroid Build Coastguard Worker         glBufferData(GL_UNIFORM_BUFFER, uboSize, initialData.data(), GL_DYNAMIC_DRAW);
81*8975f5c5SAndroid Build Coastguard Worker         glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);
82*8975f5c5SAndroid Build Coastguard Worker 
83*8975f5c5SAndroid Build Coastguard Worker         constexpr char kVerifyUBO[] = R"(#version 300 es
84*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
85*8975f5c5SAndroid Build Coastguard Worker uniform block {
86*8975f5c5SAndroid Build Coastguard Worker     uint data;
87*8975f5c5SAndroid Build Coastguard Worker } ubo;
88*8975f5c5SAndroid Build Coastguard Worker out vec4 colorOut;
89*8975f5c5SAndroid Build Coastguard Worker void main()
90*8975f5c5SAndroid Build Coastguard Worker {
91*8975f5c5SAndroid Build Coastguard Worker     if (ubo.data == 0x1234567u)
92*8975f5c5SAndroid Build Coastguard Worker         colorOut = vec4(0, 1.0, 0, 1.0);
93*8975f5c5SAndroid Build Coastguard Worker     else
94*8975f5c5SAndroid Build Coastguard Worker         colorOut = vec4(1.0, 0, 0, 1.0);
95*8975f5c5SAndroid Build Coastguard Worker })";
96*8975f5c5SAndroid Build Coastguard Worker 
97*8975f5c5SAndroid Build Coastguard Worker         ANGLE_GL_PROGRAM(verifyUbo, essl3_shaders::vs::Simple(), kVerifyUBO);
98*8975f5c5SAndroid Build Coastguard Worker 
99*8975f5c5SAndroid Build Coastguard Worker         glDisable(GL_BLEND);
100*8975f5c5SAndroid Build Coastguard Worker         drawQuad(verifyUbo, essl3_shaders::PositionAttrib(), 0.5);
101*8975f5c5SAndroid Build Coastguard Worker 
102*8975f5c5SAndroid Build Coastguard Worker         EXPECT_GL_NO_ERROR();
103*8975f5c5SAndroid Build Coastguard Worker 
104*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, 0);
105*8975f5c5SAndroid Build Coastguard Worker     }
106*8975f5c5SAndroid Build Coastguard Worker 
runTest(GLenum indexType,GLuint indexBuffer,const void * indexPtr)107*8975f5c5SAndroid Build Coastguard Worker     void runTest(GLenum indexType, GLuint indexBuffer, const void *indexPtr)
108*8975f5c5SAndroid Build Coastguard Worker     {
109*8975f5c5SAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
110*8975f5c5SAndroid Build Coastguard Worker 
111*8975f5c5SAndroid Build Coastguard Worker         static const GLfloat loopPositions[] = {0.0f,  0.0f, 0.0f, 0.0f, 0.0f, 0.0f,  0.0f,
112*8975f5c5SAndroid Build Coastguard Worker                                                 0.0f,  0.0f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f,
113*8975f5c5SAndroid Build Coastguard Worker                                                 -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f};
114*8975f5c5SAndroid Build Coastguard Worker 
115*8975f5c5SAndroid Build Coastguard Worker         static const GLfloat stripPositions[] = {-0.5f, -0.5f, -0.5f, 0.5f,
116*8975f5c5SAndroid Build Coastguard Worker                                                  0.5f,  0.5f,  0.5f,  -0.5f};
117*8975f5c5SAndroid Build Coastguard Worker         static const GLubyte stripIndices[]   = {1, 0, 3, 2, 1};
118*8975f5c5SAndroid Build Coastguard Worker 
119*8975f5c5SAndroid Build Coastguard Worker         glEnable(GL_BLEND);
120*8975f5c5SAndroid Build Coastguard Worker 
121*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(mProgram);
122*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
123*8975f5c5SAndroid Build Coastguard Worker         glEnableVertexAttribArray(mPositionLocation);
124*8975f5c5SAndroid Build Coastguard Worker         glVertexAttribPointer(mPositionLocation, 2, GL_FLOAT, GL_FALSE, 0, loopPositions);
125*8975f5c5SAndroid Build Coastguard Worker         glUniform4f(mColorLocation, 0.0f, 0.0f, 1.0f, 1.0f);
126*8975f5c5SAndroid Build Coastguard Worker         glDrawElements(GL_LINE_LOOP, 4, indexType, indexPtr);
127*8975f5c5SAndroid Build Coastguard Worker 
128*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
129*8975f5c5SAndroid Build Coastguard Worker         glVertexAttribPointer(mPositionLocation, 2, GL_FLOAT, GL_FALSE, 0, stripPositions);
130*8975f5c5SAndroid Build Coastguard Worker         glUniform4f(mColorLocation, 0, 1, 0, 1);
131*8975f5c5SAndroid Build Coastguard Worker         glDrawElements(GL_LINE_STRIP, 5, GL_UNSIGNED_BYTE, stripIndices);
132*8975f5c5SAndroid Build Coastguard Worker 
133*8975f5c5SAndroid Build Coastguard Worker         checkPixels();
134*8975f5c5SAndroid Build Coastguard Worker     }
135*8975f5c5SAndroid Build Coastguard Worker 
136*8975f5c5SAndroid Build Coastguard Worker     GLuint mProgram;
137*8975f5c5SAndroid Build Coastguard Worker     GLint mPositionLocation;
138*8975f5c5SAndroid Build Coastguard Worker     GLint mColorLocation;
139*8975f5c5SAndroid Build Coastguard Worker };
140*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(LineLoopTest,LineLoopUByteIndices)141*8975f5c5SAndroid Build Coastguard Worker TEST_P(LineLoopTest, LineLoopUByteIndices)
142*8975f5c5SAndroid Build Coastguard Worker {
143*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
144*8975f5c5SAndroid Build Coastguard Worker     // On Win7, the D3D SDK Layers emits a false warning for these tests.
145*8975f5c5SAndroid Build Coastguard Worker     // This doesn't occur on Windows 10 (Version 1511) though.
146*8975f5c5SAndroid Build Coastguard Worker     ignoreD3D11SDKLayersWarnings();
147*8975f5c5SAndroid Build Coastguard Worker 
148*8975f5c5SAndroid Build Coastguard Worker     static const GLubyte indices[] = {0, 7, 6, 9, 8, 0};
149*8975f5c5SAndroid Build Coastguard Worker     runTest(GL_UNSIGNED_BYTE, 0, indices + 1);
150*8975f5c5SAndroid Build Coastguard Worker }
151*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(LineLoopTest,LineLoopUShortIndices)152*8975f5c5SAndroid Build Coastguard Worker TEST_P(LineLoopTest, LineLoopUShortIndices)
153*8975f5c5SAndroid Build Coastguard Worker {
154*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
155*8975f5c5SAndroid Build Coastguard Worker     ignoreD3D11SDKLayersWarnings();
156*8975f5c5SAndroid Build Coastguard Worker 
157*8975f5c5SAndroid Build Coastguard Worker     static const GLushort indices[] = {0, 7, 6, 9, 8, 0};
158*8975f5c5SAndroid Build Coastguard Worker     runTest(GL_UNSIGNED_SHORT, 0, indices + 1);
159*8975f5c5SAndroid Build Coastguard Worker }
160*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(LineLoopTest,LineLoopUIntIndices)161*8975f5c5SAndroid Build Coastguard Worker TEST_P(LineLoopTest, LineLoopUIntIndices)
162*8975f5c5SAndroid Build Coastguard Worker {
163*8975f5c5SAndroid Build Coastguard Worker     if (!IsGLExtensionEnabled("GL_OES_element_index_uint"))
164*8975f5c5SAndroid Build Coastguard Worker     {
165*8975f5c5SAndroid Build Coastguard Worker         return;
166*8975f5c5SAndroid Build Coastguard Worker     }
167*8975f5c5SAndroid Build Coastguard Worker 
168*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
169*8975f5c5SAndroid Build Coastguard Worker     ignoreD3D11SDKLayersWarnings();
170*8975f5c5SAndroid Build Coastguard Worker 
171*8975f5c5SAndroid Build Coastguard Worker     static const GLuint indices[] = {0, 7, 6, 9, 8, 0};
172*8975f5c5SAndroid Build Coastguard Worker     runTest(GL_UNSIGNED_INT, 0, indices + 1);
173*8975f5c5SAndroid Build Coastguard Worker }
174*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(LineLoopTest,LineLoopUByteIndexBuffer)175*8975f5c5SAndroid Build Coastguard Worker TEST_P(LineLoopTest, LineLoopUByteIndexBuffer)
176*8975f5c5SAndroid Build Coastguard Worker {
177*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
178*8975f5c5SAndroid Build Coastguard Worker     ignoreD3D11SDKLayersWarnings();
179*8975f5c5SAndroid Build Coastguard Worker 
180*8975f5c5SAndroid Build Coastguard Worker     static const GLubyte indices[] = {0, 7, 6, 9, 8, 0};
181*8975f5c5SAndroid Build Coastguard Worker 
182*8975f5c5SAndroid Build Coastguard Worker     GLBuffer buf;
183*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
184*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
185*8975f5c5SAndroid Build Coastguard Worker 
186*8975f5c5SAndroid Build Coastguard Worker     runTest(GL_UNSIGNED_BYTE, buf, reinterpret_cast<const void *>(sizeof(GLubyte)));
187*8975f5c5SAndroid Build Coastguard Worker }
188*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(LineLoopTest,LineLoopUShortIndexBuffer)189*8975f5c5SAndroid Build Coastguard Worker TEST_P(LineLoopTest, LineLoopUShortIndexBuffer)
190*8975f5c5SAndroid Build Coastguard Worker {
191*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
192*8975f5c5SAndroid Build Coastguard Worker     ignoreD3D11SDKLayersWarnings();
193*8975f5c5SAndroid Build Coastguard Worker 
194*8975f5c5SAndroid Build Coastguard Worker     static const GLushort indices[] = {0, 7, 6, 9, 8, 0};
195*8975f5c5SAndroid Build Coastguard Worker 
196*8975f5c5SAndroid Build Coastguard Worker     GLBuffer buf;
197*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
198*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
199*8975f5c5SAndroid Build Coastguard Worker 
200*8975f5c5SAndroid Build Coastguard Worker     runTest(GL_UNSIGNED_SHORT, buf, reinterpret_cast<const void *>(sizeof(GLushort)));
201*8975f5c5SAndroid Build Coastguard Worker }
202*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(LineLoopTest,LineLoopUIntIndexBuffer)203*8975f5c5SAndroid Build Coastguard Worker TEST_P(LineLoopTest, LineLoopUIntIndexBuffer)
204*8975f5c5SAndroid Build Coastguard Worker {
205*8975f5c5SAndroid Build Coastguard Worker     if (!IsGLExtensionEnabled("GL_OES_element_index_uint"))
206*8975f5c5SAndroid Build Coastguard Worker     {
207*8975f5c5SAndroid Build Coastguard Worker         return;
208*8975f5c5SAndroid Build Coastguard Worker     }
209*8975f5c5SAndroid Build Coastguard Worker 
210*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
211*8975f5c5SAndroid Build Coastguard Worker     ignoreD3D11SDKLayersWarnings();
212*8975f5c5SAndroid Build Coastguard Worker 
213*8975f5c5SAndroid Build Coastguard Worker     static const GLuint indices[] = {0, 7, 6, 9, 8, 0};
214*8975f5c5SAndroid Build Coastguard Worker 
215*8975f5c5SAndroid Build Coastguard Worker     GLBuffer buf;
216*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
217*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
218*8975f5c5SAndroid Build Coastguard Worker 
219*8975f5c5SAndroid Build Coastguard Worker     runTest(GL_UNSIGNED_INT, buf, reinterpret_cast<const void *>(sizeof(GLuint)));
220*8975f5c5SAndroid Build Coastguard Worker }
221*8975f5c5SAndroid Build Coastguard Worker 
222*8975f5c5SAndroid Build Coastguard Worker // Test that drawing elements between line loop arrays using the same array buffer does not result
223*8975f5c5SAndroid Build Coastguard Worker // in incorrect rendering.
TEST_P(LineLoopTest,DrawTriangleElementsBetweenArrays)224*8975f5c5SAndroid Build Coastguard Worker TEST_P(LineLoopTest, DrawTriangleElementsBetweenArrays)
225*8975f5c5SAndroid Build Coastguard Worker {
226*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
227*8975f5c5SAndroid Build Coastguard Worker     ignoreD3D11SDKLayersWarnings();
228*8975f5c5SAndroid Build Coastguard Worker 
229*8975f5c5SAndroid Build Coastguard Worker     static const GLfloat positions[] = {-0.5f, -0.5f, -0.5f, 0.5f,  0.5f,  0.5f,
230*8975f5c5SAndroid Build Coastguard Worker                                         0.5f,  -0.5f, -0.5f, -0.5f, -0.1f, 0.1f,
231*8975f5c5SAndroid Build Coastguard Worker                                         -0.1f, -0.1f, 0.1f,  -0.1f, 0.1f,  0.1f};
232*8975f5c5SAndroid Build Coastguard Worker     static const GLubyte indices[]   = {5, 6, 7, 5, 7, 8};
233*8975f5c5SAndroid Build Coastguard Worker 
234*8975f5c5SAndroid Build Coastguard Worker     GLBuffer arrayBuffer;
235*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer);
236*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);
237*8975f5c5SAndroid Build Coastguard Worker 
238*8975f5c5SAndroid Build Coastguard Worker     GLBuffer indexBuffer;
239*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
240*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
241*8975f5c5SAndroid Build Coastguard Worker 
242*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
243*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(mProgram);
244*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(mPositionLocation);
245*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(mPositionLocation, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
246*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_BLEND);
247*8975f5c5SAndroid Build Coastguard Worker 
248*8975f5c5SAndroid Build Coastguard Worker     glUniform4f(mColorLocation, 0.0f, 0.0f, 1.0f, 1.0f);
249*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_LINE_LOOP, 0, 4);
250*8975f5c5SAndroid Build Coastguard Worker 
251*8975f5c5SAndroid Build Coastguard Worker     glUniform4f(mColorLocation, 0.0f, 0.0f, 0.0f, 1.0f);
252*8975f5c5SAndroid Build Coastguard Worker     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, nullptr);
253*8975f5c5SAndroid Build Coastguard Worker 
254*8975f5c5SAndroid Build Coastguard Worker     glUniform4f(mColorLocation, 0.0f, 1.0f, 0.0f, 1.0f);
255*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_LINE_LOOP, 0, 4);
256*8975f5c5SAndroid Build Coastguard Worker 
257*8975f5c5SAndroid Build Coastguard Worker     checkPixels();
258*8975f5c5SAndroid Build Coastguard Worker }
259*8975f5c5SAndroid Build Coastguard Worker 
260*8975f5c5SAndroid Build Coastguard Worker class LineLoopTestES3 : public LineLoopTest
261*8975f5c5SAndroid Build Coastguard Worker {};
262*8975f5c5SAndroid Build Coastguard Worker 
263*8975f5c5SAndroid Build Coastguard Worker // Test that uploading data to buffer that's in use then using it for line loop elements works.
TEST_P(LineLoopTestES3,UseAsUBOThenUpdateThenLineLoopUByteIndexBuffer)264*8975f5c5SAndroid Build Coastguard Worker TEST_P(LineLoopTestES3, UseAsUBOThenUpdateThenLineLoopUByteIndexBuffer)
265*8975f5c5SAndroid Build Coastguard Worker {
266*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
267*8975f5c5SAndroid Build Coastguard Worker     ignoreD3D11SDKLayersWarnings();
268*8975f5c5SAndroid Build Coastguard Worker 
269*8975f5c5SAndroid Build Coastguard Worker     static const GLubyte indices[] = {0, 7, 6, 9, 8, 0};
270*8975f5c5SAndroid Build Coastguard Worker 
271*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
272*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
273*8975f5c5SAndroid Build Coastguard Worker 
274*8975f5c5SAndroid Build Coastguard Worker     GLBuffer buf;
275*8975f5c5SAndroid Build Coastguard Worker 
276*8975f5c5SAndroid Build Coastguard Worker     preTestUpdateBuffer(framebuffer, texture, buf, sizeof(indices));
277*8975f5c5SAndroid Build Coastguard Worker 
278*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
279*8975f5c5SAndroid Build Coastguard Worker     glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(indices), indices);
280*8975f5c5SAndroid Build Coastguard Worker 
281*8975f5c5SAndroid Build Coastguard Worker     runTest(GL_UNSIGNED_BYTE, buf, reinterpret_cast<const void *>(sizeof(GLubyte)));
282*8975f5c5SAndroid Build Coastguard Worker 
283*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
284*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
285*8975f5c5SAndroid Build Coastguard Worker }
286*8975f5c5SAndroid Build Coastguard Worker 
287*8975f5c5SAndroid Build Coastguard Worker // Test that uploading data to buffer that's in use then using it for line loop elements works.
TEST_P(LineLoopTestES3,UseAsUBOThenUpdateThenLineLoopUShortIndexBuffer)288*8975f5c5SAndroid Build Coastguard Worker TEST_P(LineLoopTestES3, UseAsUBOThenUpdateThenLineLoopUShortIndexBuffer)
289*8975f5c5SAndroid Build Coastguard Worker {
290*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42264370
291*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsVulkan() && IsQualcomm());
292*8975f5c5SAndroid Build Coastguard Worker 
293*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
294*8975f5c5SAndroid Build Coastguard Worker     ignoreD3D11SDKLayersWarnings();
295*8975f5c5SAndroid Build Coastguard Worker 
296*8975f5c5SAndroid Build Coastguard Worker     static const GLushort indices[] = {0, 7, 6, 9, 8, 0};
297*8975f5c5SAndroid Build Coastguard Worker 
298*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
299*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
300*8975f5c5SAndroid Build Coastguard Worker 
301*8975f5c5SAndroid Build Coastguard Worker     GLBuffer buf;
302*8975f5c5SAndroid Build Coastguard Worker 
303*8975f5c5SAndroid Build Coastguard Worker     preTestUpdateBuffer(framebuffer, texture, buf, sizeof(indices));
304*8975f5c5SAndroid Build Coastguard Worker 
305*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
306*8975f5c5SAndroid Build Coastguard Worker     glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(indices), indices);
307*8975f5c5SAndroid Build Coastguard Worker 
308*8975f5c5SAndroid Build Coastguard Worker     runTest(GL_UNSIGNED_SHORT, buf, reinterpret_cast<const void *>(sizeof(GLushort)));
309*8975f5c5SAndroid Build Coastguard Worker 
310*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
311*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
312*8975f5c5SAndroid Build Coastguard Worker }
313*8975f5c5SAndroid Build Coastguard Worker 
314*8975f5c5SAndroid Build Coastguard Worker // Test that uploading data to buffer that's in use then using it for line loop elements works.
TEST_P(LineLoopTestES3,UseAsUBOThenUpdateThenLineLoopUIntIndexBuffer)315*8975f5c5SAndroid Build Coastguard Worker TEST_P(LineLoopTestES3, UseAsUBOThenUpdateThenLineLoopUIntIndexBuffer)
316*8975f5c5SAndroid Build Coastguard Worker {
317*8975f5c5SAndroid Build Coastguard Worker     if (!IsGLExtensionEnabled("GL_OES_element_index_uint"))
318*8975f5c5SAndroid Build Coastguard Worker     {
319*8975f5c5SAndroid Build Coastguard Worker         return;
320*8975f5c5SAndroid Build Coastguard Worker     }
321*8975f5c5SAndroid Build Coastguard Worker 
322*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42264370
323*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsVulkan() && IsQualcomm());
324*8975f5c5SAndroid Build Coastguard Worker 
325*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
326*8975f5c5SAndroid Build Coastguard Worker     ignoreD3D11SDKLayersWarnings();
327*8975f5c5SAndroid Build Coastguard Worker 
328*8975f5c5SAndroid Build Coastguard Worker     static const GLuint indices[] = {0, 7, 6, 9, 8, 0};
329*8975f5c5SAndroid Build Coastguard Worker 
330*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer framebuffer;
331*8975f5c5SAndroid Build Coastguard Worker     GLTexture texture;
332*8975f5c5SAndroid Build Coastguard Worker 
333*8975f5c5SAndroid Build Coastguard Worker     GLBuffer buf;
334*8975f5c5SAndroid Build Coastguard Worker 
335*8975f5c5SAndroid Build Coastguard Worker     preTestUpdateBuffer(framebuffer, texture, buf, sizeof(indices));
336*8975f5c5SAndroid Build Coastguard Worker 
337*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
338*8975f5c5SAndroid Build Coastguard Worker     glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(indices), indices);
339*8975f5c5SAndroid Build Coastguard Worker 
340*8975f5c5SAndroid Build Coastguard Worker     runTest(GL_UNSIGNED_INT, buf, reinterpret_cast<const void *>(sizeof(GLuint)));
341*8975f5c5SAndroid Build Coastguard Worker 
342*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
343*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
344*8975f5c5SAndroid Build Coastguard Worker }
345*8975f5c5SAndroid Build Coastguard Worker 
346*8975f5c5SAndroid Build Coastguard Worker // Tests an edge case with a very large line loop element count.
347*8975f5c5SAndroid Build Coastguard Worker // Disabled because it is slow and triggers an internal error.
TEST_P(LineLoopTest,DISABLED_DrawArraysWithLargeCount)348*8975f5c5SAndroid Build Coastguard Worker TEST_P(LineLoopTest, DISABLED_DrawArraysWithLargeCount)
349*8975f5c5SAndroid Build Coastguard Worker {
350*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVS[] = "void main() { gl_Position = vec4(0); }";
351*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] = "void main() { gl_FragColor = vec4(0, 1, 0, 1); }";
352*8975f5c5SAndroid Build Coastguard Worker 
353*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, kVS, kFS);
354*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
355*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_LINE_LOOP, 0, 0x3FFFFFFE);
356*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_ERROR(GL_OUT_OF_MEMORY);
357*8975f5c5SAndroid Build Coastguard Worker 
358*8975f5c5SAndroid Build Coastguard Worker     glDrawArrays(GL_LINE_LOOP, 0, 0x1FFFFFFE);
359*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
360*8975f5c5SAndroid Build Coastguard Worker }
361*8975f5c5SAndroid Build Coastguard Worker 
362*8975f5c5SAndroid Build Coastguard Worker class LineLoopPrimitiveRestartTest : public ANGLETest<>
363*8975f5c5SAndroid Build Coastguard Worker {
364*8975f5c5SAndroid Build Coastguard Worker   protected:
LineLoopPrimitiveRestartTest()365*8975f5c5SAndroid Build Coastguard Worker     LineLoopPrimitiveRestartTest()
366*8975f5c5SAndroid Build Coastguard Worker     {
367*8975f5c5SAndroid Build Coastguard Worker         setWindowWidth(64);
368*8975f5c5SAndroid Build Coastguard Worker         setWindowHeight(64);
369*8975f5c5SAndroid Build Coastguard Worker         setConfigRedBits(8);
370*8975f5c5SAndroid Build Coastguard Worker         setConfigGreenBits(8);
371*8975f5c5SAndroid Build Coastguard Worker         setConfigBlueBits(8);
372*8975f5c5SAndroid Build Coastguard Worker         setConfigAlphaBits(8);
373*8975f5c5SAndroid Build Coastguard Worker     }
374*8975f5c5SAndroid Build Coastguard Worker };
375*8975f5c5SAndroid Build Coastguard Worker 
TEST_P(LineLoopPrimitiveRestartTest,LineLoopWithPrimitiveRestart)376*8975f5c5SAndroid Build Coastguard Worker TEST_P(LineLoopPrimitiveRestartTest, LineLoopWithPrimitiveRestart)
377*8975f5c5SAndroid Build Coastguard Worker {
378*8975f5c5SAndroid Build Coastguard Worker     constexpr char kVS[] = R"(#version 300 es
379*8975f5c5SAndroid Build Coastguard Worker in vec2 a_position;
380*8975f5c5SAndroid Build Coastguard Worker // x,y = offset, z = scale
381*8975f5c5SAndroid Build Coastguard Worker in vec3 a_transform;
382*8975f5c5SAndroid Build Coastguard Worker 
383*8975f5c5SAndroid Build Coastguard Worker invariant gl_Position;
384*8975f5c5SAndroid Build Coastguard Worker void main()
385*8975f5c5SAndroid Build Coastguard Worker {
386*8975f5c5SAndroid Build Coastguard Worker     vec2 v_position = a_transform.z * a_position + a_transform.xy;
387*8975f5c5SAndroid Build Coastguard Worker     gl_Position = vec4(v_position, 0.0, 1.0);
388*8975f5c5SAndroid Build Coastguard Worker })";
389*8975f5c5SAndroid Build Coastguard Worker 
390*8975f5c5SAndroid Build Coastguard Worker     constexpr char kFS[] = R"(#version 300 es
391*8975f5c5SAndroid Build Coastguard Worker precision highp float;
392*8975f5c5SAndroid Build Coastguard Worker layout (location=0) out vec4 fragColor;
393*8975f5c5SAndroid Build Coastguard Worker void main()
394*8975f5c5SAndroid Build Coastguard Worker {
395*8975f5c5SAndroid Build Coastguard Worker     fragColor = vec4(1.0, 0.0, 0.0, 1.0);
396*8975f5c5SAndroid Build Coastguard Worker })";
397*8975f5c5SAndroid Build Coastguard Worker 
398*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, kVS, kFS);
399*8975f5c5SAndroid Build Coastguard Worker     glBindAttribLocation(program, 0, "a_position");
400*8975f5c5SAndroid Build Coastguard Worker     glBindAttribLocation(program, 1, "a_transform");
401*8975f5c5SAndroid Build Coastguard Worker     glLinkProgram(program);
402*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
403*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
404*8975f5c5SAndroid Build Coastguard Worker 
405*8975f5c5SAndroid Build Coastguard Worker     // clang-format off
406*8975f5c5SAndroid Build Coastguard Worker     constexpr GLfloat vertices[] = {
407*8975f5c5SAndroid Build Coastguard Worker         0.1, 0.1, -0.1, 0.1, -0.1, -0.1, 0.1, -0.1,
408*8975f5c5SAndroid Build Coastguard Worker         0.1, 0.1, -0.1, 0.1, -0.1, -0.1, 0.1, -0.1,
409*8975f5c5SAndroid Build Coastguard Worker         0.1, 0.1, -0.1, 0.1, -0.1, -0.1, 0.1, -0.1,
410*8975f5c5SAndroid Build Coastguard Worker         0.1, 0.1, -0.1, 0.1, -0.1, -0.1, 0.1, -0.1,
411*8975f5c5SAndroid Build Coastguard Worker     };
412*8975f5c5SAndroid Build Coastguard Worker 
413*8975f5c5SAndroid Build Coastguard Worker     constexpr GLfloat transform[] = {
414*8975f5c5SAndroid Build Coastguard Worker         // first loop transform
415*8975f5c5SAndroid Build Coastguard Worker         0, 0, 9,
416*8975f5c5SAndroid Build Coastguard Worker         0, 0, 9,
417*8975f5c5SAndroid Build Coastguard Worker         0, 0, 9,
418*8975f5c5SAndroid Build Coastguard Worker         0, 0, 9,
419*8975f5c5SAndroid Build Coastguard Worker         // second loop transform
420*8975f5c5SAndroid Build Coastguard Worker         0.2, 0.1, 2,
421*8975f5c5SAndroid Build Coastguard Worker         0.2, 0.1, 2,
422*8975f5c5SAndroid Build Coastguard Worker         0.2, 0.1, 2,
423*8975f5c5SAndroid Build Coastguard Worker         0.2, 0.1, 2,
424*8975f5c5SAndroid Build Coastguard Worker         // third loop transform
425*8975f5c5SAndroid Build Coastguard Worker         0.5, -0.2, 3,
426*8975f5c5SAndroid Build Coastguard Worker         0.5, -0.2, 3,
427*8975f5c5SAndroid Build Coastguard Worker         0.5, -0.2, 3,
428*8975f5c5SAndroid Build Coastguard Worker         0.5, -0.2, 3,
429*8975f5c5SAndroid Build Coastguard Worker         // forth loop transform
430*8975f5c5SAndroid Build Coastguard Worker         -0.8, -0.5, 1,
431*8975f5c5SAndroid Build Coastguard Worker         -0.8, -0.5, 1,
432*8975f5c5SAndroid Build Coastguard Worker         -0.8, -0.5, 1,
433*8975f5c5SAndroid Build Coastguard Worker         -0.8, -0.5, 1,
434*8975f5c5SAndroid Build Coastguard Worker     };
435*8975f5c5SAndroid Build Coastguard Worker 
436*8975f5c5SAndroid Build Coastguard Worker     constexpr GLushort lineloopAsStripIndices[] = {
437*8975f5c5SAndroid Build Coastguard Worker         // first strip
438*8975f5c5SAndroid Build Coastguard Worker         0, 1, 2, 3, 0,
439*8975f5c5SAndroid Build Coastguard Worker         // second strip
440*8975f5c5SAndroid Build Coastguard Worker         4, 5, 6, 7, 4,
441*8975f5c5SAndroid Build Coastguard Worker         // third strip
442*8975f5c5SAndroid Build Coastguard Worker         8, 9, 10, 11, 8,
443*8975f5c5SAndroid Build Coastguard Worker         // forth strip
444*8975f5c5SAndroid Build Coastguard Worker         12, 13, 14, 15, 12 };
445*8975f5c5SAndroid Build Coastguard Worker 
446*8975f5c5SAndroid Build Coastguard Worker     constexpr GLushort lineloopWithRestartIndices[] = {
447*8975f5c5SAndroid Build Coastguard Worker         // first loop
448*8975f5c5SAndroid Build Coastguard Worker         0, 1, 2, 3, 0xffff,
449*8975f5c5SAndroid Build Coastguard Worker         // second loop
450*8975f5c5SAndroid Build Coastguard Worker         4, 5, 6, 7, 0xffff,
451*8975f5c5SAndroid Build Coastguard Worker         // third loop
452*8975f5c5SAndroid Build Coastguard Worker         8, 9, 10, 11, 0xffff,
453*8975f5c5SAndroid Build Coastguard Worker         // forth loop
454*8975f5c5SAndroid Build Coastguard Worker         12, 13, 14, 15,
455*8975f5c5SAndroid Build Coastguard Worker     };
456*8975f5c5SAndroid Build Coastguard Worker     // clang-format on
457*8975f5c5SAndroid Build Coastguard Worker 
458*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLColor> expectedPixels(getWindowWidth() * getWindowHeight());
459*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLColor> renderedPixels(getWindowWidth() * getWindowHeight());
460*8975f5c5SAndroid Build Coastguard Worker 
461*8975f5c5SAndroid Build Coastguard Worker     // Draw in non-primitive restart way
462*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
463*8975f5c5SAndroid Build Coastguard Worker 
464*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(0);
465*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(1);
466*8975f5c5SAndroid Build Coastguard Worker 
467*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, 0);
468*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
469*8975f5c5SAndroid Build Coastguard Worker 
470*8975f5c5SAndroid Build Coastguard Worker     for (int loop = 0; loop < 4; ++loop)
471*8975f5c5SAndroid Build Coastguard Worker     {
472*8975f5c5SAndroid Build Coastguard Worker         glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices + 8 * loop);
473*8975f5c5SAndroid Build Coastguard Worker         glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, transform + 12 * loop);
474*8975f5c5SAndroid Build Coastguard Worker 
475*8975f5c5SAndroid Build Coastguard Worker         glDrawElements(GL_LINE_STRIP, 5, GL_UNSIGNED_SHORT, lineloopAsStripIndices);
476*8975f5c5SAndroid Build Coastguard Worker     }
477*8975f5c5SAndroid Build Coastguard Worker 
478*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
479*8975f5c5SAndroid Build Coastguard Worker                  expectedPixels.data());
480*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
481*8975f5c5SAndroid Build Coastguard Worker 
482*8975f5c5SAndroid Build Coastguard Worker     // Draw line loop with primitive restart:
483*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
484*8975f5c5SAndroid Build Coastguard Worker 
485*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexBuffer[2];
486*8975f5c5SAndroid Build Coastguard Worker     GLBuffer indexBuffer;
487*8975f5c5SAndroid Build Coastguard Worker 
488*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
489*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(lineloopWithRestartIndices),
490*8975f5c5SAndroid Build Coastguard Worker                  lineloopWithRestartIndices, GL_STATIC_DRAW);
491*8975f5c5SAndroid Build Coastguard Worker 
492*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[0]);
493*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
494*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(0);
495*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
496*8975f5c5SAndroid Build Coastguard Worker 
497*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[1]);
498*8975f5c5SAndroid Build Coastguard Worker     glBufferData(GL_ARRAY_BUFFER, sizeof(transform), transform, GL_STATIC_DRAW);
499*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(1);
500*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
501*8975f5c5SAndroid Build Coastguard Worker 
502*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
503*8975f5c5SAndroid Build Coastguard Worker 
504*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
505*8975f5c5SAndroid Build Coastguard Worker     glDrawElements(GL_LINE_LOOP, ArraySize(lineloopWithRestartIndices), GL_UNSIGNED_SHORT, 0);
506*8975f5c5SAndroid Build Coastguard Worker 
507*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
508*8975f5c5SAndroid Build Coastguard Worker                  renderedPixels.data());
509*8975f5c5SAndroid Build Coastguard Worker 
510*8975f5c5SAndroid Build Coastguard Worker     for (int y = 0; y < getWindowHeight(); ++y)
511*8975f5c5SAndroid Build Coastguard Worker     {
512*8975f5c5SAndroid Build Coastguard Worker         for (int x = 0; x < getWindowWidth(); ++x)
513*8975f5c5SAndroid Build Coastguard Worker         {
514*8975f5c5SAndroid Build Coastguard Worker             int idx = y * getWindowWidth() + x;
515*8975f5c5SAndroid Build Coastguard Worker             EXPECT_EQ(expectedPixels[idx], renderedPixels[idx])
516*8975f5c5SAndroid Build Coastguard Worker                 << "Expected pixel at " << x << ", " << y << " to be " << expectedPixels[idx]
517*8975f5c5SAndroid Build Coastguard Worker                 << std::endl;
518*8975f5c5SAndroid Build Coastguard Worker         }
519*8975f5c5SAndroid Build Coastguard Worker     }
520*8975f5c5SAndroid Build Coastguard Worker }
521*8975f5c5SAndroid Build Coastguard Worker 
522*8975f5c5SAndroid Build Coastguard Worker class LineLoopIndirectTest : public LineLoopTest
523*8975f5c5SAndroid Build Coastguard Worker {
524*8975f5c5SAndroid Build Coastguard Worker   protected:
525*8975f5c5SAndroid Build Coastguard Worker     struct DrawCommand
526*8975f5c5SAndroid Build Coastguard Worker     {
527*8975f5c5SAndroid Build Coastguard Worker         GLuint count;
528*8975f5c5SAndroid Build Coastguard Worker         GLuint primCount;
529*8975f5c5SAndroid Build Coastguard Worker         GLuint firstIndex;
530*8975f5c5SAndroid Build Coastguard Worker         GLint baseVertex;
531*8975f5c5SAndroid Build Coastguard Worker         GLuint reservedMustBeZero;
532*8975f5c5SAndroid Build Coastguard Worker     };
533*8975f5c5SAndroid Build Coastguard Worker 
initUpdateBuffers(GLuint vertexArray,GLuint vertexBuffer,GLuint indexBuffer,const void * positions,uint32_t positionsSize,const void * indices,uint32_t indicesSize)534*8975f5c5SAndroid Build Coastguard Worker     void initUpdateBuffers(GLuint vertexArray,
535*8975f5c5SAndroid Build Coastguard Worker                            GLuint vertexBuffer,
536*8975f5c5SAndroid Build Coastguard Worker                            GLuint indexBuffer,
537*8975f5c5SAndroid Build Coastguard Worker                            const void *positions,
538*8975f5c5SAndroid Build Coastguard Worker                            uint32_t positionsSize,
539*8975f5c5SAndroid Build Coastguard Worker                            const void *indices,
540*8975f5c5SAndroid Build Coastguard Worker                            uint32_t indicesSize)
541*8975f5c5SAndroid Build Coastguard Worker     {
542*8975f5c5SAndroid Build Coastguard Worker         glBindVertexArray(vertexArray);
543*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
544*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
545*8975f5c5SAndroid Build Coastguard Worker 
546*8975f5c5SAndroid Build Coastguard Worker         glBufferData(GL_ARRAY_BUFFER, positionsSize, positions, GL_STATIC_DRAW);
547*8975f5c5SAndroid Build Coastguard Worker         glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesSize, indices, GL_STATIC_DRAW);
548*8975f5c5SAndroid Build Coastguard Worker     }
549*8975f5c5SAndroid Build Coastguard Worker 
preTestUBOAndInitUpdateBuffers(GLuint vertexArray,GLuint vertexBuffer,GLuint indexBuffer,const void * positions,GLsizei positionsSize,const void * indices,GLsizei indicesSize,GLuint arrayUpdateFbo,GLuint arrayUpdateTexture,GLuint elementUpdateFbo,GLuint elementUpdateTexture)550*8975f5c5SAndroid Build Coastguard Worker     void preTestUBOAndInitUpdateBuffers(GLuint vertexArray,
551*8975f5c5SAndroid Build Coastguard Worker                                         GLuint vertexBuffer,
552*8975f5c5SAndroid Build Coastguard Worker                                         GLuint indexBuffer,
553*8975f5c5SAndroid Build Coastguard Worker                                         const void *positions,
554*8975f5c5SAndroid Build Coastguard Worker                                         GLsizei positionsSize,
555*8975f5c5SAndroid Build Coastguard Worker                                         const void *indices,
556*8975f5c5SAndroid Build Coastguard Worker                                         GLsizei indicesSize,
557*8975f5c5SAndroid Build Coastguard Worker                                         GLuint arrayUpdateFbo,
558*8975f5c5SAndroid Build Coastguard Worker                                         GLuint arrayUpdateTexture,
559*8975f5c5SAndroid Build Coastguard Worker                                         GLuint elementUpdateFbo,
560*8975f5c5SAndroid Build Coastguard Worker                                         GLuint elementUpdateTexture)
561*8975f5c5SAndroid Build Coastguard Worker     {
562*8975f5c5SAndroid Build Coastguard Worker         preTestUpdateBuffer(arrayUpdateFbo, arrayUpdateTexture, vertexBuffer, positionsSize);
563*8975f5c5SAndroid Build Coastguard Worker         preTestUpdateBuffer(elementUpdateFbo, elementUpdateTexture, indexBuffer, indicesSize);
564*8975f5c5SAndroid Build Coastguard Worker 
565*8975f5c5SAndroid Build Coastguard Worker         glBindVertexArray(vertexArray);
566*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
567*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
568*8975f5c5SAndroid Build Coastguard Worker 
569*8975f5c5SAndroid Build Coastguard Worker         glBufferSubData(GL_ARRAY_BUFFER, 0, positionsSize, positions);
570*8975f5c5SAndroid Build Coastguard Worker         glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, indicesSize, indices);
571*8975f5c5SAndroid Build Coastguard Worker     }
572*8975f5c5SAndroid Build Coastguard Worker 
initIndirectBuffer(GLuint indirectBuffer,GLuint firstIndex)573*8975f5c5SAndroid Build Coastguard Worker     void initIndirectBuffer(GLuint indirectBuffer, GLuint firstIndex)
574*8975f5c5SAndroid Build Coastguard Worker     {
575*8975f5c5SAndroid Build Coastguard Worker         DrawCommand indirectData = {};
576*8975f5c5SAndroid Build Coastguard Worker         indirectData.count       = 4;
577*8975f5c5SAndroid Build Coastguard Worker         indirectData.firstIndex  = firstIndex;
578*8975f5c5SAndroid Build Coastguard Worker         indirectData.primCount   = 1;
579*8975f5c5SAndroid Build Coastguard Worker 
580*8975f5c5SAndroid Build Coastguard Worker         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, indirectBuffer);
581*8975f5c5SAndroid Build Coastguard Worker         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawCommand), &indirectData, GL_STATIC_DRAW);
582*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
583*8975f5c5SAndroid Build Coastguard Worker     }
584*8975f5c5SAndroid Build Coastguard Worker 
setVertexAttribs(const void * positions)585*8975f5c5SAndroid Build Coastguard Worker     void setVertexAttribs(const void *positions)
586*8975f5c5SAndroid Build Coastguard Worker     {
587*8975f5c5SAndroid Build Coastguard Worker         glEnableVertexAttribArray(mPositionLocation);
588*8975f5c5SAndroid Build Coastguard Worker         glVertexAttribPointer(mPositionLocation, 2, GL_FLOAT, GL_FALSE, 0, positions);
589*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
590*8975f5c5SAndroid Build Coastguard Worker     }
591*8975f5c5SAndroid Build Coastguard Worker 
592*8975f5c5SAndroid Build Coastguard Worker     static constexpr GLfloat kLoopPositions[]  = {0.0f,  0.0f, 0.0f, 0.0f, 0.0f, 0.0f,  0.0f,
593*8975f5c5SAndroid Build Coastguard Worker                                                   0.0f,  0.0f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f,
594*8975f5c5SAndroid Build Coastguard Worker                                                   -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f};
595*8975f5c5SAndroid Build Coastguard Worker     static constexpr GLfloat kStripPositions[] = {-0.5f, -0.5f, -0.5f, 0.5f,
596*8975f5c5SAndroid Build Coastguard Worker                                                   0.5f,  0.5f,  0.5f,  -0.5f};
597*8975f5c5SAndroid Build Coastguard Worker     static constexpr GLubyte kStripIndices[]   = {1, 0, 3, 2, 1};
598*8975f5c5SAndroid Build Coastguard Worker };
599*8975f5c5SAndroid Build Coastguard Worker 
600*8975f5c5SAndroid Build Coastguard Worker // Test that drawing a line loop using an index buffer of unsigned bytes works.
TEST_P(LineLoopIndirectTest,UByteIndexIndirectBuffer)601*8975f5c5SAndroid Build Coastguard Worker TEST_P(LineLoopIndirectTest, UByteIndexIndirectBuffer)
602*8975f5c5SAndroid Build Coastguard Worker {
603*8975f5c5SAndroid Build Coastguard Worker     // Old drivers buggy with optimized ConvertIndexIndirectLineLoop shader.
604*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/40096699
605*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsVulkan());
606*8975f5c5SAndroid Build Coastguard Worker 
607*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
608*8975f5c5SAndroid Build Coastguard Worker     ignoreD3D11SDKLayersWarnings();
609*8975f5c5SAndroid Build Coastguard Worker 
610*8975f5c5SAndroid Build Coastguard Worker     // Start at index 1.
611*8975f5c5SAndroid Build Coastguard Worker     GLuint firstIndex       = 1;
612*8975f5c5SAndroid Build Coastguard Worker     const GLubyte indices[] = {0, 7, 6, 9, 8, 0};
613*8975f5c5SAndroid Build Coastguard Worker 
614*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
615*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(mProgram);
616*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
617*8975f5c5SAndroid Build Coastguard Worker 
618*8975f5c5SAndroid Build Coastguard Worker     GLVertexArray vertexArray;
619*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexBuffer;
620*8975f5c5SAndroid Build Coastguard Worker     GLBuffer indexBuffer;
621*8975f5c5SAndroid Build Coastguard Worker 
622*8975f5c5SAndroid Build Coastguard Worker     initUpdateBuffers(vertexArray, vertexBuffer, indexBuffer, kLoopPositions,
623*8975f5c5SAndroid Build Coastguard Worker                       sizeof(kLoopPositions), indices, sizeof(indices));
624*8975f5c5SAndroid Build Coastguard Worker 
625*8975f5c5SAndroid Build Coastguard Worker     GLBuffer indirectBuffer;
626*8975f5c5SAndroid Build Coastguard Worker     initIndirectBuffer(indirectBuffer, firstIndex);
627*8975f5c5SAndroid Build Coastguard Worker 
628*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_BLEND);
629*8975f5c5SAndroid Build Coastguard Worker     setVertexAttribs(nullptr);
630*8975f5c5SAndroid Build Coastguard Worker     glUniform4f(mColorLocation, 0.0f, 0.0f, 1.0f, 1.0f);
631*8975f5c5SAndroid Build Coastguard Worker     glDrawElementsIndirect(GL_LINE_LOOP, GL_UNSIGNED_BYTE, nullptr);
632*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
633*8975f5c5SAndroid Build Coastguard Worker 
634*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
635*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
636*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, 0);
637*8975f5c5SAndroid Build Coastguard Worker     glBindVertexArray(0);
638*8975f5c5SAndroid Build Coastguard Worker 
639*8975f5c5SAndroid Build Coastguard Worker     setVertexAttribs(kStripPositions);
640*8975f5c5SAndroid Build Coastguard Worker     glUniform4f(mColorLocation, 0.0f, 1.0f, 0.0f, 1.0f);
641*8975f5c5SAndroid Build Coastguard Worker     glDrawElements(GL_LINE_STRIP, 5, GL_UNSIGNED_BYTE, kStripIndices);
642*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
643*8975f5c5SAndroid Build Coastguard Worker 
644*8975f5c5SAndroid Build Coastguard Worker     checkPixels();
645*8975f5c5SAndroid Build Coastguard Worker }
646*8975f5c5SAndroid Build Coastguard Worker 
647*8975f5c5SAndroid Build Coastguard Worker // Test that drawing a line loop using an index buffer of unsigned short values works.
TEST_P(LineLoopIndirectTest,UShortIndexIndirectBuffer)648*8975f5c5SAndroid Build Coastguard Worker TEST_P(LineLoopIndirectTest, UShortIndexIndirectBuffer)
649*8975f5c5SAndroid Build Coastguard Worker {
650*8975f5c5SAndroid Build Coastguard Worker     // Old drivers buggy with optimized ConvertIndexIndirectLineLoop shader.
651*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/40096699
652*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsVulkan());
653*8975f5c5SAndroid Build Coastguard Worker 
654*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
655*8975f5c5SAndroid Build Coastguard Worker     ignoreD3D11SDKLayersWarnings();
656*8975f5c5SAndroid Build Coastguard Worker 
657*8975f5c5SAndroid Build Coastguard Worker     // Start at index 1.
658*8975f5c5SAndroid Build Coastguard Worker     GLuint firstIndex        = 1;
659*8975f5c5SAndroid Build Coastguard Worker     const GLushort indices[] = {0, 7, 6, 9, 8, 0};
660*8975f5c5SAndroid Build Coastguard Worker 
661*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
662*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(mProgram);
663*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
664*8975f5c5SAndroid Build Coastguard Worker 
665*8975f5c5SAndroid Build Coastguard Worker     GLVertexArray vertexArray;
666*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexBuffer;
667*8975f5c5SAndroid Build Coastguard Worker     GLBuffer indexBuffer;
668*8975f5c5SAndroid Build Coastguard Worker 
669*8975f5c5SAndroid Build Coastguard Worker     initUpdateBuffers(vertexArray, vertexBuffer, indexBuffer, kLoopPositions,
670*8975f5c5SAndroid Build Coastguard Worker                       sizeof(kLoopPositions), indices, sizeof(indices));
671*8975f5c5SAndroid Build Coastguard Worker 
672*8975f5c5SAndroid Build Coastguard Worker     GLBuffer indirectBuffer;
673*8975f5c5SAndroid Build Coastguard Worker     initIndirectBuffer(indirectBuffer, firstIndex);
674*8975f5c5SAndroid Build Coastguard Worker 
675*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_BLEND);
676*8975f5c5SAndroid Build Coastguard Worker     setVertexAttribs(nullptr);
677*8975f5c5SAndroid Build Coastguard Worker     glUniform4f(mColorLocation, 0.0f, 0.0f, 1.0f, 1.0f);
678*8975f5c5SAndroid Build Coastguard Worker     glDrawElementsIndirect(GL_LINE_LOOP, GL_UNSIGNED_SHORT, nullptr);
679*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
680*8975f5c5SAndroid Build Coastguard Worker 
681*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
682*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
683*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, 0);
684*8975f5c5SAndroid Build Coastguard Worker     glBindVertexArray(0);
685*8975f5c5SAndroid Build Coastguard Worker 
686*8975f5c5SAndroid Build Coastguard Worker     setVertexAttribs(kStripPositions);
687*8975f5c5SAndroid Build Coastguard Worker     glUniform4f(mColorLocation, 0.0f, 1.0f, 0.0f, 1.0f);
688*8975f5c5SAndroid Build Coastguard Worker     glDrawElements(GL_LINE_STRIP, 5, GL_UNSIGNED_BYTE, kStripIndices);
689*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
690*8975f5c5SAndroid Build Coastguard Worker 
691*8975f5c5SAndroid Build Coastguard Worker     checkPixels();
692*8975f5c5SAndroid Build Coastguard Worker }
693*8975f5c5SAndroid Build Coastguard Worker 
694*8975f5c5SAndroid Build Coastguard Worker // Test that uploading data to buffer that's in use then using it for line loop elements works.
TEST_P(LineLoopIndirectTest,UseAsUBOThenUpdateThenUByteIndexIndirectBuffer)695*8975f5c5SAndroid Build Coastguard Worker TEST_P(LineLoopIndirectTest, UseAsUBOThenUpdateThenUByteIndexIndirectBuffer)
696*8975f5c5SAndroid Build Coastguard Worker {
697*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42264370
698*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsVulkan() && IsQualcomm());
699*8975f5c5SAndroid Build Coastguard Worker 
700*8975f5c5SAndroid Build Coastguard Worker     // Old drivers buggy with optimized ConvertIndexIndirectLineLoop shader.
701*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/40096699
702*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsVulkan());
703*8975f5c5SAndroid Build Coastguard Worker 
704*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
705*8975f5c5SAndroid Build Coastguard Worker     ignoreD3D11SDKLayersWarnings();
706*8975f5c5SAndroid Build Coastguard Worker 
707*8975f5c5SAndroid Build Coastguard Worker     // Start at index 1.
708*8975f5c5SAndroid Build Coastguard Worker     GLuint firstIndex       = 1;
709*8975f5c5SAndroid Build Coastguard Worker     const GLubyte indices[] = {0, 7, 6, 9, 8, 0};
710*8975f5c5SAndroid Build Coastguard Worker 
711*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
712*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(mProgram);
713*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
714*8975f5c5SAndroid Build Coastguard Worker 
715*8975f5c5SAndroid Build Coastguard Worker     GLVertexArray vertexArray;
716*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer arrayUpdateFbo, elementUpdateFbo;
717*8975f5c5SAndroid Build Coastguard Worker     GLTexture arrayUpdateTex, elementUpdateTex;
718*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexBuffer;
719*8975f5c5SAndroid Build Coastguard Worker     GLBuffer indexBuffer;
720*8975f5c5SAndroid Build Coastguard Worker 
721*8975f5c5SAndroid Build Coastguard Worker     preTestUBOAndInitUpdateBuffers(vertexArray, vertexBuffer, indexBuffer, kLoopPositions,
722*8975f5c5SAndroid Build Coastguard Worker                                    sizeof(kLoopPositions), indices, sizeof(indices), arrayUpdateFbo,
723*8975f5c5SAndroid Build Coastguard Worker                                    arrayUpdateTex, elementUpdateFbo, elementUpdateTex);
724*8975f5c5SAndroid Build Coastguard Worker 
725*8975f5c5SAndroid Build Coastguard Worker     GLBuffer indirectBuffer;
726*8975f5c5SAndroid Build Coastguard Worker     initIndirectBuffer(indirectBuffer, firstIndex);
727*8975f5c5SAndroid Build Coastguard Worker 
728*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_BLEND);
729*8975f5c5SAndroid Build Coastguard Worker     setVertexAttribs(nullptr);
730*8975f5c5SAndroid Build Coastguard Worker     glUniform4f(mColorLocation, 0.0f, 0.0f, 1.0f, 1.0f);
731*8975f5c5SAndroid Build Coastguard Worker     glDrawElementsIndirect(GL_LINE_LOOP, GL_UNSIGNED_BYTE, nullptr);
732*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
733*8975f5c5SAndroid Build Coastguard Worker 
734*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
735*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
736*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, 0);
737*8975f5c5SAndroid Build Coastguard Worker     glBindVertexArray(0);
738*8975f5c5SAndroid Build Coastguard Worker 
739*8975f5c5SAndroid Build Coastguard Worker     setVertexAttribs(kStripPositions);
740*8975f5c5SAndroid Build Coastguard Worker     glUniform4f(mColorLocation, 0.0f, 1.0f, 0.0f, 1.0f);
741*8975f5c5SAndroid Build Coastguard Worker     glDrawElements(GL_LINE_STRIP, 5, GL_UNSIGNED_BYTE, kStripIndices);
742*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
743*8975f5c5SAndroid Build Coastguard Worker 
744*8975f5c5SAndroid Build Coastguard Worker     checkPixels();
745*8975f5c5SAndroid Build Coastguard Worker 
746*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, arrayUpdateFbo);
747*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
748*8975f5c5SAndroid Build Coastguard Worker 
749*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, elementUpdateFbo);
750*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
751*8975f5c5SAndroid Build Coastguard Worker }
752*8975f5c5SAndroid Build Coastguard Worker 
753*8975f5c5SAndroid Build Coastguard Worker // Test that uploading data to buffer that's in use then using it for line loop elements works.
TEST_P(LineLoopIndirectTest,UseAsUBOThenUpdateThenUShortIndexIndirectBuffer)754*8975f5c5SAndroid Build Coastguard Worker TEST_P(LineLoopIndirectTest, UseAsUBOThenUpdateThenUShortIndexIndirectBuffer)
755*8975f5c5SAndroid Build Coastguard Worker {
756*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42264370
757*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsVulkan() && IsQualcomm());
758*8975f5c5SAndroid Build Coastguard Worker 
759*8975f5c5SAndroid Build Coastguard Worker     // Old drivers buggy with optimized ConvertIndexIndirectLineLoop shader.
760*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/40096699
761*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsVulkan());
762*8975f5c5SAndroid Build Coastguard Worker 
763*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
764*8975f5c5SAndroid Build Coastguard Worker     ignoreD3D11SDKLayersWarnings();
765*8975f5c5SAndroid Build Coastguard Worker 
766*8975f5c5SAndroid Build Coastguard Worker     // Start at index 1.
767*8975f5c5SAndroid Build Coastguard Worker     GLuint firstIndex       = 1;
768*8975f5c5SAndroid Build Coastguard Worker     const GLshort indices[] = {0, 7, 6, 9, 8, 0};
769*8975f5c5SAndroid Build Coastguard Worker 
770*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
771*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(mProgram);
772*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
773*8975f5c5SAndroid Build Coastguard Worker 
774*8975f5c5SAndroid Build Coastguard Worker     GLVertexArray vertexArray;
775*8975f5c5SAndroid Build Coastguard Worker     GLFramebuffer arrayUpdateFbo, elementUpdateFbo;
776*8975f5c5SAndroid Build Coastguard Worker     GLTexture arrayUpdateTex, elementUpdateTex;
777*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexBuffer;
778*8975f5c5SAndroid Build Coastguard Worker     GLBuffer indexBuffer;
779*8975f5c5SAndroid Build Coastguard Worker 
780*8975f5c5SAndroid Build Coastguard Worker     preTestUBOAndInitUpdateBuffers(vertexArray, vertexBuffer, indexBuffer, kLoopPositions,
781*8975f5c5SAndroid Build Coastguard Worker                                    sizeof(kLoopPositions), indices, sizeof(indices), arrayUpdateFbo,
782*8975f5c5SAndroid Build Coastguard Worker                                    arrayUpdateTex, elementUpdateFbo, elementUpdateTex);
783*8975f5c5SAndroid Build Coastguard Worker 
784*8975f5c5SAndroid Build Coastguard Worker     GLBuffer indirectBuffer;
785*8975f5c5SAndroid Build Coastguard Worker     initIndirectBuffer(indirectBuffer, firstIndex);
786*8975f5c5SAndroid Build Coastguard Worker 
787*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_BLEND);
788*8975f5c5SAndroid Build Coastguard Worker     setVertexAttribs(nullptr);
789*8975f5c5SAndroid Build Coastguard Worker     glUniform4f(mColorLocation, 0.0f, 0.0f, 1.0f, 1.0f);
790*8975f5c5SAndroid Build Coastguard Worker     glDrawElementsIndirect(GL_LINE_LOOP, GL_UNSIGNED_SHORT, nullptr);
791*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
792*8975f5c5SAndroid Build Coastguard Worker 
793*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
794*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
795*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, 0);
796*8975f5c5SAndroid Build Coastguard Worker     glBindVertexArray(0);
797*8975f5c5SAndroid Build Coastguard Worker 
798*8975f5c5SAndroid Build Coastguard Worker     setVertexAttribs(kStripPositions);
799*8975f5c5SAndroid Build Coastguard Worker     glUniform4f(mColorLocation, 0.0f, 1.0f, 0.0f, 1.0f);
800*8975f5c5SAndroid Build Coastguard Worker     glDrawElements(GL_LINE_STRIP, 5, GL_UNSIGNED_BYTE, kStripIndices);
801*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
802*8975f5c5SAndroid Build Coastguard Worker 
803*8975f5c5SAndroid Build Coastguard Worker     checkPixels();
804*8975f5c5SAndroid Build Coastguard Worker 
805*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, arrayUpdateFbo);
806*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
807*8975f5c5SAndroid Build Coastguard Worker 
808*8975f5c5SAndroid Build Coastguard Worker     glBindFramebuffer(GL_FRAMEBUFFER, elementUpdateFbo);
809*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
810*8975f5c5SAndroid Build Coastguard Worker }
811*8975f5c5SAndroid Build Coastguard Worker 
812*8975f5c5SAndroid Build Coastguard Worker // Test that two indirect draws drawing lineloop and sharing same index buffer works.
TEST_P(LineLoopIndirectTest,TwoIndirectDrawsShareIndexBuffer)813*8975f5c5SAndroid Build Coastguard Worker TEST_P(LineLoopIndirectTest, TwoIndirectDrawsShareIndexBuffer)
814*8975f5c5SAndroid Build Coastguard Worker {
815*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42264370
816*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsVulkan() && IsQualcomm());
817*8975f5c5SAndroid Build Coastguard Worker 
818*8975f5c5SAndroid Build Coastguard Worker     // Old drivers buggy with optimized ConvertIndexIndirectLineLoop shader.
819*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/40096699
820*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsVulkan());
821*8975f5c5SAndroid Build Coastguard Worker 
822*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
823*8975f5c5SAndroid Build Coastguard Worker     ignoreD3D11SDKLayersWarnings();
824*8975f5c5SAndroid Build Coastguard Worker 
825*8975f5c5SAndroid Build Coastguard Worker     // Start at index 1.
826*8975f5c5SAndroid Build Coastguard Worker     GLuint firstIndex        = 1;
827*8975f5c5SAndroid Build Coastguard Worker     const GLushort indices[] = {0, 7, 6, 9, 8, 0};
828*8975f5c5SAndroid Build Coastguard Worker 
829*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
830*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(mProgram);
831*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
832*8975f5c5SAndroid Build Coastguard Worker 
833*8975f5c5SAndroid Build Coastguard Worker     GLVertexArray vertexArray;
834*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexBuffer;
835*8975f5c5SAndroid Build Coastguard Worker     GLBuffer indexBuffer;
836*8975f5c5SAndroid Build Coastguard Worker 
837*8975f5c5SAndroid Build Coastguard Worker     initUpdateBuffers(vertexArray, vertexBuffer, indexBuffer, kLoopPositions,
838*8975f5c5SAndroid Build Coastguard Worker                       sizeof(kLoopPositions), indices, sizeof(indices));
839*8975f5c5SAndroid Build Coastguard Worker 
840*8975f5c5SAndroid Build Coastguard Worker     GLBuffer indirectBuffer;
841*8975f5c5SAndroid Build Coastguard Worker     initIndirectBuffer(indirectBuffer, firstIndex);
842*8975f5c5SAndroid Build Coastguard Worker 
843*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_BLEND);
844*8975f5c5SAndroid Build Coastguard Worker     setVertexAttribs(nullptr);
845*8975f5c5SAndroid Build Coastguard Worker     glUniform4f(mColorLocation, 0.0f, 0.0f, 1.0f, 1.0f);
846*8975f5c5SAndroid Build Coastguard Worker     glDrawElementsIndirect(GL_LINE_LOOP, GL_UNSIGNED_SHORT, nullptr);
847*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
848*8975f5c5SAndroid Build Coastguard Worker     glDrawElementsIndirect(GL_LINE_LOOP, GL_UNSIGNED_SHORT, nullptr);
849*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
850*8975f5c5SAndroid Build Coastguard Worker 
851*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
852*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
853*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, 0);
854*8975f5c5SAndroid Build Coastguard Worker     glBindVertexArray(0);
855*8975f5c5SAndroid Build Coastguard Worker 
856*8975f5c5SAndroid Build Coastguard Worker     setVertexAttribs(kStripPositions);
857*8975f5c5SAndroid Build Coastguard Worker     glUniform4f(mColorLocation, 0.0f, 1.0f, 0.0f, 1.0f);
858*8975f5c5SAndroid Build Coastguard Worker     glDrawElements(GL_LINE_STRIP, 5, GL_UNSIGNED_BYTE, kStripIndices);
859*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
860*8975f5c5SAndroid Build Coastguard Worker 
861*8975f5c5SAndroid Build Coastguard Worker     checkPixels();
862*8975f5c5SAndroid Build Coastguard Worker }
863*8975f5c5SAndroid Build Coastguard Worker 
864*8975f5c5SAndroid Build Coastguard Worker // Test that one indirect line-loop followed by one non-line-loop draw that share the same index
865*8975f5c5SAndroid Build Coastguard Worker // buffer works.
TEST_P(LineLoopIndirectTest,IndirectAndElementDrawsShareIndexBuffer)866*8975f5c5SAndroid Build Coastguard Worker TEST_P(LineLoopIndirectTest, IndirectAndElementDrawsShareIndexBuffer)
867*8975f5c5SAndroid Build Coastguard Worker {
868*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42264370
869*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsVulkan() && IsQualcomm());
870*8975f5c5SAndroid Build Coastguard Worker 
871*8975f5c5SAndroid Build Coastguard Worker     // Old drivers buggy with optimized ConvertIndexIndirectLineLoop shader.
872*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/40096699
873*8975f5c5SAndroid Build Coastguard Worker     ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsVulkan());
874*8975f5c5SAndroid Build Coastguard Worker 
875*8975f5c5SAndroid Build Coastguard Worker     // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
876*8975f5c5SAndroid Build Coastguard Worker     ignoreD3D11SDKLayersWarnings();
877*8975f5c5SAndroid Build Coastguard Worker 
878*8975f5c5SAndroid Build Coastguard Worker     GLuint firstIndex                    = 10;
879*8975f5c5SAndroid Build Coastguard Worker     static const GLubyte indices[]       = {0, 6, 9, 8, 7, 6, 0, 0, 9, 1, 2, 3, 4, 1, 0};
880*8975f5c5SAndroid Build Coastguard Worker     static const GLfloat loopPositions[] = {0.0f,  0.0f, 0.5f,  0.0f, 0.0f, 0.5f,  -0.5f,
881*8975f5c5SAndroid Build Coastguard Worker                                             0.0f,  0.0f, -0.5f, 0.0f, 0.0f, -0.5f, -0.5f,
882*8975f5c5SAndroid Build Coastguard Worker                                             -0.5f, 0.5f, 0.5f,  0.5f, 0.5f, -0.5f};
883*8975f5c5SAndroid Build Coastguard Worker 
884*8975f5c5SAndroid Build Coastguard Worker     glClear(GL_COLOR_BUFFER_BIT);
885*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(mProgram);
886*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
887*8975f5c5SAndroid Build Coastguard Worker 
888*8975f5c5SAndroid Build Coastguard Worker     GLVertexArray vertexArray;
889*8975f5c5SAndroid Build Coastguard Worker     GLBuffer vertexBuffer;
890*8975f5c5SAndroid Build Coastguard Worker     GLBuffer indexBuffer;
891*8975f5c5SAndroid Build Coastguard Worker 
892*8975f5c5SAndroid Build Coastguard Worker     initUpdateBuffers(vertexArray, vertexBuffer, indexBuffer, loopPositions, sizeof(loopPositions),
893*8975f5c5SAndroid Build Coastguard Worker                       indices, sizeof(indices));
894*8975f5c5SAndroid Build Coastguard Worker 
895*8975f5c5SAndroid Build Coastguard Worker     GLBuffer indirectBuffer;
896*8975f5c5SAndroid Build Coastguard Worker     initIndirectBuffer(indirectBuffer, firstIndex);
897*8975f5c5SAndroid Build Coastguard Worker 
898*8975f5c5SAndroid Build Coastguard Worker     glEnable(GL_BLEND);
899*8975f5c5SAndroid Build Coastguard Worker     setVertexAttribs(nullptr);
900*8975f5c5SAndroid Build Coastguard Worker     glUniform4f(mColorLocation, 1.0f, 0.0f, 1.0f, 1.0f);
901*8975f5c5SAndroid Build Coastguard Worker 
902*8975f5c5SAndroid Build Coastguard Worker     glViewport(0, 0, getWindowWidth() / 2, getWindowHeight());
903*8975f5c5SAndroid Build Coastguard Worker     glDrawElementsIndirect(GL_LINE_LOOP, GL_UNSIGNED_BYTE, nullptr);
904*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
905*8975f5c5SAndroid Build Coastguard Worker 
906*8975f5c5SAndroid Build Coastguard Worker     glViewport(getWindowWidth() / 2, 0, getWindowWidth() / 2, getWindowHeight());
907*8975f5c5SAndroid Build Coastguard Worker     glUniform4f(mColorLocation, 0.0, 1.0, 1.0, 1.0);
908*8975f5c5SAndroid Build Coastguard Worker     glDrawElements(GL_LINE_STRIP, 5, GL_UNSIGNED_BYTE, reinterpret_cast<const void *>(1));
909*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
910*8975f5c5SAndroid Build Coastguard Worker 
911*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
912*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
913*8975f5c5SAndroid Build Coastguard Worker     glBindBuffer(GL_ARRAY_BUFFER, 0);
914*8975f5c5SAndroid Build Coastguard Worker     glBindVertexArray(0);
915*8975f5c5SAndroid Build Coastguard Worker 
916*8975f5c5SAndroid Build Coastguard Worker     // Check pixels.
917*8975f5c5SAndroid Build Coastguard Worker     std::vector<GLubyte> pixels(getWindowWidth() * getWindowHeight() * 4);
918*8975f5c5SAndroid Build Coastguard Worker     glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]);
919*8975f5c5SAndroid Build Coastguard Worker     ASSERT_GL_NO_ERROR();
920*8975f5c5SAndroid Build Coastguard Worker 
921*8975f5c5SAndroid Build Coastguard Worker     for (int y = 0; y < getWindowHeight(); y++)
922*8975f5c5SAndroid Build Coastguard Worker     {
923*8975f5c5SAndroid Build Coastguard Worker         for (int x = 0; x < getWindowWidth() / 2; x++)
924*8975f5c5SAndroid Build Coastguard Worker         {
925*8975f5c5SAndroid Build Coastguard Worker             const GLubyte *pixel = &pixels[0] + ((y * getWindowWidth() + x) * 4);
926*8975f5c5SAndroid Build Coastguard Worker 
927*8975f5c5SAndroid Build Coastguard Worker             EXPECT_TRUE(pixel[0] == pixel[2]) << "Failed at " << x << ", " << y << std::endl;
928*8975f5c5SAndroid Build Coastguard Worker             EXPECT_TRUE(pixel[1] == 0) << "Failed at " << x << ", " << y << std::endl;
929*8975f5c5SAndroid Build Coastguard Worker             ASSERT_EQ(pixel[3], 255) << "Failed at " << x << ", " << y << std::endl;
930*8975f5c5SAndroid Build Coastguard Worker         }
931*8975f5c5SAndroid Build Coastguard Worker         for (int x = getWindowWidth() / 2; x < getWindowWidth(); x++)
932*8975f5c5SAndroid Build Coastguard Worker         {
933*8975f5c5SAndroid Build Coastguard Worker             const GLubyte *pixel = &pixels[0] + ((y * getWindowWidth() + x) * 4);
934*8975f5c5SAndroid Build Coastguard Worker 
935*8975f5c5SAndroid Build Coastguard Worker             EXPECT_TRUE(pixel[0] == 0) << "Failed at " << x << ", " << y << std::endl;
936*8975f5c5SAndroid Build Coastguard Worker             EXPECT_TRUE(pixel[1] == pixel[2]) << "Failed at " << x << ", " << y << std::endl;
937*8975f5c5SAndroid Build Coastguard Worker             ASSERT_EQ(pixel[3], 255) << "Failed at " << x << ", " << y << std::endl;
938*8975f5c5SAndroid Build Coastguard Worker         }
939*8975f5c5SAndroid Build Coastguard Worker     }
940*8975f5c5SAndroid Build Coastguard Worker }
941*8975f5c5SAndroid Build Coastguard Worker 
942*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES2(LineLoopTest);
943*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES3(LineLoopTestES3);
944*8975f5c5SAndroid Build Coastguard Worker 
945*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(LineLoopPrimitiveRestartTest);
946*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES3_AND(
947*8975f5c5SAndroid Build Coastguard Worker     LineLoopPrimitiveRestartTest,
948*8975f5c5SAndroid Build Coastguard Worker     ES3_METAL().enable(Feature::ForceBufferGPUStorage),
949*8975f5c5SAndroid Build Coastguard Worker     ES3_METAL().disable(Feature::HasExplicitMemBarrier).disable(Feature::HasCheapRenderPass));
950*8975f5c5SAndroid Build Coastguard Worker 
951*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(LineLoopIndirectTest);
952*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES31(LineLoopIndirectTest);
953