blob: 30515a943698727bdc1962fc8a4a7ebac4e95941 [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 Ferron22294b02018-02-02 10:03:22 -0500107TEST_P(SimpleOperationTest, LinkProgramShadersNoInputs)
Geoff Langb1f435e2015-02-20 10:01:01 -0500108{
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300109 const std::string vsSource =
110 R"(void main()
Geoff Langb1f435e2015-02-20 10:01:01 -0500111 {
112 gl_Position = vec4(1.0, 1.0, 1.0, 1.0);
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300113 })";
Geoff Langb1f435e2015-02-20 10:01:01 -0500114
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300115 const std::string fsSource =
116 R"(void main()
Geoff Langb1f435e2015-02-20 10:01:01 -0500117 {
118 gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300119 })";
Geoff Langb1f435e2015-02-20 10:01:01 -0500120
Luc Ferron22294b02018-02-02 10:03:22 -0500121 const GLuint program = CompileProgram(vsSource, fsSource);
Geoff Langb1f435e2015-02-20 10:01:01 -0500122 EXPECT_NE(program, 0u);
123 glDeleteProgram(program);
124
Luc Ferron22294b02018-02-02 10:03:22 -0500125 ASSERT_GL_NO_ERROR();
Geoff Langb1f435e2015-02-20 10:01:01 -0500126}
127
Jamie Madillfa05f602015-05-07 13:47:11 -0400128TEST_P(SimpleOperationTest, LinkProgramWithUniforms)
Geoff Langb1f435e2015-02-20 10:01:01 -0500129{
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300130 const std::string vsSource =
131 R"(void main()
Geoff Langb1f435e2015-02-20 10:01:01 -0500132 {
133 gl_Position = vec4(1.0, 1.0, 1.0, 1.0);
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300134 })";
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300135 const std::string fsSource =
136 R"(precision mediump float;
Geoff Langb1f435e2015-02-20 10:01:01 -0500137 uniform vec4 u_input;
138 void main()
139 {
140 gl_FragColor = u_input;
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
Luc Ferron22294b02018-02-02 10:03:22 -0500146 const GLint uniformLoc = glGetUniformLocation(program, "u_input");
Geoff Langb1f435e2015-02-20 10:01:01 -0500147 EXPECT_NE(-1, uniformLoc);
148
149 glDeleteProgram(program);
150
Luc Ferron22294b02018-02-02 10:03:22 -0500151 ASSERT_GL_NO_ERROR();
Geoff Langb1f435e2015-02-20 10:01:01 -0500152}
153
Jamie Madillfa05f602015-05-07 13:47:11 -0400154TEST_P(SimpleOperationTest, LinkProgramWithAttributes)
Geoff Langb1f435e2015-02-20 10:01:01 -0500155{
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300156 const std::string vsSource =
157 R"(attribute vec4 a_input;
Geoff Langb1f435e2015-02-20 10:01:01 -0500158 void main()
159 {
160 gl_Position = a_input;
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300161 })";
Geoff Langb1f435e2015-02-20 10:01:01 -0500162
Luc Ferron22294b02018-02-02 10:03:22 -0500163 const GLuint program = CompileProgram(vsSource, kGreenFragmentShader);
Geoff Langb1f435e2015-02-20 10:01:01 -0500164 EXPECT_NE(program, 0u);
165
Luc Ferron22294b02018-02-02 10:03:22 -0500166 const GLint attribLoc = glGetAttribLocation(program, "a_input");
Geoff Langb1f435e2015-02-20 10:01:01 -0500167 EXPECT_NE(-1, attribLoc);
168
169 glDeleteProgram(program);
170
Luc Ferron22294b02018-02-02 10:03:22 -0500171 ASSERT_GL_NO_ERROR();
Geoff Langb1f435e2015-02-20 10:01:01 -0500172}
Geoff Lang36c79012015-02-24 11:47:20 -0500173
Jamie Madillfa05f602015-05-07 13:47:11 -0400174TEST_P(SimpleOperationTest, BufferDataWithData)
Geoff Lang36c79012015-02-24 11:47:20 -0500175{
Jamie Madillcc6ac252017-01-25 12:57:21 -0800176 GLBuffer buffer;
177 glBindBuffer(GL_ARRAY_BUFFER, buffer.get());
Geoff Lang36c79012015-02-24 11:47:20 -0500178
179 std::vector<uint8_t> data(1024);
Jamie Madillcc6ac252017-01-25 12:57:21 -0800180 FillVectorWithRandomUBytes(&data);
Geoff Lang36c79012015-02-24 11:47:20 -0500181 glBufferData(GL_ARRAY_BUFFER, data.size(), &data[0], GL_STATIC_DRAW);
182
Jamie Madillcc6ac252017-01-25 12:57:21 -0800183 verifyBuffer(data, GL_ARRAY_BUFFER);
Geoff Lang36c79012015-02-24 11:47:20 -0500184
Luc Ferron22294b02018-02-02 10:03:22 -0500185 ASSERT_GL_NO_ERROR();
Geoff Lang36c79012015-02-24 11:47:20 -0500186}
187
Jamie Madillfa05f602015-05-07 13:47:11 -0400188TEST_P(SimpleOperationTest, BufferDataWithNoData)
Geoff Lang36c79012015-02-24 11:47:20 -0500189{
Jamie Madillcc6ac252017-01-25 12:57:21 -0800190 GLBuffer buffer;
191 glBindBuffer(GL_ARRAY_BUFFER, buffer.get());
Geoff Lang36c79012015-02-24 11:47:20 -0500192 glBufferData(GL_ARRAY_BUFFER, 1024, nullptr, GL_STATIC_DRAW);
Geoff Lang36c79012015-02-24 11:47:20 -0500193
Luc Ferron22294b02018-02-02 10:03:22 -0500194 ASSERT_GL_NO_ERROR();
Geoff Lang36c79012015-02-24 11:47:20 -0500195}
196
Jamie Madillfa05f602015-05-07 13:47:11 -0400197TEST_P(SimpleOperationTest, BufferSubData)
Geoff Lang36c79012015-02-24 11:47:20 -0500198{
Jamie Madillcc6ac252017-01-25 12:57:21 -0800199 GLBuffer buffer;
200 glBindBuffer(GL_ARRAY_BUFFER, buffer.get());
Geoff Lang36c79012015-02-24 11:47:20 -0500201
Jamie Madillcc6ac252017-01-25 12:57:21 -0800202 constexpr size_t bufferSize = 1024;
203 std::vector<uint8_t> data(bufferSize);
204 FillVectorWithRandomUBytes(&data);
205
Geoff Lang36c79012015-02-24 11:47:20 -0500206 glBufferData(GL_ARRAY_BUFFER, bufferSize, nullptr, GL_STATIC_DRAW);
207
Jamie Madillcc6ac252017-01-25 12:57:21 -0800208 constexpr size_t subDataCount = 16;
209 constexpr size_t sliceSize = bufferSize / subDataCount;
Geoff Lang36c79012015-02-24 11:47:20 -0500210 for (size_t i = 0; i < subDataCount; i++)
211 {
Jamie Madillcc6ac252017-01-25 12:57:21 -0800212 size_t offset = i * sliceSize;
213 glBufferSubData(GL_ARRAY_BUFFER, offset, sliceSize, &data[offset]);
Geoff Lang36c79012015-02-24 11:47:20 -0500214 }
215
Jamie Madillcc6ac252017-01-25 12:57:21 -0800216 verifyBuffer(data, GL_ARRAY_BUFFER);
Geoff Lang36c79012015-02-24 11:47:20 -0500217
Luc Ferron22294b02018-02-02 10:03:22 -0500218 ASSERT_GL_NO_ERROR();
Geoff Lang36c79012015-02-24 11:47:20 -0500219}
Jamie Madillfa05f602015-05-07 13:47:11 -0400220
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500221// Simple quad test.
222TEST_P(SimpleOperationTest, DrawQuad)
223{
Luc Ferron22294b02018-02-02 10:03:22 -0500224 ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500225
226 drawQuad(program.get(), "position", 0.5f, 1.0f, true);
227
Luc Ferron22294b02018-02-02 10:03:22 -0500228 ASSERT_GL_NO_ERROR();
229
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500230 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
231}
232
Luc Ferron22294b02018-02-02 10:03:22 -0500233// Simple line test.
234TEST_P(SimpleOperationTest, DrawLine)
235{
Luc Ferronb5420662018-02-02 10:03:22 -0500236 // We assume in the test the width and height are equal and we are tracing
237 // the line from bottom left to top right. Verify that all pixels along that line
238 // have been traced with green.
239 ASSERT_EQ(getWindowWidth(), getWindowHeight());
240
Luc Ferron22294b02018-02-02 10:03:22 -0500241 ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
242 glUseProgram(program);
243
244 std::vector<Vector3> vertices = {{-1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}};
245
246 const GLint positionLocation = glGetAttribLocation(program, "position");
247 ASSERT_NE(-1, positionLocation);
248
249 GLBuffer vertexBuffer;
250 glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
251 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
252 GL_STATIC_DRAW);
253 glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
254 glEnableVertexAttribArray(positionLocation);
255
256 glClear(GL_COLOR_BUFFER_BIT);
257 glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(vertices.size()));
258
259 glDisableVertexAttribArray(positionLocation);
260
261 ASSERT_GL_NO_ERROR();
262
Luc Ferron22294b02018-02-02 10:03:22 -0500263 for (auto x = 0; x < getWindowWidth(); x++)
264 {
265 EXPECT_PIXEL_COLOR_EQ(x, x, GLColor::green);
266 }
267}
268
269// Simple line strip test.
270TEST_P(SimpleOperationTest, DrawLineStrip)
271{
Luc Ferronb5420662018-02-02 10:03:22 -0500272 // We assume in the test the width and height are equal and we are tracing
273 // the line from bottom left to center, then from center to bottom right.
274 // Verify that all pixels along these lines have been traced with green.
275 ASSERT_EQ(getWindowWidth(), getWindowHeight());
276
Luc Ferron22294b02018-02-02 10:03:22 -0500277 ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
278 glUseProgram(program);
279
280 auto vertices =
281 std::vector<Vector3>{{-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {1.0f, -1.0f, 0.0f}};
282
283 const GLint positionLocation = glGetAttribLocation(program, "position");
284 ASSERT_NE(-1, positionLocation);
285
286 GLBuffer vertexBuffer;
287 glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer.get());
288 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
289 GL_STATIC_DRAW);
290 glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
291
292 glEnableVertexAttribArray(positionLocation);
293
294 glClear(GL_COLOR_BUFFER_BIT);
295 glDrawArrays(GL_LINE_STRIP, 0, static_cast<GLsizei>(vertices.size()));
296
297 ASSERT_GL_NO_ERROR();
298
Luc Ferron22294b02018-02-02 10:03:22 -0500299 const auto centerX = getWindowWidth() / 2;
300 const auto centerY = getWindowHeight() / 2;
301
302 for (auto x = 0; x < centerX; x++)
303 {
304 EXPECT_PIXEL_COLOR_EQ(x, x, GLColor::green);
305 }
306
307 for (auto x = centerX, y = centerY - 1; x < getWindowWidth() && y >= 0; x++, y--)
308 {
309 EXPECT_PIXEL_COLOR_EQ(x, y, GLColor::green);
310 }
311}
312
Luc Ferronb5420662018-02-02 10:03:22 -0500313// Simple triangle fans test.
314TEST_P(SimpleOperationTest, DrawTriangleFan)
315{
316 // We assume in the test the width and height are equal and we are tracing
317 // 2 triangles to cover half the surface like this:
318 ASSERT_EQ(getWindowWidth(), getWindowHeight());
319
320 ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
321 glUseProgram(program);
322
323 auto vertices = std::vector<Vector3>{
324 {-1.0f, -1.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}};
325
326 const GLint positionLocation = glGetAttribLocation(program, "position");
327 ASSERT_NE(-1, positionLocation);
328
329 GLBuffer vertexBuffer;
330 glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer.get());
331 glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
332 GL_STATIC_DRAW);
333 glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
334 glEnableVertexAttribArray(positionLocation);
335
336 glClear(GL_COLOR_BUFFER_BIT);
337 glDrawArrays(GL_TRIANGLE_FAN, 0, static_cast<GLsizei>(vertices.size()));
338
339 glDisableVertexAttribArray(positionLocation);
340
341 EXPECT_GL_NO_ERROR();
342
343 // Check 4 lines accross de triangles to make sure we filled it.
344 // Don't check every pixel as it would slow down our tests.
345 for (auto x = 0; x < getWindowWidth(); x++)
346 {
347 EXPECT_PIXEL_COLOR_EQ(x, x, GLColor::green);
348 }
349
350 for (auto x = getWindowWidth() / 3, y = 0; x < getWindowWidth(); x++, y++)
351 {
352 EXPECT_PIXEL_COLOR_EQ(x, y, GLColor::green);
353 }
354
355 for (auto x = getWindowWidth() / 2, y = 0; x < getWindowWidth(); x++, y++)
356 {
357 EXPECT_PIXEL_COLOR_EQ(x, y, GLColor::green);
358 }
359
360 for (auto x = (getWindowWidth() / 4) * 3, y = 0; x < getWindowWidth(); x++, y++)
361 {
362 EXPECT_PIXEL_COLOR_EQ(x, y, GLColor::green);
363 }
364}
365
Jamie Madilld03a8492017-10-03 15:46:06 -0400366// Simple repeated draw and swap test.
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500367TEST_P(SimpleOperationTest, DrawQuadAndSwap)
368{
Luc Ferron22294b02018-02-02 10:03:22 -0500369 ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500370
371 for (int i = 0; i < 8; ++i)
372 {
373 drawQuad(program.get(), "position", 0.5f, 1.0f, true);
Luc Ferron22294b02018-02-02 10:03:22 -0500374 ASSERT_GL_NO_ERROR();
Jamie Madill4c26fc22017-02-24 11:04:10 -0500375 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500376 swapBuffers();
377 }
378
Luc Ferron22294b02018-02-02 10:03:22 -0500379 ASSERT_GL_NO_ERROR();
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500380}
381
Jamie Madilld03a8492017-10-03 15:46:06 -0400382// Simple indexed quad test.
383TEST_P(SimpleOperationTest, DrawIndexedQuad)
384{
Luc Ferron22294b02018-02-02 10:03:22 -0500385 ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
Jamie Madilld03a8492017-10-03 15:46:06 -0400386
387 drawIndexedQuad(program.get(), "position", 0.5f, 1.0f, true);
388
Luc Ferron22294b02018-02-02 10:03:22 -0500389 ASSERT_GL_NO_ERROR();
Jamie Madilld03a8492017-10-03 15:46:06 -0400390 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
391}
392
Jamie Madill76e471e2017-10-21 09:56:01 -0400393// Draw with a fragment uniform.
394TEST_P(SimpleOperationTest, DrawQuadWithFragmentUniform)
395{
Jamie Madill76e471e2017-10-21 09:56:01 -0400396 const std::string &fragmentShader =
397 "uniform mediump vec4 color;\n"
398 "void main()\n"
399 "{\n"
400 " gl_FragColor = color;\n"
401 "}";
Luc Ferron22294b02018-02-02 10:03:22 -0500402 ANGLE_GL_PROGRAM(program, kBasicVertexShader, fragmentShader);
Jamie Madill76e471e2017-10-21 09:56:01 -0400403
404 GLint location = glGetUniformLocation(program, "color");
405 ASSERT_NE(-1, location);
406
407 glUseProgram(program);
408 glUniform4f(location, 0.0f, 1.0f, 0.0f, 1.0f);
409
410 drawQuad(program.get(), "position", 0.5f, 1.0f, true);
411
Luc Ferron22294b02018-02-02 10:03:22 -0500412 ASSERT_GL_NO_ERROR();
Jamie Madill76e471e2017-10-21 09:56:01 -0400413 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
414}
415
416// Draw with a vertex uniform.
417TEST_P(SimpleOperationTest, DrawQuadWithVertexUniform)
418{
419 const std::string &vertexShader =
420 "attribute vec3 position;\n"
421 "uniform vec4 color;\n"
422 "varying vec4 vcolor;\n"
423 "void main()\n"
424 "{\n"
425 " gl_Position = vec4(position, 1);\n"
426 " vcolor = color;\n"
427 "}";
428 const std::string &fragmentShader =
429 "varying mediump vec4 vcolor;\n"
430 "void main()\n"
431 "{\n"
432 " gl_FragColor = vcolor;\n"
433 "}";
434 ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
435
Luc Ferron22294b02018-02-02 10:03:22 -0500436 const GLint location = glGetUniformLocation(program, "color");
Jamie Madill76e471e2017-10-21 09:56:01 -0400437 ASSERT_NE(-1, location);
438
439 glUseProgram(program);
440 glUniform4f(location, 0.0f, 1.0f, 0.0f, 1.0f);
441
442 drawQuad(program.get(), "position", 0.5f, 1.0f, true);
443
Luc Ferron22294b02018-02-02 10:03:22 -0500444 ASSERT_GL_NO_ERROR();
Jamie Madill76e471e2017-10-21 09:56:01 -0400445 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
446}
447
448// Draw with two uniforms.
449TEST_P(SimpleOperationTest, DrawQuadWithTwoUniforms)
450{
451 const std::string &vertexShader =
452 "attribute vec3 position;\n"
453 "uniform vec4 color1;\n"
454 "varying vec4 vcolor1;\n"
455 "void main()\n"
456 "{\n"
457 " gl_Position = vec4(position, 1);\n"
458 " vcolor1 = color1;\n"
459 "}";
460 const std::string &fragmentShader =
461 "uniform mediump vec4 color2;\n"
462 "varying mediump vec4 vcolor1;\n"
463 "void main()\n"
464 "{\n"
465 " gl_FragColor = vcolor1 + color2;\n"
466 "}";
467 ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
468
Luc Ferron22294b02018-02-02 10:03:22 -0500469 const GLint location1 = glGetUniformLocation(program, "color1");
Jamie Madill76e471e2017-10-21 09:56:01 -0400470 ASSERT_NE(-1, location1);
471
Luc Ferron22294b02018-02-02 10:03:22 -0500472 const GLint location2 = glGetUniformLocation(program, "color2");
Jamie Madill76e471e2017-10-21 09:56:01 -0400473 ASSERT_NE(-1, location2);
474
475 glUseProgram(program);
476 glUniform4f(location1, 0.0f, 1.0f, 0.0f, 1.0f);
477 glUniform4f(location2, 1.0f, 0.0f, 0.0f, 1.0f);
478
479 drawQuad(program.get(), "position", 0.5f, 1.0f, true);
480
Luc Ferron22294b02018-02-02 10:03:22 -0500481 ASSERT_GL_NO_ERROR();
Jamie Madill76e471e2017-10-21 09:56:01 -0400482 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
483}
484
Jamie Madill2a9e1072017-09-22 11:31:57 -0400485// Tests a shader program with more than one vertex attribute, with vertex buffers.
486TEST_P(SimpleOperationTest, ThreeVertexAttributes)
487{
488 const std::string vertexShader =
489 R"(attribute vec2 position;
490attribute vec4 color1;
491attribute vec4 color2;
492varying vec4 color;
493void main()
494{
495 gl_Position = vec4(position, 0, 1);
496 color = color1 + color2;
497})";
498
499 const std::string fragmentShader =
500 R"(precision mediump float;
501varying vec4 color;
502void main()
503{
504 gl_FragColor = color;
505}
506)";
507
508 ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
509
510 glUseProgram(program);
511
Luc Ferron22294b02018-02-02 10:03:22 -0500512 const GLint color1Loc = glGetAttribLocation(program, "color1");
513 const GLint color2Loc = glGetAttribLocation(program, "color2");
Jamie Madill2a9e1072017-09-22 11:31:57 -0400514 ASSERT_NE(-1, color1Loc);
515 ASSERT_NE(-1, color2Loc);
516
517 const auto &indices = GetQuadIndices();
518
519 // Make colored corners with red == x or 1 -x , and green = y or 1 - y.
520
521 std::array<GLColor, 4> baseColors1 = {
522 {GLColor::black, GLColor::red, GLColor::green, GLColor::yellow}};
523 std::array<GLColor, 4> baseColors2 = {
524 {GLColor::yellow, GLColor::green, GLColor::red, GLColor::black}};
525
526 std::vector<GLColor> colors1;
527 std::vector<GLColor> colors2;
528
529 for (GLushort index : indices)
530 {
531 colors1.push_back(baseColors1[index]);
532 colors2.push_back(baseColors2[index]);
533 }
534
535 GLBuffer color1Buffer;
536 glBindBuffer(GL_ARRAY_BUFFER, color1Buffer);
537 glBufferData(GL_ARRAY_BUFFER, colors1.size() * sizeof(GLColor), colors1.data(), GL_STATIC_DRAW);
538 glVertexAttribPointer(color1Loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, nullptr);
539 glEnableVertexAttribArray(color1Loc);
540
541 GLBuffer color2Buffer;
542 glBindBuffer(GL_ARRAY_BUFFER, color2Buffer);
543 glBufferData(GL_ARRAY_BUFFER, colors2.size() * sizeof(GLColor), colors2.data(), GL_STATIC_DRAW);
544 glVertexAttribPointer(color2Loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, nullptr);
545 glEnableVertexAttribArray(color2Loc);
546
547 // Draw a non-indexed quad with all vertex buffers. Should draw yellow to the entire window.
548 drawQuad(program, "position", 0.5f, 1.0f, true);
549 ASSERT_GL_NO_ERROR();
550 EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::yellow);
551}
552
Jamie Madill035fd6b2017-10-03 15:43:22 -0400553// Creates a texture, no other operations.
554TEST_P(SimpleOperationTest, CreateTexture2DNoData)
555{
556 GLTexture texture;
557 glBindTexture(GL_TEXTURE_2D, texture);
558 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
559 ASSERT_GL_NO_ERROR();
560}
561
562// Creates a texture, no other operations.
563TEST_P(SimpleOperationTest, CreateTexture2DWithData)
564{
565 std::vector<GLColor> colors(16 * 16, GLColor::red);
566
567 GLTexture texture;
568 glBindTexture(GL_TEXTURE_2D, texture);
569 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
570 ASSERT_GL_NO_ERROR();
571}
572
Jamie Madillde03e002017-10-21 14:04:20 -0400573// Creates a program with a texture.
574TEST_P(SimpleOperationTest, LinkProgramWithTexture)
575{
576 ASSERT_NE(0u, get2DTexturedQuadProgram());
Luc Ferron22294b02018-02-02 10:03:22 -0500577 ASSERT_GL_NO_ERROR();
Jamie Madillde03e002017-10-21 14:04:20 -0400578}
579
Jamie Madill5547b382017-10-23 18:16:01 -0400580// Creates a program with a texture and renders with it.
581TEST_P(SimpleOperationTest, DrawWithTexture)
582{
583 std::array<GLColor, 4> colors = {
584 {GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow}};
585
586 GLTexture tex;
587 glBindTexture(GL_TEXTURE_2D, tex);
588 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
589 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
590 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
591
592 draw2DTexturedQuad(0.5f, 1.0f, true);
Luc Ferron22294b02018-02-02 10:03:22 -0500593 ASSERT_GL_NO_ERROR();
Jamie Madill5547b382017-10-23 18:16:01 -0400594
595 int w = getWindowWidth() - 2;
596 int h = getWindowHeight() - 2;
597
598 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
599 EXPECT_PIXEL_COLOR_EQ(w, 0, GLColor::green);
600 EXPECT_PIXEL_COLOR_EQ(0, h, GLColor::blue);
601 EXPECT_PIXEL_COLOR_EQ(w, h, GLColor::yellow);
602}
603
Jamie Madillb79e7bb2017-10-24 13:55:50 -0400604// Tests rendering to a user framebuffer.
605TEST_P(SimpleOperationTest, RenderToTexture)
606{
607 constexpr int kSize = 16;
608
609 GLTexture texture;
610 glBindTexture(GL_TEXTURE_2D, texture);
611 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
612 ASSERT_GL_NO_ERROR();
613
614 GLFramebuffer framebuffer;
615 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
616 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
617 ASSERT_GL_NO_ERROR();
618 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
619
620 glViewport(0, 0, kSize, kSize);
621
Luc Ferron22294b02018-02-02 10:03:22 -0500622 ANGLE_GL_PROGRAM(program, kBasicVertexShader, kGreenFragmentShader);
Jamie Madillb79e7bb2017-10-24 13:55:50 -0400623 drawQuad(program, "position", 0.5f, 1.0f, true);
624 ASSERT_GL_NO_ERROR();
625 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
626}
627
Jamie Madillfa05f602015-05-07 13:47:11 -0400628// 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 -0500629ANGLE_INSTANTIATE_TEST(SimpleOperationTest,
630 ES2_D3D9(),
Austin Kinross2a63b3f2016-02-08 12:29:08 -0800631 ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE),
632 ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE),
Geoff Lange0cc2a42016-01-20 10:58:17 -0500633 ES3_D3D11(),
634 ES2_OPENGL(),
635 ES3_OPENGL(),
636 ES2_OPENGLES(),
Jamie Madillb8353b02017-01-25 12:57:21 -0800637 ES3_OPENGLES(),
638 ES2_VULKAN());
Jamie Madillfa05f602015-05-07 13:47:11 -0400639
640} // namespace