ilo: EOL drop unmaintained gallium drv from buildsys
[mesa.git] / src / gallium / drivers / ilo / ilo_blitter_blt.c
index 4e501f14bf13e54c9305faa5e78d68254ac271a3..66203e8613726eb0ad4ef51dc8b75363b4fb4776 100644 (file)
  *    Chia-I Wu <olv@lunarg.com>
  */
 
+#include "genhw/genhw.h"
+#include "core/ilo_builder_mi.h"
+#include "core/ilo_builder_blt.h"
 #include "util/u_pack_color.h"
-#include "intel_reg.h"
 
-#include "ilo_3d.h"
 #include "ilo_context.h"
 #include "ilo_cp.h"
+#include "ilo_blit.h"
 #include "ilo_resource.h"
 #include "ilo_blitter.h"
 
-#ifndef COLOR_BLT_CMD
-#define COLOR_BLT_CMD (CMD_2D | (0x40 << 22))
-#endif
-
-#ifndef SRC_COPY_BLT_CMD
-#define SRC_COPY_BLT_CMD (CMD_2D | (0x43 << 22))
-#endif
-
-enum gen6_blt_mask {
-   GEN6_BLT_MASK_8,
-   GEN6_BLT_MASK_16,
-   GEN6_BLT_MASK_32,
-   GEN6_BLT_MASK_32_LO,
-   GEN6_BLT_MASK_32_HI,
-};
-
-/*
- * From the Sandy Bridge PRM, volume 1 part 5, page 7:
- *
- *     "The BLT engine is capable of transferring very large quantities of
- *      graphics data. Any graphics data read from and written to the
- *      destination is permitted to represent a number of pixels that occupies
- *      up to 65,536 scan lines and up to 32,768 bytes per scan line at the
- *      destination. The maximum number of pixels that may be represented per
- *      scan line's worth of graphics data depends on the color depth."
- */
-static const int gen6_max_bytes_per_scanline = 32768;
-static const int gen6_max_scanlines = 65536;
-
-static void
-gen6_emit_MI_FLUSH_DW(struct ilo_dev_info *dev, struct ilo_cp *cp)
-{
-   const uint8_t cmd_len = 4;
-
-   ilo_cp_begin(cp, cmd_len);
-   ilo_cp_write(cp, MI_FLUSH_DW | (cmd_len - 2));
-   ilo_cp_write(cp, 0);
-   ilo_cp_write(cp, 0);
-   ilo_cp_write(cp, 0);
-   ilo_cp_end(cp);
-}
-
-static void
-gen6_emit_MI_LOAD_REGISTER_IMM(struct ilo_dev_info *dev,
-                               uint32_t reg, uint32_t val,
-                               struct ilo_cp *cp)
-{
-   const uint8_t cmd_len = 3;
-
-   ilo_cp_begin(cp, cmd_len);
-   ilo_cp_write(cp, MI_LOAD_REGISTER_IMM | (cmd_len - 2));
-   ilo_cp_write(cp, reg);
-   ilo_cp_write(cp, val);
-   ilo_cp_end(cp);
-}
-
-static uint32_t
-gen6_translate_blt_value_mask(enum gen6_blt_mask value_mask)
-{
-   switch (value_mask) {
-   case GEN6_BLT_MASK_8:  return BR13_8;
-   case GEN6_BLT_MASK_16: return BR13_565;
-   default:               return BR13_8888;
-   }
-}
-
-static uint32_t
-gen6_translate_blt_write_mask(enum gen6_blt_mask write_mask)
-{
-   switch (write_mask) {
-   case GEN6_BLT_MASK_32:    return XY_BLT_WRITE_RGB |
-                                    XY_BLT_WRITE_ALPHA;
-   case GEN6_BLT_MASK_32_LO: return XY_BLT_WRITE_RGB;
-   case GEN6_BLT_MASK_32_HI: return XY_BLT_WRITE_ALPHA;
-   default:                  return 0;
-   }
-}
-
-static uint32_t
-gen6_translate_blt_cpp(enum gen6_blt_mask mask)
-{
-   switch (mask) {
-   case GEN6_BLT_MASK_8:  return 1;
-   case GEN6_BLT_MASK_16: return 2;
-   default:               return 4;
-   }
-}
-
-static void
-gen6_emit_COLOR_BLT(struct ilo_dev_info *dev,
-                    struct intel_bo *dst_bo,
-                    int16_t dst_pitch, uint32_t dst_offset,
-                    uint16_t width, uint16_t height,
-                    uint32_t pattern, uint8_t rop,
-                    enum gen6_blt_mask value_mask,
-                    enum gen6_blt_mask write_mask,
-                    struct ilo_cp *cp)
-{
-   const uint8_t cmd_len = 5;
-   const int cpp = gen6_translate_blt_cpp(value_mask);
-   uint32_t dw0, dw1;
-
-   dw0 = COLOR_BLT_CMD |
-         gen6_translate_blt_write_mask(write_mask) |
-         (cmd_len - 2);
-
-   assert(width < gen6_max_bytes_per_scanline);
-   assert(height < gen6_max_scanlines);
-   /* offsets are naturally aligned and pitches are dword-aligned */
-   assert(dst_offset % cpp == 0 && dst_pitch % 4 == 0);
-
-   dw1 = rop << 16 |
-         gen6_translate_blt_value_mask(value_mask) |
-         dst_pitch;
-
-   ilo_cp_begin(cp, cmd_len);
-   ilo_cp_write(cp, dw0);
-   ilo_cp_write(cp, dw1);
-   ilo_cp_write(cp, height << 16 | width);
-   ilo_cp_write_bo(cp, dst_offset, dst_bo, INTEL_DOMAIN_RENDER,
-                                           INTEL_DOMAIN_RENDER);
-   ilo_cp_write(cp, pattern);
-   ilo_cp_end(cp);
-}
-
-static void
-gen6_emit_XY_COLOR_BLT(struct ilo_dev_info *dev,
-                       struct intel_bo *dst_bo,
-                       enum intel_tiling_mode dst_tiling,
-                       int16_t dst_pitch, uint32_t dst_offset,
-                       int16_t x1, int16_t y1, int16_t x2, int16_t y2,
-                       uint32_t pattern, uint8_t rop,
-                       enum gen6_blt_mask value_mask,
-                       enum gen6_blt_mask write_mask,
-                       struct ilo_cp *cp)
-{
-   const uint8_t cmd_len = 6;
-   const int cpp = gen6_translate_blt_cpp(value_mask);
-   int dst_align, dst_pitch_shift;
-   uint32_t dw0, dw1;
-
-   dw0 = XY_COLOR_BLT_CMD |
-         gen6_translate_blt_write_mask(write_mask) |
-         (cmd_len - 2);
-
-   if (dst_tiling == INTEL_TILING_NONE) {
-      dst_align = 4;
-      dst_pitch_shift = 0;
-   }
-   else {
-      dw0 |= XY_DST_TILED;
-
-      dst_align = (dst_tiling == INTEL_TILING_Y) ? 128 : 512;
-      /* in dwords when tiled */
-      dst_pitch_shift = 2;
-   }
-
-   assert((x2 - x1) * cpp < gen6_max_bytes_per_scanline);
-   assert(y2 - y1 < gen6_max_scanlines);
-   assert(dst_offset % dst_align == 0 && dst_pitch % dst_align == 0);
-
-   dw1 = rop << 16 |
-         gen6_translate_blt_value_mask(value_mask) |
-         dst_pitch >> dst_pitch_shift;
-
-   ilo_cp_begin(cp, cmd_len);
-   ilo_cp_write(cp, dw0);
-   ilo_cp_write(cp, dw1);
-   ilo_cp_write(cp, y1 << 16 | x1);
-   ilo_cp_write(cp, y2 << 16 | x2);
-   ilo_cp_write_bo(cp, dst_offset, dst_bo,
-                   INTEL_DOMAIN_RENDER, INTEL_DOMAIN_RENDER);
-   ilo_cp_write(cp, pattern);
-   ilo_cp_end(cp);
-}
-
-static void
-gen6_emit_SRC_COPY_BLT(struct ilo_dev_info *dev,
-                       struct intel_bo *dst_bo,
-                       int16_t dst_pitch, uint32_t dst_offset,
-                       uint16_t width, uint16_t height,
-                       struct intel_bo *src_bo,
-                       int16_t src_pitch, uint32_t src_offset,
-                       bool dir_rtl, uint8_t rop,
-                       enum gen6_blt_mask value_mask,
-                       enum gen6_blt_mask write_mask,
-                       struct ilo_cp *cp)
-{
-   const uint8_t cmd_len = 6;
-   const int cpp = gen6_translate_blt_cpp(value_mask);
-   uint32_t dw0, dw1;
-
-   dw0 = SRC_COPY_BLT_CMD |
-         gen6_translate_blt_write_mask(write_mask) |
-         (cmd_len - 2);
-
-   assert(width < gen6_max_bytes_per_scanline);
-   assert(height < gen6_max_scanlines);
-   /* offsets are naturally aligned and pitches are dword-aligned */
-   assert(dst_offset % cpp == 0 && dst_pitch % 4 == 0);
-   assert(src_offset % cpp == 0 && src_pitch % 4 == 0);
-
-   dw1 = rop << 16 |
-         gen6_translate_blt_value_mask(value_mask) |
-         dst_pitch;
-
-   if (dir_rtl)
-      dw1 |= 1 << 30;
-
-   ilo_cp_begin(cp, cmd_len);
-   ilo_cp_write(cp, dw0);
-   ilo_cp_write(cp, dw1);
-   ilo_cp_write(cp, height << 16 | width);
-   ilo_cp_write_bo(cp, dst_offset, dst_bo, INTEL_DOMAIN_RENDER,
-                                           INTEL_DOMAIN_RENDER);
-   ilo_cp_write(cp, src_pitch);
-   ilo_cp_write_bo(cp, src_offset, src_bo, INTEL_DOMAIN_RENDER, 0);
-   ilo_cp_end(cp);
-}
-
-static void
-gen6_emit_XY_SRC_COPY_BLT(struct ilo_dev_info *dev,
-                          struct intel_bo *dst_bo,
-                          enum intel_tiling_mode dst_tiling,
-                          int16_t dst_pitch, uint32_t dst_offset,
-                          int16_t x1, int16_t y1, int16_t x2, int16_t y2,
-                          struct intel_bo *src_bo,
-                          enum intel_tiling_mode src_tiling,
-                          int16_t src_pitch, uint32_t src_offset,
-                          int16_t src_x, int16_t src_y, uint8_t rop,
-                          enum gen6_blt_mask value_mask,
-                          enum gen6_blt_mask write_mask,
-                          struct ilo_cp *cp)
-{
-   const uint8_t cmd_len = 8;
-   const int cpp = gen6_translate_blt_cpp(value_mask);
-   int dst_align, dst_pitch_shift;
-   int src_align, src_pitch_shift;
-   uint32_t dw0, dw1;
-
-   dw0 = XY_SRC_COPY_BLT_CMD |
-         gen6_translate_blt_write_mask(write_mask) |
-         (cmd_len - 2);
-
-   if (dst_tiling == INTEL_TILING_NONE) {
-      dst_align = 4;
-      dst_pitch_shift = 0;
-   }
-   else {
-      dw0 |= XY_DST_TILED;
-
-      dst_align = (dst_tiling == INTEL_TILING_Y) ? 128 : 512;
-      /* in dwords when tiled */
-      dst_pitch_shift = 2;
-   }
-
-   if (src_tiling == INTEL_TILING_NONE) {
-      src_align = 4;
-      src_pitch_shift = 0;
-   }
-   else {
-      dw0 |= XY_SRC_TILED;
-
-      src_align = (src_tiling == INTEL_TILING_Y) ? 128 : 512;
-      /* in dwords when tiled */
-      src_pitch_shift = 2;
-   }
-
-   assert((x2 - x1) * cpp < gen6_max_bytes_per_scanline);
-   assert(y2 - y1 < gen6_max_scanlines);
-   assert(dst_offset % dst_align == 0 && dst_pitch % dst_align == 0);
-   assert(src_offset % src_align == 0 && src_pitch % src_align == 0);
-
-   dw1 = rop << 16 |
-         gen6_translate_blt_value_mask(value_mask) |
-         dst_pitch >> dst_pitch_shift;
-
-   ilo_cp_begin(cp, cmd_len);
-   ilo_cp_write(cp, dw0);
-   ilo_cp_write(cp, dw1);
-   ilo_cp_write(cp, y1 << 16 | x1);
-   ilo_cp_write(cp, y2 << 16 | x2);
-   ilo_cp_write_bo(cp, dst_offset, dst_bo, INTEL_DOMAIN_RENDER,
-                                           INTEL_DOMAIN_RENDER);
-   ilo_cp_write(cp, src_y << 16 | src_x);
-   ilo_cp_write(cp, src_pitch >> src_pitch_shift);
-   ilo_cp_write_bo(cp, src_offset, src_bo, INTEL_DOMAIN_RENDER, 0);
-   ilo_cp_end(cp);
-}
-
 static uint32_t
 ilo_blitter_blt_begin(struct ilo_blitter *blitter, int max_cmd_size,
-                      struct intel_bo *dst, enum intel_tiling_mode dst_tiling,
-                      struct intel_bo *src, enum intel_tiling_mode src_tiling)
+                      struct intel_bo *dst,
+                      enum gen_surface_tiling dst_tiling,
+                      struct intel_bo *src,
+                      enum gen_surface_tiling src_tiling)
 {
-   struct ilo_context *ilo = blitter->ilo;
-   struct intel_bo *aper_check[3];
+   struct ilo_cp *cp = blitter->ilo->cp;
+   struct intel_bo *aper_check[2];
    int count;
    uint32_t swctrl;
 
-   /* change ring */
-   ilo_cp_set_ring(ilo->cp, ILO_CP_RING_BLT);
-   ilo_cp_set_owner(ilo->cp, NULL, 0);
+   /* change owner */
+   ilo_cp_set_owner(cp, INTEL_RING_BLT, NULL);
 
    /* check aperture space */
-   aper_check[0] = ilo->cp->bo;
-   aper_check[1] = dst;
-   count = 2;
+   aper_check[0] = dst;
+   count = 1;
 
    if (src) {
-      aper_check[2] = src;
+      aper_check[1] = src;
       count++;
    }
 
-   if (intel_winsys_check_aperture_space(ilo->winsys, aper_check, count))
-      ilo_cp_flush(ilo->cp, "out of aperture");
+   if (!ilo_builder_validate(&cp->builder, count, aper_check))
+      ilo_cp_submit(cp, "out of aperture");
 
    /* set BCS_SWCTRL */
    swctrl = 0x0;
 
-   if (dst_tiling == INTEL_TILING_Y) {
-      swctrl |= BCS_SWCTRL_DST_Y << 16 |
-                BCS_SWCTRL_DST_Y;
-   }
+   assert(dst_tiling == GEN6_TILING_NONE ||
+          dst_tiling == GEN6_TILING_X ||
+          dst_tiling == GEN6_TILING_Y);
+   assert(src_tiling == GEN6_TILING_NONE ||
+          src_tiling == GEN6_TILING_X ||
+          src_tiling == GEN6_TILING_Y);
 
-   if (src && src_tiling == INTEL_TILING_Y) {
-      swctrl |= BCS_SWCTRL_SRC_Y << 16 |
-                BCS_SWCTRL_SRC_Y;
+   if (dst_tiling == GEN6_TILING_Y) {
+      swctrl |= GEN6_REG_BCS_SWCTRL_DST_TILING_Y << 16 |
+                GEN6_REG_BCS_SWCTRL_DST_TILING_Y;
    }
 
-   if (swctrl) {
-      /*
-       * Most clients expect BLT engine to be stateless.  If we have to set
-       * BCS_SWCTRL to a non-default value, we have to set it back in the same
-       * batch buffer.
-       */
-      if (ilo_cp_space(ilo->cp) < (4 + 3) * 2 + max_cmd_size)
-         ilo_cp_flush(ilo->cp, "out of space");
+   if (src && src_tiling == GEN6_TILING_Y) {
+      swctrl |= GEN6_REG_BCS_SWCTRL_SRC_TILING_Y << 16 |
+                GEN6_REG_BCS_SWCTRL_SRC_TILING_Y;
+   }
 
-      ilo_cp_assert_no_implicit_flush(ilo->cp, true);
+   /*
+    * Most clients expect BLT engine to be stateless.  If we have to set
+    * BCS_SWCTRL to a non-default value, we have to set it back in the same
+    * batch buffer.
+    */
+   if (swctrl)
+      max_cmd_size += (4 + 3) * 2;
+
+   if (ilo_cp_space(cp) < max_cmd_size) {
+      ilo_cp_submit(cp, "out of space");
+      assert(ilo_cp_space(cp) >= max_cmd_size);
+   }
 
+   if (swctrl) {
       /*
        * From the Ivy Bridge PRM, volume 1 part 4, page 133:
        *
        *     "SW is required to flush the HW before changing the polarity of
        *      this bit (Tile Y Destination/Source)."
        */
-      gen6_emit_MI_FLUSH_DW(ilo->dev, ilo->cp);
-      gen6_emit_MI_LOAD_REGISTER_IMM(ilo->dev, BCS_SWCTRL, swctrl, ilo->cp);
+      gen6_MI_FLUSH_DW(&cp->builder);
+      gen6_MI_LOAD_REGISTER_IMM(&cp->builder, GEN6_REG_BCS_SWCTRL, swctrl);
 
-      swctrl &= ~(BCS_SWCTRL_DST_Y | BCS_SWCTRL_SRC_Y);
+      swctrl &= ~(GEN6_REG_BCS_SWCTRL_DST_TILING_Y |
+                  GEN6_REG_BCS_SWCTRL_SRC_TILING_Y);
    }
 
    return swctrl;
@@ -393,59 +116,60 @@ ilo_blitter_blt_begin(struct ilo_blitter *blitter, int max_cmd_size,
 static void
 ilo_blitter_blt_end(struct ilo_blitter *blitter, uint32_t swctrl)
 {
-   struct ilo_context *ilo = blitter->ilo;
+   struct ilo_builder *builder = &blitter->ilo->cp->builder;
 
    /* set BCS_SWCTRL back */
    if (swctrl) {
-      gen6_emit_MI_FLUSH_DW(ilo->dev, ilo->cp);
-      gen6_emit_MI_LOAD_REGISTER_IMM(ilo->dev, BCS_SWCTRL, swctrl, ilo->cp);
-
-      ilo_cp_assert_no_implicit_flush(ilo->cp, false);
+      gen6_MI_FLUSH_DW(builder);
+      gen6_MI_LOAD_REGISTER_IMM(builder, GEN6_REG_BCS_SWCTRL, swctrl);
    }
 }
 
 static bool
 buf_clear_region(struct ilo_blitter *blitter,
-                 struct ilo_buffer *dst,
-                 unsigned dst_offset, unsigned dst_size,
-                 uint32_t val,
+                 struct ilo_buffer_resource *buf, unsigned offset,
+                 uint32_t val, unsigned size,
                  enum gen6_blt_mask value_mask,
                  enum gen6_blt_mask write_mask)
 {
    const uint8_t rop = 0xf0; /* PATCOPY */
-   const int cpp = gen6_translate_blt_cpp(value_mask);
-   struct ilo_context *ilo = blitter->ilo;
-   unsigned offset = 0;
+   const int cpp = gen6_blt_translate_value_cpp(value_mask);
+   struct ilo_builder *builder = &blitter->ilo->cp->builder;
+   struct gen6_blt_bo dst;
 
-   if (dst_offset % cpp || dst_size % cpp)
+   if (offset % cpp || size % cpp)
       return false;
 
-   ilo_blitter_blt_begin(blitter, 0,
-         dst->bo, INTEL_TILING_NONE, NULL, INTEL_TILING_NONE);
+   dst.bo = buf->vma.bo;
+   dst.offset = buf->vma.bo_offset + offset;
+
+   ilo_blitter_blt_begin(blitter, GEN6_COLOR_BLT__SIZE *
+         (1 + size / 32764 / gen6_blt_max_scanlines),
+         dst.bo, GEN6_TILING_NONE, NULL, GEN6_TILING_NONE);
 
-   while (dst_size) {
+   while (size) {
       unsigned width, height;
-      int16_t pitch;
 
-      width = dst_size;
+      width = size;
       height = 1;
-      pitch = 0;
 
-      if (width > gen6_max_bytes_per_scanline) {
+      if (width > gen6_blt_max_bytes_per_scanline) {
          /* less than INT16_MAX and dword-aligned */
-         pitch = 32764;
+         width = 32764;
+         height = size / width;
+         if (height > gen6_blt_max_scanlines)
+            height = gen6_blt_max_scanlines;
 
-         width = pitch;
-         height = dst_size / width;
-         if (height > gen6_max_scanlines)
-            height = gen6_max_scanlines;
+         dst.pitch = width;
+      } else {
+         dst.pitch = 0;
       }
 
-      gen6_emit_COLOR_BLT(ilo->dev, dst->bo, pitch, dst_offset + offset,
-            width, height, val, rop, value_mask, write_mask, ilo->cp);
+      gen6_COLOR_BLT(builder, &dst, val,
+            width, height, rop, value_mask, write_mask);
 
-      offset += pitch * height;
-      dst_size -= width * height;
+      dst.offset += dst.pitch * height;
+      size -= width * height;
    }
 
    ilo_blitter_blt_end(blitter, 0);
@@ -455,43 +179,52 @@ buf_clear_region(struct ilo_blitter *blitter,
 
 static bool
 buf_copy_region(struct ilo_blitter *blitter,
-                struct ilo_buffer *dst, unsigned dst_offset,
-                struct ilo_buffer *src, unsigned src_offset,
+                struct ilo_buffer_resource *dst_buf, unsigned dst_offset,
+                struct ilo_buffer_resource *src_buf, unsigned src_offset,
                 unsigned size)
 {
    const uint8_t rop = 0xcc; /* SRCCOPY */
-   struct ilo_context *ilo = blitter->ilo;
-   unsigned offset = 0;
+   struct ilo_builder *builder = &blitter->ilo->cp->builder;
+   struct gen6_blt_bo dst, src;
+
+   dst.bo = dst_buf->vma.bo;
+   dst.offset = dst_buf->vma.bo_offset + dst_offset;
+   dst.pitch = 0;
+
+   src.bo = src_buf->vma.bo;
+   src.offset = src_buf->vma.bo_offset + src_offset;
+   src.pitch = 0;
 
-   ilo_blitter_blt_begin(blitter, 0,
-         dst->bo, INTEL_TILING_NONE, src->bo, INTEL_TILING_NONE);
+   ilo_blitter_blt_begin(blitter, GEN6_SRC_COPY_BLT__SIZE *
+         (1 + size / 32764 / gen6_blt_max_scanlines),
+         dst_buf->vma.bo, GEN6_TILING_NONE,
+         src_buf->vma.bo, GEN6_TILING_NONE);
 
    while (size) {
       unsigned width, height;
-      int16_t pitch;
 
       width = size;
       height = 1;
-      pitch = 0;
 
-      if (width > gen6_max_bytes_per_scanline) {
+      if (width > gen6_blt_max_bytes_per_scanline) {
          /* less than INT16_MAX and dword-aligned */
-         pitch = 32764;
-
-         width = pitch;
+         width = 32764;
          height = size / width;
-         if (height > gen6_max_scanlines)
-            height = gen6_max_scanlines;
+         if (height > gen6_blt_max_scanlines)
+            height = gen6_blt_max_scanlines;
+
+         dst.pitch = width;
+         src.pitch = width;
+      } else {
+         dst.pitch = 0;
+         src.pitch = 0;
       }
 
-      gen6_emit_SRC_COPY_BLT(ilo->dev,
-            dst->bo, pitch, dst_offset + offset,
-            width, height,
-            src->bo, pitch, src_offset + offset,
-            false, rop, GEN6_BLT_MASK_8, GEN6_BLT_MASK_8,
-            ilo->cp);
+      gen6_SRC_COPY_BLT(builder, &dst, &src,
+            width, height, rop, GEN6_BLT_MASK_8, GEN6_BLT_MASK_8);
 
-      offset += pitch * height;
+      dst.offset += dst.pitch * height;
+      src.offset += src.pitch * height;
       size -= width * height;
    }
 
@@ -502,47 +235,54 @@ buf_copy_region(struct ilo_blitter *blitter,
 
 static bool
 tex_clear_region(struct ilo_blitter *blitter,
-                 struct ilo_texture *dst, unsigned dst_level,
+                 struct ilo_texture *dst_tex, unsigned dst_level,
                  const struct pipe_box *dst_box,
                  uint32_t val,
                  enum gen6_blt_mask value_mask,
                  enum gen6_blt_mask write_mask)
 {
-   const int cpp = gen6_translate_blt_cpp(value_mask);
+   const int cpp = gen6_blt_translate_value_cpp(value_mask);
    const unsigned max_extent = 32767; /* INT16_MAX */
    const uint8_t rop = 0xf0; /* PATCOPY */
-   struct ilo_context *ilo = blitter->ilo;
+   struct ilo_builder *builder = &blitter->ilo->cp->builder;
+   struct gen6_blt_xy_bo dst;
    uint32_t swctrl;
    int slice;
 
-   /* no W-tiling support */
-   if (dst->separate_s8)
+   /* no W-tiling nor separate stencil support */
+   if (dst_tex->image.tiling == GEN8_TILING_W || dst_tex->separate_s8)
+      return false;
+
+   if (dst_tex->image.bo_stride > max_extent)
       return false;
 
-   if (dst->bo_stride > max_extent)
+   if (dst_box->width * cpp > gen6_blt_max_bytes_per_scanline)
       return false;
 
-   swctrl = ilo_blitter_blt_begin(blitter, dst_box->depth * 6,
-         dst->bo, dst->tiling, NULL, INTEL_TILING_NONE);
+   dst.bo = dst_tex->vma.bo;
+   dst.offset = dst_tex->vma.bo_offset;
+   dst.pitch = dst_tex->image.bo_stride;
+   dst.tiling = dst_tex->image.tiling;
+
+   swctrl = ilo_blitter_blt_begin(blitter,
+         GEN6_XY_COLOR_BLT__SIZE * dst_box->depth,
+         dst_tex->vma.bo, dst_tex->image.tiling, NULL, GEN6_TILING_NONE);
 
    for (slice = 0; slice < dst_box->depth; slice++) {
-      const struct ilo_texture_slice *dst_slice =
-         &dst->slice_offsets[dst_level][dst_box->z + slice];
-      unsigned x1, y1, x2, y2;
+      unsigned x, y;
+
+      ilo_image_get_slice_pos(&dst_tex->image,
+            dst_level, dst_box->z + slice, &x, &y);
 
-      x1 = dst_slice->x + dst_box->x;
-      y1 = dst_slice->y + dst_box->y;
-      x2 = x1 + dst_box->width;
-      y2 = y1 + dst_box->height;
+      dst.x = x + dst_box->x;
+      dst.y = y + dst_box->y;
 
-      if (x2 > max_extent || y2 > max_extent ||
-          (x2 - x1) * cpp > gen6_max_bytes_per_scanline)
+      if (dst.x + dst_box->width > max_extent ||
+          dst.y + dst_box->height > max_extent)
          break;
 
-      gen6_emit_XY_COLOR_BLT(ilo->dev,
-            dst->bo, dst->tiling, dst->bo_stride, 0,
-            x1, y1, x2, y2, val, rop, value_mask, write_mask,
-            ilo->cp);
+      gen6_XY_COLOR_BLT(builder, &dst, val,
+            dst_box->width, dst_box->height, rop, value_mask, write_mask);
    }
 
    ilo_blitter_blt_end(blitter, swctrl);
@@ -552,27 +292,30 @@ tex_clear_region(struct ilo_blitter *blitter,
 
 static bool
 tex_copy_region(struct ilo_blitter *blitter,
-                struct ilo_texture *dst,
+                struct ilo_texture *dst_tex,
                 unsigned dst_level,
                 unsigned dst_x, unsigned dst_y, unsigned dst_z,
-                struct ilo_texture *src,
+                struct ilo_texture *src_tex,
                 unsigned src_level,
                 const struct pipe_box *src_box)
 {
    const struct util_format_description *desc =
-      util_format_description(dst->bo_format);
+      util_format_description(dst_tex->image_format);
    const unsigned max_extent = 32767; /* INT16_MAX */
    const uint8_t rop = 0xcc; /* SRCCOPY */
-   struct ilo_context *ilo = blitter->ilo;
+   struct ilo_builder *builder = &blitter->ilo->cp->builder;
    enum gen6_blt_mask mask;
+   struct gen6_blt_xy_bo dst, src;
    uint32_t swctrl;
    int cpp, xscale, slice;
 
-   /* no W-tiling support */
-   if (dst->separate_s8 || src->separate_s8)
+   /* no W-tiling nor separate stencil support */
+   if (dst_tex->image.tiling == GEN8_TILING_W || dst_tex->separate_s8 ||
+       src_tex->image.tiling == GEN8_TILING_W || src_tex->separate_s8)
       return false;
 
-   if (dst->bo_stride > max_extent || src->bo_stride > max_extent)
+   if (dst_tex->image.bo_stride > max_extent ||
+       src_tex->image.bo_stride > max_extent)
       return false;
 
    cpp = desc->block.bits / 8;
@@ -587,6 +330,9 @@ tex_copy_region(struct ilo_blitter *blitter,
       xscale = (desc->block.bits / 8) / cpp;
    }
 
+   if (src_box->width * cpp * xscale > gen6_blt_max_bytes_per_scanline)
+      return false;
+
    switch (cpp) {
    case 1:
       mask = GEN6_BLT_MASK_8;
@@ -602,42 +348,49 @@ tex_copy_region(struct ilo_blitter *blitter,
       break;
    }
 
-   swctrl = ilo_blitter_blt_begin(blitter, src_box->depth * 8,
-         dst->bo, dst->tiling, src->bo, src->tiling);
+   dst.bo = dst_tex->vma.bo;
+   dst.offset = dst_tex->vma.bo_offset;
+   dst.pitch = dst_tex->image.bo_stride;
+   dst.tiling = dst_tex->image.tiling;
+
+   src.bo = src_tex->vma.bo;
+   src.offset = src_tex->vma.bo_offset;
+   src.pitch = src_tex->image.bo_stride;
+   src.tiling = src_tex->image.tiling;
+
+   swctrl = ilo_blitter_blt_begin(blitter,
+         GEN6_XY_SRC_COPY_BLT__SIZE * src_box->depth,
+         dst.bo, dst.tiling, src.bo, src.tiling);
 
    for (slice = 0; slice < src_box->depth; slice++) {
-      const struct ilo_texture_slice *dst_slice =
-         &dst->slice_offsets[dst_level][dst_z + slice];
-      const struct ilo_texture_slice *src_slice =
-         &src->slice_offsets[src_level][src_box->z + slice];
-      unsigned x1, y1, x2, y2, src_x, src_y;
-
-      x1 = (dst_slice->x + dst_x) * xscale;
-      y1 = dst_slice->y + dst_y;
-      x2 = (x1 + src_box->width) * xscale;
-      y2 = y1 + src_box->height;
-      src_x = (src_slice->x + src_box->x) * xscale;
-      src_y = src_slice->y + src_box->y;
+      unsigned dx, dy, sx, sy, width, height;
+
+      ilo_image_get_slice_pos(&dst_tex->image,
+            dst_level, dst_z + slice, &dx, &dy);
+      ilo_image_get_slice_pos(&src_tex->image,
+            src_level, src_box->z + slice, &sx, &sy);
+
+      dst.x = (dx + dst_x) * xscale;
+      dst.y = dy + dst_y;
+      src.x = (sx + src_box->x) * xscale;
+      src.y = sy + src_box->y;
+      width = src_box->width * xscale;
+      height = src_box->height;
 
       /* in blocks */
-      x1 /= desc->block.width;
-      y1 /= desc->block.height;
-      x2 = (x2 + desc->block.width - 1) / desc->block.width;
-      y2 = (y2 + desc->block.height - 1) / desc->block.height;
-      src_x /= desc->block.width;
-      src_y /= desc->block.height;
-
-      if (x2 > max_extent || y2 > max_extent ||
-          src_x > max_extent || src_y > max_extent ||
-          (x2 - x1) * cpp > gen6_max_bytes_per_scanline)
+      dst.x /= desc->block.width;
+      dst.y /= desc->block.height;
+      src.x /= desc->block.width;
+      src.y /= desc->block.height;
+      width /= desc->block.width;
+      height /= desc->block.height;
+
+      if (src.x + width > max_extent || src.y + height > max_extent ||
+          dst.x + width > max_extent || dst.y + height > max_extent)
          break;
 
-      gen6_emit_XY_SRC_COPY_BLT(ilo->dev,
-            dst->bo, dst->tiling, dst->bo_stride, 0,
-            x1, y1, x2, y2,
-            src->bo, src->tiling, src->bo_stride, 0,
-            src_x, src_y, rop, mask, mask,
-            ilo->cp);
+      gen6_XY_SRC_COPY_BLT(builder, &dst, &src,
+            width, height, rop, mask, mask);
    }
 
    ilo_blitter_blt_end(blitter, swctrl);
@@ -654,6 +407,11 @@ ilo_blitter_blt_copy_resource(struct ilo_blitter *blitter,
 {
    bool success;
 
+   ilo_blit_resolve_slices(blitter->ilo, src, src_level,
+         src_box->z, src_box->depth, ILO_TEXTURE_BLT_READ);
+   ilo_blit_resolve_slices(blitter->ilo, dst, dst_level,
+         dst_z, src_box->depth, ILO_TEXTURE_BLT_WRITE);
+
    if (dst->target == PIPE_BUFFER && src->target == PIPE_BUFFER) {
       const unsigned dst_offset = dst_x;
       const unsigned src_offset = src_box->x;
@@ -666,8 +424,8 @@ ilo_blitter_blt_copy_resource(struct ilo_blitter *blitter,
              src_box->height == 1 &&
              src_box->depth == 1);
 
-      success = buf_copy_region(blitter,
-            ilo_buffer(dst), dst_offset, ilo_buffer(src), src_offset, size);
+      success = buf_copy_region(blitter, ilo_buffer_resource(dst), dst_offset,
+            ilo_buffer_resource(src), src_offset, size);
    }
    else if (dst->target != PIPE_BUFFER && src->target != PIPE_BUFFER) {
       success = tex_copy_region(blitter,
@@ -693,7 +451,7 @@ ilo_blitter_blt_clear_rt(struct ilo_blitter *blitter,
    union util_color packed;
    bool success;
 
-   if (!ilo_3d_pass_render_condition(blitter->ilo))
+   if (ilo_skip_rendering(blitter->ilo))
       return true;
 
    switch (cpp) {
@@ -715,6 +473,8 @@ ilo_blitter_blt_clear_rt(struct ilo_blitter *blitter,
        util_format_is_compressed(rt->format))
       return false;
 
+   ilo_blit_resolve_surface(blitter->ilo, rt, ILO_TEXTURE_BLT_WRITE);
+
    util_pack_color(color->f, rt->format, &packed);
 
    if (rt->texture->target == PIPE_BUFFER) {
@@ -729,8 +489,8 @@ ilo_blitter_blt_clear_rt(struct ilo_blitter *blitter,
       if (offset + size > end)
          size = end - offset;
 
-      success = buf_clear_region(blitter, ilo_buffer(rt->texture),
-            offset, size, packed.ui, mask, mask);
+      success = buf_clear_region(blitter, ilo_buffer_resource(rt->texture),
+            offset, packed.ui[0], size, mask, mask);
    }
    else {
       struct pipe_box box;
@@ -739,7 +499,7 @@ ilo_blitter_blt_clear_rt(struct ilo_blitter *blitter,
             rt->u.tex.last_layer - rt->u.tex.first_layer + 1, &box);
 
       success = tex_clear_region(blitter, ilo_texture(rt->texture),
-            rt->u.tex.level, &box, packed.ui, mask, mask);
+            rt->u.tex.level, &box, packed.ui[0], mask, mask);
    }
 
    return success;
@@ -757,7 +517,7 @@ ilo_blitter_blt_clear_zs(struct ilo_blitter *blitter,
    struct pipe_box box;
    uint32_t val;
 
-   if (!ilo_3d_pass_render_condition(blitter->ilo))
+   if (ilo_skip_rendering(blitter->ilo))
       return true;
 
    switch (zs->format) {
@@ -800,6 +560,8 @@ ilo_blitter_blt_clear_zs(struct ilo_blitter *blitter,
       break;
    }
 
+   ilo_blit_resolve_surface(blitter->ilo, zs, ILO_TEXTURE_BLT_WRITE);
+
    val = util_pack_z_stencil(zs->format, depth, stencil);
 
    u_box_3d(x, y, zs->u.tex.first_layer, width, height,