crocus: batch pinlemesini opsiyonel yap, gonderim hatasini susturma

recreate_growing_buffer() batch tamponlarina statik, monoton artan bir GTT
adresi verip EXEC_OBJECT_PINNED ile sabitliyordu (7e82b85). Amac
EXEC_OBJECT_CAPTURE ile birlikte GPU hata dokumlerinde adreslerin sabit
kalmasiydi, ama adres asla geri donusturulmuyordu.

create_batch() her flush'ta iki tampon yaratiyor (command ~20K + state
16K), yani her flush ~36K adres alani yakiyor. IVB'nin PPGTT'si 2 GB;
0x20000000'den baslayinca ~43 bin flush sonra alan bitiyor ve execbuf
ENOSPC donuyor. 60 fps'te birkac dakika: Witcher EE ve Fallout NV'de
oynanisin ortasinda tekrarlanabilir cokme.

Varsayilan artik upstream davranisi (adresi cekirdek secer).
CROCUS_PIN_BATCH=1 ile eski davranis geri gelir.

Ayrica: gonderim hatasi mesaji upstream'de MESA_DEBUG arkasinda. Release
derlemesinde hata tek satir aciklama birakmadan abort() olarak goruluyor
ve teshis edilemiyordu -- yukaridaki ENOSPC'yi bulmak bu yuzden zor oldu.
abort() zaten olumcul; sebebi artik her zaman yaziliyor.

crocus_context.c'deki gecici fprintf teshisi de kaldirildi.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
elwrclandClaude Opus 5 committed 2026-09-21 22:56:29 +03:00
1 parent 6000949371
commit e004b50acd
2 files changed
+46 -15

No files matched your search

+45 -9
View File
@@ -450,6 +450,9 @@ crocus_state_reloc(struct crocus_batch *batch, uint32_t state_offset,
target, target_offset, reloc_flags); target, target_offset, reloc_flags);
} }
/* CROCUS_PIN_BATCH icin sonraki sabit adres; asagiya bak. */
static uint64_t next_grow_pin = 0x20000000ULL; /* 512MB */
static void static void
recreate_growing_buffer(struct crocus_batch *batch, recreate_growing_buffer(struct crocus_batch *batch,
struct crocus_growing_bo *grow, struct crocus_growing_bo *grow,
@@ -458,10 +461,29 @@ recreate_growing_buffer(struct crocus_batch *batch,
struct crocus_screen *screen = batch->screen; struct crocus_screen *screen = batch->screen;
struct crocus_bufmgr *bufmgr = screen->bufmgr; struct crocus_bufmgr *bufmgr = screen->bufmgr;
grow->bo = crocus_bo_alloc(bufmgr, name, size); grow->bo = crocus_bo_alloc(bufmgr, name, size);
static uint64_t next_grow_pin = 0x20000000ULL; /* 512MB */
grow->bo->gtt_offset = next_grow_pin; /* Yerel yama (7e82b85, Tem 2026): batch tamponlarina sabit GTT adresi verip
next_grow_pin += align64(size, 4096); * EXEC_OBJECT_PINNED ile sabitliyordu -- EXEC_OBJECT_CAPTURE ile birlikte
grow->bo->kflags |= EXEC_OBJECT_CAPTURE | EXEC_OBJECT_PINNED; * GPU hata dokumlerinde adreslerin sabit kalmasi icindi.
*
* Ama next_grow_pin monoton artiyor ve adres asla geri donusturulmuyordu.
* create_batch() her flush'ta iki tampon yaratiyor (command ~20K + state
* 16K), yani her flush ~36K adres alani yakiyor. IVB'nin PPGTT'si 2 GB;
* 512 MB'den baslayinca ~43 bin flush sonra alan bitiyor ve execbuf
* ENOSPC donuyor -- _crocus_batch_flush() bunu sessiz bir abort() olarak
* gosteriyordu. Birkac dakika oynadiktan sonra her oyun cokuyordu
* (Witcher EE ve Fallout NV'de dogrulandi).
*
* Varsayilan artik upstream davranisi: adresi cekirdek secsin. Hata
* ayiklama icin sabit adres gerekirse CROCUS_PIN_BATCH=1 ile geri acilir.
*/
grow->bo->kflags |= EXEC_OBJECT_CAPTURE;
if (unlikely(debug_get_bool_option("CROCUS_PIN_BATCH", false))) {
grow->bo->gtt_offset = next_grow_pin;
next_grow_pin += align64(size, 4096);
grow->bo->kflags |= EXEC_OBJECT_PINNED;
}
grow->partial_bo = NULL; grow->partial_bo = NULL;
grow->partial_bo_map = NULL; grow->partial_bo_map = NULL;
grow->partial_bytes = 0; grow->partial_bytes = 0;
@@ -951,6 +973,14 @@ _crocus_batch_flush(struct crocus_batch *batch, const char *file, int line)
finish_growing_bos(&batch->state); finish_growing_bos(&batch->state);
int ret = submit_batch(batch); int ret = submit_batch(batch);
/* Gonderim hatasi mesajinda kullanilacak; asagidaki sayaclar abort'tan
* once sifirlandigi icin degerleri burada sakliyoruz. */
const int dbg_cmds = crocus_batch_bytes_used(batch);
const int dbg_exec = batch->exec_count;
const float dbg_ap = (float)batch->aperture_space / (1024 * 1024);
const int dbg_rc = batch->command.relocs.reloc_count;
const int dbg_rs = batch->state.relocs.reloc_count;
if (INTEL_DEBUG(DEBUG_BATCH) || if (INTEL_DEBUG(DEBUG_BATCH) ||
INTEL_DEBUG(DEBUG_SUBMIT) || INTEL_DEBUG(DEBUG_SUBMIT) ||
INTEL_DEBUG(DEBUG_PIPE_CONTROL)) { INTEL_DEBUG(DEBUG_PIPE_CONTROL)) {
@@ -1020,11 +1050,17 @@ _crocus_batch_flush(struct crocus_batch *batch, const char *file, int line)
} }
if (ret < 0) { if (ret < 0) {
#if MESA_DEBUG /* Upstream bu mesaji MESA_DEBUG arkasina koyuyor. Release derlemesinde
const bool color = INTEL_DEBUG(DEBUG_COLOR); * (-DMESA_DEBUG=0) gonderim hatasi tek satir aciklama birakmadan
fprintf(stderr, "%scrocus: Failed to submit batchbuffer: %-80s%s\n", * abort() olarak goruluyor ve teshis edilemiyor -- ENOSPC avinda bize
color ? "\e[1;41m" : "", strerror(-ret), color ? "\e[0m" : ""); * saatlere mal oldu. abort() zaten olumcul, sebebini susturmanin anlami
#endif * yok: her zaman yaz. */
fprintf(stderr,
"crocus: batch gonderimi basarisiz: %s (ret=%d) batch=%s "
"cmds=%d bayt exec_count=%d aperture=%.1f MB reloc=%d/%d\n",
strerror(-ret), ret, batch_name_to_string(batch->name),
dbg_cmds, dbg_exec, dbg_ap, dbg_rc, dbg_rs);
fflush(stderr);
abort(); abort();
} }
} }
+1 -6
View File
@@ -331,18 +331,13 @@ crocus_create_context(struct pipe_screen *pscreen, void *priv, unsigned flags)
if (ice->batch_count > 1) if (ice->batch_count > 1)
screen->vtbl.init_compute_context(&ice->batches[CROCUS_BATCH_COMPUTE]); screen->vtbl.init_compute_context(&ice->batches[CROCUS_BATCH_COMPUTE]);
if (!(flags & PIPE_CONTEXT_PREFER_THREADED)) { if (!(flags & PIPE_CONTEXT_PREFER_THREADED))
fprintf(stderr, "CROCUS unthreaded context: get_compute_state_info=%p, set_global_binding=%p\n",
ctx->get_compute_state_info, ctx->set_global_binding);
return ctx; return ctx;
}
struct pipe_context *tc = threaded_context_create(ctx, &screen->transfer_pool, struct pipe_context *tc = threaded_context_create(ctx, &screen->transfer_pool,
crocus_replace_buffer_storage, crocus_replace_buffer_storage,
NULL, /* TODO: asynchronous flushes? */ NULL, /* TODO: asynchronous flushes? */
&ice->thrctx); &ice->thrctx);
fprintf(stderr, "CROCUS threaded context: get_compute_state_info=%p, set_global_binding=%p\n",
tc->get_compute_state_info, tc->set_global_binding);
return tc; return tc;
} }