summaryrefslogtreecommitdiff
path: root/src/gallium/winsys/dri/nouveau/nv50_surface.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/winsys/dri/nouveau/nv50_surface.c')
-rw-r--r--src/gallium/winsys/dri/nouveau/nv50_surface.c158
1 files changed, 82 insertions, 76 deletions
diff --git a/src/gallium/winsys/dri/nouveau/nv50_surface.c b/src/gallium/winsys/dri/nouveau/nv50_surface.c
index cf76d76cf5..c8ab7f690f 100644
--- a/src/gallium/winsys/dri/nouveau/nv50_surface.c
+++ b/src/gallium/winsys/dri/nouveau/nv50_surface.c
@@ -22,52 +22,70 @@ nv50_format(enum pipe_format format)
}
static int
-nv50_surface_copy_prep(struct nouveau_context *nv,
- struct pipe_surface *dst, struct pipe_surface *src)
+nv50_surface_set(struct nouveau_context *nv, struct pipe_surface *surf, int dst)
{
struct nouveau_channel *chan = nv->nvc->channel;
struct nouveau_grobj *eng2d = nv->nvc->Nv2D;
- int surf_format;
-
- assert(src->format == dst->format);
+ struct nouveau_bo *bo = nouveau_buffer(surf->buffer)->bo;
+ int surf_format, mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT;
+ int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD);
+
+ surf_format = nv50_format(surf->format);
+ if (surf_format < 0)
+ return 1;
+
+ if (!nouveau_bo(bo)->tiled) {
+ BEGIN_RING(chan, eng2d, mthd, 2);
+ OUT_RING (chan, surf_format);
+ OUT_RING (chan, 1);
+ BEGIN_RING(chan, eng2d, mthd + 0x14, 5);
+ OUT_RING (chan, surf->stride);
+ OUT_RING (chan, surf->width);
+ OUT_RING (chan, surf->height);
+ OUT_RELOCh(chan, bo, surf->offset, flags);
+ OUT_RELOCl(chan, bo, surf->offset, flags);
+ } else {
+ BEGIN_RING(chan, eng2d, mthd, 5);
+ OUT_RING (chan, surf_format);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, 1);
+ OUT_RING (chan, 0);
+ BEGIN_RING(chan, eng2d, mthd + 0x18, 4);
+ OUT_RING (chan, surf->width);
+ OUT_RING (chan, surf->height);
+ OUT_RELOCh(chan, bo, surf->offset, flags);
+ OUT_RELOCl(chan, bo, surf->offset, flags);
+ }
+
+#if 0
+ if (dst) {
+ BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, surf->width);
+ OUT_RING (chan, surf->height);
+ }
+#endif
+
+ return 0;
+}
- surf_format = nv50_format(dst->format);
- assert(surf_format >= 0);
+static int
+nv50_surface_copy_prep(struct nouveau_context *nv,
+ struct pipe_surface *dst, struct pipe_surface *src)
+{
+ int ret;
- BEGIN_RING(chan, eng2d, NV50_2D_DMA_IN_MEMORY0, 2);
- OUT_RELOCo(chan, nouveau_buffer(src->buffer)->bo,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
- OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ assert(src->format == dst->format);
- BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 2);
- OUT_RING (chan, surf_format);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, eng2d, NV50_2D_DST_PITCH, 5);
- OUT_RING (chan, dst->stride);
- OUT_RING (chan, dst->width);
- OUT_RING (chan, dst->height);
- OUT_RELOCh(chan, nouveau_buffer(dst->buffer)->bo, dst->offset,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
- OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
- BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4);
- OUT_RING (chan, 0);
- OUT_RING (chan, 0);
- OUT_RING (chan, dst->width);
- OUT_RING (chan, dst->height);
+ ret = nv50_surface_set(nv, dst, 1);
+ if (ret)
+ return ret;
- BEGIN_RING(chan, eng2d, NV50_2D_SRC_FORMAT, 2);
- OUT_RING (chan, surf_format);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, eng2d, NV50_2D_SRC_PITCH, 5);
- OUT_RING (chan, src->stride);
- OUT_RING (chan, src->width);
- OUT_RING (chan, src->height);
- OUT_RELOCh(chan, nouveau_buffer(src->buffer)->bo, src->offset,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
- OUT_RELOCl(chan, nouveau_buffer(src->buffer)->bo, src->offset,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+ ret = nv50_surface_set(nv, src, 0);
+ if (ret)
+ return ret;
return 0;
}
@@ -79,17 +97,19 @@ nv50_surface_copy(struct nouveau_context *nv, unsigned dx, unsigned dy,
struct nouveau_channel *chan = nv->nvc->channel;
struct nouveau_grobj *eng2d = nv->nvc->Nv2D;
- BEGIN_RING(chan, eng2d, 0x0110, 1);
+ BEGIN_RING(chan, eng2d, 0x088c, 1);
OUT_RING (chan, 0);
- BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 12);
+ BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 4);
OUT_RING (chan, dx);
OUT_RING (chan, dy);
OUT_RING (chan, w);
OUT_RING (chan, h);
+ BEGIN_RING(chan, eng2d, 0x08c0, 4);
OUT_RING (chan, 0);
OUT_RING (chan, 1);
OUT_RING (chan, 0);
OUT_RING (chan, 1);
+ BEGIN_RING(chan, eng2d, 0x08d0, 4);
OUT_RING (chan, 0);
OUT_RING (chan, sx);
OUT_RING (chan, 0);
@@ -109,35 +129,15 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst,
{
struct nouveau_channel *chan = nv->nvc->channel;
struct nouveau_grobj *eng2d = nv->nvc->Nv2D;
- int surf_format, rect_format;
-
- surf_format = nv50_format(dst->format);
- if (surf_format < 0)
- return 1;
+ int rect_format, ret;
rect_format = nv50_format(dst->format);
if (rect_format < 0)
return 1;
- BEGIN_RING(chan, eng2d, NV50_2D_DMA_IN_MEMORY1, 1);
- OUT_RELOCo(chan, nouveau_buffer(dst->buffer)->bo,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
- BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 2);
- OUT_RING (chan, surf_format);
- OUT_RING (chan, 1);
- BEGIN_RING(chan, eng2d, NV50_2D_DST_PITCH, 5);
- OUT_RING (chan, dst->stride);
- OUT_RING (chan, dst->width);
- OUT_RING (chan, dst->height);
- OUT_RELOCh(chan, nouveau_buffer(dst->buffer)->bo, dst->offset,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
- OUT_RELOCl(chan, nouveau_buffer(dst->buffer)->bo, dst->offset,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
- BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4);
- OUT_RING (chan, 0);
- OUT_RING (chan, 0);
- OUT_RING (chan, dst->width);
- OUT_RING (chan, dst->height);
+ ret = nv50_surface_set(nv, dst, 1);
+ if (ret)
+ return ret;
BEGIN_RING(chan, eng2d, 0x0580, 3);
OUT_RING (chan, 4);
@@ -151,27 +151,33 @@ nv50_surface_fill(struct nouveau_context *nv, struct pipe_surface *dst,
OUT_RING (chan, dy + h);
FIRE_RING(chan);
-
return 0;
}
int
nouveau_surface_channel_create_nv50(struct nouveau_channel_context *nvc)
{
+ struct nouveau_channel *chan = nvc->channel;
+ struct nouveau_grobj *eng2d = NULL;
int ret;
- ret = nouveau_grobj_alloc(nvc->channel, nvc->next_handle++, NV50_2D,
- &nvc->Nv2D);
+ ret = nouveau_grobj_alloc(chan, nvc->next_handle++, NV50_2D, &eng2d);
if (ret)
return ret;
- BIND_RING (nvc->channel, nvc->Nv2D, nvc->next_subchannel++);
- BEGIN_RING(nvc->channel, nvc->Nv2D, NV50_2D_DMA_NOTIFY, 1);
- OUT_RING (nvc->channel, nvc->sync_notifier->handle);
- BEGIN_RING(nvc->channel, nvc->Nv2D, NV50_2D_DMA_IN_MEMORY0, 2);
- OUT_RING (nvc->channel, nvc->channel->vram->handle);
- OUT_RING (nvc->channel, nvc->channel->vram->handle);
- BEGIN_RING(nvc->channel, nvc->Nv2D, NV50_2D_OPERATION, 1);
- OUT_RING (nvc->channel, NV50_2D_OPERATION_SRCCOPY);
+ nvc->Nv2D = eng2d;
+
+ BIND_RING (chan, eng2d, nvc->next_subchannel++);
+ BEGIN_RING(chan, eng2d, NV50_2D_DMA_NOTIFY, 4);
+ OUT_RING (chan, nvc->sync_notifier->handle);
+ OUT_RING (chan, chan->vram->handle);
+ OUT_RING (chan, chan->vram->handle);
+ OUT_RING (chan, chan->vram->handle);
+ BEGIN_RING(chan, eng2d, NV50_2D_OPERATION, 1);
+ OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY);
+ BEGIN_RING(chan, eng2d, 0x0290, 1);
+ OUT_RING (chan, 0);
+ BEGIN_RING(chan, eng2d, 0x0888, 1);
+ OUT_RING (chan, 1);
return 0;
}