1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_format.h"
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "nvc0_context.h"
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "nv50/nv50_defs.xml.h"
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct nvc0_transfer {
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_transfer base;
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nv50_m2mf_rect rect[2];
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t nblocksx;
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint16_t nblocksy;
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint16_t nlayers;
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnvc0_m2mf_transfer_rect(struct nvc0_context *nvc0,
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct nv50_m2mf_rect *dst,
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct nv50_m2mf_rect *src,
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        uint32_t nblocksx, uint32_t nblocksy)
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_bufctx *bctx = nvc0->bufctx;
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const int cpp = dst->cpp;
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t src_ofst = src->base;
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t dst_ofst = dst->base;
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t height = nblocksy;
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t sy = src->y;
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t dy = dst->y;
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t exec = (1 << 20);
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(dst->cpp == src->cpp);
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_bufctx_refn(bctx, 0, src->bo, src->domain | NOUVEAU_BO_RD);
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_bufctx_refn(bctx, 0, dst->bo, dst->domain | NOUVEAU_BO_WR);
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_pushbuf_bufctx(push, bctx);
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_pushbuf_validate(push);
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (nouveau_bo_memtype(src->bo)) {
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NVC0(push, NVC0_M2MF(TILING_MODE_IN), 5);
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, src->tile_mode);
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, src->width * cpp);
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, src->height);
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, src->depth);
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, src->z);
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src_ofst += src->y * src->pitch + src->x * cpp;
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NVC0(push, NVC0_M2MF(PITCH_IN), 1);
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, src->width * cpp);
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      exec |= NVC0_M2MF_EXEC_LINEAR_IN;
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (nouveau_bo_memtype(dst->bo)) {
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NVC0(push, NVC0_M2MF(TILING_MODE_OUT), 5);
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, dst->tile_mode);
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, dst->width * cpp);
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, dst->height);
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, dst->depth);
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, dst->z);
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst_ofst += dst->y * dst->pitch + dst->x * cpp;
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NVC0(push, NVC0_M2MF(PITCH_OUT), 1);
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, dst->width * cpp);
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      exec |= NVC0_M2MF_EXEC_LINEAR_OUT;
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   while (height) {
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      int line_count = height > 2047 ? 2047 : height;
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NVC0(push, NVC0_M2MF(OFFSET_IN_HIGH), 2);
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATAh(push, src->bo->offset + src_ofst);
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, src->bo->offset + src_ofst);
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2);
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATAh(push, dst->bo->offset + dst_ofst);
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, dst->bo->offset + dst_ofst);
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!(exec & NVC0_M2MF_EXEC_LINEAR_IN)) {
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         BEGIN_NVC0(push, NVC0_M2MF(TILING_POSITION_IN_X), 2);
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, src->x * cpp);
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, sy);
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         src_ofst += line_count * src->pitch;
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!(exec & NVC0_M2MF_EXEC_LINEAR_OUT)) {
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         BEGIN_NVC0(push, NVC0_M2MF(TILING_POSITION_OUT_X), 2);
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, dst->x * cpp);
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         PUSH_DATA (push, dy);
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      } else {
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         dst_ofst += line_count * dst->pitch;
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2);
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, nblocksx * cpp);
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, line_count);
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1);
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, exec);
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      height -= line_count;
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      sy += line_count;
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dy += line_count;
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_bufctx_reset(bctx, 0);
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnve4_m2mf_transfer_rect(struct nvc0_context *nvc0,
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct nv50_m2mf_rect *dst,
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        const struct nv50_m2mf_rect *src,
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        uint32_t nblocksx, uint32_t nblocksy)
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_pushbuf *push = nvc0->base.pushbuf;
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_bufctx *bctx = nvc0->bufctx;
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t exec;
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t src_base = src->base;
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t dst_base = dst->base;
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   const int cpp = dst->cpp;
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(dst->cpp == src->cpp);
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_bufctx_refn(bctx, 0, dst->bo, dst->domain | NOUVEAU_BO_WR);
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_bufctx_refn(bctx, 0, src->bo, src->domain | NOUVEAU_BO_RD);
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_pushbuf_bufctx(push, bctx);
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_pushbuf_validate(push);
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   exec = 0x200 /* 2D_ENABLE */ | 0x6 /* UNK */;
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!nouveau_bo_memtype(dst->bo)) {
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(!dst->z);
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dst_base += dst->y * dst->pitch + dst->x * cpp;
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      exec |= 0x100; /* DST_MODE_2D_LINEAR */
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!nouveau_bo_memtype(src->bo)) {
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(!src->z);
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src_base += src->y * src->pitch + src->x * cpp;
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      exec |= 0x080; /* SRC_MODE_2D_LINEAR */
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   BEGIN_NVC0(push, SUBC_COPY(0x070c), 6);
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, 0x1000 | dst->tile_mode);
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, dst->pitch);
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, dst->height);
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, dst->depth);
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, dst->z);
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, (dst->y << 16) | (dst->x * cpp));
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   BEGIN_NVC0(push, SUBC_COPY(0x0728), 6);
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, 0x1000 | src->tile_mode);
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, src->pitch);
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, src->height);
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, src->depth);
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, src->z);
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, (src->y << 16) | (src->x * cpp));
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   BEGIN_NVC0(push, SUBC_COPY(0x0400), 8);
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATAh(push, src->bo->offset + src_base);
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, src->bo->offset + src_base);
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATAh(push, dst->bo->offset + dst_base);
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, dst->bo->offset + dst_base);
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, src->pitch);
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, dst->pitch);
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, nblocksx * cpp);
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, nblocksy);
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   BEGIN_NVC0(push, SUBC_COPY(0x0300), 1);
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, exec);
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_bufctx_reset(bctx, 0);
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnvc0_m2mf_push_linear(struct nouveau_context *nv,
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      struct nouveau_bo *dst, unsigned offset, unsigned domain,
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      unsigned size, const void *data)
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nvc0_context *nvc0 = nvc0_context(&nv->pipe);
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_pushbuf *push = nv->pushbuf;
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t *src = (uint32_t *)data;
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned count = (size + 3) / 4;
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_bufctx_refn(nvc0->bufctx, 0, dst, domain | NOUVEAU_BO_WR);
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_pushbuf_bufctx(push, nvc0->bufctx);
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_pushbuf_validate(push);
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   while (count) {
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned nr;
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!PUSH_SPACE(push, 16))
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nr = PUSH_AVAIL(push);
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(nr >= 16);
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nr = MIN2(count, nr - 9);
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN);
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2);
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATAh(push, dst->offset + offset);
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, dst->offset + offset);
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2);
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, nr * 4);
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, 1);
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1);
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, 0x100111);
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* must not be interrupted (trap on QUERY fence, 0x50 works however) */
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NIC0(push, NVC0_M2MF(DATA), nr);
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATAp(push, src, nr);
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      count -= nr;
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src += nr;
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      offset += nr * 4;
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_bufctx_reset(nvc0->bufctx, 0);
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnve4_p2mf_push_linear(struct nouveau_context *nv,
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      struct nouveau_bo *dst, unsigned offset, unsigned domain,
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      unsigned size, const void *data)
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nvc0_context *nvc0 = nvc0_context(&nv->pipe);
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_pushbuf *push = nv->pushbuf;
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t *src = (uint32_t *)data;
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned count = (size + 3) / 4;
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_bufctx_refn(nvc0->bufctx, 0, dst, domain | NOUVEAU_BO_WR);
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_pushbuf_bufctx(push, nvc0->bufctx);
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_pushbuf_validate(push);
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   while (count) {
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned nr;
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (!PUSH_SPACE(push, 16))
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         break;
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nr = PUSH_AVAIL(push);
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(nr >= 16);
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nr = MIN2(count, nr - 8);
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nr = MIN2(nr, (NV04_PFIFO_MAX_PACKET_LEN - 1));
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NVC0(push, NVE4_P2MF(DST_ADDRESS_HIGH), 2);
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATAh(push, dst->offset + offset);
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, dst->offset + offset);
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NVC0(push, NVE4_P2MF(LINE_LENGTH_IN), 2);
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, nr * 4);
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, 1);
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      /* must not be interrupted (trap on QUERY fence, 0x50 works however) */
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_1IC0(push, NVE4_P2MF(EXEC), nr + 1);
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, 0x1001);
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATAp(push, src, nr);
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      count -= nr;
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      src += nr;
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      offset += nr * 4;
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_bufctx_reset(nvc0->bufctx, 0);
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnvc0_m2mf_copy_linear(struct nouveau_context *nv,
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom,
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      struct nouveau_bo *src, unsigned srcoff, unsigned srcdom,
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      unsigned size)
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_pushbuf *push = nv->pushbuf;
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_bufctx *bctx = nvc0_context(&nv->pipe)->bufctx;
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_bufctx_refn(bctx, 0, src, srcdom | NOUVEAU_BO_RD);
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_bufctx_refn(bctx, 0, dst, dstdom | NOUVEAU_BO_WR);
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_pushbuf_bufctx(push, bctx);
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_pushbuf_validate(push);
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   while (size) {
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned bytes = MIN2(size, 1 << 17);
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NVC0(push, NVC0_M2MF(OFFSET_OUT_HIGH), 2);
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATAh(push, dst->offset + dstoff);
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, dst->offset + dstoff);
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NVC0(push, NVC0_M2MF(OFFSET_IN_HIGH), 2);
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATAh(push, src->offset + srcoff);
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, src->offset + srcoff);
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NVC0(push, NVC0_M2MF(LINE_LENGTH_IN), 2);
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, bytes);
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, 1);
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_NVC0(push, NVC0_M2MF(EXEC), 1);
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, (1 << NVC0_M2MF_EXEC_INC__SHIFT) |
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                 NVC0_M2MF_EXEC_LINEAR_IN | NVC0_M2MF_EXEC_LINEAR_OUT);
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      srcoff += bytes;
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      dstoff += bytes;
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      size -= bytes;
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_bufctx_reset(bctx, 0);
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnve4_m2mf_copy_linear(struct nouveau_context *nv,
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      struct nouveau_bo *dst, unsigned dstoff, unsigned dstdom,
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      struct nouveau_bo *src, unsigned srcoff, unsigned srcdom,
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                      unsigned size)
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_pushbuf *push = nv->pushbuf;
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_bufctx *bctx = nvc0_context(&nv->pipe)->bufctx;
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_bufctx_refn(bctx, 0, src, srcdom | NOUVEAU_BO_RD);
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_bufctx_refn(bctx, 0, dst, dstdom | NOUVEAU_BO_WR);
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_pushbuf_bufctx(push, bctx);
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_pushbuf_validate(push);
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   BEGIN_NVC0(push, SUBC_COPY(0x0400), 4);
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATAh(push, src->offset + srcoff);
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, src->offset + srcoff);
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATAh(push, dst->offset + dstoff);
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, dst->offset + dstoff);
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   BEGIN_NVC0(push, SUBC_COPY(0x0418), 1);
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, size);
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   BEGIN_NVC0(push, SUBC_COPY(0x0300), 1);
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, 0x186);
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_bufctx_reset(bctx, 0);
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct pipe_transfer *
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnvc0_miptree_transfer_new(struct pipe_context *pctx,
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          struct pipe_resource *res,
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          unsigned level,
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          unsigned usage,
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          const struct pipe_box *box)
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nvc0_context *nvc0 = nvc0_context(pctx);
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_device *dev = nvc0->screen->base.device;
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nv50_miptree *mt = nv50_miptree(res);
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nvc0_transfer *tx;
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   uint32_t size;
341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int ret;
342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (usage & PIPE_TRANSFER_MAP_DIRECTLY)
344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tx = CALLOC_STRUCT(nvc0_transfer);
347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!tx)
348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_resource_reference(&tx->base.resource, res);
351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tx->base.level = level;
353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tx->base.usage = usage;
354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tx->base.box = *box;
355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (util_format_is_plain(res->format)) {
357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tx->nblocksx = box->width << mt->ms_x;
358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tx->nblocksy = box->height << mt->ms_y;
359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tx->nblocksx = util_format_get_nblocksx(res->format, box->width);
361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tx->nblocksy = util_format_get_nblocksy(res->format, box->height);
362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tx->nlayers = box->depth;
364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tx->base.stride = tx->nblocksx * util_format_get_blocksize(res->format);
366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tx->base.layer_stride = tx->nblocksy * tx->base.stride;
367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nv50_m2mf_rect_setup(&tx->rect[0], res, level, box->x, box->y, box->z);
369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   size = tx->base.layer_stride;
371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0,
373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                        size * tx->nlayers, NULL, &tx->rect[1].bo);
374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ret) {
375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FREE(tx);
376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tx->rect[1].cpp = tx->rect[0].cpp;
380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tx->rect[1].width = tx->nblocksx;
381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tx->rect[1].height = tx->nblocksy;
382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tx->rect[1].depth = 1;
383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tx->rect[1].pitch = tx->base.stride;
384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   tx->rect[1].domain = NOUVEAU_BO_GART;
385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (usage & PIPE_TRANSFER_READ) {
387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned base = tx->rect[0].base;
388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned z = tx->rect[0].z;
389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned i;
390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < tx->nlayers; ++i) {
391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         nvc0->m2mf_copy_rect(nvc0, &tx->rect[1], &tx->rect[0],
392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              tx->nblocksx, tx->nblocksy);
393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (mt->layout_3d)
394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            tx->rect[0].z++;
395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else
396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            tx->rect[0].base += mt->layer_stride;
397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tx->rect[1].base += size;
398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tx->rect[0].z = z;
400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tx->rect[0].base = base;
401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      tx->rect[1].base = 0;
402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return &tx->base;
405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnvc0_miptree_transfer_del(struct pipe_context *pctx,
409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          struct pipe_transfer *transfer)
410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nvc0_context *nvc0 = nvc0_context(pctx);
412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nvc0_transfer *tx = (struct nvc0_transfer *)transfer;
413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nv50_miptree *mt = nv50_miptree(tx->base.resource);
414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned i;
415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (tx->base.usage & PIPE_TRANSFER_WRITE) {
417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (i = 0; i < tx->nlayers; ++i) {
418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         nvc0->m2mf_copy_rect(nvc0, &tx->rect[0], &tx->rect[1],
419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                              tx->nblocksx, tx->nblocksy);
420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         if (mt->layout_3d)
421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            tx->rect[0].z++;
422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         else
423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            tx->rect[0].base += mt->layer_stride;
424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         tx->rect[1].base += tx->nblocksy * tx->base.stride;
425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_bo_ref(NULL, &tx->rect[1].bo);
429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe_resource_reference(&transfer->resource, NULL);
430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   FREE(tx);
432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid *
435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnvc0_miptree_transfer_map(struct pipe_context *pctx,
436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                          struct pipe_transfer *transfer)
437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nvc0_context *nvc0 = nvc0_context(pctx);
439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nvc0_transfer *tx = (struct nvc0_transfer *)transfer;
440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int ret;
441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned flags = 0;
442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (tx->rect[1].bo->map)
444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return tx->rect[1].bo->map;
445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (transfer->usage & PIPE_TRANSFER_READ)
447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      flags = NOUVEAU_BO_RD;
448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (transfer->usage & PIPE_TRANSFER_WRITE)
449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      flags |= NOUVEAU_BO_WR;
450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ret = nouveau_bo_map(tx->rect[1].bo, flags, nvc0->screen->base.client);
452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ret)
453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return NULL;
454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return tx->rect[1].bo->map;
455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnvc0_miptree_transfer_unmap(struct pipe_context *pctx,
459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                            struct pipe_transfer *transfer)
460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnvc0_cb_push(struct nouveau_context *nv,
465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             struct nouveau_bo *bo, unsigned domain,
466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             unsigned base, unsigned size,
467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org             unsigned offset, unsigned words, const uint32_t *data)
468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_bufctx *bctx = nvc0_context(&nv->pipe)->bufctx;
470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct nouveau_pushbuf *push = nv->pushbuf;
471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(!(offset & 3));
473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   size = align(size, 0x100);
474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_bufctx_refn(bctx, 0, bo, NOUVEAU_BO_WR | domain);
476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_pushbuf_bufctx(push, bctx);
477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_pushbuf_validate(push);
478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   BEGIN_NVC0(push, NVC0_3D(CB_SIZE), 3);
480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, size);
481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATAh(push, bo->offset + base);
482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   PUSH_DATA (push, bo->offset + base);
483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   while (words) {
485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      unsigned nr = PUSH_AVAIL(push);
486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nr = MIN2(nr, words);
487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN - 1);
488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      BEGIN_1IC0(push, NVC0_3D(CB_POS), nr + 1);
490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATA (push, offset);
491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      PUSH_DATAp(push, data, nr);
492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      words -= nr;
494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      data += nr;
495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      offset += nr * 4;
496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nouveau_bufctx_reset(bctx, 0);
499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid
502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnvc0_init_transfer_functions(struct nvc0_context *nvc0)
503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (nvc0->screen->base.class_3d >= NVE4_3D_CLASS) {
505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nvc0->m2mf_copy_rect = nve4_m2mf_transfer_rect;
506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nvc0->base.copy_data = nve4_m2mf_copy_linear;
507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nvc0->base.push_data = nve4_p2mf_push_linear;
508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   } else {
509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nvc0->m2mf_copy_rect = nvc0_m2mf_transfer_rect;
510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nvc0->base.copy_data = nvc0_m2mf_copy_linear;
511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      nvc0->base.push_data = nvc0_m2mf_push_linear;
512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   nvc0->base.push_cb = nvc0_cb_push;
514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
515