summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/virgl
diff options
context:
space:
mode:
authorGurchetan Singh <[email protected]>2018-11-30 14:54:33 -0800
committerBas Nieuwenhuizen <[email protected]>2018-12-19 13:29:16 +0100
commit174f530008c1b22ede7c67995f693b3d84f2a488 (patch)
treee6f2b9bacfb6b7ef3ae2dbc21469012d519720a6 /src/gallium/drivers/virgl
parent13626b46f12eaa5ffb6c3eb72eea755e739b0b01 (diff)
virgl: consolidate transfer code
We could allocate and destroy transfers in one place. v2: Keep l_stride around. Reviewed-by: Elie Tournier <[email protected]>
Diffstat (limited to 'src/gallium/drivers/virgl')
-rw-r--r--src/gallium/drivers/virgl/virgl_buffer.c2
-rw-r--r--src/gallium/drivers/virgl/virgl_resource.c56
-rw-r--r--src/gallium/drivers/virgl/virgl_resource.h16
-rw-r--r--src/gallium/drivers/virgl/virgl_texture.c58
-rw-r--r--src/gallium/drivers/virgl/virgl_texture.h0
5 files changed, 73 insertions, 59 deletions
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
--- /dev/null
+++ b/src/gallium/drivers/virgl/virgl_texture.h