From a4188446da63ee643c254e0133c9e4431187d866 Mon Sep 17 00:00:00 2001 From: elwrcl Date: Mon, 21 Sep 2026 22:57:35 +0300 Subject: [PATCH] nine: set_vertex_buffers'a devredilen referansi al Mesa'nin "eliminate frontend refcounting" refactor'u (MR 36296) set_vertex_buffers'in sahiplik sozlesmesini degistirdi: cagiranin referansi artik devralinyor. threaded_context'te tc_set_vertex_buffers() slot'a duz memcpy yapiyor (referans almiyor) ve tc_call_set_vertex_buffers() surucuye verdikten sonra da birakmiyor -- komut asenkron calistigi icin tamponun hayatta kalmasi tamamen o devredilen referansa bagli. Nine eski sozlesmeye gore yazilmisti: odunc isaretci veriyor, referansi kendinde tutuyordu (eskiden take_ownership=false parametresi vardi). Refactor'un samplerview parcasi Nine'a uygulanmisti (Mart 2025), ama vertex/constant buffer parcasi Nine silindikten sonra geldi, dolayisiyla Nine hic uyarlanmadi. Sonuc: CSMT kuyrugu komutu calistirmadan once Nine kendi referansini birakirsa kaynak oluyor; tc replay edince crocus_set_vertex_buffers olu kaynaga referans almaya calisiyor ve u_inlines.h'de "pipe_reference_described: count != 1" ile patliyor. Zamanlamaya bagli, dolayisiyla araliklidir. Gercek cokme (The Witcher EE, 8086:0166, bes denemenin ikisinde): pipe_reference_described crocus_set_vertex_buffers tc_call_set_vertex_elements_and_buffers Co-Authored-By: Claude Opus 5 --- src/gallium/frontends/nine/nine_state.c | 35 +++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/src/gallium/frontends/nine/nine_state.c b/src/gallium/frontends/nine/nine_state.c index 5be60cf..0c7f410 100644 --- a/src/gallium/frontends/nine/nine_state.c +++ b/src/gallium/frontends/nine/nine_state.c @@ -970,6 +970,35 @@ update_vertex_elements(struct NineDevice9 *device) cso_set_vertex_elements(context->cso, &ve); } +/* Mesa 26.x (MR 36296, "eliminate frontend refcounting"): set_vertex_buffers + * artik cagiranin referansini DEVRALIYOR. threaded_context'te + * tc_set_vertex_buffers() slot'a duz memcpy yapiyor (referans almiyor) ve + * tc_call_set_vertex_buffers() surucuye verdikten sonra da birakmiyor -- + * komut asenkron calistigi icin tamponun hayatta kalmasi tamamen o devredilen + * referansa bagli. + * + * Nine eski sozlesmeye gore yazilmisti: odunc isaretci veriyor, referansi + * kendinde tutuyordu (eskiden set_vertex_buffers'in take_ownership=false + * parametresi vardi). Nine 25.2'de silindigi icin bu MR'a hic uyarlanmadi. + * Sonuc: CSMT kuyrugu komutu calistirmadan once Nine kendi referansini + * birakirsa kaynak olur; tc replay edince crocus_set_vertex_buffers olu + * kaynaga referans almaya calisir ve u_inlines.h:83'te + * "pipe_reference_described: count != 1" ile patlar. Zamanlamaya bagli + * oldugu icin araliklidir. + * + * GERCEK COKME (Witcher EE, 8086:0166): + * pipe_reference_described <- crocus_set_vertex_buffers + * <- tc_call_set_vertex_elements_and_buffers + */ +static void +nine_ref_vertex_buffers(struct pipe_vertex_buffer *vb, unsigned count) +{ + for (unsigned i = 0; i < count; i++) { + if (!vb[i].is_user_buffer && vb[i].buffer.resource) + pipe_reference(NULL, &vb[i].buffer.resource->reference); + } +} + static void update_vertex_buffers(struct NineDevice9 *device) { @@ -1000,9 +1029,10 @@ update_vertex_buffers(struct NineDevice9 *device) if (i < num_vertex_buffers) memset(&vbuffer[i], 0, sizeof(vbuffer[i]) * (num_vertex_buffers - i)); - if (num_vertex_buffers) + if (num_vertex_buffers) { + nine_ref_vertex_buffers(vbuffer, num_vertex_buffers); pipe->set_vertex_buffers(pipe, num_vertex_buffers, vbuffer); - else + } else pipe->set_vertex_buffers(pipe, 0, NULL); context->changed.vtxbuf_dirty = false; @@ -2567,6 +2597,7 @@ CSMT_ITEM_NO_WAIT(nine_context_draw_indexed_primitive_from_vtxbuf_idxbuf, else info.index.user = user_ibuf; + nine_ref_vertex_buffers(vbuf, 1); context->pipe->set_vertex_buffers(context->pipe, 1, vbuf); context->changed.vtxbuf_dirty = true;