14#include "llvm/ADT/StringSwitch.h"
15#include "llvm/TargetParser/Triple.h"
26const unsigned OfflineLibMinor = 0xF;
28bool isLegalShaderModel(Triple &T) {
29 if (T.getOS() != Triple::OSType::ShaderModel)
32 auto Version = T.getOSVersion();
33 if (Version.getBuild())
35 if (Version.getSubminor())
38 auto Kind = T.getEnvironment();
43 case Triple::EnvironmentType::Vertex:
44 case Triple::EnvironmentType::Hull:
45 case Triple::EnvironmentType::Domain:
46 case Triple::EnvironmentType::Geometry:
47 case Triple::EnvironmentType::Pixel:
48 case Triple::EnvironmentType::Compute: {
49 VersionTuple MinVer(4, 0);
50 return MinVer <= Version;
52 case Triple::EnvironmentType::Library: {
53 VersionTuple SM6x(6, OfflineLibMinor);
57 VersionTuple MinVer(6, 3);
58 return MinVer <= Version;
60 case Triple::EnvironmentType::Amplification:
61 case Triple::EnvironmentType::Mesh: {
62 VersionTuple MinVer(6, 5);
63 return MinVer <= Version;
69std::optional<std::string> tryParseProfile(StringRef Profile) {
72 Profile.split(Parts,
"_");
73 if (Parts.size() != 3)
76 Triple::EnvironmentType
Kind =
77 StringSwitch<Triple::EnvironmentType>(Parts[0])
78 .Case(
"ps", Triple::EnvironmentType::Pixel)
79 .Case(
"vs", Triple::EnvironmentType::Vertex)
80 .Case(
"gs", Triple::EnvironmentType::Geometry)
81 .Case(
"hs", Triple::EnvironmentType::Hull)
82 .Case(
"ds", Triple::EnvironmentType::Domain)
83 .Case(
"cs", Triple::EnvironmentType::Compute)
84 .Case(
"lib", Triple::EnvironmentType::Library)
85 .Case(
"ms", Triple::EnvironmentType::Mesh)
86 .Case(
"as", Triple::EnvironmentType::Amplification)
87 .Default(Triple::EnvironmentType::UnknownEnvironment);
88 if (Kind == Triple::EnvironmentType::UnknownEnvironment)
91 unsigned long long Major = 0;
92 if (llvm::getAsUnsignedInteger(Parts[1], 0, Major))
95 unsigned long long Minor = 0;
96 if (Parts[2] ==
"x" && Kind == Triple::EnvironmentType::Library)
97 Minor = OfflineLibMinor;
98 else if (llvm::getAsUnsignedInteger(Parts[2], 0, Minor))
103 T.setArch(Triple::ArchType::dxil);
104 T.setOSName(Triple::getOSTypeName(Triple::OSType::ShaderModel).str() +
106 T.setEnvironment(Kind);
107 if (isLegalShaderModel(T))
108 return T.getTriple();
113bool isLegalValidatorVersion(StringRef ValVersionStr,
const Driver &D) {
114 VersionTuple Version;
115 if (Version.tryParse(ValVersionStr) || Version.getBuild() ||
116 Version.getSubminor() || !Version.getMinor()) {
117 D.
Diag(diag::err_drv_invalid_format_dxil_validator_version)
122 uint64_t Major = Version.getMajor();
123 uint64_t Minor = *Version.getMinor();
124 if (Major == 0 && Minor != 0) {
125 D.
Diag(diag::err_drv_invalid_empty_dxil_validator_version) << ValVersionStr;
128 VersionTuple MinVer(1, 0);
129 if (Version < MinVer) {
130 D.
Diag(diag::err_drv_invalid_range_dxil_validator_version) << ValVersionStr;
142 const char *LinkingOutput)
const {
144 assert(DxvPath !=
"dxv" &&
"cannot find dxv");
146 ArgStringList CmdArgs;
147 assert(Inputs.size() == 1 &&
"Unable to handle multiple inputs.");
149 assert(Input.
isFilename() &&
"Unexpected verify input");
153 CmdArgs.push_back(
"-o");
156 const char *Exec = Args.MakeArgString(DxvPath);
158 Exec, CmdArgs, Inputs, Input));
165 if (Args.hasArg(options::OPT_dxc_validator_path_EQ))
167 Args.getLastArgValue(options::OPT_dxc_validator_path_EQ).str());
176 return Validator.get();
182std::optional<std::string>
184 StringRef TargetProfile) {
185 return tryParseProfile(TargetProfile);
191 DerivedArgList *DAL =
new DerivedArgList(Args.getBaseArgs());
195 for (Arg *A : Args) {
196 if (A->getOption().getID() == options::OPT_dxil_validator_version) {
197 StringRef ValVerStr = A->getValue();
198 std::string ErrorMsg;
199 if (!isLegalValidatorVersion(ValVerStr,
getDriver()))
202 if (A->getOption().getID() == options::OPT_dxc_entrypoint) {
203 DAL->AddSeparateArg(
nullptr, Opts.getOption(options::OPT_hlsl_entrypoint),
208 if (A->getOption().getID() == options::OPT__SLASH_O) {
209 StringRef OStr = A->getValue();
211 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_O0));
215 DAL->AddJoinedArg(
nullptr, Opts.getOption(options::OPT_O), OStr);
220 if (A->getOption().getID() == options::OPT_emit_pristine_llvm) {
222 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_S));
223 DAL->AddFlagArg(
nullptr, Opts.getOption(options::OPT_emit_llvm));
224 DAL->AddFlagArg(
nullptr,
225 Opts.getOption(options::OPT_disable_llvm_passes));
234 if (!DAL->hasArg(options::OPT_dxil_validator_version)) {
235 const StringRef DefaultValidatorVer =
"1.7";
236 DAL->AddSeparateArg(
nullptr,
237 Opts.getOption(options::OPT_dxil_validator_version),
238 DefaultValidatorVer);
240 if (!DAL->hasArg(options::OPT_O_Group)) {
241 DAL->AddJoinedArg(
nullptr, Opts.getOption(options::OPT_O),
"3");
250 if (Args.getLastArg(options::OPT_dxc_disable_validation))
254 if (DxvPath !=
"dxv")
Compilation - A set of tasks to perform for a single driver invocation.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
DiagnosticBuilder Diag(unsigned DiagID) const
const llvm::opt::OptTable & getOpts() const
@ C
Languages that the frontend can parse and compile.
llvm::StringRef getAsString(SyncScope S)
YAML serialization mapping.
static constexpr ResponseFileSupport None()
Returns a ResponseFileSupport indicating that response files are not supported.