HLSL: Attributes: Add [[vk::constant_id()]] and [[vk::push_constant]]

This commit is contained in:
John Kessenich 2017-12-23 17:29:45 -07:00
parent e08ed0ccf4
commit 046bae0bab
8 changed files with 127 additions and 80 deletions

View File

@ -2,42 +2,45 @@ hlsl.attributeC11.frag
Shader version: 500 Shader version: 500
gl_FragCoord origin is upper left gl_FragCoord origin is upper left
0:? Sequence 0:? Sequence
0:16 Function Definition: @main(vf4; ( temp 4-component vector of float) 0:20 Function Definition: @main(vf4; ( temp 4-component vector of float)
0:16 Function Parameters: 0:20 Function Parameters:
0:16 'input' ( in 4-component vector of float) 0:20 'input' ( in 4-component vector of float)
0:? Sequence 0:? Sequence
0:17 Branch: Return with expression 0:21 Branch: Return with expression
0:17 add ( temp 4-component vector of float) 0:21 add ( temp 4-component vector of float)
0:17 'input' ( in 4-component vector of float) 0:21 'input' ( in 4-component vector of float)
0:17 textureFetch ( temp 4-component vector of float) 0:21 textureFetch ( temp 4-component vector of float)
0:17 'attach' ( uniform texture2D) 0:21 'attach' ( uniform texture2D)
0:17 vector swizzle ( temp int) 0:21 vector swizzle ( temp int)
0:17 Constant: 0:21 Constant:
0:17 0 (const int) 0:21 0 (const int)
0:17 0 (const int) 0:21 0 (const int)
0:17 Sequence 0:21 Sequence
0:17 Constant: 0:21 Constant:
0:17 0 (const int) 0:21 0 (const int)
0:17 direct index ( temp int) 0:21 direct index ( temp int)
0:17 Constant: 0:21 Constant:
0:17 0 (const int) 0:21 0 (const int)
0:17 0 (const int) 0:21 0 (const int)
0:17 Constant: 0:21 Constant:
0:17 1 (const int) 0:21 1 (const int)
0:16 Function Definition: main( ( temp void) 0:20 Function Definition: main( ( temp void)
0:16 Function Parameters: 0:20 Function Parameters:
0:? Sequence 0:? Sequence
0:16 move second child to first child ( temp 4-component vector of float) 0:20 move second child to first child ( temp 4-component vector of float)
0:? 'input' ( temp 4-component vector of float) 0:? 'input' ( temp 4-component vector of float)
0:? 'input' (layout( location=8) in 4-component vector of float) 0:? 'input' (layout( location=8) in 4-component vector of float)
0:16 move second child to first child ( temp 4-component vector of float) 0:20 move second child to first child ( temp 4-component vector of float)
0:? '@entryPointOutput' (layout( location=7) out 4-component vector of float) 0:? '@entryPointOutput' (layout( location=7) out 4-component vector of float)
0:16 Function Call: @main(vf4; ( temp 4-component vector of float) 0:20 Function Call: @main(vf4; ( temp 4-component vector of float)
0:? 'input' ( temp 4-component vector of float) 0:? 'input' ( temp 4-component vector of float)
0:? Linker Objects 0:? Linker Objects
0:? 'buffer1' (layout( set=0 binding=1 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of structure{ temp 2-component vector of float f} @data}) 0:? 'buffer1' (layout( set=0 binding=1 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of structure{ temp 2-component vector of float f} @data})
0:? 'buffer3' (layout( set=2 binding=3 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of structure{ temp 2-component vector of float f} @data}) 0:? 'buffer3' (layout( set=2 binding=3 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of structure{ temp 2-component vector of float f} @data})
0:? 'attach' ( uniform texture2D) 0:? 'attach' ( uniform texture2D)
0:? 'ci' ( specialization-constant const int)
0:? 11 (const int)
0:? 'anon@0' (layout( row_major std430 push_constant) uniform block{layout( row_major std430 offset=0) uniform int a})
0:? '@entryPointOutput' (layout( location=7) out 4-component vector of float) 0:? '@entryPointOutput' (layout( location=7) out 4-component vector of float)
0:? 'input' (layout( location=8) in 4-component vector of float) 0:? 'input' (layout( location=8) in 4-component vector of float)
@ -48,48 +51,51 @@ Linked fragment stage:
Shader version: 500 Shader version: 500
gl_FragCoord origin is upper left gl_FragCoord origin is upper left
0:? Sequence 0:? Sequence
0:16 Function Definition: @main(vf4; ( temp 4-component vector of float) 0:20 Function Definition: @main(vf4; ( temp 4-component vector of float)
0:16 Function Parameters: 0:20 Function Parameters:
0:16 'input' ( in 4-component vector of float) 0:20 'input' ( in 4-component vector of float)
0:? Sequence 0:? Sequence
0:17 Branch: Return with expression 0:21 Branch: Return with expression
0:17 add ( temp 4-component vector of float) 0:21 add ( temp 4-component vector of float)
0:17 'input' ( in 4-component vector of float) 0:21 'input' ( in 4-component vector of float)
0:17 textureFetch ( temp 4-component vector of float) 0:21 textureFetch ( temp 4-component vector of float)
0:17 'attach' ( uniform texture2D) 0:21 'attach' ( uniform texture2D)
0:17 vector swizzle ( temp int) 0:21 vector swizzle ( temp int)
0:17 Constant: 0:21 Constant:
0:17 0 (const int) 0:21 0 (const int)
0:17 0 (const int) 0:21 0 (const int)
0:17 Sequence 0:21 Sequence
0:17 Constant: 0:21 Constant:
0:17 0 (const int) 0:21 0 (const int)
0:17 direct index ( temp int) 0:21 direct index ( temp int)
0:17 Constant: 0:21 Constant:
0:17 0 (const int) 0:21 0 (const int)
0:17 0 (const int) 0:21 0 (const int)
0:17 Constant: 0:21 Constant:
0:17 1 (const int) 0:21 1 (const int)
0:16 Function Definition: main( ( temp void) 0:20 Function Definition: main( ( temp void)
0:16 Function Parameters: 0:20 Function Parameters:
0:? Sequence 0:? Sequence
0:16 move second child to first child ( temp 4-component vector of float) 0:20 move second child to first child ( temp 4-component vector of float)
0:? 'input' ( temp 4-component vector of float) 0:? 'input' ( temp 4-component vector of float)
0:? 'input' (layout( location=8) in 4-component vector of float) 0:? 'input' (layout( location=8) in 4-component vector of float)
0:16 move second child to first child ( temp 4-component vector of float) 0:20 move second child to first child ( temp 4-component vector of float)
0:? '@entryPointOutput' (layout( location=7) out 4-component vector of float) 0:? '@entryPointOutput' (layout( location=7) out 4-component vector of float)
0:16 Function Call: @main(vf4; ( temp 4-component vector of float) 0:20 Function Call: @main(vf4; ( temp 4-component vector of float)
0:? 'input' ( temp 4-component vector of float) 0:? 'input' ( temp 4-component vector of float)
0:? Linker Objects 0:? Linker Objects
0:? 'buffer1' (layout( set=0 binding=1 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of structure{ temp 2-component vector of float f} @data}) 0:? 'buffer1' (layout( set=0 binding=1 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of structure{ temp 2-component vector of float f} @data})
0:? 'buffer3' (layout( set=2 binding=3 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of structure{ temp 2-component vector of float f} @data}) 0:? 'buffer3' (layout( set=2 binding=3 row_major std430) readonly buffer block{layout( row_major std430) buffer implicitly-sized array of structure{ temp 2-component vector of float f} @data})
0:? 'attach' ( uniform texture2D) 0:? 'attach' ( uniform texture2D)
0:? 'ci' ( specialization-constant const int)
0:? 11 (const int)
0:? 'anon@0' (layout( row_major std430 push_constant) uniform block{layout( row_major std430 offset=0) uniform int a})
0:? '@entryPointOutput' (layout( location=7) out 4-component vector of float) 0:? '@entryPointOutput' (layout( location=7) out 4-component vector of float)
0:? 'input' (layout( location=8) in 4-component vector of float) 0:? 'input' (layout( location=8) in 4-component vector of float)
// Module Version 10000 // Module Version 10000
// Generated by (magic number): 80003 // Generated by (magic number): 80003
// Id's are bound by 47 // Id's are bound by 51
Capability Shader Capability Shader
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
@ -111,6 +117,10 @@ gl_FragCoord origin is upper left
MemberName 43(buffer1) 0 "@data" MemberName 43(buffer1) 0 "@data"
Name 45 "buffer1" Name 45 "buffer1"
Name 46 "buffer3" Name 46 "buffer3"
Name 47 "ci"
Name 48 "pcBuf"
MemberName 48(pcBuf) 0 "a"
Name 50 ""
Decorate 16(attach) DescriptorSet 0 Decorate 16(attach) DescriptorSet 0
Decorate 16(attach) InputAttachmentIndex 4 Decorate 16(attach) InputAttachmentIndex 4
Decorate 33(input) Location 8 Decorate 33(input) Location 8
@ -124,6 +134,9 @@ gl_FragCoord origin is upper left
Decorate 45(buffer1) Binding 1 Decorate 45(buffer1) Binding 1
Decorate 46(buffer3) DescriptorSet 2 Decorate 46(buffer3) DescriptorSet 2
Decorate 46(buffer3) Binding 3 Decorate 46(buffer3) Binding 3
Decorate 47(ci) SpecId 13
MemberDecorate 48(pcBuf) 0 Offset 0
Decorate 48(pcBuf) Block
2: TypeVoid 2: TypeVoid
3: TypeFunction 2 3: TypeFunction 2
6: TypeFloat 32 6: TypeFloat 32
@ -151,6 +164,10 @@ gl_FragCoord origin is upper left
44: TypePointer Uniform 43(buffer1) 44: TypePointer Uniform 43(buffer1)
45(buffer1): 44(ptr) Variable Uniform 45(buffer1): 44(ptr) Variable Uniform
46(buffer3): 44(ptr) Variable Uniform 46(buffer3): 44(ptr) Variable Uniform
47(ci): 18(int) SpecConstant 11
48(pcBuf): TypeStruct 18(int)
49: TypePointer PushConstant 48(pcBuf)
50: 49(ptr) Variable PushConstant
4(main): 2 Function None 3 4(main): 2 Function None 3
5: Label 5: Label
31(input): 8(ptr) Variable Function 31(input): 8(ptr) Variable Function

View File

@ -11,8 +11,12 @@ StructuredBuffer<S> buffer3;
[[vk::input_attachment_index(4)]] [[vk::input_attachment_index(4)]]
Texture2D<float4> attach; Texture2D<float4> attach;
[[vk::constant_id(13)]] const int ci = 11;
[[vk::push_constant]] cbuffer pcBuf { int a; };
[[vk::location(7)]] float4 [[vk::location(7)]] float4
main([[vk::location(8)]] float4 input: A) : B main([[vk::location(8)]] float4 input: A) : B
{ {
return input + attach.Load(float2(0.5)); return input + attach.Load(float2(0.5));// * a;
} }

View File

@ -62,6 +62,10 @@ namespace glslang {
return EatGlobalBinding; return EatGlobalBinding;
else if (lowername == "builtin") else if (lowername == "builtin")
return EatBuiltIn; return EatBuiltIn;
else if (lowername == "constant_id")
return EatConstantId;
else if (lowername == "push_constant")
return EatPushConstant;
} else if (lowernameSpace.size() > 0) } else if (lowernameSpace.size() > 0)
return EatNone; return EatNone;

View File

@ -67,7 +67,9 @@ namespace glslang {
EatGlobalBinding, EatGlobalBinding,
EatLocation, EatLocation,
EatInputAttachment, EatInputAttachment,
EatBuiltIn EatBuiltIn,
EatPushConstant,
EatConstantId
}; };
} }

View File

@ -376,11 +376,9 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& nodeList)
bool forbidDeclarators = (peekTokenClass(EHTokCBuffer) || peekTokenClass(EHTokTBuffer)); bool forbidDeclarators = (peekTokenClass(EHTokCBuffer) || peekTokenClass(EHTokTBuffer));
// fully_specified_type // fully_specified_type
if (! acceptFullySpecifiedType(declaredType, nodeList)) if (! acceptFullySpecifiedType(declaredType, nodeList, declarator.attributes))
return false; return false;
parseContext.transferTypeAttributes(declarator.attributes, declaredType);
// cbuffer and tbuffer end with the closing '}'. // cbuffer and tbuffer end with the closing '}'.
// No semicolon is included. // No semicolon is included.
if (forbidDeclarators) if (forbidDeclarators)
@ -538,10 +536,11 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& nodeList)
bool HlslGrammar::acceptControlDeclaration(TIntermNode*& node) bool HlslGrammar::acceptControlDeclaration(TIntermNode*& node)
{ {
node = nullptr; node = nullptr;
TAttributeMap attributes;
// fully_specified_type // fully_specified_type
TType type; TType type;
if (! acceptFullySpecifiedType(type)) if (! acceptFullySpecifiedType(type, attributes))
return false; return false;
// filter out type casts // filter out type casts
@ -579,12 +578,12 @@ bool HlslGrammar::acceptControlDeclaration(TIntermNode*& node)
// : type_specifier // : type_specifier
// | type_qualifier type_specifier // | type_qualifier type_specifier
// //
bool HlslGrammar::acceptFullySpecifiedType(TType& type) bool HlslGrammar::acceptFullySpecifiedType(TType& type, const TAttributeMap& attributes)
{ {
TIntermNode* nodeList = nullptr; TIntermNode* nodeList = nullptr;
return acceptFullySpecifiedType(type, nodeList); return acceptFullySpecifiedType(type, nodeList, attributes);
} }
bool HlslGrammar::acceptFullySpecifiedType(TType& type, TIntermNode*& nodeList) bool HlslGrammar::acceptFullySpecifiedType(TType& type, TIntermNode*& nodeList, const TAttributeMap& attributes)
{ {
// type_qualifier // type_qualifier
TQualifier qualifier; TQualifier qualifier;
@ -603,9 +602,14 @@ bool HlslGrammar::acceptFullySpecifiedType(TType& type, TIntermNode*& nodeList)
return false; return false;
} }
if (type.getBasicType() == EbtBlock) { if (type.getBasicType() == EbtBlock) {
// the type was a block, which set some parts of the qualifier // the type was a block, which set some parts of the qualifier
parseContext.mergeQualifiers(type.getQualifier(), qualifier); parseContext.mergeQualifiers(type.getQualifier(), qualifier);
// merge in the attributes
parseContext.transferTypeAttributes(attributes, type);
// further, it can create an anonymous instance of the block // further, it can create an anonymous instance of the block
if (peek() != EHTokIdentifier) if (peek() != EHTokIdentifier)
parseContext.declareBlock(loc, type); parseContext.declareBlock(loc, type);
@ -626,7 +630,10 @@ bool HlslGrammar::acceptFullySpecifiedType(TType& type, TIntermNode*& nodeList)
if (type.isBuiltIn()) if (type.isBuiltIn())
qualifier.builtIn = type.getQualifier().builtIn; qualifier.builtIn = type.getQualifier().builtIn;
type.getQualifier() = qualifier; type.getQualifier() = qualifier;
// merge in the attributes
parseContext.transferTypeAttributes(attributes, type);
} }
return true; return true;
@ -2333,13 +2340,11 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList, TIntermNode*
// fully_specified_type // fully_specified_type
TType memberType; TType memberType;
if (! acceptFullySpecifiedType(memberType, nodeList)) { if (! acceptFullySpecifiedType(memberType, nodeList, attributes)) {
expected("member type"); expected("member type");
return false; return false;
} }
parseContext.transferTypeAttributes(attributes, memberType);
// struct_declarator COMMA struct_declarator ... // struct_declarator COMMA struct_declarator ...
bool functionDefinitionAccepted = false; bool functionDefinitionAccepted = false;
do { do {
@ -2540,11 +2545,9 @@ bool HlslGrammar::acceptParameterDeclaration(TFunction& function)
// fully_specified_type // fully_specified_type
TType* type = new TType; TType* type = new TType;
if (! acceptFullySpecifiedType(*type)) if (! acceptFullySpecifiedType(*type, attributes))
return false; return false;
parseContext.transferTypeAttributes(attributes, *type);
// identifier // identifier
HlslToken idToken; HlslToken idToken;
acceptIdentifier(idToken); acceptIdentifier(idToken);

View File

@ -71,8 +71,8 @@ namespace glslang {
bool acceptControlDeclaration(TIntermNode*& node); bool acceptControlDeclaration(TIntermNode*& node);
bool acceptSamplerDeclarationDX9(TType&); bool acceptSamplerDeclarationDX9(TType&);
bool acceptSamplerState(); bool acceptSamplerState();
bool acceptFullySpecifiedType(TType&); bool acceptFullySpecifiedType(TType&, const TAttributeMap&);
bool acceptFullySpecifiedType(TType&, TIntermNode*& nodeList); bool acceptFullySpecifiedType(TType&, TIntermNode*& nodeList, const TAttributeMap&);
bool acceptQualifier(TQualifier&); bool acceptQualifier(TQualifier&);
bool acceptLayoutQualifierList(TQualifier&); bool acceptLayoutQualifierList(TQualifier&);
bool acceptType(TType&); bool acceptType(TType&);

View File

@ -1890,6 +1890,17 @@ void HlslParseContext::transferTypeAttributes(const TAttributeMap& attributes, T
if (builtInString == "PointSize") if (builtInString == "PointSize")
type.getQualifier().builtIn = EbvPointSize; type.getQualifier().builtIn = EbvPointSize;
} }
// push_constant
if (attributes.contains(EatPushConstant))
type.getQualifier().layoutPushConstant = true;
// specialization constant
if (attributes.getInt(EatConstantId, value)) {
TSourceLoc loc;
loc.init();
setSpecConstantId(loc, type.getQualifier(), value);
}
} }
// //
@ -7041,15 +7052,7 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TQualifier& qua
return; return;
} }
if (id == "constant_id") { if (id == "constant_id") {
requireSpv(loc, "constant_id"); setSpecConstantId(loc, qualifier, value);
if (value >= (int)TQualifier::layoutSpecConstantIdEnd) {
error(loc, "specialization-constant id is too large", id.c_str(), "");
} else {
qualifier.layoutSpecConstantId = value;
qualifier.specConstant = true;
if (! intermediate.addUsedConstantId(value))
error(loc, "specialization-constant id already used", id.c_str(), "");
}
return; return;
} }
@ -7144,6 +7147,19 @@ void HlslParseContext::setLayoutQualifier(const TSourceLoc& loc, TQualifier& qua
error(loc, "there is no such layout identifier for this stage taking an assigned value", id.c_str(), ""); error(loc, "there is no such layout identifier for this stage taking an assigned value", id.c_str(), "");
} }
void HlslParseContext::setSpecConstantId(const TSourceLoc& loc, TQualifier& qualifier, int value)
{
if (value >= (int)TQualifier::layoutSpecConstantIdEnd) {
error(loc, "specialization-constant id is too large", "constant_id", "");
} else {
qualifier.layoutSpecConstantId = value;
qualifier.specConstant = true;
if (! intermediate.addUsedConstantId(value))
error(loc, "specialization-constant id already used", "constant_id", "");
}
return;
}
// Merge any layout qualifier information from src into dst, leaving everything else in dst alone // Merge any layout qualifier information from src into dst, leaving everything else in dst alone
// //
// "More than one layout qualifier may appear in a single declaration. // "More than one layout qualifier may appear in a single declaration.

View File

@ -138,6 +138,7 @@ public:
void setLayoutQualifier(const TSourceLoc&, TQualifier&, TString&); void setLayoutQualifier(const TSourceLoc&, TQualifier&, TString&);
void setLayoutQualifier(const TSourceLoc&, TQualifier&, TString&, const TIntermTyped*); void setLayoutQualifier(const TSourceLoc&, TQualifier&, TString&, const TIntermTyped*);
void setSpecConstantId(const TSourceLoc&, TQualifier&, int value);
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&);