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;