diff options
Diffstat (limited to 'src/nv04_xv_blit.c')
-rw-r--r-- | src/nv04_xv_blit.c | 262 |
1 files changed, 124 insertions, 138 deletions
diff --git a/src/nv04_xv_blit.c b/src/nv04_xv_blit.c index 4261a20..075b867 100644 --- a/src/nv04_xv_blit.c +++ b/src/nv04_xv_blit.c @@ -36,6 +36,7 @@ #include "hwdefs/nv_object.xml.h" #include "hwdefs/nv01_2d.xml.h" +#include "nv04_accel.h" #define FOURCC_RGB 0x0000003 @@ -43,140 +44,125 @@ extern Atom xvSetDefaults, xvSyncToVBlank; -/** - * NVPutBlitImage - * - * @param pScrn screen - * @param src_offset offset of image data in VRAM - * @param id pixel format - * @param src_pitch source pitch - * @param dstBox - * @param x1 - * @param y1 - * @param x2 - * @param y2 - * @param width - * @param height - * @param src_w - * @param src_h - * @param drw_w - * @param drw_h - * @param clipBoxes - * @param pDraw - */ Bool NVPutBlitImage(ScrnInfoPtr pScrn, struct nouveau_bo *src, int src_offset, int id, int src_pitch, BoxPtr dstBox, - int x1, int y1, int x2, int y2, - short width, short height, - short src_w, short src_h, - short drw_w, short drw_h, - RegionPtr clipBoxes, PixmapPtr ppix) + int x1, int y1, int x2, int y2, + short width, short height, + short src_w, short src_h, + short drw_w, short drw_h, + RegionPtr clipBoxes, PixmapPtr ppix) { - NVPtr pNv = NVPTR(pScrn); - NVPortPrivPtr pPriv = GET_BLIT_PRIVATE(pNv); - BoxPtr pbox; - int nbox; - CARD32 dsdx, dtdy; - CARD32 dst_size, dst_point; - CARD32 src_point, src_format; - struct nouveau_channel *chan = pNv->chan; + NVPtr pNv = NVPTR(pScrn); + NVPortPrivPtr pPriv = GET_BLIT_PRIVATE(pNv); + BoxPtr pbox; + int nbox; + CARD32 dsdx, dtdy; + CARD32 dst_size, dst_point; + CARD32 src_point, src_format; + struct nouveau_pushbuf *push = pNv->pushbuf; struct nouveau_bo *bo = nouveau_pixmap_bo(ppix); - int dst_format; + struct nv04_fifo *fifo = pNv->channel->data; + int dst_format; - if (!NVAccelGetCtxSurf2DFormatFromPixmap(ppix, &dst_format)) + if (!NVAccelGetCtxSurf2DFormatFromPixmap(ppix, &dst_format)) return BadImplementation; - if (MARK_RING(chan, 64, 4)) - return BadImplementation; + pbox = REGION_RECTS(clipBoxes); + nbox = REGION_NUM_RECTS(clipBoxes); + + dsdx = (src_w << 20) / drw_w; + dtdy = (src_h << 20) / drw_h; + + dst_size = ((dstBox->y2 - dstBox->y1) << 16) | + (dstBox->x2 - dstBox->x1); + dst_point = (dstBox->y1 << 16) | dstBox->x1; + + src_point = ((y1 << 4) & 0xffff0000) | (x1 >> 12); + + switch(id) { + case FOURCC_RGB: + src_format = NV03_SIFM_COLOR_FORMAT_X8R8G8B8; + break; + case FOURCC_UYVY: + src_format = NV03_SIFM_COLOR_FORMAT_YB8V8YA8U8; + break; + default: + src_format = NV03_SIFM_COLOR_FORMAT_V8YB8U8YA8; + break; + } - BEGIN_NV04(chan, NV04_SF2D(FORMAT), 4); - OUT_RING (chan, dst_format); - OUT_RING (chan, (exaGetPixmapPitch(ppix) << 16) | exaGetPixmapPitch(ppix)); - 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); + if (!PUSH_SPACE(push, 128)) return BadImplementation; + PUSH_RESET(push); + + BEGIN_NV04(push, NV04_SF2D(FORMAT), 4); + PUSH_DATA (push, dst_format); + PUSH_DATA (push, (exaGetPixmapPitch(ppix) << 16) | + exaGetPixmapPitch(ppix)); + 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, NV01_SUBC(MISC, OBJECT), 1); + PUSH_DATA (push, pNv->NvScaledImage->handle); + BEGIN_NV04(push, NV03_SIFM(DMA_IMAGE), 1); + PUSH_MTHDo(push, NV03_SIFM(DMA_IMAGE), src, NOUVEAU_BO_RD | + NOUVEAU_BO_VRAM | NOUVEAU_BO_GART, + fifo->vram, fifo->gart); + if (pNv->dev->chipset >= 0x05) { + BEGIN_NV04(push, NV03_SIFM(COLOR_FORMAT), 2); + PUSH_DATA (push, src_format); + PUSH_DATA (push, NV03_SIFM_OPERATION_SRCCOPY); + } else { + BEGIN_NV04(push, NV03_SIFM(COLOR_FORMAT), 1); + PUSH_DATA (push, src_format); + } + + nouveau_pushbuf_bufctx(push, pNv->bufctx); + if (nouveau_pushbuf_validate(push)) { + nouveau_pushbuf_bufctx(push, NULL); + return BadAlloc; } - pbox = REGION_RECTS(clipBoxes); - nbox = REGION_NUM_RECTS(clipBoxes); - - dsdx = (src_w << 20) / drw_w; - dtdy = (src_h << 20) / drw_h; - - dst_size = ((dstBox->y2 - dstBox->y1) << 16) | - (dstBox->x2 - dstBox->x1); - dst_point = (dstBox->y1 << 16) | dstBox->x1; - - src_pitch |= (NV03_SIFM_FORMAT_ORIGIN_CENTER | - NV03_SIFM_FORMAT_FILTER_BILINEAR); - src_point = ((y1 << 4) & 0xffff0000) | (x1 >> 12); - - switch(id) { - case FOURCC_RGB: - src_format = NV03_SIFM_COLOR_FORMAT_X8R8G8B8; - break; - case FOURCC_UYVY: - src_format = NV03_SIFM_COLOR_FORMAT_YB8V8YA8U8; - break; - default: - src_format = NV03_SIFM_COLOR_FORMAT_V8YB8U8YA8; - break; - } - - if(pPriv->SyncToVBlank) { - FIRE_RING(chan); + if (pPriv->SyncToVBlank) NV11SyncToVBlank(ppix, dstBox); - } - - BEGIN_NV04(chan, NV01_SUBC(MISC, OBJECT), 1); - OUT_RING (chan, pNv->NvScaledImage->handle); - if (pNv->dev->chipset >= 0x05) { - BEGIN_NV04(chan, NV03_SIFM(COLOR_FORMAT), 2); - OUT_RING (chan, src_format); - OUT_RING (chan, NV03_SIFM_OPERATION_SRCCOPY); - } else { - BEGIN_NV04(chan, NV03_SIFM(COLOR_FORMAT), 1); - OUT_RING (chan, src_format); - } - - - BEGIN_NV04(chan, NV03_SIFM(DMA_IMAGE), 1); - OUT_RELOCo(chan, src, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | - NOUVEAU_BO_RD); - while (nbox--) { - BEGIN_NV04(chan, NV04_RECT(COLOR1_A), 1); - OUT_RING (chan, 0); - - BEGIN_NV04(chan, NV03_SIFM(CLIP_POINT), 6); - OUT_RING (chan, (pbox->y1 << 16) | pbox->x1); - OUT_RING (chan, ((pbox->y2 - pbox->y1) << 16) | - (pbox->x2 - pbox->x1)); - OUT_RING (chan, dst_point); - OUT_RING (chan, dst_size); - OUT_RING (chan, dsdx); - OUT_RING (chan, dtdy); - - BEGIN_NV04(chan, NV03_SIFM(SIZE), 4); - OUT_RING (chan, (height << 16) | width); - OUT_RING (chan, src_pitch); - if (OUT_RELOCl(chan, src, src_offset, NOUVEAU_BO_VRAM | - NOUVEAU_BO_GART | NOUVEAU_BO_RD)) { - MARK_UNDO(chan); + + while (nbox--) { + if (!PUSH_SPACE(push, 16)) { + nouveau_pushbuf_bufctx(push, NULL); return BadImplementation; } - OUT_RING (chan, src_point); - pbox++; - } - FIRE_RING (chan); + BEGIN_NV04(push, NV04_RECT(COLOR1_A), 1); + PUSH_DATA (push, 0); + + BEGIN_NV04(push, NV03_SIFM(CLIP_POINT), 6); + PUSH_DATA (push, (pbox->y1 << 16) | pbox->x1); + PUSH_DATA (push, (pbox->y2 - pbox->y1) << 16 | + (pbox->x2 - pbox->x1)); + PUSH_DATA (push, dst_point); + PUSH_DATA (push, dst_size); + PUSH_DATA (push, dsdx); + PUSH_DATA (push, dtdy); + BEGIN_NV04(push, NV03_SIFM(SIZE), 4); + PUSH_DATA (push, (height << 16) | width); + PUSH_DATA (push, NV03_SIFM_FORMAT_FILTER_BILINEAR | + NV03_SIFM_FORMAT_ORIGIN_CENTER | src_pitch); + PUSH_RELOC(push, src, src_offset, NOUVEAU_BO_LOW, 0, 0); + PUSH_DATA (push, src_point); + + pbox++; + } - exaMarkSync(pScrn->pScreen); + nouveau_pushbuf_bufctx(push, NULL); + PUSH_KICK(push); + exaMarkSync(pScrn->pScreen); - pPriv->videoStatus = FREE_TIMER; - pPriv->videoTime = currentTime.milliseconds + FREE_DELAY; - extern void NVVideoTimerCallback(ScrnInfoPtr, Time); + pPriv->videoStatus = FREE_TIMER; + pPriv->videoTime = currentTime.milliseconds + FREE_DELAY; + extern void NVVideoTimerCallback(ScrnInfoPtr, Time); pNv->VideoTimerCallback = NVVideoTimerCallback; return Success; } @@ -199,22 +185,22 @@ NVPutBlitImage(ScrnInfoPtr pScrn, struct nouveau_bo *src, int src_offset, */ int NVSetBlitPortAttribute(ScrnInfoPtr pScrn, Atom attribute, - INT32 value, pointer data) + INT32 value, pointer data) { - NVPortPrivPtr pPriv = (NVPortPrivPtr)data; - NVPtr pNv = NVPTR(pScrn); - - if ((attribute == xvSyncToVBlank) && VSYNC_POSSIBLE) { - if ((value < 0) || (value > 1)) - return BadValue; - pPriv->SyncToVBlank = value; - } else - if (attribute == xvSetDefaults) { - pPriv->SyncToVBlank = VSYNC_POSSIBLE; - } else - return BadMatch; - - return Success; + NVPortPrivPtr pPriv = (NVPortPrivPtr)data; + NVPtr pNv = NVPTR(pScrn); + + if ((attribute == xvSyncToVBlank) && VSYNC_POSSIBLE) { + if ((value < 0) || (value > 1)) + return BadValue; + pPriv->SyncToVBlank = value; + } else + if (attribute == xvSetDefaults) { + pPriv->SyncToVBlank = VSYNC_POSSIBLE; + } else + return BadMatch; + + return Success; } /** @@ -230,16 +216,16 @@ NVSetBlitPortAttribute(ScrnInfoPtr pScrn, Atom attribute, */ int NVGetBlitPortAttribute(ScrnInfoPtr pScrn, Atom attribute, - INT32 *value, pointer data) + INT32 *value, pointer data) { - NVPortPrivPtr pPriv = (NVPortPrivPtr)data; + NVPortPrivPtr pPriv = (NVPortPrivPtr)data; - if(attribute == xvSyncToVBlank) - *value = (pPriv->SyncToVBlank) ? 1 : 0; - else - return BadMatch; + if(attribute == xvSyncToVBlank) + *value = (pPriv->SyncToVBlank) ? 1 : 0; + else + return BadMatch; - return Success; + return Success; } /** |