blob: 5e219b3e0620783f095de64a3dbcc4a07a0fc564 [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
Corentin Wallezd3970de2015-05-14 11:07:48 -04007#include "test_utils/ANGLETest.h"
Geoff Langf11dbdb2013-10-23 14:37:58 -04008
Jamie Madillfa05f602015-05-07 13:47:11 -04009using namespace angle;
Austin Kinross18b931d2014-09-29 12:58:31 -070010
Geoff Langf11dbdb2013-10-23 14:37:58 -040011class ReadPixelsTest : public ANGLETest
12{
Jamie Madillfa05f602015-05-07 13:47:11 -040013 protected:
14 ReadPixelsTest()
Geoff Langf11dbdb2013-10-23 14:37:58 -040015 {
16 setWindowWidth(32);
17 setWindowHeight(32);
18 setConfigRedBits(8);
19 setConfigGreenBits(8);
20 setConfigBlueBits(8);
21 setConfigAlphaBits(8);
22 }
Jamie Madill8a7bed82014-05-01 14:51:07 -040023
24 virtual void SetUp()
25 {
26 ANGLETest::SetUp();
27
28 glGenBuffers(1, &mPBO);
29 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
30 glBufferData(GL_PIXEL_PACK_BUFFER, 4 * getWindowWidth() * getWindowHeight(), NULL, GL_STATIC_DRAW);
31 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
32
33 const char *vertexShaderSrc = SHADER_SOURCE
34 (
35 attribute vec4 aTest;
36 attribute vec2 aPosition;
37 varying vec4 vTest;
38
39 void main()
40 {
41 vTest = aTest;
42 gl_Position = vec4(aPosition, 0.0, 1.0);
43 gl_PointSize = 1.0;
44 }
45 );
46
47 const char *fragmentShaderSrc = SHADER_SOURCE
48 (
49 precision mediump float;
50 varying vec4 vTest;
51
52 void main()
53 {
54 gl_FragColor = vTest;
55 }
56 );
57
Jamie Madill5599c8f2014-08-26 13:16:39 -040058 mProgram = CompileProgram(vertexShaderSrc, fragmentShaderSrc);
Jamie Madill8a7bed82014-05-01 14:51:07 -040059
60 glGenTextures(1, &mTexture);
61 glBindTexture(GL_TEXTURE_2D, mTexture);
62 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 4, 1);
63
64 glGenFramebuffers(1, &mFBO);
65 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
66 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
67 glBindFramebuffer(GL_FRAMEBUFFER, 0);
68
69 glGenBuffers(1, &mPositionVBO);
70 glBindBuffer(GL_ARRAY_BUFFER, mPositionVBO);
71 glBufferData(GL_ARRAY_BUFFER, 128, NULL, GL_DYNAMIC_DRAW);
72 glBindBuffer(GL_ARRAY_BUFFER, 0);
73
74 ASSERT_GL_NO_ERROR();
75 }
76
77 virtual void TearDown()
78 {
79 ANGLETest::TearDown();
80
81 glDeleteBuffers(1, &mPBO);
82 glDeleteProgram(mProgram);
83 glDeleteTextures(1, &mTexture);
84 glDeleteFramebuffers(1, &mFBO);
85 }
86
87 GLuint mPBO;
88 GLuint mProgram;
89 GLuint mTexture;
90 GLuint mFBO;
91 GLuint mPositionVBO;
Geoff Langf11dbdb2013-10-23 14:37:58 -040092};
93
Jamie Madillfa05f602015-05-07 13:47:11 -040094TEST_P(ReadPixelsTest, OutOfBounds)
Geoff Langf11dbdb2013-10-23 14:37:58 -040095{
96 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
97 glClear(GL_COLOR_BUFFER_BIT);
98 EXPECT_GL_NO_ERROR();
99
100 GLsizei pixelsWidth = 32;
101 GLsizei pixelsHeight = 32;
Jamie Madill1eb5bd72014-03-28 10:43:39 -0400102 GLint offset = 16;
103 std::vector<GLubyte> pixels((pixelsWidth + offset) * (pixelsHeight + offset) * 4);
Geoff Langf11dbdb2013-10-23 14:37:58 -0400104
Jamie Madillb4fd0c92014-10-01 17:40:24 -0400105 glReadPixels(-offset, -offset, pixelsWidth + offset, pixelsHeight + offset, GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]);
Geoff Langf11dbdb2013-10-23 14:37:58 -0400106 EXPECT_GL_NO_ERROR();
107
108 for (int y = pixelsHeight / 2; y < pixelsHeight; y++)
109 {
110 for (int x = pixelsWidth / 2; x < pixelsWidth; x++)
111 {
Jamie Madillb4fd0c92014-10-01 17:40:24 -0400112 const GLubyte* pixel = &pixels[0] + ((y * (pixelsWidth + offset) + x) * 4);
Jamie Madill1eb5bd72014-03-28 10:43:39 -0400113 unsigned int r = static_cast<unsigned int>(pixel[0]);
114 unsigned int g = static_cast<unsigned int>(pixel[1]);
115 unsigned int b = static_cast<unsigned int>(pixel[2]);
116 unsigned int a = static_cast<unsigned int>(pixel[3]);
Geoff Langf11dbdb2013-10-23 14:37:58 -0400117
118 // Expect that all pixels which fell within the framebuffer are red
Corentin Wallez322653b2015-06-17 18:33:56 +0200119 EXPECT_EQ(255u, r);
120 EXPECT_EQ(0u, g);
121 EXPECT_EQ(0u, b);
122 EXPECT_EQ(255u, a);
Geoff Langf11dbdb2013-10-23 14:37:58 -0400123 }
124 }
125}
Jamie Madill8a7bed82014-05-01 14:51:07 -0400126
Jamie Madillfa05f602015-05-07 13:47:11 -0400127TEST_P(ReadPixelsTest, PBOWithOtherTarget)
Jamie Madill8a7bed82014-05-01 14:51:07 -0400128{
129 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
130 glClear(GL_COLOR_BUFFER_BIT);
131 EXPECT_GL_NO_ERROR();
132
133 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
134 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
135
136 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
137 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
138
139 GLvoid *mappedPtr = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
140 unsigned char *dataPtr = static_cast<unsigned char *>(mappedPtr);
141 EXPECT_GL_NO_ERROR();
142
143 EXPECT_EQ(255, dataPtr[0]);
144 EXPECT_EQ(0, dataPtr[1]);
145 EXPECT_EQ(0, dataPtr[2]);
146 EXPECT_EQ(255, dataPtr[3]);
147
148 glUnmapBuffer(GL_ARRAY_BUFFER);
149 EXPECT_GL_NO_ERROR();
150}
Jamie Madill2b5c9cb2014-04-29 16:17:22 -0400151
Jamie Madillfa05f602015-05-07 13:47:11 -0400152TEST_P(ReadPixelsTest, PBOWithExistingData)
Jamie Madill2b5c9cb2014-04-29 16:17:22 -0400153{
Geoff Lange0cc2a42016-01-20 10:58:17 -0500154 // TODO(geofflang): Figure out why this fails on AMD OpenGL (http://anglebug.com/1291)
155 if (isAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
156 {
157 std::cout << "Test disabled on AMD OpenGL." << std::endl;
158 return;
159 }
160
Jamie Madill2b5c9cb2014-04-29 16:17:22 -0400161 // Clear backbuffer to red
162 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
163 glClear(GL_COLOR_BUFFER_BIT);
164 EXPECT_GL_NO_ERROR();
165
166 // Read 16x16 region from red backbuffer to PBO
167 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
168 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
169
170 // Clear backbuffer to green
171 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
172 glClear(GL_COLOR_BUFFER_BIT);
173 EXPECT_GL_NO_ERROR();
174
175 // Read 16x16 region from green backbuffer to PBO at offset 16
176 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<GLvoid*>(16));
177 GLvoid * mappedPtr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, 32, GL_MAP_READ_BIT);
178 unsigned char *dataPtr = static_cast<unsigned char *>(mappedPtr);
179 EXPECT_GL_NO_ERROR();
180
181 // Test pixel 0 is red (existing data)
182 EXPECT_EQ(255, dataPtr[0]);
183 EXPECT_EQ(0, dataPtr[1]);
184 EXPECT_EQ(0, dataPtr[2]);
185 EXPECT_EQ(255, dataPtr[3]);
186
187 // Test pixel 16 is green (new data)
188 EXPECT_EQ(0, dataPtr[16 * 4 + 0]);
189 EXPECT_EQ(255, dataPtr[16 * 4 + 1]);
190 EXPECT_EQ(0, dataPtr[16 * 4 + 2]);
191 EXPECT_EQ(255, dataPtr[16 * 4 + 3]);
192
193 glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
194 EXPECT_GL_NO_ERROR();
195}
Jamie Madill14764a02014-05-08 10:19:20 -0400196
Jamie Madillfa05f602015-05-07 13:47:11 -0400197TEST_P(ReadPixelsTest, PBOAndSubData)
Jamie Madill14764a02014-05-08 10:19:20 -0400198{
199 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
200 glClear(GL_COLOR_BUFFER_BIT);
201 EXPECT_GL_NO_ERROR();
202
203 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
204 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
205
206 unsigned char data[4] = { 1, 2, 3, 4 };
207
208 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
209 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
210 glBufferSubData(GL_ARRAY_BUFFER, 0, 4, data);
211
212 GLvoid *mappedPtr = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
213 unsigned char *dataPtr = static_cast<unsigned char *>(mappedPtr);
214 EXPECT_GL_NO_ERROR();
215
216 EXPECT_EQ(1, dataPtr[0]);
217 EXPECT_EQ(2, dataPtr[1]);
218 EXPECT_EQ(3, dataPtr[2]);
219 EXPECT_EQ(4, dataPtr[3]);
220
221 glUnmapBuffer(GL_ARRAY_BUFFER);
222 EXPECT_GL_NO_ERROR();
223}
224
Jamie Madillfa05f602015-05-07 13:47:11 -0400225TEST_P(ReadPixelsTest, PBOAndSubDataOffset)
Jamie Madill14764a02014-05-08 10:19:20 -0400226{
227 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
228 glClear(GL_COLOR_BUFFER_BIT);
229 EXPECT_GL_NO_ERROR();
230
231 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
232 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
233
234 unsigned char data[4] = { 1, 2, 3, 4 };
235
236 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
237 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
238 glBufferSubData(GL_ARRAY_BUFFER, 16, 4, data);
239
240 GLvoid *mappedPtr = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
241 unsigned char *dataPtr = static_cast<unsigned char *>(mappedPtr);
242 EXPECT_GL_NO_ERROR();
243
244 EXPECT_EQ(255, dataPtr[0]);
245 EXPECT_EQ(0, dataPtr[1]);
246 EXPECT_EQ(0, dataPtr[2]);
247 EXPECT_EQ(255, dataPtr[3]);
248
249 EXPECT_EQ(1, dataPtr[16]);
250 EXPECT_EQ(2, dataPtr[17]);
251 EXPECT_EQ(3, dataPtr[18]);
252 EXPECT_EQ(4, dataPtr[19]);
253
254 glUnmapBuffer(GL_ARRAY_BUFFER);
255 EXPECT_GL_NO_ERROR();
256}
Jamie Madill5fedd012014-05-08 10:19:36 -0400257
Jamie Madillfa05f602015-05-07 13:47:11 -0400258TEST_P(ReadPixelsTest, DrawWithPBO)
Jamie Madill5fedd012014-05-08 10:19:36 -0400259{
260 unsigned char data[4] = { 1, 2, 3, 4 };
261
262 glBindTexture(GL_TEXTURE_2D, mTexture);
263 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data);
264 EXPECT_GL_NO_ERROR();
265
Jamie Madill5fedd012014-05-08 10:19:36 -0400266 glBindFramebuffer(GL_READ_FRAMEBUFFER, mFBO);
267 EXPECT_GL_NO_ERROR();
268
269 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
270 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 0);
271 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
272 EXPECT_GL_NO_ERROR();
273
274 float positionData[] = { 0.5f, 0.5f };
275
276 glUseProgram(mProgram);
277 glViewport(0, 0, 1, 1);
278 glBindBuffer(GL_ARRAY_BUFFER, mPositionVBO);
279 glBufferSubData(GL_ARRAY_BUFFER, 0, 1 * 2 * 4, positionData);
280 EXPECT_GL_NO_ERROR();
281
282 GLint positionLocation = glGetAttribLocation(mProgram, "aPosition");
283 EXPECT_NE(-1, positionLocation);
284
285 GLint testLocation = glGetAttribLocation(mProgram, "aTest");
286 EXPECT_NE(-1, testLocation);
287
288 glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
289 glEnableVertexAttribArray(positionLocation);
290 EXPECT_GL_NO_ERROR();
291
292 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
293 glVertexAttribPointer(testLocation, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0, 0);
294 glEnableVertexAttribArray(testLocation);
295 EXPECT_GL_NO_ERROR();
296
297 glDrawArrays(GL_POINTS, 0, 1);
298 EXPECT_GL_NO_ERROR();
299
300 memset(data, 0, 4);
301 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data);
302 EXPECT_GL_NO_ERROR();
303
304 EXPECT_EQ(1, data[0]);
305 EXPECT_EQ(2, data[1]);
306 EXPECT_EQ(3, data[2]);
307 EXPECT_EQ(4, data[3]);
308}
Jamie Madill4fbd36e2014-07-29 15:20:48 -0400309
Jamie Madillfa05f602015-05-07 13:47:11 -0400310TEST_P(ReadPixelsTest, MultisampledPBO)
Jamie Madill4fbd36e2014-07-29 15:20:48 -0400311{
Geoff Langa8091652015-04-27 10:53:55 -0400312 if (getClientVersion() < 3 && !extensionEnabled("GL_ANGLE_framebuffer_multisample"))
313 {
314 std::cout << "Test skipped because ES3 or GL_ANGLE_framebuffer_multisample is not available." << std::endl;
315 return;
316 }
317
Jamie Madill4fbd36e2014-07-29 15:20:48 -0400318 GLuint fbo;
319 glGenFramebuffers(1, &fbo);
320 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
321
322 GLuint rbo;
323 glGenRenderbuffers(1, &rbo);
324 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
Geoff Langa8091652015-04-27 10:53:55 -0400325
326 if (extensionEnabled("GL_ANGLE_framebuffer_multisample"))
327 {
328 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 2, GL_RGBA8, 4, 4);
329 }
330 else
331 {
332 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_RGBA8, 4, 4);
333 }
Jamie Madill4fbd36e2014-07-29 15:20:48 -0400334
335 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
336
337 ASSERT_GL_NO_ERROR();
338
339 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
340 glClear(GL_COLOR_BUFFER_BIT);
341
342 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
343
344 EXPECT_GL_NO_ERROR();
345
346 glReadPixels(0, 0, 1, 1, GL_RGBA8, GL_UNSIGNED_BYTE, NULL);
347
348 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
349
350 glDeleteRenderbuffers(1, &rbo);
351 glDeleteFramebuffers(1, &fbo);
352}
Jamie Madillfa05f602015-05-07 13:47:11 -0400353
354// 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 -0500355ANGLE_INSTANTIATE_TEST(ReadPixelsTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());