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