virgl: consolidate transfer code
authorGurchetan Singh <gurchetansingh@chromium.org>
Fri, 30 Nov 2018 22:54:33 +0000 (14:54 -0800)
committerBas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
Wed, 19 Dec 2018 12:29:16 +0000 (13:29 +0100)
We could allocate and destroy transfers in one place.

v2: Keep l_stride around.

Reviewed-by: Elie Tournier <elie.tournier@collabora.com>
src/gallium/drivers/virgl/virgl_buffer.c
src/gallium/drivers/virgl/virgl_resource.c
src/gallium/drivers/virgl/virgl_resource.h
src/gallium/drivers/virgl/virgl_texture.c
src/gallium/drivers/virgl/virgl_texture.h [new file with mode: 0644]

index 7112bcbcfc96e638a576f97dccd20edb0aaf07b6..d810e9e98647f6e582b6a19797cd63a994393620 100644 (file)
@@ -113,7 +113,7 @@ static void virgl_buffer_transfer_unmap(struct pipe_context *ctx,
       }
    }
 
-   slab_free(&vctx->transfer_pool, trans);
+   virgl_resource_destroy_transfer(vctx, trans);
 }
 
 static void virgl_buffer_transfer_flush_region(struct pipe_context *ctx,
index fa589187f847466d84b04837643210b6aa612f1a..ae97d4c45e2878af94fbcb29c0c98478aa53dc8a 100644 (file)
@@ -149,24 +149,64 @@ void virgl_resource_layout(struct pipe_resource *pt,
       metadata->total_size = 0;
 }
 
-unsigned virgl_resource_offset(struct pipe_resource *pres,
-                               struct virgl_resource_metadata *metadata,
-                               unsigned level, unsigned layer)
+struct virgl_transfer *
+virgl_resource_create_transfer(struct pipe_context *ctx,
+                               struct pipe_resource *pres,
+                               const struct virgl_resource_metadata *metadata,
+                               unsigned level, unsigned usage,
+                               const struct pipe_box *box)
 {
-   unsigned offset = metadata->level_offset[level];
+   struct virgl_transfer *trans;
+   enum pipe_format format = pres->format;
+   struct virgl_context *vctx = virgl_context(ctx);
+   const unsigned blocksy = box->y / util_format_get_blockheight(format);
+   const unsigned blocksx = box->x / util_format_get_blockwidth(format);
 
+   unsigned offset = metadata->level_offset[level];
    if (pres->target == PIPE_TEXTURE_CUBE ||
        pres->target == PIPE_TEXTURE_CUBE_ARRAY ||
        pres->target == PIPE_TEXTURE_3D ||
        pres->target == PIPE_TEXTURE_2D_ARRAY) {
-      offset += layer * metadata->layer_stride[level];
+      offset += box->z * metadata->layer_stride[level];
    }
    else if (pres->target == PIPE_TEXTURE_1D_ARRAY) {
-      offset += layer * metadata->stride[level];
+      offset += box->z * metadata->stride[level];
    }
    else {
-      assert(layer == 0);
+      assert(box->z == 0);
    }
 
-   return offset;
+   offset += blocksy * metadata->stride[level];
+   offset += blocksx * util_format_get_blocksize(format);
+
+   trans = slab_alloc(&vctx->transfer_pool);
+   if (!trans)
+      return NULL;
+
+   trans->base.resource = pres;
+   trans->base.level = level;
+   trans->base.usage = usage;
+   trans->base.box = *box;
+   trans->base.stride = metadata->stride[level];
+   trans->base.layer_stride = metadata->layer_stride[level];
+   trans->offset = offset;
+   util_range_init(&trans->range);
+
+   if (trans->base.resource->target != PIPE_TEXTURE_3D &&
+       trans->base.resource->target != PIPE_TEXTURE_CUBE &&
+       trans->base.resource->target != PIPE_TEXTURE_1D_ARRAY &&
+       trans->base.resource->target != PIPE_TEXTURE_2D_ARRAY &&
+       trans->base.resource->target != PIPE_TEXTURE_CUBE_ARRAY)
+      trans->l_stride = 0;
+   else
+      trans->l_stride = trans->base.layer_stride;
+
+   return trans;
+}
+
+void virgl_resource_destroy_transfer(struct virgl_context *vctx,
+                                     struct virgl_transfer *trans)
+{
+   util_range_destroy(&trans->range);
+   slab_free(&vctx->transfer_pool, trans);
 }
index 5faedb47866211f2054eba75555e1b60ef39a010..d41b9906fb1dac2c24aed7299b7967a52596286e 100644 (file)
@@ -74,7 +74,8 @@ struct virgl_texture {
 
 struct virgl_transfer {
    struct pipe_transfer base;
-   uint32_t offset;
+   uint32_t offset, l_stride;
+   struct util_range range;
    struct virgl_resource *resolve_tmp;
 };
 
@@ -155,7 +156,14 @@ bool virgl_res_needs_readback(struct virgl_context *vctx,
 void virgl_resource_layout(struct pipe_resource *pt,
                            struct virgl_resource_metadata *metadata);
 
-unsigned virgl_resource_offset(struct pipe_resource *pres,
-                               struct virgl_resource_metadata *metadata,
-                               unsigned level, unsigned layer);
+struct virgl_transfer *
+virgl_resource_create_transfer(struct pipe_context *ctx,
+                               struct pipe_resource *pres,
+                               const struct virgl_resource_metadata *metadata,
+                               unsigned level, unsigned usage,
+                               const struct pipe_box *box);
+
+void virgl_resource_destroy_transfer(struct virgl_context *vctx,
+                                     struct virgl_transfer *trans);
+
 #endif
index c9d8e541f7ddc58c1fdb1a3b7e0817ddb173e224..80094fb6ee7c45744e88848d075e8dd34da524d4 100644 (file)
@@ -104,40 +104,18 @@ static void *virgl_texture_transfer_map(struct pipe_context *ctx,
    struct virgl_context *vctx = virgl_context(ctx);
    struct virgl_screen *vs = virgl_screen(ctx->screen);
    struct virgl_texture *vtex = virgl_texture(resource);
-   enum pipe_format format = resource->format;
    struct virgl_transfer *trans;
    void *ptr;
    boolean readback = TRUE;
-   uint32_t offset;
    struct virgl_hw_res *hw_res;
-   const unsigned h = u_minify(vtex->base.u.b.height0, level);
-   const unsigned nblocksy = util_format_get_nblocksy(format, h);
-   uint32_t l_stride;
    bool doflushwait;
 
    doflushwait = virgl_res_needs_flush_wait(vctx, &vtex->base, usage);
    if (doflushwait)
       ctx->flush(ctx, NULL, 0);
 
-   trans = slab_alloc(&vctx->transfer_pool);
-   if (!trans)
-      return NULL;
-
-   trans->base.resource = resource;
-   trans->base.level = level;
-   trans->base.usage = usage;
-   trans->base.box = *box;
-   trans->base.stride = vtex->metadata.stride[level];
-   trans->base.layer_stride = trans->base.stride * nblocksy;
-
-   if (resource->target != PIPE_TEXTURE_3D &&
-       resource->target != PIPE_TEXTURE_CUBE &&
-       resource->target != PIPE_TEXTURE_1D_ARRAY &&
-       resource->target != PIPE_TEXTURE_2D_ARRAY &&
-       resource->target != PIPE_TEXTURE_CUBE_ARRAY)
-      l_stride = 0;
-   else
-      l_stride = trans->base.layer_stride;
+   trans = virgl_resource_create_transfer(ctx, resource, &vtex->metadata, level,
+                                          usage, box);
 
    if (resource->nr_samples > 1) {
       struct pipe_resource tmp_resource;
@@ -150,21 +128,19 @@ static void *virgl_texture_transfer_map(struct pipe_context *ctx,
       ctx->flush(ctx, NULL, 0);
       /* we want to do a resolve blit into the temporary */
       hw_res = trans->resolve_tmp->hw_res;
-      offset = 0;
-      trans->base.stride = ((struct virgl_texture*)trans->resolve_tmp)->metadata.stride[level];
-      trans->base.layer_stride = trans->base.stride * nblocksy;
+      struct virgl_resource_metadata *data = &((struct virgl_texture*)trans->resolve_tmp)->metadata;
+      trans->base.stride = data->stride[level];
+      trans->base.layer_stride = data->layer_stride[level];
+      trans->offset = 0;
    } else {
-      offset = virgl_resource_offset(&vtex->base.u.b, &vtex->metadata, level, box->z);
-
-      offset += box->y / util_format_get_blockheight(format) * trans->base.stride +
-      box->x / util_format_get_blockwidth(format) * util_format_get_blocksize(format);
       hw_res = vtex->base.hw_res;
       trans->resolve_tmp = NULL;
    }
 
    readback = virgl_res_needs_readback(vctx, &vtex->base, usage);
    if (readback)
-      vs->vws->transfer_get(vs->vws, hw_res, box, trans->base.stride, l_stride, offset, level);
+      vs->vws->transfer_get(vs->vws, hw_res, box, trans->base.stride,
+                            trans->l_stride, trans->offset, level);
 
    if (doflushwait || readback)
       vs->vws->resource_wait(vs->vws, vtex->base.hw_res);
@@ -175,9 +151,7 @@ static void *virgl_texture_transfer_map(struct pipe_context *ctx,
       return NULL;
    }
 
-   trans->offset = offset;
    *transfer = &trans->base;
-
    return ptr + trans->offset;
 }
 
@@ -187,16 +161,6 @@ static void virgl_texture_transfer_unmap(struct pipe_context *ctx,
    struct virgl_context *vctx = virgl_context(ctx);
    struct virgl_transfer *trans = virgl_transfer(transfer);
    struct virgl_texture *vtex = virgl_texture(transfer->resource);
-   uint32_t l_stride;
-
-   if (transfer->resource->target != PIPE_TEXTURE_3D &&
-       transfer->resource->target != PIPE_TEXTURE_CUBE &&
-       transfer->resource->target != PIPE_TEXTURE_1D_ARRAY &&
-       transfer->resource->target != PIPE_TEXTURE_2D_ARRAY &&
-       transfer->resource->target != PIPE_TEXTURE_CUBE_ARRAY)
-      l_stride = 0;
-   else
-      l_stride = trans->base.layer_stride;
 
    if (trans->base.usage & PIPE_TRANSFER_WRITE) {
       if (!(transfer->usage & PIPE_TRANSFER_FLUSH_EXPLICIT)) {
@@ -204,7 +168,9 @@ static void virgl_texture_transfer_unmap(struct pipe_context *ctx,
          vtex->base.clean = FALSE;
          vctx->num_transfers++;
          vs->vws->transfer_put(vs->vws, vtex->base.hw_res,
-                               &transfer->box, trans->base.stride, l_stride, trans->offset, transfer->level);
+                               &transfer->box, trans->base.stride,
+                               trans->l_stride, trans->offset,
+                               transfer->level);
 
       }
    }
@@ -212,7 +178,7 @@ static void virgl_texture_transfer_unmap(struct pipe_context *ctx,
    if (trans->resolve_tmp)
       pipe_resource_reference((struct pipe_resource **)&trans->resolve_tmp, NULL);
 
-   slab_free(&vctx->transfer_pool, trans);
+   virgl_resource_destroy_transfer(vctx, trans);
 }
 
 static boolean virgl_texture_get_handle(struct pipe_screen *screen,
diff --git a/src/gallium/drivers/virgl/virgl_texture.h b/src/gallium/drivers/virgl/virgl_texture.h
new file mode 100644 (file)
index 0000000..e69de29