From 174f530008c1b22ede7c67995f693b3d84f2a488 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Fri, 30 Nov 2018 14:54:33 -0800 Subject: [PATCH] virgl: consolidate transfer code We could allocate and destroy transfers in one place. v2: Keep l_stride around. Reviewed-by: Elie Tournier --- src/gallium/drivers/virgl/virgl_buffer.c | 2 +- src/gallium/drivers/virgl/virgl_resource.c | 56 ++++++++++++++++++--- src/gallium/drivers/virgl/virgl_resource.h | 16 ++++-- src/gallium/drivers/virgl/virgl_texture.c | 58 +++++----------------- src/gallium/drivers/virgl/virgl_texture.h | 0 5 files changed, 73 insertions(+), 59 deletions(-) create mode 100644 src/gallium/drivers/virgl/virgl_texture.h diff --git a/src/gallium/drivers/virgl/virgl_buffer.c b/src/gallium/drivers/virgl/virgl_buffer.c index 7112bcbcfc9..d810e9e9864 100644 --- a/src/gallium/drivers/virgl/virgl_buffer.c +++ b/src/gallium/drivers/virgl/virgl_buffer.c @@ -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, diff --git a/src/gallium/drivers/virgl/virgl_resource.c b/src/gallium/drivers/virgl/virgl_resource.c index fa589187f84..ae97d4c45e2 100644 --- a/src/gallium/drivers/virgl/virgl_resource.c +++ b/src/gallium/drivers/virgl/virgl_resource.c @@ -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); } diff --git a/src/gallium/drivers/virgl/virgl_resource.h b/src/gallium/drivers/virgl/virgl_resource.h index 5faedb47866..d41b9906fb1 100644 --- a/src/gallium/drivers/virgl/virgl_resource.h +++ b/src/gallium/drivers/virgl/virgl_resource.h @@ -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 diff --git a/src/gallium/drivers/virgl/virgl_texture.c b/src/gallium/drivers/virgl/virgl_texture.c index c9d8e541f7d..80094fb6ee7 100644 --- a/src/gallium/drivers/virgl/virgl_texture.c +++ b/src/gallium/drivers/virgl/virgl_texture.c @@ -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 index 00000000000..e69de29bb2d -- 2.30.2