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(
{"hlsl.swizzle.frag", "PixelShaderFunction"},
{"hlsl.templatetypes.frag", "PixelShaderFunction"},
{"hlsl.tx.bracket.frag", "main"},
{"hlsl.type.half.frag", "main"},
{"hlsl.type.identifier.frag", "main"},
{"hlsl.typedef.frag", "PixelShaderFunction"},
{"hlsl.whileLoop.frag", "PixelShaderFunction"},
{"hlsl.void.frag", "PixelShaderFunction"},
......
......@@ -85,21 +85,36 @@ bool HlslGrammar::acceptIdentifier(HlslToken& idToken)
return true;
}
// Even though "sample" is a keyword (for interpolation modifiers), it IS still accepted as
// an identifier. This appears to be a solitary exception: other interp modifier keywords such
// as "linear" or "centroid" NOT valid identifiers. This code special cases "sample",
// so e.g, "int sample;" is accepted.
if (peekTokenClass(EHTokSample)) {
token.string = NewPoolTString("sample");
token.tokenClass = EHTokIdentifier;
token.symbol = nullptr;
idToken = token;
advanceToken();
return true;
// Even though "sample", "bool", "float", etc keywords (for types, interpolation modifiers),
// they ARE still accepted as identifiers. This is not a dense space: e.g, "void" is not a
// valid identifier, nor is "linear". This code special cases the known instances of this, so
// e.g, "int sample;" or "float float;" is accepted. Other cases can be added here if needed.
TString* idString = nullptr;
switch (peek()) {
case EHTokSample: idString = NewPoolTString("sample"); break;
case EHTokHalf: idString = NewPoolTString("half"); break;
case EHTokBool: idString = NewPoolTString("bool"); break;
case EHTokFloat: idString = NewPoolTString("float"); break;
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
......@@ -418,7 +433,15 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node)
// SEMICOLON
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;
}
......@@ -1086,6 +1109,7 @@ bool HlslGrammar::acceptType(TType& type)
// changes, e.g, to use native halfs.
static const TBasicType min16float_bt = EbtFloat;
static const TBasicType min10float_bt = EbtFloat;
static const TBasicType half_bt = EbtFloat;
static const TBasicType min16int_bt = EbtInt;
static const TBasicType min12int_bt = EbtInt;
static const TBasicType min16uint_bt = EbtUint;
......@@ -1255,6 +1279,23 @@ bool HlslGrammar::acceptType(TType& type)
new(&type) TType(EbtBool, EvqTemporary, 4);
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:
new(&type) TType(min16float_bt, EvqTemporary, EpqMedium);
break;
......@@ -1683,6 +1724,7 @@ bool HlslGrammar::acceptStruct(TType& type)
bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList)
{
typeList = new TTypeList();
HlslToken idToken;
do {
// success on seeing the RIGHT_BRACE coming up
......@@ -1700,8 +1742,7 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList)
// struct_declarator COMMA struct_declarator ...
do {
// peek IDENTIFIER
if (! peekTokenClass(EHTokIdentifier)) {
if (! acceptIdentifier(idToken)) {
expected("member name");
return false;
}
......@@ -1709,12 +1750,9 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList)
// add it to the list of members
TTypeLoc member = { new TType(EbtVoid), token.loc };
member.type->shallowCopy(memberType);
member.type->setFieldName(*token.string);
member.type->setFieldName(*idToken.string);
typeList->push_back(member);
// accept IDENTIFIER
advanceToken();
// array_specifier
TArraySizes* arraySizes = nullptr;
acceptArraySpecifier(arraySizes);
......@@ -2378,7 +2416,9 @@ bool HlslGrammar::acceptConstructor(TIntermTyped*& node)
// arguments
TIntermTyped* arguments = nullptr;
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;
}
......
......@@ -169,6 +169,10 @@ void HlslScanContext::fillInKeywordMap()
(*KeywordMap)["uint3"] = EHTokUint3;
(*KeywordMap)["uint4"] = EHTokUint4;
(*KeywordMap)["half1"] = EHTokHalf1;
(*KeywordMap)["half2"] = EHTokHalf2;
(*KeywordMap)["half3"] = EHTokHalf3;
(*KeywordMap)["half4"] = EHTokHalf4;
(*KeywordMap)["min16float1"] = EHTokMin16float1;
(*KeywordMap)["min16float2"] = EHTokMin16float2;
(*KeywordMap)["min16float3"] = EHTokMin16float3;
......@@ -579,6 +583,10 @@ EHlslTokenClass HlslScanContext::tokenizeIdentifier()
case EHTokUint2:
case EHTokUint3:
case EHTokUint4:
case EHTokHalf1:
case EHTokHalf2:
case EHTokHalf3:
case EHTokHalf4:
case EHTokMin16float1:
case EHTokMin16float2:
case EHTokMin16float3:
......
......@@ -120,6 +120,10 @@ enum EHlslTokenClass {
EHTokUint2,
EHTokUint3,
EHTokUint4,
EHTokHalf1,
EHTokHalf2,
EHTokHalf3,
EHTokHalf4,
EHTokMin16float1,
EHTokMin16float2,
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