mirror of
https://github.com/tangerineturtle1/NX2navi.git
synced 2026-11-15 19:19:58 -04:00
Write the GPU-drawn textures of a hard-count batch back in one upload batch before the drops.
Past RELEASED_HARD, sweep_hard drops up to HARD_BATCH released entries in one walk (2969005e). drop_tex writes a
gpu_dirty entry back for DROP_HARD when the fence write-back would take it, and each write_back_n(&e, 1) call ended
in vk_upload_flush(1), a GPU round trip. A batch with many such entries waited once per entry, under tex_lock, on the
thread that releases, the replay's overwrite_others included. The rule before dropped one entry per release, so it
waited at most once.
Now sweep_hard gathers the picked entries the same way drop_tex decides on them: an entry whose storage the CPU
rewrote since the GPU drew into it loses gpu_dirty, and one wb_wanted takes is written back. All of them go back in
one write_back_n call, one upload batch with one wait. write_back_n clears gpu_dirty, so drop_tex then finds nothing
to write back. The same entries go, in the same order, and the entries written back are counted in n_drop_wb as
before.
Not reproduced before the change: the 0.10.0 session never reached RELEASED_HARD, and no check without a device
covers write_back_n. Checks that passed: pass_cc_check on vk_texture.c, no new -Wall -Wextra warnings,
tex_release_check, tex_compact_check.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -2439,6 +2439,21 @@ static void sweep_hard(void) { // tex_lock held
|
||||
}
|
||||
int need = nreleased - (RELEASED_HARD - HARD_SLACK);
|
||||
int k = trl_hard_pick(cls, n, need < HARD_BATCH ? need : HARD_BATCH, out);
|
||||
// The picks the GPU drew into go back to their storage first, in one upload batch with one wait
|
||||
// (write_back_n), as drop_tex would write each of them back for DROP_HARD with a GPU wait of its own: up to
|
||||
// HARD_BATCH waits on the thread that releases, the replay's overwrite_others included. write_back_n clears
|
||||
// gpu_dirty, so drop_tex then finds nothing to write back; the same entries go, in the same order.
|
||||
static Tex *wbv[HARD_BATCH];
|
||||
int m = 0;
|
||||
wb_cfg_init();
|
||||
for (int i = 0; i < k; i++) {
|
||||
Tex *e = walk[out[i]];
|
||||
uint32_t t;
|
||||
if (!e->gpu_dirty) continue;
|
||||
if (storage_rewritten(e, e->gpu_gen, &t) == 1) e->gpu_dirty = 0;
|
||||
else if (wb_wanted(e)) wbv[m++] = e;
|
||||
}
|
||||
if (m) write_back_n(wbv, m), n_drop_wb += (uint64_t)m;
|
||||
for (int i = 0; i < k; i++) n_hard_by[cls[out[i]]]++, drop_tex(walk[out[i]], DROP_HARD);
|
||||
if (!k) hard_lru_drop(lru);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user