Skip to content

feat(vk): live switches for an A/B in one session (hookshot_ctl.py ab); RX_VK_OCC_QUERIES the first - #2932

Open
jordanella wants to merge 2 commits into
NotRexed:mainfrom
jordanella:feat/live-switches
Open

jordanella wants to merge 2 commits into
NotRexed:mainfrom
jordanella:feat/live-switches

Conversation

@jordanella

Copy link
Copy Markdown
Contributor

Comparing a switch's two values meant two launches: a minute apart, another walk to the scene, other warm caches, and differences of a few percent lost in that. This makes a switch changeable while the game runs, so both values are measured in one session, alternating, with the game's own numbers for each half. The dev-loop proposal's in-session A/B (#2636, D4/D5 review); the first switch is #2871's RX_VK_OCC_QUERIES.

Stacked on #2871: review the last commit; this rebases to it alone once #2871 is in.

Change

  • gpu/vk/vk_live.h (new): live switches. Each starts as its environment variable says (hookshot_env.h's rule). The control bridge asks for another value with the command it already has: hookshot_ctl.py option set RX_VK_OCC_QUERIES 1. The bridge's settings list (menu_setting) ends with the live switches (tab live, key env.<NAME>); they are not in the menu and not saved to hookshot_options.ini. No interface change: setting/setting_set carry them.
  • The present takes an ask at its next frame (live_tick, in status_tick) and first logs the time since the last ask:
    vk: live: 590 frames in 9.5 s with RX_VK_OCC_QUERIES=0: 62.1 fps (1% low 51.0), GPU 8.12 ms a frame, 1830 draws a frame
    The first half second after a change is left out (frames already on their way; GPU times are read when their slots come round). An ask for the value a switch already has changes nothing and still ends the period, so a run can start clean.
  • A switch is listed only once its reader takes it where a change is safe. RX_VK_OCC_QUERIES is asked once a command buffer, before its dry pass (replay_handle's occ_room), so the dry pass and its workers agree:
    • turned off, the run already open goes past its limit and its report stays "visible", as without the switch;
    • turned on, the next samples-passed reset opens a run;
    • its query pool is made the first time it is on.
  • hookshot_ctl.py ab NAME [--every 10] [--rounds 4]:
    • It starts from the switch's value with a mark, then flips it every N seconds, R times each way, and ends on the start value.
    • It prints each half, each value's medians (fps, 1% low, GPU ms, draws), and the difference.
    • It also prints the fps spread between halves of the same value, and says when the difference is within it.
    • A half in which the game left play or changed map is marked (a status before and after each ask).

In use

Windows 11, RTX 3080, Castle Town Market from a save, one headless launch, ab RX_VK_OCC_QUERIES --every 10 --rounds 4 standing, then again with the camera turning:

fps (median) spread GPU ms draws
standing, off 18.6 3.9 27.2 2750
standing, on 20.0 3.5 25.4 2325
turning, off 16.3 7.1 30.5 1482
turning, on 14.2 6.0 35.8 1364
  • On, the game leaves out about 15% of its draws standing. Turning, the GPU time goes up about 17%.
  • This agrees in direction with the four separate launches on fix(vk): give samples-passed reports the GPU's counts (RX_VK_OCC_QUERIES) #2871 (turning: GPU time +25%). It came from one launch, a few minutes after reaching the scene.
  • The fps differences are within the spread between halves of the same value, and ab says so.
  • In the log: 16 changes taken, the query pool made once (at the first "on"), and no errors.

Testing

  • tests/test_live_switches.py (new):
    • vk_live.h, live_tick, live_fill and menu_setting_set's env. branch are cut out and run against stub counters: the start value from the variable; an ask taken at the next frame, not before; the settle time left out; the frame counts, fps, 1% low, GPU ms and draws of each half, read back with hookshot_ctl's own pattern; a mark; a half too short.
    • ab against a fake bridge: the order of the asks, the halves kept, the medians and spread, a half with a map change marked, a menu row refused.
    • In the source: the tick is in the present, the listing comes after the rows, the ask is not saved and takes no menu lock, and only live_tick writes what the readers take.
    • Two deliberate bugs fail it: no settle time, and an ask applied before its half is logged.
  • tests/test_vk_occlusion_queries.py: the switch is in vk_live.h now, and occ_queries_on asks it before the pool is made.
  • Every check that reads the changed files (179), through run_all.py, Windows: 176 pass. test_linux_driver_fault_guard and test_readback_wait_bounded fail the same way on main here, and test_input_background fails the same way at fix(vk): give samples-passed reports the GPU's counts (RX_VK_OCC_QUERIES) #2871's head (its older base; it passes on today's main).
  • Not tested: Linux.

See #2636, #2871.

🤖 Generated with Claude Code

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant