static void nv30_transfer_rect_m2mf(XFER_ARGS) { struct nouveau_pushbuf *push = nv30->base.pushbuf; struct nouveau_pushbuf_refn refs[] = { { src->bo, src->domain | NOUVEAU_BO_RD }, { dst->bo, dst->domain | NOUVEAU_BO_WR }, }; struct nv04_fifo *fifo = push->channel->data; unsigned src_offset = src->offset; unsigned dst_offset = dst->offset; unsigned w = dst->x1 - dst->x0; unsigned h = dst->y1 - dst->y0; src_offset += (src->y0 * src->pitch) + (src->x0 * src->cpp); dst_offset += (dst->y0 * dst->pitch) + (dst->x0 * dst->cpp); BEGIN_NV04(push, NV03_M2MF(DMA_BUFFER_IN), 2); PUSH_DATA (push, (src->domain == NOUVEAU_BO_VRAM) ? fifo->vram : fifo->gart); PUSH_DATA (push, (dst->domain == NOUVEAU_BO_VRAM) ? fifo->vram : fifo->gart); while (h) { unsigned lines = (h > 2047) ? 2047 : h; if (nouveau_pushbuf_space(push, 13, 2, 0) || nouveau_pushbuf_refn (push, refs, 2)) return; BEGIN_NV04(push, NV03_M2MF(OFFSET_IN), 8); PUSH_RELOC(push, src->bo, src_offset, NOUVEAU_BO_LOW, 0, 0); PUSH_RELOC(push, dst->bo, dst_offset, NOUVEAU_BO_LOW, 0, 0); PUSH_DATA (push, src->pitch); PUSH_DATA (push, dst->pitch); PUSH_DATA (push, w * src->cpp); PUSH_DATA (push, lines); PUSH_DATA (push, NV03_M2MF_FORMAT_INPUT_INC_1 | NV03_M2MF_FORMAT_OUTPUT_INC_1); PUSH_DATA (push, 0x00000000); BEGIN_NV04(push, NV04_GRAPH(M2MF, NOP), 1); PUSH_DATA (push, 0x00000000); BEGIN_NV04(push, NV03_M2MF(OFFSET_OUT), 1); PUSH_DATA (push, 0x00000000); h -= lines; src_offset += src->pitch * lines; dst_offset += dst->pitch * lines; } }
static void nv04_surface_copy_m2mf(struct gl_context *ctx, struct nouveau_surface *dst, struct nouveau_surface *src, int dx, int dy, int sx, int sy, int w, int h) { struct nouveau_pushbuf_refn refs[] = { { src->bo, NOUVEAU_BO_RD | NOUVEAU_BO_VRAM | NOUVEAU_BO_GART }, { dst->bo, NOUVEAU_BO_WR | NOUVEAU_BO_VRAM | NOUVEAU_BO_GART }, }; struct nouveau_pushbuf *push = context_push(ctx); struct nouveau_hw_state *hw = &to_nouveau_context(ctx)->hw; struct nv04_fifo *fifo = hw->chan->data; unsigned dst_offset = dst->offset + dy * dst->pitch + dx * dst->cpp; unsigned src_offset = src->offset + sy * src->pitch + sx * src->cpp; while (h) { int count = (h > 2047) ? 2047 : h; if (nouveau_pushbuf_space(push, 16, 4, 0) || nouveau_pushbuf_refn (push, refs, 2)) return; BEGIN_NV04(push, NV03_M2MF(DMA_BUFFER_IN), 2); PUSH_RELOC(push, src->bo, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart); PUSH_RELOC(push, dst->bo, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart); BEGIN_NV04(push, NV03_M2MF(OFFSET_IN), 8); PUSH_RELOC(push, src->bo, src->offset, NOUVEAU_BO_LOW, 0, 0); PUSH_RELOC(push, dst->bo, dst->offset, NOUVEAU_BO_LOW, 0, 0); PUSH_DATA (push, src->pitch); PUSH_DATA (push, dst->pitch); PUSH_DATA (push, w * src->cpp); PUSH_DATA (push, count); PUSH_DATA (push, 0x0101); PUSH_DATA (push, 0); src_offset += src->pitch * count; dst_offset += dst->pitch * count; h -= count; } }
void nv30_transfer_copy_data(struct nouveau_context *nv, struct nouveau_bo *dst, unsigned d_off, unsigned d_dom, struct nouveau_bo *src, unsigned s_off, unsigned s_dom, unsigned size) { struct nv04_fifo *fifo = nv->screen->channel->data; struct nouveau_pushbuf_refn refs[] = { { src, s_dom | NOUVEAU_BO_RD }, { dst, d_dom | NOUVEAU_BO_WR }, }; struct nouveau_pushbuf *push = nv->pushbuf; unsigned pages, lines; pages = size >> 12; size -= (pages << 12); BEGIN_NV04(push, NV03_M2MF(DMA_BUFFER_IN), 2); PUSH_DATA (push, (s_dom == NOUVEAU_BO_VRAM) ? fifo->vram : fifo->gart); PUSH_DATA (push, (d_dom == NOUVEAU_BO_VRAM) ? fifo->vram : fifo->gart); while (pages) { lines = (pages > 2047) ? 2047 : pages; pages -= lines; if (nouveau_pushbuf_space(push, 13, 2, 0) || nouveau_pushbuf_refn (push, refs, 2)) return; BEGIN_NV04(push, NV03_M2MF(OFFSET_IN), 8); PUSH_RELOC(push, src, s_off, NOUVEAU_BO_LOW, 0, 0); PUSH_RELOC(push, dst, d_off, NOUVEAU_BO_LOW, 0, 0); PUSH_DATA (push, 4096); PUSH_DATA (push, 4096); PUSH_DATA (push, 4096); PUSH_DATA (push, lines); PUSH_DATA (push, NV03_M2MF_FORMAT_INPUT_INC_1 | NV03_M2MF_FORMAT_OUTPUT_INC_1); PUSH_DATA (push, 0x00000000); BEGIN_NV04(push, NV04_GRAPH(M2MF, NOP), 1); PUSH_DATA (push, 0x00000000); BEGIN_NV04(push, NV03_M2MF(OFFSET_OUT), 1); PUSH_DATA (push, 0x00000000); s_off += (lines << 12); d_off += (lines << 12); } if (size) { if (nouveau_pushbuf_space(push, 13, 2, 0) || nouveau_pushbuf_refn (push, refs, 2)) return; BEGIN_NV04(push, NV03_M2MF(OFFSET_IN), 8); PUSH_RELOC(push, src, s_off, NOUVEAU_BO_LOW, 0, 0); PUSH_RELOC(push, dst, d_off, NOUVEAU_BO_LOW, 0, 0); PUSH_DATA (push, size); PUSH_DATA (push, size); PUSH_DATA (push, size); PUSH_DATA (push, 1); PUSH_DATA (push, NV03_M2MF_FORMAT_INPUT_INC_1 | NV03_M2MF_FORMAT_OUTPUT_INC_1); PUSH_DATA (push, 0x00000000); BEGIN_NV04(push, NV04_GRAPH(M2MF, NOP), 1); PUSH_DATA (push, 0x00000000); BEGIN_NV04(push, NV03_M2MF(OFFSET_OUT), 1); PUSH_DATA (push, 0x00000000); } }