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;
}
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);
/* 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? */
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);
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,
#include "util/slab.h"
#include "util/list.h"
+#include "virgl_transfer_queue.h"
+
struct pipe_screen;
struct tgsi_token;
struct u_upload_mgr;
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;
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;
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 =