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
parent 57a5493e
...@@ -213,6 +213,10 @@ typedef struct ...@@ -213,6 +213,10 @@ typedef struct
int ARB_texture_rectangle; int ARB_texture_rectangle;
int EXT_draw_buffers; int EXT_draw_buffers;
// Set to 1 if highp precision is supported in the fragment language.
// Default is 0.
int FragmentPrecisionHigh;
// Name Hashing. // Name Hashing.
// Set a 64 bit hash function to enable user-defined name hashing. // Set a 64 bit hash function to enable user-defined name hashing.
// Default is NULL. // Default is NULL.
......
...@@ -38,6 +38,7 @@ bool InitializeSymbolTable( ...@@ -38,6 +38,7 @@ bool InitializeSymbolTable(
// The builtins deliberately don't specify precisions for the function // The builtins deliberately don't specify precisions for the function
// arguments and return types. For that reason we don't try to check them. // 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); TParseContext parseContext(symbolTable, extBehavior, intermediate, type, spec, 0, false, NULL, infoSink);
parseContext.fragmentPrecisionHigh = resources.FragmentPrecisionHigh == 1;
GlobalParseContext = &parseContext; GlobalParseContext = &parseContext;
...@@ -102,6 +103,7 @@ TShHandleBase::~TShHandleBase() { ...@@ -102,6 +103,7 @@ TShHandleBase::~TShHandleBase() {
TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec) TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec)
: shaderType(type), : shaderType(type),
shaderSpec(spec), shaderSpec(spec),
fragmentPrecisionHigh(false),
clampingStrategy(SH_CLAMP_WITH_CLAMP_INTRINSIC), clampingStrategy(SH_CLAMP_WITH_CLAMP_INTRINSIC),
builtInFunctionEmulator(type) builtInFunctionEmulator(type)
{ {
...@@ -125,6 +127,7 @@ bool TCompiler::Init(const ShBuiltInResources& resources) ...@@ -125,6 +127,7 @@ bool TCompiler::Init(const ShBuiltInResources& resources)
if (!InitBuiltInSymbolTable(resources)) if (!InitBuiltInSymbolTable(resources))
return false; return false;
InitExtensionBehavior(resources, extensionBehavior); InitExtensionBehavior(resources, extensionBehavior);
fragmentPrecisionHigh = resources.FragmentPrecisionHigh == 1;
arrayBoundsClamper.SetClampingStrategy(resources.ArrayIndexClampingStrategy); arrayBoundsClamper.SetClampingStrategy(resources.ArrayIndexClampingStrategy);
clampingStrategy = resources.ArrayIndexClampingStrategy; clampingStrategy = resources.ArrayIndexClampingStrategy;
...@@ -161,6 +164,7 @@ bool TCompiler::compile(const char* const shaderStrings[], ...@@ -161,6 +164,7 @@ bool TCompiler::compile(const char* const shaderStrings[],
TParseContext parseContext(symbolTable, extensionBehavior, intermediate, TParseContext parseContext(symbolTable, extensionBehavior, intermediate,
shaderType, shaderSpec, compileOptions, true, shaderType, shaderSpec, compileOptions, true,
sourcePath, infoSink); sourcePath, infoSink);
parseContext.fragmentPrecisionHigh = fragmentPrecisionHigh;
GlobalParseContext = &parseContext; GlobalParseContext = &parseContext;
// We preserve symbols at the built-in level from compile-to-compile. // We preserve symbols at the built-in level from compile-to-compile.
......
...@@ -58,6 +58,7 @@ struct TParseContext { ...@@ -58,6 +58,7 @@ struct TParseContext {
const TType* currentFunctionType; // the return type of the function that's currently being parsed 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 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 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; TString HashErrMsg;
bool AfterEOF; bool AfterEOF;
TDiagnostics diagnostics; TDiagnostics diagnostics;
......
...@@ -124,6 +124,7 @@ private: ...@@ -124,6 +124,7 @@ private:
TSymbolTable symbolTable; TSymbolTable symbolTable;
// Built-in extensions with default behavior. // Built-in extensions with default behavior.
TExtensionBehavior extensionBehavior; TExtensionBehavior extensionBehavior;
bool fragmentPrecisionHigh;
ArrayBoundsClamper arrayBoundsClamper; ArrayBoundsClamper arrayBoundsClamper;
ShArrayIndexClampingStrategy clampingStrategy; ShArrayIndexClampingStrategy clampingStrategy;
......
...@@ -128,6 +128,9 @@ void ShInitBuiltInResources(ShBuiltInResources* resources) ...@@ -128,6 +128,9 @@ void ShInitBuiltInResources(ShBuiltInResources* resources)
resources->ARB_texture_rectangle = 0; resources->ARB_texture_rectangle = 0;
resources->EXT_draw_buffers = 0; resources->EXT_draw_buffers = 0;
// Disable highp precision in fragment shader by default.
resources->FragmentPrecisionHigh = 0;
// Disable name hashing by default. // Disable name hashing by default.
resources->HashFunction = NULL; resources->HashFunction = NULL;
......
...@@ -357,6 +357,9 @@ int glslang_scan(size_t count, const char* const string[], const int length[], ...@@ -357,6 +357,9 @@ int glslang_scan(size_t count, const char* const string[], const int length[],
iter != extBehavior.end(); ++iter) { iter != extBehavior.end(); ++iter) {
context->preprocessor.predefineMacro(iter->first.c_str(), 1); context->preprocessor.predefineMacro(iter->first.c_str(), 1);
} }
if (context->fragmentPrecisionHigh)
context->preprocessor.predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1);
return 0; return 0;
} }
...@@ -991,6 +991,10 @@ declaration ...@@ -991,6 +991,10 @@ declaration
$$ = $1.intermAggregate; $$ = $1.intermAggregate;
} }
| PRECISION precision_qualifier type_specifier_no_prec SEMICOLON { | 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 )) { if (!context->symbolTable.setDefaultPrecision( $3, $2 )) {
context->error($1.line, "illegal type argument for default precision qualifier", getBasicString($3.type)); context->error($1.line, "illegal type argument for default precision qualifier", getBasicString($3.type));
context->recover(); context->recover();
...@@ -2145,4 +2149,3 @@ function_definition ...@@ -2145,4 +2149,3 @@ function_definition
int glslang_parse(TParseContext* context) { int glslang_parse(TParseContext* context) {
return yyparse(context); return yyparse(context);
} }
...@@ -2954,7 +2954,7 @@ yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner) { ...@@ -2954,7 +2954,7 @@ yy_size_t string_input(char* buf, yy_size_t max_size, yyscan_t yyscanner) {
yy_size_t len = token.type == pp::Token::LAST ? 0 : token.text.size(); yy_size_t len = token.type == pp::Token::LAST ? 0 : token.text.size();
if (len < max_size) if (len < max_size)
memcpy(buf, token.text.c_str(), len); 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) if (len >= max_size)
YY_FATAL_ERROR("Input buffer overflow"); YY_FATAL_ERROR("Input buffer overflow");
...@@ -3033,6 +3033,9 @@ int glslang_scan(size_t count, const char* const string[], const int length[], ...@@ -3033,6 +3033,9 @@ int glslang_scan(size_t count, const char* const string[], const int length[],
iter != extBehavior.end(); ++iter) { iter != extBehavior.end(); ++iter) {
context->preprocessor.predefineMacro(iter->first.c_str(), 1); context->preprocessor.predefineMacro(iter->first.c_str(), 1);
} }
if (context->fragmentPrecisionHigh)
context->preprocessor.predefineMacro("GL_FRAGMENT_PRECISION_HIGH", 1);
return 0; return 0;
} }
...@@ -667,20 +667,20 @@ static const yytype_uint16 yyrline[] = ...@@ -667,20 +667,20 @@ static const yytype_uint16 yyrline[] =
762, 773, 777, 778, 788, 798, 808, 821, 822, 832, 762, 773, 777, 778, 788, 798, 808, 821, 822, 832,
845, 849, 853, 857, 858, 871, 872, 885, 886, 899, 845, 849, 853, 857, 858, 871, 872, 885, 886, 899,
900, 917, 918, 931, 932, 933, 934, 935, 939, 942, 900, 917, 918, 931, 932, 933, 934, 935, 939, 942,
953, 961, 988, 993, 1003, 1041, 1044, 1051, 1059, 1080, 953, 961, 988, 993, 1007, 1045, 1048, 1055, 1063, 1084,
1101, 1112, 1141, 1146, 1156, 1161, 1171, 1174, 1177, 1180, 1105, 1116, 1145, 1150, 1160, 1165, 1175, 1178, 1181, 1184,
1186, 1193, 1196, 1218, 1236, 1260, 1283, 1287, 1305, 1313, 1190, 1197, 1200, 1222, 1240, 1264, 1287, 1291, 1309, 1317,
1345, 1365, 1454, 1463, 1486, 1489, 1495, 1503, 1511, 1519, 1349, 1369, 1458, 1467, 1490, 1493, 1499, 1507, 1515, 1523,
1529, 1536, 1539, 1542, 1548, 1551, 1566, 1570, 1574, 1578, 1533, 1540, 1543, 1546, 1552, 1555, 1570, 1574, 1578, 1582,
1587, 1592, 1597, 1602, 1607, 1612, 1617, 1622, 1627, 1632, 1591, 1596, 1601, 1606, 1611, 1616, 1621, 1626, 1631, 1636,
1638, 1644, 1650, 1655, 1660, 1669, 1678, 1683, 1696, 1696, 1642, 1648, 1654, 1659, 1664, 1673, 1682, 1687, 1700, 1700,
1710, 1710, 1719, 1722, 1737, 1773, 1777, 1783, 1791, 1807, 1714, 1714, 1723, 1726, 1741, 1777, 1781, 1787, 1795, 1811,
1811, 1815, 1816, 1822, 1823, 1824, 1825, 1826, 1830, 1831, 1815, 1819, 1820, 1826, 1827, 1828, 1829, 1830, 1834, 1835,
1831, 1831, 1841, 1842, 1846, 1846, 1847, 1847, 1852, 1855, 1835, 1835, 1845, 1846, 1850, 1850, 1851, 1851, 1856, 1859,
1865, 1868, 1874, 1875, 1879, 1887, 1891, 1901, 1906, 1923, 1869, 1872, 1878, 1879, 1883, 1891, 1895, 1905, 1910, 1927,
1923, 1928, 1928, 1935, 1935, 1943, 1946, 1952, 1955, 1961, 1927, 1932, 1932, 1939, 1939, 1947, 1950, 1956, 1959, 1965,
1965, 1972, 1979, 1986, 1993, 2004, 2013, 2017, 2024, 2027, 1969, 1976, 1983, 1990, 1997, 2008, 2017, 2021, 2028, 2031,
2033, 2033 2037, 2037
}; };
#endif #endif
...@@ -3088,6 +3088,10 @@ yyreduce: ...@@ -3088,6 +3088,10 @@ yyreduce:
case 73: 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) )) { 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->error((yyvsp[(1) - (4)].lex).line, "illegal type argument for default precision qualifier", getBasicString((yyvsp[(3) - (4)].interm.type).type));
context->recover(); context->recover();
...@@ -4755,3 +4759,4 @@ yyreturn: ...@@ -4755,3 +4759,4 @@ yyreturn:
int glslang_parse(TParseContext* context) { int glslang_parse(TParseContext* context) {
return yyparse(context); return yyparse(context);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment