mirror of
https://github.com/RPCS3/glslang.git
synced 2025-01-24 20:15:44 +00:00
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.frag", "PixelShaderFunction"},
|
||||
{"hlsl.intrinsics.negative.vert", "VertexShaderFunction"},
|
||||
{"hlsl.layout.frag", "main"},
|
||||
{"hlsl.load.2dms.dx10.frag", "main"},
|
||||
{"hlsl.load.array.dx10.frag", "main"},
|
||||
{"hlsl.load.basic.dx10.frag", "main"},
|
||||
|
@ -426,7 +426,8 @@ bool HlslGrammar::acceptFullySpecifiedType(TType& type)
|
||||
// type_qualifier
|
||||
TQualifier qualifier;
|
||||
qualifier.clear();
|
||||
acceptQualifier(qualifier);
|
||||
if (! acceptQualifier(qualifier))
|
||||
return false;
|
||||
TSourceLoc loc = token.loc;
|
||||
|
||||
// type_specifier
|
||||
@ -449,7 +450,7 @@ bool HlslGrammar::acceptFullySpecifiedType(TType& type)
|
||||
//
|
||||
// Zero or more of these, so this can't return false.
|
||||
//
|
||||
void HlslGrammar::acceptQualifier(TQualifier& qualifier)
|
||||
bool HlslGrammar::acceptQualifier(TQualifier& qualifier)
|
||||
{
|
||||
do {
|
||||
switch (peek()) {
|
||||
@ -508,13 +509,66 @@ void HlslGrammar::acceptQualifier(TQualifier& qualifier)
|
||||
case EHTokInOut:
|
||||
qualifier.storage = EvqInOut;
|
||||
break;
|
||||
case EHTokLayout:
|
||||
if (! acceptLayoutQualifierList(qualifier))
|
||||
return false;
|
||||
continue;
|
||||
default:
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
advanceToken();
|
||||
} 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
|
||||
// : FLOAT
|
||||
// | DOUBLE
|
||||
|
@ -67,7 +67,8 @@ namespace glslang {
|
||||
bool acceptSamplerDeclarationDX9(TType&);
|
||||
bool acceptSamplerState();
|
||||
bool acceptFullySpecifiedType(TType&);
|
||||
void acceptQualifier(TQualifier&);
|
||||
bool acceptQualifier(TQualifier&);
|
||||
bool acceptLayoutQualifierList(TQualifier&);
|
||||
bool acceptType(TType&);
|
||||
bool acceptTemplateType(TBasicType&);
|
||||
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.
|
||||
// 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);
|
||||
|
||||
if (id == TQualifier::getLayoutMatrixString(ElmColumnMajor)) {
|
||||
publicType.qualifier.layoutMatrix = ElmColumnMajor;
|
||||
qualifier.layoutMatrix = ElmColumnMajor;
|
||||
return;
|
||||
}
|
||||
if (id == TQualifier::getLayoutMatrixString(ElmRowMajor)) {
|
||||
publicType.qualifier.layoutMatrix = ElmRowMajor;
|
||||
qualifier.layoutMatrix = ElmRowMajor;
|
||||
return;
|
||||
}
|
||||
if (id == "push_constant") {
|
||||
requireVulkan(loc, "push_constant");
|
||||
publicType.qualifier.layoutPushConstant = true;
|
||||
qualifier.layoutPushConstant = true;
|
||||
return;
|
||||
}
|
||||
if (language == EShLangGeometry || language == EShLangTessEvaluation) {
|
||||
if (id == TQualifier::getGeometryString(ElgTriangles)) {
|
||||
publicType.shaderQualifiers.geometry = ElgTriangles;
|
||||
//publicType.shaderQualifiers.geometry = ElgTriangles;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
if (language == EShLangGeometry) {
|
||||
if (id == TQualifier::getGeometryString(ElgPoints)) {
|
||||
publicType.shaderQualifiers.geometry = ElgPoints;
|
||||
//publicType.shaderQualifiers.geometry = ElgPoints;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
if (id == TQualifier::getGeometryString(ElgLineStrip)) {
|
||||
publicType.shaderQualifiers.geometry = ElgLineStrip;
|
||||
//publicType.shaderQualifiers.geometry = ElgLineStrip;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
if (id == TQualifier::getGeometryString(ElgLines)) {
|
||||
publicType.shaderQualifiers.geometry = ElgLines;
|
||||
//publicType.shaderQualifiers.geometry = ElgLines;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
if (id == TQualifier::getGeometryString(ElgLinesAdjacency)) {
|
||||
publicType.shaderQualifiers.geometry = ElgLinesAdjacency;
|
||||
//publicType.shaderQualifiers.geometry = ElgLinesAdjacency;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
if (id == TQualifier::getGeometryString(ElgTrianglesAdjacency)) {
|
||||
publicType.shaderQualifiers.geometry = ElgTrianglesAdjacency;
|
||||
//publicType.shaderQualifiers.geometry = ElgTrianglesAdjacency;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
if (id == TQualifier::getGeometryString(ElgTriangleStrip)) {
|
||||
publicType.shaderQualifiers.geometry = ElgTriangleStrip;
|
||||
//publicType.shaderQualifiers.geometry = ElgTriangleStrip;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@ -3164,65 +3171,78 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu
|
||||
|
||||
// input primitive
|
||||
if (id == TQualifier::getGeometryString(ElgTriangles)) {
|
||||
publicType.shaderQualifiers.geometry = ElgTriangles;
|
||||
//publicType.shaderQualifiers.geometry = ElgTriangles;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
if (id == TQualifier::getGeometryString(ElgQuads)) {
|
||||
publicType.shaderQualifiers.geometry = ElgQuads;
|
||||
//publicType.shaderQualifiers.geometry = ElgQuads;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
if (id == TQualifier::getGeometryString(ElgIsolines)) {
|
||||
publicType.shaderQualifiers.geometry = ElgIsolines;
|
||||
//publicType.shaderQualifiers.geometry = ElgIsolines;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
|
||||
// vertex spacing
|
||||
if (id == TQualifier::getVertexSpacingString(EvsEqual)) {
|
||||
publicType.shaderQualifiers.spacing = EvsEqual;
|
||||
//publicType.shaderQualifiers.spacing = EvsEqual;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
if (id == TQualifier::getVertexSpacingString(EvsFractionalEven)) {
|
||||
publicType.shaderQualifiers.spacing = EvsFractionalEven;
|
||||
//publicType.shaderQualifiers.spacing = EvsFractionalEven;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
if (id == TQualifier::getVertexSpacingString(EvsFractionalOdd)) {
|
||||
publicType.shaderQualifiers.spacing = EvsFractionalOdd;
|
||||
//publicType.shaderQualifiers.spacing = EvsFractionalOdd;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
|
||||
// triangle order
|
||||
if (id == TQualifier::getVertexOrderString(EvoCw)) {
|
||||
publicType.shaderQualifiers.order = EvoCw;
|
||||
//publicType.shaderQualifiers.order = EvoCw;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
if (id == TQualifier::getVertexOrderString(EvoCcw)) {
|
||||
publicType.shaderQualifiers.order = EvoCcw;
|
||||
//publicType.shaderQualifiers.order = EvoCcw;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
|
||||
// point mode
|
||||
if (id == "point_mode") {
|
||||
publicType.shaderQualifiers.pointMode = true;
|
||||
//publicType.shaderQualifiers.pointMode = true;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (language == EShLangFragment) {
|
||||
if (id == "origin_upper_left") {
|
||||
publicType.shaderQualifiers.originUpperLeft = true;
|
||||
//publicType.shaderQualifiers.originUpperLeft = true;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
if (id == "pixel_center_integer") {
|
||||
publicType.shaderQualifiers.pixelCenterInteger = true;
|
||||
//publicType.shaderQualifiers.pixelCenterInteger = true;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
if (id == "early_fragment_tests") {
|
||||
publicType.shaderQualifiers.earlyFragmentTests = true;
|
||||
//publicType.shaderQualifiers.earlyFragmentTests = true;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
for (TLayoutDepth depth = (TLayoutDepth)(EldNone + 1); depth < EldCount; depth = (TLayoutDepth)(depth + 1)) {
|
||||
if (id == TQualifier::getLayoutDepthString(depth)) {
|
||||
publicType.shaderQualifiers.layoutDepth = depth;
|
||||
//publicType.shaderQualifiers.layoutDepth = depth;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -3232,7 +3252,8 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu
|
||||
if (id == TQualifier::getBlendEquationString(be)) {
|
||||
requireExtensions(loc, 1, &E_GL_KHR_blend_equation_advanced, "blend equation");
|
||||
intermediate.addBlendEquation(be);
|
||||
publicType.shaderQualifiers.blendEquation = true;
|
||||
//publicType.shaderQualifiers.blendEquation = true;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
found = true;
|
||||
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.
|
||||
// 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* 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);
|
||||
|
||||
if (id == "offset") {
|
||||
publicType.qualifier.layoutOffset = value;
|
||||
qualifier.layoutOffset = value;
|
||||
return;
|
||||
} else if (id == "align") {
|
||||
// "The specified alignment must be a power of 2, or a compile-time error results."
|
||||
if (! IsPow2(value))
|
||||
error(loc, "must be a power of 2", "align", "");
|
||||
else
|
||||
publicType.qualifier.layoutAlign = value;
|
||||
qualifier.layoutAlign = value;
|
||||
return;
|
||||
} else if (id == "location") {
|
||||
if ((unsigned int)value >= TQualifier::layoutLocationEnd)
|
||||
error(loc, "location is too large", id.c_str(), "");
|
||||
else
|
||||
publicType.qualifier.layoutLocation = value;
|
||||
qualifier.layoutLocation = value;
|
||||
return;
|
||||
} else if (id == "set") {
|
||||
if ((unsigned int)value >= TQualifier::layoutSetEnd)
|
||||
error(loc, "set is too large", id.c_str(), "");
|
||||
else
|
||||
publicType.qualifier.layoutSet = value;
|
||||
qualifier.layoutSet = value;
|
||||
return;
|
||||
} else if (id == "binding") {
|
||||
if ((unsigned int)value >= TQualifier::layoutBindingEnd)
|
||||
error(loc, "binding is too large", id.c_str(), "");
|
||||
else
|
||||
publicType.qualifier.layoutBinding = value;
|
||||
qualifier.layoutBinding = value;
|
||||
return;
|
||||
} else if (id == "component") {
|
||||
if ((unsigned)value >= TQualifier::layoutComponentEnd)
|
||||
error(loc, "component is too large", id.c_str(), "");
|
||||
else
|
||||
publicType.qualifier.layoutComponent = value;
|
||||
qualifier.layoutComponent = value;
|
||||
return;
|
||||
} else if (id.compare(0, 4, "xfb_") == 0) {
|
||||
// "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)
|
||||
error(loc, "buffer is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbBufferEnd - 1);
|
||||
else
|
||||
publicType.qualifier.layoutXfbBuffer = value;
|
||||
qualifier.layoutXfbBuffer = value;
|
||||
return;
|
||||
} else if (id == "xfb_offset") {
|
||||
if (value >= (int)TQualifier::layoutXfbOffsetEnd)
|
||||
error(loc, "offset is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbOffsetEnd - 1);
|
||||
else
|
||||
publicType.qualifier.layoutXfbOffset = value;
|
||||
qualifier.layoutXfbOffset = value;
|
||||
return;
|
||||
} else if (id == "xfb_stride") {
|
||||
// "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)
|
||||
error(loc, "stride is too large:", id.c_str(), "internal max is %d", TQualifier::layoutXfbStrideEnd - 1);
|
||||
if (value < (int)TQualifier::layoutXfbStrideEnd)
|
||||
publicType.qualifier.layoutXfbStride = value;
|
||||
qualifier.layoutXfbStride = value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -3335,7 +3356,7 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu
|
||||
if (value >= (int)TQualifier::layoutAttachmentEnd)
|
||||
error(loc, "attachment index is too large", id.c_str(), "");
|
||||
else
|
||||
publicType.qualifier.layoutAttachment = value;
|
||||
qualifier.layoutAttachment = value;
|
||||
return;
|
||||
}
|
||||
if (id == "constant_id") {
|
||||
@ -3343,8 +3364,8 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu
|
||||
if (value >= (int)TQualifier::layoutSpecConstantIdEnd) {
|
||||
error(loc, "specialization-constant id is too large", id.c_str(), "");
|
||||
} else {
|
||||
publicType.qualifier.layoutSpecConstantId = value;
|
||||
publicType.qualifier.specConstant = true;
|
||||
qualifier.layoutSpecConstantId = value;
|
||||
qualifier.specConstant = true;
|
||||
if (! intermediate.addUsedConstantId(value))
|
||||
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)
|
||||
error(loc, "must be greater than 0", "vertices", "");
|
||||
else
|
||||
publicType.shaderQualifiers.vertices = value;
|
||||
//publicType.shaderQualifiers.vertices = value;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@ -3373,24 +3395,26 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu
|
||||
if (value == 0)
|
||||
error(loc, "must be at least 1", "invocations", "");
|
||||
else
|
||||
publicType.shaderQualifiers.invocations = value;
|
||||
//publicType.shaderQualifiers.invocations = value;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
if (id == "max_vertices") {
|
||||
publicType.shaderQualifiers.vertices = value;
|
||||
//publicType.shaderQualifiers.vertices = value;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
if (value > resources.maxGeometryOutputVertices)
|
||||
error(loc, "too large, must be less than gl_MaxGeometryOutputVertices", "max_vertices", "");
|
||||
return;
|
||||
}
|
||||
if (id == "stream") {
|
||||
publicType.qualifier.layoutStream = value;
|
||||
qualifier.layoutStream = value;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case EShLangFragment:
|
||||
if (id == "index") {
|
||||
publicType.qualifier.layoutIndex = value;
|
||||
qualifier.layoutIndex = value;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@ -3398,28 +3422,34 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& pu
|
||||
case EShLangCompute:
|
||||
if (id.compare(0, 11, "local_size_") == 0) {
|
||||
if (id == "local_size_x") {
|
||||
publicType.shaderQualifiers.localSize[0] = value;
|
||||
//publicType.shaderQualifiers.localSize[0] = value;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
if (id == "local_size_y") {
|
||||
publicType.shaderQualifiers.localSize[1] = value;
|
||||
//publicType.shaderQualifiers.localSize[1] = value;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
if (id == "local_size_z") {
|
||||
publicType.shaderQualifiers.localSize[2] = value;
|
||||
//publicType.shaderQualifiers.localSize[2] = value;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
if (spvVersion.spv != 0) {
|
||||
if (id == "local_size_x_id") {
|
||||
publicType.shaderQualifiers.localSizeSpecId[0] = value;
|
||||
//publicType.shaderQualifiers.localSizeSpecId[0] = value;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
if (id == "local_size_y_id") {
|
||||
publicType.shaderQualifiers.localSizeSpecId[1] = value;
|
||||
//publicType.shaderQualifiers.localSizeSpecId[1] = value;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
if (id == "local_size_z_id") {
|
||||
publicType.shaderQualifiers.localSizeSpecId[2] = value;
|
||||
//publicType.shaderQualifiers.localSizeSpecId[2] = value;
|
||||
warn(loc, "ignored", id.c_str(), "");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -128,8 +128,8 @@ public:
|
||||
void paramFix(TType& type);
|
||||
void specializationCheck(const TSourceLoc&, const TType&, const char* op);
|
||||
|
||||
void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&);
|
||||
void setLayoutQualifier(const TSourceLoc&, TPublicType&, TString&, const TIntermTyped*);
|
||||
void setLayoutQualifier(const TSourceLoc&, TQualifier&, TString&);
|
||||
void setLayoutQualifier(const TSourceLoc&, TQualifier&, TString&, const TIntermTyped*);
|
||||
void mergeObjectLayoutQualifiers(TQualifier& dest, const TQualifier& src, bool inheritOnly);
|
||||
void checkNoShaderLayouts(const TSourceLoc&, const TShaderQualifiers&);
|
||||
|
||||
|
@ -117,6 +117,7 @@ void HlslScanContext::fillInKeywordMap()
|
||||
(*KeywordMap)["in"] = EHTokIn;
|
||||
(*KeywordMap)["out"] = EHTokOut;
|
||||
(*KeywordMap)["inout"] = EHTokInOut;
|
||||
(*KeywordMap)["layout"] = EHTokLayout;
|
||||
|
||||
(*KeywordMap)["Buffer"] = EHTokBuffer;
|
||||
(*KeywordMap)["vector"] = EHTokVector;
|
||||
@ -457,6 +458,7 @@ EHlslTokenClass HlslScanContext::tokenizeIdentifier()
|
||||
case EHTokIn:
|
||||
case EHTokOut:
|
||||
case EHTokInOut:
|
||||
case EHTokLayout:
|
||||
return keyword;
|
||||
|
||||
// template types
|
||||
|
@ -64,6 +64,7 @@ enum EHlslTokenClass {
|
||||
EHTokIn,
|
||||
EHTokOut,
|
||||
EHTokInOut,
|
||||
EHTokLayout,
|
||||
|
||||
// template types
|
||||
EHTokBuffer,
|
||||
|
Loading…
x
Reference in New Issue
Block a user