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.c266
1 files changed, 90 insertions, 176 deletions
diff --git a/src/nvc0_exa.c b/src/nvc0_exa.c
index def0e5f..c553e68 100644
--- a/src/nvc0_exa.c
+++ b/src/nvc0_exa.c
@@ -27,182 +27,6 @@
#define NOUVEAU_BO(a, b, c) (NOUVEAU_BO_##a | NOUVEAU_BO_##b | NOUVEAU_BO_##c)
-Bool
-NVC0AccelDownloadM2MF(PixmapPtr pspix, int x, int y, int w, int h,
- char *dst, unsigned dst_pitch)
-{
- ScrnInfoPtr pScrn = xf86Screens[pspix->drawable.pScreen->myNum];
- NVPtr pNv = NVPTR(pScrn);
- struct nouveau_channel *chan = pNv->chan;
- struct nouveau_bo *bo = nouveau_pixmap_bo(pspix);
- struct nouveau_grobj *m2mf = pNv->NvMemFormat;
- const int cpp = pspix->drawable.bitsPerPixel / 8;
- const int line_len = w * cpp;
- const int line_limit = (128 << 10) / line_len;
- unsigned src_offset = 0, src_pitch = 0, tiled = 1;
-
- if (!nv50_style_tiled_pixmap(pspix)) {
- tiled = 0;
- src_pitch = exaGetPixmapPitch(pspix);
- src_offset = (y * src_pitch) + (x * cpp);
- } else {
- BEGIN_RING(chan, m2mf, NVC0_M2MF_TILING_MODE_IN, 5);
- OUT_RING (chan, bo->tile_mode);
- OUT_RING (chan, pspix->drawable.width * cpp);
- OUT_RING (chan, pspix->drawable.height);
- OUT_RING (chan, 1);
- OUT_RING (chan, 0);
- }
-
- while (h) {
- const char *src;
- int line_count, i;
-
- /* GART size >= 128 KiB assumed */
- line_count = h;
- if (line_count > line_limit)
- line_count = line_limit;
-
- MARK_RING(chan, 16, 4);
-
- BEGIN_RING(chan, m2mf, NVC0_M2MF_OFFSET_OUT_HIGH, 2);
- OUT_RELOCh(chan, pNv->GART, 0, NOUVEAU_BO(GART, GART, WR));
- OUT_RELOCl(chan, pNv->GART, 0, NOUVEAU_BO(GART, GART, WR));
-
- BEGIN_RING(chan, m2mf, NVC0_M2MF_OFFSET_IN_HIGH, 6);
- OUT_RELOCh(chan, bo, src_offset, NOUVEAU_BO(VRAM, GART, RD));
- OUT_RELOCl(chan, bo, src_offset, NOUVEAU_BO(VRAM, GART, RD));
- OUT_RING (chan, src_pitch);
- OUT_RING (chan, line_len);
- OUT_RING (chan, line_len);
- OUT_RING (chan, line_count);
-
- if (tiled) {
- BEGIN_RING(chan, m2mf,
- NVC0_M2MF_TILING_POSITION_IN_X, 2);
- OUT_RING (chan, x * cpp);
- OUT_RING (chan, y);
- }
-
- BEGIN_RING(chan, m2mf, NVC0_M2MF_EXEC, 1);
- OUT_RING (chan, 0x100000 | (tiled << 8));
-
- if (nouveau_bo_map(pNv->GART, NOUVEAU_BO_RD)) {
- MARK_UNDO(chan);
- return FALSE;
- }
- src = pNv->GART->map;
-
- if (dst_pitch == line_len) {
- memcpy(dst, src, dst_pitch * line_count);
- dst += dst_pitch * line_count;
- } else {
- for (i = 0; i < line_count; ++i) {
- memcpy(dst, src, line_len);
- src += line_len;
- dst += dst_pitch;
- }
- }
- nouveau_bo_unmap(pNv->GART);
-
- if (!tiled)
- src_offset += line_count * src_pitch;
- h -= line_count;
- y += line_count;
- }
-
- return TRUE;
-}
-
-Bool
-NVC0AccelUploadM2MF(PixmapPtr pdpix, int x, int y, int w, int h,
- const char *src, int src_pitch)
-{
- ScrnInfoPtr pScrn = xf86Screens[pdpix->drawable.pScreen->myNum];
- NVPtr pNv = NVPTR(pScrn);
- struct nouveau_channel *chan = pNv->chan;
- struct nouveau_bo *bo = nouveau_pixmap_bo(pdpix);
- struct nouveau_grobj *m2mf = pNv->NvMemFormat;
- int cpp = pdpix->drawable.bitsPerPixel / 8;
- int line_len = w * cpp;
- int line_limit = (128 << 10) / line_len;
- unsigned dst_offset = 0, dst_pitch = 0, tiled = 1;
-
- if (!nv50_style_tiled_pixmap(pdpix)) {
- tiled = 0;
- dst_pitch = exaGetPixmapPitch(pdpix);
- dst_offset = (y * dst_pitch) + (x * cpp);
- } else {
- BEGIN_RING(chan, m2mf, NVC0_M2MF_TILING_MODE_OUT, 5);
- OUT_RING (chan, bo->tile_mode);
- OUT_RING (chan, pdpix->drawable.width * cpp);
- OUT_RING (chan, pdpix->drawable.height);
- OUT_RING (chan, 1);
- OUT_RING (chan, 0);
- }
-
- while (h) {
- char *dst;
- int i, line_count;
-
- line_count = h;
- if (line_count > line_limit)
- line_count = line_limit;
-
- if (nouveau_bo_map(pNv->GART, NOUVEAU_BO_WR))
- return FALSE;
- dst = pNv->GART->map;
-
- if (src_pitch == line_len) {
- memcpy(dst, src, src_pitch * line_count);
- src += src_pitch * line_count;
- } else {
- for (i = 0; i < line_count; i++) {
- memcpy(dst, src, line_len);
- src += src_pitch;
- dst += line_len;
- }
- }
- nouveau_bo_unmap(pNv->GART);
-
- if (MARK_RING(chan, 16, 4))
- return FALSE;
-
- BEGIN_RING(chan, m2mf, NVC0_M2MF_OFFSET_IN_HIGH, 2);
- OUT_RELOCh(chan, pNv->GART, 0, NOUVEAU_BO(GART, GART, RD));
- OUT_RELOCl(chan, pNv->GART, 0, NOUVEAU_BO(GART, GART, RD));
-
- BEGIN_RING(chan, m2mf, NVC0_M2MF_OFFSET_OUT_HIGH, 2);
- OUT_RELOCh(chan, bo, dst_offset, NOUVEAU_BO(VRAM, GART, WR));
- OUT_RELOCl(chan, bo, dst_offset, NOUVEAU_BO(VRAM, GART, WR));
-
- if (tiled) {
- BEGIN_RING(chan, m2mf,
- NVC0_M2MF_TILING_POSITION_OUT_X, 2);
- OUT_RING (chan, x * cpp);
- OUT_RING (chan, y);
- }
-
- BEGIN_RING(chan, m2mf, NVC0_M2MF_PITCH_IN, 4);
- OUT_RING (chan, line_len);
- OUT_RING (chan, dst_pitch);
- OUT_RING (chan, line_len);
- OUT_RING (chan, line_count);
-
- BEGIN_RING(chan, m2mf, NVC0_M2MF_EXEC, 1);
- OUT_RING (chan, 0x100000 | (tiled << 4));
- FIRE_RING (chan);
-
- if (!tiled)
- dst_offset += line_count * dst_pitch;
- h -= line_count;
- y += line_count;
- }
-
- return TRUE;
-}
-
-
struct nvc0_exa_state {
struct {
PictTransformPtr transform;
@@ -1201,3 +1025,93 @@ NVC0EXADoneComposite(PixmapPtr pdpix)
chan->flush_notify = NULL;
}
+Bool
+NVC0EXARectM2MF(NVPtr pNv, int w, int h, int cpp,
+ struct nouveau_bo *src, int src_dom, int src_pitch,
+ int src_h, int src_x, int src_y, struct nouveau_bo *dst,
+ int dst_dom, int dst_pitch, int dst_h, int dst_x, int dst_y)
+{
+ struct nouveau_grobj *m2mf = pNv->NvMemFormat;
+ struct nouveau_channel *chan = m2mf->channel;
+ unsigned src_off = 0, dst_off = 0;
+ unsigned exec = 0;
+
+ if (src->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) {
+ BEGIN_RING(chan, m2mf, NVC0_M2MF_TILING_MODE_IN, 5);
+ OUT_RING (chan, src->tile_mode);
+ OUT_RING (chan, src_pitch);
+ OUT_RING (chan, src_h);
+ OUT_RING (chan, 1);
+ OUT_RING (chan, 0);
+ } else {
+ BEGIN_RING(chan, m2mf, NVC0_M2MF_PITCH_IN, 1);
+ OUT_RING (chan, src_pitch);
+
+ exec |= NVC0_M2MF_EXEC_LINEAR_IN;
+ }
+
+ if (dst->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) {
+ BEGIN_RING(chan, m2mf, NVC0_M2MF_TILING_MODE_OUT, 5);
+ OUT_RING (chan, dst->tile_mode);
+ OUT_RING (chan, dst_pitch);
+ OUT_RING (chan, dst_h);
+ OUT_RING (chan, 1);
+ OUT_RING (chan, 0);
+ } else {
+ BEGIN_RING(chan, m2mf, NVC0_M2MF_PITCH_OUT, 1);
+ OUT_RING (chan, dst_pitch);
+
+ exec |= NVC0_M2MF_EXEC_LINEAR_OUT;
+ }
+
+ while (h) {
+ int line_count = h;
+ if (line_count > 2047)
+ line_count = 2047;
+
+ if (MARK_RING (chan, 32, 4))
+ return FALSE;
+
+ if (src->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) {
+ BEGIN_RING(chan, m2mf, NVC0_M2MF_TILING_POSITION_IN_X, 2);
+ OUT_RING (chan, src_x * cpp);
+ OUT_RING (chan, src_y);
+ } else {
+ src_off = src_y * src_pitch + src_x * cpp;
+ }
+
+ if (dst->tile_flags & NOUVEAU_BO_TILE_LAYOUT_MASK) {
+ BEGIN_RING(chan, m2mf, NVC0_M2MF_TILING_POSITION_OUT_X, 2);
+ OUT_RING (chan, dst_x * cpp);
+ OUT_RING (chan, dst_y);
+ } else {
+ dst_off = dst_y * dst_pitch + dst_x * cpp;
+ }
+
+ BEGIN_RING(chan, m2mf, NVC0_M2MF_OFFSET_OUT_HIGH, 2);
+ if (OUT_RELOCh(chan, dst, dst_off, dst_dom | NOUVEAU_BO_WR) ||
+ OUT_RELOCl(chan, dst, dst_off, dst_dom | NOUVEAU_BO_WR)) {
+ MARK_UNDO(chan);
+ return FALSE;
+ }
+
+ BEGIN_RING(chan, m2mf, NVC0_M2MF_OFFSET_IN_HIGH, 2);
+ if (OUT_RELOCh(chan, src, src_off, src_dom | NOUVEAU_BO_RD) ||
+ OUT_RELOCl(chan, src, src_off, src_dom | NOUVEAU_BO_RD)) {
+ MARK_UNDO(chan);
+ return FALSE;
+ }
+
+ BEGIN_RING(chan, m2mf, NVC0_M2MF_LINE_LENGTH_IN, 2);
+ OUT_RING (chan, w * cpp);
+ OUT_RING (chan, line_count);
+ BEGIN_RING(chan, m2mf, NVC0_M2MF_EXEC, 1);
+ OUT_RING (chan, NVC0_M2MF_EXEC_QUERY_SHORT | exec);
+
+ src_y += line_count;
+ dst_y += line_count;
+ h -= line_count;
+ }
+
+ return TRUE;
+}