blob: bf48c55336ac969695a9ea000da3c53e98b38d9b [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{
154 // Clear backbuffer to red
155 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
156 glClear(GL_COLOR_BUFFER_BIT);
157 EXPECT_GL_NO_ERROR();
158
159 // Read 16x16 region from red backbuffer to PBO
160 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
161 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
162
163 // Clear backbuffer to green
164 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
165 glClear(GL_COLOR_BUFFER_BIT);
166 EXPECT_GL_NO_ERROR();
167
168 // Read 16x16 region from green backbuffer to PBO at offset 16
169 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<GLvoid*>(16));
170 GLvoid * mappedPtr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, 32, GL_MAP_READ_BIT);
171 unsigned char *dataPtr = static_cast<unsigned char *>(mappedPtr);
172 EXPECT_GL_NO_ERROR();
173
174 // Test pixel 0 is red (existing data)
175 EXPECT_EQ(255, dataPtr[0]);
176 EXPECT_EQ(0, dataPtr[1]);
177 EXPECT_EQ(0, dataPtr[2]);
178 EXPECT_EQ(255, dataPtr[3]);
179
180 // Test pixel 16 is green (new data)
181 EXPECT_EQ(0, dataPtr[16 * 4 + 0]);
182 EXPECT_EQ(255, dataPtr[16 * 4 + 1]);
183 EXPECT_EQ(0, dataPtr[16 * 4 + 2]);
184 EXPECT_EQ(255, dataPtr[16 * 4 + 3]);
185
186 glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
187 EXPECT_GL_NO_ERROR();
188}
Jamie Madill14764a02014-05-08 10:19:20 -0400189
Jamie Madillfa05f602015-05-07 13:47:11 -0400190TEST_P(ReadPixelsTest, PBOAndSubData)
Jamie Madill14764a02014-05-08 10:19:20 -0400191{
192 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
193 glClear(GL_COLOR_BUFFER_BIT);
194 EXPECT_GL_NO_ERROR();
195
196 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
197 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
198
199 unsigned char data[4] = { 1, 2, 3, 4 };
200
201 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
202 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
203 glBufferSubData(GL_ARRAY_BUFFER, 0, 4, data);
204
205 GLvoid *mappedPtr = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
206 unsigned char *dataPtr = static_cast<unsigned char *>(mappedPtr);
207 EXPECT_GL_NO_ERROR();
208
209 EXPECT_EQ(1, dataPtr[0]);
210 EXPECT_EQ(2, dataPtr[1]);
211 EXPECT_EQ(3, dataPtr[2]);
212 EXPECT_EQ(4, dataPtr[3]);
213
214 glUnmapBuffer(GL_ARRAY_BUFFER);
215 EXPECT_GL_NO_ERROR();
216}
217
Jamie Madillfa05f602015-05-07 13:47:11 -0400218TEST_P(ReadPixelsTest, PBOAndSubDataOffset)
Jamie Madill14764a02014-05-08 10:19:20 -0400219{
220 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
221 glClear(GL_COLOR_BUFFER_BIT);
222 EXPECT_GL_NO_ERROR();
223
224 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
225 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
226
227 unsigned char data[4] = { 1, 2, 3, 4 };
228
229 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
230 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
231 glBufferSubData(GL_ARRAY_BUFFER, 16, 4, data);
232
233 GLvoid *mappedPtr = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
234 unsigned char *dataPtr = static_cast<unsigned char *>(mappedPtr);
235 EXPECT_GL_NO_ERROR();
236
237 EXPECT_EQ(255, dataPtr[0]);
238 EXPECT_EQ(0, dataPtr[1]);
239 EXPECT_EQ(0, dataPtr[2]);
240 EXPECT_EQ(255, dataPtr[3]);
241
242 EXPECT_EQ(1, dataPtr[16]);
243 EXPECT_EQ(2, dataPtr[17]);
244 EXPECT_EQ(3, dataPtr[18]);
245 EXPECT_EQ(4, dataPtr[19]);
246
247 glUnmapBuffer(GL_ARRAY_BUFFER);
248 EXPECT_GL_NO_ERROR();
249}
Jamie Madill5fedd012014-05-08 10:19:36 -0400250
Jamie Madillfa05f602015-05-07 13:47:11 -0400251TEST_P(ReadPixelsTest, DrawWithPBO)
Jamie Madill5fedd012014-05-08 10:19:36 -0400252{
253 unsigned char data[4] = { 1, 2, 3, 4 };
254
255 glBindTexture(GL_TEXTURE_2D, mTexture);
256 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data);
257 EXPECT_GL_NO_ERROR();
258
259 // glReadBuffer(GL_COLOR_ATTACHMENT0); // FIXME: currently UNIMPLEMENTED
260 glBindFramebuffer(GL_READ_FRAMEBUFFER, mFBO);
261 EXPECT_GL_NO_ERROR();
262
263 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
264 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 0);
265 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
266 EXPECT_GL_NO_ERROR();
267
268 float positionData[] = { 0.5f, 0.5f };
269
270 glUseProgram(mProgram);
271 glViewport(0, 0, 1, 1);
272 glBindBuffer(GL_ARRAY_BUFFER, mPositionVBO);
273 glBufferSubData(GL_ARRAY_BUFFER, 0, 1 * 2 * 4, positionData);
274 EXPECT_GL_NO_ERROR();
275
276 GLint positionLocation = glGetAttribLocation(mProgram, "aPosition");
277 EXPECT_NE(-1, positionLocation);
278
279 GLint testLocation = glGetAttribLocation(mProgram, "aTest");
280 EXPECT_NE(-1, testLocation);
281
282 glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
283 glEnableVertexAttribArray(positionLocation);
284 EXPECT_GL_NO_ERROR();
285
286 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
287 glVertexAttribPointer(testLocation, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0, 0);
288 glEnableVertexAttribArray(testLocation);
289 EXPECT_GL_NO_ERROR();
290
291 glDrawArrays(GL_POINTS, 0, 1);
292 EXPECT_GL_NO_ERROR();
293
294 memset(data, 0, 4);
295 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data);
296 EXPECT_GL_NO_ERROR();
297
298 EXPECT_EQ(1, data[0]);
299 EXPECT_EQ(2, data[1]);
300 EXPECT_EQ(3, data[2]);
301 EXPECT_EQ(4, data[3]);
302}
Jamie Madill4fbd36e2014-07-29 15:20:48 -0400303
Jamie Madillfa05f602015-05-07 13:47:11 -0400304TEST_P(ReadPixelsTest, MultisampledPBO)
Jamie Madill4fbd36e2014-07-29 15:20:48 -0400305{
Geoff Langa8091652015-04-27 10:53:55 -0400306 if (getClientVersion() < 3 && !extensionEnabled("GL_ANGLE_framebuffer_multisample"))
307 {
308 std::cout << "Test skipped because ES3 or GL_ANGLE_framebuffer_multisample is not available." << std::endl;
309 return;
310 }
311
Jamie Madill4fbd36e2014-07-29 15:20:48 -0400312 GLuint fbo;
313 glGenFramebuffers(1, &fbo);
314 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
315
316 GLuint rbo;
317 glGenRenderbuffers(1, &rbo);
318 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
Geoff Langa8091652015-04-27 10:53:55 -0400319
320 if (extensionEnabled("GL_ANGLE_framebuffer_multisample"))
321 {
322 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 2, GL_RGBA8, 4, 4);
323 }
324 else
325 {
326 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_RGBA8, 4, 4);
327 }
Jamie Madill4fbd36e2014-07-29 15:20:48 -0400328
329 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
330
331 ASSERT_GL_NO_ERROR();
332
333 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
334 glClear(GL_COLOR_BUFFER_BIT);
335
336 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
337
338 EXPECT_GL_NO_ERROR();
339
340 glReadPixels(0, 0, 1, 1, GL_RGBA8, GL_UNSIGNED_BYTE, NULL);
341
342 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
343
344 glDeleteRenderbuffers(1, &rbo);
345 glDeleteFramebuffers(1, &fbo);
346}
Jamie Madillfa05f602015-05-07 13:47:11 -0400347
348// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
349ANGLE_INSTANTIATE_TEST(ReadPixelsTest, ES3_D3D11());