• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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