Skip to content

[SPIRV][HLSL] Add DXC compatibility option for extension #151554

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -9428,8 +9428,12 @@ def fspv_target_env_EQ : Joined<["-"], "fspv-target-env=">, Group<dxc_Group>,
def fspv_extension_EQ
: Joined<["-"], "fspv-extension=">,
Group<dxc_Group>,
HelpText<"Specify the available SPIR-V extensions. If this option is not "
"specified, then all extensions are available.">;
HelpText<
"Specify the available SPIR-V extensions. If this option is not "
"specified, then all extensions are available. If KHR is specified, "
"then all KHR extensions will be available. If DXC is specifided, "
"then all extensions implemented by the DirectX Shader compiler will "
"be available. This option is useful for moving from DXC to Clang.">;
def fvk_use_dx_layout
: DXCFlag<"fvk-use-dx-layout">,
HelpText<"Use DirectX memory layout for Vulkan resources.">;
Expand Down
80 changes: 70 additions & 10 deletions clang/lib/Driver/ToolChains/HLSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,24 +173,84 @@ bool isLegalValidatorVersion(StringRef ValVersionStr, const Driver &D) {
return true;
}

std::string getSpirvExtArg(ArrayRef<std::string> SpvExtensionArgs) {
void getSpirvExtOperand(llvm::StringRef SpvExtensionArg, raw_ostream &out) {
// The extensions that are commented out are supported in DXC, but the SPIR-V
// backend does not know about them yet.
static const std::vector<StringRef> DxcSupportedExtensions = {
"SPV_KHR_16bit_storage",
"SPV_KHR_device_group",
"SPV_KHR_fragment_shading_rate",
"SPV_KHR_multiview",
"SPV_KHR_post_depth_coverage",
"SPV_KHR_non_semantic_info",
"SPV_KHR_shader_draw_parameters",
"SPV_KHR_ray_tracing",
"SPV_KHR_shader_clock",
"SPV_EXT_demote_to_helper_invocation",
"SPV_EXT_descriptor_indexing",
"SPV_EXT_fragment_fully_covered",
"SPV_EXT_fragment_invocation_density",
"SPV_EXT_fragment_shader_interlock",
"SPV_EXT_mesh_shader",
"SPV_EXT_shader_stencil_export",
"SPV_EXT_shader_viewport_index_layer",
// "SPV_AMD_shader_early_and_late_fragment_tests",
"SPV_GOOGLE_hlsl_functionality1",
"SPV_GOOGLE_user_type",
"SPV_KHR_ray_query",
"SPV_EXT_shader_image_int64",
"SPV_KHR_fragment_shader_barycentric",
"SPV_KHR_physical_storage_buffer",
"SPV_KHR_vulkan_memory_model",
// "SPV_KHR_compute_shader_derivatives",
// "SPV_KHR_maximal_reconvergence",
"SPV_KHR_float_controls",
"SPV_NV_shader_subgroup_partitioned",
// "SPV_KHR_quad_control"
};

if (SpvExtensionArg.starts_with("SPV_")) {
out << "+" << SpvExtensionArg;
return;
}

if (SpvExtensionArg.compare_insensitive("DXC") == 0) {
bool first = true;
std::string Operand;
for (llvm::StringRef E : DxcSupportedExtensions) {
if (!first)
out << ",";
else
first = false;
out << "+" << E;
}
return;
}
out << SpvExtensionArg;
return;
}

llvm::SmallString<1024> getSpirvExtArg(ArrayRef<std::string> SpvExtensionArgs) {
if (SpvExtensionArgs.empty()) {
return "-spirv-ext=all";
return llvm::StringRef("-spirv-ext=all");
}

std::string LlvmOption =
(Twine("-spirv-ext=+") + SpvExtensionArgs.front()).str();
llvm::SmallString<1024> LlvmOption;
raw_svector_ostream out(LlvmOption);

out << "-spirv-ext=";
getSpirvExtOperand(SpvExtensionArgs[0], out);

SpvExtensionArgs = SpvExtensionArgs.slice(1);
for (auto Extension : SpvExtensionArgs) {
if (Extension != "KHR")
Extension = (Twine("+") + Extension).str();
LlvmOption = (Twine(LlvmOption) + "," + Extension).str();
for (llvm::StringRef Extension : SpvExtensionArgs) {
out << ",";
getSpirvExtOperand(Extension, out);
}
return LlvmOption;
}

bool isValidSPIRVExtensionName(const std::string &str) {
std::regex pattern("KHR|SPV_[a-zA-Z0-9_]+");
std::regex pattern("dxc|DXC|KHR|SPV_[a-zA-Z0-9_]+");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
std::regex pattern("dxc|DXC|KHR|SPV_[a-zA-Z0-9_]+");
std::regex pattern("dxc|DXC|khr|KHR|SPV_[a-zA-Z0-9_]+");

return std::regex_match(str, pattern);
}

Expand Down Expand Up @@ -371,7 +431,7 @@ HLSLToolChain::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,
std::vector<std::string> SpvExtensionArgs =
Args.getAllArgValues(options::OPT_fspv_extension_EQ);
if (checkExtensionArgsAreValid(SpvExtensionArgs, getDriver())) {
std::string LlvmOption = getSpirvExtArg(SpvExtensionArgs);
llvm::SmallString<1024> LlvmOption = getSpirvExtArg(SpvExtensionArgs);
DAL->AddSeparateArg(nullptr, Opts.getOption(options::OPT_mllvm),
LlvmOption);
}
Expand Down
8 changes: 8 additions & 0 deletions clang/test/Driver/dxc_fspv_extension.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@
// RUN: %clang_dxc -spirv -Tlib_6_7 -### %s -fspv-extension=SPV_TEST1 -fspv-extension=KHR -fspv-extension=SPV_TEST2 2>&1 | FileCheck %s -check-prefix=TEST3
// TEST3: "-spirv-ext=+SPV_TEST1,KHR,+SPV_TEST2"

// Merge KHR with other extensions.
// RUN: %clang_dxc -spirv -Tlib_6_7 -### %s -fspv-extension=KHR -fspv-extension=SPV_TEST2 2>&1 | FileCheck %s -check-prefix=TEST4
// TEST4: "-spirv-ext=KHR,+SPV_TEST2"

// Merge KHR with other extensions.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: comment seems wrong

Suggested change
// Merge KHR with other extensions.

// RUN: %clang_dxc -spirv -Tlib_6_7 -### %s -fspv-extension=DXC 2>&1 | FileCheck %s -check-prefix=TEST5
// TEST5: "-spirv-ext={{(\+SPV_[a-zA-Z0-9_]+,?)+}}"

// Check for the error message if the extension name is not properly formed.
// RUN: not %clang_dxc -spirv -Tlib_6_7 -### %s -fspv-extension=KHR_BAD -fspv-extension=TEST1 -fspv-extension=SPV_GOOD -fspv-extension=TEST2 2>&1 | FileCheck %s -check-prefix=FAIL
// FAIL: invalid value 'KHR_BAD' in '-fspv-extension'
Expand Down
42 changes: 42 additions & 0 deletions llvm/lib/Target/SPIRV/SPIRVCommandLine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,24 @@ static const std::map<std::string, SPIRV::Extension::Extension, std::less<>>
SPIRV::Extension::Extension::SPV_EXT_arithmetic_fence},
{"SPV_EXT_demote_to_helper_invocation",
SPIRV::Extension::Extension::SPV_EXT_demote_to_helper_invocation},
{"SPV_EXT_descriptor_indexing",
SPIRV::Extension::Extension::SPV_EXT_descriptor_indexing},
{"SPV_EXT_fragment_fully_covered",
SPIRV::Extension::Extension::SPV_EXT_fragment_fully_covered},
{"SPV_EXT_fragment_invocation_density",
SPIRV::Extension::Extension::SPV_EXT_fragment_invocation_density},
{"SPV_EXT_fragment_shader_interlock",
SPIRV::Extension::Extension::SPV_EXT_fragment_shader_interlock},
{"SPV_EXT_mesh_shader",
SPIRV::Extension::Extension::SPV_EXT_mesh_shader},
{"SPV_EXT_shader_stencil_export",
SPIRV::Extension::Extension::SPV_EXT_shader_stencil_export},
{"SPV_EXT_shader_viewport_index_layer",
SPIRV::Extension::Extension::SPV_EXT_shader_viewport_index_layer},
{"SPV_GOOGLE_hlsl_functionality1",
SPIRV::Extension::Extension::SPV_GOOGLE_hlsl_functionality1},
{"SPV_GOOGLE_user_type",
SPIRV::Extension::Extension::SPV_GOOGLE_user_type},
{"SPV_INTEL_arbitrary_precision_integers",
SPIRV::Extension::Extension::SPV_INTEL_arbitrary_precision_integers},
{"SPV_INTEL_cache_controls",
Expand All @@ -57,6 +75,19 @@ static const std::map<std::string, SPIRV::Extension::Extension, std::less<>>
SPIRV::Extension::Extension::SPV_INTEL_memory_access_aliasing},
{"SPV_INTEL_joint_matrix",
SPIRV::Extension::Extension::SPV_INTEL_joint_matrix},
{"SPV_KHR_16bit_storage",
SPIRV::Extension::Extension::SPV_KHR_16bit_storage},
{"SPV_KHR_device_group",
SPIRV::Extension::Extension::SPV_KHR_device_group},
{"SPV_KHR_fragment_shading_rate",
SPIRV::Extension::Extension::SPV_KHR_fragment_shading_rate},
{"SPV_KHR_multiview", SPIRV::Extension::Extension::SPV_KHR_multiview},
{"SPV_KHR_post_depth_coverage",
SPIRV::Extension::Extension::SPV_KHR_post_depth_coverage},
{"SPV_KHR_shader_draw_parameters",
SPIRV::Extension::Extension::SPV_KHR_shader_draw_parameters},
{"SPV_KHR_ray_tracing",
SPIRV::Extension::Extension::SPV_KHR_ray_tracing},
{"SPV_KHR_uniform_group_instructions",
SPIRV::Extension::Extension::SPV_KHR_uniform_group_instructions},
{"SPV_KHR_no_integer_wrap_decoration",
Expand Down Expand Up @@ -89,6 +120,17 @@ static const std::map<std::string, SPIRV::Extension::Extension, std::less<>>
SPIRV::Extension::Extension::SPV_KHR_cooperative_matrix},
{"SPV_KHR_non_semantic_info",
SPIRV::Extension::Extension::SPV_KHR_non_semantic_info},
{"SPV_KHR_ray_query", SPIRV::Extension::Extension::SPV_KHR_ray_query},
{"SPV_EXT_shader_image_int64",
SPIRV::Extension::Extension::SPV_EXT_shader_image_int64},
{"SPV_KHR_fragment_shader_barycentric",
SPIRV::Extension::Extension::SPV_KHR_fragment_shader_barycentric},
{"SPV_KHR_physical_storage_buffer",
SPIRV::Extension::Extension::SPV_KHR_physical_storage_buffer},
{"SPV_KHR_vulkan_memory_model",
SPIRV::Extension::Extension::SPV_KHR_vulkan_memory_model},
{"SPV_NV_shader_subgroup_partitioned",
SPIRV::Extension::Extension::SPV_NV_shader_subgroup_partitioned},
{"SPV_INTEL_long_composites",
SPIRV::Extension::Extension::SPV_INTEL_long_composites},
{"SPV_INTEL_fp_max_error",
Expand Down
Loading