diff --git a/Test/baseResults/constantOp.vert.out b/Test/baseResults/constantOp.vert.out new file mode 100644 index 0000000000..67c6a83e9e --- /dev/null +++ b/Test/baseResults/constantOp.vert.out @@ -0,0 +1,375 @@ +constantOp.vert +Shader version: 460 +Requested GL_EXT_shader_explicit_arithmetic_types +0:? Sequence +0:4 Function Definition: main( ( global void) +0:4 Function Parameters: +0:5 Sequence +0:5 Sequence +0:5 move second child to first child ( temp 2-component vector of float) +0:5 'v2Base' ( temp 2-component vector of float) +0:5 Constant: +0:5 1.000000 +0:5 0.000000 +0:6 Sequence +0:6 move second child to first child ( temp uint) +0:6 'uiBase' ( temp uint) +0:6 Constant: +0:6 1 (const uint) +0:7 Sequence +0:7 move second child to first child ( temp double) +0:7 'f64Base' ( temp double) +0:7 Constant: +0:7 0.500000 +0:8 Sequence +0:8 move second child to first child ( temp float) +0:8 'hpFpBase' ( temp float) +0:8 Constant: +0:8 0.500000 +0:9 Sequence +0:9 move second child to first child ( temp int) +0:9 'hpIntBase' ( temp int) +0:9 Constant: +0:9 1 (const int) +0:10 Sequence +0:10 move second child to first child ( temp int) +0:10 'hpUintBase' ( temp int) +0:10 Constant: +0:10 1 (const int) +0:11 Sequence +0:11 move second child to first child ( temp double) +0:11 'doubleBase' ( temp double) +0:11 Constant: +0:11 0.500000 +0:12 Sequence +0:12 move second child to first child ( temp int64_t) +0:12 'i64Base' ( temp int64_t) +0:12 Constant: +0:12 1 (const int64_t) +0:13 Sequence +0:13 move second child to first child ( temp uint64_t) +0:13 'ui64Base' ( temp uint64_t) +0:13 Constant: +0:13 1 (const uint64_t) +0:14 Sequence +0:14 move second child to first child ( temp 3X3 matrix of float) +0:14 'matBase' ( temp 3X3 matrix of float) +0:16 Constant: +0:16 1.000000 +0:16 0.000000 +0:16 0.000000 +0:16 0.000000 +0:16 1.000000 +0:16 0.000000 +0:16 0.000000 +0:16 1.000000 +0:16 1.000000 +0:17 Sequence +0:17 move second child to first child ( temp 3X3 matrix of float) +0:17 'inverseMat' ( temp 3X3 matrix of float) +0:17 inverse ( global 3X3 matrix of float) +0:17 'matBase' ( temp 3X3 matrix of float) +0:18 Sequence +0:18 move second child to first child ( temp 3X3 matrix of float) +0:18 'transpMat' ( temp 3X3 matrix of float) +0:18 transpose ( global 3X3 matrix of float) +0:18 'matBase' ( temp 3X3 matrix of float) +0:19 Sequence +0:19 move second child to first child ( temp uint) +0:19 'pkSnorm216' ( temp uint) +0:19 packSnorm2x16 ( global uint) +0:19 'v2Base' ( temp 2-component vector of float) +0:20 Sequence +0:20 move second child to first child ( temp uint) +0:20 'pkUnorm216' ( temp uint) +0:20 packUnorm2x16 ( global uint) +0:20 'v2Base' ( temp 2-component vector of float) +0:21 Sequence +0:21 move second child to first child ( temp uint) +0:21 'pkHalf216' ( temp uint) +0:21 packHalf2x16 ( global uint) +0:21 'v2Base' ( temp 2-component vector of float) +0:22 Sequence +0:22 move second child to first child ( temp 2-component vector of float) +0:22 'upkSnorm216' ( temp 2-component vector of float) +0:22 unpackSnorm2x16 ( global 2-component vector of float) +0:22 'uiBase' ( temp uint) +0:23 Sequence +0:23 move second child to first child ( temp 2-component vector of float) +0:23 'upkUnorm216' ( temp 2-component vector of float) +0:23 unpackUnorm2x16 ( global 2-component vector of float) +0:23 'uiBase' ( temp uint) +0:24 Sequence +0:24 move second child to first child ( temp 2-component vector of float) +0:24 'upkHalf216' ( temp 2-component vector of float) +0:24 unpackHalf2x16 ( global 2-component vector of float) +0:24 'uiBase' ( temp uint) +0:25 Sequence +0:25 move second child to first child ( temp float) +0:25 'dtmnant' ( temp float) +0:25 determinant ( global float) +0:25 'matBase' ( temp 3X3 matrix of float) +0:26 Sequence +0:26 move second child to first child ( temp double) +0:26 'sh' ( temp double) +0:26 hyp. sine ( global double) +0:26 'f64Base' ( temp double) +0:27 Sequence +0:27 move second child to first child ( temp double) +0:27 'ch' ( temp double) +0:27 hyp. cosine ( global double) +0:27 'f64Base' ( temp double) +0:28 Sequence +0:28 move second child to first child ( temp double) +0:28 'th' ( temp double) +0:28 hyp. tangent ( global double) +0:28 'f64Base' ( temp double) +0:29 Sequence +0:29 move second child to first child ( temp double) +0:29 'ash' ( temp double) +0:29 arc hyp. sine ( global double) +0:29 'f64Base' ( temp double) +0:30 Sequence +0:30 move second child to first child ( temp double) +0:30 'ach' ( temp double) +0:30 arc hyp. cosine ( global double) +0:30 'f64Base' ( temp double) +0:31 Sequence +0:31 move second child to first child ( temp double) +0:31 'ath' ( temp double) +0:31 arc hyp. tangent ( global double) +0:31 'f64Base' ( temp double) +0:32 Sequence +0:32 move second child to first child ( temp int) +0:32 'f2i' ( temp int) +0:32 floatBitsToInt ( global int) +0:32 'hpFpBase' ( temp float) +0:33 Sequence +0:33 move second child to first child ( temp uint) +0:33 'f2ui' ( temp uint) +0:33 floatBitsToUint ( global uint) +0:33 'hpFpBase' ( temp float) +0:34 Sequence +0:34 move second child to first child ( temp float) +0:34 'i2f' ( temp float) +0:34 intBitsToFloat ( global float) +0:34 'hpIntBase' ( temp int) +0:35 Sequence +0:35 move second child to first child ( temp float) +0:35 'ui2f' ( temp float) +0:35 uintBitsToFloat ( global float) +0:35 Convert int to uint ( temp uint) +0:35 'hpUintBase' ( temp int) +0:36 Sequence +0:36 move second child to first child ( temp int64_t) +0:36 'd2i64' ( temp int64_t) +0:36 doubleBitsToInt64 ( global int64_t) +0:36 'doubleBase' ( temp double) +0:37 Sequence +0:37 move second child to first child ( temp uint64_t) +0:37 'd2ui64' ( temp uint64_t) +0:37 doubleBitsToUint64 ( global uint64_t) +0:37 'doubleBase' ( temp double) +0:38 Sequence +0:38 move second child to first child ( temp double) +0:38 'i642d' ( temp double) +0:38 int64BitsToDouble ( global double) +0:38 'i64Base' ( temp int64_t) +0:39 Sequence +0:39 move second child to first child ( temp double) +0:39 'ui642d' ( temp double) +0:39 uint64BitsToDouble ( global double) +0:39 'ui64Base' ( temp uint64_t) +0:? Linker Objects +0:? 'gl_VertexID' ( gl_VertexId int VertexId) +0:? 'gl_InstanceID' ( gl_InstanceId int InstanceId) + + +Linked vertex stage: + + +Shader version: 460 +Requested GL_EXT_shader_explicit_arithmetic_types +0:? Sequence +0:4 Function Definition: main( ( global void) +0:4 Function Parameters: +0:5 Sequence +0:5 Sequence +0:5 move second child to first child ( temp 2-component vector of float) +0:5 'v2Base' ( temp 2-component vector of float) +0:5 Constant: +0:5 1.000000 +0:5 0.000000 +0:6 Sequence +0:6 move second child to first child ( temp uint) +0:6 'uiBase' ( temp uint) +0:6 Constant: +0:6 1 (const uint) +0:7 Sequence +0:7 move second child to first child ( temp double) +0:7 'f64Base' ( temp double) +0:7 Constant: +0:7 0.500000 +0:8 Sequence +0:8 move second child to first child ( temp float) +0:8 'hpFpBase' ( temp float) +0:8 Constant: +0:8 0.500000 +0:9 Sequence +0:9 move second child to first child ( temp int) +0:9 'hpIntBase' ( temp int) +0:9 Constant: +0:9 1 (const int) +0:10 Sequence +0:10 move second child to first child ( temp int) +0:10 'hpUintBase' ( temp int) +0:10 Constant: +0:10 1 (const int) +0:11 Sequence +0:11 move second child to first child ( temp double) +0:11 'doubleBase' ( temp double) +0:11 Constant: +0:11 0.500000 +0:12 Sequence +0:12 move second child to first child ( temp int64_t) +0:12 'i64Base' ( temp int64_t) +0:12 Constant: +0:12 1 (const int64_t) +0:13 Sequence +0:13 move second child to first child ( temp uint64_t) +0:13 'ui64Base' ( temp uint64_t) +0:13 Constant: +0:13 1 (const uint64_t) +0:14 Sequence +0:14 move second child to first child ( temp 3X3 matrix of float) +0:14 'matBase' ( temp 3X3 matrix of float) +0:16 Constant: +0:16 1.000000 +0:16 0.000000 +0:16 0.000000 +0:16 0.000000 +0:16 1.000000 +0:16 0.000000 +0:16 0.000000 +0:16 1.000000 +0:16 1.000000 +0:17 Sequence +0:17 move second child to first child ( temp 3X3 matrix of float) +0:17 'inverseMat' ( temp 3X3 matrix of float) +0:17 inverse ( global 3X3 matrix of float) +0:17 'matBase' ( temp 3X3 matrix of float) +0:18 Sequence +0:18 move second child to first child ( temp 3X3 matrix of float) +0:18 'transpMat' ( temp 3X3 matrix of float) +0:18 transpose ( global 3X3 matrix of float) +0:18 'matBase' ( temp 3X3 matrix of float) +0:19 Sequence +0:19 move second child to first child ( temp uint) +0:19 'pkSnorm216' ( temp uint) +0:19 packSnorm2x16 ( global uint) +0:19 'v2Base' ( temp 2-component vector of float) +0:20 Sequence +0:20 move second child to first child ( temp uint) +0:20 'pkUnorm216' ( temp uint) +0:20 packUnorm2x16 ( global uint) +0:20 'v2Base' ( temp 2-component vector of float) +0:21 Sequence +0:21 move second child to first child ( temp uint) +0:21 'pkHalf216' ( temp uint) +0:21 packHalf2x16 ( global uint) +0:21 'v2Base' ( temp 2-component vector of float) +0:22 Sequence +0:22 move second child to first child ( temp 2-component vector of float) +0:22 'upkSnorm216' ( temp 2-component vector of float) +0:22 unpackSnorm2x16 ( global 2-component vector of float) +0:22 'uiBase' ( temp uint) +0:23 Sequence +0:23 move second child to first child ( temp 2-component vector of float) +0:23 'upkUnorm216' ( temp 2-component vector of float) +0:23 unpackUnorm2x16 ( global 2-component vector of float) +0:23 'uiBase' ( temp uint) +0:24 Sequence +0:24 move second child to first child ( temp 2-component vector of float) +0:24 'upkHalf216' ( temp 2-component vector of float) +0:24 unpackHalf2x16 ( global 2-component vector of float) +0:24 'uiBase' ( temp uint) +0:25 Sequence +0:25 move second child to first child ( temp float) +0:25 'dtmnant' ( temp float) +0:25 determinant ( global float) +0:25 'matBase' ( temp 3X3 matrix of float) +0:26 Sequence +0:26 move second child to first child ( temp double) +0:26 'sh' ( temp double) +0:26 hyp. sine ( global double) +0:26 'f64Base' ( temp double) +0:27 Sequence +0:27 move second child to first child ( temp double) +0:27 'ch' ( temp double) +0:27 hyp. cosine ( global double) +0:27 'f64Base' ( temp double) +0:28 Sequence +0:28 move second child to first child ( temp double) +0:28 'th' ( temp double) +0:28 hyp. tangent ( global double) +0:28 'f64Base' ( temp double) +0:29 Sequence +0:29 move second child to first child ( temp double) +0:29 'ash' ( temp double) +0:29 arc hyp. sine ( global double) +0:29 'f64Base' ( temp double) +0:30 Sequence +0:30 move second child to first child ( temp double) +0:30 'ach' ( temp double) +0:30 arc hyp. cosine ( global double) +0:30 'f64Base' ( temp double) +0:31 Sequence +0:31 move second child to first child ( temp double) +0:31 'ath' ( temp double) +0:31 arc hyp. tangent ( global double) +0:31 'f64Base' ( temp double) +0:32 Sequence +0:32 move second child to first child ( temp int) +0:32 'f2i' ( temp int) +0:32 floatBitsToInt ( global int) +0:32 'hpFpBase' ( temp float) +0:33 Sequence +0:33 move second child to first child ( temp uint) +0:33 'f2ui' ( temp uint) +0:33 floatBitsToUint ( global uint) +0:33 'hpFpBase' ( temp float) +0:34 Sequence +0:34 move second child to first child ( temp float) +0:34 'i2f' ( temp float) +0:34 intBitsToFloat ( global float) +0:34 'hpIntBase' ( temp int) +0:35 Sequence +0:35 move second child to first child ( temp float) +0:35 'ui2f' ( temp float) +0:35 uintBitsToFloat ( global float) +0:35 Convert int to uint ( temp uint) +0:35 'hpUintBase' ( temp int) +0:36 Sequence +0:36 move second child to first child ( temp int64_t) +0:36 'd2i64' ( temp int64_t) +0:36 doubleBitsToInt64 ( global int64_t) +0:36 'doubleBase' ( temp double) +0:37 Sequence +0:37 move second child to first child ( temp uint64_t) +0:37 'd2ui64' ( temp uint64_t) +0:37 doubleBitsToUint64 ( global uint64_t) +0:37 'doubleBase' ( temp double) +0:38 Sequence +0:38 move second child to first child ( temp double) +0:38 'i642d' ( temp double) +0:38 int64BitsToDouble ( global double) +0:38 'i64Base' ( temp int64_t) +0:39 Sequence +0:39 move second child to first child ( temp double) +0:39 'ui642d' ( temp double) +0:39 uint64BitsToDouble ( global double) +0:39 'ui64Base' ( temp uint64_t) +0:? Linker Objects +0:? 'gl_VertexID' ( gl_VertexId int VertexId) +0:? 'gl_InstanceID' ( gl_InstanceId int InstanceId) + diff --git a/Test/constantOp.vert b/Test/constantOp.vert new file mode 100644 index 0000000000..10512c20a6 --- /dev/null +++ b/Test/constantOp.vert @@ -0,0 +1,40 @@ +#version 460 core +#extension GL_EXT_shader_explicit_arithmetic_types : enable + +void main(){ + vec2 v2Base = vec2(1.0, 0.0); + uint uiBase = 1; + float64_t f64Base = 0.5; + highp float hpFpBase = 0.5; + highp int hpIntBase = 1; + highp int hpUintBase = 1; + double doubleBase = 0.5; + int64_t i64Base = 1; + uint64_t ui64Base = 1; + mat3 matBase = mat3(1.0, 0.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 1.0, 1.0); + mat3 inverseMat = inverse(matBase); // EOpMatrixInverse + mat3 transpMat = transpose(matBase); // EOpTranspose + uint pkSnorm216 = packSnorm2x16(v2Base); // EOpPackSnorm2x16 + uint pkUnorm216 = packUnorm2x16(v2Base); // EOpPackUnorm2x16 + uint pkHalf216 = packHalf2x16(v2Base); // EOpPackHalf2x16 + vec2 upkSnorm216 = unpackSnorm2x16(uiBase); // EOpUnpackSnorm2x16 + vec2 upkUnorm216 = unpackUnorm2x16(uiBase); // EOpUnpackUnorm2x16 + vec2 upkHalf216 = unpackHalf2x16(uiBase); // EOpUnpackHalf2x16 + float dtmnant = determinant(matBase); // EOpDeterminant + float64_t sh = sinh(f64Base); // EOpSinh + float64_t ch = cosh(f64Base); // EOpCosh + float64_t th = tanh(f64Base); // EOpTanh + float64_t ash = asinh(f64Base); // EOpAsinh + float64_t ach = acosh(f64Base); // EOpAcosh + float64_t ath = atanh(f64Base); // EOpAtanh + int f2i = floatBitsToInt(hpFpBase); // EOpFloatBitsToInt + uint f2ui = floatBitsToUint(hpFpBase); // EOpFloatBitsToUint + float i2f = intBitsToFloat(hpIntBase); // EOpIntBitsToFloat + float ui2f = uintBitsToFloat(hpUintBase); // EOpUintBitsToFloat + int64_t d2i64 = doubleBitsToInt64(doubleBase); // EOpDoubleBitsToInt64 + uint64_t d2ui64 = doubleBitsToUint64(doubleBase); // EOpDoubleBitsToUint64 + double i642d = int64BitsToDouble(i64Base); // EOpInt64BitsToDouble + double ui642d = uint64BitsToDouble(ui64Base); // EOpUint64BitsToDouble +} \ No newline at end of file diff --git a/glslang/MachineIndependent/Constant.cpp b/glslang/MachineIndependent/Constant.cpp index 5fc61dbb79..cc7325c26e 100644 --- a/glslang/MachineIndependent/Constant.cpp +++ b/glslang/MachineIndependent/Constant.cpp @@ -37,6 +37,7 @@ // #include "localintermediate.h" +#include "../../SPIRV/hex_float.h" #include #include #include @@ -45,6 +46,167 @@ namespace { using namespace glslang; +using namespace spvutils; + +typedef union { + double d; + int i[2]; +} DoubleIntUnion; + +// Some helper functions + +bool isNan(double x) +{ + DoubleIntUnion u; + // tough to find a platform independent library function, do it directly + u.d = x; + int bitPatternL = u.i[0]; + int bitPatternH = u.i[1]; + return (bitPatternH & 0x7ff80000) == 0x7ff80000 && + ((bitPatternH & 0xFFFFF) != 0 || bitPatternL != 0); +} + +bool isInf(double x) +{ + DoubleIntUnion u; + // tough to find a platform independent library function, do it directly + u.d = x; + int bitPatternL = u.i[0]; + int bitPatternH = u.i[1]; + return (bitPatternH & 0x7ff00000) == 0x7ff00000 && + (bitPatternH & 0xFFFFF) == 0 && bitPatternL == 0; +} + +// Convert from float32 to float16 bits (Round direct to zero) +uint16_t float32ToFloat16Bits(float input) +{ + HexFloat> in(input); + HexFloat> out(0); + + in.castTo(out, kRoundToZero); + + return (out.getBits()); +} + +// Convert from float16 to float32 (Round direct will be ignored) +float float16ToFloat32(HexFloat> input) +{ + HexFloat> in(input); + HexFloat> out(float(0)); + + in.castTo(out, kRoundToZero); + + return out.value().getAsFloat(); +} + +double clamp(const double& x, const double& minval, const double& maxval) +{ + return Min(Max(x, minval), maxval); +} + +double determinant3(const double* col1, const double* col2, const double* col3) +{ + return col1[0] * col2[1] * col3[2] + + col1[1] * col2[2] * col3[0] + + col1[2] * col2[0] * col3[1] + - col1[2] * col2[1] * col3[0] + - col1[1] * col2[0] * col3[2] + - col1[0] * col2[2] * col3[1]; +} + +void invserseMat2(const double* mat, double* inversedMat) +{ + double determinant = mat[0] * mat[3] - mat[1] * mat[2]; + inversedMat[0] = mat[3]; + inversedMat[1] = -mat[1]; + inversedMat[2] = -mat[2]; + inversedMat[3] = mat[0]; + + if (fabs(determinant) < 1e-8) + { + for (int i = 0; i < 4; ++i) + inversedMat[i] = 0.0; + } + else + { + for (int i = 0; i < 4; ++i) + inversedMat[i] /= determinant; + } +} + +void invserseMat3(const double* mat, double* inversedMat) +{ + double fC00 = mat[3 + 1] * mat[6 + 2] - mat[3 + 2] * mat[6 + 1]; + double fC10 = mat[3 + 2] * mat[6 + 0] - mat[3 + 0] * mat[6 + 2]; + double fC20 = mat[3 + 0] * mat[6 + 1] - mat[3 + 1] * mat[6 + 0]; + double determinant = mat[0 + 0] * fC00 + mat[0 + 1] * fC10 + mat[0 + 2] * fC20; + + inversedMat[0 + 0] = fC00; + inversedMat[0 + 1] = mat[0 + 2] * mat[6 + 1] - mat[0 + 1] * mat[6 + 2]; + inversedMat[0 + 2] = mat[0 + 1] * mat[3 + 2] - mat[0 + 2] * mat[3 + 1]; + inversedMat[3 + 0] = fC10; + inversedMat[3 + 1] = mat[0 + 0] * mat[6 + 2] - mat[0 + 2] * mat[6 + 0]; + inversedMat[3 + 2] = mat[0 + 2] * mat[3 + 0] - mat[0 + 0] * mat[3 + 2]; + inversedMat[6 + 0] = fC20; + inversedMat[6 + 1] = mat[0 + 1] * mat[6 + 0] - mat[0 + 0] * mat[6 + 1]; + inversedMat[6 + 2] = mat[0 + 0] * mat[3 + 1] - mat[0 + 1] * mat[3 + 0]; + + if (fabs(determinant) < 1e-8) + { + for (int i = 0; i < 9; ++i) + inversedMat[i] = 0.0; + } + else + { + for (int i = 0; i < 9; ++i) + inversedMat[i] /= determinant; + } +} + +void invserseMat4(const double* mat, double* inversedMat) +{ + double fA0 = mat[0 + 0] * mat[4 + 1] - mat[0 + 1] * mat[4 + 0]; + double fA1 = mat[0 + 0] * mat[4 + 2] - mat[0 + 2] * mat[4 + 0]; + double fA2 = mat[0 + 0] * mat[4 + 3] - mat[0 + 3] * mat[4 + 0]; + double fA3 = mat[0 + 1] * mat[4 + 2] - mat[0 + 2] * mat[4 + 1]; + double fA4 = mat[0 + 1] * mat[4 + 3] - mat[0 + 3] * mat[4 + 1]; + double fA5 = mat[0 + 2] * mat[4 + 3] - mat[0 + 3] * mat[4 + 2]; + double fB0 = mat[8 + 0] * mat[12 + 1] - mat[8 + 1] * mat[12 + 0]; + double fB1 = mat[8 + 0] * mat[12 + 2] - mat[8 + 2] * mat[12 + 0]; + double fB2 = mat[8 + 0] * mat[12 + 3] - mat[8 + 3] * mat[12 + 0]; + double fB3 = mat[8 + 1] * mat[12 + 2] - mat[8 + 2] * mat[12 + 1]; + double fB4 = mat[8 + 1] * mat[12 + 3] - mat[8 + 3] * mat[12 + 1]; + double fB5 = mat[8 + 2] * mat[12 + 3] - mat[8 + 3] * mat[12 + 2]; + double determinant = fA0 * fB5 - fA1 * fB4 + fA2 * fB3 + fA3 * fB2 - fA4 * fB1 + fA5 * fB0; + + inversedMat[0 + 0] = +mat[4 + 1] * fB5 - mat[4 + 2] * fB4 + mat[4 + 3] * fB3; + inversedMat[4 + 0] = -mat[4 + 0] * fB5 + mat[4 + 2] * fB2 - mat[4 + 3] * fB1; + inversedMat[8 + 0] = +mat[4 + 0] * fB4 - mat[4 + 1] * fB2 + mat[4 + 3] * fB0; + inversedMat[12 + 0] = -mat[4 + 0] * fB3 + mat[4 + 1] * fB1 - mat[4 + 2] * fB0; + inversedMat[0 + 1] = -mat[0 + 1] * fB5 + mat[0 + 2] * fB4 - mat[0 + 3] * fB3; + inversedMat[4 + 1] = +mat[0 + 0] * fB5 - mat[0 + 2] * fB2 + mat[0 + 3] * fB1; + inversedMat[8 + 1] = -mat[0 + 0] * fB4 + mat[0 + 1] * fB2 - mat[0 + 3] * fB0; + inversedMat[12 + 1] = +mat[0 + 0] * fB3 - mat[0 + 1] * fB1 + mat[0 + 2] * fB0; + inversedMat[0 + 2] = +mat[12 + 1] * fA5 - mat[12 + 2] * fA4 + mat[12 + 3] * fA3; + inversedMat[4 + 2] = -mat[12 + 0] * fA5 + mat[12 + 2] * fA2 - mat[12 + 3] * fA1; + inversedMat[8 + 2] = +mat[12 + 0] * fA4 - mat[12 + 1] * fA2 + mat[12 + 3] * fA0; + inversedMat[12 + 2] = -mat[12 + 0] * fA3 + mat[12 + 1] * fA1 - mat[12 + 2] * fA0; + inversedMat[0 + 3] = -mat[8 + 1] * fA5 + mat[8 + 2] * fA4 - mat[8 + 3] * fA3; + inversedMat[4 + 3] = +mat[8 + 0] * fA5 - mat[8 + 2] * fA2 + mat[8 + 3] * fA1; + inversedMat[8 + 3] = -mat[8 + 0] * fA4 + mat[8 + 1] * fA2 - mat[8 + 3] * fA0; + inversedMat[12 + 3] = +mat[8 + 0] * fA3 - mat[8 + 1] * fA1 + mat[8 + 2] * fA0; + + if (fabs(determinant) < 1e-8) + { + for (int i = 0; i < 16; ++i) + inversedMat[i] = 0.0; + } + else + { + for (int i = 0; i < 16; ++i) + inversedMat[i] /= determinant; + } +} const double pi = 3.1415926535897932384626433832795; @@ -115,7 +277,19 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right break; } - TConstUnionArray newConstArray(newComps); + // constant array resize + int resultComps = newComps; + switch (op) { + case EOpNotEqual: + case EOpEqual: + resultComps = 1; + break; + default: + resultComps = newComps; + break; + } + + TConstUnionArray newConstArray(resultComps); TType constBool(EbtBool, EvqConst); switch(op) { @@ -415,7 +589,11 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) componentWise = false; resultSize = objectSize; break; - + case EOpMatrixInverse: + case EOpTranspose: + componentWise = false; + resultSize = objectSize; + break; default: resultSize = objectSize; break; @@ -465,24 +643,152 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) } case EOpPackSnorm2x16: + { + // packSnorm2x16: round(clamp(c, -1, +1) * 32767.0) + assert(2 == objectSize); + unsigned int v = 0; + unsigned short vc; + vc = (unsigned int)(round(clamp(unionArray[0].getDConst(), -1.0, 1.0) * 32767)); + v = (unsigned int)(*(unsigned short*)&vc); + vc = (unsigned int)(round(clamp(unionArray[1].getDConst(), -1.0, 1.0) * 32767)); + v |= (unsigned int)(*(unsigned short*)&vc) << 16; + newConstArray[0].setUConst(v); + break; + } case EOpPackUnorm2x16: + { + // packUnorm2x16: round(clamp(c, 0, +1) * 65535.0) + assert(2 == objectSize); + unsigned int v = 0; + unsigned short vc; + vc = (unsigned int)(round(clamp(unionArray[0].getDConst(), 0.0, 1.0) * 65535)); + v = (unsigned int)(*(unsigned short*)&vc); + vc = (unsigned int)(round(clamp(unionArray[1].getDConst(), 0.0, 1.0) * 65535)); + v |= (unsigned int)(*(unsigned short*)&vc) << 16; + newConstArray[0].setUConst(v); + break; + } case EOpPackHalf2x16: + { + assert(2 == objectSize); + unsigned int v = 0; + v = float32ToFloat16Bits(static_cast(unionArray[0].getDConst())); + v |= float32ToFloat16Bits(static_cast(unionArray[1].getDConst())) << 16; + newConstArray[0].setUConst(v); + break; + } case EOpPack16: case EOpPack32: case EOpPack64: case EOpUnpack32: case EOpUnpack16: case EOpUnpack8: + return nullptr; case EOpUnpackSnorm2x16: + { + // unpackSnorm2x16: clamp(f / 32767.0, -1, +1) + assert(1 == objectSize); + unsigned int v = unionArray[0].getUConst(); + unsigned short vc = (unsigned short)(v & 0xFFFF); + newConstArray[0].setDConst(*(short*)&vc / 32767.0f); + vc = (unsigned short)((v >> 16) & 0xFFFF); + newConstArray[1].setDConst(*(short*)&vc / 32767.0f); + break; + } case EOpUnpackUnorm2x16: + { + // unpackUnorm2x16: f / 65535.0 + assert(1 == objectSize); + unsigned int v = unionArray[0].getUConst(); + newConstArray[0].setDConst((v & 0xFFFF) / 65535.0f); + newConstArray[1].setDConst((v >> 16) / 65535.0f); + break; + } case EOpUnpackHalf2x16: - + { + assert(1 == objectSize); + unsigned int v = unionArray[0].getUConst(); + uint16_t b0 = (unsigned short)(v & 0xFFFF); + uint16_t b1 = (unsigned short)(v >> 16); + HexFloat> v0(b0), v1(b1); + newConstArray[0].setDConst(float16ToFloat32(v0)); + newConstArray[1].setDConst(float16ToFloat32(v1)); + break; + } case EOpDeterminant: + { + double det = 0.0; + double mat[16]; + for (int i = 0; i < objectSize; ++i) + mat[i] = unionArray[i].getDConst(); + + switch (objectSize) + { + case 1: // scalar + det = mat[0]; + break; + case 4: // mat2 + det = mat[0] * mat[3] - mat[1] * mat[2]; + break; + case 9: // mat3 + det = determinant3(mat + 0, mat + 3, mat + 6); + break; + case 16:// mat4 + det = - mat[3] * determinant3(mat + 4, mat + 8, mat + 12) + + mat[7] * determinant3(mat + 0, mat + 8, mat + 12) + - mat[11] * determinant3(mat + 0, mat + 4, mat + 12) + + mat[15] * determinant3(mat + 0, mat + 4, mat + 8); + break; + default: + assert("Unsupported matrix size!"); + } + + newConstArray[0].setDConst(det); + break; + } case EOpMatrixInverse: + { + double mat[16]; + double inversedMat[16]; + + for (int i = 0; i < objectSize; ++i) + mat[i] = unionArray[i].getDConst(); + + //double determinant = 0.0; + switch (objectSize) + { + case 1: // scalar + inversedMat[0] = 1.0; + break; + case 4: // mat2 + invserseMat2(mat, inversedMat); + break; + case 9: // mat3 + invserseMat3(mat, inversedMat); + break; + case 16:// mat4 + invserseMat4(mat, inversedMat); + break; + default: + assert("Unsupported matrix size!"); + } + + for (int i = 0; i < objectSize; ++i) + newConstArray[i].setDConst(inversedMat[i]); + + break; + } case EOpTranspose: - return nullptr; + { + int numRows = getType().getMatrixRows(); + int numCols = getType().getMatrixCols(); + for (int row = 0; row < numRows; row++) + for (int col = 0; col < numCols; col++) + newConstArray[row * numCols + col].setDConst(unionArray[col * numRows + row].getDConst()); + break; + } default: assert(componentWise); break; @@ -924,20 +1230,66 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) // TODO: 3.0 Functionality: unary constant folding: the rest of the ops have to be fleshed out case EOpSinh: + newConstArray[i].setDConst(sinh(unionArray[i].getDConst())); break; case EOpCosh: + newConstArray[i].setDConst(cosh(unionArray[i].getDConst())); break; case EOpTanh: + newConstArray[i].setDConst(tanh(unionArray[i].getDConst())); break; case EOpAsinh: + newConstArray[i].setDConst(asinh(unionArray[i].getDConst())); break; case EOpAcosh: + newConstArray[i].setDConst(acosh(unionArray[i].getDConst())); break; case EOpAtanh: + newConstArray[i].setDConst(atanh(unionArray[i].getDConst())); break; case EOpFloatBitsToInt: + { + float constData = static_cast(unionArray[i].getDConst()); + newConstArray[i].setIConst(*(int*)&constData); + break; + } case EOpFloatBitsToUint: + { + float constData = static_cast(unionArray[i].getDConst()); + newConstArray[i].setUConst(*(unsigned int*)&constData); + break; + } case EOpIntBitsToFloat: + { + int constData = unionArray[i].getIConst(); + newConstArray[i].setDConst(*(float*)&constData); + break; + } case EOpUintBitsToFloat: + { + unsigned int constData = unionArray[i].getUConst(); + newConstArray[i].setDConst(*(float*)&constData); + break; + } case EOpDoubleBitsToInt64: + { + double constData = unionArray[i].getDConst(); + newConstArray[i].setI64Const(*(long long*)&constData); + break; + } case EOpDoubleBitsToUint64: + { + double constData = unionArray[i].getDConst(); + newConstArray[i].setU64Const(*(unsigned long long*)&constData); + break; + } case EOpInt64BitsToDouble: + { + long long constData = unionArray[i].getI64Const(); + newConstArray[i].setDConst(*(double*)&constData); + break; + } case EOpUint64BitsToDouble: + { + unsigned long long constData = unionArray[i].getU64Const(); + newConstArray[i].setDConst(*(double*)&constData); + break; + } case EOpFloat16BitsToInt16: case EOpFloat16BitsToUint16: case EOpInt16BitsToFloat16: @@ -1017,6 +1369,12 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) objectSize = std::max(children[0]->getAsTyped()->getType().getVectorSize(), children[2]->getAsTyped()->getType().getVectorSize()); break; + case EOpMul: + objectSize = children[0]->getAsTyped()->getType().getMatrixRows() * + children[0]->getAsTyped()->getType().getMatrixCols(); + break; + case EOpComma: + return children.back()->getAsTyped(); default: return aggrNode; } @@ -1049,6 +1407,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) { double arg0 = childConstUnions[0][arg0comp].getDConst(); double arg1 = childConstUnions[1][arg1comp].getDConst(); + assert(arg1 != 0.0); double result = arg0 - arg1 * floor(arg0 / arg1); newConstArray[comp].setDConst(result); break; @@ -1290,6 +1649,15 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) newConstArray[col * numRows + row] = childConstUnions[0][row] * childConstUnions[1][col]; break; } + case EOpMul: // matrixCompMult + { + double mat[16]; + for (int i = 0; i < objectSize; ++i) + mat[i] = childConstUnions[0][i].getDConst() * childConstUnions[1][i].getDConst(); + for (int i = 0; i< objectSize; ++i) + newConstArray[i].setDConst(mat[i]); + break; + } default: return aggrNode; } diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp index 5a9e5003de..7fa921e7e7 100644 --- a/glslang/MachineIndependent/Initialize.cpp +++ b/glslang/MachineIndependent/Initialize.cpp @@ -78,6 +78,14 @@ const char* TypeString[] = { "float", "vec2", "vec3", "vec4", "int", "ivec2", "ivec3", "ivec4", "uint", "uvec2", "uvec3", "uvec4", + "float16_t", "f16vec2","f16vec3", "f16vec4", + "double", "dvec2", "dvec3", "dvec4", + "int8_t", "i8vec2", "i8vec3", "i8vec4", + "int16_t", "i16vec2", "i16vec3", "i16vec4", + "int64_t", "i64vec2", "i64vec3", "i64vec4", + "uint8_t", "u8vec2", "u8vec3", "u8vec4", + "uint16_t", "u16vec2", "u16vec3", "u16vec4", + "uint64_t", "u64vec2", "u64vec3", "u64vec4", }; const int TypeStringCount = sizeof(TypeString) / sizeof(char*); // number of entries in 'TypeString' const int TypeStringRowShift = 2; // shift amount to go downe one row in 'TypeString' @@ -4138,6 +4146,106 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "u16vec4 unpack16(uint64_t);" "i32vec2 unpack32(int64_t);" "u32vec2 unpack32(uint64_t);" + + "float64_t radians(float64_t);" + "f64vec2 radians(f64vec2);" + "f64vec3 radians(f64vec3);" + "f64vec4 radians(f64vec4);" + + "float64_t degrees(float64_t);" + "f64vec2 degrees(f64vec2);" + "f64vec3 degrees(f64vec3);" + "f64vec4 degrees(f64vec4);" + + "float64_t sin(float64_t);" + "f64vec2 sin(f64vec2);" + "f64vec3 sin(f64vec3);" + "f64vec4 sin(f64vec4);" + + "float64_t cos(float64_t);" + "f64vec2 cos(f64vec2);" + "f64vec3 cos(f64vec3);" + "f64vec4 cos(f64vec4);" + + "float64_t tan(float64_t);" + "f64vec2 tan(f64vec2);" + "f64vec3 tan(f64vec3);" + "f64vec4 tan(f64vec4);" + + "float64_t asin(float64_t);" + "f64vec2 asin(f64vec2);" + "f64vec3 asin(f64vec3);" + "f64vec4 asin(f64vec4);" + + "float64_t acos(float64_t);" + "f64vec2 acos(f64vec2);" + "f64vec3 acos(f64vec3);" + "f64vec4 acos(f64vec4);" + + "float64_t atan(float64_t, float64_t);" + "f64vec2 atan(f64vec2, f64vec2);" + "f64vec3 atan(f64vec3, f64vec3);" + "f64vec4 atan(f64vec4, f64vec4);" + + "float64_t atan(float64_t);" + "f64vec2 atan(f64vec2);" + "f64vec3 atan(f64vec3);" + "f64vec4 atan(f64vec4);" + + "float64_t sinh(float64_t);" + "f64vec2 sinh(f64vec2);" + "f64vec3 sinh(f64vec3);" + "f64vec4 sinh(f64vec4);" + + "float64_t cosh(float64_t);" + "f64vec2 cosh(f64vec2);" + "f64vec3 cosh(f64vec3);" + "f64vec4 cosh(f64vec4);" + + "float64_t tanh(float64_t);" + "f64vec2 tanh(f64vec2);" + "f64vec3 tanh(f64vec3);" + "f64vec4 tanh(f64vec4);" + + "float64_t asinh(float64_t);" + "f64vec2 asinh(f64vec2);" + "f64vec3 asinh(f64vec3);" + "f64vec4 asinh(f64vec4);" + + "float64_t acosh(float64_t);" + "f64vec2 acosh(f64vec2);" + "f64vec3 acosh(f64vec3);" + "f64vec4 acosh(f64vec4);" + + "float64_t atanh(float64_t);" + "f64vec2 atanh(f64vec2);" + "f64vec3 atanh(f64vec3);" + "f64vec4 atanh(f64vec4);" + + "float64_t pow(float64_t, float64_t);" + "f64vec2 pow(f64vec2, f64vec2);" + "f64vec3 pow(f64vec3, f64vec3);" + "f64vec4 pow(f64vec4, f64vec4);" + + "float64_t exp(float64_t);" + "f64vec2 exp(f64vec2);" + "f64vec3 exp(f64vec3);" + "f64vec4 exp(f64vec4);" + + "float64_t log(float64_t);" + "f64vec2 log(f64vec2);" + "f64vec3 log(f64vec3);" + "f64vec4 log(f64vec4);" + + "float64_t exp2(float64_t);" + "f64vec2 exp2(f64vec2);" + "f64vec3 exp2(f64vec3);" + "f64vec4 exp2(f64vec4);" + + "float64_t log2(float64_t);" + "f64vec2 log2(f64vec2);" + "f64vec3 log2(f64vec3);" + "f64vec4 log2(f64vec4);" "\n"); } diff --git a/glslang/MachineIndependent/intermOut.cpp b/glslang/MachineIndependent/intermOut.cpp index a79a6928bc..21e7b8b68e 100644 --- a/glslang/MachineIndependent/intermOut.cpp +++ b/glslang/MachineIndependent/intermOut.cpp @@ -48,6 +48,37 @@ #endif #include +namespace { + +bool IsInfinity(double x) { +#ifdef _MSC_VER + switch (_fpclass(x)) { + case _FPCLASS_NINF: + case _FPCLASS_PINF: + return true; + default: + return false; + } +#else + return std::isinf(x); +#endif +} + +bool IsNan(double x) { +#ifdef _MSC_VER + switch (_fpclass(x)) { + case _FPCLASS_SNAN: + case _FPCLASS_QNAN: + return true; + default: + return false; + } +#else + return std::isnan(x); +#endif +} + +} namespace glslang { diff --git a/gtests/AST.FromFile.cpp b/gtests/AST.FromFile.cpp index 1d975464f1..25901ffc1a 100644 --- a/gtests/AST.FromFile.cpp +++ b/gtests/AST.FromFile.cpp @@ -295,7 +295,8 @@ INSTANTIATE_TEST_SUITE_P( "EndStreamPrimitive.geom", "floatBitsToInt.vert", "coord_conventions.frag", - "gl_FragCoord.frag" + "gl_FragCoord.frag", + "constantOp.vert" })), FileNameAsCustomTestSuffix );