• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }  // anonymous namespace
25 
26 class BPTCCompressedTextureTest : public ANGLETest
27 {
28   protected:
BPTCCompressedTextureTest()29     BPTCCompressedTextureTest()
30     {
31         setWindowWidth(128);
32         setWindowHeight(128);
33         setConfigRedBits(8);
34         setConfigGreenBits(8);
35         setConfigBlueBits(8);
36         setConfigAlphaBits(8);
37     }
38 
testSetUp()39     void testSetUp() override
40     {
41         constexpr char kVS[] = R"(precision highp float;
42 attribute vec4 position;
43 varying vec2 texcoord;
44 
45 void main()
46 {
47     gl_Position = position;
48     texcoord = (position.xy * 0.5) + 0.5;
49     texcoord.y = 1.0 - texcoord.y;
50 })";
51 
52         constexpr char kFS[] = R"(precision highp float;
53 uniform sampler2D tex;
54 varying vec2 texcoord;
55 
56 void main()
57 {
58     gl_FragColor = texture2D(tex, texcoord);
59 })";
60 
61         mTextureProgram = CompileProgram(kVS, kFS);
62         if (mTextureProgram == 0)
63         {
64             FAIL() << "shader compilation failed.";
65         }
66 
67         mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex");
68 
69         ASSERT_GL_NO_ERROR();
70     }
71 
testTearDown()72     void testTearDown() override { glDeleteProgram(mTextureProgram); }
73 
setupTextureParameters(GLuint texture)74     void setupTextureParameters(GLuint texture)
75     {
76         glBindTexture(GL_TEXTURE_2D, texture);
77         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
78         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
79         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
80         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
81     }
82 
drawTexture()83     void drawTexture()
84     {
85         glUseProgram(mTextureProgram);
86         glUniform1i(mTextureUniformLocation, 0);
87         drawQuad(mTextureProgram, "position", 0.5f);
88         EXPECT_GL_NO_ERROR();
89     }
90 
91     GLuint mTextureProgram;
92     GLint mTextureUniformLocation;
93 };
94 
95 class BPTCCompressedTextureTestES3 : public BPTCCompressedTextureTest
96 {
97   public:
BPTCCompressedTextureTestES3()98     BPTCCompressedTextureTestES3() : BPTCCompressedTextureTest() {}
99 };
100 
101 // Test sampling from a BC7 non-SRGB image.
TEST_P(BPTCCompressedTextureTest,CompressedTexImageBC7)102 TEST_P(BPTCCompressedTextureTest, CompressedTexImageBC7)
103 {
104     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));
105 
106     GLTexture texture;
107     setupTextureParameters(texture);
108 
109     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4, 0,
110                            kBC7Data4x4.size(), kBC7Data4x4.data());
111 
112     EXPECT_GL_NO_ERROR();
113 
114     drawTexture();
115 
116     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::red, kPixelTolerance);
117     EXPECT_PIXEL_COLOR_NEAR(0, getWindowHeight() - 1, GLColor::red, kPixelTolerance);
118     EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, 0, GLColor::green, kPixelTolerance);
119     EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green,
120                             kPixelTolerance);
121 }
122 
123 // Test sampling from a BC7 SRGB image.
TEST_P(BPTCCompressedTextureTest,CompressedTexImageBC7SRGB)124 TEST_P(BPTCCompressedTextureTest, CompressedTexImageBC7SRGB)
125 {
126     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));
127 
128     GLTexture texture;
129     setupTextureParameters(texture);
130 
131     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT, 4, 4, 0,
132                            kBC7Data4x4.size(), kBC7Data4x4.data());
133 
134     EXPECT_GL_NO_ERROR();
135 
136     drawTexture();
137 
138     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::red, kPixelTolerance);
139     EXPECT_PIXEL_COLOR_NEAR(0, getWindowHeight() - 1, GLColor::red, kPixelTolerance);
140     EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, 0, GLColor::green, kPixelTolerance);
141     EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green,
142                             kPixelTolerance);
143 }
144 
145 // Test that using the BC6H floating point formats doesn't crash.
TEST_P(BPTCCompressedTextureTest,CompressedTexImageBC6HNoCrash)146 TEST_P(BPTCCompressedTextureTest, CompressedTexImageBC6HNoCrash)
147 {
148     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));
149 
150     GLTexture texture;
151     setupTextureParameters(texture);
152 
153     // This dummy pixel data represents a 4x4 pixel image.
154     // TODO(http://anglebug.com/2869): Add pixel tests for these formats. These need HDR source
155     // images.
156     std::vector<GLubyte> data;
157     data.resize(16u, 0u);
158 
159     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT, 4, 4, 0,
160                            data.size(), data.data());
161     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT, 4, 4, 0,
162                            data.size(), data.data());
163 
164     EXPECT_GL_NO_ERROR();
165 
166     drawTexture();
167 }
168 
169 // Test texStorage2D with a BPTC format.
TEST_P(BPTCCompressedTextureTestES3,CompressedTexStorage)170 TEST_P(BPTCCompressedTextureTestES3, CompressedTexStorage)
171 {
172     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));
173 
174     ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
175 
176     GLTexture texture;
177     setupTextureParameters(texture);
178 
179     glTexStorage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4);
180     EXPECT_GL_NO_ERROR();
181     glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT,
182                               kBC7Data4x4.size(), kBC7Data4x4.data());
183     EXPECT_GL_NO_ERROR();
184 
185     drawTexture();
186 
187     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::red, kPixelTolerance);
188     EXPECT_PIXEL_COLOR_NEAR(0, getWindowHeight() - 1, GLColor::red, kPixelTolerance);
189     EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, 0, GLColor::green, kPixelTolerance);
190     EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green,
191                             kPixelTolerance);
192 }
193 
194 // Test validation of glCompressedTexSubImage2D with BPTC formats
TEST_P(BPTCCompressedTextureTest,CompressedTexSubImageValidation)195 TEST_P(BPTCCompressedTextureTest, CompressedTexSubImageValidation)
196 {
197     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));
198 
199     GLTexture texture;
200     glBindTexture(GL_TEXTURE_2D, texture);
201 
202     std::vector<GLubyte> data(16 * 2 * 2);  // 2x2 blocks, thats 8x8 pixels.
203 
204     // Size mip 0 to a large size.
205     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 8, 8, 0,
206                            data.size(), data.data());
207     ASSERT_GL_NO_ERROR();
208 
209     // Test a sub image with an offset that isn't a multiple of the block size.
210     glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 1, 0, 4, 4, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT,
211                               kBC7Data4x4.size(), kBC7Data4x4.data());
212     ASSERT_GL_ERROR(GL_INVALID_OPERATION);
213     glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 3, 4, 4, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT,
214                               kBC7Data4x4.size(), kBC7Data4x4.data());
215     ASSERT_GL_ERROR(GL_INVALID_OPERATION);
216 
217     // Test a sub image with a negative offset.
218     glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, -1, 0, 4, 4, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT,
219                               kBC7Data4x4.size(), kBC7Data4x4.data());
220     ASSERT_GL_ERROR(GL_INVALID_VALUE);
221     glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, -1, 4, 4, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT,
222                               kBC7Data4x4.size(), kBC7Data4x4.data());
223     ASSERT_GL_ERROR(GL_INVALID_VALUE);
224 }
225 
226 // Test that copying BPTC textures is not allowed. This restriction exists only in
227 // EXT_texture_compression_bptc, and not in the ARB variant.
TEST_P(BPTCCompressedTextureTest,CopyTexImage2DDisallowed)228 TEST_P(BPTCCompressedTextureTest, CopyTexImage2DDisallowed)
229 {
230     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));
231 
232     GLTexture texture;
233     setupTextureParameters(texture);
234 
235     glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 0, 0, 4, 4, 0);
236     ASSERT_GL_ERROR(GL_INVALID_OPERATION);
237 }
238 
239 // Test that copying BPTC textures is not allowed. This restriction exists only in
240 // EXT_texture_compression_bptc, and not in the ARB variant.
TEST_P(BPTCCompressedTextureTest,CopyTexSubImage2DDisallowed)241 TEST_P(BPTCCompressedTextureTest, CopyTexSubImage2DDisallowed)
242 {
243     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));
244 
245     GLTexture texture;
246     setupTextureParameters(texture);
247 
248     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4, 0,
249                            kBC7Data4x4.size(), kBC7Data4x4.data());
250     ASSERT_GL_NO_ERROR();
251 
252     glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, 4, 4);
253     ASSERT_GL_ERROR(GL_INVALID_OPERATION);
254 }
255 
256 // Test that copying BPTC textures is not allowed. This restriction exists only in
257 // EXT_texture_compression_bptc, and not in the ARB variant.
TEST_P(BPTCCompressedTextureTestES3,CopyTexSubImage3DDisallowed)258 TEST_P(BPTCCompressedTextureTestES3, CopyTexSubImage3DDisallowed)
259 {
260     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));
261 
262     GLTexture texture;
263     glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
264 
265     glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4, 1);
266     ASSERT_GL_NO_ERROR();
267 
268     glCopyTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, 0, 0, 4, 4);
269     ASSERT_GL_ERROR(GL_INVALID_OPERATION);
270 }
271 
272 // Test uploading texture data from a PBO to a texture.
TEST_P(BPTCCompressedTextureTestES3,PBOCompressedTexImage)273 TEST_P(BPTCCompressedTextureTestES3, PBOCompressedTexImage)
274 {
275     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));
276 
277     GLTexture texture;
278     setupTextureParameters(texture);
279 
280     GLBuffer buffer;
281     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
282     glBufferData(GL_PIXEL_UNPACK_BUFFER, kBC7Data4x4.size(), kBC7Data4x4.data(), GL_STREAM_DRAW);
283     ASSERT_GL_NO_ERROR();
284 
285     glCompressedTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4, 0,
286                            kBC7Data4x4.size(), nullptr);
287     ASSERT_GL_NO_ERROR();
288 
289     drawTexture();
290 
291     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::red, kPixelTolerance);
292     EXPECT_PIXEL_COLOR_NEAR(0, getWindowHeight() - 1, GLColor::red, kPixelTolerance);
293     EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, 0, GLColor::green, kPixelTolerance);
294     EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green,
295                             kPixelTolerance);
296 }
297 
298 // Test uploading texture data from a PBO to a texture allocated with texStorage2D.
TEST_P(BPTCCompressedTextureTestES3,PBOCompressedTexStorage)299 TEST_P(BPTCCompressedTextureTestES3, PBOCompressedTexStorage)
300 {
301     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));
302 
303     GLTexture texture;
304     setupTextureParameters(texture);
305 
306     glTexStorage2D(GL_TEXTURE_2D, 1, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 4, 4);
307     ASSERT_GL_NO_ERROR();
308 
309     GLBuffer buffer;
310     glBindBuffer(GL_PIXEL_UNPACK_BUFFER, buffer);
311     glBufferData(GL_PIXEL_UNPACK_BUFFER, kBC7Data4x4.size(), kBC7Data4x4.data(), GL_STREAM_DRAW);
312     ASSERT_GL_NO_ERROR();
313 
314     glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 4, 4, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT,
315                               kBC7Data4x4.size(), nullptr);
316 
317     ASSERT_GL_NO_ERROR();
318 
319     drawTexture();
320 
321     EXPECT_PIXEL_COLOR_NEAR(0, 0, GLColor::red, kPixelTolerance);
322     EXPECT_PIXEL_COLOR_NEAR(0, getWindowHeight() - 1, GLColor::red, kPixelTolerance);
323     EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, 0, GLColor::green, kPixelTolerance);
324     EXPECT_PIXEL_COLOR_NEAR(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green,
325                             kPixelTolerance);
326 }
327 
328 // Test validation of glCompressedTexSubImage3D with BPTC formats
TEST_P(BPTCCompressedTextureTestES3,CompressedTexSubImage3DValidation)329 TEST_P(BPTCCompressedTextureTestES3, CompressedTexSubImage3DValidation)
330 {
331     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));
332 
333     GLTexture texture;
334     glBindTexture(GL_TEXTURE_2D_ARRAY, texture.get());
335 
336     std::vector<GLubyte> data(16 * 2 * 2);  // 2x2x1 blocks, thats 8x8x1 pixels.
337 
338     // Size mip 0 to a large size.
339     glCompressedTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, 8, 8, 1, 0,
340                            data.size(), data.data());
341     ASSERT_GL_NO_ERROR();
342 
343     // Test a sub image with an offset that isn't a multiple of the block size.
344     glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 2, 0, 0, 4, 4, 1,
345                               GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, kBC7Data4x4.size(),
346                               kBC7Data4x4.data());
347     ASSERT_GL_ERROR(GL_INVALID_OPERATION);
348     glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 2, 0, 4, 4, 1,
349                               GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, kBC7Data4x4.size(),
350                               kBC7Data4x4.data());
351     ASSERT_GL_ERROR(GL_INVALID_OPERATION);
352 
353     // Test a sub image with a negative offset.
354     glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, -1, 0, 0, 4, 4, 1,
355                               GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, kBC7Data4x4.size(),
356                               kBC7Data4x4.data());
357     ASSERT_GL_ERROR(GL_INVALID_VALUE);
358     glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, -1, 0, 4, 4, 1,
359                               GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, kBC7Data4x4.size(),
360                               kBC7Data4x4.data());
361     ASSERT_GL_ERROR(GL_INVALID_VALUE);
362     glCompressedTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, -1, 4, 4, 1,
363                               GL_COMPRESSED_RGBA_BPTC_UNORM_EXT, kBC7Data4x4.size(),
364                               kBC7Data4x4.data());
365     ASSERT_GL_ERROR(GL_INVALID_VALUE);
366 }
367 
368 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
369 // tests should be run against.
370 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(BPTCCompressedTextureTest);
371 
372 ANGLE_INSTANTIATE_TEST_ES3(BPTCCompressedTextureTestES3);
373