summaryrefslogtreecommitdiff
path: root/src/nvc0_exa.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvc0_exa.c')
-rw-r--r--src/nvc0_exa.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/src/nvc0_exa.c b/src/nvc0_exa.c
index 4ba862d..8b6d51e 100644
--- a/src/nvc0_exa.c
+++ b/src/nvc0_exa.c
@@ -1006,3 +1006,60 @@ NVC0EXARectM2MF(NVPtr pNv, int w, int h, int cpp,
return TRUE;
}
+
+Bool
+NVE0EXARectCopy(NVPtr pNv, int w, int h, int cpp,
+ struct nouveau_bo *src, uint32_t src_off, int src_dom,
+ int src_pitch, int src_h, int src_x, int src_y,
+ struct nouveau_bo *dst, uint32_t dst_off, int dst_dom,
+ int dst_pitch, int dst_h, int dst_x, int dst_y)
+{
+ struct nouveau_pushbuf *push = pNv->pushbuf;
+ struct nouveau_pushbuf_refn refs[] = {
+ { src, src_dom | NOUVEAU_BO_RD },
+ { dst, dst_dom | NOUVEAU_BO_WR },
+ };
+ unsigned exec;
+
+ if (nouveau_pushbuf_space(push, 64, 0, 0) ||
+ nouveau_pushbuf_refn (push, refs, 2))
+ return FALSE;
+
+ exec = 0x00000206;
+ if (!src->config.nvc0.memtype) {
+ src_off += src_y * src_pitch + src_x * cpp;
+ exec |= 0x00000080;
+ }
+ if (!dst->config.nvc0.memtype) {
+ dst_off += dst_y * dst_pitch + dst_x * cpp;
+ exec |= 0x00000100;
+ }
+
+ BEGIN_NVC0(push, SUBC_COPY(0x0728), 6);
+ PUSH_DATA (push, 0x00001000 | src->config.nvc0.tile_mode);
+ PUSH_DATA (push, src_pitch);
+ PUSH_DATA (push, src_h);
+ PUSH_DATA (push, 1);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, (src_y << 16) | src_x * cpp);
+ BEGIN_NVC0(push, SUBC_COPY(0x070c), 6);
+ PUSH_DATA (push, 0x000001000 | dst->config.nvc0.tile_mode);
+ PUSH_DATA (push, dst_pitch);
+ PUSH_DATA (push, dst_h);
+ PUSH_DATA (push, 1);
+ PUSH_DATA (push, 0);
+ PUSH_DATA (push, (dst_y << 16) | dst_x * cpp);
+ BEGIN_NVC0(push, SUBC_COPY(0x0400), 8);
+ PUSH_DATA (push, (src->offset + src_off) >> 32);
+ PUSH_DATA (push, (src->offset + src_off));
+ PUSH_DATA (push, (dst->offset + dst_off) >> 32);
+ PUSH_DATA (push, (dst->offset + dst_off));
+ PUSH_DATA (push, src_pitch);
+ PUSH_DATA (push, dst_pitch);
+ PUSH_DATA (push, w * cpp);
+ PUSH_DATA (push, h);
+ BEGIN_NVC0(push, SUBC_COPY(0x0300), 1);
+ PUSH_DATA (push, exec);
+
+ return TRUE;
+}