xref: /aosp_15_r20/external/angle/src/tests/gl_tests/DXT1CompressedTextureTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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     auto test = [&](const std::string &extName, GLenum format) {
117         ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled(extName));
118 
119         // On platforms without native support for DXT1 RGB or texture swizzling (such as D3D or
120         // some Metal configurations), this test is allowed to succeed with transparent black
121         // instead of opaque black.
122         const bool opaque = !IsD3D() && !(IsMetal() && !IsMetalTextureSwizzleAvailable());
123 
124         GLTexture texture;
125         glBindTexture(GL_TEXTURE_2D, texture);
126         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
127         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
128 
129         // Image using pixels with the code for transparent black:
130         //          "BLACK,             if color0 <= color1 and code(x,y) == 3"
131         constexpr uint8_t CompressedImageDXT1[] = {0, 0, 0, 0, 255, 255, 255, 255};
132         glCompressedTexImage2D(GL_TEXTURE_2D, 0, format, 4, 4, 0, sizeof(CompressedImageDXT1),
133                                CompressedImageDXT1);
134 
135         EXPECT_GL_NO_ERROR();
136 
137         glUseProgram(mTextureProgram);
138         glUniform1i(mTextureUniformLocation, 0);
139 
140         constexpr GLint kDrawSize = 4;
141         // The image is one 4x4 block, make the viewport only 4x4.
142         glViewport(0, 0, kDrawSize, kDrawSize);
143 
144         drawQuad(mTextureProgram, "position", 0.5f);
145 
146         EXPECT_GL_NO_ERROR();
147 
148         for (GLint y = 0; y < kDrawSize; y++)
149         {
150             for (GLint x = 0; x < kDrawSize; x++)
151             {
152                 EXPECT_PIXEL_EQ(x, y, 0, 0, 0, opaque ? 255 : 0)
153                     << "at (" << x << ", " << y << ") for " << extName;
154             }
155         }
156     };
157 
158     test("GL_EXT_texture_compression_dxt1", GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
159     test("GL_EXT_texture_compression_s3tc_srgb", GL_COMPRESSED_SRGB_S3TC_DXT1_EXT);
160 }
161 
TEST_P(DXT1CompressedTextureTest,CompressedTexStorage)162 TEST_P(DXT1CompressedTextureTest, CompressedTexStorage)
163 {
164     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
165 
166     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
167                        (!IsGLExtensionEnabled("GL_EXT_texture_storage") ||
168                         !IsGLExtensionEnabled("GL_OES_rgb8_rgba8")));
169 
170     GLuint texture;
171     glGenTextures(1, &texture);
172     glBindTexture(GL_TEXTURE_2D, texture);
173     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
174     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
175     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
176     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
177 
178     if (getClientMajorVersion() < 3)
179     {
180         glTexStorage2DEXT(GL_TEXTURE_2D, pixel_levels, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
181                           pixel_0_width, pixel_0_height);
182     }
183     else
184     {
185         glTexStorage2D(GL_TEXTURE_2D, pixel_levels, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width,
186                        pixel_0_height);
187     }
188     EXPECT_GL_NO_ERROR();
189 
190     glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pixel_0_width, pixel_0_height,
191                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_size, pixel_0_data);
192     glCompressedTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, pixel_1_width, pixel_1_height,
193                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_1_size, pixel_1_data);
194     glCompressedTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, pixel_2_width, pixel_2_height,
195                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_2_size, pixel_2_data);
196     glCompressedTexSubImage2D(GL_TEXTURE_2D, 3, 0, 0, pixel_3_width, pixel_3_height,
197                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_3_size, pixel_3_data);
198     glCompressedTexSubImage2D(GL_TEXTURE_2D, 4, 0, 0, pixel_4_width, pixel_4_height,
199                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_4_size, pixel_4_data);
200     glCompressedTexSubImage2D(GL_TEXTURE_2D, 5, 0, 0, pixel_5_width, pixel_5_height,
201                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_5_size, pixel_5_data);
202     glCompressedTexSubImage2D(GL_TEXTURE_2D, 6, 0, 0, pixel_6_width, pixel_6_height,
203                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_6_size, pixel_6_data);
204     glCompressedTexSubImage2D(GL_TEXTURE_2D, 7, 0, 0, pixel_7_width, pixel_7_height,
205                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_7_size, pixel_7_data);
206     glCompressedTexSubImage2D(GL_TEXTURE_2D, 8, 0, 0, pixel_8_width, pixel_8_height,
207                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_8_size, pixel_8_data);
208     glCompressedTexSubImage2D(GL_TEXTURE_2D, 9, 0, 0, pixel_9_width, pixel_9_height,
209                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_9_size, pixel_9_data);
210 
211     EXPECT_GL_NO_ERROR();
212 
213     glUseProgram(mTextureProgram);
214     glUniform1i(mTextureUniformLocation, 0);
215 
216     drawQuad(mTextureProgram, "position", 0.5f);
217 
218     EXPECT_GL_NO_ERROR();
219 
220     glDeleteTextures(1, &texture);
221 
222     EXPECT_GL_NO_ERROR();
223 }
224 
225 // Test validation of non block sizes, width 672 and height 114 and multiple mip levels
TEST_P(DXT1CompressedTextureTest,NonBlockSizesMipLevels)226 TEST_P(DXT1CompressedTextureTest, NonBlockSizesMipLevels)
227 {
228     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
229 
230     GLTexture texture;
231     glBindTexture(GL_TEXTURE_2D, texture);
232 
233     constexpr GLuint kWidth  = 674;
234     constexpr GLuint kHeight = 114;
235 
236     // From EXT_texture_compression_s3tc specifications:
237     // When an S3TC image with a width of <w>, height of <h>, and block size of
238     // <blocksize> (8 or 16 bytes) is decoded, the corresponding image size (in
239     // bytes) is:
240     //     ceil(<w>/4) * ceil(<h>/4) * blocksize.
241     constexpr GLuint kImageSize = ((kWidth + 3) / 4) * ((kHeight + 3) / 4) * 8;
242 
243     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, kWidth, kHeight, 0,
244                            kImageSize, nullptr);
245     ASSERT_GL_NO_ERROR();
246 
247     constexpr GLuint kImageSize1 = ((kWidth / 2 + 3) / 4) * ((kHeight / 2 + 3) / 4) * 8;
248     glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, kWidth / 2,
249                            kHeight / 2, 0, kImageSize1, nullptr);
250     ASSERT_GL_NO_ERROR();
251 
252     constexpr GLuint kImageSize2 = ((kWidth / 4 + 3) / 4) * ((kHeight / 4 + 3) / 4) * 8;
253     glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, kWidth / 4,
254                            kHeight / 4, 0, kImageSize2, nullptr);
255     ASSERT_GL_NO_ERROR();
256 }
257 
258 // Test validation of glCompressedTexSubImage2D with DXT formats
TEST_P(DXT1CompressedTextureTest,CompressedTexSubImageValidation)259 TEST_P(DXT1CompressedTextureTest, CompressedTexSubImageValidation)
260 {
261     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
262 
263     GLTexture texture;
264     glBindTexture(GL_TEXTURE_2D, texture);
265 
266     // Size mip 0 to a large size
267     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width,
268                            pixel_0_height, 0, pixel_0_size, nullptr);
269     ASSERT_GL_NO_ERROR();
270 
271     // Set a sub image with an offset that isn't a multiple of the block size
272     glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 1, 3, pixel_1_width, pixel_1_height,
273                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_1_size, pixel_1_data);
274     ASSERT_GL_ERROR(GL_INVALID_OPERATION);
275 
276     // Set a sub image with a negative offset
277     glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, -1, 0, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 8,
278                               pixel_1_data);
279     ASSERT_GL_ERROR(GL_INVALID_VALUE);
280 
281     glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, -1, 4, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 8,
282                               pixel_1_data);
283     ASSERT_GL_ERROR(GL_INVALID_VALUE);
284 }
285 
286 // Test that it's not possible to call CopyTexSubImage2D on a compressed texture
TEST_P(DXT1CompressedTextureTest,CopyTexSubImage2DDisallowed)287 TEST_P(DXT1CompressedTextureTest, CopyTexSubImage2DDisallowed)
288 {
289     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
290 
291     GLTexture texture;
292     glBindTexture(GL_TEXTURE_2D, texture);
293 
294     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width,
295                            pixel_0_height, 0, pixel_0_size, nullptr);
296     ASSERT_GL_NO_ERROR();
297 
298     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 4, 4);
299     ASSERT_GL_ERROR(GL_INVALID_OPERATION);
300 }
301 
TEST_P(DXT1CompressedTextureTest,PBOCompressedTexStorage)302 TEST_P(DXT1CompressedTextureTest, PBOCompressedTexStorage)
303 {
304     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
305 
306     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
307                        !IsGLExtensionEnabled("GL_NV_pixel_buffer_object"));
308 
309     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3 &&
310                        (!IsGLExtensionEnabled("GL_EXT_texture_storage") ||
311                         !IsGLExtensionEnabled("GL_OES_rgb8_rgba8")));
312 
313     GLuint texture;
314     glGenTextures(1, &texture);
315     glBindTexture(GL_TEXTURE_2D, texture);
316     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
317     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
318     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
319     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
320 
321     if (getClientMajorVersion() < 3)
322     {
323         glTexStorage2DEXT(GL_TEXTURE_2D, pixel_levels, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
324                           pixel_0_width, pixel_0_height);
325     }
326     else
327     {
328         glTexStorage2D(GL_TEXTURE_2D, pixel_levels, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width,
329                        pixel_0_height);
330     }
331     EXPECT_GL_NO_ERROR();
332 
333     GLuint buffer;
334     glGenBuffers(1, &buffer);
335     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
336     glBufferData(GL_PIXEL_UNPACK_BUFFER, pixel_0_size, nullptr, GL_STREAM_DRAW);
337     EXPECT_GL_NO_ERROR();
338 
339     glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_0_size, pixel_0_data);
340     glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pixel_0_width, pixel_0_height,
341                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_size, nullptr);
342     glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_1_size, pixel_1_data);
343     glCompressedTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, pixel_1_width, pixel_1_height,
344                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_1_size, nullptr);
345     glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_2_size, pixel_2_data);
346     glCompressedTexSubImage2D(GL_TEXTURE_2D, 2, 0, 0, pixel_2_width, pixel_2_height,
347                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_2_size, nullptr);
348     glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_3_size, pixel_3_data);
349     glCompressedTexSubImage2D(GL_TEXTURE_2D, 3, 0, 0, pixel_3_width, pixel_3_height,
350                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_3_size, nullptr);
351     glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_4_size, pixel_4_data);
352     glCompressedTexSubImage2D(GL_TEXTURE_2D, 4, 0, 0, pixel_4_width, pixel_4_height,
353                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_4_size, nullptr);
354     glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_5_size, pixel_5_data);
355     glCompressedTexSubImage2D(GL_TEXTURE_2D, 5, 0, 0, pixel_5_width, pixel_5_height,
356                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_5_size, nullptr);
357     glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_6_size, pixel_6_data);
358     glCompressedTexSubImage2D(GL_TEXTURE_2D, 6, 0, 0, pixel_6_width, pixel_6_height,
359                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_6_size, nullptr);
360     glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_7_size, pixel_7_data);
361     glCompressedTexSubImage2D(GL_TEXTURE_2D, 7, 0, 0, pixel_7_width, pixel_7_height,
362                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_7_size, nullptr);
363     glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_8_size, pixel_8_data);
364     glCompressedTexSubImage2D(GL_TEXTURE_2D, 8, 0, 0, pixel_8_width, pixel_8_height,
365                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_8_size, nullptr);
366     glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_9_size, pixel_9_data);
367     glCompressedTexSubImage2D(GL_TEXTURE_2D, 9, 0, 0, pixel_9_width, pixel_9_height,
368                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_9_size, nullptr);
369 
370     EXPECT_GL_NO_ERROR();
371 
372     glUseProgram(mTextureProgram);
373     glUniform1i(mTextureUniformLocation, 0);
374 
375     drawQuad(mTextureProgram, "position", 0.5f);
376 
377     EXPECT_GL_NO_ERROR();
378 
379     glDeleteTextures(1, &texture);
380 
381     EXPECT_GL_NO_ERROR();
382 }
383 
384 class DXT1CompressedTextureTestES3 : public DXT1CompressedTextureTest
385 {};
386 
TEST_P(DXT1CompressedTextureTestES3,PBOCompressedTexImage)387 TEST_P(DXT1CompressedTextureTestES3, PBOCompressedTexImage)
388 {
389     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
390 
391     GLuint texture;
392     glGenTextures(1, &texture);
393     glBindTexture(GL_TEXTURE_2D, texture);
394     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
395     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
396     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
397     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
398 
399     GLuint buffer;
400     glGenBuffers(1, &buffer);
401     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
402     glBufferData(GL_PIXEL_UNPACK_BUFFER, pixel_0_size, nullptr, GL_STREAM_DRAW);
403     EXPECT_GL_NO_ERROR();
404 
405     glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_0_size, pixel_0_data);
406     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width,
407                            pixel_0_height, 0, pixel_0_size, nullptr);
408     glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_1_size, pixel_1_data);
409     glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_1_width,
410                            pixel_1_height, 0, pixel_1_size, nullptr);
411     glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_2_size, pixel_2_data);
412     glCompressedTexImage2D(GL_TEXTURE_2D, 2, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_2_width,
413                            pixel_2_height, 0, pixel_2_size, nullptr);
414     glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_3_size, pixel_3_data);
415     glCompressedTexImage2D(GL_TEXTURE_2D, 3, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_3_width,
416                            pixel_3_height, 0, pixel_3_size, nullptr);
417     glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_4_size, pixel_4_data);
418     glCompressedTexImage2D(GL_TEXTURE_2D, 4, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_4_width,
419                            pixel_4_height, 0, pixel_4_size, nullptr);
420     glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_5_size, pixel_5_data);
421     glCompressedTexImage2D(GL_TEXTURE_2D, 5, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_5_width,
422                            pixel_5_height, 0, pixel_5_size, nullptr);
423     glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_6_size, pixel_6_data);
424     glCompressedTexImage2D(GL_TEXTURE_2D, 6, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_6_width,
425                            pixel_6_height, 0, pixel_6_size, nullptr);
426     glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_7_size, pixel_7_data);
427     glCompressedTexImage2D(GL_TEXTURE_2D, 7, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_7_width,
428                            pixel_7_height, 0, pixel_7_size, nullptr);
429     glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_8_size, pixel_8_data);
430     glCompressedTexImage2D(GL_TEXTURE_2D, 8, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_8_width,
431                            pixel_8_height, 0, pixel_8_size, nullptr);
432     glBufferSubData(GL_PIXEL_UNPACK_BUFFER, 0, pixel_9_size, pixel_9_data);
433     glCompressedTexImage2D(GL_TEXTURE_2D, 9, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_9_width,
434                            pixel_9_height, 0, pixel_9_size, nullptr);
435 
436     EXPECT_GL_NO_ERROR();
437 
438     glUseProgram(mTextureProgram);
439     glUniform1i(mTextureUniformLocation, 0);
440 
441     drawQuad(mTextureProgram, "position", 0.5f);
442 
443     EXPECT_GL_NO_ERROR();
444 
445     glDeleteTextures(1, &buffer);
446     glDeleteTextures(1, &texture);
447 
448     EXPECT_GL_NO_ERROR();
449 }
450 
451 // Test validation of glCompressedTexSubImage3D with DXT formats
TEST_P(DXT1CompressedTextureTestES3,CompressedTexSubImageValidation)452 TEST_P(DXT1CompressedTextureTestES3, CompressedTexSubImageValidation)
453 {
454     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
455 
456     GLTexture texture;
457     glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
458 
459     // Size mip 0 to a large size
460     glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width,
461                            pixel_0_height, 1, 0, pixel_0_size, nullptr);
462     ASSERT_GL_NO_ERROR();
463 
464     // Set a sub image with a negative offset
465     glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, -1, 0, 0, 4, 4, 1,
466                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 8, pixel_1_data);
467     ASSERT_GL_ERROR(GL_INVALID_VALUE);
468 
469     glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, -1, 0, 4, 4, 1,
470                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 8, pixel_1_data);
471     ASSERT_GL_ERROR(GL_INVALID_VALUE);
472 
473     glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, -1, 4, 4, 1,
474                               GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 8, pixel_1_data);
475     ASSERT_GL_ERROR(GL_INVALID_VALUE);
476 }
477 
478 // Test validation of glCompressedTexSubImage3D with per-slice data uploads
TEST_P(DXT1CompressedTextureTestES3,CompressedTexSubImage3DValidationPerSlice)479 TEST_P(DXT1CompressedTextureTestES3, CompressedTexSubImage3DValidationPerSlice)
480 {
481     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
482 
483     GLTexture texture;
484     glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
485     const GLenum format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
486 
487     // 8x8x2, 4x4x2, 2x2x2, 1x1x2
488     glTexStorage3D(GL_TEXTURE_2D_ARRAY, 4, format, 8, 8, 2);
489     ASSERT_GL_NO_ERROR();
490 
491     uint8_t data[32] = {};
492     glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, 8, 8, 1, format, 32, data);
493     ASSERT_GL_NO_ERROR();
494     glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 1, 8, 8, 1, format, 32, data);
495     ASSERT_GL_NO_ERROR();
496 
497     glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 1, 0, 0, 0, 4, 4, 1, format, 8, data);
498     ASSERT_GL_NO_ERROR();
499     glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 1, 0, 0, 1, 4, 4, 1, format, 8, data);
500     ASSERT_GL_NO_ERROR();
501 
502     glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 2, 0, 0, 0, 2, 2, 1, format, 8, data);
503     ASSERT_GL_NO_ERROR();
504     glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 2, 0, 0, 1, 2, 2, 1, format, 8, data);
505     ASSERT_GL_NO_ERROR();
506 
507     glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 3, 0, 0, 0, 1, 1, 1, format, 8, data);
508     ASSERT_GL_NO_ERROR();
509     glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 3, 0, 0, 1, 1, 1, 1, format, 8, data);
510     ASSERT_GL_NO_ERROR();
511 }
512 
513 // Test validation of glCompressedTexSubImage3D with combined per-level data uploads
TEST_P(DXT1CompressedTextureTestES3,CompressedTexSubImage3DValidationPerLevel)514 TEST_P(DXT1CompressedTextureTestES3, CompressedTexSubImage3DValidationPerLevel)
515 {
516     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
517 
518     GLTexture texture;
519     glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
520     const GLenum format = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
521 
522     // 8x8x2, 4x4x2, 2x2x2, 1x1x2
523     glTexStorage3D(GL_TEXTURE_2D_ARRAY, 4, format, 8, 8, 2);
524     ASSERT_GL_NO_ERROR();
525 
526     uint8_t data[64] = {};
527     glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, 8, 8, 2, format, 64, data);
528     ASSERT_GL_NO_ERROR();
529 
530     glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 1, 0, 0, 0, 4, 4, 2, format, 16, data);
531     ASSERT_GL_NO_ERROR();
532 
533     glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 2, 0, 0, 0, 2, 2, 2, format, 16, data);
534     ASSERT_GL_NO_ERROR();
535 
536     glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 3, 0, 0, 0, 1, 1, 2, format, 16, data);
537     ASSERT_GL_NO_ERROR();
538 }
539 
540 // Test validation of glCompressedTexSubImage3D with DXT formats
TEST_P(DXT1CompressedTextureTestES3,CopyTexSubImage3DDisallowed)541 TEST_P(DXT1CompressedTextureTestES3, CopyTexSubImage3DDisallowed)
542 {
543     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
544 
545     GLTexture texture;
546     glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
547 
548     GLsizei depth = 4;
549     glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, pixel_0_width,
550                            pixel_0_height, depth, 0, pixel_0_size * depth, nullptr);
551     ASSERT_GL_NO_ERROR();
552 
553     glCopyTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, 0, 0, 4, 4);
554     ASSERT_GL_ERROR(GL_INVALID_OPERATION);
555 }
556 
557 class DXT1CompressedTextureTestWebGL2 : public DXT1CompressedTextureTest
558 {
559   protected:
DXT1CompressedTextureTestWebGL2()560     DXT1CompressedTextureTestWebGL2()
561     {
562         setWebGLCompatibilityEnabled(true);
563         setRobustResourceInit(true);
564     }
565 };
566 
567 // Regression test for https://crbug.com/1289428
TEST_P(DXT1CompressedTextureTestWebGL2,InitializeTextureContents)568 TEST_P(DXT1CompressedTextureTestWebGL2, InitializeTextureContents)
569 {
570     ANGLE_SKIP_TEST_IF(!EnsureGLExtensionEnabled("GL_EXT_texture_compression_dxt1"));
571 
572     glUseProgram(mTextureProgram);
573     glUniform1i(mTextureUniformLocation, 0);
574 
575     glClearColor(0, 0, 1, 1);
576 
577     const std::array<uint8_t, 8> kGreen = {0xE0, 0x07, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00};
578 
579     GLTexture tex;
580     glBindTexture(GL_TEXTURE_2D, tex);
581     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
582     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
583     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
584     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
585 
586     glTexStorage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4);
587     EXPECT_GL_NO_ERROR();
588 
589     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
590     drawQuad(mTextureProgram, "position", 0.5f, 1.0f, true);
591     EXPECT_GL_NO_ERROR();
592     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::black);
593 
594     glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 8,
595                               kGreen.data());
596     EXPECT_GL_NO_ERROR();
597 
598     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
599     drawQuad(mTextureProgram, "position", 0.5f, 1.0f, true);
600     EXPECT_GL_NO_ERROR();
601     EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::green);
602 }
603 
604 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(DXT1CompressedTextureTest);
605 
606 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DXT1CompressedTextureTestES3);
607 ANGLE_INSTANTIATE_TEST_ES3_AND(DXT1CompressedTextureTestES3,
608                                ES3_VULKAN().enable(angle::Feature::ForceRobustResourceInit));
609 
610 ANGLE_INSTANTIATE_TEST_ES3(DXT1CompressedTextureTestWebGL2);
611