|
|
@@ -227,6 +227,7 @@ protected:
|
|
|
spv::Id createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId);
|
|
|
spv::Id getSymbolId(const glslang::TIntermSymbol* node);
|
|
|
void addMeshNVDecoration(spv::Id id, int member, const glslang::TQualifier & qualifier);
|
|
|
+ bool hasQCOMImageProceessingDecoration(spv::Id id, spv::Decoration decor);
|
|
|
void addImageProcessingQCOMDecoration(spv::Id id, spv::Decoration decor);
|
|
|
void addImageProcessing2QCOMDecoration(spv::Id id, bool isForGather);
|
|
|
spv::Id createSpvConstant(const glslang::TIntermTyped&);
|
|
|
@@ -283,6 +284,7 @@ protected:
|
|
|
spv::Id taskPayloadID;
|
|
|
// Used later for generating OpTraceKHR/OpExecuteCallableKHR/OpHitObjectRecordHit*/OpHitObjectGetShaderBindingTableData
|
|
|
std::unordered_map<unsigned int, glslang::TIntermSymbol *> locationToSymbol[4];
|
|
|
+ std::unordered_map<spv::Id, std::vector<spv::Decoration> > idToQCOMDecorations;
|
|
|
};
|
|
|
|
|
|
//
|
|
|
@@ -398,11 +400,11 @@ void TranslateMemoryDecoration(const glslang::TQualifier& qualifier, std::vector
|
|
|
bool useVulkanMemoryModel)
|
|
|
{
|
|
|
if (!useVulkanMemoryModel) {
|
|
|
- if (qualifier.isCoherent())
|
|
|
- memory.push_back(spv::DecorationCoherent);
|
|
|
if (qualifier.isVolatile()) {
|
|
|
memory.push_back(spv::DecorationVolatile);
|
|
|
memory.push_back(spv::DecorationCoherent);
|
|
|
+ } else if (qualifier.isCoherent()) {
|
|
|
+ memory.push_back(spv::DecorationCoherent);
|
|
|
}
|
|
|
}
|
|
|
if (qualifier.isRestrict())
|
|
|
@@ -987,18 +989,6 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
|
|
|
return spv::BuiltInHitTriangleVertexPositionsKHR;
|
|
|
case glslang::EbvInstanceCustomIndex:
|
|
|
return spv::BuiltInInstanceCustomIndexKHR;
|
|
|
- case glslang::EbvHitT:
|
|
|
- {
|
|
|
- // this is a GLSL alias of RayTmax
|
|
|
- // in SPV_NV_ray_tracing it has a dedicated builtin
|
|
|
- // but in SPV_KHR_ray_tracing it gets mapped to RayTmax
|
|
|
- auto& extensions = glslangIntermediate->getRequestedExtensions();
|
|
|
- if (extensions.find("GL_NV_ray_tracing") != extensions.end()) {
|
|
|
- return spv::BuiltInHitTNV;
|
|
|
- } else {
|
|
|
- return spv::BuiltInRayTmaxKHR;
|
|
|
- }
|
|
|
- }
|
|
|
case glslang::EbvHitKind:
|
|
|
return spv::BuiltInHitKindKHR;
|
|
|
case glslang::EbvObjectToWorld:
|
|
|
@@ -3382,6 +3372,8 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|
|
|
|
|
case glslang::EOpImageBlockMatchGatherSSDQCOM:
|
|
|
case glslang::EOpImageBlockMatchGatherSADQCOM:
|
|
|
+ builder.addCapability(spv::CapabilityTextureBlockMatchQCOM);
|
|
|
+ builder.addExtension(spv::E_SPV_QCOM_image_processing);
|
|
|
builder.addCapability(spv::CapabilityTextureBlockMatch2QCOM);
|
|
|
builder.addExtension(spv::E_SPV_QCOM_image_processing2);
|
|
|
break;
|
|
|
@@ -5377,17 +5369,34 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType
|
|
|
int memberAlignment = glslangIntermediate->getMemberAlignment(memberType, memberSize, dummyStride, explicitLayout,
|
|
|
matrixLayout == glslang::ElmRowMajor);
|
|
|
|
|
|
+ bool isVectorLike = memberType.isVector();
|
|
|
+ if (memberType.isMatrix()) {
|
|
|
+ if (matrixLayout == glslang::ElmRowMajor)
|
|
|
+ isVectorLike = memberType.getMatrixRows() == 1;
|
|
|
+ else
|
|
|
+ isVectorLike = memberType.getMatrixCols() == 1;
|
|
|
+ }
|
|
|
+
|
|
|
// Adjust alignment for HLSL rules
|
|
|
// TODO: make this consistent in early phases of code:
|
|
|
// adjusting this late means inconsistencies with earlier code, which for reflection is an issue
|
|
|
// Until reflection is brought in sync with these adjustments, don't apply to $Global,
|
|
|
// which is the most likely to rely on reflection, and least likely to rely implicit layouts
|
|
|
if (glslangIntermediate->usingHlslOffsets() &&
|
|
|
- ! memberType.isArray() && memberType.isVector() && structType.getTypeName().compare("$Global") != 0) {
|
|
|
- int dummySize;
|
|
|
- int componentAlignment = glslangIntermediate->getBaseAlignmentScalar(memberType, dummySize);
|
|
|
- if (componentAlignment <= 4)
|
|
|
+ ! memberType.isStruct() && structType.getTypeName().compare("$Global") != 0) {
|
|
|
+ int componentSize;
|
|
|
+ int componentAlignment = glslangIntermediate->getBaseAlignmentScalar(memberType, componentSize);
|
|
|
+ if (! memberType.isArray() && isVectorLike && componentAlignment <= 4)
|
|
|
memberAlignment = componentAlignment;
|
|
|
+
|
|
|
+ // Don't add unnecessary padding after this member
|
|
|
+ if (memberType.isMatrix()) {
|
|
|
+ if (matrixLayout == glslang::ElmRowMajor)
|
|
|
+ memberSize -= componentSize * (4 - memberType.getMatrixCols());
|
|
|
+ else
|
|
|
+ memberSize -= componentSize * (4 - memberType.getMatrixRows());
|
|
|
+ } else if (memberType.isArray())
|
|
|
+ memberSize -= componentSize * (4 - memberType.getVectorSize());
|
|
|
}
|
|
|
|
|
|
// Bump up to member alignment
|
|
|
@@ -5395,7 +5404,7 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType
|
|
|
|
|
|
// Bump up to vec4 if there is a bad straddle
|
|
|
if (explicitLayout != glslang::ElpScalar && glslangIntermediate->improperStraddle(memberType, memberSize,
|
|
|
- currentOffset))
|
|
|
+ currentOffset, isVectorLike))
|
|
|
glslang::RoundToPow2(currentOffset, 16);
|
|
|
|
|
|
nextOffset = currentOffset + memberSize;
|
|
|
@@ -5480,8 +5489,10 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF
|
|
|
// memory and use RestrictPointer/AliasedPointer.
|
|
|
if (originalParam(type.getQualifier().storage, type, false) ||
|
|
|
!writableParam(type.getQualifier().storage)) {
|
|
|
- decorations.push_back(type.getQualifier().isRestrict() ? spv::DecorationRestrict :
|
|
|
- spv::DecorationAliased);
|
|
|
+ // TranslateMemoryDecoration added Restrict decoration already.
|
|
|
+ if (!type.getQualifier().isRestrict()) {
|
|
|
+ decorations.push_back(spv::DecorationAliased);
|
|
|
+ }
|
|
|
} else {
|
|
|
decorations.push_back(type.getQualifier().isRestrict() ? spv::DecorationRestrictPointerEXT :
|
|
|
spv::DecorationAliasedPointerEXT);
|
|
|
@@ -8056,6 +8067,7 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
|
|
|
}
|
|
|
|
|
|
std::vector<spv::Id> spvAtomicOperands; // hold the spv operands
|
|
|
+ spvAtomicOperands.reserve(6);
|
|
|
spvAtomicOperands.push_back(pointerId);
|
|
|
spvAtomicOperands.push_back(scopeId);
|
|
|
spvAtomicOperands.push_back(semanticsId);
|
|
|
@@ -9814,6 +9826,16 @@ void TGlslangToSpvTraverser::addMeshNVDecoration(spv::Id id, int member, const g
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+bool TGlslangToSpvTraverser::hasQCOMImageProceessingDecoration(spv::Id id, spv::Decoration decor)
|
|
|
+{
|
|
|
+ std::vector<spv::Decoration> &decoVec = idToQCOMDecorations[id];
|
|
|
+ for ( auto d : decoVec ) {
|
|
|
+ if ( d == decor )
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
void TGlslangToSpvTraverser::addImageProcessingQCOMDecoration(spv::Id id, spv::Decoration decor)
|
|
|
{
|
|
|
spv::Op opc = builder.getOpCode(id);
|
|
|
@@ -9824,7 +9846,10 @@ void TGlslangToSpvTraverser::addImageProcessingQCOMDecoration(spv::Id id, spv::D
|
|
|
|
|
|
if (opc == spv::OpLoad) {
|
|
|
spv::Id texid = builder.getIdOperand(id, 0);
|
|
|
- builder.addDecoration(texid, decor);
|
|
|
+ if (!hasQCOMImageProceessingDecoration(texid, decor)) {//
|
|
|
+ builder.addDecoration(texid, decor);
|
|
|
+ idToQCOMDecorations[texid].push_back(decor);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -9842,7 +9867,10 @@ void TGlslangToSpvTraverser::addImageProcessing2QCOMDecoration(spv::Id id, bool
|
|
|
if (this->glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_4) {
|
|
|
assert(iOSet.count(tsid) > 0);
|
|
|
}
|
|
|
- this->builder.addDecoration(tsid, decor);
|
|
|
+ if (!hasQCOMImageProceessingDecoration(tsid, decor)) {
|
|
|
+ this->builder.addDecoration(tsid, decor);
|
|
|
+ idToQCOMDecorations[tsid].push_back(decor);
|
|
|
+ }
|
|
|
}
|
|
|
};
|
|
|
|
|
|
@@ -10184,6 +10212,7 @@ spv::Id TGlslangToSpvTraverser::createShortCircuit(glslang::TOperator op, glslan
|
|
|
|
|
|
// Operands to accumulate OpPhi operands
|
|
|
std::vector<spv::Id> phiOperands;
|
|
|
+ phiOperands.reserve(4);
|
|
|
// accumulate left operand's phi information
|
|
|
phiOperands.push_back(leftId);
|
|
|
phiOperands.push_back(builder.getBuildPoint()->getId());
|