WIP: perf(vk): write-backs left out only in pools the CPU reads after an invalidate (the pools' NVN flags reach the renderer) #799

Draft
dyst wants to merge 1 commit from dyst/Longshot:perf/vk-writeback-pool-flags into main
Member

Type: perf · Risk: low · Tested on: Windows 11 (the game-free checks; the game A/B is next) · Needs: a game run on NVIDIA, AMD and Intel

Why

Copying the GPU's writes back to the game's memory is up to 60-68 MB a frame in Kokiri Forest and Hyrule Field, and RX_VK_WB_MAX_KB can leave most of it out (2.5 ms of GPU time on an RX 5600 XT in #547). It is off for everyone because some ranges are read by the CPU with no warning and were found stale. Those are the game's uncached pools: in its CPU-cached pools the CPU must invalidate before it reads what the GPU wrote, and the renderer hears every invalidate. The renderer never knew a pool's flags. In a Kokiri run 3,368 of the game's 4,588 pools were CPU-cached, and the import that took most of the write-back was 126 MB of cached pools and 0.4 MB of uncached ones.

What changed

nvnMemoryPoolInitialize now passes the pool's NVN flags to the renderer, which keeps them by guest address, and RX_VK_WB_MAX_KB's leave-out applies only where a binding lies wholly in CPU-cached pools or pools with no CPU access. A log line splits the write-back by pool kind with the cap on or off. The cap itself stays off by default in this PR; the numbers below decide whether a follow-up turns it on.

  • host: rx_nvn_pool_created(gpu, size, flags) from nvnMemoryPoolInitialize (host/nvn_native.c, host/rx_backend.c, gpu/render/rx_nvn.h); MkwVkRenderer::nvn_pool_created takes the flags, MKWVK_API_VERSION 24 (gpu/vk/vk_api.h)
  • memory: gpu/vk/wb_pool_flags.h (the map and the rule), pool_flags in memory_pool_created, the check in wb_leave_out, wb_access_note/wb_access_report (gpu/vk/vk_memory.cpp)
  • docs: README's RX_VK_WB_MAX_KB paragraph
  • tests: tests/test_wb_pool_flags.py

Measurements

Verdict: not measured yet: the measurements are pending from the RX_VK_BENCH A/B of this PR @ 506ac7a4 against main @ b9e95173 (under way), which will replace this section. First numbers (Kokiri Forest, RTX 3080) are in the comment of 18:33: with RX_VK_WB_MAX_KB=1024 the write-back fell from 68.9 to 16.5 MB a frame, the same as with RX_VK_WB_ANY_POOL=1.

Flags and settings

Switches:

Flag What it is Before this PR After this PR Effect Helps / doesn't help / untested Recommendation
RX_VK_WB_ANY_POOL=1 With RX_VK_WB_MAX_KB: leave out in any pool, as before - unset On: the old leave-out measurement pending leave unset; =1 only to compare
RX_VK_WB_MAX_KB=<KB> (unchanged) The size from which a written binding may be left out unset (off) unset (off) Now only in cached or no-access pools measurement pending unchanged here

Testing

Tested: Windows 11 (Ryzen 9 3900X), llvm-mingw and the Vulkan headers of the builder's v2.0.14 tools: rebased onto main @ b9e95173 (this PR @ 506ac7a4; it stands alone on main, on no other PR). The 124 checks that read this diff (listed below: those under tests/ and nx2/ that name a changed file, and the ones this PR adds or changes), not the whole suite: python -I -B tests/run_all.py --jobs 6 <those checks> with RX_CPM at the builder's CPM cache: 117 passed, 7 failed; each failure (tests/test_appimage_player_build.py, tests/test_crash_dialog.py, tests/test_longshot_saves.py, tests/test_pipeline_tour.py, tests/test_tested_configurations.py, tests/test_vk_pgo.py, tests/test_walk_key.py) also fails on main @ b9e95173 in the same checks, on the same PC and the same day.

The 124 checks

nx2/test_import_windows.py tests/test_amd_subgroup_profiles.py tests/test_appimage_player_build.py tests/test_audio_in.py tests/test_audio_mono.py tests/test_audio_volume.py tests/test_auto_settings.py tests/test_bake_ds.py tests/test_bind_memo.py tests/test_bound_keys.py tests/test_camera_speed.py tests/test_capture_copy_helpers.py tests/test_capture_copy_nt.py tests/test_capture_copy_runs.py tests/test_capture_wait_log.py tests/test_check_pr_description.py tests/test_collect_wide.py tests/test_crash_dialog.py tests/test_dev_packs.py tests/test_device_lost_exit.py tests/test_direct_buffer_writes.py tests/test_dlss_math.py tests/test_drawn_page_map.py tests/test_forge_pr.py tests/test_fps_stats.py tests/test_frame_rate_cap_step.py tests/test_frame_trace_waits.py tests/test_fsr_uniform_ownership.py tests/test_hle_stats.py tests/test_hud_layout.py tests/test_import_buffer_binding.py tests/test_import_chunk_default.py tests/test_import_span.py tests/test_import_write_watch.py tests/test_input_background.py tests/test_intel_compiler_gate.py tests/test_intel_compiles_auto.py tests/test_invalidate_vcore.py tests/test_jobs_failure.py tests/test_jobs_wait_runs_queued.py tests/test_late_fix_build.py tests/test_late_fix_shaders.py tests/test_launcher_capture.py tests/test_linux_pressure.py tests/test_log_levels.py tests/test_longshot_ctl.py tests/test_longshot_saves.py tests/test_low_vram_texture_mips.py tests/test_mem_trim.py tests/test_menu_hit.py tests/test_menu_keys.py tests/test_menu_text_field.py tests/test_met_wait_capture.py tests/test_mirror_budget.py tests/test_mirror_gpu_only.py tests/test_mirror_inherit.py tests/test_mirror_trim.py tests/test_mouse_settings.py tests/test_no_webgpu.py tests/test_nvn_buffer_map.py tests/test_nvn_host_tables.py tests/test_nvn_null_pool.py tests/test_nvn_tex_builder_guard.py tests/test_nvn_texture_handle.py tests/test_ocarina_note_bindings.py tests/test_ocarina_notes.py tests/test_oot_damage.py tests/test_oot_fov.py tests/test_oot_menu_mouse.py tests/test_opening_skip.py tests/test_option_ids.py tests/test_pad_layout.py tests/test_parallel_mirror_make.py tests/test_parallel_rb_refresh.py tests/test_pipeline_tour.py tests/test_pool_span.py tests/test_prepare_stall.py tests/test_present_trace.py tests/test_prof_clock.py tests/test_prof_sampling.py tests/test_program_cache_format.py tests/test_prompt_auto_face.py tests/test_prompt_font_bind.py tests/test_prompts_live.py tests/test_readback_part.py tests/test_readme_menu_rows.py tests/test_registration_host_copies.py tests/test_renderer_load_error.py tests/test_report_words.py tests/test_retired_give_back.py tests/test_rumble_menu.py tests/test_sampler_admission.py tests/test_scene_format.py tests/test_shader_stamp_cache.py tests/test_shader_stamp_inputs.py tests/test_skip_title.py tests/test_sparse_mirror.py tests/test_split_ub_flush.py tests/test_stick_dead_zone.py tests/test_submitted_page.py tests/test_switches_removed.py tests/test_temporal_jitter.py tests/test_tested_configurations.py tests/test_tex_spans_once_a_present.py tests/test_texel_buffer_ownership.py tests/test_text_size.py tests/test_texture_layout_sizes.py tests/test_threaded_rendering.py tests/test_touchpad_menu.py tests/test_vertex_bind.py tests/test_vk_pgo.py tests/test_vk_range_walk.py tests/test_vram_pressure.py tests/test_walk_key.py tests/test_wb_diff_cpu_writes.py tests/test_wb_diff_split.py tests/test_wb_diff_stale_shadow.py tests/test_wb_learn.py tests/test_wb_observation_lifetime.py tests/test_wb_pages.py tests/test_wb_pool_flags.py tests/test_wb_shadow_follows_sync.py tests/test_wb_shadow_remake.py tests/test_wide_ui.py

Not tested: the game yet. This PR is WIP until its A/B is in: the RX_VK_BENCH A/B against main is running on an RTX 3080 with a Ryzen 9 3900X, Windows 11; AMD and Intel need other testers.

Must be tested:

  • Any OS and GPU, with RX_VK_WB_MAX_KB=1024: Kokiri Forest, Hyrule Field and Castle Town a few minutes each, expecting no flicker, wrong exposure or popping (the stale reads the cap had), and the log's written back by the pools' CPU access and write-backs left out lines (Test Farm: @Beanstalk any, those scenes with RX_VK_WB_MAX_KB=1024)

Risks

What could break: With the cap on: a range the CPU reads rarely (less often than every 8 frames) in a cached pool still finds the stale copy once, as before. Off (the default) only the new log line differs.

Turning it off: leave RX_VK_WB_MAX_KB unset (the default); revert the commit

Compatibility: MKWVK_API_VERSION 23 -> 24: the game and the renderer must come from the same build (they always do in a release). No caches or settings change.

Checklist

Everyone

  • One topic.
  • The title is a Conventional Commit (type(scope): description) of the status line's type.
  • Why gives the reason plainly and links the issues that fit (the tracker searched).
  • Measurements has a verdict, or one line saying why there is nothing to measure.
  • Testing names what was tested, what wasn't, and what must still be tested, where and how.
  • Rebased on current main.
  • python -I -B tests/run_all.py passes (any failure that also fails on main is named).
  • No game files, dumps, build output or generated files.
  • third_party/ untouched (a new folder with a PROVENANCE.md instead).
  • The license is OK: GPL-3.0-or-later, nothing incompatible and nothing decompiled.

When it applies

  • AI assistance recorded with Assisted-by: / Co-Authored-By: trailers.
  • MKWVK_API_VERSION bumped (gpu/vk/vk_api.h's MkwVkHost or MkwVkRenderer changed).
  • Switches documented (docs/development.md; the README for a menu row) and shipped at their recommended value.
  • A game-free test added for the fix, failing on main and passing here.
  • Docs updated.

🤖 Generated with Claude Code

**Type:** perf · **Risk:** low · **Tested on:** Windows 11 (the game-free checks; the game A/B is next) · **Needs:** a game run on NVIDIA, AMD and Intel ## Why Copying the GPU's writes back to the game's memory is up to 60-68 MB a frame in Kokiri Forest and Hyrule Field, and `RX_VK_WB_MAX_KB` can leave most of it out (2.5 ms of GPU time on an RX 5600 XT in https://git.magicbean.dev/MagicBeanDev/Longshot/pulls/547). It is off for everyone because some ranges are read by the CPU with no warning and were found stale. Those are the game's uncached pools: in its CPU-cached pools the CPU must invalidate before it reads what the GPU wrote, and the renderer hears every invalidate. The renderer never knew a pool's flags. In a Kokiri run 3,368 of the game's 4,588 pools were CPU-cached, and the import that took most of the write-back was 126 MB of cached pools and 0.4 MB of uncached ones. ## What changed `nvnMemoryPoolInitialize` now passes the pool's NVN flags to the renderer, which keeps them by guest address, and `RX_VK_WB_MAX_KB`'s leave-out applies only where a binding lies wholly in CPU-cached pools or pools with no CPU access. A log line splits the write-back by pool kind with the cap on or off. The cap itself stays off by default in this PR; the numbers below decide whether a follow-up turns it on. - host: `rx_nvn_pool_created(gpu, size, flags)` from `nvnMemoryPoolInitialize` (`host/nvn_native.c`, `host/rx_backend.c`, `gpu/render/rx_nvn.h`); `MkwVkRenderer::nvn_pool_created` takes the flags, `MKWVK_API_VERSION` 24 (`gpu/vk/vk_api.h`) - memory: `gpu/vk/wb_pool_flags.h` (the map and the rule), `pool_flags` in `memory_pool_created`, the check in `wb_leave_out`, `wb_access_note`/`wb_access_report` (`gpu/vk/vk_memory.cpp`) - docs: README's `RX_VK_WB_MAX_KB` paragraph - tests: `tests/test_wb_pool_flags.py` ## Measurements **Verdict:** not measured yet: the measurements are pending from the RX_VK_BENCH A/B of this PR @ 506ac7a4 against main @ b9e95173 (under way), which will replace this section. First numbers (Kokiri Forest, RTX 3080) are in the comment of 18:33: with `RX_VK_WB_MAX_KB=1024` the write-back fell from 68.9 to 16.5 MB a frame, the same as with `RX_VK_WB_ANY_POOL=1`. ### Flags and settings Switches: | Flag | What it is | Before this PR | After this PR | Effect | Helps / doesn't help / untested | Recommendation | |---|---|---|---|---|---|---| | `RX_VK_WB_ANY_POOL=1` | With `RX_VK_WB_MAX_KB`: leave out in any pool, as before | - | unset | On: the old leave-out | measurement pending | leave unset; `=1` only to compare | | `RX_VK_WB_MAX_KB=<KB>` (unchanged) | The size from which a written binding may be left out | unset (off) | unset (off) | Now only in cached or no-access pools | measurement pending | unchanged here | ## Testing **Tested:** Windows 11 (Ryzen 9 3900X), llvm-mingw and the Vulkan headers of the builder's v2.0.14 tools: rebased onto main @ b9e95173 (this PR @ 506ac7a4; it stands alone on main, on no other PR). The 124 checks that read this diff (listed below: those under tests/ and nx2/ that name a changed file, and the ones this PR adds or changes), not the whole suite: `python -I -B tests/run_all.py --jobs 6 <those checks>` with `RX_CPM` at the builder's CPM cache: 117 passed, 7 failed; each failure (`tests/test_appimage_player_build.py`, `tests/test_crash_dialog.py`, `tests/test_longshot_saves.py`, `tests/test_pipeline_tour.py`, `tests/test_tested_configurations.py`, `tests/test_vk_pgo.py`, `tests/test_walk_key.py`) also fails on main @ b9e95173 in the same checks, on the same PC and the same day. <details><summary>The 124 checks</summary> `nx2/test_import_windows.py` `tests/test_amd_subgroup_profiles.py` `tests/test_appimage_player_build.py` `tests/test_audio_in.py` `tests/test_audio_mono.py` `tests/test_audio_volume.py` `tests/test_auto_settings.py` `tests/test_bake_ds.py` `tests/test_bind_memo.py` `tests/test_bound_keys.py` `tests/test_camera_speed.py` `tests/test_capture_copy_helpers.py` `tests/test_capture_copy_nt.py` `tests/test_capture_copy_runs.py` `tests/test_capture_wait_log.py` `tests/test_check_pr_description.py` `tests/test_collect_wide.py` `tests/test_crash_dialog.py` `tests/test_dev_packs.py` `tests/test_device_lost_exit.py` `tests/test_direct_buffer_writes.py` `tests/test_dlss_math.py` `tests/test_drawn_page_map.py` `tests/test_forge_pr.py` `tests/test_fps_stats.py` `tests/test_frame_rate_cap_step.py` `tests/test_frame_trace_waits.py` `tests/test_fsr_uniform_ownership.py` `tests/test_hle_stats.py` `tests/test_hud_layout.py` `tests/test_import_buffer_binding.py` `tests/test_import_chunk_default.py` `tests/test_import_span.py` `tests/test_import_write_watch.py` `tests/test_input_background.py` `tests/test_intel_compiler_gate.py` `tests/test_intel_compiles_auto.py` `tests/test_invalidate_vcore.py` `tests/test_jobs_failure.py` `tests/test_jobs_wait_runs_queued.py` `tests/test_late_fix_build.py` `tests/test_late_fix_shaders.py` `tests/test_launcher_capture.py` `tests/test_linux_pressure.py` `tests/test_log_levels.py` `tests/test_longshot_ctl.py` `tests/test_longshot_saves.py` `tests/test_low_vram_texture_mips.py` `tests/test_mem_trim.py` `tests/test_menu_hit.py` `tests/test_menu_keys.py` `tests/test_menu_text_field.py` `tests/test_met_wait_capture.py` `tests/test_mirror_budget.py` `tests/test_mirror_gpu_only.py` `tests/test_mirror_inherit.py` `tests/test_mirror_trim.py` `tests/test_mouse_settings.py` `tests/test_no_webgpu.py` `tests/test_nvn_buffer_map.py` `tests/test_nvn_host_tables.py` `tests/test_nvn_null_pool.py` `tests/test_nvn_tex_builder_guard.py` `tests/test_nvn_texture_handle.py` `tests/test_ocarina_note_bindings.py` `tests/test_ocarina_notes.py` `tests/test_oot_damage.py` `tests/test_oot_fov.py` `tests/test_oot_menu_mouse.py` `tests/test_opening_skip.py` `tests/test_option_ids.py` `tests/test_pad_layout.py` `tests/test_parallel_mirror_make.py` `tests/test_parallel_rb_refresh.py` `tests/test_pipeline_tour.py` `tests/test_pool_span.py` `tests/test_prepare_stall.py` `tests/test_present_trace.py` `tests/test_prof_clock.py` `tests/test_prof_sampling.py` `tests/test_program_cache_format.py` `tests/test_prompt_auto_face.py` `tests/test_prompt_font_bind.py` `tests/test_prompts_live.py` `tests/test_readback_part.py` `tests/test_readme_menu_rows.py` `tests/test_registration_host_copies.py` `tests/test_renderer_load_error.py` `tests/test_report_words.py` `tests/test_retired_give_back.py` `tests/test_rumble_menu.py` `tests/test_sampler_admission.py` `tests/test_scene_format.py` `tests/test_shader_stamp_cache.py` `tests/test_shader_stamp_inputs.py` `tests/test_skip_title.py` `tests/test_sparse_mirror.py` `tests/test_split_ub_flush.py` `tests/test_stick_dead_zone.py` `tests/test_submitted_page.py` `tests/test_switches_removed.py` `tests/test_temporal_jitter.py` `tests/test_tested_configurations.py` `tests/test_tex_spans_once_a_present.py` `tests/test_texel_buffer_ownership.py` `tests/test_text_size.py` `tests/test_texture_layout_sizes.py` `tests/test_threaded_rendering.py` `tests/test_touchpad_menu.py` `tests/test_vertex_bind.py` `tests/test_vk_pgo.py` `tests/test_vk_range_walk.py` `tests/test_vram_pressure.py` `tests/test_walk_key.py` `tests/test_wb_diff_cpu_writes.py` `tests/test_wb_diff_split.py` `tests/test_wb_diff_stale_shadow.py` `tests/test_wb_learn.py` `tests/test_wb_observation_lifetime.py` `tests/test_wb_pages.py` `tests/test_wb_pool_flags.py` `tests/test_wb_shadow_follows_sync.py` `tests/test_wb_shadow_remake.py` `tests/test_wide_ui.py` </details> **Not tested:** the game yet. This PR is WIP until its A/B is in: the RX_VK_BENCH A/B against main is running on an RTX 3080 with a Ryzen 9 3900X, Windows 11; AMD and Intel need other testers. **Must be tested:** - Any OS and GPU, with `RX_VK_WB_MAX_KB=1024`: Kokiri Forest, Hyrule Field and Castle Town a few minutes each, expecting no flicker, wrong exposure or popping (the stale reads the cap had), and the log's `written back by the pools' CPU access` and `write-backs left out` lines (Test Farm: @Beanstalk any, those scenes with RX_VK_WB_MAX_KB=1024) ## Risks **What could break:** With the cap on: a range the CPU reads rarely (less often than every 8 frames) in a cached pool still finds the stale copy once, as before. Off (the default) only the new log line differs. **Turning it off:** leave `RX_VK_WB_MAX_KB` unset (the default); revert the commit **Compatibility:** `MKWVK_API_VERSION` 23 -> 24: the game and the renderer must come from the same build (they always do in a release). No caches or settings change. ## Checklist ### Everyone - [x] One topic. - [x] The title is a Conventional Commit (`type(scope): description`) of the status line's type. - [x] Why gives the reason plainly and links the issues that fit (the tracker searched). - [x] Measurements has a verdict, or one line saying why there is nothing to measure. - [x] Testing names what was tested, what wasn't, and what must still be tested, where and how. - [x] Rebased on current `main`. - [x] `python -I -B tests/run_all.py` passes (any failure that also fails on `main` is named). - [x] No game files, dumps, build output or generated files. - [x] `third_party/` untouched (a new folder with a `PROVENANCE.md` instead). - [x] The license is OK: GPL-3.0-or-later, nothing incompatible and nothing decompiled. ### When it applies - [x] AI assistance recorded with `Assisted-by:` / `Co-Authored-By:` trailers. - [x] `MKWVK_API_VERSION` bumped (`gpu/vk/vk_api.h`'s `MkwVkHost` or `MkwVkRenderer` changed). - [x] Switches documented (docs/development.md; the README for a menu row) and shipped at their recommended value. - [x] A game-free test added for the fix, failing on `main` and passing here. - [x] Docs updated. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
perf(vk): write-backs left out only in pools the CPU reads after an invalidate (the pools' NVN flags reach the renderer)
Some checks failed
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Has been skipped
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Has been skipped
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Has been skipped
Third-party parts / The same as upstream (pull_request) Has been skipped
PR description / Description follows the template (pull_request_target) Successful in 5s
CI / Conventional Commit title (pull_request) Successful in 4s
CI / Workflow lint (actionlint) (pull_request) Successful in 6s
Guide screenshots / Guide images and local UI source review (pull_request) Failing after 5s
Third-party parts / As their notes say (pull_request) Successful in 8s
Website / Website on Cloudflare (pull_request_target) Has been skipped
2181a1c793
RX_VK_WB_MAX_KB leaves out the write-back of large GPU-written bindings the CPU has not touched, learned from the CPU's
invalidates and writes (wb_learn.h). It is off for everyone because some ranges are read with no invalidate and were found
stale. Those are the uncached pools: NVN's CPU-cached pools (NVN_MEMORY_POOL_FLAGS_CPU_CACHED) need
nvnMemoryPoolInvalidateMappedRange before the CPU reads what the GPU wrote, which the renderer hears, and pools with no CPU
access are never read. The renderer never knew a pool's flags.

nvnMemoryPoolInitialize now passes the pool's flags with rx_nvn_pool_created (MKWVK_API_VERSION 24), the renderer keeps them by
guest address (gpu/vk/wb_pool_flags.h), and wb_leave_out leaves a binding out only where every part of it lies in a cached pool
or one with no CPU access. RX_VK_WB_ANY_POOL=1: in any pool, as before. A new line every 600 submits splits what is written back
by the pools' CPU access (uncached, cached, no access, in no pool known), with the cap on or off, and the leave-out report
counts the bindings kept for uncached pools.

In Kokiri Forest 3,368 of the 4,588 pools the game made were CPU-cached (3.6 GB), and the import that took most of the
write-back (about 5.6 MB of each submission's 6.8) was 126 MB of cached pools and 0.4 MB of uncached ones.

tests/test_wb_pool_flags.py runs the map's rules and checks the flags' way from the host to wb_leave_out.

Assisted-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Author
Member

The checks on this PC (Windows 11, RTX 3080, Ryzen 9 3900X, llvm-mingw from the builder's v2.0.14 tools): python -I -B tests/run_all.py on main @ aa95d35f fails these 19 here, and so does this branch: test_appimage_player_build.py, test_bake_portability.py, test_cpm_discovery.py, test_cpp_preflight.py, test_crash_dialog.py, test_env_on.py, test_fpx_sticky.py, test_lift_cleanup_error.py, test_linux_preflight.py, test_make_game_cache.py, test_make_game_prepare.py, test_missing_nup.py, test_oot_state_tap.py, test_options_budget_once.py, test_readback_late.py, test_spawn_emit.py, test_tested_configurations.py, test_vk_pgo.py, test_walk_key.py. Any other failure in a full run on this branch was rerun on its own and passed (the full runs shared the PC with dev_packs builds: timing checks).

Next: an interleaved A/B in the game against main on one dev_packs base of aa95d35f; the numbers will replace the Measurements section.

The checks on this PC (Windows 11, RTX 3080, Ryzen 9 3900X, llvm-mingw from the builder's v2.0.14 tools): `python -I -B tests/run_all.py` on main @ aa95d35f fails these 19 here, and so does this branch: `test_appimage_player_build.py`, `test_bake_portability.py`, `test_cpm_discovery.py`, `test_cpp_preflight.py`, `test_crash_dialog.py`, `test_env_on.py`, `test_fpx_sticky.py`, `test_lift_cleanup_error.py`, `test_linux_preflight.py`, `test_make_game_cache.py`, `test_make_game_prepare.py`, `test_missing_nup.py`, `test_oot_state_tap.py`, `test_options_budget_once.py`, `test_readback_late.py`, `test_spawn_emit.py`, `test_tested_configurations.py`, `test_vk_pgo.py`, `test_walk_key.py`. Any other failure in a full run on this branch was rerun on its own and passed (the full runs shared the PC with dev_packs builds: timing checks). Next: an interleaved A/B in the game against main on one dev_packs base of aa95d35f; the numbers will replace the Measurements section.
Author
Member

First in-game numbers (RTX 3080, Ryzen 9 3900X, Windows 11; dev_packs runtimes of this PR and main @ aa95d35f on one base; Kokiri Forest, 3 interleaved runs, camera turning): with RX_VK_WB_MAX_KB=1024 the write-back went from 68.9 MB a frame (main) to 16.5 MB, and with RX_VK_WB_ANY_POOL=1 (the cap in any pool, as before this PR) also 16.5 MB: in Kokiri every binding the cap leaves out lies in CPU-cached or no-access pools, so keeping uncached pools whole costs nothing here. On this fast card fps and GPU time did not move beyond the runs' spread (main 30.5-32.2 fps, this PR with the cap 32.7-35.0; GPU 11.6-13.7 against 11.1-11.8 ms), as #753 found on an RX 9070 XT; the gain the cap gave on an RX 5600 XT (#547) is where to look. Not checked yet: pictures (stale reads), other scenes. Stays WIP.

First in-game numbers (RTX 3080, Ryzen 9 3900X, Windows 11; dev_packs runtimes of this PR and main @ aa95d35f on one base; Kokiri Forest, 3 interleaved runs, camera turning): with RX_VK_WB_MAX_KB=1024 the write-back went from 68.9 MB a frame (main) to 16.5 MB, and with RX_VK_WB_ANY_POOL=1 (the cap in any pool, as before this PR) also 16.5 MB: in Kokiri every binding the cap leaves out lies in CPU-cached or no-access pools, so keeping uncached pools whole costs nothing here. On this fast card fps and GPU time did not move beyond the runs' spread (main 30.5-32.2 fps, this PR with the cap 32.7-35.0; GPU 11.6-13.7 against 11.1-11.8 ms), as #753 found on an RX 9070 XT; the gain the cap gave on an RX 5600 XT (#547) is where to look. Not checked yet: pictures (stale reads), other scenes. Stays WIP.
dyst force-pushed perf/vk-writeback-pool-flags from 2181a1c793
Some checks failed
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Has been skipped
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Has been skipped
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Has been skipped
Third-party parts / The same as upstream (pull_request) Has been skipped
PR description / Description follows the template (pull_request_target) Successful in 5s
CI / Conventional Commit title (pull_request) Successful in 4s
CI / Workflow lint (actionlint) (pull_request) Successful in 6s
Guide screenshots / Guide images and local UI source review (pull_request) Failing after 5s
Third-party parts / As their notes say (pull_request) Successful in 8s
Website / Website on Cloudflare (pull_request_target) Has been skipped
to 506ac7a4e0
Some checks are pending
PR description / Description follows the template (pull_request_target) Waiting to run
CI / Conventional Commit title (pull_request) Waiting to run
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Has been skipped
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Has been skipped
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Has been skipped
CI / Workflow lint (actionlint) (pull_request) Waiting to run
Guide screenshots / Guide images and local UI source review (pull_request) Waiting to run
Third-party parts / The same as upstream (pull_request) Has been skipped
Third-party parts / As their notes say (pull_request) Waiting to run
Website / Website on Cloudflare (pull_request) Has been skipped
2026-11-15 19:28:09 +00:00
Compare
Some checks are pending
PR description / Description follows the template (pull_request_target) Waiting to run
CI / Conventional Commit title (pull_request) Waiting to run
CI / Python source checks (ubuntu-24.04, part 1/2) (pull_request) Has been skipped
CI / Python source checks (ubuntu-24.04, part 2/2) (pull_request) Has been skipped
CI / SPIR-V fixtures (global narrow load/store, direct surface atomics, F2I immediate) (pull_request) Has been skipped
CI / Workflow lint (actionlint) (pull_request) Waiting to run
Guide screenshots / Guide images and local UI source review (pull_request) Waiting to run
Third-party parts / The same as upstream (pull_request) Has been skipped
Third-party parts / As their notes say (pull_request) Waiting to run
Website / Website on Cloudflare (pull_request) Has been skipped
This pull request is marked as a work in progress.
This branch is out-of-date with the base branch
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u 'perf/vk-writeback-pool-flags:dyst-perf/vk-writeback-pool-flags'
git switch 'dyst-perf/vk-writeback-pool-flags'
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
MagicBeanDev/Longshot!799
No description provided.