From f0e71b1088848e4190d6f8a5415571d0ddf130aa Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Thu, 3 Jan 2019 10:31:06 -0800 Subject: [PATCH] virgl: use transfer queue This improves Unigine Valley benchmark by 3 to 10 fps (depending on the scene). It also improves the Team Fortress 2 benchmark from 6 fps to 13 fps (host: 20 fps). Reviewed-by: Gert Wollny --- src/gallium/drivers/virgl/virgl_buffer.c | 16 ++++++---------- src/gallium/drivers/virgl/virgl_context.c | 13 +++++++++++++ src/gallium/drivers/virgl/virgl_context.h | 5 ++++- src/gallium/drivers/virgl/virgl_resource.c | 2 ++ src/gallium/drivers/virgl/virgl_texture.c | 18 +++++++++++------- 5 files changed, 36 insertions(+), 18 deletions(-) diff --git a/src/gallium/drivers/virgl/virgl_buffer.c b/src/gallium/drivers/virgl/virgl_buffer.c index 269a451ac18..c500b1c297a 100644 --- a/src/gallium/drivers/virgl/virgl_buffer.c +++ b/src/gallium/drivers/virgl/virgl_buffer.c @@ -83,8 +83,10 @@ static void virgl_buffer_transfer_unmap(struct pipe_context *ctx, if (trans->base.usage & PIPE_TRANSFER_WRITE) { struct virgl_screen *vs = virgl_screen(ctx->screen); if (transfer->usage & PIPE_TRANSFER_FLUSH_EXPLICIT) { - if (trans->range.end <= trans->range.start) - goto out; + if (trans->range.end <= trans->range.start) { + virgl_resource_destroy_transfer(&vctx->transfer_pool, trans); + return; + } transfer->box.x += trans->range.start; transfer->box.width = trans->range.end - trans->range.start; @@ -92,21 +94,15 @@ static void virgl_buffer_transfer_unmap(struct pipe_context *ctx, } vctx->num_transfers++; - vs->vws->transfer_put(vs->vws, vbuf->hw_res, - &transfer->box, trans->base.stride, - trans->l_stride, trans->offset, - transfer->level); - + virgl_transfer_queue_unmap(&vctx->queue, trans); } - -out: - virgl_resource_destroy_transfer(&vctx->transfer_pool, trans); } static void virgl_buffer_transfer_flush_region(struct pipe_context *ctx, struct pipe_transfer *transfer, const struct pipe_box *box) { + struct virgl_context *vctx = virgl_context(ctx); struct virgl_resource *vbuf = virgl_resource(transfer->resource); struct virgl_transfer *trans = virgl_transfer(transfer); diff --git a/src/gallium/drivers/virgl/virgl_context.c b/src/gallium/drivers/virgl/virgl_context.c index afc9fe883f7..4c74b16d01d 100644 --- a/src/gallium/drivers/virgl/virgl_context.c +++ b/src/gallium/drivers/virgl/virgl_context.c @@ -762,12 +762,17 @@ static void virgl_flush_eq(struct virgl_context *ctx, void *closure, /* send the buffer to the remote side for decoding */ ctx->num_transfers = ctx->num_draws = ctx->num_compute = 0; + virgl_transfer_queue_clear(&ctx->queue, ctx->cbuf); rs->vws->submit_cmd(rs->vws, ctx->cbuf, ctx->cbuf->in_fence_fd, ctx->cbuf->needs_out_fence_fd ? &out_fence_fd : NULL); if (fence) *fence = rs->vws->cs_create_fence(rs->vws, out_fence_fd); + /* Reserve some space for transfers. */ + if (ctx->encoded_transfers) + ctx->cbuf->cdw = VIRGL_MAX_TBUF_DWORDS; + virgl_encoder_set_sub_ctx(ctx, ctx->hw_sub_ctx_id); /* add back current framebuffer resources to reference list? */ @@ -1190,6 +1195,7 @@ virgl_context_destroy( struct pipe_context *ctx ) if (vctx->uploader) u_upload_destroy(vctx->uploader); util_primconvert_destroy(vctx->primconvert); + virgl_transfer_queue_fini(&vctx->queue); slab_destroy_child(&vctx->transfer_pool); FREE(vctx); @@ -1333,6 +1339,13 @@ struct pipe_context *virgl_context_create(struct pipe_screen *pscreen, virgl_init_so_functions(vctx); slab_create_child(&vctx->transfer_pool, &rs->transfer_pool); + virgl_transfer_queue_init(&vctx->queue, rs, &vctx->transfer_pool); + vctx->encoded_transfers = (rs->vws->supports_encoded_transfers && + (rs->caps.caps.v2.capability_bits & VIRGL_CAP_TRANSFER)); + + /* Reserve some space for transfers. */ + if (vctx->encoded_transfers) + vctx->cbuf->cdw = VIRGL_MAX_TBUF_DWORDS; vctx->primconvert = util_primconvert_create(&vctx->base, rs->caps.caps.v1.prim_mask); vctx->uploader = u_upload_create(&vctx->base, 1024 * 1024, diff --git a/src/gallium/drivers/virgl/virgl_context.h b/src/gallium/drivers/virgl/virgl_context.h index 65485475d9d..f42a719966d 100644 --- a/src/gallium/drivers/virgl/virgl_context.h +++ b/src/gallium/drivers/virgl/virgl_context.h @@ -28,6 +28,8 @@ #include "util/slab.h" #include "util/list.h" +#include "virgl_transfer_queue.h" + struct pipe_screen; struct tgsi_token; struct u_upload_mgr; @@ -64,8 +66,9 @@ struct virgl_context { struct pipe_framebuffer_state framebuffer; struct slab_child_pool transfer_pool; - + struct virgl_transfer_queue queue; struct u_upload_mgr *uploader; + bool encoded_transfers; struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS]; unsigned num_vertex_buffers; diff --git a/src/gallium/drivers/virgl/virgl_resource.c b/src/gallium/drivers/virgl/virgl_resource.c index ddb6b77b769..a21e9111769 100644 --- a/src/gallium/drivers/virgl/virgl_resource.c +++ b/src/gallium/drivers/virgl/virgl_resource.c @@ -40,6 +40,8 @@ bool virgl_res_needs_flush_wait(struct virgl_context *vctx, if (res->clean[trans->base.level]) { if (vctx->num_draws == 0 && vctx->num_compute == 0) return false; + if (!virgl_transfer_queue_is_queued(&vctx->queue, trans)) + return false; } return true; diff --git a/src/gallium/drivers/virgl/virgl_texture.c b/src/gallium/drivers/virgl/virgl_texture.c index 3bffee9b7a5..c661ca91752 100644 --- a/src/gallium/drivers/virgl/virgl_texture.c +++ b/src/gallium/drivers/virgl/virgl_texture.c @@ -166,18 +166,22 @@ static void virgl_texture_transfer_unmap(struct pipe_context *ctx, if (!(transfer->usage & PIPE_TRANSFER_FLUSH_EXPLICIT)) { struct virgl_screen *vs = virgl_screen(ctx->screen); vctx->num_transfers++; - vs->vws->transfer_put(vs->vws, vtex->hw_res, - &transfer->box, trans->base.stride, - trans->l_stride, trans->offset, - transfer->level); + if (trans->resolve_tmp) { + vs->vws->transfer_put(vs->vws, vtex->hw_res, + &transfer->box, trans->base.stride, + trans->l_stride, trans->offset, + transfer->level); + } else { + virgl_transfer_queue_unmap(&vctx->queue, trans); + } } } - if (trans->resolve_tmp) + if (trans->resolve_tmp) { pipe_resource_reference((struct pipe_resource **)&trans->resolve_tmp, NULL); - - virgl_resource_destroy_transfer(&vctx->transfer_pool, trans); + virgl_resource_destroy_transfer(&vctx->transfer_pool, trans); + } } static const struct u_resource_vtbl virgl_texture_vtbl = -- 2.30.2