diff options
Diffstat (limited to 'src/nvc0_exa.c')
-rw-r--r-- | src/nvc0_exa.c | 57 |
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; +} |