Commit 91d56945 by Geoff Lang Committed by Commit Bot

Emulate the pack/unpack functions for unorms.

BUG=angleproject:1044 Change-Id: I2cfb792de43d3a6fddd750100c74f948948dc1f6 Reviewed-on: https://chromium-review.googlesource.com/287290Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Geoff Lang <geofflang@chromium.org>
parent 3bc116e7
......@@ -42,6 +42,31 @@ void InitBuiltInFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu,
void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator *emu, sh::GLenum shaderType,
int targetGLSLVersion)
{
// Emulate packUnorm2x16 and unpackUnorm2x16 (GLSL 4.10)
if (targetGLSLVersion < GLSL_VERSION_410)
{
const TType *float2 = TCache::getType(EbtFloat, 2);
const TType *uint1 = TCache::getType(EbtUInt);
// clang-format off
emu->addEmulatedFunction(EOpPackUnorm2x16, float2,
"uint webgl_packUnorm2x16_emu(vec2 v)\n"
"{\n"
" int x = int(round(clamp(v.x, 0.0, 1.0) * 65535.0));\n"
" int y = int(round(clamp(v.y, 0.0, 1.0) * 65535.0));\n"
" return uint((y << 16) | (x & 0xFFFF));\n"
"}\n");
emu->addEmulatedFunction(EOpUnpackUnorm2x16, uint1,
"vec2 webgl_unpackUnorm2x16_emu(uint u)\n"
"{\n"
" float x = float(u & 0xFFFFu) / 65535.0;\n"
" float y = float(u >> 16) / 65535.0;\n"
" return vec2(x, y);\n"
"}\n");
// clang-format on
}
// Emulate packSnorm2x16, packHalf2x16, unpackSnorm2x16, and unpackHalf2x16 (GLSL 4.20)
// by using floatBitsToInt, floatBitsToUint, intBitsToFloat, and uintBitsToFloat (GLSL 3.30).
if (targetGLSLVersion >= GLSL_VERSION_330 && targetGLSLVersion < GLSL_VERSION_420)
......
......@@ -4,7 +4,7 @@
// found in the LICENSE file.
//
// Pack_Unpack_test.cpp:
// Tests for the emulating pack_unpack functions for GLSL 4.1.
// Tests for the emulating pack_unpack functions for GLSL.
//
#include "angle_gl.h"
......@@ -18,10 +18,10 @@ namespace
class PackUnpackTest : public MatchOutputCodeTest
{
public:
PackUnpackTest() : MatchOutputCodeTest(GL_FRAGMENT_SHADER, 0, SH_GLSL_410_CORE_OUTPUT) {}
PackUnpackTest() : MatchOutputCodeTest(GL_FRAGMENT_SHADER, 0, SH_GLSL_400_CORE_OUTPUT) {}
};
//Check if PackSnorm2x16 Emulation for GLSL 4.1 compile correctly.
// Check if PackSnorm2x16 Emulation for GLSL < 4.2 compile correctly.
TEST_F(PackUnpackTest, PackSnorm2x16Emulation)
{
const std::string &shaderString =
......@@ -37,7 +37,7 @@ TEST_F(PackUnpackTest, PackSnorm2x16Emulation)
ASSERT_TRUE(foundInCode("uint webgl_packSnorm2x16_emu(vec2 v)"));
}
//Check if UnpackSnorm2x16 Emulation for GLSL 4.1 compile correctly.
// Check if UnpackSnorm2x16 Emulation for GLSL < 4.2 compile correctly.
TEST_F(PackUnpackTest, UnpackSnorm2x16Emulation)
{
const std::string &shaderString =
......@@ -53,7 +53,39 @@ TEST_F(PackUnpackTest, UnpackSnorm2x16Emulation)
ASSERT_TRUE(foundInCode("vec2 webgl_unpackSnorm2x16_emu(uint u)"));
}
//Check if PackHalf2x16 Emulation for GLSL 4.1 compile correctly.
// Check if PackUnorm2x16 Emulation for GLSL < 4.1 compiles correctly.
TEST_F(PackUnpackTest, PackUnorm2x16Emulation)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"layout(location = 0) out mediump vec4 fragColor;"
"void main() {\n"
" vec2 v;\n"
" uint u = packUnorm2x16(v);\n"
" fragColor = vec4(0.0);\n"
"}\n";
compile(shaderString);
ASSERT_TRUE(foundInCode("uint webgl_packUnorm2x16_emu(vec2 v)"));
}
// Check if UnpackSnorm2x16 Emulation for GLSL < 4.1 compiles correctly.
TEST_F(PackUnpackTest, UnpackUnorm2x16Emulation)
{
const std::string &shaderString =
"#version 300 es\n"
"precision mediump float;\n"
"layout(location = 0) out mediump vec4 fragColor;"
"void main() {\n"
" uint u;\n"
" vec2 v=unpackUnorm2x16(u);\n"
" fragColor = vec4(0.0);\n"
"}\n";
compile(shaderString);
ASSERT_TRUE(foundInCode("vec2 webgl_unpackUnorm2x16_emu(uint u)"));
}
// Check if PackHalf2x16 Emulation for GLSL < 4.2 compiles correctly.
TEST_F(PackUnpackTest, PackHalf2x16Emulation)
{
const std::string &shaderString =
......@@ -69,7 +101,7 @@ TEST_F(PackUnpackTest, PackHalf2x16Emulation)
ASSERT_TRUE(foundInCode("uint webgl_packHalf2x16_emu(vec2 v)"));
}
//Check if UnpackHalf2x16 Emulation for GLSL 4.1 compile correctly.
// Check if UnpackHalf2x16 Emulation for GLSL < 4.2 compiles correctly.
TEST_F(PackUnpackTest, UnpackHalf2x16Emulation)
{
const std::string &shaderString =
......
......@@ -43,6 +43,7 @@ class PackUnpackTest : public ANGLETest
}
);
// clang-format off
// Fragment Shader source
const std::string sNormFS = SHADER_SOURCE
( #version 300 es\n
......@@ -59,6 +60,21 @@ class PackUnpackTest : public ANGLETest
);
// 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;
......@@ -72,10 +88,12 @@ class PackUnpackTest : public ANGLETest
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 || mHalfProgram == 0)
if (mSNormProgram == 0 || mUNormProgram == 0 || mHalfProgram == 0)
{
FAIL() << "shader compilation failed.";
}
......@@ -99,6 +117,7 @@ class PackUnpackTest : public ANGLETest
glDeleteTextures(1, &mOffscreenTexture2D);
glDeleteFramebuffers(1, &mOffscreenFramebuffer);
glDeleteProgram(mSNormProgram);
glDeleteProgram(mUNormProgram);
glDeleteProgram(mHalfProgram);
ANGLETest::TearDown();
......@@ -131,6 +150,7 @@ class PackUnpackTest : public ANGLETest
}
GLuint mSNormProgram;
GLuint mUNormProgram;
GLuint mHalfProgram;
GLuint mOffscreenFramebuffer;
GLuint mOffscreenTexture2D;
......@@ -146,6 +166,17 @@ TEST_P(PackUnpackTest, PackUnpackSnormNormal)
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)
{
......@@ -172,6 +203,15 @@ TEST_P(PackUnpackTest, PackUnpackSnormSubnormal)
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)
{
......@@ -186,6 +226,13 @@ TEST_P(PackUnpackTest, PackUnpackSnormZero)
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)
{
......@@ -193,6 +240,14 @@ TEST_P(PackUnpackTest, PackUnpackHalfZero)
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)
{
......
......@@ -104,6 +104,11 @@ bool MatchOutputCodeTest::foundInCode(ShShaderOutput output, const char *stringT
{
const auto code = mOutputCode.find(output);
EXPECT_NE(mOutputCode.end(), code);
if (code == mOutputCode.end())
{
return false;
}
return code->second.find(stringToFind) != std::string::npos;
}
......@@ -113,6 +118,11 @@ bool MatchOutputCodeTest::foundInCode(ShShaderOutput output,
{
const auto code = mOutputCode.find(output);
EXPECT_NE(mOutputCode.end(), code);
if (code == mOutputCode.end())
{
return false;
}
size_t currentPos = 0;
int occurencesLeft = expectedOccurrences;
while (occurencesLeft-- > 0)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment