-
Notifications
You must be signed in to change notification settings - Fork 12.3k
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
Set shader analysis flag EnableRawAndStructuredBuffers for RawBuffer and StructuredBuffer resource types #114449
Set shader analysis flag EnableRawAndStructuredBuffers for RawBuffer and StructuredBuffer resource types #114449
Conversation
@llvm/pr-subscribers-backend-directx Author: Cooper Partin (coopp) ChangesThis commit address Issue #112273 . This change includes updates to the shader analysis pass and walking the resource metadata to properly set the required shader flags for RWbuffers. Full diff: https://github.com/llvm/llvm-project/pull/114449.diff 4 Files Affected:
diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
index 9fa137b4c025e1..e24b8b5e8e594f 100644
--- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
+++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
@@ -13,8 +13,11 @@
#include "DXILShaderFlags.h"
#include "DirectX.h"
+#include "llvm/Analysis/DXILMetadataAnalysis.h"
+#include "llvm/Analysis/DXILResource.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Module.h"
+#include "llvm/Support/DXILABI.h"
#include "llvm/Support/FormatVariadic.h"
using namespace llvm;
@@ -36,8 +39,35 @@ static void updateFlags(ComputedShaderFlags &Flags, const Instruction &I) {
}
}
-ComputedShaderFlags ComputedShaderFlags::computeFlags(Module &M) {
+static void updateResourceFlags(ComputedShaderFlags &Flags, Module &M,
+ ModuleAnalysisManager *AM) {
+ if (!AM)
+ return;
+
+ const DXILResourceMap &DRM = AM->getResult<DXILResourceAnalysis>(M);
+ if (DRM.empty())
+ return;
+
+ const dxil::ModuleMetadataInfo &MMDI = AM->getResult<DXILMetadataAnalysis>(M);
+ VersionTuple SM = MMDI.ShaderModelVersion;
+ Triple::EnvironmentType SP = MMDI.ShaderProfile;
+
+ // RWBuffer
+ for (const ResourceInfo &RI : DRM.uavs()) {
+ if (RI.getResourceKind() == ResourceKind::TypedBuffer) {
+ Flags.EnableRawAndStructuredBuffers = true;
+ Flags.ComputeShadersPlusRawAndStructuredBuffers =
+ (SP == Triple::EnvironmentType::Compute && SM.getMajor() == 4);
+ break;
+ }
+ }
+}
+
+ComputedShaderFlags
+ComputedShaderFlags::computeFlags(Module &M, ModuleAnalysisManager *AM) {
ComputedShaderFlags Flags;
+ updateResourceFlags(Flags, M, AM);
+
for (const auto &F : M)
for (const auto &BB : F)
for (const auto &I : BB)
@@ -67,7 +97,7 @@ AnalysisKey ShaderFlagsAnalysis::Key;
ComputedShaderFlags ShaderFlagsAnalysis::run(Module &M,
ModuleAnalysisManager &AM) {
- return ComputedShaderFlags::computeFlags(M);
+ return ComputedShaderFlags::computeFlags(M, &AM);
}
PreservedAnalyses ShaderFlagsAnalysisPrinter::run(Module &M,
diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.h b/llvm/lib/Target/DirectX/DXILShaderFlags.h
index 1df7d27de13d3c..86d0a70dcbee10 100644
--- a/llvm/lib/Target/DirectX/DXILShaderFlags.h
+++ b/llvm/lib/Target/DirectX/DXILShaderFlags.h
@@ -60,7 +60,7 @@ struct ComputedShaderFlags {
return FeatureFlags;
}
- static ComputedShaderFlags computeFlags(Module &M);
+ static ComputedShaderFlags computeFlags(Module &M, ModuleAnalysisManager *AM);
void print(raw_ostream &OS = dbgs()) const;
LLVM_DUMP_METHOD void dump() const { print(); }
};
@@ -102,7 +102,7 @@ class ShaderFlagsAnalysisWrapper : public ModulePass {
const ComputedShaderFlags &getShaderFlags() { return Flags; }
bool runOnModule(Module &M) override {
- Flags = ComputedShaderFlags::computeFlags(M);
+ Flags = ComputedShaderFlags::computeFlags(M, nullptr);
return false;
}
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/buffers.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/buffers.ll
new file mode 100644
index 00000000000000..93346c2d5587db
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/buffers.ll
@@ -0,0 +1,23 @@
+; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
+
+target triple = "dxil-pc-shadermodel6.3-compute"
+
+@G = external constant <4 x float>, align 4
+
+define void @test_bufferflags() {
+
+ ; RWBuffer<int> Buf : register(u7, space2)
+ %uav0 = call target("dx.TypedBuffer", i32, 1, 0, 1)
+ @llvm.dx.handle.fromBinding.tdx.TypedBuffer_i32_1_0t(
+ i32 2, i32 7, i32 1, i32 0, i1 false)
+
+; CHECK: ; Shader Flags Value: 0x00000010
+; CHECK: ; Note: shader requires additional functionality:
+; CHECK-NEXT: ; Note: extra DXIL module flags:
+; CHECK-NEXT: ; D3D11_SB_GLOBAL_FLAG_ENABLE_RAW_AND_STRUCTURED_BUFFERS
+; CHECK-NEXT: {{^;$}}
+
+ ret void
+}
+
+attributes #0 = { nocallback nofree nosync nounwind willreturn memory(none) }
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/buffers_cs4.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/buffers_cs4.ll
new file mode 100644
index 00000000000000..21b05e4ef59a22
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/buffers_cs4.ll
@@ -0,0 +1,24 @@
+; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
+
+target triple = "dxil-pc-shadermodel4.0-compute"
+
+@G = external constant <4 x float>, align 4
+
+define void @test_bufferflags() {
+
+ ; RWBuffer<int> Buf : register(u7, space2)
+ %uav0 = call target("dx.TypedBuffer", i32, 1, 0, 1)
+ @llvm.dx.handle.fromBinding.tdx.TypedBuffer_i32_1_0t(
+ i32 2, i32 7, i32 1, i32 0, i1 false)
+
+; CHECK: ; Shader Flags Value: 0x00020010
+; CHECK: ; Note: shader requires additional functionality:
+; CHECK-NEXT: ; Raw and Structured buffers
+; CHECK-NEXT: ; Note: extra DXIL module flags:
+; CHECK-NEXT: ; D3D11_SB_GLOBAL_FLAG_ENABLE_RAW_AND_STRUCTURED_BUFFERS
+; CHECK-NEXT: {{^;$}}
+
+ ret void
+}
+
+attributes #0 = { nocallback nofree nosync nounwind willreturn memory(none) }
|
Hopefully this PR helps validate my approach for setting these flags. I have not figured out how to get strcuturedbuffers to work/be detected yet. I thought I had the correct IR, but they are not being picked up for some reason. I had this logic in the code which is not in this PR
|
|
||
// RWBuffer | ||
for (const ResourceInfo &RI : DRM.uavs()) { | ||
if (RI.getResourceKind() == ResourceKind::TypedBuffer) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks wrong. It should only set this if it's a StructuredBuffer
or RawBuffer
(aka. ByteAddressBuffer
), but not if it's a TypedBuffer
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm.. I went for this approach because of how the IR looked. Maybe I missed something here.
; RWBuffer<int> Buf : register(u7, space2)
%uav0 = call target("dx.TypedBuffer", i32, 1, 0, 1)
@llvm.dx.handle.fromBinding.tdx.TypedBuffer_i32_1_0t(
i32 2, i32 7, i32 1, i32 0, i1 false)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In HLSL: RWBuffer
is a typed buffer. You want to set this if one of the HLSL types: RWStructuredBuffer
or RWByteAddressBuffer
, is used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe I fixed this now.
if (RI.getResourceKind() == ResourceKind::TypedBuffer) { | ||
Flags.EnableRawAndStructuredBuffers = true; | ||
Flags.ComputeShadersPlusRawAndStructuredBuffers = | ||
(SP == Triple::EnvironmentType::Compute && SM.getMajor() == 4); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SM.getMajor() == 4
This means SM 4.x? In which case this flag will never be set. I'm surprised it isn't >= 4
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah.. I was too! I looked at the DXC source and it does this type of check.. Since I recently learned that there is no way we would even support SM4, we should just not set this flag anyway and remove it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably should get some more opinions on this. If we were to ever support SM 4.0 via DXBC in the future then having this in here would likely be helpful to that effort.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This issue has been resolved in chat. The result is to not set this flag as it will not be used at this time.
…t that went along with it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After some further analysis, I don't think we should set this flag in this compiler, unless/until we support ps_4_0
/ps_4_1
DXBC targets, where the flag is used in the DXBC instruction stream. This is the only place this flag is used.
; CHECK: ; Shader Flags Value: 0x00000010 | ||
; CHECK: ; Note: shader requires additional functionality: | ||
; CHECK-NEXT: ; Note: extra DXIL module flags: | ||
; CHECK-NEXT: ; D3D11_SB_GLOBAL_FLAG_ENABLE_RAW_AND_STRUCTURED_BUFFERS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't one of the optional feature flags used by the runtime. So, it should not have a comment saying "shader requires additional functionality". You can tell which flags should be reported under this statement by looking at the ones set in the ShaderFlags::GetFeatureInfo method in DxilShaderFlags.cpp in DXC.
Instead, this flag mirrors a global flag that was set in the DXBC dcl_globalFlags instruction token: D3D11_SB_GLOBAL_FLAG_ENABLE_RAW_AND_STRUCTURED_BUFFERS
. This value this identifier is defined to in the DXBC token stream is not the same value as in the DXIL Shader Flags, so that could be a bit confusing to write that out here as the flag name.
Additionally: It turns out that this flag is only generated for SRV raw/structured buffers on ps_4_0
or ps_4_1
. UAV's not allowed for those targets at all.
It only exists in DXIL as the way to preserve this DXBC flag when we were writing the initial version of the DXBC to DXIL converter (DxilConv.dll), which originally would try to preserve the shader model and any flags set in the original DXBC.
So due to these limitations, I believe we shouldn't ever need to set this flag for DXIL in this compiler after all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've opened microsoft/DirectXShaderCompiler#7003 to track removal for validation.
Closing this pull request as these flags being set are no longer needed or used. Tex opened microsoft/DirectXShaderCompiler#7003 to track addressing what to do with them long term. |
This commit address Issue #112273 .
This change includes updates to the shader analysis pass and walking the resource metadata to properly set the required shader flags for RWbuffers.