• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2016 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 
7 // CopyCompressedTextureTest.cpp: Tests of the GL_CHROMIUM_copy_compressed_texture extension
8 
9 #include "test_utils/ANGLETest.h"
10 
11 namespace angle
12 {
13 
14 class CopyCompressedTextureTest : public ANGLETest
15 {
16   protected:
CopyCompressedTextureTest()17     CopyCompressedTextureTest()
18     {
19         setWindowWidth(256);
20         setWindowHeight(256);
21         setConfigRedBits(8);
22         setConfigGreenBits(8);
23         setConfigBlueBits(8);
24         setConfigAlphaBits(8);
25     }
26 
testSetUp()27     void testSetUp() override
28     {
29         glGenTextures(2, mTextures);
30 
31         constexpr char kVS[] =
32             "attribute vec2 a_position;\n"
33             "varying vec2 v_texcoord;\n"
34             "void main()\n"
35             "{\n"
36             "   gl_Position = vec4(a_position, 0.0, 1.0);\n"
37             "   v_texcoord = (a_position + 1.0) * 0.5;\n"
38             "}\n";
39 
40         constexpr char kFS[] =
41             "precision mediump float;\n"
42             "uniform sampler2D u_texture;\n"
43             "varying vec2 v_texcoord;\n"
44             "void main()\n"
45             "{\n"
46             "    gl_FragColor = texture2D(u_texture, v_texcoord);\n"
47             "}\n";
48 
49         mProgram = CompileProgram(kVS, kFS);
50         ASSERT_NE(0u, mProgram);
51     }
52 
testTearDown()53     void testTearDown() override
54     {
55         glDeleteTextures(2, mTextures);
56         glDeleteProgram(mProgram);
57     }
58 
checkExtensions() const59     bool checkExtensions() const
60     {
61         if (!IsGLExtensionEnabled("GL_CHROMIUM_copy_compressed_texture"))
62         {
63             std::cout
64                 << "Test skipped because GL_CHROMIUM_copy_compressed_texture is not available."
65                 << std::endl;
66             return false;
67         }
68 
69         EXPECT_NE(nullptr, glCompressedCopyTextureCHROMIUM);
70         if (glCompressedCopyTextureCHROMIUM == nullptr)
71         {
72             return false;
73         }
74 
75         return true;
76     }
77 
78     GLuint mProgram     = 0;
79     GLuint mTextures[2] = {0, 0};
80 };
81 
82 namespace
83 {
84 
85 const GLColor &CompressedImageColor = GLColor::red;
86 
87 // Single compressed ATC block of source pixels all set to:
88 // CompressedImageColor.
89 const uint8_t CompressedImageATC[8] = {0x0, 0x7c, 0x0, 0xf8, 0x55, 0x55, 0x55, 0x55};
90 
91 // Single compressed ATCIA block of source pixels all set to:
92 // CompressedImageColor.
93 const uint8_t CompressedImageATCIA[16] = {0xff, 0xff, 0x0, 0x0,  0x0,  0x0,  0x0,  0x0,
94                                           0x0,  0x7c, 0x0, 0xf8, 0x55, 0x55, 0x55, 0x55};
95 
96 // Single compressed DXT1 block of source pixels all set to:
97 // CompressedImageColor.
98 const uint8_t CompressedImageDXT1[8] = {0x00, 0xf8, 0x00, 0xf8, 0xaa, 0xaa, 0xaa, 0xaa};
99 
100 // Single compressed DXT5 block of source pixels all set to:
101 // CompressedImageColor.
102 const uint8_t CompressedImageDXT5[16] = {0xff, 0xff, 0x0, 0x0,  0x0,  0x0,  0x0,  0x0,
103                                          0x0,  0xf8, 0x0, 0xf8, 0xaa, 0xaa, 0xaa, 0xaa};
104 
105 // Single compressed DXT1 block of source pixels all set to:
106 // CompressedImageColor.
107 const uint8_t CompressedImageETC1[8] = {0x0, 0x0, 0xf8, 0x2, 0xff, 0xff, 0x0, 0x0};
108 
109 }  // anonymous namespace
110 
111 // Test to ensure that the basic functionality of the extension works.
TEST_P(CopyCompressedTextureTest,Basic)112 TEST_P(CopyCompressedTextureTest, Basic)
113 {
114     ANGLE_SKIP_TEST_IF(!checkExtensions());
115 
116     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
117 
118     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
119     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
120     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
121     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
122     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
123     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0,
124                            sizeof(CompressedImageDXT1), CompressedImageDXT1);
125     ASSERT_GL_NO_ERROR();
126 
127     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
128     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
129     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
130     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
131     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
132     glCompressedCopyTextureCHROMIUM(mTextures[0], mTextures[1]);
133     ASSERT_GL_NO_ERROR();
134 
135     // Load texture.
136     glActiveTexture(GL_TEXTURE0);
137     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
138     GLint textureLoc = glGetUniformLocation(mProgram, "u_texture");
139     glUseProgram(mProgram);
140     glUniform1i(textureLoc, 0);
141 
142     // Draw.
143     drawQuad(mProgram, "a_position", 0.5f);
144 
145     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, CompressedImageColor);
146     ASSERT_GL_NO_ERROR();
147 }
148 
149 // Test validation of compressed formats
TEST_P(CopyCompressedTextureTest,InternalFormat)150 TEST_P(CopyCompressedTextureTest, InternalFormat)
151 {
152     if (!checkExtensions())
153     {
154         return;
155     }
156 
157     struct Data
158     {
159         GLint format;
160         const uint8_t *data;
161         GLsizei dataSize;
162 
163         Data() : Data(GL_NONE, nullptr, 0) {}
164         Data(GLint format, const uint8_t *data, GLsizei dataSize)
165             : format(format), data(data), dataSize(dataSize)
166         {}
167     };
168     std::vector<Data> supportedFormats;
169 
170     if (IsGLExtensionEnabled("GL_AMD_compressed_ATC_texture"))
171     {
172         supportedFormats.push_back(
173             Data(GL_ATC_RGB_AMD, CompressedImageATC, sizeof(CompressedImageATC)));
174         supportedFormats.push_back(Data(GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD, CompressedImageATCIA,
175                                         sizeof(CompressedImageATCIA)));
176     }
177     if (IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"))
178     {
179         supportedFormats.push_back(Data(GL_COMPRESSED_RGB_S3TC_DXT1_EXT, CompressedImageDXT1,
180                                         sizeof(CompressedImageDXT1)));
181     }
182     if (IsGLExtensionEnabled("GL_ANGLE_texture_compression_dxt5"))
183     {
184         supportedFormats.push_back(Data(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, CompressedImageDXT5,
185                                         sizeof(CompressedImageDXT5)));
186     }
187     if (IsGLExtensionEnabled("GL_OES_compressed_ETC1_RGB8_texture"))
188     {
189         supportedFormats.push_back(
190             Data(GL_ETC1_RGB8_OES, CompressedImageETC1, sizeof(CompressedImageETC1)));
191     }
192 
193     for (const auto &supportedFormat : supportedFormats)
194     {
195         glBindTexture(GL_TEXTURE_2D, mTextures[0]);
196         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
197         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
198         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
199         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
200         glCompressedTexImage2D(GL_TEXTURE_2D, 0, supportedFormat.format, 4, 4, 0,
201                                supportedFormat.dataSize, supportedFormat.data);
202         ASSERT_GL_NO_ERROR();
203 
204         glBindTexture(GL_TEXTURE_2D, mTextures[1]);
205         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
206         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
207         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
208         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
209         glCompressedCopyTextureCHROMIUM(mTextures[0], mTextures[1]);
210         ASSERT_GL_NO_ERROR();
211     }
212 }
213 
214 // Test that uncompressed textures generate errors when copying
TEST_P(CopyCompressedTextureTest,InternalFormatNotSupported)215 TEST_P(CopyCompressedTextureTest, InternalFormatNotSupported)
216 {
217     if (!checkExtensions())
218     {
219         return;
220     }
221 
222     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
223     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
224     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
225     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
226     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
227     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
228     ASSERT_GL_NO_ERROR();
229 
230     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
231     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
232     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
233     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
234     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
235     ASSERT_GL_NO_ERROR();
236 
237     // Check that the GL_RGBA format reports an error.
238     glCompressedCopyTextureCHROMIUM(mTextures[0], mTextures[1]);
239     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
240 }
241 
242 // Test validation of texture IDs
TEST_P(CopyCompressedTextureTest,InvalidTextureIds)243 TEST_P(CopyCompressedTextureTest, InvalidTextureIds)
244 {
245     if (!checkExtensions())
246     {
247         return;
248     }
249 
250     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
251 
252     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
253     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
254     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
255     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
256     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
257     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0,
258                            sizeof(CompressedImageDXT1), CompressedImageDXT1);
259     ASSERT_GL_NO_ERROR();
260 
261     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
262     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
263     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
264     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
265     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
266     ASSERT_GL_NO_ERROR();
267 
268     glCompressedCopyTextureCHROMIUM(mTextures[0], 99993);
269     EXPECT_GL_ERROR(GL_INVALID_VALUE);
270 
271     glCompressedCopyTextureCHROMIUM(99994, mTextures[1]);
272     EXPECT_GL_ERROR(GL_INVALID_VALUE);
273 
274     glCompressedCopyTextureCHROMIUM(99995, 99996);
275     EXPECT_GL_ERROR(GL_INVALID_VALUE);
276 
277     glCompressedCopyTextureCHROMIUM(mTextures[0], mTextures[1]);
278     EXPECT_GL_NO_ERROR();
279 }
280 
281 // Test that only 2D textures are valid
TEST_P(CopyCompressedTextureTest,BindingPoints)282 TEST_P(CopyCompressedTextureTest, BindingPoints)
283 {
284     if (!checkExtensions())
285     {
286         return;
287     }
288 
289     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
290 
291     glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[0]);
292     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
293     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
294     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
295     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
296     for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
297          face++)
298     {
299         glCompressedTexImage2D(face, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0,
300                                sizeof(CompressedImageDXT1), CompressedImageDXT1);
301     }
302     ASSERT_GL_NO_ERROR();
303 
304     glBindTexture(GL_TEXTURE_CUBE_MAP, mTextures[1]);
305     glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
306     glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
307     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
308     glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
309     ASSERT_GL_NO_ERROR();
310 
311     glCompressedCopyTextureCHROMIUM(mTextures[0], mTextures[1]);
312     EXPECT_GL_ERROR(GL_INVALID_VALUE);
313 }
314 
315 // Test the destination texture cannot be immutable
TEST_P(CopyCompressedTextureTest,Immutable)316 TEST_P(CopyCompressedTextureTest, Immutable)
317 {
318     if (!checkExtensions() || getClientMajorVersion() < 3)
319     {
320         return;
321     }
322 
323     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
324 
325     glBindTexture(GL_TEXTURE_2D, mTextures[0]);
326     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
327     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
328     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
329     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
330     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0,
331                            sizeof(CompressedImageDXT1), CompressedImageDXT1);
332     ASSERT_GL_NO_ERROR();
333 
334     glBindTexture(GL_TEXTURE_2D, mTextures[1]);
335     glTexStorage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4);
336     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
337     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
338     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
339     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
340     ASSERT_GL_NO_ERROR();
341 
342     glCompressedCopyTextureCHROMIUM(mTextures[0], mTextures[1]);
343     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
344 }
345 
346 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
347 // tests should be run against.
348 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(CopyCompressedTextureTest);
349 
350 }  // namespace angle
351