diff --git a/llvm/lib/Target/DirectX/DXILMetadata.h b/llvm/lib/Target/DirectX/DXILMetadata.h --- a/llvm/lib/Target/DirectX/DXILMetadata.h +++ b/llvm/lib/Target/DirectX/DXILMetadata.h @@ -30,6 +30,8 @@ bool isEmpty(); }; +void createShaderModelMD(Module &M); + } // namespace dxil } // namespace llvm diff --git a/llvm/lib/Target/DirectX/DXILMetadata.cpp b/llvm/lib/Target/DirectX/DXILMetadata.cpp --- a/llvm/lib/Target/DirectX/DXILMetadata.cpp +++ b/llvm/lib/Target/DirectX/DXILMetadata.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "DXILMetadata.h" +#include "llvm/ADT/Triple.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" @@ -38,3 +39,44 @@ } bool ValidatorVersionMD::isEmpty() { return Entry->getNumOperands() == 0; } + +static StringRef getShortShaderStage(Triple::EnvironmentType Env) { + switch (Env) { + case Triple::Pixel: + return "ps"; + case Triple::Vertex: + return "vs"; + case Triple::Geometry: + return "gs"; + case Triple::Hull: + return "hs"; + case Triple::Domain: + return "ds"; + case Triple::Compute: + return "cs"; + case Triple::Library: + return "lib"; + case Triple::Mesh: + return "ms"; + case Triple::Amplification: + return "as"; + default: + break; + } + llvm_unreachable("Unsupported environment for DXIL generation."); + return ""; +} + +void dxil::createShaderModelMD(Module &M) { + NamedMDNode *Entry = M.getOrInsertNamedMetadata("dx.shaderModel"); + Triple TT(M.getTargetTriple()); + VersionTuple Ver = TT.getOSVersion(); + LLVMContext &Ctx = M.getContext(); + IRBuilder<> B(Ctx); + + Metadata *Vals[3]; + Vals[0] = MDString::get(Ctx, getShortShaderStage(TT.getEnvironment())); + Vals[1] = ConstantAsMetadata::get(B.getInt32(Ver.getMajor())); + Vals[2] = ConstantAsMetadata::get(B.getInt32(Ver.getMinor().value_or(0))); + Entry->addOperand(MDNode::get(Ctx, Vals)); +} diff --git a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp --- a/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp +++ b/llvm/lib/Target/DirectX/DXILTranslateMetadata.cpp @@ -37,6 +37,7 @@ dxil::ValidatorVersionMD ValVerMD(M); if (ValVerMD.isEmpty()) ValVerMD.update(VersionTuple(1, 0)); + dxil::createShaderModelMD(M); return false; } diff --git a/llvm/test/CodeGen/DirectX/Metadata/shaderModel-as.ll b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-as.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-as.ll @@ -0,0 +1,5 @@ +; RUN: opt -S -dxil-metadata-emit %s | FileCheck %s +target triple = "dxil-pc-shadermodel6-amplification" + +; CHECK: !dx.shaderModel = !{![[SM:[0-9]+]]} +; CHECK: ![[SM]] = !{!"as", i32 6, i32 0} diff --git a/llvm/test/CodeGen/DirectX/Metadata/shaderModel-cs.ll b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-cs.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-cs.ll @@ -0,0 +1,5 @@ +; RUN: opt -S -dxil-metadata-emit %s | FileCheck %s +target triple = "dxil-pc-shadermodel6.6-compute" + +; CHECK: !dx.shaderModel = !{![[SM:[0-9]+]]} +; CHECK: ![[SM]] = !{!"cs", i32 6, i32 6} diff --git a/llvm/test/CodeGen/DirectX/Metadata/shaderModel-gs.ll b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-gs.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-gs.ll @@ -0,0 +1,5 @@ +; RUN: opt -S -dxil-metadata-emit %s | FileCheck %s +target triple = "dxil-pc-shadermodel6.6-geometry" + +; CHECK: !dx.shaderModel = !{![[SM:[0-9]+]]} +; CHECK: ![[SM]] = !{!"gs", i32 6, i32 6} diff --git a/llvm/test/CodeGen/DirectX/Metadata/shaderModel-hs.ll b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-hs.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-hs.ll @@ -0,0 +1,5 @@ +; RUN: opt -S -dxil-metadata-emit %s | FileCheck %s +target triple = "dxil-pc-shadermodel6.6-hull" + +; CHECK: !dx.shaderModel = !{![[SM:[0-9]+]]} +; CHECK: ![[SM]] = !{!"hs", i32 6, i32 6} diff --git a/llvm/test/CodeGen/DirectX/Metadata/shaderModel-lib.ll b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-lib.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-lib.ll @@ -0,0 +1,5 @@ +; RUN: opt -S -dxil-metadata-emit %s | FileCheck %s +target triple = "dxil-pc-shadermodel6.3-library" + +; CHECK: !dx.shaderModel = !{![[SM:[0-9]+]]} +; CHECK: ![[SM]] = !{!"lib", i32 6, i32 3} diff --git a/llvm/test/CodeGen/DirectX/Metadata/shaderModel-ms.ll b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-ms.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-ms.ll @@ -0,0 +1,5 @@ +; RUN: opt -S -dxil-metadata-emit %s | FileCheck %s +target triple = "dxil-pc-shadermodel6.6-mesh" + +; CHECK: !dx.shaderModel = !{![[SM:[0-9]+]]} +; CHECK: ![[SM]] = !{!"ms", i32 6, i32 6} diff --git a/llvm/test/CodeGen/DirectX/Metadata/shaderModel-ps.ll b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-ps.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-ps.ll @@ -0,0 +1,5 @@ +; RUN: opt -S -dxil-metadata-emit %s | FileCheck %s +target triple = "dxil-pc-shadermodel5.0-pixel" + +; CHECK: !dx.shaderModel = !{![[SM:[0-9]+]]} +; CHECK: ![[SM]] = !{!"ps", i32 5, i32 0} diff --git a/llvm/test/CodeGen/DirectX/Metadata/shaderModel-vs.ll b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-vs.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/DirectX/Metadata/shaderModel-vs.ll @@ -0,0 +1,5 @@ +; RUN: opt -S -dxil-metadata-emit %s | FileCheck %s +target triple = "dxil-pc-shadermodel-vertex" + +; CHECK: !dx.shaderModel = !{![[SM:[0-9]+]]} +; CHECK: ![[SM]] = !{!"vs", i32 0, i32 0}