Skip to content

M3a: D3D12 completion watermark + resource-state handoff to wgpu's tracker #3

Description

@Bantarus

Context

Two of the four D3D12 primitives need the bridge's attention beyond a straight port:

  • Watermark (GO, simpler than Vulkan): D3D12 fences are already monotonic timeline counters. With our own ID3D12Fence, call queue.as_raw().Signal(fence, frame_no) AFTER wgpu's submit, read lock-free via GetCompletedValue(). No add_signal_semaphore plumbing (unlike the Vulkan M2b path).
  • Resource state (ADAPT): rive issues its own ResourceBarriers and leaves the target in D3D12_RESOURCE_STATE_COMMON at end of flush (render_context_d3d12_impl.cpp:2027-2030) — not a shader-read state. Also setTargetTexture seeds the tracked state to PRESENT (:433), so rive's first barrier is PRESENT -> RENDER_TARGET; for a wgpu-owned (non-swapchain) texture the real prior state differs.

Scope

  • Implement the post-submit Signal watermark using an own ID3D12Fence; recycle frames when GetCompletedValue() reaches the frame number. Reuse the safe/current-frame-number watermark already in the external-frame ABI.
  • Tell wgpu's dx12 state tracker the wrapped texture is in COMMON after rive's submit (COMMON's implicit promotion/decay is friendly). Reconcile the PRESENT-seeded initial state: hand the texture to rive decayed to COMMON, or extend wrap_d3d12_resource to set the initial tracked state. Pin the exact state values (the spike confirmed the mechanism, not the values).

Acceptance criteria

  • Frames recycle exactly when their GPU work completes (no over-/under-hold), verified under load.
  • No D3D12 debug-layer resource-state errors across rive<->wgpu handoff; the texture samples correctly in the subsequent wgpu pass.

Refs

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions