Add new ESSL 3.10 pack/unpack builtins
This adds new built-ins found in ESSL 3.10 section 8.4 Floating-Point
Pack and Unpack Functions.
This includes constant folding support and support for both GLSL and
HLSL output. In HLSL all of these functions need to be emulated.
BUG=angleproject:1730
TEST=angle_unittests
TEST=dEQP-GLES31.functional.shaders.*pack*norm4x8*
Change-Id: Ibed60286a366cd35c4faafd405e79af562a02a06
Reviewed-on: https://chromium-review.googlesource.com/434170
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp b/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp
index d0f4dfa..3f8acde 100644
--- a/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp
+++ b/src/compiler/translator/BuiltInFunctionEmulatorHLSL.cpp
@@ -297,23 +297,23 @@
"}\n");
emu->addEmulatedFunction(EOpPackSnorm2x16, float2,
- "int webgl_toSnorm(in float x) {\n"
+ "int webgl_toSnorm16(in float x) {\n"
" return int(round(clamp(x, -1.0, 1.0) * 32767.0));\n"
"}\n"
"\n"
"uint webgl_packSnorm2x16_emu(in float2 v) {\n"
- " int x = webgl_toSnorm(v.x);\n"
- " int y = webgl_toSnorm(v.y);\n"
+ " int x = webgl_toSnorm16(v.x);\n"
+ " int y = webgl_toSnorm16(v.y);\n"
" return (asuint(y) << 16) | (asuint(x) & 0xffffu);\n"
"}\n");
emu->addEmulatedFunction(EOpPackUnorm2x16, float2,
- "uint webgl_toUnorm(in float x) {\n"
+ "uint webgl_toUnorm16(in float x) {\n"
" return uint(round(clamp(x, 0.0, 1.0) * 65535.0));\n"
"}\n"
"\n"
"uint webgl_packUnorm2x16_emu(in float2 v) {\n"
- " uint x = webgl_toUnorm(v.x);\n"
- " uint y = webgl_toUnorm(v.y);\n"
+ " uint x = webgl_toUnorm16(v.x);\n"
+ " uint y = webgl_toUnorm16(v.y);\n"
" return (y << 16) | x;\n"
"}\n");
emu->addEmulatedFunction(EOpPackHalf2x16, float2,
@@ -324,7 +324,7 @@
"}\n");
emu->addEmulatedFunction(EOpUnpackSnorm2x16, uint1,
- "float webgl_fromSnorm(in uint x) {\n"
+ "float webgl_fromSnorm16(in uint x) {\n"
" int xi = asint(x & 0x7fffu) - asint(x & 0x8000u);\n"
" return clamp(float(xi) / 32767.0, -1.0, 1.0);\n"
"}\n"
@@ -332,17 +332,17 @@
"float2 webgl_unpackSnorm2x16_emu(in uint u) {\n"
" uint y = (u >> 16);\n"
" uint x = u;\n"
- " return float2(webgl_fromSnorm(x), webgl_fromSnorm(y));\n"
+ " return float2(webgl_fromSnorm16(x), webgl_fromSnorm16(y));\n"
"}\n");
emu->addEmulatedFunction(EOpUnpackUnorm2x16, uint1,
- "float webgl_fromUnorm(in uint x) {\n"
+ "float webgl_fromUnorm16(in uint x) {\n"
" return float(x) / 65535.0;\n"
"}\n"
"\n"
"float2 webgl_unpackUnorm2x16_emu(in uint u) {\n"
" uint y = (u >> 16);\n"
" uint x = u & 0xffffu;\n"
- " return float2(webgl_fromUnorm(x), webgl_fromUnorm(y));\n"
+ " return float2(webgl_fromUnorm16(x), webgl_fromUnorm16(y));\n"
"}\n");
emu->addEmulatedFunction(EOpUnpackHalf2x16, uint1,
"float2 webgl_unpackHalf2x16_emu(in uint u) {\n"
@@ -351,6 +351,60 @@
" return float2(f16tof32(x), f16tof32(y));\n"
"}\n");
+ emu->addEmulatedFunction(EOpPackSnorm4x8, float4,
+ "int webgl_toSnorm8(in float x) {\n"
+ " return int(round(clamp(x, -1.0, 1.0) * 127.0));\n"
+ "}\n"
+ "\n"
+ "uint webgl_packSnorm4x8_emu(in float4 v) {\n"
+ " int x = webgl_toSnorm8(v.x);\n"
+ " int y = webgl_toSnorm8(v.y);\n"
+ " int z = webgl_toSnorm8(v.z);\n"
+ " int w = webgl_toSnorm8(v.w);\n"
+ " return ((asuint(w) & 0xffu) << 24) | ((asuint(z) & 0xffu) << 16) "
+ "| ((asuint(y) & 0xffu) << 8) | (asuint(x) & 0xffu);\n"
+ "}\n");
+ emu->addEmulatedFunction(EOpPackUnorm4x8, float4,
+ "uint webgl_toUnorm8(in float x) {\n"
+ " return uint(round(clamp(x, 0.0, 1.0) * 255.0));\n"
+ "}\n"
+ "\n"
+ "uint webgl_packUnorm4x8_emu(in float4 v) {\n"
+ " uint x = webgl_toUnorm8(v.x);\n"
+ " uint y = webgl_toUnorm8(v.y);\n"
+ " uint z = webgl_toUnorm8(v.z);\n"
+ " uint w = webgl_toUnorm8(v.w);\n"
+ " return (w << 24) | (z << 16) | (y << 8) | x;\n"
+ "}\n");
+
+ emu->addEmulatedFunction(EOpUnpackSnorm4x8, uint1,
+ "float webgl_fromSnorm8(in uint x) {\n"
+ " int xi = asint(x & 0x7fu) - asint(x & 0x80u);\n"
+ " return clamp(float(xi) / 127.0, -1.0, 1.0);\n"
+ "}\n"
+ "\n"
+ "float4 webgl_unpackSnorm4x8_emu(in uint u) {\n"
+ " uint w = (u >> 24);\n"
+ " uint z = (u >> 16);\n"
+ " uint y = (u >> 8);\n"
+ " uint x = u;\n"
+ " return float4(webgl_fromSnorm8(x), webgl_fromSnorm8(y), "
+ "webgl_fromSnorm8(z), webgl_fromSnorm8(w));\n"
+ "}\n");
+ emu->addEmulatedFunction(EOpUnpackUnorm4x8, uint1,
+ "float webgl_fromUnorm8(in uint x) {\n"
+ " return float(x) / 255.0;\n"
+ "}\n"
+ "\n"
+ "float4 webgl_unpackUnorm4x8_emu(in uint u) {\n"
+ " uint w = (u >> 24) & 0xffu;\n"
+ " uint z = (u >> 16) & 0xffu;\n"
+ " uint y = (u >> 8) & 0xffu;\n"
+ " uint x = u & 0xffu;\n"
+ " return float4(webgl_fromUnorm8(x), webgl_fromUnorm8(y), "
+ "webgl_fromUnorm8(z), webgl_fromUnorm8(w));\n"
+ "}\n");
+
// The matrix resulting from outer product needs to be transposed
// (matrices are stored as transposed to simplify element access in HLSL).
// So the function should return transpose(c * r) where c is a column vector
diff --git a/src/compiler/translator/Initialize.cpp b/src/compiler/translator/Initialize.cpp
index e016a10..8a6a63a 100644
--- a/src/compiler/translator/Initialize.cpp
+++ b/src/compiler/translator/Initialize.cpp
@@ -128,6 +128,11 @@
symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpUnpackUnorm2x16, float2, uint1);
symbolTable.insertBuiltInOp(ESSL3_BUILTINS, EOpUnpackHalf2x16, float2, uint1);
+ symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpPackUnorm4x8, uint1, float4);
+ symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpPackSnorm4x8, uint1, float4);
+ symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpUnpackUnorm4x8, float4, uint1);
+ symbolTable.insertBuiltInOp(ESSL3_1_BUILTINS, EOpUnpackSnorm4x8, float4, uint1);
+
//
// Geometric Functions.
//
diff --git a/src/compiler/translator/IntermNode.cpp b/src/compiler/translator/IntermNode.cpp
index 276b653..4039305 100644
--- a/src/compiler/translator/IntermNode.cpp
+++ b/src/compiler/translator/IntermNode.cpp
@@ -821,6 +821,8 @@
case EOpPackSnorm2x16:
case EOpPackUnorm2x16:
case EOpPackHalf2x16:
+ case EOpPackUnorm4x8:
+ case EOpPackSnorm4x8:
setType(TType(EbtUInt, EbpHigh, resultQualifier));
break;
case EOpUnpackSnorm2x16:
@@ -830,6 +832,10 @@
case EOpUnpackHalf2x16:
setType(TType(EbtFloat, EbpMedium, resultQualifier, 2));
break;
+ case EOpUnpackUnorm4x8:
+ case EOpUnpackSnorm4x8:
+ setType(TType(EbtFloat, EbpMedium, resultQualifier, 4));
+ break;
case EOpAny:
case EOpAll:
setType(TType(EbtBool, EbpUndefined, resultQualifier));
@@ -1315,6 +1321,10 @@
case EOpUnpackUnorm2x16:
case EOpPackHalf2x16:
case EOpUnpackHalf2x16:
+ case EOpPackUnorm4x8:
+ case EOpPackSnorm4x8:
+ case EOpUnpackUnorm4x8:
+ case EOpUnpackSnorm4x8:
constArray = operandConstant->foldUnaryNonComponentWise(mOp);
break;
default:
@@ -1868,6 +1878,49 @@
break;
}
+ case EOpPackUnorm4x8:
+ {
+ ASSERT(getType().getBasicType() == EbtFloat);
+ resultArray = new TConstantUnion();
+ resultArray->setUConst(
+ gl::PackUnorm4x8(operandArray[0].getFConst(), operandArray[1].getFConst(),
+ operandArray[2].getFConst(), operandArray[3].getFConst()));
+ break;
+ }
+ case EOpPackSnorm4x8:
+ {
+ ASSERT(getType().getBasicType() == EbtFloat);
+ resultArray = new TConstantUnion();
+ resultArray->setUConst(
+ gl::PackSnorm4x8(operandArray[0].getFConst(), operandArray[1].getFConst(),
+ operandArray[2].getFConst(), operandArray[3].getFConst()));
+ break;
+ }
+ case EOpUnpackUnorm4x8:
+ {
+ ASSERT(getType().getBasicType() == EbtUInt);
+ resultArray = new TConstantUnion[4];
+ float f[4];
+ gl::UnpackUnorm4x8(operandArray[0].getUConst(), f);
+ for (size_t i = 0; i < 4; ++i)
+ {
+ resultArray[i].setFConst(f[i]);
+ }
+ break;
+ }
+ case EOpUnpackSnorm4x8:
+ {
+ ASSERT(getType().getBasicType() == EbtUInt);
+ resultArray = new TConstantUnion[4];
+ float f[4];
+ gl::UnpackSnorm4x8(operandArray[0].getUConst(), f);
+ for (size_t i = 0; i < 4; ++i)
+ {
+ resultArray[i].setFConst(f[i]);
+ }
+ break;
+ }
+
default:
UNREACHABLE();
break;
diff --git a/src/compiler/translator/Operator.cpp b/src/compiler/translator/Operator.cpp
index 12ae1a9..64e8052 100644
--- a/src/compiler/translator/Operator.cpp
+++ b/src/compiler/translator/Operator.cpp
@@ -210,6 +210,15 @@
case EOpUnpackHalf2x16:
return "unpackHalf2x16";
+ case EOpPackUnorm4x8:
+ return "packUnorm4x8";
+ case EOpPackSnorm4x8:
+ return "packSnorm4x8";
+ case EOpUnpackUnorm4x8:
+ return "unpackUnorm4x8";
+ case EOpUnpackSnorm4x8:
+ return "unpackSnorm4x8";
+
case EOpLength:
return "length";
case EOpDistance:
diff --git a/src/compiler/translator/Operator.h b/src/compiler/translator/Operator.h
index 968dbac..18e7ca5 100644
--- a/src/compiler/translator/Operator.h
+++ b/src/compiler/translator/Operator.h
@@ -150,6 +150,11 @@
EOpUnpackUnorm2x16,
EOpUnpackHalf2x16,
+ EOpPackUnorm4x8,
+ EOpPackSnorm4x8,
+ EOpUnpackUnorm4x8,
+ EOpUnpackSnorm4x8,
+
EOpLength,
EOpDistance,
EOpDot,
diff --git a/src/compiler/translator/OutputGLSLBase.cpp b/src/compiler/translator/OutputGLSLBase.cpp
index 3a2a757..4ae8651 100644
--- a/src/compiler/translator/OutputGLSLBase.cpp
+++ b/src/compiler/translator/OutputGLSLBase.cpp
@@ -714,6 +714,10 @@
case EOpUnpackSnorm2x16:
case EOpUnpackUnorm2x16:
case EOpUnpackHalf2x16:
+ case EOpPackUnorm4x8:
+ case EOpPackSnorm4x8:
+ case EOpUnpackUnorm4x8:
+ case EOpUnpackSnorm4x8:
case EOpLength:
case EOpNormalize:
case EOpDFdx:
diff --git a/src/compiler/translator/OutputHLSL.cpp b/src/compiler/translator/OutputHLSL.cpp
index 8a3794d..df0fa9f 100644
--- a/src/compiler/translator/OutputHLSL.cpp
+++ b/src/compiler/translator/OutputHLSL.cpp
@@ -1414,6 +1414,10 @@
case EOpUnpackSnorm2x16:
case EOpUnpackUnorm2x16:
case EOpUnpackHalf2x16:
+ case EOpPackUnorm4x8:
+ case EOpPackSnorm4x8:
+ case EOpUnpackUnorm4x8:
+ case EOpUnpackSnorm4x8:
ASSERT(node->getUseEmulatedFunction());
writeEmulatedFunctionTriplet(out, visit, node->getOp());
break;