etnaviv: optimize RS transfers
[mesa.git] / src / gallium / drivers / etnaviv / etnaviv_transfer.c
index 6c1edd483541d5417e03b0f13e4cc1947842ae3f..ee5cda5e8ec2f5a240a17ab0ad6996f7f0850511 100644 (file)
@@ -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);