Ask the pipeline cache for a compute pipeline before queueing its build #1765

Merged
jarynclouatre merged 1 commit from fix/compute-pipeline-from-cache into main 2026-11-10 17:15:20 +00:00
jarynclouatre commented 2026-11-10 16:12:04 +00:00 (Migrated from github.com)

Since #1485 the precompile builds only the compute programs play has dispatched before. The rest are made at their first dispatch, from the pipeline cache the prepare filled, on a worker. That build is quick, but the job waits for a free worker, and on arrival in a new area the four workers are busy with graphics pipelines and stage libraries. The dispatch that starts the build waits up to 50 ms for it, so a frame that meets several new compute programs stops for 50 ms on each, and the ones still queued after that are left out.

With timing added on one run of the route below: 175 compute pipelines made in play, each 0 to 1 ms in the driver, but queued for a median 11 ms, 364 ms at the 90th percentile and 847 ms at most, behind up to 712 pending jobs. The dispatches spent 3.8 s waiting in all, and 49 of the 175 were left out.

The dispatch now asks the pipeline cache for the pipeline first, with VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT, as gpl_part asks for a stage library. A cached one comes back at once and is used. Only one the cache does not have goes to a worker, as before, so a slow compile (AMD's culling programs, Intel's serial builds) still stays off the recording thread. Needs pipelineCreationCacheControl; without it nothing changes.

fallback_pipelines_ready (#1512) has the same shape for the mesh fallback. I left it alone since this GPU has mesh shaders and I can't run the fallback.

Testing: RTX 4070 Ti Super, driver 621.14, Windows 11, Ryzen 7 9800X3D.

Build: on adb7a5d the Windows DLL builds.

Route: the scripted 10-minute route from #1429, first visit, each run from the same folder state after the first start (RX_VK_GPL=1), on 7d1562d with #1586, #1627 and #1714 underneath. The runs with this change had a log line counting the cache hits: 176 and 177, and no compute pipeline went to a worker.

without with this
time lost against 60 fps, s 18.0, 17.1, 17.5 13.7, 13.4
dispatch time in the logged slow submits, s 2.9, 3.0, 3.1 0.3, 0.3
dispatches left out while their pipeline compiled 40 or more (the log stops at 40) 0
frames over 40 ms 98, 92, 82 77, 77

RX_VK_COMPUTE_SERIAL=1 on the same folder, which gives the compute builds a thread of their own, came out at 13.1 s with none left out, so the time was the queue and not the builds. That switch serializes the builds, which this change does not need.

Since #1485 the precompile builds only the compute programs play has dispatched before. The rest are made at their first dispatch, from the pipeline cache the prepare filled, on a worker. That build is quick, but the job waits for a free worker, and on arrival in a new area the four workers are busy with graphics pipelines and stage libraries. The dispatch that starts the build waits up to 50 ms for it, so a frame that meets several new compute programs stops for 50 ms on each, and the ones still queued after that are left out. With timing added on one run of the route below: 175 compute pipelines made in play, each 0 to 1 ms in the driver, but queued for a median 11 ms, 364 ms at the 90th percentile and 847 ms at most, behind up to 712 pending jobs. The dispatches spent 3.8 s waiting in all, and 49 of the 175 were left out. The dispatch now asks the pipeline cache for the pipeline first, with VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT, as gpl_part asks for a stage library. A cached one comes back at once and is used. Only one the cache does not have goes to a worker, as before, so a slow compile (AMD's culling programs, Intel's serial builds) still stays off the recording thread. Needs pipelineCreationCacheControl; without it nothing changes. fallback_pipelines_ready (#1512) has the same shape for the mesh fallback. I left it alone since this GPU has mesh shaders and I can't run the fallback. Testing: RTX 4070 Ti Super, driver 621.14, Windows 11, Ryzen 7 9800X3D. Build: on adb7a5d the Windows DLL builds. Route: the scripted 10-minute route from #1429, first visit, each run from the same folder state after the first start (RX_VK_GPL=1), on 7d1562d with #1586, #1627 and #1714 underneath. The runs with this change had a log line counting the cache hits: 176 and 177, and no compute pipeline went to a worker. | | without | with this | |---|---|---| | time lost against 60 fps, s | 18.0, 17.1, 17.5 | 13.7, 13.4 | | dispatch time in the logged slow submits, s | 2.9, 3.0, 3.1 | 0.3, 0.3 | | dispatches left out while their pipeline compiled | 40 or more (the log stops at 40) | 0 | | frames over 40 ms | 98, 92, 82 | 77, 77 | RX_VK_COMPUTE_SERIAL=1 on the same folder, which gives the compute builds a thread of their own, came out at 13.1 s with none left out, so the time was the queue and not the builds. That switch serializes the builds, which this change does not need.
hckrman101 (Migrated from github.com) approved these changes 2026-11-10 16:41:25 +00:00
hckrman101 (Migrated from github.com) left a comment

Looks good. The cache-only probe uses the same flag and guard as the stage-library path, the fallback to the worker is unchanged, and it's a no-op without pipelineCreationCacheControl. The measurements in the description back it up (3 s of dispatch waiting down to 0.3 s, no dispatches left out). CI is green.

Nit: the failed probe's return code is dropped silently, which is fine, but a driver fault (-77) in the probe will log the fault line and then still queue the build, so the same program gets compiled at the worker. That seems acceptable.

Looks good. The cache-only probe uses the same flag and guard as the stage-library path, the fallback to the worker is unchanged, and it's a no-op without pipelineCreationCacheControl. The measurements in the description back it up (3 s of dispatch waiting down to 0.3 s, no dispatches left out). CI is green. Nit: the failed probe's return code is dropped silently, which is fine, but a driver fault (-77) in the probe will log the fault line and then still queue the build, so the same program gets compiled at the worker. That seems acceptable.
Commenting is not possible because the repository is archived.
No description provided.