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

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

View File

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

View File

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

View File

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

View File

@@ -1890,6 +1890,17 @@ void HlslParseContext::transferTypeAttributes(const TAttributeMap& attributes, T
if (builtInString == "PointSize")
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;
}
if (id == "constant_id") {
requireSpv(loc, "constant_id");
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(), "");
}
setSpecConstantId(loc, qualifier, value);
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(), "");
}
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
//
// "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&, const TIntermTyped*);
void setSpecConstantId(const TSourceLoc&, TQualifier&, int value);
void mergeObjectLayoutQualifiers(TQualifier& dest, const TQualifier& src, bool inheritOnly);
void checkNoShaderLayouts(const TSourceLoc&, const TShaderQualifiers&);