• 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 
7 #include "test_utils/ANGLETest.h"
8 
9 #include "test_utils/gl_raii.h"
10 
11 using namespace angle;
12 
13 class LineLoopTest : public ANGLETest
14 {
15   protected:
LineLoopTest()16     LineLoopTest()
17     {
18         setWindowWidth(256);
19         setWindowHeight(256);
20         setConfigRedBits(8);
21         setConfigGreenBits(8);
22         setConfigBlueBits(8);
23         setConfigAlphaBits(8);
24     }
25 
testSetUp()26     void testSetUp() override
27     {
28         mProgram = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
29         if (mProgram == 0)
30         {
31             FAIL() << "shader compilation failed.";
32         }
33 
34         mPositionLocation = glGetAttribLocation(mProgram, essl1_shaders::PositionAttrib());
35         mColorLocation    = glGetUniformLocation(mProgram, essl1_shaders::ColorUniform());
36 
37         glBlendFunc(GL_ONE, GL_ONE);
38         glEnable(GL_BLEND);
39         glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
40 
41         ASSERT_GL_NO_ERROR();
42     }
43 
testTearDown()44     void testTearDown() override { glDeleteProgram(mProgram); }
45 
checkPixels()46     void checkPixels()
47     {
48         std::vector<GLubyte> pixels(getWindowWidth() * getWindowHeight() * 4);
49         glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
50                      &pixels[0]);
51 
52         ASSERT_GL_NO_ERROR();
53 
54         for (int y = 0; y < getWindowHeight(); y++)
55         {
56             for (int x = 0; x < getWindowWidth(); x++)
57             {
58                 const GLubyte *pixel = &pixels[0] + ((y * getWindowWidth() + x) * 4);
59 
60                 EXPECT_EQ(pixel[0], 0);
61                 EXPECT_EQ(pixel[1], pixel[2]);
62                 ASSERT_EQ(pixel[3], 255);
63             }
64         }
65     }
66 
runTest(GLenum indexType,GLuint indexBuffer,const void * indexPtr)67     void runTest(GLenum indexType, GLuint indexBuffer, const void *indexPtr)
68     {
69         glClear(GL_COLOR_BUFFER_BIT);
70 
71         static const GLfloat loopPositions[] = {0.0f,  0.0f, 0.0f, 0.0f, 0.0f, 0.0f,  0.0f,
72                                                 0.0f,  0.0f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f,
73                                                 -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f};
74 
75         static const GLfloat stripPositions[] = {-0.5f, -0.5f, -0.5f, 0.5f,
76                                                  0.5f,  0.5f,  0.5f,  -0.5f};
77         static const GLubyte stripIndices[]   = {1, 0, 3, 2, 1};
78 
79         glUseProgram(mProgram);
80         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
81         glEnableVertexAttribArray(mPositionLocation);
82         glVertexAttribPointer(mPositionLocation, 2, GL_FLOAT, GL_FALSE, 0, loopPositions);
83         glUniform4f(mColorLocation, 0.0f, 0.0f, 1.0f, 1.0f);
84         glDrawElements(GL_LINE_LOOP, 4, indexType, indexPtr);
85 
86         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
87         glVertexAttribPointer(mPositionLocation, 2, GL_FLOAT, GL_FALSE, 0, stripPositions);
88         glUniform4f(mColorLocation, 0, 1, 0, 1);
89         glDrawElements(GL_LINE_STRIP, 5, GL_UNSIGNED_BYTE, stripIndices);
90 
91         checkPixels();
92     }
93 
94     GLuint mProgram;
95     GLint mPositionLocation;
96     GLint mColorLocation;
97 };
98 
TEST_P(LineLoopTest,LineLoopUByteIndices)99 TEST_P(LineLoopTest, LineLoopUByteIndices)
100 {
101     // Disable D3D11 SDK Layers warnings checks, see ANGLE issue 667 for details
102     // On Win7, the D3D SDK Layers emits a false warning for these tests.
103     // This doesn't occur on Windows 10 (Version 1511) though.
104     ignoreD3D11SDKLayersWarnings();
105 
106     static const GLubyte indices[] = {0, 7, 6, 9, 8, 0};
107     runTest(GL_UNSIGNED_BYTE, 0, indices + 1);
108 }
109 
TEST_P(LineLoopTest,LineLoopUShortIndices)110 TEST_P(LineLoopTest, LineLoopUShortIndices)
111 {
112     // Disable D3D11 SDK Layers warnings checks, see ANGLE issue 667 for details
113     ignoreD3D11SDKLayersWarnings();
114 
115     static const GLushort indices[] = {0, 7, 6, 9, 8, 0};
116     runTest(GL_UNSIGNED_SHORT, 0, indices + 1);
117 }
118 
TEST_P(LineLoopTest,LineLoopUIntIndices)119 TEST_P(LineLoopTest, LineLoopUIntIndices)
120 {
121     if (!IsGLExtensionEnabled("GL_OES_element_index_uint"))
122     {
123         return;
124     }
125 
126     // Disable D3D11 SDK Layers warnings checks, see ANGLE issue 667 for details
127     ignoreD3D11SDKLayersWarnings();
128 
129     static const GLuint indices[] = {0, 7, 6, 9, 8, 0};
130     runTest(GL_UNSIGNED_INT, 0, indices + 1);
131 }
132 
TEST_P(LineLoopTest,LineLoopUByteIndexBuffer)133 TEST_P(LineLoopTest, LineLoopUByteIndexBuffer)
134 {
135     // Disable D3D11 SDK Layers warnings checks, see ANGLE issue 667 for details
136     ignoreD3D11SDKLayersWarnings();
137 
138     static const GLubyte indices[] = {0, 7, 6, 9, 8, 0};
139 
140     GLuint buf;
141     glGenBuffers(1, &buf);
142     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
143     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
144 
145     runTest(GL_UNSIGNED_BYTE, buf, reinterpret_cast<const void *>(sizeof(GLubyte)));
146 
147     glDeleteBuffers(1, &buf);
148 }
149 
TEST_P(LineLoopTest,LineLoopUShortIndexBuffer)150 TEST_P(LineLoopTest, LineLoopUShortIndexBuffer)
151 {
152     // Disable D3D11 SDK Layers warnings checks, see ANGLE issue 667 for details
153     ignoreD3D11SDKLayersWarnings();
154 
155     static const GLushort indices[] = {0, 7, 6, 9, 8, 0};
156 
157     GLuint buf;
158     glGenBuffers(1, &buf);
159     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
160     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
161 
162     runTest(GL_UNSIGNED_SHORT, buf, reinterpret_cast<const void *>(sizeof(GLushort)));
163 
164     glDeleteBuffers(1, &buf);
165 }
166 
TEST_P(LineLoopTest,LineLoopUIntIndexBuffer)167 TEST_P(LineLoopTest, LineLoopUIntIndexBuffer)
168 {
169     if (!IsGLExtensionEnabled("GL_OES_element_index_uint"))
170     {
171         return;
172     }
173 
174     // Disable D3D11 SDK Layers warnings checks, see ANGLE issue 667 for details
175     ignoreD3D11SDKLayersWarnings();
176 
177     static const GLuint indices[] = {0, 7, 6, 9, 8, 0};
178 
179     GLuint buf;
180     glGenBuffers(1, &buf);
181     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
182     glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
183 
184     runTest(GL_UNSIGNED_INT, buf, reinterpret_cast<const void *>(sizeof(GLuint)));
185 
186     glDeleteBuffers(1, &buf);
187 }
188 
189 // Tests an edge case with a very large line loop element count.
190 // Disabled because it is slow and triggers an internal error.
TEST_P(LineLoopTest,DISABLED_DrawArraysWithLargeCount)191 TEST_P(LineLoopTest, DISABLED_DrawArraysWithLargeCount)
192 {
193     constexpr char kVS[] = "void main() { gl_Position = vec4(0); }";
194     constexpr char kFS[] = "void main() { gl_FragColor = vec4(0, 1, 0, 1); }";
195 
196     ANGLE_GL_PROGRAM(program, kVS, kFS);
197     glUseProgram(program);
198     glDrawArrays(GL_LINE_LOOP, 0, 0x3FFFFFFE);
199     EXPECT_GL_ERROR(GL_OUT_OF_MEMORY);
200 
201     glDrawArrays(GL_LINE_LOOP, 0, 0x1FFFFFFE);
202     EXPECT_GL_NO_ERROR();
203 }
204 
205 class LineLoopIndirectTest : public LineLoopTest
206 {
207   protected:
runTest(GLenum indexType,const void * indices,GLuint indicesSize,GLuint firstIndex)208     void runTest(GLenum indexType, const void *indices, GLuint indicesSize, GLuint firstIndex)
209     {
210         struct DrawCommand
211         {
212             GLuint count;
213             GLuint primCount;
214             GLuint firstIndex;
215             GLint baseVertex;
216             GLuint reservedMustBeZero;
217         };
218 
219         glClear(GL_COLOR_BUFFER_BIT);
220 
221         static const GLfloat loopPositions[] = {0.0f,  0.0f, 0.0f, 0.0f, 0.0f, 0.0f,  0.0f,
222                                                 0.0f,  0.0f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f,
223                                                 -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f};
224 
225         static const GLfloat stripPositions[] = {-0.5f, -0.5f, -0.5f, 0.5f,
226                                                  0.5f,  0.5f,  0.5f,  -0.5f};
227         static const GLubyte stripIndices[]   = {1, 0, 3, 2, 1};
228 
229         glUseProgram(mProgram);
230 
231         GLuint vertexArray = 0;
232         glGenVertexArrays(1, &vertexArray);
233         glBindVertexArray(vertexArray);
234 
235         ASSERT_GL_NO_ERROR();
236 
237         GLuint vertBuffer = 0;
238         glGenBuffers(1, &vertBuffer);
239         glBindBuffer(GL_ARRAY_BUFFER, vertBuffer);
240         glBufferData(GL_ARRAY_BUFFER, sizeof(loopPositions), loopPositions, GL_STATIC_DRAW);
241         glEnableVertexAttribArray(mPositionLocation);
242         glVertexAttribPointer(mPositionLocation, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
243         glUniform4f(mColorLocation, 0.0f, 0.0f, 1.0f, 1.0f);
244 
245         ASSERT_GL_NO_ERROR();
246 
247         GLuint buf;
248         glGenBuffers(1, &buf);
249         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
250         glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesSize, indices, GL_STATIC_DRAW);
251 
252         DrawCommand cmdBuffer = {};
253         cmdBuffer.count       = 4;
254         cmdBuffer.firstIndex  = firstIndex;
255         cmdBuffer.primCount   = 1;
256         GLuint indirectBuf    = 0;
257         glGenBuffers(1, &indirectBuf);
258         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, indirectBuf);
259         glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawCommand), &cmdBuffer, GL_STATIC_DRAW);
260 
261         ASSERT_GL_NO_ERROR();
262 
263         glDrawElementsIndirect(GL_LINE_LOOP, indexType, nullptr);
264         ASSERT_GL_NO_ERROR();
265 
266         glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
267         glDeleteBuffers(1, &indirectBuf);
268 
269         glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
270         glDeleteBuffers(1, &buf);
271 
272         glBindVertexArray(0);
273         glDeleteVertexArrays(1, &vertexArray);
274 
275         glBindBuffer(GL_ARRAY_BUFFER, 0);
276         glDeleteBuffers(1, &vertBuffer);
277 
278         glEnableVertexAttribArray(mPositionLocation);
279         glVertexAttribPointer(mPositionLocation, 2, GL_FLOAT, GL_FALSE, 0, stripPositions);
280         glUniform4f(mColorLocation, 0, 1, 0, 1);
281         glDrawElements(GL_LINE_STRIP, 5, GL_UNSIGNED_BYTE, stripIndices);
282 
283         checkPixels();
284     }
285 };
286 
TEST_P(LineLoopIndirectTest,UByteIndexIndirectBuffer)287 TEST_P(LineLoopIndirectTest, UByteIndexIndirectBuffer)
288 {
289 
290     // Disable D3D11 SDK Layers warnings checks, see ANGLE issue 667 for details
291     ignoreD3D11SDKLayersWarnings();
292 
293     static const GLubyte indices[] = {0, 7, 6, 9, 8, 0};
294 
295     // Start at index 1.
296     runTest(GL_UNSIGNED_BYTE, reinterpret_cast<const void *>(indices), sizeof(indices), 1);
297 }
298 
TEST_P(LineLoopIndirectTest,UShortIndexIndirectBuffer)299 TEST_P(LineLoopIndirectTest, UShortIndexIndirectBuffer)
300 {
301 
302     // Disable D3D11 SDK Layers warnings checks, see ANGLE issue 667 for details
303     ignoreD3D11SDKLayersWarnings();
304 
305     static const GLushort indices[] = {0, 7, 6, 9, 8, 0};
306 
307     // Start at index 1.
308     runTest(GL_UNSIGNED_SHORT, reinterpret_cast<const void *>(indices), sizeof(indices), 1);
309 }
310 
311 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
312 // tests should be run against.
313 ANGLE_INSTANTIATE_TEST_ES2(LineLoopTest);
314 
315 ANGLE_INSTANTIATE_TEST_ES31(LineLoopIndirectTest);
316