Skip to content

Commit 3bf61f2

Browse files
committed
fix: D3D12 skip upload/readback resources by heap type, not state
TransitionDescriptorResources skipped resources whose NativeResourceState was GenericRead or CopyDest, treating those states as upload/readback heap markers. That conflates heap type (a lifetime property of Upload/ Readback heaps) with transient state (a Default-heap resource can be in CopyDest after a Copy/Resolve/UpdateSubresource). The skip silently dropped the binding-time transition and left stale layouts leaking into the next SRV/Present — D3D12 GPU validation 'Incompatible texture barrier layout', SRV sampling in LEGACY_COPY_DEST, WARP 1.0.18 missing glyphs in dynamic sprite font tests, back-buffer Present failing in COPY_SOURCE on RenderToWindow. Track heap type explicitly: add IsHostVisibleHeap on GraphicsResource, set at resource creation (Upload/Readback → true, Default → false). Draw prep skips on that flag, not on state. Default-heap resources in CopyDest/CopySource/GenericRead after a copy go through the normal transition to ShaderResource at next bind — single barrier, no reliance on a post-copy Common transition and on barrier coalescing to merge it.
1 parent 29409a3 commit 3bf61f2

4 files changed

Lines changed: 20 additions & 3 deletions

File tree

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ public void Recreate(IntPtr dataPointer)
176176
NativeResourceState |= ResourceStates.IndirectArgument;
177177

178178
var heapType = HeapType.Default;
179+
IsHostVisibleHeap = false;
179180
if (Usage == GraphicsResourceUsage.Staging)
180181
{
181182
// Per our own definition of staging resource (read-back only)
@@ -184,11 +185,13 @@ public void Recreate(IntPtr dataPointer)
184185

185186
heapType = HeapType.Readback;
186187
NativeResourceState = ResourceStates.CopyDest;
188+
IsHostVisibleHeap = true;
187189
}
188190
else if (Usage == GraphicsResourceUsage.Dynamic)
189191
{
190192
heapType = HeapType.Upload;
191193
NativeResourceState = ResourceStates.GenericRead;
194+
IsHostVisibleHeap = true;
192195
}
193196

194197
// TODO: D3D12: Move to a global allocator in bigger committed resources

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -430,9 +430,11 @@ private void TransitionDescriptorResources()
430430
if (resource is null)
431431
continue;
432432

433-
// Skip resources on upload/readback heaps (GenericRead/CopyDest) — they can't be transitioned
434-
if (resource.NativeResourceState == ResourceStates.GenericRead ||
435-
resource.NativeResourceState == ResourceStates.CopyDest)
433+
// Skip resources on CPU-visible heaps (Upload/Readback) — they have a fixed
434+
// D3D12 state for their lifetime and cannot be transitioned. Must check by heap
435+
// type, not by state: default-heap resources can be in CopyDest/GenericRead
436+
// transiently after a copy and must still go through the transition.
437+
if (resource.IsHostVisibleHeap)
436438
continue;
437439

438440
if (isUAV[j])

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,16 @@ public abstract partial class GraphicsResource
3636
/// </summary>
3737
internal ResourceStates NativeResourceState;
3838

39+
/// <summary>
40+
/// Whether this resource is on a CPU-visible heap (Upload or Readback).
41+
/// Resources on these heaps have a fixed D3D12 state (<see cref="ResourceStates.GenericRead"/>
42+
/// or <see cref="ResourceStates.CopyDest"/>) for their lifetime and cannot be transitioned —
43+
/// lazy barrier code must skip them. This is a heap-type property; don't confuse it with the
44+
/// transient <see cref="NativeResourceState"/> (default-heap resources can legitimately be in
45+
/// CopyDest after a copy).
46+
/// </summary>
47+
internal bool IsHostVisibleHeap;
48+
3949
/// <summary>
4050
/// Gets a value indicating whether the Graphics Resource is in "Debug mode".
4151
/// </summary>
@@ -75,6 +85,7 @@ internal override void SwapInternal(GraphicsResourceBase other)
7585
(NativeShaderResourceView, otherResource.NativeShaderResourceView) = (otherResource.NativeShaderResourceView, NativeShaderResourceView);
7686
(NativeUnorderedAccessView, otherResource.NativeUnorderedAccessView) = (otherResource.NativeUnorderedAccessView, NativeUnorderedAccessView);
7787
(NativeResourceState, otherResource.NativeResourceState) = (otherResource.NativeResourceState, NativeResourceState);
88+
(IsHostVisibleHeap, otherResource.IsHostVisibleHeap) = (otherResource.IsHostVisibleHeap, IsHostVisibleHeap);
7889
}
7990
}
8091
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ private partial void InitializeFromImpl(DataBox[] dataBoxes)
228228
void InitializeStagingTexture()
229229
{
230230
NativeResourceState = ResourceStates.CopyDest;
231+
IsHostVisibleHeap = true;
231232
LayoutTracker.Initialize(BarrierLayout.CopyDest, ArraySize * MipLevelCount);
232233
NativeTextureDescription = GetTextureDescription(Dimension);
233234

0 commit comments

Comments
 (0)