• 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 
21 class GetImageTest : public ANGLETest
22 {
23   public:
GetImageTest()24     GetImageTest()
25     {
26         setWindowWidth(kSize);
27         setWindowHeight(kSize);
28         setConfigRedBits(8);
29         setConfigGreenBits(8);
30         setConfigBlueBits(8);
31         setConfigAlphaBits(8);
32     }
33 };
34 
35 class GetImageTestNoExtensions : public ANGLETest
36 {
37   public:
GetImageTestNoExtensions()38     GetImageTestNoExtensions() { setExtensionsEnabled(false); }
39 };
40 
InitTextureWithSize(uint32_t size,void * pixelData)41 GLTexture InitTextureWithSize(uint32_t size, void *pixelData)
42 {
43     // Create a simple texture.
44     GLTexture tex;
45     glBindTexture(GL_TEXTURE_2D, tex);
46     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixelData);
47     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
48     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
49     return tex;
50 }
51 
InitSimpleTexture()52 GLTexture InitSimpleTexture()
53 {
54     std::vector<GLColor> pixelData(kSize * kSize, GLColor::red);
55     return InitTextureWithSize(kSize, pixelData.data());
56 }
57 
InitRenderbufferWithSize(uint32_t size)58 GLRenderbuffer InitRenderbufferWithSize(uint32_t size)
59 {
60     // Create a simple renderbuffer.
61     GLRenderbuffer renderbuf;
62     glBindRenderbuffer(GL_RENDERBUFFER, renderbuf);
63     glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, size, size);
64     return renderbuf;
65 }
66 
InitSimpleRenderbuffer()67 GLRenderbuffer InitSimpleRenderbuffer()
68 {
69     return InitRenderbufferWithSize(kSize);
70 }
71 
72 // Test validation for the extension functions.
TEST_P(GetImageTest,NegativeAPI)73 TEST_P(GetImageTest, NegativeAPI)
74 {
75     // Verify the extension is enabled.
76     ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));
77 
78     // Draw once with simple texture.
79     GLTexture tex = InitSimpleTexture();
80     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
81     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5, 1.0f, true);
82     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
83     ASSERT_GL_NO_ERROR();
84 
85     // Pack pixels tightly.
86     glPixelStorei(GL_PACK_ALIGNMENT, 1);
87 
88     // Verify GetTexImage can work with correct parameters.
89     std::vector<GLColor> buffer(kSize * kSize);
90     glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
91     EXPECT_GL_NO_ERROR();
92 
93     // Test invalid texture target.
94     glGetTexImageANGLE(GL_TEXTURE_CUBE_MAP, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
95     EXPECT_GL_ERROR(GL_INVALID_ENUM);
96 
97     // Test invalid texture level.
98     glGetTexImageANGLE(GL_TEXTURE_2D, -1, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
99     EXPECT_GL_ERROR(GL_INVALID_VALUE);
100     glGetTexImageANGLE(GL_TEXTURE_2D, 2000, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
101     EXPECT_GL_ERROR(GL_INVALID_VALUE);
102 
103     // Test invalid format and type.
104     glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_NONE, GL_UNSIGNED_BYTE, buffer.data());
105     EXPECT_GL_ERROR(GL_INVALID_ENUM);
106     glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_NONE, buffer.data());
107     EXPECT_GL_ERROR(GL_INVALID_ENUM);
108 
109     // Create a simple renderbuffer.
110     GLRenderbuffer renderbuf = InitSimpleRenderbuffer();
111     ASSERT_GL_NO_ERROR();
112 
113     // Verify GetRenderbufferImage can work with correct parameters.
114     glGetRenderbufferImageANGLE(GL_RENDERBUFFER, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
115     EXPECT_GL_NO_ERROR();
116 
117     // Test invalid renderbuffer target.
118     glGetRenderbufferImageANGLE(GL_TEXTURE_2D, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
119     EXPECT_GL_ERROR(GL_INVALID_ENUM);
120 
121     // Test invalid renderbuffer format/type.
122     glGetRenderbufferImageANGLE(GL_RENDERBUFFER, GL_NONE, GL_UNSIGNED_BYTE, buffer.data());
123     EXPECT_GL_ERROR(GL_INVALID_ENUM);
124     glGetRenderbufferImageANGLE(GL_RENDERBUFFER, GL_RGBA, GL_NONE, buffer.data());
125     EXPECT_GL_ERROR(GL_INVALID_ENUM);
126 
127     // Pack buffer tests. Requires ES 3+ or extension.
128     if (getClientMajorVersion() >= 3 || IsGLExtensionEnabled("GL_NV_pixel_buffer_object"))
129     {
130         // Test valid pack buffer.
131         GLBuffer packBuffer;
132         glBindBuffer(GL_PIXEL_PACK_BUFFER, packBuffer);
133         glBufferData(GL_PIXEL_PACK_BUFFER, kSize * kSize * sizeof(GLColor), nullptr,
134                      GL_STATIC_DRAW);
135         glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
136         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
137         glGetRenderbufferImageANGLE(GL_RENDERBUFFER, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
138         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
139 
140         // Test too small pack buffer.
141         glBufferData(GL_PIXEL_PACK_BUFFER, kSize, nullptr, GL_STATIC_DRAW);
142         glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
143         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
144         glGetRenderbufferImageANGLE(GL_RENDERBUFFER, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
145         EXPECT_GL_ERROR(GL_INVALID_OPERATION);
146     }
147 }
148 
149 // Simple test for GetTexImage
TEST_P(GetImageTest,GetTexImage)150 TEST_P(GetImageTest, GetTexImage)
151 {
152     // Verify the extension is enabled.
153     ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));
154 
155     constexpr uint32_t kSmallSize     = 2;
156     std::vector<GLColor> expectedData = {GLColor::red, GLColor::blue, GLColor::green,
157                                          GLColor::yellow};
158 
159     glViewport(0, 0, kSmallSize, kSmallSize);
160 
161     // Draw once with simple texture.
162     GLTexture tex = InitTextureWithSize(kSmallSize, expectedData.data());
163     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
164     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5, 1.0f, true);
165     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
166     ASSERT_GL_NO_ERROR();
167 
168     // Pack pixels tightly.
169     glPixelStorei(GL_PACK_ALIGNMENT, 1);
170 
171     // Verify GetImage.
172     std::vector<GLColor> actualData(kSmallSize * kSmallSize);
173     glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, actualData.data());
174     EXPECT_GL_NO_ERROR();
175     EXPECT_EQ(expectedData, actualData);
176 }
177 
178 // Simple cube map test for GetTexImage
TEST_P(GetImageTest,CubeMap)179 TEST_P(GetImageTest, CubeMap)
180 {
181     // Verify the extension is enabled.
182     ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));
183 
184     const std::array<std::array<GLColor, kSmallSize * kSmallSize>, kCubeFaces.size()> expectedData =
185         {{
186             {GLColor::red, GLColor::red, GLColor::red, GLColor::red},
187             {GLColor::green, GLColor::green, GLColor::green, GLColor::green},
188             {GLColor::blue, GLColor::blue, GLColor::blue, GLColor::blue},
189             {GLColor::yellow, GLColor::yellow, GLColor::yellow, GLColor::yellow},
190             {GLColor::cyan, GLColor::cyan, GLColor::cyan, GLColor::cyan},
191             {GLColor::magenta, GLColor::magenta, GLColor::magenta, GLColor::magenta},
192         }};
193 
194     GLTexture texture;
195     glBindTexture(GL_TEXTURE_CUBE_MAP, texture);
196 
197     for (size_t faceIndex = 0; faceIndex < kCubeFaces.size(); ++faceIndex)
198     {
199         glTexImage2D(kCubeFaces[faceIndex], 0, GL_RGBA, kSmallSize, kSmallSize, 0, GL_RGBA,
200                      GL_UNSIGNED_BYTE, expectedData[faceIndex].data());
201     }
202     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
203     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
204 
205     // Pack pixels tightly.
206     glPixelStorei(GL_PACK_ALIGNMENT, 1);
207 
208     // Verify GetImage.
209     std::array<GLColor, kSmallSize *kSmallSize> actualData = {};
210     for (size_t faceIndex = 0; faceIndex < kCubeFaces.size(); ++faceIndex)
211     {
212         glGetTexImageANGLE(kCubeFaces[faceIndex], 0, GL_RGBA, GL_UNSIGNED_BYTE, actualData.data());
213         EXPECT_GL_NO_ERROR();
214         EXPECT_EQ(expectedData[faceIndex], actualData);
215     }
216 }
217 
218 // Simple test for GetRenderbufferImage
TEST_P(GetImageTest,GetRenderbufferImage)219 TEST_P(GetImageTest, GetRenderbufferImage)
220 {
221     // Verify the extension is enabled.
222     ASSERT_TRUE(IsGLExtensionEnabled(kExtensionName));
223 
224     std::vector<GLColor> expectedData = {GLColor::red, GLColor::blue, GLColor::green,
225                                          GLColor::yellow};
226 
227     glViewport(0, 0, kSmallSize, kSmallSize);
228 
229     // Set up a simple Framebuffer with a Renderbuffer.
230     GLRenderbuffer renderbuffer = InitRenderbufferWithSize(kSmallSize);
231     GLFramebuffer framebuffer;
232     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
233     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
234     ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
235 
236     // Draw once with simple texture.
237     GLTexture tex = InitTextureWithSize(kSmallSize, expectedData.data());
238     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
239     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5, 1.0f, true);
240     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
241     ASSERT_GL_NO_ERROR();
242 
243     // Pack pixels tightly.
244     glPixelStorei(GL_PACK_ALIGNMENT, 1);
245 
246     // Verify GetImage.
247     std::vector<GLColor> actualData(kSmallSize * kSmallSize);
248     glGetRenderbufferImageANGLE(GL_RENDERBUFFER, GL_RGBA, GL_UNSIGNED_BYTE, actualData.data());
249     EXPECT_GL_NO_ERROR();
250     EXPECT_EQ(expectedData, actualData);
251 }
252 
253 // Verifies that the extension enums and entry points are invalid when the extension is disabled.
TEST_P(GetImageTestNoExtensions,EntryPointsInactive)254 TEST_P(GetImageTestNoExtensions, EntryPointsInactive)
255 {
256     // Verify the extension is not enabled.
257     ASSERT_FALSE(IsGLExtensionEnabled(kExtensionName));
258 
259     // Draw once with simple texture.
260     GLTexture tex = InitSimpleTexture();
261     ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
262     drawQuad(program, essl1_shaders::PositionAttrib(), 0.5, 1.0f, true);
263     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
264     ASSERT_GL_NO_ERROR();
265 
266     // Query implementation format and type. Should give invalid enum.
267     GLint param;
268     glGetTexParameteriv(GL_TEXTURE_2D, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &param);
269     EXPECT_GL_ERROR(GL_INVALID_ENUM);
270 
271     glGetTexParameteriv(GL_TEXTURE_2D, GL_IMPLEMENTATION_COLOR_READ_TYPE, &param);
272     EXPECT_GL_ERROR(GL_INVALID_ENUM);
273 
274     // Verify calling GetTexImage produces an error.
275     std::vector<GLColor> buffer(kSize * kSize, 0);
276     glGetTexImageANGLE(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
277     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
278 
279     // Create a simple renderbuffer.
280     GLRenderbuffer renderbuf = InitSimpleRenderbuffer();
281     ASSERT_GL_NO_ERROR();
282 
283     // Query implementation format and type. Should give invalid enum.
284     glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_IMPLEMENTATION_COLOR_READ_FORMAT, &param);
285     EXPECT_GL_ERROR(GL_INVALID_ENUM);
286 
287     glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_IMPLEMENTATION_COLOR_READ_TYPE, &param);
288     EXPECT_GL_ERROR(GL_INVALID_ENUM);
289 
290     // Verify calling GetRenderbufferImage produces an error.
291     glGetRenderbufferImageANGLE(GL_RENDERBUFFER, GL_RGBA, GL_UNSIGNED_BYTE, buffer.data());
292     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
293 }
294 
295 ANGLE_INSTANTIATE_TEST(GetImageTest, ES2_VULKAN(), ES3_VULKAN());
296 ANGLE_INSTANTIATE_TEST(GetImageTestNoExtensions, ES2_VULKAN(), ES3_VULKAN());
297 }  // namespace