diff options
author | Lucas Stach <[email protected]> | 2017-09-06 14:30:40 +0200 |
---|---|---|
committer | Lucas Stach <[email protected]> | 2017-09-28 17:41:07 +0200 |
commit | 15e3657e433f0e370632fdb70889eb6dfafeba34 (patch) | |
tree | 85bf13d773a1b4140ae2018733ce541de9ade9ea /src/gallium/drivers/etnaviv/etnaviv_transfer.c | |
parent | 69eb93cbb9bc544272300796b6f8d7c8c7502575 (diff) |
etnaviv: optimize RS transfers
Currently we are blitting the whole resource when the RS is used to
de-/tile a resource. This can be very inefficient for large resources
where the transfer is only changing a small part of the resource
(happens a lot with glTexSubImage2D).
Optimize this by only blitting the tile aligned subregion of the
resource, which the transfer is going to change.
Signed-off-by: Lucas Stach <[email protected]>
Reviewed-By: Wladimir J. van der Laan <[email protected]>
Diffstat (limited to 'src/gallium/drivers/etnaviv/etnaviv_transfer.c')
-rw-r--r-- | src/gallium/drivers/etnaviv/etnaviv_transfer.c | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/src/gallium/drivers/etnaviv/etnaviv_transfer.c b/src/gallium/drivers/etnaviv/etnaviv_transfer.c index 6c1edd48354..ee5cda5e8ec 100644 --- a/src/gallium/drivers/etnaviv/etnaviv_transfer.c +++ b/src/gallium/drivers/etnaviv/etnaviv_transfer.c @@ -28,6 +28,7 @@ #include "etnaviv_clear_blit.h" #include "etnaviv_context.h" #include "etnaviv_debug.h" +#include "etnaviv_screen.h" #include "pipe/p_defines.h" #include "pipe/p_format.h" @@ -84,8 +85,7 @@ etna_transfer_unmap(struct pipe_context *pctx, struct pipe_transfer *ptrans) /* We have a temporary resource due to either tile status or * tiling format. Write back the updated buffer contents. * FIXME: we need to invalidate the tile status. */ - etna_copy_resource(pctx, ptrans->resource, trans->rsc, ptrans->level, - trans->rsc->last_level); + etna_copy_resource_box(pctx, ptrans->resource, trans->rsc, ptrans->level, &ptrans->box); } else if (trans->staging) { /* map buffer object */ struct etna_resource_level *res_level = &rsc->levels[ptrans->level]; @@ -212,9 +212,30 @@ etna_transfer_map(struct pipe_context *pctx, struct pipe_resource *prsc, return NULL; } + /* Need to align the transfer region to satisfy RS restrictions, as we + * really want to hit the RS blit path here. + */ + unsigned w_align, h_align; + + if (rsc->layout & ETNA_LAYOUT_BIT_SUPER) { + w_align = h_align = 64; + } else { + w_align = ETNA_RS_WIDTH_MASK + 1; + h_align = ETNA_RS_HEIGHT_MASK + 1; + } + h_align *= ctx->screen->specs.pixel_pipes; + + ptrans->box.width += ptrans->box.x & (w_align - 1); + ptrans->box.x = ptrans->box.x & ~(w_align - 1); + ptrans->box.width = align(ptrans->box.width, (ETNA_RS_WIDTH_MASK + 1)); + ptrans->box.height += ptrans->box.y & (h_align - 1); + ptrans->box.y = ptrans->box.y & ~(h_align - 1); + ptrans->box.height = align(ptrans->box.height, + (ETNA_RS_HEIGHT_MASK + 1) * + ctx->screen->specs.pixel_pipes); + if (!(usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE)) - etna_copy_resource(pctx, trans->rsc, prsc, level, - trans->rsc->last_level); + etna_copy_resource_box(pctx, trans->rsc, prsc, level, &ptrans->box); /* Switch to using the temporary resource instead */ rsc = etna_resource(trans->rsc); |