summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/tests/gl_tests/PackUnpackTest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/src/tests/gl_tests/PackUnpackTest.cpp')
-rwxr-xr-xgfx/angle/src/tests/gl_tests/PackUnpackTest.cpp268
1 files changed, 268 insertions, 0 deletions
diff --git a/gfx/angle/src/tests/gl_tests/PackUnpackTest.cpp b/gfx/angle/src/tests/gl_tests/PackUnpackTest.cpp
new file mode 100755
index 000000000..032504b80
--- /dev/null
+++ b/gfx/angle/src/tests/gl_tests/PackUnpackTest.cpp
@@ -0,0 +1,268 @@
+//
+// Copyright 2015 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// PackUnpackTest:
+// Tests the corrrectness of opengl 4.1 emulation of pack/unpack built-in functions.
+//
+
+#include "test_utils/ANGLETest.h"
+
+using namespace angle;
+
+namespace
+{
+
+class PackUnpackTest : public ANGLETest
+{
+ protected:
+ PackUnpackTest()
+ {
+ setWindowWidth(16);
+ setWindowHeight(16);
+ setConfigRedBits(8);
+ setConfigGreenBits(8);
+ setConfigBlueBits(8);
+ setConfigAlphaBits(8);
+ }
+
+ void SetUp() override
+ {
+ ANGLETest::SetUp();
+
+ // Vertex Shader source
+ const std::string vs = SHADER_SOURCE
+ ( #version 300 es\n
+ precision mediump float;
+ in vec4 position;
+
+ void main()
+ {
+ gl_Position = position;
+ }
+ );
+
+ // clang-format off
+ // Fragment Shader source
+ const std::string sNormFS = SHADER_SOURCE
+ ( #version 300 es\n
+ precision mediump float;
+ uniform mediump vec2 v;
+ layout(location = 0) out mediump vec4 fragColor;
+
+ void main()
+ {
+ uint u = packSnorm2x16(v);
+ vec2 r = unpackSnorm2x16(u);
+ fragColor = vec4(r, 0.0, 1.0);
+ }
+ );
+
+ // Fragment Shader source
+ const std::string uNormFS = SHADER_SOURCE
+ ( #version 300 es\n
+ precision mediump float;
+ uniform mediump vec2 v;
+ layout(location = 0) out mediump vec4 fragColor;
+
+ void main()
+ {
+ uint u = packUnorm2x16(v);
+ vec2 r = unpackUnorm2x16(u);
+ fragColor = vec4(r, 0.0, 1.0);
+ }
+ );
+
+ // Fragment Shader source
+ const std::string halfFS = SHADER_SOURCE
+ ( #version 300 es\n
+ precision mediump float;
+ uniform mediump vec2 v;
+ layout(location = 0) out mediump vec4 fragColor;
+
+ void main()
+ {
+ uint u = packHalf2x16(v);
+ vec2 r = unpackHalf2x16(u);
+ fragColor = vec4(r, 0.0, 1.0);
+ }
+ );
+ // clang-format on
+
+ mSNormProgram = CompileProgram(vs, sNormFS);
+ mUNormProgram = CompileProgram(vs, uNormFS);
+ mHalfProgram = CompileProgram(vs, halfFS);
+ if (mSNormProgram == 0 || mUNormProgram == 0 || mHalfProgram == 0)
+ {
+ FAIL() << "shader compilation failed.";
+ }
+
+ glGenTextures(1, &mOffscreenTexture2D);
+ glBindTexture(GL_TEXTURE_2D, mOffscreenTexture2D);
+ glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, getWindowWidth(), getWindowHeight());
+
+ glGenFramebuffers(1, &mOffscreenFramebuffer);
+ glBindFramebuffer(GL_FRAMEBUFFER, mOffscreenFramebuffer);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mOffscreenTexture2D, 0);
+
+ glViewport(0, 0, 16, 16);
+
+ const GLfloat color[] = { 1.0f, 1.0f, 0.0f, 1.0f };
+ glClearBufferfv(GL_COLOR, 0, color);
+ }
+
+ void TearDown() override
+ {
+ glDeleteTextures(1, &mOffscreenTexture2D);
+ glDeleteFramebuffers(1, &mOffscreenFramebuffer);
+ glDeleteProgram(mSNormProgram);
+ glDeleteProgram(mUNormProgram);
+ glDeleteProgram(mHalfProgram);
+
+ ANGLETest::TearDown();
+ }
+
+ void compareBeforeAfter(GLuint program, float input1, float input2)
+ {
+ compareBeforeAfter(program, input1, input2, input1, input2);
+ }
+
+ void compareBeforeAfter(GLuint program, float input1, float input2, float expect1, float expect2)
+ {
+ GLint vec2Location = glGetUniformLocation(program, "v");
+
+ glUseProgram(program);
+ glUniform2f(vec2Location, input1, input2);
+
+ drawQuad(program, "position", 0.5f);
+
+ ASSERT_GL_NO_ERROR();
+
+ GLfloat p[2] = { 0 };
+ glReadPixels(8, 8, 1, 1, GL_RG, GL_FLOAT, p);
+
+ ASSERT_GL_NO_ERROR();
+
+ static const double epsilon = 0.0005;
+ EXPECT_NEAR(p[0], expect1, epsilon);
+ EXPECT_NEAR(p[1], expect2, epsilon);
+ }
+
+ GLuint mSNormProgram;
+ GLuint mUNormProgram;
+ GLuint mHalfProgram;
+ GLuint mOffscreenFramebuffer;
+ GLuint mOffscreenTexture2D;
+};
+
+// Test the correctness of packSnorm2x16 and unpackSnorm2x16 functions calculating normal floating numbers.
+TEST_P(PackUnpackTest, PackUnpackSnormNormal)
+{
+ // Expect the shader to output the same value as the input
+ compareBeforeAfter(mSNormProgram, 0.5f, -0.2f);
+ compareBeforeAfter(mSNormProgram, -0.35f, 0.75f);
+ compareBeforeAfter(mSNormProgram, 0.00392f, -0.99215f);
+ compareBeforeAfter(mSNormProgram, 1.0f, -0.00392f);
+}
+
+// Test the correctness of packSnorm2x16 and unpackSnorm2x16 functions calculating normal floating
+// numbers.
+TEST_P(PackUnpackTest, PackUnpackUnormNormal)
+{
+ // Expect the shader to output the same value as the input
+ compareBeforeAfter(mUNormProgram, 0.5f, 0.2f, 0.5f, 0.2f);
+ compareBeforeAfter(mUNormProgram, 0.35f, 0.75f, 0.35f, 0.75f);
+ compareBeforeAfter(mUNormProgram, 0.00392f, 0.99215f, 0.00392f, 0.99215f);
+ compareBeforeAfter(mUNormProgram, 1.0f, 0.00392f, 1.0f, 0.00392f);
+}
+
+// Test the correctness of packHalf2x16 and unpackHalf2x16 functions calculating normal floating numbers.
+TEST_P(PackUnpackTest, PackUnpackHalfNormal)
+{
+ // TODO(cwallez) figure out why it is broken on Intel on Mac
+#if defined(ANGLE_PLATFORM_APPLE)
+ if (IsIntel() && getPlatformRenderer() == EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
+ {
+ std::cout << "Test skipped on Intel on Mac." << std::endl;
+ return;
+ }
+#endif
+
+ // Expect the shader to output the same value as the input
+ compareBeforeAfter(mHalfProgram, 0.5f, -0.2f);
+ compareBeforeAfter(mHalfProgram, -0.35f, 0.75f);
+ compareBeforeAfter(mHalfProgram, 0.00392f, -0.99215f);
+ compareBeforeAfter(mHalfProgram, 1.0f, -0.00392f);
+}
+
+// Test the correctness of packSnorm2x16 and unpackSnorm2x16 functions calculating subnormal floating numbers.
+TEST_P(PackUnpackTest, PackUnpackSnormSubnormal)
+{
+ // Expect the shader to output the same value as the input
+ compareBeforeAfter(mSNormProgram, 0.00001f, -0.00001f);
+}
+
+// Test the correctness of packUnorm2x16 and unpackUnorm2x16 functions calculating subnormal
+// floating numbers.
+TEST_P(PackUnpackTest, PackUnpackUnormSubnormal)
+{
+ // Expect the shader to output the same value as the input for positive numbers and clamp
+ // to [0, 1]
+ compareBeforeAfter(mUNormProgram, 0.00001f, -0.00001f, 0.00001f, 0.0f);
+}
+
+// Test the correctness of packHalf2x16 and unpackHalf2x16 functions calculating subnormal floating numbers.
+TEST_P(PackUnpackTest, PackUnpackHalfSubnormal)
+{
+ // Expect the shader to output the same value as the input
+ compareBeforeAfter(mHalfProgram, 0.00001f, -0.00001f);
+}
+
+// Test the correctness of packSnorm2x16 and unpackSnorm2x16 functions calculating zero floating numbers.
+TEST_P(PackUnpackTest, PackUnpackSnormZero)
+{
+ // Expect the shader to output the same value as the input
+ compareBeforeAfter(mSNormProgram, 0.00000f, -0.00000f);
+}
+
+// Test the correctness of packUnorm2x16 and unpackUnorm2x16 functions calculating zero floating
+// numbers.
+TEST_P(PackUnpackTest, PackUnpackUnormZero)
+{
+ compareBeforeAfter(mUNormProgram, 0.00000f, -0.00000f, 0.00000f, 0.00000f);
+}
+
+// Test the correctness of packHalf2x16 and unpackHalf2x16 functions calculating zero floating numbers.
+TEST_P(PackUnpackTest, PackUnpackHalfZero)
+{
+ // Expect the shader to output the same value as the input
+ compareBeforeAfter(mHalfProgram, 0.00000f, -0.00000f);
+}
+
+// Test the correctness of packUnorm2x16 and unpackUnorm2x16 functions calculating overflow floating
+// numbers.
+TEST_P(PackUnpackTest, PackUnpackUnormOverflow)
+{
+ // Expect the shader to clamp the input to [0, 1]
+ compareBeforeAfter(mUNormProgram, 67000.0f, -67000.0f, 1.0f, 0.0f);
+}
+
+// Test the correctness of packSnorm2x16 and unpackSnorm2x16 functions calculating overflow floating numbers.
+TEST_P(PackUnpackTest, PackUnpackSnormOverflow)
+{
+ // Expect the shader to clamp the input to [-1, 1]
+ compareBeforeAfter(mSNormProgram, 67000.0f, -67000.0f, 1.0f, -1.0f);
+}
+
+// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
+ANGLE_INSTANTIATE_TEST(PackUnpackTest,
+ ES3_OPENGL(3, 3),
+ ES3_OPENGL(4, 0),
+ ES3_OPENGL(4, 1),
+ ES3_OPENGL(4, 2),
+ ES3_OPENGL(4, 3),
+ ES3_OPENGL(4, 4),
+ ES3_OPENGL(4, 5),
+ ES3_OPENGLES());
+}