• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2019 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 // GetImageTest:
7 //   Tests for the ANGLE_get_image extension.
8 //
9 
10 #include "test_utils/ANGLETest.h"
11 #include "test_utils/gl_raii.h"
12 
13 using namespace angle;
14 
15 namespace
16 {
17 constexpr uint32_t kSize        = 32;
18 constexpr char kExtensionName[] = "GL_ANGLE_get_image";
19 constexpr uint32_t kSmallSize   = 2;
20 constexpr uint8_t kUNormZero    = 0x00;
21 constexpr uint8_t kUNormHalf    = 0x7F;
22 constexpr uint8_t kUNormFull    = 0xFF;
23 
24 class GetImageTest : public ANGLETest
25 {
26   public:
GetImageTest()27     GetImageTest()
28     {
29         setWindowWidth(kSize);
30         setWindowHeight(kSize);
31         setConfigRedBits(8);
32         setConfigGreenBits(8);
33         setConfigBlueBits(8);
34         setConfigAlphaBits(8);
35     }
36 };
37 
38 class GetImageTestNoExtensions : public ANGLETest
39 {
40   public:
GetImageTestNoExtensions()41     GetImageTestNoExtensions() { setExtensionsEnabled(false); }
42 };
43 
44 class GetImageTestES31 : public GetImageTest
45 {
46   public:
GetImageTestES31()47     GetImageTestES31() {}
48 };
49 
InitTextureWithFormatAndSize(GLenum format,uint32_t size,void * pixelData)50 GLTexture InitTextureWithFormatAndSize(GLenum format, uint32_t size, void *pixelData)
51 {
52     GLTexture tex;
53     glBindTexture(GL_TEXTURE_2D, tex);
54     glTexImage2D(GL_TEXTURE_2D, 0, format, size, size, 0, format, GL_UNSIGNED_BYTE, pixelData);
55     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
56     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
57     return tex;
58 }
59 
InitTextureWithSize(uint32_t size,void * pixelData)60 GLTexture InitTextureWithSize(uint32_t size, void *pixelData)
61 {
62     // Create a simple texture.
63     GLTexture tex;
64     glBindTexture(GL_TEXTURE_2D, tex);
65     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData);
66     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
67     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
68     return tex;
69 }
70 
InitSimpleTexture()71 GLTexture InitSimpleTexture()
72 {
73     std::vector<GLColor> pixelData(kSize * kSize, GLColor::red);
74     return InitTextureWithSize(kSize, pixelData.data());
75 }
76 
InitRenderbufferWithSize(uint32_t size)77 GLRenderbuffer InitRenderbufferWithSize(uint32_t size)
78 {
79     // Create a simple renderbuffer.
80     GLRenderbuffer renderbuf;
81     glBindRenderbuffer(GL_RENDERBUFFER, renderbuf);
82     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, size, size);
83     return renderbuf;
84 }
85 
InitSimpleRenderbuffer()86 GLRenderbuffer InitSimpleRenderbuffer()
87 {
88     return InitRenderbufferWithSize(kSize);
89 }
90 
91 // Test validation for the extension functions.
TEST_P(GetImageTest,NegativeAPI)92 TEST_P(GetImageTest, NegativeAPI)
93 {
94     // Verify the extension is enabled.
95     ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));
96 
97     // Draw once with simple texture.
98     GLTexture tex = InitSimpleTexture();
99     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
100     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5, 1.0f, true);
101     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
102     ASSERT_GL_NO_ERROR();
103 
104     // Pack pixels tightly.
105     glPixelStorei(GL_PACK_ALIGNMENT, 1);
106 
107     // Verify GetTexImage can work with correct parameters.
108     std::vector<GLColor> buffer(kSize * kSize);
109     glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
110     EXPECT_GL_NO_ERROR();
111 
112     // Test invalid texture target.
113     glGetTexImageANGLE(GL_TEXTURE_CUBE_MAP, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
114     EXPECT_GL_ERROR(GL_INVALID_ENUM);
115 
116     // Test invalid texture level.
117     glGetTexImageANGLE(GL_TEXTURE_2D, -1, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
118     EXPECT_GL_ERROR(GL_INVALID_VALUE);
119     glGetTexImageANGLE(GL_TEXTURE_2D, 2000, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
120     EXPECT_GL_ERROR(GL_INVALID_VALUE);
121 
122     // Test invalid format and type.
123     glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_NONE, GL_UNSIGNED_BYTE, buffer.data());
124     EXPECT_GL_ERROR(GL_INVALID_ENUM);
125     glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_NONE, buffer.data());
126     EXPECT_GL_ERROR(GL_INVALID_ENUM);
127 
128     // Create a simple renderbuffer.
129     GLRenderbuffer renderbuf = InitSimpleRenderbuffer();
130     ASSERT_GL_NO_ERROR();
131 
132     // Verify GetRenderbufferImage can work with correct parameters.
133     glGetRenderbufferImageANGLE(GL_RENDERBUFFER, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
134     EXPECT_GL_NO_ERROR();
135 
136     // Test invalid renderbuffer target.
137     glGetRenderbufferImageANGLE(GL_TEXTURE_2D, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
138     EXPECT_GL_ERROR(GL_INVALID_ENUM);
139 
140     // Test invalid renderbuffer format/type.
141     glGetRenderbufferImageANGLE(GL_RENDERBUFFER, GL_NONE, GL_UNSIGNED_BYTE, buffer.data());
142     EXPECT_GL_ERROR(GL_INVALID_ENUM);
143     glGetRenderbufferImageANGLE(GL_RENDERBUFFER, GL_RGBA, GL_NONE, buffer.data());
144     EXPECT_GL_ERROR(GL_INVALID_ENUM);
145 
146     // Pack buffer tests. Requires ES 3+ or extension.
147     if (getClientMajorVersion() >= 3 || IsGLExtensionEnabled("GL_NV_pixel_buffer_object"))
148     {
149         // Test valid pack buffer.
150         GLBuffer packBuffer;
151         glBindBuffer(GL_PIXEL_PACK_BUFFER, packBuffer);
152         glBufferData(GL_PIXEL_PACK_BUFFER, kSize * kSize * sizeof(GLColor), nullptr,
153                      GL_STATIC_DRAW);
154         glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
155         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
156         glGetRenderbufferImageANGLE(GL_RENDERBUFFER, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
157         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
158 
159         // Test too small pack buffer.
160         glBufferData(GL_PIXEL_PACK_BUFFER, kSize, nullptr, GL_STATIC_DRAW);
161         glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
162         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
163         glGetRenderbufferImageANGLE(GL_RENDERBUFFER, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
164         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
165     }
166 }
167 
168 // Simple test for GetTexImage
TEST_P(GetImageTest,GetTexImage)169 TEST_P(GetImageTest, GetTexImage)
170 {
171     // Verify the extension is enabled.
172     ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));
173 
174     std::vector<GLColor> expectedData = {GLColor::red, GLColor::blue, GLColor::green,
175                                          GLColor::yellow};
176 
177     glViewport(0, 0, kSmallSize, kSmallSize);
178 
179     // Draw once with simple texture.
180     GLTexture tex = InitTextureWithSize(kSmallSize, expectedData.data());
181     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
182     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5, 1.0f, true);
183     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
184     ASSERT_GL_NO_ERROR();
185 
186     // Pack pixels tightly.
187     glPixelStorei(GL_PACK_ALIGNMENT, 1);
188 
189     // Verify GetImage.
190     std::vector<GLColor> actualData(kSmallSize * kSmallSize);
191     glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, actualData.data());
192     EXPECT_GL_NO_ERROR();
193     EXPECT_EQ(expectedData, actualData);
194 }
195 
196 // Simple cube map test for GetTexImage
TEST_P(GetImageTest,CubeMap)197 TEST_P(GetImageTest, CubeMap)
198 {
199     // Verify the extension is enabled.
200     ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));
201 
202     const std::array<std::array<GLColor, kSmallSize * kSmallSize>, kCubeFaces.size()> expectedData =
203         {{
204             {GLColor::red, GLColor::red, GLColor::red, GLColor::red},
205             {GLColor::green, GLColor::green, GLColor::green, GLColor::green},
206             {GLColor::blue, GLColor::blue, GLColor::blue, GLColor::blue},
207             {GLColor::yellow, GLColor::yellow, GLColor::yellow, GLColor::yellow},
208             {GLColor::cyan, GLColor::cyan, GLColor::cyan, GLColor::cyan},
209             {GLColor::magenta, GLColor::magenta, GLColor::magenta, GLColor::magenta},
210         }};
211 
212     GLTexture texture;
213     glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
214 
215     for (size_t faceIndex = 0; faceIndex < kCubeFaces.size(); ++faceIndex)
216     {
217         glTexImage2D(kCubeFaces[faceIndex], 0, GL_RGBA, kSmallSize, kSmallSize, 0, GL_RGBA,
218                      GL_UNSIGNED_BYTE, expectedData[faceIndex].data());
219     }
220     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
221     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
222 
223     // Pack pixels tightly.
224     glPixelStorei(GL_PACK_ALIGNMENT, 1);
225 
226     // Verify GetImage.
227     std::array<GLColor, kSmallSize *kSmallSize> actualData = {};
228     for (size_t faceIndex = 0; faceIndex < kCubeFaces.size(); ++faceIndex)
229     {
230         glGetTexImageANGLE(kCubeFaces[faceIndex], 0, GL_RGBA, GL_UNSIGNED_BYTE, actualData.data());
231         EXPECT_GL_NO_ERROR();
232         EXPECT_EQ(expectedData[faceIndex], actualData);
233     }
234 }
235 
236 // Simple test for GetRenderbufferImage
TEST_P(GetImageTest,GetRenderbufferImage)237 TEST_P(GetImageTest, GetRenderbufferImage)
238 {
239     // Verify the extension is enabled.
240     ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));
241 
242     std::vector<GLColor> expectedData = {GLColor::red, GLColor::blue, GLColor::green,
243                                          GLColor::yellow};
244 
245     glViewport(0, 0, kSmallSize, kSmallSize);
246 
247     // Set up a simple Framebuffer with a Renderbuffer.
248     GLRenderbuffer renderbuffer = InitRenderbufferWithSize(kSmallSize);
249     GLFramebuffer framebuffer;
250     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
251     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
252     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
253 
254     // Draw once with simple texture.
255     GLTexture tex = InitTextureWithSize(kSmallSize, expectedData.data());
256     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
257     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5, 1.0f, true);
258     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
259     ASSERT_GL_NO_ERROR();
260 
261     // Pack pixels tightly.
262     glPixelStorei(GL_PACK_ALIGNMENT, 1);
263 
264     // Verify GetImage.
265     std::vector<GLColor> actualData(kSmallSize * kSmallSize);
266     glGetRenderbufferImageANGLE(GL_RENDERBUFFER, GL_RGBA, GL_UNSIGNED_BYTE, actualData.data());
267     EXPECT_GL_NO_ERROR();
268     EXPECT_EQ(expectedData, actualData);
269 }
270 
271 // Verifies that the extension enums and entry points are invalid when the extension is disabled.
TEST_P(GetImageTestNoExtensions,EntryPointsInactive)272 TEST_P(GetImageTestNoExtensions, EntryPointsInactive)
273 {
274     // Verify the extension is not enabled.
275     ASSERT_FALSE(IsGLExtensionEnabled(kExtensionName));
276 
277     // Draw once with simple texture.
278     GLTexture tex = InitSimpleTexture();
279     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
280     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5, 1.0f, true);
281     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
282     ASSERT_GL_NO_ERROR();
283 
284     // Query implementation format and type. Should give invalid enum.
285     GLint param;
286     glGetTexParameteriv(GL_TEXTURE_2D, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &param);
287     EXPECT_GL_ERROR(GL_INVALID_ENUM);
288 
289     glGetTexParameteriv(GL_TEXTURE_2D, GL_IMPLEMENTATION_COLOR_READ_TYPE, &param);
290     EXPECT_GL_ERROR(GL_INVALID_ENUM);
291 
292     // Verify calling GetTexImage produces an error.
293     std::vector<GLColor> buffer(kSize * kSize, 0);
294     glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
295     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
296 
297     // Create a simple renderbuffer.
298     GLRenderbuffer renderbuf = InitSimpleRenderbuffer();
299     ASSERT_GL_NO_ERROR();
300 
301     // Query implementation format and type. Should give invalid enum.
302     glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &param);
303     EXPECT_GL_ERROR(GL_INVALID_ENUM);
304 
305     glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_IMPLEMENTATION_COLOR_READ_TYPE, &param);
306     EXPECT_GL_ERROR(GL_INVALID_ENUM);
307 
308     // Verify calling GetRenderbufferImage produces an error.
309     glGetRenderbufferImageANGLE(GL_RENDERBUFFER, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
310     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
311 }
312 
313 // Test LUMINANCE_ALPHA (non-renderable) format with GetTexImage
TEST_P(GetImageTest,GetTexImageLuminanceAlpha)314 TEST_P(GetImageTest, GetTexImageLuminanceAlpha)
315 {
316     // Verify the extension is enabled.
317     ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));
318 
319     constexpr GLColorRG kMediumLumAlpha = GLColorRG(kUNormHalf, kUNormHalf);
320     std::vector<GLColorRG> expectedData = {kMediumLumAlpha, kMediumLumAlpha, kMediumLumAlpha,
321                                            kMediumLumAlpha};
322 
323     glViewport(0, 0, kSmallSize, kSmallSize);
324 
325     // Set up a simple LUMINANCE_ALPHA texture
326     GLTexture tex =
327         InitTextureWithFormatAndSize(GL_LUMINANCE_ALPHA, kSmallSize, expectedData.data());
328 
329     // Draw once with simple texture.
330     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
331     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5, 1.0f, true);
332     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(kUNormHalf, kUNormHalf, kUNormHalf, kUNormHalf));
333     ASSERT_GL_NO_ERROR();
334 
335     // Pack pixels tightly.
336     glPixelStorei(GL_PACK_ALIGNMENT, 1);
337 
338     // Verify GetImage.
339     std::vector<GLColorRG> actualData(kSmallSize * kSmallSize);
340     glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, actualData.data());
341     EXPECT_GL_NO_ERROR();
342     for (uint32_t i = 0; i < kSmallSize * kSmallSize; ++i)
343     {
344         EXPECT_EQ(expectedData[i].R, actualData[i].R);
345         EXPECT_EQ(expectedData[i].G, actualData[i].G);
346     }
347 }
348 
349 // Test LUMINANCE (non-renderable) format with GetTexImage
TEST_P(GetImageTest,GetTexImageLuminance)350 TEST_P(GetImageTest, GetTexImageLuminance)
351 {
352     // Verify the extension is enabled.
353     ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));
354 
355     constexpr GLColorR kMediumLuminance = GLColorR(kUNormHalf);
356     std::vector<GLColorR> expectedData  = {kMediumLuminance, kMediumLuminance, kMediumLuminance,
357                                           kMediumLuminance};
358 
359     glViewport(0, 0, kSmallSize, kSmallSize);
360 
361     // Set up a simple LUMINANCE texture
362     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
363     GLTexture tex = InitTextureWithFormatAndSize(GL_LUMINANCE, kSmallSize, expectedData.data());
364 
365     // Draw once with simple texture.
366     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
367     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5, 1.0f, true);
368     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(kUNormHalf, kUNormHalf, kUNormHalf, kUNormFull));
369     ASSERT_GL_NO_ERROR();
370 
371     // Pack pixels tightly.
372     glPixelStorei(GL_PACK_ALIGNMENT, 1);
373 
374     // Verify GetImage.
375     std::vector<GLColorR> actualData(kSmallSize * kSmallSize);
376     glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, actualData.data());
377     EXPECT_GL_NO_ERROR();
378     for (uint32_t i = 0; i < kSmallSize * kSmallSize; ++i)
379     {
380         EXPECT_EQ(expectedData[i].R, actualData[i].R);
381     }
382 }
383 
384 // Test ALPHA (non-renderable) format with GetTexImage
TEST_P(GetImageTest,GetTexImageAlpha)385 TEST_P(GetImageTest, GetTexImageAlpha)
386 {
387     // Verify the extension is enabled.
388     ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));
389 
390     constexpr GLColorR kMediumAlpha    = GLColorR(kUNormHalf);
391     std::vector<GLColorR> expectedData = {kMediumAlpha, kMediumAlpha, kMediumAlpha, kMediumAlpha};
392 
393     glViewport(0, 0, kSmallSize, kSmallSize);
394 
395     // Set up a simple ALPHA texture
396     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
397     GLTexture tex = InitTextureWithFormatAndSize(GL_ALPHA, kSmallSize, expectedData.data());
398 
399     // Draw once with simple texture
400     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
401     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5, 1.0f, true);
402     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor(kUNormZero, kUNormZero, kUNormZero, kUNormHalf));
403     ASSERT_GL_NO_ERROR();
404 
405     // Pack pixels tightly.
406     glPixelStorei(GL_PACK_ALIGNMENT, 1);
407 
408     // Verify we get back the correct pixels from GetTexImage
409     std::vector<GLColorR> actualData(kSmallSize * kSmallSize);
410     glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_ALPHA, GL_UNSIGNED_BYTE, actualData.data());
411     EXPECT_GL_NO_ERROR();
412     for (uint32_t i = 0; i < kSmallSize * kSmallSize; ++i)
413     {
414         EXPECT_EQ(expectedData[i].R, actualData[i].R);
415     }
416 }
417 
418 // Tests GetImage behaviour with an RGB image.
TEST_P(GetImageTest,GetImageRGB)419 TEST_P(GetImageTest, GetImageRGB)
420 {
421     // Verify the extension is enabled.
422     ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));
423 
424     std::vector<GLColorRGB> expectedData = {GLColorRGB::red, GLColorRGB::blue, GLColorRGB::green,
425                                             GLColorRGB::yellow};
426 
427     glViewport(0, 0, kSmallSize, kSmallSize);
428 
429     // Pack pixels tightly.
430     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
431     glPixelStorei(GL_PACK_ALIGNMENT, 1);
432 
433     // Init simple texture.
434     GLTexture tex;
435     glBindTexture(GL_TEXTURE_2D, tex);
436     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, kSmallSize, kSmallSize, 0, GL_RGB, GL_UNSIGNED_BYTE,
437                  expectedData.data());
438     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGB, kSmallSize / 2, kSmallSize / 2, 0, GL_RGB,
439                  GL_UNSIGNED_BYTE, expectedData.data());
440     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
441     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
442 
443     // Verify GetImage.
444     std::vector<GLColorRGB> actualData(kSmallSize * kSmallSize);
445     glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, actualData.data());
446     EXPECT_GL_NO_ERROR();
447     EXPECT_EQ(expectedData, actualData);
448 
449     // Draw after the GetImage.
450     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
451     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5, 1.0f, true);
452 
453     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
454     EXPECT_PIXEL_COLOR_EQ(0, 1, GLColor::green);
455     EXPECT_PIXEL_COLOR_EQ(1, 0, GLColor::blue);
456     EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::yellow);
457 }
458 
459 // Tests GetImage with 2D array textures.
TEST_P(GetImageTestES31,Texture2DArray)460 TEST_P(GetImageTestES31, Texture2DArray)
461 {
462     // Verify the extension is enabled.
463     ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));
464 
465     constexpr GLsizei kTextureSize = 2;
466     constexpr GLsizei kLayers      = 4;
467 
468     std::vector<GLColor> expectedPixels = {
469         GLColor::red,    GLColor::red,    GLColor::red,    GLColor::red,
470         GLColor::green,  GLColor::green,  GLColor::green,  GLColor::green,
471         GLColor::blue,   GLColor::blue,   GLColor::blue,   GLColor::blue,
472         GLColor::yellow, GLColor::yellow, GLColor::yellow, GLColor::yellow,
473     };
474 
475     GLTexture tex;
476     glBindTexture(GL_TEXTURE_2D_ARRAY, tex);
477     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, kTextureSize, kTextureSize, kLayers, 0, GL_RGBA,
478                  GL_UNSIGNED_BYTE, expectedPixels.data());
479     ASSERT_GL_NO_ERROR();
480 
481     std::vector<GLColor> actualPixels(expectedPixels.size(), GLColor::white);
482     glGetTexImageANGLE(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, GL_UNSIGNED_BYTE, actualPixels.data());
483     ASSERT_GL_NO_ERROR();
484     EXPECT_EQ(expectedPixels, actualPixels);
485 }
486 
487 // Tests GetImage with 3D textures.
TEST_P(GetImageTestES31,Texture3D)488 TEST_P(GetImageTestES31, Texture3D)
489 {
490     // Verify the extension is enabled.
491     ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));
492 
493     constexpr GLsizei kTextureSize = 2;
494 
495     std::vector<GLColor> expectedPixels = {
496         GLColor::red,  GLColor::red,  GLColor::green,  GLColor::green,
497         GLColor::blue, GLColor::blue, GLColor::yellow, GLColor::yellow,
498     };
499 
500     GLTexture tex;
501     glBindTexture(GL_TEXTURE_3D, tex);
502     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, kTextureSize, kTextureSize, kTextureSize, 0, GL_RGBA,
503                  GL_UNSIGNED_BYTE, expectedPixels.data());
504     ASSERT_GL_NO_ERROR();
505 
506     std::vector<GLColor> actualPixels(expectedPixels.size(), GLColor::white);
507     glGetTexImageANGLE(GL_TEXTURE_3D, 0, GL_RGBA, GL_UNSIGNED_BYTE, actualPixels.data());
508     ASSERT_GL_NO_ERROR();
509     EXPECT_EQ(expectedPixels, actualPixels);
510 }
511 
512 // Tests GetImage with cube map array textures.
TEST_P(GetImageTestES31,TextureCubeMapArray)513 TEST_P(GetImageTestES31, TextureCubeMapArray)
514 {
515     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_cube_map_array") &&
516                        !IsGLExtensionEnabled("GL_OES_texture_cube_map_array"));
517 
518     // Verify the extension is enabled.
519     ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));
520 
521     constexpr GLsizei kTextureSize = 1;
522     constexpr GLsizei kLayers      = 2;
523 
524     std::vector<GLColor> expectedPixels = {
525         GLColor::red,  GLColor::green,   GLColor::blue, GLColor::yellow,
526         GLColor::cyan, GLColor::magenta, GLColor::red,  GLColor::green,
527         GLColor::blue, GLColor::yellow,  GLColor::cyan, GLColor::magenta,
528     };
529 
530     ASSERT_EQ(expectedPixels.size(),
531               static_cast<size_t>(6 * kTextureSize * kTextureSize * kLayers));
532 
533     GLTexture tex;
534     glBindTexture(GL_TEXTURE_CUBE_MAP_ARRAY, tex);
535     glTexImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, kTextureSize, kTextureSize, kLayers * 6, 0,
536                  GL_RGBA, GL_UNSIGNED_BYTE, expectedPixels.data());
537     ASSERT_GL_NO_ERROR();
538 
539     std::vector<GLColor> actualPixels(expectedPixels.size(), GLColor::white);
540     glGetTexImageANGLE(GL_TEXTURE_CUBE_MAP_ARRAY, 0, GL_RGBA, GL_UNSIGNED_BYTE,
541                        actualPixels.data());
542     ASSERT_GL_NO_ERROR();
543     EXPECT_EQ(expectedPixels, actualPixels);
544 }
545 
546 // Tests GetImage with an inconsistent 2D texture.
TEST_P(GetImageTest,InconsistentTexture2D)547 TEST_P(GetImageTest, InconsistentTexture2D)
548 {
549     // Verify the extension is enabled.
550     ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));
551 
552     std::vector<GLColor> expectedData = {GLColor::red, GLColor::blue, GLColor::green,
553                                          GLColor::yellow};
554 
555     glViewport(0, 0, kSmallSize, kSmallSize);
556 
557     // Draw once with simple texture.
558     GLTexture tex;
559     glBindTexture(GL_TEXTURE_2D, tex);
560     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSmallSize, kSmallSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
561                  expectedData.data());
562     // The texture becomes inconsistent because a second 2x2 image does not fit in the mip chain.
563     glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, kSmallSize, kSmallSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
564                  expectedData.data());
565 
566     // Pack pixels tightly.
567     glPixelStorei(GL_PACK_ALIGNMENT, 1);
568 
569     // Verify GetImage.
570     std::vector<GLColor> actualData(kSmallSize * kSmallSize, GLColor::white);
571     glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, actualData.data());
572     EXPECT_GL_NO_ERROR();
573     EXPECT_EQ(expectedData, actualData);
574 
575     std::fill(actualData.begin(), actualData.end(), GLColor::white);
576     glGetTexImageANGLE(GL_TEXTURE_2D, 1, GL_RGBA, GL_UNSIGNED_BYTE, actualData.data());
577     EXPECT_GL_NO_ERROR();
578     EXPECT_EQ(expectedData, actualData);
579 }
580 
581 // Test GetImage with non-defined textures.
TEST_P(GetImageTest,EmptyTexture)582 TEST_P(GetImageTest, EmptyTexture)
583 {
584     // Verify the extension is enabled.
585     ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));
586 
587     GLTexture tex;
588     glBindTexture(GL_TEXTURE_2D, tex);
589 
590     std::vector<GLColor> expectedData(4, GLColor::white);
591     std::vector<GLColor> actualData(4, GLColor::white);
592     glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, actualData.data());
593     EXPECT_GL_NO_ERROR();
594     EXPECT_EQ(expectedData, actualData);
595 }
596 
597 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GetImageTest);
598 ANGLE_INSTANTIATE_TEST(GetImageTest, ES2_VULKAN(), ES3_VULKAN());
599 
600 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GetImageTestES31);
601 ANGLE_INSTANTIATE_TEST(GetImageTestES31, ES31_VULKAN());
602 
603 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GetImageTestNoExtensions);
604 ANGLE_INSTANTIATE_TEST(GetImageTestNoExtensions, ES2_VULKAN(), ES3_VULKAN());
605 
606 }  // namespace