blob: 19a0f05994301fb0da597f9805b0bfbb00b64123 [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 Madillefb5a5c2018-01-29 15:56:59 -050088// Covers a simple bug in Vulkan to do with dependencies between the Surface and the default
89// Framebuffer.
90TEST_P(SimpleOperationTest, ClearAndSwap)
91{
92 glClearColor(1.0, 0.0, 0.0, 1.0);
93 glClear(GL_COLOR_BUFFER_BIT);
94 swapBuffers();
95
96 // Can't check the pixel result after the swap, and checking the pixel result affects the
97 // behaviour of the test on the Vulkan back-end, so don't bother checking correctness.
98 EXPECT_GL_NO_ERROR();
99 EXPECT_EGL_SUCCESS();
100}
101
Jamie Madillfa05f602015-05-07 13:47:11 -0400102TEST_P(SimpleOperationTest, LinkProgram)
Geoff Langb1f435e2015-02-20 10:01:01 -0500103{
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300104 const std::string vsSource =
105 R"(void main()
Geoff Langb1f435e2015-02-20 10:01:01 -0500106 {
107 gl_Position = vec4(1.0, 1.0, 1.0, 1.0);
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300108 })";
Geoff Langb1f435e2015-02-20 10:01:01 -0500109
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300110 const std::string fsSource =
111 R"(void main()
Geoff Langb1f435e2015-02-20 10:01:01 -0500112 {
113 gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300114 })";
Geoff Langb1f435e2015-02-20 10:01:01 -0500115
116 GLuint program = CompileProgram(vsSource, fsSource);
117 EXPECT_NE(program, 0u);
118 glDeleteProgram(program);
119
120 EXPECT_GL_NO_ERROR();
121}
122
Jamie Madillfa05f602015-05-07 13:47:11 -0400123TEST_P(SimpleOperationTest, LinkProgramWithUniforms)
Geoff Langb1f435e2015-02-20 10:01:01 -0500124{
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300125 const std::string vsSource =
126 R"(void main()
Geoff Langb1f435e2015-02-20 10:01:01 -0500127 {
128 gl_Position = vec4(1.0, 1.0, 1.0, 1.0);
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300129 })";
Geoff Langb1f435e2015-02-20 10:01:01 -0500130
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300131 const std::string fsSource =
132 R"(precision mediump float;
Geoff Langb1f435e2015-02-20 10:01:01 -0500133 uniform vec4 u_input;
134 void main()
135 {
136 gl_FragColor = u_input;
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300137 })";
Geoff Langb1f435e2015-02-20 10:01:01 -0500138
139 GLuint program = CompileProgram(vsSource, fsSource);
140 EXPECT_NE(program, 0u);
141
142 GLint uniformLoc = glGetUniformLocation(program, "u_input");
143 EXPECT_NE(-1, uniformLoc);
144
145 glDeleteProgram(program);
146
147 EXPECT_GL_NO_ERROR();
148}
149
Jamie Madillfa05f602015-05-07 13:47:11 -0400150TEST_P(SimpleOperationTest, LinkProgramWithAttributes)
Geoff Langb1f435e2015-02-20 10:01:01 -0500151{
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300152 const std::string vsSource =
153 R"(attribute vec4 a_input;
Geoff Langb1f435e2015-02-20 10:01:01 -0500154 void main()
155 {
156 gl_Position = a_input;
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300157 })";
Geoff Langb1f435e2015-02-20 10:01:01 -0500158
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300159 const std::string fsSource =
160 R"(void main()
Geoff Langb1f435e2015-02-20 10:01:01 -0500161 {
162 gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
Olli Etuahoa20af6d2017-09-18 13:32:29 +0300163 })";
Geoff Langb1f435e2015-02-20 10:01:01 -0500164
165 GLuint program = CompileProgram(vsSource, fsSource);
166 EXPECT_NE(program, 0u);
167
168 GLint attribLoc = glGetAttribLocation(program, "a_input");
169 EXPECT_NE(-1, attribLoc);
170
171 glDeleteProgram(program);
172
173 EXPECT_GL_NO_ERROR();
174}
Geoff Lang36c79012015-02-24 11:47:20 -0500175
Jamie Madillfa05f602015-05-07 13:47:11 -0400176TEST_P(SimpleOperationTest, BufferDataWithData)
Geoff Lang36c79012015-02-24 11:47:20 -0500177{
Jamie Madillcc6ac252017-01-25 12:57:21 -0800178 GLBuffer buffer;
179 glBindBuffer(GL_ARRAY_BUFFER, buffer.get());
Geoff Lang36c79012015-02-24 11:47:20 -0500180
181 std::vector<uint8_t> data(1024);
Jamie Madillcc6ac252017-01-25 12:57:21 -0800182 FillVectorWithRandomUBytes(&data);
Geoff Lang36c79012015-02-24 11:47:20 -0500183 glBufferData(GL_ARRAY_BUFFER, data.size(), &data[0], GL_STATIC_DRAW);
184
Jamie Madillcc6ac252017-01-25 12:57:21 -0800185 verifyBuffer(data, GL_ARRAY_BUFFER);
Geoff Lang36c79012015-02-24 11:47:20 -0500186
187 EXPECT_GL_NO_ERROR();
188}
189
Jamie Madillfa05f602015-05-07 13:47:11 -0400190TEST_P(SimpleOperationTest, BufferDataWithNoData)
Geoff Lang36c79012015-02-24 11:47:20 -0500191{
Jamie Madillcc6ac252017-01-25 12:57:21 -0800192 GLBuffer buffer;
193 glBindBuffer(GL_ARRAY_BUFFER, buffer.get());
Geoff Lang36c79012015-02-24 11:47:20 -0500194 glBufferData(GL_ARRAY_BUFFER, 1024, nullptr, GL_STATIC_DRAW);
Geoff Lang36c79012015-02-24 11:47:20 -0500195
196 EXPECT_GL_NO_ERROR();
197}
198
Jamie Madillfa05f602015-05-07 13:47:11 -0400199TEST_P(SimpleOperationTest, BufferSubData)
Geoff Lang36c79012015-02-24 11:47:20 -0500200{
Jamie Madillcc6ac252017-01-25 12:57:21 -0800201 GLBuffer buffer;
202 glBindBuffer(GL_ARRAY_BUFFER, buffer.get());
Geoff Lang36c79012015-02-24 11:47:20 -0500203
Jamie Madillcc6ac252017-01-25 12:57:21 -0800204 constexpr size_t bufferSize = 1024;
205 std::vector<uint8_t> data(bufferSize);
206 FillVectorWithRandomUBytes(&data);
207
Geoff Lang36c79012015-02-24 11:47:20 -0500208 glBufferData(GL_ARRAY_BUFFER, bufferSize, nullptr, GL_STATIC_DRAW);
209
Jamie Madillcc6ac252017-01-25 12:57:21 -0800210 constexpr size_t subDataCount = 16;
211 constexpr size_t sliceSize = bufferSize / subDataCount;
Geoff Lang36c79012015-02-24 11:47:20 -0500212 for (size_t i = 0; i < subDataCount; i++)
213 {
Jamie Madillcc6ac252017-01-25 12:57:21 -0800214 size_t offset = i * sliceSize;
215 glBufferSubData(GL_ARRAY_BUFFER, offset, sliceSize, &data[offset]);
Geoff Lang36c79012015-02-24 11:47:20 -0500216 }
217
Jamie Madillcc6ac252017-01-25 12:57:21 -0800218 verifyBuffer(data, GL_ARRAY_BUFFER);
Geoff Lang36c79012015-02-24 11:47:20 -0500219
220 EXPECT_GL_NO_ERROR();
221}
Jamie Madillfa05f602015-05-07 13:47:11 -0400222
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500223// Simple quad test.
224TEST_P(SimpleOperationTest, DrawQuad)
225{
226 const std::string &vertexShader =
227 "attribute vec3 position;\n"
228 "void main()\n"
229 "{\n"
230 " gl_Position = vec4(position, 1);\n"
231 "}";
232 const std::string &fragmentShader =
233 "void main()\n"
234 "{\n"
235 " gl_FragColor = vec4(0, 1, 0, 1);\n"
236 "}";
237 ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
238
239 drawQuad(program.get(), "position", 0.5f, 1.0f, true);
240
241 EXPECT_GL_NO_ERROR();
242 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
243}
244
Jamie Madilld03a8492017-10-03 15:46:06 -0400245// Simple repeated draw and swap test.
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500246TEST_P(SimpleOperationTest, DrawQuadAndSwap)
247{
Yuly Novikov47c98882018-01-08 15:01:11 -0500248 // anglebug.com/2301
249 ANGLE_SKIP_TEST_IF(IsLinux() && IsIntel() && IsVulkan());
250
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500251 const std::string &vertexShader =
252 "attribute vec3 position;\n"
253 "void main()\n"
254 "{\n"
255 " gl_Position = vec4(position, 1);\n"
256 "}";
257 const std::string &fragmentShader =
258 "void main()\n"
259 "{\n"
260 " gl_FragColor = vec4(0, 1, 0, 1);\n"
261 "}";
262 ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
263
264 for (int i = 0; i < 8; ++i)
265 {
266 drawQuad(program.get(), "position", 0.5f, 1.0f, true);
267 EXPECT_GL_NO_ERROR();
Jamie Madill4c26fc22017-02-24 11:04:10 -0500268 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
Jamie Madilldf68a6f2017-01-13 17:29:53 -0500269 swapBuffers();
270 }
271
272 EXPECT_GL_NO_ERROR();
273}
274
Jamie Madilld03a8492017-10-03 15:46:06 -0400275// Simple indexed quad test.
276TEST_P(SimpleOperationTest, DrawIndexedQuad)
277{
278 const std::string vertexShader =
279 "attribute vec3 position;\n"
280 "void main()\n"
281 "{\n"
282 " gl_Position = vec4(position, 1);\n"
283 "}";
284 const std::string fragmentShader =
285 "void main()\n"
286 "{\n"
287 " gl_FragColor = vec4(0, 1, 0, 1);\n"
288 "}";
289 ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
290
291 drawIndexedQuad(program.get(), "position", 0.5f, 1.0f, true);
292
293 EXPECT_GL_NO_ERROR();
294 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
295}
296
Jamie Madill76e471e2017-10-21 09:56:01 -0400297// Draw with a fragment uniform.
298TEST_P(SimpleOperationTest, DrawQuadWithFragmentUniform)
299{
300 const std::string &vertexShader =
301 "attribute vec3 position;\n"
302 "void main()\n"
303 "{\n"
304 " gl_Position = vec4(position, 1);\n"
305 "}";
306 const std::string &fragmentShader =
307 "uniform mediump vec4 color;\n"
308 "void main()\n"
309 "{\n"
310 " gl_FragColor = color;\n"
311 "}";
312 ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
313
314 GLint location = glGetUniformLocation(program, "color");
315 ASSERT_NE(-1, location);
316
317 glUseProgram(program);
318 glUniform4f(location, 0.0f, 1.0f, 0.0f, 1.0f);
319
320 drawQuad(program.get(), "position", 0.5f, 1.0f, true);
321
322 EXPECT_GL_NO_ERROR();
323 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
324}
325
326// Draw with a vertex uniform.
327TEST_P(SimpleOperationTest, DrawQuadWithVertexUniform)
328{
329 const std::string &vertexShader =
330 "attribute vec3 position;\n"
331 "uniform vec4 color;\n"
332 "varying vec4 vcolor;\n"
333 "void main()\n"
334 "{\n"
335 " gl_Position = vec4(position, 1);\n"
336 " vcolor = color;\n"
337 "}";
338 const std::string &fragmentShader =
339 "varying mediump vec4 vcolor;\n"
340 "void main()\n"
341 "{\n"
342 " gl_FragColor = vcolor;\n"
343 "}";
344 ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
345
346 GLint location = glGetUniformLocation(program, "color");
347 ASSERT_NE(-1, location);
348
349 glUseProgram(program);
350 glUniform4f(location, 0.0f, 1.0f, 0.0f, 1.0f);
351
352 drawQuad(program.get(), "position", 0.5f, 1.0f, true);
353
354 EXPECT_GL_NO_ERROR();
355 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
356}
357
358// Draw with two uniforms.
359TEST_P(SimpleOperationTest, DrawQuadWithTwoUniforms)
360{
361 const std::string &vertexShader =
362 "attribute vec3 position;\n"
363 "uniform vec4 color1;\n"
364 "varying vec4 vcolor1;\n"
365 "void main()\n"
366 "{\n"
367 " gl_Position = vec4(position, 1);\n"
368 " vcolor1 = color1;\n"
369 "}";
370 const std::string &fragmentShader =
371 "uniform mediump vec4 color2;\n"
372 "varying mediump vec4 vcolor1;\n"
373 "void main()\n"
374 "{\n"
375 " gl_FragColor = vcolor1 + color2;\n"
376 "}";
377 ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
378
379 GLint location1 = glGetUniformLocation(program, "color1");
380 ASSERT_NE(-1, location1);
381
382 GLint location2 = glGetUniformLocation(program, "color2");
383 ASSERT_NE(-1, location2);
384
385 glUseProgram(program);
386 glUniform4f(location1, 0.0f, 1.0f, 0.0f, 1.0f);
387 glUniform4f(location2, 1.0f, 0.0f, 0.0f, 1.0f);
388
389 drawQuad(program.get(), "position", 0.5f, 1.0f, true);
390
391 EXPECT_GL_NO_ERROR();
392 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
393}
394
Jamie Madill2a9e1072017-09-22 11:31:57 -0400395// Tests a shader program with more than one vertex attribute, with vertex buffers.
396TEST_P(SimpleOperationTest, ThreeVertexAttributes)
397{
398 const std::string vertexShader =
399 R"(attribute vec2 position;
400attribute vec4 color1;
401attribute vec4 color2;
402varying vec4 color;
403void main()
404{
405 gl_Position = vec4(position, 0, 1);
406 color = color1 + color2;
407})";
408
409 const std::string fragmentShader =
410 R"(precision mediump float;
411varying vec4 color;
412void main()
413{
414 gl_FragColor = color;
415}
416)";
417
418 ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
419
420 glUseProgram(program);
421
422 GLint color1Loc = glGetAttribLocation(program, "color1");
423 GLint color2Loc = glGetAttribLocation(program, "color2");
424 ASSERT_NE(-1, color1Loc);
425 ASSERT_NE(-1, color2Loc);
426
427 const auto &indices = GetQuadIndices();
428
429 // Make colored corners with red == x or 1 -x , and green = y or 1 - y.
430
431 std::array<GLColor, 4> baseColors1 = {
432 {GLColor::black, GLColor::red, GLColor::green, GLColor::yellow}};
433 std::array<GLColor, 4> baseColors2 = {
434 {GLColor::yellow, GLColor::green, GLColor::red, GLColor::black}};
435
436 std::vector<GLColor> colors1;
437 std::vector<GLColor> colors2;
438
439 for (GLushort index : indices)
440 {
441 colors1.push_back(baseColors1[index]);
442 colors2.push_back(baseColors2[index]);
443 }
444
445 GLBuffer color1Buffer;
446 glBindBuffer(GL_ARRAY_BUFFER, color1Buffer);
447 glBufferData(GL_ARRAY_BUFFER, colors1.size() * sizeof(GLColor), colors1.data(), GL_STATIC_DRAW);
448 glVertexAttribPointer(color1Loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, nullptr);
449 glEnableVertexAttribArray(color1Loc);
450
451 GLBuffer color2Buffer;
452 glBindBuffer(GL_ARRAY_BUFFER, color2Buffer);
453 glBufferData(GL_ARRAY_BUFFER, colors2.size() * sizeof(GLColor), colors2.data(), GL_STATIC_DRAW);
454 glVertexAttribPointer(color2Loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, nullptr);
455 glEnableVertexAttribArray(color2Loc);
456
457 // Draw a non-indexed quad with all vertex buffers. Should draw yellow to the entire window.
458 drawQuad(program, "position", 0.5f, 1.0f, true);
459 ASSERT_GL_NO_ERROR();
460 EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::yellow);
461}
462
Jamie Madill035fd6b2017-10-03 15:43:22 -0400463// Creates a texture, no other operations.
464TEST_P(SimpleOperationTest, CreateTexture2DNoData)
465{
466 GLTexture texture;
467 glBindTexture(GL_TEXTURE_2D, texture);
468 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
469 ASSERT_GL_NO_ERROR();
470}
471
472// Creates a texture, no other operations.
473TEST_P(SimpleOperationTest, CreateTexture2DWithData)
474{
475 std::vector<GLColor> colors(16 * 16, GLColor::red);
476
477 GLTexture texture;
478 glBindTexture(GL_TEXTURE_2D, texture);
479 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
480 ASSERT_GL_NO_ERROR();
481}
482
Jamie Madillde03e002017-10-21 14:04:20 -0400483// Creates a program with a texture.
484TEST_P(SimpleOperationTest, LinkProgramWithTexture)
485{
486 ASSERT_NE(0u, get2DTexturedQuadProgram());
487 EXPECT_GL_NO_ERROR();
488}
489
Jamie Madill5547b382017-10-23 18:16:01 -0400490// Creates a program with a texture and renders with it.
491TEST_P(SimpleOperationTest, DrawWithTexture)
492{
493 std::array<GLColor, 4> colors = {
494 {GLColor::red, GLColor::green, GLColor::blue, GLColor::yellow}};
495
496 GLTexture tex;
497 glBindTexture(GL_TEXTURE_2D, tex);
498 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors.data());
499 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
500 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
501
502 draw2DTexturedQuad(0.5f, 1.0f, true);
503 EXPECT_GL_NO_ERROR();
504
505 int w = getWindowWidth() - 2;
506 int h = getWindowHeight() - 2;
507
508 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
509 EXPECT_PIXEL_COLOR_EQ(w, 0, GLColor::green);
510 EXPECT_PIXEL_COLOR_EQ(0, h, GLColor::blue);
511 EXPECT_PIXEL_COLOR_EQ(w, h, GLColor::yellow);
512}
513
Jamie Madillb79e7bb2017-10-24 13:55:50 -0400514// Tests rendering to a user framebuffer.
515TEST_P(SimpleOperationTest, RenderToTexture)
516{
517 constexpr int kSize = 16;
518
519 GLTexture texture;
520 glBindTexture(GL_TEXTURE_2D, texture);
521 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
522 ASSERT_GL_NO_ERROR();
523
524 GLFramebuffer framebuffer;
525 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
526 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
527 ASSERT_GL_NO_ERROR();
528 ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
529
530 glViewport(0, 0, kSize, kSize);
531
532 const std::string &vertexShader =
533 "attribute vec3 position;\n"
534 "void main()\n"
535 "{\n"
536 " gl_Position = vec4(position, 1);\n"
537 "}";
538 const std::string &fragmentShader =
539 "void main()\n"
540 "{\n"
541 " gl_FragColor = vec4(0, 1, 0, 1);\n"
542 "}";
543 ANGLE_GL_PROGRAM(program, vertexShader, fragmentShader);
544 drawQuad(program, "position", 0.5f, 1.0f, true);
545 ASSERT_GL_NO_ERROR();
546 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
547}
548
Jamie Madillfa05f602015-05-07 13:47:11 -0400549// 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 -0500550ANGLE_INSTANTIATE_TEST(SimpleOperationTest,
551 ES2_D3D9(),
Austin Kinross2a63b3f2016-02-08 12:29:08 -0800552 ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_COPY_ANGLE),
553 ES2_D3D11(EGL_EXPERIMENTAL_PRESENT_PATH_FAST_ANGLE),
Geoff Lange0cc2a42016-01-20 10:58:17 -0500554 ES3_D3D11(),
555 ES2_OPENGL(),
556 ES3_OPENGL(),
557 ES2_OPENGLES(),
Jamie Madillb8353b02017-01-25 12:57:21 -0800558 ES3_OPENGLES(),
559 ES2_VULKAN());
Jamie Madillfa05f602015-05-07 13:47:11 -0400560
561} // namespace