1 //
2 // Copyright 2016 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 // DXTSRGBCompressedTextureTest.cpp
7 // Tests for sRGB DXT textures (GL_EXT_texture_compression_s3tc_srgb)
8 //
9
10 #include "test_utils/ANGLETest.h"
11 #include "test_utils/gl_raii.h"
12
13 #include "media/pixel.inc"
14
15 #include "DXTSRGBCompressedTextureTestData.inl"
16
17 using namespace angle;
18
19 static constexpr int kWindowSize = 64;
20
21 class DXTSRGBCompressedTextureTest : public ANGLETest
22 {
23 protected:
DXTSRGBCompressedTextureTest()24 DXTSRGBCompressedTextureTest()
25 {
26 setWindowWidth(kWindowSize);
27 setWindowHeight(kWindowSize);
28 setConfigRedBits(8);
29 setConfigGreenBits(8);
30 setConfigBlueBits(8);
31 setConfigAlphaBits(8);
32 }
33
testSetUp()34 void testSetUp() override
35 {
36 constexpr char kVS[] =
37 "precision highp float;\n"
38 "attribute vec4 position;\n"
39 "varying vec2 texcoord;\n"
40 "void main() {\n"
41 " gl_Position = position;\n"
42 " texcoord = (position.xy * 0.5) + 0.5;\n"
43 " texcoord.y = 1.0 - texcoord.y;\n"
44 "}";
45
46 constexpr char kFS[] =
47 "precision highp float;\n"
48 "uniform sampler2D tex;\n"
49 "varying vec2 texcoord;\n"
50 "void main() {\n"
51 " gl_FragColor = texture2D(tex, texcoord);\n"
52 "}\n";
53
54 mTextureProgram = CompileProgram(kVS, kFS);
55 ASSERT_NE(0u, mTextureProgram);
56
57 mTextureUniformLocation = glGetUniformLocation(mTextureProgram, "tex");
58 ASSERT_NE(-1, mTextureUniformLocation);
59
60 ASSERT_GL_NO_ERROR();
61 }
62
testTearDown()63 void testTearDown() override { glDeleteProgram(mTextureProgram); }
64
runTestChecks(const TestCase & test)65 void runTestChecks(const TestCase &test)
66 {
67 GLColor actual[kWindowSize * kWindowSize] = {0};
68 drawQuad(mTextureProgram, "position", 0.5f);
69 ASSERT_GL_NO_ERROR();
70 glReadPixels(0, 0, kWindowSize, kWindowSize, GL_RGBA, GL_UNSIGNED_BYTE,
71 reinterpret_cast<void *>(actual));
72 ASSERT_GL_NO_ERROR();
73 for (GLsizei y = 0; y < test.height; ++y)
74 {
75 for (GLsizei x = 0; x < test.width; ++x)
76 {
77 GLColor exp = reinterpret_cast<const GLColor *>(test.expected)[y * test.width + x];
78 size_t x_actual = (x * kWindowSize + kWindowSize / 2) / test.width;
79 size_t y_actual =
80 ((test.height - y - 1) * kWindowSize + kWindowSize / 2) / test.height;
81 GLColor act = actual[y_actual * kWindowSize + x_actual];
82 EXPECT_COLOR_NEAR(exp, act, 2.0);
83 }
84 }
85 }
86
runTest(GLenum format)87 void runTest(GLenum format)
88 {
89 ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_texture_compression_s3tc_srgb"));
90
91 const TestCase &test = kTests.at(format);
92
93 GLTexture texture;
94 glBindTexture(GL_TEXTURE_2D, texture.get());
95 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
96 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
97 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
98 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
99
100 glUseProgram(mTextureProgram);
101 glUniform1i(mTextureUniformLocation, 0);
102 ASSERT_GL_NO_ERROR();
103
104 glCompressedTexImage2D(GL_TEXTURE_2D, 0, format, test.width, test.height, 0, test.dataSize,
105 test.data);
106 ASSERT_GL_NO_ERROR() << "glCompressedTexImage2D(format=" << format << ")";
107 runTestChecks(test);
108
109 glCompressedTexImage2D(GL_TEXTURE_2D, 0, format, test.width, test.height, 0, test.dataSize,
110 nullptr);
111 ASSERT_GL_NO_ERROR() << "glCompressedTexImage2D(format=" << format << ", data=null)";
112 glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, test.width, test.height, format,
113 test.dataSize, test.data);
114 ASSERT_GL_NO_ERROR() << "glCompressedTexSubImage2D(format=" << format << ")";
115 runTestChecks(test);
116
117 ASSERT_GL_NO_ERROR();
118 }
119
120 GLuint mTextureProgram = 0;
121 GLint mTextureUniformLocation = -1;
122 };
123
124 // Test correct decompression of 8x8 textures (four 4x4 blocks) of SRGB_S3TC_DXT1
TEST_P(DXTSRGBCompressedTextureTest,Decompression8x8RGBDXT1)125 TEST_P(DXTSRGBCompressedTextureTest, Decompression8x8RGBDXT1)
126 {
127 runTest(GL_COMPRESSED_SRGB_S3TC_DXT1_EXT);
128 }
129
130 // Test correct decompression of 8x8 textures (four 4x4 blocks) of SRGB_ALPHA_S3TC_DXT1
TEST_P(DXTSRGBCompressedTextureTest,Decompression8x8RGBADXT1)131 TEST_P(DXTSRGBCompressedTextureTest, Decompression8x8RGBADXT1)
132 {
133 runTest(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT);
134 }
135
136 // Test correct decompression of 8x8 textures (four 4x4 blocks) of SRGB_ALPHA_S3TC_DXT3
TEST_P(DXTSRGBCompressedTextureTest,Decompression8x8RGBADXT3)137 TEST_P(DXTSRGBCompressedTextureTest, Decompression8x8RGBADXT3)
138 {
139 runTest(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT);
140 }
141
142 // Test correct decompression of 8x8 textures (four 4x4 blocks) of SRGB_ALPHA_S3TC_DXT5
TEST_P(DXTSRGBCompressedTextureTest,Decompression8x8RGBADXT5)143 TEST_P(DXTSRGBCompressedTextureTest, Decompression8x8RGBADXT5)
144 {
145 runTest(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT);
146 }
147
148 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
149 // tests should be run against.
150 ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(DXTSRGBCompressedTextureTest);
151