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