blob: 8d5c077a97163696e9a716f6525207f0ae64d260 [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//
Jamie Madill3e1b4f82016-01-27 12:39:27 -05006// ReadPixelsTest:
7// Tests calls related to glReadPixels.
8//
Jamie Madillfa05f602015-05-07 13:47:11 -04009
Corentin Wallezd3970de2015-05-14 11:07:48 -040010#include "test_utils/ANGLETest.h"
Geoff Langf11dbdb2013-10-23 14:37:58 -040011
Jamie Madill3e1b4f82016-01-27 12:39:27 -050012#include <array>
13
14#include "random_utils.h"
15
Jamie Madillfa05f602015-05-07 13:47:11 -040016using namespace angle;
Austin Kinross18b931d2014-09-29 12:58:31 -070017
Jamie Madill3e1b4f82016-01-27 12:39:27 -050018namespace
19{
20
Geoff Langf11dbdb2013-10-23 14:37:58 -040021class ReadPixelsTest : public ANGLETest
22{
Jamie Madillfa05f602015-05-07 13:47:11 -040023 protected:
24 ReadPixelsTest()
Geoff Langf11dbdb2013-10-23 14:37:58 -040025 {
26 setWindowWidth(32);
27 setWindowHeight(32);
28 setConfigRedBits(8);
29 setConfigGreenBits(8);
30 setConfigBlueBits(8);
31 setConfigAlphaBits(8);
32 }
33};
34
Jamie Madill3e1b4f82016-01-27 12:39:27 -050035// Test out of bounds reads.
Jamie Madillfa05f602015-05-07 13:47:11 -040036TEST_P(ReadPixelsTest, OutOfBounds)
Geoff Langf11dbdb2013-10-23 14:37:58 -040037{
38 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
39 glClear(GL_COLOR_BUFFER_BIT);
40 EXPECT_GL_NO_ERROR();
41
42 GLsizei pixelsWidth = 32;
43 GLsizei pixelsHeight = 32;
Jamie Madill1eb5bd72014-03-28 10:43:39 -040044 GLint offset = 16;
45 std::vector<GLubyte> pixels((pixelsWidth + offset) * (pixelsHeight + offset) * 4);
Geoff Langf11dbdb2013-10-23 14:37:58 -040046
Jamie Madillb4fd0c92014-10-01 17:40:24 -040047 glReadPixels(-offset, -offset, pixelsWidth + offset, pixelsHeight + offset, GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]);
Geoff Langf11dbdb2013-10-23 14:37:58 -040048 EXPECT_GL_NO_ERROR();
49
50 for (int y = pixelsHeight / 2; y < pixelsHeight; y++)
51 {
52 for (int x = pixelsWidth / 2; x < pixelsWidth; x++)
53 {
Jamie Madillb4fd0c92014-10-01 17:40:24 -040054 const GLubyte* pixel = &pixels[0] + ((y * (pixelsWidth + offset) + x) * 4);
Jamie Madill1eb5bd72014-03-28 10:43:39 -040055 unsigned int r = static_cast<unsigned int>(pixel[0]);
56 unsigned int g = static_cast<unsigned int>(pixel[1]);
57 unsigned int b = static_cast<unsigned int>(pixel[2]);
58 unsigned int a = static_cast<unsigned int>(pixel[3]);
Geoff Langf11dbdb2013-10-23 14:37:58 -040059
60 // Expect that all pixels which fell within the framebuffer are red
Corentin Wallez322653b2015-06-17 18:33:56 +020061 EXPECT_EQ(255u, r);
62 EXPECT_EQ(0u, g);
63 EXPECT_EQ(0u, b);
64 EXPECT_EQ(255u, a);
Geoff Langf11dbdb2013-10-23 14:37:58 -040065 }
66 }
67}
Jamie Madill8a7bed82014-05-01 14:51:07 -040068
Jamie Madill3e1b4f82016-01-27 12:39:27 -050069class ReadPixelsPBOTest : public ReadPixelsTest
70{
71 protected:
72 ReadPixelsPBOTest() : mPBO(0), mTexture(0), mFBO(0) {}
73
74 void SetUp() override
75 {
76 ANGLETest::SetUp();
77
78 glGenBuffers(1, &mPBO);
79 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
80 glBufferData(GL_PIXEL_PACK_BUFFER, 4 * getWindowWidth() * getWindowHeight(), nullptr,
81 GL_STATIC_DRAW);
82 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
83
84 glGenTextures(1, &mTexture);
85 glBindTexture(GL_TEXTURE_2D, mTexture);
86 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 4, 1);
87
88 glGenFramebuffers(1, &mFBO);
89 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
90 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
91 glBindFramebuffer(GL_FRAMEBUFFER, 0);
92
93 ASSERT_GL_NO_ERROR();
94 }
95
96 void TearDown() override
97 {
98 ANGLETest::TearDown();
99
100 glDeleteBuffers(1, &mPBO);
101 glDeleteTextures(1, &mTexture);
102 glDeleteFramebuffers(1, &mFBO);
103 }
104
105 GLuint mPBO;
106 GLuint mTexture;
107 GLuint mFBO;
108};
109
110// Test that binding a PBO to ARRAY_BUFFER works as expected.
111TEST_P(ReadPixelsPBOTest, ArrayBufferTarget)
Jamie Madill8a7bed82014-05-01 14:51:07 -0400112{
113 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
114 glClear(GL_COLOR_BUFFER_BIT);
115 EXPECT_GL_NO_ERROR();
116
117 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
118 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
119
120 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
121 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
122
123 GLvoid *mappedPtr = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
124 unsigned char *dataPtr = static_cast<unsigned char *>(mappedPtr);
125 EXPECT_GL_NO_ERROR();
126
127 EXPECT_EQ(255, dataPtr[0]);
128 EXPECT_EQ(0, dataPtr[1]);
129 EXPECT_EQ(0, dataPtr[2]);
130 EXPECT_EQ(255, dataPtr[3]);
131
132 glUnmapBuffer(GL_ARRAY_BUFFER);
133 EXPECT_GL_NO_ERROR();
134}
Jamie Madill2b5c9cb2014-04-29 16:17:22 -0400135
Jamie Madill3e1b4f82016-01-27 12:39:27 -0500136// Test that using a PBO does not overwrite existing data.
137TEST_P(ReadPixelsPBOTest, ExistingDataPreserved)
Jamie Madill2b5c9cb2014-04-29 16:17:22 -0400138{
Geoff Lange0cc2a42016-01-20 10:58:17 -0500139 // TODO(geofflang): Figure out why this fails on AMD OpenGL (http://anglebug.com/1291)
140 if (isAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
141 {
142 std::cout << "Test disabled on AMD OpenGL." << std::endl;
143 return;
144 }
145
Jamie Madill2b5c9cb2014-04-29 16:17:22 -0400146 // Clear backbuffer to red
147 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
148 glClear(GL_COLOR_BUFFER_BIT);
149 EXPECT_GL_NO_ERROR();
150
151 // Read 16x16 region from red backbuffer to PBO
152 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
153 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
154
155 // Clear backbuffer to green
156 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
157 glClear(GL_COLOR_BUFFER_BIT);
158 EXPECT_GL_NO_ERROR();
159
160 // Read 16x16 region from green backbuffer to PBO at offset 16
161 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<GLvoid*>(16));
162 GLvoid * mappedPtr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, 32, GL_MAP_READ_BIT);
163 unsigned char *dataPtr = static_cast<unsigned char *>(mappedPtr);
164 EXPECT_GL_NO_ERROR();
165
166 // Test pixel 0 is red (existing data)
167 EXPECT_EQ(255, dataPtr[0]);
168 EXPECT_EQ(0, dataPtr[1]);
169 EXPECT_EQ(0, dataPtr[2]);
170 EXPECT_EQ(255, dataPtr[3]);
171
172 // Test pixel 16 is green (new data)
173 EXPECT_EQ(0, dataPtr[16 * 4 + 0]);
174 EXPECT_EQ(255, dataPtr[16 * 4 + 1]);
175 EXPECT_EQ(0, dataPtr[16 * 4 + 2]);
176 EXPECT_EQ(255, dataPtr[16 * 4 + 3]);
177
178 glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
179 EXPECT_GL_NO_ERROR();
180}
Jamie Madill14764a02014-05-08 10:19:20 -0400181
Jamie Madill3e1b4f82016-01-27 12:39:27 -0500182// Test that calling SubData preserves PBO data.
183TEST_P(ReadPixelsPBOTest, SubDataPreservesContents)
Jamie Madill14764a02014-05-08 10:19:20 -0400184{
185 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
186 glClear(GL_COLOR_BUFFER_BIT);
187 EXPECT_GL_NO_ERROR();
188
189 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
190 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
191
192 unsigned char data[4] = { 1, 2, 3, 4 };
193
194 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
195 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
196 glBufferSubData(GL_ARRAY_BUFFER, 0, 4, data);
197
198 GLvoid *mappedPtr = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
199 unsigned char *dataPtr = static_cast<unsigned char *>(mappedPtr);
200 EXPECT_GL_NO_ERROR();
201
202 EXPECT_EQ(1, dataPtr[0]);
203 EXPECT_EQ(2, dataPtr[1]);
204 EXPECT_EQ(3, dataPtr[2]);
205 EXPECT_EQ(4, dataPtr[3]);
206
207 glUnmapBuffer(GL_ARRAY_BUFFER);
208 EXPECT_GL_NO_ERROR();
209}
210
Jamie Madill3e1b4f82016-01-27 12:39:27 -0500211// Same as the prior test, but with an offset.
212TEST_P(ReadPixelsPBOTest, SubDataOffsetPreservesContents)
Jamie Madill14764a02014-05-08 10:19:20 -0400213{
214 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
215 glClear(GL_COLOR_BUFFER_BIT);
216 EXPECT_GL_NO_ERROR();
217
218 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
219 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
220
221 unsigned char data[4] = { 1, 2, 3, 4 };
222
223 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
224 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
225 glBufferSubData(GL_ARRAY_BUFFER, 16, 4, data);
226
227 GLvoid *mappedPtr = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
228 unsigned char *dataPtr = static_cast<unsigned char *>(mappedPtr);
229 EXPECT_GL_NO_ERROR();
230
231 EXPECT_EQ(255, dataPtr[0]);
232 EXPECT_EQ(0, dataPtr[1]);
233 EXPECT_EQ(0, dataPtr[2]);
234 EXPECT_EQ(255, dataPtr[3]);
235
236 EXPECT_EQ(1, dataPtr[16]);
237 EXPECT_EQ(2, dataPtr[17]);
238 EXPECT_EQ(3, dataPtr[18]);
239 EXPECT_EQ(4, dataPtr[19]);
240
241 glUnmapBuffer(GL_ARRAY_BUFFER);
242 EXPECT_GL_NO_ERROR();
243}
Jamie Madill5fedd012014-05-08 10:19:36 -0400244
Jamie Madill3e1b4f82016-01-27 12:39:27 -0500245class ReadPixelsPBODrawTest : public ReadPixelsPBOTest
246{
247 protected:
248 ReadPixelsPBODrawTest() : mProgram(0), mPositionVBO(0) {}
249
250 void SetUp() override
251 {
252 ReadPixelsPBOTest::SetUp();
253
254 const char *vertexShaderSrc =
255 "attribute vec4 aTest; attribute vec2 aPosition; varying vec4 vTest;\n"
256 "void main()\n"
257 "{\n"
258 " vTest = aTest;\n"
259 " gl_Position = vec4(aPosition, 0.0, 1.0);\n"
260 " gl_PointSize = 1.0;\n"
261 "}";
262
263 const char *fragmentShaderSrc =
264 "precision mediump float; varying vec4 vTest;\n"
265 "void main()\n"
266 "{\n"
267 " gl_FragColor = vTest;\n"
268 "}";
269
270 mProgram = CompileProgram(vertexShaderSrc, fragmentShaderSrc);
271 ASSERT_NE(0u, mProgram);
272
273 glGenBuffers(1, &mPositionVBO);
274 glBindBuffer(GL_ARRAY_BUFFER, mPositionVBO);
275 glBufferData(GL_ARRAY_BUFFER, 128, NULL, GL_DYNAMIC_DRAW);
276 glBindBuffer(GL_ARRAY_BUFFER, 0);
277 }
278
279 void TearDown() override
280 {
281 glDeleteProgram(mProgram);
282 glDeleteBuffers(1, &mPositionVBO);
283 ReadPixelsPBOTest::TearDown();
284 }
285
286 GLuint mProgram;
287 GLuint mPositionVBO;
288};
289
290// Test that we can draw with PBO data.
291TEST_P(ReadPixelsPBODrawTest, DrawWithPBO)
Jamie Madill5fedd012014-05-08 10:19:36 -0400292{
293 unsigned char data[4] = { 1, 2, 3, 4 };
294
295 glBindTexture(GL_TEXTURE_2D, mTexture);
296 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data);
297 EXPECT_GL_NO_ERROR();
298
Jamie Madill5fedd012014-05-08 10:19:36 -0400299 glBindFramebuffer(GL_READ_FRAMEBUFFER, mFBO);
300 EXPECT_GL_NO_ERROR();
301
302 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
303 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 0);
304 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
305 EXPECT_GL_NO_ERROR();
306
307 float positionData[] = { 0.5f, 0.5f };
308
309 glUseProgram(mProgram);
310 glViewport(0, 0, 1, 1);
311 glBindBuffer(GL_ARRAY_BUFFER, mPositionVBO);
312 glBufferSubData(GL_ARRAY_BUFFER, 0, 1 * 2 * 4, positionData);
313 EXPECT_GL_NO_ERROR();
314
315 GLint positionLocation = glGetAttribLocation(mProgram, "aPosition");
316 EXPECT_NE(-1, positionLocation);
317
318 GLint testLocation = glGetAttribLocation(mProgram, "aTest");
319 EXPECT_NE(-1, testLocation);
320
321 glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
322 glEnableVertexAttribArray(positionLocation);
323 EXPECT_GL_NO_ERROR();
324
325 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
326 glVertexAttribPointer(testLocation, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0, 0);
327 glEnableVertexAttribArray(testLocation);
328 EXPECT_GL_NO_ERROR();
329
330 glDrawArrays(GL_POINTS, 0, 1);
331 EXPECT_GL_NO_ERROR();
332
333 memset(data, 0, 4);
334 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, data);
335 EXPECT_GL_NO_ERROR();
336
337 EXPECT_EQ(1, data[0]);
338 EXPECT_EQ(2, data[1]);
339 EXPECT_EQ(3, data[2]);
340 EXPECT_EQ(4, data[3]);
341}
Jamie Madill4fbd36e2014-07-29 15:20:48 -0400342
Jamie Madill3e1b4f82016-01-27 12:39:27 -0500343class ReadPixelsMultisampleTest : public ReadPixelsTest
344{
345 protected:
346 ReadPixelsMultisampleTest() : mFBO(0), mRBO(0), mPBO(0) {}
347
348 void SetUp() override
349 {
350 ANGLETest::SetUp();
351
352 glGenFramebuffers(1, &mFBO);
353 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
354
355 glGenRenderbuffers(1, &mRBO);
356 glBindRenderbuffer(GL_RENDERBUFFER, mRBO);
357
358 glGenBuffers(1, &mPBO);
359 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
360 glBufferData(GL_PIXEL_PACK_BUFFER, 4 * getWindowWidth() * getWindowHeight(), nullptr,
361 GL_STATIC_DRAW);
362 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
363
364 ASSERT_GL_NO_ERROR();
365 }
366
367 void TearDown() override
368 {
369 ANGLETest::TearDown();
370
371 glDeleteFramebuffers(1, &mFBO);
372 glDeleteRenderbuffers(1, &mRBO);
373 glDeleteBuffers(1, &mPBO);
374 }
375
376 GLuint mFBO;
377 GLuint mRBO;
378 GLuint mPBO;
379};
380
381// Test ReadPixels from a multisampled framebuffer.
382TEST_P(ReadPixelsMultisampleTest, BasicClear)
Jamie Madill4fbd36e2014-07-29 15:20:48 -0400383{
Geoff Langa8091652015-04-27 10:53:55 -0400384 if (getClientVersion() < 3 && !extensionEnabled("GL_ANGLE_framebuffer_multisample"))
385 {
386 std::cout << "Test skipped because ES3 or GL_ANGLE_framebuffer_multisample is not available." << std::endl;
387 return;
388 }
389
Geoff Langa8091652015-04-27 10:53:55 -0400390 if (extensionEnabled("GL_ANGLE_framebuffer_multisample"))
391 {
392 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 2, GL_RGBA8, 4, 4);
393 }
394 else
395 {
396 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_RGBA8, 4, 4);
397 }
Jamie Madill4fbd36e2014-07-29 15:20:48 -0400398
Jamie Madill3e1b4f82016-01-27 12:39:27 -0500399 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mRBO);
Jamie Madill4fbd36e2014-07-29 15:20:48 -0400400 ASSERT_GL_NO_ERROR();
401
402 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
403 glClear(GL_COLOR_BUFFER_BIT);
404
405 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
Jamie Madill4fbd36e2014-07-29 15:20:48 -0400406 EXPECT_GL_NO_ERROR();
407
408 glReadPixels(0, 0, 1, 1, GL_RGBA8, GL_UNSIGNED_BYTE, NULL);
Jamie Madill4fbd36e2014-07-29 15:20:48 -0400409 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
Jamie Madill4fbd36e2014-07-29 15:20:48 -0400410}
Jamie Madillfa05f602015-05-07 13:47:11 -0400411
Jamie Madille2509a32016-02-01 14:09:05 -0500412class ReadPixelsTextureTest : public ANGLETest
413{
414 public:
415 ReadPixelsTextureTest() : mFBO(0), mTexture(0)
416 {
417 setWindowWidth(32);
418 setWindowHeight(32);
419 setConfigRedBits(8);
420 setConfigGreenBits(8);
421 setConfigBlueBits(8);
422 setConfigAlphaBits(8);
423 }
424
425 void SetUp() override
426 {
427 ANGLETest::SetUp();
428
429 glGenTextures(1, &mTexture);
430 glGenFramebuffers(1, &mFBO);
431 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
432 }
433
434 void TearDown() override
435 {
436 glDeleteFramebuffers(1, &mFBO);
437 glDeleteTextures(1, &mTexture);
438
439 ANGLETest::TearDown();
440 }
441
Jamie Madillb0c14b72016-02-05 16:49:10 -0500442 void initTexture(GLenum textureTarget,
443 GLint levels,
444 GLint attachmentLevel,
445 GLint attachmentLayer)
Jamie Madille2509a32016-02-01 14:09:05 -0500446 {
447 glBindTexture(textureTarget, mTexture);
448 glTexStorage3D(textureTarget, levels, GL_RGBA8, 4, 4, 4);
449 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, attachmentLevel,
450 attachmentLayer);
Jamie Madille2509a32016-02-01 14:09:05 -0500451 initializeTextureData(textureTarget, levels);
Jamie Madillb0c14b72016-02-05 16:49:10 -0500452 }
453
454 void testRead(GLenum textureTarget, GLint levels, GLint attachmentLevel, GLint attachmentLayer)
455 {
456 initTexture(textureTarget, levels, attachmentLevel, attachmentLayer);
Jamie Madille2509a32016-02-01 14:09:05 -0500457 verifyColor(attachmentLevel, attachmentLayer);
458 }
459
Jamie Madillb0c14b72016-02-05 16:49:10 -0500460 void initPBO()
461 {
462 glGenBuffers(1, &mBuffer);
463 glBindBuffer(GL_PIXEL_PACK_BUFFER, mBuffer);
464 glBufferData(GL_PIXEL_PACK_BUFFER, sizeof(angle::GLColor), nullptr, GL_STREAM_COPY);
465 ASSERT_GL_NO_ERROR();
466 }
467
468 void testPBORead(GLenum textureTarget,
469 GLint levels,
470 GLint attachmentLevel,
471 GLint attachmentLayer)
472 {
473 initPBO();
474 initTexture(textureTarget, levels, attachmentLevel, attachmentLayer);
475 verifyPBO(attachmentLevel, attachmentLayer);
476 }
477
Jamie Madille2509a32016-02-01 14:09:05 -0500478 // Give each {level,layer} pair a (probably) unique color via random.
479 GLuint getColorValue(GLint level, GLint layer)
480 {
481 mRNG.reseed(level + layer * 32);
482 return mRNG.randomUInt();
483 }
484
485 void verifyColor(GLint level, GLint layer)
486 {
487 angle::GLColor colorValue(getColorValue(level, layer));
488 EXPECT_PIXEL_COLOR_EQ(0, 0, colorValue);
489 }
490
Jamie Madillb0c14b72016-02-05 16:49:10 -0500491 void verifyPBO(GLint level, GLint layer)
492 {
493 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
494
495 angle::GLColor expectedColor(getColorValue(level, layer));
496 void *mapPointer =
497 glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, sizeof(angle::GLColor), GL_MAP_READ_BIT);
498 ASSERT_NE(nullptr, mapPointer);
499 angle::GLColor actualColor;
500 memcpy(&actualColor, mapPointer, sizeof(angle::GLColor));
501 glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
502 ASSERT_GL_NO_ERROR();
503 EXPECT_EQ(expectedColor, actualColor);
504 }
505
Jamie Madille2509a32016-02-01 14:09:05 -0500506 void initializeTextureData(GLenum textureTarget, GLint levels)
507 {
508 for (GLint level = 0; level < levels; ++level)
509 {
510 GLint mipSize = 4 >> level;
511 GLint layers = (textureTarget == GL_TEXTURE_3D ? mipSize : 4);
512
513 size_t layerSize = mipSize * mipSize;
514 std::vector<GLuint> textureData(layers * layerSize);
515
516 for (GLint layer = 0; layer < layers; ++layer)
517 {
518 GLuint colorValue = getColorValue(level, layer);
519 size_t offset = (layer * layerSize);
520 std::fill(textureData.begin() + offset, textureData.begin() + offset + layerSize,
521 colorValue);
522 }
523
524 glTexSubImage3D(textureTarget, level, 0, 0, 0, mipSize, mipSize, layers, GL_RGBA,
525 GL_UNSIGNED_BYTE, textureData.data());
526 }
527 }
528
529 angle::RNG mRNG;
530 GLuint mFBO;
531 GLuint mTexture;
Jamie Madillb0c14b72016-02-05 16:49:10 -0500532 GLuint mBuffer;
Jamie Madille2509a32016-02-01 14:09:05 -0500533};
534
535// Test 3D attachment readback.
536TEST_P(ReadPixelsTextureTest, BasicAttachment3D)
537{
538 testRead(GL_TEXTURE_3D, 1, 0, 0);
539}
540
541// Test 3D attachment readback, non-zero mip.
542TEST_P(ReadPixelsTextureTest, MipAttachment3D)
543{
544 testRead(GL_TEXTURE_3D, 2, 1, 0);
545}
546
547// Test 3D attachment readback, non-zero layer.
548TEST_P(ReadPixelsTextureTest, LayerAttachment3D)
549{
Jamie Madille2509a32016-02-01 14:09:05 -0500550 testRead(GL_TEXTURE_3D, 1, 0, 1);
551}
552
553// Test 3D attachment readback, non-zero mip and layer.
554TEST_P(ReadPixelsTextureTest, MipLayerAttachment3D)
555{
Jamie Madille2509a32016-02-01 14:09:05 -0500556 testRead(GL_TEXTURE_3D, 2, 1, 1);
557}
558
559// Test 2D array attachment readback.
560TEST_P(ReadPixelsTextureTest, BasicAttachment2DArray)
561{
562 testRead(GL_TEXTURE_2D_ARRAY, 1, 0, 0);
563}
564
565// Test 3D attachment readback, non-zero mip.
566TEST_P(ReadPixelsTextureTest, MipAttachment2DArray)
567{
568 testRead(GL_TEXTURE_2D_ARRAY, 2, 1, 0);
569}
570
571// Test 3D attachment readback, non-zero layer.
572TEST_P(ReadPixelsTextureTest, LayerAttachment2DArray)
573{
574 testRead(GL_TEXTURE_2D_ARRAY, 1, 0, 1);
575}
576
577// Test 3D attachment readback, non-zero mip and layer.
578TEST_P(ReadPixelsTextureTest, MipLayerAttachment2DArray)
579{
580 testRead(GL_TEXTURE_2D_ARRAY, 2, 1, 1);
581}
582
Jamie Madillb0c14b72016-02-05 16:49:10 -0500583// Test 3D attachment PBO readback.
584TEST_P(ReadPixelsTextureTest, BasicAttachment3DPBO)
585{
586 testPBORead(GL_TEXTURE_3D, 1, 0, 0);
587}
588
589// Test 3D attachment readback, non-zero mip.
590TEST_P(ReadPixelsTextureTest, MipAttachment3DPBO)
591{
592 testPBORead(GL_TEXTURE_3D, 2, 1, 0);
593}
594
595// Test 3D attachment readback, non-zero layer.
596TEST_P(ReadPixelsTextureTest, LayerAttachment3DPBO)
597{
598 testPBORead(GL_TEXTURE_3D, 1, 0, 1);
599}
600
601// Test 3D attachment readback, non-zero mip and layer.
602TEST_P(ReadPixelsTextureTest, MipLayerAttachment3DPBO)
603{
604 testPBORead(GL_TEXTURE_3D, 2, 1, 1);
605}
606
607// Test 2D array attachment readback.
608TEST_P(ReadPixelsTextureTest, BasicAttachment2DArrayPBO)
609{
610 testPBORead(GL_TEXTURE_2D_ARRAY, 1, 0, 0);
611}
612
613// Test 3D attachment readback, non-zero mip.
614TEST_P(ReadPixelsTextureTest, MipAttachment2DArrayPBO)
615{
616 testPBORead(GL_TEXTURE_2D_ARRAY, 2, 1, 0);
617}
618
619// Test 3D attachment readback, non-zero layer.
620TEST_P(ReadPixelsTextureTest, LayerAttachment2DArrayPBO)
621{
622 testPBORead(GL_TEXTURE_2D_ARRAY, 1, 0, 1);
623}
624
625// Test 3D attachment readback, non-zero mip and layer.
626TEST_P(ReadPixelsTextureTest, MipLayerAttachment2DArrayPBO)
627{
628 testPBORead(GL_TEXTURE_2D_ARRAY, 2, 1, 1);
629}
Jamie Madille2509a32016-02-01 14:09:05 -0500630
Jamie Madill3e1b4f82016-01-27 12:39:27 -0500631} // anonymous namespace
632
Jamie Madillfa05f602015-05-07 13:47:11 -0400633// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
Jamie Madill3e1b4f82016-01-27 12:39:27 -0500634ANGLE_INSTANTIATE_TEST(ReadPixelsTest, ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES());
635ANGLE_INSTANTIATE_TEST(ReadPixelsPBOTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
636ANGLE_INSTANTIATE_TEST(ReadPixelsPBODrawTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
637ANGLE_INSTANTIATE_TEST(ReadPixelsMultisampleTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
Jamie Madille2509a32016-02-01 14:09:05 -0500638ANGLE_INSTANTIATE_TEST(ReadPixelsTextureTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());