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 <gert.wollny@collabora.com>
This commit is contained in:
parent
4a7857b377
commit
f0e71b1088
|
@ -83,8 +83,10 @@ static void virgl_buffer_transfer_unmap(struct pipe_context *ctx,
|
||||||
if (trans->base.usage & PIPE_TRANSFER_WRITE) {
|
if (trans->base.usage & PIPE_TRANSFER_WRITE) {
|
||||||
struct virgl_screen *vs = virgl_screen(ctx->screen);
|
struct virgl_screen *vs = virgl_screen(ctx->screen);
|
||||||
if (transfer->usage & PIPE_TRANSFER_FLUSH_EXPLICIT) {
|
if (transfer->usage & PIPE_TRANSFER_FLUSH_EXPLICIT) {
|
||||||
if (trans->range.end <= trans->range.start)
|
if (trans->range.end <= trans->range.start) {
|
||||||
goto out;
|
virgl_resource_destroy_transfer(&vctx->transfer_pool, trans);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
transfer->box.x += trans->range.start;
|
transfer->box.x += trans->range.start;
|
||||||
transfer->box.width = trans->range.end - 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++;
|
vctx->num_transfers++;
|
||||||
vs->vws->transfer_put(vs->vws, vbuf->hw_res,
|
virgl_transfer_queue_unmap(&vctx->queue, trans);
|
||||||
&transfer->box, trans->base.stride,
|
|
||||||
trans->l_stride, trans->offset,
|
|
||||||
transfer->level);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
|
||||||
virgl_resource_destroy_transfer(&vctx->transfer_pool, trans);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void virgl_buffer_transfer_flush_region(struct pipe_context *ctx,
|
static void virgl_buffer_transfer_flush_region(struct pipe_context *ctx,
|
||||||
struct pipe_transfer *transfer,
|
struct pipe_transfer *transfer,
|
||||||
const struct pipe_box *box)
|
const struct pipe_box *box)
|
||||||
{
|
{
|
||||||
|
struct virgl_context *vctx = virgl_context(ctx);
|
||||||
struct virgl_resource *vbuf = virgl_resource(transfer->resource);
|
struct virgl_resource *vbuf = virgl_resource(transfer->resource);
|
||||||
struct virgl_transfer *trans = virgl_transfer(transfer);
|
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 */
|
/* send the buffer to the remote side for decoding */
|
||||||
ctx->num_transfers = ctx->num_draws = ctx->num_compute = 0;
|
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,
|
rs->vws->submit_cmd(rs->vws, ctx->cbuf, ctx->cbuf->in_fence_fd,
|
||||||
ctx->cbuf->needs_out_fence_fd ? &out_fence_fd : NULL);
|
ctx->cbuf->needs_out_fence_fd ? &out_fence_fd : NULL);
|
||||||
|
|
||||||
if (fence)
|
if (fence)
|
||||||
*fence = rs->vws->cs_create_fence(rs->vws, out_fence_fd);
|
*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);
|
virgl_encoder_set_sub_ctx(ctx, ctx->hw_sub_ctx_id);
|
||||||
|
|
||||||
/* add back current framebuffer resources to reference list? */
|
/* add back current framebuffer resources to reference list? */
|
||||||
|
@ -1190,6 +1195,7 @@ virgl_context_destroy( struct pipe_context *ctx )
|
||||||
if (vctx->uploader)
|
if (vctx->uploader)
|
||||||
u_upload_destroy(vctx->uploader);
|
u_upload_destroy(vctx->uploader);
|
||||||
util_primconvert_destroy(vctx->primconvert);
|
util_primconvert_destroy(vctx->primconvert);
|
||||||
|
virgl_transfer_queue_fini(&vctx->queue);
|
||||||
|
|
||||||
slab_destroy_child(&vctx->transfer_pool);
|
slab_destroy_child(&vctx->transfer_pool);
|
||||||
FREE(vctx);
|
FREE(vctx);
|
||||||
|
@ -1333,6 +1339,13 @@ struct pipe_context *virgl_context_create(struct pipe_screen *pscreen,
|
||||||
virgl_init_so_functions(vctx);
|
virgl_init_so_functions(vctx);
|
||||||
|
|
||||||
slab_create_child(&vctx->transfer_pool, &rs->transfer_pool);
|
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->primconvert = util_primconvert_create(&vctx->base, rs->caps.caps.v1.prim_mask);
|
||||||
vctx->uploader = u_upload_create(&vctx->base, 1024 * 1024,
|
vctx->uploader = u_upload_create(&vctx->base, 1024 * 1024,
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
#include "util/slab.h"
|
#include "util/slab.h"
|
||||||
#include "util/list.h"
|
#include "util/list.h"
|
||||||
|
|
||||||
|
#include "virgl_transfer_queue.h"
|
||||||
|
|
||||||
struct pipe_screen;
|
struct pipe_screen;
|
||||||
struct tgsi_token;
|
struct tgsi_token;
|
||||||
struct u_upload_mgr;
|
struct u_upload_mgr;
|
||||||
|
@ -64,8 +66,9 @@ struct virgl_context {
|
||||||
struct pipe_framebuffer_state framebuffer;
|
struct pipe_framebuffer_state framebuffer;
|
||||||
|
|
||||||
struct slab_child_pool transfer_pool;
|
struct slab_child_pool transfer_pool;
|
||||||
|
struct virgl_transfer_queue queue;
|
||||||
struct u_upload_mgr *uploader;
|
struct u_upload_mgr *uploader;
|
||||||
|
bool encoded_transfers;
|
||||||
|
|
||||||
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
|
struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
|
||||||
unsigned num_vertex_buffers;
|
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 (res->clean[trans->base.level]) {
|
||||||
if (vctx->num_draws == 0 && vctx->num_compute == 0)
|
if (vctx->num_draws == 0 && vctx->num_compute == 0)
|
||||||
return false;
|
return false;
|
||||||
|
if (!virgl_transfer_queue_is_queued(&vctx->queue, trans))
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -166,18 +166,22 @@ static void virgl_texture_transfer_unmap(struct pipe_context *ctx,
|
||||||
if (!(transfer->usage & PIPE_TRANSFER_FLUSH_EXPLICIT)) {
|
if (!(transfer->usage & PIPE_TRANSFER_FLUSH_EXPLICIT)) {
|
||||||
struct virgl_screen *vs = virgl_screen(ctx->screen);
|
struct virgl_screen *vs = virgl_screen(ctx->screen);
|
||||||
vctx->num_transfers++;
|
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);
|
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 =
|
static const struct u_resource_vtbl virgl_texture_vtbl =
|
||||||
|
|
Loading…
Reference in New Issue