mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-02-17 20:52:36 +01:00
Updated glslang.
This commit is contained in:
committed by
Branimir Karadžić
parent
f78f1aee10
commit
59e6b4efbb
13
3rdparty/glslang/SPIRV/GlslangToSpv.cpp
vendored
13
3rdparty/glslang/SPIRV/GlslangToSpv.cpp
vendored
@@ -5167,6 +5167,16 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
|
||||
}
|
||||
|
||||
spv::Id var = builder.createVariable(spv::NoPrecision, storageClass, spvType, name, initializer, false);
|
||||
|
||||
if (options.emitNonSemanticShaderDebugInfo && storageClass != spv::StorageClass::Function) {
|
||||
// Create variable alias for retargeted symbols if any.
|
||||
// Notably, this is only applicable to built-in variables so that it is okay to only use name as the key.
|
||||
auto [itBegin, itEnd] = glslangIntermediate->getBuiltinAliasLookup().equal_range(name);
|
||||
for (auto it = itBegin; it != itEnd; ++it) {
|
||||
builder.createDebugGlobalVariable(builder.getDebugType(spvType), it->second.c_str(), var);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<spv::Decoration> topLevelDecorations;
|
||||
glslang::TQualifier typeQualifier = node->getType().getQualifier();
|
||||
TranslateMemoryDecoration(typeQualifier, topLevelDecorations, glslangIntermediate->usingVulkanMemoryModel());
|
||||
@@ -5675,7 +5685,8 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
|
||||
if (type.isSizedArray())
|
||||
spvType = builder.makeArrayType(spvType, makeArraySizeId(*type.getArraySizes(), 0), stride);
|
||||
else {
|
||||
if (!lastBufferBlockMember) {
|
||||
// If we see an runtime array in a buffer_reference, it is not a descriptor
|
||||
if (!lastBufferBlockMember && type.getBasicType() != glslang::EbtReference) {
|
||||
builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5);
|
||||
builder.addCapability(spv::Capability::RuntimeDescriptorArrayEXT);
|
||||
}
|
||||
|
||||
217
3rdparty/glslang/SPIRV/SpvBuilder.cpp
vendored
217
3rdparty/glslang/SPIRV/SpvBuilder.cpp
vendored
@@ -97,7 +97,7 @@ Id Builder::makeVoidType()
|
||||
module.mapInstruction(type);
|
||||
// Core OpTypeVoid used for debug void type
|
||||
if (emitNonSemanticShaderDebugInfo)
|
||||
debugId[typeId] = typeId;
|
||||
debugTypeIdLookup[typeId] = typeId;
|
||||
} else
|
||||
type = groupedTypes[enumCast(Op::OpTypeVoid)].back();
|
||||
|
||||
@@ -115,7 +115,7 @@ Id Builder::makeBoolType()
|
||||
|
||||
if (emitNonSemanticShaderDebugInfo) {
|
||||
auto const debugResultId = makeBoolDebugType(32);
|
||||
debugId[type->getResultId()] = debugResultId;
|
||||
debugTypeIdLookup[type->getResultId()] = debugResultId;
|
||||
}
|
||||
|
||||
} else
|
||||
@@ -139,7 +139,7 @@ Id Builder::makeSamplerType(const char* debugName)
|
||||
if (emitNonSemanticShaderDebugInfo)
|
||||
{
|
||||
auto const debugResultId = makeOpaqueDebugType(debugName);
|
||||
debugId[type->getResultId()] = debugResultId;
|
||||
debugTypeIdLookup[type->getResultId()] = debugResultId;
|
||||
}
|
||||
|
||||
return type->getResultId();
|
||||
@@ -167,7 +167,7 @@ Id Builder::makePointer(StorageClass storageClass, Id pointee)
|
||||
|
||||
if (emitNonSemanticShaderDebugInfo) {
|
||||
const Id debugResultId = makePointerDebugType(storageClass, pointee);
|
||||
debugId[type->getResultId()] = debugResultId;
|
||||
debugTypeIdLookup[type->getResultId()] = debugResultId;
|
||||
}
|
||||
|
||||
return type->getResultId();
|
||||
@@ -185,7 +185,7 @@ Id Builder::makeForwardPointer(StorageClass storageClass)
|
||||
|
||||
if (emitNonSemanticShaderDebugInfo) {
|
||||
const Id debugResultId = makeForwardPointerDebugType(storageClass);
|
||||
debugId[type->getResultId()] = debugResultId;
|
||||
debugTypeIdLookup[type->getResultId()] = debugResultId;
|
||||
}
|
||||
return type->getResultId();
|
||||
}
|
||||
@@ -213,9 +213,9 @@ Id Builder::makePointerFromForwardPointer(StorageClass storageClass, Id forwardP
|
||||
// that was emitted alongside the forward pointer, now that we have a pointee debug
|
||||
// type for it to point to.
|
||||
if (emitNonSemanticShaderDebugInfo) {
|
||||
Instruction *debugForwardPointer = module.getInstruction(debugId[forwardPointerType]);
|
||||
assert(debugId[pointee]);
|
||||
debugForwardPointer->setIdOperand(2, debugId[pointee]);
|
||||
Instruction *debugForwardPointer = module.getInstruction(getDebugType(forwardPointerType));
|
||||
assert(getDebugType(pointee));
|
||||
debugForwardPointer->setIdOperand(2, getDebugType(pointee));
|
||||
}
|
||||
|
||||
return type->getResultId();
|
||||
@@ -257,7 +257,7 @@ Id Builder::makeIntegerType(int width, bool hasSign)
|
||||
if (emitNonSemanticShaderDebugInfo)
|
||||
{
|
||||
auto const debugResultId = makeIntegerDebugType(width, hasSign);
|
||||
debugId[type->getResultId()] = debugResultId;
|
||||
debugTypeIdLookup[type->getResultId()] = debugResultId;
|
||||
}
|
||||
|
||||
return type->getResultId();
|
||||
@@ -298,7 +298,7 @@ Id Builder::makeFloatType(int width)
|
||||
if (emitNonSemanticShaderDebugInfo)
|
||||
{
|
||||
auto const debugResultId = makeFloatDebugType(width);
|
||||
debugId[type->getResultId()] = debugResultId;
|
||||
debugTypeIdLookup[type->getResultId()] = debugResultId;
|
||||
}
|
||||
|
||||
return type->getResultId();
|
||||
@@ -334,7 +334,7 @@ Id Builder::makeBFloat16Type()
|
||||
if (emitNonSemanticShaderDebugInfo)
|
||||
{
|
||||
auto const debugResultId = makeFloatDebugType(width);
|
||||
debugId[type->getResultId()] = debugResultId;
|
||||
debugTypeIdLookup[type->getResultId()] = debugResultId;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -371,7 +371,7 @@ Id Builder::makeFloatE5M2Type()
|
||||
if (emitNonSemanticShaderDebugInfo)
|
||||
{
|
||||
auto const debugResultId = makeFloatDebugType(width);
|
||||
debugId[type->getResultId()] = debugResultId;
|
||||
debugTypeIdLookup[type->getResultId()] = debugResultId;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -408,7 +408,7 @@ Id Builder::makeFloatE4M3Type()
|
||||
if (emitNonSemanticShaderDebugInfo)
|
||||
{
|
||||
auto const debugResultId = makeFloatDebugType(width);
|
||||
debugId[type->getResultId()] = debugResultId;
|
||||
debugTypeIdLookup[type->getResultId()] = debugResultId;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -439,7 +439,7 @@ Id Builder::makeStructType(const std::vector<Id>& members, const std::vector<spv
|
||||
assert(members.size() == memberDebugInfo.size());
|
||||
auto const debugResultId =
|
||||
makeCompositeDebugType(members, memberDebugInfo, name, NonSemanticShaderDebugInfo100Structure);
|
||||
debugId[type->getResultId()] = debugResultId;
|
||||
debugTypeIdLookup[type->getResultId()] = debugResultId;
|
||||
}
|
||||
|
||||
return type->getResultId();
|
||||
@@ -492,7 +492,7 @@ Id Builder::makeVectorType(Id component, int size)
|
||||
if (emitNonSemanticShaderDebugInfo)
|
||||
{
|
||||
auto const debugResultId = makeVectorDebugType(component, size);
|
||||
debugId[type->getResultId()] = debugResultId;
|
||||
debugTypeIdLookup[type->getResultId()] = debugResultId;
|
||||
}
|
||||
|
||||
return type->getResultId();
|
||||
@@ -525,7 +525,7 @@ Id Builder::makeMatrixType(Id component, int cols, int rows)
|
||||
if (emitNonSemanticShaderDebugInfo)
|
||||
{
|
||||
auto const debugResultId = makeMatrixDebugType(column, cols);
|
||||
debugId[type->getResultId()] = debugResultId;
|
||||
debugTypeIdLookup[type->getResultId()] = debugResultId;
|
||||
}
|
||||
|
||||
return type->getResultId();
|
||||
@@ -562,7 +562,7 @@ Id Builder::makeCooperativeMatrixTypeKHR(Id component, Id scope, Id rows, Id col
|
||||
// Find a name for one of the parameters. It can either come from debuginfo for another
|
||||
// type, or an OpName from a constant.
|
||||
auto const findName = [&](Id id) {
|
||||
Id id2 = debugId[id];
|
||||
Id id2 = getDebugType(id);
|
||||
for (auto &t : groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeBasic]) {
|
||||
if (t->getResultId() == id2) {
|
||||
for (auto &s : strings) {
|
||||
@@ -591,7 +591,7 @@ Id Builder::makeCooperativeMatrixTypeKHR(Id component, Id scope, Id rows, Id col
|
||||
// There's no nonsemantic debug info instruction for cooperative matrix types,
|
||||
// use opaque composite instead.
|
||||
auto const debugResultId = makeOpaqueDebugType(debugName.c_str());
|
||||
debugId[type->getResultId()] = debugResultId;
|
||||
debugTypeIdLookup[type->getResultId()] = debugResultId;
|
||||
}
|
||||
|
||||
return type->getResultId();
|
||||
@@ -742,7 +742,7 @@ Id Builder::makeArrayType(Id element, Id sizeId, int stride)
|
||||
if (emitNonSemanticShaderDebugInfo)
|
||||
{
|
||||
auto const debugResultId = makeArrayDebugType(element, sizeId);
|
||||
debugId[type->getResultId()] = debugResultId;
|
||||
debugTypeIdLookup[type->getResultId()] = debugResultId;
|
||||
}
|
||||
|
||||
return type->getResultId();
|
||||
@@ -758,7 +758,7 @@ Id Builder::makeRuntimeArray(Id element)
|
||||
if (emitNonSemanticShaderDebugInfo)
|
||||
{
|
||||
auto const debugResultId = makeArrayDebugType(element, makeUintConstant(0));
|
||||
debugId[type->getResultId()] = debugResultId;
|
||||
debugTypeIdLookup[type->getResultId()] = debugResultId;
|
||||
}
|
||||
|
||||
return type->getResultId();
|
||||
@@ -785,12 +785,12 @@ Id Builder::makeFunctionType(Id returnType, const std::vector<Id>& paramTypes)
|
||||
// function type is created for the wrapper function. However, nonsemantic shader debug information is disabled
|
||||
// while creating the HLSL wrapper. Consequently, if we encounter another void(void) function, we need to create
|
||||
// the associated debug function type if it hasn't been created yet.
|
||||
if(emitNonSemanticShaderDebugInfo && debugId[type->getResultId()] == 0) {
|
||||
if(emitNonSemanticShaderDebugInfo && getDebugType(type->getResultId()) == NoType) {
|
||||
assert(sourceLang == spv::SourceLanguage::HLSL);
|
||||
assert(getTypeClass(returnType) == Op::OpTypeVoid && paramTypes.size() == 0);
|
||||
|
||||
Id debugTypeId = makeDebugFunctionType(returnType, {});
|
||||
debugId[type->getResultId()] = debugTypeId;
|
||||
Id id = makeDebugFunctionType(returnType, {});
|
||||
debugTypeIdLookup[type->getResultId()] = id;
|
||||
}
|
||||
return type->getResultId();
|
||||
}
|
||||
@@ -810,7 +810,7 @@ Id Builder::makeFunctionType(Id returnType, const std::vector<Id>& paramTypes)
|
||||
// make debug type and map it
|
||||
if (emitNonSemanticShaderDebugInfo) {
|
||||
Id debugTypeId = makeDebugFunctionType(returnType, paramTypes);
|
||||
debugId[typeId] = debugTypeId;
|
||||
debugTypeIdLookup[typeId] = debugTypeId;
|
||||
}
|
||||
|
||||
return type->getResultId();
|
||||
@@ -818,7 +818,7 @@ Id Builder::makeFunctionType(Id returnType, const std::vector<Id>& paramTypes)
|
||||
|
||||
Id Builder::makeDebugFunctionType(Id returnType, const std::vector<Id>& paramTypes)
|
||||
{
|
||||
assert(debugId[returnType] != 0);
|
||||
assert(getDebugType(returnType) != NoType);
|
||||
|
||||
Id typeId = getUniqueId();
|
||||
auto type = new Instruction(typeId, makeVoidType(), Op::OpExtInst);
|
||||
@@ -826,13 +826,13 @@ Id Builder::makeDebugFunctionType(Id returnType, const std::vector<Id>& paramTyp
|
||||
type->addIdOperand(nonSemanticShaderDebugInfo);
|
||||
type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeFunction);
|
||||
type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100FlagIsPublic));
|
||||
type->addIdOperand(debugId[returnType]);
|
||||
type->addIdOperand(getDebugType(returnType));
|
||||
for (auto const paramType : paramTypes) {
|
||||
if (isPointerType(paramType) || isArrayType(paramType)) {
|
||||
type->addIdOperand(debugId[getContainedTypeId(paramType)]);
|
||||
type->addIdOperand(getDebugType(getContainedTypeId(paramType)));
|
||||
}
|
||||
else {
|
||||
type->addIdOperand(debugId[paramType]);
|
||||
type->addIdOperand(getDebugType(paramType));
|
||||
}
|
||||
}
|
||||
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
|
||||
@@ -923,7 +923,7 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo
|
||||
if (emitNonSemanticShaderDebugInfo)
|
||||
{
|
||||
auto const debugResultId = makeOpaqueDebugType(debugName);
|
||||
debugId[type->getResultId()] = debugResultId;
|
||||
debugTypeIdLookup[type->getResultId()] = debugResultId;
|
||||
}
|
||||
|
||||
return type->getResultId();
|
||||
@@ -950,7 +950,7 @@ Id Builder::makeSampledImageType(Id imageType, const char* debugName)
|
||||
if (emitNonSemanticShaderDebugInfo)
|
||||
{
|
||||
auto const debugResultId = makeOpaqueDebugType(debugName);
|
||||
debugId[type->getResultId()] = debugResultId;
|
||||
debugTypeIdLookup[type->getResultId()] = debugResultId;
|
||||
}
|
||||
|
||||
return type->getResultId();
|
||||
@@ -1099,7 +1099,7 @@ Id Builder::makeSequentialDebugType(Id const baseType, Id const componentCount,
|
||||
type->reserveOperands(4);
|
||||
type->addIdOperand(nonSemanticShaderDebugInfo);
|
||||
type->addImmediateOperand(sequenceType);
|
||||
type->addIdOperand(debugId[baseType]); // base type
|
||||
type->addIdOperand(getDebugType(baseType)); // base type
|
||||
type->addIdOperand(componentCount); // component count
|
||||
|
||||
groupedDebugTypes[sequenceType].push_back(type);
|
||||
@@ -1135,7 +1135,7 @@ Id Builder::makeMatrixDebugType(Id const vectorType, int const vectorCount, bool
|
||||
type->reserveOperands(5);
|
||||
type->addIdOperand(nonSemanticShaderDebugInfo);
|
||||
type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeMatrix);
|
||||
type->addIdOperand(debugId[vectorType]); // vector type id
|
||||
type->addIdOperand(getDebugType(vectorType)); // vector type id
|
||||
type->addIdOperand(makeUintConstant(vectorCount)); // component count id
|
||||
type->addIdOperand(makeBoolConstant(columnMajor)); // column-major id
|
||||
|
||||
@@ -1148,7 +1148,7 @@ Id Builder::makeMatrixDebugType(Id const vectorType, int const vectorCount, bool
|
||||
|
||||
Id Builder::makeMemberDebugType(Id const memberType, StructMemberDebugInfo const& debugTypeLoc)
|
||||
{
|
||||
assert(debugId[memberType] != 0);
|
||||
assert(getDebugType(memberType) != NoType);
|
||||
|
||||
Instruction* type = new Instruction(getUniqueId(), makeVoidType(), Op::OpExtInst);
|
||||
type->reserveOperands(10);
|
||||
@@ -1156,7 +1156,7 @@ Id Builder::makeMemberDebugType(Id const memberType, StructMemberDebugInfo const
|
||||
type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeMember);
|
||||
type->addIdOperand(getStringId(debugTypeLoc.name)); // name id
|
||||
type->addIdOperand(debugTypeLoc.debugTypeOverride != 0 ? debugTypeLoc.debugTypeOverride
|
||||
: debugId[memberType]); // type id
|
||||
: getDebugType(memberType)); // type id
|
||||
type->addIdOperand(makeDebugSource(currentFileId)); // source id
|
||||
type->addIdOperand(makeUintConstant(debugTypeLoc.line)); // line id TODO: currentLine is always zero
|
||||
type->addIdOperand(makeUintConstant(debugTypeLoc.column)); // TODO: column id
|
||||
@@ -1178,7 +1178,7 @@ Id Builder::makeCompositeDebugType(std::vector<Id> const& memberTypes, std::vect
|
||||
std::vector<Id> memberDebugTypes;
|
||||
assert(memberTypes.size() == memberDebugInfo.size());
|
||||
for (size_t i = 0; i < memberTypes.size(); i++) {
|
||||
if (debugId[memberTypes[i]]) {
|
||||
if (getDebugType(memberTypes[i]) != NoType) {
|
||||
memberDebugTypes.emplace_back(makeMemberDebugType(memberTypes[i], memberDebugInfo[i]));
|
||||
}
|
||||
}
|
||||
@@ -1238,7 +1238,7 @@ Id Builder::makeOpaqueDebugType(char const* const name)
|
||||
|
||||
Id Builder::makePointerDebugType(StorageClass storageClass, Id const baseType)
|
||||
{
|
||||
const Id debugBaseType = debugId[baseType];
|
||||
const Id debugBaseType = getDebugType(baseType);
|
||||
if (!debugBaseType) {
|
||||
return makeDebugInfoNone();
|
||||
}
|
||||
@@ -1474,7 +1474,7 @@ Id Builder::makeAccelerationStructureType()
|
||||
module.mapInstruction(type);
|
||||
if (emitNonSemanticShaderDebugInfo) {
|
||||
spv::Id debugType = makeOpaqueDebugType("accelerationStructure");
|
||||
debugId[type->getResultId()] = debugType;
|
||||
debugTypeIdLookup[type->getResultId()] = debugType;
|
||||
}
|
||||
} else {
|
||||
type = groupedTypes[enumCast(Op::OpTypeAccelerationStructureKHR)].back();
|
||||
@@ -1493,7 +1493,7 @@ Id Builder::makeRayQueryType()
|
||||
module.mapInstruction(type);
|
||||
if (emitNonSemanticShaderDebugInfo) {
|
||||
spv::Id debugType = makeOpaqueDebugType("rayQuery");
|
||||
debugId[type->getResultId()] = debugType;
|
||||
debugTypeIdLookup[type->getResultId()] = debugType;
|
||||
}
|
||||
} else {
|
||||
type = groupedTypes[enumCast(Op::OpTypeRayQueryKHR)].back();
|
||||
@@ -1526,7 +1526,7 @@ Id Builder::makeHitObjectNVType()
|
||||
module.mapInstruction(type);
|
||||
if (emitNonSemanticShaderDebugInfo) {
|
||||
spv::Id debugType = makeOpaqueDebugType("hitObjectNV");
|
||||
debugId[type->getResultId()] = debugType;
|
||||
debugTypeIdLookup[type->getResultId()] = debugType;
|
||||
}
|
||||
} else {
|
||||
type = groupedTypes[enumCast(Op::OpTypeHitObjectNV)].back();
|
||||
@@ -1734,32 +1734,17 @@ bool Builder::containsPhysicalStorageBufferOrArray(Id typeId) const
|
||||
// can be reused rather than duplicated. (Required by the specification).
|
||||
Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value)
|
||||
{
|
||||
Instruction* constant;
|
||||
for (int i = 0; i < (int)groupedConstants[enumCast(typeClass)].size(); ++i) {
|
||||
constant = groupedConstants[enumCast(typeClass)][i];
|
||||
if (constant->getOpCode() == opcode &&
|
||||
constant->getTypeId() == typeId &&
|
||||
constant->getImmediateOperand(0) == value)
|
||||
return constant->getResultId();
|
||||
}
|
||||
|
||||
return 0;
|
||||
ScalarConstantKey key{ enumCast(typeClass), enumCast(opcode), typeId, value, 0 };
|
||||
auto it = groupedScalarConstantResultIDs.find(key);
|
||||
return (it != groupedScalarConstantResultIDs.end()) ? it->second : 0;
|
||||
}
|
||||
|
||||
// Version of findScalarConstant (see above) for scalars that take two operands (e.g. a 'double' or 'int64').
|
||||
Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2)
|
||||
{
|
||||
Instruction* constant;
|
||||
for (int i = 0; i < (int)groupedConstants[enumCast(typeClass)].size(); ++i) {
|
||||
constant = groupedConstants[enumCast(typeClass)][i];
|
||||
if (constant->getOpCode() == opcode &&
|
||||
constant->getTypeId() == typeId &&
|
||||
constant->getImmediateOperand(0) == v1 &&
|
||||
constant->getImmediateOperand(1) == v2)
|
||||
return constant->getResultId();
|
||||
}
|
||||
|
||||
return 0;
|
||||
ScalarConstantKey key{ enumCast(typeClass), enumCast(opcode), typeId, v1, v2 };
|
||||
auto it = groupedScalarConstantResultIDs.find(key);
|
||||
return (it != groupedScalarConstantResultIDs.end()) ? it->second : 0;
|
||||
}
|
||||
|
||||
// Return true if consuming 'opcode' means consuming a constant.
|
||||
@@ -1831,19 +1816,12 @@ Id Builder::makeNullConstant(Id typeId)
|
||||
Id Builder::makeBoolConstant(bool b, bool specConstant)
|
||||
{
|
||||
Id typeId = makeBoolType();
|
||||
Instruction* constant;
|
||||
Op opcode = specConstant ? (b ? Op::OpSpecConstantTrue : Op::OpSpecConstantFalse) : (b ? Op::OpConstantTrue : Op::OpConstantFalse);
|
||||
|
||||
// See if we already made it. Applies only to regular constants, because specialization constants
|
||||
// must remain distinct for the purpose of applying a SpecId decoration.
|
||||
if (! specConstant) {
|
||||
Id existing = 0;
|
||||
for (int i = 0; i < (int)groupedConstants[enumCast(Op::OpTypeBool)].size(); ++i) {
|
||||
constant = groupedConstants[enumCast(Op::OpTypeBool)][i];
|
||||
if (constant->getTypeId() == typeId && constant->getOpCode() == opcode)
|
||||
existing = constant->getResultId();
|
||||
}
|
||||
|
||||
if (!specConstant) {
|
||||
Id existing = findScalarConstant(Op::OpTypeBool, opcode, typeId, 0);
|
||||
if (existing)
|
||||
return existing;
|
||||
}
|
||||
@@ -1851,10 +1829,14 @@ Id Builder::makeBoolConstant(bool b, bool specConstant)
|
||||
// Make it
|
||||
Instruction* c = new Instruction(getUniqueId(), typeId, opcode);
|
||||
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));
|
||||
groupedConstants[enumCast(Op::OpTypeBool)].push_back(c);
|
||||
module.mapInstruction(c);
|
||||
|
||||
return c->getResultId();
|
||||
Id resultId = c->getResultId();
|
||||
if (!specConstant) {
|
||||
ScalarConstantKey key{enumCast(Op::OpTypeBool), enumCast(opcode), typeId, 0, 0};
|
||||
groupedScalarConstantResultIDs[key] = resultId;
|
||||
}
|
||||
return resultId;
|
||||
}
|
||||
|
||||
Id Builder::makeIntConstant(Id typeId, unsigned value, bool specConstant)
|
||||
@@ -1872,10 +1854,14 @@ Id Builder::makeIntConstant(Id typeId, unsigned value, bool specConstant)
|
||||
Instruction* c = new Instruction(getUniqueId(), typeId, opcode);
|
||||
c->addImmediateOperand(value);
|
||||
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));
|
||||
groupedConstants[enumCast(Op::OpTypeInt)].push_back(c);
|
||||
module.mapInstruction(c);
|
||||
|
||||
return c->getResultId();
|
||||
Id resultId = c->getResultId();
|
||||
if (!specConstant) {
|
||||
ScalarConstantKey key{ enumCast(Op::OpTypeInt), enumCast(opcode), typeId, value, 0 };
|
||||
groupedScalarConstantResultIDs[key] = resultId;
|
||||
}
|
||||
return resultId;
|
||||
}
|
||||
|
||||
Id Builder::makeInt64Constant(Id typeId, unsigned long long value, bool specConstant)
|
||||
@@ -1898,10 +1884,14 @@ Id Builder::makeInt64Constant(Id typeId, unsigned long long value, bool specCons
|
||||
c->addImmediateOperand(op1);
|
||||
c->addImmediateOperand(op2);
|
||||
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));
|
||||
groupedConstants[enumCast(Op::OpTypeInt)].push_back(c);
|
||||
module.mapInstruction(c);
|
||||
|
||||
return c->getResultId();
|
||||
Id resultId = c->getResultId();
|
||||
if (!specConstant) {
|
||||
ScalarConstantKey key{ enumCast(Op::OpTypeInt), enumCast(opcode), typeId, op1, op2 };
|
||||
groupedScalarConstantResultIDs[key] = resultId;
|
||||
}
|
||||
return resultId;
|
||||
}
|
||||
|
||||
Id Builder::makeFloatConstant(float f, bool specConstant)
|
||||
@@ -1923,10 +1913,14 @@ Id Builder::makeFloatConstant(float f, bool specConstant)
|
||||
Instruction* c = new Instruction(getUniqueId(), typeId, opcode);
|
||||
c->addImmediateOperand(value);
|
||||
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));
|
||||
groupedConstants[enumCast(Op::OpTypeFloat)].push_back(c);
|
||||
module.mapInstruction(c);
|
||||
|
||||
return c->getResultId();
|
||||
Id resultId = c->getResultId();
|
||||
if (!specConstant) {
|
||||
ScalarConstantKey key{ enumCast(Op::OpTypeFloat), enumCast(opcode), typeId, value, 0 };
|
||||
groupedScalarConstantResultIDs[key] = resultId;
|
||||
}
|
||||
return resultId;
|
||||
}
|
||||
|
||||
Id Builder::makeDoubleConstant(double d, bool specConstant)
|
||||
@@ -1952,10 +1946,14 @@ Id Builder::makeDoubleConstant(double d, bool specConstant)
|
||||
c->addImmediateOperand(op1);
|
||||
c->addImmediateOperand(op2);
|
||||
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));
|
||||
groupedConstants[enumCast(Op::OpTypeFloat)].push_back(c);
|
||||
module.mapInstruction(c);
|
||||
|
||||
return c->getResultId();
|
||||
Id resultId = c->getResultId();
|
||||
if (!specConstant) {
|
||||
ScalarConstantKey key{ enumCast(Op::OpTypeFloat), enumCast(opcode), typeId, op1, op2 };
|
||||
groupedScalarConstantResultIDs[key] = resultId;
|
||||
}
|
||||
return resultId;
|
||||
}
|
||||
|
||||
Id Builder::makeFloat16Constant(float f16, bool specConstant)
|
||||
@@ -1980,10 +1978,14 @@ Id Builder::makeFloat16Constant(float f16, bool specConstant)
|
||||
Instruction* c = new Instruction(getUniqueId(), typeId, opcode);
|
||||
c->addImmediateOperand(value);
|
||||
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));
|
||||
groupedConstants[enumCast(Op::OpTypeFloat)].push_back(c);
|
||||
module.mapInstruction(c);
|
||||
|
||||
return c->getResultId();
|
||||
Id resultId = c->getResultId();
|
||||
if (!specConstant) {
|
||||
ScalarConstantKey key{ enumCast(Op::OpTypeFloat), enumCast(opcode), typeId, value, 0 };
|
||||
groupedScalarConstantResultIDs[key] = resultId;
|
||||
}
|
||||
return resultId;
|
||||
}
|
||||
|
||||
Id Builder::makeBFloat16Constant(float bf16, bool specConstant)
|
||||
@@ -2011,10 +2013,14 @@ Id Builder::makeBFloat16Constant(float bf16, bool specConstant)
|
||||
Instruction* c = new Instruction(getUniqueId(), typeId, opcode);
|
||||
c->addImmediateOperand(value);
|
||||
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));
|
||||
groupedConstants[enumCast(Op::OpTypeFloat)].push_back(c);
|
||||
module.mapInstruction(c);
|
||||
|
||||
return c->getResultId();
|
||||
Id resultId = c->getResultId();
|
||||
if (!specConstant) {
|
||||
ScalarConstantKey key{ enumCast(Op::OpTypeFloat), enumCast(opcode), typeId, value, 0 };
|
||||
groupedScalarConstantResultIDs[key] = resultId;
|
||||
}
|
||||
return resultId;
|
||||
}
|
||||
|
||||
Id Builder::makeFloatE5M2Constant(float fe5m2, bool specConstant)
|
||||
@@ -2039,10 +2045,14 @@ Id Builder::makeFloatE5M2Constant(float fe5m2, bool specConstant)
|
||||
Instruction* c = new Instruction(getUniqueId(), typeId, opcode);
|
||||
c->addImmediateOperand(value);
|
||||
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));
|
||||
groupedConstants[enumCast(Op::OpTypeFloat)].push_back(c);
|
||||
module.mapInstruction(c);
|
||||
|
||||
return c->getResultId();
|
||||
Id resultId = c->getResultId();
|
||||
if (!specConstant) {
|
||||
ScalarConstantKey key{enumCast(Op::OpTypeFloat), enumCast(opcode), typeId, value, 0};
|
||||
groupedScalarConstantResultIDs[key] = resultId;
|
||||
}
|
||||
return resultId;
|
||||
}
|
||||
|
||||
Id Builder::makeFloatE4M3Constant(float fe4m3, bool specConstant)
|
||||
@@ -2067,10 +2077,14 @@ Id Builder::makeFloatE4M3Constant(float fe4m3, bool specConstant)
|
||||
Instruction* c = new Instruction(getUniqueId(), typeId, opcode);
|
||||
c->addImmediateOperand(value);
|
||||
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));
|
||||
groupedConstants[enumCast(Op::OpTypeFloat)].push_back(c);
|
||||
module.mapInstruction(c);
|
||||
|
||||
return c->getResultId();
|
||||
Id resultId = c->getResultId();
|
||||
if (!specConstant) {
|
||||
ScalarConstantKey key{enumCast(Op::OpTypeFloat), enumCast(opcode), typeId, value, 0};
|
||||
groupedScalarConstantResultIDs[key] = resultId;
|
||||
}
|
||||
return resultId;
|
||||
}
|
||||
|
||||
Id Builder::makeFpConstant(Id type, double d, bool specConstant)
|
||||
@@ -2111,8 +2125,8 @@ Id Builder::findCompositeConstant(Op typeClass, Op opcode, Id typeId, const std:
|
||||
{
|
||||
Instruction* constant = nullptr;
|
||||
bool found = false;
|
||||
for (int i = 0; i < (int)groupedConstants[enumCast(typeClass)].size(); ++i) {
|
||||
constant = groupedConstants[enumCast(typeClass)][i];
|
||||
for (int i = 0; i < (int)groupedCompositeConstants[enumCast(typeClass)].size(); ++i) {
|
||||
constant = groupedCompositeConstants[enumCast(typeClass)][i];
|
||||
|
||||
if (constant->getTypeId() != typeId)
|
||||
continue;
|
||||
@@ -2222,7 +2236,7 @@ Id Builder::makeCompositeConstant(Id typeId, const std::vector<Id>& members, boo
|
||||
if (typeClass == Op::OpTypeStruct)
|
||||
groupedStructConstants[typeId].push_back(c);
|
||||
else
|
||||
groupedConstants[enumCast(typeClass)].push_back(c);
|
||||
groupedCompositeConstants[enumCast(typeClass)].push_back(c);
|
||||
module.mapInstruction(c);
|
||||
|
||||
return c->getResultId();
|
||||
@@ -2603,14 +2617,14 @@ void Builder::setupFunctionDebugInfo(Function* function, const char* name, const
|
||||
|
||||
Id nameId = getStringId(unmangleFunctionName(name));
|
||||
Id funcTypeId = function->getFuncTypeId();
|
||||
assert(debugId[funcTypeId] != 0);
|
||||
assert(getDebugType(funcTypeId) != NoType);
|
||||
Id funcId = function->getId();
|
||||
|
||||
assert(funcId != 0);
|
||||
|
||||
// Make the debug function instruction
|
||||
Id debugFuncId = makeDebugFunction(function, nameId, funcTypeId);
|
||||
debugId[funcId] = debugFuncId;
|
||||
debugFuncIdLookup[funcId] = debugFuncId;
|
||||
currentDebugScopeId.push(debugFuncId);
|
||||
|
||||
// DebugScope and DebugLine for parameter DebugDeclares
|
||||
@@ -2629,9 +2643,8 @@ void Builder::setupFunctionDebugInfo(Function* function, const char* name, const
|
||||
}
|
||||
|
||||
auto const& paramName = paramNames[p];
|
||||
auto const debugLocalVariableId = createDebugLocalVariable(debugId[paramTypeId], paramName, p + 1);
|
||||
auto const debugLocalVariableId = createDebugLocalVariable(getDebugType(paramTypeId), paramName, p + 1);
|
||||
auto const paramId = static_cast<Id>(firstParamId + p);
|
||||
debugId[paramId] = debugLocalVariableId;
|
||||
|
||||
if (passByRef) {
|
||||
makeDebugDeclare(debugLocalVariableId, paramId);
|
||||
@@ -2651,7 +2664,7 @@ Id Builder::makeDebugFunction([[maybe_unused]] Function* function, Id nameId, Id
|
||||
assert(function != nullptr);
|
||||
assert(nameId != 0);
|
||||
assert(funcTypeId != 0);
|
||||
assert(debugId[funcTypeId] != 0);
|
||||
assert(getDebugType(funcTypeId) != NoType);
|
||||
|
||||
Id funcId = getUniqueId();
|
||||
auto type = new Instruction(funcId, makeVoidType(), Op::OpExtInst);
|
||||
@@ -2659,7 +2672,7 @@ Id Builder::makeDebugFunction([[maybe_unused]] Function* function, Id nameId, Id
|
||||
type->addIdOperand(nonSemanticShaderDebugInfo);
|
||||
type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugFunction);
|
||||
type->addIdOperand(nameId);
|
||||
type->addIdOperand(debugId[funcTypeId]);
|
||||
type->addIdOperand(getDebugType(funcTypeId));
|
||||
type->addIdOperand(makeDebugSource(currentFileId)); // TODO: This points to file of definition instead of declaration
|
||||
type->addIdOperand(makeUintConstant(currentLine)); // TODO: This points to line of definition instead of declaration
|
||||
type->addIdOperand(makeUintConstant(0)); // column
|
||||
@@ -2754,14 +2767,15 @@ void Builder::enterFunction(Function const* function)
|
||||
if (emitNonSemanticShaderDebugInfo) {
|
||||
// Initialize scope state
|
||||
Id funcId = function->getFuncId();
|
||||
currentDebugScopeId.push(debugId[funcId]);
|
||||
Id debugFuncId = getDebugFunction(funcId);
|
||||
currentDebugScopeId.push(debugFuncId);
|
||||
// Create DebugFunctionDefinition
|
||||
spv::Id resultId = getUniqueId();
|
||||
Instruction* defInst = new Instruction(resultId, makeVoidType(), Op::OpExtInst);
|
||||
defInst->reserveOperands(4);
|
||||
defInst->addIdOperand(nonSemanticShaderDebugInfo);
|
||||
defInst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugFunctionDefinition);
|
||||
defInst->addIdOperand(debugId[funcId]);
|
||||
defInst->addIdOperand(debugFuncId);
|
||||
defInst->addIdOperand(funcId);
|
||||
addInstruction(std::unique_ptr<Instruction>(defInst));
|
||||
}
|
||||
@@ -2855,14 +2869,11 @@ Id Builder::createVariable(Decoration precision, StorageClass storageClass, Id t
|
||||
// We may emulate some local variables as global variable with private storage in SPIR-V, but we still want to
|
||||
// treat them as local variables in debug info.
|
||||
if (storageClass == StorageClass::Function || (currentFunction && storageClass == StorageClass::Private)) {
|
||||
auto const debugLocalVariableId = createDebugLocalVariable(debugId[type], name);
|
||||
debugId[inst->getResultId()] = debugLocalVariableId;
|
||||
|
||||
auto const debugLocalVariableId = createDebugLocalVariable(getDebugType(type), name);
|
||||
makeDebugDeclare(debugLocalVariableId, inst->getResultId());
|
||||
}
|
||||
else {
|
||||
auto const debugResultId = createDebugGlobalVariable(debugId[type], name, inst->getResultId());
|
||||
debugId[inst->getResultId()] = debugResultId;
|
||||
createDebugGlobalVariable(getDebugType(type), name, inst->getResultId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
77
3rdparty/glslang/SPIRV/SpvBuilder.h
vendored
77
3rdparty/glslang/SPIRV/SpvBuilder.h
vendored
@@ -208,10 +208,20 @@ public:
|
||||
|
||||
// Maps the given OpType Id to a Non-Semantic DebugType Id.
|
||||
Id getDebugType(Id type) {
|
||||
if (emitNonSemanticShaderDebugInfo) {
|
||||
return debugId[type];
|
||||
if (auto it = debugTypeIdLookup.find(type); it != debugTypeIdLookup.end()) {
|
||||
return it->second;
|
||||
}
|
||||
return 0;
|
||||
|
||||
return NoType;
|
||||
}
|
||||
|
||||
// Maps the given OpFunction Id to a Non-Semantic DebugFunction Id.
|
||||
Id getDebugFunction(Id func) {
|
||||
if (auto it = debugFuncIdLookup.find(func); it != debugFuncIdLookup.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return NoResult;
|
||||
}
|
||||
|
||||
// For creating new types (will return old type if the requested one was already made).
|
||||
@@ -1031,8 +1041,58 @@ protected:
|
||||
|
||||
// not output, internally used for quick & dirty canonical (unique) creation
|
||||
|
||||
// Key for scalar constants (handles both 32-bit and 64-bit)
|
||||
struct ScalarConstantKey {
|
||||
unsigned int typeClass; // OpTypeInt, OpTypeFloat, OpTypeBool
|
||||
unsigned int opcode; // OpConstant, OpSpecConstant, OpConstantTrue, etc.
|
||||
Id typeId; // The specific type
|
||||
unsigned value1; // First operand (or only operand)
|
||||
unsigned value2; // Second operand (0 for single-operand constants)
|
||||
|
||||
bool operator==(const ScalarConstantKey& other) const {
|
||||
return typeClass == other.typeClass &&
|
||||
opcode == other.opcode &&
|
||||
typeId == other.typeId &&
|
||||
value1 == other.value1 &&
|
||||
value2 == other.value2;
|
||||
}
|
||||
};
|
||||
|
||||
struct ScalarConstantKeyHash {
|
||||
// 64/32 bit mix function from MurmurHash3
|
||||
inline std::size_t hash_mix(std::size_t h) const {
|
||||
if constexpr (sizeof(std::size_t) == 8) {
|
||||
h ^= h >> 33;
|
||||
h *= UINT64_C(0xff51afd7ed558ccd);
|
||||
h ^= h >> 33;
|
||||
h *= UINT64_C(0xc4ceb9fe1a85ec53);
|
||||
h ^= h >> 33;
|
||||
return h;
|
||||
} else {
|
||||
h ^= h >> 16;
|
||||
h *= UINT32_C(0x85ebca6b);
|
||||
h ^= h >> 13;
|
||||
h *= UINT32_C(0xc2b2ae35);
|
||||
h ^= h >> 16;
|
||||
return h;
|
||||
}
|
||||
}
|
||||
|
||||
// Hash combine from boost
|
||||
inline std::size_t hash_combine(std::size_t seed, std::size_t v) const {
|
||||
return hash_mix(seed + 0x9e3779b9 + v);
|
||||
}
|
||||
|
||||
std::size_t operator()(const ScalarConstantKey& k) const {
|
||||
size_t hash1 = hash_combine(std::hash<unsigned>{}(k.typeClass), std::hash<unsigned>{}(k.opcode));
|
||||
size_t hash2 = hash_combine(std::hash<Id>{}(k.value1), std::hash<unsigned>{}(k.value2));
|
||||
size_t hash3 = hash_combine(hash1, hash2);
|
||||
return hash_combine(hash3, std::hash<unsigned>{}(k.typeId));
|
||||
}
|
||||
};
|
||||
|
||||
// map type opcodes to constant inst.
|
||||
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedConstants;
|
||||
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedCompositeConstants;
|
||||
// map struct-id to constant instructions
|
||||
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedStructConstants;
|
||||
// map type opcodes to type instructions
|
||||
@@ -1041,6 +1101,8 @@ protected:
|
||||
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedDebugTypes;
|
||||
// list of OpConstantNull instructions
|
||||
std::vector<Instruction*> nullConstants;
|
||||
// map scalar constants to result IDs
|
||||
std::unordered_map<ScalarConstantKey, Id, ScalarConstantKeyHash> groupedScalarConstantResultIDs;
|
||||
|
||||
// Track which types have explicit layouts, to avoid reusing in storage classes without layout.
|
||||
// Currently only tracks array types.
|
||||
@@ -1058,8 +1120,11 @@ protected:
|
||||
// map from include file name ids to their contents
|
||||
std::map<spv::Id, const std::string*> includeFiles;
|
||||
|
||||
// map from core id to debug id
|
||||
std::map <spv::Id, spv::Id> debugId;
|
||||
// maps from OpTypeXXX id to DebugTypeXXX id
|
||||
std::unordered_map<spv::Id, spv::Id> debugTypeIdLookup;
|
||||
|
||||
// maps from OpFunction id to DebugFunction id
|
||||
std::unordered_map<spv::Id, spv::Id> debugFuncIdLookup;
|
||||
|
||||
// map from file name string id to DebugSource id
|
||||
std::unordered_map<spv::Id, spv::Id> debugSourceId;
|
||||
|
||||
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 16
|
||||
#define GLSLANG_VERSION_MINOR 0
|
||||
#define GLSLANG_VERSION_MINOR 1
|
||||
#define GLSLANG_VERSION_PATCH 0
|
||||
#define GLSLANG_VERSION_FLAVOR ""
|
||||
|
||||
|
||||
@@ -4188,6 +4188,10 @@ void TParseContext::reservedErrorCheck(const TSourceLoc& loc, const TString& ide
|
||||
// "Identifiers starting with "gl_" are reserved for use by OpenGL, and may not be
|
||||
// declared in a shader; this results in a compile-time error."
|
||||
if (! symbolTable.atBuiltInLevel()) {
|
||||
// The extension GL_EXT_conservative_depth allows us to declare "gl_FragDepth".
|
||||
if (identifier == "gl_FragDepth" && extensionTurnedOn(E_GL_EXT_conservative_depth))
|
||||
return;
|
||||
|
||||
if (builtInName(identifier) && !extensionTurnedOn(E_GL_EXT_spirv_intrinsics))
|
||||
// The extension GL_EXT_spirv_intrinsics allows us to declare identifiers starting with "gl_".
|
||||
error(loc, "identifiers starting with \"gl_\" are reserved", identifier.c_str(), "");
|
||||
@@ -5830,7 +5834,8 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS
|
||||
|
||||
bool nonEsRedecls = (!isEsProfile() && (version >= 130 || identifier == "gl_TexCoord"));
|
||||
bool esRedecls = (isEsProfile() &&
|
||||
(version >= 320 || extensionsTurnedOn(Num_AEP_shader_io_blocks, AEP_shader_io_blocks)));
|
||||
(version >= 320 || extensionsTurnedOn(Num_AEP_shader_io_blocks, AEP_shader_io_blocks) ||
|
||||
(identifier == "gl_FragDepth" && extensionTurnedOn(E_GL_EXT_conservative_depth))));
|
||||
if (! esRedecls && ! nonEsRedecls)
|
||||
return nullptr;
|
||||
|
||||
@@ -6535,6 +6540,9 @@ void TParseContext::finish()
|
||||
if (parsingBuiltins)
|
||||
return;
|
||||
|
||||
// Forward builtin alias to AST for later use
|
||||
intermediate.setBuiltinAliasLookup(symbolTable.collectBuiltinAlias());
|
||||
|
||||
// Check on array indexes for ES 2.0 (version 100) limitations.
|
||||
for (size_t i = 0; i < needsIndexLimitationChecking.size(); ++i)
|
||||
constantIndexExpressionCheck(needsIndexLimitationChecking[i]);
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
#include "../Include/InfoSink.h"
|
||||
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace glslang {
|
||||
|
||||
@@ -505,6 +506,11 @@ public:
|
||||
retargetedSymbols.push_back({from, to});
|
||||
}
|
||||
|
||||
void collectRetargetedSymbols(std::unordered_multimap<std::string, std::string> &out) const {
|
||||
for (const auto &[fromName, toName] : retargetedSymbols)
|
||||
out.insert({std::string{toName}, std::string{fromName}});
|
||||
}
|
||||
|
||||
TSymbol* find(const TString& name) const
|
||||
{
|
||||
tLevel::const_iterator it = level.find(name);
|
||||
@@ -662,9 +668,10 @@ public:
|
||||
//
|
||||
protected:
|
||||
static const uint32_t LevelFlagBitOffset = 56;
|
||||
static const int globalLevel = 3;
|
||||
static constexpr int builtinLevel = 2;
|
||||
static constexpr int globalLevel = 3;
|
||||
static bool isSharedLevel(int level) { return level <= 1; } // exclude all per-compile levels
|
||||
static bool isBuiltInLevel(int level) { return level <= 2; } // exclude user globals
|
||||
static bool isBuiltInLevel(int level) { return level <= builtinLevel; } // exclude user globals
|
||||
static bool isGlobalLevel(int level) { return level <= globalLevel; } // include user globals
|
||||
public:
|
||||
bool isEmpty() { return table.size() == 0; }
|
||||
@@ -829,6 +836,13 @@ public:
|
||||
table[level]->retargetSymbol(from, to);
|
||||
}
|
||||
|
||||
std::unordered_multimap<std::string, std::string> collectBuiltinAlias() {
|
||||
std::unordered_multimap<std::string, std::string> allRetargets;
|
||||
for (int level = 0; level <= std::min(currentLevel(), builtinLevel); ++level)
|
||||
table[level]->collectRetargetedSymbols(allRetargets);
|
||||
|
||||
return allRetargets;
|
||||
}
|
||||
|
||||
// Find of a symbol that returns how many layers deep of nested
|
||||
// structures-with-member-functions ('this' scopes) deep the symbol was
|
||||
|
||||
@@ -728,8 +728,8 @@ void TParseVersions::getPreamble(std::string& preamble)
|
||||
case EShLangClosestHit: preamble += "#define GL_CLOSEST_HIT_SHADER_EXT 1 \n"; break;
|
||||
case EShLangMiss: preamble += "#define GL_MISS_SHADER_EXT 1 \n"; break;
|
||||
case EShLangCallable: preamble += "#define GL_CALLABLE_SHADER_EXT 1 \n"; break;
|
||||
case EShLangTask: preamble += "#define GL_TASK_SHADER_NV 1 \n"; break;
|
||||
case EShLangMesh: preamble += "#define GL_MESH_SHADER_NV 1 \n"; break;
|
||||
case EShLangTask: preamble += "#define GL_TASK_SHADER_EXT 1 \n"; break;
|
||||
case EShLangMesh: preamble += "#define GL_MESH_SHADER_EXT 1 \n"; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include <functional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
class TInfoSink;
|
||||
@@ -1161,6 +1162,13 @@ public:
|
||||
void updateNumericFeature(TNumericFeatures::feature f, bool on)
|
||||
{ on ? numericFeatures.insert(f) : numericFeatures.erase(f); }
|
||||
|
||||
void setBuiltinAliasLookup(std::unordered_multimap<std::string, std::string> symbolMap) {
|
||||
builtinAliasLookup = std::move(symbolMap);
|
||||
}
|
||||
const std::unordered_multimap<std::string, std::string>& getBuiltinAliasLookup() const {
|
||||
return builtinAliasLookup;
|
||||
}
|
||||
|
||||
protected:
|
||||
TIntermSymbol* addSymbol(long long Id, const TString&, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
|
||||
void error(TInfoSink& infoSink, const TSourceLoc* loc, EShMessages messages, const char*, EShLanguage unitStage = EShLangCount);
|
||||
@@ -1335,6 +1343,9 @@ protected:
|
||||
// Included text. First string is a name, second is the included text
|
||||
std::map<std::string, std::string> includeText;
|
||||
|
||||
// Maps from canonical symbol name to alias symbol names
|
||||
std::unordered_multimap<std::string, std::string> builtinAliasLookup;
|
||||
|
||||
// for OpModuleProcessed, or equivalent
|
||||
TProcesses processes;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user