xref: /aosp_15_r20/external/angle/src/tests/gl_tests/BPTCCompressedTextureTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2018 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 // BPTCCompressedTextureTest.cpp: Tests of the GL_EXT_texture_compression_bptc extension
8 
9 #include "test_utils/ANGLETest.h"
10 #include "test_utils/gl_raii.h"
11 
12 using namespace angle;
13 
14 namespace
15 {
16 
17 const unsigned int kPixelTolerance = 1u;
18 
19 // The pixel data represents a 4x4 pixel image with the left side colored red and the right side
20 // green. It was BC7 encoded using Microsoft's BC6HBC7Encoder.
21 const std::array<GLubyte, 16> kBC7Data4x4 = {0x50, 0x1f, 0xfc, 0xf, 0x0,  0xf0, 0xe3, 0xe1,
22                                              0xe1, 0xe1, 0xc1, 0xf, 0xfc, 0xc0, 0xf,  0xfc};
23 
24 // The pixel data represents a 4x4 pixel image with the transparent black solid color.
25 // Sampling from a zero-filled block is undefined, so use a valid one.
26 const std::array<GLubyte, 16> kBC7BlackData4x4 = {0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
27                                                   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
28 }  // anonymous namespace
29 
30 class BPTCCompressedTextureTest : public ANGLETest<>
31 {
32   protected:
BPTCCompressedTextureTest()33     BPTCCompressedTextureTest()
34     {
35         setWindowWidth(128);
36         setWindowHeight(128);
37         setConfigRedBits(8);
38         setConfigGreenBits(8);
39         setConfigBlueBits(8);
40         setConfigAlphaBits(8);
41     }
42 
testSetUp()43     void testSetUp() override
44     {
45         constexpr char kVS[] = R"(precision highp float;
46 attribute vec4 position;
47 varying vec2 texcoord;
48 
49 void main()
50 {
51     gl_Position = position;
52     texcoord = (position.xy * 0.5) + 0.5;
53     texcoord.y = 1.0 - texcoord.y;
54 })";
55 
56         constexpr char kFS[] = R"(precision highp float;
57 uniform sampler2D tex;
58 varying vec2 texcoord;
59 
60 void main()
61 {
62     gl_FragColor = texture2D(tex, texcoord);
63 })";
64 
65         mTextureProgram = CompileProgram(kVS, kFS);
66         if (mTextureProgram == 0)
67         {
68             FAIL() << "shader compilation failed.";
69         }
70 
71         mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex");
72 
73         ASSERT_GL_NO_ERROR();
74     }
75 
testTearDown()76     void testTearDown() override { glDeleteProgram(mTextureProgram); }
77 
setupTextureParameters(GLuint texture)78     void setupTextureParameters(GLuint texture)
79     {
80         glBindTexture(GL_TEXTURE_2D, texture);
81         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
82         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
83         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
84         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
85     }
86 
drawTexture()87     void drawTexture()
88     {
89         glUseProgram(mTextureProgram);
90         glUniform1i(mTextureUniformLocation, 0);
91         drawQuad(mTextureProgram, "position", 0.5f);
92         EXPECT_GL_NO_ERROR();
93     }
94 
95     GLuint mTextureProgram;
96     GLint mTextureUniformLocation;
97 };
98 
99 class BPTCCompressedTextureTestES3 : public BPTCCompressedTextureTest
100 {
101   public:
BPTCCompressedTextureTestES3()102     BPTCCompressedTextureTestES3() : BPTCCompressedTextureTest() {}
103 };
104 
105 // Test sampling from a BC7 non-SRGB image.
TEST_P(BPTCCompressedTextureTest,CompressedTexImageBC7)106 TEST_P(BPTCCompressedTextureTest, CompressedTexImageBC7)
107 {
108     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));
109 
110     GLTexture texture;
111     setupTextureParameters(texture);
112 
113     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4, 0,
114                            kBC7Data4x4.size(), kBC7Data4x4.data());
115 
116     EXPECT_GL_NO_ERROR();
117 
118     drawTexture();
119 
120     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::red, kPixelTolerance);
121     EXPECT_PIXEL_COLOR_NEAR(0, getWindowHeight() - 1, GLColor::red, kPixelTolerance);
122     EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, 0, GLColor::green, kPixelTolerance);
123     EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green,
124                             kPixelTolerance);
125 }
126 
127 // Test sampling from a BC7 SRGB image.
TEST_P(BPTCCompressedTextureTest,CompressedTexImageBC7SRGB)128 TEST_P(BPTCCompressedTextureTest, CompressedTexImageBC7SRGB)
129 {
130     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));
131 
132     GLTexture texture;
133     setupTextureParameters(texture);
134 
135     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT, 4, 4, 0,
136                            kBC7Data4x4.size(), kBC7Data4x4.data());
137 
138     EXPECT_GL_NO_ERROR();
139 
140     drawTexture();
141 
142     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::red, kPixelTolerance);
143     EXPECT_PIXEL_COLOR_NEAR(0, getWindowHeight() - 1, GLColor::red, kPixelTolerance);
144     EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, 0, GLColor::green, kPixelTolerance);
145     EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green,
146                             kPixelTolerance);
147 }
148 
149 // Test that using the BC6H floating point formats doesn't crash.
TEST_P(BPTCCompressedTextureTest,CompressedTexImageBC6HNoCrash)150 TEST_P(BPTCCompressedTextureTest, CompressedTexImageBC6HNoCrash)
151 {
152     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));
153 
154     GLTexture texture;
155     setupTextureParameters(texture);
156 
157     // This fake pixel data represents a 4x4 pixel image.
158     // TODO(http://anglebug.com/40096529): Add pixel tests for these formats. These need HDR source
159     // images.
160     std::vector<GLubyte> data;
161     data.resize(16u, 0u);
162 
163     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT, 4, 4, 0,
164                            data.size(), data.data());
165     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT, 4, 4, 0,
166                            data.size(), data.data());
167 
168     EXPECT_GL_NO_ERROR();
169 
170     drawTexture();
171 }
172 
173 // Test texStorage2D with a BPTC format.
TEST_P(BPTCCompressedTextureTestES3,CompressedTexStorage)174 TEST_P(BPTCCompressedTextureTestES3, CompressedTexStorage)
175 {
176     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));
177 
178     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
179 
180     GLTexture texture;
181     setupTextureParameters(texture);
182 
183     glTexStorage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4);
184     EXPECT_GL_NO_ERROR();
185     glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT,
186                               kBC7Data4x4.size(), kBC7Data4x4.data());
187     EXPECT_GL_NO_ERROR();
188 
189     drawTexture();
190 
191     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::red, kPixelTolerance);
192     EXPECT_PIXEL_COLOR_NEAR(0, getWindowHeight() - 1, GLColor::red, kPixelTolerance);
193     EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, 0, GLColor::green, kPixelTolerance);
194     EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green,
195                             kPixelTolerance);
196 }
197 
198 // Test validation of glCompressedTexSubImage2D with BPTC formats
TEST_P(BPTCCompressedTextureTest,CompressedTexSubImageValidation)199 TEST_P(BPTCCompressedTextureTest, CompressedTexSubImageValidation)
200 {
201     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));
202 
203     GLTexture texture;
204     glBindTexture(GL_TEXTURE_2D, texture);
205 
206     std::vector<GLubyte> data(16 * 2 * 2);  // 2x2 blocks, thats 8x8 pixels.
207 
208     // Size mip 0 to a large size.
209     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 8, 8, 0,
210                            data.size(), data.data());
211     ASSERT_GL_NO_ERROR();
212 
213     // Test a sub image with an offset that isn't a multiple of the block size.
214     glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 1, 0, 4, 4, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT,
215                               kBC7Data4x4.size(), kBC7Data4x4.data());
216     ASSERT_GL_ERROR(GL_INVALID_OPERATION);
217     glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 3, 4, 4, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT,
218                               kBC7Data4x4.size(), kBC7Data4x4.data());
219     ASSERT_GL_ERROR(GL_INVALID_OPERATION);
220 
221     // Test a sub image with a negative offset.
222     glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, -1, 0, 4, 4, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT,
223                               kBC7Data4x4.size(), kBC7Data4x4.data());
224     ASSERT_GL_ERROR(GL_INVALID_VALUE);
225     glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, -1, 4, 4, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT,
226                               kBC7Data4x4.size(), kBC7Data4x4.data());
227     ASSERT_GL_ERROR(GL_INVALID_VALUE);
228 }
229 
230 // Test that copying BPTC textures is not allowed. This restriction exists only in
231 // EXT_texture_compression_bptc, and not in the ARB variant.
TEST_P(BPTCCompressedTextureTest,CopyTexImage2DDisallowed)232 TEST_P(BPTCCompressedTextureTest, CopyTexImage2DDisallowed)
233 {
234     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));
235 
236     GLTexture texture;
237     setupTextureParameters(texture);
238 
239     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 0, 0, 4, 4, 0);
240     ASSERT_GL_ERROR(GL_INVALID_OPERATION);
241 }
242 
243 // Test that copying BPTC textures is not allowed. This restriction exists only in
244 // EXT_texture_compression_bptc, and not in the ARB variant.
TEST_P(BPTCCompressedTextureTest,CopyTexSubImage2DDisallowed)245 TEST_P(BPTCCompressedTextureTest, CopyTexSubImage2DDisallowed)
246 {
247     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));
248 
249     GLTexture texture;
250     setupTextureParameters(texture);
251 
252     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4, 0,
253                            kBC7Data4x4.size(), kBC7Data4x4.data());
254     ASSERT_GL_NO_ERROR();
255 
256     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 4, 4);
257     ASSERT_GL_ERROR(GL_INVALID_OPERATION);
258 }
259 
260 // Test that copying BPTC textures is not allowed. This restriction exists only in
261 // EXT_texture_compression_bptc, and not in the ARB variant.
TEST_P(BPTCCompressedTextureTestES3,CopyTexSubImage3DDisallowed)262 TEST_P(BPTCCompressedTextureTestES3, CopyTexSubImage3DDisallowed)
263 {
264     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));
265 
266     GLTexture texture;
267     glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
268 
269     glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4, 1);
270     ASSERT_GL_NO_ERROR();
271 
272     glCopyTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, 0, 0, 4, 4);
273     ASSERT_GL_ERROR(GL_INVALID_OPERATION);
274 }
275 
276 // Test uploading texture data from a PBO to a texture.
TEST_P(BPTCCompressedTextureTestES3,PBOCompressedTexImage)277 TEST_P(BPTCCompressedTextureTestES3, PBOCompressedTexImage)
278 {
279     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));
280 
281     GLTexture texture;
282     setupTextureParameters(texture);
283 
284     GLBuffer buffer;
285     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
286     glBufferData(GL_PIXEL_UNPACK_BUFFER, kBC7Data4x4.size(), kBC7Data4x4.data(), GL_STREAM_DRAW);
287     ASSERT_GL_NO_ERROR();
288 
289     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4, 0,
290                            kBC7Data4x4.size(), nullptr);
291     ASSERT_GL_NO_ERROR();
292 
293     drawTexture();
294 
295     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::red, kPixelTolerance);
296     EXPECT_PIXEL_COLOR_NEAR(0, getWindowHeight() - 1, GLColor::red, kPixelTolerance);
297     EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, 0, GLColor::green, kPixelTolerance);
298     EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green,
299                             kPixelTolerance);
300 
301     // Destroy the data
302     glBufferData(GL_PIXEL_UNPACK_BUFFER, kBC7BlackData4x4.size(), kBC7BlackData4x4.data(),
303                  GL_STREAM_DRAW);
304     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4, 0,
305                            kBC7BlackData4x4.size(), nullptr);
306     ASSERT_GL_NO_ERROR();
307 
308     drawTexture();
309     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);
310 
311     // Initialize again.  This time, the texture's image is already allocated, so the PBO data
312     // upload could be directly done.
313     glBufferData(GL_PIXEL_UNPACK_BUFFER, kBC7Data4x4.size(), kBC7Data4x4.data(), GL_STREAM_DRAW);
314     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4, 0,
315                            kBC7Data4x4.size(), nullptr);
316     ASSERT_GL_NO_ERROR();
317 
318     drawTexture();
319 
320     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::red, kPixelTolerance);
321     EXPECT_PIXEL_COLOR_NEAR(0, getWindowHeight() - 1, GLColor::red, kPixelTolerance);
322     EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, 0, GLColor::green, kPixelTolerance);
323     EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green,
324                             kPixelTolerance);
325 }
326 
327 // Test uploading texture data from a PBO to a non-zero base texture.
TEST_P(BPTCCompressedTextureTestES3,PBOCompressedTexImageNonZeroBase)328 TEST_P(BPTCCompressedTextureTestES3, PBOCompressedTexImageNonZeroBase)
329 {
330     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));
331 
332     GLTexture texture;
333     setupTextureParameters(texture);
334 
335     GLBuffer buffer;
336     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
337     glBufferData(GL_PIXEL_UNPACK_BUFFER, kBC7Data4x4.size(), kBC7Data4x4.data(), GL_STREAM_DRAW);
338     ASSERT_GL_NO_ERROR();
339 
340     glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4, 0,
341                            kBC7Data4x4.size(), nullptr);
342     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 1);
343     ASSERT_GL_NO_ERROR();
344 
345     drawTexture();
346 
347     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::red, kPixelTolerance);
348     EXPECT_PIXEL_COLOR_NEAR(0, getWindowHeight() - 1, GLColor::red, kPixelTolerance);
349     EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, 0, GLColor::green, kPixelTolerance);
350     EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green,
351                             kPixelTolerance);
352 
353     // Destroy the data
354     glBufferData(GL_PIXEL_UNPACK_BUFFER, kBC7BlackData4x4.size(), kBC7BlackData4x4.data(),
355                  GL_STREAM_DRAW);
356     glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4, 0,
357                            kBC7BlackData4x4.size(), nullptr);
358     ASSERT_GL_NO_ERROR();
359 
360     drawTexture();
361     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::transparentBlack);
362 
363     // Initialize again.  This time, the texture's image is already allocated, so the PBO data
364     // upload could be directly done.
365     glBufferData(GL_PIXEL_UNPACK_BUFFER, kBC7Data4x4.size(), kBC7Data4x4.data(), GL_STREAM_DRAW);
366     glCompressedTexImage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4, 0,
367                            kBC7Data4x4.size(), nullptr);
368     ASSERT_GL_NO_ERROR();
369 
370     drawTexture();
371 
372     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::red, kPixelTolerance);
373     EXPECT_PIXEL_COLOR_NEAR(0, getWindowHeight() - 1, GLColor::red, kPixelTolerance);
374     EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, 0, GLColor::green, kPixelTolerance);
375     EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green,
376                             kPixelTolerance);
377 }
378 
379 // Test uploading texture data from a PBO to a texture allocated with texStorage2D.
TEST_P(BPTCCompressedTextureTestES3,PBOCompressedTexStorage)380 TEST_P(BPTCCompressedTextureTestES3, PBOCompressedTexStorage)
381 {
382     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));
383 
384     GLTexture texture;
385     setupTextureParameters(texture);
386 
387     glTexStorage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4);
388     ASSERT_GL_NO_ERROR();
389 
390     GLBuffer buffer;
391     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
392     glBufferData(GL_PIXEL_UNPACK_BUFFER, kBC7Data4x4.size(), kBC7Data4x4.data(), GL_STREAM_DRAW);
393     ASSERT_GL_NO_ERROR();
394 
395     glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT,
396                               kBC7Data4x4.size(), nullptr);
397 
398     ASSERT_GL_NO_ERROR();
399 
400     drawTexture();
401 
402     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::red, kPixelTolerance);
403     EXPECT_PIXEL_COLOR_NEAR(0, getWindowHeight() - 1, GLColor::red, kPixelTolerance);
404     EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, 0, GLColor::green, kPixelTolerance);
405     EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green,
406                             kPixelTolerance);
407 }
408 
409 // Test validation of glCompressedTexSubImage3D with BPTC formats
TEST_P(BPTCCompressedTextureTestES3,CompressedTexSubImage3DValidation)410 TEST_P(BPTCCompressedTextureTestES3, CompressedTexSubImage3DValidation)
411 {
412     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));
413 
414     GLTexture texture;
415     glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
416 
417     std::vector<GLubyte> data(16 * 2 * 2);  // 2x2x1 blocks, thats 8x8x1 pixels.
418 
419     // Size mip 0 to a large size.
420     glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 8, 8, 1, 0,
421                            data.size(), data.data());
422     ASSERT_GL_NO_ERROR();
423 
424     // Test a sub image with an offset that isn't a multiple of the block size.
425     glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 2, 0, 0, 4, 4, 1,
426                               GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, kBC7Data4x4.size(),
427                               kBC7Data4x4.data());
428     ASSERT_GL_ERROR(GL_INVALID_OPERATION);
429     glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 2, 0, 4, 4, 1,
430                               GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, kBC7Data4x4.size(),
431                               kBC7Data4x4.data());
432     ASSERT_GL_ERROR(GL_INVALID_OPERATION);
433 
434     // Test a sub image with a negative offset.
435     glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, -1, 0, 0, 4, 4, 1,
436                               GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, kBC7Data4x4.size(),
437                               kBC7Data4x4.data());
438     ASSERT_GL_ERROR(GL_INVALID_VALUE);
439     glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, -1, 0, 4, 4, 1,
440                               GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, kBC7Data4x4.size(),
441                               kBC7Data4x4.data());
442     ASSERT_GL_ERROR(GL_INVALID_VALUE);
443     glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, -1, 4, 4, 1,
444                               GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, kBC7Data4x4.size(),
445                               kBC7Data4x4.data());
446     ASSERT_GL_ERROR(GL_INVALID_VALUE);
447 }
448 
449 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
450 // tests should be run against.
451 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(BPTCCompressedTextureTest);
452 
453 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(BPTCCompressedTextureTestES3);
454 ANGLE_INSTANTIATE_TEST_ES3(BPTCCompressedTextureTestES3);
455