1 //
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 // ReadPixelsTest:
7 // Tests calls related to glReadPixels.
8 //
9
10 #include "test_utils/ANGLETest.h"
11
12 #include <array>
13
14 #include "random_utils.h"
15
16 using namespace angle;
17
18 namespace
19 {
20
21 class ReadPixelsTest : public ANGLETest
22 {
23 protected:
ReadPixelsTest()24 ReadPixelsTest()
25 {
26 setWindowWidth(32);
27 setWindowHeight(32);
28 setConfigRedBits(8);
29 setConfigGreenBits(8);
30 setConfigBlueBits(8);
31 setConfigAlphaBits(8);
32 }
33 };
34
35 // Test out of bounds framebuffer reads.
TEST_P(ReadPixelsTest,OutOfBounds)36 TEST_P(ReadPixelsTest, OutOfBounds)
37 {
38 // TODO: re-enable once root cause of http://anglebug.com/1413 is fixed
39 if (IsAndroid() && IsAdreno() && IsOpenGLES())
40 {
41 std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl;
42 return;
43 }
44
45 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
46 glClear(GL_COLOR_BUFFER_BIT);
47 EXPECT_GL_NO_ERROR();
48
49 GLsizei pixelsWidth = 32;
50 GLsizei pixelsHeight = 32;
51 GLint offset = 16;
52 std::vector<GLColor> pixels((pixelsWidth + offset) * (pixelsHeight + offset));
53
54 glReadPixels(-offset, -offset, pixelsWidth + offset, pixelsHeight + offset, GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]);
55 EXPECT_GL_NO_ERROR();
56
57 // Expect that all pixels which fell within the framebuffer are red
58 for (int y = pixelsHeight / 2; y < pixelsHeight; y++)
59 {
60 for (int x = pixelsWidth / 2; x < pixelsWidth; x++)
61 {
62 EXPECT_EQ(GLColor::red, pixels[y * (pixelsWidth + offset) + x]);
63 }
64 }
65 }
66
67 class ReadPixelsPBOTest : public ReadPixelsTest
68 {
69 protected:
ReadPixelsPBOTest()70 ReadPixelsPBOTest() : mPBO(0), mTexture(0), mFBO(0) {}
71
SetUp()72 void SetUp() override
73 {
74 ANGLETest::SetUp();
75
76 glGenBuffers(1, &mPBO);
77 glGenFramebuffers(1, &mFBO);
78
79 Reset(4 * getWindowWidth() * getWindowHeight(), 4, 1);
80 }
81
Reset(GLuint bufferSize,GLuint fboWidth,GLuint fboHeight)82 void Reset(GLuint bufferSize, GLuint fboWidth, GLuint fboHeight)
83 {
84 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
85 glBufferData(GL_PIXEL_PACK_BUFFER, bufferSize, nullptr, GL_STATIC_DRAW);
86 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
87
88 glDeleteTextures(1, &mTexture);
89 glGenTextures(1, &mTexture);
90 glBindTexture(GL_TEXTURE_2D, mTexture);
91 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, fboWidth, fboHeight);
92
93 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
94 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
95 glBindFramebuffer(GL_FRAMEBUFFER, 0);
96
97 ASSERT_GL_NO_ERROR();
98 }
99
TearDown()100 void TearDown() override
101 {
102 glDeleteBuffers(1, &mPBO);
103 glDeleteTextures(1, &mTexture);
104 glDeleteFramebuffers(1, &mFBO);
105
106 ANGLETest::TearDown();
107 }
108
109 GLuint mPBO = 0;
110 GLuint mTexture = 0;
111 GLuint mFBO = 0;
112 };
113
114 // Test basic usage of PBOs.
TEST_P(ReadPixelsPBOTest,Basic)115 TEST_P(ReadPixelsPBOTest, Basic)
116 {
117 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
118 glClear(GL_COLOR_BUFFER_BIT);
119 EXPECT_GL_NO_ERROR();
120
121 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
122 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
123
124 GLvoid *mappedPtr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, 32, GL_MAP_READ_BIT);
125 GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
126 EXPECT_GL_NO_ERROR();
127
128 EXPECT_EQ(GLColor::red, dataColor[0]);
129
130 glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
131 EXPECT_GL_NO_ERROR();
132 }
133
134 // Test an error is generated when the PBO is too small.
TEST_P(ReadPixelsPBOTest,PBOTooSmall)135 TEST_P(ReadPixelsPBOTest, PBOTooSmall)
136 {
137 Reset(4 * 16 * 16 - 1, 16, 16);
138
139 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
140 glClear(GL_COLOR_BUFFER_BIT);
141 EXPECT_GL_NO_ERROR();
142
143 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
144 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
145
146 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
147 }
148
149 // Test an error is generated when the PBO is mapped.
TEST_P(ReadPixelsPBOTest,PBOMapped)150 TEST_P(ReadPixelsPBOTest, PBOMapped)
151 {
152 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
153 glClear(GL_COLOR_BUFFER_BIT);
154 EXPECT_GL_NO_ERROR();
155
156 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
157 glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, 32, GL_MAP_READ_BIT);
158 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
159
160 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
161 }
162
163 // Test that binding a PBO to ARRAY_BUFFER works as expected.
TEST_P(ReadPixelsPBOTest,ArrayBufferTarget)164 TEST_P(ReadPixelsPBOTest, ArrayBufferTarget)
165 {
166 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
167 glClear(GL_COLOR_BUFFER_BIT);
168 EXPECT_GL_NO_ERROR();
169
170 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
171 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
172
173 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
174 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
175
176 GLvoid *mappedPtr = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
177 GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
178 EXPECT_GL_NO_ERROR();
179
180 EXPECT_EQ(GLColor::red, dataColor[0]);
181
182 glUnmapBuffer(GL_ARRAY_BUFFER);
183 EXPECT_GL_NO_ERROR();
184 }
185
186 // Test that using a PBO does not overwrite existing data.
TEST_P(ReadPixelsPBOTest,ExistingDataPreserved)187 TEST_P(ReadPixelsPBOTest, ExistingDataPreserved)
188 {
189 // TODO(geofflang): Figure out why this fails on AMD OpenGL (http://anglebug.com/1291)
190 if (IsAMD() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
191 {
192 std::cout << "Test disabled on AMD OpenGL." << std::endl;
193 return;
194 }
195
196 // Clear backbuffer to red
197 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
198 glClear(GL_COLOR_BUFFER_BIT);
199 EXPECT_GL_NO_ERROR();
200
201 // Read 16x16 region from red backbuffer to PBO
202 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
203 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
204
205 // Clear backbuffer to green
206 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
207 glClear(GL_COLOR_BUFFER_BIT);
208 EXPECT_GL_NO_ERROR();
209
210 // Read 16x16 region from green backbuffer to PBO at offset 16
211 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<GLvoid*>(16));
212 GLvoid *mappedPtr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, 32, GL_MAP_READ_BIT);
213 GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
214 EXPECT_GL_NO_ERROR();
215
216 // Test pixel 0 is red (existing data)
217 EXPECT_EQ(GLColor::red, dataColor[0]);
218
219 // Test pixel 16 is green (new data)
220 EXPECT_EQ(GLColor::green, dataColor[16]);
221
222 glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
223 EXPECT_GL_NO_ERROR();
224 }
225
226 // Test that calling SubData preserves PBO data.
TEST_P(ReadPixelsPBOTest,SubDataPreservesContents)227 TEST_P(ReadPixelsPBOTest, SubDataPreservesContents)
228 {
229 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
230 glClear(GL_COLOR_BUFFER_BIT);
231 EXPECT_GL_NO_ERROR();
232
233 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
234 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
235
236 unsigned char data[4] = { 1, 2, 3, 4 };
237
238 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
239 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
240 glBufferSubData(GL_ARRAY_BUFFER, 0, 4, data);
241
242 GLvoid *mappedPtr = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
243 GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
244 EXPECT_GL_NO_ERROR();
245
246 EXPECT_EQ(GLColor(1, 2, 3, 4), dataColor[0]);
247
248 glUnmapBuffer(GL_ARRAY_BUFFER);
249 EXPECT_GL_NO_ERROR();
250 }
251
252 // Same as the prior test, but with an offset.
TEST_P(ReadPixelsPBOTest,SubDataOffsetPreservesContents)253 TEST_P(ReadPixelsPBOTest, SubDataOffsetPreservesContents)
254 {
255 // TODO: re-enable once root cause of http://anglebug.com/1415 is fixed
256 if (IsAndroid() && IsAdreno() && IsOpenGLES())
257 {
258 std::cout << "Test skipped on Adreno OpenGLES on Android." << std::endl;
259 return;
260 }
261
262 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
263 glClear(GL_COLOR_BUFFER_BIT);
264 EXPECT_GL_NO_ERROR();
265
266 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
267 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
268
269 unsigned char data[4] = { 1, 2, 3, 4 };
270
271 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
272 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
273 glBufferSubData(GL_ARRAY_BUFFER, 16, 4, data);
274
275 GLvoid *mappedPtr = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
276 GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
277 EXPECT_GL_NO_ERROR();
278
279 EXPECT_EQ(GLColor::red, dataColor[0]);
280 EXPECT_EQ(GLColor(1, 2, 3, 4), dataColor[4]);
281
282 glUnmapBuffer(GL_ARRAY_BUFFER);
283 EXPECT_GL_NO_ERROR();
284 }
285
286 class ReadPixelsPBODrawTest : public ReadPixelsPBOTest
287 {
288 protected:
ReadPixelsPBODrawTest()289 ReadPixelsPBODrawTest() : mProgram(0), mPositionVBO(0) {}
290
SetUp()291 void SetUp() override
292 {
293 ReadPixelsPBOTest::SetUp();
294
295 const char *vertexShaderSrc =
296 "attribute vec4 aTest; attribute vec2 aPosition; varying vec4 vTest;\n"
297 "void main()\n"
298 "{\n"
299 " vTest = aTest;\n"
300 " gl_Position = vec4(aPosition, 0.0, 1.0);\n"
301 " gl_PointSize = 1.0;\n"
302 "}";
303
304 const char *fragmentShaderSrc =
305 "precision mediump float; varying vec4 vTest;\n"
306 "void main()\n"
307 "{\n"
308 " gl_FragColor = vTest;\n"
309 "}";
310
311 mProgram = CompileProgram(vertexShaderSrc, fragmentShaderSrc);
312 ASSERT_NE(0u, mProgram);
313
314 glGenBuffers(1, &mPositionVBO);
315 glBindBuffer(GL_ARRAY_BUFFER, mPositionVBO);
316 glBufferData(GL_ARRAY_BUFFER, 128, NULL, GL_DYNAMIC_DRAW);
317 glBindBuffer(GL_ARRAY_BUFFER, 0);
318 }
319
TearDown()320 void TearDown() override
321 {
322 glDeleteProgram(mProgram);
323 glDeleteBuffers(1, &mPositionVBO);
324 ReadPixelsPBOTest::TearDown();
325 }
326
327 GLuint mProgram;
328 GLuint mPositionVBO;
329 };
330
331 // Test that we can draw with PBO data.
TEST_P(ReadPixelsPBODrawTest,DrawWithPBO)332 TEST_P(ReadPixelsPBODrawTest, DrawWithPBO)
333 {
334 GLColor color(1, 2, 3, 4);
335 glBindTexture(GL_TEXTURE_2D, mTexture);
336 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &color);
337 EXPECT_GL_NO_ERROR();
338
339 glBindFramebuffer(GL_READ_FRAMEBUFFER, mFBO);
340 EXPECT_GL_NO_ERROR();
341
342 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
343 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 0);
344 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
345 EXPECT_GL_NO_ERROR();
346
347 float positionData[] = { 0.5f, 0.5f };
348
349 glUseProgram(mProgram);
350 glViewport(0, 0, 1, 1);
351 glBindBuffer(GL_ARRAY_BUFFER, mPositionVBO);
352 glBufferSubData(GL_ARRAY_BUFFER, 0, 1 * 2 * 4, positionData);
353 EXPECT_GL_NO_ERROR();
354
355 GLint positionLocation = glGetAttribLocation(mProgram, "aPosition");
356 EXPECT_NE(-1, positionLocation);
357
358 GLint testLocation = glGetAttribLocation(mProgram, "aTest");
359 EXPECT_NE(-1, testLocation);
360
361 glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
362 glEnableVertexAttribArray(positionLocation);
363 EXPECT_GL_NO_ERROR();
364
365 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
366 glVertexAttribPointer(testLocation, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0, 0);
367 glEnableVertexAttribArray(testLocation);
368 EXPECT_GL_NO_ERROR();
369
370 glDrawArrays(GL_POINTS, 0, 1);
371 EXPECT_GL_NO_ERROR();
372
373 color = GLColor(0, 0, 0, 0);
374 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &color);
375 EXPECT_GL_NO_ERROR();
376
377 EXPECT_EQ(GLColor(1, 2, 3, 4), color);
378 }
379
380 class ReadPixelsMultisampleTest : public ReadPixelsTest
381 {
382 protected:
ReadPixelsMultisampleTest()383 ReadPixelsMultisampleTest() : mFBO(0), mRBO(0), mPBO(0) {}
384
SetUp()385 void SetUp() override
386 {
387 ANGLETest::SetUp();
388
389 glGenFramebuffers(1, &mFBO);
390 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
391
392 glGenRenderbuffers(1, &mRBO);
393 glBindRenderbuffer(GL_RENDERBUFFER, mRBO);
394
395 glGenBuffers(1, &mPBO);
396 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
397 glBufferData(GL_PIXEL_PACK_BUFFER, 4 * getWindowWidth() * getWindowHeight(), nullptr,
398 GL_STATIC_DRAW);
399 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
400
401 ASSERT_GL_NO_ERROR();
402 }
403
TearDown()404 void TearDown() override
405 {
406 ANGLETest::TearDown();
407
408 glDeleteFramebuffers(1, &mFBO);
409 glDeleteRenderbuffers(1, &mRBO);
410 glDeleteBuffers(1, &mPBO);
411 }
412
413 GLuint mFBO;
414 GLuint mRBO;
415 GLuint mPBO;
416 };
417
418 // Test ReadPixels from a multisampled framebuffer.
TEST_P(ReadPixelsMultisampleTest,BasicClear)419 TEST_P(ReadPixelsMultisampleTest, BasicClear)
420 {
421 if (getClientMajorVersion() < 3 && !extensionEnabled("GL_ANGLE_framebuffer_multisample"))
422 {
423 std::cout << "Test skipped because ES3 or GL_ANGLE_framebuffer_multisample is not available." << std::endl;
424 return;
425 }
426
427 if (extensionEnabled("GL_ANGLE_framebuffer_multisample"))
428 {
429 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 2, GL_RGBA8, 4, 4);
430 }
431 else
432 {
433 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_RGBA8, 4, 4);
434 }
435
436 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mRBO);
437 ASSERT_GL_NO_ERROR();
438
439 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
440 glClear(GL_COLOR_BUFFER_BIT);
441
442 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
443 EXPECT_GL_NO_ERROR();
444
445 glReadPixels(0, 0, 1, 1, GL_RGBA8, GL_UNSIGNED_BYTE, NULL);
446 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
447 }
448
449 class ReadPixelsTextureTest : public ANGLETest
450 {
451 public:
ReadPixelsTextureTest()452 ReadPixelsTextureTest() : mFBO(0), mTexture(0)
453 {
454 setWindowWidth(32);
455 setWindowHeight(32);
456 setConfigRedBits(8);
457 setConfigGreenBits(8);
458 setConfigBlueBits(8);
459 setConfigAlphaBits(8);
460 }
461
SetUp()462 void SetUp() override
463 {
464 ANGLETest::SetUp();
465
466 glGenTextures(1, &mTexture);
467 glGenFramebuffers(1, &mFBO);
468 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
469 }
470
TearDown()471 void TearDown() override
472 {
473 glDeleteFramebuffers(1, &mFBO);
474 glDeleteTextures(1, &mTexture);
475
476 ANGLETest::TearDown();
477 }
478
initTexture(GLenum textureTarget,GLint levels,GLint attachmentLevel,GLint attachmentLayer)479 void initTexture(GLenum textureTarget,
480 GLint levels,
481 GLint attachmentLevel,
482 GLint attachmentLayer)
483 {
484 glBindTexture(textureTarget, mTexture);
485 glTexStorage3D(textureTarget, levels, GL_RGBA8, 4, 4, 4);
486 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, attachmentLevel,
487 attachmentLayer);
488 initializeTextureData(textureTarget, levels);
489 }
490
testRead(GLenum textureTarget,GLint levels,GLint attachmentLevel,GLint attachmentLayer)491 void testRead(GLenum textureTarget, GLint levels, GLint attachmentLevel, GLint attachmentLayer)
492 {
493 initTexture(textureTarget, levels, attachmentLevel, attachmentLayer);
494 verifyColor(attachmentLevel, attachmentLayer);
495 }
496
initPBO()497 void initPBO()
498 {
499 glGenBuffers(1, &mBuffer);
500 glBindBuffer(GL_PIXEL_PACK_BUFFER, mBuffer);
501 glBufferData(GL_PIXEL_PACK_BUFFER, sizeof(angle::GLColor), nullptr, GL_STREAM_COPY);
502 ASSERT_GL_NO_ERROR();
503 }
504
testPBORead(GLenum textureTarget,GLint levels,GLint attachmentLevel,GLint attachmentLayer)505 void testPBORead(GLenum textureTarget,
506 GLint levels,
507 GLint attachmentLevel,
508 GLint attachmentLayer)
509 {
510 initPBO();
511 initTexture(textureTarget, levels, attachmentLevel, attachmentLayer);
512 verifyPBO(attachmentLevel, attachmentLayer);
513 }
514
515 // Give each {level,layer} pair a (probably) unique color via random.
getColorValue(GLint level,GLint layer)516 GLuint getColorValue(GLint level, GLint layer)
517 {
518 mRNG.reseed(level + layer * 32);
519 return mRNG.randomUInt();
520 }
521
verifyColor(GLint level,GLint layer)522 void verifyColor(GLint level, GLint layer)
523 {
524 angle::GLColor colorValue(getColorValue(level, layer));
525 EXPECT_PIXEL_COLOR_EQ(0, 0, colorValue);
526 }
527
verifyPBO(GLint level,GLint layer)528 void verifyPBO(GLint level, GLint layer)
529 {
530 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
531
532 angle::GLColor expectedColor(getColorValue(level, layer));
533 void *mapPointer =
534 glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, sizeof(angle::GLColor), GL_MAP_READ_BIT);
535 ASSERT_NE(nullptr, mapPointer);
536 angle::GLColor actualColor;
537 memcpy(&actualColor, mapPointer, sizeof(angle::GLColor));
538 glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
539 ASSERT_GL_NO_ERROR();
540 EXPECT_EQ(expectedColor, actualColor);
541 }
542
initializeTextureData(GLenum textureTarget,GLint levels)543 void initializeTextureData(GLenum textureTarget, GLint levels)
544 {
545 for (GLint level = 0; level < levels; ++level)
546 {
547 GLint mipSize = 4 >> level;
548 GLint layers = (textureTarget == GL_TEXTURE_3D ? mipSize : 4);
549
550 size_t layerSize = mipSize * mipSize;
551 std::vector<GLuint> textureData(layers * layerSize);
552
553 for (GLint layer = 0; layer < layers; ++layer)
554 {
555 GLuint colorValue = getColorValue(level, layer);
556 size_t offset = (layer * layerSize);
557 std::fill(textureData.begin() + offset, textureData.begin() + offset + layerSize,
558 colorValue);
559 }
560
561 glTexSubImage3D(textureTarget, level, 0, 0, 0, mipSize, mipSize, layers, GL_RGBA,
562 GL_UNSIGNED_BYTE, textureData.data());
563 }
564 }
565
566 angle::RNG mRNG;
567 GLuint mFBO;
568 GLuint mTexture;
569 GLuint mBuffer;
570 };
571
572 // Test 3D attachment readback.
TEST_P(ReadPixelsTextureTest,BasicAttachment3D)573 TEST_P(ReadPixelsTextureTest, BasicAttachment3D)
574 {
575 testRead(GL_TEXTURE_3D, 1, 0, 0);
576 }
577
578 // Test 3D attachment readback, non-zero mip.
TEST_P(ReadPixelsTextureTest,MipAttachment3D)579 TEST_P(ReadPixelsTextureTest, MipAttachment3D)
580 {
581 testRead(GL_TEXTURE_3D, 2, 1, 0);
582 }
583
584 // Test 3D attachment readback, non-zero layer.
TEST_P(ReadPixelsTextureTest,LayerAttachment3D)585 TEST_P(ReadPixelsTextureTest, LayerAttachment3D)
586 {
587 testRead(GL_TEXTURE_3D, 1, 0, 1);
588 }
589
590 // Test 3D attachment readback, non-zero mip and layer.
TEST_P(ReadPixelsTextureTest,MipLayerAttachment3D)591 TEST_P(ReadPixelsTextureTest, MipLayerAttachment3D)
592 {
593 testRead(GL_TEXTURE_3D, 2, 1, 1);
594 }
595
596 // Test 2D array attachment readback.
TEST_P(ReadPixelsTextureTest,BasicAttachment2DArray)597 TEST_P(ReadPixelsTextureTest, BasicAttachment2DArray)
598 {
599 testRead(GL_TEXTURE_2D_ARRAY, 1, 0, 0);
600 }
601
602 // Test 3D attachment readback, non-zero mip.
TEST_P(ReadPixelsTextureTest,MipAttachment2DArray)603 TEST_P(ReadPixelsTextureTest, MipAttachment2DArray)
604 {
605 testRead(GL_TEXTURE_2D_ARRAY, 2, 1, 0);
606 }
607
608 // Test 3D attachment readback, non-zero layer.
TEST_P(ReadPixelsTextureTest,LayerAttachment2DArray)609 TEST_P(ReadPixelsTextureTest, LayerAttachment2DArray)
610 {
611 testRead(GL_TEXTURE_2D_ARRAY, 1, 0, 1);
612 }
613
614 // Test 3D attachment readback, non-zero mip and layer.
TEST_P(ReadPixelsTextureTest,MipLayerAttachment2DArray)615 TEST_P(ReadPixelsTextureTest, MipLayerAttachment2DArray)
616 {
617 testRead(GL_TEXTURE_2D_ARRAY, 2, 1, 1);
618 }
619
620 // Test 3D attachment PBO readback.
TEST_P(ReadPixelsTextureTest,BasicAttachment3DPBO)621 TEST_P(ReadPixelsTextureTest, BasicAttachment3DPBO)
622 {
623 testPBORead(GL_TEXTURE_3D, 1, 0, 0);
624 }
625
626 // Test 3D attachment readback, non-zero mip.
TEST_P(ReadPixelsTextureTest,MipAttachment3DPBO)627 TEST_P(ReadPixelsTextureTest, MipAttachment3DPBO)
628 {
629 testPBORead(GL_TEXTURE_3D, 2, 1, 0);
630 }
631
632 // Test 3D attachment readback, non-zero layer.
TEST_P(ReadPixelsTextureTest,LayerAttachment3DPBO)633 TEST_P(ReadPixelsTextureTest, LayerAttachment3DPBO)
634 {
635 testPBORead(GL_TEXTURE_3D, 1, 0, 1);
636 }
637
638 // Test 3D attachment readback, non-zero mip and layer.
TEST_P(ReadPixelsTextureTest,MipLayerAttachment3DPBO)639 TEST_P(ReadPixelsTextureTest, MipLayerAttachment3DPBO)
640 {
641 testPBORead(GL_TEXTURE_3D, 2, 1, 1);
642 }
643
644 // Test 2D array attachment readback.
TEST_P(ReadPixelsTextureTest,BasicAttachment2DArrayPBO)645 TEST_P(ReadPixelsTextureTest, BasicAttachment2DArrayPBO)
646 {
647 testPBORead(GL_TEXTURE_2D_ARRAY, 1, 0, 0);
648 }
649
650 // Test 3D attachment readback, non-zero mip.
TEST_P(ReadPixelsTextureTest,MipAttachment2DArrayPBO)651 TEST_P(ReadPixelsTextureTest, MipAttachment2DArrayPBO)
652 {
653 testPBORead(GL_TEXTURE_2D_ARRAY, 2, 1, 0);
654 }
655
656 // Test 3D attachment readback, non-zero layer.
TEST_P(ReadPixelsTextureTest,LayerAttachment2DArrayPBO)657 TEST_P(ReadPixelsTextureTest, LayerAttachment2DArrayPBO)
658 {
659 testPBORead(GL_TEXTURE_2D_ARRAY, 1, 0, 1);
660 }
661
662 // Test 3D attachment readback, non-zero mip and layer.
TEST_P(ReadPixelsTextureTest,MipLayerAttachment2DArrayPBO)663 TEST_P(ReadPixelsTextureTest, MipLayerAttachment2DArrayPBO)
664 {
665 testPBORead(GL_TEXTURE_2D_ARRAY, 2, 1, 1);
666 }
667
668 // a test class to be used for error checking of glReadPixels
669 class ReadPixelsErrorTest : public ReadPixelsTest
670 {
671 protected:
ReadPixelsErrorTest()672 ReadPixelsErrorTest() : mTexture(0), mFBO(0) {}
673
SetUp()674 void SetUp() override
675 {
676 ANGLETest::SetUp();
677
678 glGenTextures(1, &mTexture);
679 glBindTexture(GL_TEXTURE_2D, mTexture);
680 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 4, 1);
681
682 glGenFramebuffers(1, &mFBO);
683 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
684 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
685 glBindFramebuffer(GL_FRAMEBUFFER, 0);
686
687 ASSERT_GL_NO_ERROR();
688 }
689
TearDown()690 void TearDown() override
691 {
692 ANGLETest::TearDown();
693
694 glDeleteTextures(1, &mTexture);
695 glDeleteFramebuffers(1, &mFBO);
696 }
697
698 GLuint mTexture;
699 GLuint mFBO;
700 };
701
702 // The test verifies that glReadPixels generates a GL_INVALID_OPERATION error
703 // when the read buffer is GL_NONE.
704 // Reference: GLES 3.0.4, Section 4.3.2 Reading Pixels
TEST_P(ReadPixelsErrorTest,ReadBufferIsNone)705 TEST_P(ReadPixelsErrorTest, ReadBufferIsNone)
706 {
707 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
708 glReadBuffer(GL_NONE);
709 std::vector<GLubyte> pixels(4);
710 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
711 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
712 }
713
714 } // anonymous namespace
715
716 // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
717 ANGLE_INSTANTIATE_TEST(ReadPixelsTest, ES2_D3D11(), ES2_OPENGL(), ES2_OPENGLES());
718 ANGLE_INSTANTIATE_TEST(ReadPixelsPBOTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
719 ANGLE_INSTANTIATE_TEST(ReadPixelsPBODrawTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
720 ANGLE_INSTANTIATE_TEST(ReadPixelsMultisampleTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
721 ANGLE_INSTANTIATE_TEST(ReadPixelsTextureTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
722 ANGLE_INSTANTIATE_TEST(ReadPixelsErrorTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
723