https://github.com/llvm-beanz created https://github.com/llvm/llvm-project/pull/130173
This adds a flag to the DXC driver to enable calling the metal shader converter if it is available to convert the final shader output for metal. >From 0e5a24665c3a9522263b2ddfbce5f46e6a0e33c9 Mon Sep 17 00:00:00 2001 From: Chris Bieneman <chris.biene...@me.com> Date: Thu, 6 Mar 2025 13:25:16 -0600 Subject: [PATCH] [DXC] Add `-metal` flag to DXC driver This adds a flag to the DXC driver to enable calling the metal shader converter if it is available to convert the final shader output for metal. --- clang/include/clang/Driver/Action.h | 14 +++++++++++++- clang/include/clang/Driver/Options.td | 1 + clang/lib/Driver/Action.cpp | 8 ++++++++ clang/lib/Driver/Driver.cpp | 10 ++++++++++ clang/lib/Driver/ToolChain.cpp | 1 + clang/lib/Driver/ToolChains/HLSL.cpp | 20 ++++++++++++++++++++ clang/lib/Driver/ToolChains/HLSL.h | 14 ++++++++++++++ clang/test/Driver/HLSL/metal-converter.hlsl | 14 ++++++++++++++ 8 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 clang/test/Driver/HLSL/metal-converter.hlsl diff --git a/clang/include/clang/Driver/Action.h b/clang/include/clang/Driver/Action.h index e5307b0fcedd5..92bb19314e3d6 100644 --- a/clang/include/clang/Driver/Action.h +++ b/clang/include/clang/Driver/Action.h @@ -75,9 +75,10 @@ class Action { LinkerWrapperJobClass, StaticLibJobClass, BinaryAnalyzeJobClass, + BinaryTranslatorJobClass, JobClassFirst = PreprocessJobClass, - JobClassLast = BinaryAnalyzeJobClass + JobClassLast = BinaryTranslatorJobClass }; // The offloading kind determines if this action is binded to a particular @@ -675,6 +676,17 @@ class BinaryAnalyzeJobAction : public JobAction { } }; +class BinaryTranslatorJobAction : public JobAction { + void anchor() override; + +public: + BinaryTranslatorJobAction(Action *Input, types::ID Type); + + static bool classof(const Action *A) { + return A->getKind() == BinaryTranslatorJobClass; + } +}; + } // namespace driver } // namespace clang diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index d0414aba35209..6ed579cb88d90 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -9085,6 +9085,7 @@ def : Option<["/", "-"], "Qembed_debug", KIND_FLAG>, Group<dxc_Group>, HelpText<"Embed PDB in shader container (ignored)">; def spirv : DXCFlag<"spirv">, HelpText<"Generate SPIR-V code">; +def metal : DXCFlag<"metal">, HelpText<"Generate Metal library">; def fspv_target_env_EQ : Joined<["-"], "fspv-target-env=">, Group<dxc_Group>, HelpText<"Specify the target environment">, Values<"vulkan1.2, vulkan1.3">; diff --git a/clang/lib/Driver/Action.cpp b/clang/lib/Driver/Action.cpp index 0899b8ef00152..ec09726044812 100644 --- a/clang/lib/Driver/Action.cpp +++ b/clang/lib/Driver/Action.cpp @@ -50,6 +50,8 @@ const char *Action::getClassName(ActionClass AC) { return "static-lib-linker"; case BinaryAnalyzeJobClass: return "binary-analyzer"; + case BinaryTranslatorJobClass: + return "binary-translator"; } llvm_unreachable("invalid class"); @@ -459,3 +461,9 @@ void BinaryAnalyzeJobAction::anchor() {} BinaryAnalyzeJobAction::BinaryAnalyzeJobAction(Action *Input, types::ID Type) : JobAction(BinaryAnalyzeJobClass, Input, Type) {} + +void BinaryTranslatorJobAction::anchor() {} + +BinaryTranslatorJobAction::BinaryTranslatorJobAction(Action *Input, + types::ID Type) + : JobAction(BinaryTranslatorJobClass, Input, Type) {} diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index eca96c1cce7f7..565d804aa8187 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -4672,6 +4672,16 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args, Actions.push_back(C.MakeAction<BinaryAnalyzeJobAction>( LastAction, types::TY_DX_CONTAINER)); } + if (Args.getLastArg(options::OPT_metal)) { + Action *LastAction = Actions.back(); + // Metal shader converter runs on DXIL containers, which can either be + // validated (in which case they are TY_DX_CONTAINER), or unvalidated + // (TY_OBJECT). + if (LastAction->getType() == types::TY_DX_CONTAINER || + LastAction->getType() == types::TY_Object) + Actions.push_back(C.MakeAction<BinaryTranslatorJobAction>( + LastAction, types::TY_DX_CONTAINER)); + } } // Claim ignored clang-cl options. diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 65acbe8a9dbea..fa810457a06cd 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -639,6 +639,7 @@ Tool *ToolChain::getTool(Action::ActionClass AC) const { case Action::DsymutilJobClass: case Action::VerifyDebugInfoJobClass: case Action::BinaryAnalyzeJobClass: + case Action::BinaryTranslatorJobClass: llvm_unreachable("Invalid tool kind."); case Action::CompileJobClass: diff --git a/clang/lib/Driver/ToolChains/HLSL.cpp b/clang/lib/Driver/ToolChains/HLSL.cpp index ad44c2cfcd811..62e4d14390b90 100644 --- a/clang/lib/Driver/ToolChains/HLSL.cpp +++ b/clang/lib/Driver/ToolChains/HLSL.cpp @@ -198,6 +198,22 @@ void tools::hlsl::Validator::ConstructJob(Compilation &C, const JobAction &JA, Exec, CmdArgs, Inputs, Input)); } +void tools::hlsl::MetalConverter::ConstructJob( + Compilation &C, const JobAction &JA, const InputInfo &Output, + const InputInfoList &Inputs, const ArgList &Args, + const char *LinkingOutput) const { + std::string MSCPath = getToolChain().GetProgramPath("metal-shaderconverter"); + ArgStringList CmdArgs; + const InputInfo &Input = Inputs[0]; + CmdArgs.push_back(Input.getFilename()); + CmdArgs.push_back("-o"); + CmdArgs.push_back(Input.getFilename()); + + const char *Exec = Args.MakeArgString(MSCPath); + C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(), + Exec, CmdArgs, Inputs, Input)); +} + /// DirectX Toolchain HLSLToolChain::HLSLToolChain(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) @@ -214,6 +230,10 @@ Tool *clang::driver::toolchains::HLSLToolChain::getTool( if (!Validator) Validator.reset(new tools::hlsl::Validator(*this)); return Validator.get(); + case Action::BinaryTranslatorJobClass: + if (!MetalConverter) + MetalConverter.reset(new tools::hlsl::MetalConverter(*this)); + return MetalConverter.get(); default: return ToolChain::getTool(AC); } diff --git a/clang/lib/Driver/ToolChains/HLSL.h b/clang/lib/Driver/ToolChains/HLSL.h index b2a31aabab7dc..86dd65f0b80c6 100644 --- a/clang/lib/Driver/ToolChains/HLSL.h +++ b/clang/lib/Driver/ToolChains/HLSL.h @@ -29,6 +29,19 @@ class LLVM_LIBRARY_VISIBILITY Validator : public Tool { const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override; }; + +class LLVM_LIBRARY_VISIBILITY MetalConverter : public Tool { +public: + MetalConverter(const ToolChain &TC) + : Tool("hlsl::MetalConverter", "metal-shaderconverter", TC) {} + + bool hasIntegratedCPP() const override { return false; } + + void ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, const InputInfoList &Inputs, + const llvm::opt::ArgList &TCArgs, + const char *LinkingOutput) const override; +}; } // namespace hlsl } // namespace tools @@ -57,6 +70,7 @@ class LLVM_LIBRARY_VISIBILITY HLSLToolChain : public ToolChain { private: mutable std::unique_ptr<tools::hlsl::Validator> Validator; + mutable std::unique_ptr<tools::hlsl::MetalConverter> MetalConverter; }; } // end namespace toolchains diff --git a/clang/test/Driver/HLSL/metal-converter.hlsl b/clang/test/Driver/HLSL/metal-converter.hlsl new file mode 100644 index 0000000000000..4402e5044dc7b --- /dev/null +++ b/clang/test/Driver/HLSL/metal-converter.hlsl @@ -0,0 +1,14 @@ +// RUN: %clang_dxc -T cs_6_0 %s -metal -Fo tmp.mtl -### 2>&1 | FileCheck %s +// RUN: %clang_dxc -T cs_6_0 %s -metal -Vd -Fo tmp.mtl -### 2>&1 | FileCheck %s +// CHECK: "{{.*}}metal-shaderconverter{{(.exe)?}}" "tmp.mtl" "-o" "tmp.mtl" + +// RUN: %clang_dxc -T cs_6_0 %s -metal -### 2>&1 | FileCheck --check-prefix=NO_MTL %s +// NO_MTL-NOT: metal-shaderconverter + +RWBuffer<float4> In : register(u0, space0); +RWBuffer<float4> Out : register(u1, space4); + +[numthreads(1,1,1)] +void main(uint GI : SV_GroupIndex) { + Out[GI] = In[GI] * In[GI]; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits