Skip to content

Commit 8f37a2e

Browse files
committed
d3d12: raw SRV/UAV views for structured buffers
1 parent d56eb57 commit 8f37a2e

1 file changed

Lines changed: 29 additions & 19 deletions

File tree

sources/engine/Stride.Graphics/Direct3D12/Buffer.Direct3D12.cs

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -304,23 +304,32 @@ internal CpuDescriptorHandle GetShaderResourceView(PixelFormat viewFormat)
304304

305305
if (ViewFlags.HasFlag(BufferFlags.ShaderResource))
306306
{
307+
// The DXIL produced by mesa's spirv_to_dxil lowers SPIR-V SSBOs to ByteAddressBuffer
308+
// (DXIL_RESOURCE_KIND_RAW_BUFFER) regardless of whether the original SDSL declared
309+
// them as StructuredBuffer<T>. Binding a structured-buffer SRV (StructureByteStride > 0)
310+
// to a ByteAddressBuffer DXIL slot has undefined access bounds per the D3D12 spec —
311+
// observed clamp on NVIDIA is NumElements * 16 bytes, hiding ~3/4 of the buffer.
312+
// Always emit raw SRVs for buffers flagged as ShaderResource so byte-addressed
313+
// access from DXIL covers the full buffer.
314+
bool useRawView = ViewFlags.HasFlag(BufferFlags.RawBuffer)
315+
|| ViewFlags.HasFlag(BufferFlags.StructuredBuffer);
316+
307317
var description = new ShaderResourceViewDesc
308318
{
309319
Shader4ComponentMapping = 0x00001688,
310-
Format = (Format) viewFormat,
320+
Format = useRawView ? Format.FormatR32Typeless : (Format) viewFormat,
311321
ViewDimension = SrvDimension.Buffer,
312322
Buffer = new()
313323
{
314-
NumElements = (uint) ElementCount,
315324
FirstElement = 0,
316-
Flags = BufferSrvFlags.None,
317-
StructureByteStride = (uint) StructureByteStride
325+
NumElements = useRawView
326+
? (uint) (SizeInBytes / 4)
327+
: (uint) ElementCount,
328+
Flags = useRawView ? BufferSrvFlags.Raw : BufferSrvFlags.None,
329+
StructureByteStride = useRawView ? 0u : (uint) StructureByteStride,
318330
}
319331
};
320332

321-
if (ViewFlags.HasFlag(BufferFlags.RawBuffer))
322-
description.Buffer.Flags |= BufferSrvFlags.Raw;
323-
324333
srv = GraphicsDevice.ShaderResourceViewAllocator.Allocate();
325334
NativeDevice.CreateShaderResourceView(NativeResource, in description, srv);
326335
}
@@ -343,34 +352,35 @@ internal CpuDescriptorHandle GetUnorderedAccessView(PixelFormat viewFormat)
343352

344353
if (ViewFlags.HasFlag(BufferFlags.UnorderedAccess))
345354
{
355+
// Mesa's spirv_to_dxil emits writable SSBOs as RWByteAddressBuffer; mirror the
356+
// SRV-side decision and always use raw UAV views for structured / raw buffers.
357+
bool useRawView = ViewFlags.HasFlag(BufferFlags.RawBuffer)
358+
|| ViewFlags.HasFlag(BufferFlags.StructuredBuffer);
359+
346360
var description = new UnorderedAccessViewDesc
347361
{
348-
Format = (Format) viewFormat,
362+
Format = useRawView ? Format.FormatR32Typeless : (Format) viewFormat,
349363
ViewDimension = UavDimension.Buffer,
350364
Buffer = new()
351365
{
352-
NumElements = (uint) ElementCount,
353366
FirstElement = 0,
354-
Flags = BufferUavFlags.None,
355-
StructureByteStride = (uint) StructureByteStride,
367+
NumElements = useRawView
368+
? (uint) (SizeInBytes / 4)
369+
: (uint) ElementCount,
370+
Flags = useRawView ? BufferUavFlags.Raw : BufferUavFlags.None,
371+
StructureByteStride = useRawView ? 0u : (uint) StructureByteStride,
356372
CounterOffsetInBytes = 0
357373
}
358374
};
359375

360-
if (ViewFlags.HasFlag(BufferFlags.RawBuffer))
361-
{
362-
description.Buffer.Flags |= BufferUavFlags.Raw;
363-
description.Format = Format.FormatR32Typeless;
364-
}
365-
366376
uav = GraphicsDevice.UnorderedAccessViewAllocator.Allocate(1);
367377

368378
// TODO: Manage counter value here if Buffer has 'Counter' or 'Append' flag
369379
// if (Flags == BufferFlags.StructuredAppendBuffer || Flags == BufferFlags.StructuredCounterBuffer))
370380
NativeDevice.CreateUnorderedAccessView(NativeResource, pCounterResource: null, in description, uav);
371381
}
372382
return uav;
373-
}}
383+
}
374384
}
375-
385+
}
376386
#endif

0 commit comments

Comments
 (0)