HLSL: Partially address issue #463: accept GLSL layout(...).
This includes all "per variable" layout qualifiers, but the key ones mattering and tested for now are: set= binding= constant_id= push_constant
This commit is contained in:
parent
78a8b0737c
commit
b9e39120b4
112
Test/baseResults/hlsl.layout.frag.out
Executable file
112
Test/baseResults/hlsl.layout.frag.out
Executable file
@ -0,0 +1,112 @@
|
|||||||
|
hlsl.layout.frag
|
||||||
|
Shader version: 450
|
||||||
|
gl_FragCoord origin is upper left
|
||||||
|
0:? Sequence
|
||||||
|
0:15 Function Definition: PixelShaderFunction(vf4; (global 4-component vector of float)
|
||||||
|
0:12 Function Parameters:
|
||||||
|
0:12 'input' (in 4-component vector of float)
|
||||||
|
0:? Sequence
|
||||||
|
0:13 Branch: Return with expression
|
||||||
|
0:13 add (temp 4-component vector of float)
|
||||||
|
0:13 add (temp 4-component vector of float)
|
||||||
|
0:13 'input' (in 4-component vector of float)
|
||||||
|
0:13 v1: direct index for structure (layout(column_major std430 offset=16 ) buffer 4-component vector of float)
|
||||||
|
0:13 'anon@0' (layout(set=3 binding=5 column_major std430 ) buffer block{layout(column_major std430 offset=16 ) buffer 4-component vector of float v1})
|
||||||
|
0:13 Constant:
|
||||||
|
0:13 0 (const uint)
|
||||||
|
0:13 v5: direct index for structure (layout(column_major std430 offset=0 ) buffer 4-component vector of float)
|
||||||
|
0:13 'anon@1' (layout(column_major std430 push_constant ) buffer block{layout(column_major std430 offset=0 ) buffer 4-component vector of float v5})
|
||||||
|
0:13 Constant:
|
||||||
|
0:13 0 (const uint)
|
||||||
|
0:? Linker Objects
|
||||||
|
0:? 'anon@0' (layout(set=3 binding=5 column_major std430 ) buffer block{layout(column_major std430 offset=16 ) buffer 4-component vector of float v1})
|
||||||
|
0:? 'anon@1' (layout(column_major std430 push_constant ) buffer block{layout(column_major std430 offset=0 ) buffer 4-component vector of float v5})
|
||||||
|
0:? 'specConst' (specialization-constant const int)
|
||||||
|
0:? 10 (const int)
|
||||||
|
|
||||||
|
|
||||||
|
Linked fragment stage:
|
||||||
|
|
||||||
|
|
||||||
|
Shader version: 450
|
||||||
|
gl_FragCoord origin is upper left
|
||||||
|
0:? Sequence
|
||||||
|
0:15 Function Definition: PixelShaderFunction(vf4; (global 4-component vector of float)
|
||||||
|
0:12 Function Parameters:
|
||||||
|
0:12 'input' (in 4-component vector of float)
|
||||||
|
0:? Sequence
|
||||||
|
0:13 Branch: Return with expression
|
||||||
|
0:13 add (temp 4-component vector of float)
|
||||||
|
0:13 add (temp 4-component vector of float)
|
||||||
|
0:13 'input' (in 4-component vector of float)
|
||||||
|
0:13 v1: direct index for structure (layout(column_major std430 offset=16 ) buffer 4-component vector of float)
|
||||||
|
0:13 'anon@0' (layout(set=3 binding=5 column_major std430 ) buffer block{layout(column_major std430 offset=16 ) buffer 4-component vector of float v1})
|
||||||
|
0:13 Constant:
|
||||||
|
0:13 0 (const uint)
|
||||||
|
0:13 v5: direct index for structure (layout(column_major std430 offset=0 ) buffer 4-component vector of float)
|
||||||
|
0:13 'anon@1' (layout(column_major std430 push_constant ) buffer block{layout(column_major std430 offset=0 ) buffer 4-component vector of float v5})
|
||||||
|
0:13 Constant:
|
||||||
|
0:13 0 (const uint)
|
||||||
|
0:? Linker Objects
|
||||||
|
0:? 'anon@0' (layout(set=3 binding=5 column_major std430 ) buffer block{layout(column_major std430 offset=16 ) buffer 4-component vector of float v1})
|
||||||
|
0:? 'anon@1' (layout(column_major std430 push_constant ) buffer block{layout(column_major std430 offset=0 ) buffer 4-component vector of float v5})
|
||||||
|
0:? 'specConst' (specialization-constant const int)
|
||||||
|
0:? 10 (const int)
|
||||||
|
|
||||||
|
// Module Version 10000
|
||||||
|
// Generated by (magic number): 80001
|
||||||
|
// Id's are bound by 33
|
||||||
|
|
||||||
|
Capability Shader
|
||||||
|
1: ExtInstImport "GLSL.std.450"
|
||||||
|
MemoryModel Logical GLSL450
|
||||||
|
EntryPoint Fragment 4 "main"
|
||||||
|
ExecutionMode 4 OriginUpperLeft
|
||||||
|
Name 4 "main"
|
||||||
|
Name 11 "PixelShaderFunction(vf4;"
|
||||||
|
Name 10 "input"
|
||||||
|
Name 14 ""
|
||||||
|
MemberName 14 0 "v1"
|
||||||
|
Name 16 ""
|
||||||
|
Name 23 ""
|
||||||
|
MemberName 23 0 "v5"
|
||||||
|
Name 25 ""
|
||||||
|
MemberDecorate 14 0 Offset 16
|
||||||
|
Decorate 14 BufferBlock
|
||||||
|
Decorate 16 DescriptorSet 3
|
||||||
|
Decorate 16 Binding 5
|
||||||
|
MemberDecorate 23 0 Offset 0
|
||||||
|
Decorate 23 BufferBlock
|
||||||
|
Decorate 32 SpecId 17
|
||||||
|
2: TypeVoid
|
||||||
|
3: TypeFunction 2
|
||||||
|
6: TypeFloat 32
|
||||||
|
7: TypeVector 6(float) 4
|
||||||
|
8: TypePointer Function 7(fvec4)
|
||||||
|
9: TypeFunction 7(fvec4) 8(ptr)
|
||||||
|
14: TypeStruct 7(fvec4)
|
||||||
|
15: TypePointer Uniform 14(struct)
|
||||||
|
16: 15(ptr) Variable Uniform
|
||||||
|
17: TypeInt 32 1
|
||||||
|
18: 17(int) Constant 0
|
||||||
|
19: TypePointer Uniform 7(fvec4)
|
||||||
|
23: TypeStruct 7(fvec4)
|
||||||
|
24: TypePointer PushConstant 23(struct)
|
||||||
|
25: 24(ptr) Variable PushConstant
|
||||||
|
26: TypePointer PushConstant 7(fvec4)
|
||||||
|
32: 17(int) SpecConstant 10
|
||||||
|
4(main): 2 Function None 3
|
||||||
|
5: Label
|
||||||
|
FunctionEnd
|
||||||
|
11(PixelShaderFunction(vf4;): 7(fvec4) Function None 9
|
||||||
|
10(input): 8(ptr) FunctionParameter
|
||||||
|
12: Label
|
||||||
|
13: 7(fvec4) Load 10(input)
|
||||||
|
20: 19(ptr) AccessChain 16 18
|
||||||
|
21: 7(fvec4) Load 20
|
||||||
|
22: 7(fvec4) FAdd 13 21
|
||||||
|
27: 26(ptr) AccessChain 25 18
|
||||||
|
28: 7(fvec4) Load 27
|
||||||
|
29: 7(fvec4) FAdd 22 28
|
||||||
|
ReturnValue 29
|
||||||
|
FunctionEnd
|
14
Test/hlsl.layout.frag
Normal file
14
Test/hlsl.layout.frag
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
layout(set=3,binding=5) tbuffer tbufName {
|
||||||
|
layout(offset = 16) float4 v1;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(push_constant) tbuffer tbufName2 {
|
||||||
|
float4 v5;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(constant_id=17) const int specConst = 10;
|
||||||
|
|
||||||
|
float4 PixelShaderFunction(float4 input) : COLOR0
|
||||||
|
{
|
||||||
|
return input + v1 + v5;
|
||||||
|
}
|
@ -112,6 +112,7 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
{"hlsl.intrinsics.negative.comp", "ComputeShaderFunction"},
|
{"hlsl.intrinsics.negative.comp", "ComputeShaderFunction"},
|
||||||
{"hlsl.intrinsics.negative.frag", "PixelShaderFunction"},
|
{"hlsl.intrinsics.negative.frag", "PixelShaderFunction"},
|
||||||
{"hlsl.intrinsics.negative.vert", "VertexShaderFunction"},
|
{"hlsl.intrinsics.negative.vert", "VertexShaderFunction"},
|
||||||
|
{"hlsl.layout.frag", "main"},
|
||||||
{"hlsl.load.2dms.dx10.frag", "main"},
|
{"hlsl.load.2dms.dx10.frag", "main"},
|
||||||
{"hlsl.load.array.dx10.frag", "main"},
|
{"hlsl.load.array.dx10.frag", "main"},
|
||||||
{"hlsl.load.basic.dx10.frag", "main"},
|
{"hlsl.load.basic.dx10.frag", "main"},
|
||||||
|
@ -426,7 +426,8 @@ bool HlslGrammar::acceptFullySpecifiedType(TType& type)
|
|||||||
// type_qualifier
|
// type_qualifier
|
||||||
TQualifier qualifier;
|
TQualifier qualifier;
|
||||||
qualifier.clear();
|
qualifier.clear();
|
||||||
acceptQualifier(qualifier);
|
if (! acceptQualifier(qualifier))
|
||||||
|
return false;
|
||||||
TSourceLoc loc = token.loc;
|
TSourceLoc loc = token.loc;
|
||||||
|
|
||||||
// type_specifier
|
// type_specifier
|
||||||
@ -449,7 +450,7 @@ bool HlslGrammar::acceptFullySpecifiedType(TType& type)
|
|||||||
//
|
//
|
||||||
// Zero or more of these, so this can't return false.
|
// Zero or more of these, so this can't return false.
|
||||||
//
|
//
|
||||||
void HlslGrammar::acceptQualifier(TQualifier& qualifier)
|
bool HlslGrammar::acceptQualifier(TQualifier& qualifier)
|
||||||
{
|
{
|
||||||
do {
|
do {
|
||||||
switch (peek()) {
|
switch (peek()) {
|
||||||
@ -508,13 +509,66 @@ void HlslGrammar::acceptQualifier(TQualifier& qualifier)
|
|||||||
case EHTokInOut:
|
case EHTokInOut:
|
||||||
qualifier.storage = EvqInOut;
|
qualifier.storage = EvqInOut;
|
||||||
break;
|
break;
|
||||||
|
case EHTokLayout:
|
||||||
|
if (! acceptLayoutQualifierList(qualifier))
|
||||||
|
return false;
|
||||||
|
continue;
|
||||||
default:
|
default:
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
advanceToken();
|
advanceToken();
|
||||||
} while (true);
|
} while (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// layout_qualifier_list
|
||||||
|
// : LEFT_PAREN layout_qualifier COMMA layout_qualifier ... RIGHT_PAREN
|
||||||
|
//
|
||||||
|
// layout_qualifier
|
||||||
|
// : identifier
|
||||||
|
// | identifier EQUAL expresion
|
||||||
|
//
|
||||||
|
// Zero or more of these, so this can't return false.
|
||||||
|
//
|
||||||
|
bool HlslGrammar::acceptLayoutQualifierList(TQualifier& qualifier)
|
||||||
|
{
|
||||||
|
if (! acceptTokenClass(EHTokLayout))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// LEFT_PAREN
|
||||||
|
if (! acceptTokenClass(EHTokLeftParen))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
do {
|
||||||
|
// identifier
|
||||||
|
HlslToken idToken;
|
||||||
|
if (! acceptIdentifier(idToken))
|
||||||
|
break;
|
||||||
|
|
||||||
|
// EQUAL expression
|
||||||
|
if (acceptTokenClass(EHTokAssign)) {
|
||||||
|
TIntermTyped* expr;
|
||||||
|
if (! acceptConditionalExpression(expr)) {
|
||||||
|
expected("expression");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
parseContext.setLayoutQualifier(idToken.loc, qualifier, *idToken.string, expr);
|
||||||
|
} else
|
||||||
|
parseContext.setLayoutQualifier(idToken.loc, qualifier, *idToken.string);
|
||||||
|
|
||||||
|
// COMMA
|
||||||
|
if (! acceptTokenClass(EHTokComma))
|
||||||
|
break;
|
||||||
|
} while (true);
|
||||||
|
|
||||||
|
// RIGHT_PAREN
|
||||||
|
if (! acceptTokenClass(EHTokRightParen)) {
|
||||||
|
expected(")");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// template_type
|
// template_type
|
||||||
// : FLOAT
|
// : FLOAT
|
||||||
// | DOUBLE
|
// | DOUBLE
|
||||||
|
@ -67,7 +67,8 @@ namespace glslang {
|
|||||||
bool acceptSamplerDeclarationDX9(TType&);
|
bool acceptSamplerDeclarationDX9(TType&);
|
||||||
bool acceptSamplerState();
|
bool acceptSamplerState();
|
||||||
bool acceptFullySpecifiedType(TType&);
|
bool acceptFullySpecifiedType(TType&);
|
||||||
void acceptQualifier(TQualifier&);
|
bool acceptQualifier(TQualifier&);
|
||||||
|
bool acceptLayoutQualifierList(TQualifier&);
|
||||||
bool acceptType(TType&);
|
bool acceptType(TType&);
|
||||||
bool acceptTemplateType(TBasicType&);
|
bool acceptTemplateType(TBasicType&);
|
||||||
bool acceptVectorTemplateType(TType&);
|
bool acceptVectorTemplateType(TType&);
|
||||||
|
@ -3112,51 +3112,58 @@ void HlslParseContext::specializationCheck(const TSourceLoc& loc, const TType& t
|
|||||||
|
|
||||||
// Put the id's layout qualification into the public type, for qualifiers not having a number set.
|
// Put the id's layout qualification into the public type, for qualifiers not having a number set.
|
||||||
// This is before we know any type information for error checking.
|
// This is before we know any type information for error checking.
|
||||||
void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publicType, TString& id)
|
void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TQualifier& qualifier, TString& id)
|
||||||
{
|
{
|
||||||
std::transform(id.begin(), id.end(), id.begin(), ::tolower);
|
std::transform(id.begin(), id.end(), id.begin(), ::tolower);
|
||||||
|
|
||||||
if (id == TQualifier::getLayoutMatrixString(ElmColumnMajor)) {
|
if (id == TQualifier::getLayoutMatrixString(ElmColumnMajor)) {
|
||||||
publicType.qualifier.layoutMatrix = ElmColumnMajor;
|
qualifier.layoutMatrix = ElmColumnMajor;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (id == TQualifier::getLayoutMatrixString(ElmRowMajor)) {
|
if (id == TQualifier::getLayoutMatrixString(ElmRowMajor)) {
|
||||||
publicType.qualifier.layoutMatrix = ElmRowMajor;
|
qualifier.layoutMatrix = ElmRowMajor;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (id == "push_constant") {
|
if (id == "push_constant") {
|
||||||
requireVulkan(loc, "push_constant");
|
requireVulkan(loc, "push_constant");
|
||||||
publicType.qualifier.layoutPushConstant = true;
|
qualifier.layoutPushConstant = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (language == EShLangGeometry || language == EShLangTessEvaluation) {
|
if (language == EShLangGeometry || language == EShLangTessEvaluation) {
|
||||||
if (id == TQualifier::getGeometryString(ElgTriangles)) {
|
if (id == TQualifier::getGeometryString(ElgTriangles)) {
|
||||||
publicType.shaderQualifiers.geometry = ElgTriangles;
|
//publicType.shaderQualifiers.geometry = ElgTriangles;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (language == EShLangGeometry) {
|
if (language == EShLangGeometry) {
|
||||||
if (id == TQualifier::getGeometryString(ElgPoints)) {
|
if (id == TQualifier::getGeometryString(ElgPoints)) {
|
||||||
publicType.shaderQualifiers.geometry = ElgPoints;
|
//publicType.shaderQualifiers.geometry = ElgPoints;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (id == TQualifier::getGeometryString(ElgLineStrip)) {
|
if (id == TQualifier::getGeometryString(ElgLineStrip)) {
|
||||||
publicType.shaderQualifiers.geometry = ElgLineStrip;
|
//publicType.shaderQualifiers.geometry = ElgLineStrip;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (id == TQualifier::getGeometryString(ElgLines)) {
|
if (id == TQualifier::getGeometryString(ElgLines)) {
|
||||||
publicType.shaderQualifiers.geometry = ElgLines;
|
//publicType.shaderQualifiers.geometry = ElgLines;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (id == TQualifier::getGeometryString(ElgLinesAdjacency)) {
|
if (id == TQualifier::getGeometryString(ElgLinesAdjacency)) {
|
||||||
publicType.shaderQualifiers.geometry = ElgLinesAdjacency;
|
//publicType.shaderQualifiers.geometry = ElgLinesAdjacency;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (id == TQualifier::getGeometryString(ElgTrianglesAdjacency)) {
|
if (id == TQualifier::getGeometryString(ElgTrianglesAdjacency)) {
|
||||||
publicType.shaderQualifiers.geometry = ElgTrianglesAdjacency;
|
//publicType.shaderQualifiers.geometry = ElgTrianglesAdjacency;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (id == TQualifier::getGeometryString(ElgTriangleStrip)) {
|
if (id == TQualifier::getGeometryString(ElgTriangleStrip)) {
|
||||||
publicType.shaderQualifiers.geometry = ElgTriangleStrip;
|
//publicType.shaderQualifiers.geometry = ElgTriangleStrip;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -3164,65 +3171,78 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu
|
|||||||
|
|
||||||
// input primitive
|
// input primitive
|
||||||
if (id == TQualifier::getGeometryString(ElgTriangles)) {
|
if (id == TQualifier::getGeometryString(ElgTriangles)) {
|
||||||
publicType.shaderQualifiers.geometry = ElgTriangles;
|
//publicType.shaderQualifiers.geometry = ElgTriangles;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (id == TQualifier::getGeometryString(ElgQuads)) {
|
if (id == TQualifier::getGeometryString(ElgQuads)) {
|
||||||
publicType.shaderQualifiers.geometry = ElgQuads;
|
//publicType.shaderQualifiers.geometry = ElgQuads;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (id == TQualifier::getGeometryString(ElgIsolines)) {
|
if (id == TQualifier::getGeometryString(ElgIsolines)) {
|
||||||
publicType.shaderQualifiers.geometry = ElgIsolines;
|
//publicType.shaderQualifiers.geometry = ElgIsolines;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// vertex spacing
|
// vertex spacing
|
||||||
if (id == TQualifier::getVertexSpacingString(EvsEqual)) {
|
if (id == TQualifier::getVertexSpacingString(EvsEqual)) {
|
||||||
publicType.shaderQualifiers.spacing = EvsEqual;
|
//publicType.shaderQualifiers.spacing = EvsEqual;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (id == TQualifier::getVertexSpacingString(EvsFractionalEven)) {
|
if (id == TQualifier::getVertexSpacingString(EvsFractionalEven)) {
|
||||||
publicType.shaderQualifiers.spacing = EvsFractionalEven;
|
//publicType.shaderQualifiers.spacing = EvsFractionalEven;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (id == TQualifier::getVertexSpacingString(EvsFractionalOdd)) {
|
if (id == TQualifier::getVertexSpacingString(EvsFractionalOdd)) {
|
||||||
publicType.shaderQualifiers.spacing = EvsFractionalOdd;
|
//publicType.shaderQualifiers.spacing = EvsFractionalOdd;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// triangle order
|
// triangle order
|
||||||
if (id == TQualifier::getVertexOrderString(EvoCw)) {
|
if (id == TQualifier::getVertexOrderString(EvoCw)) {
|
||||||
publicType.shaderQualifiers.order = EvoCw;
|
//publicType.shaderQualifiers.order = EvoCw;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (id == TQualifier::getVertexOrderString(EvoCcw)) {
|
if (id == TQualifier::getVertexOrderString(EvoCcw)) {
|
||||||
publicType.shaderQualifiers.order = EvoCcw;
|
//publicType.shaderQualifiers.order = EvoCcw;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// point mode
|
// point mode
|
||||||
if (id == "point_mode") {
|
if (id == "point_mode") {
|
||||||
publicType.shaderQualifiers.pointMode = true;
|
//publicType.shaderQualifiers.pointMode = true;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (language == EShLangFragment) {
|
if (language == EShLangFragment) {
|
||||||
if (id == "origin_upper_left") {
|
if (id == "origin_upper_left") {
|
||||||
publicType.shaderQualifiers.originUpperLeft = true;
|
//publicType.shaderQualifiers.originUpperLeft = true;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (id == "pixel_center_integer") {
|
if (id == "pixel_center_integer") {
|
||||||
publicType.shaderQualifiers.pixelCenterInteger = true;
|
//publicType.shaderQualifiers.pixelCenterInteger = true;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (id == "early_fragment_tests") {
|
if (id == "early_fragment_tests") {
|
||||||
publicType.shaderQualifiers.earlyFragmentTests = true;
|
//publicType.shaderQualifiers.earlyFragmentTests = true;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (TLayoutDepth depth = (TLayoutDepth)(EldNone + 1); depth < EldCount; depth = (TLayoutDepth)(depth + 1)) {
|
for (TLayoutDepth depth = (TLayoutDepth)(EldNone + 1); depth < EldCount; depth = (TLayoutDepth)(depth + 1)) {
|
||||||
if (id == TQualifier::getLayoutDepthString(depth)) {
|
if (id == TQualifier::getLayoutDepthString(depth)) {
|
||||||
publicType.shaderQualifiers.layoutDepth = depth;
|
//publicType.shaderQualifiers.layoutDepth = depth;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3232,7 +3252,8 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu
|
|||||||
if (id == TQualifier::getBlendEquationString(be)) {
|
if (id == TQualifier::getBlendEquationString(be)) {
|
||||||
requireExtensions(loc, 1, &E_GL_KHR_blend_equation_advanced, "blend equation");
|
requireExtensions(loc, 1, &E_GL_KHR_blend_equation_advanced, "blend equation");
|
||||||
intermediate.addBlendEquation(be);
|
intermediate.addBlendEquation(be);
|
||||||
publicType.shaderQualifiers.blendEquation = true;
|
//publicType.shaderQualifiers.blendEquation = true;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3247,7 +3268,7 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu
|
|||||||
|
|
||||||
// Put the id's layout qualifier value into the public type, for qualifiers having a number set.
|
// Put the id's layout qualifier value into the public type, for qualifiers having a number set.
|
||||||
// This is before we know any type information for error checking.
|
// This is before we know any type information for error checking.
|
||||||
void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publicType, TString& id, const TIntermTyped* node)
|
void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TQualifier& qualifier, TString& id, const TIntermTyped* node)
|
||||||
{
|
{
|
||||||
const char* feature = "layout-id value";
|
const char* feature = "layout-id value";
|
||||||
//const char* nonLiteralFeature = "non-literal layout-id value";
|
//const char* nonLiteralFeature = "non-literal layout-id value";
|
||||||
@ -3262,38 +3283,38 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu
|
|||||||
std::transform(id.begin(), id.end(), id.begin(), ::tolower);
|
std::transform(id.begin(), id.end(), id.begin(), ::tolower);
|
||||||
|
|
||||||
if (id == "offset") {
|
if (id == "offset") {
|
||||||
publicType.qualifier.layoutOffset = value;
|
qualifier.layoutOffset = value;
|
||||||
return;
|
return;
|
||||||
} else if (id == "align") {
|
} else if (id == "align") {
|
||||||
// "The specified alignment must be a power of 2, or a compile-time error results."
|
// "The specified alignment must be a power of 2, or a compile-time error results."
|
||||||
if (! IsPow2(value))
|
if (! IsPow2(value))
|
||||||
error(loc, "must be a power of 2", "align", "");
|
error(loc, "must be a power of 2", "align", "");
|
||||||
else
|
else
|
||||||
publicType.qualifier.layoutAlign = value;
|
qualifier.layoutAlign = value;
|
||||||
return;
|
return;
|
||||||
} else if (id == "location") {
|
} else if (id == "location") {
|
||||||
if ((unsigned int)value >= TQualifier::layoutLocationEnd)
|
if ((unsigned int)value >= TQualifier::layoutLocationEnd)
|
||||||
error(loc, "location is too large", id.c_str(), "");
|
error(loc, "location is too large", id.c_str(), "");
|
||||||
else
|
else
|
||||||
publicType.qualifier.layoutLocation = value;
|
qualifier.layoutLocation = value;
|
||||||
return;
|
return;
|
||||||
} else if (id == "set") {
|
} else if (id == "set") {
|
||||||
if ((unsigned int)value >= TQualifier::layoutSetEnd)
|
if ((unsigned int)value >= TQualifier::layoutSetEnd)
|
||||||
error(loc, "set is too large", id.c_str(), "");
|
error(loc, "set is too large", id.c_str(), "");
|
||||||
else
|
else
|
||||||
publicType.qualifier.layoutSet = value;
|
qualifier.layoutSet = value;
|
||||||
return;
|
return;
|
||||||
} else if (id == "binding") {
|
} else if (id == "binding") {
|
||||||
if ((unsigned int)value >= TQualifier::layoutBindingEnd)
|
if ((unsigned int)value >= TQualifier::layoutBindingEnd)
|
||||||
error(loc, "binding is too large", id.c_str(), "");
|
error(loc, "binding is too large", id.c_str(), "");
|
||||||
else
|
else
|
||||||
publicType.qualifier.layoutBinding = value;
|
qualifier.layoutBinding = value;
|
||||||
return;
|
return;
|
||||||
} else if (id == "component") {
|
} else if (id == "component") {
|
||||||
if ((unsigned)value >= TQualifier::layoutComponentEnd)
|
if ((unsigned)value >= TQualifier::layoutComponentEnd)
|
||||||
error(loc, "component is too large", id.c_str(), "");
|
error(loc, "component is too large", id.c_str(), "");
|
||||||
else
|
else
|
||||||
publicType.qualifier.layoutComponent = value;
|
qualifier.layoutComponent = value;
|
||||||
return;
|
return;
|
||||||
} else if (id.compare(0, 4, "xfb_") == 0) {
|
} else if (id.compare(0, 4, "xfb_") == 0) {
|
||||||
// "Any shader making any static use (after preprocessing) of any of these
|
// "Any shader making any static use (after preprocessing) of any of these
|
||||||
@ -3309,13 +3330,13 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu
|
|||||||
if (value >= (int)TQualifier::layoutXfbBufferEnd)
|
if (value >= (int)TQualifier::layoutXfbBufferEnd)
|
||||||
error(loc, "buffer is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbBufferEnd - 1);
|
error(loc, "buffer is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbBufferEnd - 1);
|
||||||
else
|
else
|
||||||
publicType.qualifier.layoutXfbBuffer = value;
|
qualifier.layoutXfbBuffer = value;
|
||||||
return;
|
return;
|
||||||
} else if (id == "xfb_offset") {
|
} else if (id == "xfb_offset") {
|
||||||
if (value >= (int)TQualifier::layoutXfbOffsetEnd)
|
if (value >= (int)TQualifier::layoutXfbOffsetEnd)
|
||||||
error(loc, "offset is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbOffsetEnd - 1);
|
error(loc, "offset is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbOffsetEnd - 1);
|
||||||
else
|
else
|
||||||
publicType.qualifier.layoutXfbOffset = value;
|
qualifier.layoutXfbOffset = value;
|
||||||
return;
|
return;
|
||||||
} else if (id == "xfb_stride") {
|
} else if (id == "xfb_stride") {
|
||||||
// "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the
|
// "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the
|
||||||
@ -3325,7 +3346,7 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu
|
|||||||
else if (value >= (int)TQualifier::layoutXfbStrideEnd)
|
else if (value >= (int)TQualifier::layoutXfbStrideEnd)
|
||||||
error(loc, "stride is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbStrideEnd - 1);
|
error(loc, "stride is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbStrideEnd - 1);
|
||||||
if (value < (int)TQualifier::layoutXfbStrideEnd)
|
if (value < (int)TQualifier::layoutXfbStrideEnd)
|
||||||
publicType.qualifier.layoutXfbStride = value;
|
qualifier.layoutXfbStride = value;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3335,7 +3356,7 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu
|
|||||||
if (value >= (int)TQualifier::layoutAttachmentEnd)
|
if (value >= (int)TQualifier::layoutAttachmentEnd)
|
||||||
error(loc, "attachment index is too large", id.c_str(), "");
|
error(loc, "attachment index is too large", id.c_str(), "");
|
||||||
else
|
else
|
||||||
publicType.qualifier.layoutAttachment = value;
|
qualifier.layoutAttachment = value;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (id == "constant_id") {
|
if (id == "constant_id") {
|
||||||
@ -3343,8 +3364,8 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu
|
|||||||
if (value >= (int)TQualifier::layoutSpecConstantIdEnd) {
|
if (value >= (int)TQualifier::layoutSpecConstantIdEnd) {
|
||||||
error(loc, "specialization-constant id is too large", id.c_str(), "");
|
error(loc, "specialization-constant id is too large", id.c_str(), "");
|
||||||
} else {
|
} else {
|
||||||
publicType.qualifier.layoutSpecConstantId = value;
|
qualifier.layoutSpecConstantId = value;
|
||||||
publicType.qualifier.specConstant = true;
|
qualifier.specConstant = true;
|
||||||
if (! intermediate.addUsedConstantId(value))
|
if (! intermediate.addUsedConstantId(value))
|
||||||
error(loc, "specialization-constant id already used", id.c_str(), "");
|
error(loc, "specialization-constant id already used", id.c_str(), "");
|
||||||
}
|
}
|
||||||
@ -3360,7 +3381,8 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu
|
|||||||
if (value == 0)
|
if (value == 0)
|
||||||
error(loc, "must be greater than 0", "vertices", "");
|
error(loc, "must be greater than 0", "vertices", "");
|
||||||
else
|
else
|
||||||
publicType.shaderQualifiers.vertices = value;
|
//publicType.shaderQualifiers.vertices = value;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -3373,24 +3395,26 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu
|
|||||||
if (value == 0)
|
if (value == 0)
|
||||||
error(loc, "must be at least 1", "invocations", "");
|
error(loc, "must be at least 1", "invocations", "");
|
||||||
else
|
else
|
||||||
publicType.shaderQualifiers.invocations = value;
|
//publicType.shaderQualifiers.invocations = value;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (id == "max_vertices") {
|
if (id == "max_vertices") {
|
||||||
publicType.shaderQualifiers.vertices = value;
|
//publicType.shaderQualifiers.vertices = value;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
if (value > resources.maxGeometryOutputVertices)
|
if (value > resources.maxGeometryOutputVertices)
|
||||||
error(loc, "too large, must be less than gl_MaxGeometryOutputVertices", "max_vertices", "");
|
error(loc, "too large, must be less than gl_MaxGeometryOutputVertices", "max_vertices", "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (id == "stream") {
|
if (id == "stream") {
|
||||||
publicType.qualifier.layoutStream = value;
|
qualifier.layoutStream = value;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EShLangFragment:
|
case EShLangFragment:
|
||||||
if (id == "index") {
|
if (id == "index") {
|
||||||
publicType.qualifier.layoutIndex = value;
|
qualifier.layoutIndex = value;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -3398,28 +3422,34 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu
|
|||||||
case EShLangCompute:
|
case EShLangCompute:
|
||||||
if (id.compare(0, 11, "local_size_") == 0) {
|
if (id.compare(0, 11, "local_size_") == 0) {
|
||||||
if (id == "local_size_x") {
|
if (id == "local_size_x") {
|
||||||
publicType.shaderQualifiers.localSize[0] = value;
|
//publicType.shaderQualifiers.localSize[0] = value;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (id == "local_size_y") {
|
if (id == "local_size_y") {
|
||||||
publicType.shaderQualifiers.localSize[1] = value;
|
//publicType.shaderQualifiers.localSize[1] = value;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (id == "local_size_z") {
|
if (id == "local_size_z") {
|
||||||
publicType.shaderQualifiers.localSize[2] = value;
|
//publicType.shaderQualifiers.localSize[2] = value;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (spvVersion.spv != 0) {
|
if (spvVersion.spv != 0) {
|
||||||
if (id == "local_size_x_id") {
|
if (id == "local_size_x_id") {
|
||||||
publicType.shaderQualifiers.localSizeSpecId[0] = value;
|
//publicType.shaderQualifiers.localSizeSpecId[0] = value;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (id == "local_size_y_id") {
|
if (id == "local_size_y_id") {
|
||||||
publicType.shaderQualifiers.localSizeSpecId[1] = value;
|
//publicType.shaderQualifiers.localSizeSpecId[1] = value;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (id == "local_size_z_id") {
|
if (id == "local_size_z_id") {
|
||||||
publicType.shaderQualifiers.localSizeSpecId[2] = value;
|
//publicType.shaderQualifiers.localSizeSpecId[2] = value;
|
||||||
|
warn(loc, "ignored", id.c_str(), "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,8 +128,8 @@ public:
|
|||||||
void paramFix(TType& type);
|
void paramFix(TType& type);
|
||||||
void specializationCheck(const TSourceLoc&, const TType&, const char* op);
|
void specializationCheck(const TSourceLoc&, const TType&, const char* op);
|
||||||
|
|
||||||
void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&);
|
void setLayoutQualifier(const TSourceLoc&, TQualifier&, TString&);
|
||||||
void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&, const TIntermTyped*);
|
void setLayoutQualifier(const TSourceLoc&, TQualifier&, TString&, const TIntermTyped*);
|
||||||
void mergeObjectLayoutQualifiers(TQualifier& dest, const TQualifier& src, bool inheritOnly);
|
void mergeObjectLayoutQualifiers(TQualifier& dest, const TQualifier& src, bool inheritOnly);
|
||||||
void checkNoShaderLayouts(const TSourceLoc&, const TShaderQualifiers&);
|
void checkNoShaderLayouts(const TSourceLoc&, const TShaderQualifiers&);
|
||||||
|
|
||||||
|
@ -117,6 +117,7 @@ void HlslScanContext::fillInKeywordMap()
|
|||||||
(*KeywordMap)["in"] = EHTokIn;
|
(*KeywordMap)["in"] = EHTokIn;
|
||||||
(*KeywordMap)["out"] = EHTokOut;
|
(*KeywordMap)["out"] = EHTokOut;
|
||||||
(*KeywordMap)["inout"] = EHTokInOut;
|
(*KeywordMap)["inout"] = EHTokInOut;
|
||||||
|
(*KeywordMap)["layout"] = EHTokLayout;
|
||||||
|
|
||||||
(*KeywordMap)["Buffer"] = EHTokBuffer;
|
(*KeywordMap)["Buffer"] = EHTokBuffer;
|
||||||
(*KeywordMap)["vector"] = EHTokVector;
|
(*KeywordMap)["vector"] = EHTokVector;
|
||||||
@ -457,6 +458,7 @@ EHlslTokenClass HlslScanContext::tokenizeIdentifier()
|
|||||||
case EHTokIn:
|
case EHTokIn:
|
||||||
case EHTokOut:
|
case EHTokOut:
|
||||||
case EHTokInOut:
|
case EHTokInOut:
|
||||||
|
case EHTokLayout:
|
||||||
return keyword;
|
return keyword;
|
||||||
|
|
||||||
// template types
|
// template types
|
||||||
|
@ -64,6 +64,7 @@ enum EHlslTokenClass {
|
|||||||
EHTokIn,
|
EHTokIn,
|
||||||
EHTokOut,
|
EHTokOut,
|
||||||
EHTokInOut,
|
EHTokInOut,
|
||||||
|
EHTokLayout,
|
||||||
|
|
||||||
// template types
|
// template types
|
||||||
EHTokBuffer,
|
EHTokBuffer,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user