• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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