HLSL: Attributes: Add [[vk::constant_id()]] and [[vk::push_constant]]
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -67,7 +67,9 @@ namespace glslang {
|
||||
EatGlobalBinding,
|
||||
EatLocation,
|
||||
EatInputAttachment,
|
||||
EatBuiltIn
|
||||
EatBuiltIn,
|
||||
EatPushConstant,
|
||||
EatConstantId
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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&);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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&);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user