Mesa (master): virgl: save virgl_hw_res in virgl_transfer

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Jun 17 16:44:07 UTC 2019


Module: Mesa
Branch: master
Commit: 7e0508d9aa9575db7f608eae0c5337e2a0634197
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=7e0508d9aa9575db7f608eae0c5337e2a0634197

Author: Chia-I Wu <olvaffe at gmail.com>
Date:   Wed May 15 15:34:44 2019 -0700

virgl: save virgl_hw_res in virgl_transfer

When PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE is properly supported,
virgl_transfer might refer to a different virgl_hw_res than
virgl_resource does.  We need to save the virgl_hw_res and use the
saved one.

Signed-off-by: Chia-I Wu <olvaffe at gmail.com>
Reviewed-by: Alexandros Frantzis <alexandros.frantzis at collabora.com>

---

 src/gallium/drivers/virgl/virgl_encode.c         |  8 ++++++--
 src/gallium/drivers/virgl/virgl_resource.c       |  7 +++++++
 src/gallium/drivers/virgl/virgl_resource.h       |  2 ++
 src/gallium/drivers/virgl/virgl_texture.c        |  2 +-
 src/gallium/drivers/virgl/virgl_transfer_queue.c | 17 ++++++-----------
 5 files changed, 22 insertions(+), 14 deletions(-)

diff --git a/src/gallium/drivers/virgl/virgl_encode.c b/src/gallium/drivers/virgl/virgl_encode.c
index d26c0670f72..95a5bf97c18 100644
--- a/src/gallium/drivers/virgl/virgl_encode.c
+++ b/src/gallium/drivers/virgl/virgl_encode.c
@@ -527,7 +527,6 @@ static void virgl_encoder_transfer3d_common(struct virgl_screen *vs,
 
 {
    struct pipe_transfer *transfer = &xfer->base;
-   struct virgl_resource *res = virgl_resource(transfer->resource);
    unsigned stride;
    unsigned layer_stride;
 
@@ -541,7 +540,11 @@ static void virgl_encoder_transfer3d_common(struct virgl_screen *vs,
       assert(!"Invalid virgl_transfer3d_encode_stride value");
    }
 
-   virgl_encoder_emit_resource(vs, buf, res);
+   /* We cannot use virgl_encoder_emit_resource with transfer->resource here
+    * because transfer->resource might have a different virgl_hw_res than what
+    * this transfer targets, which is saved in xfer->hw_res.
+    */
+   vs->vws->emit_res(vs->vws, buf, xfer->hw_res, TRUE);
    virgl_encoder_write_dword(buf, transfer->level);
    virgl_encoder_write_dword(buf, transfer->usage);
    virgl_encoder_write_dword(buf, stride);
@@ -567,6 +570,7 @@ int virgl_encoder_inline_write(struct virgl_context *ctx,
    struct virgl_screen *vs = virgl_screen(ctx->base.screen);
 
    transfer.base.resource = &res->u.b;
+   transfer.hw_res = res->hw_res;
    transfer.base.level = level;
    transfer.base.usage = usage;
    transfer.base.box = *box;
diff --git a/src/gallium/drivers/virgl/virgl_resource.c b/src/gallium/drivers/virgl/virgl_resource.c
index 1c8e264e573..59afcca968e 100644
--- a/src/gallium/drivers/virgl/virgl_resource.c
+++ b/src/gallium/drivers/virgl/virgl_resource.c
@@ -387,6 +387,7 @@ virgl_resource_create_transfer(struct virgl_context *vctx,
                                unsigned level, unsigned usage,
                                const struct pipe_box *box)
 {
+   struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws;
    struct virgl_transfer *trans;
    enum pipe_format format = pres->format;
    const unsigned blocksy = box->y / util_format_get_blockheight(format);
@@ -418,6 +419,9 @@ virgl_resource_create_transfer(struct virgl_context *vctx,
    /* note that trans is not zero-initialized */
    trans->base.resource = NULL;
    pipe_resource_reference(&trans->base.resource, pres);
+   trans->hw_res = NULL;
+   vws->resource_reference(vws, &trans->hw_res, virgl_resource(pres)->hw_res);
+
    trans->base.level = level;
    trans->base.usage = usage;
    trans->base.box = *box;
@@ -443,9 +447,12 @@ virgl_resource_create_transfer(struct virgl_context *vctx,
 void virgl_resource_destroy_transfer(struct virgl_context *vctx,
                                      struct virgl_transfer *trans)
 {
+   struct virgl_winsys *vws = virgl_screen(vctx->base.screen)->vws;
+
    pipe_resource_reference(&trans->copy_src_res, NULL);
 
    util_range_destroy(&trans->range);
+   vws->resource_reference(vws, &trans->hw_res, NULL);
    pipe_resource_reference(&trans->base.resource, NULL);
    slab_free(&vctx->transfer_pool, trans);
 }
diff --git a/src/gallium/drivers/virgl/virgl_resource.h b/src/gallium/drivers/virgl/virgl_resource.h
index 710244d2c7f..a69b172ef2a 100644
--- a/src/gallium/drivers/virgl/virgl_resource.h
+++ b/src/gallium/drivers/virgl/virgl_resource.h
@@ -76,6 +76,8 @@ struct virgl_transfer {
    struct util_range range;
    struct list_head queue_link;
    struct pipe_transfer *resolve_transfer;
+
+   struct virgl_hw_res *hw_res;
    void *hw_res_map;
    /* If not NULL, denotes that this is a copy transfer, i.e.,
     * that the transfer source data should be taken from this
diff --git a/src/gallium/drivers/virgl/virgl_texture.c b/src/gallium/drivers/virgl/virgl_texture.c
index 6e26493cb61..1de6d4f17db 100644
--- a/src/gallium/drivers/virgl/virgl_texture.c
+++ b/src/gallium/drivers/virgl/virgl_texture.c
@@ -296,7 +296,7 @@ static void flush_data(struct pipe_context *ctx,
                        const struct pipe_box *box)
 {
    struct virgl_winsys *vws = virgl_screen(ctx->screen)->vws;
-   vws->transfer_put(vws, virgl_resource(trans->base.resource)->hw_res, box,
+   vws->transfer_put(vws, trans->hw_res, box,
                      trans->base.stride, trans->l_stride, trans->offset,
                      trans->base.level);
 }
diff --git a/src/gallium/drivers/virgl/virgl_transfer_queue.c b/src/gallium/drivers/virgl/virgl_transfer_queue.c
index f41c0defbbe..33f8b62f4a3 100644
--- a/src/gallium/drivers/virgl/virgl_transfer_queue.c
+++ b/src/gallium/drivers/virgl/virgl_transfer_queue.c
@@ -57,10 +57,8 @@ static bool transfers_intersect(struct virgl_transfer *queued,
                                 struct virgl_transfer *current)
 {
    boolean tmp;
-   struct pipe_resource *queued_res = queued->base.resource;
-   struct pipe_resource *current_res = current->base.resource;
 
-   if (queued_res != current_res)
+   if (queued->hw_res != current->hw_res)
       return false;
 
    tmp = u_box_test_intersection_2d(&queued->base.box, &current->base.box);
@@ -71,10 +69,8 @@ static bool transfers_overlap(struct virgl_transfer *queued,
                               struct virgl_transfer *current)
 {
    boolean tmp;
-   struct pipe_resource *queued_res = queued->base.resource;
-   struct pipe_resource *current_res = current->base.resource;
 
-   if (queued_res != current_res)
+   if (queued->hw_res != current->hw_res)
       return false;
 
    if (queued->base.level != current->base.level)
@@ -89,7 +85,7 @@ static bool transfers_overlap(struct virgl_transfer *queued,
    /*
     * Special case for boxes with [x: 0, width: 1] and [x: 1, width: 1].
     */
-   if (queued_res->target == PIPE_BUFFER) {
+   if (queued->base.resource->target == PIPE_BUFFER) {
       if (queued->base.box.x + queued->base.box.width == current->base.box.x)
          return false;
 
@@ -141,9 +137,9 @@ static void transfer_put(struct virgl_transfer_queue *queue,
                          struct list_action_args *args)
 {
    struct virgl_transfer *queued = args->queued;
-   struct virgl_resource *res = virgl_resource(queued->base.resource);
 
-   queue->vs->vws->transfer_put(queue->vs->vws, res->hw_res, &queued->base.box,
+   queue->vs->vws->transfer_put(queue->vs->vws, queued->hw_res,
+                                &queued->base.box,
                                 queued->base.stride, queued->l_stride,
                                 queued->offset, queued->base.level);
 
@@ -290,14 +286,13 @@ void virgl_transfer_queue_fini(struct virgl_transfer_queue *queue)
 int virgl_transfer_queue_unmap(struct virgl_transfer_queue *queue,
                                struct virgl_transfer *transfer)
 {
-   struct pipe_resource *res = transfer->base.resource;
    struct list_iteration_args iter;
 
    /* We don't support copy transfers in the transfer queue. */
    assert(!transfer->copy_src_res);
 
    /* Attempt to merge multiple intersecting transfers into a single one. */
-   if (res->target == PIPE_BUFFER) {
+   if (transfer->base.resource->target == PIPE_BUFFER) {
       memset(&iter, 0, sizeof(iter));
       iter.current = transfer;
       iter.compare = transfers_intersect;




More information about the mesa-commit mailing list