Skip to content

[DirectX] Set the EnableRawAndStructuredBuffers shader flag #122667

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

Merged
merged 1 commit into from
Jan 21, 2025

Conversation

bogner
Copy link
Contributor

@bogner bogner commented Jan 13, 2025

When raw or structured buffers are used, we need to set the DXIL flag saying so.

Fixes #122663.

When raw or structured buffers are used, we need to set the DXIL flag
saying so.

Fixes llvm#122663.
@llvmbot
Copy link
Member

llvmbot commented Jan 13, 2025

@llvm/pr-subscribers-backend-directx

Author: Justin Bogner (bogner)

Changes

When raw or structured buffers are used, we need to set the DXIL flag saying so.

Fixes #122663.


Full diff: https://github.com/llvm/llvm-project/pull/122667.diff

3 Files Affected:

  • (modified) llvm/include/llvm/BinaryFormat/DXContainerConstants.def (+1-1)
  • (modified) llvm/lib/Target/DirectX/DXILShaderFlags.cpp (+11)
  • (added) llvm/test/CodeGen/DirectX/ShaderFlags/raw-and-structured-buffers.ll (+42)
diff --git a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
index 1aacbb2f65b27f..96d4499c9cadc9 100644
--- a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
+++ b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
@@ -58,7 +58,7 @@ SHADER_FEATURE_FLAG(31, 36, NextUnusedBit, "Next reserved shader flag bit (not a
 DXIL_MODULE_FLAG( 0,  DisableOptimizations,   "D3D11_1_SB_GLOBAL_FLAG_SKIP_OPTIMIZATION")
 DXIL_MODULE_FLAG( 1,  DisableMathRefactoring, "D3D10_SB_GLOBAL_FLAG_REFACTORING_ALLOWED")
 DXIL_MODULE_FLAG( 3,  ForceEarlyDepthStencil, "D3D11_SB_GLOBAL_FLAG_FORCE_EARLY_DEPTH_STENCIL")
-DXIL_MODULE_FLAG( 4,  EnableRawAndStructuredBuffers, "D3D11_SB_GLOBAL_FLAG_ENABLE_RAW_AND_STRUCTURED_BUFFERS")
+DXIL_MODULE_FLAG( 4,  EnableRawAndStructuredBuffers, "Raw and Structured buffers")
 DXIL_MODULE_FLAG( 5,  LowPrecisionPresent, "D3D11_1_SB_GLOBAL_FLAG_ENABLE_MINIMUM_PRECISION")
 DXIL_MODULE_FLAG( 8,  AllResourcesBound, "D3D12_SB_GLOBAL_FLAG_ALL_RESOURCES_BOUND")
 DXIL_MODULE_FLAG(23,  UseNativeLowPrecision, "Native 16bit types enabled")
diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
index 2edfc707ce6c79..36e9119363f5c7 100644
--- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
+++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
@@ -54,11 +54,22 @@ static void updateFunctionFlags(ComputedShaderFlags &CSF, const Instruction &I,
     switch (II->getIntrinsicID()) {
     default:
       break;
+    case Intrinsic::dx_resource_handlefrombinding:
+      switch (DRTM[cast<TargetExtType>(II->getType())].getResourceKind()) {
+      case dxil::ResourceKind::StructuredBuffer:
+      case dxil::ResourceKind::RawBuffer:
+        CSF.EnableRawAndStructuredBuffers = true;
+        break;
+      default:
+        break;
+      }
+      break;
     case Intrinsic::dx_resource_load_typedbuffer: {
       dxil::ResourceTypeInfo &RTI =
           DRTM[cast<TargetExtType>(II->getArgOperand(0)->getType())];
       if (RTI.isTyped())
         CSF.TypedUAVLoadAdditionalFormats |= RTI.getTyped().ElementCount > 1;
+      break;
     }
     }
   }
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/raw-and-structured-buffers.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/raw-and-structured-buffers.ll
new file mode 100644
index 00000000000000..9cb83c4e992bad
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/raw-and-structured-buffers.ll
@@ -0,0 +1,42 @@
+; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
+
+; Note: there is no feature flag here (only a module flag), so we don't have an
+; object test.
+
+target triple = "dxil-pc-shadermodel6.7-library"
+
+; CHECK:      Combined Shader Flags for Module
+; CHECK-NEXT: Shader Flags Value: 0x00000010
+
+; CHECK: Note: shader requires additional functionality:
+; CHECK:       Raw and Structured buffers
+
+; CHECK: Function rawbuf : 0x00000010
+define float @rawbuf() "hlsl.export" {
+  %buffer = call target("dx.RawBuffer", i8, 0, 0, 0)
+      @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false)
+  %load = call {float, i1} @llvm.dx.resource.load.rawbuffer.f32(
+      target("dx.RawBuffer", i8, 0, 0, 0) %buffer, i32 0, i32 0)
+  %data = extractvalue {float, i1} %load, 0
+  ret float %data
+}
+
+; CHECK: Function structbuf : 0x00000010
+define float @structbuf() "hlsl.export" {
+  %buffer = call target("dx.RawBuffer", float, 0, 0, 0)
+      @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false)
+  %load = call {float, i1} @llvm.dx.resource.load.rawbuffer.f32(
+      target("dx.RawBuffer", float, 0, 0, 0) %buffer, i32 0, i32 0)
+  %data = extractvalue {float, i1} %load, 0
+  ret float %data
+}
+
+; CHECK: Function typedbuf : 0x00000000
+define float @typedbuf(<4 x float> %val) "hlsl.export" {
+  %buffer = call target("dx.TypedBuffer", float, 0, 0, 0)
+      @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false)
+  %load = call {float, i1} @llvm.dx.resource.load.typedbuffer(
+      target("dx.TypedBuffer", float, 0, 0, 0) %buffer, i32 0)
+  %data = extractvalue {float, i1} %load, 0
+  ret float %data
+}

@llvmbot
Copy link
Member

llvmbot commented Jan 13, 2025

@llvm/pr-subscribers-llvm-binary-utilities

Author: Justin Bogner (bogner)

Changes

When raw or structured buffers are used, we need to set the DXIL flag saying so.

Fixes #122663.


Full diff: https://github.com/llvm/llvm-project/pull/122667.diff

3 Files Affected:

  • (modified) llvm/include/llvm/BinaryFormat/DXContainerConstants.def (+1-1)
  • (modified) llvm/lib/Target/DirectX/DXILShaderFlags.cpp (+11)
  • (added) llvm/test/CodeGen/DirectX/ShaderFlags/raw-and-structured-buffers.ll (+42)
diff --git a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
index 1aacbb2f65b27f..96d4499c9cadc9 100644
--- a/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
+++ b/llvm/include/llvm/BinaryFormat/DXContainerConstants.def
@@ -58,7 +58,7 @@ SHADER_FEATURE_FLAG(31, 36, NextUnusedBit, "Next reserved shader flag bit (not a
 DXIL_MODULE_FLAG( 0,  DisableOptimizations,   "D3D11_1_SB_GLOBAL_FLAG_SKIP_OPTIMIZATION")
 DXIL_MODULE_FLAG( 1,  DisableMathRefactoring, "D3D10_SB_GLOBAL_FLAG_REFACTORING_ALLOWED")
 DXIL_MODULE_FLAG( 3,  ForceEarlyDepthStencil, "D3D11_SB_GLOBAL_FLAG_FORCE_EARLY_DEPTH_STENCIL")
-DXIL_MODULE_FLAG( 4,  EnableRawAndStructuredBuffers, "D3D11_SB_GLOBAL_FLAG_ENABLE_RAW_AND_STRUCTURED_BUFFERS")
+DXIL_MODULE_FLAG( 4,  EnableRawAndStructuredBuffers, "Raw and Structured buffers")
 DXIL_MODULE_FLAG( 5,  LowPrecisionPresent, "D3D11_1_SB_GLOBAL_FLAG_ENABLE_MINIMUM_PRECISION")
 DXIL_MODULE_FLAG( 8,  AllResourcesBound, "D3D12_SB_GLOBAL_FLAG_ALL_RESOURCES_BOUND")
 DXIL_MODULE_FLAG(23,  UseNativeLowPrecision, "Native 16bit types enabled")
diff --git a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
index 2edfc707ce6c79..36e9119363f5c7 100644
--- a/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
+++ b/llvm/lib/Target/DirectX/DXILShaderFlags.cpp
@@ -54,11 +54,22 @@ static void updateFunctionFlags(ComputedShaderFlags &CSF, const Instruction &I,
     switch (II->getIntrinsicID()) {
     default:
       break;
+    case Intrinsic::dx_resource_handlefrombinding:
+      switch (DRTM[cast<TargetExtType>(II->getType())].getResourceKind()) {
+      case dxil::ResourceKind::StructuredBuffer:
+      case dxil::ResourceKind::RawBuffer:
+        CSF.EnableRawAndStructuredBuffers = true;
+        break;
+      default:
+        break;
+      }
+      break;
     case Intrinsic::dx_resource_load_typedbuffer: {
       dxil::ResourceTypeInfo &RTI =
           DRTM[cast<TargetExtType>(II->getArgOperand(0)->getType())];
       if (RTI.isTyped())
         CSF.TypedUAVLoadAdditionalFormats |= RTI.getTyped().ElementCount > 1;
+      break;
     }
     }
   }
diff --git a/llvm/test/CodeGen/DirectX/ShaderFlags/raw-and-structured-buffers.ll b/llvm/test/CodeGen/DirectX/ShaderFlags/raw-and-structured-buffers.ll
new file mode 100644
index 00000000000000..9cb83c4e992bad
--- /dev/null
+++ b/llvm/test/CodeGen/DirectX/ShaderFlags/raw-and-structured-buffers.ll
@@ -0,0 +1,42 @@
+; RUN: opt -S --passes="print-dx-shader-flags" 2>&1 %s | FileCheck %s
+
+; Note: there is no feature flag here (only a module flag), so we don't have an
+; object test.
+
+target triple = "dxil-pc-shadermodel6.7-library"
+
+; CHECK:      Combined Shader Flags for Module
+; CHECK-NEXT: Shader Flags Value: 0x00000010
+
+; CHECK: Note: shader requires additional functionality:
+; CHECK:       Raw and Structured buffers
+
+; CHECK: Function rawbuf : 0x00000010
+define float @rawbuf() "hlsl.export" {
+  %buffer = call target("dx.RawBuffer", i8, 0, 0, 0)
+      @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false)
+  %load = call {float, i1} @llvm.dx.resource.load.rawbuffer.f32(
+      target("dx.RawBuffer", i8, 0, 0, 0) %buffer, i32 0, i32 0)
+  %data = extractvalue {float, i1} %load, 0
+  ret float %data
+}
+
+; CHECK: Function structbuf : 0x00000010
+define float @structbuf() "hlsl.export" {
+  %buffer = call target("dx.RawBuffer", float, 0, 0, 0)
+      @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false)
+  %load = call {float, i1} @llvm.dx.resource.load.rawbuffer.f32(
+      target("dx.RawBuffer", float, 0, 0, 0) %buffer, i32 0, i32 0)
+  %data = extractvalue {float, i1} %load, 0
+  ret float %data
+}
+
+; CHECK: Function typedbuf : 0x00000000
+define float @typedbuf(<4 x float> %val) "hlsl.export" {
+  %buffer = call target("dx.TypedBuffer", float, 0, 0, 0)
+      @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false)
+  %load = call {float, i1} @llvm.dx.resource.load.typedbuffer(
+      target("dx.TypedBuffer", float, 0, 0, 0) %buffer, i32 0)
+  %data = extractvalue {float, i1} %load, 0
+  ret float %data
+}

@bharadwajy
Copy link
Contributor

An issue to track setting of EnableRawAndStructuredBuffers was closed as not needed with a link to the issue that explains why it is not needed and how it is expected to be addressed in DXC.

Is this shader flag needed in clang? Is it planned to be consumed in the generated shaders?

@bogner
Copy link
Contributor Author

bogner commented Jan 14, 2025

An issue to track setting of EnableRawAndStructuredBuffers was closed as not needed with a link to the issue that explains why it is not needed and how it is expected to be addressed in DXC.

Is this shader flag needed in clang? Is it planned to be consumed in the generated shaders?

So we definitely need these flags to be set if we want to be able to pass the dxil validator as it is today, and I don't really understand why we closed those issues as not needed. As far as I can tell microsoft/DirectXShaderCompiler#7003 isn't scheduled, so until there's some movement on that we definitely need these flags set for the particle_life milestone

@bogner bogner merged commit b6287fd into llvm:main Jan 21, 2025
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

[DirectX] Implement shader flag analysis for EnableRawAndStructuredBuffers
5 participants