Added preprocessor support for GL_FRAGMENT_PRECISION_HIGH.
I will send the tests in a separate patch because I need to refactor the way compiler_tests are setup.
Review URL: https://codereview.appspot.com/7402051

git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1990 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/include/GLSLANG/ShaderLang.h b/include/GLSLANG/ShaderLang.h
index 4db996a..c503908 100644
--- a/include/GLSLANG/ShaderLang.h
+++ b/include/GLSLANG/ShaderLang.h
@@ -213,6 +213,10 @@
     int ARB_texture_rectangle;
     int EXT_draw_buffers;
 
+    // Set to 1 if highp precision is supported in the fragment language.
+    // Default is 0.
+    int FragmentPrecisionHigh;
+
     // Name Hashing.
     // Set a 64 bit hash function to enable user-defined name hashing.
     // Default is NULL.
diff --git a/src/compiler/Compiler.cpp b/src/compiler/Compiler.cpp
index 0e39fcf..9c9f9e7 100644
--- a/src/compiler/Compiler.cpp
+++ b/src/compiler/Compiler.cpp
@@ -38,6 +38,7 @@
     // The builtins deliberately don't specify precisions for the function
     // arguments and return types. For that reason we don't try to check them.
     TParseContext parseContext(symbolTable, extBehavior, intermediate, type, spec, 0, false, NULL, infoSink);
+    parseContext.fragmentPrecisionHigh = resources.FragmentPrecisionHigh == 1;
 
     GlobalParseContext = &parseContext;
 
@@ -102,6 +103,7 @@
 TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec)
     : shaderType(type),
       shaderSpec(spec),
+      fragmentPrecisionHigh(false),
       clampingStrategy(SH_CLAMP_WITH_CLAMP_INTRINSIC),
       builtInFunctionEmulator(type)
 {
@@ -125,6 +127,7 @@
     if (!InitBuiltInSymbolTable(resources))
         return false;
     InitExtensionBehavior(resources, extensionBehavior);
+    fragmentPrecisionHigh = resources.FragmentPrecisionHigh == 1;
 
     arrayBoundsClamper.SetClampingStrategy(resources.ArrayIndexClampingStrategy);
     clampingStrategy = resources.ArrayIndexClampingStrategy;
@@ -161,6 +164,7 @@
     TParseContext parseContext(symbolTable, extensionBehavior, intermediate,
                                shaderType, shaderSpec, compileOptions, true,
                                sourcePath, infoSink);
+    parseContext.fragmentPrecisionHigh = fragmentPrecisionHigh;
     GlobalParseContext = &parseContext;
 
     // We preserve symbols at the built-in level from compile-to-compile.
diff --git a/src/compiler/ParseHelper.h b/src/compiler/ParseHelper.h
index 9fb9f4d..26a3ea1 100644
--- a/src/compiler/ParseHelper.h
+++ b/src/compiler/ParseHelper.h
@@ -58,6 +58,7 @@
     const TType* currentFunctionType;  // the return type of the function that's currently being parsed
     bool functionReturnsValue;   // true if a non-void function has a return
     bool checksPrecisionErrors;  // true if an error will be generated when a variable is declared without precision, explicit or implicit.
+    bool fragmentPrecisionHigh;  // true if highp precision is supported in the fragment language.
     TString HashErrMsg;
     bool AfterEOF;
     TDiagnostics diagnostics;
diff --git a/src/compiler/ShHandle.h b/src/compiler/ShHandle.h
index 48f2dd9..af302d6 100644
--- a/src/compiler/ShHandle.h
+++ b/src/compiler/ShHandle.h
@@ -124,6 +124,7 @@
     TSymbolTable symbolTable;
     // Built-in extensions with default behavior.
     TExtensionBehavior extensionBehavior;
+    bool fragmentPrecisionHigh;
 
     ArrayBoundsClamper arrayBoundsClamper;
     ShArrayIndexClampingStrategy clampingStrategy;
diff --git a/src/compiler/ShaderLang.cpp b/src/compiler/ShaderLang.cpp
index 06372a9..92f3931 100644
--- a/src/compiler/ShaderLang.cpp
+++ b/src/compiler/ShaderLang.cpp
@@ -128,6 +128,9 @@
     resources->ARB_texture_rectangle = 0;
     resources->EXT_draw_buffers = 0;
 
+    // Disable highp precision in fragment shader by default.
+    resources->FragmentPrecisionHigh = 0;
+
     // Disable name hashing by default.
     resources->HashFunction = NULL;
 
diff --git a/src/compiler/glslang.l b/src/compiler/glslang.l
index b504227..140a9ae 100644
--- a/src/compiler/glslang.l
+++ b/src/compiler/glslang.l
@@ -357,6 +357,9 @@
          iter != extBehavior.end(); ++iter) {
         context->preprocessor.predefineMacro(iter->first.c_str(), 1);
     }
+    if (context->fragmentPrecisionHigh)
+        context->preprocessor.predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1);
+
     return 0;
 }
 
diff --git a/src/compiler/glslang.y b/src/compiler/glslang.y
index fe966af..fc75049 100644
--- a/src/compiler/glslang.y
+++ b/src/compiler/glslang.y
@@ -991,6 +991,10 @@
         $$ = $1.intermAggregate;
     }
     | PRECISION precision_qualifier type_specifier_no_prec SEMICOLON {
+        if (($2 == EbpHigh) && (context->shaderType == SH_FRAGMENT_SHADER) && !context->fragmentPrecisionHigh) {
+            context->error($1.line, "precision is not supported in fragment shader", "highp");
+            context->recover();
+        }
         if (!context->symbolTable.setDefaultPrecision( $3, $2 )) {
             context->error($1.line, "illegal type argument for default precision qualifier", getBasicString($3.type));
             context->recover();
@@ -2145,4 +2149,3 @@
 int glslang_parse(TParseContext* context) {
     return yyparse(context);
 }
-
diff --git a/src/compiler/glslang_lex.cpp b/src/compiler/glslang_lex.cpp
index 424ac98..a60dad5 100644
--- a/src/compiler/glslang_lex.cpp
+++ b/src/compiler/glslang_lex.cpp
@@ -2954,7 +2954,7 @@
     yy_size_t len = token.type == pp::Token::LAST ? 0 : token.text.size();
     if (len < max_size)
         memcpy(buf, token.text.c_str(), len);
-    yyset_lineno(EncodeSourceLoc(token.location.file, token.location.line), yyscanner);
+    yyset_lineno(EncodeSourceLoc(token.location.file, token.location.line),yyscanner);
 
     if (len >= max_size)
         YY_FATAL_ERROR("Input buffer overflow");
@@ -3033,6 +3033,9 @@
          iter != extBehavior.end(); ++iter) {
         context->preprocessor.predefineMacro(iter->first.c_str(), 1);
     }
+    if (context->fragmentPrecisionHigh)
+        context->preprocessor.predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1);
+
     return 0;
 }
 
diff --git a/src/compiler/glslang_tab.cpp b/src/compiler/glslang_tab.cpp
index 4f408c6..f35854a 100644
--- a/src/compiler/glslang_tab.cpp
+++ b/src/compiler/glslang_tab.cpp
@@ -667,20 +667,20 @@
      762,   773,   777,   778,   788,   798,   808,   821,   822,   832,
      845,   849,   853,   857,   858,   871,   872,   885,   886,   899,
      900,   917,   918,   931,   932,   933,   934,   935,   939,   942,
-     953,   961,   988,   993,  1003,  1041,  1044,  1051,  1059,  1080,
-    1101,  1112,  1141,  1146,  1156,  1161,  1171,  1174,  1177,  1180,
-    1186,  1193,  1196,  1218,  1236,  1260,  1283,  1287,  1305,  1313,
-    1345,  1365,  1454,  1463,  1486,  1489,  1495,  1503,  1511,  1519,
-    1529,  1536,  1539,  1542,  1548,  1551,  1566,  1570,  1574,  1578,
-    1587,  1592,  1597,  1602,  1607,  1612,  1617,  1622,  1627,  1632,
-    1638,  1644,  1650,  1655,  1660,  1669,  1678,  1683,  1696,  1696,
-    1710,  1710,  1719,  1722,  1737,  1773,  1777,  1783,  1791,  1807,
-    1811,  1815,  1816,  1822,  1823,  1824,  1825,  1826,  1830,  1831,
-    1831,  1831,  1841,  1842,  1846,  1846,  1847,  1847,  1852,  1855,
-    1865,  1868,  1874,  1875,  1879,  1887,  1891,  1901,  1906,  1923,
-    1923,  1928,  1928,  1935,  1935,  1943,  1946,  1952,  1955,  1961,
-    1965,  1972,  1979,  1986,  1993,  2004,  2013,  2017,  2024,  2027,
-    2033,  2033
+     953,   961,   988,   993,  1007,  1045,  1048,  1055,  1063,  1084,
+    1105,  1116,  1145,  1150,  1160,  1165,  1175,  1178,  1181,  1184,
+    1190,  1197,  1200,  1222,  1240,  1264,  1287,  1291,  1309,  1317,
+    1349,  1369,  1458,  1467,  1490,  1493,  1499,  1507,  1515,  1523,
+    1533,  1540,  1543,  1546,  1552,  1555,  1570,  1574,  1578,  1582,
+    1591,  1596,  1601,  1606,  1611,  1616,  1621,  1626,  1631,  1636,
+    1642,  1648,  1654,  1659,  1664,  1673,  1682,  1687,  1700,  1700,
+    1714,  1714,  1723,  1726,  1741,  1777,  1781,  1787,  1795,  1811,
+    1815,  1819,  1820,  1826,  1827,  1828,  1829,  1830,  1834,  1835,
+    1835,  1835,  1845,  1846,  1850,  1850,  1851,  1851,  1856,  1859,
+    1869,  1872,  1878,  1879,  1883,  1891,  1895,  1905,  1910,  1927,
+    1927,  1932,  1932,  1939,  1939,  1947,  1950,  1956,  1959,  1965,
+    1969,  1976,  1983,  1990,  1997,  2008,  2017,  2021,  2028,  2031,
+    2037,  2037
 };
 #endif
 
@@ -3088,6 +3088,10 @@
   case 73:
 
     {
+        if (((yyvsp[(2) - (4)].interm.precision) == EbpHigh) && (context->shaderType == SH_FRAGMENT_SHADER) && !context->fragmentPrecisionHigh) {
+            context->error((yyvsp[(1) - (4)].lex).line, "precision is not supported in fragment shader", "highp");
+            context->recover();
+        }
         if (!context->symbolTable.setDefaultPrecision( (yyvsp[(3) - (4)].interm.type), (yyvsp[(2) - (4)].interm.precision) )) {
             context->error((yyvsp[(1) - (4)].lex).line, "illegal type argument for default precision qualifier", getBasicString((yyvsp[(3) - (4)].interm.type).type));
             context->recover();
@@ -4755,3 +4759,4 @@
 int glslang_parse(TParseContext* context) {
     return yyparse(context);
 }
+