Skip to content

Commit a8fec46

Browse files
antiagainstehsannas
authored andcommitted
[spirv] Allow aliasing builtin variables
This behavior is supported by FXC. Fixes microsoft#1690
1 parent 71e2bf1 commit a8fec46

File tree

3 files changed

+48
-3
lines changed

3 files changed

+48
-3
lines changed

tools/clang/include/clang/SPIRV/SpirvBuilder.h

+11
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,17 @@ class SpirvBuilder {
594594

595595
llvm::SetVector<spv::Capability> existingCapabilities;
596596
llvm::SetVector<Extension> existingExtensions;
597+
598+
/// A struct containing information regarding a builtin variable.
599+
struct BuiltInVarInfo {
600+
BuiltInVarInfo(spv::StorageClass s, spv::BuiltIn b, SpirvVariable *v)
601+
: sc(s), builtIn(b), variable(v) {}
602+
spv::StorageClass sc;
603+
spv::BuiltIn builtIn;
604+
SpirvVariable *variable;
605+
};
606+
/// Used as caches for all created builtin variables to avoid duplication.
607+
llvm::SmallVector<BuiltInVarInfo, 16> builtinVars;
597608
};
598609

599610
void SpirvBuilder::requireCapability(spv::Capability cap, SourceLocation loc) {

tools/clang/lib/SPIRV/DeclResultIdMapper.cpp

+9-3
Original file line numberDiff line numberDiff line change
@@ -1013,8 +1013,14 @@ std::vector<SpirvVariable *> DeclResultIdMapper::collectStageVars() const {
10131013
for (auto var : glPerVertex.getStageOutVars())
10141014
vars.push_back(var);
10151015

1016-
for (const auto &var : stageVars)
1017-
vars.push_back(var.getSpirvInstr());
1016+
llvm::DenseSet<SpirvInstruction *> seenVars;
1017+
for (const auto &var : stageVars) {
1018+
auto *instr = var.getSpirvInstr();
1019+
if (seenVars.count(instr) == 0) {
1020+
vars.push_back(instr);
1021+
seenVars.insert(instr);
1022+
}
1023+
}
10181024

10191025
return vars;
10201026
}
@@ -1115,7 +1121,7 @@ bool DeclResultIdMapper::checkSemanticDuplication(bool forInput) {
11151121
}
11161122

11171123
// Allow builtin variables to alias each other. We already have uniqify
1118-
// mechanism in ModuleBuilder.
1124+
// mechanism in SpirvBuilder.
11191125
if (var.isSpirvBuitin())
11201126
continue;
11211127

tools/clang/lib/SPIRV/SpirvBuilder.cpp

+28
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,17 @@ SpirvVariable *SpirvBuilder::addStageBuiltinVar(const SpirvType *type,
851851
spv::StorageClass storageClass,
852852
spv::BuiltIn builtin,
853853
SourceLocation loc) {
854+
// If the built-in variable has already been added (via a built-in alias),
855+
// return the existing variable.
856+
auto found = std::find_if(
857+
builtinVars.begin(), builtinVars.end(),
858+
[storageClass, builtin](const BuiltInVarInfo &varInfo) {
859+
return varInfo.sc == storageClass && varInfo.builtIn == builtin;
860+
});
861+
if (found != builtinVars.end()) {
862+
return found->variable;
863+
}
864+
854865
// Note: We store the underlying type in the variable, *not* the pointer type.
855866
auto *var =
856867
new (context) SpirvVariable(/*QualType*/ {}, /*id*/ 0, loc, storageClass);
@@ -862,13 +873,27 @@ SpirvVariable *SpirvBuilder::addStageBuiltinVar(const SpirvType *type,
862873
loc, var, spv::Decoration::BuiltIn, {static_cast<uint32_t>(builtin)});
863874
module->addDecoration(decor);
864875

876+
// Add variable to cache.
877+
builtinVars.emplace_back(storageClass, builtin, var);
878+
865879
return var;
866880
}
867881

868882
SpirvVariable *SpirvBuilder::addStageBuiltinVar(QualType type,
869883
spv::StorageClass storageClass,
870884
spv::BuiltIn builtin,
871885
SourceLocation loc) {
886+
// If the built-in variable has already been added (via a built-in alias),
887+
// return the existing variable.
888+
auto found = std::find_if(
889+
builtinVars.begin(), builtinVars.end(),
890+
[storageClass, builtin](const BuiltInVarInfo &varInfo) {
891+
return varInfo.sc == storageClass && varInfo.builtIn == builtin;
892+
});
893+
if (found != builtinVars.end()) {
894+
return found->variable;
895+
}
896+
872897
// Note: We store the underlying type in the variable, *not* the pointer type.
873898
auto *var = new (context) SpirvVariable(type, /*id*/ 0, loc, storageClass);
874899
module->addVariable(var);
@@ -878,6 +903,9 @@ SpirvVariable *SpirvBuilder::addStageBuiltinVar(QualType type,
878903
loc, var, spv::Decoration::BuiltIn, {static_cast<uint32_t>(builtin)});
879904
module->addDecoration(decor);
880905

906+
// Add variable to cache.
907+
builtinVars.emplace_back(storageClass, builtin, var);
908+
881909
return var;
882910
}
883911

0 commit comments

Comments
 (0)