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);
|
||||
|
||||
protected:
|
||||
TGlslangToSpvTraverser(TGlslangToSpvTraverser&);
|
||||
TGlslangToSpvTraverser& operator=(TGlslangToSpvTraverser&);
|
||||
|
||||
spv::Decoration TranslateInterpolationDecoration(const glslang::TQualifier& qualifier);
|
||||
spv::Decoration TranslateAuxiliaryStorageDecoration(const glslang::TQualifier& qualifier);
|
||||
spv::BuiltIn TranslateBuiltInDecoration(glslang::TBuiltInVariable, bool memberDeclaration);
|
||||
@ -153,7 +156,8 @@ protected:
|
||||
glslang::TLayoutPacking getExplicitLayout(const glslang::TType& type) const;
|
||||
int getArrayStride(const glslang::TType& arrayType, 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);
|
||||
|
||||
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 createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId);
|
||||
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 createSpvConstantFromConstUnionArray(const glslang::TType& type, const glslang::TConstUnionArray&, int& nextConst, bool specConstant);
|
||||
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_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*, 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::unordered_map<std::string, const glslang::TIntermSymbol*> counterOriginator;
|
||||
};
|
||||
|
||||
//
|
||||
@ -1195,6 +1197,36 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol)
|
||||
else
|
||||
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)
|
||||
@ -2709,89 +2741,102 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
|
||||
InheritQualifiers(memberQualifier, qualifier);
|
||||
|
||||
// using -1 above to indicate a hidden member
|
||||
if (member >= 0) {
|
||||
builder.addMemberName(spvType, member, glslangMember.getFieldName().c_str());
|
||||
addMemberDecoration(spvType, member, TranslateLayoutDecoration(glslangMember, memberQualifier.layoutMatrix));
|
||||
addMemberDecoration(spvType, member, TranslatePrecisionDecoration(glslangMember));
|
||||
// Add interpolation and auxiliary storage decorations only to top-level members of Input and Output storage classes
|
||||
if (type.getQualifier().storage == glslang::EvqVaryingIn ||
|
||||
type.getQualifier().storage == glslang::EvqVaryingOut) {
|
||||
if (type.getBasicType() == glslang::EbtBlock ||
|
||||
glslangIntermediate->getSource() == glslang::EShSourceHlsl) {
|
||||
addMemberDecoration(spvType, member, TranslateInterpolationDecoration(memberQualifier));
|
||||
addMemberDecoration(spvType, member, TranslateAuxiliaryStorageDecoration(memberQualifier));
|
||||
}
|
||||
if (member < 0)
|
||||
continue;
|
||||
|
||||
builder.addMemberName(spvType, member, glslangMember.getFieldName().c_str());
|
||||
builder.addMemberDecoration(spvType, member,
|
||||
TranslateLayoutDecoration(glslangMember, memberQualifier.layoutMatrix));
|
||||
builder.addMemberDecoration(spvType, member, TranslatePrecisionDecoration(glslangMember));
|
||||
// Add interpolation and auxiliary storage decorations only to
|
||||
// top-level members of Input and Output storage classes
|
||||
if (type.getQualifier().storage == glslang::EvqVaryingIn ||
|
||||
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 &&
|
||||
qualifier.storage == glslang::EvqBuffer) {
|
||||
// Add memory decorations only to top-level members of shader storage block
|
||||
std::vector<spv::Decoration> memory;
|
||||
TranslateMemoryDecoration(memberQualifier, memory);
|
||||
for (unsigned int i = 0; i < memory.size(); ++i)
|
||||
addMemberDecoration(spvType, member, memory[i]);
|
||||
}
|
||||
if (type.getBasicType() == glslang::EbtBlock &&
|
||||
qualifier.storage == glslang::EvqBuffer) {
|
||||
// Add memory decorations only to top-level members of shader storage block
|
||||
std::vector<spv::Decoration> memory;
|
||||
TranslateMemoryDecoration(memberQualifier, memory);
|
||||
for (unsigned int i = 0; i < memory.size(); ++i)
|
||||
builder.addMemberDecoration(spvType, member, memory[i]);
|
||||
}
|
||||
|
||||
// Location assignment was already completed correctly by the front end,
|
||||
// just track whether a member needs to be decorated.
|
||||
// Ignore member locations if the container is an array, as that's
|
||||
// ill-specified and decisions have been made to not allow this.
|
||||
if (! type.isArray() && memberQualifier.hasLocation())
|
||||
builder.addMemberDecoration(spvType, member, spv::DecorationLocation, memberQualifier.layoutLocation);
|
||||
// Location assignment was already completed correctly by the front end,
|
||||
// just track whether a member needs to be decorated.
|
||||
// Ignore member locations if the container is an array, as that's
|
||||
// ill-specified and decisions have been made to not allow this.
|
||||
if (! type.isArray() && memberQualifier.hasLocation())
|
||||
builder.addMemberDecoration(spvType, member, spv::DecorationLocation, memberQualifier.layoutLocation);
|
||||
|
||||
if (qualifier.hasLocation()) // track for upcoming inheritance
|
||||
locationOffset += glslangIntermediate->computeTypeLocationSize(
|
||||
glslangMember, glslangIntermediate->getStage());
|
||||
if (qualifier.hasLocation()) // track for upcoming inheritance
|
||||
locationOffset += glslangIntermediate->computeTypeLocationSize(
|
||||
glslangMember, glslangIntermediate->getStage());
|
||||
|
||||
// component, XFB, others
|
||||
if (glslangMember.getQualifier().hasComponent())
|
||||
builder.addMemberDecoration(spvType, member, spv::DecorationComponent, glslangMember.getQualifier().layoutComponent);
|
||||
if (glslangMember.getQualifier().hasXfbOffset())
|
||||
builder.addMemberDecoration(spvType, member, spv::DecorationOffset, glslangMember.getQualifier().layoutXfbOffset);
|
||||
else if (explicitLayout != glslang::ElpNone) {
|
||||
// figure out what to do with offset, which is accumulating
|
||||
int nextOffset;
|
||||
updateMemberOffset(type, glslangMember, offset, nextOffset, explicitLayout, memberQualifier.layoutMatrix);
|
||||
if (offset >= 0)
|
||||
builder.addMemberDecoration(spvType, member, spv::DecorationOffset, offset);
|
||||
offset = nextOffset;
|
||||
}
|
||||
// component, XFB, others
|
||||
if (glslangMember.getQualifier().hasComponent())
|
||||
builder.addMemberDecoration(spvType, member, spv::DecorationComponent,
|
||||
glslangMember.getQualifier().layoutComponent);
|
||||
if (glslangMember.getQualifier().hasXfbOffset())
|
||||
builder.addMemberDecoration(spvType, member, spv::DecorationOffset,
|
||||
glslangMember.getQualifier().layoutXfbOffset);
|
||||
else if (explicitLayout != glslang::ElpNone) {
|
||||
// figure out what to do with offset, which is accumulating
|
||||
int nextOffset;
|
||||
updateMemberOffset(type, glslangMember, offset, nextOffset, explicitLayout, memberQualifier.layoutMatrix);
|
||||
if (offset >= 0)
|
||||
builder.addMemberDecoration(spvType, member, spv::DecorationOffset, offset);
|
||||
offset = nextOffset;
|
||||
}
|
||||
|
||||
if (glslangMember.isMatrix() && explicitLayout != glslang::ElpNone)
|
||||
builder.addMemberDecoration(spvType, member, spv::DecorationMatrixStride, getMatrixStride(glslangMember, explicitLayout, memberQualifier.layoutMatrix));
|
||||
if (glslangMember.isMatrix() && explicitLayout != glslang::ElpNone)
|
||||
builder.addMemberDecoration(spvType, member, spv::DecorationMatrixStride,
|
||||
getMatrixStride(glslangMember, explicitLayout, memberQualifier.layoutMatrix));
|
||||
|
||||
// built-in variable decorations
|
||||
spv::BuiltIn builtIn = TranslateBuiltInDecoration(glslangMember.getQualifier().builtIn, true);
|
||||
if (builtIn != spv::BuiltInMax)
|
||||
addMemberDecoration(spvType, member, spv::DecorationBuiltIn, (int)builtIn);
|
||||
// built-in variable decorations
|
||||
spv::BuiltIn builtIn = TranslateBuiltInDecoration(glslangMember.getQualifier().builtIn, true);
|
||||
if (builtIn != spv::BuiltInMax)
|
||||
builder.addMemberDecoration(spvType, member, spv::DecorationBuiltIn, (int)builtIn);
|
||||
|
||||
#ifdef NV_EXTENSIONS
|
||||
if (builtIn == spv::BuiltInLayer) {
|
||||
// SPV_NV_viewport_array2 extension
|
||||
if (glslangMember.getQualifier().layoutViewportRelative){
|
||||
addMemberDecoration(spvType, member, (spv::Decoration)spv::DecorationViewportRelativeNV);
|
||||
builder.addCapability(spv::CapabilityShaderViewportMaskNV);
|
||||
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 (builtIn == spv::BuiltInLayer) {
|
||||
// SPV_NV_viewport_array2 extension
|
||||
if (glslangMember.getQualifier().layoutViewportRelative){
|
||||
builder.addMemberDecoration(spvType, member, (spv::Decoration)spv::DecorationViewportRelativeNV);
|
||||
builder.addCapability(spv::CapabilityShaderViewportMaskNV);
|
||||
builder.addExtension(spv::E_SPV_NV_viewport_array2);
|
||||
}
|
||||
if (glslangMember.getQualifier().layoutPassthrough) {
|
||||
addMemberDecoration(spvType, member, (spv::Decoration)spv::DecorationPassthroughNV);
|
||||
builder.addCapability(spv::CapabilityGeometryShaderPassthroughNV);
|
||||
builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough);
|
||||
if (glslangMember.getQualifier().layoutSecondaryViewportRelativeOffset != -2048){
|
||||
builder.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) {
|
||||
builder.addMemberDecoration(spvType, member, (spv::Decoration)spv::DecorationPassthroughNV);
|
||||
builder.addCapability(spv::CapabilityGeometryShaderPassthroughNV);
|
||||
builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough);
|
||||
}
|
||||
#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
|
||||
addDecoration(spvType, TranslateLayoutDecoration(type, qualifier.layoutMatrix));
|
||||
addDecoration(spvType, TranslateBlockDecoration(type, glslangIntermediate->usingStorageBuffer()));
|
||||
builder.addDecoration(spvType, TranslateLayoutDecoration(type, qualifier.layoutMatrix));
|
||||
builder.addDecoration(spvType, TranslateBlockDecoration(type, glslangIntermediate->usingStorageBuffer()));
|
||||
if (type.getQualifier().hasStream() && glslangIntermediate->isMultiStream()) {
|
||||
builder.addCapability(spv::CapabilityGeometryStreams);
|
||||
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);
|
||||
|
||||
spv::Id result = builder.createBinOp(binOp, typeId, left, right);
|
||||
addDecoration(result, noContraction);
|
||||
builder.addDecoration(result, noContraction);
|
||||
return builder.setPrecision(result, precision);
|
||||
}
|
||||
|
||||
@ -4107,7 +4152,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, spv
|
||||
|
||||
if (binOp != spv::OpNop) {
|
||||
spv::Id result = builder.createBinOp(binOp, typeId, left, right);
|
||||
addDecoration(result, noContraction);
|
||||
builder.addDecoration(result, noContraction);
|
||||
return builder.setPrecision(result, precision);
|
||||
}
|
||||
|
||||
@ -4167,7 +4212,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, spv::Dec
|
||||
|
||||
if (firstClass) {
|
||||
spv::Id result = builder.createBinOp(op, typeId, left, right);
|
||||
addDecoration(result, noContraction);
|
||||
builder.addDecoration(result, noContraction);
|
||||
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 rightVec = rightMat ? builder.createCompositeExtract(right, vecType, indexes) : smearVec;
|
||||
spv::Id result = builder.createBinOp(op, vecType, leftVec, rightVec);
|
||||
addDecoration(result, noContraction);
|
||||
builder.addDecoration(result, noContraction);
|
||||
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);
|
||||
}
|
||||
|
||||
addDecoration(id, noContraction);
|
||||
builder.addDecoration(id, noContraction);
|
||||
return builder.setPrecision(id, precision);
|
||||
}
|
||||
|
||||
@ -4638,7 +4683,7 @@ spv::Id TGlslangToSpvTraverser::createUnaryMatrixOperation(spv::Op op, spv::Deco
|
||||
indexes.push_back(c);
|
||||
spv::Id srcVec = builder.createCompositeExtract(operand, srcVecType, indexes);
|
||||
spv::Id destVec = builder.createUnaryOp(op, destVecType, srcVec);
|
||||
addDecoration(destVec, noContraction);
|
||||
builder.addDecoration(destVec, noContraction);
|
||||
results.push_back(builder.setPrecision(destVec, precision));
|
||||
}
|
||||
|
||||
@ -6147,11 +6192,11 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
|
||||
symbolValues[symbol->getId()] = id;
|
||||
|
||||
if (symbol->getBasicType() != glslang::EbtBlock) {
|
||||
addDecoration(id, TranslatePrecisionDecoration(symbol->getType()));
|
||||
addDecoration(id, TranslateInterpolationDecoration(symbol->getType().getQualifier()));
|
||||
addDecoration(id, TranslateAuxiliaryStorageDecoration(symbol->getType().getQualifier()));
|
||||
builder.addDecoration(id, TranslatePrecisionDecoration(symbol->getType()));
|
||||
builder.addDecoration(id, TranslateInterpolationDecoration(symbol->getType().getQualifier()));
|
||||
builder.addDecoration(id, TranslateAuxiliaryStorageDecoration(symbol->getType().getQualifier()));
|
||||
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())
|
||||
builder.addDecoration(id, spv::DecorationIndex, symbol->getQualifier().layoutIndex);
|
||||
if (symbol->getQualifier().hasComponent())
|
||||
@ -6163,7 +6208,7 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
|
||||
|
||||
if (symbol->getQualifier().hasLocation())
|
||||
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()) {
|
||||
builder.addCapability(spv::CapabilityGeometryStreams);
|
||||
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;
|
||||
TranslateMemoryDecoration(symbol->getType().getQualifier(), memory);
|
||||
for (unsigned int i = 0; i < memory.size(); ++i)
|
||||
addDecoration(id, memory[i]);
|
||||
builder.addDecoration(id, memory[i]);
|
||||
}
|
||||
|
||||
// built-in variable decorations
|
||||
spv::BuiltIn builtIn = TranslateBuiltInDecoration(symbol->getQualifier().builtIn, false);
|
||||
if (builtIn != spv::BuiltInMax)
|
||||
addDecoration(id, spv::DecorationBuiltIn, (int)builtIn);
|
||||
builder.addDecoration(id, spv::DecorationBuiltIn, (int)builtIn);
|
||||
|
||||
#ifdef NV_EXTENSIONS
|
||||
if (builtIn == spv::BuiltInSampleMask) {
|
||||
@ -6212,7 +6257,7 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
|
||||
decoration = (spv::Decoration)spv::DecorationOverrideCoverageNV;
|
||||
else
|
||||
decoration = (spv::Decoration)spv::DecorationMax;
|
||||
addDecoration(id, decoration);
|
||||
builder.addDecoration(id, decoration);
|
||||
if (decoration != spv::DecorationMax) {
|
||||
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) {
|
||||
// SPV_NV_viewport_array2 extension
|
||||
if (symbol->getQualifier().layoutViewportRelative) {
|
||||
addDecoration(id, (spv::Decoration)spv::DecorationViewportRelativeNV);
|
||||
builder.addDecoration(id, (spv::Decoration)spv::DecorationViewportRelativeNV);
|
||||
builder.addCapability(spv::CapabilityShaderViewportMaskNV);
|
||||
builder.addExtension(spv::E_SPV_NV_viewport_array2);
|
||||
}
|
||||
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.addExtension(spv::E_SPV_NV_stereo_view_rendering);
|
||||
}
|
||||
}
|
||||
|
||||
if (symbol->getQualifier().layoutPassthrough) {
|
||||
addDecoration(id, spv::DecorationPassthroughNV);
|
||||
builder.addDecoration(id, spv::DecorationPassthroughNV);
|
||||
builder.addCapability(spv::CapabilityGeometryShaderPassthroughNV);
|
||||
builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough);
|
||||
}
|
||||
#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;
|
||||
}
|
||||
|
||||
// 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,
|
||||
// or regular constant if possible.
|
||||
//
|
||||
@ -6301,8 +6325,10 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TIntermTyped& n
|
||||
for (int dim = 0; dim < 3; ++dim) {
|
||||
bool specConst = (glslangIntermediate->getLocalSizeSpecId(dim) != glslang::TQualifier::layoutNotSet);
|
||||
dimConstId.push_back(builder.makeUintConstant(glslangIntermediate->getLocalSize(dim), specConst));
|
||||
if (specConst)
|
||||
addDecoration(dimConstId.back(), spv::DecorationSpecId, glslangIntermediate->getLocalSizeSpecId(dim));
|
||||
if (specConst) {
|
||||
builder.addDecoration(dimConstId.back(), spv::DecorationSpecId,
|
||||
glslangIntermediate->getLocalSizeSpecId(dim));
|
||||
}
|
||||
}
|
||||
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)
|
||||
return;
|
||||
|
||||
Instruction* dec = new Instruction(OpDecorate);
|
||||
dec->addIdOperand(id);
|
||||
dec->addImmediateOperand(decoration);
|
||||
@ -1019,8 +1020,37 @@ void Builder::addDecoration(Id id, Decoration decoration, int num)
|
||||
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)
|
||||
{
|
||||
if (decoration == spv::DecorationMax)
|
||||
return;
|
||||
|
||||
Instruction* dec = new Instruction(OpMemberDecorate);
|
||||
dec->addIdOperand(id);
|
||||
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));
|
||||
}
|
||||
|
||||
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
|
||||
Function* Builder::makeEntryPoint(const char* entryPoint)
|
||||
{
|
||||
|
@ -237,7 +237,10 @@ public:
|
||||
void addName(Id, const char* name);
|
||||
void addMemberName(Id, int member, const char* name);
|
||||
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, const char*);
|
||||
|
||||
// At the end of what block do the next create*() instructions go?
|
||||
void setBuildPoint(Block* bp) { buildPoint = bp; }
|
||||
|
@ -269,6 +269,9 @@ const char* DecorationString(int decoration)
|
||||
case 5252: return "ViewportRelativeNV";
|
||||
case 5256: return "SecondaryViewportRelativeNV";
|
||||
#endif
|
||||
|
||||
case DecorationHlslCounterBufferGOOGLE: return "DecorationHlslCounterBufferGOOGLE";
|
||||
case DecorationHlslSemanticGOOGLE: return "DecorationHlslSemanticGOOGLE";
|
||||
}
|
||||
}
|
||||
|
||||
@ -1208,6 +1211,7 @@ const char* OpcodeString(int op)
|
||||
case 320: return "OpImageSparseRead";
|
||||
|
||||
case OpModuleProcessed: return "OpModuleProcessed";
|
||||
case OpDecorateId: return "OpDecorateId";
|
||||
|
||||
case 333: return "OpGroupNonUniformElect";
|
||||
case 334: return "OpGroupNonUniformAll";
|
||||
@ -1265,6 +1269,9 @@ const char* OpcodeString(int op)
|
||||
case 5012: return "OpFragmentFetchAMD";
|
||||
#endif
|
||||
|
||||
case OpDecorateStringGOOGLE: return "OpDecorateStringGOOGLE";
|
||||
case OpMemberDecorateStringGOOGLE: return "OpMemberDecorateStringGOOGLE";
|
||||
|
||||
case OpcodeCeiling:
|
||||
default:
|
||||
return "Bad";
|
||||
@ -1356,7 +1363,10 @@ void Parameterize()
|
||||
InstructionDesc[OpImageWrite].setResultAndType(false, false);
|
||||
InstructionDesc[OpDecorationGroup].setResultAndType(true, false);
|
||||
InstructionDesc[OpDecorate].setResultAndType(false, false);
|
||||
InstructionDesc[OpDecorateId].setResultAndType(false, false);
|
||||
InstructionDesc[OpDecorateStringGOOGLE].setResultAndType(false, false);
|
||||
InstructionDesc[OpMemberDecorate].setResultAndType(false, false);
|
||||
InstructionDesc[OpMemberDecorateStringGOOGLE].setResultAndType(false, false);
|
||||
InstructionDesc[OpGroupDecorate].setResultAndType(false, false);
|
||||
InstructionDesc[OpGroupMemberDecorate].setResultAndType(false, false);
|
||||
InstructionDesc[OpName].setResultAndType(false, false);
|
||||
@ -1921,11 +1931,24 @@ void Parameterize()
|
||||
InstructionDesc[OpDecorate].operands.push(OperandDecoration, "");
|
||||
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(OperandLiteralNumber, "'Member'");
|
||||
InstructionDesc[OpMemberDecorate].operands.push(OperandDecoration, "");
|
||||
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(OperandVariableIds, "'Targets'");
|
||||
|
||||
|
@ -101,6 +101,7 @@ enum TOptions {
|
||||
EOptionInvertY = (1 << 30),
|
||||
EOptionDumpBareVersion = (1 << 31),
|
||||
};
|
||||
bool targetHlslFunctionality1 = false;
|
||||
|
||||
//
|
||||
// Return codes from main/exit().
|
||||
@ -523,7 +524,7 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
|
||||
setOpenGlSpv();
|
||||
OpenGLClientVersion = glslang::EShTargetOpenGL_450;
|
||||
} else
|
||||
Error("--target-env expected vulkan1.0, opengl, or hlsl-16bit-types");
|
||||
Error("--target-env expected vulkan1.0, vulkan1.1, or opengl");
|
||||
}
|
||||
bumpArg();
|
||||
} 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");
|
||||
bumpArg();
|
||||
break;
|
||||
case 'f':
|
||||
if (strcmp(&argv[0][2], "hlsl_functionality1") == 0)
|
||||
targetHlslFunctionality1 = true;
|
||||
else
|
||||
Error("-f: expected hlsl_functionality1");
|
||||
break;
|
||||
case 'g':
|
||||
Options |= EOptionDebug;
|
||||
break;
|
||||
@ -874,14 +881,15 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
|
||||
: glslang::EShSourceGlsl,
|
||||
compUnit.stage, glslang::EShClientVulkan, ClientInputSemanticsVersion);
|
||||
shader->setEnvClient(glslang::EShClientVulkan, VulkanClientVersion);
|
||||
shader->setEnvTarget(glslang::EShTargetSpv, TargetVersion);
|
||||
} else {
|
||||
shader->setEnvInput((Options & EOptionReadHlsl) ? glslang::EShSourceHlsl
|
||||
: glslang::EShSourceGlsl,
|
||||
compUnit.stage, glslang::EShClientOpenGL, ClientInputSemanticsVersion);
|
||||
shader->setEnvClient(glslang::EShClientOpenGL, OpenGLClientVersion);
|
||||
shader->setEnvTarget(glslang::EshTargetSpv, TargetVersion);
|
||||
}
|
||||
shader->setEnvTarget(glslang::EShTargetSpv, TargetVersion);
|
||||
if (targetHlslFunctionality1)
|
||||
shader->setEnvTargetHlslFunctionality1();
|
||||
}
|
||||
|
||||
shaders.push_back(shader);
|
||||
@ -1318,6 +1326,9 @@ void usage()
|
||||
" -d default to desktop (#version 110) when there is no shader #version\n"
|
||||
" (default is ES version 100)\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"
|
||||
" -h print this usage message\n"
|
||||
" -i intermediate tree (glslang AST) is printed out\n"
|
||||
@ -1390,8 +1401,8 @@ void usage()
|
||||
" set execution environment that emitted code\n"
|
||||
" will execute in (as opposed to the language\n"
|
||||
" semantics selected by --client) defaults:\n"
|
||||
" 'vulkan1.0' under '--client vulkan<ver>'\n"
|
||||
" 'opengl' under '--client opengl<ver>'\n"
|
||||
" 'vulkan1.0' under '--client vulkan<ver>'\n"
|
||||
" 'opengl' under '--client opengl<ver>'\n"
|
||||
" --variable-name <name> Creates a C header file that contains a\n"
|
||||
" uint32_t array named <name>\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
|
||||
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
|
||||
#
|
||||
|
@ -228,6 +228,7 @@ void TParseContextBase::rValueErrorCheck(const TSourceLoc& loc, const char* op,
|
||||
// must still be valid.
|
||||
// It is okay if the symbol's type will be subsequently edited;
|
||||
// the modifications will be tracked.
|
||||
// Order is preserved, to avoid creating novel forward references.
|
||||
void TParseContextBase::trackLinkage(TSymbol& symbol)
|
||||
{
|
||||
if (!parsingBuiltins)
|
||||
@ -602,7 +603,7 @@ void TParseContextBase::finish()
|
||||
if (parsingBuiltins)
|
||||
return;
|
||||
|
||||
// Transfer the linkage symbols to AST nodes
|
||||
// Transfer the linkage symbols to AST nodes, preserving order.
|
||||
TIntermAggregate* linkage = new TIntermAggregate;
|
||||
for (auto i = linkageSymbols.begin(); i != linkageSymbols.end(); ++i)
|
||||
intermediate.addSymbolLinkageNode(linkage, **i);
|
||||
|
@ -187,7 +187,7 @@ protected:
|
||||
TParseContextBase& operator=(TParseContextBase&);
|
||||
|
||||
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;
|
||||
TPpContext* ppContext;
|
||||
TBuiltInResource resources;
|
||||
|
@ -768,6 +768,8 @@ bool ProcessDeferred(
|
||||
SpvVersion spvVersion;
|
||||
EShLanguage stage = compiler->getLanguage();
|
||||
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
|
||||
// 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.client.client = EShClientNone;
|
||||
environment.target.language = EShTargetNone;
|
||||
environment.target.hlslFunctionality1 = false;
|
||||
}
|
||||
|
||||
TShader::~TShader()
|
||||
|
@ -210,7 +210,7 @@ class TVariable;
|
||||
class TIntermediate {
|
||||
public:
|
||||
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),
|
||||
numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false),
|
||||
invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet),
|
||||
@ -218,6 +218,7 @@ public:
|
||||
pixelCenterInteger(false), originUpperLeft(false),
|
||||
vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), earlyFragmentTests(false),
|
||||
postDepthCoverage(false), depthLayout(EldNone), depthReplacing(false),
|
||||
hlslFunctionality1(false),
|
||||
blendEquations(0), xfbMode(false), multiStream(false),
|
||||
#ifdef NV_EXTENSIONS
|
||||
layoutOverrideCoverage(false),
|
||||
@ -362,6 +363,13 @@ public:
|
||||
}
|
||||
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 setVersion(int v) { version = v; }
|
||||
@ -564,6 +572,9 @@ public:
|
||||
void setDepthReplacing() { depthReplacing = true; }
|
||||
bool isDepthReplacing() const { return depthReplacing; }
|
||||
|
||||
void setHlslFunctionality1() { hlslFunctionality1 = true; }
|
||||
bool getHlslFunctionality1() const { return hlslFunctionality1; }
|
||||
|
||||
void addBlendEquation(TBlendEquationShift b) { blendEquations |= (1 << b); }
|
||||
unsigned int getBlendEquations() const { return blendEquations; }
|
||||
|
||||
@ -623,6 +634,7 @@ public:
|
||||
bool needsLegalization() const { return needToLegalize; }
|
||||
|
||||
const char* const implicitThisName;
|
||||
const char* const implicitCounterName;
|
||||
|
||||
protected:
|
||||
TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
|
||||
@ -682,6 +694,7 @@ protected:
|
||||
bool postDepthCoverage;
|
||||
TLayoutDepth depthLayout;
|
||||
bool depthReplacing;
|
||||
bool hlslFunctionality1;
|
||||
int blendEquations; // an 'or'ing of masks of shifts of TBlendEquationShift
|
||||
bool xfbMode;
|
||||
bool multiStream;
|
||||
|
@ -766,11 +766,11 @@ void TReflection::buildAttributeReflection(EShLanguage stage, const TIntermediat
|
||||
}
|
||||
|
||||
// build counter block index associations for buffers
|
||||
void TReflection::buildCounterIndices()
|
||||
void TReflection::buildCounterIndices(const TIntermediate& intermediate)
|
||||
{
|
||||
// search for ones that have counters
|
||||
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);
|
||||
|
||||
if (index >= 0)
|
||||
@ -802,7 +802,7 @@ bool TReflection::addStage(EShLanguage stage, const TIntermediate& intermediate)
|
||||
function->traverse(&it);
|
||||
}
|
||||
|
||||
buildCounterIndices();
|
||||
buildCounterIndices(intermediate);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ public:
|
||||
protected:
|
||||
friend class glslang::TReflectionTraverser;
|
||||
|
||||
void buildCounterIndices();
|
||||
void buildCounterIndices(const TIntermediate&);
|
||||
void buildAttributeReflection(EShLanguage, const TIntermediate&);
|
||||
|
||||
// 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
|
||||
// a more major number.
|
||||
// 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.
|
||||
@ -154,6 +154,7 @@ struct TClient {
|
||||
struct TTarget {
|
||||
EShTargetLanguage language;
|
||||
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.
|
||||
@ -420,6 +421,8 @@ public:
|
||||
environment.target.language = lang;
|
||||
environment.target.version = version;
|
||||
}
|
||||
void setEnvTargetHlslFunctionality1() { environment.target.hlslFunctionality1 = true; }
|
||||
bool getEnvTargetHlslFunctionality1() const { return environment.target.hlslFunctionality1; }
|
||||
|
||||
// Interface to #include handlers.
|
||||
//
|
||||
|
@ -1608,7 +1608,7 @@ void HlslParseContext::addStructBufferHiddenCounterParam(const TSourceLoc& loc,
|
||||
if (! hasStructBuffCounter(*param.type))
|
||||
return;
|
||||
|
||||
const TString counterBlockName(getStructBuffCounterName(*param.name));
|
||||
const TString counterBlockName(intermediate.addCounterBufferName(*param.name));
|
||||
|
||||
TType counterType;
|
||||
counterBufferType(loc, counterType);
|
||||
@ -3163,7 +3163,7 @@ void HlslParseContext::counterBufferType(const TSourceLoc& loc, TType& type)
|
||||
{
|
||||
// Counter type
|
||||
TType* counterType = new TType(EbtInt, EvqBuffer);
|
||||
counterType->setFieldName("@count");
|
||||
counterType->setFieldName(intermediate.implicitCounterName);
|
||||
|
||||
TTypeList* blockStruct = new TTypeList;
|
||||
TTypeLoc member = { counterType, loc };
|
||||
@ -3176,12 +3176,6 @@ void HlslParseContext::counterBufferType(const TSourceLoc& loc, TType& 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
|
||||
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;
|
||||
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;
|
||||
|
||||
shareStructBufferType(blockType);
|
||||
@ -3211,7 +3205,7 @@ TIntermTyped* HlslParseContext::getStructBufferCounter(const TSourceLoc& loc, TI
|
||||
if (buffer == nullptr || ! isStructBufferType(buffer->getType()))
|
||||
return nullptr;
|
||||
|
||||
const TString counterBlockName(getStructBuffCounterName(buffer->getAsSymbolNode()->getName()));
|
||||
const TString counterBlockName(intermediate.addCounterBufferName(buffer->getAsSymbolNode()->getName()));
|
||||
|
||||
// Mark the counter as being used
|
||||
structBufferCounter[counterBlockName] = true;
|
||||
@ -3224,7 +3218,6 @@ TIntermTyped* HlslParseContext::getStructBufferCounter(const TSourceLoc& loc, TI
|
||||
return counterMember;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Decompose structure buffer methods into AST
|
||||
//
|
||||
@ -5743,12 +5736,11 @@ void HlslParseContext::addStructBuffArguments(const TSourceLoc& loc, TIntermAggr
|
||||
TType counterType;
|
||||
counterBufferType(loc, counterType);
|
||||
|
||||
const TString counterBlockName(getStructBuffCounterName(blockSym->getName()));
|
||||
const TString counterBlockName(intermediate.addCounterBufferName(blockSym->getName()));
|
||||
|
||||
TVariable* variable = makeInternalVariable(counterBlockName, counterType);
|
||||
|
||||
// Mark this buffer as requiring a counter block. TODO: there should be a better
|
||||
// way to track it.
|
||||
// Mark this buffer's counter block as being in use
|
||||
structBufferCounter[counterBlockName] = true;
|
||||
|
||||
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
|
||||
// shader is entirely compiled)
|
||||
// shader is entirely compiled).
|
||||
// Preserve order of remaining symbols.
|
||||
void HlslParseContext::removeUnusedStructBufferCounters()
|
||||
{
|
||||
const auto endIt = std::remove_if(linkageSymbols.begin(), linkageSymbols.end(),
|
||||
|
@ -405,7 +405,7 @@ protected:
|
||||
// may fit in TSampler::structReturnIndex.
|
||||
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
|
||||
// can build the linkage correctly if position appears on both sides. Otherwise, multiple positions
|
||||
|
Loading…
x
Reference in New Issue
Block a user