Implement SPV_GOOGLE_hlsl_functionality1.
Enabled via -fhlsl_functionality1
This commit is contained in:
parent
cd23a47566
commit
5d610ee1dc
@ -126,6 +126,9 @@ public:
|
|||||||
void dumpSpv(std::vector<unsigned int>& out);
|
void dumpSpv(std::vector<unsigned int>& out);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
TGlslangToSpvTraverser(TGlslangToSpvTraverser&);
|
||||||
|
TGlslangToSpvTraverser& operator=(TGlslangToSpvTraverser&);
|
||||||
|
|
||||||
spv::Decoration TranslateInterpolationDecoration(const glslang::TQualifier& qualifier);
|
spv::Decoration TranslateInterpolationDecoration(const glslang::TQualifier& qualifier);
|
||||||
spv::Decoration TranslateAuxiliaryStorageDecoration(const glslang::TQualifier& qualifier);
|
spv::Decoration TranslateAuxiliaryStorageDecoration(const glslang::TQualifier& qualifier);
|
||||||
spv::BuiltIn TranslateBuiltInDecoration(glslang::TBuiltInVariable, bool memberDeclaration);
|
spv::BuiltIn TranslateBuiltInDecoration(glslang::TBuiltInVariable, bool memberDeclaration);
|
||||||
@ -153,7 +156,8 @@ protected:
|
|||||||
glslang::TLayoutPacking getExplicitLayout(const glslang::TType& type) const;
|
glslang::TLayoutPacking getExplicitLayout(const glslang::TType& type) const;
|
||||||
int getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking, glslang::TLayoutMatrix);
|
int getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking, glslang::TLayoutMatrix);
|
||||||
int getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking, glslang::TLayoutMatrix);
|
int getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking, glslang::TLayoutMatrix);
|
||||||
void updateMemberOffset(const glslang::TType& structType, const glslang::TType& memberType, int& currentOffset, int& nextOffset, glslang::TLayoutPacking, glslang::TLayoutMatrix);
|
void updateMemberOffset(const glslang::TType& structType, const glslang::TType& memberType, int& currentOffset,
|
||||||
|
int& nextOffset, glslang::TLayoutPacking, glslang::TLayoutMatrix);
|
||||||
void declareUseOfStructMember(const glslang::TTypeList& members, int glslangMember);
|
void declareUseOfStructMember(const glslang::TTypeList& members, int glslangMember);
|
||||||
|
|
||||||
bool isShaderEntryPoint(const glslang::TIntermAggregate* node);
|
bool isShaderEntryPoint(const glslang::TIntermAggregate* node);
|
||||||
@ -182,10 +186,6 @@ protected:
|
|||||||
spv::Id createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
|
spv::Id createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
|
||||||
spv::Id createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId);
|
spv::Id createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId);
|
||||||
spv::Id getSymbolId(const glslang::TIntermSymbol* node);
|
spv::Id getSymbolId(const glslang::TIntermSymbol* node);
|
||||||
void addDecoration(spv::Id id, spv::Decoration dec);
|
|
||||||
void addDecoration(spv::Id id, spv::Decoration dec, unsigned value);
|
|
||||||
void addMemberDecoration(spv::Id id, int member, spv::Decoration dec);
|
|
||||||
void addMemberDecoration(spv::Id id, int member, spv::Decoration dec, unsigned value);
|
|
||||||
spv::Id createSpvConstant(const glslang::TIntermTyped&);
|
spv::Id createSpvConstant(const glslang::TIntermTyped&);
|
||||||
spv::Id createSpvConstantFromConstUnionArray(const glslang::TType& type, const glslang::TConstUnionArray&, int& nextConst, bool specConstant);
|
spv::Id createSpvConstantFromConstUnionArray(const glslang::TType& type, const glslang::TConstUnionArray&, int& nextConst, bool specConstant);
|
||||||
bool isTrivialLeaf(const glslang::TIntermTyped* node);
|
bool isTrivialLeaf(const glslang::TIntermTyped* node);
|
||||||
@ -222,8 +222,10 @@ protected:
|
|||||||
std::unordered_set<int> rValueParameters; // set of formal function parameters passed as rValues, rather than a pointer
|
std::unordered_set<int> rValueParameters; // set of formal function parameters passed as rValues, rather than a pointer
|
||||||
std::unordered_map<std::string, spv::Function*> functionMap;
|
std::unordered_map<std::string, spv::Function*> functionMap;
|
||||||
std::unordered_map<const glslang::TTypeList*, spv::Id> structMap[glslang::ElpCount][glslang::ElmCount];
|
std::unordered_map<const glslang::TTypeList*, spv::Id> structMap[glslang::ElpCount][glslang::ElmCount];
|
||||||
std::unordered_map<const glslang::TTypeList*, std::vector<int> > memberRemapper; // for mapping glslang block indices to spv indices (e.g., due to hidden members)
|
// for mapping glslang block indices to spv indices (e.g., due to hidden members):
|
||||||
|
std::unordered_map<const glslang::TTypeList*, std::vector<int> > memberRemapper;
|
||||||
std::stack<bool> breakForLoop; // false means break for switch
|
std::stack<bool> breakForLoop; // false means break for switch
|
||||||
|
std::unordered_map<std::string, const glslang::TIntermSymbol*> counterOriginator;
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -1195,6 +1197,36 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol)
|
|||||||
else
|
else
|
||||||
builder.setAccessChainLValue(id);
|
builder.setAccessChainLValue(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Process linkage-only nodes for any special additional interface work.
|
||||||
|
if (linkageOnly) {
|
||||||
|
if (glslangIntermediate->getHlslFunctionality1()) {
|
||||||
|
// Map implicit counter buffers to their originating buffers, which should have been
|
||||||
|
// seen by now, given earlier pruning of unused counters, and preservation of order
|
||||||
|
// of declaration.
|
||||||
|
if (symbol->getType().getQualifier().isUniformOrBuffer()) {
|
||||||
|
if (!glslangIntermediate->hasCounterBufferName(symbol->getName())) {
|
||||||
|
// Save possible originating buffers for counter buffers, keyed by
|
||||||
|
// making the potential counter-buffer name.
|
||||||
|
std::string keyName = symbol->getName().c_str();
|
||||||
|
keyName = glslangIntermediate->addCounterBufferName(keyName);
|
||||||
|
counterOriginator[keyName] = symbol;
|
||||||
|
} else {
|
||||||
|
// Handle a counter buffer, by finding the saved originating buffer.
|
||||||
|
std::string keyName = symbol->getName().c_str();
|
||||||
|
auto it = counterOriginator.find(keyName);
|
||||||
|
if (it != counterOriginator.end()) {
|
||||||
|
id = getSymbolId(it->second);
|
||||||
|
if (id != spv::NoResult) {
|
||||||
|
spv::Id counterId = getSymbolId(symbol);
|
||||||
|
if (counterId != spv::NoResult)
|
||||||
|
builder.addDecorationId(id, spv::DecorationHlslCounterBufferGOOGLE, counterId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::TIntermBinary* node)
|
bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::TIntermBinary* node)
|
||||||
@ -2709,89 +2741,102 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
|
|||||||
InheritQualifiers(memberQualifier, qualifier);
|
InheritQualifiers(memberQualifier, qualifier);
|
||||||
|
|
||||||
// using -1 above to indicate a hidden member
|
// using -1 above to indicate a hidden member
|
||||||
if (member >= 0) {
|
if (member < 0)
|
||||||
builder.addMemberName(spvType, member, glslangMember.getFieldName().c_str());
|
continue;
|
||||||
addMemberDecoration(spvType, member, TranslateLayoutDecoration(glslangMember, memberQualifier.layoutMatrix));
|
|
||||||
addMemberDecoration(spvType, member, TranslatePrecisionDecoration(glslangMember));
|
builder.addMemberName(spvType, member, glslangMember.getFieldName().c_str());
|
||||||
// Add interpolation and auxiliary storage decorations only to top-level members of Input and Output storage classes
|
builder.addMemberDecoration(spvType, member,
|
||||||
if (type.getQualifier().storage == glslang::EvqVaryingIn ||
|
TranslateLayoutDecoration(glslangMember, memberQualifier.layoutMatrix));
|
||||||
type.getQualifier().storage == glslang::EvqVaryingOut) {
|
builder.addMemberDecoration(spvType, member, TranslatePrecisionDecoration(glslangMember));
|
||||||
if (type.getBasicType() == glslang::EbtBlock ||
|
// Add interpolation and auxiliary storage decorations only to
|
||||||
glslangIntermediate->getSource() == glslang::EShSourceHlsl) {
|
// top-level members of Input and Output storage classes
|
||||||
addMemberDecoration(spvType, member, TranslateInterpolationDecoration(memberQualifier));
|
if (type.getQualifier().storage == glslang::EvqVaryingIn ||
|
||||||
addMemberDecoration(spvType, member, TranslateAuxiliaryStorageDecoration(memberQualifier));
|
type.getQualifier().storage == glslang::EvqVaryingOut) {
|
||||||
}
|
if (type.getBasicType() == glslang::EbtBlock ||
|
||||||
|
glslangIntermediate->getSource() == glslang::EShSourceHlsl) {
|
||||||
|
builder.addMemberDecoration(spvType, member, TranslateInterpolationDecoration(memberQualifier));
|
||||||
|
builder.addMemberDecoration(spvType, member, TranslateAuxiliaryStorageDecoration(memberQualifier));
|
||||||
}
|
}
|
||||||
addMemberDecoration(spvType, member, TranslateInvariantDecoration(memberQualifier));
|
}
|
||||||
|
builder.addMemberDecoration(spvType, member, TranslateInvariantDecoration(memberQualifier));
|
||||||
|
|
||||||
if (type.getBasicType() == glslang::EbtBlock &&
|
if (type.getBasicType() == glslang::EbtBlock &&
|
||||||
qualifier.storage == glslang::EvqBuffer) {
|
qualifier.storage == glslang::EvqBuffer) {
|
||||||
// Add memory decorations only to top-level members of shader storage block
|
// Add memory decorations only to top-level members of shader storage block
|
||||||
std::vector<spv::Decoration> memory;
|
std::vector<spv::Decoration> memory;
|
||||||
TranslateMemoryDecoration(memberQualifier, memory);
|
TranslateMemoryDecoration(memberQualifier, memory);
|
||||||
for (unsigned int i = 0; i < memory.size(); ++i)
|
for (unsigned int i = 0; i < memory.size(); ++i)
|
||||||
addMemberDecoration(spvType, member, memory[i]);
|
builder.addMemberDecoration(spvType, member, memory[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Location assignment was already completed correctly by the front end,
|
// Location assignment was already completed correctly by the front end,
|
||||||
// just track whether a member needs to be decorated.
|
// just track whether a member needs to be decorated.
|
||||||
// Ignore member locations if the container is an array, as that's
|
// Ignore member locations if the container is an array, as that's
|
||||||
// ill-specified and decisions have been made to not allow this.
|
// ill-specified and decisions have been made to not allow this.
|
||||||
if (! type.isArray() && memberQualifier.hasLocation())
|
if (! type.isArray() && memberQualifier.hasLocation())
|
||||||
builder.addMemberDecoration(spvType, member, spv::DecorationLocation, memberQualifier.layoutLocation);
|
builder.addMemberDecoration(spvType, member, spv::DecorationLocation, memberQualifier.layoutLocation);
|
||||||
|
|
||||||
if (qualifier.hasLocation()) // track for upcoming inheritance
|
if (qualifier.hasLocation()) // track for upcoming inheritance
|
||||||
locationOffset += glslangIntermediate->computeTypeLocationSize(
|
locationOffset += glslangIntermediate->computeTypeLocationSize(
|
||||||
glslangMember, glslangIntermediate->getStage());
|
glslangMember, glslangIntermediate->getStage());
|
||||||
|
|
||||||
// component, XFB, others
|
// component, XFB, others
|
||||||
if (glslangMember.getQualifier().hasComponent())
|
if (glslangMember.getQualifier().hasComponent())
|
||||||
builder.addMemberDecoration(spvType, member, spv::DecorationComponent, glslangMember.getQualifier().layoutComponent);
|
builder.addMemberDecoration(spvType, member, spv::DecorationComponent,
|
||||||
if (glslangMember.getQualifier().hasXfbOffset())
|
glslangMember.getQualifier().layoutComponent);
|
||||||
builder.addMemberDecoration(spvType, member, spv::DecorationOffset, glslangMember.getQualifier().layoutXfbOffset);
|
if (glslangMember.getQualifier().hasXfbOffset())
|
||||||
else if (explicitLayout != glslang::ElpNone) {
|
builder.addMemberDecoration(spvType, member, spv::DecorationOffset,
|
||||||
// figure out what to do with offset, which is accumulating
|
glslangMember.getQualifier().layoutXfbOffset);
|
||||||
int nextOffset;
|
else if (explicitLayout != glslang::ElpNone) {
|
||||||
updateMemberOffset(type, glslangMember, offset, nextOffset, explicitLayout, memberQualifier.layoutMatrix);
|
// figure out what to do with offset, which is accumulating
|
||||||
if (offset >= 0)
|
int nextOffset;
|
||||||
builder.addMemberDecoration(spvType, member, spv::DecorationOffset, offset);
|
updateMemberOffset(type, glslangMember, offset, nextOffset, explicitLayout, memberQualifier.layoutMatrix);
|
||||||
offset = nextOffset;
|
if (offset >= 0)
|
||||||
}
|
builder.addMemberDecoration(spvType, member, spv::DecorationOffset, offset);
|
||||||
|
offset = nextOffset;
|
||||||
|
}
|
||||||
|
|
||||||
if (glslangMember.isMatrix() && explicitLayout != glslang::ElpNone)
|
if (glslangMember.isMatrix() && explicitLayout != glslang::ElpNone)
|
||||||
builder.addMemberDecoration(spvType, member, spv::DecorationMatrixStride, getMatrixStride(glslangMember, explicitLayout, memberQualifier.layoutMatrix));
|
builder.addMemberDecoration(spvType, member, spv::DecorationMatrixStride,
|
||||||
|
getMatrixStride(glslangMember, explicitLayout, memberQualifier.layoutMatrix));
|
||||||
|
|
||||||
// built-in variable decorations
|
// built-in variable decorations
|
||||||
spv::BuiltIn builtIn = TranslateBuiltInDecoration(glslangMember.getQualifier().builtIn, true);
|
spv::BuiltIn builtIn = TranslateBuiltInDecoration(glslangMember.getQualifier().builtIn, true);
|
||||||
if (builtIn != spv::BuiltInMax)
|
if (builtIn != spv::BuiltInMax)
|
||||||
addMemberDecoration(spvType, member, spv::DecorationBuiltIn, (int)builtIn);
|
builder.addMemberDecoration(spvType, member, spv::DecorationBuiltIn, (int)builtIn);
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
if (builtIn == spv::BuiltInLayer) {
|
if (builtIn == spv::BuiltInLayer) {
|
||||||
// SPV_NV_viewport_array2 extension
|
// SPV_NV_viewport_array2 extension
|
||||||
if (glslangMember.getQualifier().layoutViewportRelative){
|
if (glslangMember.getQualifier().layoutViewportRelative){
|
||||||
addMemberDecoration(spvType, member, (spv::Decoration)spv::DecorationViewportRelativeNV);
|
builder.addMemberDecoration(spvType, member, (spv::Decoration)spv::DecorationViewportRelativeNV);
|
||||||
builder.addCapability(spv::CapabilityShaderViewportMaskNV);
|
builder.addCapability(spv::CapabilityShaderViewportMaskNV);
|
||||||
builder.addExtension(spv::E_SPV_NV_viewport_array2);
|
builder.addExtension(spv::E_SPV_NV_viewport_array2);
|
||||||
}
|
|
||||||
if (glslangMember.getQualifier().layoutSecondaryViewportRelativeOffset != -2048){
|
|
||||||
addMemberDecoration(spvType, member, (spv::Decoration)spv::DecorationSecondaryViewportRelativeNV, glslangMember.getQualifier().layoutSecondaryViewportRelativeOffset);
|
|
||||||
builder.addCapability(spv::CapabilityShaderStereoViewNV);
|
|
||||||
builder.addExtension(spv::E_SPV_NV_stereo_view_rendering);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (glslangMember.getQualifier().layoutPassthrough) {
|
if (glslangMember.getQualifier().layoutSecondaryViewportRelativeOffset != -2048){
|
||||||
addMemberDecoration(spvType, member, (spv::Decoration)spv::DecorationPassthroughNV);
|
builder.addMemberDecoration(spvType, member,
|
||||||
builder.addCapability(spv::CapabilityGeometryShaderPassthroughNV);
|
(spv::Decoration)spv::DecorationSecondaryViewportRelativeNV,
|
||||||
builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough);
|
glslangMember.getQualifier().layoutSecondaryViewportRelativeOffset);
|
||||||
|
builder.addCapability(spv::CapabilityShaderStereoViewNV);
|
||||||
|
builder.addExtension(spv::E_SPV_NV_stereo_view_rendering);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (glslangMember.getQualifier().layoutPassthrough) {
|
||||||
|
builder.addMemberDecoration(spvType, member, (spv::Decoration)spv::DecorationPassthroughNV);
|
||||||
|
builder.addCapability(spv::CapabilityGeometryShaderPassthroughNV);
|
||||||
|
builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (glslangIntermediate->getHlslFunctionality1() && memberQualifier.semanticName != nullptr) {
|
||||||
|
builder.addExtension("SPV_GOOGLE_hlsl_functionality1");
|
||||||
|
builder.addMemberDecoration(spvType, member, (spv::Decoration)spv::DecorationHlslSemanticGOOGLE,
|
||||||
|
memberQualifier.semanticName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decorate the structure
|
// Decorate the structure
|
||||||
addDecoration(spvType, TranslateLayoutDecoration(type, qualifier.layoutMatrix));
|
builder.addDecoration(spvType, TranslateLayoutDecoration(type, qualifier.layoutMatrix));
|
||||||
addDecoration(spvType, TranslateBlockDecoration(type, glslangIntermediate->usingStorageBuffer()));
|
builder.addDecoration(spvType, TranslateBlockDecoration(type, glslangIntermediate->usingStorageBuffer()));
|
||||||
if (type.getQualifier().hasStream() && glslangIntermediate->isMultiStream()) {
|
if (type.getQualifier().hasStream() && glslangIntermediate->isMultiStream()) {
|
||||||
builder.addCapability(spv::CapabilityGeometryStreams);
|
builder.addCapability(spv::CapabilityGeometryStreams);
|
||||||
builder.addDecoration(spvType, spv::DecorationStream, type.getQualifier().layoutStream);
|
builder.addDecoration(spvType, spv::DecorationStream, type.getQualifier().layoutStream);
|
||||||
@ -4037,7 +4082,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, spv
|
|||||||
builder.promoteScalar(precision, left, right);
|
builder.promoteScalar(precision, left, right);
|
||||||
|
|
||||||
spv::Id result = builder.createBinOp(binOp, typeId, left, right);
|
spv::Id result = builder.createBinOp(binOp, typeId, left, right);
|
||||||
addDecoration(result, noContraction);
|
builder.addDecoration(result, noContraction);
|
||||||
return builder.setPrecision(result, precision);
|
return builder.setPrecision(result, precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4107,7 +4152,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, spv
|
|||||||
|
|
||||||
if (binOp != spv::OpNop) {
|
if (binOp != spv::OpNop) {
|
||||||
spv::Id result = builder.createBinOp(binOp, typeId, left, right);
|
spv::Id result = builder.createBinOp(binOp, typeId, left, right);
|
||||||
addDecoration(result, noContraction);
|
builder.addDecoration(result, noContraction);
|
||||||
return builder.setPrecision(result, precision);
|
return builder.setPrecision(result, precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4167,7 +4212,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, spv::Dec
|
|||||||
|
|
||||||
if (firstClass) {
|
if (firstClass) {
|
||||||
spv::Id result = builder.createBinOp(op, typeId, left, right);
|
spv::Id result = builder.createBinOp(op, typeId, left, right);
|
||||||
addDecoration(result, noContraction);
|
builder.addDecoration(result, noContraction);
|
||||||
return builder.setPrecision(result, precision);
|
return builder.setPrecision(result, precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4206,7 +4251,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, spv::Dec
|
|||||||
spv::Id leftVec = leftMat ? builder.createCompositeExtract( left, vecType, indexes) : smearVec;
|
spv::Id leftVec = leftMat ? builder.createCompositeExtract( left, vecType, indexes) : smearVec;
|
||||||
spv::Id rightVec = rightMat ? builder.createCompositeExtract(right, vecType, indexes) : smearVec;
|
spv::Id rightVec = rightMat ? builder.createCompositeExtract(right, vecType, indexes) : smearVec;
|
||||||
spv::Id result = builder.createBinOp(op, vecType, leftVec, rightVec);
|
spv::Id result = builder.createBinOp(op, vecType, leftVec, rightVec);
|
||||||
addDecoration(result, noContraction);
|
builder.addDecoration(result, noContraction);
|
||||||
results.push_back(builder.setPrecision(result, precision));
|
results.push_back(builder.setPrecision(result, precision));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4611,7 +4656,7 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, spv:
|
|||||||
id = builder.createUnaryOp(unaryOp, typeId, operand);
|
id = builder.createUnaryOp(unaryOp, typeId, operand);
|
||||||
}
|
}
|
||||||
|
|
||||||
addDecoration(id, noContraction);
|
builder.addDecoration(id, noContraction);
|
||||||
return builder.setPrecision(id, precision);
|
return builder.setPrecision(id, precision);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4638,7 +4683,7 @@ spv::Id TGlslangToSpvTraverser::createUnaryMatrixOperation(spv::Op op, spv::Deco
|
|||||||
indexes.push_back(c);
|
indexes.push_back(c);
|
||||||
spv::Id srcVec = builder.createCompositeExtract(operand, srcVecType, indexes);
|
spv::Id srcVec = builder.createCompositeExtract(operand, srcVecType, indexes);
|
||||||
spv::Id destVec = builder.createUnaryOp(op, destVecType, srcVec);
|
spv::Id destVec = builder.createUnaryOp(op, destVecType, srcVec);
|
||||||
addDecoration(destVec, noContraction);
|
builder.addDecoration(destVec, noContraction);
|
||||||
results.push_back(builder.setPrecision(destVec, precision));
|
results.push_back(builder.setPrecision(destVec, precision));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6147,11 +6192,11 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
|
|||||||
symbolValues[symbol->getId()] = id;
|
symbolValues[symbol->getId()] = id;
|
||||||
|
|
||||||
if (symbol->getBasicType() != glslang::EbtBlock) {
|
if (symbol->getBasicType() != glslang::EbtBlock) {
|
||||||
addDecoration(id, TranslatePrecisionDecoration(symbol->getType()));
|
builder.addDecoration(id, TranslatePrecisionDecoration(symbol->getType()));
|
||||||
addDecoration(id, TranslateInterpolationDecoration(symbol->getType().getQualifier()));
|
builder.addDecoration(id, TranslateInterpolationDecoration(symbol->getType().getQualifier()));
|
||||||
addDecoration(id, TranslateAuxiliaryStorageDecoration(symbol->getType().getQualifier()));
|
builder.addDecoration(id, TranslateAuxiliaryStorageDecoration(symbol->getType().getQualifier()));
|
||||||
if (symbol->getType().getQualifier().hasSpecConstantId())
|
if (symbol->getType().getQualifier().hasSpecConstantId())
|
||||||
addDecoration(id, spv::DecorationSpecId, symbol->getType().getQualifier().layoutSpecConstantId);
|
builder.addDecoration(id, spv::DecorationSpecId, symbol->getType().getQualifier().layoutSpecConstantId);
|
||||||
if (symbol->getQualifier().hasIndex())
|
if (symbol->getQualifier().hasIndex())
|
||||||
builder.addDecoration(id, spv::DecorationIndex, symbol->getQualifier().layoutIndex);
|
builder.addDecoration(id, spv::DecorationIndex, symbol->getQualifier().layoutIndex);
|
||||||
if (symbol->getQualifier().hasComponent())
|
if (symbol->getQualifier().hasComponent())
|
||||||
@ -6163,7 +6208,7 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
|
|||||||
|
|
||||||
if (symbol->getQualifier().hasLocation())
|
if (symbol->getQualifier().hasLocation())
|
||||||
builder.addDecoration(id, spv::DecorationLocation, symbol->getQualifier().layoutLocation);
|
builder.addDecoration(id, spv::DecorationLocation, symbol->getQualifier().layoutLocation);
|
||||||
addDecoration(id, TranslateInvariantDecoration(symbol->getType().getQualifier()));
|
builder.addDecoration(id, TranslateInvariantDecoration(symbol->getType().getQualifier()));
|
||||||
if (symbol->getQualifier().hasStream() && glslangIntermediate->isMultiStream()) {
|
if (symbol->getQualifier().hasStream() && glslangIntermediate->isMultiStream()) {
|
||||||
builder.addCapability(spv::CapabilityGeometryStreams);
|
builder.addCapability(spv::CapabilityGeometryStreams);
|
||||||
builder.addDecoration(id, spv::DecorationStream, symbol->getQualifier().layoutStream);
|
builder.addDecoration(id, spv::DecorationStream, symbol->getQualifier().layoutStream);
|
||||||
@ -6196,13 +6241,13 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
|
|||||||
std::vector<spv::Decoration> memory;
|
std::vector<spv::Decoration> memory;
|
||||||
TranslateMemoryDecoration(symbol->getType().getQualifier(), memory);
|
TranslateMemoryDecoration(symbol->getType().getQualifier(), memory);
|
||||||
for (unsigned int i = 0; i < memory.size(); ++i)
|
for (unsigned int i = 0; i < memory.size(); ++i)
|
||||||
addDecoration(id, memory[i]);
|
builder.addDecoration(id, memory[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// built-in variable decorations
|
// built-in variable decorations
|
||||||
spv::BuiltIn builtIn = TranslateBuiltInDecoration(symbol->getQualifier().builtIn, false);
|
spv::BuiltIn builtIn = TranslateBuiltInDecoration(symbol->getQualifier().builtIn, false);
|
||||||
if (builtIn != spv::BuiltInMax)
|
if (builtIn != spv::BuiltInMax)
|
||||||
addDecoration(id, spv::DecorationBuiltIn, (int)builtIn);
|
builder.addDecoration(id, spv::DecorationBuiltIn, (int)builtIn);
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
if (builtIn == spv::BuiltInSampleMask) {
|
if (builtIn == spv::BuiltInSampleMask) {
|
||||||
@ -6212,7 +6257,7 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
|
|||||||
decoration = (spv::Decoration)spv::DecorationOverrideCoverageNV;
|
decoration = (spv::Decoration)spv::DecorationOverrideCoverageNV;
|
||||||
else
|
else
|
||||||
decoration = (spv::Decoration)spv::DecorationMax;
|
decoration = (spv::Decoration)spv::DecorationMax;
|
||||||
addDecoration(id, decoration);
|
builder.addDecoration(id, decoration);
|
||||||
if (decoration != spv::DecorationMax) {
|
if (decoration != spv::DecorationMax) {
|
||||||
builder.addExtension(spv::E_SPV_NV_sample_mask_override_coverage);
|
builder.addExtension(spv::E_SPV_NV_sample_mask_override_coverage);
|
||||||
}
|
}
|
||||||
@ -6220,55 +6265,34 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
|
|||||||
else if (builtIn == spv::BuiltInLayer) {
|
else if (builtIn == spv::BuiltInLayer) {
|
||||||
// SPV_NV_viewport_array2 extension
|
// SPV_NV_viewport_array2 extension
|
||||||
if (symbol->getQualifier().layoutViewportRelative) {
|
if (symbol->getQualifier().layoutViewportRelative) {
|
||||||
addDecoration(id, (spv::Decoration)spv::DecorationViewportRelativeNV);
|
builder.addDecoration(id, (spv::Decoration)spv::DecorationViewportRelativeNV);
|
||||||
builder.addCapability(spv::CapabilityShaderViewportMaskNV);
|
builder.addCapability(spv::CapabilityShaderViewportMaskNV);
|
||||||
builder.addExtension(spv::E_SPV_NV_viewport_array2);
|
builder.addExtension(spv::E_SPV_NV_viewport_array2);
|
||||||
}
|
}
|
||||||
if (symbol->getQualifier().layoutSecondaryViewportRelativeOffset != -2048) {
|
if (symbol->getQualifier().layoutSecondaryViewportRelativeOffset != -2048) {
|
||||||
addDecoration(id, (spv::Decoration)spv::DecorationSecondaryViewportRelativeNV, symbol->getQualifier().layoutSecondaryViewportRelativeOffset);
|
builder.addDecoration(id, (spv::Decoration)spv::DecorationSecondaryViewportRelativeNV,
|
||||||
|
symbol->getQualifier().layoutSecondaryViewportRelativeOffset);
|
||||||
builder.addCapability(spv::CapabilityShaderStereoViewNV);
|
builder.addCapability(spv::CapabilityShaderStereoViewNV);
|
||||||
builder.addExtension(spv::E_SPV_NV_stereo_view_rendering);
|
builder.addExtension(spv::E_SPV_NV_stereo_view_rendering);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (symbol->getQualifier().layoutPassthrough) {
|
if (symbol->getQualifier().layoutPassthrough) {
|
||||||
addDecoration(id, spv::DecorationPassthroughNV);
|
builder.addDecoration(id, spv::DecorationPassthroughNV);
|
||||||
builder.addCapability(spv::CapabilityGeometryShaderPassthroughNV);
|
builder.addCapability(spv::CapabilityGeometryShaderPassthroughNV);
|
||||||
builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough);
|
builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (glslangIntermediate->getHlslFunctionality1() && symbol->getType().getQualifier().semanticName != nullptr) {
|
||||||
|
builder.addExtension("SPV_GOOGLE_hlsl_functionality1");
|
||||||
|
builder.addDecoration(id, (spv::Decoration)spv::DecorationHlslSemanticGOOGLE,
|
||||||
|
symbol->getType().getQualifier().semanticName);
|
||||||
|
}
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If 'dec' is valid, add no-operand decoration to an object
|
|
||||||
void TGlslangToSpvTraverser::addDecoration(spv::Id id, spv::Decoration dec)
|
|
||||||
{
|
|
||||||
if (dec != spv::DecorationMax)
|
|
||||||
builder.addDecoration(id, dec);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If 'dec' is valid, add a one-operand decoration to an object
|
|
||||||
void TGlslangToSpvTraverser::addDecoration(spv::Id id, spv::Decoration dec, unsigned value)
|
|
||||||
{
|
|
||||||
if (dec != spv::DecorationMax)
|
|
||||||
builder.addDecoration(id, dec, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If 'dec' is valid, add a no-operand decoration to a struct member
|
|
||||||
void TGlslangToSpvTraverser::addMemberDecoration(spv::Id id, int member, spv::Decoration dec)
|
|
||||||
{
|
|
||||||
if (dec != spv::DecorationMax)
|
|
||||||
builder.addMemberDecoration(id, (unsigned)member, dec);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If 'dec' is valid, add a one-operand decoration to a struct member
|
|
||||||
void TGlslangToSpvTraverser::addMemberDecoration(spv::Id id, int member, spv::Decoration dec, unsigned value)
|
|
||||||
{
|
|
||||||
if (dec != spv::DecorationMax)
|
|
||||||
builder.addMemberDecoration(id, (unsigned)member, dec, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make a full tree of instructions to build a SPIR-V specialization constant,
|
// Make a full tree of instructions to build a SPIR-V specialization constant,
|
||||||
// or regular constant if possible.
|
// or regular constant if possible.
|
||||||
//
|
//
|
||||||
@ -6301,8 +6325,10 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TIntermTyped& n
|
|||||||
for (int dim = 0; dim < 3; ++dim) {
|
for (int dim = 0; dim < 3; ++dim) {
|
||||||
bool specConst = (glslangIntermediate->getLocalSizeSpecId(dim) != glslang::TQualifier::layoutNotSet);
|
bool specConst = (glslangIntermediate->getLocalSizeSpecId(dim) != glslang::TQualifier::layoutNotSet);
|
||||||
dimConstId.push_back(builder.makeUintConstant(glslangIntermediate->getLocalSize(dim), specConst));
|
dimConstId.push_back(builder.makeUintConstant(glslangIntermediate->getLocalSize(dim), specConst));
|
||||||
if (specConst)
|
if (specConst) {
|
||||||
addDecoration(dimConstId.back(), spv::DecorationSpecId, glslangIntermediate->getLocalSizeSpecId(dim));
|
builder.addDecoration(dimConstId.back(), spv::DecorationSpecId,
|
||||||
|
glslangIntermediate->getLocalSizeSpecId(dim));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return builder.makeCompositeConstant(builder.makeVectorType(builder.makeUintType(32), 3), dimConstId, true);
|
return builder.makeCompositeConstant(builder.makeVectorType(builder.makeUintType(32), 3), dimConstId, true);
|
||||||
}
|
}
|
||||||
|
@ -1010,6 +1010,7 @@ void Builder::addDecoration(Id id, Decoration decoration, int num)
|
|||||||
{
|
{
|
||||||
if (decoration == spv::DecorationMax)
|
if (decoration == spv::DecorationMax)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Instruction* dec = new Instruction(OpDecorate);
|
Instruction* dec = new Instruction(OpDecorate);
|
||||||
dec->addIdOperand(id);
|
dec->addIdOperand(id);
|
||||||
dec->addImmediateOperand(decoration);
|
dec->addImmediateOperand(decoration);
|
||||||
@ -1019,8 +1020,37 @@ void Builder::addDecoration(Id id, Decoration decoration, int num)
|
|||||||
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Builder::addDecoration(Id id, Decoration decoration, const char* s)
|
||||||
|
{
|
||||||
|
if (decoration == spv::DecorationMax)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Instruction* dec = new Instruction(OpDecorateStringGOOGLE);
|
||||||
|
dec->addIdOperand(id);
|
||||||
|
dec->addImmediateOperand(decoration);
|
||||||
|
dec->addStringOperand(s);
|
||||||
|
|
||||||
|
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Builder::addDecorationId(Id id, Decoration decoration, Id idDecoration)
|
||||||
|
{
|
||||||
|
if (decoration == spv::DecorationMax)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Instruction* dec = new Instruction(OpDecorateId);
|
||||||
|
dec->addIdOperand(id);
|
||||||
|
dec->addImmediateOperand(decoration);
|
||||||
|
dec->addIdOperand(idDecoration);
|
||||||
|
|
||||||
|
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||||
|
}
|
||||||
|
|
||||||
void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, int num)
|
void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, int num)
|
||||||
{
|
{
|
||||||
|
if (decoration == spv::DecorationMax)
|
||||||
|
return;
|
||||||
|
|
||||||
Instruction* dec = new Instruction(OpMemberDecorate);
|
Instruction* dec = new Instruction(OpMemberDecorate);
|
||||||
dec->addIdOperand(id);
|
dec->addIdOperand(id);
|
||||||
dec->addImmediateOperand(member);
|
dec->addImmediateOperand(member);
|
||||||
@ -1031,6 +1061,20 @@ void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decorat
|
|||||||
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Builder::addMemberDecoration(Id id, unsigned int member, Decoration decoration, const char *s)
|
||||||
|
{
|
||||||
|
if (decoration == spv::DecorationMax)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Instruction* dec = new Instruction(OpMemberDecorateStringGOOGLE);
|
||||||
|
dec->addIdOperand(id);
|
||||||
|
dec->addImmediateOperand(member);
|
||||||
|
dec->addImmediateOperand(decoration);
|
||||||
|
dec->addStringOperand(s);
|
||||||
|
|
||||||
|
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||||
|
}
|
||||||
|
|
||||||
// Comments in header
|
// Comments in header
|
||||||
Function* Builder::makeEntryPoint(const char* entryPoint)
|
Function* Builder::makeEntryPoint(const char* entryPoint)
|
||||||
{
|
{
|
||||||
|
@ -237,7 +237,10 @@ public:
|
|||||||
void addName(Id, const char* name);
|
void addName(Id, const char* name);
|
||||||
void addMemberName(Id, int member, const char* name);
|
void addMemberName(Id, int member, const char* name);
|
||||||
void addDecoration(Id, Decoration, int num = -1);
|
void addDecoration(Id, Decoration, int num = -1);
|
||||||
|
void addDecoration(Id, Decoration, const char*);
|
||||||
|
void addDecorationId(Id id, Decoration, Id idDecoration);
|
||||||
void addMemberDecoration(Id, unsigned int member, Decoration, int num = -1);
|
void addMemberDecoration(Id, unsigned int member, Decoration, int num = -1);
|
||||||
|
void addMemberDecoration(Id, unsigned int member, Decoration, const char*);
|
||||||
|
|
||||||
// At the end of what block do the next create*() instructions go?
|
// At the end of what block do the next create*() instructions go?
|
||||||
void setBuildPoint(Block* bp) { buildPoint = bp; }
|
void setBuildPoint(Block* bp) { buildPoint = bp; }
|
||||||
|
@ -269,6 +269,9 @@ const char* DecorationString(int decoration)
|
|||||||
case 5252: return "ViewportRelativeNV";
|
case 5252: return "ViewportRelativeNV";
|
||||||
case 5256: return "SecondaryViewportRelativeNV";
|
case 5256: return "SecondaryViewportRelativeNV";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
case DecorationHlslCounterBufferGOOGLE: return "DecorationHlslCounterBufferGOOGLE";
|
||||||
|
case DecorationHlslSemanticGOOGLE: return "DecorationHlslSemanticGOOGLE";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1208,6 +1211,7 @@ const char* OpcodeString(int op)
|
|||||||
case 320: return "OpImageSparseRead";
|
case 320: return "OpImageSparseRead";
|
||||||
|
|
||||||
case OpModuleProcessed: return "OpModuleProcessed";
|
case OpModuleProcessed: return "OpModuleProcessed";
|
||||||
|
case OpDecorateId: return "OpDecorateId";
|
||||||
|
|
||||||
case 333: return "OpGroupNonUniformElect";
|
case 333: return "OpGroupNonUniformElect";
|
||||||
case 334: return "OpGroupNonUniformAll";
|
case 334: return "OpGroupNonUniformAll";
|
||||||
@ -1265,6 +1269,9 @@ const char* OpcodeString(int op)
|
|||||||
case 5012: return "OpFragmentFetchAMD";
|
case 5012: return "OpFragmentFetchAMD";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
case OpDecorateStringGOOGLE: return "OpDecorateStringGOOGLE";
|
||||||
|
case OpMemberDecorateStringGOOGLE: return "OpMemberDecorateStringGOOGLE";
|
||||||
|
|
||||||
case OpcodeCeiling:
|
case OpcodeCeiling:
|
||||||
default:
|
default:
|
||||||
return "Bad";
|
return "Bad";
|
||||||
@ -1356,7 +1363,10 @@ void Parameterize()
|
|||||||
InstructionDesc[OpImageWrite].setResultAndType(false, false);
|
InstructionDesc[OpImageWrite].setResultAndType(false, false);
|
||||||
InstructionDesc[OpDecorationGroup].setResultAndType(true, false);
|
InstructionDesc[OpDecorationGroup].setResultAndType(true, false);
|
||||||
InstructionDesc[OpDecorate].setResultAndType(false, false);
|
InstructionDesc[OpDecorate].setResultAndType(false, false);
|
||||||
|
InstructionDesc[OpDecorateId].setResultAndType(false, false);
|
||||||
|
InstructionDesc[OpDecorateStringGOOGLE].setResultAndType(false, false);
|
||||||
InstructionDesc[OpMemberDecorate].setResultAndType(false, false);
|
InstructionDesc[OpMemberDecorate].setResultAndType(false, false);
|
||||||
|
InstructionDesc[OpMemberDecorateStringGOOGLE].setResultAndType(false, false);
|
||||||
InstructionDesc[OpGroupDecorate].setResultAndType(false, false);
|
InstructionDesc[OpGroupDecorate].setResultAndType(false, false);
|
||||||
InstructionDesc[OpGroupMemberDecorate].setResultAndType(false, false);
|
InstructionDesc[OpGroupMemberDecorate].setResultAndType(false, false);
|
||||||
InstructionDesc[OpName].setResultAndType(false, false);
|
InstructionDesc[OpName].setResultAndType(false, false);
|
||||||
@ -1921,11 +1931,24 @@ void Parameterize()
|
|||||||
InstructionDesc[OpDecorate].operands.push(OperandDecoration, "");
|
InstructionDesc[OpDecorate].operands.push(OperandDecoration, "");
|
||||||
InstructionDesc[OpDecorate].operands.push(OperandVariableLiterals, "See <<Decoration,'Decoration'>>.");
|
InstructionDesc[OpDecorate].operands.push(OperandVariableLiterals, "See <<Decoration,'Decoration'>>.");
|
||||||
|
|
||||||
|
InstructionDesc[OpDecorateId].operands.push(OperandId, "'Target'");
|
||||||
|
InstructionDesc[OpDecorateId].operands.push(OperandDecoration, "");
|
||||||
|
InstructionDesc[OpDecorateId].operands.push(OperandVariableIds, "See <<Decoration,'Decoration'>>.");
|
||||||
|
|
||||||
|
InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandId, "'Target'");
|
||||||
|
InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandDecoration, "");
|
||||||
|
InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandLiteralString, "'Literal String'");
|
||||||
|
|
||||||
InstructionDesc[OpMemberDecorate].operands.push(OperandId, "'Structure Type'");
|
InstructionDesc[OpMemberDecorate].operands.push(OperandId, "'Structure Type'");
|
||||||
InstructionDesc[OpMemberDecorate].operands.push(OperandLiteralNumber, "'Member'");
|
InstructionDesc[OpMemberDecorate].operands.push(OperandLiteralNumber, "'Member'");
|
||||||
InstructionDesc[OpMemberDecorate].operands.push(OperandDecoration, "");
|
InstructionDesc[OpMemberDecorate].operands.push(OperandDecoration, "");
|
||||||
InstructionDesc[OpMemberDecorate].operands.push(OperandVariableLiterals, "See <<Decoration,'Decoration'>>.");
|
InstructionDesc[OpMemberDecorate].operands.push(OperandVariableLiterals, "See <<Decoration,'Decoration'>>.");
|
||||||
|
|
||||||
|
InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandId, "'Structure Type'");
|
||||||
|
InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandLiteralNumber, "'Member'");
|
||||||
|
InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandDecoration, "");
|
||||||
|
InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandLiteralString, "'Literal String'");
|
||||||
|
|
||||||
InstructionDesc[OpGroupDecorate].operands.push(OperandId, "'Decoration Group'");
|
InstructionDesc[OpGroupDecorate].operands.push(OperandId, "'Decoration Group'");
|
||||||
InstructionDesc[OpGroupDecorate].operands.push(OperandVariableIds, "'Targets'");
|
InstructionDesc[OpGroupDecorate].operands.push(OperandVariableIds, "'Targets'");
|
||||||
|
|
||||||
|
@ -101,6 +101,7 @@ enum TOptions {
|
|||||||
EOptionInvertY = (1 << 30),
|
EOptionInvertY = (1 << 30),
|
||||||
EOptionDumpBareVersion = (1 << 31),
|
EOptionDumpBareVersion = (1 << 31),
|
||||||
};
|
};
|
||||||
|
bool targetHlslFunctionality1 = false;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Return codes from main/exit().
|
// Return codes from main/exit().
|
||||||
@ -523,7 +524,7 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
|
|||||||
setOpenGlSpv();
|
setOpenGlSpv();
|
||||||
OpenGLClientVersion = glslang::EShTargetOpenGL_450;
|
OpenGLClientVersion = glslang::EShTargetOpenGL_450;
|
||||||
} else
|
} else
|
||||||
Error("--target-env expected vulkan1.0, opengl, or hlsl-16bit-types");
|
Error("--target-env expected vulkan1.0, vulkan1.1, or opengl");
|
||||||
}
|
}
|
||||||
bumpArg();
|
bumpArg();
|
||||||
} else if (lowerword == "variable-name" || // synonyms
|
} else if (lowerword == "variable-name" || // synonyms
|
||||||
@ -613,6 +614,12 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
|
|||||||
Error("no <name> provided for -e");
|
Error("no <name> provided for -e");
|
||||||
bumpArg();
|
bumpArg();
|
||||||
break;
|
break;
|
||||||
|
case 'f':
|
||||||
|
if (strcmp(&argv[0][2], "hlsl_functionality1") == 0)
|
||||||
|
targetHlslFunctionality1 = true;
|
||||||
|
else
|
||||||
|
Error("-f: expected hlsl_functionality1");
|
||||||
|
break;
|
||||||
case 'g':
|
case 'g':
|
||||||
Options |= EOptionDebug;
|
Options |= EOptionDebug;
|
||||||
break;
|
break;
|
||||||
@ -874,14 +881,15 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
|
|||||||
: glslang::EShSourceGlsl,
|
: glslang::EShSourceGlsl,
|
||||||
compUnit.stage, glslang::EShClientVulkan, ClientInputSemanticsVersion);
|
compUnit.stage, glslang::EShClientVulkan, ClientInputSemanticsVersion);
|
||||||
shader->setEnvClient(glslang::EShClientVulkan, VulkanClientVersion);
|
shader->setEnvClient(glslang::EShClientVulkan, VulkanClientVersion);
|
||||||
shader->setEnvTarget(glslang::EShTargetSpv, TargetVersion);
|
|
||||||
} else {
|
} else {
|
||||||
shader->setEnvInput((Options & EOptionReadHlsl) ? glslang::EShSourceHlsl
|
shader->setEnvInput((Options & EOptionReadHlsl) ? glslang::EShSourceHlsl
|
||||||
: glslang::EShSourceGlsl,
|
: glslang::EShSourceGlsl,
|
||||||
compUnit.stage, glslang::EShClientOpenGL, ClientInputSemanticsVersion);
|
compUnit.stage, glslang::EShClientOpenGL, ClientInputSemanticsVersion);
|
||||||
shader->setEnvClient(glslang::EShClientOpenGL, OpenGLClientVersion);
|
shader->setEnvClient(glslang::EShClientOpenGL, OpenGLClientVersion);
|
||||||
shader->setEnvTarget(glslang::EshTargetSpv, TargetVersion);
|
|
||||||
}
|
}
|
||||||
|
shader->setEnvTarget(glslang::EShTargetSpv, TargetVersion);
|
||||||
|
if (targetHlslFunctionality1)
|
||||||
|
shader->setEnvTargetHlslFunctionality1();
|
||||||
}
|
}
|
||||||
|
|
||||||
shaders.push_back(shader);
|
shaders.push_back(shader);
|
||||||
@ -1318,6 +1326,9 @@ void usage()
|
|||||||
" -d default to desktop (#version 110) when there is no shader #version\n"
|
" -d default to desktop (#version 110) when there is no shader #version\n"
|
||||||
" (default is ES version 100)\n"
|
" (default is ES version 100)\n"
|
||||||
" -e <name> specify <name> as the entry-point name\n"
|
" -e <name> specify <name> as the entry-point name\n"
|
||||||
|
" -f{hlsl_functionality1}\n"
|
||||||
|
" 'hlsl_functionality1' enables use of the\n"
|
||||||
|
" SPV_GOOGLE_hlsl_functionality1 extension\n"
|
||||||
" -g generate debug information\n"
|
" -g generate debug information\n"
|
||||||
" -h print this usage message\n"
|
" -h print this usage message\n"
|
||||||
" -i intermediate tree (glslang AST) is printed out\n"
|
" -i intermediate tree (glslang AST) is printed out\n"
|
||||||
@ -1390,8 +1401,8 @@ void usage()
|
|||||||
" set execution environment that emitted code\n"
|
" set execution environment that emitted code\n"
|
||||||
" will execute in (as opposed to the language\n"
|
" will execute in (as opposed to the language\n"
|
||||||
" semantics selected by --client) defaults:\n"
|
" semantics selected by --client) defaults:\n"
|
||||||
" 'vulkan1.0' under '--client vulkan<ver>'\n"
|
" 'vulkan1.0' under '--client vulkan<ver>'\n"
|
||||||
" 'opengl' under '--client opengl<ver>'\n"
|
" 'opengl' under '--client opengl<ver>'\n"
|
||||||
" --variable-name <name> Creates a C header file that contains a\n"
|
" --variable-name <name> Creates a C header file that contains a\n"
|
||||||
" uint32_t array named <name>\n"
|
" uint32_t array named <name>\n"
|
||||||
" initialized with the shader binary code.\n"
|
" initialized with the shader binary code.\n"
|
||||||
|
125
Test/baseResults/hlsl.structbuffer.incdec.frag.hlslfun1.out
Normal file
125
Test/baseResults/hlsl.structbuffer.incdec.frag.hlslfun1.out
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
hlsl.structbuffer.incdec.frag
|
||||||
|
// Module Version 10000
|
||||||
|
// Generated by (magic number): 80006
|
||||||
|
// Id's are bound by 70
|
||||||
|
|
||||||
|
Capability Shader
|
||||||
|
Extension "SPV_GOOGLE_hlsl_functionality1"
|
||||||
|
1: ExtInstImport "GLSL.std.450"
|
||||||
|
MemoryModel Logical GLSL450
|
||||||
|
EntryPoint Fragment 4 "main" 63 66
|
||||||
|
ExecutionMode 4 OriginUpperLeft
|
||||||
|
Source HLSL 500
|
||||||
|
Name 4 "main"
|
||||||
|
Name 12 "@main(u1;"
|
||||||
|
Name 11 "pos"
|
||||||
|
Name 16 "result"
|
||||||
|
Name 20 "sbuf_rw_i"
|
||||||
|
MemberName 20(sbuf_rw_i) 0 "@data"
|
||||||
|
Name 22 "sbuf_rw_i"
|
||||||
|
Name 26 "sbuf_rw_d"
|
||||||
|
Name 27 "sbuf_rw_nocounter"
|
||||||
|
Name 33 "c1"
|
||||||
|
Name 34 "sbuf_rw_i@count"
|
||||||
|
MemberName 34(sbuf_rw_i@count) 0 "@count"
|
||||||
|
Name 36 "sbuf_rw_i@count"
|
||||||
|
Name 42 "c2"
|
||||||
|
Name 43 "sbuf_rw_d@count"
|
||||||
|
Name 61 "pos"
|
||||||
|
Name 63 "pos"
|
||||||
|
Name 66 "@entryPointOutput"
|
||||||
|
Name 67 "param"
|
||||||
|
Decorate 19 ArrayStride 16
|
||||||
|
MemberDecorate 20(sbuf_rw_i) 0 Offset 0
|
||||||
|
Decorate 20(sbuf_rw_i) BufferBlock
|
||||||
|
Decorate 22(sbuf_rw_i) DescriptorSet 0
|
||||||
|
Decorate 26(sbuf_rw_d) DescriptorSet 0
|
||||||
|
Decorate 27(sbuf_rw_nocounter) DescriptorSet 0
|
||||||
|
MemberDecorate 34(sbuf_rw_i@count) 0 Offset 0
|
||||||
|
Decorate 34(sbuf_rw_i@count) BufferBlock
|
||||||
|
Decorate 36(sbuf_rw_i@count) DescriptorSet 0
|
||||||
|
Decorate 43(sbuf_rw_d@count) DescriptorSet 0
|
||||||
|
Decorate 63(pos) Flat
|
||||||
|
Decorate 63(pos) Location 0
|
||||||
|
DecorateStringGOOGLE 63(pos) DecorationHlslSemanticGOOGLE "FOO"
|
||||||
|
Decorate 66(@entryPointOutput) Location 0
|
||||||
|
DecorateStringGOOGLE 66(@entryPointOutput) DecorationHlslSemanticGOOGLE "SV_TARGET0"
|
||||||
|
DecorateId 22(sbuf_rw_i) DecorationHlslCounterBufferGOOGLE 36(sbuf_rw_i@count)
|
||||||
|
DecorateId 26(sbuf_rw_d) DecorationHlslCounterBufferGOOGLE 43(sbuf_rw_d@count)
|
||||||
|
2: TypeVoid
|
||||||
|
3: TypeFunction 2
|
||||||
|
6: TypeInt 32 0
|
||||||
|
7: TypePointer Function 6(int)
|
||||||
|
8: TypeFloat 32
|
||||||
|
9: TypeVector 8(float) 4
|
||||||
|
10: TypeFunction 9(fvec4) 7(ptr)
|
||||||
|
14: TypeVector 6(int) 4
|
||||||
|
15: TypePointer Function 14(ivec4)
|
||||||
|
17: 6(int) Constant 0
|
||||||
|
18: 14(ivec4) ConstantComposite 17 17 17 17
|
||||||
|
19: TypeRuntimeArray 14(ivec4)
|
||||||
|
20(sbuf_rw_i): TypeStruct 19
|
||||||
|
21: TypePointer Uniform 20(sbuf_rw_i)
|
||||||
|
22(sbuf_rw_i): 21(ptr) Variable Uniform
|
||||||
|
23: TypeInt 32 1
|
||||||
|
24: 23(int) Constant 0
|
||||||
|
25: 23(int) Constant 7
|
||||||
|
26(sbuf_rw_d): 21(ptr) Variable Uniform
|
||||||
|
27(sbuf_rw_nocounter): 21(ptr) Variable Uniform
|
||||||
|
28: 23(int) Constant 5
|
||||||
|
29: 6(int) Constant 2
|
||||||
|
30: 14(ivec4) ConstantComposite 29 29 29 29
|
||||||
|
31: TypePointer Uniform 14(ivec4)
|
||||||
|
34(sbuf_rw_i@count): TypeStruct 23(int)
|
||||||
|
35: TypePointer Uniform 34(sbuf_rw_i@count)
|
||||||
|
36(sbuf_rw_i@count): 35(ptr) Variable Uniform
|
||||||
|
37: TypePointer Uniform 23(int)
|
||||||
|
39: 23(int) Constant 1
|
||||||
|
40: 6(int) Constant 1
|
||||||
|
43(sbuf_rw_d@count): 35(ptr) Variable Uniform
|
||||||
|
45: 23(int) Constant 4294967295
|
||||||
|
62: TypePointer Input 6(int)
|
||||||
|
63(pos): 62(ptr) Variable Input
|
||||||
|
65: TypePointer Output 9(fvec4)
|
||||||
|
66(@entryPointOutput): 65(ptr) Variable Output
|
||||||
|
4(main): 2 Function None 3
|
||||||
|
5: Label
|
||||||
|
61(pos): 7(ptr) Variable Function
|
||||||
|
67(param): 7(ptr) Variable Function
|
||||||
|
64: 6(int) Load 63(pos)
|
||||||
|
Store 61(pos) 64
|
||||||
|
68: 6(int) Load 61(pos)
|
||||||
|
Store 67(param) 68
|
||||||
|
69: 9(fvec4) FunctionCall 12(@main(u1;) 67(param)
|
||||||
|
Store 66(@entryPointOutput) 69
|
||||||
|
Return
|
||||||
|
FunctionEnd
|
||||||
|
12(@main(u1;): 9(fvec4) Function None 10
|
||||||
|
11(pos): 7(ptr) FunctionParameter
|
||||||
|
13: Label
|
||||||
|
16(result): 15(ptr) Variable Function
|
||||||
|
33(c1): 7(ptr) Variable Function
|
||||||
|
42(c2): 7(ptr) Variable Function
|
||||||
|
Store 16(result) 18
|
||||||
|
32: 31(ptr) AccessChain 27(sbuf_rw_nocounter) 24 28
|
||||||
|
Store 32 30
|
||||||
|
38: 37(ptr) AccessChain 36(sbuf_rw_i@count) 24
|
||||||
|
41: 6(int) AtomicIAdd 38 40 17 39
|
||||||
|
Store 33(c1) 41
|
||||||
|
44: 37(ptr) AccessChain 43(sbuf_rw_d@count) 24
|
||||||
|
46: 6(int) AtomicIAdd 44 40 17 45
|
||||||
|
47: 6(int) IAdd 46 45
|
||||||
|
Store 42(c2) 47
|
||||||
|
48: 7(ptr) AccessChain 16(result) 17
|
||||||
|
49: 6(int) Load 48
|
||||||
|
50: 8(float) ConvertUToF 49
|
||||||
|
51: 7(ptr) AccessChain 16(result) 40
|
||||||
|
52: 6(int) Load 51
|
||||||
|
53: 8(float) ConvertUToF 52
|
||||||
|
54: 6(int) Load 33(c1)
|
||||||
|
55: 8(float) ConvertUToF 54
|
||||||
|
56: 6(int) Load 42(c2)
|
||||||
|
57: 8(float) ConvertUToF 56
|
||||||
|
58: 9(fvec4) CompositeConstruct 50 53 55 57
|
||||||
|
ReturnValue 58
|
||||||
|
FunctionEnd
|
@ -201,6 +201,13 @@ diff -b $BASEDIR/hlsl.y-negate-2.vert.out $TARGETDIR/hlsl.y-negate-2.vert.out ||
|
|||||||
$EXE -H -e main -V -D -Od -H -i --invert-y hlsl.y-negate-3.vert > $TARGETDIR/hlsl.y-negate-3.vert.out
|
$EXE -H -e main -V -D -Od -H -i --invert-y hlsl.y-negate-3.vert > $TARGETDIR/hlsl.y-negate-3.vert.out
|
||||||
diff -b $BASEDIR/hlsl.y-negate-3.vert.out $TARGETDIR/hlsl.y-negate-3.vert.out || HASERROR=1
|
diff -b $BASEDIR/hlsl.y-negate-3.vert.out $TARGETDIR/hlsl.y-negate-3.vert.out || HASERROR=1
|
||||||
|
|
||||||
|
#
|
||||||
|
# Testing hlsl_functionality1
|
||||||
|
#
|
||||||
|
$EXE -H -e main -D -Od -fhlsl_functionality1 hlsl.structbuffer.incdec.frag > \
|
||||||
|
$TARGETDIR/hlsl.structbuffer.incdec.frag.hlslfun1.out
|
||||||
|
diff -b $BASEDIR/hlsl.structbuffer.incdec.frag.hlslfun1.out $TARGETDIR/hlsl.structbuffer.incdec.frag.hlslfun1.out || HASERROR=1
|
||||||
|
|
||||||
#
|
#
|
||||||
# Final checking
|
# Final checking
|
||||||
#
|
#
|
||||||
|
@ -228,6 +228,7 @@ void TParseContextBase::rValueErrorCheck(const TSourceLoc& loc, const char* op,
|
|||||||
// must still be valid.
|
// must still be valid.
|
||||||
// It is okay if the symbol's type will be subsequently edited;
|
// It is okay if the symbol's type will be subsequently edited;
|
||||||
// the modifications will be tracked.
|
// the modifications will be tracked.
|
||||||
|
// Order is preserved, to avoid creating novel forward references.
|
||||||
void TParseContextBase::trackLinkage(TSymbol& symbol)
|
void TParseContextBase::trackLinkage(TSymbol& symbol)
|
||||||
{
|
{
|
||||||
if (!parsingBuiltins)
|
if (!parsingBuiltins)
|
||||||
@ -602,7 +603,7 @@ void TParseContextBase::finish()
|
|||||||
if (parsingBuiltins)
|
if (parsingBuiltins)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Transfer the linkage symbols to AST nodes
|
// Transfer the linkage symbols to AST nodes, preserving order.
|
||||||
TIntermAggregate* linkage = new TIntermAggregate;
|
TIntermAggregate* linkage = new TIntermAggregate;
|
||||||
for (auto i = linkageSymbols.begin(); i != linkageSymbols.end(); ++i)
|
for (auto i = linkageSymbols.begin(); i != linkageSymbols.end(); ++i)
|
||||||
intermediate.addSymbolLinkageNode(linkage, **i);
|
intermediate.addSymbolLinkageNode(linkage, **i);
|
||||||
|
@ -187,7 +187,7 @@ protected:
|
|||||||
TParseContextBase& operator=(TParseContextBase&);
|
TParseContextBase& operator=(TParseContextBase&);
|
||||||
|
|
||||||
const bool parsingBuiltins; // true if parsing built-in symbols/functions
|
const bool parsingBuiltins; // true if parsing built-in symbols/functions
|
||||||
TVector<TSymbol*> linkageSymbols; // these need to be transferred to 'linkage', after all editing is done
|
TVector<TSymbol*> linkageSymbols; // will be transferred to 'linkage', after all editing is done, order preserving
|
||||||
TScanContext* scanContext;
|
TScanContext* scanContext;
|
||||||
TPpContext* ppContext;
|
TPpContext* ppContext;
|
||||||
TBuiltInResource resources;
|
TBuiltInResource resources;
|
||||||
|
@ -768,6 +768,8 @@ bool ProcessDeferred(
|
|||||||
SpvVersion spvVersion;
|
SpvVersion spvVersion;
|
||||||
EShLanguage stage = compiler->getLanguage();
|
EShLanguage stage = compiler->getLanguage();
|
||||||
TranslateEnvironment(environment, messages, source, stage, spvVersion);
|
TranslateEnvironment(environment, messages, source, stage, spvVersion);
|
||||||
|
if (environment != nullptr && environment->target.hlslFunctionality1)
|
||||||
|
intermediate.setHlslFunctionality1();
|
||||||
|
|
||||||
// First, without using the preprocessor or parser, find the #version, so we know what
|
// First, without using the preprocessor or parser, find the #version, so we know what
|
||||||
// symbol tables, processing rules, etc. to set up. This does not need the extra strings
|
// symbol tables, processing rules, etc. to set up. This does not need the extra strings
|
||||||
@ -1629,6 +1631,7 @@ TShader::TShader(EShLanguage s)
|
|||||||
environment.input.dialect = EShClientNone;
|
environment.input.dialect = EShClientNone;
|
||||||
environment.client.client = EShClientNone;
|
environment.client.client = EShClientNone;
|
||||||
environment.target.language = EShTargetNone;
|
environment.target.language = EShTargetNone;
|
||||||
|
environment.target.hlslFunctionality1 = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TShader::~TShader()
|
TShader::~TShader()
|
||||||
|
@ -210,7 +210,7 @@ class TVariable;
|
|||||||
class TIntermediate {
|
class TIntermediate {
|
||||||
public:
|
public:
|
||||||
explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) :
|
explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) :
|
||||||
implicitThisName("@this"),
|
implicitThisName("@this"), implicitCounterName("@count"),
|
||||||
language(l), source(EShSourceNone), profile(p), version(v), treeRoot(0),
|
language(l), source(EShSourceNone), profile(p), version(v), treeRoot(0),
|
||||||
numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false),
|
numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false),
|
||||||
invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet),
|
invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet),
|
||||||
@ -218,6 +218,7 @@ public:
|
|||||||
pixelCenterInteger(false), originUpperLeft(false),
|
pixelCenterInteger(false), originUpperLeft(false),
|
||||||
vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), earlyFragmentTests(false),
|
vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), earlyFragmentTests(false),
|
||||||
postDepthCoverage(false), depthLayout(EldNone), depthReplacing(false),
|
postDepthCoverage(false), depthLayout(EldNone), depthReplacing(false),
|
||||||
|
hlslFunctionality1(false),
|
||||||
blendEquations(0), xfbMode(false), multiStream(false),
|
blendEquations(0), xfbMode(false), multiStream(false),
|
||||||
#ifdef NV_EXTENSIONS
|
#ifdef NV_EXTENSIONS
|
||||||
layoutOverrideCoverage(false),
|
layoutOverrideCoverage(false),
|
||||||
@ -362,6 +363,13 @@ public:
|
|||||||
}
|
}
|
||||||
bool usingHlslIoMapping() { return hlslIoMapping; }
|
bool usingHlslIoMapping() { return hlslIoMapping; }
|
||||||
|
|
||||||
|
template<class T> T addCounterBufferName(const T& name) const { return name + implicitCounterName; }
|
||||||
|
bool hasCounterBufferName(const TString& name) const {
|
||||||
|
size_t len = strlen(implicitCounterName);
|
||||||
|
return name.size() > len &&
|
||||||
|
name.compare(name.size() - len, len, implicitCounterName) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; }
|
void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; }
|
||||||
|
|
||||||
void setVersion(int v) { version = v; }
|
void setVersion(int v) { version = v; }
|
||||||
@ -564,6 +572,9 @@ public:
|
|||||||
void setDepthReplacing() { depthReplacing = true; }
|
void setDepthReplacing() { depthReplacing = true; }
|
||||||
bool isDepthReplacing() const { return depthReplacing; }
|
bool isDepthReplacing() const { return depthReplacing; }
|
||||||
|
|
||||||
|
void setHlslFunctionality1() { hlslFunctionality1 = true; }
|
||||||
|
bool getHlslFunctionality1() const { return hlslFunctionality1; }
|
||||||
|
|
||||||
void addBlendEquation(TBlendEquationShift b) { blendEquations |= (1 << b); }
|
void addBlendEquation(TBlendEquationShift b) { blendEquations |= (1 << b); }
|
||||||
unsigned int getBlendEquations() const { return blendEquations; }
|
unsigned int getBlendEquations() const { return blendEquations; }
|
||||||
|
|
||||||
@ -623,6 +634,7 @@ public:
|
|||||||
bool needsLegalization() const { return needToLegalize; }
|
bool needsLegalization() const { return needToLegalize; }
|
||||||
|
|
||||||
const char* const implicitThisName;
|
const char* const implicitThisName;
|
||||||
|
const char* const implicitCounterName;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
|
TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
|
||||||
@ -682,6 +694,7 @@ protected:
|
|||||||
bool postDepthCoverage;
|
bool postDepthCoverage;
|
||||||
TLayoutDepth depthLayout;
|
TLayoutDepth depthLayout;
|
||||||
bool depthReplacing;
|
bool depthReplacing;
|
||||||
|
bool hlslFunctionality1;
|
||||||
int blendEquations; // an 'or'ing of masks of shifts of TBlendEquationShift
|
int blendEquations; // an 'or'ing of masks of shifts of TBlendEquationShift
|
||||||
bool xfbMode;
|
bool xfbMode;
|
||||||
bool multiStream;
|
bool multiStream;
|
||||||
|
@ -766,11 +766,11 @@ void TReflection::buildAttributeReflection(EShLanguage stage, const TIntermediat
|
|||||||
}
|
}
|
||||||
|
|
||||||
// build counter block index associations for buffers
|
// build counter block index associations for buffers
|
||||||
void TReflection::buildCounterIndices()
|
void TReflection::buildCounterIndices(const TIntermediate& intermediate)
|
||||||
{
|
{
|
||||||
// search for ones that have counters
|
// search for ones that have counters
|
||||||
for (int i = 0; i < int(indexToUniformBlock.size()); ++i) {
|
for (int i = 0; i < int(indexToUniformBlock.size()); ++i) {
|
||||||
const TString counterName(indexToUniformBlock[i].name + "@count");
|
const TString counterName(intermediate.addCounterBufferName(indexToUniformBlock[i].name));
|
||||||
const int index = getIndex(counterName);
|
const int index = getIndex(counterName);
|
||||||
|
|
||||||
if (index >= 0)
|
if (index >= 0)
|
||||||
@ -802,7 +802,7 @@ bool TReflection::addStage(EShLanguage stage, const TIntermediate& intermediate)
|
|||||||
function->traverse(&it);
|
function->traverse(&it);
|
||||||
}
|
}
|
||||||
|
|
||||||
buildCounterIndices();
|
buildCounterIndices(intermediate);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -156,7 +156,7 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
friend class glslang::TReflectionTraverser;
|
friend class glslang::TReflectionTraverser;
|
||||||
|
|
||||||
void buildCounterIndices();
|
void buildCounterIndices(const TIntermediate&);
|
||||||
void buildAttributeReflection(EShLanguage, const TIntermediate&);
|
void buildAttributeReflection(EShLanguage, const TIntermediate&);
|
||||||
|
|
||||||
// Need a TString hash: typedef std::unordered_map<TString, int> TNameToIndex;
|
// Need a TString hash: typedef std::unordered_map<TString, int> TNameToIndex;
|
||||||
|
@ -70,7 +70,7 @@
|
|||||||
// This should always increase, as some paths to do not consume
|
// This should always increase, as some paths to do not consume
|
||||||
// a more major number.
|
// a more major number.
|
||||||
// It should increment by one when new functionality is added.
|
// It should increment by one when new functionality is added.
|
||||||
#define GLSLANG_MINOR_VERSION 4
|
#define GLSLANG_MINOR_VERSION 5
|
||||||
|
|
||||||
//
|
//
|
||||||
// Call before doing any other compiler/linker operations.
|
// Call before doing any other compiler/linker operations.
|
||||||
@ -154,6 +154,7 @@ struct TClient {
|
|||||||
struct TTarget {
|
struct TTarget {
|
||||||
EShTargetLanguage language;
|
EShTargetLanguage language;
|
||||||
EShTargetLanguageVersion version; // version to target, if SPIR-V, defined by "word 1" of the SPIR-V header
|
EShTargetLanguageVersion version; // version to target, if SPIR-V, defined by "word 1" of the SPIR-V header
|
||||||
|
bool hlslFunctionality1; // can target hlsl_functionality1 extension(s)
|
||||||
};
|
};
|
||||||
|
|
||||||
// All source/client/target versions and settings.
|
// All source/client/target versions and settings.
|
||||||
@ -420,6 +421,8 @@ public:
|
|||||||
environment.target.language = lang;
|
environment.target.language = lang;
|
||||||
environment.target.version = version;
|
environment.target.version = version;
|
||||||
}
|
}
|
||||||
|
void setEnvTargetHlslFunctionality1() { environment.target.hlslFunctionality1 = true; }
|
||||||
|
bool getEnvTargetHlslFunctionality1() const { return environment.target.hlslFunctionality1; }
|
||||||
|
|
||||||
// Interface to #include handlers.
|
// Interface to #include handlers.
|
||||||
//
|
//
|
||||||
|
@ -1608,7 +1608,7 @@ void HlslParseContext::addStructBufferHiddenCounterParam(const TSourceLoc& loc,
|
|||||||
if (! hasStructBuffCounter(*param.type))
|
if (! hasStructBuffCounter(*param.type))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const TString counterBlockName(getStructBuffCounterName(*param.name));
|
const TString counterBlockName(intermediate.addCounterBufferName(*param.name));
|
||||||
|
|
||||||
TType counterType;
|
TType counterType;
|
||||||
counterBufferType(loc, counterType);
|
counterBufferType(loc, counterType);
|
||||||
@ -3163,7 +3163,7 @@ void HlslParseContext::counterBufferType(const TSourceLoc& loc, TType& type)
|
|||||||
{
|
{
|
||||||
// Counter type
|
// Counter type
|
||||||
TType* counterType = new TType(EbtInt, EvqBuffer);
|
TType* counterType = new TType(EbtInt, EvqBuffer);
|
||||||
counterType->setFieldName("@count");
|
counterType->setFieldName(intermediate.implicitCounterName);
|
||||||
|
|
||||||
TTypeList* blockStruct = new TTypeList;
|
TTypeList* blockStruct = new TTypeList;
|
||||||
TTypeLoc member = { counterType, loc };
|
TTypeLoc member = { counterType, loc };
|
||||||
@ -3176,12 +3176,6 @@ void HlslParseContext::counterBufferType(const TSourceLoc& loc, TType& type)
|
|||||||
shareStructBufferType(type);
|
shareStructBufferType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// knowledge of how to construct block name, in one place instead of N places.
|
|
||||||
TString HlslParseContext::getStructBuffCounterName(const TString& blockName) const
|
|
||||||
{
|
|
||||||
return blockName + "@count";
|
|
||||||
}
|
|
||||||
|
|
||||||
// declare counter for a structured buffer type
|
// declare counter for a structured buffer type
|
||||||
void HlslParseContext::declareStructBufferCounter(const TSourceLoc& loc, const TType& bufferType, const TString& name)
|
void HlslParseContext::declareStructBufferCounter(const TSourceLoc& loc, const TType& bufferType, const TString& name)
|
||||||
{
|
{
|
||||||
@ -3195,9 +3189,9 @@ void HlslParseContext::declareStructBufferCounter(const TSourceLoc& loc, const T
|
|||||||
TType blockType;
|
TType blockType;
|
||||||
counterBufferType(loc, blockType);
|
counterBufferType(loc, blockType);
|
||||||
|
|
||||||
TString* blockName = new TString(getStructBuffCounterName(name));
|
TString* blockName = new TString(intermediate.addCounterBufferName(name));
|
||||||
|
|
||||||
// Counter buffer does not have its own counter buffer. TODO: there should be a better way to track this.
|
// Counter buffer is not yet in use
|
||||||
structBufferCounter[*blockName] = false;
|
structBufferCounter[*blockName] = false;
|
||||||
|
|
||||||
shareStructBufferType(blockType);
|
shareStructBufferType(blockType);
|
||||||
@ -3211,7 +3205,7 @@ TIntermTyped* HlslParseContext::getStructBufferCounter(const TSourceLoc& loc, TI
|
|||||||
if (buffer == nullptr || ! isStructBufferType(buffer->getType()))
|
if (buffer == nullptr || ! isStructBufferType(buffer->getType()))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
const TString counterBlockName(getStructBuffCounterName(buffer->getAsSymbolNode()->getName()));
|
const TString counterBlockName(intermediate.addCounterBufferName(buffer->getAsSymbolNode()->getName()));
|
||||||
|
|
||||||
// Mark the counter as being used
|
// Mark the counter as being used
|
||||||
structBufferCounter[counterBlockName] = true;
|
structBufferCounter[counterBlockName] = true;
|
||||||
@ -3224,7 +3218,6 @@ TIntermTyped* HlslParseContext::getStructBufferCounter(const TSourceLoc& loc, TI
|
|||||||
return counterMember;
|
return counterMember;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Decompose structure buffer methods into AST
|
// Decompose structure buffer methods into AST
|
||||||
//
|
//
|
||||||
@ -5743,12 +5736,11 @@ void HlslParseContext::addStructBuffArguments(const TSourceLoc& loc, TIntermAggr
|
|||||||
TType counterType;
|
TType counterType;
|
||||||
counterBufferType(loc, counterType);
|
counterBufferType(loc, counterType);
|
||||||
|
|
||||||
const TString counterBlockName(getStructBuffCounterName(blockSym->getName()));
|
const TString counterBlockName(intermediate.addCounterBufferName(blockSym->getName()));
|
||||||
|
|
||||||
TVariable* variable = makeInternalVariable(counterBlockName, counterType);
|
TVariable* variable = makeInternalVariable(counterBlockName, counterType);
|
||||||
|
|
||||||
// Mark this buffer as requiring a counter block. TODO: there should be a better
|
// Mark this buffer's counter block as being in use
|
||||||
// way to track it.
|
|
||||||
structBufferCounter[counterBlockName] = true;
|
structBufferCounter[counterBlockName] = true;
|
||||||
|
|
||||||
TIntermSymbol* sym = intermediate.addSymbol(*variable, loc);
|
TIntermSymbol* sym = intermediate.addSymbol(*variable, loc);
|
||||||
@ -9944,7 +9936,8 @@ void HlslParseContext::addPatchConstantInvocation()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Finalization step: remove unused buffer blocks from linkage (we don't know until the
|
// Finalization step: remove unused buffer blocks from linkage (we don't know until the
|
||||||
// shader is entirely compiled)
|
// shader is entirely compiled).
|
||||||
|
// Preserve order of remaining symbols.
|
||||||
void HlslParseContext::removeUnusedStructBufferCounters()
|
void HlslParseContext::removeUnusedStructBufferCounters()
|
||||||
{
|
{
|
||||||
const auto endIt = std::remove_if(linkageSymbols.begin(), linkageSymbols.end(),
|
const auto endIt = std::remove_if(linkageSymbols.begin(), linkageSymbols.end(),
|
||||||
|
@ -405,7 +405,7 @@ protected:
|
|||||||
// may fit in TSampler::structReturnIndex.
|
// may fit in TSampler::structReturnIndex.
|
||||||
TVector<TTypeList*> textureReturnStruct;
|
TVector<TTypeList*> textureReturnStruct;
|
||||||
|
|
||||||
TMap<TString, bool> structBufferCounter;
|
TMap<TString, bool> structBufferCounter; // true if counter buffer is in use
|
||||||
|
|
||||||
// The built-in interstage IO map considers e.g, EvqPosition on input and output separately, so that we
|
// The built-in interstage IO map considers e.g, EvqPosition on input and output separately, so that we
|
||||||
// can build the linkage correctly if position appears on both sides. Otherwise, multiple positions
|
// can build the linkage correctly if position appears on both sides. Otherwise, multiple positions
|
||||||
|
Loading…
x
Reference in New Issue
Block a user