From 1ea1b13f388a06cbfa363585657eec7f4fc189a7 Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Thu, 24 May 2018 18:11:47 -0600 Subject: [PATCH 1/3] Testing: Add new tests, and new ways of testing, for floating-point. - Adds a pragma to see binary output of double values (not portable) - Print decimals that show more values, but in a portable way (lots of portability issues) - Expand the tests to test more double values Note: it is quite difficult to have 100% portable tests for floating point. The current situation works by not printing full precision, and working around several portability issues. --- Test/baseResults/cppPassMacroName.frag.out | 106 +- Test/baseResults/lineContinuation.vert.out | 4 +- Test/baseResults/numeral.frag.out | 4 +- Test/baseResults/stringToDouble.vert.out | 903 ++++++++++++++++++ Test/cppPassMacroName.frag | 18 + Test/stringToDouble.vert | 98 ++ Test/tokenLength.vert | 2 +- glslang/MachineIndependent/ParseHelper.cpp | 3 +- glslang/MachineIndependent/intermOut.cpp | 93 +- .../MachineIndependent/localintermediate.h | 7 +- gtests/AST.FromFile.cpp | 1 + 11 files changed, 1161 insertions(+), 78 deletions(-) create mode 100755 Test/baseResults/stringToDouble.vert.out mode change 100644 => 100755 Test/cppPassMacroName.frag create mode 100755 Test/stringToDouble.vert mode change 100644 => 100755 Test/tokenLength.vert mode change 100644 => 100755 glslang/MachineIndependent/ParseHelper.cpp mode change 100644 => 100755 glslang/MachineIndependent/intermOut.cpp mode change 100644 => 100755 glslang/MachineIndependent/localintermediate.h mode change 100644 => 100755 gtests/AST.FromFile.cpp diff --git a/Test/baseResults/cppPassMacroName.frag.out b/Test/baseResults/cppPassMacroName.frag.out index d8459b3bc..e09b00d7e 100755 --- a/Test/baseResults/cppPassMacroName.frag.out +++ b/Test/baseResults/cppPassMacroName.frag.out @@ -1,33 +1,38 @@ cppPassMacroName.frag Shader version: 100 0:? Sequence -0:5 Function Definition: main( ( global void) -0:5 Function Parameters: -0:7 Sequence -0:7 Sequence -0:7 move second child to first child ( temp mediump int) -0:7 'f1' ( temp mediump int) -0:7 Constant: -0:7 4 (const int) -0:8 Sequence -0:8 move second child to first child ( temp mediump int) -0:8 'f2' ( temp mediump int) -0:8 'f1' ( temp mediump int) -0:9 Sequence -0:9 move second child to first child ( temp mediump int) -0:9 'f3' ( temp mediump int) -0:9 Constant: -0:9 9 (const int) -0:10 Sequence -0:10 move second child to first child ( temp mediump int) -0:10 'f4' ( temp mediump int) -0:10 Constant: -0:10 1 (const int) +0:9 Function Definition: main( ( global void) +0:9 Function Parameters: +0:11 Sequence 0:11 Sequence 0:11 move second child to first child ( temp mediump int) -0:11 'f5' ( temp mediump int) +0:11 'f1' ( temp mediump int) 0:11 Constant: -0:11 5 (const int) +0:11 4 (const int) +0:12 Sequence +0:12 move second child to first child ( temp mediump int) +0:12 'f2' ( temp mediump int) +0:12 'f1' ( temp mediump int) +0:13 Sequence +0:13 move second child to first child ( temp mediump int) +0:13 'f3' ( temp mediump int) +0:13 Constant: +0:13 9 (const int) +0:14 Sequence +0:14 move second child to first child ( temp mediump int) +0:14 'f4' ( temp mediump int) +0:14 Constant: +0:14 1 (const int) +0:15 Sequence +0:15 move second child to first child ( temp mediump int) +0:15 'f5' ( temp mediump int) +0:15 Constant: +0:15 5 (const int) +0:17 Sequence +0:17 move second child to first child ( temp highp float) +0:17 'fl_f5' ( temp highp float) +0:17 Constant: +0:17 0.460000 0:? Linker Objects @@ -36,32 +41,37 @@ Linked fragment stage: Shader version: 100 0:? Sequence -0:5 Function Definition: main( ( global void) -0:5 Function Parameters: -0:7 Sequence -0:7 Sequence -0:7 move second child to first child ( temp mediump int) -0:7 'f1' ( temp mediump int) -0:7 Constant: -0:7 4 (const int) -0:8 Sequence -0:8 move second child to first child ( temp mediump int) -0:8 'f2' ( temp mediump int) -0:8 'f1' ( temp mediump int) -0:9 Sequence -0:9 move second child to first child ( temp mediump int) -0:9 'f3' ( temp mediump int) -0:9 Constant: -0:9 9 (const int) -0:10 Sequence -0:10 move second child to first child ( temp mediump int) -0:10 'f4' ( temp mediump int) -0:10 Constant: -0:10 1 (const int) +0:9 Function Definition: main( ( global void) +0:9 Function Parameters: +0:11 Sequence 0:11 Sequence 0:11 move second child to first child ( temp mediump int) -0:11 'f5' ( temp mediump int) +0:11 'f1' ( temp mediump int) 0:11 Constant: -0:11 5 (const int) +0:11 4 (const int) +0:12 Sequence +0:12 move second child to first child ( temp mediump int) +0:12 'f2' ( temp mediump int) +0:12 'f1' ( temp mediump int) +0:13 Sequence +0:13 move second child to first child ( temp mediump int) +0:13 'f3' ( temp mediump int) +0:13 Constant: +0:13 9 (const int) +0:14 Sequence +0:14 move second child to first child ( temp mediump int) +0:14 'f4' ( temp mediump int) +0:14 Constant: +0:14 1 (const int) +0:15 Sequence +0:15 move second child to first child ( temp mediump int) +0:15 'f5' ( temp mediump int) +0:15 Constant: +0:15 5 (const int) +0:17 Sequence +0:17 move second child to first child ( temp highp float) +0:17 'fl_f5' ( temp highp float) +0:17 Constant: +0:17 0.460000 0:? Linker Objects diff --git a/Test/baseResults/lineContinuation.vert.out b/Test/baseResults/lineContinuation.vert.out index 3dd820610..9faa420b3 100644 --- a/Test/baseResults/lineContinuation.vert.out +++ b/Test/baseResults/lineContinuation.vert.out @@ -66,7 +66,7 @@ ERROR: node is still EOpNull! 0:74 move second child to first child ( temp highp float) 0:74 'funkyf' ( global highp float) 0:75 Constant: -0:75 12300000000000000.000000 +0:75 1.2300000000000e+16 0:85 Sequence 0:84 move second child to first child ( temp highp int) 0:84 'funkyh' ( global highp int) @@ -200,7 +200,7 @@ ERROR: node is still EOpNull! 0:74 move second child to first child ( temp highp float) 0:74 'funkyf' ( global highp float) 0:75 Constant: -0:75 12300000000000000.000000 +0:75 1.2300000000000e+16 0:85 Sequence 0:84 move second child to first child ( temp highp int) 0:84 'funkyh' ( global highp int) diff --git a/Test/baseResults/numeral.frag.out b/Test/baseResults/numeral.frag.out index a7343f9c0..b7c0a78b7 100644 --- a/Test/baseResults/numeral.frag.out +++ b/Test/baseResults/numeral.frag.out @@ -330,7 +330,7 @@ ERROR: node is still EOpNull! 0:73 move second child to first child ( temp float) 0:73 'g6' ( temp float) 0:73 Constant: -0:73 0.000005 +0:73 5.0000000000000e-06 0:74 Sequence 0:74 move second child to first child ( temp float) 0:74 'g7' ( temp float) @@ -739,7 +739,7 @@ ERROR: node is still EOpNull! 0:73 move second child to first child ( temp float) 0:73 'g6' ( temp float) 0:73 Constant: -0:73 0.000005 +0:73 5.0000000000000e-06 0:74 Sequence 0:74 move second child to first child ( temp float) 0:74 'g7' ( temp float) diff --git a/Test/baseResults/stringToDouble.vert.out b/Test/baseResults/stringToDouble.vert.out new file mode 100755 index 000000000..c85fc5851 --- /dev/null +++ b/Test/baseResults/stringToDouble.vert.out @@ -0,0 +1,903 @@ +stringToDouble.vert +Shader version: 460 +0:? Sequence +0:3 Function Definition: main( ( global void) +0:3 Function Parameters: +0:5 Sequence +0:5 Sequence +0:5 move second child to first child ( temp float) +0:5 'w1' ( temp float) +0:5 Constant: +0:5 0.000000 +0:6 Sequence +0:6 move second child to first child ( temp float) +0:6 'w2' ( temp float) +0:6 Constant: +0:6 1.000000 +0:7 Sequence +0:7 move second child to first child ( temp float) +0:7 'w3' ( temp float) +0:7 Constant: +0:7 7.000000 +0:8 Sequence +0:8 move second child to first child ( temp float) +0:8 'w4' ( temp float) +0:8 Constant: +0:8 130000.000000 +0:9 Sequence +0:9 move second child to first child ( temp float) +0:9 'w5' ( temp float) +0:9 Constant: +0:9 123456789.000000 +0:10 Sequence +0:10 move second child to first child ( temp double) +0:10 'w6' ( temp double) +0:10 Constant: +0:10 1.2345678901235e+15 +0:11 Sequence +0:11 move second child to first child ( temp double) +0:11 'w7' ( temp double) +0:11 Constant: +0:11 1.2345678901235e+16 +0:12 Sequence +0:12 move second child to first child ( temp double) +0:12 'w8' ( temp double) +0:12 Constant: +0:12 1.2345678901235e+17 +0:13 Sequence +0:13 move second child to first child ( temp double) +0:13 'w9' ( temp double) +0:13 Constant: +0:13 1.2345678901235e+19 +0:14 Sequence +0:14 move second child to first child ( temp double) +0:14 'w10' ( temp double) +0:14 Constant: +0:14 1.2345678901235e+24 +0:16 Sequence +0:16 move second child to first child ( temp float) +0:16 'e1' ( temp float) +0:16 Constant: +0:16 0.000000 +0:17 Sequence +0:17 move second child to first child ( temp float) +0:17 'e2' ( temp float) +0:17 Constant: +0:17 1.000000 +0:18 Sequence +0:18 move second child to first child ( temp float) +0:18 'e3' ( temp float) +0:18 Constant: +0:18 0.000000 +0:19 Sequence +0:19 move second child to first child ( temp float) +0:19 'e4' ( temp float) +0:19 Constant: +0:19 1.0000000000000e+15 +0:20 Sequence +0:20 move second child to first child ( temp float) +0:20 'e5' ( temp float) +0:20 Constant: +0:20 1.0000000000000e+16 +0:21 Sequence +0:21 move second child to first child ( temp float) +0:21 'e6' ( temp float) +0:21 Constant: +0:21 0.000000 +0:22 Sequence +0:22 move second child to first child ( temp float) +0:22 'e7' ( temp float) +0:22 Constant: +0:22 1.0000000000000e-15 +0:23 Sequence +0:23 move second child to first child ( temp float) +0:23 'e8' ( temp float) +0:23 Constant: +0:23 1.0000000000000e-16 +0:24 Sequence +0:24 move second child to first child ( temp double) +0:24 'e9' ( temp double) +0:24 Constant: +0:24 1.0000000000000e+100 +0:25 Sequence +0:25 move second child to first child ( temp double) +0:25 'e10' ( temp double) +0:25 Constant: +0:25 1.0000000000000e+308 +0:26 Sequence +0:26 move second child to first child ( temp double) +0:26 'e11' ( temp double) +0:26 Constant: +0:26 9.8813129168249e-324 +0:27 Sequence +0:27 move second child to first child ( temp double) +0:27 'e12' ( temp double) +0:27 Constant: +0:27 +1.#INF +0:28 Sequence +0:28 move second child to first child ( temp double) +0:28 'e13' ( temp double) +0:28 Constant: +0:28 0.000000 +0:29 Sequence +0:29 move second child to first child ( temp double) +0:29 'e24' ( temp double) +0:29 Constant: +0:29 +1.#INF +0:30 Sequence +0:30 move second child to first child ( temp double) +0:30 'e25' ( temp double) +0:30 Constant: +0:30 0.000000 +0:32 Sequence +0:32 move second child to first child ( temp double) +0:32 'f1' ( temp double) +0:32 Constant: +0:32 0.500000 +0:33 Sequence +0:33 move second child to first child ( temp double) +0:33 'f2' ( temp double) +0:33 Constant: +0:33 0.125000 +0:34 Sequence +0:34 move second child to first child ( temp double) +0:34 'f31' ( temp double) +0:34 Constant: +0:34 0.100000 +0:35 Sequence +0:35 move second child to first child ( temp double) +0:35 'f32' ( temp double) +0:35 Constant: +0:35 0.200000 +0:36 Sequence +0:36 move second child to first child ( temp double) +0:36 'f33' ( temp double) +0:36 Constant: +0:36 0.300000 +0:37 Sequence +0:37 move second child to first child ( temp double) +0:37 'f34' ( temp double) +0:37 Constant: +0:37 0.400000 +0:38 Sequence +0:38 move second child to first child ( temp double) +0:38 'f35' ( temp double) +0:38 Constant: +0:38 0.500000 +0:39 Sequence +0:39 move second child to first child ( temp double) +0:39 'f36' ( temp double) +0:39 Constant: +0:39 0.600000 +0:40 Sequence +0:40 move second child to first child ( temp double) +0:40 'f37' ( temp double) +0:40 Constant: +0:40 0.700000 +0:41 Sequence +0:41 move second child to first child ( temp double) +0:41 'f38' ( temp double) +0:41 Constant: +0:41 0.800000 +0:42 Sequence +0:42 move second child to first child ( temp double) +0:42 'f39' ( temp double) +0:42 Constant: +0:42 0.900000 +0:43 Sequence +0:43 move second child to first child ( temp double) +0:43 'f4' ( temp double) +0:43 Constant: +0:43 0.333333 +0:44 Sequence +0:44 move second child to first child ( temp double) +0:44 'f51' ( temp double) +0:44 Constant: +0:44 7.8347500000000e-37 +0:45 Sequence +0:45 move second child to first child ( temp double) +0:45 'f52' ( temp double) +0:45 Constant: +0:45 7.8347500000000e-37 +0:46 Sequence +0:46 move second child to first child ( temp double) +0:46 'f53' ( temp double) +0:46 Constant: +0:46 7.8347500000000e-37 +0:47 Sequence +0:47 move second child to first child ( temp double) +0:47 'f54' ( temp double) +0:47 Constant: +0:47 7.8347500000000e-37 +0:48 Sequence +0:48 move second child to first child ( temp double) +0:48 'f61' ( temp double) +0:48 Constant: +0:48 4.000000 +0:49 Sequence +0:49 move second child to first child ( temp double) +0:49 'f62' ( temp double) +0:49 Constant: +0:49 40.000000 +0:50 Sequence +0:50 move second child to first child ( temp double) +0:50 'f63' ( temp double) +0:50 Constant: +0:50 0.000000 +0:51 Sequence +0:51 move second child to first child ( temp double) +0:51 'f64' ( temp double) +0:51 Constant: +0:51 4.000000 +0:52 Sequence +0:52 move second child to first child ( temp double) +0:52 'f65' ( temp double) +0:52 Constant: +0:52 0.000000 +0:53 Sequence +0:53 move second child to first child ( temp double) +0:53 'f66' ( temp double) +0:53 Constant: +0:53 0.004000 +0:54 Sequence +0:54 move second child to first child ( temp double) +0:54 'f67' ( temp double) +0:54 Constant: +0:54 0.400000 +0:55 Sequence +0:55 move second child to first child ( temp double) +0:55 'f68' ( temp double) +0:55 Constant: +0:55 0.040000 +0:57 Sequence +0:57 move second child to first child ( temp double) +0:57 'c1' ( temp double) +0:57 Constant: +0:57 0.000810 +0:58 Sequence +0:58 move second child to first child ( temp double) +0:58 'c2' ( temp double) +0:58 Constant: +0:58 7.300000 +0:59 Sequence +0:59 move second child to first child ( temp double) +0:59 'c3' ( temp double) +0:59 Constant: +0:59 3.450000 +0:60 Sequence +0:60 move second child to first child ( temp double) +0:60 'c4' ( temp double) +0:60 Constant: +0:60 0.003570 +0:61 Sequence +0:61 move second child to first child ( temp double) +0:61 'c5' ( temp double) +0:61 Constant: +0:61 439.000000 +0:62 Sequence +0:62 move second child to first child ( temp double) +0:62 'c6' ( temp double) +0:62 Constant: +0:62 522000.000000 +0:63 Sequence +0:63 move second child to first child ( temp double) +0:63 'c7' ( temp double) +0:63 Constant: +0:63 61000000.000000 +0:64 Sequence +0:64 move second child to first child ( temp double) +0:64 'c8' ( temp double) +0:64 Constant: +0:64 0.610000 +0:65 Sequence +0:65 move second child to first child ( temp double) +0:65 'c9' ( temp double) +0:65 Constant: +0:65 1.2345678901235e+18 +0:66 Sequence +0:66 move second child to first child ( temp double) +0:66 'c10' ( temp double) +0:66 Constant: +0:66 1.0000000000000e+21 +0:67 Sequence +0:67 move second child to first child ( temp double) +0:67 'c11' ( temp double) +0:67 Constant: +0:67 1230000.004560 +0:68 Sequence +0:68 move second child to first child ( temp double) +0:68 'c12' ( temp double) +0:68 Constant: +0:68 1230.000004 +0:69 Sequence +0:69 move second child to first child ( temp double) +0:69 'c13' ( temp double) +0:69 Constant: +0:69 123.000000 +0:70 Sequence +0:70 move second child to first child ( temp double) +0:70 'c14' ( temp double) +0:70 Constant: +0:70 102.300000 +0:71 Sequence +0:71 move second child to first child ( temp double) +0:71 'c15' ( temp double) +0:71 Constant: +0:71 1.2003000000456e+12 +0:72 Sequence +0:72 move second child to first child ( temp double) +0:72 'c16' ( temp double) +0:72 Constant: +0:72 123000000456.000000 +0:73 Sequence +0:73 move second child to first child ( temp double) +0:73 'c17' ( temp double) +0:73 Constant: +0:73 1.2300000045600e+12 +0:74 Sequence +0:74 move second child to first child ( temp double) +0:74 'c18' ( temp double) +0:74 Constant: +0:74 1.2300000045601e+12 +0:76 Sequence +0:76 move second child to first child ( temp double) +0:76 'b11' ( temp double) +0:76 Constant: +0:76 7.2057594037928e+16 +0:77 Sequence +0:77 move second child to first child ( temp double) +0:77 'b12' ( temp double) +0:77 Constant: +0:77 7.2057594037928e+16 +0:78 Sequence +0:78 move second child to first child ( temp double) +0:78 'b13' ( temp double) +0:78 Constant: +0:78 7.2057594037928e+16 +0:79 Sequence +0:79 move second child to first child ( temp double) +0:79 'b14' ( temp double) +0:79 Constant: +0:79 7.2057594037928e+16 +0:80 Sequence +0:80 move second child to first child ( temp double) +0:80 'b15' ( temp double) +0:80 Constant: +0:80 7.2057594037928e+16 +0:81 Sequence +0:81 move second child to first child ( temp double) +0:81 'b21' ( temp double) +0:81 Constant: +0:81 9.2233720368548e+18 +0:82 Sequence +0:82 move second child to first child ( temp double) +0:82 'b22' ( temp double) +0:82 Constant: +0:82 9.2233720368548e+18 +0:83 Sequence +0:83 move second child to first child ( temp double) +0:83 'b23' ( temp double) +0:83 Constant: +0:83 9.2233720368548e+18 +0:84 Sequence +0:84 move second child to first child ( temp double) +0:84 'b24' ( temp double) +0:84 Constant: +0:84 9.2233720368548e+18 +0:85 Sequence +0:85 move second child to first child ( temp double) +0:85 'b25' ( temp double) +0:85 Constant: +0:85 9.2233720368548e+18 +0:86 Sequence +0:86 move second child to first child ( temp double) +0:86 'b31' ( temp double) +0:86 Constant: +0:86 1.0141204801826e+31 +0:87 Sequence +0:87 move second child to first child ( temp double) +0:87 'b32' ( temp double) +0:87 Constant: +0:87 1.0141204801826e+31 +0:88 Sequence +0:88 move second child to first child ( temp double) +0:88 'b33' ( temp double) +0:88 Constant: +0:88 1.0141204801826e+31 +0:89 Sequence +0:89 move second child to first child ( temp double) +0:89 'b34' ( temp double) +0:89 Constant: +0:89 1.0141204801826e+31 +0:90 Sequence +0:90 move second child to first child ( temp double) +0:90 'b35' ( temp double) +0:90 Constant: +0:90 1.0141204801826e+31 +0:91 Sequence +0:91 move second child to first child ( temp double) +0:91 'b41' ( temp double) +0:91 Constant: +0:91 5.7089907708238e+45 +0:92 Sequence +0:92 move second child to first child ( temp double) +0:92 'b42' ( temp double) +0:92 Constant: +0:92 5.7089907708238e+45 +0:93 Sequence +0:93 move second child to first child ( temp double) +0:93 'b43' ( temp double) +0:93 Constant: +0:93 5.7089907708238e+45 +0:94 Sequence +0:94 move second child to first child ( temp double) +0:94 'b44' ( temp double) +0:94 Constant: +0:94 5.7089907708238e+45 +0:95 Sequence +0:95 move second child to first child ( temp double) +0:95 'b45' ( temp double) +0:95 Constant: +0:95 5.7089907708238e+45 +0:97 Sequence +0:97 move second child to first child ( temp double) +0:97 'pi' ( temp double) +0:97 Constant: +0:97 3.141593 +0:? Linker Objects +0:? 'gl_VertexID' ( gl_VertexId int VertexId) +0:? 'gl_InstanceID' ( gl_InstanceId int InstanceId) + + +Linked vertex stage: + + +Shader version: 460 +0:? Sequence +0:3 Function Definition: main( ( global void) +0:3 Function Parameters: +0:5 Sequence +0:5 Sequence +0:5 move second child to first child ( temp float) +0:5 'w1' ( temp float) +0:5 Constant: +0:5 0.000000 +0:6 Sequence +0:6 move second child to first child ( temp float) +0:6 'w2' ( temp float) +0:6 Constant: +0:6 1.000000 +0:7 Sequence +0:7 move second child to first child ( temp float) +0:7 'w3' ( temp float) +0:7 Constant: +0:7 7.000000 +0:8 Sequence +0:8 move second child to first child ( temp float) +0:8 'w4' ( temp float) +0:8 Constant: +0:8 130000.000000 +0:9 Sequence +0:9 move second child to first child ( temp float) +0:9 'w5' ( temp float) +0:9 Constant: +0:9 123456789.000000 +0:10 Sequence +0:10 move second child to first child ( temp double) +0:10 'w6' ( temp double) +0:10 Constant: +0:10 1.2345678901235e+15 +0:11 Sequence +0:11 move second child to first child ( temp double) +0:11 'w7' ( temp double) +0:11 Constant: +0:11 1.2345678901235e+16 +0:12 Sequence +0:12 move second child to first child ( temp double) +0:12 'w8' ( temp double) +0:12 Constant: +0:12 1.2345678901235e+17 +0:13 Sequence +0:13 move second child to first child ( temp double) +0:13 'w9' ( temp double) +0:13 Constant: +0:13 1.2345678901235e+19 +0:14 Sequence +0:14 move second child to first child ( temp double) +0:14 'w10' ( temp double) +0:14 Constant: +0:14 1.2345678901235e+24 +0:16 Sequence +0:16 move second child to first child ( temp float) +0:16 'e1' ( temp float) +0:16 Constant: +0:16 0.000000 +0:17 Sequence +0:17 move second child to first child ( temp float) +0:17 'e2' ( temp float) +0:17 Constant: +0:17 1.000000 +0:18 Sequence +0:18 move second child to first child ( temp float) +0:18 'e3' ( temp float) +0:18 Constant: +0:18 0.000000 +0:19 Sequence +0:19 move second child to first child ( temp float) +0:19 'e4' ( temp float) +0:19 Constant: +0:19 1.0000000000000e+15 +0:20 Sequence +0:20 move second child to first child ( temp float) +0:20 'e5' ( temp float) +0:20 Constant: +0:20 1.0000000000000e+16 +0:21 Sequence +0:21 move second child to first child ( temp float) +0:21 'e6' ( temp float) +0:21 Constant: +0:21 0.000000 +0:22 Sequence +0:22 move second child to first child ( temp float) +0:22 'e7' ( temp float) +0:22 Constant: +0:22 1.0000000000000e-15 +0:23 Sequence +0:23 move second child to first child ( temp float) +0:23 'e8' ( temp float) +0:23 Constant: +0:23 1.0000000000000e-16 +0:24 Sequence +0:24 move second child to first child ( temp double) +0:24 'e9' ( temp double) +0:24 Constant: +0:24 1.0000000000000e+100 +0:25 Sequence +0:25 move second child to first child ( temp double) +0:25 'e10' ( temp double) +0:25 Constant: +0:25 1.0000000000000e+308 +0:26 Sequence +0:26 move second child to first child ( temp double) +0:26 'e11' ( temp double) +0:26 Constant: +0:26 9.8813129168249e-324 +0:27 Sequence +0:27 move second child to first child ( temp double) +0:27 'e12' ( temp double) +0:27 Constant: +0:27 +1.#INF +0:28 Sequence +0:28 move second child to first child ( temp double) +0:28 'e13' ( temp double) +0:28 Constant: +0:28 0.000000 +0:29 Sequence +0:29 move second child to first child ( temp double) +0:29 'e24' ( temp double) +0:29 Constant: +0:29 +1.#INF +0:30 Sequence +0:30 move second child to first child ( temp double) +0:30 'e25' ( temp double) +0:30 Constant: +0:30 0.000000 +0:32 Sequence +0:32 move second child to first child ( temp double) +0:32 'f1' ( temp double) +0:32 Constant: +0:32 0.500000 +0:33 Sequence +0:33 move second child to first child ( temp double) +0:33 'f2' ( temp double) +0:33 Constant: +0:33 0.125000 +0:34 Sequence +0:34 move second child to first child ( temp double) +0:34 'f31' ( temp double) +0:34 Constant: +0:34 0.100000 +0:35 Sequence +0:35 move second child to first child ( temp double) +0:35 'f32' ( temp double) +0:35 Constant: +0:35 0.200000 +0:36 Sequence +0:36 move second child to first child ( temp double) +0:36 'f33' ( temp double) +0:36 Constant: +0:36 0.300000 +0:37 Sequence +0:37 move second child to first child ( temp double) +0:37 'f34' ( temp double) +0:37 Constant: +0:37 0.400000 +0:38 Sequence +0:38 move second child to first child ( temp double) +0:38 'f35' ( temp double) +0:38 Constant: +0:38 0.500000 +0:39 Sequence +0:39 move second child to first child ( temp double) +0:39 'f36' ( temp double) +0:39 Constant: +0:39 0.600000 +0:40 Sequence +0:40 move second child to first child ( temp double) +0:40 'f37' ( temp double) +0:40 Constant: +0:40 0.700000 +0:41 Sequence +0:41 move second child to first child ( temp double) +0:41 'f38' ( temp double) +0:41 Constant: +0:41 0.800000 +0:42 Sequence +0:42 move second child to first child ( temp double) +0:42 'f39' ( temp double) +0:42 Constant: +0:42 0.900000 +0:43 Sequence +0:43 move second child to first child ( temp double) +0:43 'f4' ( temp double) +0:43 Constant: +0:43 0.333333 +0:44 Sequence +0:44 move second child to first child ( temp double) +0:44 'f51' ( temp double) +0:44 Constant: +0:44 7.8347500000000e-37 +0:45 Sequence +0:45 move second child to first child ( temp double) +0:45 'f52' ( temp double) +0:45 Constant: +0:45 7.8347500000000e-37 +0:46 Sequence +0:46 move second child to first child ( temp double) +0:46 'f53' ( temp double) +0:46 Constant: +0:46 7.8347500000000e-37 +0:47 Sequence +0:47 move second child to first child ( temp double) +0:47 'f54' ( temp double) +0:47 Constant: +0:47 7.8347500000000e-37 +0:48 Sequence +0:48 move second child to first child ( temp double) +0:48 'f61' ( temp double) +0:48 Constant: +0:48 4.000000 +0:49 Sequence +0:49 move second child to first child ( temp double) +0:49 'f62' ( temp double) +0:49 Constant: +0:49 40.000000 +0:50 Sequence +0:50 move second child to first child ( temp double) +0:50 'f63' ( temp double) +0:50 Constant: +0:50 0.000000 +0:51 Sequence +0:51 move second child to first child ( temp double) +0:51 'f64' ( temp double) +0:51 Constant: +0:51 4.000000 +0:52 Sequence +0:52 move second child to first child ( temp double) +0:52 'f65' ( temp double) +0:52 Constant: +0:52 0.000000 +0:53 Sequence +0:53 move second child to first child ( temp double) +0:53 'f66' ( temp double) +0:53 Constant: +0:53 0.004000 +0:54 Sequence +0:54 move second child to first child ( temp double) +0:54 'f67' ( temp double) +0:54 Constant: +0:54 0.400000 +0:55 Sequence +0:55 move second child to first child ( temp double) +0:55 'f68' ( temp double) +0:55 Constant: +0:55 0.040000 +0:57 Sequence +0:57 move second child to first child ( temp double) +0:57 'c1' ( temp double) +0:57 Constant: +0:57 0.000810 +0:58 Sequence +0:58 move second child to first child ( temp double) +0:58 'c2' ( temp double) +0:58 Constant: +0:58 7.300000 +0:59 Sequence +0:59 move second child to first child ( temp double) +0:59 'c3' ( temp double) +0:59 Constant: +0:59 3.450000 +0:60 Sequence +0:60 move second child to first child ( temp double) +0:60 'c4' ( temp double) +0:60 Constant: +0:60 0.003570 +0:61 Sequence +0:61 move second child to first child ( temp double) +0:61 'c5' ( temp double) +0:61 Constant: +0:61 439.000000 +0:62 Sequence +0:62 move second child to first child ( temp double) +0:62 'c6' ( temp double) +0:62 Constant: +0:62 522000.000000 +0:63 Sequence +0:63 move second child to first child ( temp double) +0:63 'c7' ( temp double) +0:63 Constant: +0:63 61000000.000000 +0:64 Sequence +0:64 move second child to first child ( temp double) +0:64 'c8' ( temp double) +0:64 Constant: +0:64 0.610000 +0:65 Sequence +0:65 move second child to first child ( temp double) +0:65 'c9' ( temp double) +0:65 Constant: +0:65 1.2345678901235e+18 +0:66 Sequence +0:66 move second child to first child ( temp double) +0:66 'c10' ( temp double) +0:66 Constant: +0:66 1.0000000000000e+21 +0:67 Sequence +0:67 move second child to first child ( temp double) +0:67 'c11' ( temp double) +0:67 Constant: +0:67 1230000.004560 +0:68 Sequence +0:68 move second child to first child ( temp double) +0:68 'c12' ( temp double) +0:68 Constant: +0:68 1230.000004 +0:69 Sequence +0:69 move second child to first child ( temp double) +0:69 'c13' ( temp double) +0:69 Constant: +0:69 123.000000 +0:70 Sequence +0:70 move second child to first child ( temp double) +0:70 'c14' ( temp double) +0:70 Constant: +0:70 102.300000 +0:71 Sequence +0:71 move second child to first child ( temp double) +0:71 'c15' ( temp double) +0:71 Constant: +0:71 1.2003000000456e+12 +0:72 Sequence +0:72 move second child to first child ( temp double) +0:72 'c16' ( temp double) +0:72 Constant: +0:72 123000000456.000000 +0:73 Sequence +0:73 move second child to first child ( temp double) +0:73 'c17' ( temp double) +0:73 Constant: +0:73 1.2300000045600e+12 +0:74 Sequence +0:74 move second child to first child ( temp double) +0:74 'c18' ( temp double) +0:74 Constant: +0:74 1.2300000045601e+12 +0:76 Sequence +0:76 move second child to first child ( temp double) +0:76 'b11' ( temp double) +0:76 Constant: +0:76 7.2057594037928e+16 +0:77 Sequence +0:77 move second child to first child ( temp double) +0:77 'b12' ( temp double) +0:77 Constant: +0:77 7.2057594037928e+16 +0:78 Sequence +0:78 move second child to first child ( temp double) +0:78 'b13' ( temp double) +0:78 Constant: +0:78 7.2057594037928e+16 +0:79 Sequence +0:79 move second child to first child ( temp double) +0:79 'b14' ( temp double) +0:79 Constant: +0:79 7.2057594037928e+16 +0:80 Sequence +0:80 move second child to first child ( temp double) +0:80 'b15' ( temp double) +0:80 Constant: +0:80 7.2057594037928e+16 +0:81 Sequence +0:81 move second child to first child ( temp double) +0:81 'b21' ( temp double) +0:81 Constant: +0:81 9.2233720368548e+18 +0:82 Sequence +0:82 move second child to first child ( temp double) +0:82 'b22' ( temp double) +0:82 Constant: +0:82 9.2233720368548e+18 +0:83 Sequence +0:83 move second child to first child ( temp double) +0:83 'b23' ( temp double) +0:83 Constant: +0:83 9.2233720368548e+18 +0:84 Sequence +0:84 move second child to first child ( temp double) +0:84 'b24' ( temp double) +0:84 Constant: +0:84 9.2233720368548e+18 +0:85 Sequence +0:85 move second child to first child ( temp double) +0:85 'b25' ( temp double) +0:85 Constant: +0:85 9.2233720368548e+18 +0:86 Sequence +0:86 move second child to first child ( temp double) +0:86 'b31' ( temp double) +0:86 Constant: +0:86 1.0141204801826e+31 +0:87 Sequence +0:87 move second child to first child ( temp double) +0:87 'b32' ( temp double) +0:87 Constant: +0:87 1.0141204801826e+31 +0:88 Sequence +0:88 move second child to first child ( temp double) +0:88 'b33' ( temp double) +0:88 Constant: +0:88 1.0141204801826e+31 +0:89 Sequence +0:89 move second child to first child ( temp double) +0:89 'b34' ( temp double) +0:89 Constant: +0:89 1.0141204801826e+31 +0:90 Sequence +0:90 move second child to first child ( temp double) +0:90 'b35' ( temp double) +0:90 Constant: +0:90 1.0141204801826e+31 +0:91 Sequence +0:91 move second child to first child ( temp double) +0:91 'b41' ( temp double) +0:91 Constant: +0:91 5.7089907708238e+45 +0:92 Sequence +0:92 move second child to first child ( temp double) +0:92 'b42' ( temp double) +0:92 Constant: +0:92 5.7089907708238e+45 +0:93 Sequence +0:93 move second child to first child ( temp double) +0:93 'b43' ( temp double) +0:93 Constant: +0:93 5.7089907708238e+45 +0:94 Sequence +0:94 move second child to first child ( temp double) +0:94 'b44' ( temp double) +0:94 Constant: +0:94 5.7089907708238e+45 +0:95 Sequence +0:95 move second child to first child ( temp double) +0:95 'b45' ( temp double) +0:95 Constant: +0:95 5.7089907708238e+45 +0:97 Sequence +0:97 move second child to first child ( temp double) +0:97 'pi' ( temp double) +0:97 Constant: +0:97 3.141593 +0:? Linker Objects +0:? 'gl_VertexID' ( gl_VertexId int VertexId) +0:? 'gl_InstanceID' ( gl_InstanceId int InstanceId) + diff --git a/Test/cppPassMacroName.frag b/Test/cppPassMacroName.frag old mode 100644 new mode 100755 index f42d9de6d..046629f2c --- a/Test/cppPassMacroName.frag +++ b/Test/cppPassMacroName.frag @@ -2,6 +2,10 @@ #define I2(f, n) f(n) + f(n+1) #define I3(f, n) I2(f, n) + f(n+2) +#define FL_f1(i) ((i)*(i)) +#define FL_I2(f, n) f(n) + f(n+0.2) +#define FL_I3(f, n) FL_I2(f, n) + f(n+0.5) + void main() { int f1 = 4; @@ -9,4 +13,18 @@ void main() int f3 = f1(3); int f4 = I2(f1, 0); int f5 = I3(f1, 0); + + highp float fl_f5 = FL_I3(FL_f1, 0.1); } + +// f5 = I3(f1, 0) +// = I2(f1, 0) + f1(0 + 2) +// = f1(0) + f1(0+1) + f1(0+2) +// = 0*0 + 1*1 + 2*2 +// = 5 + +// fl_f5 = FL_I3(FL_f1, 0.1) +// = FL_I2(FL_f1, 0.1) + FL_f1(0.1 + 0.5) +// = FL_f1(0.1) + FL_f1(0.1 + 0.2) + FL_f1(0.1 + 0.5) +// = 0.1*0.1 + 0.3*0.3 + 0.6*0.6 +// = 0.46 diff --git a/Test/stringToDouble.vert b/Test/stringToDouble.vert new file mode 100755 index 000000000..1cb0a18bf --- /dev/null +++ b/Test/stringToDouble.vert @@ -0,0 +1,98 @@ +#version 460 +//#pragma glslang_binary_double_output +void main() +{ + float w1 = 00000.000; + float w2 = 1.0; + float w3 = 007.00; + float w4 = 000130000.0; + float w5 = 123456789.0000; + double w6 = 1234567890123456.0; + double w7 = 12345678901234567.0; + double w8 = 123456789012345678.0; + double w9 = 12345678901234567893.0; + double w10 = 1234567890123456789012345.0; + + float e1 = 0e0; + float e2 = 1e0; + float e3 = 0e14; + float e4 = 1e15; + float e5 = 1e16; + float e6 = 0e-14; + float e7 = 1e-15; + float e8 = 1e-16; + double e9 = 1e100; + double e10 = 1e+308; + double e11 = 1e-323; + double e12 = 1e+309; + double e13 = 1e-324; + double e24 = 1e+999; + double e25 = 1e-999; + + double f1 = 0.5; + double f2 = 0.125; + double f31 = 0.1; + double f32 = 0.2; + double f33 = 0.3; + double f34 = 0.4; + double f35 = 0.5; + double f36 = 0.6; + double f37 = 0.7; + double f38 = 0.8; + double f39 = 0.9; + double f4 = 0.33333333333333333333333333333333333333333333333333333333333333333333333333333; + double f51 = 0.000000000000000000000000000000000000783475; + double f52 = 0.0000000000000000000000000000000000007834750; + double f53 = .00000000000000000000000000000000000078347500; + double f54 = 0.000000000000000000000000000000000000783475000000; + double f61 = 4.; + double f62 = 40.; + double f63 = 0.; + double f64 = 04.; + double f65 = .0; + double f66 = .004; + double f67 = .400; + double f68 = .04000; + + double c1 = .081e-2; + double c2 = .073e2; + double c3 = 34.5e-1; + double c4 = 35.7e-4; + double c5 = 43.9e1; + double c6 = 52.2e4; + double c7 = 000610000e2; + double c8 = 000610000e-6; + double c9 = 000001234567890123450000.0; + double c10 = 000999999999999999999000.0; + double c11 = 0001230000.0045600000; + double c12 = 0001230000.00405600000e-3; + double c13 = 0001230000.004500600000e-4; + double c14 = 00010230000.0045600000e-5; + double c15 = 000120030000.0045600000e4; + double c16 = 0001230000.0045600000e5; + double c17 = 0001230000.0045600000e6; + double c18 = 0001230000.00456007e6; + + double b11 = 72057594037927928.0; + double b12 = 72057594037927936.0; + double b13 = 72057594037927932.0; + double b14 = 7205759403792793199999e-5; + double b15 = 7205759403792793200001e-5; + double b21 = 9223372036854774784.0; + double b22 = 9223372036854775808.0; + double b23 = 9223372036854775296.0; + double b24 = 922337203685477529599999e-5; + double b25 = 922337203685477529600001e-5; + double b31 = 10141204801825834086073718800384.0; + double b32 = 10141204801825835211973625643008.0; + double b33 = 10141204801825834649023672221696.0; + double b34 = 1014120480182583464902367222169599999e-5; + double b35 = 1014120480182583464902367222169600001e-5; + double b41 = 5708990770823838890407843763683279797179383808.0; + double b42 = 5708990770823839524233143877797980545530986496.0; + double b43 = 5708990770823839207320493820740630171355185152.0; + double b44 = 5708990770823839207320493820740630171355185151999e-3; + double b45 = 5708990770823839207320493820740630171355185152001e-3; + + double pi = 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679; +} diff --git a/Test/tokenLength.vert b/Test/tokenLength.vert old mode 100644 new mode 100755 index 691b10423..21d446fae --- a/Test/tokenLength.vert +++ b/Test/tokenLength.vert @@ -1,5 +1,5 @@ #version 300 es - +//#pragma glslang_binary_double_output // 1023 characters in float BCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789; diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp old mode 100644 new mode 100755 index cf808f11e..828e49651 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -269,7 +269,8 @@ void TParseContext::handlePragma(const TSourceLoc& loc, const TVector& intermediate.setUseStorageBuffer(); } else if (tokens[0].compare("once") == 0) { warn(loc, "not implemented", "#pragma once", ""); - } + } else if (tokens[0].compare("glslang_binary_double_output") == 0) + intermediate.setBinaryDoubleOutput(); } // diff --git a/glslang/MachineIndependent/intermOut.cpp b/glslang/MachineIndependent/intermOut.cpp old mode 100644 new mode 100755 index 4d6ad040b..883bc03a9 --- a/glslang/MachineIndependent/intermOut.cpp +++ b/glslang/MachineIndependent/intermOut.cpp @@ -93,7 +93,13 @@ namespace glslang { // class TOutputTraverser : public TIntermTraverser { public: - TOutputTraverser(TInfoSink& i) : infoSink(i) { } + TOutputTraverser(TInfoSink& i) : infoSink(i), extraOutput(NoExtraOutput) { } + + enum EExtraOutput { + NoExtraOutput, + BinaryDoubleOutput + }; + void setDoubleOutput(EExtraOutput extra) { extraOutput = extra; } virtual bool visitBinary(TVisit, TIntermBinary* node); virtual bool visitUnary(TVisit, TIntermUnary* node); @@ -109,6 +115,8 @@ public: protected: TOutputTraverser(TOutputTraverser&); TOutputTraverser& operator=(TOutputTraverser&); + + EExtraOutput extraOutput; }; // @@ -1082,7 +1090,61 @@ bool TOutputTraverser::visitSelection(TVisit /* visit */, TIntermSelection* node return false; } -static void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const TConstUnionArray& constUnion, int depth) +// Print infinities and NaNs, and numbers in a portable way. +// Goals: +// - portable (across IEEE 754 platforms) +// - shows all possible IEEE values +// - shows simple numbers in a simple way, e.g., no leading/trailing 0s +// - shows all digits, no premature rounding +static void OutputDouble(TInfoSink& out, double value, TOutputTraverser::EExtraOutput extra) +{ + if (IsInfinity(value)) { + if (value < 0) + out.debug << "-1.#INF"; + else + out.debug << "+1.#INF"; + } else if (IsNan(value)) + out.debug << "1.#IND"; + else { + const int maxSize = 340; + char buf[maxSize]; + const char* format = "%f"; + if (fabs(value) > 0.0 && (fabs(value) < 1e-5 || fabs(value) > 1e12)) + format = "%-.13e"; + snprintf(buf, maxSize, format, value); + + // remove a leading zero in the 100s slot in exponent; it is not portable + // pattern: XX...XXXe+0XX or XX...XXXe-0XX + int len = (int)strnlen(buf, maxSize); + if (len > 5) { + if (buf[len-5] == 'e' && (buf[len-4] == '+' || buf[len-4] == '-') && buf[len-3] == '0') { + buf[len-3] = buf[len-2]; + buf[len-2] = buf[len-1]; + buf[len-1] = '\0'; + } + } + + out.debug << buf; + + switch (extra) { + case TOutputTraverser::BinaryDoubleOutput: + { + out.debug << " : "; + long long b = *reinterpret_cast(&value); + for (int i = 0; i < 8 * sizeof(value); ++i, ++b) { + out.debug << ((b & 0x8000000000000000) != 0 ? "1" : "0"); + b <<= 1; + } + break; + } + default: + break; + } + } +} + +static void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const TConstUnionArray& constUnion, + TOutputTraverser::EExtraOutput extra, int depth) { int size = node->getType().computeNumComponents(); @@ -1102,24 +1164,8 @@ static void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const case EbtFloat: case EbtDouble: case EbtFloat16: - { - const double value = constUnion[i].getDConst(); - // Print infinities and NaNs in a portable way. - if (IsInfinity(value)) { - if (value < 0) - out.debug << "-1.#INF\n"; - else - out.debug << "+1.#INF\n"; - } else if (IsNan(value)) - out.debug << "1.#IND\n"; - else { - const int maxSize = 300; - char buf[maxSize]; - snprintf(buf, maxSize, "%f", value); - - out.debug << buf << "\n"; - } - } + OutputDouble(out, constUnion[i].getDConst(), extra); + out.debug << "\n"; break; case EbtInt8: { @@ -1205,7 +1251,7 @@ void TOutputTraverser::visitConstantUnion(TIntermConstantUnion* node) OutputTreeText(infoSink, node, depth); infoSink.debug << "Constant:\n"; - OutputConstantUnion(infoSink, node, node->getConstArray(), depth + 1); + OutputConstantUnion(infoSink, node, node->getConstArray(), extraOutput, depth + 1); } void TOutputTraverser::visitSymbol(TIntermSymbol* node) @@ -1215,7 +1261,7 @@ void TOutputTraverser::visitSymbol(TIntermSymbol* node) infoSink.debug << "'" << node->getName() << "' (" << node->getCompleteString() << ")\n"; if (! node->getConstArray().empty()) - OutputConstantUnion(infoSink, node, node->getConstArray(), depth + 1); + OutputConstantUnion(infoSink, node, node->getConstArray(), extraOutput, depth + 1); else if (node->getConstSubtree()) { incrementDepth(node); node->getConstSubtree()->traverse(this); @@ -1417,7 +1463,8 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree) return; TOutputTraverser it(infoSink); - + if (getBinaryDoubleOutput()) + it.setDoubleOutput(TOutputTraverser::BinaryDoubleOutput); treeRoot->traverse(&it); } diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h old mode 100644 new mode 100755 index 17e076519..f3a0e413e --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -233,7 +233,8 @@ public: useStorageBuffer(false), hlslIoMapping(false), textureSamplerTransformMode(EShTexSampTransKeep), - needToLegalize(false) + needToLegalize(false), + binaryDoubleOutput(false) { localSize[0] = 1; localSize[1] = 1; @@ -634,6 +635,9 @@ public: void setNeedsLegalization() { needToLegalize = true; } bool needsLegalization() const { return needToLegalize; } + void setBinaryDoubleOutput() { binaryDoubleOutput = true; } + bool getBinaryDoubleOutput() { return binaryDoubleOutput; } + const char* const implicitThisName; const char* const implicitCounterName; @@ -742,6 +746,7 @@ protected: TProcesses processes; bool needToLegalize; + bool binaryDoubleOutput; private: void operator=(TIntermediate&); // prevent assignments diff --git a/gtests/AST.FromFile.cpp b/gtests/AST.FromFile.cpp old mode 100644 new mode 100755 index 701db4633..b89fc5156 --- a/gtests/AST.FromFile.cpp +++ b/gtests/AST.FromFile.cpp @@ -208,6 +208,7 @@ INSTANTIATE_TEST_CASE_P( "prepost.frag", "runtimeArray.vert", "simpleFunctionCall.frag", + "stringToDouble.vert", "structAssignment.frag", "structDeref.frag", "structure.frag", From 6c52f8968c169598419b5dd433a345979a2fe1e5 Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Thu, 24 May 2018 18:24:06 -0600 Subject: [PATCH 2/3] PP: Remove second parsing of numbers recorded in macros; save/use original. This partly addresses #1228 and #234 by reducing usage of strtod (or atof). There is now only place to parse a floating-point number. --- .../preprocessor/PpContext.h | 17 +- .../preprocessor/PpTokens.cpp | 205 ++++++++---------- 2 files changed, 103 insertions(+), 119 deletions(-) mode change 100644 => 100755 glslang/MachineIndependent/preprocessor/PpContext.h mode change 100644 => 100755 glslang/MachineIndependent/preprocessor/PpTokens.cpp diff --git a/glslang/MachineIndependent/preprocessor/PpContext.h b/glslang/MachineIndependent/preprocessor/PpContext.h old mode 100644 new mode 100755 index 854bbbad2..04d23b221 --- a/glslang/MachineIndependent/preprocessor/PpContext.h +++ b/glslang/MachineIndependent/preprocessor/PpContext.h @@ -92,13 +92,16 @@ namespace glslang { class TPpToken { public: - TPpToken() : space(false), i64val(0) + TPpToken() { clear(); } + void clear() { + space = false; + i64val = 0; loc.init(); name[0] = 0; } - // This is used for comparing macro definitions, so checks what is relevant for that. + // Used for comparing macro definitions, so checks what is relevant for that. bool operator==(const TPpToken& right) { return space == right.space && @@ -108,15 +111,17 @@ public: bool operator!=(const TPpToken& right) { return ! operator==(right); } TSourceLoc loc; - bool space; // true if a space (for white space or a removed comment) should also be recognized, in front of the token returned - + // True if a space (for white space or a removed comment) should also be + // recognized, in front of the token returned: + bool space; + // Numeric value of the token: union { int ival; double dval; long long i64val; }; - - char name[MaxTokenLength + 1]; + // Text string of the token: + char name[MaxTokenLength + 1]; }; class TStringAtomMap { diff --git a/glslang/MachineIndependent/preprocessor/PpTokens.cpp b/glslang/MachineIndependent/preprocessor/PpTokens.cpp old mode 100644 new mode 100755 index 31e0d1f96..d8088e7d4 --- a/glslang/MachineIndependent/preprocessor/PpTokens.cpp +++ b/glslang/MachineIndependent/preprocessor/PpTokens.cpp @@ -97,6 +97,56 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace glslang { + +namespace { + + // When recording (and playing back) should the backing name string + // be saved (restored)? + bool SaveName(int atom) + { + switch (atom) { + case PpAtomIdentifier: + case PpAtomConstString: + case PpAtomConstInt: + case PpAtomConstUint: + case PpAtomConstInt64: + case PpAtomConstUint64: + #ifdef AMD_EXTENSIONS + case PpAtomConstInt16: + case PpAtomConstUint16: + #endif + case PpAtomConstFloat: + case PpAtomConstDouble: + case PpAtomConstFloat16: + return true; + default: + return false; + } + } + + // When recording (and playing back) should the numeric value + // be saved (restored)? + bool SaveValue(int atom) + { + switch (atom) { + case PpAtomConstInt: + case PpAtomConstUint: + case PpAtomConstInt64: + case PpAtomConstUint64: + #ifdef AMD_EXTENSIONS + case PpAtomConstInt16: + case PpAtomConstUint16: + #endif + case PpAtomConstFloat: + case PpAtomConstDouble: + case PpAtomConstFloat16: + return true; + default: + return false; + } + } +} + // push onto back of stream void TPpContext::TokenStream::putSubtoken(char subtoken) { @@ -121,42 +171,25 @@ void TPpContext::TokenStream::ungetSubtoken() // Add a complete token (including backing string) to the end of a list // for later playback. -void TPpContext::TokenStream::putToken(int token, TPpToken* ppToken) +void TPpContext::TokenStream::putToken(int atom, TPpToken* ppToken) { - const char* s; - char* str = NULL; + // save the atom + assert((atom & ~0xff) == 0); + putSubtoken(static_cast(atom)); - assert((token & ~0xff) == 0); - putSubtoken(static_cast(token)); - - switch (token) { - case PpAtomIdentifier: - case PpAtomConstString: - s = ppToken->name; + // save the backing name string + if (SaveName(atom)) { + const char* s = ppToken->name; while (*s) putSubtoken(*s++); putSubtoken(0); - break; - case PpAtomConstInt: - case PpAtomConstUint: - case PpAtomConstInt64: - case PpAtomConstUint64: -#ifdef AMD_EXTENSIONS - case PpAtomConstInt16: - case PpAtomConstUint16: -#endif - case PpAtomConstFloat: - case PpAtomConstDouble: - case PpAtomConstFloat16: - str = ppToken->name; - while (*str) { - putSubtoken(*str); - str++; - } - putSubtoken(0); - break; - default: - break; + } + + // save the numeric value + if (SaveValue(atom)) { + const char* n = reinterpret_cast(&ppToken->i64val); + for (int i = 0; i < sizeof(ppToken->i64val); ++i) + putSubtoken(*n++); } } @@ -164,38 +197,19 @@ void TPpContext::TokenStream::putToken(int token, TPpToken* ppToken) // (Not the source stream, but a stream used to hold a tokenized macro). int TPpContext::TokenStream::getToken(TParseContextBase& parseContext, TPpToken *ppToken) { - int len; - int ch; + // get the atom + int atom = getSubtoken(); + if (atom == EndOfInput) + return atom; - int subtoken = getSubtoken(); + // init the token + ppToken->clear(); ppToken->loc = parseContext.getCurrentLoc(); - switch (subtoken) { - case '#': - // Check for ##, unless the current # is the last character - if (current < data.size()) { - if (getSubtoken() == '#') { - parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)"); - parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, 0, "token pasting (##)"); - subtoken = PpAtomPaste; - } else - ungetSubtoken(); - } - break; - case PpAtomConstString: - case PpAtomIdentifier: - case PpAtomConstFloat: - case PpAtomConstDouble: - case PpAtomConstFloat16: - case PpAtomConstInt: - case PpAtomConstUint: - case PpAtomConstInt64: - case PpAtomConstUint64: -#ifdef AMD_EXTENSIONS - case PpAtomConstInt16: - case PpAtomConstUint16: -#endif - len = 0; - ch = getSubtoken(); + + // get the backing name string + if (SaveName(atom)) { + int ch = getSubtoken(); + int len = 0; while (ch != 0 && ch != EndOfInput) { if (len < MaxTokenLength) { ppToken->name[len] = (char)ch; @@ -207,63 +221,28 @@ int TPpContext::TokenStream::getToken(TParseContextBase& parseContext, TPpToken } } ppToken->name[len] = 0; + } - switch (subtoken) { - case PpAtomIdentifier: - break; - case PpAtomConstString: - break; - case PpAtomConstFloat: - case PpAtomConstDouble: - case PpAtomConstFloat16: - ppToken->dval = atof(ppToken->name); - break; - case PpAtomConstInt: -#ifdef AMD_EXTENSIONS - case PpAtomConstInt16: -#endif - if (len > 0 && ppToken->name[0] == '0') { - if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X')) - ppToken->ival = (int)strtol(ppToken->name, 0, 16); - else - ppToken->ival = (int)strtol(ppToken->name, 0, 8); + // Check for ##, unless the current # is the last character + if (atom == '#') { + if (current < data.size()) { + if (getSubtoken() == '#') { + parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)"); + parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, 0, "token pasting (##)"); + atom = PpAtomPaste; } else - ppToken->ival = atoi(ppToken->name); - break; - case PpAtomConstUint: -#ifdef AMD_EXTENSIONS - case PpAtomConstUint16: -#endif - if (len > 0 && ppToken->name[0] == '0') { - if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X')) - ppToken->ival = (int)strtoul(ppToken->name, 0, 16); - else - ppToken->ival = (int)strtoul(ppToken->name, 0, 8); - } else - ppToken->ival = (int)strtoul(ppToken->name, 0, 10); - break; - case PpAtomConstInt64: - if (len > 0 && ppToken->name[0] == '0') { - if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X')) - ppToken->i64val = strtoll(ppToken->name, nullptr, 16); - else - ppToken->i64val = strtoll(ppToken->name, nullptr, 8); - } else - ppToken->i64val = atoll(ppToken->name); - break; - case PpAtomConstUint64: - if (len > 0 && ppToken->name[0] == '0') { - if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X')) - ppToken->i64val = (long long)strtoull(ppToken->name, nullptr, 16); - else - ppToken->i64val = (long long)strtoull(ppToken->name, nullptr, 8); - } else - ppToken->i64val = (long long)strtoull(ppToken->name, 0, 10); - break; + ungetSubtoken(); } } - return subtoken; + // get the numeric value + if (SaveValue(atom)) { + char* n = reinterpret_cast(&ppToken->i64val); + for (int i = 0; i < sizeof(ppToken->i64val); ++i) + *n++ = getSubtoken(); + } + + return atom; } // We are pasting if From 3e8e9f7bbdafe393ca3a088e72bf4958552bae7e Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Thu, 24 May 2018 18:26:44 -0600 Subject: [PATCH 3/3] PP: Implement locale-independent strtod, using istringstream and a fast path. Fixes #1228. Fixes #234. This uses imbue() to be locale independent. Notes: - 'sstream >> double' is much slower than strtod() * this was measurable in the test suite as a whole, despite being a tiny fraction of what the test suite does - so, this embeds a fast path that bypasses sstream most of the time => the test suite is faster than before - sstream is probably slower, because it does more accurate rounding than strtod() - sstream does not create INFINITY by itself, this was done based on failure inferencing --- .../preprocessor/PpContext.cpp | 3 + .../preprocessor/PpContext.h | 3 + .../preprocessor/PpScanner.cpp | 146 +++++++++++++++--- 3 files changed, 127 insertions(+), 25 deletions(-) mode change 100644 => 100755 glslang/MachineIndependent/preprocessor/PpContext.cpp mode change 100644 => 100755 glslang/MachineIndependent/preprocessor/PpScanner.cpp diff --git a/glslang/MachineIndependent/preprocessor/PpContext.cpp b/glslang/MachineIndependent/preprocessor/PpContext.cpp old mode 100644 new mode 100755 index 6a2e05fef..c89b37688 --- a/glslang/MachineIndependent/preprocessor/PpContext.cpp +++ b/glslang/MachineIndependent/preprocessor/PpContext.cpp @@ -77,6 +77,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \****************************************************************************/ #include +#include #include "PpContext.h" @@ -91,6 +92,8 @@ TPpContext::TPpContext(TParseContextBase& pc, const std::string& rootFileName, T for (elsetracker = 0; elsetracker < maxIfNesting; elsetracker++) elseSeen[elsetracker] = false; elsetracker = 0; + + strtodStream.imbue(std::locale::classic()); } TPpContext::~TPpContext() diff --git a/glslang/MachineIndependent/preprocessor/PpContext.h b/glslang/MachineIndependent/preprocessor/PpContext.h index 04d23b221..b3a39c5cb 100755 --- a/glslang/MachineIndependent/preprocessor/PpContext.h +++ b/glslang/MachineIndependent/preprocessor/PpContext.h @@ -80,6 +80,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include #include +#include #include "../ParseHelper.h" @@ -620,6 +621,8 @@ protected: std::string rootFileName; std::stack includeStack; std::string currentSourceFile; + + std::istringstream strtodStream; }; } // end namespace glslang diff --git a/glslang/MachineIndependent/preprocessor/PpScanner.cpp b/glslang/MachineIndependent/preprocessor/PpScanner.cpp old mode 100644 new mode 100755 index f4eaf57d3..0c620a5f5 --- a/glslang/MachineIndependent/preprocessor/PpScanner.cpp +++ b/glslang/MachineIndependent/preprocessor/PpScanner.cpp @@ -102,20 +102,36 @@ namespace glslang { int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken) { - bool HasDecimalOrExponent = false; - int isDouble = 0; - const auto saveName = [&](int ch) { if (len <= MaxTokenLength) ppToken->name[len++] = static_cast(ch); }; - // Decimal: + // find the range of non-zero digits before the decimal point + int startNonZero = 0; + while (startNonZero < len && ppToken->name[startNonZero] == '0') + ++startNonZero; + int endNonZero = len; + while (endNonZero > startNonZero && ppToken->name[endNonZero-1] == '0') + --endNonZero; + int numWholeNumberDigits = endNonZero - startNonZero; + // accumulate the range's value + bool fastPath = numWholeNumberDigits <= 15; // when the number gets too complex, set to false + unsigned long long wholeNumber = 0; + if (fastPath) { + for (int i = startNonZero; i < endNonZero; ++i) + wholeNumber = wholeNumber * 10 + (ppToken->name[i] - '0'); + } + int decimalShift = len - endNonZero; + + // Decimal point: + bool hasDecimalOrExponent = false; if (ch == '.') { - HasDecimalOrExponent = true; + hasDecimalOrExponent = true; saveName(ch); ch = getChar(); + int firstDecimal = len; // 1.#INF or -1.#INF if (ch == '#' && (ifdepth > 0 || parseContext.intermediate.getSource() == EShSourceHlsl)) { @@ -145,38 +161,97 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken) } } - while (ch >= '0' && ch <= '9') { + // Consume leading-zero digits after the decimal point + while (ch == '0') { saveName(ch); ch = getChar(); } + int startNonZeroDecimal = len; + int endNonZeroDecimal = len; + + // Consume remaining digits, up to the exponent + while (ch >= '0' && ch <= '9') { + saveName(ch); + if (ch != '0') + endNonZeroDecimal = len; + ch = getChar(); + } + + // Compute accumulation up to the last non-zero digit + if (endNonZeroDecimal > startNonZeroDecimal) { + numWholeNumberDigits += endNonZeroDecimal - endNonZero - 1; // don't include the "." + if (numWholeNumberDigits > 15) + fastPath = false; + if (fastPath) { + for (int i = endNonZero; i < endNonZeroDecimal; ++i) { + if (ppToken->name[i] != '.') + wholeNumber = wholeNumber * 10 + (ppToken->name[i] - '0'); + } + } + decimalShift = firstDecimal - endNonZeroDecimal; + } } // Exponent: - - if (ch == 'e' || ch == 'E') { - HasDecimalOrExponent = true; - saveName(ch); - ch = getChar(); - if (ch == '+' || ch == '-') { + bool negativeExponent = false; + double exponentValue = 0.0; + int exponent = 0; + { + if (ch == 'e' || ch == 'E') { + hasDecimalOrExponent = true; saveName(ch); ch = getChar(); - } - if (ch >= '0' && ch <= '9') { - while (ch >= '0' && ch <= '9') { + if (ch == '+' || ch == '-') { + negativeExponent = ch == '-'; saveName(ch); ch = getChar(); } - } else { - parseContext.ppError(ppToken->loc, "bad character in float exponent", "", ""); + if (ch >= '0' && ch <= '9') { + while (ch >= '0' && ch <= '9') { + exponent = exponent * 10 + (ch - '0'); + saveName(ch); + ch = getChar(); + } + } else { + parseContext.ppError(ppToken->loc, "bad character in float exponent", "", ""); + } + } + + // Compensate for location of decimal + if (negativeExponent) + exponent -= decimalShift; + else { + exponent += decimalShift; + if (exponent < 0) { + negativeExponent = true; + exponent = -exponent; + } + } + if (exponent > 22) + fastPath = false; + + if (fastPath) { + // Compute the floating-point value of the exponent + exponentValue = 1.0; + if (exponent > 0) { + double expFactor = 10; + while (exponent > 0) { + if (exponent & 0x1) + exponentValue *= expFactor; + expFactor *= expFactor; + exponent >>= 1; + } + } } } // Suffix: + bool isDouble = false; bool isFloat16 = false; if (ch == 'l' || ch == 'L') { if (ifdepth == 0 && parseContext.intermediate.getSource() == EShSourceGlsl) parseContext.doubleCheck(ppToken->loc, "double floating-point suffix"); - if (ifdepth == 0 && !HasDecimalOrExponent) + if (ifdepth == 0 && !hasDecimalOrExponent) parseContext.ppError(ppToken->loc, "float literal needs a decimal point or exponent", "", ""); if (parseContext.intermediate.getSource() == EShSourceGlsl) { int ch2 = getChar(); @@ -186,16 +261,16 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken) } else { saveName(ch); saveName(ch2); - isDouble = 1; + isDouble = true; } } else if (parseContext.intermediate.getSource() == EShSourceHlsl) { saveName(ch); - isDouble = 1; + isDouble = true; } } else if (ch == 'h' || ch == 'H') { if (ifdepth == 0 && parseContext.intermediate.getSource() == EShSourceGlsl) parseContext.float16Check(ppToken->loc, "half floating-point suffix"); - if (ifdepth == 0 && !HasDecimalOrExponent) + if (ifdepth == 0 && !hasDecimalOrExponent) parseContext.ppError(ppToken->loc, "float literal needs a decimal point or exponent", "", ""); if (parseContext.intermediate.getSource() == EShSourceGlsl) { int ch2 = getChar(); @@ -216,13 +291,13 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken) parseContext.profileRequires(ppToken->loc, EEsProfile, 300, nullptr, "floating-point suffix"); if (ifdepth == 0 && !parseContext.relaxedErrors()) parseContext.profileRequires(ppToken->loc, ~EEsProfile, 120, nullptr, "floating-point suffix"); - if (ifdepth == 0 && !HasDecimalOrExponent) + if (ifdepth == 0 && !hasDecimalOrExponent) parseContext.ppError(ppToken->loc, "float literal needs a decimal point or exponent", "", ""); saveName(ch); } else ungetChar(); - // Patch up the name, length, etc. + // Patch up the name and length for overflow if (len > MaxTokenLength) { len = MaxTokenLength; @@ -230,8 +305,29 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken) } ppToken->name[len] = '\0'; - // Get the numerical value - ppToken->dval = strtod(ppToken->name, nullptr); + // Compute the numerical value + if (fastPath) { + // compute the floating-point value of the exponent + if (exponentValue == 0.0) + ppToken->dval = (double)wholeNumber; + else if (negativeExponent) + ppToken->dval = (double)wholeNumber / exponentValue; + else + ppToken->dval = (double)wholeNumber * exponentValue; + } else { + // slow path + strtodStream.clear(); + strtodStream.str(ppToken->name); + strtodStream >> ppToken->dval; + // Assume failure combined with a large exponent was overflow, in + // an attempt to set INF. Otherwise, assume underflow, and set 0.0. + if (strtodStream.fail()) { + if (!negativeExponent && exponent + numWholeNumberDigits > 300) + ppToken->i64val = 0x7ff0000000000000; // +Infinity + else + ppToken->dval = 0.0; + } + } // Return the right token type if (isDouble)