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
7 #include "test_utils/ANGLETest.h"
8 #include "test_utils/gl_raii.h"
9
10 #include "media/pixel.inc"
11
12 using namespace angle;
13
14 class DXT1CompressedTextureTest : public ANGLETest
15 {
16 protected:
DXT1CompressedTextureTest()17 DXT1CompressedTextureTest()
18 {
19 setWindowWidth(512);
20 setWindowHeight(512);
21 setConfigRedBits(8);
22 setConfigGreenBits(8);
23 setConfigBlueBits(8);
24 setConfigAlphaBits(8);
25 }
26
testSetUp()27 void testSetUp() override
28 {
29 constexpr char kVS[] = R"(precision highp float;
30 attribute vec4 position;
31 varying vec2 texcoord;
32
33 void main()
34 {
35 gl_Position = position;
36 texcoord = (position.xy * 0.5) + 0.5;
37 texcoord.y = 1.0 - texcoord.y;
38 })";
39
40 constexpr char kFS[] = R"(precision highp float;
41 uniform sampler2D tex;
42 varying vec2 texcoord;
43
44 void main()
45 {
46 gl_FragColor = texture2D(tex, texcoord);
47 })";
48
49 mTextureProgram = CompileProgram(kVS, kFS);
50 if (mTextureProgram == 0)
51 {
52 FAIL() << "shader compilation failed.";
53 }
54
55 mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex");
56
57 ASSERT_GL_NO_ERROR();
58 }
59
testTearDown()60 void testTearDown() override { glDeleteProgram(mTextureProgram); }
61
62 GLuint mTextureProgram;
63 GLint mTextureUniformLocation;
64 };
65
TEST_P(DXT1CompressedTextureTest,CompressedTexImage)66 TEST_P(DXT1CompressedTextureTest, CompressedTexImage)
67 {
68 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
69
70 GLuint texture;
71 glGenTextures(1, &texture);
72 glBindTexture(GL_TEXTURE_2D, texture);
73 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
74 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
75 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
76 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
77
78 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width,
79 pixel_0_height, 0, pixel_0_size, pixel_0_data);
80 glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_1_width,
81 pixel_1_height, 0, pixel_1_size, pixel_1_data);
82 glCompressedTexImage2D(GL_TEXTURE_2D, 2, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_2_width,
83 pixel_2_height, 0, pixel_2_size, pixel_2_data);
84 glCompressedTexImage2D(GL_TEXTURE_2D, 3, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_3_width,
85 pixel_3_height, 0, pixel_3_size, pixel_3_data);
86 glCompressedTexImage2D(GL_TEXTURE_2D, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_4_width,
87 pixel_4_height, 0, pixel_4_size, pixel_4_data);
88 glCompressedTexImage2D(GL_TEXTURE_2D, 5, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_5_width,
89 pixel_5_height, 0, pixel_5_size, pixel_5_data);
90 glCompressedTexImage2D(GL_TEXTURE_2D, 6, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_6_width,
91 pixel_6_height, 0, pixel_6_size, pixel_6_data);
92 glCompressedTexImage2D(GL_TEXTURE_2D, 7, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_7_width,
93 pixel_7_height, 0, pixel_7_size, pixel_7_data);
94 glCompressedTexImage2D(GL_TEXTURE_2D, 8, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_8_width,
95 pixel_8_height, 0, pixel_8_size, pixel_8_data);
96 glCompressedTexImage2D(GL_TEXTURE_2D, 9, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_9_width,
97 pixel_9_height, 0, pixel_9_size, pixel_9_data);
98
99 EXPECT_GL_NO_ERROR();
100
101 glUseProgram(mTextureProgram);
102 glUniform1i(mTextureUniformLocation, 0);
103
104 drawQuad(mTextureProgram, "position", 0.5f);
105
106 EXPECT_GL_NO_ERROR();
107
108 glDeleteTextures(1, &texture);
109
110 EXPECT_GL_NO_ERROR();
111 }
112
113 // Verify that DXT1 RGB textures have 1.0 alpha when sampled
TEST_P(DXT1CompressedTextureTest,DXT1Alpha)114 TEST_P(DXT1CompressedTextureTest, DXT1Alpha)
115 {
116 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
117
118 // On platforms without native support for DXT1 RGB or texture swizzling (such as D3D or some
119 // Metal configurations), this test is allowed to succeed with transparent black instead of
120 // opaque black.
121 const bool opaque = !IsD3D() && !(IsMetal() && !IsMetalTextureSwizzleAvailable());
122
123 GLTexture texture;
124 glBindTexture(GL_TEXTURE_2D, texture);
125 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
126 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
127
128 // Image using pixels with the code for transparent black:
129 // "BLACK, if color0 <= color1 and code(x,y) == 3"
130 constexpr uint8_t CompressedImageDXT1[] = {0, 0, 0, 0, 255, 255, 255, 255};
131 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0,
132 sizeof(CompressedImageDXT1), CompressedImageDXT1);
133
134 EXPECT_GL_NO_ERROR();
135
136 glUseProgram(mTextureProgram);
137 glUniform1i(mTextureUniformLocation, 0);
138
139 constexpr GLint kDrawSize = 4;
140 // The image is one 4x4 block, make the viewport only 4x4.
141 glViewport(0, 0, kDrawSize, kDrawSize);
142
143 drawQuad(mTextureProgram, "position", 0.5f);
144
145 EXPECT_GL_NO_ERROR();
146
147 for (GLint y = 0; y < kDrawSize; y++)
148 {
149 for (GLint x = 0; x < kDrawSize; x++)
150 {
151 EXPECT_PIXEL_EQ(x, y, 0, 0, 0, opaque ? 255 : 0) << "at (" << x << ", " << y << ")";
152 }
153 }
154 }
155
TEST_P(DXT1CompressedTextureTest,CompressedTexStorage)156 TEST_P(DXT1CompressedTextureTest, CompressedTexStorage)
157 {
158 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
159
160 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
161 (!IsGLExtensionEnabled("GL_EXT_texture_storage") ||
162 !IsGLExtensionEnabled("GL_OES_rgb8_rgba8")));
163
164 GLuint texture;
165 glGenTextures(1, &texture);
166 glBindTexture(GL_TEXTURE_2D, texture);
167 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
168 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
169 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
170 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
171
172 if (getClientMajorVersion() < 3)
173 {
174 glTexStorage2DEXT(GL_TEXTURE_2D, pixel_levels, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
175 pixel_0_width, pixel_0_height);
176 }
177 else
178 {
179 glTexStorage2D(GL_TEXTURE_2D, pixel_levels, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width,
180 pixel_0_height);
181 }
182 EXPECT_GL_NO_ERROR();
183
184 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pixel_0_width, pixel_0_height,
185 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_size, pixel_0_data);
186 glCompressedTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, pixel_1_width, pixel_1_height,
187 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_1_size, pixel_1_data);
188 glCompressedTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, pixel_2_width, pixel_2_height,
189 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_2_size, pixel_2_data);
190 glCompressedTexSubImage2D(GL_TEXTURE_2D, 3, 0, 0, pixel_3_width, pixel_3_height,
191 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_3_size, pixel_3_data);
192 glCompressedTexSubImage2D(GL_TEXTURE_2D, 4, 0, 0, pixel_4_width, pixel_4_height,
193 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_4_size, pixel_4_data);
194 glCompressedTexSubImage2D(GL_TEXTURE_2D, 5, 0, 0, pixel_5_width, pixel_5_height,
195 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_5_size, pixel_5_data);
196 glCompressedTexSubImage2D(GL_TEXTURE_2D, 6, 0, 0, pixel_6_width, pixel_6_height,
197 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_6_size, pixel_6_data);
198 glCompressedTexSubImage2D(GL_TEXTURE_2D, 7, 0, 0, pixel_7_width, pixel_7_height,
199 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_7_size, pixel_7_data);
200 glCompressedTexSubImage2D(GL_TEXTURE_2D, 8, 0, 0, pixel_8_width, pixel_8_height,
201 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_8_size, pixel_8_data);
202 glCompressedTexSubImage2D(GL_TEXTURE_2D, 9, 0, 0, pixel_9_width, pixel_9_height,
203 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_9_size, pixel_9_data);
204
205 EXPECT_GL_NO_ERROR();
206
207 glUseProgram(mTextureProgram);
208 glUniform1i(mTextureUniformLocation, 0);
209
210 drawQuad(mTextureProgram, "position", 0.5f);
211
212 EXPECT_GL_NO_ERROR();
213
214 glDeleteTextures(1, &texture);
215
216 EXPECT_GL_NO_ERROR();
217 }
218
219 // Test validation of non block sizes, width 672 and height 114 and multiple mip levels
TEST_P(DXT1CompressedTextureTest,NonBlockSizesMipLevels)220 TEST_P(DXT1CompressedTextureTest, NonBlockSizesMipLevels)
221 {
222 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
223
224 GLTexture texture;
225 glBindTexture(GL_TEXTURE_2D, texture.get());
226
227 constexpr GLuint kWidth = 674;
228 constexpr GLuint kHeight = 114;
229
230 // From EXT_texture_compression_s3tc specifications:
231 // When an S3TC image with a width of <w>, height of <h>, and block size of
232 // <blocksize> (8 or 16 bytes) is decoded, the corresponding image size (in
233 // bytes) is:
234 // ceil(<w>/4) * ceil(<h>/4) * blocksize.
235 constexpr GLuint kImageSize = ((kWidth + 3) / 4) * ((kHeight + 3) / 4) * 8;
236
237 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, kWidth, kHeight, 0,
238 kImageSize, nullptr);
239 ASSERT_GL_NO_ERROR();
240
241 constexpr GLuint kImageSize1 = ((kWidth / 2 + 3) / 4) * ((kHeight / 2 + 3) / 4) * 8;
242 glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, kWidth / 2,
243 kHeight / 2, 0, kImageSize1, nullptr);
244 ASSERT_GL_NO_ERROR();
245
246 constexpr GLuint kImageSize2 = ((kWidth / 4 + 3) / 4) * ((kHeight / 4 + 3) / 4) * 8;
247 glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, kWidth / 4,
248 kHeight / 4, 0, kImageSize2, nullptr);
249 ASSERT_GL_NO_ERROR();
250 }
251
252 // Test validation of glCompressedTexSubImage2D with DXT formats
TEST_P(DXT1CompressedTextureTest,CompressedTexSubImageValidation)253 TEST_P(DXT1CompressedTextureTest, CompressedTexSubImageValidation)
254 {
255 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
256
257 GLTexture texture;
258 glBindTexture(GL_TEXTURE_2D, texture.get());
259
260 // Size mip 0 to a large size
261 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width,
262 pixel_0_height, 0, pixel_0_size, nullptr);
263 ASSERT_GL_NO_ERROR();
264
265 // Set a sub image with an offset that isn't a multiple of the block size
266 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 1, 3, pixel_1_width, pixel_1_height,
267 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_1_size, pixel_1_data);
268 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
269
270 // Set a sub image with a negative offset
271 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, -1, 0, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 8,
272 pixel_1_data);
273 ASSERT_GL_ERROR(GL_INVALID_VALUE);
274
275 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, -1, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 8,
276 pixel_1_data);
277 ASSERT_GL_ERROR(GL_INVALID_VALUE);
278 }
279
280 // Test that it's not possible to call CopyTexSubImage2D on a compressed texture
TEST_P(DXT1CompressedTextureTest,CopyTexSubImage2DDisallowed)281 TEST_P(DXT1CompressedTextureTest, CopyTexSubImage2DDisallowed)
282 {
283 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
284
285 GLTexture texture;
286 glBindTexture(GL_TEXTURE_2D, texture.get());
287
288 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width,
289 pixel_0_height, 0, pixel_0_size, nullptr);
290 ASSERT_GL_NO_ERROR();
291
292 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 4, 4);
293 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
294 }
295
TEST_P(DXT1CompressedTextureTest,PBOCompressedTexStorage)296 TEST_P(DXT1CompressedTextureTest, PBOCompressedTexStorage)
297 {
298 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
299
300 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
301 !IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
302
303 ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
304 (!IsGLExtensionEnabled("GL_EXT_texture_storage") ||
305 !IsGLExtensionEnabled("GL_OES_rgb8_rgba8")));
306
307 GLuint texture;
308 glGenTextures(1, &texture);
309 glBindTexture(GL_TEXTURE_2D, texture);
310 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
311 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
312 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
313 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
314
315 if (getClientMajorVersion() < 3)
316 {
317 glTexStorage2DEXT(GL_TEXTURE_2D, pixel_levels, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
318 pixel_0_width, pixel_0_height);
319 }
320 else
321 {
322 glTexStorage2D(GL_TEXTURE_2D, pixel_levels, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width,
323 pixel_0_height);
324 }
325 EXPECT_GL_NO_ERROR();
326
327 GLuint buffer;
328 glGenBuffers(1, &buffer);
329 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
330 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixel_0_size, nullptr, GL_STREAM_DRAW);
331 EXPECT_GL_NO_ERROR();
332
333 glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_0_size, pixel_0_data);
334 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pixel_0_width, pixel_0_height,
335 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_size, nullptr);
336 glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_1_size, pixel_1_data);
337 glCompressedTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, pixel_1_width, pixel_1_height,
338 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_1_size, nullptr);
339 glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_2_size, pixel_2_data);
340 glCompressedTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, pixel_2_width, pixel_2_height,
341 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_2_size, nullptr);
342 glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_3_size, pixel_3_data);
343 glCompressedTexSubImage2D(GL_TEXTURE_2D, 3, 0, 0, pixel_3_width, pixel_3_height,
344 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_3_size, nullptr);
345 glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_4_size, pixel_4_data);
346 glCompressedTexSubImage2D(GL_TEXTURE_2D, 4, 0, 0, pixel_4_width, pixel_4_height,
347 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_4_size, nullptr);
348 glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_5_size, pixel_5_data);
349 glCompressedTexSubImage2D(GL_TEXTURE_2D, 5, 0, 0, pixel_5_width, pixel_5_height,
350 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_5_size, nullptr);
351 glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_6_size, pixel_6_data);
352 glCompressedTexSubImage2D(GL_TEXTURE_2D, 6, 0, 0, pixel_6_width, pixel_6_height,
353 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_6_size, nullptr);
354 glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_7_size, pixel_7_data);
355 glCompressedTexSubImage2D(GL_TEXTURE_2D, 7, 0, 0, pixel_7_width, pixel_7_height,
356 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_7_size, nullptr);
357 glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_8_size, pixel_8_data);
358 glCompressedTexSubImage2D(GL_TEXTURE_2D, 8, 0, 0, pixel_8_width, pixel_8_height,
359 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_8_size, nullptr);
360 glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_9_size, pixel_9_data);
361 glCompressedTexSubImage2D(GL_TEXTURE_2D, 9, 0, 0, pixel_9_width, pixel_9_height,
362 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_9_size, nullptr);
363
364 EXPECT_GL_NO_ERROR();
365
366 glUseProgram(mTextureProgram);
367 glUniform1i(mTextureUniformLocation, 0);
368
369 drawQuad(mTextureProgram, "position", 0.5f);
370
371 EXPECT_GL_NO_ERROR();
372
373 glDeleteTextures(1, &texture);
374
375 EXPECT_GL_NO_ERROR();
376 }
377
378 class DXT1CompressedTextureTestES3 : public DXT1CompressedTextureTest
379 {};
380
TEST_P(DXT1CompressedTextureTestES3,PBOCompressedTexImage)381 TEST_P(DXT1CompressedTextureTestES3, PBOCompressedTexImage)
382 {
383 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
384
385 GLuint texture;
386 glGenTextures(1, &texture);
387 glBindTexture(GL_TEXTURE_2D, texture);
388 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
389 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
390 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
391 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
392
393 GLuint buffer;
394 glGenBuffers(1, &buffer);
395 glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
396 glBufferData(GL_PIXEL_UNPACK_BUFFER, pixel_0_size, nullptr, GL_STREAM_DRAW);
397 EXPECT_GL_NO_ERROR();
398
399 glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_0_size, pixel_0_data);
400 glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width,
401 pixel_0_height, 0, pixel_0_size, nullptr);
402 glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_1_size, pixel_1_data);
403 glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_1_width,
404 pixel_1_height, 0, pixel_1_size, nullptr);
405 glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_2_size, pixel_2_data);
406 glCompressedTexImage2D(GL_TEXTURE_2D, 2, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_2_width,
407 pixel_2_height, 0, pixel_2_size, nullptr);
408 glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_3_size, pixel_3_data);
409 glCompressedTexImage2D(GL_TEXTURE_2D, 3, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_3_width,
410 pixel_3_height, 0, pixel_3_size, nullptr);
411 glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_4_size, pixel_4_data);
412 glCompressedTexImage2D(GL_TEXTURE_2D, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_4_width,
413 pixel_4_height, 0, pixel_4_size, nullptr);
414 glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_5_size, pixel_5_data);
415 glCompressedTexImage2D(GL_TEXTURE_2D, 5, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_5_width,
416 pixel_5_height, 0, pixel_5_size, nullptr);
417 glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_6_size, pixel_6_data);
418 glCompressedTexImage2D(GL_TEXTURE_2D, 6, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_6_width,
419 pixel_6_height, 0, pixel_6_size, nullptr);
420 glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_7_size, pixel_7_data);
421 glCompressedTexImage2D(GL_TEXTURE_2D, 7, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_7_width,
422 pixel_7_height, 0, pixel_7_size, nullptr);
423 glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_8_size, pixel_8_data);
424 glCompressedTexImage2D(GL_TEXTURE_2D, 8, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_8_width,
425 pixel_8_height, 0, pixel_8_size, nullptr);
426 glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_9_size, pixel_9_data);
427 glCompressedTexImage2D(GL_TEXTURE_2D, 9, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_9_width,
428 pixel_9_height, 0, pixel_9_size, nullptr);
429
430 EXPECT_GL_NO_ERROR();
431
432 glUseProgram(mTextureProgram);
433 glUniform1i(mTextureUniformLocation, 0);
434
435 drawQuad(mTextureProgram, "position", 0.5f);
436
437 EXPECT_GL_NO_ERROR();
438
439 glDeleteTextures(1, &buffer);
440 glDeleteTextures(1, &texture);
441
442 EXPECT_GL_NO_ERROR();
443 }
444
445 // Test validation of glCompressedTexSubImage3D with DXT formats
TEST_P(DXT1CompressedTextureTestES3,CompressedTexSubImageValidation)446 TEST_P(DXT1CompressedTextureTestES3, CompressedTexSubImageValidation)
447 {
448 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
449
450 GLTexture texture;
451 glBindTexture(GL_TEXTURE_2D_ARRAY, texture.get());
452
453 // Size mip 0 to a large size
454 glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width,
455 pixel_0_height, 1, 0, pixel_0_size, nullptr);
456 ASSERT_GL_NO_ERROR();
457
458 // Set a sub image with a negative offset
459 glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, -1, 0, 0, 4, 4, 1,
460 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 8, pixel_1_data);
461 ASSERT_GL_ERROR(GL_INVALID_VALUE);
462
463 glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, -1, 0, 4, 4, 1,
464 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 8, pixel_1_data);
465 ASSERT_GL_ERROR(GL_INVALID_VALUE);
466
467 glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, -1, 4, 4, 1,
468 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 8, pixel_1_data);
469 ASSERT_GL_ERROR(GL_INVALID_VALUE);
470 }
471
472 // Test validation of glCompressedTexSubImage3D with DXT formats
TEST_P(DXT1CompressedTextureTestES3,CopyTexSubImage3DDisallowed)473 TEST_P(DXT1CompressedTextureTestES3, CopyTexSubImage3DDisallowed)
474 {
475 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
476
477 GLTexture texture;
478 glBindTexture(GL_TEXTURE_2D_ARRAY, texture.get());
479
480 GLsizei depth = 4;
481 glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width,
482 pixel_0_height, depth, 0, pixel_0_size * depth, nullptr);
483 ASSERT_GL_NO_ERROR();
484
485 glCopyTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, 0, 0, 4, 4);
486 ASSERT_GL_ERROR(GL_INVALID_OPERATION);
487 }
488
489 class DXT1CompressedTextureTestWebGL2 : public DXT1CompressedTextureTest
490 {
491 protected:
DXT1CompressedTextureTestWebGL2()492 DXT1CompressedTextureTestWebGL2()
493 {
494 setWebGLCompatibilityEnabled(true);
495 setRobustResourceInit(true);
496 }
497 };
498
499 // Regression test for https://crbug.com/1289428
TEST_P(DXT1CompressedTextureTestWebGL2,InitializeTextureContents)500 TEST_P(DXT1CompressedTextureTestWebGL2, InitializeTextureContents)
501 {
502 ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
503
504 glUseProgram(mTextureProgram);
505 glUniform1i(mTextureUniformLocation, 0);
506
507 glClearColor(0, 0, 1, 1);
508
509 const std::array<uint8_t, 8> kGreen = {0xE0, 0x07, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00};
510
511 GLTexture tex;
512 glBindTexture(GL_TEXTURE_2D, tex);
513 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
514 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
515 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
516 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
517
518 glTexStorage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4);
519 EXPECT_GL_NO_ERROR();
520
521 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
522 drawQuad(mTextureProgram, "position", 0.5f, 1.0f, true);
523 EXPECT_GL_NO_ERROR();
524 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::black);
525
526 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8,
527 kGreen.data());
528 EXPECT_GL_NO_ERROR();
529
530 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
531 drawQuad(mTextureProgram, "position", 0.5f, 1.0f, true);
532 EXPECT_GL_NO_ERROR();
533 EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::green);
534 }
535
536 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(DXT1CompressedTextureTest);
537
538 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DXT1CompressedTextureTestES3);
539 ANGLE_INSTANTIATE_TEST_ES3(DXT1CompressedTextureTestES3);
540
541 ANGLE_INSTANTIATE_TEST_ES3(DXT1CompressedTextureTestWebGL2);
542