[DXC] Add -metal flag to DXC driver (#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.
This commit is contained in:
Chris B
2025-03-07 17:28:41 -06:00
committed by GitHub
parent 23a44b925a
commit 0ea52234fc
8 changed files with 81 additions and 1 deletions

View File

@@ -75,9 +75,10 @@ public:
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 @@ public:
}
};
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

View File

@@ -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">;

View File

@@ -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) {}

View File

@@ -4669,6 +4669,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.

View File

@@ -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:

View File

@@ -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);
}

View File

@@ -29,6 +29,19 @@ public:
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 @@ public:
private:
mutable std::unique_ptr<tools::hlsl::Validator> Validator;
mutable std::unique_ptr<tools::hlsl::MetalConverter> MetalConverter;
};
} // end namespace toolchains

View File

@@ -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];
}