Skip to content
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

Closed
42 changes: 40 additions & 2 deletions llvm/lib/Target/DirectX/DXILShaderFlags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -36,8 +39,43 @@ 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;

for (const ResourceInfo &RI : DRM.uavs()) {
switch (RI.getResourceKind()) {
case ResourceKind::RawBuffer:
case ResourceKind::StructuredBuffer:
Flags.EnableRawAndStructuredBuffers = true;
break;
default:
break;
}
}

for (const ResourceInfo &RI : DRM.srvs()) {
switch (RI.getResourceKind()) {
case ResourceKind::RawBuffer:
case ResourceKind::StructuredBuffer:
Flags.EnableRawAndStructuredBuffers = true;
break;
default:
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)
Expand Down Expand Up @@ -67,7 +105,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,
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Target/DirectX/DXILShaderFlags.h
Original file line number Diff line number Diff line change
Expand Up @@ -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(); }
};
Expand Down Expand Up @@ -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;
}

Expand Down
23 changes: 23 additions & 0 deletions llvm/test/CodeGen/DirectX/ShaderFlags/buffer.ll
Original file line number Diff line number Diff line change
@@ -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() {

; ByteAddressBuffer Buf : register(t8, space1)
%srv0 = call target("dx.RawBuffer", i8, 0, 0)
@llvm.dx.handle.fromBinding.tdx.RawBuffer_i8_0_0t(
i32 1, i32 8, i32 1, i32 0, i1 false)

ret void
}

attributes #0 = { nocallback nofree nosync nounwind willreturn memory(none) }

; 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
Comment on lines +19 to +22
Copy link
Contributor

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.

Copy link
Contributor

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.

; CHECK-NEXT: {{^;$}}
23 changes: 23 additions & 0 deletions llvm/test/CodeGen/DirectX/ShaderFlags/rwbuffer.ll
Original file line number Diff line number Diff line change
@@ -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() {

; RWByteAddressBuffer Buf : register(u8, space1)
%uav0 = call target("dx.RawBuffer", i8, 1, 0)
@llvm.dx.handle.fromBinding.tdx.RawBuffer_i8_0_0t(
i32 1, i32 8, i32 1, i32 0, i1 false)

ret void
}

attributes #0 = { nocallback nofree nosync nounwind willreturn memory(none) }

; 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: {{^;$}}
24 changes: 24 additions & 0 deletions llvm/test/CodeGen/DirectX/ShaderFlags/rwstructuredbuffer.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s

target triple = "dxil-pc-shadermodel6.7-library"

@G = external constant <4 x float>, align 4

define void @test_bufferflags() {

; struct S { float4 a; uint4 b; };
; RWStructuredBuffer<S> Buf : register(u2, space4)
%struct0 = call target("dx.RawBuffer", {<4 x float>, <4 x i32>}, 1, 0)
@llvm.dx.handle.fromBinding.tdx.RawBuffer_sl_v4f32v4i32s_0_0t(
i32 4, i32 2, i32 1, i32 10, i1 true)

ret void
}

attributes #0 = { nocallback nofree nosync nounwind willreturn memory(none) }

; 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: {{^;$}}
24 changes: 24 additions & 0 deletions llvm/test/CodeGen/DirectX/ShaderFlags/structuredbuffer.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s

target triple = "dxil-pc-shadermodel6.7-library"

@G = external constant <4 x float>, align 4

define void @test_bufferflags() {

; struct S { float4 a; uint4 b; };
; StructuredBuffer<S> Buf : register(t2, space4)
%struct0 = call target("dx.RawBuffer", {<4 x float>, <4 x i32>}, 0, 0)
@llvm.dx.handle.fromBinding.tdx.RawBuffer_sl_v4f32v4i32s_0_0t(
i32 4, i32 2, i32 1, i32 10, i1 true)

ret void
}

attributes #0 = { nocallback nofree nosync nounwind willreturn memory(none) }

; 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: {{^;$}}