diff options
Diffstat (limited to 'gfx/angle/src/tests/gl_tests/PackUnpackTest.cpp')
-rwxr-xr-x | gfx/angle/src/tests/gl_tests/PackUnpackTest.cpp | 268 |
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()); +} |