xref: /aosp_15_r20/external/angle/src/tests/gl_tests/PackUnpackTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // PackUnpackTest:
7*8975f5c5SAndroid Build Coastguard Worker //   Tests the corrrectness of opengl 4.1 emulation of pack/unpack built-in functions.
8*8975f5c5SAndroid Build Coastguard Worker //
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.h"
11*8975f5c5SAndroid Build Coastguard Worker 
12*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
13*8975f5c5SAndroid Build Coastguard Worker 
14*8975f5c5SAndroid Build Coastguard Worker namespace
15*8975f5c5SAndroid Build Coastguard Worker {
16*8975f5c5SAndroid Build Coastguard Worker 
17*8975f5c5SAndroid Build Coastguard Worker class PackUnpackTest : public ANGLETest<>
18*8975f5c5SAndroid Build Coastguard Worker {
19*8975f5c5SAndroid Build Coastguard Worker   protected:
PackUnpackTest()20*8975f5c5SAndroid Build Coastguard Worker     PackUnpackTest()
21*8975f5c5SAndroid Build Coastguard Worker     {
22*8975f5c5SAndroid Build Coastguard Worker         setWindowWidth(16);
23*8975f5c5SAndroid Build Coastguard Worker         setWindowHeight(16);
24*8975f5c5SAndroid Build Coastguard Worker         setConfigRedBits(8);
25*8975f5c5SAndroid Build Coastguard Worker         setConfigGreenBits(8);
26*8975f5c5SAndroid Build Coastguard Worker         setConfigBlueBits(8);
27*8975f5c5SAndroid Build Coastguard Worker         setConfigAlphaBits(8);
28*8975f5c5SAndroid Build Coastguard Worker     }
29*8975f5c5SAndroid Build Coastguard Worker 
testSetUp()30*8975f5c5SAndroid Build Coastguard Worker     void testSetUp() override
31*8975f5c5SAndroid Build Coastguard Worker     {
32*8975f5c5SAndroid Build Coastguard Worker         // Fragment Shader source
33*8975f5c5SAndroid Build Coastguard Worker         constexpr char kSNormFS[] = R"(#version 300 es
34*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
35*8975f5c5SAndroid Build Coastguard Worker uniform mediump vec2 v;
36*8975f5c5SAndroid Build Coastguard Worker layout(location = 0) out mediump vec4 fragColor;
37*8975f5c5SAndroid Build Coastguard Worker 
38*8975f5c5SAndroid Build Coastguard Worker void main()
39*8975f5c5SAndroid Build Coastguard Worker {
40*8975f5c5SAndroid Build Coastguard Worker     highp uint u = packSnorm2x16(v);
41*8975f5c5SAndroid Build Coastguard Worker     vec2 r = unpackSnorm2x16(u);
42*8975f5c5SAndroid Build Coastguard Worker     fragColor = vec4(r, 0.0, 1.0);
43*8975f5c5SAndroid Build Coastguard Worker })";
44*8975f5c5SAndroid Build Coastguard Worker 
45*8975f5c5SAndroid Build Coastguard Worker         // Fragment Shader source
46*8975f5c5SAndroid Build Coastguard Worker         constexpr char kUNormFS[] = R"(#version 300 es
47*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
48*8975f5c5SAndroid Build Coastguard Worker uniform mediump vec2 v;
49*8975f5c5SAndroid Build Coastguard Worker layout(location = 0) out mediump vec4 fragColor;
50*8975f5c5SAndroid Build Coastguard Worker 
51*8975f5c5SAndroid Build Coastguard Worker void main()
52*8975f5c5SAndroid Build Coastguard Worker {
53*8975f5c5SAndroid Build Coastguard Worker     highp uint u = packUnorm2x16(v);
54*8975f5c5SAndroid Build Coastguard Worker     vec2 r = unpackUnorm2x16(u);
55*8975f5c5SAndroid Build Coastguard Worker     fragColor = vec4(r, 0.0, 1.0);
56*8975f5c5SAndroid Build Coastguard Worker })";
57*8975f5c5SAndroid Build Coastguard Worker 
58*8975f5c5SAndroid Build Coastguard Worker         // Fragment Shader source
59*8975f5c5SAndroid Build Coastguard Worker         constexpr char kHalfFS[] = R"(#version 300 es
60*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
61*8975f5c5SAndroid Build Coastguard Worker uniform mediump vec2 v;
62*8975f5c5SAndroid Build Coastguard Worker layout(location = 0) out mediump vec4 fragColor;
63*8975f5c5SAndroid Build Coastguard Worker 
64*8975f5c5SAndroid Build Coastguard Worker void main()
65*8975f5c5SAndroid Build Coastguard Worker {
66*8975f5c5SAndroid Build Coastguard Worker     highp uint u = packHalf2x16(v);
67*8975f5c5SAndroid Build Coastguard Worker     vec2 r = unpackHalf2x16(u);
68*8975f5c5SAndroid Build Coastguard Worker     fragColor = vec4(r, 0.0, 1.0);
69*8975f5c5SAndroid Build Coastguard Worker })";
70*8975f5c5SAndroid Build Coastguard Worker 
71*8975f5c5SAndroid Build Coastguard Worker         mSNormProgram = CompileProgram(essl3_shaders::vs::Simple(), kSNormFS);
72*8975f5c5SAndroid Build Coastguard Worker         mUNormProgram = CompileProgram(essl3_shaders::vs::Simple(), kUNormFS);
73*8975f5c5SAndroid Build Coastguard Worker         mHalfProgram  = CompileProgram(essl3_shaders::vs::Simple(), kHalfFS);
74*8975f5c5SAndroid Build Coastguard Worker         if (mSNormProgram == 0 || mUNormProgram == 0 || mHalfProgram == 0)
75*8975f5c5SAndroid Build Coastguard Worker         {
76*8975f5c5SAndroid Build Coastguard Worker             FAIL() << "shader compilation failed.";
77*8975f5c5SAndroid Build Coastguard Worker         }
78*8975f5c5SAndroid Build Coastguard Worker 
79*8975f5c5SAndroid Build Coastguard Worker         glGenTextures(1, &mOffscreenTexture2D);
80*8975f5c5SAndroid Build Coastguard Worker         glBindTexture(GL_TEXTURE_2D, mOffscreenTexture2D);
81*8975f5c5SAndroid Build Coastguard Worker         glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, getWindowWidth(), getWindowHeight());
82*8975f5c5SAndroid Build Coastguard Worker 
83*8975f5c5SAndroid Build Coastguard Worker         glGenFramebuffers(1, &mOffscreenFramebuffer);
84*8975f5c5SAndroid Build Coastguard Worker         glBindFramebuffer(GL_FRAMEBUFFER, mOffscreenFramebuffer);
85*8975f5c5SAndroid Build Coastguard Worker         glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
86*8975f5c5SAndroid Build Coastguard Worker                                mOffscreenTexture2D, 0);
87*8975f5c5SAndroid Build Coastguard Worker 
88*8975f5c5SAndroid Build Coastguard Worker         glViewport(0, 0, 16, 16);
89*8975f5c5SAndroid Build Coastguard Worker 
90*8975f5c5SAndroid Build Coastguard Worker         const GLfloat color[] = {1.0f, 1.0f, 0.0f, 1.0f};
91*8975f5c5SAndroid Build Coastguard Worker         glClearBufferfv(GL_COLOR, 0, color);
92*8975f5c5SAndroid Build Coastguard Worker     }
93*8975f5c5SAndroid Build Coastguard Worker 
testTearDown()94*8975f5c5SAndroid Build Coastguard Worker     void testTearDown() override
95*8975f5c5SAndroid Build Coastguard Worker     {
96*8975f5c5SAndroid Build Coastguard Worker         glDeleteTextures(1, &mOffscreenTexture2D);
97*8975f5c5SAndroid Build Coastguard Worker         glDeleteFramebuffers(1, &mOffscreenFramebuffer);
98*8975f5c5SAndroid Build Coastguard Worker         glDeleteProgram(mSNormProgram);
99*8975f5c5SAndroid Build Coastguard Worker         glDeleteProgram(mUNormProgram);
100*8975f5c5SAndroid Build Coastguard Worker         glDeleteProgram(mHalfProgram);
101*8975f5c5SAndroid Build Coastguard Worker     }
102*8975f5c5SAndroid Build Coastguard Worker 
compareBeforeAfter(GLuint program,float input1,float input2)103*8975f5c5SAndroid Build Coastguard Worker     void compareBeforeAfter(GLuint program, float input1, float input2)
104*8975f5c5SAndroid Build Coastguard Worker     {
105*8975f5c5SAndroid Build Coastguard Worker         compareBeforeAfter(program, input1, input2, input1, input2);
106*8975f5c5SAndroid Build Coastguard Worker     }
107*8975f5c5SAndroid Build Coastguard Worker 
compareBeforeAfter(GLuint program,float input1,float input2,float expect1,float expect2)108*8975f5c5SAndroid Build Coastguard Worker     void compareBeforeAfter(GLuint program,
109*8975f5c5SAndroid Build Coastguard Worker                             float input1,
110*8975f5c5SAndroid Build Coastguard Worker                             float input2,
111*8975f5c5SAndroid Build Coastguard Worker                             float expect1,
112*8975f5c5SAndroid Build Coastguard Worker                             float expect2)
113*8975f5c5SAndroid Build Coastguard Worker     {
114*8975f5c5SAndroid Build Coastguard Worker         GLint vec2Location = glGetUniformLocation(program, "v");
115*8975f5c5SAndroid Build Coastguard Worker 
116*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(program);
117*8975f5c5SAndroid Build Coastguard Worker         glUniform2f(vec2Location, input1, input2);
118*8975f5c5SAndroid Build Coastguard Worker 
119*8975f5c5SAndroid Build Coastguard Worker         drawQuad(program, essl3_shaders::PositionAttrib(), 0.5f);
120*8975f5c5SAndroid Build Coastguard Worker 
121*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
122*8975f5c5SAndroid Build Coastguard Worker 
123*8975f5c5SAndroid Build Coastguard Worker         GLfloat p[2] = {0};
124*8975f5c5SAndroid Build Coastguard Worker         glReadPixels(8, 8, 1, 1, GL_RG, GL_FLOAT, p);
125*8975f5c5SAndroid Build Coastguard Worker 
126*8975f5c5SAndroid Build Coastguard Worker         ASSERT_GL_NO_ERROR();
127*8975f5c5SAndroid Build Coastguard Worker 
128*8975f5c5SAndroid Build Coastguard Worker         static const double epsilon = 0.0005;
129*8975f5c5SAndroid Build Coastguard Worker         EXPECT_NEAR(p[0], expect1, epsilon);
130*8975f5c5SAndroid Build Coastguard Worker         EXPECT_NEAR(p[1], expect2, epsilon);
131*8975f5c5SAndroid Build Coastguard Worker     }
132*8975f5c5SAndroid Build Coastguard Worker 
133*8975f5c5SAndroid Build Coastguard Worker     GLuint mSNormProgram;
134*8975f5c5SAndroid Build Coastguard Worker     GLuint mUNormProgram;
135*8975f5c5SAndroid Build Coastguard Worker     GLuint mHalfProgram;
136*8975f5c5SAndroid Build Coastguard Worker     GLuint mOffscreenFramebuffer;
137*8975f5c5SAndroid Build Coastguard Worker     GLuint mOffscreenTexture2D;
138*8975f5c5SAndroid Build Coastguard Worker };
139*8975f5c5SAndroid Build Coastguard Worker 
140*8975f5c5SAndroid Build Coastguard Worker // Test the correctness of packSnorm2x16 and unpackSnorm2x16 functions calculating normal floating
141*8975f5c5SAndroid Build Coastguard Worker // numbers.
TEST_P(PackUnpackTest,PackUnpackSnormNormal)142*8975f5c5SAndroid Build Coastguard Worker TEST_P(PackUnpackTest, PackUnpackSnormNormal)
143*8975f5c5SAndroid Build Coastguard Worker {
144*8975f5c5SAndroid Build Coastguard Worker     // Expect the shader to output the same value as the input
145*8975f5c5SAndroid Build Coastguard Worker     compareBeforeAfter(mSNormProgram, 0.5f, -0.2f);
146*8975f5c5SAndroid Build Coastguard Worker     compareBeforeAfter(mSNormProgram, -0.35f, 0.75f);
147*8975f5c5SAndroid Build Coastguard Worker     compareBeforeAfter(mSNormProgram, 0.00392f, -0.99215f);
148*8975f5c5SAndroid Build Coastguard Worker     compareBeforeAfter(mSNormProgram, 1.0f, -0.00392f);
149*8975f5c5SAndroid Build Coastguard Worker }
150*8975f5c5SAndroid Build Coastguard Worker 
151*8975f5c5SAndroid Build Coastguard Worker // Test the correctness of packSnorm2x16 and unpackSnorm2x16 functions calculating normal floating
152*8975f5c5SAndroid Build Coastguard Worker // numbers.
TEST_P(PackUnpackTest,PackUnpackUnormNormal)153*8975f5c5SAndroid Build Coastguard Worker TEST_P(PackUnpackTest, PackUnpackUnormNormal)
154*8975f5c5SAndroid Build Coastguard Worker {
155*8975f5c5SAndroid Build Coastguard Worker     // Expect the shader to output the same value as the input
156*8975f5c5SAndroid Build Coastguard Worker     compareBeforeAfter(mUNormProgram, 0.5f, 0.2f, 0.5f, 0.2f);
157*8975f5c5SAndroid Build Coastguard Worker     compareBeforeAfter(mUNormProgram, 0.35f, 0.75f, 0.35f, 0.75f);
158*8975f5c5SAndroid Build Coastguard Worker     compareBeforeAfter(mUNormProgram, 0.00392f, 0.99215f, 0.00392f, 0.99215f);
159*8975f5c5SAndroid Build Coastguard Worker     compareBeforeAfter(mUNormProgram, 1.0f, 0.00392f, 1.0f, 0.00392f);
160*8975f5c5SAndroid Build Coastguard Worker }
161*8975f5c5SAndroid Build Coastguard Worker 
162*8975f5c5SAndroid Build Coastguard Worker // Test the correctness of packHalf2x16 and unpackHalf2x16 functions calculating normal floating
163*8975f5c5SAndroid Build Coastguard Worker // numbers.
TEST_P(PackUnpackTest,PackUnpackHalfNormal)164*8975f5c5SAndroid Build Coastguard Worker TEST_P(PackUnpackTest, PackUnpackHalfNormal)
165*8975f5c5SAndroid Build Coastguard Worker {
166*8975f5c5SAndroid Build Coastguard Worker     // Expect the shader to output the same value as the input
167*8975f5c5SAndroid Build Coastguard Worker     compareBeforeAfter(mHalfProgram, 0.5f, -0.2f);
168*8975f5c5SAndroid Build Coastguard Worker     compareBeforeAfter(mHalfProgram, -0.35f, 0.75f);
169*8975f5c5SAndroid Build Coastguard Worker     compareBeforeAfter(mHalfProgram, 0.00392f, -0.99215f);
170*8975f5c5SAndroid Build Coastguard Worker     compareBeforeAfter(mHalfProgram, 1.0f, -0.00392f);
171*8975f5c5SAndroid Build Coastguard Worker }
172*8975f5c5SAndroid Build Coastguard Worker 
173*8975f5c5SAndroid Build Coastguard Worker // Test the correctness of packSnorm2x16 and unpackSnorm2x16 functions calculating subnormal
174*8975f5c5SAndroid Build Coastguard Worker // floating numbers.
TEST_P(PackUnpackTest,PackUnpackSnormSubnormal)175*8975f5c5SAndroid Build Coastguard Worker TEST_P(PackUnpackTest, PackUnpackSnormSubnormal)
176*8975f5c5SAndroid Build Coastguard Worker {
177*8975f5c5SAndroid Build Coastguard Worker     // Expect the shader to output the same value as the input
178*8975f5c5SAndroid Build Coastguard Worker     compareBeforeAfter(mSNormProgram, 0.00001f, -0.00001f);
179*8975f5c5SAndroid Build Coastguard Worker }
180*8975f5c5SAndroid Build Coastguard Worker 
181*8975f5c5SAndroid Build Coastguard Worker // Test the correctness of packUnorm2x16 and unpackUnorm2x16 functions calculating subnormal
182*8975f5c5SAndroid Build Coastguard Worker // floating numbers.
TEST_P(PackUnpackTest,PackUnpackUnormSubnormal)183*8975f5c5SAndroid Build Coastguard Worker TEST_P(PackUnpackTest, PackUnpackUnormSubnormal)
184*8975f5c5SAndroid Build Coastguard Worker {
185*8975f5c5SAndroid Build Coastguard Worker     // Expect the shader to output the same value as the input for positive numbers and clamp
186*8975f5c5SAndroid Build Coastguard Worker     // to [0, 1]
187*8975f5c5SAndroid Build Coastguard Worker     compareBeforeAfter(mUNormProgram, 0.00001f, -0.00001f, 0.00001f, 0.0f);
188*8975f5c5SAndroid Build Coastguard Worker }
189*8975f5c5SAndroid Build Coastguard Worker 
190*8975f5c5SAndroid Build Coastguard Worker // Test the correctness of packHalf2x16 and unpackHalf2x16 functions calculating subnormal floating
191*8975f5c5SAndroid Build Coastguard Worker // numbers.
TEST_P(PackUnpackTest,PackUnpackHalfSubnormal)192*8975f5c5SAndroid Build Coastguard Worker TEST_P(PackUnpackTest, PackUnpackHalfSubnormal)
193*8975f5c5SAndroid Build Coastguard Worker {
194*8975f5c5SAndroid Build Coastguard Worker     // Expect the shader to output the same value as the input
195*8975f5c5SAndroid Build Coastguard Worker     compareBeforeAfter(mHalfProgram, 0.00001f, -0.00001f);
196*8975f5c5SAndroid Build Coastguard Worker }
197*8975f5c5SAndroid Build Coastguard Worker 
198*8975f5c5SAndroid Build Coastguard Worker // Test the correctness of packSnorm2x16 and unpackSnorm2x16 functions calculating zero floating
199*8975f5c5SAndroid Build Coastguard Worker // numbers.
TEST_P(PackUnpackTest,PackUnpackSnormZero)200*8975f5c5SAndroid Build Coastguard Worker TEST_P(PackUnpackTest, PackUnpackSnormZero)
201*8975f5c5SAndroid Build Coastguard Worker {
202*8975f5c5SAndroid Build Coastguard Worker     // Expect the shader to output the same value as the input
203*8975f5c5SAndroid Build Coastguard Worker     compareBeforeAfter(mSNormProgram, 0.00000f, -0.00000f);
204*8975f5c5SAndroid Build Coastguard Worker }
205*8975f5c5SAndroid Build Coastguard Worker 
206*8975f5c5SAndroid Build Coastguard Worker // Test the correctness of packUnorm2x16 and unpackUnorm2x16 functions calculating zero floating
207*8975f5c5SAndroid Build Coastguard Worker // numbers.
TEST_P(PackUnpackTest,PackUnpackUnormZero)208*8975f5c5SAndroid Build Coastguard Worker TEST_P(PackUnpackTest, PackUnpackUnormZero)
209*8975f5c5SAndroid Build Coastguard Worker {
210*8975f5c5SAndroid Build Coastguard Worker     compareBeforeAfter(mUNormProgram, 0.00000f, -0.00000f, 0.00000f, 0.00000f);
211*8975f5c5SAndroid Build Coastguard Worker }
212*8975f5c5SAndroid Build Coastguard Worker 
213*8975f5c5SAndroid Build Coastguard Worker // Test the correctness of packHalf2x16 and unpackHalf2x16 functions calculating zero floating
214*8975f5c5SAndroid Build Coastguard Worker // numbers.
TEST_P(PackUnpackTest,PackUnpackHalfZero)215*8975f5c5SAndroid Build Coastguard Worker TEST_P(PackUnpackTest, PackUnpackHalfZero)
216*8975f5c5SAndroid Build Coastguard Worker {
217*8975f5c5SAndroid Build Coastguard Worker     // Expect the shader to output the same value as the input
218*8975f5c5SAndroid Build Coastguard Worker     compareBeforeAfter(mHalfProgram, 0.00000f, -0.00000f);
219*8975f5c5SAndroid Build Coastguard Worker }
220*8975f5c5SAndroid Build Coastguard Worker 
221*8975f5c5SAndroid Build Coastguard Worker // Test the correctness of packUnorm2x16 and unpackUnorm2x16 functions calculating overflow floating
222*8975f5c5SAndroid Build Coastguard Worker // numbers.
TEST_P(PackUnpackTest,PackUnpackUnormOverflow)223*8975f5c5SAndroid Build Coastguard Worker TEST_P(PackUnpackTest, PackUnpackUnormOverflow)
224*8975f5c5SAndroid Build Coastguard Worker {
225*8975f5c5SAndroid Build Coastguard Worker     // Expect the shader to clamp the input to [0, 1]
226*8975f5c5SAndroid Build Coastguard Worker     compareBeforeAfter(mUNormProgram, 67000.0f, -67000.0f, 1.0f, 0.0f);
227*8975f5c5SAndroid Build Coastguard Worker }
228*8975f5c5SAndroid Build Coastguard Worker 
229*8975f5c5SAndroid Build Coastguard Worker // Test the correctness of packSnorm2x16 and unpackSnorm2x16 functions calculating overflow floating
230*8975f5c5SAndroid Build Coastguard Worker // numbers.
TEST_P(PackUnpackTest,PackUnpackSnormOverflow)231*8975f5c5SAndroid Build Coastguard Worker TEST_P(PackUnpackTest, PackUnpackSnormOverflow)
232*8975f5c5SAndroid Build Coastguard Worker {
233*8975f5c5SAndroid Build Coastguard Worker     // Expect the shader to clamp the input to [-1, 1]
234*8975f5c5SAndroid Build Coastguard Worker     compareBeforeAfter(mSNormProgram, 67000.0f, -67000.0f, 1.0f, -1.0f);
235*8975f5c5SAndroid Build Coastguard Worker }
236*8975f5c5SAndroid Build Coastguard Worker 
237*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PackUnpackTest);
238*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES3(PackUnpackTest);
239*8975f5c5SAndroid Build Coastguard Worker }  // namespace
240