Skip to content

feat(vk): RX_VK_WAIT_FIRST_PART=1, an A/B of #2419's fence-wait cost … - #2587

Closed
SadTransGirl wants to merge 1 commit into
NotRexed:mainfrom
SadTransGirl:feat/wait-first-part-ab
Closed

SadTransGirl wants to merge 1 commit into
NotRexed:mainfrom
SadTransGirl:feat/wait-first-part-ab

Conversation

@SadTransGirl

Copy link
Copy Markdown
Contributor

…where pools have VRAM mirrors

#2419 made the game's fence waits cover the last part of a split submission, which fixed one-frame flashes on iGPUs (#997), where the later parts read guest memory in place. It costs frame rate: 45-70 -> 38-49 fps on the ROG Ally X it was measured on, and it was not measured on discrete GPUs, where the buffer pools have VRAM mirrors synced at submit.

RX_VK_WAIT_FIRST_PART=1 maps a value to its first part again, as before #2419, and only when mirrors are on. The default is unchanged. Pools left without a mirror (budget full, over 1 GB) are still read in place, so this is an A/B to measure the cost on NVIDIA and discrete AMD, not a fix.

Assisted-by: Claude Opus 5.5, Claude Mythos 5.2

…it cost where pools have VRAM mirrors

NotRexed#2419 made the game's fence waits cover the last part of a split
submission, which fixed one-frame flashes on iGPUs (NotRexed#997), where the later
parts read guest memory in place. It costs frame rate: 45-70 -> 38-49 fps
on the ROG Ally X it was measured on, and it was not measured on discrete
GPUs, where the buffer pools have VRAM mirrors synced at submit.

RX_VK_WAIT_FIRST_PART=1 maps a value to its first part again, as before
NotRexed#2419, and only when mirrors are on. The default is unchanged. Pools left
without a mirror (budget full, over 1 GB) are still read in place, so this
is an A/B to measure the cost on NVIDIA and discrete AMD, not a fix.

Assisted-by: Claude Opus 5.5, Claude Mythos 5.2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Mythos 5.2 <noreply@anthropic.com>
@Waryxxful

Copy link
Copy Markdown
Contributor

Measured on a discrete AMD card, as the description asks. Short version: on this card #2419's wait costs about half the frame rate in Kokiri Forest, and RX_VK_WAIT_FIRST_PART=1 brings back #997's whole-screen flashes. The flashes come from a pool the full mirror budget left in system memory.

Setup

  • GPU: RX 5600 XT 6 GB (RDNA1, no mesh shaders: the compute fallback). Adrenalin 26.10.1, Windows 11.
  • CPU / RAM: Ryzen 5 5600X, 24 GB.
  • Build: this PR merged on main de866017 (renderer only). Conflicts with main resolved: pools_mirrored() and memory_mirrors_on() kept side by side, and the first_part static moved above map_recording. tests/test_value_rec_last_part.py passes.
  • Settings: 1920x1080, frame generation off, the user's own options.
  • Method: every run starts from the same copied save and uses a scripted route through the control bridge: teleport, settle 15 s, 60 s standing. The fps are the medians of the log's N presents lines.
Kokiri Forest fps Hyrule Field fps GPU time (Kokiri)
main, 4 runs 34.0 / 31.5 / 34.6 / 32.4 34.7 / 32.1 / 34.8 / 33.6 18.2-18.9 ms
this PR, switch off 33.4 / 32.8 33.6 18.3-18.5 ms
this PR, RX_VK_WAIT_FIRST_PART=1 62.1 / 63.6 / 61.0 45.7 / 54.8 12.7-13.8 ms

The bridge's own fps agree: 61.1 against the log's 62.1. The log confirms the switch: fence waits return after a split submission's first part.

Flashes (RX_VK_FRAMELOG for the two 40 s windows, scripts/framelog.py):

Why, on this card. The mirror budget fills, and a pool is read in place:

vk: pool 0x7fd3000000 (160 MB) stays in system memory: the mirrors have 688 MB of 734

That is the case the description warns about (pools left without a mirror ... are still read in place). On a 6 GB card it happens in normal play: VRAM sits at the driver's allowance, 4,480 of 4,480 MB.

Suggestion. The gain is so large here (2x in Kokiri) that the last-part wait looks worth narrowing rather than dropping. For example, a value keeps its first part's recording only when none of the later parts reads or writes a pool without a mirror, so the unmirrored pool decides per submission instead of per run. I'm happy to measure a version like that on this card, flashes included.

@SadTransGirl

Copy link
Copy Markdown
Contributor Author

Thanks for measuring this on the RX 5600 XT, @Waryxxful. That settles it: the switch's gain comes with #997's flashes back wherever a pool is read in place, and on a 6 GB card that's normal play. On NVIDIA, #2602 has since taken back most of #2419's cost (Castle Town to the field within about 1 fps of the switch here), so an A/B switch isn't worth carrying. Closing this.

Your narrower idea (a value keeps its first part's recording only when no later part reads or writes a pool without a mirror) looks like the real fix for AMD. It's a different change from this one, so it would be its own PR.

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.

2 participants