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 using namespace angle;
10
11 template <typename IndexType, GLenum IndexTypeName>
12 class IndexedPointsTest : public ANGLETest<>
13 {
14 protected:
IndexedPointsTest()15 IndexedPointsTest()
16 {
17 setWindowWidth(128);
18 setWindowHeight(128);
19 setConfigRedBits(8);
20 setConfigGreenBits(8);
21 setConfigBlueBits(8);
22 setConfigAlphaBits(8);
23 setConfigDepthBits(24);
24 }
25
getIndexPositionX(size_t idx)26 float getIndexPositionX(size_t idx) { return (idx == 0 || idx == 3) ? -0.5f : 0.5f; }
27
getIndexPositionY(size_t idx)28 float getIndexPositionY(size_t idx) { return (idx == 2 || idx == 3) ? -0.5f : 0.5f; }
29
testSetUp()30 void testSetUp() override
31 {
32 constexpr char kVS[] = R"(precision highp float;
33 attribute vec2 position;
34
35 void main() {
36 gl_PointSize = 5.0;
37 gl_Position = vec4(position, 0.0, 1.0);
38 })";
39
40 constexpr char kFS[] = R"(precision highp float;
41 void main()
42 {
43 gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
44 })";
45
46 mProgram = CompileProgram(kVS, kFS);
47 ASSERT_NE(0u, mProgram);
48
49 constexpr char kVS2[] = R"(precision highp float;
50 attribute vec2 position;
51 attribute vec4 color;
52 varying vec4 vcolor;
53
54 void main() {
55 gl_PointSize = 5.0;
56 gl_Position = vec4(position, 0.0, 1.0);
57 vcolor = color;
58 })";
59
60 constexpr char kFS2[] = R"(precision highp float;
61 varying vec4 vcolor;
62
63 void main()
64 {
65 gl_FragColor = vec4(vcolor.xyz, 1.0);
66 })";
67
68 mVertexWithColorBufferProgram = CompileProgram(kVS2, kFS2);
69 ASSERT_NE(0u, mVertexWithColorBufferProgram);
70
71 // Construct a vertex buffer of position values and color values
72 // contained in a single structure
73 const float verticesWithColor[] = {
74 getIndexPositionX(0), getIndexPositionY(0), 0.0f, 1.0f, 0.0f,
75 getIndexPositionX(2), getIndexPositionY(2), 0.0f, 1.0f, 0.0f,
76 getIndexPositionX(1), getIndexPositionY(1), 0.0f, 1.0f, 0.0f,
77 getIndexPositionX(3), getIndexPositionY(3), 0.0f, 1.0f, 0.0f,
78 };
79
80 glGenBuffers(1, &mVertexWithColorBuffer);
81 glBindBuffer(GL_ARRAY_BUFFER, mVertexWithColorBuffer);
82 glBufferData(GL_ARRAY_BUFFER, sizeof(verticesWithColor), &verticesWithColor[0],
83 GL_STATIC_DRAW);
84
85 // Construct a vertex buffer of position values only
86 const GLfloat vertices[] = {
87 getIndexPositionX(0), getIndexPositionY(0), getIndexPositionX(2), getIndexPositionY(2),
88 getIndexPositionX(1), getIndexPositionY(1), getIndexPositionX(3), getIndexPositionY(3),
89 };
90 glGenBuffers(1, &mVertexBuffer);
91 glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
92 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), &vertices[0], GL_STATIC_DRAW);
93
94 // The indices buffer is shared between both variations of tests
95 const IndexType indices[] = {0, 2, 1, 3};
96 glGenBuffers(1, &mIndexBuffer);
97 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
98 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), &indices[0], GL_STATIC_DRAW);
99 }
100
testTearDown()101 void testTearDown() override
102 {
103 glDeleteBuffers(1, &mVertexBuffer);
104 glDeleteBuffers(1, &mIndexBuffer);
105 glDeleteProgram(mProgram);
106
107 glDeleteBuffers(1, &mVertexWithColorBuffer);
108 glDeleteProgram(mVertexWithColorBufferProgram);
109 }
110
runTest(GLuint firstIndex,bool useVertexBufferWithColor=false)111 void runTest(GLuint firstIndex, bool useVertexBufferWithColor = false)
112 {
113 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
114 glClear(GL_COLOR_BUFFER_BIT);
115
116 GLint viewportSize[4];
117 glGetIntegerv(GL_VIEWPORT, viewportSize);
118
119 // Choose appropriate program to apply for the test
120 GLuint program = useVertexBufferWithColor ? mVertexWithColorBufferProgram : mProgram;
121
122 if (useVertexBufferWithColor)
123 {
124 glBindBuffer(GL_ARRAY_BUFFER, mVertexWithColorBuffer);
125 GLint vertexLocation = glGetAttribLocation(program, "position");
126 glVertexAttribPointer(vertexLocation, 2, GL_FLOAT, GL_FALSE,
127 static_cast<const GLsizei>(VertexWithColorSize), 0);
128 glEnableVertexAttribArray(vertexLocation);
129
130 GLint vertexColorLocation = glGetAttribLocation(program, "color");
131 glVertexAttribPointer(vertexColorLocation, 3, GL_FLOAT, GL_FALSE,
132 static_cast<const GLsizei>(VertexWithColorSize),
133 (void *)((sizeof(float) * 2)));
134 glEnableVertexAttribArray(vertexColorLocation);
135 }
136 else
137 {
138 glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
139 GLint vertexLocation = glGetAttribLocation(program, "position");
140 glVertexAttribPointer(vertexLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
141 glEnableVertexAttribArray(vertexLocation);
142 }
143
144 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
145 glUseProgram(program);
146
147 glDrawElements(GL_POINTS, mPointCount - firstIndex, IndexTypeName,
148 reinterpret_cast<void *>(firstIndex * sizeof(IndexType)));
149
150 for (size_t i = 0; i < mPointCount; i++)
151 {
152 GLuint x =
153 static_cast<GLuint>(viewportSize[0] + (getIndexPositionX(i) * 0.5f + 0.5f) *
154 (viewportSize[2] - viewportSize[0]));
155 GLuint y =
156 static_cast<GLuint>(viewportSize[1] + (getIndexPositionY(i) * 0.5f + 0.5f) *
157 (viewportSize[3] - viewportSize[1]));
158
159 if (i < firstIndex)
160 {
161 EXPECT_PIXEL_COLOR_EQ(x, y, GLColor::black);
162 }
163 else
164 {
165 if (useVertexBufferWithColor)
166 {
167 EXPECT_PIXEL_COLOR_EQ(x, y, GLColor::green);
168 }
169 else
170 {
171 EXPECT_PIXEL_COLOR_EQ(x, y, GLColor::red);
172 }
173 }
174 }
175 swapBuffers();
176 }
177
178 GLuint mProgram;
179 GLuint mVertexBuffer;
180 GLuint mIndexBuffer;
181
182 GLuint mVertexWithColorBufferProgram;
183 GLuint mVertexWithColorBuffer;
184
185 static const GLuint mPointCount = 4;
186
187 private:
188 const size_t VertexWithColorSize = sizeof(float) * 5;
189 };
190
191 typedef IndexedPointsTest<GLubyte, GL_UNSIGNED_BYTE> IndexedPointsTestUByte;
192
TEST_P(IndexedPointsTestUByte,UnsignedByteOffset0)193 TEST_P(IndexedPointsTestUByte, UnsignedByteOffset0)
194 {
195 runTest(0);
196 }
197
TEST_P(IndexedPointsTestUByte,UnsignedByteOffset1)198 TEST_P(IndexedPointsTestUByte, UnsignedByteOffset1)
199 {
200 runTest(1);
201 }
202
TEST_P(IndexedPointsTestUByte,UnsignedByteOffset2)203 TEST_P(IndexedPointsTestUByte, UnsignedByteOffset2)
204 {
205 runTest(2);
206 }
207
TEST_P(IndexedPointsTestUByte,UnsignedByteOffset3)208 TEST_P(IndexedPointsTestUByte, UnsignedByteOffset3)
209 {
210 runTest(3);
211 }
212
TEST_P(IndexedPointsTestUByte,VertexWithColorUnsignedByteOffset0)213 TEST_P(IndexedPointsTestUByte, VertexWithColorUnsignedByteOffset0)
214 {
215 runTest(0, true);
216 }
217
TEST_P(IndexedPointsTestUByte,VertexWithColorUnsignedByteOffset1)218 TEST_P(IndexedPointsTestUByte, VertexWithColorUnsignedByteOffset1)
219 {
220 runTest(1, true);
221 }
222
TEST_P(IndexedPointsTestUByte,VertexWithColorUnsignedByteOffset2)223 TEST_P(IndexedPointsTestUByte, VertexWithColorUnsignedByteOffset2)
224 {
225 runTest(2, true);
226 }
227
TEST_P(IndexedPointsTestUByte,VertexWithColorUnsignedByteOffset3)228 TEST_P(IndexedPointsTestUByte, VertexWithColorUnsignedByteOffset3)
229 {
230 runTest(3, true);
231 }
232
233 typedef IndexedPointsTest<GLushort, GL_UNSIGNED_SHORT> IndexedPointsTestUShort;
234
TEST_P(IndexedPointsTestUShort,UnsignedShortOffset0)235 TEST_P(IndexedPointsTestUShort, UnsignedShortOffset0)
236 {
237 runTest(0);
238 }
239
TEST_P(IndexedPointsTestUShort,UnsignedShortOffset1)240 TEST_P(IndexedPointsTestUShort, UnsignedShortOffset1)
241 {
242 runTest(1);
243 }
244
TEST_P(IndexedPointsTestUShort,UnsignedShortOffset2)245 TEST_P(IndexedPointsTestUShort, UnsignedShortOffset2)
246 {
247 runTest(2);
248 }
249
TEST_P(IndexedPointsTestUShort,UnsignedShortOffset3)250 TEST_P(IndexedPointsTestUShort, UnsignedShortOffset3)
251 {
252 runTest(3);
253 }
254
TEST_P(IndexedPointsTestUShort,VertexWithColorUnsignedShortOffset0)255 TEST_P(IndexedPointsTestUShort, VertexWithColorUnsignedShortOffset0)
256 {
257 runTest(0, true);
258 }
259
TEST_P(IndexedPointsTestUShort,VertexWithColorUnsignedShortOffset1)260 TEST_P(IndexedPointsTestUShort, VertexWithColorUnsignedShortOffset1)
261 {
262 runTest(1, true);
263 }
264
TEST_P(IndexedPointsTestUShort,VertexWithColorUnsignedShortOffset2)265 TEST_P(IndexedPointsTestUShort, VertexWithColorUnsignedShortOffset2)
266 {
267 runTest(2, true);
268 }
269
TEST_P(IndexedPointsTestUShort,VertexWithColorUnsignedShortOffset3)270 TEST_P(IndexedPointsTestUShort, VertexWithColorUnsignedShortOffset3)
271 {
272 runTest(3, true);
273 }
274
TEST_P(IndexedPointsTestUShort,VertexWithColorUnsignedShortOffsetChangingIndices)275 TEST_P(IndexedPointsTestUShort, VertexWithColorUnsignedShortOffsetChangingIndices)
276 {
277 // TODO(fjhenigman): Figure out why this fails on Ozone Intel.
278 ANGLE_SKIP_TEST_IF(IsOzone() && IsIntel() && IsOpenGLES());
279
280 runTest(3, true);
281 runTest(1, true);
282 runTest(0, true);
283 runTest(2, true);
284 }
285
286 typedef IndexedPointsTest<GLuint, GL_UNSIGNED_INT> IndexedPointsTestUInt;
287
TEST_P(IndexedPointsTestUInt,UnsignedIntOffset0)288 TEST_P(IndexedPointsTestUInt, UnsignedIntOffset0)
289 {
290 if (getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_OES_element_index_uint"))
291 {
292 return;
293 }
294 runTest(0);
295 }
296
TEST_P(IndexedPointsTestUInt,UnsignedIntOffset1)297 TEST_P(IndexedPointsTestUInt, UnsignedIntOffset1)
298 {
299 if (getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_OES_element_index_uint"))
300 {
301 return;
302 }
303 runTest(1);
304 }
305
TEST_P(IndexedPointsTestUInt,UnsignedIntOffset2)306 TEST_P(IndexedPointsTestUInt, UnsignedIntOffset2)
307 {
308 if (getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_OES_element_index_uint"))
309 {
310 return;
311 }
312 runTest(2);
313 }
314
TEST_P(IndexedPointsTestUInt,UnsignedIntOffset3)315 TEST_P(IndexedPointsTestUInt, UnsignedIntOffset3)
316 {
317 if (getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_OES_element_index_uint"))
318 {
319 return;
320 }
321 runTest(3);
322 }
323
TEST_P(IndexedPointsTestUInt,VertexWithColorUnsignedIntOffset0)324 TEST_P(IndexedPointsTestUInt, VertexWithColorUnsignedIntOffset0)
325 {
326 if (getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_OES_element_index_uint"))
327 {
328 return;
329 }
330 runTest(0, true);
331 }
332
TEST_P(IndexedPointsTestUInt,VertexWithColorUnsignedIntOffset1)333 TEST_P(IndexedPointsTestUInt, VertexWithColorUnsignedIntOffset1)
334 {
335 if (getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_OES_element_index_uint"))
336 {
337 return;
338 }
339 runTest(1, true);
340 }
341
TEST_P(IndexedPointsTestUInt,VertexWithColorUnsignedIntOffset2)342 TEST_P(IndexedPointsTestUInt, VertexWithColorUnsignedIntOffset2)
343 {
344 if (getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_OES_element_index_uint"))
345 {
346 return;
347 }
348 runTest(2, true);
349 }
350
TEST_P(IndexedPointsTestUInt,VertexWithColorUnsignedIntOffset3)351 TEST_P(IndexedPointsTestUInt, VertexWithColorUnsignedIntOffset3)
352 {
353 if (getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_OES_element_index_uint"))
354 {
355 return;
356 }
357 runTest(3, true);
358 }
359
360 // TODO(lucferron): Diagnose and fix the UByte tests below for Vulkan.
361 // http://anglebug.com/42261353
362
363 // TODO(geofflang): Figure out why this test fails on Intel OpenGL
364 ANGLE_INSTANTIATE_TEST_ES2(IndexedPointsTestUByte);
365 ANGLE_INSTANTIATE_TEST_ES2(IndexedPointsTestUShort);
366 ANGLE_INSTANTIATE_TEST_ES2(IndexedPointsTestUInt);
367