blob: 4e40215753dc86ef2aa9ad2eed766c221cff81f7 [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{
20
Geoff Langf1e85922015-02-23 14:40:04 -050021class SimpleOperationTest : public ANGLETest
22{
23 protected:
Jamie Madillfa05f602015-05-07 13:47:11 -040024 SimpleOperationTest()
Geoff Langf1e85922015-02-23 14:40:04 -050025 {
26 setWindowWidth(128);
27 setWindowHeight(128);
28 setConfigRedBits(8);
29 setConfigGreenBits(8);
30 setConfigBlueBits(8);
31 setConfigAlphaBits(8);
32 }
Jamie Madillcc6ac252017-01-25 12:57:21 -080033
34 void verifyBuffer(const std::vector<uint8_t> &data, GLenum binding);
Geoff Langf1e85922015-02-23 14:40:04 -050035};
36
Jamie Madillcc6ac252017-01-25 12:57:21 -080037void SimpleOperationTest::verifyBuffer(const std::vector<uint8_t> &data, GLenum binding)
38{
39 if (!extensionEnabled("GL_EXT_map_buffer_range"))
40 {
41 return;
42 }
43
44 uint8_t *mapPointer =
45 static_cast<uint8_t *>(glMapBufferRangeEXT(GL_ARRAY_BUFFER, 0, 1024, GL_MAP_READ_BIT));
46 ASSERT_GL_NO_ERROR();
47
48 std::vector<uint8_t> readbackData(data.size());
49 memcpy(readbackData.data(), mapPointer, data.size());
50 glUnmapBufferOES(GL_ARRAY_BUFFER);
51
52 EXPECT_EQ(data, readbackData);
53}
54
Jamie Madillfa05f602015-05-07 13:47:11 -040055TEST_P(SimpleOperationTest, CompileVertexShader)
Geoff Langf1e85922015-02-23 14:40:04 -050056{
Olli Etuahoa20af6d2017-09-18 13:32:29 +030057 const std::string source =
58 R"(attribute vec4 a_input;
Geoff Langf1e85922015-02-23 14:40:04 -050059 void main()
60 {
61 gl_Position = a_input;
Olli Etuahoa20af6d2017-09-18 13:32:29 +030062 })";
Geoff Langf1e85922015-02-23 14:40:04 -050063
64 GLuint shader = CompileShader(GL_VERTEX_SHADER, source);
65 EXPECT_NE(shader, 0u);
66 glDeleteShader(shader);
67
68 EXPECT_GL_NO_ERROR();
69}
70
Jamie Madillfa05f602015-05-07 13:47:11 -040071TEST_P(SimpleOperationTest, CompileFragmentShader)
Geoff Langf1e85922015-02-23 14:40:04 -050072{
Olli Etuahoa20af6d2017-09-18 13:32:29 +030073 const std::string source =
74 R"(precision mediump float;
Geoff Langf1e85922015-02-23 14:40:04 -050075 varying vec4 v_input;
76 void main()
77 {
78 gl_FragColor = v_input;
Olli Etuahoa20af6d2017-09-18 13:32:29 +030079 })";
Geoff Langf1e85922015-02-23 14:40:04 -050080
81 GLuint shader = CompileShader(GL_FRAGMENT_SHADER, source);
82 EXPECT_NE(shader, 0u);
83 glDeleteShader(shader);
84
85 EXPECT_GL_NO_ERROR();
86}
Geoff Langb1f435e2015-02-20 10:01:01 -050087
Jamie Madillfa05f602015-05-07 13:47:11 -040088TEST_P(SimpleOperationTest, LinkProgram)
Geoff Langb1f435e2015-02-20 10:01:01 -050089{
Olli Etuahoa20af6d2017-09-18 13:32:29 +030090 const std::string vsSource =
91 R"(void main()
Geoff Langb1f435e2015-02-20 10:01:01 -050092 {
93 gl_Position = vec4(1.0, 1.0, 1.0, 1.0);
Olli Etuahoa20af6d2017-09-18 13:32:29 +030094 })";
Geoff Langb1f435e2015-02-20 10:01:01 -050095
Olli Etuahoa20af6d2017-09-18 13:32:29 +030096 const std::string fsSource =
97 R"(void main()
Geoff Langb1f435e2015-02-20 10:01:01 -050098 {
99 gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300100 })";
Geoff Langb1f435e2015-02-20 10:01:01 -0500101
102 GLuint program = CompileProgram(vsSource, fsSource);
103 EXPECT_NE(program, 0u);
104 glDeleteProgram(program);
105
106 EXPECT_GL_NO_ERROR();
107}
108
Jamie Madillfa05f602015-05-07 13:47:11 -0400109TEST_P(SimpleOperationTest, LinkProgramWithUniforms)
Geoff Langb1f435e2015-02-20 10:01:01 -0500110{
Jamie Madillb8353b02017-01-25 12:57:21 -0800111 if (IsVulkan())
112 {
113 // TODO(jmadill): Complete Vulkan implementation.
114 std::cout << "Test skipped on Vulkan." << std::endl;
115 return;
116 }
117
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300118 const std::string vsSource =
119 R"(void main()
Geoff Langb1f435e2015-02-20 10:01:01 -0500120 {
121 gl_Position = vec4(1.0, 1.0, 1.0, 1.0);
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300122 })";
Geoff Langb1f435e2015-02-20 10:01:01 -0500123
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300124 const std::string fsSource =
125 R"(precision mediump float;
Geoff Langb1f435e2015-02-20 10:01:01 -0500126 uniform vec4 u_input;
127 void main()
128 {
129 gl_FragColor = u_input;
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300130 })";
Geoff Langb1f435e2015-02-20 10:01:01 -0500131
132 GLuint program = CompileProgram(vsSource, fsSource);
133 EXPECT_NE(program, 0u);
134
135 GLint uniformLoc = glGetUniformLocation(program, "u_input");
136 EXPECT_NE(-1, uniformLoc);
137
138 glDeleteProgram(program);
139
140 EXPECT_GL_NO_ERROR();
141}
142
Jamie Madillfa05f602015-05-07 13:47:11 -0400143TEST_P(SimpleOperationTest, LinkProgramWithAttributes)
Geoff Langb1f435e2015-02-20 10:01:01 -0500144{
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300145 const std::string vsSource =
146 R"(attribute vec4 a_input;
Geoff Langb1f435e2015-02-20 10:01:01 -0500147 void main()
148 {
149 gl_Position = a_input;
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300150 })";
Geoff Langb1f435e2015-02-20 10:01:01 -0500151
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300152 const std::string fsSource =
153 R"(void main()
Geoff Langb1f435e2015-02-20 10:01:01 -0500154 {
155 gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300156 })";
Geoff Langb1f435e2015-02-20 10:01:01 -0500157
158 GLuint program = CompileProgram(vsSource, fsSource);
159 EXPECT_NE(program, 0u);
160
161 GLint attribLoc = glGetAttribLocation(program, "a_input");
162 EXPECT_NE(-1, attribLoc);
163
164 glDeleteProgram(program);
165
166 EXPECT_GL_NO_ERROR();
167}
Geoff Lang36c79012015-02-24 11:47:20 -0500168
Jamie Madillfa05f602015-05-07 13:47:11 -0400169TEST_P(SimpleOperationTest, BufferDataWithData)
Geoff Lang36c79012015-02-24 11:47:20 -0500170{
Jamie Madillcc6ac252017-01-25 12:57:21 -0800171 GLBuffer buffer;
172 glBindBuffer(GL_ARRAY_BUFFER, buffer.get());
Geoff Lang36c79012015-02-24 11:47:20 -0500173
174 std::vector<uint8_t> data(1024);
Jamie Madillcc6ac252017-01-25 12:57:21 -0800175 FillVectorWithRandomUBytes(&data);
Geoff Lang36c79012015-02-24 11:47:20 -0500176 glBufferData(GL_ARRAY_BUFFER, data.size(), &data[0], GL_STATIC_DRAW);
177
Jamie Madillcc6ac252017-01-25 12:57:21 -0800178 verifyBuffer(data, GL_ARRAY_BUFFER);
Geoff Lang36c79012015-02-24 11:47:20 -0500179
180 EXPECT_GL_NO_ERROR();
181}
182
Jamie Madillfa05f602015-05-07 13:47:11 -0400183TEST_P(SimpleOperationTest, BufferDataWithNoData)
Geoff Lang36c79012015-02-24 11:47:20 -0500184{
Jamie Madillcc6ac252017-01-25 12:57:21 -0800185 GLBuffer buffer;
186 glBindBuffer(GL_ARRAY_BUFFER, buffer.get());
Geoff Lang36c79012015-02-24 11:47:20 -0500187 glBufferData(GL_ARRAY_BUFFER, 1024, nullptr, GL_STATIC_DRAW);
Geoff Lang36c79012015-02-24 11:47:20 -0500188
189 EXPECT_GL_NO_ERROR();
190}
191
Jamie Madillfa05f602015-05-07 13:47:11 -0400192TEST_P(SimpleOperationTest, BufferSubData)
Geoff Lang36c79012015-02-24 11:47:20 -0500193{
Jamie Madillcc6ac252017-01-25 12:57:21 -0800194 GLBuffer buffer;
195 glBindBuffer(GL_ARRAY_BUFFER, buffer.get());
Geoff Lang36c79012015-02-24 11:47:20 -0500196
Jamie Madillcc6ac252017-01-25 12:57:21 -0800197 constexpr size_t bufferSize = 1024;
198 std::vector<uint8_t> data(bufferSize);
199 FillVectorWithRandomUBytes(&data);
200
Geoff Lang36c79012015-02-24 11:47:20 -0500201 glBufferData(GL_ARRAY_BUFFER, bufferSize, nullptr, GL_STATIC_DRAW);
202
Jamie Madillcc6ac252017-01-25 12:57:21 -0800203 constexpr size_t subDataCount = 16;
204 constexpr size_t sliceSize = bufferSize / subDataCount;
Geoff Lang36c79012015-02-24 11:47:20 -0500205 for (size_t i = 0; i < subDataCount; i++)
206 {
Jamie Madillcc6ac252017-01-25 12:57:21 -0800207 size_t offset = i * sliceSize;
208 glBufferSubData(GL_ARRAY_BUFFER, offset, sliceSize, &data[offset]);
Geoff Lang36c79012015-02-24 11:47:20 -0500209 }
210
Jamie Madillcc6ac252017-01-25 12:57:21 -0800211 verifyBuffer(data, GL_ARRAY_BUFFER);
Geoff Lang36c79012015-02-24 11:47:20 -0500212
213 EXPECT_GL_NO_ERROR();
214}
Jamie Madillfa05f602015-05-07 13:47:11 -0400215
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500216// Simple quad test.
217TEST_P(SimpleOperationTest, DrawQuad)
218{
219 const std::string &vertexShader =
220 "attribute vec3 position;\n"
221 "void main()\n"
222 "{\n"
223 " gl_Position = vec4(position, 1);\n"
224 "}";
225 const std::string &fragmentShader =
226 "void main()\n"
227 "{\n"
228 " gl_FragColor = vec4(0, 1, 0, 1);\n"
229 "}";
230 ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
231
232 drawQuad(program.get(), "position", 0.5f, 1.0f, true);
233
234 EXPECT_GL_NO_ERROR();
235 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
236}
237
238// Simple repeatd draw and swap test.
239TEST_P(SimpleOperationTest, DrawQuadAndSwap)
240{
241 const std::string &vertexShader =
242 "attribute vec3 position;\n"
243 "void main()\n"
244 "{\n"
245 " gl_Position = vec4(position, 1);\n"
246 "}";
247 const std::string &fragmentShader =
248 "void main()\n"
249 "{\n"
250 " gl_FragColor = vec4(0, 1, 0, 1);\n"
251 "}";
252 ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
253
254 for (int i = 0; i < 8; ++i)
255 {
256 drawQuad(program.get(), "position", 0.5f, 1.0f, true);
257 EXPECT_GL_NO_ERROR();
Jamie Madill4c26fc22017-02-24 11:04:10 -0500258 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500259 swapBuffers();
260 }
261
262 EXPECT_GL_NO_ERROR();
263}
264
Jamie Madill2a9e1072017-09-22 11:31:57 -0400265// Tests a shader program with more than one vertex attribute, with vertex buffers.
266TEST_P(SimpleOperationTest, ThreeVertexAttributes)
267{
268 const std::string vertexShader =
269 R"(attribute vec2 position;
270attribute vec4 color1;
271attribute vec4 color2;
272varying vec4 color;
273void main()
274{
275 gl_Position = vec4(position, 0, 1);
276 color = color1 + color2;
277})";
278
279 const std::string fragmentShader =
280 R"(precision mediump float;
281varying vec4 color;
282void main()
283{
284 gl_FragColor = color;
285}
286)";
287
288 ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
289
290 glUseProgram(program);
291
292 GLint color1Loc = glGetAttribLocation(program, "color1");
293 GLint color2Loc = glGetAttribLocation(program, "color2");
294 ASSERT_NE(-1, color1Loc);
295 ASSERT_NE(-1, color2Loc);
296
297 const auto &indices = GetQuadIndices();
298
299 // Make colored corners with red == x or 1 -x , and green = y or 1 - y.
300
301 std::array<GLColor, 4> baseColors1 = {
302 {GLColor::black, GLColor::red, GLColor::green, GLColor::yellow}};
303 std::array<GLColor, 4> baseColors2 = {
304 {GLColor::yellow, GLColor::green, GLColor::red, GLColor::black}};
305
306 std::vector<GLColor> colors1;
307 std::vector<GLColor> colors2;
308
309 for (GLushort index : indices)
310 {
311 colors1.push_back(baseColors1[index]);
312 colors2.push_back(baseColors2[index]);
313 }
314
315 GLBuffer color1Buffer;
316 glBindBuffer(GL_ARRAY_BUFFER, color1Buffer);
317 glBufferData(GL_ARRAY_BUFFER, colors1.size() * sizeof(GLColor), colors1.data(), GL_STATIC_DRAW);
318 glVertexAttribPointer(color1Loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, nullptr);
319 glEnableVertexAttribArray(color1Loc);
320
321 GLBuffer color2Buffer;
322 glBindBuffer(GL_ARRAY_BUFFER, color2Buffer);
323 glBufferData(GL_ARRAY_BUFFER, colors2.size() * sizeof(GLColor), colors2.data(), GL_STATIC_DRAW);
324 glVertexAttribPointer(color2Loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, nullptr);
325 glEnableVertexAttribArray(color2Loc);
326
327 // Draw a non-indexed quad with all vertex buffers. Should draw yellow to the entire window.
328 drawQuad(program, "position", 0.5f, 1.0f, true);
329 ASSERT_GL_NO_ERROR();
330 EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::yellow);
331}
332
Jamie Madillfa05f602015-05-07 13:47:11 -0400333// 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 -0500334ANGLE_INSTANTIATE_TEST(SimpleOperationTest,
335 ES2_D3D9(),
Austin Kinross2a63b3f2016-02-08 12:29:08 -0800336 ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE),
337 ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE),
Geoff Lange0cc2a42016-01-20 10:58:17 -0500338 ES3_D3D11(),
339 ES2_OPENGL(),
340 ES3_OPENGL(),
341 ES2_OPENGLES(),
Jamie Madillb8353b02017-01-25 12:57:21 -0800342 ES3_OPENGLES(),
343 ES2_VULKAN());
Jamie Madillfa05f602015-05-07 13:47:11 -0400344
345} // namespace