Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions include/dxc/Support/SPIRVOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ struct SpirvCodeGenOptions {
std::vector<std::string> bindRegister;
std::vector<std::string> bindGlobals;
std::string entrypointName;
std::string floatDenormalMode; // OPT_denorm

bool signaturePacking; ///< Whether signature packing is enabled or not

Expand Down
2 changes: 2 additions & 0 deletions lib/DxcSupport/HLSLOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1201,6 +1201,8 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
hasUnsupportedSpirvOption(Args, errors))
return 1;

opts.SpirvOptions.floatDenormalMode = Args.getLastArgValue(OPT_denorm);

#else
if (Args.hasFlag(OPT_spirv, OPT_INVALID, false) ||
Args.hasFlag(OPT_fvk_invert_y, OPT_INVALID, false) ||
Expand Down
1 change: 1 addition & 0 deletions tools/clang/include/clang/SPIRV/FeatureManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ enum class Extension {
NV_compute_shader_derivatives,
KHR_fragment_shader_barycentric,
KHR_maximal_reconvergence,
KHR_float_controls,
Unknown,
};

Expand Down
12 changes: 12 additions & 0 deletions tools/clang/lib/SPIRV/CapabilityVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,18 @@ bool CapabilityVisitor::visit(SpirvExecutionMode *execMode) {
addExtension(Extension::KHR_maximal_reconvergence, "",
execModeSourceLocation);
break;
case spv::ExecutionMode::DenormPreserve:
case spv::ExecutionMode::DenormFlushToZero:
// KHR_float_controls was promoted to core in Vulkan 1.2.
if (!featureManager.isTargetEnvVulkan1p2OrAbove()) {
addExtension(Extension::KHR_float_controls, "SPV_KHR_float_controls",
execModeSourceLocation);
}
addCapability(executionMode == spv::ExecutionMode::DenormPreserve
? spv::Capability::DenormPreserve
: spv::Capability::DenormFlushToZero,
execModeSourceLocation);
break;
default:
break;
}
Expand Down
3 changes: 3 additions & 0 deletions tools/clang/lib/SPIRV/FeatureManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ Extension FeatureManager::getExtensionSymbol(llvm::StringRef name) {
Extension::KHR_fragment_shader_barycentric)
.Case("SPV_KHR_maximal_reconvergence",
Extension::KHR_maximal_reconvergence)
.Case("SPV_KHR_float_controls", Extension::KHR_float_controls)
.Default(Extension::Unknown);
}

Expand Down Expand Up @@ -261,6 +262,8 @@ const char *FeatureManager::getExtensionName(Extension symbol) {
return "SPV_KHR_fragment_shader_barycentric";
case Extension::KHR_maximal_reconvergence:
return "SPV_KHR_maximal_reconvergence";
case Extension::KHR_float_controls:
return "SPV_KHR_float_controls";
default:
break;
}
Expand Down
17 changes: 17 additions & 0 deletions tools/clang/lib/SPIRV/SpirvEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,23 @@ void SpirvEmitter::HandleTranslationUnit(ASTContext &context) {
SourceLocation());
}

llvm::StringRef denormMode = spirvOptions.floatDenormalMode;
if (!denormMode.empty()) {
if (denormMode.equals_lower("preserve")) {
spvBuilder.addExecutionMode(entryFunction,
spv::ExecutionMode::DenormPreserve, {32}, {});
} else if (denormMode.equals_lower("ftz")) {
spvBuilder.addExecutionMode(
entryFunction, spv::ExecutionMode::DenormFlushToZero, {32}, {});
} else if (denormMode.equals_lower("any")) {
// Do nothing. Since any behavior is allowed, we could optionally choose
// to translate to DenormPreserve or DenormFlushToZero if one was known to
// be more performant on most platforms.
} else {
assert(false && "unsupported denorm value");
}
}

// Output the constructed module.
std::vector<uint32_t> m = spvBuilder.takeModule();
if (context.getDiagnostics().hasErrorOccurred())
Expand Down
7 changes: 7 additions & 0 deletions tools/clang/test/CodeGenSPIRV/opt.denorm.error.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// RUN: not %dxc -E main -T ps_6_2 -denorm bad -spirv %s 2>&1 | FileCheck %s

// CHECK: dxc failed : Unsupported value 'bad' for denorm option.

float4 main(float4 col : COL) : SV_Target {
return col;
}
24 changes: 24 additions & 0 deletions tools/clang/test/CodeGenSPIRV/opt.denorm.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// RUN: %dxc -E main -T ps_6_2 -denorm preserve -spirv %s | FileCheck --check-prefixes=CHECK-PRE %s
// RUN: %dxc -E main -T ps_6_2 -denorm preserve -spirv -fspv-target-env=vulkan1.2 %s | FileCheck --check-prefixes=CHECK-PRE-VK12 %s
// RUN: %dxc -E main -T ps_6_2 -denorm ftz -spirv %s | FileCheck --check-prefixes=CHECK-FTZ %s
// RUN: %dxc -E main -T ps_6_2 -denorm any -spirv %s | FileCheck --check-prefixes=CHECK-DEFAULT %s
// RUN: %dxc -E main -T ps_6_2 -spirv %s | FileCheck --check-prefixes=CHECK-DEFAULT %s

// CHECK-PRE: OpCapability DenormPreserve
// CHECK-PRE: OpExtension "SPV_KHR_float_controls"
// CHECK-PRE: OpExecutionMode %main DenormPreserve 32

// CHECK-PRE-VK12: OpCapability DenormPreserve
// CHECK-PRE-VK12-NOT: OpExtension "SPV_KHR_float_controls"
// CHECK-PRE-VK12: OpExecutionMode %main DenormPreserve 32

// CHECK-FTZ: OpCapability DenormFlushToZero
// CHECK-FTZ: OpExtension "SPV_KHR_float_controls"
// CHECK-FTZ: OpExecutionMode %main DenormFlushToZero 32

// CHECK-DEFAULT-NOT: OpCapability DenormPreserve
// CHECK-DEFAULT-NOT: OpExtension "SPV_KHR_float_controls"
// CHECK-DEFAULT-NOT: OpExecutionMode %main Denorm
float4 main(float4 col : COL) : SV_Target {
return col;
}