/*
 * Copyright 2012 Red Hat Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 * Authors: Ben Skeggs
 *
 */

#define XFER_ARGS                                                              \
   struct nv30_context *nv30, enum nv30_transfer_filter filter,                \
   struct nv30_rect *src, struct nv30_rect *dst

#include "util/u_math.h"

#include "nouveau/nv_object.xml.h"
#include "nouveau/nv_m2mf.xml.h"
#include "nv01_2d.xml.h"
#include "nv30-40_3d.xml.h"

#include "nv30_context.h"
#include "nv30_transfer.h"

/* Various helper functions to transfer different types of data in a number
 * of different ways.
 */

static INLINE boolean
nv30_transfer_scaled(struct nv30_rect *src, struct nv30_rect *dst)
{
   if (src->x1 - src->x0 != dst->x1 - dst->x0)
      return TRUE;
   if (src->y1 - src->y0 != dst->y1 - dst->y0)
      return TRUE;
   return FALSE;
}

static INLINE boolean
nv30_transfer_blit(XFER_ARGS)
{
   if (nv30->screen->eng3d->oclass < NV40_3D_CLASS)
      return FALSE;
   if (dst->offset & 63 || dst->pitch & 63 || dst->d > 1)
      return FALSE;
   if (dst->w < 2 || dst->h < 2)
      return FALSE;
   if (dst->cpp > 4 || (dst->cpp == 1 && !dst->pitch))
      return FALSE;
   if (src->cpp > 4)
      return FALSE;
   return TRUE;
}

static INLINE struct nouveau_heap *
nv30_transfer_rect_vertprog(struct nv30_context *nv30)
{
   struct nouveau_heap *heap = nv30->screen->vp_exec_heap;
   struct nouveau_heap *vp;

   vp = nv30->blit_vp;
   if (!vp) {
      if (nouveau_heap_alloc(heap, 2, &nv30->blit_vp, &nv30->blit_vp)) {
         while (heap->next && heap->size < 2) {
            struct nouveau_heap **evict = heap->next->priv;
            nouveau_heap_free(evict);
         }

         if (nouveau_heap_alloc(heap, 2, &nv30->blit_vp, &nv30->blit_vp))
            return NULL;
      }

      vp = nv30->blit_vp;
      if (vp) {
         struct nouveau_pushbuf *push = nv30->base.pushbuf;

         BEGIN_NV04(push, NV30_3D(VP_UPLOAD_FROM_ID), 1);
         PUSH_DATA (push, vp->start);
         BEGIN_NV04(push, NV30_3D(VP_UPLOAD_INST(0)), 4);
         PUSH_DATA (push, 0x401f9c6c); /* mov o[hpos], a[0]; */
         PUSH_DATA (push, 0x0040000d);
         PUSH_DATA (push, 0x8106c083);
         PUSH_DATA (push, 0x6041ff80);
         BEGIN_NV04(push, NV30_3D(VP_UPLOAD_INST(0)), 4);
         PUSH_DATA (push, 0x401f9c6c); /* mov o[tex0], a[8]; end; */
         PUSH_DATA (push, 0x0040080d);
         PUSH_DATA (push, 0x8106c083);
         PUSH_DATA (push, 0x6041ff9d);
      }
   }

   return vp;
}


static INLINE struct nv04_resource *
nv30_transfer_rect_fragprog(struct nv30_context *nv30)
{
   struct nv04_resource *fp = nv04_resource(nv30->blit_fp);
   struct pipe_context *pipe = &nv30->base.pipe;

   if (!fp) {
      nv30->blit_fp = pipe_buffer_create(pipe->screen, 0, 0, 12 * 4);
      if (nv30->blit_fp) {
         struct pipe_transfer *transfer;
         u32 *map = pipe_buffer_map(pipe, nv30->blit_fp,
                                    PIPE_TRANSFER_WRITE, &transfer);
         if (map) {
            map[0] = 0x17009e00; /* texr r0, i[tex0], texture[0]; end; */
            map[1] = 0x1c9dc801;
            map[2] = 0x0001c800;
            map[3] = 0x3fe1c800;
            map[4] = 0x01401e81; /* end; */
            map[5] = 0x1c9dc800;
            map[6] = 0x0001c800;
            map[7] = 0x0001c800;
            pipe_buffer_unmap(pipe, transfer);
         }

         fp = nv04_resource(nv30->blit_fp);
         nouveau_buffer_migrate(&nv30->base, fp, NOUVEAU_BO_VRAM);
      }
   }

   return fp;
}

static void
nv30_transfer_rect_blit(XFER_ARGS)
{
   struct nv04_resource *fp = nv30_transfer_rect_fragprog(nv30);
   struct nouveau_heap *vp = nv30_transfer_rect_vertprog(nv30);
   struct nouveau_pushbuf *push = nv30->base.pushbuf;
   struct nouveau_pushbuf_refn refs[] = {
      { fp->bo, fp->domain | NOUVEAU_BO_RD },
      { src->bo, src->domain | NOUVEAU_BO_RD },
      { dst->bo, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR },
   };
   u32 texfmt, texswz;
   u32 format, stride;

   if (nouveau_pushbuf_space(push, 512, 8, 0) ||
       nouveau_pushbuf_refn (push, refs, sizeof(refs) / sizeof(refs[0])))
      return;

   /* various switches depending on cpp of the transfer */
   switch (dst->cpp) {
   case 4:
      format = NV30_3D_RT_FORMAT_COLOR_A8R8G8B8 |
               NV30_3D_RT_FORMAT_ZETA_Z24S8;
      texfmt = NV40_3D_TEX_FORMAT_FORMAT_A8R8G8B8;
      texswz = 0x0000aae4;
      break;
   case 2:
      format = NV30_3D_RT_FORMAT_COLOR_R5G6B5 |
               NV30_3D_RT_FORMAT_ZETA_Z16;
      texfmt = NV40_3D_TEX_FORMAT_FORMAT_R5G6B5;
      texswz = 0x0000a9e4;
      break;
   case 1:
      format = NV30_3D_RT_FORMAT_COLOR_B8 |
               NV30_3D_RT_FORMAT_ZETA_Z16;
      texfmt = NV40_3D_TEX_FORMAT_FORMAT_L8;
      texswz = 0x0000aaff;
      break;
   default:
      assert(0);
      return;
   }

   /* render target */
   if (!dst->pitch) {
      format |= NV30_3D_RT_FORMAT_TYPE_SWIZZLED;
      format |= util_logbase2(dst->w) << 16;
      format |= util_logbase2(dst->h) << 24;
      stride  = 64;
   } else {
      format |= NV30_3D_RT_FORMAT_TYPE_LINEAR;
      stride  = dst->pitch;
   }

   BEGIN_NV04(push, NV30_3D(VIEWPORT_HORIZ), 2);
   PUSH_DATA (push, dst->w << 16);
   PUSH_DATA (push, dst->h << 16);
   BEGIN_NV04(push, NV30_3D(RT_HORIZ), 5);
   PUSH_DATA (push, dst->w << 16);
   PUSH_DATA (push, dst->h << 16);
   PUSH_DATA (push, format);
   PUSH_DATA (push, stride);
   PUSH_RELOC(push, dst->bo, dst->offset, NOUVEAU_BO_LOW, 0, 0);
   BEGIN_NV04(push, NV30_3D(RT_ENABLE), 1);
   PUSH_DATA (push, NV30_3D_RT_ENABLE_COLOR0);

   nv30->dirty |= NV30_NEW_FRAMEBUFFER;

   /* viewport state */
   BEGIN_NV04(push, NV30_3D(VIEWPORT_TRANSLATE_X), 8);
   PUSH_DATAf(push, 0.0);
   PUSH_DATAf(push, 0.0);
   PUSH_DATAf(push, 0.0);
   PUSH_DATAf(push, 0.0);
   PUSH_DATAf(push, 1.0);
   PUSH_DATAf(push, 1.0);
   PUSH_DATAf(push, 1.0);
   PUSH_DATAf(push, 1.0);
   BEGIN_NV04(push, NV30_3D(DEPTH_RANGE_NEAR), 2);
   PUSH_DATAf(push, 0.0);
   PUSH_DATAf(push, 1.0);

   nv30->dirty |= NV30_NEW_VIEWPORT;

   /* blend state */
   BEGIN_NV04(push, NV30_3D(COLOR_LOGIC_OP_ENABLE), 1);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, NV30_3D(DITHER_ENABLE), 1);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, NV30_3D(BLEND_FUNC_ENABLE), 1);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, NV30_3D(COLOR_MASK), 1);
   PUSH_DATA (push, 0x01010101);

   nv30->dirty |= NV30_NEW_BLEND;

   /* depth-stencil-alpha state */
   BEGIN_NV04(push, NV30_3D(DEPTH_WRITE_ENABLE), 2);
   PUSH_DATA (push, 0);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, NV30_3D(STENCIL_ENABLE(0)), 1);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, NV30_3D(STENCIL_ENABLE(1)), 1);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, NV30_3D(ALPHA_FUNC_ENABLE), 1);
   PUSH_DATA (push, 0);

   nv30->dirty |= NV30_NEW_ZSA;

   /* rasterizer state */
   BEGIN_NV04(push, NV30_3D(SHADE_MODEL), 1);
   PUSH_DATA (push, NV30_3D_SHADE_MODEL_FLAT);
   BEGIN_NV04(push, NV30_3D(CULL_FACE_ENABLE), 1);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, NV30_3D(POLYGON_MODE_FRONT), 2);
   PUSH_DATA (push, NV30_3D_POLYGON_MODE_FRONT_FILL);
   PUSH_DATA (push, NV30_3D_POLYGON_MODE_BACK_FILL);
   BEGIN_NV04(push, NV30_3D(POLYGON_OFFSET_FILL_ENABLE), 1);
   PUSH_DATA (push, 0);
   BEGIN_NV04(push, NV30_3D(POLYGON_STIPPLE_ENABLE), 1);
   PUSH_DATA (push, 0);

   nv30->state.scissor_off = 0;
   nv30->dirty |= NV30_NEW_RASTERIZER;

   /* vertex program */
   BEGIN_NV04(push, NV30_3D(VP_START_FROM_ID), 1);
   PUSH_DATA (push, vp->start);
   BEGIN_NV04(push, NV40_3D(VP_ATTRIB_EN), 2);
   PUSH_DATA (push, 0x00000101); /* attrib: 0, 8 */
   PUSH_DATA (push, 0x00004000); /* result: hpos, tex0 */
   BEGIN_NV04(push, NV30_3D(ENGINE), 1);
   PUSH_DATA (push, 0x00000103);
   BEGIN_NV04(push, NV30_3D(VP_CLIP_PLANES_ENABLE), 1);
   PUSH_DATA (push, 0x00000000);

   nv30->dirty |= NV30_NEW_VERTPROG;
   nv30->dirty |= NV30_NEW_CLIP;

   /* fragment program */
   BEGIN_NV04(push, NV30_3D(FP_ACTIVE_PROGRAM), 1);
   PUSH_RELOC(push, fp->bo, fp->offset, fp->domain |
                    NOUVEAU_BO_LOW | NOUVEAU_BO_OR,
                    NV30_3D_FP_ACTIVE_PROGRAM_DMA0,
                    NV30_3D_FP_ACTIVE_PROGRAM_DMA1);
   BEGIN_NV04(push, NV30_3D(FP_CONTROL), 1);
   PUSH_DATA (push, 0x02000000);

   nv30->state.fragprog = NULL;
   nv30->dirty |= NV30_NEW_FRAGPROG;

   /* texture */
   texfmt |= 1 << NV40_3D_TEX_FORMAT_MIPMAP_COUNT__SHIFT;
   texfmt |= NV30_3D_TEX_FORMAT_NO_BORDER;
   texfmt |= NV40_3D_TEX_FORMAT_RECT;
   texfmt |= 0x00008000;
   if (src->d < 2)
      texfmt |= NV30_3D_TEX_FORMAT_DIMS_2D;
   else
      texfmt |= NV30_3D_TEX_FORMAT_DIMS_3D;
   if (src->pitch)
      texfmt |= NV40_3D_TEX_FORMAT_LINEAR;

   BEGIN_NV04(push, NV30_3D(TEX_OFFSET(0)), 8);
   PUSH_RELOC(push, src->bo, src->offset, NOUVEAU_BO_LOW, 0, 0);
   PUSH_RELOC(push, src->bo, texfmt, NOUVEAU_BO_OR,
                    NV30_3D_TEX_FORMAT_DMA0, NV30_3D_TEX_FORMAT_DMA1);
   PUSH_DATA (push, NV30_3D_TEX_WRAP_S_CLAMP_TO_EDGE |
                    NV30_3D_TEX_WRAP_T_CLAMP_TO_EDGE |
                    NV30_3D_TEX_WRAP_R_CLAMP_TO_EDGE);
   PUSH_DATA (push, NV40_3D_TEX_ENABLE_ENABLE);
   PUSH_DATA (push, texswz);
   switch (filter) {
   case BILINEAR:
      PUSH_DATA (push, NV30_3D_TEX_FILTER_MIN_LINEAR |
                       NV30_3D_TEX_FILTER_MAG_LINEAR | 0x00002000);
      break;
   default:
      PUSH_DATA (push, NV30_3D_TEX_FILTER_MIN_NEAREST |
                       NV30_3D_TEX_FILTER_MAG_NEAREST | 0x00002000);
      break;
   }
   PUSH_DATA (push, (src->w << 16) | src->h);
   PUSH_DATA (push, 0x00000000);
   BEGIN_NV04(push, NV40_3D(TEX_SIZE1(0)), 1);
   PUSH_DATA (push, 0x00100000 | src->pitch);
   BEGIN_NV04(push, SUBC_3D(0x0b40), 1);
   PUSH_DATA (push, src->d < 2 ? 0x00000001 : 0x00000000);
   BEGIN_NV04(push, NV40_3D(TEX_CACHE_CTL), 1);
   PUSH_DATA (push, 1);

   nv30->fragprog.dirty_samplers |= 1;
   nv30->dirty |= NV30_NEW_FRAGTEX;

   /* blit! */
   BEGIN_NV04(push, NV30_3D(SCISSOR_HORIZ), 2);
   PUSH_DATA (push, (dst->x1 - dst->x0) << 16 | dst->x0);
   PUSH_DATA (push, (dst->y1 - dst->y0) << 16 | dst->y0);
   BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
   PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_QUADS);
   BEGIN_NV04(push, NV30_3D(VTX_ATTR_3F(8)), 3);
   PUSH_DATAf(push, src->x0);
   PUSH_DATAf(push, src->y0);
   PUSH_DATAf(push, src->z);
   BEGIN_NV04(push, NV30_3D(VTX_ATTR_2I(0)), 1);
   PUSH_DATA (push, (dst->y0 << 16) | dst->x0);
   BEGIN_NV04(push, NV30_3D(VTX_ATTR_3F(8)), 3);
   PUSH_DATAf(push, src->x1);
   PUSH_DATAf(push, src->y0);
   PUSH_DATAf(push, src->z);
   BEGIN_NV04(push, NV30_3D(VTX_ATTR_2I(0)), 1);
   PUSH_DATA (push, (dst->y0 << 16) | dst->x1);
   BEGIN_NV04(push, NV30_3D(VTX_ATTR_3F(8)), 3);
   PUSH_DATAf(push, src->x1);
   PUSH_DATAf(push, src->y1);
   PUSH_DATAf(push, src->z);
   BEGIN_NV04(push, NV30_3D(VTX_ATTR_2I(0)), 1);
   PUSH_DATA (push, (dst->y1 << 16) | dst->x1);
   BEGIN_NV04(push, NV30_3D(VTX_ATTR_3F(8)), 3);
   PUSH_DATAf(push, src->x0);
   PUSH_DATAf(push, src->y1);
   PUSH_DATAf(push, src->z);
   BEGIN_NV04(push, NV30_3D(VTX_ATTR_2I(0)), 1);
   PUSH_DATA (push, (dst->y1 << 16) | dst->x0);
   BEGIN_NV04(push, NV30_3D(VERTEX_BEGIN_END), 1);
   PUSH_DATA (push, NV30_3D_VERTEX_BEGIN_END_STOP);
}

static boolean
nv30_transfer_sifm(XFER_ARGS)
{
   if (!src->pitch || (src->w | src->h) > 1024 || src->w < 2 || src->h < 2)
      return FALSE;

   if (src->d > 1 || dst->d > 1)
      return FALSE;

   if (dst->offset & 63)
      return FALSE;

   if (!dst->pitch) {
      if ((dst->w | dst->h) > 2048 || dst->w < 2 || dst->h < 2)
         return FALSE;
   } else {
      if (dst->domain != NOUVEAU_BO_VRAM)
         return FALSE;
      if (dst->pitch & 63)
         return FALSE;
   }

   return TRUE;
}

static void
nv30_transfer_rect_sifm(XFER_ARGS)

{
   struct nouveau_pushbuf *push = nv30->base.pushbuf;
   struct nouveau_pushbuf_refn refs[] = {
      { src->bo, src->domain | NOUVEAU_BO_RD },
      { dst->bo, dst->domain | NOUVEAU_BO_WR },
   };
   struct nv04_fifo *fifo = push->channel->data;
   unsigned si_fmt, si_arg;
   unsigned ss_fmt;

   switch (dst->cpp) {
   case 4: ss_fmt = NV04_SURFACE_SWZ_FORMAT_COLOR_A8R8G8B8; break;
   case 2: ss_fmt = NV04_SURFACE_SWZ_FORMAT_COLOR_R5G6B5; break;
   default:
      ss_fmt = NV04_SURFACE_SWZ_FORMAT_COLOR_Y8;
      break;
   }

   switch (src->cpp) {
   case 4: si_fmt = NV03_SIFM_COLOR_FORMAT_A8R8G8B8; break;
   case 2: si_fmt = NV03_SIFM_COLOR_FORMAT_R5G6B5; break;
   default:
      si_fmt = NV03_SIFM_COLOR_FORMAT_AY8;
      break;
   }

   if (filter == NEAREST) {
      si_arg  = NV03_SIFM_FORMAT_ORIGIN_CENTER;
      si_arg |= NV03_SIFM_FORMAT_FILTER_POINT_SAMPLE;
   } else {
      si_arg  = NV03_SIFM_FORMAT_ORIGIN_CORNER;
      si_arg |= NV03_SIFM_FORMAT_FILTER_BILINEAR;
   }

   if (nouveau_pushbuf_space(push, 32, 6, 0) ||
       nouveau_pushbuf_refn (push, refs, 2))
      return;

   if (dst->pitch) {
      BEGIN_NV04(push, NV04_SF2D(DMA_IMAGE_SOURCE), 2);
      PUSH_RELOC(push, dst->bo, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart);
      PUSH_RELOC(push, dst->bo, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart);
      BEGIN_NV04(push, NV04_SF2D(FORMAT), 4);
      PUSH_DATA (push, ss_fmt);
      PUSH_DATA (push, dst->pitch << 16 | dst->pitch);
      PUSH_RELOC(push, dst->bo, dst->offset, NOUVEAU_BO_LOW, 0, 0);
      PUSH_RELOC(push, dst->bo, dst->offset, NOUVEAU_BO_LOW, 0, 0);
      BEGIN_NV04(push, NV05_SIFM(SURFACE), 1);
      PUSH_DATA (push, nv30->screen->surf2d->handle);
   } else {
      BEGIN_NV04(push, NV04_SSWZ(DMA_IMAGE), 1);
      PUSH_RELOC(push, dst->bo, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart);
      BEGIN_NV04(push, NV04_SSWZ(FORMAT), 2);
      PUSH_DATA (push, ss_fmt | (util_logbase2(dst->w) << 16) |
                                (util_logbase2(dst->h) << 24));
      PUSH_RELOC(push, dst->bo, dst->offset, NOUVEAU_BO_LOW, 0, 0);
      BEGIN_NV04(push, NV05_SIFM(SURFACE), 1);
      PUSH_DATA (push, nv30->screen->swzsurf->handle);
   }

   BEGIN_NV04(push, NV03_SIFM(DMA_IMAGE), 1);
   PUSH_RELOC(push, src->bo, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart);
   BEGIN_NV04(push, NV03_SIFM(COLOR_FORMAT), 8);
   PUSH_DATA (push, si_fmt);
   PUSH_DATA (push, NV03_SIFM_OPERATION_SRCCOPY);
   PUSH_DATA (push, (           dst->y0  << 16) |            dst->x0);
   PUSH_DATA (push, ((dst->y1 - dst->y0) << 16) | (dst->x1 - dst->x0));
   PUSH_DATA (push, (           dst->y0  << 16) |            dst->x0);
   PUSH_DATA (push, ((dst->y1 - dst->y0) << 16) | (dst->x1 - dst->x0));
   PUSH_DATA (push, ((src->x1 - src->x0) << 20) / (dst->x1 - dst->x0));
   PUSH_DATA (push, ((src->y1 - src->y0) << 20) / (dst->y1 - dst->y0));
   BEGIN_NV04(push, NV03_SIFM(SIZE), 4);
   PUSH_DATA (push, align(src->h, 2) << 16 | align(src->w, 2));
   PUSH_DATA (push, src->pitch | si_arg);
   PUSH_RELOC(push, src->bo, src->offset, NOUVEAU_BO_LOW, 0, 0);
   PUSH_DATA (push, (src->y0 << 20) | src->x0 << 4);
}

/* The NOP+OFFSET_OUT stuff after each M2MF transfer *is* actually required
 * to prevent some odd things from happening, easily reproducible by
 * attempting to do conditional rendering that has a M2MF transfer done
 * some time before it.  0x1e98 will fail with a DMA_W_PROTECTION (assuming
 * that name is still accurate on nv4x) error.
 */

static boolean
nv30_transfer_m2mf(XFER_ARGS)
{
   if (!src->pitch || !dst->pitch)
      return FALSE;
   if (nv30_transfer_scaled(src, dst))
      return FALSE;
   return TRUE;
}

static void
nv30_transfer_rect_m2mf(XFER_ARGS)
{
   struct nouveau_pushbuf *push = nv30->base.pushbuf;
   struct nouveau_pushbuf_refn refs[] = {
      { src->bo, src->domain | NOUVEAU_BO_RD },
      { dst->bo, dst->domain | NOUVEAU_BO_WR },
   };
   struct nv04_fifo *fifo = push->channel->data;
   unsigned src_offset = src->offset;
   unsigned dst_offset = dst->offset;
   unsigned w = dst->x1 - dst->x0;
   unsigned h = dst->y1 - dst->y0;

   src_offset += (src->y0 * src->pitch) + (src->x0 * src->cpp);
   dst_offset += (dst->y0 * dst->pitch) + (dst->x0 * dst->cpp);

   BEGIN_NV04(push, NV03_M2MF(DMA_BUFFER_IN), 2);
   PUSH_DATA (push, (src->domain == NOUVEAU_BO_VRAM) ? fifo->vram : fifo->gart);
   PUSH_DATA (push, (dst->domain == NOUVEAU_BO_VRAM) ? fifo->vram : fifo->gart);

   while (h) {
      unsigned lines = (h > 2047) ? 2047 : h;

      if (nouveau_pushbuf_space(push, 13, 2, 0) ||
          nouveau_pushbuf_refn (push, refs, 2))
         return;

      BEGIN_NV04(push, NV03_M2MF(OFFSET_IN), 8);
      PUSH_RELOC(push, src->bo, src_offset, NOUVEAU_BO_LOW, 0, 0);
      PUSH_RELOC(push, dst->bo, dst_offset, NOUVEAU_BO_LOW, 0, 0);
      PUSH_DATA (push, src->pitch);
      PUSH_DATA (push, dst->pitch);
      PUSH_DATA (push, w * src->cpp);
      PUSH_DATA (push, lines);
      PUSH_DATA (push, NV03_M2MF_FORMAT_INPUT_INC_1 |
                       NV03_M2MF_FORMAT_OUTPUT_INC_1);
      PUSH_DATA (push, 0x00000000);
      BEGIN_NV04(push, NV04_GRAPH(M2MF, NOP), 1);
      PUSH_DATA (push, 0x00000000);
      BEGIN_NV04(push, NV03_M2MF(OFFSET_OUT), 1);
      PUSH_DATA (push, 0x00000000);

      h -= lines;
      src_offset += src->pitch * lines;
      dst_offset += dst->pitch * lines;
   }
}

static boolean
nv30_transfer_cpu(XFER_ARGS)
{
   if (nv30_transfer_scaled(src, dst))
      return FALSE;
   return TRUE;
}

static char *
linear_ptr(struct nv30_rect *rect, char *base, int x, int y, int z)
{
   return base + (y * rect->pitch) + (x * rect->cpp);
}

static INLINE unsigned
swizzle2d(unsigned v, unsigned s)
{
   v = (v | (v << 8)) & 0x00ff00ff;
   v = (v | (v << 4)) & 0x0f0f0f0f;
   v = (v | (v << 2)) & 0x33333333;
   v = (v | (v << 1)) & 0x55555555;
   return v << s;
}

static char *
swizzle2d_ptr(struct nv30_rect *rect, char *base, int x, int y, int z)
{
   unsigned k = util_logbase2(MIN2(rect->w, rect->h));
   unsigned km = (1 << k) - 1;
   unsigned nx = rect->w >> k;
   unsigned tx = x >> k;
   unsigned ty = y >> k;
   unsigned m;

   m  = swizzle2d(x & km, 0);
   m |= swizzle2d(y & km, 1);
   m += ((ty * nx) + tx) << k << k;

   return base + (m * rect->cpp);
}

static char *
swizzle3d_ptr(struct nv30_rect *rect, char *base, int x, int y, int z)
{
   unsigned w = rect->w >> 1;
   unsigned h = rect->h >> 1;
   unsigned d = rect->d >> 1;
   unsigned i = 0, o;
   unsigned v = 0;

   do {
      o = i;
      if (w) {
         v |= (x & 1) << i++;
         x >>= 1;
         w >>= 1;
      }
      if (h) {
         v |= (y & 1) << i++;
         y >>= 1;
         h >>= 1;
      }
      if (d) {
         v |= (z & 1) << i++;
         z >>= 1;
         d >>= 1;
      }
   } while(o != i);

   return base + (v * rect->cpp);
}

typedef char *(*get_ptr_t)(struct nv30_rect *, char *, int, int, int);

static INLINE get_ptr_t
get_ptr(struct nv30_rect *rect)
{
   if (rect->pitch)
      return linear_ptr;

   if (rect->d <= 1)
      return swizzle2d_ptr;

   return swizzle3d_ptr;
}

static void
nv30_transfer_rect_cpu(XFER_ARGS)
{
   get_ptr_t sp = get_ptr(src);
   get_ptr_t dp = get_ptr(dst);
   char *srcmap, *dstmap;
   int x, y;

   nouveau_bo_map(src->bo, NOUVEAU_BO_RD, nv30->base.client);
   nouveau_bo_map(dst->bo, NOUVEAU_BO_WR, nv30->base.client);
   srcmap = src->bo->map + src->offset;
   dstmap = dst->bo->map + dst->offset;

   for (y = 0; y < (dst->y1 - dst->y0); y++) {
      for (x = 0; x < (dst->x1 - dst->x0); x++) {
         memcpy(dp(dst, dstmap, dst->x0 + x, dst->y0 + y, dst->z),
                sp(src, srcmap, src->x0 + x, src->y0 + y, src->z), dst->cpp);
      }
   }
}

void
nv30_transfer_rect(struct nv30_context *nv30, enum nv30_transfer_filter filter,
                   struct nv30_rect *src, struct nv30_rect *dst)
{
   static const struct {
      char *name;
      boolean (*possible)(XFER_ARGS);
      void (*execute)(XFER_ARGS);
   } *method, methods[] = {
      { "m2mf", nv30_transfer_m2mf, nv30_transfer_rect_m2mf },
      { "sifm", nv30_transfer_sifm, nv30_transfer_rect_sifm },
      { "blit", nv30_transfer_blit, nv30_transfer_rect_blit },
      { "rect", nv30_transfer_cpu, nv30_transfer_rect_cpu },
      {}
   };

   method = methods - 1;
   while ((++method)->possible) {
      if (method->possible(nv30, filter, src, dst)) {
         method->execute(nv30, filter, src, dst);
         return;
      }
   }

   assert(0);
}

void
nv30_transfer_push_data(struct nouveau_context *nv,
                        struct nouveau_bo *bo, unsigned offset, unsigned domain,
                        unsigned size, void *data)
{
   /* use ifc, or scratch + copy_data? */
   fprintf(stderr, "nv30: push_data not implemented\n");
}

void
nv30_transfer_copy_data(struct nouveau_context *nv,
                        struct nouveau_bo *dst, unsigned d_off, unsigned d_dom,
                        struct nouveau_bo *src, unsigned s_off, unsigned s_dom,
                        unsigned size)
{
   struct nv04_fifo *fifo = nv->screen->channel->data;
   struct nouveau_pushbuf_refn refs[] = {
      { src, s_dom | NOUVEAU_BO_RD },
      { dst, d_dom | NOUVEAU_BO_WR },
   };
   struct nouveau_pushbuf *push = nv->pushbuf;
   unsigned pages, lines;

   pages = size >> 12;
   size -= (pages << 12);

   BEGIN_NV04(push, NV03_M2MF(DMA_BUFFER_IN), 2);
   PUSH_DATA (push, (s_dom == NOUVEAU_BO_VRAM) ? fifo->vram : fifo->gart);
   PUSH_DATA (push, (d_dom == NOUVEAU_BO_VRAM) ? fifo->vram : fifo->gart);

   while (pages) {
      lines  = (pages > 2047) ? 2047 : pages;
      pages -= lines;

      if (nouveau_pushbuf_space(push, 13, 2, 0) ||
          nouveau_pushbuf_refn (push, refs, 2))
         return;

      BEGIN_NV04(push, NV03_M2MF(OFFSET_IN), 8);
      PUSH_RELOC(push, src, s_off, NOUVEAU_BO_LOW, 0, 0);
      PUSH_RELOC(push, dst, d_off, NOUVEAU_BO_LOW, 0, 0);
      PUSH_DATA (push, 4096);
      PUSH_DATA (push, 4096);
      PUSH_DATA (push, 4096);
      PUSH_DATA (push, lines);
      PUSH_DATA (push, NV03_M2MF_FORMAT_INPUT_INC_1 |
                       NV03_M2MF_FORMAT_OUTPUT_INC_1);
      PUSH_DATA (push, 0x00000000);
      BEGIN_NV04(push, NV04_GRAPH(M2MF, NOP), 1);
      PUSH_DATA (push, 0x00000000);
      BEGIN_NV04(push, NV03_M2MF(OFFSET_OUT), 1);
      PUSH_DATA (push, 0x00000000);

      s_off += (lines << 12);
      d_off += (lines << 12);
   }

   if (size) {
      if (nouveau_pushbuf_space(push, 13, 2, 0) ||
          nouveau_pushbuf_refn (push, refs, 2))
         return;

      BEGIN_NV04(push, NV03_M2MF(OFFSET_IN), 8);
      PUSH_RELOC(push, src, s_off, NOUVEAU_BO_LOW, 0, 0);
      PUSH_RELOC(push, dst, d_off, NOUVEAU_BO_LOW, 0, 0);
      PUSH_DATA (push, size);
      PUSH_DATA (push, size);
      PUSH_DATA (push, size);
      PUSH_DATA (push, 1);
      PUSH_DATA (push, NV03_M2MF_FORMAT_INPUT_INC_1 |
                       NV03_M2MF_FORMAT_OUTPUT_INC_1);
      PUSH_DATA (push, 0x00000000);
      BEGIN_NV04(push, NV04_GRAPH(M2MF, NOP), 1);
      PUSH_DATA (push, 0x00000000);
      BEGIN_NV04(push, NV03_M2MF(OFFSET_OUT), 1);
      PUSH_DATA (push, 0x00000000);
   }
}
