From 453331951b0df2a612f9bc0d68eab2ad786ec5bf Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Thu, 1 Nov 2018 15:08:54 -0700 Subject: Add support for a "strict" floating-point mode (#709) This change adds an API function and command line options for controlling the default floating-point behavior for a target, with options for "fast" and "precise" computation. The "precise" option gets mapped to the "IEEE strictness" mode in `fxc` and `dxc` (there is currently no equivalent option for glslang that I could find). --- source/slang/compiler.cpp | 16 ++++++++++++-- source/slang/compiler.h | 8 +++++++ source/slang/diagnostic-defs.h | 1 + source/slang/dxc-support.cpp | 10 +++++++++ source/slang/options.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++ source/slang/slang.cpp | 9 ++++++++ 6 files changed, 92 insertions(+), 2 deletions(-) (limited to 'source') diff --git a/source/slang/compiler.cpp b/source/slang/compiler.cpp index ed222d181..52a31645c 100644 --- a/source/slang/compiler.cpp +++ b/source/slang/compiler.cpp @@ -428,6 +428,18 @@ namespace Slang dxMacros = dxMacrosStorage.Buffer(); } + DWORD flags = 0; + + switch( targetReq->floatingPointMode ) + { + default: + break; + + case FloatingPointMode::Precise: + flags |= D3DCOMPILE_IEEE_STRICTNESS; + break; + } + ID3DBlob* codeBlob; ID3DBlob* diagnosticsBlob; HRESULT hr = D3DCompile_( @@ -438,8 +450,8 @@ namespace Slang nullptr, getText(entryPoint->name).begin(), GetHLSLProfileName(profile).Buffer(), - 0, - 0, + flags, + 0, // unused: effect flags &codeBlob, &diagnosticsBlob); diff --git a/source/slang/compiler.h b/source/slang/compiler.h index c62daf228..1f4a4736a 100644 --- a/source/slang/compiler.h +++ b/source/slang/compiler.h @@ -203,6 +203,13 @@ namespace Slang RefPtr irModule; }; + enum class FloatingPointMode : SlangFloatingPointMode + { + Default = SLANG_FLOATING_POINT_MODE_DEFAULT, + Fast = SLANG_FLOATING_POINT_MODE_FAST, + Precise = SLANG_FLOATING_POINT_MODE_PRECISE, + }; + // A request to generate output in some target format class TargetRequest : public RefObject { @@ -211,6 +218,7 @@ namespace Slang CodeGenTarget target; SlangTargetFlags targetFlags = 0; Slang::Profile targetProfile = Slang::Profile(); + FloatingPointMode floatingPointMode = FloatingPointMode::Default; // Requested output paths for each entry point. // An empty string indices no output desired for diff --git a/source/slang/diagnostic-defs.h b/source/slang/diagnostic-defs.h index a32dbb315..277e9a48f 100644 --- a/source/slang/diagnostic-defs.h +++ b/source/slang/diagnostic-defs.h @@ -73,6 +73,7 @@ DIAGNOSTIC( 20, Error, entryPointsNeedToBeAssociatedWithTranslationUnits, "wh DIAGNOSTIC( 21, Error, expectedArgumentForOption, "expected an argument for command-line option '$0'"); DIAGNOSTIC( 24, Error, unknownLineDirectiveMode, "unknown '#line' directive mode '$0'"); +DIAGNOSTIC( 25, Error, unknownFloatingPointMode, "unknown floating-point mode '$0'"); DIAGNOSTIC( 30, Error, sameStageSpecifiedMoreThanOnce, "the stage '$0' was specified more than once for entry point '$1'") DIAGNOSTIC( 31, Error, conflictingStagesForEntryPoint, "conflicting stages have been specified for entry point '$0'") diff --git a/source/slang/dxc-support.cpp b/source/slang/dxc-support.cpp index 7c42ad242..0478eef25 100644 --- a/source/slang/dxc-support.cpp +++ b/source/slang/dxc-support.cpp @@ -132,6 +132,16 @@ namespace Slang break; } + switch( targetReq->floatingPointMode ) + { + default: + break; + + case FloatingPointMode::Precise: + args[argCount++] = L"-Gis"; // "force IEEE strictness" + break; + } + // Slang strives to produce correct code, and by default // we do not show the user warnings produced by a downstream // compiler. When the downstream compiler *does* produce an diff --git a/source/slang/options.cpp b/source/slang/options.cpp index 485b7d78b..cfa631340 100644 --- a/source/slang/options.cpp +++ b/source/slang/options.cpp @@ -147,6 +147,7 @@ struct OptionsParser ProfileVersion profileVersion = ProfileVersion::Unknown; SlangTargetFlags targetFlags = 0; int targetID = -1; + FloatingPointMode floatingPointMode = FloatingPointMode::Default; // State for tracking command-line errors bool conflictingProfilesSet = false; @@ -402,6 +403,11 @@ struct OptionsParser rawTarget->profileVersion = profileVersion; } + void setFloatingPointMode(RawTarget* rawTarget, FloatingPointMode mode) + { + rawTarget->floatingPointMode = mode; + } + SlangResult parse( int argc, char const* const* argv) @@ -660,6 +666,28 @@ struct OptionsParser spSetLineDirectiveMode(compileRequest, mode); } + else if( argStr == "-fp-mode" || argStr == "-floating-point-mode" ) + { + String name; + SLANG_RETURN_ON_FAIL(tryReadCommandLineArgument(sink, arg, &argCursor, argEnd, name)); + + FloatingPointMode mode = FloatingPointMode::Default; + if(name == "fast") + { + mode = FloatingPointMode::Fast; + } + else if(name == "precise") + { + mode = FloatingPointMode::Precise; + } + else + { + sink->diagnose(SourceLoc(), Diagnostics::unknownFloatingPointMode, name); + return SLANG_FAIL; + } + + setFloatingPointMode(getCurrentTarget(), mode); + } else if (argStr == "--") { // The `--` option causes us to stop trying to parse options, @@ -983,6 +1011,11 @@ struct OptionsParser } getCurrentTarget()->targetFlags |= defaultTarget.targetFlags; + + if( defaultTarget.floatingPointMode != FloatingPointMode::Default ) + { + setFloatingPointMode(getCurrentTarget(), defaultTarget.floatingPointMode); + } } else { @@ -1018,6 +1051,18 @@ struct OptionsParser } } + if( defaultTarget.floatingPointMode != FloatingPointMode::Default ) + { + if( rawTargets.Count() == 0 ) + { + sink->diagnose(SourceLoc(), Diagnostics::targetFlagsIgnoredBecauseNoTargets); + } + else + { + sink->diagnose(SourceLoc(), Diagnostics::targetFlagsIgnoredBecauseBeforeAllTargets); + } + } + } for(auto& rawTarget : rawTargets) @@ -1054,6 +1099,11 @@ struct OptionsParser { spSetTargetFlags(compileRequest, targetID, rawTarget.targetFlags); } + + if( rawTarget.floatingPointMode != FloatingPointMode::Default ) + { + spSetTargetFloatingPointMode(compileRequest, targetID, SlangFloatingPointMode(rawTarget.floatingPointMode)); + } } if(defaultMatrixLayoutMode != SLANG_MATRIX_LAYOUT_MODE_UNKNOWN) diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index f67123cc6..1e3d1e716 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -1229,6 +1229,15 @@ SLANG_API void spSetTargetFlags( req->targets[targetIndex]->targetFlags = flags; } +SLANG_API void spSetTargetFloatingPointMode( + SlangCompileRequest* request, + int targetIndex, + SlangFloatingPointMode mode) +{ + auto req = REQ(request); + req->targets[targetIndex]->floatingPointMode = Slang::FloatingPointMode(mode); +} + SLANG_API void spSetMatrixLayoutMode( SlangCompileRequest* request, SlangMatrixLayoutMode mode) -- cgit v1.2.3