@@ -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