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 <gert.wollny@collabora.com>tags/19.1-branchpoint
@@ -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); | |||
@@ -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, |
@@ -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; |
@@ -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; |
@@ -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 = |