mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-03 09:58:05 +02:00
v3d: Implement texture_subdata to reduce teximage upload copies.
This lets us store the non-PBO glTexImage data directly into the tiled image without making an extra untiled memcpy for the gallium transfer. Improves 1024x1024 TexImage perf by ~19%, mostly from not thrashing around in the kernel mapping and unmapping the transfer's temporary area.
This commit is contained in:
parent
e09d8aecb4
commit
8ee752194c
1 changed files with 85 additions and 29 deletions
|
|
@ -146,37 +146,13 @@ v3d_resource_transfer_unmap(struct pipe_context *pctx,
|
|||
slab_free(&v3d->transfer_pool, ptrans);
|
||||
}
|
||||
|
||||
static void *
|
||||
v3d_resource_transfer_map(struct pipe_context *pctx,
|
||||
struct pipe_resource *prsc,
|
||||
unsigned level, unsigned usage,
|
||||
const struct pipe_box *box,
|
||||
struct pipe_transfer **pptrans)
|
||||
static void
|
||||
v3d_map_usage_prep(struct pipe_context *pctx,
|
||||
struct pipe_resource *prsc,
|
||||
unsigned usage)
|
||||
{
|
||||
struct v3d_context *v3d = v3d_context(pctx);
|
||||
struct v3d_resource *rsc = v3d_resource(prsc);
|
||||
struct v3d_transfer *trans;
|
||||
struct pipe_transfer *ptrans;
|
||||
enum pipe_format format = prsc->format;
|
||||
char *buf;
|
||||
|
||||
/* MSAA maps should have been handled by u_transfer_helper. */
|
||||
assert(prsc->nr_samples <= 1);
|
||||
|
||||
/* Upgrade DISCARD_RANGE to WHOLE_RESOURCE if the whole resource is
|
||||
* being mapped.
|
||||
*/
|
||||
if ((usage & PIPE_TRANSFER_DISCARD_RANGE) &&
|
||||
!(usage & PIPE_TRANSFER_UNSYNCHRONIZED) &&
|
||||
!(prsc->flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT) &&
|
||||
prsc->last_level == 0 &&
|
||||
prsc->width0 == box->width &&
|
||||
prsc->height0 == box->height &&
|
||||
prsc->depth0 == box->depth &&
|
||||
prsc->array_size == 1 &&
|
||||
rsc->bo->private) {
|
||||
usage |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
|
||||
}
|
||||
|
||||
if (usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) {
|
||||
if (v3d_resource_bo_alloc(rsc)) {
|
||||
|
|
@ -209,6 +185,41 @@ v3d_resource_transfer_map(struct pipe_context *pctx,
|
|||
rsc->writes++;
|
||||
rsc->initialized_buffers = ~0;
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
v3d_resource_transfer_map(struct pipe_context *pctx,
|
||||
struct pipe_resource *prsc,
|
||||
unsigned level, unsigned usage,
|
||||
const struct pipe_box *box,
|
||||
struct pipe_transfer **pptrans)
|
||||
{
|
||||
struct v3d_context *v3d = v3d_context(pctx);
|
||||
struct v3d_resource *rsc = v3d_resource(prsc);
|
||||
struct v3d_transfer *trans;
|
||||
struct pipe_transfer *ptrans;
|
||||
enum pipe_format format = prsc->format;
|
||||
char *buf;
|
||||
|
||||
/* MSAA maps should have been handled by u_transfer_helper. */
|
||||
assert(prsc->nr_samples <= 1);
|
||||
|
||||
/* Upgrade DISCARD_RANGE to WHOLE_RESOURCE if the whole resource is
|
||||
* being mapped.
|
||||
*/
|
||||
if ((usage & PIPE_TRANSFER_DISCARD_RANGE) &&
|
||||
!(usage & PIPE_TRANSFER_UNSYNCHRONIZED) &&
|
||||
!(prsc->flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT) &&
|
||||
prsc->last_level == 0 &&
|
||||
prsc->width0 == box->width &&
|
||||
prsc->height0 == box->height &&
|
||||
prsc->depth0 == box->depth &&
|
||||
prsc->array_size == 1 &&
|
||||
rsc->bo->private) {
|
||||
usage |= PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
|
||||
}
|
||||
|
||||
v3d_map_usage_prep(pctx, prsc, usage);
|
||||
|
||||
trans = slab_alloc(&v3d->transfer_pool);
|
||||
if (!trans)
|
||||
|
|
@ -295,6 +306,51 @@ fail:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
v3d_texture_subdata(struct pipe_context *pctx,
|
||||
struct pipe_resource *prsc,
|
||||
unsigned level,
|
||||
unsigned usage,
|
||||
const struct pipe_box *box,
|
||||
const void *data,
|
||||
unsigned stride,
|
||||
unsigned layer_stride)
|
||||
{
|
||||
struct v3d_resource *rsc = v3d_resource(prsc);
|
||||
struct v3d_resource_slice *slice = &rsc->slices[level];
|
||||
|
||||
/* For a direct mapping, we can just take the u_transfer path. */
|
||||
if (!rsc->tiled) {
|
||||
return u_default_texture_subdata(pctx, prsc, level, usage, box,
|
||||
data, stride, layer_stride);
|
||||
}
|
||||
|
||||
/* Otherwise, map and store the texture data directly into the tiled
|
||||
* texture. Note that gallium's texture_subdata may be called with
|
||||
* obvious usage flags missing!
|
||||
*/
|
||||
v3d_map_usage_prep(pctx, prsc, usage | (PIPE_TRANSFER_WRITE |
|
||||
PIPE_TRANSFER_DISCARD_RANGE));
|
||||
|
||||
void *buf;
|
||||
if (usage & PIPE_TRANSFER_UNSYNCHRONIZED)
|
||||
buf = v3d_bo_map_unsynchronized(rsc->bo);
|
||||
else
|
||||
buf = v3d_bo_map(rsc->bo);
|
||||
|
||||
for (int i = 0; i < box->depth; i++) {
|
||||
v3d_store_tiled_image(buf +
|
||||
v3d_layer_offset(&rsc->base,
|
||||
level,
|
||||
box->z + i),
|
||||
slice->stride,
|
||||
(void *)data + layer_stride * i,
|
||||
stride,
|
||||
slice->tiling, rsc->cpp, slice->padded_height,
|
||||
box);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
v3d_resource_destroy(struct pipe_screen *pscreen,
|
||||
struct pipe_resource *prsc)
|
||||
|
|
@ -1041,7 +1097,7 @@ v3d_resource_context_init(struct pipe_context *pctx)
|
|||
pctx->transfer_flush_region = u_transfer_helper_transfer_flush_region;
|
||||
pctx->transfer_unmap = u_transfer_helper_transfer_unmap;
|
||||
pctx->buffer_subdata = u_default_buffer_subdata;
|
||||
pctx->texture_subdata = u_default_texture_subdata;
|
||||
pctx->texture_subdata = v3d_texture_subdata;
|
||||
pctx->create_surface = v3d_create_surface;
|
||||
pctx->surface_destroy = v3d_surface_destroy;
|
||||
pctx->resource_copy_region = util_resource_copy_region;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue