Skip to content

Commit 368c7f7

Browse files
authored
[DirectX] Match DXC's resource order in DX container (#130233)
DXC and the DXIL validator expect resources in a DX container to be specifically ordered CBuffers, Samplers, SRVs, and then UAVs. Match this behaviour so that we can pass the validator. Fixes #130232.
1 parent 6f4ddef commit 368c7f7

File tree

4 files changed

+95
-38
lines changed

4 files changed

+95
-38
lines changed

llvm/include/llvm/BinaryFormat/DXContainer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ ArrayRef<EnumEntry<ResourceKind>> getResourceKinds();
320320

321321
#define RESOURCE_FLAG(Index, Enum) bool Enum = false;
322322
struct ResourceFlags {
323-
ResourceFlags() {};
323+
ResourceFlags() : Flags(0U) {};
324324
struct FlagsBits {
325325
#include "llvm/BinaryFormat/DXContainerConstants.def"
326326
};

llvm/lib/Target/DirectX/DXContainerGlobals.cpp

Lines changed: 57 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -186,51 +186,71 @@ void DXContainerGlobals::addResourcesForPSV(Module &M, PSVRuntimeInfo &PSV) {
186186
DXILResourceTypeMap &DRTM =
187187
getAnalysis<DXILResourceTypeWrapperPass>().getResourceTypeMap();
188188

189-
for (const dxil::ResourceBindingInfo &RBI : DBM) {
189+
auto MakeBinding =
190+
[](const dxil::ResourceBindingInfo::ResourceBinding &Binding,
191+
const dxbc::PSV::ResourceType Type, const dxil::ResourceKind Kind,
192+
const dxbc::PSV::ResourceFlags Flags = dxbc::PSV::ResourceFlags()) {
193+
dxbc::PSV::v2::ResourceBindInfo BindInfo;
194+
BindInfo.Type = Type;
195+
BindInfo.LowerBound = Binding.LowerBound;
196+
BindInfo.UpperBound = Binding.LowerBound + Binding.Size - 1;
197+
BindInfo.Space = Binding.Space;
198+
BindInfo.Kind = static_cast<dxbc::PSV::ResourceKind>(Kind);
199+
BindInfo.Flags = Flags;
200+
return BindInfo;
201+
};
202+
203+
for (const dxil::ResourceBindingInfo &RBI : DBM.cbuffers()) {
204+
const dxil::ResourceBindingInfo::ResourceBinding &Binding =
205+
RBI.getBinding();
206+
PSV.Resources.push_back(MakeBinding(Binding, dxbc::PSV::ResourceType::CBV,
207+
dxil::ResourceKind::CBuffer));
208+
}
209+
for (const dxil::ResourceBindingInfo &RBI : DBM.samplers()) {
210+
const dxil::ResourceBindingInfo::ResourceBinding &Binding =
211+
RBI.getBinding();
212+
PSV.Resources.push_back(MakeBinding(Binding,
213+
dxbc::PSV::ResourceType::Sampler,
214+
dxil::ResourceKind::Sampler));
215+
}
216+
for (const dxil::ResourceBindingInfo &RBI : DBM.srvs()) {
190217
const dxil::ResourceBindingInfo::ResourceBinding &Binding =
191218
RBI.getBinding();
192-
dxbc::PSV::v2::ResourceBindInfo BindInfo;
193-
BindInfo.LowerBound = Binding.LowerBound;
194-
BindInfo.UpperBound = Binding.LowerBound + Binding.Size - 1;
195-
BindInfo.Space = Binding.Space;
196219

197220
dxil::ResourceTypeInfo &TypeInfo = DRTM[RBI.getHandleTy()];
198-
dxbc::PSV::ResourceType ResType = dxbc::PSV::ResourceType::Invalid;
199-
bool IsUAV = TypeInfo.getResourceClass() == dxil::ResourceClass::UAV;
200-
switch (TypeInfo.getResourceKind()) {
201-
case dxil::ResourceKind::Sampler:
202-
ResType = dxbc::PSV::ResourceType::Sampler;
203-
break;
204-
case dxil::ResourceKind::CBuffer:
205-
ResType = dxbc::PSV::ResourceType::CBV;
206-
break;
207-
case dxil::ResourceKind::StructuredBuffer:
208-
ResType = IsUAV ? dxbc::PSV::ResourceType::UAVStructured
209-
: dxbc::PSV::ResourceType::SRVStructured;
210-
if (IsUAV && TypeInfo.getUAV().HasCounter)
211-
ResType = dxbc::PSV::ResourceType::UAVStructuredWithCounter;
212-
break;
213-
case dxil::ResourceKind::RTAccelerationStructure:
221+
dxbc::PSV::ResourceType ResType;
222+
if (TypeInfo.isStruct())
223+
ResType = dxbc::PSV::ResourceType::SRVStructured;
224+
else if (TypeInfo.isTyped())
225+
ResType = dxbc::PSV::ResourceType::SRVTyped;
226+
else
214227
ResType = dxbc::PSV::ResourceType::SRVRaw;
215-
break;
216-
case dxil::ResourceKind::RawBuffer:
217-
ResType = IsUAV ? dxbc::PSV::ResourceType::UAVRaw
218-
: dxbc::PSV::ResourceType::SRVRaw;
219-
break;
220-
default:
221-
ResType = IsUAV ? dxbc::PSV::ResourceType::UAVTyped
222-
: dxbc::PSV::ResourceType::SRVTyped;
223-
break;
224-
}
225-
BindInfo.Type = ResType;
226-
227-
BindInfo.Kind =
228-
static_cast<dxbc::PSV::ResourceKind>(TypeInfo.getResourceKind());
228+
229+
PSV.Resources.push_back(
230+
MakeBinding(Binding, ResType, TypeInfo.getResourceKind()));
231+
}
232+
for (const dxil::ResourceBindingInfo &RBI : DBM.uavs()) {
233+
const dxil::ResourceBindingInfo::ResourceBinding &Binding =
234+
RBI.getBinding();
235+
236+
dxil::ResourceTypeInfo &TypeInfo = DRTM[RBI.getHandleTy()];
237+
dxbc::PSV::ResourceType ResType;
238+
if (TypeInfo.getUAV().HasCounter)
239+
ResType = dxbc::PSV::ResourceType::UAVStructuredWithCounter;
240+
else if (TypeInfo.isStruct())
241+
ResType = dxbc::PSV::ResourceType::UAVStructured;
242+
else if (TypeInfo.isTyped())
243+
ResType = dxbc::PSV::ResourceType::UAVTyped;
244+
else
245+
ResType = dxbc::PSV::ResourceType::UAVRaw;
246+
247+
dxbc::PSV::ResourceFlags Flags;
229248
// TODO: Add support for dxbc::PSV::ResourceFlag::UsedByAtomic64, tracking
230249
// with https://github.com/llvm/llvm-project/issues/104392
231-
BindInfo.Flags.Flags = 0u;
250+
Flags.Flags = 0u;
232251

233-
PSV.Resources.emplace_back(BindInfo);
252+
PSV.Resources.push_back(
253+
MakeBinding(Binding, ResType, TypeInfo.getResourceKind(), Flags));
234254
}
235255
}
236256

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
; RUN: llc %s --filetype=obj -o - | obj2yaml | FileCheck %s
2+
3+
; Check that resources are emitted to the object in the order that matches what
4+
; the DXIL validator expects: CBuffers, Samplers, SRVs, and then UAVs.
5+
6+
; CHECK: Resources:
7+
; CHECK: - Type: CBV
8+
; TODO: - Type: Sampler
9+
; CHECK: - Type: SRVRaw
10+
; CHECK: - Type: UAVTyped
11+
12+
target triple = "dxil-unknown-shadermodel6.0-compute"
13+
14+
define void @main() #0 {
15+
%uav0 = call target("dx.TypedBuffer", i32, 1, 0, 1)
16+
@llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_i32_1_0t(
17+
i32 2, i32 7, i32 1, i32 0, i1 false)
18+
%srv0 = call target("dx.RawBuffer", i8, 0, 0)
19+
@llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_0_0t(
20+
i32 1, i32 8, i32 1, i32 0, i1 false)
21+
%cbuf = call target("dx.CBuffer", target("dx.Layout", {float}, 4, 0))
22+
@llvm.dx.resource.handlefrombinding(i32 3, i32 2, i32 1, i32 0, i1 false)
23+
ret void
24+
}
25+
26+
attributes #0 = { "hlsl.numthreads"="1,1,1" "hlsl.shader"="compute" }

llvm/test/CodeGen/DirectX/ContainerData/PSVResources.ll

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,17 @@ target triple = "dxil-unknown-shadermodel6.0-compute"
66

77
define void @main() #0 {
88

9+
; cbuffer : register(b2, space3) { float x; }
10+
; CHECK: - Type: CBV
11+
; CHECK: Space: 3
12+
; CHECK: LowerBound: 2
13+
; CHECK: UpperBound: 2
14+
; CHECK: Kind: CBuffer
15+
; CHECK: Flags:
16+
; CHECK: UsedByAtomic64: false
17+
%cbuf = call target("dx.CBuffer", target("dx.Layout", {float}, 4, 0))
18+
@llvm.dx.resource.handlefrombinding(i32 3, i32 2, i32 1, i32 0, i1 false)
19+
920
; ByteAddressBuffer Buf : register(t8, space1)
1021
; CHECK: - Type: SRVRaw
1122
; CHECK: Space: 1

0 commit comments

Comments
 (0)