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 "test_utils/gl_raii.h"
15 #include "util/random_utils.h"
16
17 using namespace angle;
18
19 namespace
20 {
21
22 class ReadPixelsTest : public ANGLETest<>
23 {
24 protected:
ReadPixelsTest()25 ReadPixelsTest()
26 {
27 setWindowWidth(32);
28 setWindowHeight(32);
29 setConfigRedBits(8);
30 setConfigGreenBits(8);
31 setConfigBlueBits(8);
32 setConfigAlphaBits(8);
33 }
34 };
35
36 // Test out of bounds framebuffer reads.
TEST_P(ReadPixelsTest,OutOfBounds)37 TEST_P(ReadPixelsTest, OutOfBounds)
38 {
39 // TODO: re-enable once root cause of http://anglebug.com/42260408 is fixed
40 ANGLE_SKIP_TEST_IF(IsAndroid() && IsAdreno() && IsOpenGLES());
41
42 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
43 glClear(GL_COLOR_BUFFER_BIT);
44 EXPECT_GL_NO_ERROR();
45
46 GLsizei pixelsWidth = 32;
47 GLsizei pixelsHeight = 32;
48 GLint offset = 16;
49 std::vector<GLColor> pixels((pixelsWidth + offset) * (pixelsHeight + offset));
50
51 glReadPixels(-offset, -offset, pixelsWidth + offset, pixelsHeight + offset, GL_RGBA,
52 GL_UNSIGNED_BYTE, &pixels[0]);
53 EXPECT_GL_NO_ERROR();
54
55 // Expect that all pixels which fell within the framebuffer are red
56 for (int y = pixelsHeight / 2; y < pixelsHeight; y++)
57 {
58 for (int x = pixelsWidth / 2; x < pixelsWidth; x++)
59 {
60 EXPECT_EQ(GLColor::red, pixels[y * (pixelsWidth + offset) + x]);
61 }
62 }
63 }
64
65 class ReadPixelsPBONVTest : public ReadPixelsTest
66 {
67 protected:
ReadPixelsPBONVTest()68 ReadPixelsPBONVTest() : mPBO(0), mTexture(0), mFBO(0) {}
69
testSetUp()70 void testSetUp() override
71 {
72 glGenBuffers(1, &mPBO);
73 glGenFramebuffers(1, &mFBO);
74
75 reset(4 * getWindowWidth() * getWindowHeight(), 4, 4);
76 }
77
reset(GLuint bufferSize,GLuint fboWidth,GLuint fboHeight)78 virtual void reset(GLuint bufferSize, GLuint fboWidth, GLuint fboHeight)
79 {
80 ANGLE_SKIP_TEST_IF(!hasPBOExts());
81
82 mPBOBufferSize = bufferSize;
83 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
84 glBufferData(GL_PIXEL_PACK_BUFFER, mPBOBufferSize, nullptr, GL_STATIC_DRAW);
85 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
86
87 glDeleteTextures(1, &mTexture);
88 glGenTextures(1, &mTexture);
89 glBindTexture(GL_TEXTURE_2D, mTexture);
90 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, fboWidth, fboHeight);
91 mFBOWidth = fboWidth;
92 mFBOHeight = fboHeight;
93
94 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
95 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
96 glBindFramebuffer(GL_FRAMEBUFFER, 0);
97
98 ASSERT_GL_NO_ERROR();
99 }
100
testTearDown()101 void testTearDown() override
102 {
103 glDeleteBuffers(1, &mPBO);
104 glDeleteTextures(1, &mTexture);
105 glDeleteFramebuffers(1, &mFBO);
106 }
107
hasPBOExts() const108 bool hasPBOExts() const
109 {
110 return IsGLExtensionEnabled("GL_NV_pixel_buffer_object") &&
111 IsGLExtensionEnabled("GL_EXT_texture_storage");
112 }
113
114 GLuint mPBO = 0;
115 GLuint mTexture = 0;
116 GLuint mFBO = 0;
117 GLuint mFBOWidth = 0;
118 GLuint mFBOHeight = 0;
119 GLuint mPBOBufferSize = 0;
120 };
121
122 // Test basic usage of PBOs.
TEST_P(ReadPixelsPBONVTest,Basic)123 TEST_P(ReadPixelsPBONVTest, Basic)
124 {
125 ANGLE_SKIP_TEST_IF(!hasPBOExts() || !IsGLExtensionEnabled("GL_EXT_map_buffer_range") ||
126 !IsGLExtensionEnabled("GL_OES_mapbuffer"));
127
128 // http://anglebug.com/42263593
129 ANGLE_SKIP_TEST_IF(IsWindows() && IsDesktopOpenGL());
130 // http://anglebug.com/42263926
131 ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsDesktopOpenGL());
132
133 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
134 glClear(GL_COLOR_BUFFER_BIT);
135 // Clear last pixel to green
136 glScissor(15, 15, 1, 1);
137 glEnable(GL_SCISSOR_TEST);
138 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
139 glClear(GL_COLOR_BUFFER_BIT);
140 EXPECT_GL_NO_ERROR();
141
142 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
143 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
144
145 void *mappedPtr = glMapBufferRangeEXT(GL_PIXEL_PACK_BUFFER, 0, mPBOBufferSize, GL_MAP_READ_BIT);
146 GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
147 EXPECT_GL_NO_ERROR();
148
149 EXPECT_EQ(GLColor::red, dataColor[0]);
150 EXPECT_EQ(GLColor::red, dataColor[16 * 16 - 2]);
151 EXPECT_EQ(GLColor::green, dataColor[16 * 16 - 1]);
152
153 glUnmapBufferOES(GL_PIXEL_PACK_BUFFER);
154 EXPECT_GL_NO_ERROR();
155 }
156
157 // Test that calling SubData preserves PBO data.
TEST_P(ReadPixelsPBONVTest,SubDataPreservesContents)158 TEST_P(ReadPixelsPBONVTest, SubDataPreservesContents)
159 {
160 ANGLE_SKIP_TEST_IF(!hasPBOExts() || !IsGLExtensionEnabled("GL_EXT_map_buffer_range") ||
161 !IsGLExtensionEnabled("GL_OES_mapbuffer"));
162
163 // anglebug.com/40096466
164 ANGLE_SKIP_TEST_IF(IsMac() && IsNVIDIA() && IsDesktopOpenGL());
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 unsigned char data[4] = {1, 2, 3, 4};
174
175 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
176 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
177 glBufferSubData(GL_ARRAY_BUFFER, 0, 4, data);
178
179 void *mappedPtr = glMapBufferRangeEXT(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
180 GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
181 EXPECT_GL_NO_ERROR();
182
183 EXPECT_EQ(GLColor(1, 2, 3, 4), dataColor[0]);
184 EXPECT_EQ(GLColor::red, dataColor[1]);
185
186 glUnmapBufferOES(GL_ARRAY_BUFFER);
187 EXPECT_GL_NO_ERROR();
188 }
189
190 // Test that calling ReadPixels with GL_DYNAMIC_DRAW buffer works
TEST_P(ReadPixelsPBONVTest,DynamicPBO)191 TEST_P(ReadPixelsPBONVTest, DynamicPBO)
192 {
193 ANGLE_SKIP_TEST_IF(!hasPBOExts() || !IsGLExtensionEnabled("GL_EXT_map_buffer_range") ||
194 !IsGLExtensionEnabled("GL_OES_mapbuffer"));
195
196 // anglebug.com/40096466
197 ANGLE_SKIP_TEST_IF(IsMac() && IsNVIDIA() && IsDesktopOpenGL());
198
199 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
200 glBufferData(GL_PIXEL_PACK_BUFFER, 4 * getWindowWidth() * getWindowHeight(), nullptr,
201 GL_DYNAMIC_DRAW);
202
203 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
204 glClear(GL_COLOR_BUFFER_BIT);
205 EXPECT_GL_NO_ERROR();
206
207 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
208
209 unsigned char data[4] = {1, 2, 3, 4};
210
211 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
212 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
213 glBufferSubData(GL_ARRAY_BUFFER, 0, 4, data);
214
215 void *mappedPtr = glMapBufferRangeEXT(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
216 GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
217 EXPECT_GL_NO_ERROR();
218
219 EXPECT_EQ(GLColor(1, 2, 3, 4), dataColor[0]);
220 EXPECT_EQ(GLColor::red, dataColor[1]);
221
222 glUnmapBufferOES(GL_ARRAY_BUFFER);
223 EXPECT_GL_NO_ERROR();
224 }
225
TEST_P(ReadPixelsPBONVTest,ReadFromFBO)226 TEST_P(ReadPixelsPBONVTest, ReadFromFBO)
227 {
228 ANGLE_SKIP_TEST_IF(!hasPBOExts() || !IsGLExtensionEnabled("GL_EXT_map_buffer_range") ||
229 !IsGLExtensionEnabled("GL_OES_mapbuffer"));
230
231 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
232 glViewport(0, 0, mFBOWidth, mFBOHeight);
233 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
234 glClear(GL_COLOR_BUFFER_BIT);
235 // Clear last pixel to green
236 glScissor(mFBOWidth - 1, mFBOHeight - 1, 1, 1);
237 glEnable(GL_SCISSOR_TEST);
238 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
239 glClear(GL_COLOR_BUFFER_BIT);
240 EXPECT_GL_NO_ERROR();
241
242 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
243 glReadPixels(0, 0, mFBOWidth, mFBOHeight, GL_RGBA, GL_UNSIGNED_BYTE, 0);
244
245 void *mappedPtr =
246 glMapBufferRangeEXT(GL_PIXEL_PACK_BUFFER, 0, 4 * mFBOWidth * mFBOHeight, GL_MAP_READ_BIT);
247 GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
248 EXPECT_GL_NO_ERROR();
249
250 EXPECT_EQ(GLColor::red, dataColor[0]);
251 EXPECT_EQ(GLColor::red, dataColor[mFBOWidth * mFBOHeight - 2]);
252 EXPECT_EQ(GLColor::green, dataColor[mFBOWidth * mFBOHeight - 1]);
253
254 glUnmapBufferOES(GL_PIXEL_PACK_BUFFER);
255 EXPECT_GL_NO_ERROR();
256 }
257
258 // Test calling ReadPixels with a non-zero "data" param into a PBO
TEST_P(ReadPixelsPBONVTest,ReadFromFBOWithDataOffset)259 TEST_P(ReadPixelsPBONVTest, ReadFromFBOWithDataOffset)
260 {
261 ANGLE_SKIP_TEST_IF(!hasPBOExts() || !IsGLExtensionEnabled("GL_EXT_map_buffer_range") ||
262 !IsGLExtensionEnabled("GL_OES_mapbuffer"));
263
264 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
265 glViewport(0, 0, mFBOWidth, mFBOHeight);
266 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
267 glClear(GL_COLOR_BUFFER_BIT);
268 // Clear first pixel to green
269 glScissor(0, 0, 1, 1);
270 glEnable(GL_SCISSOR_TEST);
271 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
272 glClear(GL_COLOR_BUFFER_BIT);
273 EXPECT_GL_NO_ERROR();
274
275 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
276
277 // Read (height - 1) rows offset by width * 4.
278 glReadPixels(0, 0, mFBOWidth, mFBOHeight - 1, GL_RGBA, GL_UNSIGNED_BYTE,
279 reinterpret_cast<void *>(mFBOWidth * static_cast<uintptr_t>(4)));
280
281 void *mappedPtr =
282 glMapBufferRangeEXT(GL_PIXEL_PACK_BUFFER, 0, 4 * mFBOWidth * mFBOHeight, GL_MAP_READ_BIT);
283 GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
284 EXPECT_GL_NO_ERROR();
285
286 EXPECT_EQ(GLColor::green, dataColor[mFBOWidth]);
287 EXPECT_EQ(GLColor::red, dataColor[mFBOWidth + 1]);
288 EXPECT_EQ(GLColor::red, dataColor[mFBOWidth * mFBOHeight - 1]);
289
290 glUnmapBufferOES(GL_PIXEL_PACK_BUFFER);
291 EXPECT_GL_NO_ERROR();
292 }
293
294 class ReadPixelsPBOTest : public ReadPixelsPBONVTest
295 {
296 protected:
ReadPixelsPBOTest()297 ReadPixelsPBOTest() : ReadPixelsPBONVTest() {}
298
testSetUp()299 void testSetUp() override
300 {
301 glGenBuffers(1, &mPBO);
302 glGenFramebuffers(1, &mFBO);
303
304 reset(4 * getWindowWidth() * getWindowHeight(), 4, 1);
305 }
306
reset(GLuint bufferSize,GLuint fboWidth,GLuint fboHeight)307 void reset(GLuint bufferSize, GLuint fboWidth, GLuint fboHeight) override
308 {
309 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
310 glBufferData(GL_PIXEL_PACK_BUFFER, bufferSize, nullptr, GL_STATIC_DRAW);
311 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
312
313 glDeleteTextures(1, &mTexture);
314 glGenTextures(1, &mTexture);
315 glBindTexture(GL_TEXTURE_2D, mTexture);
316 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, fboWidth, fboHeight);
317
318 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
319 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
320 glBindFramebuffer(GL_FRAMEBUFFER, 0);
321
322 mFBOWidth = fboWidth;
323 mFBOHeight = fboHeight;
324
325 mPBOBufferSize = bufferSize;
326
327 ASSERT_GL_NO_ERROR();
328 }
329 };
330
331 // Test basic usage of PBOs.
TEST_P(ReadPixelsPBOTest,Basic)332 TEST_P(ReadPixelsPBOTest, Basic)
333 {
334 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
335 glClear(GL_COLOR_BUFFER_BIT);
336 EXPECT_GL_NO_ERROR();
337
338 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
339 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
340
341 void *mappedPtr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, 32, GL_MAP_READ_BIT);
342 GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
343 EXPECT_GL_NO_ERROR();
344
345 EXPECT_EQ(GLColor::red, dataColor[0]);
346
347 glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
348 EXPECT_GL_NO_ERROR();
349 }
350
351 // Test copy to snorm
TEST_P(ReadPixelsPBOTest,Snorm)352 TEST_P(ReadPixelsPBOTest, Snorm)
353 {
354 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_render_snorm"));
355
356 constexpr GLsizei kSize = 6;
357
358 GLRenderbuffer rbo;
359 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
360 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_SNORM, kSize, kSize);
361 ASSERT_GL_NO_ERROR();
362
363 GLFramebuffer fbo;
364 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
365 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
366 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
367 ASSERT_GL_NO_ERROR();
368
369 glEnable(GL_SCISSOR_TEST);
370 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
371 glScissor(0, 0, kSize / 2, kSize / 2);
372 glClear(GL_COLOR_BUFFER_BIT);
373
374 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
375 glScissor(kSize / 2, 0, kSize / 2, kSize / 2);
376 glClear(GL_COLOR_BUFFER_BIT);
377
378 glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
379 glScissor(0, kSize / 2, kSize / 2, kSize / 2);
380 glClear(GL_COLOR_BUFFER_BIT);
381
382 glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
383 glScissor(kSize / 2, kSize / 2, kSize / 2, kSize / 2);
384 glClear(GL_COLOR_BUFFER_BIT);
385 EXPECT_GL_NO_ERROR();
386
387 glDisable(GL_SCISSOR_TEST);
388
389 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
390 glReadPixels(0, 0, kSize, kSize, GL_RGBA, GL_BYTE, 0);
391
392 std::vector<GLColor> result(kSize * kSize);
393 void *mappedPtr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, kSize * kSize * 4, GL_MAP_READ_BIT);
394 memcpy(result.data(), mappedPtr, kSize * kSize * 4);
395 glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
396 EXPECT_GL_NO_ERROR();
397
398 auto verify = [&](const GLColor expect[4]) {
399 for (size_t i = 0; i < kSize; ++i)
400 {
401 for (size_t j = 0; j < kSize; ++j)
402 {
403 uint32_t index = (i < kSize / 2 ? 0 : 1) << 1 | (j < kSize / 2 ? 0 : 1);
404 EXPECT_EQ(result[i * kSize + j], expect[index]) << i << " " << j;
405 }
406 }
407 };
408
409 // The image should have the following colors
410 //
411 // +---+---+
412 // | R | G |
413 // +---+---+
414 // | B | Y |
415 // +---+---+
416 //
417 const GLColor kColors[4] = {
418 GLColor(127, 0, 0, 127),
419 GLColor(0, 127, 0, 127),
420 GLColor(0, 0, 127, 127),
421 GLColor(127, 127, 0, 127),
422 };
423 verify(kColors);
424
425 // Test again, but this time with reverse order
426 if (EnsureGLExtensionEnabled("GL_ANGLE_pack_reverse_row_order"))
427 {
428 glPixelStorei(GL_PACK_REVERSE_ROW_ORDER_ANGLE, GL_TRUE);
429 glReadPixels(0, 0, kSize, kSize, GL_RGBA, GL_BYTE, 0);
430
431 mappedPtr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, kSize * kSize * 4, GL_MAP_READ_BIT);
432 memcpy(result.data(), mappedPtr, kSize * kSize * 4);
433 glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
434 EXPECT_GL_NO_ERROR();
435
436 const GLColor kReversedColors[4] = {
437 GLColor(0, 0, 127, 127),
438 GLColor(127, 127, 0, 127),
439 GLColor(127, 0, 0, 127),
440 GLColor(0, 127, 0, 127),
441 };
442 verify(kReversedColors);
443 }
444 }
445
446 // Test read pixel to PBO of an sRGB unorm renderbuffer
TEST_P(ReadPixelsPBOTest,SrgbUnorm)447 TEST_P(ReadPixelsPBOTest, SrgbUnorm)
448 {
449 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_ANGLE_pack_reverse_row_order"));
450
451 constexpr GLsizei kSize = 1;
452 constexpr angle::GLColor clearColor(64, 0, 0, 255);
453 constexpr angle::GLColor encodedToSrgbColor(136, 0, 0, 255);
454
455 GLRenderbuffer rbo;
456 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
457 glRenderbufferStorage(GL_RENDERBUFFER, GL_SRGB8_ALPHA8, kSize, kSize);
458 ASSERT_GL_NO_ERROR();
459
460 GLFramebuffer fbo;
461 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
462 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
463 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
464 ASSERT_GL_NO_ERROR();
465
466 glClearColor(clearColor[0] / 255.0f, 0.0f, 0.0f, 1.0f);
467 glClear(GL_COLOR_BUFFER_BIT);
468
469 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
470 glPixelStorei(GL_PACK_REVERSE_ROW_ORDER_ANGLE, GL_TRUE);
471 glReadPixels(0, 0, kSize, kSize, GL_RGBA, GL_UNSIGNED_BYTE, 0);
472
473 GLColor result;
474 void *mappedPtr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, kSize * kSize * 4, GL_MAP_READ_BIT);
475 memcpy(result.data(), mappedPtr, kSize * kSize * 4);
476 glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
477 EXPECT_GL_NO_ERROR();
478
479 EXPECT_NEAR(result[0], encodedToSrgbColor[0], 1);
480 }
481
482 // Test an error is generated when the PBO is too small.
TEST_P(ReadPixelsPBOTest,PBOTooSmall)483 TEST_P(ReadPixelsPBOTest, PBOTooSmall)
484 {
485 reset(4 * 16 * 16 - 1, 16, 16);
486
487 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
488 glClear(GL_COLOR_BUFFER_BIT);
489 EXPECT_GL_NO_ERROR();
490
491 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
492 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
493
494 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
495 }
496
497 // Test an error is generated when the PBO is mapped.
TEST_P(ReadPixelsPBOTest,PBOMapped)498 TEST_P(ReadPixelsPBOTest, PBOMapped)
499 {
500 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
501 glClear(GL_COLOR_BUFFER_BIT);
502 EXPECT_GL_NO_ERROR();
503
504 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
505 glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, 32, GL_MAP_READ_BIT);
506 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
507
508 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
509 }
510
511 // Test that binding a PBO to ARRAY_BUFFER works as expected.
TEST_P(ReadPixelsPBOTest,ArrayBufferTarget)512 TEST_P(ReadPixelsPBOTest, ArrayBufferTarget)
513 {
514 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
515 glClear(GL_COLOR_BUFFER_BIT);
516 EXPECT_GL_NO_ERROR();
517
518 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
519 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
520
521 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
522 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
523
524 void *mappedPtr = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
525 GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
526 EXPECT_GL_NO_ERROR();
527
528 EXPECT_EQ(GLColor::red, dataColor[0]);
529
530 glUnmapBuffer(GL_ARRAY_BUFFER);
531 EXPECT_GL_NO_ERROR();
532 }
533
534 // Test that using a PBO does not overwrite existing data.
TEST_P(ReadPixelsPBOTest,ExistingDataPreserved)535 TEST_P(ReadPixelsPBOTest, ExistingDataPreserved)
536 {
537 // Clear backbuffer to red
538 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
539 glClear(GL_COLOR_BUFFER_BIT);
540 EXPECT_GL_NO_ERROR();
541
542 // Read 16x16 region from red backbuffer to PBO
543 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
544 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
545
546 // Clear backbuffer to green
547 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
548 glClear(GL_COLOR_BUFFER_BIT);
549 EXPECT_GL_NO_ERROR();
550
551 // Read 16x16 region from green backbuffer to PBO at offset 16
552 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<void *>(16));
553 void *mappedPtr =
554 glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, 17 * sizeof(GLColor), GL_MAP_READ_BIT);
555 GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
556 EXPECT_GL_NO_ERROR();
557
558 // Test pixel 0 is red (existing data)
559 EXPECT_EQ(GLColor::red, dataColor[0]);
560
561 // Test pixel 16 is green (new data)
562 EXPECT_EQ(GLColor::green, dataColor[16]);
563
564 glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
565 EXPECT_GL_NO_ERROR();
566 }
567
568 // Test that calling SubData preserves PBO data.
TEST_P(ReadPixelsPBOTest,SubDataPreservesContents)569 TEST_P(ReadPixelsPBOTest, SubDataPreservesContents)
570 {
571 // anglebug.com/40096466
572 ANGLE_SKIP_TEST_IF(IsMac() && IsNVIDIA() && IsDesktopOpenGL());
573
574 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
575 glClear(GL_COLOR_BUFFER_BIT);
576 EXPECT_GL_NO_ERROR();
577
578 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
579 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
580
581 unsigned char data[4] = {1, 2, 3, 4};
582
583 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
584 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
585 glBufferSubData(GL_ARRAY_BUFFER, 0, 4, data);
586
587 void *mappedPtr = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
588 GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
589 EXPECT_GL_NO_ERROR();
590
591 EXPECT_EQ(GLColor(1, 2, 3, 4), dataColor[0]);
592
593 glUnmapBuffer(GL_ARRAY_BUFFER);
594 EXPECT_GL_NO_ERROR();
595 }
596
597 // Same as the prior test, but with an offset.
TEST_P(ReadPixelsPBOTest,SubDataOffsetPreservesContents)598 TEST_P(ReadPixelsPBOTest, SubDataOffsetPreservesContents)
599 {
600 // anglebug.com/42260410
601 ANGLE_SKIP_TEST_IF(IsNexus5X() && IsAdreno() && IsOpenGLES());
602 // anglebug.com/40096466
603 ANGLE_SKIP_TEST_IF(IsMac() && IsNVIDIA() && IsDesktopOpenGL());
604
605 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
606 glClear(GL_COLOR_BUFFER_BIT);
607 EXPECT_GL_NO_ERROR();
608
609 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
610 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
611
612 unsigned char data[4] = {1, 2, 3, 4};
613
614 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
615 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
616 glBufferSubData(GL_ARRAY_BUFFER, 16, 4, data);
617
618 void *mappedPtr = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
619 GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
620 EXPECT_GL_NO_ERROR();
621
622 EXPECT_EQ(GLColor::red, dataColor[0]);
623 EXPECT_EQ(GLColor(1, 2, 3, 4), dataColor[4]);
624
625 glUnmapBuffer(GL_ARRAY_BUFFER);
626 EXPECT_GL_NO_ERROR();
627 }
628
629 // Test that uploading data to buffer that's in use then writing to it as PBO works.
TEST_P(ReadPixelsPBOTest,UseAsUBOThenUpdateThenReadFromFBO)630 TEST_P(ReadPixelsPBOTest, UseAsUBOThenUpdateThenReadFromFBO)
631 {
632 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
633 glViewport(0, 0, mFBOWidth, mFBOHeight);
634
635 const std::array<GLColor, 4> kInitialData = {GLColor::red, GLColor::red, GLColor::red,
636 GLColor::red};
637 const std::array<GLColor, 4> kUpdateData = {GLColor::white, GLColor::white, GLColor::white,
638 GLColor::white};
639
640 GLBuffer buffer;
641 glBindBuffer(GL_UNIFORM_BUFFER, buffer);
642 glBufferData(GL_UNIFORM_BUFFER, sizeof(kInitialData), kInitialData.data(), GL_DYNAMIC_COPY);
643 glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);
644 EXPECT_GL_NO_ERROR();
645
646 constexpr char kVerifyUBO[] = R"(#version 300 es
647 precision mediump float;
648 uniform block {
649 uvec4 data;
650 } ubo;
651 out vec4 colorOut;
652 void main()
653 {
654 if (all(equal(ubo.data, uvec4(0xFF0000FFu))))
655 colorOut = vec4(0, 1.0, 0, 1.0);
656 else
657 colorOut = vec4(1.0, 0, 0, 1.0);
658 })";
659
660 ANGLE_GL_PROGRAM(verifyUbo, essl3_shaders::vs::Simple(), kVerifyUBO);
661 drawQuad(verifyUbo, essl3_shaders::PositionAttrib(), 0.5);
662 EXPECT_GL_NO_ERROR();
663
664 // Update buffer data
665 glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(kInitialData), kUpdateData.data());
666 EXPECT_GL_NO_ERROR();
667
668 // Clear first pixel to blue
669 glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
670 glScissor(0, 0, 1, 1);
671 glEnable(GL_SCISSOR_TEST);
672 glClear(GL_COLOR_BUFFER_BIT);
673 EXPECT_GL_NO_ERROR();
674
675 glBindBuffer(GL_PIXEL_PACK_BUFFER, buffer);
676
677 // Read the framebuffer pixels
678 glReadPixels(0, 0, mFBOWidth, mFBOHeight, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
679
680 void *mappedPtr =
681 glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, sizeof(kInitialData), GL_MAP_READ_BIT);
682 GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
683 EXPECT_GL_NO_ERROR();
684
685 EXPECT_EQ(GLColor::blue, dataColor[0]);
686 EXPECT_EQ(GLColor::green, dataColor[1]);
687 EXPECT_EQ(GLColor::green, dataColor[2]);
688 EXPECT_EQ(GLColor::green, dataColor[3]);
689
690 glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
691 EXPECT_GL_NO_ERROR();
692
693 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
694 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
695 EXPECT_PIXEL_COLOR_EQ(1, 0, GLColor::green);
696 EXPECT_PIXEL_COLOR_EQ(2, 0, GLColor::green);
697 EXPECT_PIXEL_COLOR_EQ(3, 0, GLColor::green);
698 }
699
700 // Test PBO readback with row length smaller than area width.
TEST_P(ReadPixelsPBOTest,SmallRowLength)701 TEST_P(ReadPixelsPBOTest, SmallRowLength)
702 {
703 constexpr int kSize = 2;
704 reset(kSize * kSize * 4, kSize, kSize);
705 std::vector<GLColor> texData(kSize * kSize);
706 texData[0] = GLColor::red;
707 texData[1] = GLColor::green;
708 texData[2] = GLColor::blue;
709 texData[3] = GLColor::white;
710 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kSize, kSize, GL_RGBA, GL_UNSIGNED_BYTE,
711 texData.data());
712 ASSERT_GL_NO_ERROR();
713
714 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
715 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
716
717 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
718 std::vector<GLColor> bufData(kSize * kSize, GLColor::black);
719 glBufferData(GL_PIXEL_PACK_BUFFER, mPBOBufferSize, bufData.data(), GL_STATIC_DRAW);
720
721 glPixelStorei(GL_PACK_ROW_LENGTH, 1);
722 glReadPixels(0, 0, kSize, kSize, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
723 ASSERT_GL_NO_ERROR();
724
725 void *mappedPtr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, mPBOBufferSize, GL_MAP_READ_BIT);
726 ASSERT_NE(nullptr, mappedPtr);
727 ASSERT_GL_NO_ERROR();
728
729 // TODO(anglebug.com/354005999)
730 // Metal compute path may produce flaky results
731 // Suppressed until a fallback is implemented
732 if (!IsMetal())
733 {
734 GLColor *colorPtr = static_cast<GLColor *>(mappedPtr);
735 EXPECT_EQ(colorPtr[0], GLColor::red);
736 EXPECT_EQ(colorPtr[1], GLColor::blue);
737 EXPECT_EQ(colorPtr[2], GLColor::white);
738 EXPECT_EQ(colorPtr[3], GLColor::black);
739 }
740 ASSERT_TRUE(glUnmapBuffer(GL_PIXEL_PACK_BUFFER));
741 ASSERT_GL_NO_ERROR();
742 }
743
744 class ReadPixelsPBODrawTest : public ReadPixelsPBOTest
745 {
746 protected:
ReadPixelsPBODrawTest()747 ReadPixelsPBODrawTest() : mProgram(0), mPositionVBO(0) {}
748
testSetUp()749 void testSetUp() override
750 {
751 ReadPixelsPBOTest::testSetUp();
752
753 constexpr char kVS[] =
754 "attribute vec4 aTest; attribute vec2 aPosition; varying vec4 vTest;\n"
755 "void main()\n"
756 "{\n"
757 " vTest = aTest;\n"
758 " gl_Position = vec4(aPosition, 0.0, 1.0);\n"
759 " gl_PointSize = 1.0;\n"
760 "}";
761
762 constexpr char kFS[] =
763 "precision mediump float; varying vec4 vTest;\n"
764 "void main()\n"
765 "{\n"
766 " gl_FragColor = vTest;\n"
767 "}";
768
769 mProgram = CompileProgram(kVS, kFS);
770 ASSERT_NE(0u, mProgram);
771
772 glGenBuffers(1, &mPositionVBO);
773 glBindBuffer(GL_ARRAY_BUFFER, mPositionVBO);
774 glBufferData(GL_ARRAY_BUFFER, 128, nullptr, GL_DYNAMIC_DRAW);
775 glBindBuffer(GL_ARRAY_BUFFER, 0);
776 }
777
testTearDown()778 void testTearDown() override
779 {
780 glDeleteProgram(mProgram);
781 glDeleteBuffers(1, &mPositionVBO);
782 ReadPixelsPBOTest::testTearDown();
783 }
784
785 GLuint mProgram;
786 GLuint mPositionVBO;
787 };
788
789 // Test that we can draw with PBO data.
TEST_P(ReadPixelsPBODrawTest,DrawWithPBO)790 TEST_P(ReadPixelsPBODrawTest, DrawWithPBO)
791 {
792 GLColor color(1, 2, 3, 4);
793 glBindTexture(GL_TEXTURE_2D, mTexture);
794 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &color);
795 EXPECT_GL_NO_ERROR();
796
797 glBindFramebuffer(GL_READ_FRAMEBUFFER, mFBO);
798 EXPECT_GL_NO_ERROR();
799
800 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
801 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 0);
802 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
803 EXPECT_GL_NO_ERROR();
804
805 float positionData[] = {0.5f, 0.5f};
806
807 glUseProgram(mProgram);
808 glViewport(0, 0, 1, 1);
809 glBindBuffer(GL_ARRAY_BUFFER, mPositionVBO);
810 glBufferSubData(GL_ARRAY_BUFFER, 0, 1 * 2 * 4, positionData);
811 EXPECT_GL_NO_ERROR();
812
813 GLint positionLocation = glGetAttribLocation(mProgram, "aPosition");
814 EXPECT_NE(-1, positionLocation);
815
816 GLint testLocation = glGetAttribLocation(mProgram, "aTest");
817 EXPECT_NE(-1, testLocation);
818
819 glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
820 glEnableVertexAttribArray(positionLocation);
821 EXPECT_GL_NO_ERROR();
822
823 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
824 glVertexAttribPointer(testLocation, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0, 0);
825 glEnableVertexAttribArray(testLocation);
826 EXPECT_GL_NO_ERROR();
827
828 glDrawArrays(GL_POINTS, 0, 1);
829 EXPECT_GL_NO_ERROR();
830
831 color = GLColor(0, 0, 0, 0);
832 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &color);
833 EXPECT_GL_NO_ERROR();
834
835 EXPECT_EQ(GLColor(1, 2, 3, 4), color);
836 }
837
838 // Test that we can correctly update a buffer bound to the vertex stage with PBO.
TEST_P(ReadPixelsPBODrawTest,UpdateVertexArrayWithPixelPack)839 TEST_P(ReadPixelsPBODrawTest, UpdateVertexArrayWithPixelPack)
840 {
841 glUseProgram(mProgram);
842 glViewport(0, 0, 1, 1);
843 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
844 ASSERT_GL_NO_ERROR();
845
846 // First draw with pre-defined data.
847 std::array<float, 2> positionData = {0.5f, 0.5f};
848
849 glBindBuffer(GL_ARRAY_BUFFER, mPositionVBO);
850 glBufferSubData(GL_ARRAY_BUFFER, 0, positionData.size() * sizeof(positionData[0]),
851 positionData.data());
852 ASSERT_GL_NO_ERROR();
853
854 GLint positionLocation = glGetAttribLocation(mProgram, "aPosition");
855 EXPECT_NE(-1, positionLocation);
856
857 GLint testLocation = glGetAttribLocation(mProgram, "aTest");
858 EXPECT_NE(-1, testLocation);
859
860 glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
861 glEnableVertexAttribArray(positionLocation);
862 ASSERT_GL_NO_ERROR();
863
864 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
865 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GLColor), &GLColor::red);
866 glVertexAttribPointer(testLocation, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0, 0);
867 glEnableVertexAttribArray(testLocation);
868 ASSERT_GL_NO_ERROR();
869
870 glDrawArrays(GL_POINTS, 0, 1);
871 ASSERT_GL_NO_ERROR();
872
873 // Update the buffer bound to the VAO with a PBO.
874 glBindTexture(GL_TEXTURE_2D, mTexture);
875 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
876 ASSERT_GL_NO_ERROR();
877
878 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
879 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 0);
880 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
881 ASSERT_GL_NO_ERROR();
882
883 // Draw again and verify the VAO has the updated data.
884 glDrawArrays(GL_POINTS, 0, 1);
885
886 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
887 }
888
889 class ReadPixelsTextureNorm16PBOTest : public ReadPixelsTest
890 {
891 protected:
testSetUp()892 void testSetUp() override
893 {
894 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
895 glBindTexture(GL_TEXTURE_2D, mTex);
896 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTex, 0);
897 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
898 ASSERT_GL_NO_ERROR();
899 }
900
901 template <typename T>
test(GLenum format,GLenum internalFormat,GLenum readFormat)902 void test(GLenum format, GLenum internalFormat, GLenum readFormat)
903 {
904 const bool isSigned = std::is_same<T, GLshort>::value;
905 const GLenum type = isSigned ? GL_SHORT : GL_UNSIGNED_SHORT;
906
907 T data[4] = {};
908 data[0] = isSigned ? -32767 : 32767;
909 data[1] = isSigned ? -16383 : 16383;
910 data[2] = isSigned ? -8191 : 8191;
911 data[3] = isSigned ? -4095 : 4095;
912
913 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, 1, 1, 0, format, type, data);
914 ASSERT_GL_NO_ERROR();
915 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
916
917 bool supportedCombination = true;
918 if (readFormat != GL_RGBA)
919 {
920 GLenum implementationFormat, implementationType;
921 glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT,
922 reinterpret_cast<GLint *>(&implementationFormat));
923 glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE,
924 reinterpret_cast<GLint *>(&implementationType));
925 ASSERT_GL_NO_ERROR();
926
927 supportedCombination = implementationFormat == readFormat && implementationType == type;
928 }
929
930 glBufferData(GL_PIXEL_PACK_BUFFER, 12, nullptr, GL_STATIC_COPY);
931 ASSERT_GL_NO_ERROR();
932
933 // Use non-zero offset for better code coverage
934 constexpr GLint offset = 4;
935 glReadPixels(0, 0, 1, 1, readFormat, type, reinterpret_cast<void *>(offset));
936 if (supportedCombination)
937 {
938 ASSERT_GL_NO_ERROR();
939 }
940 else
941 {
942 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
943 ANGLE_SKIP_TEST_IF(!supportedCombination);
944 }
945
946 T *dataRead =
947 static_cast<T *>(glMapBufferRange(GL_PIXEL_PACK_BUFFER, offset, 8, GL_MAP_READ_BIT));
948 ASSERT_GL_NO_ERROR();
949
950 EXPECT_EQ(dataRead[0], data[0]);
951 if (readFormat == GL_RGBA || readFormat == GL_RG)
952 {
953 EXPECT_EQ(dataRead[1], format != GL_RED ? data[1] : 0);
954 }
955 if (readFormat == GL_RGBA)
956 {
957 EXPECT_EQ(dataRead[2], format == GL_RGBA ? data[2] : 0);
958 EXPECT_EQ(dataRead[3], format == GL_RGBA ? data[3] : (isSigned ? 32767 : 65535));
959 }
960 glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
961 }
962
testUnsigned(GLenum format,GLenum internalFormat,GLenum readFormat)963 void testUnsigned(GLenum format, GLenum internalFormat, GLenum readFormat)
964 {
965 ASSERT(internalFormat == GL_RGBA16_EXT || internalFormat == GL_RG16_EXT ||
966 internalFormat == GL_R16_EXT);
967 test<GLushort>(format, internalFormat, readFormat);
968 }
969
testSigned(GLenum format,GLenum internalFormat,GLenum readFormat)970 void testSigned(GLenum format, GLenum internalFormat, GLenum readFormat)
971 {
972 ASSERT(internalFormat == GL_RGBA16_SNORM_EXT || internalFormat == GL_RG16_SNORM_EXT ||
973 internalFormat == GL_R16_SNORM_EXT);
974 test<GLshort>(format, internalFormat, readFormat);
975 }
976
977 GLFramebuffer mFBO;
978 GLTexture mTex;
979 GLBuffer mPBO;
980 };
981
982 // Test PBO RGBA readback for RGBA16 color buffer.
TEST_P(ReadPixelsTextureNorm16PBOTest,RGBA16_RGBA)983 TEST_P(ReadPixelsTextureNorm16PBOTest, RGBA16_RGBA)
984 {
985 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
986 testUnsigned(GL_RGBA, GL_RGBA16_EXT, GL_RGBA);
987 }
988
989 // Test PBO RGBA readback for RG16 color buffer.
TEST_P(ReadPixelsTextureNorm16PBOTest,RG16_RGBA)990 TEST_P(ReadPixelsTextureNorm16PBOTest, RG16_RGBA)
991 {
992 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
993 testUnsigned(GL_RG, GL_RG16_EXT, GL_RGBA);
994 }
995
996 // Test PBO RG readback for RG16 color buffer.
TEST_P(ReadPixelsTextureNorm16PBOTest,RG16_RG)997 TEST_P(ReadPixelsTextureNorm16PBOTest, RG16_RG)
998 {
999 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
1000 testUnsigned(GL_RG, GL_RG16_EXT, GL_RG);
1001 }
1002
1003 // Test PBO RGBA readback for R16 color buffer.
TEST_P(ReadPixelsTextureNorm16PBOTest,R16_RGBA)1004 TEST_P(ReadPixelsTextureNorm16PBOTest, R16_RGBA)
1005 {
1006 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
1007 testUnsigned(GL_RED, GL_R16_EXT, GL_RGBA);
1008 }
1009
1010 // Test PBO RED readback for R16 color buffer.
TEST_P(ReadPixelsTextureNorm16PBOTest,R16_RED)1011 TEST_P(ReadPixelsTextureNorm16PBOTest, R16_RED)
1012 {
1013 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
1014 testUnsigned(GL_RED, GL_R16_EXT, GL_RED);
1015 }
1016
1017 // Test PBO RGBA readback for RGBA16_SNORM color buffer.
TEST_P(ReadPixelsTextureNorm16PBOTest,RGBA16_SNORM_RGBA)1018 TEST_P(ReadPixelsTextureNorm16PBOTest, RGBA16_SNORM_RGBA)
1019 {
1020 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_render_snorm"));
1021 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
1022 testSigned(GL_RGBA, GL_RGBA16_SNORM_EXT, GL_RGBA);
1023 }
1024
1025 // Test PBO RGBA readback for RG16_SNORM color buffer.
TEST_P(ReadPixelsTextureNorm16PBOTest,RG16_SNORM_RGBA)1026 TEST_P(ReadPixelsTextureNorm16PBOTest, RG16_SNORM_RGBA)
1027 {
1028 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_render_snorm"));
1029 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
1030 testSigned(GL_RG, GL_RG16_SNORM_EXT, GL_RGBA);
1031 }
1032
1033 // Test PBO RG readback for RG16_SNORM color buffer.
TEST_P(ReadPixelsTextureNorm16PBOTest,RG16_SNORM_RG)1034 TEST_P(ReadPixelsTextureNorm16PBOTest, RG16_SNORM_RG)
1035 {
1036 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_render_snorm"));
1037 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
1038 testSigned(GL_RG, GL_RG16_SNORM_EXT, GL_RG);
1039 }
1040
1041 // Test PBO RGBA readback for R16_SNORM color buffer.
TEST_P(ReadPixelsTextureNorm16PBOTest,R16_SNORM_RGBA)1042 TEST_P(ReadPixelsTextureNorm16PBOTest, R16_SNORM_RGBA)
1043 {
1044 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_render_snorm"));
1045 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
1046 testSigned(GL_RED, GL_R16_SNORM_EXT, GL_RGBA);
1047 }
1048
1049 // Test PBO RED readback for R16_SNORM color buffer.
TEST_P(ReadPixelsTextureNorm16PBOTest,R16_SNORM_RED)1050 TEST_P(ReadPixelsTextureNorm16PBOTest, R16_SNORM_RED)
1051 {
1052 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_render_snorm"));
1053 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
1054 testSigned(GL_RED, GL_R16_SNORM_EXT, GL_RED);
1055 }
1056
1057 class ReadPixelsMultisampleTest : public ReadPixelsTest
1058 {
1059 protected:
ReadPixelsMultisampleTest()1060 ReadPixelsMultisampleTest() : mFBO(0), mRBO(0), mPBO(0)
1061 {
1062 setSamples(4);
1063 setMultisampleEnabled(true);
1064 }
1065
testSetUp()1066 void testSetUp() override
1067 {
1068 glGenFramebuffers(1, &mFBO);
1069 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
1070
1071 glGenRenderbuffers(1, &mRBO);
1072 glBindRenderbuffer(GL_RENDERBUFFER, mRBO);
1073
1074 glGenBuffers(1, &mPBO);
1075 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
1076 glBufferData(GL_PIXEL_PACK_BUFFER, 4 * getWindowWidth() * getWindowHeight(), nullptr,
1077 GL_STATIC_DRAW);
1078 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
1079
1080 ASSERT_GL_NO_ERROR();
1081 }
1082
testTearDown()1083 void testTearDown() override
1084 {
1085 glDeleteFramebuffers(1, &mFBO);
1086 glDeleteRenderbuffers(1, &mRBO);
1087 glDeleteBuffers(1, &mPBO);
1088 }
1089
1090 GLuint mFBO;
1091 GLuint mRBO;
1092 GLuint mPBO;
1093 };
1094
1095 // Test ReadPixels from a multisampled framebuffer.
TEST_P(ReadPixelsMultisampleTest,BasicClear)1096 TEST_P(ReadPixelsMultisampleTest, BasicClear)
1097 {
1098 if (getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_ANGLE_framebuffer_multisample"))
1099 {
1100 std::cout
1101 << "Test skipped because ES3 or GL_ANGLE_framebuffer_multisample is not available."
1102 << std::endl;
1103 return;
1104 }
1105
1106 if (IsGLExtensionEnabled("GL_ANGLE_framebuffer_multisample"))
1107 {
1108 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 2, GL_RGBA8, 4, 4);
1109 }
1110 else
1111 {
1112 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_RGBA8, 4, 4);
1113 }
1114
1115 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mRBO);
1116 ASSERT_GL_NO_ERROR();
1117
1118 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
1119 glClear(GL_COLOR_BUFFER_BIT);
1120
1121 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
1122 EXPECT_GL_NO_ERROR();
1123
1124 glReadPixels(0, 0, 1, 1, GL_RGBA8, GL_UNSIGNED_BYTE, nullptr);
1125 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1126 }
1127
1128 // Test ReadPixels from a multisampled swapchain.
TEST_P(ReadPixelsMultisampleTest,DefaultFramebuffer)1129 TEST_P(ReadPixelsMultisampleTest, DefaultFramebuffer)
1130 {
1131 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1132
1133 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
1134 glClear(GL_COLOR_BUFFER_BIT);
1135
1136 EXPECT_PIXEL_RECT_EQ(0, 0, getWindowWidth(), getWindowHeight(), GLColor::red);
1137 EXPECT_GL_NO_ERROR();
1138 }
1139
1140 // Test ReadPixels from a multisampled swapchain into a PBO.
TEST_P(ReadPixelsMultisampleTest,DefaultFramebufferPBO)1141 TEST_P(ReadPixelsMultisampleTest, DefaultFramebufferPBO)
1142 {
1143 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1144
1145 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
1146 glClear(GL_COLOR_BUFFER_BIT);
1147
1148 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
1149
1150 const int w = getWindowWidth();
1151 const int h = getWindowHeight();
1152 glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
1153 EXPECT_GL_NO_ERROR();
1154
1155 const std::vector<angle::GLColor> expectedColor(w * h, GLColor::red);
1156 std::vector<angle::GLColor> actualColor(w * h);
1157 const void *mapPointer =
1158 glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, sizeof(angle::GLColor) * w * h, GL_MAP_READ_BIT);
1159 ASSERT_NE(nullptr, mapPointer);
1160 memcpy(actualColor.data(), mapPointer, sizeof(angle::GLColor) * w * h);
1161 glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
1162
1163 EXPECT_EQ(expectedColor, actualColor);
1164 }
1165
1166 class ReadPixelsTextureTest : public ANGLETest<>
1167 {
1168 public:
ReadPixelsTextureTest()1169 ReadPixelsTextureTest() : mFBO(0), mTextureRGBA(0), mTextureBGRA(0)
1170 {
1171 setWindowWidth(32);
1172 setWindowHeight(32);
1173 setConfigRedBits(8);
1174 setConfigGreenBits(8);
1175 setConfigBlueBits(8);
1176 setConfigAlphaBits(8);
1177 }
1178
testSetUp()1179 void testSetUp() override
1180 {
1181 glGenTextures(1, &mTextureRGBA);
1182 glGenTextures(1, &mTextureBGRA);
1183 glGenFramebuffers(1, &mFBO);
1184 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
1185 }
1186
testTearDown()1187 void testTearDown() override
1188 {
1189 glDeleteFramebuffers(1, &mFBO);
1190 glDeleteTextures(1, &mTextureRGBA);
1191 glDeleteTextures(1, &mTextureBGRA);
1192 }
1193
initTextureRGBA(GLenum textureTarget,GLint levels,GLint attachmentLevel,GLint attachmentLayer)1194 void initTextureRGBA(GLenum textureTarget,
1195 GLint levels,
1196 GLint attachmentLevel,
1197 GLint attachmentLayer)
1198 {
1199 glBindTexture(textureTarget, mTextureRGBA);
1200 glTexStorage3D(textureTarget, levels, GL_RGBA8, kSize, kSize, kSize);
1201 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTextureRGBA,
1202 attachmentLevel, attachmentLayer);
1203 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1204 ASSERT_GL_NO_ERROR();
1205 initializeTextureData(textureTarget, levels, GL_RGBA);
1206 }
1207
initTextureBGRA(GLenum textureTarget,GLint levels,GLint attachmentLevel,GLint attachmentLayer)1208 void initTextureBGRA(GLenum textureTarget,
1209 GLint levels,
1210 GLint attachmentLevel,
1211 GLint attachmentLayer)
1212 {
1213 glBindTexture(textureTarget, mTextureBGRA);
1214 for (GLint level = 0; level < levels; ++level)
1215 {
1216 glTexImage3D(textureTarget, level, GL_BGRA_EXT, kSize >> level, kSize >> level,
1217 textureTarget == GL_TEXTURE_3D ? kSize >> level : kSize, 0, GL_BGRA_EXT,
1218 GL_UNSIGNED_BYTE, nullptr);
1219 }
1220 glTexParameteri(textureTarget, GL_TEXTURE_BASE_LEVEL, 0);
1221 glTexParameteri(textureTarget, GL_TEXTURE_MAX_LEVEL, levels - 1);
1222 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTextureBGRA,
1223 attachmentLevel, attachmentLayer);
1224 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1225 ASSERT_GL_NO_ERROR();
1226 initializeTextureData(textureTarget, levels, GL_BGRA_EXT);
1227 }
1228
testRead(GLenum textureTarget,GLint levels,GLint attachmentLevel,GLint attachmentLayer)1229 void testRead(GLenum textureTarget, GLint levels, GLint attachmentLevel, GLint attachmentLayer)
1230 {
1231 initTextureRGBA(textureTarget, levels, attachmentLevel, attachmentLayer);
1232 verifyColor(attachmentLevel, attachmentLayer);
1233
1234 // Skip BGRA test on GL/Nvidia, leading to internal incomplete framebuffer error.
1235 // http://anglebug.com/42266676
1236 ANGLE_SKIP_TEST_IF(IsNVIDIA() && IsOpenGL());
1237
1238 if (IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"))
1239 {
1240 initTextureBGRA(textureTarget, levels, attachmentLevel, attachmentLayer);
1241 verifyColor(attachmentLevel, attachmentLayer);
1242 }
1243 }
1244
initPBO()1245 void initPBO()
1246 {
1247 // Create a buffer big enough to hold mip 0 + allow some offset during readback.
1248 glGenBuffers(1, &mBuffer);
1249 glBindBuffer(GL_PIXEL_PACK_BUFFER, mBuffer);
1250 glBufferData(GL_PIXEL_PACK_BUFFER, sizeof(angle::GLColor) * 16 * 2, nullptr,
1251 GL_STREAM_COPY);
1252 ASSERT_GL_NO_ERROR();
1253 }
1254
testPBORead(GLenum textureTarget,GLint levels,GLint attachmentLevel,GLint attachmentLayer)1255 void testPBORead(GLenum textureTarget,
1256 GLint levels,
1257 GLint attachmentLevel,
1258 GLint attachmentLayer)
1259 {
1260 initPBO();
1261 initTextureRGBA(textureTarget, levels, attachmentLevel, attachmentLayer);
1262 verifyPBO(attachmentLevel, attachmentLayer);
1263
1264 // Skip BGRA test on GL/Nvidia, leading to internal incomplete framebuffer error.
1265 // http://anglebug.com/42266676
1266 ANGLE_SKIP_TEST_IF(IsNVIDIA() && IsOpenGL());
1267
1268 if (IsGLExtensionEnabled("GL_EXT_texture_format_BGRA8888"))
1269 {
1270 initTextureBGRA(textureTarget, levels, attachmentLevel, attachmentLayer);
1271 verifyPBO(attachmentLevel, attachmentLayer);
1272 }
1273 }
1274
1275 // Give each {level,layer} pair a (probably) unique color via random.
getColorValue(GLint level,GLint layer)1276 GLuint getColorValue(GLint level, GLint layer)
1277 {
1278 mRNG.reseed(level + layer * 32);
1279 return mRNG.randomUInt();
1280 }
1281
verifyColor(GLint level,GLint layer)1282 void verifyColor(GLint level, GLint layer)
1283 {
1284 const angle::GLColor colorValue(getColorValue(level, layer));
1285 const GLint size = kSize >> level;
1286 EXPECT_PIXEL_RECT_EQ(0, 0, size, size, colorValue);
1287 }
1288
verifyPBO(GLint level,GLint layer)1289 void verifyPBO(GLint level, GLint layer)
1290 {
1291 const GLint size = kSize >> level;
1292 const GLsizei offset = kSize * (level + layer);
1293 glReadPixels(0, 0, size, size, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<void *>(offset));
1294
1295 const std::vector<angle::GLColor> expectedColor(size * size, getColorValue(level, layer));
1296 std::vector<angle::GLColor> actualColor(size * size);
1297
1298 void *mapPointer = glMapBufferRange(GL_PIXEL_PACK_BUFFER, offset,
1299 sizeof(angle::GLColor) * size * size, GL_MAP_READ_BIT);
1300 ASSERT_NE(nullptr, mapPointer);
1301 memcpy(actualColor.data(), mapPointer, sizeof(angle::GLColor) * size * size);
1302 glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
1303
1304 ASSERT_GL_NO_ERROR();
1305 EXPECT_EQ(expectedColor, actualColor);
1306 }
1307
initializeTextureData(GLenum textureTarget,GLint levels,GLenum format)1308 void initializeTextureData(GLenum textureTarget, GLint levels, GLenum format)
1309 {
1310 for (GLint level = 0; level < levels; ++level)
1311 {
1312 GLint mipSize = kSize >> level;
1313 GLint layers = (textureTarget == GL_TEXTURE_3D ? mipSize : kSize);
1314
1315 size_t layerSize = mipSize * mipSize;
1316 std::vector<GLuint> textureData(layers * layerSize);
1317
1318 for (GLint layer = 0; layer < layers; ++layer)
1319 {
1320 GLuint colorValue = getColorValue(level, layer);
1321 size_t offset = (layer * layerSize);
1322
1323 if (format == GL_BGRA_EXT)
1324 {
1325 const GLuint rb = colorValue & 0x00FF00FF;
1326 const GLuint br = (rb & 0xFF) << 16 | rb >> 16;
1327 const GLuint ga = colorValue & 0xFF00FF00;
1328 colorValue = ga | br;
1329 }
1330
1331 std::fill(textureData.begin() + offset, textureData.begin() + offset + layerSize,
1332 colorValue);
1333 }
1334
1335 glTexSubImage3D(textureTarget, level, 0, 0, 0, mipSize, mipSize, layers, format,
1336 GL_UNSIGNED_BYTE, textureData.data());
1337 }
1338 }
1339
1340 static constexpr GLint kSize = 4;
1341
1342 angle::RNG mRNG;
1343 GLuint mFBO;
1344 GLuint mTextureRGBA;
1345 GLuint mTextureBGRA;
1346 GLuint mBuffer;
1347 };
1348
1349 // Test 3D attachment readback.
TEST_P(ReadPixelsTextureTest,BasicAttachment3D)1350 TEST_P(ReadPixelsTextureTest, BasicAttachment3D)
1351 {
1352 testRead(GL_TEXTURE_3D, 1, 0, 0);
1353 }
1354
1355 // Test 3D attachment readback, non-zero mip.
TEST_P(ReadPixelsTextureTest,MipAttachment3D)1356 TEST_P(ReadPixelsTextureTest, MipAttachment3D)
1357 {
1358 testRead(GL_TEXTURE_3D, 2, 1, 0);
1359 }
1360
1361 // Test 3D attachment readback, non-zero layer.
TEST_P(ReadPixelsTextureTest,LayerAttachment3D)1362 TEST_P(ReadPixelsTextureTest, LayerAttachment3D)
1363 {
1364 testRead(GL_TEXTURE_3D, 1, 0, 1);
1365 }
1366
1367 // Test 3D attachment readback, non-zero mip and layer.
TEST_P(ReadPixelsTextureTest,MipLayerAttachment3D)1368 TEST_P(ReadPixelsTextureTest, MipLayerAttachment3D)
1369 {
1370 testRead(GL_TEXTURE_3D, 2, 1, 1);
1371 }
1372
1373 // Test 2D array attachment readback.
TEST_P(ReadPixelsTextureTest,BasicAttachment2DArray)1374 TEST_P(ReadPixelsTextureTest, BasicAttachment2DArray)
1375 {
1376 testRead(GL_TEXTURE_2D_ARRAY, 1, 0, 0);
1377 }
1378
1379 // Test 3D attachment readback, non-zero mip.
TEST_P(ReadPixelsTextureTest,MipAttachment2DArray)1380 TEST_P(ReadPixelsTextureTest, MipAttachment2DArray)
1381 {
1382 testRead(GL_TEXTURE_2D_ARRAY, 2, 1, 0);
1383 }
1384
1385 // Test 3D attachment readback, non-zero layer.
TEST_P(ReadPixelsTextureTest,LayerAttachment2DArray)1386 TEST_P(ReadPixelsTextureTest, LayerAttachment2DArray)
1387 {
1388 testRead(GL_TEXTURE_2D_ARRAY, 1, 0, 1);
1389 }
1390
1391 // Test 3D attachment readback, non-zero mip and layer.
TEST_P(ReadPixelsTextureTest,MipLayerAttachment2DArray)1392 TEST_P(ReadPixelsTextureTest, MipLayerAttachment2DArray)
1393 {
1394 testRead(GL_TEXTURE_2D_ARRAY, 2, 1, 1);
1395 }
1396
1397 // Test 3D attachment PBO readback.
TEST_P(ReadPixelsTextureTest,BasicAttachment3DPBO)1398 TEST_P(ReadPixelsTextureTest, BasicAttachment3DPBO)
1399 {
1400 testPBORead(GL_TEXTURE_3D, 1, 0, 0);
1401 }
1402
1403 // Test 3D attachment readback, non-zero mip.
TEST_P(ReadPixelsTextureTest,MipAttachment3DPBO)1404 TEST_P(ReadPixelsTextureTest, MipAttachment3DPBO)
1405 {
1406 testPBORead(GL_TEXTURE_3D, 2, 1, 0);
1407 }
1408
1409 // Test 3D attachment readback, non-zero layer.
TEST_P(ReadPixelsTextureTest,LayerAttachment3DPBO)1410 TEST_P(ReadPixelsTextureTest, LayerAttachment3DPBO)
1411 {
1412 // http://anglebug.com/40644770
1413 ANGLE_SKIP_TEST_IF(IsMac() && IsIntelUHD630Mobile() && IsDesktopOpenGL());
1414
1415 testPBORead(GL_TEXTURE_3D, 1, 0, 1);
1416 }
1417
1418 // Test 3D attachment readback, non-zero mip and layer.
TEST_P(ReadPixelsTextureTest,MipLayerAttachment3DPBO)1419 TEST_P(ReadPixelsTextureTest, MipLayerAttachment3DPBO)
1420 {
1421 // http://anglebug.com/40644770
1422 ANGLE_SKIP_TEST_IF(IsMac() && IsIntelUHD630Mobile() && IsDesktopOpenGL());
1423
1424 testPBORead(GL_TEXTURE_3D, 2, 1, 1);
1425 }
1426
1427 // Test 2D array attachment readback.
TEST_P(ReadPixelsTextureTest,BasicAttachment2DArrayPBO)1428 TEST_P(ReadPixelsTextureTest, BasicAttachment2DArrayPBO)
1429 {
1430 testPBORead(GL_TEXTURE_2D_ARRAY, 1, 0, 0);
1431 }
1432
1433 // Test 3D attachment readback, non-zero mip.
TEST_P(ReadPixelsTextureTest,MipAttachment2DArrayPBO)1434 TEST_P(ReadPixelsTextureTest, MipAttachment2DArrayPBO)
1435 {
1436 testPBORead(GL_TEXTURE_2D_ARRAY, 2, 1, 0);
1437 }
1438
1439 // Test 3D attachment readback, non-zero layer.
TEST_P(ReadPixelsTextureTest,LayerAttachment2DArrayPBO)1440 TEST_P(ReadPixelsTextureTest, LayerAttachment2DArrayPBO)
1441 {
1442 // http://anglebug.com/40644770
1443 ANGLE_SKIP_TEST_IF(IsMac() && IsIntelUHD630Mobile() && IsDesktopOpenGL());
1444
1445 testPBORead(GL_TEXTURE_2D_ARRAY, 1, 0, 1);
1446 }
1447
1448 // Test 3D attachment readback, non-zero mip and layer.
TEST_P(ReadPixelsTextureTest,MipLayerAttachment2DArrayPBO)1449 TEST_P(ReadPixelsTextureTest, MipLayerAttachment2DArrayPBO)
1450 {
1451 // http://anglebug.com/40644770
1452 ANGLE_SKIP_TEST_IF(IsMac() && IsIntelUHD630Mobile() && IsDesktopOpenGL());
1453
1454 testPBORead(GL_TEXTURE_2D_ARRAY, 2, 1, 1);
1455 }
1456
1457 // a test class to be used for error checking of glReadPixels
1458 class ReadPixelsErrorTest : public ReadPixelsTest
1459 {
1460 protected:
ReadPixelsErrorTest()1461 ReadPixelsErrorTest() : mTexture(0), mFBO(0) {}
1462
testSetUp()1463 void testSetUp() override
1464 {
1465 glGenTextures(1, &mTexture);
1466 glBindTexture(GL_TEXTURE_2D, mTexture);
1467 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 4, 1);
1468
1469 glGenFramebuffers(1, &mFBO);
1470 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
1471 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
1472 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1473
1474 ASSERT_GL_NO_ERROR();
1475 }
1476
testTearDown()1477 void testTearDown() override
1478 {
1479 glDeleteTextures(1, &mTexture);
1480 glDeleteFramebuffers(1, &mFBO);
1481 }
1482
testUnsupportedTypeConversions(std::vector<GLenum> internalFormats,std::vector<GLenum> unsupportedTypes)1483 void testUnsupportedTypeConversions(std::vector<GLenum> internalFormats,
1484 std::vector<GLenum> unsupportedTypes)
1485 {
1486 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
1487 for (GLenum internalFormat : internalFormats)
1488 {
1489 GLRenderbuffer rbo;
1490 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
1491 glRenderbufferStorage(GL_RENDERBUFFER, internalFormat, 1, 1);
1492 ASSERT_GL_NO_ERROR();
1493
1494 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo);
1495 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1496
1497 GLenum implementationFormat, implementationType;
1498 glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT,
1499 reinterpret_cast<GLint *>(&implementationFormat));
1500 ASSERT_GL_NO_ERROR();
1501 glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE,
1502 reinterpret_cast<GLint *>(&implementationType));
1503 ASSERT_GL_NO_ERROR();
1504
1505 for (GLenum type : unsupportedTypes)
1506 {
1507 uint8_t pixel[8] = {};
1508 if (implementationFormat != GL_RGBA || implementationType != type)
1509 {
1510 glReadPixels(0, 0, 1, 1, GL_RGBA, type, pixel);
1511 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1512 }
1513 }
1514 }
1515 }
1516
1517 GLuint mTexture;
1518 GLuint mFBO;
1519 };
1520
1521 // The test verifies that glReadPixels generates a GL_INVALID_OPERATION error
1522 // when the read buffer is GL_NONE.
1523 // Reference: GLES 3.0.4, Section 4.3.2 Reading Pixels
TEST_P(ReadPixelsErrorTest,ReadBufferIsNone)1524 TEST_P(ReadPixelsErrorTest, ReadBufferIsNone)
1525 {
1526 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
1527 glReadBuffer(GL_NONE);
1528 std::vector<GLubyte> pixels(4);
1529 EXPECT_GL_NO_ERROR();
1530 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
1531 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1532 }
1533
1534 // The test verifies that glReadPixels generates a GL_INVALID_OPERATION
1535 // error when reading signed 8-bit color buffers using incompatible types.
TEST_P(ReadPixelsErrorTest,ColorBufferSnorm8)1536 TEST_P(ReadPixelsErrorTest, ColorBufferSnorm8)
1537 {
1538 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_render_snorm"));
1539
1540 testUnsupportedTypeConversions({GL_R8_SNORM, GL_RG8_SNORM, GL_RGBA8_SNORM},
1541 {GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT});
1542 }
1543
1544 // The test verifies that glReadPixels generates a GL_INVALID_OPERATION
1545 // error when reading signed 16-bit color buffers using incompatible types.
TEST_P(ReadPixelsErrorTest,ColorBufferSnorm16)1546 TEST_P(ReadPixelsErrorTest, ColorBufferSnorm16)
1547 {
1548 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_render_snorm"));
1549 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_norm16"));
1550
1551 testUnsupportedTypeConversions({GL_R16_SNORM_EXT, GL_RG16_SNORM_EXT, GL_RGBA16_SNORM_EXT},
1552 {GL_BYTE, GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT});
1553 }
1554
1555 // a test class to be used for error checking of glReadPixels with WebGLCompatibility
1556 class ReadPixelsWebGLErrorTest : public ReadPixelsTest
1557 {
1558 protected:
ReadPixelsWebGLErrorTest()1559 ReadPixelsWebGLErrorTest() : mTexture(0), mFBO(0) { setWebGLCompatibilityEnabled(true); }
1560
testSetUp()1561 void testSetUp() override
1562 {
1563 glGenTextures(1, &mTexture);
1564 glBindTexture(GL_TEXTURE_2D, mTexture);
1565 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 4, 1);
1566
1567 glGenFramebuffers(1, &mFBO);
1568 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
1569 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
1570 ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1571
1572 ASSERT_GL_NO_ERROR();
1573 }
1574
testTearDown()1575 void testTearDown() override
1576 {
1577 glDeleteTextures(1, &mTexture);
1578 glDeleteFramebuffers(1, &mFBO);
1579 }
1580
1581 GLuint mTexture;
1582 GLuint mFBO;
1583 };
1584
1585 // Test that WebGL context readpixels generates an error when reading GL_UNSIGNED_INT_24_8 type.
TEST_P(ReadPixelsWebGLErrorTest,TypeIsUnsignedInt24_8)1586 TEST_P(ReadPixelsWebGLErrorTest, TypeIsUnsignedInt24_8)
1587 {
1588 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
1589 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
1590 glReadBuffer(GL_COLOR_ATTACHMENT0);
1591 std::vector<GLuint> pixels(4);
1592 EXPECT_GL_NO_ERROR();
1593 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_INT_24_8, pixels.data());
1594 EXPECT_GL_ERROR(GL_INVALID_ENUM);
1595 }
1596
1597 // Test that WebGL context readpixels generates an error when reading GL_DEPTH_COMPONENT format.
TEST_P(ReadPixelsWebGLErrorTest,FormatIsDepthComponent)1598 TEST_P(ReadPixelsWebGLErrorTest, FormatIsDepthComponent)
1599 {
1600 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
1601 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
1602 glReadBuffer(GL_COLOR_ATTACHMENT0);
1603 std::vector<GLubyte> pixels(4);
1604 EXPECT_GL_NO_ERROR();
1605 glReadPixels(0, 0, 1, 1, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, pixels.data());
1606 EXPECT_GL_ERROR(GL_INVALID_ENUM);
1607 }
1608
1609 } // anonymous namespace
1610
1611 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
1612 // tests should be run against.
1613 ANGLE_INSTANTIATE_TEST_ES2(ReadPixelsTest);
1614 ANGLE_INSTANTIATE_TEST_ES2(ReadPixelsPBONVTest);
1615
1616 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ReadPixelsPBOTest);
1617 ANGLE_INSTANTIATE_TEST_ES3(ReadPixelsPBOTest);
1618
1619 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ReadPixelsPBODrawTest);
1620 ANGLE_INSTANTIATE_TEST_ES3_AND(ReadPixelsPBODrawTest,
1621 ES3_VULKAN().enable(Feature::ForceFallbackFormat));
1622
1623 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ReadPixelsTextureNorm16PBOTest);
1624 ANGLE_INSTANTIATE_TEST_ES3(ReadPixelsTextureNorm16PBOTest);
1625
1626 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ReadPixelsMultisampleTest);
1627 ANGLE_INSTANTIATE_TEST_ES3(ReadPixelsMultisampleTest);
1628
1629 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ReadPixelsTextureTest);
1630 ANGLE_INSTANTIATE_TEST_ES3(ReadPixelsTextureTest);
1631
1632 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ReadPixelsErrorTest);
1633 ANGLE_INSTANTIATE_TEST_ES3(ReadPixelsErrorTest);
1634
1635 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ReadPixelsWebGLErrorTest);
1636 ANGLE_INSTANTIATE_TEST_ES3(ReadPixelsWebGLErrorTest);
1637