Skip to content

Commit

Permalink
[spirv] Allow aliasing builtin variables (#1691)
Browse files Browse the repository at this point in the history
This behavior is supported by FXC.

Fixes #1690
  • Loading branch information
antiagainst authored and ehsannas committed Nov 11, 2018
1 parent d75f96a commit de62ed4
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 2 deletions.
13 changes: 13 additions & 0 deletions tools/clang/include/clang/SPIRV/ModuleBuilder.h
Expand Up @@ -524,6 +524,19 @@ class ModuleBuilder {
InstBuilder instBuilder;
std::vector<uint32_t> constructSite; ///< InstBuilder construction site.
uint32_t glslExtSetId; ///< The <result-id> of GLSL extended instruction set.

/// A struct containing information regarding a builtin variable.
struct BuiltInVarInfo {
BuiltInVarInfo(spv::StorageClass s, spv::BuiltIn b, uint32_t v)
: sc(s), builtIn(b), variable(v) {}

spv::StorageClass sc;
spv::BuiltIn builtIn;
uint32_t variable;
};

/// Used as caches for all created builtin variables to avoid duplication.
llvm::SmallVector<BuiltInVarInfo, 16> builtinVars;
};

SPIRVContext *ModuleBuilder::getSPIRVContext() { return &theContext; }
Expand Down
15 changes: 13 additions & 2 deletions tools/clang/lib/SPIRV/DeclResultIdMapper.cpp
Expand Up @@ -873,8 +873,14 @@ std::vector<uint32_t> DeclResultIdMapper::collectStageVars() const {
for (auto var : glPerVertex.getStageOutVars())
vars.push_back(var);

for (const auto &var : stageVars)
vars.push_back(var.getSpirvId());
llvm::DenseSet<uint32_t> seenVars;
for (const auto &var : stageVars) {
const auto id = var.getSpirvId();
if (seenVars.count(id) == 0) {
vars.push_back(id);
seenVars.insert(id);
}
}

return vars;
}
Expand Down Expand Up @@ -974,6 +980,11 @@ bool DeclResultIdMapper::checkSemanticDuplication(bool forInput) {
continue;
}

// Allow builtin variables to alias each other. We already have uniqify
// mechanism in ModuleBuilder.
if (var.isSpirvBuitin())
continue;

if (forInput && var.getSigPoint()->IsInput()) {
if (seenSemantics.count(s)) {
emitError("input semantic '%0' used more than once", {}) << s;
Expand Down
11 changes: 11 additions & 0 deletions tools/clang/lib/SPIRV/ModuleBuilder.cpp
Expand Up @@ -762,6 +762,15 @@ uint32_t ModuleBuilder::addStageIOVar(uint32_t type,

uint32_t ModuleBuilder::addStageBuiltinVar(uint32_t type, spv::StorageClass sc,
spv::BuiltIn builtin) {
auto found =
std::find_if(builtinVars.begin(), builtinVars.end(),
[sc, builtin](const BuiltInVarInfo &varInfo) {
return varInfo.sc == sc && varInfo.builtIn == builtin;
});
if (found != builtinVars.end()) {
return found->variable;
}

const uint32_t pointerType = getPointerType(type, sc);
const uint32_t varId = theContext.takeNextId();
instBuilder.opVariable(pointerType, varId, sc, llvm::None).x();
Expand All @@ -771,6 +780,8 @@ uint32_t ModuleBuilder::addStageBuiltinVar(uint32_t type, spv::StorageClass sc,
const Decoration *d = Decoration::getBuiltIn(theContext, builtin);
theModule.addDecoration(d, varId);

builtinVars.emplace_back(sc, builtin, varId);

return varId;
}

Expand Down
21 changes: 21 additions & 0 deletions tools/clang/test/CodeGenSPIRV/spirv.interface.alias-builtin.hlsl
@@ -0,0 +1,21 @@
// Run: %dxc -T ps_6_0 -E main

// CHECK: OpEntryPoint Fragment %main "main" %gl_FragCoord %out_var_SV_Target

// CHECK: %gl_FragCoord = OpVariable %_ptr_Input_v4float Input
// CHECK-NOT: {{%\d+}} = OpVariable %_ptr_Input_v4float Input

struct PSInput {
float4 a : SV_Position;
float4 b : SV_Position;
};

// CHECK: [[a:%\d+]] = OpLoad %v4float %gl_FragCoord
// CHECK-NEXT: [[b:%\d+]] = OpLoad %v4float %gl_FragCoord
// CHECK-NEXT: {{%\d+}} = OpCompositeConstruct %PSInput [[a]] [[b]]

float4 main(PSInput input) : SV_Target
{
return input.a + input.b;
}

4 changes: 4 additions & 0 deletions tools/clang/unittests/SPIRV/CodeGenSPIRVTest.cpp
Expand Up @@ -1294,6 +1294,10 @@ TEST_F(FileTest, SpirvStageIOInterfacePS) {
runFileTest("spirv.interface.ps.hlsl");
}

TEST_F(FileTest, SpirvStageIOAliasBuiltIn) {
runFileTest("spirv.interface.alias-builtin.hlsl");
}

TEST_F(FileTest, SpirvStageIO16bitTypes) {
runFileTest("spirv.stage-io.16bit.hlsl");
}
Expand Down

0 comments on commit de62ed4

Please sign in to comment.