-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[DirectX] Set shader feature flags MinimumPrecision and NativeLowPrecision, and refactor the logic for setting low-precision-related flags #139623
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
Changes from 6 commits
2039fa7
aa824ac
4cb533b
610f435
bc8396d
70d4849
fe5d588
c0dbfbb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -142,6 +142,13 @@ void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF, | |
} | ||
} | ||
|
||
if (CSF.LowPrecisionPresent) { | ||
if (NativeLowPrecisionMode) | ||
CSF.NativeLowPrecision = true; | ||
else | ||
CSF.MinimumPrecision = true; | ||
} | ||
|
||
if (!CSF.Int64Ops) | ||
CSF.Int64Ops = I.getType()->isIntegerTy(64); | ||
|
||
|
@@ -206,14 +213,23 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM, | |
const ModuleMetadataInfo &MMDI) { | ||
|
||
CanSetResMayNotAlias = MMDI.DXILVersion >= VersionTuple(1, 7); | ||
|
||
// Check if -res-may-alias was provided on the command line. | ||
// The command line option will set the dx.resmayalias module flag to 1. | ||
// The command line option -res-may-alias will set the dx.resmayalias module | ||
// flag to 1 and disable the ability to set the ResMayNotAlias flag | ||
if (auto *RMA = mdconst::extract_or_null<ConstantInt>( | ||
M.getModuleFlag("dx.resmayalias"))) | ||
if (RMA->getValue() != 0) | ||
CanSetResMayNotAlias = false; | ||
|
||
// NativeLowPrecisionMode can only be set when the command line option | ||
// -enable-16bit-types is provided. This is indicated by the dx.nativelowprec | ||
// module flag being set | ||
NativeLowPrecisionMode = false; | ||
if (auto *NativeLowPrec = mdconst::extract_or_null<ConstantInt>( | ||
M.getModuleFlag("dx.nativelowprec"))) | ||
if (MMDI.ShaderModelVersion >= VersionTuple(6, 2) && | ||
NativeLowPrec->getValue() != 0) | ||
NativeLowPrecisionMode = true; | ||
|
||
CallGraph CG(M); | ||
|
||
// Compute Shader Flags Mask for all functions using post-order visit of SCC | ||
|
@@ -238,18 +254,6 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM, | |
continue; | ||
} | ||
|
||
// Set ResMayNotAlias to true if DXIL validator version < 1.8 and there | ||
// are UAVs present globally. | ||
if (CanSetResMayNotAlias && MMDI.ValidatorVersion < VersionTuple(1, 8)) | ||
SCCSF.ResMayNotAlias = !DRM.uavs().empty(); | ||
|
||
// Set UseNativeLowPrecision using dx.nativelowprec module metadata | ||
if (auto *NativeLowPrec = mdconst::extract_or_null<ConstantInt>( | ||
M.getModuleFlag("dx.nativelowprec"))) | ||
if (MMDI.ShaderModelVersion >= VersionTuple(6, 2) && | ||
NativeLowPrec->getValue() != 0) | ||
SCCSF.UseNativeLowPrecision = true; | ||
|
||
ComputedShaderFlags CSF; | ||
for (const auto &BB : *F) | ||
for (const auto &I : BB) | ||
|
@@ -286,6 +290,17 @@ void ModuleShaderFlags::initialize(Module &M, DXILResourceTypeMap &DRTM, | |
*(EntryFunProps.Entry), "Inconsistent optnone attribute ")); | ||
} | ||
|
||
// Set ResMayNotAlias to true if DXIL validator version < 1.8 and there | ||
// are UAVs present globally. | ||
if (CanSetResMayNotAlias && MMDI.ValidatorVersion < VersionTuple(1, 8)) | ||
CombinedSFMask.ResMayNotAlias = !DRM.uavs().empty(); | ||
|
||
// Set the module flag that enables native low-precision execution mode. This | ||
// is needed even if the module does not use 16-bit types because a | ||
// corresponding debug module may include 16-bit types, and tools that use the | ||
// debug module may expect it to have the same flags as the original | ||
CombinedSFMask.NativeLowPrecisionMode = NativeLowPrecisionMode; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Setting the module flags via CombinedSFMask instead of SCCSF will make the module flags be set on the module only and not the functions themselves. This is consistent with the way the DisableOptimizations flag is currently set in Clang. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, this feels like an implementation detail - I don't think there's any way to see a difference in the end. |
||
|
||
// Set the Max64UAVs flag if the number of UAVs is > 8 | ||
uint32_t NumUAVs = 0; | ||
for (auto &UAV : DRM.uavs()) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,44 @@ | ||
; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s | ||
; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC | ||
|
||
; Check that when the dx.nativelowprec module flag is not specified, the | ||
; module-level shader flag UseNativeLowPrecision is not set, and the | ||
; MinimumPrecision feature flag is set due to the presence of half and i16 | ||
; without native low precision. | ||
|
||
target triple = "dxil-pc-shadermodel6.7-library" | ||
|
||
;CHECK: ; Combined Shader Flags for Module | ||
;CHECK-NEXT: ; Shader Flags Value: 0x00000020 | ||
;CHECK-NEXT: ; | ||
;CHECK-NEXT: ; Note: shader requires additional functionality: | ||
;CHECK-NEXT: ; Minimum-precision data types | ||
;CHECK-NEXT: ; Note: extra DXIL module flags: | ||
;CHECK-NEXT: ; Low-precision data types | ||
;CHECK-NEXT: ; Low-precision data types present | ||
;CHECK-NEXT: ; | ||
;CHECK-NEXT: ; Shader Flags for Module Functions | ||
|
||
;CHECK-LABEL: ; Function add_i16 : 0x00000020 | ||
define i16 @add_i16(i16 %a, i16 %b) { | ||
define i16 @add_i16(i16 %a, i16 %b) "hlsl.export" { | ||
%sum = add i16 %a, %b | ||
ret i16 %sum | ||
} | ||
|
||
;CHECK-LABEL: ; Function add_i32 : 0x00000000 | ||
define i32 @add_i32(i32 %a, i32 %b) { | ||
define i32 @add_i32(i32 %a, i32 %b) "hlsl.export" { | ||
%sum = add i32 %a, %b | ||
ret i32 %sum | ||
} | ||
|
||
;CHECK-LABEL: ; Function add_half : 0x00000020 | ||
define half @add_half(half %a, half %b) { | ||
define half @add_half(half %a, half %b) "hlsl.export" { | ||
%sum = fadd half %a, %b | ||
ret half %sum | ||
} | ||
|
||
; DXC: - Name: SFI0 | ||
; DXC-NEXT: Size: 8 | ||
; DXC-NEXT: Flags: | ||
; DXC: MinimumPrecision: true | ||
; DXC: NativeLowPrecision: false | ||
; DXC: ... |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,47 @@ | ||
; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s | ||
; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC | ||
|
||
; Check that when the dx.nativelowprec module flag is set to 0, the module-level | ||
; shader flag UseNativeLowPrecision is not set | ||
; shader flag UseNativeLowPrecision is not set, and the MinimumPrecision feature | ||
; flag is set due to the presence of half and i16 without native low precision. | ||
|
||
target triple = "dxil-pc-shadermodel6.7-library" | ||
|
||
;CHECK: ; Combined Shader Flags for Module | ||
;CHECK-NEXT: ; Shader Flags Value: 0x00000020 | ||
;CHECK-NEXT: ; | ||
;CHECK-NEXT: ; Note: shader requires additional functionality: | ||
;CHECK-NEXT: ; Minimum-precision data types | ||
;CHECK-NEXT: ; Note: extra DXIL module flags: | ||
;CHECK-NEXT: ; Low-precision data types | ||
;CHECK-NOT: ; Native 16bit types enabled | ||
;CHECK-NEXT: ; Low-precision data types present | ||
;CHECK-NOT: ; Enable native low-precision data types | ||
;CHECK-NEXT: ; | ||
;CHECK-NEXT: ; Shader Flags for Module Functions | ||
|
||
;CHECK-LABEL: ; Function add_i16 : 0x00000020 | ||
define i16 @add_i16(i16 %a, i16 %b) { | ||
define i16 @add_i16(i16 %a, i16 %b) "hlsl.export" { | ||
%sum = add i16 %a, %b | ||
ret i16 %sum | ||
} | ||
|
||
;CHECK-LABEL: ; Function add_i32 : 0x00000000 | ||
define i32 @add_i32(i32 %a, i32 %b) { | ||
define i32 @add_i32(i32 %a, i32 %b) "hlsl.export" { | ||
%sum = add i32 %a, %b | ||
ret i32 %sum | ||
} | ||
|
||
;CHECK-LABEL: ; Function add_half : 0x00000020 | ||
define half @add_half(half %a, half %b) { | ||
define half @add_half(half %a, half %b) "hlsl.export" { | ||
%sum = fadd half %a, %b | ||
ret half %sum | ||
} | ||
|
||
!llvm.module.flags = !{!0} | ||
!0 = !{i32 1, !"dx.nativelowprec", i32 0} | ||
|
||
; DXC: - Name: SFI0 | ||
; DXC-NEXT: Size: 8 | ||
; DXC-NEXT: Flags: | ||
; DXC: MinimumPrecision: true | ||
; DXC: NativeLowPrecision: false | ||
; DXC: ... |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,47 @@ | ||
; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s | ||
; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s --check-prefix=DXC | ||
|
||
; Check that when the dx.nativelowprec module flag is set to 1, the module-level | ||
; shader flag UseNativeLowPrecision is set, and the NativeLowPrecision feature | ||
; flag is set | ||
|
||
target triple = "dxil-pc-shadermodel6.7-library" | ||
|
||
;CHECK: ; Combined Shader Flags for Module | ||
;CHECK-NEXT: ; Shader Flags Value: 0x00800020 | ||
;CHECK-NEXT: ; | ||
;CHECK-NEXT: ; Note: shader requires additional functionality: | ||
;CHECK-NEXT: ; Native low-precision data types | ||
;CHECK-NEXT: ; Note: extra DXIL module flags: | ||
;CHECK-NEXT: ; Low-precision data types | ||
;CHECK-NEXT: ; Use native low precision | ||
;CHECK-NEXT: ; Low-precision data types present | ||
;CHECK-NEXT: ; Enable native low-precision data types | ||
;CHECK-NEXT: ; | ||
;CHECK-NEXT: ; Shader Flags for Module Functions | ||
|
||
;CHECK-LABEL: ; Function add_i16 : 0x00800020 | ||
define i16 @add_i16(i16 %a, i16 %b) { | ||
;CHECK-LABEL: ; Function add_i16 : 0x00000020 | ||
define i16 @add_i16(i16 %a, i16 %b) "hlsl.export" { | ||
%sum = add i16 %a, %b | ||
ret i16 %sum | ||
} | ||
|
||
; NOTE: The flag for native low precision (0x80000) is set for every function | ||
; in the module regardless of whether or not the function uses low precision | ||
; data types (flag 0x20). This matches the behavior in DXC | ||
;CHECK-LABEL: ; Function add_i32 : 0x00800000 | ||
define i32 @add_i32(i32 %a, i32 %b) { | ||
;CHECK-LABEL: ; Function add_i32 : 0x00000000 | ||
define i32 @add_i32(i32 %a, i32 %b) "hlsl.export" { | ||
%sum = add i32 %a, %b | ||
ret i32 %sum | ||
} | ||
|
||
;CHECK-LABEL: ; Function add_half : 0x00800020 | ||
define half @add_half(half %a, half %b) { | ||
;CHECK-LABEL: ; Function add_half : 0x00000020 | ||
define half @add_half(half %a, half %b) "hlsl.export" { | ||
%sum = fadd half %a, %b | ||
ret half %sum | ||
} | ||
|
||
!llvm.module.flags = !{!0} | ||
!0 = !{i32 1, !"dx.nativelowprec", i32 1} | ||
|
||
; DXC: - Name: SFI0 | ||
; DXC-NEXT: Size: 8 | ||
; DXC-NEXT: Flags: | ||
; DXC: MinimumPrecision: false | ||
; DXC: NativeLowPrecision: true | ||
; DXC: ... |
Uh oh!
There was an error while loading. Please reload this page.