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/1413 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 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
83 glBufferData(GL_PIXEL_PACK_BUFFER, bufferSize, nullptr, GL_STATIC_DRAW);
84 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
85
86 glDeleteTextures(1, &mTexture);
87 glGenTextures(1, &mTexture);
88 glBindTexture(GL_TEXTURE_2D, mTexture);
89 glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, fboWidth, fboHeight);
90 mFBOWidth = fboWidth;
91 mFBOHeight = 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
testTearDown()100 void testTearDown() override
101 {
102 glDeleteBuffers(1, &mPBO);
103 glDeleteTextures(1, &mTexture);
104 glDeleteFramebuffers(1, &mFBO);
105 }
106
hasPBOExts() const107 bool hasPBOExts() const
108 {
109 return IsGLExtensionEnabled("GL_NV_pixel_buffer_object") &&
110 IsGLExtensionEnabled("GL_EXT_texture_storage");
111 }
112
113 GLuint mPBO = 0;
114 GLuint mTexture = 0;
115 GLuint mFBO = 0;
116 GLuint mFBOWidth = 0;
117 GLuint mFBOHeight = 0;
118 };
119
120 // Test basic usage of PBOs.
TEST_P(ReadPixelsPBONVTest,Basic)121 TEST_P(ReadPixelsPBONVTest, Basic)
122 {
123 ANGLE_SKIP_TEST_IF(!hasPBOExts() || !IsGLExtensionEnabled("GL_EXT_map_buffer_range") ||
124 !IsGLExtensionEnabled("GL_OES_mapbuffer"));
125
126 // http://anglebug.com/5022
127 ANGLE_SKIP_TEST_IF(IsWindows() && IsDesktopOpenGL());
128 // http://anglebug.com/5386
129 ANGLE_SKIP_TEST_IF(IsLinux() && IsAMD() && IsDesktopOpenGL());
130
131 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
132 glClear(GL_COLOR_BUFFER_BIT);
133 // Clear last pixel to green
134 glScissor(15, 15, 1, 1);
135 glEnable(GL_SCISSOR_TEST);
136 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
137 glClear(GL_COLOR_BUFFER_BIT);
138 EXPECT_GL_NO_ERROR();
139
140 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
141 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
142
143 void *mappedPtr = glMapBufferRangeEXT(GL_PIXEL_PACK_BUFFER, 0, 32, GL_MAP_READ_BIT);
144 GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
145 EXPECT_GL_NO_ERROR();
146
147 EXPECT_EQ(GLColor::red, dataColor[0]);
148 EXPECT_EQ(GLColor::red, dataColor[16 * 16 - 2]);
149 EXPECT_EQ(GLColor::green, dataColor[16 * 16 - 1]);
150
151 glUnmapBufferOES(GL_PIXEL_PACK_BUFFER);
152 EXPECT_GL_NO_ERROR();
153 }
154
155 // Test that calling SubData preserves PBO data.
TEST_P(ReadPixelsPBONVTest,SubDataPreservesContents)156 TEST_P(ReadPixelsPBONVTest, SubDataPreservesContents)
157 {
158 ANGLE_SKIP_TEST_IF(!hasPBOExts() || !IsGLExtensionEnabled("GL_EXT_map_buffer_range") ||
159 !IsGLExtensionEnabled("GL_OES_mapbuffer"));
160
161 // anglebug.com/2185
162 ANGLE_SKIP_TEST_IF(IsOSX() && IsNVIDIA() && IsDesktopOpenGL());
163
164 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
165 glClear(GL_COLOR_BUFFER_BIT);
166 EXPECT_GL_NO_ERROR();
167
168 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
169 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
170
171 unsigned char data[4] = {1, 2, 3, 4};
172
173 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
174 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
175 glBufferSubData(GL_ARRAY_BUFFER, 0, 4, data);
176
177 void *mappedPtr = glMapBufferRangeEXT(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
178 GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
179 EXPECT_GL_NO_ERROR();
180
181 EXPECT_EQ(GLColor(1, 2, 3, 4), dataColor[0]);
182 EXPECT_EQ(GLColor::red, dataColor[1]);
183
184 glUnmapBufferOES(GL_ARRAY_BUFFER);
185 EXPECT_GL_NO_ERROR();
186 }
187
188 // Test that calling ReadPixels with GL_DYNAMIC_DRAW buffer works
TEST_P(ReadPixelsPBONVTest,DynamicPBO)189 TEST_P(ReadPixelsPBONVTest, DynamicPBO)
190 {
191 ANGLE_SKIP_TEST_IF(!hasPBOExts() || !IsGLExtensionEnabled("GL_EXT_map_buffer_range") ||
192 !IsGLExtensionEnabled("GL_OES_mapbuffer"));
193
194 // anglebug.com/2185
195 ANGLE_SKIP_TEST_IF(IsOSX() && IsNVIDIA() && IsDesktopOpenGL());
196
197 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
198 glBufferData(GL_PIXEL_PACK_BUFFER, 4 * getWindowWidth() * getWindowHeight(), nullptr,
199 GL_DYNAMIC_DRAW);
200
201 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
202 glClear(GL_COLOR_BUFFER_BIT);
203 EXPECT_GL_NO_ERROR();
204
205 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
206
207 unsigned char data[4] = {1, 2, 3, 4};
208
209 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
210 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
211 glBufferSubData(GL_ARRAY_BUFFER, 0, 4, data);
212
213 void *mappedPtr = glMapBufferRangeEXT(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
214 GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
215 EXPECT_GL_NO_ERROR();
216
217 EXPECT_EQ(GLColor(1, 2, 3, 4), dataColor[0]);
218 EXPECT_EQ(GLColor::red, dataColor[1]);
219
220 glUnmapBufferOES(GL_ARRAY_BUFFER);
221 EXPECT_GL_NO_ERROR();
222 }
223
TEST_P(ReadPixelsPBONVTest,ReadFromFBO)224 TEST_P(ReadPixelsPBONVTest, ReadFromFBO)
225 {
226 ANGLE_SKIP_TEST_IF(!hasPBOExts() || !IsGLExtensionEnabled("GL_EXT_map_buffer_range") ||
227 !IsGLExtensionEnabled("GL_OES_mapbuffer"));
228
229 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
230 glViewport(0, 0, mFBOWidth, mFBOHeight);
231 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
232 glClear(GL_COLOR_BUFFER_BIT);
233 // Clear last pixel to green
234 glScissor(mFBOWidth - 1, mFBOHeight - 1, 1, 1);
235 glEnable(GL_SCISSOR_TEST);
236 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
237 glClear(GL_COLOR_BUFFER_BIT);
238 EXPECT_GL_NO_ERROR();
239
240 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
241 glReadPixels(0, 0, mFBOWidth, mFBOHeight, GL_RGBA, GL_UNSIGNED_BYTE, 0);
242
243 void *mappedPtr =
244 glMapBufferRangeEXT(GL_PIXEL_PACK_BUFFER, 0, 4 * mFBOWidth * mFBOHeight, GL_MAP_READ_BIT);
245 GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
246 EXPECT_GL_NO_ERROR();
247
248 EXPECT_EQ(GLColor::red, dataColor[0]);
249 EXPECT_EQ(GLColor::red, dataColor[mFBOWidth * mFBOHeight - 2]);
250 EXPECT_EQ(GLColor::green, dataColor[mFBOWidth * mFBOHeight - 1]);
251
252 glUnmapBufferOES(GL_PIXEL_PACK_BUFFER);
253 EXPECT_GL_NO_ERROR();
254 }
255
256 // Test calling ReadPixels with a non-zero "data" param into a PBO
TEST_P(ReadPixelsPBONVTest,ReadFromFBOWithDataOffset)257 TEST_P(ReadPixelsPBONVTest, ReadFromFBOWithDataOffset)
258 {
259 ANGLE_SKIP_TEST_IF(!hasPBOExts() || !IsGLExtensionEnabled("GL_EXT_map_buffer_range") ||
260 !IsGLExtensionEnabled("GL_OES_mapbuffer"));
261
262 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
263 glViewport(0, 0, mFBOWidth, mFBOHeight);
264 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
265 glClear(GL_COLOR_BUFFER_BIT);
266 // Clear first pixel to green
267 glScissor(0, 0, 1, 1);
268 glEnable(GL_SCISSOR_TEST);
269 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
270 glClear(GL_COLOR_BUFFER_BIT);
271 EXPECT_GL_NO_ERROR();
272
273 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
274
275 // Read (height - 1) rows offset by width * 4.
276 glReadPixels(0, 0, mFBOWidth, mFBOHeight - 1, GL_RGBA, GL_UNSIGNED_BYTE,
277 reinterpret_cast<void *>(mFBOWidth * static_cast<uintptr_t>(4)));
278
279 void *mappedPtr =
280 glMapBufferRangeEXT(GL_PIXEL_PACK_BUFFER, 0, 4 * mFBOWidth * mFBOHeight, GL_MAP_READ_BIT);
281 GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
282 EXPECT_GL_NO_ERROR();
283
284 EXPECT_EQ(GLColor::green, dataColor[mFBOWidth]);
285 EXPECT_EQ(GLColor::red, dataColor[mFBOWidth + 1]);
286 EXPECT_EQ(GLColor::red, dataColor[mFBOWidth * mFBOHeight - 1]);
287
288 glUnmapBufferOES(GL_PIXEL_PACK_BUFFER);
289 EXPECT_GL_NO_ERROR();
290 }
291
292 class ReadPixelsPBOTest : public ReadPixelsPBONVTest
293 {
294 protected:
ReadPixelsPBOTest()295 ReadPixelsPBOTest() : ReadPixelsPBONVTest() {}
296
testSetUp()297 void testSetUp() override
298 {
299 glGenBuffers(1, &mPBO);
300 glGenFramebuffers(1, &mFBO);
301
302 Reset(4 * getWindowWidth() * getWindowHeight(), 4, 1);
303 }
304
Reset(GLuint bufferSize,GLuint fboWidth,GLuint fboHeight)305 void Reset(GLuint bufferSize, GLuint fboWidth, GLuint fboHeight) override
306 {
307 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
308 glBufferData(GL_PIXEL_PACK_BUFFER, bufferSize, nullptr, GL_STATIC_DRAW);
309 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
310
311 glDeleteTextures(1, &mTexture);
312 glGenTextures(1, &mTexture);
313 glBindTexture(GL_TEXTURE_2D, mTexture);
314 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, fboWidth, fboHeight);
315
316 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
317 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
318 glBindFramebuffer(GL_FRAMEBUFFER, 0);
319
320 mFBOWidth = fboWidth;
321 mFBOHeight = fboHeight;
322
323 ASSERT_GL_NO_ERROR();
324 }
325 };
326
327 // Test basic usage of PBOs.
TEST_P(ReadPixelsPBOTest,Basic)328 TEST_P(ReadPixelsPBOTest, Basic)
329 {
330 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
331 glClear(GL_COLOR_BUFFER_BIT);
332 EXPECT_GL_NO_ERROR();
333
334 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
335 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
336
337 void *mappedPtr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, 32, GL_MAP_READ_BIT);
338 GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
339 EXPECT_GL_NO_ERROR();
340
341 EXPECT_EQ(GLColor::red, dataColor[0]);
342
343 glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
344 EXPECT_GL_NO_ERROR();
345 }
346
347 // Test an error is generated when the PBO is too small.
TEST_P(ReadPixelsPBOTest,PBOTooSmall)348 TEST_P(ReadPixelsPBOTest, PBOTooSmall)
349 {
350 Reset(4 * 16 * 16 - 1, 16, 16);
351
352 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
353 glClear(GL_COLOR_BUFFER_BIT);
354 EXPECT_GL_NO_ERROR();
355
356 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
357 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
358
359 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
360 }
361
362 // Test an error is generated when the PBO is mapped.
TEST_P(ReadPixelsPBOTest,PBOMapped)363 TEST_P(ReadPixelsPBOTest, PBOMapped)
364 {
365 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
366 glClear(GL_COLOR_BUFFER_BIT);
367 EXPECT_GL_NO_ERROR();
368
369 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
370 glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, 32, GL_MAP_READ_BIT);
371 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
372
373 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
374 }
375
376 // Test that binding a PBO to ARRAY_BUFFER works as expected.
TEST_P(ReadPixelsPBOTest,ArrayBufferTarget)377 TEST_P(ReadPixelsPBOTest, ArrayBufferTarget)
378 {
379 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
380 glClear(GL_COLOR_BUFFER_BIT);
381 EXPECT_GL_NO_ERROR();
382
383 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
384 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
385
386 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
387 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
388
389 void *mappedPtr = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
390 GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
391 EXPECT_GL_NO_ERROR();
392
393 EXPECT_EQ(GLColor::red, dataColor[0]);
394
395 glUnmapBuffer(GL_ARRAY_BUFFER);
396 EXPECT_GL_NO_ERROR();
397 }
398
399 // Test that using a PBO does not overwrite existing data.
TEST_P(ReadPixelsPBOTest,ExistingDataPreserved)400 TEST_P(ReadPixelsPBOTest, ExistingDataPreserved)
401 {
402 // TODO(geofflang): Figure out why this fails on AMD OpenGL (http://anglebug.com/1291)
403 ANGLE_SKIP_TEST_IF(IsAMD() && IsOpenGL());
404
405 // Clear backbuffer to red
406 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
407 glClear(GL_COLOR_BUFFER_BIT);
408 EXPECT_GL_NO_ERROR();
409
410 // Read 16x16 region from red backbuffer to PBO
411 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
412 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
413
414 // Clear backbuffer to green
415 glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
416 glClear(GL_COLOR_BUFFER_BIT);
417 EXPECT_GL_NO_ERROR();
418
419 // Read 16x16 region from green backbuffer to PBO at offset 16
420 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, reinterpret_cast<void *>(16));
421 void *mappedPtr = glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, 32, GL_MAP_READ_BIT);
422 GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
423 EXPECT_GL_NO_ERROR();
424
425 // Test pixel 0 is red (existing data)
426 EXPECT_EQ(GLColor::red, dataColor[0]);
427
428 // Test pixel 16 is green (new data)
429 EXPECT_EQ(GLColor::green, dataColor[16]);
430
431 glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
432 EXPECT_GL_NO_ERROR();
433 }
434
435 // Test that calling SubData preserves PBO data.
TEST_P(ReadPixelsPBOTest,SubDataPreservesContents)436 TEST_P(ReadPixelsPBOTest, SubDataPreservesContents)
437 {
438 // anglebug.com/2185
439 ANGLE_SKIP_TEST_IF(IsOSX() && IsNVIDIA() && IsDesktopOpenGL());
440
441 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
442 glClear(GL_COLOR_BUFFER_BIT);
443 EXPECT_GL_NO_ERROR();
444
445 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
446 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
447
448 unsigned char data[4] = {1, 2, 3, 4};
449
450 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
451 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
452 glBufferSubData(GL_ARRAY_BUFFER, 0, 4, data);
453
454 void *mappedPtr = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
455 GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
456 EXPECT_GL_NO_ERROR();
457
458 EXPECT_EQ(GLColor(1, 2, 3, 4), dataColor[0]);
459
460 glUnmapBuffer(GL_ARRAY_BUFFER);
461 EXPECT_GL_NO_ERROR();
462 }
463
464 // Same as the prior test, but with an offset.
TEST_P(ReadPixelsPBOTest,SubDataOffsetPreservesContents)465 TEST_P(ReadPixelsPBOTest, SubDataOffsetPreservesContents)
466 {
467 // anglebug.com/1415
468 ANGLE_SKIP_TEST_IF(IsNexus5X() && IsAdreno() && IsOpenGLES());
469 // anglebug.com/2185
470 ANGLE_SKIP_TEST_IF(IsOSX() && IsNVIDIA() && IsDesktopOpenGL());
471
472 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
473 glClear(GL_COLOR_BUFFER_BIT);
474 EXPECT_GL_NO_ERROR();
475
476 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
477 glReadPixels(0, 0, 16, 16, GL_RGBA, GL_UNSIGNED_BYTE, 0);
478
479 unsigned char data[4] = {1, 2, 3, 4};
480
481 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
482 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
483 glBufferSubData(GL_ARRAY_BUFFER, 16, 4, data);
484
485 void *mappedPtr = glMapBufferRange(GL_ARRAY_BUFFER, 0, 32, GL_MAP_READ_BIT);
486 GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
487 EXPECT_GL_NO_ERROR();
488
489 EXPECT_EQ(GLColor::red, dataColor[0]);
490 EXPECT_EQ(GLColor(1, 2, 3, 4), dataColor[4]);
491
492 glUnmapBuffer(GL_ARRAY_BUFFER);
493 EXPECT_GL_NO_ERROR();
494 }
495
496 // Test that uploading data to buffer that's in use then writing to it as PBO works.
TEST_P(ReadPixelsPBOTest,UseAsUBOThenUpdateThenReadFromFBO)497 TEST_P(ReadPixelsPBOTest, UseAsUBOThenUpdateThenReadFromFBO)
498 {
499 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
500 glViewport(0, 0, mFBOWidth, mFBOHeight);
501
502 const std::array<GLColor, 4> kInitialData = {GLColor::red, GLColor::red, GLColor::red,
503 GLColor::red};
504 const std::array<GLColor, 4> kUpdateData = {GLColor::white, GLColor::white, GLColor::white,
505 GLColor::white};
506
507 GLBuffer buffer;
508 glBindBuffer(GL_UNIFORM_BUFFER, buffer);
509 glBufferData(GL_UNIFORM_BUFFER, sizeof(kInitialData), kInitialData.data(), GL_DYNAMIC_COPY);
510 glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);
511 EXPECT_GL_NO_ERROR();
512
513 constexpr char kVerifyUBO[] = R"(#version 300 es
514 precision mediump float;
515 uniform block {
516 uvec4 data;
517 } ubo;
518 out vec4 colorOut;
519 void main()
520 {
521 if (all(equal(ubo.data, uvec4(0xFF0000FFu))))
522 colorOut = vec4(0, 1.0, 0, 1.0);
523 else
524 colorOut = vec4(1.0, 0, 0, 1.0);
525 })";
526
527 ANGLE_GL_PROGRAM(verifyUbo, essl3_shaders::vs::Simple(), kVerifyUBO);
528 drawQuad(verifyUbo, essl3_shaders::PositionAttrib(), 0.5);
529 EXPECT_GL_NO_ERROR();
530
531 // Update buffer data
532 glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(kInitialData), kUpdateData.data());
533 EXPECT_GL_NO_ERROR();
534
535 // Clear first pixel to blue
536 glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
537 glScissor(0, 0, 1, 1);
538 glEnable(GL_SCISSOR_TEST);
539 glClear(GL_COLOR_BUFFER_BIT);
540 EXPECT_GL_NO_ERROR();
541
542 glBindBuffer(GL_PIXEL_PACK_BUFFER, buffer);
543
544 // Read the framebuffer pixels
545 glReadPixels(0, 0, mFBOWidth, mFBOHeight, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
546
547 void *mappedPtr =
548 glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, sizeof(kInitialData), GL_MAP_READ_BIT);
549 GLColor *dataColor = static_cast<GLColor *>(mappedPtr);
550 EXPECT_GL_NO_ERROR();
551
552 EXPECT_EQ(GLColor::blue, dataColor[0]);
553 EXPECT_EQ(GLColor::green, dataColor[1]);
554 EXPECT_EQ(GLColor::green, dataColor[2]);
555 EXPECT_EQ(GLColor::green, dataColor[3]);
556
557 glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
558 EXPECT_GL_NO_ERROR();
559
560 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
561 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
562 EXPECT_PIXEL_COLOR_EQ(1, 0, GLColor::green);
563 EXPECT_PIXEL_COLOR_EQ(2, 0, GLColor::green);
564 EXPECT_PIXEL_COLOR_EQ(3, 0, GLColor::green);
565 }
566
567 class ReadPixelsPBODrawTest : public ReadPixelsPBOTest
568 {
569 protected:
ReadPixelsPBODrawTest()570 ReadPixelsPBODrawTest() : mProgram(0), mPositionVBO(0) {}
571
testSetUp()572 void testSetUp() override
573 {
574 ReadPixelsPBOTest::testSetUp();
575
576 constexpr char kVS[] =
577 "attribute vec4 aTest; attribute vec2 aPosition; varying vec4 vTest;\n"
578 "void main()\n"
579 "{\n"
580 " vTest = aTest;\n"
581 " gl_Position = vec4(aPosition, 0.0, 1.0);\n"
582 " gl_PointSize = 1.0;\n"
583 "}";
584
585 constexpr char kFS[] =
586 "precision mediump float; varying vec4 vTest;\n"
587 "void main()\n"
588 "{\n"
589 " gl_FragColor = vTest;\n"
590 "}";
591
592 mProgram = CompileProgram(kVS, kFS);
593 ASSERT_NE(0u, mProgram);
594
595 glGenBuffers(1, &mPositionVBO);
596 glBindBuffer(GL_ARRAY_BUFFER, mPositionVBO);
597 glBufferData(GL_ARRAY_BUFFER, 128, nullptr, GL_DYNAMIC_DRAW);
598 glBindBuffer(GL_ARRAY_BUFFER, 0);
599 }
600
testTearDown()601 void testTearDown() override
602 {
603 glDeleteProgram(mProgram);
604 glDeleteBuffers(1, &mPositionVBO);
605 ReadPixelsPBOTest::testTearDown();
606 }
607
608 GLuint mProgram;
609 GLuint mPositionVBO;
610 };
611
612 // Test that we can draw with PBO data.
TEST_P(ReadPixelsPBODrawTest,DrawWithPBO)613 TEST_P(ReadPixelsPBODrawTest, DrawWithPBO)
614 {
615 GLColor color(1, 2, 3, 4);
616 glBindTexture(GL_TEXTURE_2D, mTexture);
617 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &color);
618 EXPECT_GL_NO_ERROR();
619
620 glBindFramebuffer(GL_READ_FRAMEBUFFER, mFBO);
621 EXPECT_GL_NO_ERROR();
622
623 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
624 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 0);
625 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
626 EXPECT_GL_NO_ERROR();
627
628 float positionData[] = {0.5f, 0.5f};
629
630 glUseProgram(mProgram);
631 glViewport(0, 0, 1, 1);
632 glBindBuffer(GL_ARRAY_BUFFER, mPositionVBO);
633 glBufferSubData(GL_ARRAY_BUFFER, 0, 1 * 2 * 4, positionData);
634 EXPECT_GL_NO_ERROR();
635
636 GLint positionLocation = glGetAttribLocation(mProgram, "aPosition");
637 EXPECT_NE(-1, positionLocation);
638
639 GLint testLocation = glGetAttribLocation(mProgram, "aTest");
640 EXPECT_NE(-1, testLocation);
641
642 glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
643 glEnableVertexAttribArray(positionLocation);
644 EXPECT_GL_NO_ERROR();
645
646 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
647 glVertexAttribPointer(testLocation, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0, 0);
648 glEnableVertexAttribArray(testLocation);
649 EXPECT_GL_NO_ERROR();
650
651 glDrawArrays(GL_POINTS, 0, 1);
652 EXPECT_GL_NO_ERROR();
653
654 color = GLColor(0, 0, 0, 0);
655 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &color);
656 EXPECT_GL_NO_ERROR();
657
658 EXPECT_EQ(GLColor(1, 2, 3, 4), color);
659 }
660
661 // Test that we can correctly update a buffer bound to the vertex stage with PBO.
TEST_P(ReadPixelsPBODrawTest,UpdateVertexArrayWithPixelPack)662 TEST_P(ReadPixelsPBODrawTest, UpdateVertexArrayWithPixelPack)
663 {
664 glUseProgram(mProgram);
665 glViewport(0, 0, 1, 1);
666 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
667 ASSERT_GL_NO_ERROR();
668
669 // First draw with pre-defined data.
670 std::array<float, 2> positionData = {0.5f, 0.5f};
671
672 glBindBuffer(GL_ARRAY_BUFFER, mPositionVBO);
673 glBufferSubData(GL_ARRAY_BUFFER, 0, positionData.size() * sizeof(positionData[0]),
674 positionData.data());
675 ASSERT_GL_NO_ERROR();
676
677 GLint positionLocation = glGetAttribLocation(mProgram, "aPosition");
678 EXPECT_NE(-1, positionLocation);
679
680 GLint testLocation = glGetAttribLocation(mProgram, "aTest");
681 EXPECT_NE(-1, testLocation);
682
683 glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
684 glEnableVertexAttribArray(positionLocation);
685 ASSERT_GL_NO_ERROR();
686
687 glBindBuffer(GL_ARRAY_BUFFER, mPBO);
688 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GLColor), &GLColor::red);
689 glVertexAttribPointer(testLocation, 4, GL_UNSIGNED_BYTE, GL_FALSE, 0, 0);
690 glEnableVertexAttribArray(testLocation);
691 ASSERT_GL_NO_ERROR();
692
693 glDrawArrays(GL_POINTS, 0, 1);
694 ASSERT_GL_NO_ERROR();
695
696 // Update the buffer bound to the VAO with a PBO.
697 glBindTexture(GL_TEXTURE_2D, mTexture);
698 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::green);
699 ASSERT_GL_NO_ERROR();
700
701 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
702 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 0);
703 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
704 ASSERT_GL_NO_ERROR();
705
706 // Draw again and verify the VAO has the updated data.
707 glDrawArrays(GL_POINTS, 0, 1);
708
709 EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
710 }
711
712 class ReadPixelsMultisampleTest : public ReadPixelsTest
713 {
714 protected:
ReadPixelsMultisampleTest()715 ReadPixelsMultisampleTest() : mFBO(0), mRBO(0), mPBO(0) {}
716
testSetUp()717 void testSetUp() override
718 {
719 glGenFramebuffers(1, &mFBO);
720 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
721
722 glGenRenderbuffers(1, &mRBO);
723 glBindRenderbuffer(GL_RENDERBUFFER, mRBO);
724
725 glGenBuffers(1, &mPBO);
726 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
727 glBufferData(GL_PIXEL_PACK_BUFFER, 4 * getWindowWidth() * getWindowHeight(), nullptr,
728 GL_STATIC_DRAW);
729 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
730
731 ASSERT_GL_NO_ERROR();
732 }
733
testTearDown()734 void testTearDown() override
735 {
736 glDeleteFramebuffers(1, &mFBO);
737 glDeleteRenderbuffers(1, &mRBO);
738 glDeleteBuffers(1, &mPBO);
739 }
740
741 GLuint mFBO;
742 GLuint mRBO;
743 GLuint mPBO;
744 };
745
746 // Test ReadPixels from a multisampled framebuffer.
TEST_P(ReadPixelsMultisampleTest,BasicClear)747 TEST_P(ReadPixelsMultisampleTest, BasicClear)
748 {
749 if (getClientMajorVersion() < 3 && !IsGLExtensionEnabled("GL_ANGLE_framebuffer_multisample"))
750 {
751 std::cout
752 << "Test skipped because ES3 or GL_ANGLE_framebuffer_multisample is not available."
753 << std::endl;
754 return;
755 }
756
757 if (IsGLExtensionEnabled("GL_ANGLE_framebuffer_multisample"))
758 {
759 glRenderbufferStorageMultisampleANGLE(GL_RENDERBUFFER, 2, GL_RGBA8, 4, 4);
760 }
761 else
762 {
763 glRenderbufferStorageMultisample(GL_RENDERBUFFER, 2, GL_RGBA8, 4, 4);
764 }
765
766 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mRBO);
767 ASSERT_GL_NO_ERROR();
768
769 glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
770 glClear(GL_COLOR_BUFFER_BIT);
771
772 glBindBuffer(GL_PIXEL_PACK_BUFFER, mPBO);
773 EXPECT_GL_NO_ERROR();
774
775 glReadPixels(0, 0, 1, 1, GL_RGBA8, GL_UNSIGNED_BYTE, nullptr);
776 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
777 }
778
779 class ReadPixelsTextureTest : public ANGLETest
780 {
781 public:
ReadPixelsTextureTest()782 ReadPixelsTextureTest() : mFBO(0), mTexture(0)
783 {
784 setWindowWidth(32);
785 setWindowHeight(32);
786 setConfigRedBits(8);
787 setConfigGreenBits(8);
788 setConfigBlueBits(8);
789 setConfigAlphaBits(8);
790 }
791
testSetUp()792 void testSetUp() override
793 {
794 glGenTextures(1, &mTexture);
795 glGenFramebuffers(1, &mFBO);
796 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
797 }
798
testTearDown()799 void testTearDown() override
800 {
801 glDeleteFramebuffers(1, &mFBO);
802 glDeleteTextures(1, &mTexture);
803 }
804
initTexture(GLenum textureTarget,GLint levels,GLint attachmentLevel,GLint attachmentLayer)805 void initTexture(GLenum textureTarget,
806 GLint levels,
807 GLint attachmentLevel,
808 GLint attachmentLayer)
809 {
810 glBindTexture(textureTarget, mTexture);
811 glTexStorage3D(textureTarget, levels, GL_RGBA8, 4, 4, 4);
812 glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTexture, attachmentLevel,
813 attachmentLayer);
814 initializeTextureData(textureTarget, levels);
815 }
816
testRead(GLenum textureTarget,GLint levels,GLint attachmentLevel,GLint attachmentLayer)817 void testRead(GLenum textureTarget, GLint levels, GLint attachmentLevel, GLint attachmentLayer)
818 {
819 initTexture(textureTarget, levels, attachmentLevel, attachmentLayer);
820 verifyColor(attachmentLevel, attachmentLayer);
821 }
822
initPBO()823 void initPBO()
824 {
825 glGenBuffers(1, &mBuffer);
826 glBindBuffer(GL_PIXEL_PACK_BUFFER, mBuffer);
827 glBufferData(GL_PIXEL_PACK_BUFFER, sizeof(angle::GLColor), nullptr, GL_STREAM_COPY);
828 ASSERT_GL_NO_ERROR();
829 }
830
testPBORead(GLenum textureTarget,GLint levels,GLint attachmentLevel,GLint attachmentLayer)831 void testPBORead(GLenum textureTarget,
832 GLint levels,
833 GLint attachmentLevel,
834 GLint attachmentLayer)
835 {
836 initPBO();
837 initTexture(textureTarget, levels, attachmentLevel, attachmentLayer);
838 verifyPBO(attachmentLevel, attachmentLayer);
839 }
840
841 // Give each {level,layer} pair a (probably) unique color via random.
getColorValue(GLint level,GLint layer)842 GLuint getColorValue(GLint level, GLint layer)
843 {
844 mRNG.reseed(level + layer * 32);
845 return mRNG.randomUInt();
846 }
847
verifyColor(GLint level,GLint layer)848 void verifyColor(GLint level, GLint layer)
849 {
850 angle::GLColor colorValue(getColorValue(level, layer));
851 EXPECT_PIXEL_COLOR_EQ(0, 0, colorValue);
852 }
853
verifyPBO(GLint level,GLint layer)854 void verifyPBO(GLint level, GLint layer)
855 {
856 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
857
858 angle::GLColor expectedColor(getColorValue(level, layer));
859 void *mapPointer =
860 glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, sizeof(angle::GLColor), GL_MAP_READ_BIT);
861 ASSERT_NE(nullptr, mapPointer);
862 angle::GLColor actualColor;
863 memcpy(&actualColor, mapPointer, sizeof(angle::GLColor));
864 glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
865 ASSERT_GL_NO_ERROR();
866 EXPECT_EQ(expectedColor, actualColor);
867 }
868
initializeTextureData(GLenum textureTarget,GLint levels)869 void initializeTextureData(GLenum textureTarget, GLint levels)
870 {
871 for (GLint level = 0; level < levels; ++level)
872 {
873 GLint mipSize = 4 >> level;
874 GLint layers = (textureTarget == GL_TEXTURE_3D ? mipSize : 4);
875
876 size_t layerSize = mipSize * mipSize;
877 std::vector<GLuint> textureData(layers * layerSize);
878
879 for (GLint layer = 0; layer < layers; ++layer)
880 {
881 GLuint colorValue = getColorValue(level, layer);
882 size_t offset = (layer * layerSize);
883 std::fill(textureData.begin() + offset, textureData.begin() + offset + layerSize,
884 colorValue);
885 }
886
887 glTexSubImage3D(textureTarget, level, 0, 0, 0, mipSize, mipSize, layers, GL_RGBA,
888 GL_UNSIGNED_BYTE, textureData.data());
889 }
890 }
891
892 angle::RNG mRNG;
893 GLuint mFBO;
894 GLuint mTexture;
895 GLuint mBuffer;
896 };
897
898 // Test 3D attachment readback.
TEST_P(ReadPixelsTextureTest,BasicAttachment3D)899 TEST_P(ReadPixelsTextureTest, BasicAttachment3D)
900 {
901 testRead(GL_TEXTURE_3D, 1, 0, 0);
902 }
903
904 // Test 3D attachment readback, non-zero mip.
TEST_P(ReadPixelsTextureTest,MipAttachment3D)905 TEST_P(ReadPixelsTextureTest, MipAttachment3D)
906 {
907 testRead(GL_TEXTURE_3D, 2, 1, 0);
908 }
909
910 // Test 3D attachment readback, non-zero layer.
TEST_P(ReadPixelsTextureTest,LayerAttachment3D)911 TEST_P(ReadPixelsTextureTest, LayerAttachment3D)
912 {
913 testRead(GL_TEXTURE_3D, 1, 0, 1);
914 }
915
916 // Test 3D attachment readback, non-zero mip and layer.
TEST_P(ReadPixelsTextureTest,MipLayerAttachment3D)917 TEST_P(ReadPixelsTextureTest, MipLayerAttachment3D)
918 {
919 testRead(GL_TEXTURE_3D, 2, 1, 1);
920 }
921
922 // Test 2D array attachment readback.
TEST_P(ReadPixelsTextureTest,BasicAttachment2DArray)923 TEST_P(ReadPixelsTextureTest, BasicAttachment2DArray)
924 {
925 testRead(GL_TEXTURE_2D_ARRAY, 1, 0, 0);
926 }
927
928 // Test 3D attachment readback, non-zero mip.
TEST_P(ReadPixelsTextureTest,MipAttachment2DArray)929 TEST_P(ReadPixelsTextureTest, MipAttachment2DArray)
930 {
931 testRead(GL_TEXTURE_2D_ARRAY, 2, 1, 0);
932 }
933
934 // Test 3D attachment readback, non-zero layer.
TEST_P(ReadPixelsTextureTest,LayerAttachment2DArray)935 TEST_P(ReadPixelsTextureTest, LayerAttachment2DArray)
936 {
937 testRead(GL_TEXTURE_2D_ARRAY, 1, 0, 1);
938 }
939
940 // Test 3D attachment readback, non-zero mip and layer.
TEST_P(ReadPixelsTextureTest,MipLayerAttachment2DArray)941 TEST_P(ReadPixelsTextureTest, MipLayerAttachment2DArray)
942 {
943 testRead(GL_TEXTURE_2D_ARRAY, 2, 1, 1);
944 }
945
946 // Test 3D attachment PBO readback.
TEST_P(ReadPixelsTextureTest,BasicAttachment3DPBO)947 TEST_P(ReadPixelsTextureTest, BasicAttachment3DPBO)
948 {
949 testPBORead(GL_TEXTURE_3D, 1, 0, 0);
950 }
951
952 // Test 3D attachment readback, non-zero mip.
TEST_P(ReadPixelsTextureTest,MipAttachment3DPBO)953 TEST_P(ReadPixelsTextureTest, MipAttachment3DPBO)
954 {
955 testPBORead(GL_TEXTURE_3D, 2, 1, 0);
956 }
957
958 // Test 3D attachment readback, non-zero layer.
TEST_P(ReadPixelsTextureTest,LayerAttachment3DPBO)959 TEST_P(ReadPixelsTextureTest, LayerAttachment3DPBO)
960 {
961 // http://anglebug.com/5267
962 ANGLE_SKIP_TEST_IF(IsOSX() && IsIntelUHD630Mobile() && IsDesktopOpenGL());
963
964 testPBORead(GL_TEXTURE_3D, 1, 0, 1);
965 }
966
967 // Test 3D attachment readback, non-zero mip and layer.
TEST_P(ReadPixelsTextureTest,MipLayerAttachment3DPBO)968 TEST_P(ReadPixelsTextureTest, MipLayerAttachment3DPBO)
969 {
970 // http://anglebug.com/5267
971 ANGLE_SKIP_TEST_IF(IsOSX() && IsIntelUHD630Mobile() && IsDesktopOpenGL());
972
973 testPBORead(GL_TEXTURE_3D, 2, 1, 1);
974 }
975
976 // Test 2D array attachment readback.
TEST_P(ReadPixelsTextureTest,BasicAttachment2DArrayPBO)977 TEST_P(ReadPixelsTextureTest, BasicAttachment2DArrayPBO)
978 {
979 testPBORead(GL_TEXTURE_2D_ARRAY, 1, 0, 0);
980 }
981
982 // Test 3D attachment readback, non-zero mip.
TEST_P(ReadPixelsTextureTest,MipAttachment2DArrayPBO)983 TEST_P(ReadPixelsTextureTest, MipAttachment2DArrayPBO)
984 {
985 testPBORead(GL_TEXTURE_2D_ARRAY, 2, 1, 0);
986 }
987
988 // Test 3D attachment readback, non-zero layer.
TEST_P(ReadPixelsTextureTest,LayerAttachment2DArrayPBO)989 TEST_P(ReadPixelsTextureTest, LayerAttachment2DArrayPBO)
990 {
991 // http://anglebug.com/5267
992 ANGLE_SKIP_TEST_IF(IsOSX() && IsIntelUHD630Mobile() && IsDesktopOpenGL());
993
994 testPBORead(GL_TEXTURE_2D_ARRAY, 1, 0, 1);
995 }
996
997 // Test 3D attachment readback, non-zero mip and layer.
TEST_P(ReadPixelsTextureTest,MipLayerAttachment2DArrayPBO)998 TEST_P(ReadPixelsTextureTest, MipLayerAttachment2DArrayPBO)
999 {
1000 // http://anglebug.com/5267
1001 ANGLE_SKIP_TEST_IF(IsOSX() && IsIntelUHD630Mobile() && IsDesktopOpenGL());
1002
1003 testPBORead(GL_TEXTURE_2D_ARRAY, 2, 1, 1);
1004 }
1005
1006 // a test class to be used for error checking of glReadPixels
1007 class ReadPixelsErrorTest : public ReadPixelsTest
1008 {
1009 protected:
ReadPixelsErrorTest()1010 ReadPixelsErrorTest() : mTexture(0), mFBO(0) {}
1011
testSetUp()1012 void testSetUp() override
1013 {
1014 glGenTextures(1, &mTexture);
1015 glBindTexture(GL_TEXTURE_2D, mTexture);
1016 glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 4, 1);
1017
1018 glGenFramebuffers(1, &mFBO);
1019 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
1020 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
1021 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1022
1023 ASSERT_GL_NO_ERROR();
1024 }
1025
testTearDown()1026 void testTearDown() override
1027 {
1028 glDeleteTextures(1, &mTexture);
1029 glDeleteFramebuffers(1, &mFBO);
1030 }
1031
1032 GLuint mTexture;
1033 GLuint mFBO;
1034 };
1035
1036 // The test verifies that glReadPixels generates a GL_INVALID_OPERATION error
1037 // when the read buffer is GL_NONE.
1038 // Reference: GLES 3.0.4, Section 4.3.2 Reading Pixels
TEST_P(ReadPixelsErrorTest,ReadBufferIsNone)1039 TEST_P(ReadPixelsErrorTest, ReadBufferIsNone)
1040 {
1041 glBindFramebuffer(GL_FRAMEBUFFER, mFBO);
1042 glReadBuffer(GL_NONE);
1043 std::vector<GLubyte> pixels(4);
1044 glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
1045 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
1046 }
1047
1048 } // anonymous namespace
1049
1050 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
1051 // tests should be run against.
1052 ANGLE_INSTANTIATE_TEST_ES2(ReadPixelsTest);
1053 ANGLE_INSTANTIATE_TEST_ES2(ReadPixelsPBONVTest);
1054
1055 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ReadPixelsPBOTest);
1056 ANGLE_INSTANTIATE_TEST_ES3(ReadPixelsPBOTest);
1057
1058 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ReadPixelsPBODrawTest);
1059 ANGLE_INSTANTIATE_TEST_ES3_AND(ReadPixelsPBODrawTest, WithForceVulkanFallbackFormat(ES3_VULKAN()));
1060
1061 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ReadPixelsMultisampleTest);
1062 ANGLE_INSTANTIATE_TEST_ES3(ReadPixelsMultisampleTest);
1063
1064 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ReadPixelsTextureTest);
1065 ANGLE_INSTANTIATE_TEST_ES3(ReadPixelsTextureTest);
1066
1067 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ReadPixelsErrorTest);
1068 ANGLE_INSTANTIATE_TEST_ES3(ReadPixelsErrorTest);
1069