Skip to content

Commit 7c25b3e

Browse files
committed
vo_gpu_next: fix upload synchronization
And make them actually async when copied from host ptr. The issue was when we used DR buf upload, which is always async, it was not synchronized in anyway. Fixes: #13811
1 parent d8be860 commit 7c25b3e

1 file changed

Lines changed: 23 additions & 3 deletions

File tree

video/out/vo_gpu_next.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -346,14 +346,21 @@ static void update_overlays(struct vo *vo, struct mp_osd_res res,
346346
MP_ERR(vo, "Failed recreating OSD texture!\n");
347347
break;
348348
}
349-
ok = pl_tex_upload(p->gpu, &(struct pl_tex_transfer_params) {
349+
struct pl_tex_transfer_params upload_params = {
350350
.tex = entry->tex,
351351
.rc = { .x1 = item->packed_w, .y1 = item->packed_h, },
352352
.row_pitch = item->packed->stride[0],
353353
.ptr = item->packed->planes[0],
354-
});
354+
};
355+
// Keep the image alive until it's fully read.
356+
if (p->gpu->limits.callbacks) {
357+
upload_params.callback = talloc_free;
358+
upload_params.priv = mp_image_new_ref(item->packed);
359+
}
360+
ok = pl_tex_upload(p->gpu, &upload_params);
355361
if (!ok) {
356362
MP_ERR(vo, "Failed uploading OSD texture!\n");
363+
talloc_free(upload_params.priv);
357364
break;
358365
}
359366

@@ -791,8 +798,12 @@ static bool map_frame(pl_gpu gpu, pl_tex *tex, const struct pl_source_frame *src
791798
data[n].buf = buf;
792799
data[n].buf_offset = (uint8_t *) data[n].pixels - buf->data;
793800
data[n].pixels = NULL;
794-
} else if (gpu->limits.callbacks) {
801+
}
802+
// Keep the image alive until it's fully read.
803+
if (gpu->limits.callbacks) {
804+
mp_assert(!data[n].callback);
795805
data[n].callback = talloc_free;
806+
mp_assert(!data[n].priv);
796807
data[n].priv = mp_image_new_ref(mpi);
797808
}
798809

@@ -804,6 +815,10 @@ static bool map_frame(pl_gpu gpu, pl_tex *tex, const struct pl_source_frame *src
804815
talloc_free(mpi);
805816
return false;
806817
}
818+
819+
// Without async callback support, we have to poll...
820+
if (!gpu->limits.callbacks && data[n].buf)
821+
while (pl_buf_poll(gpu, data[n].buf, UINT64_MAX));
807822
}
808823
timer_pool_stop(p->sw_upload_timer);
809824
p->sw_upload_perf = timer_pool_measure(p->sw_upload_timer);
@@ -2150,6 +2165,11 @@ static void cache_uninit(struct priv *p, struct cache *cache)
21502165
static void uninit(struct vo *vo)
21512166
{
21522167
struct priv *p = vo->priv;
2168+
2169+
// Drain any in-flight uploads.
2170+
if (p->gpu)
2171+
pl_gpu_finish(p->gpu);
2172+
21532173
pl_queue_destroy(&p->queue); // destroy this first
21542174
for (int i = 0; i < MP_ARRAY_SIZE(p->osd_state.entries); i++)
21552175
pl_tex_destroy(p->gpu, &p->osd_state.entries[i].tex);

0 commit comments

Comments
 (0)