Commit bf9a2f30 by John Kessenich Committed by GitHub

Merge pull request #648 from steve-lunarg/type-identifiers

HLSL: allow type keywords as identifiers, and add half type
parents ddfbbe26 5ca85ad9
hlsl.type.half.frag
Shader version: 450
gl_FragCoord origin is upper left
0:? Sequence
0:3 Function Definition: main( (temp 4-component vector of float)
0:3 Function Parameters:
0:? Sequence
0:4 Sequence
0:4 move second child to first child (temp mediump float)
0:4 'h0' (temp mediump float)
0:4 Constant:
0:4 0.000000
0:5 Sequence
0:5 move second child to first child (temp mediump 1-component vector of float)
0:5 'h1' (temp mediump 1-component vector of float)
0:5 Constant:
0:5 1.000000
0:6 Sequence
0:6 move second child to first child (temp mediump 2-component vector of float)
0:6 'h2' (temp mediump 2-component vector of float)
0:6 Constant:
0:6 2.000000
0:6 2.000000
0:7 Sequence
0:7 move second child to first child (temp mediump 3-component vector of float)
0:7 'h3' (temp mediump 3-component vector of float)
0:7 Constant:
0:7 3.000000
0:7 3.000000
0:7 3.000000
0:8 Sequence
0:8 move second child to first child (temp mediump 4-component vector of float)
0:8 'h4' (temp mediump 4-component vector of float)
0:8 Constant:
0:8 4.000000
0:8 4.000000
0:8 4.000000
0:8 4.000000
0:10 Sequence
0:10 move second child to first child (temp 4-component vector of float)
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
0:10 Constant:
0:10 0.000000
0:10 0.000000
0:10 0.000000
0:10 0.000000
0:10 Branch: Return
0:? Linker Objects
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
Linked fragment stage:
Shader version: 450
gl_FragCoord origin is upper left
0:? Sequence
0:3 Function Definition: main( (temp 4-component vector of float)
0:3 Function Parameters:
0:? Sequence
0:4 Sequence
0:4 move second child to first child (temp mediump float)
0:4 'h0' (temp mediump float)
0:4 Constant:
0:4 0.000000
0:5 Sequence
0:5 move second child to first child (temp mediump 1-component vector of float)
0:5 'h1' (temp mediump 1-component vector of float)
0:5 Constant:
0:5 1.000000
0:6 Sequence
0:6 move second child to first child (temp mediump 2-component vector of float)
0:6 'h2' (temp mediump 2-component vector of float)
0:6 Constant:
0:6 2.000000
0:6 2.000000
0:7 Sequence
0:7 move second child to first child (temp mediump 3-component vector of float)
0:7 'h3' (temp mediump 3-component vector of float)
0:7 Constant:
0:7 3.000000
0:7 3.000000
0:7 3.000000
0:8 Sequence
0:8 move second child to first child (temp mediump 4-component vector of float)
0:8 'h4' (temp mediump 4-component vector of float)
0:8 Constant:
0:8 4.000000
0:8 4.000000
0:8 4.000000
0:8 4.000000
0:10 Sequence
0:10 move second child to first child (temp 4-component vector of float)
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
0:10 Constant:
0:10 0.000000
0:10 0.000000
0:10 0.000000
0:10 0.000000
0:10 Branch: Return
0:? Linker Objects
0:? '@entryPointOutput' (layout(location=0 ) out 4-component vector of float)
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 31
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 28
ExecutionMode 4 OriginUpperLeft
Name 4 "main"
Name 8 "h0"
Name 10 "h1"
Name 14 "h2"
Name 19 "h3"
Name 24 "h4"
Name 28 "@entryPointOutput"
Decorate 8(h0) RelaxedPrecision
Decorate 10(h1) RelaxedPrecision
Decorate 14(h2) RelaxedPrecision
Decorate 19(h3) RelaxedPrecision
Decorate 24(h4) RelaxedPrecision
Decorate 28(@entryPointOutput) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypePointer Function 6(float)
9: 6(float) Constant 0
11: 6(float) Constant 1065353216
12: TypeVector 6(float) 2
13: TypePointer Function 12(fvec2)
15: 6(float) Constant 1073741824
16: 12(fvec2) ConstantComposite 15 15
17: TypeVector 6(float) 3
18: TypePointer Function 17(fvec3)
20: 6(float) Constant 1077936128
21: 17(fvec3) ConstantComposite 20 20 20
22: TypeVector 6(float) 4
23: TypePointer Function 22(fvec4)
25: 6(float) Constant 1082130432
26: 22(fvec4) ConstantComposite 25 25 25 25
27: TypePointer Output 22(fvec4)
28(@entryPointOutput): 27(ptr) Variable Output
29: 22(fvec4) ConstantComposite 9 9 9 9
4(main): 2 Function None 3
5: Label
8(h0): 7(ptr) Variable Function
10(h1): 7(ptr) Variable Function
14(h2): 13(ptr) Variable Function
19(h3): 18(ptr) Variable Function
24(h4): 23(ptr) Variable Function
Store 8(h0) 9
Store 10(h1) 11
Store 14(h2) 16
Store 19(h3) 21
Store 24(h4) 26
Store 28(@entryPointOutput) 29
Return
FunctionEnd
float4 main() : SV_Target0
{
half h0 = 0;
half1 h1 = 1;
half2 h2 = 2;
half3 h3 = 3;
half4 h4 = 4;
return 0.0;
}
struct foo_t {
float float;
};
float fn(float float) { return float; }
float4 main() : SV_Target0
{
float float = 7;
bool bool[2] = { float, float };
int int = bool[1];
uint uint = float + int;
min16float min16float = uint;
min10float min10float = min16float;
half half = 0.5;
{
foo_t float;
float.float = 42;
}
bool[0] = bool[1];
float = float + int + uint + min16float + min10float + (bool[0] ? int : float) + fn(float);
return float;
}
...@@ -230,6 +230,8 @@ INSTANTIATE_TEST_CASE_P( ...@@ -230,6 +230,8 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.swizzle.frag", "PixelShaderFunction"}, {"hlsl.swizzle.frag", "PixelShaderFunction"},
{"hlsl.templatetypes.frag", "PixelShaderFunction"}, {"hlsl.templatetypes.frag", "PixelShaderFunction"},
{"hlsl.tx.bracket.frag", "main"}, {"hlsl.tx.bracket.frag", "main"},
{"hlsl.type.half.frag", "main"},
{"hlsl.type.identifier.frag", "main"},
{"hlsl.typedef.frag", "PixelShaderFunction"}, {"hlsl.typedef.frag", "PixelShaderFunction"},
{"hlsl.whileLoop.frag", "PixelShaderFunction"}, {"hlsl.whileLoop.frag", "PixelShaderFunction"},
{"hlsl.void.frag", "PixelShaderFunction"}, {"hlsl.void.frag", "PixelShaderFunction"},
......
...@@ -85,21 +85,36 @@ bool HlslGrammar::acceptIdentifier(HlslToken& idToken) ...@@ -85,21 +85,36 @@ bool HlslGrammar::acceptIdentifier(HlslToken& idToken)
return true; return true;
} }
// Even though "sample" is a keyword (for interpolation modifiers), it IS still accepted as // Even though "sample", "bool", "float", etc keywords (for types, interpolation modifiers),
// an identifier. This appears to be a solitary exception: other interp modifier keywords such // they ARE still accepted as identifiers. This is not a dense space: e.g, "void" is not a
// as "linear" or "centroid" NOT valid identifiers. This code special cases "sample", // valid identifier, nor is "linear". This code special cases the known instances of this, so
// so e.g, "int sample;" is accepted. // e.g, "int sample;" or "float float;" is accepted. Other cases can be added here if needed.
if (peekTokenClass(EHTokSample)) {
token.string = NewPoolTString("sample"); TString* idString = nullptr;
token.tokenClass = EHTokIdentifier; switch (peek()) {
token.symbol = nullptr; case EHTokSample: idString = NewPoolTString("sample"); break;
case EHTokHalf: idString = NewPoolTString("half"); break;
idToken = token; case EHTokBool: idString = NewPoolTString("bool"); break;
advanceToken(); case EHTokFloat: idString = NewPoolTString("float"); break;
return true; case EHTokDouble: idString = NewPoolTString("double"); break;
case EHTokInt: idString = NewPoolTString("int"); break;
case EHTokUint: idString = NewPoolTString("uint"); break;
case EHTokMin16float: idString = NewPoolTString("min16float"); break;
case EHTokMin10float: idString = NewPoolTString("min10float"); break;
case EHTokMin16int: idString = NewPoolTString("min16int"); break;
case EHTokMin12int: idString = NewPoolTString("min12int"); break;
default:
return false;
} }
return false; token.string = idString;
token.tokenClass = EHTokIdentifier;
token.symbol = nullptr;
idToken = token;
advanceToken();
return true;
} }
// compilationUnit // compilationUnit
...@@ -418,7 +433,15 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node) ...@@ -418,7 +433,15 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node)
// SEMICOLON // SEMICOLON
if (! acceptTokenClass(EHTokSemicolon)) { if (! acceptTokenClass(EHTokSemicolon)) {
expected(";"); // This may have been a false detection of what appeared to be a declaration, but
// was actually an assignment such as "float = 4", where "float" is an identifier.
// We put the token back to let further parsing happen for cases where that may
// happen. This errors on the side of caution, and mostly triggers the error.
if (peek() == EHTokAssign || peek() == EHTokLeftBracket || peek() == EHTokDot || peek() == EHTokComma)
recedeToken();
else
expected(";");
return false; return false;
} }
...@@ -1086,6 +1109,7 @@ bool HlslGrammar::acceptType(TType& type) ...@@ -1086,6 +1109,7 @@ bool HlslGrammar::acceptType(TType& type)
// changes, e.g, to use native halfs. // changes, e.g, to use native halfs.
static const TBasicType min16float_bt = EbtFloat; static const TBasicType min16float_bt = EbtFloat;
static const TBasicType min10float_bt = EbtFloat; static const TBasicType min10float_bt = EbtFloat;
static const TBasicType half_bt = EbtFloat;
static const TBasicType min16int_bt = EbtInt; static const TBasicType min16int_bt = EbtInt;
static const TBasicType min12int_bt = EbtInt; static const TBasicType min12int_bt = EbtInt;
static const TBasicType min16uint_bt = EbtUint; static const TBasicType min16uint_bt = EbtUint;
...@@ -1255,6 +1279,23 @@ bool HlslGrammar::acceptType(TType& type) ...@@ -1255,6 +1279,23 @@ bool HlslGrammar::acceptType(TType& type)
new(&type) TType(EbtBool, EvqTemporary, 4); new(&type) TType(EbtBool, EvqTemporary, 4);
break; break;
case EHTokHalf:
new(&type) TType(half_bt, EvqTemporary, EpqMedium);
break;
case EHTokHalf1:
new(&type) TType(half_bt, EvqTemporary, EpqMedium);
type.makeVector();
break;
case EHTokHalf2:
new(&type) TType(half_bt, EvqTemporary, EpqMedium, 2);
break;
case EHTokHalf3:
new(&type) TType(half_bt, EvqTemporary, EpqMedium, 3);
break;
case EHTokHalf4:
new(&type) TType(half_bt, EvqTemporary, EpqMedium, 4);
break;
case EHTokMin16float: case EHTokMin16float:
new(&type) TType(min16float_bt, EvqTemporary, EpqMedium); new(&type) TType(min16float_bt, EvqTemporary, EpqMedium);
break; break;
...@@ -1683,6 +1724,7 @@ bool HlslGrammar::acceptStruct(TType& type) ...@@ -1683,6 +1724,7 @@ bool HlslGrammar::acceptStruct(TType& type)
bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList) bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList)
{ {
typeList = new TTypeList(); typeList = new TTypeList();
HlslToken idToken;
do { do {
// success on seeing the RIGHT_BRACE coming up // success on seeing the RIGHT_BRACE coming up
...@@ -1700,8 +1742,7 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList) ...@@ -1700,8 +1742,7 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList)
// struct_declarator COMMA struct_declarator ... // struct_declarator COMMA struct_declarator ...
do { do {
// peek IDENTIFIER if (! acceptIdentifier(idToken)) {
if (! peekTokenClass(EHTokIdentifier)) {
expected("member name"); expected("member name");
return false; return false;
} }
...@@ -1709,12 +1750,9 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList) ...@@ -1709,12 +1750,9 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList)
// add it to the list of members // add it to the list of members
TTypeLoc member = { new TType(EbtVoid), token.loc }; TTypeLoc member = { new TType(EbtVoid), token.loc };
member.type->shallowCopy(memberType); member.type->shallowCopy(memberType);
member.type->setFieldName(*token.string); member.type->setFieldName(*idToken.string);
typeList->push_back(member); typeList->push_back(member);
// accept IDENTIFIER
advanceToken();
// array_specifier // array_specifier
TArraySizes* arraySizes = nullptr; TArraySizes* arraySizes = nullptr;
acceptArraySpecifier(arraySizes); acceptArraySpecifier(arraySizes);
...@@ -2378,7 +2416,9 @@ bool HlslGrammar::acceptConstructor(TIntermTyped*& node) ...@@ -2378,7 +2416,9 @@ bool HlslGrammar::acceptConstructor(TIntermTyped*& node)
// arguments // arguments
TIntermTyped* arguments = nullptr; TIntermTyped* arguments = nullptr;
if (! acceptArguments(constructorFunction, arguments)) { if (! acceptArguments(constructorFunction, arguments)) {
expected("constructor arguments"); // It's possible this is a type keyword used as an identifier. Put the token back
// for later use.
recedeToken();
return false; return false;
} }
......
...@@ -169,6 +169,10 @@ void HlslScanContext::fillInKeywordMap() ...@@ -169,6 +169,10 @@ void HlslScanContext::fillInKeywordMap()
(*KeywordMap)["uint3"] = EHTokUint3; (*KeywordMap)["uint3"] = EHTokUint3;
(*KeywordMap)["uint4"] = EHTokUint4; (*KeywordMap)["uint4"] = EHTokUint4;
(*KeywordMap)["half1"] = EHTokHalf1;
(*KeywordMap)["half2"] = EHTokHalf2;
(*KeywordMap)["half3"] = EHTokHalf3;
(*KeywordMap)["half4"] = EHTokHalf4;
(*KeywordMap)["min16float1"] = EHTokMin16float1; (*KeywordMap)["min16float1"] = EHTokMin16float1;
(*KeywordMap)["min16float2"] = EHTokMin16float2; (*KeywordMap)["min16float2"] = EHTokMin16float2;
(*KeywordMap)["min16float3"] = EHTokMin16float3; (*KeywordMap)["min16float3"] = EHTokMin16float3;
...@@ -579,6 +583,10 @@ EHlslTokenClass HlslScanContext::tokenizeIdentifier() ...@@ -579,6 +583,10 @@ EHlslTokenClass HlslScanContext::tokenizeIdentifier()
case EHTokUint2: case EHTokUint2:
case EHTokUint3: case EHTokUint3:
case EHTokUint4: case EHTokUint4:
case EHTokHalf1:
case EHTokHalf2:
case EHTokHalf3:
case EHTokHalf4:
case EHTokMin16float1: case EHTokMin16float1:
case EHTokMin16float2: case EHTokMin16float2:
case EHTokMin16float3: case EHTokMin16float3:
......
...@@ -120,6 +120,10 @@ enum EHlslTokenClass { ...@@ -120,6 +120,10 @@ enum EHlslTokenClass {
EHTokUint2, EHTokUint2,
EHTokUint3, EHTokUint3,
EHTokUint4, EHTokUint4,
EHTokHalf1,
EHTokHalf2,
EHTokHalf3,
EHTokHalf4,
EHTokMin16float1, EHTokMin16float1,
EHTokMin16float2, EHTokMin16float2,
EHTokMin16float3, EHTokMin16float3,
......
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