Merge pull request #1098 from LoopDawg/attribute-gets
HLSL: nonfunctional: add helper access methods to TAttributeMap
This commit is contained in:
commit
60e9161100
@ -36,6 +36,7 @@
|
|||||||
#include "hlslAttributes.h"
|
#include "hlslAttributes.h"
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
// Map the given string to an attribute enum from TAttributeType,
|
// Map the given string to an attribute enum from TAttributeType,
|
||||||
@ -131,4 +132,51 @@ namespace glslang {
|
|||||||
return attributes.find(attr) != attributes.end();
|
return attributes.find(attr) != attributes.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// extract integers out of attribute arguments stored in attribute aggregate
|
||||||
|
bool TAttributeMap::getInt(TAttributeType attr, int& value, int argNum) const
|
||||||
|
{
|
||||||
|
const TConstUnion* intConst = getConstUnion(attr, EbtInt, argNum);
|
||||||
|
|
||||||
|
if (intConst == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
value = intConst->getIConst();
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// extract strings out of attribute arguments stored in attribute aggregate.
|
||||||
|
// convert to lower case if converToLower is true (for case-insensitive compare convenience)
|
||||||
|
bool TAttributeMap::getString(TAttributeType attr, TString& value, int argNum, bool convertToLower) const
|
||||||
|
{
|
||||||
|
const TConstUnion* stringConst = getConstUnion(attr, EbtString, argNum);
|
||||||
|
|
||||||
|
if (stringConst == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
value = *stringConst->getSConst();
|
||||||
|
|
||||||
|
// Convenience.
|
||||||
|
if (convertToLower)
|
||||||
|
std::transform(value.begin(), value.end(), value.begin(), ::tolower);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Helper to get attribute const union. Returns nullptr on failure.
|
||||||
|
const TConstUnion* TAttributeMap::getConstUnion(TAttributeType attr, TBasicType basicType, int argNum) const
|
||||||
|
{
|
||||||
|
const TIntermAggregate* attrAgg = (*this)[attr];
|
||||||
|
if (attrAgg == nullptr)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
if (argNum >= int(attrAgg->getSequence().size()))
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
const TConstUnion* constVal = &attrAgg->getSequence()[argNum]->getAsConstantUnion()->getConstArray()[0];
|
||||||
|
if (constVal == nullptr || constVal->getType() != basicType)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return constVal;
|
||||||
|
}
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|||||||
@ -93,7 +93,16 @@ namespace glslang {
|
|||||||
// True if entry exists in map (even if value is nullptr)
|
// True if entry exists in map (even if value is nullptr)
|
||||||
bool contains(TAttributeType) const;
|
bool contains(TAttributeType) const;
|
||||||
|
|
||||||
|
// Obtain attribute as integer
|
||||||
|
bool getInt(TAttributeType attr, int& value, int argNum = 0) const;
|
||||||
|
|
||||||
|
// Obtain attribute as string, with optional to-lower transform
|
||||||
|
bool getString(TAttributeType attr, TString& value, int argNum = 0, bool convertToLower = true) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// Helper to get attribute const union
|
||||||
|
const TConstUnion* getConstUnion(TAttributeType attr, TBasicType, int argNum) const;
|
||||||
|
|
||||||
// Find an attribute enum given its name.
|
// Find an attribute enum given its name.
|
||||||
static TAttributeType attributeFromName(const TString& nameSpace, const TString& name);
|
static TAttributeType attributeFromName(const TString& nameSpace, const TString& name);
|
||||||
|
|
||||||
|
|||||||
@ -1717,36 +1717,33 @@ void HlslParseContext::handleEntryPointAttributes(const TSourceLoc& loc, const T
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MaxVertexCount
|
// MaxVertexCount
|
||||||
const TIntermAggregate* maxVertexCount = attributes[EatMaxVertexCount];
|
if (attributes.contains(EatMaxVertexCount)) {
|
||||||
if (maxVertexCount != nullptr) {
|
int maxVertexCount;
|
||||||
if (! intermediate.setVertices(maxVertexCount->getSequence()[0]->getAsConstantUnion()->
|
|
||||||
getConstArray()[0].getIConst())) {
|
if (! attributes.getInt(EatMaxVertexCount, maxVertexCount)) {
|
||||||
|
error(loc, "invalid maxvertexcount", "", "");
|
||||||
|
} else {
|
||||||
|
if (! intermediate.setVertices(maxVertexCount))
|
||||||
error(loc, "cannot change previously set maxvertexcount attribute", "", "");
|
error(loc, "cannot change previously set maxvertexcount attribute", "", "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle [patchconstantfunction("...")]
|
// Handle [patchconstantfunction("...")]
|
||||||
const TIntermAggregate* pcfAttr = attributes[EatPatchConstantFunc];
|
if (attributes.contains(EatPatchConstantFunc)) {
|
||||||
if (pcfAttr != nullptr) {
|
TString pcfName;
|
||||||
const TConstUnion& pcfName = pcfAttr->getSequence()[0]->getAsConstantUnion()->getConstArray()[0];
|
if (! attributes.getString(EatPatchConstantFunc, pcfName, 0, false)) {
|
||||||
|
|
||||||
if (pcfName.getType() != EbtString) {
|
|
||||||
error(loc, "invalid patch constant function", "", "");
|
error(loc, "invalid patch constant function", "", "");
|
||||||
} else {
|
} else {
|
||||||
patchConstantFunctionName = *pcfName.getSConst();
|
patchConstantFunctionName = pcfName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle [domain("...")]
|
// Handle [domain("...")]
|
||||||
const TIntermAggregate* domainAttr = attributes[EatDomain];
|
if (attributes.contains(EatDomain)) {
|
||||||
if (domainAttr != nullptr) {
|
TString domainStr;
|
||||||
const TConstUnion& domainType = domainAttr->getSequence()[0]->getAsConstantUnion()->getConstArray()[0];
|
if (! attributes.getString(EatDomain, domainStr)) {
|
||||||
if (domainType.getType() != EbtString) {
|
|
||||||
error(loc, "invalid domain", "", "");
|
error(loc, "invalid domain", "", "");
|
||||||
} else {
|
} else {
|
||||||
TString domainStr = *domainType.getSConst();
|
|
||||||
std::transform(domainStr.begin(), domainStr.end(), domainStr.begin(), ::tolower);
|
|
||||||
|
|
||||||
TLayoutGeometry domain = ElgNone;
|
TLayoutGeometry domain = ElgNone;
|
||||||
|
|
||||||
if (domainStr == "tri") {
|
if (domainStr == "tri") {
|
||||||
@ -1770,15 +1767,11 @@ void HlslParseContext::handleEntryPointAttributes(const TSourceLoc& loc, const T
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle [outputtopology("...")]
|
// Handle [outputtopology("...")]
|
||||||
const TIntermAggregate* topologyAttr = attributes[EatOutputTopology];
|
if (attributes.contains(EatOutputTopology)) {
|
||||||
if (topologyAttr != nullptr) {
|
TString topologyStr;
|
||||||
const TConstUnion& topoType = topologyAttr->getSequence()[0]->getAsConstantUnion()->getConstArray()[0];
|
if (! attributes.getString(EatOutputTopology, topologyStr)) {
|
||||||
if (topoType.getType() != EbtString) {
|
|
||||||
error(loc, "invalid outputtopology", "", "");
|
error(loc, "invalid outputtopology", "", "");
|
||||||
} else {
|
} else {
|
||||||
TString topologyStr = *topoType.getSConst();
|
|
||||||
std::transform(topologyStr.begin(), topologyStr.end(), topologyStr.begin(), ::tolower);
|
|
||||||
|
|
||||||
TVertexOrder vertexOrder = EvoNone;
|
TVertexOrder vertexOrder = EvoNone;
|
||||||
TLayoutGeometry primitive = ElgNone;
|
TLayoutGeometry primitive = ElgNone;
|
||||||
|
|
||||||
@ -1808,15 +1801,11 @@ void HlslParseContext::handleEntryPointAttributes(const TSourceLoc& loc, const T
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle [partitioning("...")]
|
// Handle [partitioning("...")]
|
||||||
const TIntermAggregate* partitionAttr = attributes[EatPartitioning];
|
if (attributes.contains(EatPartitioning)) {
|
||||||
if (partitionAttr != nullptr) {
|
TString partitionStr;
|
||||||
const TConstUnion& partType = partitionAttr->getSequence()[0]->getAsConstantUnion()->getConstArray()[0];
|
if (! attributes.getString(EatPartitioning, partitionStr)) {
|
||||||
if (partType.getType() != EbtString) {
|
|
||||||
error(loc, "invalid partitioning", "", "");
|
error(loc, "invalid partitioning", "", "");
|
||||||
} else {
|
} else {
|
||||||
TString partitionStr = *partType.getSConst();
|
|
||||||
std::transform(partitionStr.begin(), partitionStr.end(), partitionStr.begin(), ::tolower);
|
|
||||||
|
|
||||||
TVertexSpacing partitioning = EvsNone;
|
TVertexSpacing partitioning = EvsNone;
|
||||||
|
|
||||||
if (partitionStr == "integer") {
|
if (partitionStr == "integer") {
|
||||||
@ -1837,14 +1826,11 @@ void HlslParseContext::handleEntryPointAttributes(const TSourceLoc& loc, const T
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle [outputcontrolpoints("...")]
|
// Handle [outputcontrolpoints("...")]
|
||||||
const TIntermAggregate* outputControlPoints = attributes[EatOutputControlPoints];
|
if (attributes.contains(EatOutputControlPoints)) {
|
||||||
if (outputControlPoints != nullptr) {
|
int ctrlPoints;
|
||||||
const TConstUnion& ctrlPointConst =
|
if (! attributes.getInt(EatOutputControlPoints, ctrlPoints)) {
|
||||||
outputControlPoints->getSequence()[0]->getAsConstantUnion()->getConstArray()[0];
|
|
||||||
if (ctrlPointConst.getType() != EbtInt) {
|
|
||||||
error(loc, "invalid outputcontrolpoints", "", "");
|
error(loc, "invalid outputcontrolpoints", "", "");
|
||||||
} else {
|
} else {
|
||||||
const int ctrlPoints = ctrlPointConst.getIConst();
|
|
||||||
if (! intermediate.setVertices(ctrlPoints)) {
|
if (! intermediate.setVertices(ctrlPoints)) {
|
||||||
error(loc, "cannot change previously set outputcontrolpoints attribute", "", "");
|
error(loc, "cannot change previously set outputcontrolpoints attribute", "", "");
|
||||||
}
|
}
|
||||||
@ -1856,37 +1842,23 @@ void HlslParseContext::handleEntryPointAttributes(const TSourceLoc& loc, const T
|
|||||||
// attributes.
|
// attributes.
|
||||||
void HlslParseContext::transferTypeAttributes(const TAttributeMap& attributes, TType& type)
|
void HlslParseContext::transferTypeAttributes(const TAttributeMap& attributes, TType& type)
|
||||||
{
|
{
|
||||||
// extract integers out of attribute arguments stored in attribute aggregate
|
|
||||||
const auto getInt = [&](TAttributeType attr, int argNum, int& value) -> bool {
|
|
||||||
const TIntermAggregate* attrAgg = attributes[attr];
|
|
||||||
if (attrAgg == nullptr)
|
|
||||||
return false;
|
|
||||||
if (argNum >= (int)attrAgg->getSequence().size())
|
|
||||||
return false;
|
|
||||||
const TConstUnion& intConst = attrAgg->getSequence()[argNum]->getAsConstantUnion()->getConstArray()[0];
|
|
||||||
if (intConst.getType() != EbtInt)
|
|
||||||
return false;
|
|
||||||
value = intConst.getIConst();
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// location
|
// location
|
||||||
int value;
|
int value;
|
||||||
if (getInt(EatLocation, 0, value))
|
if (attributes.getInt(EatLocation, value))
|
||||||
type.getQualifier().layoutLocation = value;
|
type.getQualifier().layoutLocation = value;
|
||||||
|
|
||||||
// binding
|
// binding
|
||||||
if (getInt(EatBinding, 0, value)) {
|
if (attributes.getInt(EatBinding, value)) {
|
||||||
type.getQualifier().layoutBinding = value;
|
type.getQualifier().layoutBinding = value;
|
||||||
type.getQualifier().layoutSet = 0;
|
type.getQualifier().layoutSet = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set
|
// set
|
||||||
if (getInt(EatBinding, 1, value))
|
if (attributes.getInt(EatBinding, value, 1))
|
||||||
type.getQualifier().layoutSet = value;
|
type.getQualifier().layoutSet = value;
|
||||||
|
|
||||||
// input attachment
|
// input attachment
|
||||||
if (getInt(EatInputAttachment, 0, value))
|
if (attributes.getInt(EatInputAttachment, value))
|
||||||
type.getQualifier().layoutAttachment = value;
|
type.getQualifier().layoutAttachment = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user