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, ...@@ -42,6 +42,31 @@ void InitBuiltInFunctionEmulatorForGLSLWorkarounds(BuiltInFunctionEmulator *emu,
void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator *emu, sh::GLenum shaderType, void InitBuiltInFunctionEmulatorForGLSLMissingFunctions(BuiltInFunctionEmulator *emu, sh::GLenum shaderType,
int targetGLSLVersion) 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) // Emulate packSnorm2x16, packHalf2x16, unpackSnorm2x16, and unpackHalf2x16 (GLSL 4.20)
// by using floatBitsToInt, floatBitsToUint, intBitsToFloat, and uintBitsToFloat (GLSL 3.30). // by using floatBitsToInt, floatBitsToUint, intBitsToFloat, and uintBitsToFloat (GLSL 3.30).
if (targetGLSLVersion >= GLSL_VERSION_330 && targetGLSLVersion < GLSL_VERSION_420) if (targetGLSLVersion >= GLSL_VERSION_330 && targetGLSLVersion < GLSL_VERSION_420)
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
// found in the LICENSE file. // found in the LICENSE file.
// //
// Pack_Unpack_test.cpp: // 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" #include "angle_gl.h"
...@@ -18,10 +18,10 @@ namespace ...@@ -18,10 +18,10 @@ namespace
class PackUnpackTest : public MatchOutputCodeTest class PackUnpackTest : public MatchOutputCodeTest
{ {
public: 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) TEST_F(PackUnpackTest, PackSnorm2x16Emulation)
{ {
const std::string &shaderString = const std::string &shaderString =
...@@ -37,7 +37,7 @@ TEST_F(PackUnpackTest, PackSnorm2x16Emulation) ...@@ -37,7 +37,7 @@ TEST_F(PackUnpackTest, PackSnorm2x16Emulation)
ASSERT_TRUE(foundInCode("uint webgl_packSnorm2x16_emu(vec2 v)")); 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) TEST_F(PackUnpackTest, UnpackSnorm2x16Emulation)
{ {
const std::string &shaderString = const std::string &shaderString =
...@@ -53,7 +53,39 @@ TEST_F(PackUnpackTest, UnpackSnorm2x16Emulation) ...@@ -53,7 +53,39 @@ TEST_F(PackUnpackTest, UnpackSnorm2x16Emulation)
ASSERT_TRUE(foundInCode("vec2 webgl_unpackSnorm2x16_emu(uint u)")); 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) TEST_F(PackUnpackTest, PackHalf2x16Emulation)
{ {
const std::string &shaderString = const std::string &shaderString =
...@@ -69,7 +101,7 @@ TEST_F(PackUnpackTest, PackHalf2x16Emulation) ...@@ -69,7 +101,7 @@ TEST_F(PackUnpackTest, PackHalf2x16Emulation)
ASSERT_TRUE(foundInCode("uint webgl_packHalf2x16_emu(vec2 v)")); 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) TEST_F(PackUnpackTest, UnpackHalf2x16Emulation)
{ {
const std::string &shaderString = const std::string &shaderString =
......
...@@ -43,6 +43,7 @@ class PackUnpackTest : public ANGLETest ...@@ -43,6 +43,7 @@ class PackUnpackTest : public ANGLETest
} }
); );
// clang-format off
// Fragment Shader source // Fragment Shader source
const std::string sNormFS = SHADER_SOURCE const std::string sNormFS = SHADER_SOURCE
( #version 300 es\n ( #version 300 es\n
...@@ -59,6 +60,21 @@ class PackUnpackTest : public ANGLETest ...@@ -59,6 +60,21 @@ class PackUnpackTest : public ANGLETest
); );
// Fragment Shader source // 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 const std::string halfFS = SHADER_SOURCE
( #version 300 es\n ( #version 300 es\n
precision mediump float; precision mediump float;
...@@ -72,10 +88,12 @@ class PackUnpackTest : public ANGLETest ...@@ -72,10 +88,12 @@ class PackUnpackTest : public ANGLETest
fragColor = vec4(r, 0.0, 1.0); fragColor = vec4(r, 0.0, 1.0);
} }
); );
// clang-format on
mSNormProgram = CompileProgram(vs, sNormFS); mSNormProgram = CompileProgram(vs, sNormFS);
mUNormProgram = CompileProgram(vs, uNormFS);
mHalfProgram = CompileProgram(vs, halfFS); mHalfProgram = CompileProgram(vs, halfFS);
if (mSNormProgram == 0 || mHalfProgram == 0) if (mSNormProgram == 0 || mUNormProgram == 0 || mHalfProgram == 0)
{ {
FAIL() << "shader compilation failed."; FAIL() << "shader compilation failed.";
} }
...@@ -99,6 +117,7 @@ class PackUnpackTest : public ANGLETest ...@@ -99,6 +117,7 @@ class PackUnpackTest : public ANGLETest
glDeleteTextures(1, &mOffscreenTexture2D); glDeleteTextures(1, &mOffscreenTexture2D);
glDeleteFramebuffers(1, &mOffscreenFramebuffer); glDeleteFramebuffers(1, &mOffscreenFramebuffer);
glDeleteProgram(mSNormProgram); glDeleteProgram(mSNormProgram);
glDeleteProgram(mUNormProgram);
glDeleteProgram(mHalfProgram); glDeleteProgram(mHalfProgram);
ANGLETest::TearDown(); ANGLETest::TearDown();
...@@ -131,6 +150,7 @@ class PackUnpackTest : public ANGLETest ...@@ -131,6 +150,7 @@ class PackUnpackTest : public ANGLETest
} }
GLuint mSNormProgram; GLuint mSNormProgram;
GLuint mUNormProgram;
GLuint mHalfProgram; GLuint mHalfProgram;
GLuint mOffscreenFramebuffer; GLuint mOffscreenFramebuffer;
GLuint mOffscreenTexture2D; GLuint mOffscreenTexture2D;
...@@ -146,6 +166,17 @@ TEST_P(PackUnpackTest, PackUnpackSnormNormal) ...@@ -146,6 +166,17 @@ TEST_P(PackUnpackTest, PackUnpackSnormNormal)
compareBeforeAfter(mSNormProgram, 1.0f, -0.00392f); 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 the correctness of packHalf2x16 and unpackHalf2x16 functions calculating normal floating numbers.
TEST_P(PackUnpackTest, PackUnpackHalfNormal) TEST_P(PackUnpackTest, PackUnpackHalfNormal)
{ {
...@@ -172,6 +203,15 @@ TEST_P(PackUnpackTest, PackUnpackSnormSubnormal) ...@@ -172,6 +203,15 @@ TEST_P(PackUnpackTest, PackUnpackSnormSubnormal)
compareBeforeAfter(mSNormProgram, 0.00001f, -0.00001f); 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 the correctness of packHalf2x16 and unpackHalf2x16 functions calculating subnormal floating numbers.
TEST_P(PackUnpackTest, PackUnpackHalfSubnormal) TEST_P(PackUnpackTest, PackUnpackHalfSubnormal)
{ {
...@@ -186,6 +226,13 @@ TEST_P(PackUnpackTest, PackUnpackSnormZero) ...@@ -186,6 +226,13 @@ TEST_P(PackUnpackTest, PackUnpackSnormZero)
compareBeforeAfter(mSNormProgram, 0.00000f, -0.00000f); 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 the correctness of packHalf2x16 and unpackHalf2x16 functions calculating zero floating numbers.
TEST_P(PackUnpackTest, PackUnpackHalfZero) TEST_P(PackUnpackTest, PackUnpackHalfZero)
{ {
...@@ -193,6 +240,14 @@ TEST_P(PackUnpackTest, PackUnpackHalfZero) ...@@ -193,6 +240,14 @@ TEST_P(PackUnpackTest, PackUnpackHalfZero)
compareBeforeAfter(mHalfProgram, 0.00000f, -0.00000f); 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 the correctness of packSnorm2x16 and unpackSnorm2x16 functions calculating overflow floating numbers.
TEST_P(PackUnpackTest, PackUnpackSnormOverflow) TEST_P(PackUnpackTest, PackUnpackSnormOverflow)
{ {
......
...@@ -104,6 +104,11 @@ bool MatchOutputCodeTest::foundInCode(ShShaderOutput output, const char *stringT ...@@ -104,6 +104,11 @@ bool MatchOutputCodeTest::foundInCode(ShShaderOutput output, const char *stringT
{ {
const auto code = mOutputCode.find(output); const auto code = mOutputCode.find(output);
EXPECT_NE(mOutputCode.end(), code); EXPECT_NE(mOutputCode.end(), code);
if (code == mOutputCode.end())
{
return false;
}
return code->second.find(stringToFind) != std::string::npos; return code->second.find(stringToFind) != std::string::npos;
} }
...@@ -113,6 +118,11 @@ bool MatchOutputCodeTest::foundInCode(ShShaderOutput output, ...@@ -113,6 +118,11 @@ bool MatchOutputCodeTest::foundInCode(ShShaderOutput output,
{ {
const auto code = mOutputCode.find(output); const auto code = mOutputCode.find(output);
EXPECT_NE(mOutputCode.end(), code); EXPECT_NE(mOutputCode.end(), code);
if (code == mOutputCode.end())
{
return false;
}
size_t currentPos = 0; size_t currentPos = 0;
int occurencesLeft = expectedOccurrences; int occurencesLeft = expectedOccurrences;
while (occurencesLeft-- > 0) 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