Skip to content

Commit

Permalink
[DirectX backend] emits metadata for DXIL version. (llvm#88350)
Browse files Browse the repository at this point in the history
Emit named metadata "dx.version" for DXIL version.

Default to DXIL 1.0
  • Loading branch information
python3kgae committed May 8, 2024
1 parent 3ceacd8 commit 665af09
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 0 deletions.
4 changes: 4 additions & 0 deletions llvm/include/llvm/TargetParser/Triple.h
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,10 @@ class Triple {
/// (SubArch). This should only be called with Vulkan SPIR-V triples.
VersionTuple getVulkanVersion() const;

/// Parse the DXIL version number from the DXIL version
/// (SubArch). This should only be called with DXIL triples.
VersionTuple getDXILVersion() const;

/// @}
/// @name Direct Component Access
/// @{
Expand Down
12 changes: 12 additions & 0 deletions llvm/lib/Target/DirectX/DXILMetadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,18 @@ void dxil::createShaderModelMD(Module &M) {
Entry->addOperand(MDNode::get(Ctx, Vals));
}

void dxil::createDXILVersionMD(Module &M) {
Triple TT(Triple::normalize(M.getTargetTriple()));
VersionTuple Ver = TT.getDXILVersion();
LLVMContext &Ctx = M.getContext();
IRBuilder<> B(Ctx);
NamedMDNode *Entry = M.getOrInsertNamedMetadata("dx.version");
Metadata *Vals[2];
Vals[0] = ConstantAsMetadata::get(B.getInt32(Ver.getMajor()));
Vals[1] = ConstantAsMetadata::get(B.getInt32(Ver.getMinor().value_or(0)));
Entry->addOperand(MDNode::get(Ctx, Vals));
}

static uint32_t getShaderStage(Triple::EnvironmentType Env) {
return (uint32_t)Env - (uint32_t)llvm::Triple::Pixel;
}
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/DirectX/DXILMetadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class ValidatorVersionMD {
};

void createShaderModelMD(Module &M);
void createDXILVersionMD(Module &M);
void createEntryMD(Module &M, const uint64_t ShaderFlags);

} // namespace dxil
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ bool DXILTranslateMetadata::runOnModule(Module &M) {
if (ValVerMD.isEmpty())
ValVerMD.update(VersionTuple(1, 0));
dxil::createShaderModelMD(M);
dxil::createDXILVersionMD(M);

const dxil::Resources &Res =
getAnalysis<DXILResourceWrapper>().getDXILResource();
Expand Down
11 changes: 11 additions & 0 deletions llvm/lib/TargetParser/Triple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1420,6 +1420,17 @@ VersionTuple Triple::getVulkanVersion() const {
return VersionTuple(0);
}

VersionTuple Triple::getDXILVersion() const {
if (getArch() != dxil || getOS() != ShaderModel)
llvm_unreachable("invalid DXIL triple");
StringRef Arch = getArchName();
Arch.consume_front("dxilv");
VersionTuple DXILVersion = parseVersionFromName(Arch);
// FIXME: validate DXIL version against Shader Model version.
// Tracked by https://github.com/llvm/llvm-project/issues/91388
return DXILVersion;
}

void Triple::setTriple(const Twine &Str) {
*this = Triple(Str);
}
Expand Down
12 changes: 12 additions & 0 deletions llvm/test/CodeGen/DirectX/Metadata/dxilVer-1.0.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
; RUN: opt -S -dxil-metadata-emit %s | FileCheck %s
target triple = "dxil-pc-shadermodel6.0-vertex"

; CHECK: !dx.version = !{![[DXVER:[0-9]+]]}
; CHECK: ![[DXVER]] = !{i32 1, i32 0}

define void @entry() #0 {
entry:
ret void
}

attributes #0 = { noinline nounwind "hlsl.shader"="vertex" }
12 changes: 12 additions & 0 deletions llvm/test/CodeGen/DirectX/Metadata/dxilVer-1.8.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
; RUN: opt -S -dxil-metadata-emit %s | FileCheck %s
target triple = "dxil-pc-shadermodel6.8-compute"

; CHECK: !dx.version = !{![[DXVER:[0-9]+]]}
; CHECK: ![[DXVER]] = !{i32 1, i32 8}

define void @entry() #0 {
entry:
ret void
}

attributes #0 = { noinline nounwind "hlsl.numthreads"="1,2,1" "hlsl.shader"="compute" }
79 changes: 79 additions & 0 deletions llvm/unittests/TargetParser/TripleTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,85 @@ TEST(TripleTest, ParsedIDs) {
EXPECT_EQ(VersionTuple(1, 3), T.getVulkanVersion());
EXPECT_EQ(Triple::Compute, T.getEnvironment());

T = Triple("dxilv1.0--shadermodel6.0-pixel");
EXPECT_EQ(Triple::dxil, T.getArch());
EXPECT_EQ(Triple::DXILSubArch_v1_0, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::ShaderModel, T.getOS());
EXPECT_EQ(VersionTuple(1, 0), T.getDXILVersion());
EXPECT_EQ(Triple::Pixel, T.getEnvironment());

T = Triple("dxilv1.1--shadermodel6.1-vertex");
EXPECT_EQ(Triple::dxil, T.getArch());
EXPECT_EQ(Triple::DXILSubArch_v1_1, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::ShaderModel, T.getOS());
EXPECT_EQ(VersionTuple(1, 1), T.getDXILVersion());
EXPECT_EQ(Triple::Vertex, T.getEnvironment());

T = Triple("dxilv1.2--shadermodel6.2-geometry");
EXPECT_EQ(Triple::dxil, T.getArch());
EXPECT_EQ(Triple::DXILSubArch_v1_2, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::ShaderModel, T.getOS());
EXPECT_EQ(VersionTuple(1, 2), T.getDXILVersion());
EXPECT_EQ(Triple::Geometry, T.getEnvironment());

T = Triple("dxilv1.3--shadermodel6.3-library");
EXPECT_EQ(Triple::dxil, T.getArch());
EXPECT_EQ(Triple::DXILSubArch_v1_3, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::ShaderModel, T.getOS());
EXPECT_EQ(VersionTuple(1, 3), T.getDXILVersion());
EXPECT_EQ(Triple::Library, T.getEnvironment());

T = Triple("dxilv1.4--shadermodel6.4-hull");
EXPECT_EQ(Triple::dxil, T.getArch());
EXPECT_EQ(Triple::DXILSubArch_v1_4, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::ShaderModel, T.getOS());
EXPECT_EQ(VersionTuple(1, 4), T.getDXILVersion());
EXPECT_EQ(Triple::Hull, T.getEnvironment());

T = Triple("dxilv1.5--shadermodel6.5-domain");
EXPECT_EQ(Triple::dxil, T.getArch());
EXPECT_EQ(Triple::DXILSubArch_v1_5, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::ShaderModel, T.getOS());
EXPECT_EQ(VersionTuple(1, 5), T.getDXILVersion());
EXPECT_EQ(Triple::Domain, T.getEnvironment());

T = Triple("dxilv1.6--shadermodel6.6-compute");
EXPECT_EQ(Triple::dxil, T.getArch());
EXPECT_EQ(Triple::DXILSubArch_v1_6, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::ShaderModel, T.getOS());
EXPECT_EQ(VersionTuple(1, 6), T.getDXILVersion());
EXPECT_EQ(Triple::Compute, T.getEnvironment());

T = Triple("dxilv1.7-unknown-shadermodel6.7-mesh");
EXPECT_EQ(Triple::dxil, T.getArch());
EXPECT_EQ(Triple::DXILSubArch_v1_7, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::ShaderModel, T.getOS());
EXPECT_EQ(VersionTuple(1, 7), T.getDXILVersion());
EXPECT_EQ(Triple::Mesh, T.getEnvironment());

T = Triple("dxilv1.8-unknown-shadermodel6.8-amplification");
EXPECT_EQ(Triple::dxil, T.getArch());
EXPECT_EQ(Triple::DXILSubArch_v1_8, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::ShaderModel, T.getOS());
EXPECT_EQ(VersionTuple(1, 8), T.getDXILVersion());
EXPECT_EQ(Triple::Amplification, T.getEnvironment());

T = Triple("dxilv1.8-unknown-shadermodel6.15-library");
EXPECT_EQ(Triple::dxil, T.getArch());
EXPECT_EQ(Triple::DXILSubArch_v1_8, T.getSubArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
EXPECT_EQ(Triple::ShaderModel, T.getOS());
EXPECT_EQ(VersionTuple(1, 8), T.getDXILVersion());

T = Triple("x86_64-unknown-fuchsia");
EXPECT_EQ(Triple::x86_64, T.getArch());
EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
Expand Down

0 comments on commit 665af09

Please sign in to comment.