summaryrefslogtreecommitdiff
path: root/src/nv04_exa.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nv04_exa.c')
-rw-r--r--src/nv04_exa.c524
1 files changed, 244 insertions, 280 deletions
diff --git a/src/nv04_exa.c b/src/nv04_exa.c
index 29b8c10..77bb3b7 100644
--- a/src/nv04_exa.c
+++ b/src/nv04_exa.c
@@ -23,229 +23,206 @@
#include "nv_include.h"
#include "nv_rop.h"
-
#include "hwdefs/nv_object.xml.h"
#include "hwdefs/nv_m2mf.xml.h"
#include "hwdefs/nv01_2d.xml.h"
+#include "nv04_accel.h"
static void
-NV04EXASetPattern(ScrnInfoPtr pScrn, CARD32 clr0, CARD32 clr1,
- CARD32 pat0, CARD32 pat1)
+NV04EXASetPattern(NVPtr pNv, CARD32 clr0, CARD32 clr1, CARD32 pat0, CARD32 pat1)
{
- NVPtr pNv = NVPTR(pScrn);
- struct nouveau_channel *chan = pNv->chan;
-
- BEGIN_NV04(chan, NV01_SUBC(MISC, OBJECT), 1);
- OUT_RING (chan, pNv->NvImagePattern->handle);
- BEGIN_NV04(chan, NV01_PATT(MONOCHROME_COLOR(0)), 4);
- OUT_RING (chan, clr0);
- OUT_RING (chan, clr1);
- OUT_RING (chan, pat0);
- OUT_RING (chan, pat1);
+ struct nouveau_pushbuf *push = pNv->pushbuf;
+
+ BEGIN_NV04(push, NV01_SUBC(MISC, OBJECT), 1);
+ PUSH_DATA (push, pNv->NvImagePattern->handle);
+ BEGIN_NV04(push, NV01_PATT(MONOCHROME_COLOR(0)), 4);
+ PUSH_DATA (push, clr0);
+ PUSH_DATA (push, clr1);
+ PUSH_DATA (push, pat0);
+ PUSH_DATA (push, pat1);
}
-static void
-NV04EXASetROP(ScrnInfoPtr pScrn, CARD32 alu, CARD32 planemask)
+static Bool
+NV04EXASetROP(PixmapPtr ppix, int subc, int mthd, int alu, Pixel planemask)
{
+ ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum];
NVPtr pNv = NVPTR(pScrn);
- struct nouveau_channel *chan = pNv->chan;
-
- if (planemask != ~0) {
- NV04EXASetPattern(pScrn, 0, planemask, ~0, ~0);
- if (pNv->currentRop != (alu + 32)) {
- BEGIN_NV04(chan, NV01_SUBC(MISC, OBJECT), 1);
- OUT_RING (chan, pNv->NvRop->handle);
- BEGIN_NV04(chan, NV01_ROP(ROP), 1);
- OUT_RING (chan, NVROP[alu].copy_planemask);
- pNv->currentRop = alu + 32;
+ struct nouveau_pushbuf *push = pNv->pushbuf;
+
+ planemask |= ~0 << ppix->drawable.bitsPerPixel;
+ if (planemask != ~0 || alu != GXcopy) {
+ if (ppix->drawable.bitsPerPixel == 32)
+ return FALSE;
+ if (planemask != ~0) {
+ NV04EXASetPattern(pNv, 0, planemask, ~0, ~0);
+ if (pNv->currentRop != (alu + 32)) {
+ BEGIN_NV04(push, NV01_SUBC(MISC, OBJECT), 1);
+ PUSH_DATA (push, pNv->NvRop->handle);
+ BEGIN_NV04(push, NV01_ROP(ROP), 1);
+ PUSH_DATA (push, NVROP[alu].copy_planemask);
+ pNv->currentRop = alu + 32;
+ }
+ } else
+ if (pNv->currentRop != alu) {
+ if(pNv->currentRop >= 16)
+ NV04EXASetPattern(pNv, ~0, ~0, ~0, ~0);
+ BEGIN_NV04(push, NV01_SUBC(MISC, OBJECT), 1);
+ PUSH_DATA (push, pNv->NvRop->handle);
+ BEGIN_NV04(push, NV01_ROP(ROP), 1);
+ PUSH_DATA (push, NVROP[alu].copy);
+ pNv->currentRop = alu;
}
- } else
- if (pNv->currentRop != alu) {
- if(pNv->currentRop >= 16)
- NV04EXASetPattern(pScrn, ~0, ~0, ~0, ~0);
- BEGIN_NV04(chan, NV01_SUBC(MISC, OBJECT), 1);
- OUT_RING (chan, pNv->NvRop->handle);
- BEGIN_NV04(chan, NV01_ROP(ROP), 1);
- OUT_RING (chan, NVROP[alu].copy);
- pNv->currentRop = alu;
- }
-}
-static void
-NV04EXAStateSolidResubmit(struct nouveau_channel *chan)
-{
- ScrnInfoPtr pScrn = chan->user_private;
- NVPtr pNv = NVPTR(pScrn);
+ BEGIN_NV04(push, subc, mthd, 1);
+ PUSH_DATA (push, 1); /* ROP_AND */
+ } else {
+ BEGIN_NV04(push, subc, mthd, 1);
+ PUSH_DATA (push, 3); /* SRCCOPY */
+ }
- NV04EXAPrepareSolid(pNv->pdpix, pNv->alu, pNv->planemask, pNv->fg_colour);
+ return TRUE;
}
Bool
-NV04EXAPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg)
+NV04EXAPrepareSolid(PixmapPtr ppix, int alu, Pixel planemask, Pixel fg)
{
- ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+ ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum];
NVPtr pNv = NVPTR(pScrn);
- struct nouveau_channel *chan = pNv->chan;
- struct nouveau_bo *bo = nouveau_pixmap_bo(pPixmap);
- unsigned int fmt, pitch, fmt2 = NV04_GDI_COLOR_FORMAT_A8R8G8B8;
+ struct nouveau_pushbuf *push = pNv->pushbuf;
+ struct nouveau_bo *bo = nouveau_pixmap_bo(ppix);
+ unsigned pitch = exaGetPixmapPitch(ppix);
+ unsigned surf_fmt, rect_fmt;
- if (MARK_RING(chan, 64, 2))
+ /* When SURFACE_FORMAT_A8R8G8B8 is used with GDI_RECTANGLE_TEXT, the
+ * alpha channel gets forced to 0xFF for some reason. We're using
+ * SURFACE_FORMAT_Y32 as a workaround
+ */
+ if (!NVAccelGetCtxSurf2DFormatFromPixmap(ppix, (int*)&surf_fmt))
return FALSE;
-
- planemask |= ~0 << pPixmap->drawable.bitsPerPixel;
- if (planemask != ~0 || alu != GXcopy) {
- if (pPixmap->drawable.bitsPerPixel == 32)
- return FALSE;
- BEGIN_NV04(chan, NV04_RECT(OPERATION), 1);
- OUT_RING (chan, 1); /* ROP_AND */
- NV04EXASetROP(pScrn, alu, planemask);
- } else {
- BEGIN_NV04(chan, NV04_RECT(OPERATION), 1);
- OUT_RING (chan, 3); /* SRCCOPY */
+ if (surf_fmt == NV04_SURFACE_2D_FORMAT_A8R8G8B8)
+ surf_fmt = NV04_SURFACE_2D_FORMAT_Y32;
+
+ rect_fmt = NV04_GDI_COLOR_FORMAT_A8R8G8B8;
+ if (ppix->drawable.bitsPerPixel == 16) {
+ if (ppix->drawable.depth == 16)
+ rect_fmt = NV04_GDI_COLOR_FORMAT_A16R5G6B5;
+ else
+ rect_fmt = NV04_GDI_COLOR_FORMAT_X16A1R5G5B5;
}
- if (!NVAccelGetCtxSurf2DFormatFromPixmap(pPixmap, (int*)&fmt))
+ if (!PUSH_SPACE(push, 64))
return FALSE;
- pitch = exaGetPixmapPitch(pPixmap);
+ PUSH_RESET(push);
- if (pPixmap->drawable.bitsPerPixel == 16) {
- if (pPixmap->drawable.depth == 16) {
- fmt2 = NV04_GDI_COLOR_FORMAT_A16R5G6B5;
- } else if (pPixmap->drawable.depth == 15) {
- fmt2 = NV04_GDI_COLOR_FORMAT_X16A1R5G5B5;
- }
- }
+ if (!NV04EXASetROP(ppix, NV04_RECT(OPERATION), alu, planemask))
+ return FALSE;
- /* When SURFACE_FORMAT_A8R8G8B8 is used with GDI_RECTANGLE_TEXT, the
- * alpha channel gets forced to 0xFF for some reason. We're using
- * SURFACE_FORMAT_Y32 as a workaround
- */
- if (fmt == NV04_SURFACE_2D_FORMAT_A8R8G8B8)
- fmt = NV04_SURFACE_2D_FORMAT_Y32;
-
- BEGIN_NV04(chan, NV04_SF2D(FORMAT), 4);
- OUT_RING (chan, fmt);
- OUT_RING (chan, (pitch << 16) | pitch);
- if (OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR) ||
- OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) {
- MARK_UNDO(chan);
+ BEGIN_NV04(push, NV04_SF2D(FORMAT), 4);
+ PUSH_DATA (push, surf_fmt);
+ PUSH_DATA (push, (pitch << 16) | pitch);
+ PUSH_MTHDl(push, NV04_SF2D(OFFSET_SOURCE), bo, 0,
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ PUSH_MTHDl(push, NV04_SF2D(OFFSET_DESTIN), bo, 0,
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ BEGIN_NV04(push, NV04_RECT(COLOR_FORMAT), 1);
+ PUSH_DATA (push, rect_fmt);
+
+ nouveau_pushbuf_bufctx(push, pNv->bufctx);
+ if (nouveau_pushbuf_validate(push)) {
+ nouveau_pushbuf_bufctx(push, NULL);
return FALSE;
}
- BEGIN_NV04(chan, NV04_RECT(COLOR_FORMAT), 1);
- OUT_RING (chan, fmt2);
- BEGIN_NV04(chan, NV04_RECT(COLOR1_A), 1);
- OUT_RING (chan, fg);
-
- pNv->pdpix = pPixmap;
- pNv->alu = alu;
- pNv->planemask = planemask;
pNv->fg_colour = fg;
- chan->flush_notify = NV04EXAStateSolidResubmit;
return TRUE;
}
void
-NV04EXASolid (PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
+NV04EXASolid (PixmapPtr pPixmap, int x, int y, int x2, int y2)
{
ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
NVPtr pNv = NVPTR(pScrn);
- struct nouveau_channel *chan = pNv->chan;
- int width = x2-x1;
- int height = y2-y1;
-
- BEGIN_NV04(chan, NV04_RECT(UNCLIPPED_RECTANGLE_POINT(0)), 2);
- OUT_RING (chan, (x1 << 16) | y1);
- OUT_RING (chan, (width << 16) | height);
-
- if((width * height) >= 512)
- FIRE_RING (chan);
+ struct nouveau_pushbuf *push = pNv->pushbuf;
+ int w = x2 - x;
+ int h = y2 - y;
+
+ if (!PUSH_SPACE(push, 5))
+ return;
+
+ BEGIN_NV04(push, NV04_RECT(COLOR1_A), 1);
+ PUSH_DATA (push, pNv->fg_colour);
+ BEGIN_NV04(push, NV04_RECT(UNCLIPPED_RECTANGLE_POINT(0)), 2);
+ PUSH_DATA (push, (x << 16) | y);
+ PUSH_DATA (push, (w << 16) | h);
+ if ((w * h) >= 512)
+ PUSH_KICK(push);
}
void
NV04EXADoneSolid (PixmapPtr pPixmap)
{
ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
- NVPtr pNv = NVPTR(pScrn);
-
- pNv->chan->flush_notify = NULL;
-}
-
-static void
-NV04EXAStateCopyResubmit(struct nouveau_channel *chan)
-{
- ScrnInfoPtr pScrn = chan->user_private;
- NVPtr pNv = NVPTR(pScrn);
-
- NV04EXAPrepareCopy(pNv->pspix, pNv->pdpix, 0, 0, pNv->alu,
- pNv->planemask);
+ nouveau_pushbuf_bufctx(NVPTR(pScrn)->pushbuf, NULL);
}
Bool
-NV04EXAPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int dx, int dy,
+NV04EXAPrepareCopy(PixmapPtr pspix, PixmapPtr pdpix, int dx, int dy,
int alu, Pixel planemask)
{
- ScrnInfoPtr pScrn = xf86Screens[pSrcPixmap->drawable.pScreen->myNum];
+ ScrnInfoPtr pScrn = xf86Screens[pspix->drawable.pScreen->myNum];
NVPtr pNv = NVPTR(pScrn);
- struct nouveau_channel *chan = pNv->chan;
- struct nouveau_bo *src_bo = nouveau_pixmap_bo(pSrcPixmap);
- struct nouveau_bo *dst_bo = nouveau_pixmap_bo(pDstPixmap);
- int fmt;
+ struct nouveau_pushbuf *push = pNv->pushbuf;
+ struct nouveau_bo *src_bo = nouveau_pixmap_bo(pspix);
+ struct nouveau_bo *dst_bo = nouveau_pixmap_bo(pdpix);
+ int surf_fmt;
- if (pSrcPixmap->drawable.bitsPerPixel !=
- pDstPixmap->drawable.bitsPerPixel)
+ if (pspix->drawable.bitsPerPixel != pdpix->drawable.bitsPerPixel)
return FALSE;
- if (!NVAccelGetCtxSurf2DFormatFromPixmap(pDstPixmap, &fmt))
+ if (!NVAccelGetCtxSurf2DFormatFromPixmap(pdpix, &surf_fmt))
return FALSE;
- if (MARK_RING(chan, 64, 2))
+ if (!PUSH_SPACE(push, 64))
return FALSE;
+ PUSH_RESET(push);
- planemask |= ~0 << pDstPixmap->drawable.bitsPerPixel;
- if (planemask != ~0 || alu != GXcopy) {
- if (pDstPixmap->drawable.bitsPerPixel == 32) {
- MARK_UNDO(chan);
- return FALSE;
- }
-
- BEGIN_NV04(chan, NV01_BLIT(OPERATION), 1);
- OUT_RING (chan, 1); /* ROP_AND */
-
- NV04EXASetROP(pScrn, alu, planemask);
- } else {
- BEGIN_NV04(chan, NV01_BLIT(OPERATION), 1);
- OUT_RING (chan, 3); /* SRCCOPY */
- }
+ if (!NV04EXASetROP(pdpix, NV01_BLIT(OPERATION), alu, planemask))
+ return FALSE;
- BEGIN_NV04(chan, NV04_SF2D(FORMAT), 4);
- OUT_RING (chan, fmt);
- OUT_RING (chan, (exaGetPixmapPitch(pDstPixmap) << 16) |
- (exaGetPixmapPitch(pSrcPixmap)));
- if (OUT_RELOCl(chan, src_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD) ||
- OUT_RELOCl(chan, dst_bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) {
- MARK_UNDO(chan);
+ BEGIN_NV04(push, NV04_SF2D(FORMAT), 4);
+ PUSH_DATA (push, surf_fmt);
+ PUSH_DATA (push, (exaGetPixmapPitch(pdpix) << 16) |
+ exaGetPixmapPitch(pspix));
+ PUSH_MTHDl(push, NV04_SF2D(OFFSET_SOURCE), src_bo, 0,
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+ PUSH_MTHDl(push, NV04_SF2D(OFFSET_DESTIN), dst_bo, 0,
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+
+ nouveau_pushbuf_bufctx(push, pNv->bufctx);
+ if (nouveau_pushbuf_validate(push)) {
+ nouveau_pushbuf_bufctx(push, NULL);
return FALSE;
}
- pNv->pspix = pSrcPixmap;
- pNv->pdpix = pDstPixmap;
- pNv->alu = alu;
- pNv->planemask = planemask;
- chan->flush_notify = NV04EXAStateCopyResubmit;
+ pNv->pspix = pspix;
+ pNv->pmpix = NULL;
+ pNv->pdpix = pdpix;
return TRUE;
}
void
-NV04EXACopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
+NV04EXACopy(PixmapPtr pdpix, int srcX, int srcY, int dstX, int dstY,
int width, int height)
{
- ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
+ ScrnInfoPtr pScrn = xf86Screens[pdpix->drawable.pScreen->myNum];
NVPtr pNv = NVPTR(pScrn);
- struct nouveau_channel *chan = pNv->chan;
+ struct nouveau_pushbuf *push = pNv->pushbuf;
int split_dstY = NOUVEAU_ALIGN(dstY + 1, 64);
int split_height = split_dstY - dstY;
+ if (nouveau_pushbuf_space(push, 16, 1, 0))
+ return;
+
if ((width * height) >= 200000 && pNv->pspix != pNv->pdpix &&
(dstY > srcY || dstX > srcX) && split_height < height) {
/*
@@ -257,90 +234,59 @@ NV04EXACopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
* different (not nicer) trick to achieve the same
* effect.
*/
- struct nouveau_bo *dst_bo = nouveau_pixmap_bo(pNv->pdpix);
- unsigned dst_pitch = exaGetPixmapPitch(pNv->pdpix);
-
- if (MARK_RING(chan, 10, 1))
- return;
-
- BEGIN_NV04(chan, NV01_BLIT(POINT_IN), 3);
- OUT_RING (chan, (srcY << 16) | srcX);
- OUT_RING (chan, (dstY << 16) | dstX);
- OUT_RING (chan, (split_height << 16) | width);
+ struct nouveau_bo *dst_bo = nouveau_pixmap_bo(pdpix);
+ unsigned dst_pitch = exaGetPixmapPitch(pdpix);
- BEGIN_NV04(chan, NV04_SF2D(OFFSET_DESTIN), 1);
- OUT_RELOCl(chan, dst_bo, split_dstY * dst_pitch,
- NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ BEGIN_NV04(push, NV01_BLIT(POINT_IN), 3);
+ PUSH_DATA (push, (srcY << 16) | srcX);
+ PUSH_DATA (push, (dstY << 16) | dstX);
+ PUSH_DATA (push, (split_height << 16) | width);
+ BEGIN_NV04(push, NV04_SF2D(OFFSET_DESTIN), 1);
+ PUSH_RELOC(push, dst_bo, split_dstY * dst_pitch,
+ NOUVEAU_BO_LOW, 0, 0);
srcY += split_height;
height -= split_height;
dstY = 0;
+ pNv->pmpix = pdpix;
+ } else
+ if (pNv->pmpix) {
+ struct nouveau_bo *dst_bo = nouveau_pixmap_bo(pdpix);
+
+ BEGIN_NV04(push, NV04_SF2D(OFFSET_DESTIN), 1);
+ PUSH_RELOC(push, dst_bo, 0, NOUVEAU_BO_LOW, 0, 0);
+ pNv->pmpix = NULL;
}
- BEGIN_NV04(chan, NV01_BLIT(POINT_IN), 3);
- OUT_RING (chan, (srcY << 16) | srcX);
- OUT_RING (chan, (dstY << 16) | dstX);
- OUT_RING (chan, (height << 16) | width);
+ BEGIN_NV04(push, NV01_BLIT(POINT_IN), 3);
+ PUSH_DATA (push, (srcY << 16) | srcX);
+ PUSH_DATA (push, (dstY << 16) | dstX);
+ PUSH_DATA (push, (height << 16) | width);
- if((width * height) >= 512)
- FIRE_RING (chan);
+ if ((width * height) >= 512)
+ PUSH_KICK(push);
}
void
-NV04EXADoneCopy(PixmapPtr pDstPixmap)
+NV04EXADoneCopy(PixmapPtr pdpix)
{
- ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
- NVPtr pNv = NVPTR(pScrn);
-
- pNv->chan->flush_notify = NULL;
-}
-
-static Bool
-NV04EXAStateIFCSubmit(struct nouveau_channel *chan)
-{
- ScrnInfoPtr pScrn = chan->user_private;
- NVPtr pNv = NVPTR(pScrn);
- struct nouveau_bo *bo = nouveau_pixmap_bo(pNv->pdpix);
- int surf_fmt;
-
- NVAccelGetCtxSurf2DFormatFromPixmap(pNv->pdpix, &surf_fmt);
-
- if (MARK_RING(chan, 64, 2))
- return FALSE;
-
- BEGIN_NV04(chan, NV04_SF2D(FORMAT), 4);
- OUT_RING (chan, surf_fmt);
- OUT_RING (chan, (exaGetPixmapPitch(pNv->pdpix) << 16) |
- exaGetPixmapPitch(pNv->pdpix));
- if (OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR) ||
- OUT_RELOCl(chan, bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR)) {
- MARK_UNDO(chan);
- return FALSE;
- }
- BEGIN_NV04(chan, NV01_IFC(POINT), 3);
- OUT_RING (chan, (pNv->point_y << 16) | pNv->point_x);
- OUT_RING (chan, (pNv->height_out << 16) | pNv->width_out);
- OUT_RING (chan, (pNv->height_in << 16) | pNv->width_in);
-
- return TRUE;
-}
-
-static void
-NV04EXAStateIFCResubmit(struct nouveau_channel *chan)
-{
- NV04EXAStateIFCSubmit(chan);
+ ScrnInfoPtr pScrn = xf86Screens[pdpix->drawable.pScreen->myNum];
+ nouveau_pushbuf_bufctx(NVPTR(pScrn)->pushbuf, NULL);
}
Bool
NV04EXAUploadIFC(ScrnInfoPtr pScrn, const char *src, int src_pitch,
- PixmapPtr pDst, int x, int y, int w, int h, int cpp)
+ PixmapPtr pdpix, int x, int y, int w, int h, int cpp)
{
NVPtr pNv = NVPTR(pScrn);
- ScreenPtr pScreen = pDst->drawable.pScreen;
- struct nouveau_channel *chan = pNv->chan;
+ ScreenPtr pScreen = pdpix->drawable.pScreen;
+ struct nouveau_bo *bo = nouveau_pixmap_bo(pdpix);
+ struct nouveau_pushbuf *push = pNv->pushbuf;
int line_len = w * cpp;
- int iw, id, surf_fmt, ifc_fmt;
+ int surf_fmt, ifc_fmt;
+ int iw, id, py, ph;
int padbytes;
+ Bool ret = FALSE;
if (pNv->Architecture >= NV_ARCH_50)
return FALSE;
@@ -348,7 +294,7 @@ NV04EXAUploadIFC(ScrnInfoPtr pScrn, const char *src, int src_pitch,
if (h > 1024)
return FALSE;
- if (line_len<4)
+ if (line_len < 4)
return FALSE;
switch (cpp) {
@@ -358,7 +304,7 @@ NV04EXAUploadIFC(ScrnInfoPtr pScrn, const char *src, int src_pitch,
return FALSE;
}
- if (!NVAccelGetCtxSurf2DFormatFromPixmap(pDst, &surf_fmt))
+ if (!NVAccelGetCtxSurf2DFormatFromPixmap(pdpix, &surf_fmt))
return FALSE;
/* Pad out input width to cover both COLORA() and COLORB() */
@@ -371,49 +317,67 @@ NV04EXAUploadIFC(ScrnInfoPtr pScrn, const char *src, int src_pitch,
if (id > 1792)
return FALSE;
- BEGIN_NV04(chan, NV01_SUBC(MISC, OBJECT), 1);
- OUT_RING (chan, pNv->NvClipRectangle->handle);
- BEGIN_NV04(chan, NV01_CLIP(POINT), 2);
- OUT_RING (chan, (y << 16) | x);
- OUT_RING (chan, (h << 16) | w);
- BEGIN_NV04(chan, NV01_IFC(OPERATION), 2);
- OUT_RING (chan, NV01_IFC_OPERATION_SRCCOPY);
- OUT_RING (chan, ifc_fmt);
-
- pNv->point_x = x;
- pNv->point_y = y;
- pNv->height_in = pNv->height_out = h;
- pNv->width_in = iw;
- pNv->width_out = w;
- pNv->pdpix = pDst;
- chan->flush_notify = NV04EXAStateIFCResubmit;
- if (!NV04EXAStateIFCSubmit(chan))
+ if (!PUSH_SPACE(push, 16))
return FALSE;
+ PUSH_RESET(push);
+
+ BEGIN_NV04(push, NV01_SUBC(MISC, OBJECT), 1);
+ PUSH_DATA (push, pNv->NvClipRectangle->handle);
+ BEGIN_NV04(push, NV01_CLIP(POINT), 2);
+ PUSH_DATA (push, (y << 16) | x);
+ PUSH_DATA (push, (h << 16) | w);
+
+ BEGIN_NV04(push, NV04_SF2D(FORMAT), 4);
+ PUSH_DATA (push, surf_fmt);
+ PUSH_DATA (push, (exaGetPixmapPitch(pdpix) << 16) |
+ exaGetPixmapPitch(pdpix));
+ PUSH_MTHDl(push, NV04_SF2D(OFFSET_SOURCE), bo, 0,
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ PUSH_MTHDl(push, NV04_SF2D(OFFSET_DESTIN), bo, 0,
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+
+ nouveau_pushbuf_bufctx(push, pNv->bufctx);
+ if (nouveau_pushbuf_validate(push))
+ goto out;
+
+ py = y;
+ ph = h;
+ while (ph--) {
+ if (PUSH_AVAIL(push) < id + 1 || (py == y)) {
+ if (!PUSH_SPACE(push, id + 8))
+ goto out;
+ BEGIN_NV04(push, NV01_IFC(OPERATION), 2);
+ PUSH_DATA (push, NV01_IFC_OPERATION_SRCCOPY);
+ PUSH_DATA (push, ifc_fmt);
+ BEGIN_NV04(push, NV01_IFC(POINT), 3);
+ PUSH_DATA (push, (py << 16) | x);
+ PUSH_DATA (push, (h << 16) | w);
+ PUSH_DATA (push, (h << 16) | iw);
+ }
- if (padbytes)
- h--;
- while (h--) {
/* send a line */
- BEGIN_NV04(chan, NV01_IFC(COLOR(0)), id);
- OUT_RINGp (chan, src, id);
+ if (ph > 0 || !padbytes) {
+ BEGIN_NV04(push, NV01_IFC(COLOR(0)), id);
+ PUSH_DATAp(push, src, id);
+ } else {
+ char padding[8];
+ int aux = (padbytes + 7) >> 2;
+ memcpy(padding, src + (id - aux) * 4, padbytes);
+ BEGIN_NV04(push, NV01_IFC(COLOR(0)), id);
+ PUSH_DATAp(push, src, id - aux);
+ PUSH_DATAp(push, padding, aux);
+ }
src += src_pitch;
- pNv->point_y++;
+ py++;
}
- if (padbytes) {
- char padding[8];
- int aux = (padbytes + 7) >> 2;
- BEGIN_NV04(chan, NV01_IFC(COLOR(0)), id);
- OUT_RINGp (chan, src, id - aux);
- memcpy(padding, src + (id - aux) * 4, padbytes);
- OUT_RINGp (chan, padding, aux);
- }
-
- chan->flush_notify = NULL;
- if (pDst == pScreen->GetScreenPixmap(pScreen))
- FIRE_RING(chan);
- return TRUE;
+ ret = TRUE;
+out:
+ nouveau_pushbuf_bufctx(push, NULL);
+ if (pdpix == pScreen->GetScreenPixmap(pScreen))
+ PUSH_KICK(push);
+ return ret;
}
Bool
@@ -423,7 +387,12 @@ NV04EXARectM2MF(NVPtr pNv, int w, int h, int cpp,
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_channel *chan = pNv->chan;
+ struct nv04_fifo *fifo = pNv->channel->data;
+ struct nouveau_pushbuf *push = pNv->pushbuf;
+ struct nouveau_pushbuf_refn refs[] = {
+ { src, src_dom | NOUVEAU_BO_RD },
+ { dst, dst_dom | NOUVEAU_BO_WR },
+ };
src_off += src_y * src_pitch + src_x * cpp;
dst_off += dst_y * dst_pitch + dst_x * cpp;
@@ -434,31 +403,26 @@ NV04EXARectM2MF(NVPtr pNv, int w, int h, int cpp,
line_count = 2047;
h -= line_count;
- if (MARK_RING (chan, 16, 4))
+ if (nouveau_pushbuf_space(push, 16, 4, 0) ||
+ nouveau_pushbuf_refn (push, refs, 2))
return FALSE;
- BEGIN_NV04(chan, NV03_M2MF(DMA_BUFFER_IN), 2);
- if (OUT_RELOCo(chan, src, src_dom | NOUVEAU_BO_RD) ||
- OUT_RELOCo(chan, dst, dst_dom | NOUVEAU_BO_WR)) {
- MARK_UNDO(chan);
- return FALSE;
- }
- BEGIN_NV04(chan, NV03_M2MF(OFFSET_IN), 8);
- if (OUT_RELOCl(chan, src, src_off, src_dom | NOUVEAU_BO_RD) ||
- OUT_RELOCl(chan, dst, dst_off, dst_dom | NOUVEAU_BO_WR)) {
- MARK_UNDO(chan);
- return FALSE;
- }
- OUT_RING (chan, src_pitch);
- OUT_RING (chan, dst_pitch);
- OUT_RING (chan, w * cpp);
- OUT_RING (chan, line_count);
- OUT_RING (chan, 0x00000101);
- OUT_RING (chan, 0x00000000);
- BEGIN_NV04(chan, NV04_GRAPH(M2MF, NOP), 1);
- OUT_RING (chan, 0x00000000);
- BEGIN_NV04(chan, NV03_M2MF(OFFSET_OUT), 1);
- OUT_RING (chan, 0x00000000);
+ BEGIN_NV04(push, NV03_M2MF(DMA_BUFFER_IN), 2);
+ PUSH_RELOC(push, src, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart);
+ PUSH_RELOC(push, dst, 0, NOUVEAU_BO_OR, fifo->vram, fifo->gart);
+ BEGIN_NV04(push, NV03_M2MF(OFFSET_IN), 8);
+ PUSH_RELOC(push, src, src_off, NOUVEAU_BO_LOW, 0, 0);
+ PUSH_RELOC(push, dst, dst_off, NOUVEAU_BO_LOW, 0, 0);
+ PUSH_DATA (push, src_pitch);
+ PUSH_DATA (push, dst_pitch);
+ PUSH_DATA (push, w * cpp);
+ PUSH_DATA (push, line_count);
+ PUSH_DATA (push, 0x00000101);
+ 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);
src_off += src_pitch * line_count;
dst_off += dst_pitch * line_count;