blob: ee13ca9b7fff42e891aaa658c7d0b4bd291bb322 [file] [log] [blame]
Jamie Madillfa05f602015-05-07 13:47:11 -04001//
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// SimpleOperationTest:
7// Basic GL commands such as linking a program, initializing a buffer, etc.
8
Corentin Wallezd3970de2015-05-14 11:07:48 -04009#include "test_utils/ANGLETest.h"
Geoff Langf1e85922015-02-23 14:40:04 -050010
11#include <vector>
12
Jamie Madillcc6ac252017-01-25 12:57:21 -080013#include "random_utils.h"
14#include "test_utils/gl_raii.h"
15
Jamie Madillfa05f602015-05-07 13:47:11 -040016using namespace angle;
Geoff Langf1e85922015-02-23 14:40:04 -050017
Jamie Madillfa05f602015-05-07 13:47:11 -040018namespace
19{
Luc Ferron22294b02018-02-02 10:03:22 -050020constexpr char kBasicVertexShader[] =
21 R"(attribute vec3 position;
22void main()
23{
24 gl_Position = vec4(position, 1);
25})";
26
27constexpr char kGreenFragmentShader[] =
28 R"(void main()
29{
30 gl_FragColor = vec4(0, 1, 0, 1);
31})";
Jamie Madillfa05f602015-05-07 13:47:11 -040032
Geoff Langf1e85922015-02-23 14:40:04 -050033class SimpleOperationTest : public ANGLETest
34{
35 protected:
Jamie Madillfa05f602015-05-07 13:47:11 -040036 SimpleOperationTest()
Geoff Langf1e85922015-02-23 14:40:04 -050037 {
38 setWindowWidth(128);
39 setWindowHeight(128);
40 setConfigRedBits(8);
41 setConfigGreenBits(8);
42 setConfigBlueBits(8);
43 setConfigAlphaBits(8);
44 }
Jamie Madillcc6ac252017-01-25 12:57:21 -080045
46 void verifyBuffer(const std::vector<uint8_t> &data, GLenum binding);
Geoff Langf1e85922015-02-23 14:40:04 -050047};
48
Jamie Madillcc6ac252017-01-25 12:57:21 -080049void SimpleOperationTest::verifyBuffer(const std::vector<uint8_t> &data, GLenum binding)
50{
51 if (!extensionEnabled("GL_EXT_map_buffer_range"))
52 {
53 return;
54 }
55
56 uint8_t *mapPointer =
57 static_cast<uint8_t *>(glMapBufferRangeEXT(GL_ARRAY_BUFFER, 0, 1024, GL_MAP_READ_BIT));
58 ASSERT_GL_NO_ERROR();
59
60 std::vector<uint8_t> readbackData(data.size());
61 memcpy(readbackData.data(), mapPointer, data.size());
62 glUnmapBufferOES(GL_ARRAY_BUFFER);
63
64 EXPECT_EQ(data, readbackData);
65}
66
Jamie Madillfa05f602015-05-07 13:47:11 -040067TEST_P(SimpleOperationTest, CompileVertexShader)
Geoff Langf1e85922015-02-23 14:40:04 -050068{
Luc Ferron22294b02018-02-02 10:03:22 -050069 GLuint shader = CompileShader(GL_VERTEX_SHADER, kBasicVertexShader);
Geoff Langf1e85922015-02-23 14:40:04 -050070 EXPECT_NE(shader, 0u);
71 glDeleteShader(shader);
72
Luc Ferron22294b02018-02-02 10:03:22 -050073 ASSERT_GL_NO_ERROR();
Geoff Langf1e85922015-02-23 14:40:04 -050074}
75
Luc Ferron22294b02018-02-02 10:03:22 -050076TEST_P(SimpleOperationTest, CompileFragmentShaderSingleVaryingInput)
Geoff Langf1e85922015-02-23 14:40:04 -050077{
Olli Etuahoa20af6d2017-09-18 13:32:29 +030078 const std::string source =
79 R"(precision mediump float;
Geoff Langf1e85922015-02-23 14:40:04 -050080 varying vec4 v_input;
81 void main()
82 {
83 gl_FragColor = v_input;
Olli Etuahoa20af6d2017-09-18 13:32:29 +030084 })";
Geoff Langf1e85922015-02-23 14:40:04 -050085
86 GLuint shader = CompileShader(GL_FRAGMENT_SHADER, source);
87 EXPECT_NE(shader, 0u);
88 glDeleteShader(shader);
89
Luc Ferron22294b02018-02-02 10:03:22 -050090 ASSERT_GL_NO_ERROR();
Geoff Langf1e85922015-02-23 14:40:04 -050091}
Geoff Langb1f435e2015-02-20 10:01:01 -050092
Jamie Madillefb5a5c2018-01-29 15:56:59 -050093// Covers a simple bug in Vulkan to do with dependencies between the Surface and the default
94// Framebuffer.
95TEST_P(SimpleOperationTest, ClearAndSwap)
96{
97 glClearColor(1.0, 0.0, 0.0, 1.0);
98 glClear(GL_COLOR_BUFFER_BIT);
99 swapBuffers();
100
101 // Can't check the pixel result after the swap, and checking the pixel result affects the
102 // behaviour of the test on the Vulkan back-end, so don't bother checking correctness.
Luc Ferron22294b02018-02-02 10:03:22 -0500103 ASSERT_GL_NO_ERROR();
Jamie Madillefb5a5c2018-01-29 15:56:59 -0500104 EXPECT_EGL_SUCCESS();
105}
106
Luc Ferron00155d52018-02-06 10:48:47 -0500107// Simple case of setting a scissor, enabled or disabled.
108TEST_P(SimpleOperationTest, ScissorTest)
109{
110 ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
111
112 glClear(GL_COLOR_BUFFER_BIT);
113 glEnable(GL_SCISSOR_TEST);
114 glScissor(getWindowWidth() / 4, getWindowHeight() / 4, getWindowWidth() / 2,
115 getWindowHeight() / 2);
116
117 // Fill the whole screen with a quad.
118 drawQuad(program.get(), "position", 0.0f, 1.0f, true);
119
120 ASSERT_GL_NO_ERROR();
121
122 // Test outside the scissor test, pitch black.
123 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);
124
125 // Test inside, green of the fragment shader.
126 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::green);
127}
128
Luc Ferron22294b02018-02-02 10:03:22 -0500129TEST_P(SimpleOperationTest, LinkProgramShadersNoInputs)
Geoff Langb1f435e2015-02-20 10:01:01 -0500130{
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300131 const std::string vsSource =
132 R"(void main()
Geoff Langb1f435e2015-02-20 10:01:01 -0500133 {
134 gl_Position = vec4(1.0, 1.0, 1.0, 1.0);
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300135 })";
Geoff Langb1f435e2015-02-20 10:01:01 -0500136
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300137 const std::string fsSource =
138 R"(void main()
Geoff Langb1f435e2015-02-20 10:01:01 -0500139 {
140 gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300141 })";
Geoff Langb1f435e2015-02-20 10:01:01 -0500142
Luc Ferron22294b02018-02-02 10:03:22 -0500143 const GLuint program = CompileProgram(vsSource, fsSource);
Geoff Langb1f435e2015-02-20 10:01:01 -0500144 EXPECT_NE(program, 0u);
145 glDeleteProgram(program);
146
Luc Ferron22294b02018-02-02 10:03:22 -0500147 ASSERT_GL_NO_ERROR();
Geoff Langb1f435e2015-02-20 10:01:01 -0500148}
149
Jamie Madillfa05f602015-05-07 13:47:11 -0400150TEST_P(SimpleOperationTest, LinkProgramWithUniforms)
Geoff Langb1f435e2015-02-20 10:01:01 -0500151{
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300152 const std::string vsSource =
153 R"(void main()
Geoff Langb1f435e2015-02-20 10:01:01 -0500154 {
155 gl_Position = vec4(1.0, 1.0, 1.0, 1.0);
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300156 })";
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300157 const std::string fsSource =
158 R"(precision mediump float;
Geoff Langb1f435e2015-02-20 10:01:01 -0500159 uniform vec4 u_input;
160 void main()
161 {
162 gl_FragColor = u_input;
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300163 })";
Geoff Langb1f435e2015-02-20 10:01:01 -0500164
Luc Ferron22294b02018-02-02 10:03:22 -0500165 const GLuint program = CompileProgram(vsSource, fsSource);
Geoff Langb1f435e2015-02-20 10:01:01 -0500166 EXPECT_NE(program, 0u);
167
Luc Ferron22294b02018-02-02 10:03:22 -0500168 const GLint uniformLoc = glGetUniformLocation(program, "u_input");
Geoff Langb1f435e2015-02-20 10:01:01 -0500169 EXPECT_NE(-1, uniformLoc);
170
171 glDeleteProgram(program);
172
Luc Ferron22294b02018-02-02 10:03:22 -0500173 ASSERT_GL_NO_ERROR();
Geoff Langb1f435e2015-02-20 10:01:01 -0500174}
175
Jamie Madillfa05f602015-05-07 13:47:11 -0400176TEST_P(SimpleOperationTest, LinkProgramWithAttributes)
Geoff Langb1f435e2015-02-20 10:01:01 -0500177{
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300178 const std::string vsSource =
179 R"(attribute vec4 a_input;
Geoff Langb1f435e2015-02-20 10:01:01 -0500180 void main()
181 {
182 gl_Position = a_input;
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300183 })";
Geoff Langb1f435e2015-02-20 10:01:01 -0500184
Luc Ferron22294b02018-02-02 10:03:22 -0500185 const GLuint program = CompileProgram(vsSource, kGreenFragmentShader);
Geoff Langb1f435e2015-02-20 10:01:01 -0500186 EXPECT_NE(program, 0u);
187
Luc Ferron22294b02018-02-02 10:03:22 -0500188 const GLint attribLoc = glGetAttribLocation(program, "a_input");
Geoff Langb1f435e2015-02-20 10:01:01 -0500189 EXPECT_NE(-1, attribLoc);
190
191 glDeleteProgram(program);
192
Luc Ferron22294b02018-02-02 10:03:22 -0500193 ASSERT_GL_NO_ERROR();
Geoff Langb1f435e2015-02-20 10:01:01 -0500194}
Geoff Lang36c79012015-02-24 11:47:20 -0500195
Jamie Madillfa05f602015-05-07 13:47:11 -0400196TEST_P(SimpleOperationTest, BufferDataWithData)
Geoff Lang36c79012015-02-24 11:47:20 -0500197{
Jamie Madillcc6ac252017-01-25 12:57:21 -0800198 GLBuffer buffer;
199 glBindBuffer(GL_ARRAY_BUFFER, buffer.get());
Geoff Lang36c79012015-02-24 11:47:20 -0500200
201 std::vector<uint8_t> data(1024);
Jamie Madillcc6ac252017-01-25 12:57:21 -0800202 FillVectorWithRandomUBytes(&data);
Geoff Lang36c79012015-02-24 11:47:20 -0500203 glBufferData(GL_ARRAY_BUFFER, data.size(), &data[0], GL_STATIC_DRAW);
204
Jamie Madillcc6ac252017-01-25 12:57:21 -0800205 verifyBuffer(data, GL_ARRAY_BUFFER);
Geoff Lang36c79012015-02-24 11:47:20 -0500206
Luc Ferron22294b02018-02-02 10:03:22 -0500207 ASSERT_GL_NO_ERROR();
Geoff Lang36c79012015-02-24 11:47:20 -0500208}
209
Jamie Madillfa05f602015-05-07 13:47:11 -0400210TEST_P(SimpleOperationTest, BufferDataWithNoData)
Geoff Lang36c79012015-02-24 11:47:20 -0500211{
Jamie Madillcc6ac252017-01-25 12:57:21 -0800212 GLBuffer buffer;
213 glBindBuffer(GL_ARRAY_BUFFER, buffer.get());
Geoff Lang36c79012015-02-24 11:47:20 -0500214 glBufferData(GL_ARRAY_BUFFER, 1024, nullptr, GL_STATIC_DRAW);
Geoff Lang36c79012015-02-24 11:47:20 -0500215
Luc Ferron22294b02018-02-02 10:03:22 -0500216 ASSERT_GL_NO_ERROR();
Geoff Lang36c79012015-02-24 11:47:20 -0500217}
218
Jamie Madillfa05f602015-05-07 13:47:11 -0400219TEST_P(SimpleOperationTest, BufferSubData)
Geoff Lang36c79012015-02-24 11:47:20 -0500220{
Jamie Madillcc6ac252017-01-25 12:57:21 -0800221 GLBuffer buffer;
222 glBindBuffer(GL_ARRAY_BUFFER, buffer.get());
Geoff Lang36c79012015-02-24 11:47:20 -0500223
Jamie Madillcc6ac252017-01-25 12:57:21 -0800224 constexpr size_t bufferSize = 1024;
225 std::vector<uint8_t> data(bufferSize);
226 FillVectorWithRandomUBytes(&data);
227
Geoff Lang36c79012015-02-24 11:47:20 -0500228 glBufferData(GL_ARRAY_BUFFER, bufferSize, nullptr, GL_STATIC_DRAW);
229
Jamie Madillcc6ac252017-01-25 12:57:21 -0800230 constexpr size_t subDataCount = 16;
231 constexpr size_t sliceSize = bufferSize / subDataCount;
Geoff Lang36c79012015-02-24 11:47:20 -0500232 for (size_t i = 0; i < subDataCount; i++)
233 {
Jamie Madillcc6ac252017-01-25 12:57:21 -0800234 size_t offset = i * sliceSize;
235 glBufferSubData(GL_ARRAY_BUFFER, offset, sliceSize, &data[offset]);
Geoff Lang36c79012015-02-24 11:47:20 -0500236 }
237
Jamie Madillcc6ac252017-01-25 12:57:21 -0800238 verifyBuffer(data, GL_ARRAY_BUFFER);
Geoff Lang36c79012015-02-24 11:47:20 -0500239
Luc Ferron22294b02018-02-02 10:03:22 -0500240 ASSERT_GL_NO_ERROR();
Geoff Lang36c79012015-02-24 11:47:20 -0500241}
Jamie Madillfa05f602015-05-07 13:47:11 -0400242
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500243// Simple quad test.
244TEST_P(SimpleOperationTest, DrawQuad)
245{
Luc Ferron22294b02018-02-02 10:03:22 -0500246 ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500247
248 drawQuad(program.get(), "position", 0.5f, 1.0f, true);
249
Luc Ferron22294b02018-02-02 10:03:22 -0500250 ASSERT_GL_NO_ERROR();
251
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500252 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
253}
254
Jamie Madill0e654542018-02-07 14:50:06 -0500255// Simple double quad test.
256TEST_P(SimpleOperationTest, DrawQuadTwice)
257{
258 ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
259
260 drawQuad(program.get(), "position", 0.5f, 1.0f, true);
261 drawQuad(program.get(), "position", 0.5f, 1.0f, true);
262
263 ASSERT_GL_NO_ERROR();
264
265 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
266}
267
Luc Ferron22294b02018-02-02 10:03:22 -0500268// Simple line test.
269TEST_P(SimpleOperationTest, DrawLine)
270{
Luc Ferronb5420662018-02-02 10:03:22 -0500271 // We assume in the test the width and height are equal and we are tracing
272 // the line from bottom left to top right. Verify that all pixels along that line
273 // have been traced with green.
274 ASSERT_EQ(getWindowWidth(), getWindowHeight());
275
Luc Ferron22294b02018-02-02 10:03:22 -0500276 ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
277 glUseProgram(program);
278
279 std::vector<Vector3> vertices = {{-1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}};
280
281 const GLint positionLocation = glGetAttribLocation(program, "position");
282 ASSERT_NE(-1, positionLocation);
283
284 GLBuffer vertexBuffer;
285 glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
286 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
287 GL_STATIC_DRAW);
288 glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
289 glEnableVertexAttribArray(positionLocation);
290
291 glClear(GL_COLOR_BUFFER_BIT);
292 glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(vertices.size()));
293
294 glDisableVertexAttribArray(positionLocation);
295
296 ASSERT_GL_NO_ERROR();
297
Luc Ferron22294b02018-02-02 10:03:22 -0500298 for (auto x = 0; x < getWindowWidth(); x++)
299 {
300 EXPECT_PIXEL_COLOR_EQ(x, x, GLColor::green);
301 }
302}
303
304// Simple line strip test.
305TEST_P(SimpleOperationTest, DrawLineStrip)
306{
Luc Ferronb5420662018-02-02 10:03:22 -0500307 // We assume in the test the width and height are equal and we are tracing
308 // the line from bottom left to center, then from center to bottom right.
309 // Verify that all pixels along these lines have been traced with green.
310 ASSERT_EQ(getWindowWidth(), getWindowHeight());
311
Luc Ferron22294b02018-02-02 10:03:22 -0500312 ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
313 glUseProgram(program);
314
315 auto vertices =
316 std::vector<Vector3>{{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {1.0f, -1.0f, 0.0f}};
317
318 const GLint positionLocation = glGetAttribLocation(program, "position");
319 ASSERT_NE(-1, positionLocation);
320
321 GLBuffer vertexBuffer;
322 glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer.get());
323 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
324 GL_STATIC_DRAW);
325 glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
326
327 glEnableVertexAttribArray(positionLocation);
328
329 glClear(GL_COLOR_BUFFER_BIT);
330 glDrawArrays(GL_LINE_STRIP, 0, static_cast<GLsizei>(vertices.size()));
331
332 ASSERT_GL_NO_ERROR();
333
Luc Ferron22294b02018-02-02 10:03:22 -0500334 const auto centerX = getWindowWidth() / 2;
335 const auto centerY = getWindowHeight() / 2;
336
337 for (auto x = 0; x < centerX; x++)
338 {
339 EXPECT_PIXEL_COLOR_EQ(x, x, GLColor::green);
340 }
341
342 for (auto x = centerX, y = centerY - 1; x < getWindowWidth() && y >= 0; x++, y--)
343 {
344 EXPECT_PIXEL_COLOR_EQ(x, y, GLColor::green);
345 }
346}
347
Luc Ferronb5420662018-02-02 10:03:22 -0500348// Simple triangle fans test.
349TEST_P(SimpleOperationTest, DrawTriangleFan)
350{
351 // We assume in the test the width and height are equal and we are tracing
352 // 2 triangles to cover half the surface like this:
353 ASSERT_EQ(getWindowWidth(), getWindowHeight());
354
355 ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
356 glUseProgram(program);
357
358 auto vertices = std::vector<Vector3>{
359 {-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}};
360
361 const GLint positionLocation = glGetAttribLocation(program, "position");
362 ASSERT_NE(-1, positionLocation);
363
364 GLBuffer vertexBuffer;
365 glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer.get());
366 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
367 GL_STATIC_DRAW);
368 glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
369 glEnableVertexAttribArray(positionLocation);
370
371 glClear(GL_COLOR_BUFFER_BIT);
372 glDrawArrays(GL_TRIANGLE_FAN, 0, static_cast<GLsizei>(vertices.size()));
373
374 glDisableVertexAttribArray(positionLocation);
375
376 EXPECT_GL_NO_ERROR();
377
378 // Check 4 lines accross de triangles to make sure we filled it.
379 // Don't check every pixel as it would slow down our tests.
380 for (auto x = 0; x < getWindowWidth(); x++)
381 {
382 EXPECT_PIXEL_COLOR_EQ(x, x, GLColor::green);
383 }
384
385 for (auto x = getWindowWidth() / 3, y = 0; x < getWindowWidth(); x++, y++)
386 {
387 EXPECT_PIXEL_COLOR_EQ(x, y, GLColor::green);
388 }
389
390 for (auto x = getWindowWidth() / 2, y = 0; x < getWindowWidth(); x++, y++)
391 {
392 EXPECT_PIXEL_COLOR_EQ(x, y, GLColor::green);
393 }
394
395 for (auto x = (getWindowWidth() / 4) * 3, y = 0; x < getWindowWidth(); x++, y++)
396 {
397 EXPECT_PIXEL_COLOR_EQ(x, y, GLColor::green);
398 }
399}
400
Jamie Madilld03a8492017-10-03 15:46:06 -0400401// Simple repeated draw and swap test.
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500402TEST_P(SimpleOperationTest, DrawQuadAndSwap)
403{
Luc Ferron22294b02018-02-02 10:03:22 -0500404 ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500405
406 for (int i = 0; i < 8; ++i)
407 {
408 drawQuad(program.get(), "position", 0.5f, 1.0f, true);
Luc Ferron22294b02018-02-02 10:03:22 -0500409 ASSERT_GL_NO_ERROR();
Jamie Madill4c26fc22017-02-24 11:04:10 -0500410 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500411 swapBuffers();
412 }
413
Luc Ferron22294b02018-02-02 10:03:22 -0500414 ASSERT_GL_NO_ERROR();
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500415}
416
Jamie Madilld03a8492017-10-03 15:46:06 -0400417// Simple indexed quad test.
418TEST_P(SimpleOperationTest, DrawIndexedQuad)
419{
Luc Ferron22294b02018-02-02 10:03:22 -0500420 ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
Jamie Madilld03a8492017-10-03 15:46:06 -0400421
422 drawIndexedQuad(program.get(), "position", 0.5f, 1.0f, true);
423
Luc Ferron22294b02018-02-02 10:03:22 -0500424 ASSERT_GL_NO_ERROR();
Jamie Madilld03a8492017-10-03 15:46:06 -0400425 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
426}
427
Jamie Madill76e471e2017-10-21 09:56:01 -0400428// Draw with a fragment uniform.
429TEST_P(SimpleOperationTest, DrawQuadWithFragmentUniform)
430{
Jamie Madill76e471e2017-10-21 09:56:01 -0400431 const std::string &fragmentShader =
432 "uniform mediump vec4 color;\n"
433 "void main()\n"
434 "{\n"
435 " gl_FragColor = color;\n"
436 "}";
Luc Ferron22294b02018-02-02 10:03:22 -0500437 ANGLE_GL_PROGRAM(program, kBasicVertexShader, fragmentShader);
Jamie Madill76e471e2017-10-21 09:56:01 -0400438
439 GLint location = glGetUniformLocation(program, "color");
440 ASSERT_NE(-1, location);
441
442 glUseProgram(program);
443 glUniform4f(location, 0.0f, 1.0f, 0.0f, 1.0f);
444
445 drawQuad(program.get(), "position", 0.5f, 1.0f, true);
446
Luc Ferron22294b02018-02-02 10:03:22 -0500447 ASSERT_GL_NO_ERROR();
Jamie Madill76e471e2017-10-21 09:56:01 -0400448 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
449}
450
451// Draw with a vertex uniform.
452TEST_P(SimpleOperationTest, DrawQuadWithVertexUniform)
453{
454 const std::string &vertexShader =
455 "attribute vec3 position;\n"
456 "uniform vec4 color;\n"
457 "varying vec4 vcolor;\n"
458 "void main()\n"
459 "{\n"
460 " gl_Position = vec4(position, 1);\n"
461 " vcolor = color;\n"
462 "}";
463 const std::string &fragmentShader =
464 "varying mediump vec4 vcolor;\n"
465 "void main()\n"
466 "{\n"
467 " gl_FragColor = vcolor;\n"
468 "}";
469 ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
470
Luc Ferron22294b02018-02-02 10:03:22 -0500471 const GLint location = glGetUniformLocation(program, "color");
Jamie Madill76e471e2017-10-21 09:56:01 -0400472 ASSERT_NE(-1, location);
473
474 glUseProgram(program);
475 glUniform4f(location, 0.0f, 1.0f, 0.0f, 1.0f);
476
477 drawQuad(program.get(), "position", 0.5f, 1.0f, true);
478
Luc Ferron22294b02018-02-02 10:03:22 -0500479 ASSERT_GL_NO_ERROR();
Jamie Madill76e471e2017-10-21 09:56:01 -0400480 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
481}
482
483// Draw with two uniforms.
484TEST_P(SimpleOperationTest, DrawQuadWithTwoUniforms)
485{
486 const std::string &vertexShader =
487 "attribute vec3 position;\n"
488 "uniform vec4 color1;\n"
489 "varying vec4 vcolor1;\n"
490 "void main()\n"
491 "{\n"
492 " gl_Position = vec4(position, 1);\n"
493 " vcolor1 = color1;\n"
494 "}";
495 const std::string &fragmentShader =
496 "uniform mediump vec4 color2;\n"
497 "varying mediump vec4 vcolor1;\n"
498 "void main()\n"
499 "{\n"
500 " gl_FragColor = vcolor1 + color2;\n"
501 "}";
502 ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
503
Luc Ferron22294b02018-02-02 10:03:22 -0500504 const GLint location1 = glGetUniformLocation(program, "color1");
Jamie Madill76e471e2017-10-21 09:56:01 -0400505 ASSERT_NE(-1, location1);
506
Luc Ferron22294b02018-02-02 10:03:22 -0500507 const GLint location2 = glGetUniformLocation(program, "color2");
Jamie Madill76e471e2017-10-21 09:56:01 -0400508 ASSERT_NE(-1, location2);
509
510 glUseProgram(program);
511 glUniform4f(location1, 0.0f, 1.0f, 0.0f, 1.0f);
512 glUniform4f(location2, 1.0f, 0.0f, 0.0f, 1.0f);
513
514 drawQuad(program.get(), "position", 0.5f, 1.0f, true);
515
Luc Ferron22294b02018-02-02 10:03:22 -0500516 ASSERT_GL_NO_ERROR();
Jamie Madill76e471e2017-10-21 09:56:01 -0400517 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
518}
519
Jamie Madill2a9e1072017-09-22 11:31:57 -0400520// Tests a shader program with more than one vertex attribute, with vertex buffers.
521TEST_P(SimpleOperationTest, ThreeVertexAttributes)
522{
523 const std::string vertexShader =
524 R"(attribute vec2 position;
525attribute vec4 color1;
526attribute vec4 color2;
527varying vec4 color;
528void main()
529{
530 gl_Position = vec4(position, 0, 1);
531 color = color1 + color2;
532})";
533
534 const std::string fragmentShader =
535 R"(precision mediump float;
536varying vec4 color;
537void main()
538{
539 gl_FragColor = color;
540}
541)";
542
543 ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
544
545 glUseProgram(program);
546
Luc Ferron22294b02018-02-02 10:03:22 -0500547 const GLint color1Loc = glGetAttribLocation(program, "color1");
548 const GLint color2Loc = glGetAttribLocation(program, "color2");
Jamie Madill2a9e1072017-09-22 11:31:57 -0400549 ASSERT_NE(-1, color1Loc);
550 ASSERT_NE(-1, color2Loc);
551
552 const auto &indices = GetQuadIndices();
553
554 // Make colored corners with red == x or 1 -x , and green = y or 1 - y.
555
556 std::array<GLColor, 4> baseColors1 = {
557 {GLColor::black, GLColor::red, GLColor::green, GLColor::yellow}};
558 std::array<GLColor, 4> baseColors2 = {
559 {GLColor::yellow, GLColor::green, GLColor::red, GLColor::black}};
560
561 std::vector<GLColor> colors1;
562 std::vector<GLColor> colors2;
563
564 for (GLushort index : indices)
565 {
566 colors1.push_back(baseColors1[index]);
567 colors2.push_back(baseColors2[index]);
568 }
569
570 GLBuffer color1Buffer;
571 glBindBuffer(GL_ARRAY_BUFFER, color1Buffer);
572 glBufferData(GL_ARRAY_BUFFER, colors1.size() * sizeof(GLColor), colors1.data(), GL_STATIC_DRAW);
573 glVertexAttribPointer(color1Loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, nullptr);
574 glEnableVertexAttribArray(color1Loc);
575
576 GLBuffer color2Buffer;
577 glBindBuffer(GL_ARRAY_BUFFER, color2Buffer);
578 glBufferData(GL_ARRAY_BUFFER, colors2.size() * sizeof(GLColor), colors2.data(), GL_STATIC_DRAW);
579 glVertexAttribPointer(color2Loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, nullptr);
580 glEnableVertexAttribArray(color2Loc);
581
582 // Draw a non-indexed quad with all vertex buffers. Should draw yellow to the entire window.
583 drawQuad(program, "position", 0.5f, 1.0f, true);
584 ASSERT_GL_NO_ERROR();
585 EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::yellow);
586}
587
Jamie Madill035fd6b2017-10-03 15:43:22 -0400588// Creates a texture, no other operations.
589TEST_P(SimpleOperationTest, CreateTexture2DNoData)
590{
591 GLTexture texture;
592 glBindTexture(GL_TEXTURE_2D, texture);
593 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
594 ASSERT_GL_NO_ERROR();
595}
596
597// Creates a texture, no other operations.
598TEST_P(SimpleOperationTest, CreateTexture2DWithData)
599{
600 std::vector<GLColor> colors(16 * 16, GLColor::red);
601
602 GLTexture texture;
603 glBindTexture(GL_TEXTURE_2D, texture);
604 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
605 ASSERT_GL_NO_ERROR();
606}
607
Jamie Madillde03e002017-10-21 14:04:20 -0400608// Creates a program with a texture.
609TEST_P(SimpleOperationTest, LinkProgramWithTexture)
610{
611 ASSERT_NE(0u, get2DTexturedQuadProgram());
Luc Ferron22294b02018-02-02 10:03:22 -0500612 ASSERT_GL_NO_ERROR();
Jamie Madillde03e002017-10-21 14:04:20 -0400613}
614
Jamie Madill5547b382017-10-23 18:16:01 -0400615// Creates a program with a texture and renders with it.
616TEST_P(SimpleOperationTest, DrawWithTexture)
617{
618 std::array<GLColor, 4> colors = {
619 {GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow}};
620
621 GLTexture tex;
622 glBindTexture(GL_TEXTURE_2D, tex);
623 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
624 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
625 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
626
627 draw2DTexturedQuad(0.5f, 1.0f, true);
Luc Ferron22294b02018-02-02 10:03:22 -0500628 ASSERT_GL_NO_ERROR();
Jamie Madill5547b382017-10-23 18:16:01 -0400629
630 int w = getWindowWidth() - 2;
631 int h = getWindowHeight() - 2;
632
633 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
634 EXPECT_PIXEL_COLOR_EQ(w, 0, GLColor::green);
635 EXPECT_PIXEL_COLOR_EQ(0, h, GLColor::blue);
636 EXPECT_PIXEL_COLOR_EQ(w, h, GLColor::yellow);
637}
638
Jamie Madillb79e7bb2017-10-24 13:55:50 -0400639// Tests rendering to a user framebuffer.
640TEST_P(SimpleOperationTest, RenderToTexture)
641{
642 constexpr int kSize = 16;
643
644 GLTexture texture;
645 glBindTexture(GL_TEXTURE_2D, texture);
646 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
647 ASSERT_GL_NO_ERROR();
648
649 GLFramebuffer framebuffer;
650 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
651 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
652 ASSERT_GL_NO_ERROR();
653 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
654
655 glViewport(0, 0, kSize, kSize);
656
Luc Ferron22294b02018-02-02 10:03:22 -0500657 ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
Jamie Madillb79e7bb2017-10-24 13:55:50 -0400658 drawQuad(program, "position", 0.5f, 1.0f, true);
659 ASSERT_GL_NO_ERROR();
660 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
661}
662
Jamie Madillfa05f602015-05-07 13:47:11 -0400663// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
Geoff Lange0cc2a42016-01-20 10:58:17 -0500664ANGLE_INSTANTIATE_TEST(SimpleOperationTest,
665 ES2_D3D9(),
Austin Kinross2a63b3f2016-02-08 12:29:08 -0800666 ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE),
667 ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE),
Geoff Lange0cc2a42016-01-20 10:58:17 -0500668 ES3_D3D11(),
669 ES2_OPENGL(),
670 ES3_OPENGL(),
671 ES2_OPENGLES(),
Jamie Madillb8353b02017-01-25 12:57:21 -0800672 ES3_OPENGLES(),
673 ES2_VULKAN());
Jamie Madillfa05f602015-05-07 13:47:11 -0400674
675} // namespace