Updated glslang.
This commit is contained in:
parent
887dbc8ffe
commit
3e2188c27d
75
3rdparty/glslang/SPIRV/GlslangToSpv.cpp
vendored
75
3rdparty/glslang/SPIRV/GlslangToSpv.cpp
vendored
@ -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());
|
||||
|
9
3rdparty/glslang/SPIRV/SpvBuilder.cpp
vendored
9
3rdparty/glslang/SPIRV/SpvBuilder.cpp
vendored
@ -3409,10 +3409,13 @@ Id Builder::createConstructor(Decoration precision, const std::vector<Id>& sourc
|
||||
}
|
||||
|
||||
// If the result is a vector, make it from the gathered constituents.
|
||||
if (constituents.size() > 0)
|
||||
if (constituents.size() > 0) {
|
||||
result = createCompositeConstruct(resultTypeId, constituents);
|
||||
|
||||
return setPrecision(result, precision);
|
||||
return setPrecision(result, precision);
|
||||
} else {
|
||||
// Precision was set when generating this component.
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Comments in header
|
||||
|
2
3rdparty/glslang/SPIRV/SpvBuilder.h
vendored
2
3rdparty/glslang/SPIRV/SpvBuilder.h
vendored
@ -855,6 +855,8 @@ public:
|
||||
void postProcess(Instruction&);
|
||||
// Hook to visit each non-32-bit sized float/int operation in a block.
|
||||
void postProcessType(const Instruction&, spv::Id typeId);
|
||||
// move OpSampledImage instructions to be next to their users.
|
||||
void postProcessSamplers();
|
||||
|
||||
void dump(std::vector<unsigned int>&) const;
|
||||
|
||||
|
53
3rdparty/glslang/SPIRV/SpvPostProcess.cpp
vendored
53
3rdparty/glslang/SPIRV/SpvPostProcess.cpp
vendored
@ -483,6 +483,58 @@ void Builder::postProcessFeatures() {
|
||||
}
|
||||
}
|
||||
|
||||
// SPIR-V requires that any instruction consuming the result of an OpSampledImage
|
||||
// be in the same block as the OpSampledImage instruction. This pass goes finds
|
||||
// uses of OpSampledImage where that is not the case and duplicates the
|
||||
// OpSampledImage to be immediately before the instruction that consumes it.
|
||||
// The old OpSampledImage is left in place, potentially with no users.
|
||||
void Builder::postProcessSamplers()
|
||||
{
|
||||
// first, find all OpSampledImage instructions and store them in a map.
|
||||
std::map<Id, Instruction*> sampledImageInstrs;
|
||||
for (auto f: module.getFunctions()) {
|
||||
for (auto b: f->getBlocks()) {
|
||||
for (auto &i: b->getInstructions()) {
|
||||
if (i->getOpCode() == spv::OpSampledImage) {
|
||||
sampledImageInstrs[i->getResultId()] = i.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// next find all uses of the given ids and rewrite them if needed.
|
||||
for (auto f: module.getFunctions()) {
|
||||
for (auto b: f->getBlocks()) {
|
||||
auto &instrs = b->getInstructions();
|
||||
for (size_t idx = 0; idx < instrs.size(); idx++) {
|
||||
Instruction *i = instrs[idx].get();
|
||||
for (int opnum = 0; opnum < i->getNumOperands(); opnum++) {
|
||||
// Is this operand of the current instruction the result of an OpSampledImage?
|
||||
if (i->isIdOperand(opnum) &&
|
||||
sampledImageInstrs.count(i->getIdOperand(opnum)))
|
||||
{
|
||||
Instruction *opSampImg = sampledImageInstrs[i->getIdOperand(opnum)];
|
||||
if (i->getBlock() != opSampImg->getBlock()) {
|
||||
Instruction *newInstr = new Instruction(getUniqueId(),
|
||||
opSampImg->getTypeId(),
|
||||
spv::OpSampledImage);
|
||||
newInstr->addIdOperand(opSampImg->getIdOperand(0));
|
||||
newInstr->addIdOperand(opSampImg->getIdOperand(1));
|
||||
newInstr->setBlock(b);
|
||||
|
||||
// rewrite the user of the OpSampledImage to use the new instruction.
|
||||
i->setIdOperand(opnum, newInstr->getResultId());
|
||||
// insert the new OpSampledImage right before the current instruction.
|
||||
instrs.insert(instrs.begin() + idx,
|
||||
std::unique_ptr<Instruction>(newInstr));
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// comment in header
|
||||
void Builder::postProcess(bool compileOnly)
|
||||
{
|
||||
@ -491,6 +543,7 @@ void Builder::postProcess(bool compileOnly)
|
||||
postProcessCFG();
|
||||
|
||||
postProcessFeatures();
|
||||
postProcessSamplers();
|
||||
}
|
||||
|
||||
}; // end spv namespace
|
||||
|
1
3rdparty/glslang/SPIRV/doc.cpp
vendored
1
3rdparty/glslang/SPIRV/doc.cpp
vendored
@ -1064,6 +1064,7 @@ const char* CapabilityString(int info)
|
||||
case CapabilityTextureSampleWeightedQCOM: return "TextureSampleWeightedQCOM";
|
||||
case CapabilityTextureBoxFilterQCOM: return "TextureBoxFilterQCOM";
|
||||
case CapabilityTextureBlockMatchQCOM: return "TextureBlockMatchQCOM";
|
||||
case CapabilityTextureBlockMatch2QCOM: return "TextureBlockMatch2QCOM";
|
||||
|
||||
default: return "Bad";
|
||||
}
|
||||
|
10
3rdparty/glslang/SPIRV/spvIR.h
vendored
10
3rdparty/glslang/SPIRV/spvIR.h
vendored
@ -107,6 +107,14 @@ public:
|
||||
operands.push_back(id);
|
||||
idOperand.push_back(true);
|
||||
}
|
||||
// This method is potentially dangerous as it can break assumptions
|
||||
// about SSA and lack of forward references.
|
||||
void setIdOperand(unsigned idx, Id id) {
|
||||
assert(id);
|
||||
assert(idOperand[idx]);
|
||||
operands[idx] = id;
|
||||
}
|
||||
|
||||
void addImmediateOperand(unsigned int immediate) {
|
||||
operands.push_back(immediate);
|
||||
idOperand.push_back(false);
|
||||
@ -238,7 +246,7 @@ public:
|
||||
void addLocalVariable(std::unique_ptr<Instruction> inst) { localVariables.push_back(std::move(inst)); }
|
||||
const std::vector<Block*>& getPredecessors() const { return predecessors; }
|
||||
const std::vector<Block*>& getSuccessors() const { return successors; }
|
||||
const std::vector<std::unique_ptr<Instruction> >& getInstructions() const {
|
||||
std::vector<std::unique_ptr<Instruction> >& getInstructions() {
|
||||
return instructions;
|
||||
}
|
||||
const std::vector<std::unique_ptr<Instruction> >& getLocalVariables() const { return localVariables; }
|
||||
|
2
3rdparty/glslang/build_info.h
vendored
2
3rdparty/glslang/build_info.h
vendored
@ -35,7 +35,7 @@
|
||||
#define GLSLANG_BUILD_INFO
|
||||
|
||||
#define GLSLANG_VERSION_MAJOR 14
|
||||
#define GLSLANG_VERSION_MINOR 1
|
||||
#define GLSLANG_VERSION_MINOR 2
|
||||
#define GLSLANG_VERSION_PATCH 0
|
||||
#define GLSLANG_VERSION_FLAVOR ""
|
||||
|
||||
|
@ -962,14 +962,11 @@ TIntermTyped* HlslParseContext::handleDotDereference(const TSourceLoc& loc, TInt
|
||||
return addConstructor(loc, base, type);
|
||||
}
|
||||
}
|
||||
if (base->getVectorSize() == 1) {
|
||||
// Use EOpIndexDirect (below) with vec1.x so that it remains l-value (Test/hlsl.swizzle.vec1.comp)
|
||||
if (base->getVectorSize() == 1 && selectors.size() > 1) {
|
||||
TType scalarType(base->getBasicType(), EvqTemporary, 1);
|
||||
if (selectors.size() == 1)
|
||||
return addConstructor(loc, base, scalarType);
|
||||
else {
|
||||
TType vectorType(base->getBasicType(), EvqTemporary, selectors.size());
|
||||
return addConstructor(loc, addConstructor(loc, base, scalarType), vectorType);
|
||||
}
|
||||
TType vectorType(base->getBasicType(), EvqTemporary, selectors.size());
|
||||
return addConstructor(loc, addConstructor(loc, base, scalarType), vectorType);
|
||||
}
|
||||
|
||||
if (base->getType().getQualifier().isFrontEndConstant())
|
||||
|
2
3rdparty/glslang/glslang/Include/BaseTypes.h
vendored
2
3rdparty/glslang/glslang/Include/BaseTypes.h
vendored
@ -268,7 +268,6 @@ enum TBuiltInVariable {
|
||||
EbvRayTmin,
|
||||
EbvRayTmax,
|
||||
EbvCullMask,
|
||||
EbvHitT,
|
||||
EbvHitKind,
|
||||
EbvObjectToWorld,
|
||||
EbvObjectToWorld3x4,
|
||||
@ -495,7 +494,6 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
|
||||
case EbvObjectRayDirection: return "ObjectRayDirectionNV";
|
||||
case EbvRayTmin: return "ObjectRayTminNV";
|
||||
case EbvRayTmax: return "ObjectRayTmaxNV";
|
||||
case EbvHitT: return "HitTNV";
|
||||
case EbvHitKind: return "HitKindNV";
|
||||
case EbvIncomingRayFlags: return "IncomingRayFlagsNV";
|
||||
case EbvObjectToWorld: return "ObjectToWorldNV";
|
||||
|
@ -9209,8 +9209,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
||||
BuiltInVariable("gl_RayTmaxNV", EbvRayTmax, symbolTable);
|
||||
BuiltInVariable("gl_RayTmaxEXT", EbvRayTmax, symbolTable);
|
||||
BuiltInVariable("gl_CullMaskEXT", EbvCullMask, symbolTable);
|
||||
BuiltInVariable("gl_HitTNV", EbvHitT, symbolTable);
|
||||
BuiltInVariable("gl_HitTEXT", EbvHitT, symbolTable);
|
||||
BuiltInVariable("gl_HitKindNV", EbvHitKind, symbolTable);
|
||||
BuiltInVariable("gl_HitKindEXT", EbvHitKind, symbolTable);
|
||||
BuiltInVariable("gl_ObjectToWorldNV", EbvObjectToWorld, symbolTable);
|
||||
@ -9229,6 +9227,10 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
||||
BuiltInVariable("gl_HitKindFrontFacingMicroTriangleNV", EbvHitKindFrontFacingMicroTriangleNV, symbolTable);
|
||||
BuiltInVariable("gl_HitKindBackFacingMicroTriangleNV", EbvHitKindBackFacingMicroTriangleNV, symbolTable);
|
||||
|
||||
// gl_HitT variables are aliases of their gl_RayTmax counterparts.
|
||||
RetargetVariable("gl_HitTNV", "gl_RayTmaxNV", symbolTable);
|
||||
RetargetVariable("gl_HitTEXT", "gl_RayTmaxEXT", symbolTable);
|
||||
|
||||
// GL_ARB_shader_ballot
|
||||
symbolTable.setVariableExtensions("gl_SubGroupSizeARB", 1, &E_GL_ARB_shader_ballot);
|
||||
symbolTable.setVariableExtensions("gl_SubGroupInvocationARB", 1, &E_GL_ARB_shader_ballot);
|
||||
|
@ -492,7 +492,7 @@ TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symb
|
||||
if ((variable->getMangledName() == "gl_PrimitiveTriangleIndicesEXT" && primitiveType != ElgTriangles) ||
|
||||
(variable->getMangledName() == "gl_PrimitiveLineIndicesEXT" && primitiveType != ElgLines) ||
|
||||
(variable->getMangledName() == "gl_PrimitivePointIndicesEXT" && primitiveType != ElgPoints)) {
|
||||
error(loc, "cannot be used (ouput primitive type mismatch)", string->c_str(), "");
|
||||
error(loc, "cannot be used (output primitive type mismatch)", string->c_str(), "");
|
||||
variable = nullptr;
|
||||
}
|
||||
}
|
||||
@ -598,6 +598,10 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn
|
||||
indexValue >= resources.maxCullDistances) {
|
||||
error(loc, "gl_CullDistance", "[", "array index out of range '%d'", indexValue);
|
||||
}
|
||||
else if (base->getQualifier().builtIn == EbvSampleMask &&
|
||||
indexValue >= (resources.maxSamples + 31) / 32) {
|
||||
error(loc, "gl_SampleMask", "[", "array index out of range '%d'", indexValue);
|
||||
}
|
||||
// For 2D per-view builtin arrays, update the inner dimension size in parent type
|
||||
if (base->getQualifier().isPerView() && base->getQualifier().builtIn != EbvNone) {
|
||||
TIntermBinary* binaryNode = base->getAsBinaryNode();
|
||||
@ -2700,7 +2704,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
|
||||
case EOpEmitStreamVertex:
|
||||
case EOpEndStreamPrimitive:
|
||||
if (version == 150)
|
||||
requireExtensions(loc, 1, &E_GL_ARB_gpu_shader5, "if the verison is 150 , the EmitStreamVertex and EndStreamPrimitive only support at extension GL_ARB_gpu_shader5");
|
||||
requireExtensions(loc, 1, &E_GL_ARB_gpu_shader5, "if the version is 150 , the EmitStreamVertex and EndStreamPrimitive only support at extension GL_ARB_gpu_shader5");
|
||||
intermediate.setMultiStream();
|
||||
break;
|
||||
|
||||
@ -6564,10 +6568,10 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
|
||||
int repeated = intermediate.addUsedLocation(qualifier, type, typeCollision);
|
||||
if (repeated >= 0 && ! typeCollision)
|
||||
error(loc, "overlapping use of location", "location", "%d", repeated);
|
||||
// "fragment-shader outputs/tileImageEXT ... if two variables are placed within the same
|
||||
// location, they must have the same underlying type (floating-point or integer)"
|
||||
if (typeCollision && language == EShLangFragment && (qualifier.isPipeOutput() || qualifier.storage == EvqTileImageEXT))
|
||||
error(loc, "fragment outputs or tileImageEXTs sharing the same location", "location", "%d must be the same basic type", repeated);
|
||||
// When location aliasing, the aliases sharing the location must have the same underlying numerical type and bit width(
|
||||
// floating - point or integer, 32 - bit versus 64 - bit,etc.)
|
||||
if (typeCollision && (qualifier.isPipeInput() || qualifier.isPipeOutput() || qualifier.storage == EvqTileImageEXT))
|
||||
error(loc, "the aliases sharing the location", "location", "%d must be the same basic type and interpolation qualification", repeated);
|
||||
}
|
||||
|
||||
if (qualifier.hasXfbOffset() && qualifier.hasXfbBuffer()) {
|
||||
|
@ -788,7 +788,7 @@ bool ProcessDeferred(
|
||||
// set version/profile to defaultVersion/defaultProfile regardless of the #version
|
||||
// directive in the source code
|
||||
bool forceDefaultVersionAndProfile,
|
||||
int overrideVersion, // overrides version specified by #verison or default version
|
||||
int overrideVersion, // overrides version specified by #version or default version
|
||||
bool forwardCompatible, // give errors for use of deprecated features
|
||||
EShMessages messages, // warnings/errors/AST; things to print out
|
||||
TIntermediate& intermediate, // returned tree, etc.
|
||||
@ -2105,6 +2105,8 @@ const char* TProgram::getInfoDebugLog()
|
||||
// Reflection implementation.
|
||||
//
|
||||
|
||||
unsigned int TObjectReflection::layoutLocation() const { return type->getQualifier().layoutLocation; }
|
||||
|
||||
bool TProgram::buildReflection(int opts)
|
||||
{
|
||||
if (! linked || reflection != nullptr)
|
||||
|
@ -1689,7 +1689,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
|
||||
// First range:
|
||||
TRange locationRange(qualifier.layoutLocation, qualifier.layoutLocation);
|
||||
TRange componentRange(0, 3);
|
||||
TIoRange range(locationRange, componentRange, type.getBasicType(), 0);
|
||||
TIoRange range(locationRange, componentRange, type.getBasicType(), 0, qualifier.centroid, qualifier.smooth, qualifier.flat);
|
||||
|
||||
// check for collisions
|
||||
collision = checkLocationRange(set, range, type, typeCollision);
|
||||
@ -1699,7 +1699,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
|
||||
// Second range:
|
||||
TRange locationRange2(qualifier.layoutLocation + 1, qualifier.layoutLocation + 1);
|
||||
TRange componentRange2(0, 1);
|
||||
TIoRange range2(locationRange2, componentRange2, type.getBasicType(), 0);
|
||||
TIoRange range2(locationRange2, componentRange2, type.getBasicType(), 0, qualifier.centroid, qualifier.smooth, qualifier.flat);
|
||||
|
||||
// check for collisions
|
||||
collision = checkLocationRange(set, range2, type, typeCollision);
|
||||
@ -1725,7 +1725,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
|
||||
TBasicType basicTy = type.getBasicType();
|
||||
if (basicTy == EbtSampler && type.getSampler().isAttachmentEXT())
|
||||
basicTy = type.getSampler().type;
|
||||
TIoRange range(locationRange, componentRange, basicTy, qualifier.hasIndex() ? qualifier.getIndex() : 0);
|
||||
TIoRange range(locationRange, componentRange, basicTy, qualifier.hasIndex() ? qualifier.getIndex() : 0, qualifier.centroid, qualifier.smooth, qualifier.flat);
|
||||
|
||||
// check for collisions, except for vertex inputs on desktop targeting OpenGL
|
||||
if (! (!isEsProfile() && language == EShLangVertex && qualifier.isPipeInput()) || spvVersion.vulkan > 0)
|
||||
@ -1748,7 +1748,11 @@ int TIntermediate::checkLocationRange(int set, const TIoRange& range, const TTyp
|
||||
if (range.overlap(usedIo[set][r])) {
|
||||
// there is a collision; pick one
|
||||
return std::max(range.location.start, usedIo[set][r].location.start);
|
||||
} else if (range.location.overlap(usedIo[set][r].location) && type.getBasicType() != usedIo[set][r].basicType) {
|
||||
} else if (range.location.overlap(usedIo[set][r].location) &&
|
||||
(type.getBasicType() != usedIo[set][r].basicType ||
|
||||
type.getQualifier().centroid != usedIo[set][r].centroid ||
|
||||
type.getQualifier().smooth != usedIo[set][r].smooth ||
|
||||
type.getQualifier().flat != usedIo[set][r].flat)) {
|
||||
// aliased-type mismatch
|
||||
typeCollision = true;
|
||||
return std::max(range.location.start, usedIo[set][r].location.start);
|
||||
@ -2217,9 +2221,9 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, T
|
||||
}
|
||||
|
||||
// To aid the basic HLSL rule about crossing vec4 boundaries.
|
||||
bool TIntermediate::improperStraddle(const TType& type, int size, int offset)
|
||||
bool TIntermediate::improperStraddle(const TType& type, int size, int offset, bool vectorLike)
|
||||
{
|
||||
if (! type.isVector() || type.isArray())
|
||||
if (! vectorLike || type.isArray())
|
||||
return false;
|
||||
|
||||
return size <= 16 ? offset / 16 != (offset + size - 1) / 16
|
||||
|
@ -123,8 +123,10 @@ struct TRange {
|
||||
// within the same location range, component range, and index value. Locations don't alias unless
|
||||
// all other dimensions of their range overlap.
|
||||
struct TIoRange {
|
||||
TIoRange(TRange location, TRange component, TBasicType basicType, int index)
|
||||
: location(location), component(component), basicType(basicType), index(index) { }
|
||||
TIoRange(TRange location, TRange component, TBasicType basicType, int index, bool centroid, bool smooth, bool flat)
|
||||
: location(location), component(component), basicType(basicType), index(index), centroid(centroid), smooth(smooth), flat(flat)
|
||||
{
|
||||
}
|
||||
bool overlap(const TIoRange& rhs) const
|
||||
{
|
||||
return location.overlap(rhs.location) && component.overlap(rhs.component) && index == rhs.index;
|
||||
@ -133,6 +135,9 @@ struct TIoRange {
|
||||
TRange component;
|
||||
TBasicType basicType;
|
||||
int index;
|
||||
bool centroid;
|
||||
bool smooth;
|
||||
bool flat;
|
||||
};
|
||||
|
||||
// An offset range is a 2-D rectangle; the set of (binding, offset) pairs all lying
|
||||
@ -1057,7 +1062,7 @@ public:
|
||||
static int getBaseAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor);
|
||||
static int getScalarAlignment(const TType&, int& size, int& stride, bool rowMajor);
|
||||
static int getMemberAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor);
|
||||
static bool improperStraddle(const TType& type, int size, int offset);
|
||||
static bool improperStraddle(const TType& type, int size, int offset, bool vectorLike);
|
||||
static void updateOffset(const TType& parentType, const TType& memberType, int& offset, int& memberSize);
|
||||
static int getOffset(const TType& type, int index);
|
||||
static int getBlockSize(const TType& blockType);
|
||||
@ -1251,7 +1256,7 @@ protected:
|
||||
|
||||
std::unordered_set<int> usedConstantId; // specialization constant ids used
|
||||
std::vector<TOffsetRange> usedAtomics; // sets of bindings used by atomic counters
|
||||
std::vector<TIoRange> usedIo[4]; // sets of used locations, one for each of in, out, uniform, and buffers
|
||||
std::vector<TIoRange> usedIo[5]; // sets of used locations, one for each of in, out, uniform, and buffers
|
||||
std::vector<TRange> usedIoRT[4]; // sets of used location, one for rayPayload/rayPayloadIN,
|
||||
// one for callableData/callableDataIn, one for hitObjectAttributeNV and
|
||||
// one for shaderrecordhitobjectNV
|
||||
|
2
3rdparty/glslang/glslang/Public/ShaderLang.h
vendored
2
3rdparty/glslang/glslang/Public/ShaderLang.h
vendored
@ -745,6 +745,8 @@ public:
|
||||
GLSLANG_EXPORT void dump() const;
|
||||
static TObjectReflection badReflection() { return TObjectReflection(); }
|
||||
|
||||
GLSLANG_EXPORT unsigned int layoutLocation() const;
|
||||
|
||||
std::string name;
|
||||
int offset;
|
||||
int glDefineType;
|
||||
|
Loading…
Reference in New Issue
Block a user