Skip to content

cpu: move draw resource resolution off the committer, from 25 to 10-15 µs per draw #4

Open

Description

@panicDa3m0n

Problem

With the recommended launch profile (APS5_NO_DRAW_RELOCATION=1, APS5_PARALLEL_DRAW_PREPARE=2) the frame (about 74 ms on the test machine) is set by the single committer thread: about 2,050 draws per frame at about 25 µs each, roughly 51 ms of work. 99 % of draws are template hits, yet the committer still resolves their whole bound state from guest memory, under the GPU lock, every time.

Where the 25 µs go on the template-hit path (APS5_PROFILE_DRAW), in µs per draw:

Phase µs
lookup and proof 5.3
recording (of which PrepareDrawBindings about 6) 9.6
vertex inputs 3.0
keep 1.6
pipeline 1.5
target 1.4

Details are in docs/research/cpu-chain.md.

What was tried

  • A validity token per template (tracker generation, collection epoch, pending serial, storage-cache serial). It was correct, but worth only about −0.8 ms per frame. The remaining cost of the proof is concentrated in about 28 % of the proofs, at about 12.5 µs each, so it was archived.
  • Lock-free per-texture validity. Inside the fast proof, CollectWrites is about 37 %. The ceiling of this piece is 3-4 % of the frame, so it was not prototyped.

The conclusion: small memos on the committer are not enough. The work has to leave the committer.

Direction being explored

The direction follows the command-stream model of DXVK, with ideas from vkd3d-proton and shadPS4:

  • resolve a draw's resources on the draw preparation threads, outside the GPU lock, speculatively;
  • validate the speculation at commit with cheap stamps;
  • keep only recording under the lock.

A probe that counts what such a speculation would have kept, without changing behaviour, says it holds for 99.46 % of the draws in the reference scene (0.54 % fall back). The estimated committer cost after the step is about 13.5 µs per draw.

There are three prototypes, each behind its own switch, with a verification mode and tests with mutations. The first is in progress:

  1. bindings;
  2. vertex inputs, validation and pipeline;
  3. the template proof.

Help wanted

  • Review of the approach: what can go stale between preparation and commit (CPU writes, GPU writes, labels, pending imports), and which stamps catch it.
  • Measurements on other CPUs: the split of the 25 µs may differ on AMD CPUs or CPUs with more cache. Use the Performance report form.
  • Descriptors: pushing per-draw descriptors (maxPushDescriptors 32) or a descriptor heap instead of a new set per draw.

Related upstream work

Activity

  1. added
    help wantedExtra attention is needed
    cpuCPU side of the driver
    performanceFrame-time work or a measured slowdown
    on Oct 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    cpuCPU side of the driverhelp wantedExtra attention is neededperformanceFrame-time work or a measured slowdown

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions