14c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
24c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller#include "util/u_format.h"
34c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
44c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller#include "nvc0_context.h"
54c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
6e4c968cdbbdc020afbf869d12b536c0a0dbf9de8Christoph Bumiller#include "nv50/nv50_defs.xml.h"
74c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
84c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillerstruct nvc0_transfer {
94c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   struct pipe_transfer base;
10b2dcf880e8bcd61be59602f5a2d18c77a5fc60c1Christoph Bumiller   struct nv50_m2mf_rect rect[2];
114c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   uint32_t nblocksx;
127fd29468ec68b5cd08222428577a7dbe8f123426Christoph Bumiller   uint16_t nblocksy;
137fd29468ec68b5cd08222428577a7dbe8f123426Christoph Bumiller   uint16_t nlayers;
144c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller};
154c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
16e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumillerstatic void
176d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumillernvc0_m2mf_transfer_rect(struct nvc0_context *nvc0,
18b2dcf880e8bcd61be59602f5a2d18c77a5fc60c1Christoph Bumiller                        const struct nv50_m2mf_rect *dst,
19b2dcf880e8bcd61be59602f5a2d18c77a5fc60c1Christoph Bumiller                        const struct nv50_m2mf_rect *src,
204c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller                        uint32_t nblocksx, uint32_t nblocksy)
214c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller{
226d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
236d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   struct nouveau_bufctx *bctx = nvc0->bufctx;
244c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   const int cpp = dst->cpp;
254c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   uint32_t src_ofst = src->base;
264c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   uint32_t dst_ofst = dst->base;
274c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   uint32_t height = nblocksy;
284c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   uint32_t sy = src->y;
294c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   uint32_t dy = dst->y;
304c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   uint32_t exec = (1 << 20);
314c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
324c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   assert(dst->cpp == src->cpp);
334c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
346d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   nouveau_bufctx_refn(bctx, 0, src->bo, src->domain | NOUVEAU_BO_RD);
356d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   nouveau_bufctx_refn(bctx, 0, dst->bo, dst->domain | NOUVEAU_BO_WR);
366d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   nouveau_pushbuf_bufctx(push, bctx);
376d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   nouveau_pushbuf_validate(push);
386d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller
396d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   if (nouveau_bo_memtype(src->bo)) {
406d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NVC0(push, NVC0_M2MF(TILING_MODE_IN), 5);
416d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, src->tile_mode);
426d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, src->width * cpp);
436d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, src->height);
446d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, src->depth);
456d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, src->z);
464c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   } else {
474c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      src_ofst += src->y * src->pitch + src->x * cpp;
484c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
496d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NVC0(push, NVC0_M2MF(PITCH_IN), 1);
506d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, src->width * cpp);
514c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
524c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      exec |= NVC0_M2MF_EXEC_LINEAR_IN;
534c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   }
544c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
556d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   if (nouveau_bo_memtype(dst->bo)) {
566d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NVC0(push, NVC0_M2MF(TILING_MODE_OUT), 5);
576d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, dst->tile_mode);
586d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, dst->width * cpp);
596d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, dst->height);
606d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, dst->depth);
616d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, dst->z);
624c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   } else {
634c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      dst_ofst += dst->y * dst->pitch + dst->x * cpp;
644c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
656d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NVC0(push, NVC0_M2MF(PITCH_OUT), 1);
666d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, dst->width * cpp);
674c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
684c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      exec |= NVC0_M2MF_EXEC_LINEAR_OUT;
694c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   }
704c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
714c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   while (height) {
724c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      int line_count = height > 2047 ? 2047 : height;
734c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
746d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NVC0(push, NVC0_M2MF(OFFSET_IN_HIGH), 2);
756d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATAh(push, src->bo->offset + src_ofst);
766d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, src->bo->offset + src_ofst);
774c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
786d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2);
796d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATAh(push, dst->bo->offset + dst_ofst);
806d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, dst->bo->offset + dst_ofst);
814c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
824c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      if (!(exec & NVC0_M2MF_EXEC_LINEAR_IN)) {
836d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         BEGIN_NVC0(push, NVC0_M2MF(TILING_POSITION_IN_X), 2);
846d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         PUSH_DATA (push, src->x * cpp);
856d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         PUSH_DATA (push, sy);
864c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      } else {
874c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller         src_ofst += line_count * src->pitch;
884c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      }
894c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      if (!(exec & NVC0_M2MF_EXEC_LINEAR_OUT)) {
906d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         BEGIN_NVC0(push, NVC0_M2MF(TILING_POSITION_OUT_X), 2);
916d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         PUSH_DATA (push, dst->x * cpp);
926d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         PUSH_DATA (push, dy);
934c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      } else {
944c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller         dst_ofst += line_count * dst->pitch;
954c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      }
964c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
976d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2);
986d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, nblocksx * cpp);
996d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, line_count);
1006d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1);
1016d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, exec);
1024c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
1034c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      height -= line_count;
1044c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      sy += line_count;
1054c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      dy += line_count;
1064c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   }
1076d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller
1086d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   nouveau_bufctx_reset(bctx, 0);
1094c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller}
1104c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
111e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumillerstatic void
112e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumillernve4_m2mf_transfer_rect(struct nvc0_context *nvc0,
113e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller                        const struct nv50_m2mf_rect *dst,
114e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller                        const struct nv50_m2mf_rect *src,
115e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller                        uint32_t nblocksx, uint32_t nblocksy)
116e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller{
117e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
118e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   struct nouveau_bufctx *bctx = nvc0->bufctx;
119e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   uint32_t exec;
120e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   uint32_t src_base = src->base;
121e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   uint32_t dst_base = dst->base;
122e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   const int cpp = dst->cpp;
123e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller
124e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   assert(dst->cpp == src->cpp);
125e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller
126e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   nouveau_bufctx_refn(bctx, 0, dst->bo, dst->domain | NOUVEAU_BO_WR);
127e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   nouveau_bufctx_refn(bctx, 0, src->bo, src->domain | NOUVEAU_BO_RD);
128e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   nouveau_pushbuf_bufctx(push, bctx);
129e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   nouveau_pushbuf_validate(push);
130e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller
131e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   exec = 0x200 /* 2D_ENABLE */ | 0x6 /* UNK */;
132e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller
133e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   if (!nouveau_bo_memtype(dst->bo)) {
134e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      assert(!dst->z);
135e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      dst_base += dst->y * dst->pitch + dst->x * cpp;
136e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      exec |= 0x100; /* DST_MODE_2D_LINEAR */
137e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   }
138e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   if (!nouveau_bo_memtype(src->bo)) {
139e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      assert(!src->z);
140e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      src_base += src->y * src->pitch + src->x * cpp;
141e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      exec |= 0x080; /* SRC_MODE_2D_LINEAR */
142e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   }
143e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller
144e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   BEGIN_NVC0(push, SUBC_COPY(0x070c), 6);
145e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   PUSH_DATA (push, 0x1000 | dst->tile_mode);
146e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   PUSH_DATA (push, dst->pitch);
147e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   PUSH_DATA (push, dst->height);
148e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   PUSH_DATA (push, dst->depth);
149e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   PUSH_DATA (push, dst->z);
150e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   PUSH_DATA (push, (dst->y << 16) | (dst->x * cpp));
151e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller
152e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   BEGIN_NVC0(push, SUBC_COPY(0x0728), 6);
153e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   PUSH_DATA (push, 0x1000 | src->tile_mode);
154e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   PUSH_DATA (push, src->pitch);
155e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   PUSH_DATA (push, src->height);
156e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   PUSH_DATA (push, src->depth);
157e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   PUSH_DATA (push, src->z);
158e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   PUSH_DATA (push, (src->y << 16) | (src->x * cpp));
159e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller
160e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   BEGIN_NVC0(push, SUBC_COPY(0x0400), 8);
161e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   PUSH_DATAh(push, src->bo->offset + src_base);
162e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   PUSH_DATA (push, src->bo->offset + src_base);
163e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   PUSH_DATAh(push, dst->bo->offset + dst_base);
164e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   PUSH_DATA (push, dst->bo->offset + dst_base);
165e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   PUSH_DATA (push, src->pitch);
166e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   PUSH_DATA (push, dst->pitch);
167e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   PUSH_DATA (push, nblocksx * cpp);
168e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   PUSH_DATA (push, nblocksy);
169e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller
170e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   BEGIN_NVC0(push, SUBC_COPY(0x0300), 1);
171e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   PUSH_DATA (push, exec);
172e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller
173e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   nouveau_bufctx_reset(bctx, 0);
174e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller}
175e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller
1764c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillervoid
1771ba8e9510812f155359d380bda6876cdee5ba21eBen Skeggsnvc0_m2mf_push_linear(struct nouveau_context *nv,
1784826cd0f6125b071530026143ffd8205d84b3d5eBen Skeggs                      struct nouveau_bo *dst, unsigned offset, unsigned domain,
179150bb0fb34b74055c7dd6d2925ce9c5a1d7decf5Christoph Bumiller                      unsigned size, const void *data)
1804c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller{
1816d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   struct nvc0_context *nvc0 = nvc0_context(&nv->pipe);
1826d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   struct nouveau_pushbuf *push = nv->pushbuf;
1834c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   uint32_t *src = (uint32_t *)data;
1844c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   unsigned count = (size + 3) / 4;
1854c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
1866d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   nouveau_bufctx_refn(nvc0->bufctx, 0, dst, domain | NOUVEAU_BO_WR);
1876d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   nouveau_pushbuf_bufctx(push, nvc0->bufctx);
1886d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   nouveau_pushbuf_validate(push);
1896d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller
1904c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   while (count) {
191a42eca84c56f6860e67c0c57f4765a5530cc5f81Christoph Bumiller      unsigned nr;
1924c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
1936d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      if (!PUSH_SPACE(push, 16))
1946d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller         break;
1956d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      nr = PUSH_AVAIL(push);
1966d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      assert(nr >= 16);
1976d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      nr = MIN2(count, nr - 9);
1984c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN);
199a42eca84c56f6860e67c0c57f4765a5530cc5f81Christoph Bumiller
2006d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2);
2016d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATAh(push, dst->offset + offset);
2026d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, dst->offset + offset);
2036d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2);
2046d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, nr * 4);
2056d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, 1);
2066d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1);
2076d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, 0x100111);
208a42eca84c56f6860e67c0c57f4765a5530cc5f81Christoph Bumiller
209a42eca84c56f6860e67c0c57f4765a5530cc5f81Christoph Bumiller      /* must not be interrupted (trap on QUERY fence, 0x50 works however) */
2106d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NIC0(push, NVC0_M2MF(DATA), nr);
2116d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATAp(push, src, nr);
2124c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
2134c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      count -= nr;
214a42eca84c56f6860e67c0c57f4765a5530cc5f81Christoph Bumiller      src += nr;
215a42eca84c56f6860e67c0c57f4765a5530cc5f81Christoph Bumiller      offset += nr * 4;
2164c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   }
2176d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller
2186d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   nouveau_bufctx_reset(nvc0->bufctx, 0);
2194c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller}
2204c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
2213ef1616b63507db01f54efa882a9cf28839cfdf3Christoph Bumillervoid
222e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumillernve4_p2mf_push_linear(struct nouveau_context *nv,
223e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller                      struct nouveau_bo *dst, unsigned offset, unsigned domain,
224e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller                      unsigned size, const void *data)
225e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller{
226e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   struct nvc0_context *nvc0 = nvc0_context(&nv->pipe);
227e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   struct nouveau_pushbuf *push = nv->pushbuf;
228e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   uint32_t *src = (uint32_t *)data;
229e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   unsigned count = (size + 3) / 4;
230e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller
231e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   nouveau_bufctx_refn(nvc0->bufctx, 0, dst, domain | NOUVEAU_BO_WR);
232e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   nouveau_pushbuf_bufctx(push, nvc0->bufctx);
233e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   nouveau_pushbuf_validate(push);
234e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller
235e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   while (count) {
236e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      unsigned nr;
237e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller
238e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      if (!PUSH_SPACE(push, 16))
239e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller         break;
240e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      nr = PUSH_AVAIL(push);
241e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      assert(nr >= 16);
242e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      nr = MIN2(count, nr - 8);
243e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      nr = MIN2(nr, (NV04_PFIFO_MAX_PACKET_LEN - 1));
244e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller
245e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      BEGIN_NVC0(push, NVE4_P2MF(DST_ADDRESS_HIGH), 2);
246e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      PUSH_DATAh(push, dst->offset + offset);
247e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      PUSH_DATA (push, dst->offset + offset);
248e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      BEGIN_NVC0(push, NVE4_P2MF(LINE_LENGTH_IN), 2);
249e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      PUSH_DATA (push, nr * 4);
250e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      PUSH_DATA (push, 1);
251e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      /* must not be interrupted (trap on QUERY fence, 0x50 works however) */
252e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      BEGIN_1IC0(push, NVE4_P2MF(EXEC), nr + 1);
253e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      PUSH_DATA (push, 0x1001);
254e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      PUSH_DATAp(push, src, nr);
255e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller
256e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      count -= nr;
257e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      src += nr;
258e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      offset += nr * 4;
259e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   }
260e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller
261e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   nouveau_bufctx_reset(nvc0->bufctx, 0);
262e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller}
263e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller
264e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumillerstatic void
2651ba8e9510812f155359d380bda6876cdee5ba21eBen Skeggsnvc0_m2mf_copy_linear(struct nouveau_context *nv,
2663ef1616b63507db01f54efa882a9cf28839cfdf3Christoph Bumiller                      struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom,
2673ef1616b63507db01f54efa882a9cf28839cfdf3Christoph Bumiller                      struct nouveau_bo *src, unsigned srcoff, unsigned srcdom,
2683ef1616b63507db01f54efa882a9cf28839cfdf3Christoph Bumiller                      unsigned size)
2693ef1616b63507db01f54efa882a9cf28839cfdf3Christoph Bumiller{
2706d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   struct nouveau_pushbuf *push = nv->pushbuf;
2716d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   struct nouveau_bufctx *bctx = nvc0_context(&nv->pipe)->bufctx;
2726d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller
2736d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   nouveau_bufctx_refn(bctx, 0, src, srcdom | NOUVEAU_BO_RD);
2746d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   nouveau_bufctx_refn(bctx, 0, dst, dstdom | NOUVEAU_BO_WR);
2756d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   nouveau_pushbuf_bufctx(push, bctx);
2766d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   nouveau_pushbuf_validate(push);
2773ef1616b63507db01f54efa882a9cf28839cfdf3Christoph Bumiller
2783ef1616b63507db01f54efa882a9cf28839cfdf3Christoph Bumiller   while (size) {
2793ef1616b63507db01f54efa882a9cf28839cfdf3Christoph Bumiller      unsigned bytes = MIN2(size, 1 << 17);
2803ef1616b63507db01f54efa882a9cf28839cfdf3Christoph Bumiller
2816d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2);
2826d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATAh(push, dst->offset + dstoff);
2836d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, dst->offset + dstoff);
2846d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NVC0(push, NVC0_M2MF(OFFSET_IN_HIGH), 2);
2856d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATAh(push, src->offset + srcoff);
2866d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, src->offset + srcoff);
2876d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2);
2886d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, bytes);
2896d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, 1);
2906d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1);
2916d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, (1 << NVC0_M2MF_EXEC_INC__SHIFT) |
2923ef1616b63507db01f54efa882a9cf28839cfdf3Christoph Bumiller                 NVC0_M2MF_EXEC_LINEAR_IN | NVC0_M2MF_EXEC_LINEAR_OUT);
2933ef1616b63507db01f54efa882a9cf28839cfdf3Christoph Bumiller
2943ef1616b63507db01f54efa882a9cf28839cfdf3Christoph Bumiller      srcoff += bytes;
2953ef1616b63507db01f54efa882a9cf28839cfdf3Christoph Bumiller      dstoff += bytes;
2963ef1616b63507db01f54efa882a9cf28839cfdf3Christoph Bumiller      size -= bytes;
2973ef1616b63507db01f54efa882a9cf28839cfdf3Christoph Bumiller   }
2984c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
2996d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   nouveau_bufctx_reset(bctx, 0);
3004c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller}
3014c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
302e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumillerstatic void
303e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumillernve4_m2mf_copy_linear(struct nouveau_context *nv,
304e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller                      struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom,
305e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller                      struct nouveau_bo *src, unsigned srcoff, unsigned srcdom,
306e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller                      unsigned size)
307e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller{
308e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   struct nouveau_pushbuf *push = nv->pushbuf;
309e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   struct nouveau_bufctx *bctx = nvc0_context(&nv->pipe)->bufctx;
310e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller
311e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   nouveau_bufctx_refn(bctx, 0, src, srcdom | NOUVEAU_BO_RD);
312e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   nouveau_bufctx_refn(bctx, 0, dst, dstdom | NOUVEAU_BO_WR);
313e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   nouveau_pushbuf_bufctx(push, bctx);
314e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   nouveau_pushbuf_validate(push);
315e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller
316e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   BEGIN_NVC0(push, SUBC_COPY(0x0400), 4);
317e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   PUSH_DATAh(push, src->offset + srcoff);
318e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   PUSH_DATA (push, src->offset + srcoff);
319e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   PUSH_DATAh(push, dst->offset + dstoff);
320e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   PUSH_DATA (push, dst->offset + dstoff);
321e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   BEGIN_NVC0(push, SUBC_COPY(0x0418), 1);
322e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   PUSH_DATA (push, size);
323847c89870238fe5813e89831b38d5fab5356158cChristoph Bumiller   BEGIN_NVC0(push, SUBC_COPY(0x0300), 1);
324847c89870238fe5813e89831b38d5fab5356158cChristoph Bumiller   PUSH_DATA (push, 0x186);
325e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller
326e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   nouveau_bufctx_reset(bctx, 0);
327e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller}
328e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller
3294c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillerstruct pipe_transfer *
3304c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillernvc0_miptree_transfer_new(struct pipe_context *pctx,
3314c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller                          struct pipe_resource *res,
332ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller                          unsigned level,
3334c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller                          unsigned usage,
3344c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller                          const struct pipe_box *box)
3354c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller{
3364c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   struct nvc0_context *nvc0 = nvc0_context(pctx);
3374c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   struct nouveau_device *dev = nvc0->screen->base.device;
338cad17554c4b121c03e188dd0281718a52d603a15Christoph Bumiller   struct nv50_miptree *mt = nv50_miptree(res);
3394c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   struct nvc0_transfer *tx;
340ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller   uint32_t size;
3414c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   int ret;
3424c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
34362f44f670bb0162e89fd4786af877f8da9ff607cMarek Olšák   if (usage & PIPE_TRANSFER_MAP_DIRECTLY)
3444e1b1cbd0dd5c436d3c9360870df14e2b5e548f3Marcin Slusarz      return NULL;
3454e1b1cbd0dd5c436d3c9360870df14e2b5e548f3Marcin Slusarz
3467fd29468ec68b5cd08222428577a7dbe8f123426Christoph Bumiller   tx = CALLOC_STRUCT(nvc0_transfer);
3477fd29468ec68b5cd08222428577a7dbe8f123426Christoph Bumiller   if (!tx)
3487fd29468ec68b5cd08222428577a7dbe8f123426Christoph Bumiller      return NULL;
3497fd29468ec68b5cd08222428577a7dbe8f123426Christoph Bumiller
3504c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   pipe_resource_reference(&tx->base.resource, res);
3514c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
352ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller   tx->base.level = level;
3534c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   tx->base.usage = usage;
3544c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   tx->base.box = *box;
3554c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
356b2dcf880e8bcd61be59602f5a2d18c77a5fc60c1Christoph Bumiller   if (util_format_is_plain(res->format)) {
357b2dcf880e8bcd61be59602f5a2d18c77a5fc60c1Christoph Bumiller      tx->nblocksx = box->width << mt->ms_x;
358b2dcf880e8bcd61be59602f5a2d18c77a5fc60c1Christoph Bumiller      tx->nblocksy = box->height << mt->ms_y;
359b2dcf880e8bcd61be59602f5a2d18c77a5fc60c1Christoph Bumiller   } else {
360b2dcf880e8bcd61be59602f5a2d18c77a5fc60c1Christoph Bumiller      tx->nblocksx = util_format_get_nblocksx(res->format, box->width);
361b2dcf880e8bcd61be59602f5a2d18c77a5fc60c1Christoph Bumiller      tx->nblocksy = util_format_get_nblocksy(res->format, box->height);
362b2dcf880e8bcd61be59602f5a2d18c77a5fc60c1Christoph Bumiller   }
363b2dcf880e8bcd61be59602f5a2d18c77a5fc60c1Christoph Bumiller   tx->nlayers = box->depth;
3644c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
3654c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   tx->base.stride = tx->nblocksx * util_format_get_blocksize(res->format);
366abd08f4c014f24231505de2d3cb466a0901107e2Christoph Bumiller   tx->base.layer_stride = tx->nblocksy * tx->base.stride;
3674c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
368b2dcf880e8bcd61be59602f5a2d18c77a5fc60c1Christoph Bumiller   nv50_m2mf_rect_setup(&tx->rect[0], res, level, box->x, box->y, box->z);
3694c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
370abd08f4c014f24231505de2d3cb466a0901107e2Christoph Bumiller   size = tx->base.layer_stride;
3713ef1616b63507db01f54efa882a9cf28839cfdf3Christoph Bumiller
3724c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0,
3736d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller                        size * tx->nlayers, NULL, &tx->rect[1].bo);
3744c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   if (ret) {
3754c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      FREE(tx);
3764c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      return NULL;
3774c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   }
3784c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
379b2dcf880e8bcd61be59602f5a2d18c77a5fc60c1Christoph Bumiller   tx->rect[1].cpp = tx->rect[0].cpp;
3804c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   tx->rect[1].width = tx->nblocksx;
3814c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   tx->rect[1].height = tx->nblocksy;
382ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller   tx->rect[1].depth = 1;
3834c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   tx->rect[1].pitch = tx->base.stride;
3844c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   tx->rect[1].domain = NOUVEAU_BO_GART;
3854c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
3864c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   if (usage & PIPE_TRANSFER_READ) {
387c62fc50c884e2755c0731c395f200d23b975fbdeChristoph Bumiller      unsigned base = tx->rect[0].base;
388b2dcf880e8bcd61be59602f5a2d18c77a5fc60c1Christoph Bumiller      unsigned z = tx->rect[0].z;
389ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller      unsigned i;
3907fd29468ec68b5cd08222428577a7dbe8f123426Christoph Bumiller      for (i = 0; i < tx->nlayers; ++i) {
391e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller         nvc0->m2mf_copy_rect(nvc0, &tx->rect[1], &tx->rect[0],
392e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller                              tx->nblocksx, tx->nblocksy);
393ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller         if (mt->layout_3d)
394ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller            tx->rect[0].z++;
395ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller         else
396ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller            tx->rect[0].base += mt->layer_stride;
397ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller         tx->rect[1].base += size;
3984c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      }
399c62fc50c884e2755c0731c395f200d23b975fbdeChristoph Bumiller      tx->rect[0].z = z;
400c62fc50c884e2755c0731c395f200d23b975fbdeChristoph Bumiller      tx->rect[0].base = base;
401c62fc50c884e2755c0731c395f200d23b975fbdeChristoph Bumiller      tx->rect[1].base = 0;
4024c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   }
4034c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
4044c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   return &tx->base;
4054c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller}
4064c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
4074c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillervoid
4084c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillernvc0_miptree_transfer_del(struct pipe_context *pctx,
4094c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller                          struct pipe_transfer *transfer)
4104c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller{
4116d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   struct nvc0_context *nvc0 = nvc0_context(pctx);
4124c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   struct nvc0_transfer *tx = (struct nvc0_transfer *)transfer;
413cad17554c4b121c03e188dd0281718a52d603a15Christoph Bumiller   struct nv50_miptree *mt = nv50_miptree(tx->base.resource);
414ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller   unsigned i;
4154c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
4164c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   if (tx->base.usage & PIPE_TRANSFER_WRITE) {
4177fd29468ec68b5cd08222428577a7dbe8f123426Christoph Bumiller      for (i = 0; i < tx->nlayers; ++i) {
418e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller         nvc0->m2mf_copy_rect(nvc0, &tx->rect[0], &tx->rect[1],
419e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller                              tx->nblocksx, tx->nblocksy);
420ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller         if (mt->layout_3d)
421ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller            tx->rect[0].z++;
422ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller         else
423ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller            tx->rect[0].base += mt->layer_stride;
424ca5deb0c355cc4a120b754a228ff5f51007fbceaChristoph Bumiller         tx->rect[1].base += tx->nblocksy * tx->base.stride;
4254c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      }
4264c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   }
4274c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
4284c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   nouveau_bo_ref(NULL, &tx->rect[1].bo);
4294c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   pipe_resource_reference(&transfer->resource, NULL);
4304c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
4314c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   FREE(tx);
4324c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller}
4334c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
4344c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillervoid *
4354c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillernvc0_miptree_transfer_map(struct pipe_context *pctx,
4364c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller                          struct pipe_transfer *transfer)
4374c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller{
4386d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   struct nvc0_context *nvc0 = nvc0_context(pctx);
4394c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   struct nvc0_transfer *tx = (struct nvc0_transfer *)transfer;
4404c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   int ret;
4414c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   unsigned flags = 0;
4424c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
4434c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   if (tx->rect[1].bo->map)
4444c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      return tx->rect[1].bo->map;
4454c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
4464c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   if (transfer->usage & PIPE_TRANSFER_READ)
4474c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      flags = NOUVEAU_BO_RD;
4484c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   if (transfer->usage & PIPE_TRANSFER_WRITE)
4494c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      flags |= NOUVEAU_BO_WR;
4504c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
4516d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   ret = nouveau_bo_map(tx->rect[1].bo, flags, nvc0->screen->base.client);
4524c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   if (ret)
4534c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller      return NULL;
4544c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller   return tx->rect[1].bo->map;
4554c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller}
4564c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
4574c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillervoid
4584c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumillernvc0_miptree_transfer_unmap(struct pipe_context *pctx,
4594c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller                            struct pipe_transfer *transfer)
4604c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller{
4614c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller}
4624c2247538394a313e1e90bfcd07c1ab9c7d41281Christoph Bumiller
463d988361ead27ce61615669bd428b04d2aac7af4fChristoph Bumillervoid
464d988361ead27ce61615669bd428b04d2aac7af4fChristoph Bumillernvc0_cb_push(struct nouveau_context *nv,
465d988361ead27ce61615669bd428b04d2aac7af4fChristoph Bumiller             struct nouveau_bo *bo, unsigned domain,
466d988361ead27ce61615669bd428b04d2aac7af4fChristoph Bumiller             unsigned base, unsigned size,
467d988361ead27ce61615669bd428b04d2aac7af4fChristoph Bumiller             unsigned offset, unsigned words, const uint32_t *data)
468d988361ead27ce61615669bd428b04d2aac7af4fChristoph Bumiller{
4696d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   struct nouveau_bufctx *bctx = nvc0_context(&nv->pipe)->bufctx;
4706d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   struct nouveau_pushbuf *push = nv->pushbuf;
471d988361ead27ce61615669bd428b04d2aac7af4fChristoph Bumiller
472d988361ead27ce61615669bd428b04d2aac7af4fChristoph Bumiller   assert(!(offset & 3));
473d988361ead27ce61615669bd428b04d2aac7af4fChristoph Bumiller   size = align(size, 0x100);
474d988361ead27ce61615669bd428b04d2aac7af4fChristoph Bumiller
4756d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   nouveau_bufctx_refn(bctx, 0, bo, NOUVEAU_BO_WR | domain);
4766d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   nouveau_pushbuf_bufctx(push, bctx);
4776d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   nouveau_pushbuf_validate(push);
4786d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller
4796d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
4806d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   PUSH_DATA (push, size);
4816d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   PUSH_DATAh(push, bo->offset + base);
4826d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   PUSH_DATA (push, bo->offset + base);
483d988361ead27ce61615669bd428b04d2aac7af4fChristoph Bumiller
484d988361ead27ce61615669bd428b04d2aac7af4fChristoph Bumiller   while (words) {
4856d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      unsigned nr = PUSH_AVAIL(push);
486d988361ead27ce61615669bd428b04d2aac7af4fChristoph Bumiller      nr = MIN2(nr, words);
487d988361ead27ce61615669bd428b04d2aac7af4fChristoph Bumiller      nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN - 1);
488d988361ead27ce61615669bd428b04d2aac7af4fChristoph Bumiller
4896d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      BEGIN_1IC0(push, NVC0_3D(CB_POS), nr + 1);
4906d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATA (push, offset);
4916d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller      PUSH_DATAp(push, data, nr);
492d988361ead27ce61615669bd428b04d2aac7af4fChristoph Bumiller
493d988361ead27ce61615669bd428b04d2aac7af4fChristoph Bumiller      words -= nr;
494d988361ead27ce61615669bd428b04d2aac7af4fChristoph Bumiller      data += nr;
495d988361ead27ce61615669bd428b04d2aac7af4fChristoph Bumiller      offset += nr * 4;
496d988361ead27ce61615669bd428b04d2aac7af4fChristoph Bumiller   }
4976d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller
4986d1cdec3ba151168bfc3aef222fba6265dfb41fbChristoph Bumiller   nouveau_bufctx_reset(bctx, 0);
499d988361ead27ce61615669bd428b04d2aac7af4fChristoph Bumiller}
500e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller
501e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumillervoid
502e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumillernvc0_init_transfer_functions(struct nvc0_context *nvc0)
503e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller{
504e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   if (nvc0->screen->base.class_3d >= NVE4_3D_CLASS) {
505e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      nvc0->m2mf_copy_rect = nve4_m2mf_transfer_rect;
506e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      nvc0->base.copy_data = nve4_m2mf_copy_linear;
507e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      nvc0->base.push_data = nve4_p2mf_push_linear;
508e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   } else {
509e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      nvc0->m2mf_copy_rect = nvc0_m2mf_transfer_rect;
510e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      nvc0->base.copy_data = nvc0_m2mf_copy_linear;
511e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller      nvc0->base.push_data = nvc0_m2mf_push_linear;
512e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   }
513e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller   nvc0->base.push_cb = nvc0_cb_push;
514e44089b2f79aa2dcaacf348911433d1e21235c0cChristoph Bumiller}
515