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