From 590e385cb5e4f26532ec5ee380f2aaae1cd69894 Mon Sep 17 00:00:00 2001 From: Arthur Huillet Date: Thu, 12 Jul 2007 03:19:21 +0200 Subject: new structure for PutImage, and DMA transfers --- src/nv_video.c | 548 ++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 404 insertions(+), 144 deletions(-) diff --git a/src/nv_video.c b/src/nv_video.c index d8622a5..fc654fd 100644 --- a/src/nv_video.c +++ b/src/nv_video.c @@ -1,4 +1,3 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_video.c,v 1.23 2004/03/20 22:07:06 mvojkovi Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -25,6 +24,9 @@ #include "nv_include.h" #include "nv_dma.h" +#define IMAGE_MAX_W 2046 +#define IMAGE_MAX_H 2046 + #define OFF_DELAY 500 /* milliseconds */ #define FREE_DELAY 5000 @@ -74,7 +76,7 @@ static XF86VideoEncodingRec DummyEncoding = { 0, "XV_IMAGE", - 2046, 2046, + IMAGE_MAX_W, IMAGE_MAX_H, {1, 1} }; @@ -140,6 +142,13 @@ static XF86ImageRec NVImages[NUM_IMAGES_ALL] = XVIMAGE_RGB }; +/** + * NVSetPortDefaults + * set attributes of port "pPriv" to compiled-in (except for colorKey) defaults + * + * @param pScrn screen to get the default colorKey from + * @param pPriv port to reset to defaults + */ static void NVSetPortDefaults (ScrnInfoPtr pScrn, NVPortPrivPtr pPriv) { @@ -155,7 +164,10 @@ NVSetPortDefaults (ScrnInfoPtr pScrn, NVPortPrivPtr pPriv) pPriv->iturbt_709 = FALSE; } - +/** + * NVResetVideo + * writes the current attributes from the overlay port to the hardware + */ void NVResetVideo (ScrnInfoPtr pScrn) { @@ -184,8 +196,10 @@ NVResetVideo (ScrnInfoPtr pScrn) nvWriteVIDEO(pNv, NV_PVIDEO_COLOR_KEY, pPriv->colorKey); } - - +/** + * NVStopOverlay + * Tell the hardware to stop the overlay + */ static void NVStopOverlay (ScrnInfoPtr pScrn) { @@ -194,6 +208,30 @@ NVStopOverlay (ScrnInfoPtr pScrn) nvWriteVIDEO(pNv, NV_PVIDEO_STOP, 1); } +/** + * NVAllocateOverlayMemory + * allocates memory + * + * - why does the funciton have "Overlay" in its name? It does not + * have anything "Overlay"-specific in its function body and it is called by + * non-"Overlay"-specific functions. + * TODO: rename to something like NVAllocateVideoMemory or NVAllocateXvMemory + * - the function only (re-)allocates memory if it absolutely necessary, + * that is, if the requested size is larger than the current size. that means, + * that the size of allocated memory never shrinks, even if the requested + * does. from a performance point of view this is most likely the best + * alternative. but how often does the requested size of memory for video + * playback change? whenever video-size/scaling changes? probably not very + * often. so maybe sacrifice a tiny bit of performance (whenever the video is + * rescaled) and not waste (RAM-)resources? + * - the function makes assumptions about the XAA fb manager being used. isn't + * there a way to check? what aboaut EXA? + * + * @param pScrn screen which requests the memory + * @param mem pointer to previously allocated memory for reallocation + * @param size size of requested memory segment + * @return pointer to the allocated memory + */ static NVAllocRec * NVAllocateOverlayMemory(ScrnInfoPtr pScrn, NVAllocRec *mem, int size) { @@ -206,7 +244,7 @@ NVAllocateOverlayMemory(ScrnInfoPtr pScrn, NVAllocRec *mem, int size) size *= (pScrn->bitsPerPixel >> 3); if(mem) { - if(mem->size >= size) + if(mem->size >= size) // if(mem->size == size) return mem; NVFreeMemory(pNv, mem); } @@ -214,6 +252,13 @@ NVAllocateOverlayMemory(ScrnInfoPtr pScrn, NVAllocRec *mem, int size) return NVAllocateMemory(pNv, NOUVEAU_MEM_FB, size); /* align 32? */ } +/** + * NVFreeOverlayMemory + * frees memory held by the overlay port + * this function (unlike NVAllocateOverlayMemory) is "Overlay"-specific + * + * @param pScrn screen whose overlay port wants to free memory + */ static void NVFreeOverlayMemory(ScrnInfoPtr pScrn) { @@ -226,7 +271,12 @@ NVFreeOverlayMemory(ScrnInfoPtr pScrn) } } - +/** + * NVFreeBlitMemory + * frees memory held by the blit port + * + * @param pScrn screen whose blit port wants to free memory + */ static void NVFreeBlitMemory(ScrnInfoPtr pScrn) { @@ -239,6 +289,11 @@ NVFreeBlitMemory(ScrnInfoPtr pScrn) } } +/** + * NVVideoTimerCallback + * callback function which perform cleanup tasks (stop overlay, free memory). + * within the driver it is only called once from NVBlockHandler in nv_driver.c + */ static void NVVideoTimerCallback(ScrnInfoPtr pScrn, Time currentTime) { @@ -291,6 +346,27 @@ NVVideoTimerCallback(ScrnInfoPtr pScrn, Time currentTime) pNv->VideoTimerCallback = needCallback ? NVVideoTimerCallback : NULL; } +/** + * NVPutOverlayImage + * program hardware to overlay image into front buffer + * + * @param pScrn screen + * @param src_offset + * @param id colorspace of image + * @param src_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 + */ static void NVPutOverlayImage(ScrnInfoPtr pScrn, int offset, int id, int dstPitch, BoxPtr dstBox, @@ -358,6 +434,27 @@ extern Bool exaPixmapIsOffscreen(PixmapPtr p); extern void exaMoveInPixmap(PixmapPtr pPixmap); #endif +/** + * NVPutBlitImage + * + * @param pScrn screen + * @param src_offset + * @param id colorspace of image + * @param src_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 + */ static void NVPutBlitImage(ScrnInfoPtr pScrn, int src_offset, int id, int src_pitch, BoxPtr dstBox, @@ -530,11 +627,29 @@ NVStopOverlayVideo(ScrnInfoPtr pScrn, pointer data, Bool Exit) } } +/** + * NVStopBlitVideo + * TODO ? + */ static void NVStopBlitVideo(ScrnInfoPtr pScrn, pointer data, Bool Exit) { } +/** + * NVSetOverlayPortAttribute + * sets the attribute "attribute" of port "data" to value "value" + * calls NVResetVideo(pScrn) to apply changes to hardware + * + * @param pScrenInfo + * @param attribute attribute to set + * @param value value to which attribute is to be set + * @param data port from which the attribute is to be set + * + * @return Success, if setting is successful + * BadValue/BadMatch, if value/attribute are invalid + * @see NVResetVideo(ScrnInfoPtr pScrn) + */ static int NVSetOverlayPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 value, pointer data) @@ -590,7 +705,15 @@ NVSetOverlayPortAttribute(ScrnInfoPtr pScrn, Atom attribute, return Success; } - +/** + * NVGetOverlayPortAttribute + * + * @param pScrn unused + * @param attribute attribute to be read + * @param value value of attribute will be stored in this pointer + * @param data port from which attribute will be read + * @return Success, if queried attribute exists + */ static int NVGetOverlayPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 *value, pointer data) @@ -619,6 +742,21 @@ NVGetOverlayPortAttribute(ScrnInfoPtr pScrn, Atom attribute, return Success; } +/** + * NVSetBlitPortAttribute + * sets the attribute "attribute" of port "data" to value "value" + * supported attributes: + * - xvSyncToVBlank (values: 0,1) + * - xvSetDefaults (values: NA; SyncToVBlank will be set, if hardware supports it) + * + * @param pScrenInfo + * @param attribute attribute to set + * @param value value to which attribute is to be set + * @param data port from which the attribute is to be set + * + * @return Success, if setting is successful + * BadValue/BadMatch, if value/attribute are invalid + */ static int NVSetBlitPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 value, pointer data) @@ -639,6 +777,17 @@ NVSetBlitPortAttribute(ScrnInfoPtr pScrn, Atom attribute, return Success; } +/** + * NVGetBlitPortAttribute + * reads the value of attribute "attribute" from port "data" into INT32 "*value" + * currently only one attribute supported: xvSyncToVBlank + * + * @param pScrn unused + * @param attribute attribute to be read + * @param value value of attribute will be stored here + * @param data port from which attribute will be read + * @return Success, if queried attribute exists + */ static int NVGetBlitPortAttribute(ScrnInfoPtr pScrn, Atom attribute, INT32 *value, pointer data) @@ -654,8 +803,28 @@ NVGetBlitPortAttribute(ScrnInfoPtr pScrn, Atom attribute, } -/* +/** * QueryBestSize + * used by client applications to ask the driver: + * how would you actually scale a video of dimensions + * vid_w, vid_h, if i wanted you to scale it to dimensions + * drw_w, drw_h? + * function stores actual scaling size in pointers p_w, p_h. + * + * - currently the image cannot be scaled to less than + * 1/8th of the original size in either dimension. why? + * - what happens if the client requests a scaling to a larger value than + * the hardware is capable of (IMAGE_MAX_W, IMAGE_MAX_H)? + * + * @param pScrn unused + * @param motion unused + * @param vid_w width of source video + * @param vid_h height of source video + * @param drw_w desired scaled width as requested by client + * @param drw_h desired scaled height as requested by client + * @param p_w actual scaled width as the driver is capable of + * @param p_h actual scaled height as the driver is capable of + * @param data unused */ static void NVQueryBestSize(ScrnInfoPtr pScrn, Bool motion, @@ -673,7 +842,22 @@ NVQueryBestSize(ScrnInfoPtr pScrn, Bool motion, *p_h = drw_h; } -static void NVCopyData420(unsigned char *src1, unsigned char *src2, +/** + * NVCopyData420 + * used by NVPutImage() function to copy (image)data from + * system RAM to VRAM and change data order. + * + * @param src1 source buffer of luma + * @param src2 source buffer of chroma1 + * @param src3 source buffer of chroma2 + * @param dst1 destination buffer + * @param srcPitch pitch of src1 + * @param srcPitch2 pitch of src2, src3 + * @param dstPitch pitch of dst1 + * @param h number of lines to copy + * @param w length of lines to copy + */ +static inline void NVCopyData420(unsigned char *src1, unsigned char *src2, unsigned char *src3, unsigned char *dst1, int srcPitch, int srcPitch2, int dstPitch, @@ -690,7 +874,7 @@ static void NVCopyData420(unsigned char *src1, unsigned char *src2, s1 = src1; s2 = src2; s3 = src3; i = w; - while (i > 4) { + while (i > 4) { // wouldn't it be better to write (i >= 4) ? #if X_BYTE_ORDER == X_BIG_ENDIAN dst[0] = (s1[0] << 24) | (s1[1] << 8) | (s3[0] << 16) | s2[0]; dst[1] = (s1[2] << 24) | (s1[3] << 8) | (s3[1] << 16) | s2[1]; @@ -726,75 +910,30 @@ static void NVCopyData420(unsigned char *src1, unsigned char *src2, } -static void -NVMoveDWORDS(CARD32* dest, CARD32* src, int dwords) -{ - while (dwords & ~0x03) { - *dest = *src; - *(dest + 1) = *(src + 1); - *(dest + 2) = *(src + 2); - *(dest + 3) = *(src + 3); - src += 4; - dest += 4; - dwords -= 4; - } - - if (!dwords) - return; - *dest = *src; - - if (dwords == 1) - return; - *(dest + 1) = *(src + 1); - - if (dwords == 2) - return; - *(dest + 2) = *(src + 2); -} - -#if X_BYTE_ORDER == X_BIG_ENDIAN -static void -NVMoveDWORDSSwapped(CARD32* dest, CARD8* src, int dwords) -{ - while (dwords--) { - *dest++ = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0]; - src += 4; - } -} -#endif - -static void -NVCopyData422(unsigned char *src, unsigned char *dst, - int srcPitch, int dstPitch, - int h, int w) -{ - w >>= 1; /* pixels to DWORDS */ - while (h--) { - NVMoveDWORDS((CARD32*)dst, (CARD32*)src, w); - src += srcPitch; - dst += dstPitch; - } -} - -static void -NVCopyDataRGB(unsigned char *src, unsigned char *dst, - int srcPitch, int dstPitch, - int h, int w) -{ - while (h--) { -#if X_BYTE_ORDER == X_BIG_ENDIAN - NVMoveDWORDSSwapped((CARD32*)dst, (CARD8*)src, w); -#else - NVMoveDWORDS((CARD32*)dst, (CARD32*)src, w); -#endif - src += srcPitch; - dst += dstPitch; - } -} - - -/* - * PutImage +/** + * NVPutImage + * PutImage is "the" important function of the Xv extention. + * a client (e.g. video player) calls this function for every + * image (of the video) to be displayed. this function then + * scales and displays the image. + * + * @param pScrn screen which hold the port where the image is put + * @param src_x + * @param src_y + * @param src_w + * @param src_h + * @param drw_x + * @param drw_y + * @param drw_w + * @param drw_h + * @param id colorspace of image + * @param buf pointer to buffer containing the source image + * @param width + * @param height + * @param Sync unused + * @param clipBoxes + * @param data pointer to port + * @param pDraw */ static int NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, @@ -813,17 +952,16 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, NVPortPrivPtr pPriv = (NVPortPrivPtr)data; NVPtr pNv = NVPTR(pScrn); INT32 xa, xb, ya, yb; - unsigned char *dst_start; int newSize, offset, s2offset, s3offset; int srcPitch, srcPitch2, dstPitch; int top, left, right, bottom, npixels, nlines, bpp; Bool skip = FALSE; BoxRec dstBox; CARD32 tmp; - + int line_len; + /* s2offset, s3offset - byte offsets into U and V plane of the - * source where copying starts. Y plane is - * done by editing "buf". + * source where copying starts. YV12 is indeed one plane of Y and two subsampled planes of U and V * offset - byte offset to the first line of the destination. * dst_start - byte address to the first displayed pel. */ @@ -834,7 +972,7 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, /* make the compiler happy */ s2offset = s3offset = srcPitch2 = 0; - if (!pPriv->blitter) { + if (!pPriv->blitter) { /* overlay hardware scaler limitation */ if (src_w > (drw_w << 3)) drw_w = src_w >> 3; if (src_h > (drw_h << 3)) @@ -863,14 +1001,16 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, dstBox.y2 -= pScrn->frameY0; } - bpp = pScrn->bitsPerPixel >> 3; + + /* determine required memory size */ + bpp = pScrn->bitsPerPixel >> 3; // bytes per pixel switch(id) { case FOURCC_YV12: case FOURCC_I420: srcPitch = (width + 3) & ~3; /* of luma */ s2offset = srcPitch * height; - srcPitch2 = ((width >> 1) + 3) & ~3; + srcPitch2 = ((width >> 1) + 3) & ~3; /*of chroma*/ s3offset = (srcPitch2 * (height >> 1)) + s2offset; dstPitch = ((width << 1) + 63) & ~63; break; @@ -886,11 +1026,13 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, default: return BadImplementation; } + /* dstPitch = number of bytes per row + but the allocation is done is pixel, hence the division to get the real number of bytes */ newSize = height * dstPitch / bpp; - - if (pPriv->doubleBuffer) - newSize <<= 1; - + + if (pPriv->doubleBuffer) // double buffering ... + newSize <<= 1; // ... means double the amount of VRAM needed + pPriv->video_mem = NVAllocateOverlayMemory(pScrn, pPriv->video_mem, newSize); if (!pPriv->video_mem) @@ -900,26 +1042,21 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, if (pPriv->doubleBuffer) { int mask = 1 << (pPriv->currentBuffer << 2); -#if 0 - /* burn the CPU until the next buffer is available */ - while(nvReadVIDEO(pNv, NV_PVIDEO_BUFFER) & mask); -#else /* overwrite the newest buffer if there's not one free */ if (nvReadVIDEO(pNv, NV_PVIDEO_BUFFER) & mask) { if (!pPriv->currentBuffer) - offset += (newSize * bpp) >> 1; + offset += (height + 1) * dstPitch; skip = TRUE; } else -#endif + if (pPriv->currentBuffer) - offset += (newSize * bpp) >> 1; + offset += (height + 1) * dstPitch; } - dst_start = pPriv->video_mem->map + - (offset - (uint32_t)pPriv->video_mem->offset); /* We need to enlarge the copied rectangle by a pixel so the HW * filtering doesn't pick up junk laying outside of the source */ + /* fixed point arithmetic */ left = (xa - 0x00010000) >> 16; if (left < 0) left = 0; top = (ya - 0x00010000) >> 16; @@ -931,6 +1068,7 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, if(pPriv->blitter) NVSync(pScrn); + switch(id) { case FOURCC_YV12: case FOURCC_I420: @@ -939,7 +1077,7 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, top &= ~1; nlines = ((bottom + 1) & ~1) - top; - dst_start += (left << 1) + (top * dstPitch); + offset += (left << 1) + (top * dstPitch); tmp = ((top >> 1) * srcPitch2) + (left >> 1); s2offset += tmp; s3offset += tmp; @@ -948,11 +1086,7 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, s2offset = s3offset; s3offset = tmp; } - - NVCopyData420(buf + (top * srcPitch) + left, - buf + s2offset, buf + s3offset, - dst_start, srcPitch, srcPitch2, - dstPitch, nlines, npixels); + line_len = dstPitch; break; case FOURCC_UYVY: case FOURCC_YUY2: @@ -962,26 +1096,93 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, left <<= 1; buf += (top * srcPitch) + left; - dst_start += left + (top * dstPitch); - - NVCopyData422(buf, dst_start, srcPitch, - dstPitch, nlines, npixels); + offset += left + (top * dstPitch); + line_len = width << 1; break; case FOURCC_RGB: npixels = right - left; nlines = bottom - top; - left <<= 2; buf += (top * srcPitch) + left; - dst_start += left + (top * dstPitch); - - NVCopyDataRGB(buf, dst_start, srcPitch, - dstPitch, nlines, npixels); + offset += left + (top * dstPitch); + line_len = width << 2; break; default: return BadImplementation; } + + + /*Below is *almost* a copypaste from NvAccelUploadM2MF, cannot use it directly because of YV12 -> YUY2 conversion */ + + NVDmaStart(pNv, NvSubMemFormat, MEMFORMAT_DMA_OBJECT_IN, 2); + NVDmaNext (pNv, NvDmaTT); + NVDmaNext (pNv, NvDmaFB); + pNv->M2MFDirection = 1; + int lc; + + /* Determine max amount of data we can DMA at once */ + if (nlines * line_len <= pNv->GARTScratch->size) { + lc = nlines; + } else { + lc = pNv->GARTScratch->size / line_len; + } + + while (nlines) { /*actually Xv doesn't like looping here much, especially for YV12*/ + char *dst = pNv->GARTScratch->map; + + /* Upload to GART */ + switch(id) { + case FOURCC_YV12: + case FOURCC_I420: + + NVCopyData420(buf + (top * srcPitch) + left, + buf + s2offset, buf + s3offset, + dst, srcPitch, srcPitch2, + dstPitch, nlines, npixels); + buf += srcPitch * lc; /*typically this will NOT WORK WITH YV12 so you need to have a large enough scratch zone.*/ + + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + case FOURCC_RGB: + memcpy(dst, buf, srcPitch * lc); + buf += srcPitch * lc; + break; + default: + return BadImplementation; + } + + + /* DMA to VRAM */ + NVNotifierReset(pScrn, pNv->Notifier0); + NVDmaStart(pNv, NvSubMemFormat, + NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); + NVDmaNext (pNv, 0); + + NVDmaStart(pNv, NvSubMemFormat, + NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); + NVDmaNext (pNv, (uint32_t)pNv->GARTScratch->offset); + NVDmaNext (pNv, (uint32_t)offset); + NVDmaNext (pNv, line_len); + NVDmaNext (pNv, dstPitch); + NVDmaNext (pNv, line_len); + NVDmaNext (pNv, lc); + NVDmaNext (pNv, (1<<8)|1); + NVDmaNext (pNv, 0); + + NVDmaKickoff(pNv); + if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) + //you lost + return FALSE; + + nlines -= lc; + } + + + + + if (!skip) { if (pPriv->blitter) { NVPutBlitImage(pScrn, offset, id, @@ -1000,11 +1201,30 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, pPriv->currentBuffer ^= 1; } } - return Success; } -/* + +/** * QueryImageAttributes + * + * calculates + * - size (memory required to store image), + * - pitches, + * - offsets + * of image + * depending on colorspace (id) and dimensions (w,h) of image + * values of + * - w, + * - h + * may be adjusted as needed + * + * @param pScrn unused + * @param id colorspace of image + * @param w pointer to width of image + * @param h pointer to height of image + * @param pitches pitches[i] = length of a scanline in plane[i] + * @param offsets offsets[i] = offset of plane i from the beginning of the image + * @return size of the memory required for the XvImage queried */ static int NVQueryImageAttributes(ScrnInfoPtr pScrn, int id, @@ -1013,46 +1233,46 @@ NVQueryImageAttributes(ScrnInfoPtr pScrn, int id, { int size, tmp; - if (*w > 2046) - *w = 2046; - if (*h > 2046) - *h = 2046; + if (*w > IMAGE_MAX_W) + *w = IMAGE_MAX_W; + if (*h > IMAGE_MAX_H) + *h = IMAGE_MAX_H; - *w = (*w + 1) & ~1; + *w = (*w + 1) & ~1; // width rounded up to an even number if (offsets) offsets[0] = 0; switch (id) { case FOURCC_YV12: case FOURCC_I420: - *h = (*h + 1) & ~1; - size = (*w + 3) & ~3; + *h = (*h + 1) & ~1; // height rounded up to an even number + size = (*w + 3) & ~3; // width rounded up to a multiple of 4 if (pitches) - pitches[0] = size; + pitches[0] = size; // width rounded up to a multiple of 4 size *= *h; if (offsets) - offsets[1] = size; - tmp = ((*w >> 1) + 3) & ~3; + offsets[1] = size; // number of pixels in "rounded up" image + tmp = ((*w >> 1) + 3) & ~3; // width/2 rounded up to a multiple of 4 if (pitches) - pitches[1] = pitches[2] = tmp; - tmp *= (*h >> 1); - size += tmp; + pitches[1] = pitches[2] = tmp; // width/2 rounded up to a multiple of 4 + tmp *= (*h >> 1); // 1/4*number of pixels in "rounded up" image + size += tmp; // 5/4*number of pixels in "rounded up" image if (offsets) - offsets[2] = size; - size += tmp; + offsets[2] = size; // 5/4*number of pixels in "rounded up" image + size += tmp; // = 3/2*number of pixels in "rounded up" image break; case FOURCC_UYVY: case FOURCC_YUY2: - size = *w << 1; + size = *w << 1; // 2*width if (pitches) - pitches[0] = size; - size *= *h; + pitches[0] = size; // 2*width + size *= *h; // 2*width*height break; case FOURCC_RGB: - size = *w << 2; + size = *w << 2; // 4*width (32 bit per pixel) if (pitches) - pitches[0] = size; - size *= *h; + pitches[0] = size; // 4*width + size *= *h; // 4*width*height break; default: *w = *h = size = 0; @@ -1079,7 +1299,7 @@ NVAllocSurface(ScrnInfoPtr pScrn, int id, if (pPriv->grabbedByV4L) return BadAlloc; - if ((w > 2046) || (h > 2046)) + if ((w > IMAGE_MAX_W) || (h > IMAGE_MAX_H)) return BadValue; w = (w + 1) & ~1; @@ -1209,6 +1429,12 @@ NVDisplaySurface(XF86SurfacePtr surface, return Success; } +/** + * NVSetupBlitVideo + * this function does all the work setting up a blit port + * + * @return blit port + */ static XF86VideoAdaptorPtr NVSetupBlitVideo (ScreenPtr pScreen) { @@ -1271,6 +1497,13 @@ NVSetupBlitVideo (ScreenPtr pScreen) return adapt; } +/** + * NV10SetupOverlayVideo + * this function does all the work setting up an overlay port + * + * @return overlay port + * @see NVResetVideo(ScrnInfoPtr pScrn) + */ static XF86VideoAdaptorPtr NV10SetupOverlayVideo(ScreenPtr pScreen) { @@ -1350,7 +1583,7 @@ XF86OffscreenImageRec NVOffscreenImages[2] = { NVStopSurface, NVGetSurfaceAttribute, NVSetSurfaceAttribute, - 2046, 2046, + IMAGE_MAX_W, IMAGE_MAX_H, NUM_OVERLAY_ATTRIBUTES - 1, &NVOverlayAttributes[1] }, @@ -1363,7 +1596,7 @@ XF86OffscreenImageRec NVOffscreenImages[2] = { NVStopSurface, NVGetSurfaceAttribute, NVSetSurfaceAttribute, - 2046, 2046, + IMAGE_MAX_W, IMAGE_MAX_H, NUM_OVERLAY_ATTRIBUTES - 1, &NVOverlayAttributes[1] } @@ -1375,6 +1608,15 @@ NVInitOffscreenImages (ScreenPtr pScreen) xf86XVRegisterOffscreenImages(pScreen, NVOffscreenImages, 2); } +/** + * NVChipsetHasOverlay + * + * newer chips don't support overlay anymore. + * overlay feature is emulated via textures. + * + * @param pNv + * @return true, if chipset supports overlay + */ static Bool NVChipsetHasOverlay(NVPtr pNv) { @@ -1394,6 +1636,16 @@ NVChipsetHasOverlay(NVPtr pNv) return FALSE; } +/** + * NVSetupOverlayVideo + * check if chipset supports Overlay and CompositeExtension is disabled. + * if so, setup overlay port + * + * @return overlay port + * @see NVChipsetHasOverlay(NVPtr pNv) + * @see NV10SetupOverlayVideo(ScreenPtr pScreen) + * @see NVInitOffscreenImages(ScreenPtr pScreen) + */ static XF86VideoAdaptorPtr NVSetupOverlayVideo(ScreenPtr pScreen) { @@ -1408,13 +1660,12 @@ NVSetupOverlayVideo(ScreenPtr pScreen) * blit adaptor the default if composite is enabled? */ #ifdef COMPOSITE - if (!noCompositeExtension) { +/* if (!noCompositeExtension) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "XV: Video overlay not available, composite enabled\n"); return NULL; - } + }*/ #endif - overlayAdaptor = NV10SetupOverlayVideo(pScreen); if (overlayAdaptor) NVInitOffscreenImages(pScreen); @@ -1422,6 +1673,15 @@ NVSetupOverlayVideo(ScreenPtr pScreen) return overlayAdaptor; } +/** + * NVInitVideo + * tries to initialize one new overlay port and one new blit port + * and add them to the list of ports on screen "pScreen". + * + * @param pScreen + * @see NVSetupOverlayVideo(ScreenPtr pScreen) + * @see NVSetupBlitVideo(ScreenPtr pScreen) + */ void NVInitVideo (ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; -- cgit v1.2.1 From 74ed14e1d27903f0647fe650da666cacb1e2e940 Mon Sep 17 00:00:00 2001 From: Arthur Huillet Date: Sun, 15 Jul 2007 00:35:46 +0200 Subject: VERY EXPERIMENTAL moved the notifier wait at the beginning of NvPutImage --- src/nv_video.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/nv_video.c b/src/nv_video.c index fc654fd..7a0d070 100644 --- a/src/nv_video.c +++ b/src/nv_video.c @@ -1128,7 +1128,12 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, lc = pNv->GARTScratch->size / line_len; } - while (nlines) { /*actually Xv doesn't like looping here much, especially for YV12*/ + + if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) + //you lost + return FALSE; + + while (nlines > 0) { /*actually Xv doesn't like looping here much, especially for YV12*/ char *dst = pNv->GARTScratch->map; /* Upload to GART */ @@ -1172,9 +1177,10 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, NVDmaNext (pNv, 0); NVDmaKickoff(pNv); - if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) - //you lost - return FALSE; + if ( (nlines - lc ) > 0 ) + if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) + //you lost + return FALSE; nlines -= lc; } @@ -1201,6 +1207,8 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, pPriv->currentBuffer ^= 1; } } + + return Success; } -- cgit v1.2.1 From 81cc744eb31343a509f9ca0d37993d462f162d80 Mon Sep 17 00:00:00 2001 From: Arthur Huillet Date: Sun, 15 Jul 2007 01:00:19 +0200 Subject: VERY EXPERIMENTAL now EXA waits for sync before its operations - this removed the text corruption and didn't affect performance here, please report. --- src/nv_exa.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/nv_exa.c b/src/nv_exa.c index fde1d09..da73669 100644 --- a/src/nv_exa.c +++ b/src/nv_exa.c @@ -285,6 +285,8 @@ NVAccelDownloadM2MF(ScrnInfoPtr pScrn, char *dst, uint64_t src_offset, NVPtr pNv = NVPTR(pScrn); setM2MFDirection(pScrn, 0); + if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) + return FALSE; while (line_count) { char *src = pNv->GARTScratch->map; @@ -375,6 +377,9 @@ NVAccelUploadM2MF(ScrnInfoPtr pScrn, uint64_t dst_offset, const char *src, setM2MFDirection(pScrn, 1); + if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) + return FALSE; + while (line_count) { char *dst = pNv->GARTScratch->map; int lc, i; @@ -420,8 +425,9 @@ NVAccelUploadM2MF(ScrnInfoPtr pScrn, uint64_t dst_offset, const char *src, NVDmaStart(pNv, NvSubMemFormat, 0x100, 1); NVDmaNext (pNv, 0); NVDmaKickoff(pNv); - if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) - return FALSE; + if ( line_count - lc > 0 ) + if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) + return FALSE; line_count -= lc; } -- cgit v1.2.1 From a97181f95a1f5da6180b8a72f3ca307079b92079 Mon Sep 17 00:00:00 2001 From: Arthur Huillet Date: Fri, 20 Jul 2007 01:22:11 +0200 Subject: now yielding in the wait for notifier for Xv only --- src/nv_exa.c | 10 ++-------- src/nv_notifier.c | 36 ++++++++++++++++++++++++++++++++++++ src/nv_video.c | 28 +++++++++++++++------------- 3 files changed, 53 insertions(+), 21 deletions(-) diff --git a/src/nv_exa.c b/src/nv_exa.c index da73669..fde1d09 100644 --- a/src/nv_exa.c +++ b/src/nv_exa.c @@ -285,8 +285,6 @@ NVAccelDownloadM2MF(ScrnInfoPtr pScrn, char *dst, uint64_t src_offset, NVPtr pNv = NVPTR(pScrn); setM2MFDirection(pScrn, 0); - if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) - return FALSE; while (line_count) { char *src = pNv->GARTScratch->map; @@ -377,9 +375,6 @@ NVAccelUploadM2MF(ScrnInfoPtr pScrn, uint64_t dst_offset, const char *src, setM2MFDirection(pScrn, 1); - if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) - return FALSE; - while (line_count) { char *dst = pNv->GARTScratch->map; int lc, i; @@ -425,9 +420,8 @@ NVAccelUploadM2MF(ScrnInfoPtr pScrn, uint64_t dst_offset, const char *src, NVDmaStart(pNv, NvSubMemFormat, 0x100, 1); NVDmaNext (pNv, 0); NVDmaKickoff(pNv); - if ( line_count - lc > 0 ) - if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) - return FALSE; + if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) + return FALSE; line_count -= lc; } diff --git a/src/nv_notifier.c b/src/nv_notifier.c index 70a7fcc..866ebf8 100644 --- a/src/nv_notifier.c +++ b/src/nv_notifier.c @@ -130,3 +130,39 @@ NVNotifierWaitStatus(ScrnInfoPtr pScrn, return FALSE; } +Bool +NVNotifierWaitStatusSleep(ScrnInfoPtr pScrn, + struct drm_nouveau_notifier_alloc *notifier, + unsigned int status, unsigned int timeout) +{ + NOTIFIER(n); + unsigned int t_start, time = 0; + + t_start = GetTimeInMillis(); + while (time <= timeout) { +#if 0 + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "N(0x%08x)/%d = 0x%08x/0x%08x/0x%08x/0x%08x\n", + notifier->handle, time, n[0], n[1], n[2], n[3]); +#endif + if (n[NV_NOTIFY_STATE/4] & NV_NOTIFY_STATE_ERROR_CODE_MASK) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Notifier returned error: 0x%04x\n", + NVNotifierErrorCode(pScrn, notifier)); + return FALSE; + } + + if ((n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT) + == status) + return TRUE; + + if (timeout) + time = GetTimeInMillis() - t_start; + sched_yield(); + } + + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Notifier (0x%08x) timeout!\n", notifier->handle); + return FALSE; +} + diff --git a/src/nv_video.c b/src/nv_video.c index 7a0d070..890d731 100644 --- a/src/nv_video.c +++ b/src/nv_video.c @@ -558,6 +558,10 @@ NVPutBlitImage(ScrnInfoPtr pScrn, int src_offset, int id, NVDmaStart(pNv, NvSubScaledImage, STRETCH_BLIT_FORMAT, 1); NVDmaNext (pNv, src_format); } + + NVDmaStart(pNv, NvSubScaledImage, + NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); + NVDmaNext (pNv, NvDmaTT); /* source object */ while(nbox--) { NVDmaStart(pNv, NvSubRectangle, RECT_SOLID_COLOR, 1); @@ -1128,10 +1132,7 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, lc = pNv->GARTScratch->size / line_len; } - - if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) - //you lost - return FALSE; + while (nlines > 0) { /*actually Xv doesn't like looping here much, especially for YV12*/ char *dst = pNv->GARTScratch->map; @@ -1160,11 +1161,7 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, /* DMA to VRAM */ - NVNotifierReset(pScrn, pNv->Notifier0); - NVDmaStart(pNv, NvSubMemFormat, - NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); - NVDmaNext (pNv, 0); - + NVDmaStart(pNv, NvSubMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); NVDmaNext (pNv, (uint32_t)pNv->GARTScratch->offset); @@ -1176,11 +1173,16 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, NVDmaNext (pNv, (1<<8)|1); NVDmaNext (pNv, 0); + NVNotifierReset(pScrn, pNv->Notifier0); + NVDmaStart(pNv, NvSubMemFormat, + NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); + NVDmaNext (pNv, 0); + NVDmaStart(pNv, NvSubMemFormat, 0x100, 1); + NVDmaNext (pNv, 0); NVDmaKickoff(pNv); - if ( (nlines - lc ) > 0 ) - if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) - //you lost - return FALSE; + + if (!NVNotifierWaitStatusSleep(pScrn, pNv->Notifier0, 0, 0)) + return FALSE; nlines -= lc; } -- cgit v1.2.1 From e760235a0596895b726220366c50d4e7c244006e Mon Sep 17 00:00:00 2001 From: Arthur Huillet Date: Fri, 20 Jul 2007 01:33:49 +0200 Subject: Now using GART as the source for the blitter - preliminary implementation, gotta clean it up --- src/nv_video.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/nv_video.c b/src/nv_video.c index 890d731..4cdaafc 100644 --- a/src/nv_video.c +++ b/src/nv_video.c @@ -591,7 +591,9 @@ NVPutBlitImage(ScrnInfoPtr pScrn, int src_offset, int id, NVDmaNext (pNv, SURFACE_FORMAT_R5G6B5); } } - + NVDmaStart(pNv, NvSubScaledImage, + NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); + NVDmaNext (pNv, NvDmaFB); /* source object */ NVDmaKickoff(pNv); if (pNv->useEXA) @@ -1193,7 +1195,7 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, if (!skip) { if (pPriv->blitter) { - NVPutBlitImage(pScrn, offset, id, + NVPutBlitImage(pScrn, pNv->GARTScratch->offset, id, dstPitch, &dstBox, xa, ya, xb, yb, width, height, -- cgit v1.2.1 From 290e71edfbc6297c63989d5c21a67717b4ca5f76 Mon Sep 17 00:00:00 2001 From: Arthur Huillet Date: Fri, 20 Jul 2007 17:46:18 +0200 Subject: cleaner Xv code - fallback on CPU copy yet to be implemented --- src/nv_video.c | 113 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 63 insertions(+), 50 deletions(-) diff --git a/src/nv_video.c b/src/nv_video.c index 4cdaafc..bff7168 100644 --- a/src/nv_video.c +++ b/src/nv_video.c @@ -591,9 +591,7 @@ NVPutBlitImage(ScrnInfoPtr pScrn, int src_offset, int id, NVDmaNext (pNv, SURFACE_FORMAT_R5G6B5); } } - NVDmaStart(pNv, NvSubScaledImage, - NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); - NVDmaNext (pNv, NvDmaFB); /* source object */ + NVDmaKickoff(pNv); if (pNv->useEXA) @@ -1120,23 +1118,8 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, /*Below is *almost* a copypaste from NvAccelUploadM2MF, cannot use it directly because of YV12 -> YUY2 conversion */ - - NVDmaStart(pNv, NvSubMemFormat, MEMFORMAT_DMA_OBJECT_IN, 2); - NVDmaNext (pNv, NvDmaTT); - NVDmaNext (pNv, NvDmaFB); - pNv->M2MFDirection = 1; - int lc; - - /* Determine max amount of data we can DMA at once */ - if (nlines * line_len <= pNv->GARTScratch->size) { - lc = nlines; - } else { - lc = pNv->GARTScratch->size / line_len; - } - - - - while (nlines > 0) { /*actually Xv doesn't like looping here much, especially for YV12*/ + if ( nlines * line_len <= pNv->GARTScratch->size) + { char *dst = pNv->GARTScratch->map; /* Upload to GART */ @@ -1148,54 +1131,84 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, buf + s2offset, buf + s3offset, dst, srcPitch, srcPitch2, dstPitch, nlines, npixels); - buf += srcPitch * lc; /*typically this will NOT WORK WITH YV12 so you need to have a large enough scratch zone.*/ break; case FOURCC_UYVY: case FOURCC_YUY2: case FOURCC_RGB: - memcpy(dst, buf, srcPitch * lc); - buf += srcPitch * lc; + memcpy(dst, buf, srcPitch * nlines); break; default: return BadImplementation; } - - /* DMA to VRAM */ + if ( !pPriv -> blitter ) + { + NVDmaStart(pNv, NvSubMemFormat, MEMFORMAT_DMA_OBJECT_IN, 2); + NVDmaNext (pNv, NvDmaTT); + NVDmaNext (pNv, NvDmaFB); + pNv->M2MFDirection = 1; - NVDmaStart(pNv, NvSubMemFormat, + /* DMA to VRAM */ + + NVDmaStart(pNv, NvSubMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); - NVDmaNext (pNv, (uint32_t)pNv->GARTScratch->offset); - NVDmaNext (pNv, (uint32_t)offset); - NVDmaNext (pNv, line_len); - NVDmaNext (pNv, dstPitch); - NVDmaNext (pNv, line_len); - NVDmaNext (pNv, lc); - NVDmaNext (pNv, (1<<8)|1); - NVDmaNext (pNv, 0); - - NVNotifierReset(pScrn, pNv->Notifier0); - NVDmaStart(pNv, NvSubMemFormat, + NVDmaNext (pNv, (uint32_t)pNv->GARTScratch->offset); + NVDmaNext (pNv, (uint32_t)offset); + NVDmaNext (pNv, line_len); + NVDmaNext (pNv, dstPitch); + NVDmaNext (pNv, line_len); + NVDmaNext (pNv, nlines); + NVDmaNext (pNv, (1<<8)|1); + NVDmaNext (pNv, 0); + + NVNotifierReset(pScrn, pNv->Notifier0); + NVDmaStart(pNv, NvSubMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); - NVDmaNext (pNv, 0); - NVDmaStart(pNv, NvSubMemFormat, 0x100, 1); - NVDmaNext (pNv, 0); - NVDmaKickoff(pNv); + NVDmaNext (pNv, 0); + NVDmaStart(pNv, NvSubMemFormat, 0x100, 1); + NVDmaNext (pNv, 0); + NVDmaKickoff(pNv); - if (!NVNotifierWaitStatusSleep(pScrn, pNv->Notifier0, 0, 0)) - return FALSE; - - nlines -= lc; - } - - - + if (!NVNotifierWaitStatusSleep(pScrn, pNv->Notifier0, 0, 0)) + return FALSE; + } + else + { + NVDmaStart(pNv, NvSubScaledImage, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); + NVDmaNext (pNv, NvDmaTT); /* source object */ + + NVPutBlitImage(pScrn, pNv->GARTScratch->offset, id, + dstPitch, &dstBox, + xa, ya, xb, yb, + width, height, + src_w, src_h, drw_w, drw_h, + clipBoxes, pDraw); + + NVNotifierReset(pScrn, pNv->Notifier0); + NVDmaStart(pNv, NvSubScaledImage, + NV10_IMAGE_BLIT_NOTIFY, 1); + NVDmaNext (pNv, 0); + NVDmaStart(pNv, NvSubScaledImage, 0x100, 1); + NVDmaNext (pNv, 0); + + NVDmaStart(pNv, NvSubScaledImage, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); + NVDmaNext (pNv, NvDmaFB); /* source object */ + NVDmaKickoff(pNv); + if (!NVNotifierWaitStatusSleep(pScrn, pNv->Notifier0, 0, 0)) + return FALSE; + return Success; + } + } + else //GART is too small, we fallback on CPU copy for simplicity + { + } + if (!skip) { if (pPriv->blitter) { - NVPutBlitImage(pScrn, pNv->GARTScratch->offset, id, + NVPutBlitImage(pScrn, offset, id, dstPitch, &dstBox, xa, ya, xb, yb, width, height, -- cgit v1.2.1 From 4f4721f1b8a76a0bf9938e3c614ba7166d5f3dab Mon Sep 17 00:00:00 2001 From: Arthur Huillet Date: Wed, 25 Jul 2007 22:23:37 +0200 Subject: removed pointless sleep in notifier wait --- src/nv_notifier.c | 36 ------------------------------------ src/nv_video.c | 8 ++++---- 2 files changed, 4 insertions(+), 40 deletions(-) diff --git a/src/nv_notifier.c b/src/nv_notifier.c index 866ebf8..70a7fcc 100644 --- a/src/nv_notifier.c +++ b/src/nv_notifier.c @@ -130,39 +130,3 @@ NVNotifierWaitStatus(ScrnInfoPtr pScrn, return FALSE; } -Bool -NVNotifierWaitStatusSleep(ScrnInfoPtr pScrn, - struct drm_nouveau_notifier_alloc *notifier, - unsigned int status, unsigned int timeout) -{ - NOTIFIER(n); - unsigned int t_start, time = 0; - - t_start = GetTimeInMillis(); - while (time <= timeout) { -#if 0 - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "N(0x%08x)/%d = 0x%08x/0x%08x/0x%08x/0x%08x\n", - notifier->handle, time, n[0], n[1], n[2], n[3]); -#endif - if (n[NV_NOTIFY_STATE/4] & NV_NOTIFY_STATE_ERROR_CODE_MASK) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Notifier returned error: 0x%04x\n", - NVNotifierErrorCode(pScrn, notifier)); - return FALSE; - } - - if ((n[NV_NOTIFY_STATE/4] >> NV_NOTIFY_STATE_STATUS_SHIFT) - == status) - return TRUE; - - if (timeout) - time = GetTimeInMillis() - t_start; - sched_yield(); - } - - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Notifier (0x%08x) timeout!\n", notifier->handle); - return FALSE; -} - diff --git a/src/nv_video.c b/src/nv_video.c index bff7168..45ab72f 100644 --- a/src/nv_video.c +++ b/src/nv_video.c @@ -1170,7 +1170,7 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, NVDmaNext (pNv, 0); NVDmaKickoff(pNv); - if (!NVNotifierWaitStatusSleep(pScrn, pNv->Notifier0, 0, 0)) + if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) return FALSE; } else @@ -1190,12 +1190,12 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, NV10_IMAGE_BLIT_NOTIFY, 1); NVDmaNext (pNv, 0); NVDmaStart(pNv, NvSubScaledImage, 0x100, 1); - NVDmaNext (pNv, 0); - + NVDmaNext (pNv, 106); + NVDmaStart(pNv, NvSubScaledImage, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); NVDmaNext (pNv, NvDmaFB); /* source object */ NVDmaKickoff(pNv); - if (!NVNotifierWaitStatusSleep(pScrn, pNv->Notifier0, 0, 0)) + if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) return FALSE; return Success; } -- cgit v1.2.1 From 8ba6a9c7494ebd53a3fe775d4d9b402e918a6598 Mon Sep 17 00:00:00 2001 From: Arthur Huillet Date: Thu, 26 Jul 2007 15:21:08 +0200 Subject: Preliminary implementation of "host-side double buffering" to improve performance of Xv --- src/nv_video.c | 129 +++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 94 insertions(+), 35 deletions(-) diff --git a/src/nv_video.c b/src/nv_video.c index 45ab72f..aa27882 100644 --- a/src/nv_video.c +++ b/src/nv_video.c @@ -57,6 +57,8 @@ typedef struct _NVPortPrivRec { NVAllocRec * video_mem; int pitch; int offset; + NVAllocRec * TT_mem_chunk[2]; + int currentHostBuffer; } NVPortPrivRec, *NVPortPrivPtr; #define GET_OVERLAY_PRIVATE(pNv) \ @@ -209,23 +211,8 @@ NVStopOverlay (ScrnInfoPtr pScrn) } /** - * NVAllocateOverlayMemory - * allocates memory - * - * - why does the funciton have "Overlay" in its name? It does not - * have anything "Overlay"-specific in its function body and it is called by - * non-"Overlay"-specific functions. - * TODO: rename to something like NVAllocateVideoMemory or NVAllocateXvMemory - * - the function only (re-)allocates memory if it absolutely necessary, - * that is, if the requested size is larger than the current size. that means, - * that the size of allocated memory never shrinks, even if the requested - * does. from a performance point of view this is most likely the best - * alternative. but how often does the requested size of memory for video - * playback change? whenever video-size/scaling changes? probably not very - * often. so maybe sacrifice a tiny bit of performance (whenever the video is - * rescaled) and not waste (RAM-)resources? - * - the function makes assumptions about the XAA fb manager being used. isn't - * there a way to check? what aboaut EXA? + * NVAllocateVideoMemory + * allocates video memory for a given port * * @param pScrn screen which requests the memory * @param mem pointer to previously allocated memory for reallocation @@ -233,18 +220,17 @@ NVStopOverlay (ScrnInfoPtr pScrn) * @return pointer to the allocated memory */ static NVAllocRec * -NVAllocateOverlayMemory(ScrnInfoPtr pScrn, NVAllocRec *mem, int size) +NVAllocateVideoMemory(ScrnInfoPtr pScrn, NVAllocRec *mem, int size) { NVPtr pNv = NVPTR(pScrn); - /* The code assumes the XAA fb manager is being used here, - * which allocates in pixels. We allocate in bytes so we - * need to adjust the size here. + /* + We allocate in bytes, so we need to adapt. */ size *= (pScrn->bitsPerPixel >> 3); if(mem) { - if(mem->size >= size) // if(mem->size == size) + if(mem->size >= size) return mem; NVFreeMemory(pNv, mem); } @@ -252,6 +238,34 @@ NVAllocateOverlayMemory(ScrnInfoPtr pScrn, NVAllocRec *mem, int size) return NVAllocateMemory(pNv, NOUVEAU_MEM_FB, size); /* align 32? */ } +/** + * NVAllocateTTMemory + * allocates TT memory for a given port + * + * @param pScrn screen which requests the memory + * @param mem pointer to previously allocated memory for reallocation + * @param size size of requested memory segment + * @return pointer to the allocated memory + */ +static NVAllocRec * +NVAllocateTTMemory(ScrnInfoPtr pScrn, NVAllocRec *mem, int size) +{ + NVPtr pNv = NVPTR(pScrn); + + /* + We allocate in bytes, so we need to adapt. + */ + size *= (pScrn->bitsPerPixel >> 3); + + if(mem) { + if(mem->size >= size) + return mem; + NVFreeMemory(pNv, mem); + } + /*We take only AGP memory, because PCI DMA is too slow and I prefer a fallback on CPU copy.*/ + return NVAllocateMemory(pNv, NOUVEAU_MEM_AGP, size); /* align 32? */ +} + /** * NVFreeOverlayMemory * frees memory held by the overlay port @@ -269,6 +283,16 @@ NVFreeOverlayMemory(ScrnInfoPtr pScrn) NVFreeMemory(pNv, pPriv->video_mem); pPriv->video_mem = NULL; } + + if(pPriv->TT_mem_chunk[0]) { + NVFreeMemory(pNv, pPriv->video_mem); + pPriv->video_mem = NULL; + } + + if(pPriv->TT_mem_chunk[1]) { + NVFreeMemory(pNv, pPriv->video_mem); + pPriv->video_mem = NULL; + } } /** @@ -287,6 +311,16 @@ NVFreeBlitMemory(ScrnInfoPtr pScrn) NVFreeMemory(pNv, pPriv->video_mem); pPriv->video_mem = NULL; } + + if(pPriv->TT_mem_chunk[0]) { + NVFreeMemory(pNv, pPriv->video_mem); + pPriv->video_mem = NULL; + } + + if(pPriv->TT_mem_chunk[1]) { + NVFreeMemory(pNv, pPriv->video_mem); + pPriv->video_mem = NULL; + } } /** @@ -737,7 +771,7 @@ NVGetOverlayPortAttribute(ScrnInfoPtr pScrn, Atom attribute, else if (attribute == xvColorKey) *value = pPriv->colorKey; else if (attribute == xvAutopaintColorKey) - *value = (pPriv->autopaintColorKey) ? 1 : 0; + *value = (pPriv->autopaintColorKey) ? 1 : 0; else if (attribute == xvITURBT709) *value = (pPriv->iturbt_709) ? 1 : 0; else @@ -916,7 +950,7 @@ static inline void NVCopyData420(unsigned char *src1, unsigned char *src2, /** * NVPutImage - * PutImage is "the" important function of the Xv extention. + * PutImage is "the" important function of the Xv extension. * a client (e.g. video player) calls this function for every * image (of the video) to be displayed. this function then * scales and displays the image. @@ -1037,7 +1071,7 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, if (pPriv->doubleBuffer) // double buffering ... newSize <<= 1; // ... means double the amount of VRAM needed - pPriv->video_mem = NVAllocateOverlayMemory(pScrn, pPriv->video_mem, + pPriv->video_mem = NVAllocateVideoMemory(pScrn, pPriv->video_mem, newSize); if (!pPriv->video_mem) return BadAlloc; @@ -1115,12 +1149,36 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, return BadImplementation; } + //xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Got fence handle %lld\n", fence_id); - + /*Now we take a decision regarding the way we send the data to the card. + Either we use double buffering of "private" TT memory + Either we rely on X's GARTScratch + Either we fallback on CPU copy + */ + pPriv->TT_mem_chunk[0] = NVAllocateTTMemory(pScrn, pPriv->TT_mem_chunk[0], + newSize); + pPriv->TT_mem_chunk[1] = NVAllocateTTMemory(pScrn, pPriv->TT_mem_chunk[1], + newSize); + + + NVAllocRec * destination_buffer; + + if ( pPriv->TT_mem_chunk[pPriv->currentHostBuffer] ) + { + destination_buffer = pPriv->TT_mem_chunk[pPriv->currentHostBuffer]; + xf86DrvMsg(0, X_INFO, "Using private TT memory chunk #%d\n", pPriv->currentHostBuffer); + } + else + { + destination_buffer = pNv->GARTScratch; + xf86DrvMsg(0, X_INFO, "Using global GART memory chunk\n", pPriv->currentHostBuffer); + } + /*Below is *almost* a copypaste from NvAccelUploadM2MF, cannot use it directly because of YV12 -> YUY2 conversion */ - if ( nlines * line_len <= pNv->GARTScratch->size) + if ( nlines * line_len <= destination_buffer->size) { - char *dst = pNv->GARTScratch->map; + unsigned char *dst = destination_buffer->map; /* Upload to GART */ switch(id) { @@ -1153,7 +1211,7 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, NVDmaStart(pNv, NvSubMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); - NVDmaNext (pNv, (uint32_t)pNv->GARTScratch->offset); + NVDmaNext (pNv, (uint32_t)destination_buffer->offset); NVDmaNext (pNv, (uint32_t)offset); NVDmaNext (pNv, line_len); NVDmaNext (pNv, dstPitch); @@ -1178,7 +1236,7 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, NVDmaStart(pNv, NvSubScaledImage, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); NVDmaNext (pNv, NvDmaTT); /* source object */ - NVPutBlitImage(pScrn, pNv->GARTScratch->offset, id, + NVPutBlitImage(pScrn, destination_buffer->offset, id, dstPitch, &dstBox, xa, ya, xb, yb, width, height, @@ -1190,7 +1248,7 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, NV10_IMAGE_BLIT_NOTIFY, 1); NVDmaNext (pNv, 0); NVDmaStart(pNv, NvSubScaledImage, 0x100, 1); - NVDmaNext (pNv, 106); + NVDmaNext (pNv, 0); NVDmaStart(pNv, NvSubScaledImage, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); NVDmaNext (pNv, NvDmaFB); /* source object */ @@ -1202,10 +1260,11 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, } else //GART is too small, we fallback on CPU copy for simplicity { + xf86DrvMsg(0, X_ERROR, "Fallback on CPU copy not implemented yet\n"); } - - + pPriv->currentHostBuffer ^= 1; + if (!skip) { if (pPriv->blitter) { NVPutBlitImage(pScrn, offset, id, @@ -1225,7 +1284,7 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, } } - + return Success; } @@ -1331,7 +1390,7 @@ NVAllocSurface(ScrnInfoPtr pScrn, int id, pPriv->pitch = ((w << 1) + 63) & ~63; size = h * pPriv->pitch / bpp; - pPriv->video_mem = NVAllocateOverlayMemory(pScrn, + pPriv->video_mem = NVAllocateVideoMemory(pScrn, pPriv->video_mem, size); if (!pPriv->video_mem) -- cgit v1.2.1 From c4dfad770d380dacddd3be025e96f867047327cc Mon Sep 17 00:00:00 2001 From: Arthur Huillet Date: Thu, 26 Jul 2007 16:08:40 +0200 Subject: Completely removed notifier wait, when using double buffered stuff. I may have to re-add a wait in the future, but I'm not sure yet how to use two notifiers at a time. --- src/nv_video.c | 54 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/src/nv_video.c b/src/nv_video.c index aa27882..54b1a93 100644 --- a/src/nv_video.c +++ b/src/nv_video.c @@ -164,6 +164,7 @@ NVSetPortDefaults (ScrnInfoPtr pScrn, NVPortPrivPtr pPriv) pPriv->autopaintColorKey = TRUE; pPriv->doubleBuffer = TRUE; pPriv->iturbt_709 = FALSE; + pPriv->currentHostBuffer = 0; } /** @@ -1156,6 +1157,7 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, Either we rely on X's GARTScratch Either we fallback on CPU copy */ + pPriv->TT_mem_chunk[0] = NVAllocateTTMemory(pScrn, pPriv->TT_mem_chunk[0], newSize); pPriv->TT_mem_chunk[1] = NVAllocateTTMemory(pScrn, pPriv->TT_mem_chunk[1], @@ -1167,16 +1169,19 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, if ( pPriv->TT_mem_chunk[pPriv->currentHostBuffer] ) { destination_buffer = pPriv->TT_mem_chunk[pPriv->currentHostBuffer]; - xf86DrvMsg(0, X_INFO, "Using private TT memory chunk #%d\n", pPriv->currentHostBuffer); + //xf86DrvMsg(0, X_INFO, "Using private TT memory chunk #%d\n", pPriv->currentHostBuffer); } else { destination_buffer = pNv->GARTScratch; - xf86DrvMsg(0, X_INFO, "Using global GART memory chunk\n", pPriv->currentHostBuffer); + xf86DrvMsg(0, X_INFO, "Using global GART memory chunk\n"); } /*Below is *almost* a copypaste from NvAccelUploadM2MF, cannot use it directly because of YV12 -> YUY2 conversion */ - if ( nlines * line_len <= destination_buffer->size) + if ( !destination_buffer) + goto CPU_copy; + + if(nlines * line_len <= destination_buffer->size) { unsigned char *dst = destination_buffer->map; @@ -1219,17 +1224,22 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, NVDmaNext (pNv, nlines); NVDmaNext (pNv, (1<<8)|1); NVDmaNext (pNv, 0); - - NVNotifierReset(pScrn, pNv->Notifier0); - NVDmaStart(pNv, NvSubMemFormat, - NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); - NVDmaNext (pNv, 0); + + if ( destination_buffer == pNv->GARTScratch ) + { + NVNotifierReset(pScrn, pNv->Notifier0); + NVDmaStart(pNv, NvSubMemFormat, + NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); + NVDmaNext (pNv, 0); + } + NVDmaStart(pNv, NvSubMemFormat, 0x100, 1); NVDmaNext (pNv, 0); NVDmaKickoff(pNv); - - if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) - return FALSE; + + if ( destination_buffer == pNv->GARTScratch ) + if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) + return FALSE; } else { @@ -1243,23 +1253,29 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, src_w, src_h, drw_w, drw_h, clipBoxes, pDraw); - NVNotifierReset(pScrn, pNv->Notifier0); - NVDmaStart(pNv, NvSubScaledImage, - NV10_IMAGE_BLIT_NOTIFY, 1); - NVDmaNext (pNv, 0); + if ( destination_buffer == pNv->GARTScratch ) + { + NVNotifierReset(pScrn, pNv->Notifier0); + NVDmaStart(pNv, NvSubScaledImage, + NV10_IMAGE_BLIT_NOTIFY, 1); + NVDmaNext (pNv, 0); + } + NVDmaStart(pNv, NvSubScaledImage, 0x100, 1); NVDmaNext (pNv, 0); NVDmaStart(pNv, NvSubScaledImage, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); NVDmaNext (pNv, NvDmaFB); /* source object */ NVDmaKickoff(pNv); - if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) - return FALSE; + + if ( destination_buffer == pNv->GARTScratch ) + if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) + return FALSE; return Success; } } - else //GART is too small, we fallback on CPU copy for simplicity - { + else { //GART is too small, we fallback on CPU copy for simplicity + CPU_copy: xf86DrvMsg(0, X_ERROR, "Fallback on CPU copy not implemented yet\n"); } -- cgit v1.2.1 From 2c60f6e9fc5260eba5b7ddaf67085781f35bfc58 Mon Sep 17 00:00:00 2001 From: Arthur Huillet Date: Thu, 26 Jul 2007 23:00:02 +0200 Subject: re-added CPU copy code as a second fallback option (first being to use X GARTScratch) --- src/nv_video.c | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/src/nv_video.c b/src/nv_video.c index 54b1a93..19f7c53 100644 --- a/src/nv_video.c +++ b/src/nv_video.c @@ -263,8 +263,8 @@ NVAllocateTTMemory(ScrnInfoPtr pScrn, NVAllocRec *mem, int size) return mem; NVFreeMemory(pNv, mem); } - /*We take only AGP memory, because PCI DMA is too slow and I prefer a fallback on CPU copy.*/ - return NVAllocateMemory(pNv, NOUVEAU_MEM_AGP, size); /* align 32? */ + /*We may take PCI memory, but that does not mean we won't fallback on CPU copy in that case.*/ + return NVAllocateMemory(pNv, NOUVEAU_MEM_AGP | NOUVEAU_MEM_PCI_ACCEPTABLE, size); /* align 32? */ } /** @@ -1169,15 +1169,15 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, if ( pPriv->TT_mem_chunk[pPriv->currentHostBuffer] ) { destination_buffer = pPriv->TT_mem_chunk[pPriv->currentHostBuffer]; - //xf86DrvMsg(0, X_INFO, "Using private TT memory chunk #%d\n", pPriv->currentHostBuffer); + xf86DrvMsg(0, X_INFO, "Using private TT memory chunk #%d\n", pPriv->currentHostBuffer); } else { - destination_buffer = pNv->GARTScratch; - xf86DrvMsg(0, X_INFO, "Using global GART memory chunk\n"); + /*destination_buffer = pNv->GARTScratch; + xf86DrvMsg(0, X_INFO, "Using global GART memory chunk\n");*/ + destination_buffer = NULL; } - /*Below is *almost* a copypaste from NvAccelUploadM2MF, cannot use it directly because of YV12 -> YUY2 conversion */ if ( !destination_buffer) goto CPU_copy; @@ -1276,7 +1276,27 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, } else { //GART is too small, we fallback on CPU copy for simplicity CPU_copy: - xf86DrvMsg(0, X_ERROR, "Fallback on CPU copy not implemented yet\n"); + xf86DrvMsg(0, X_INFO, "Fallback on CPU copy\n"); + unsigned char * video_mem_destination = pPriv->video_mem->map + (offset - (uint32_t)pPriv->video_mem->offset); + switch(id) + { + case FOURCC_YV12: + case FOURCC_I420: + + NVCopyData420(buf + (top * srcPitch) + left, + buf + s2offset, buf + s3offset, + video_mem_destination, srcPitch, srcPitch2, + dstPitch, nlines, npixels); + + break; + case FOURCC_UYVY: + case FOURCC_YUY2: + case FOURCC_RGB: + memcpy(video_mem_destination, buf, srcPitch * nlines); + break; + default: + return BadImplementation; + } } pPriv->currentHostBuffer ^= 1; -- cgit v1.2.1 From 8544c0ce64780be1bb5f66550d9d6f1e3c87865c Mon Sep 17 00:00:00 2001 From: Arthur Huillet Date: Fri, 27 Jul 2007 15:11:31 +0200 Subject: Removed comments in preparation for upstream push --- src/nv_video.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/nv_video.c b/src/nv_video.c index 19f7c53..047da6e 100644 --- a/src/nv_video.c +++ b/src/nv_video.c @@ -1169,13 +1169,13 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, if ( pPriv->TT_mem_chunk[pPriv->currentHostBuffer] ) { destination_buffer = pPriv->TT_mem_chunk[pPriv->currentHostBuffer]; - xf86DrvMsg(0, X_INFO, "Using private TT memory chunk #%d\n", pPriv->currentHostBuffer); + //xf86DrvMsg(0, X_INFO, "Using private TT memory chunk #%d\n", pPriv->currentHostBuffer); } else { - /*destination_buffer = pNv->GARTScratch; - xf86DrvMsg(0, X_INFO, "Using global GART memory chunk\n");*/ - destination_buffer = NULL; + destination_buffer = pNv->GARTScratch; + //xf86DrvMsg(0, X_INFO, "Using global GART memory chunk\n"); + //destination_buffer = NULL; } if ( !destination_buffer) @@ -1276,7 +1276,7 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, } else { //GART is too small, we fallback on CPU copy for simplicity CPU_copy: - xf86DrvMsg(0, X_INFO, "Fallback on CPU copy\n"); + //xf86DrvMsg(0, X_INFO, "Fallback on CPU copy\n"); unsigned char * video_mem_destination = pPriv->video_mem->map + (offset - (uint32_t)pPriv->video_mem->offset); switch(id) { -- cgit v1.2.1 From 200c82634971b32bcc308b5e07c113048cf37aa4 Mon Sep 17 00:00:00 2001 From: Arthur Huillet Date: Fri, 27 Jul 2007 16:28:48 +0200 Subject: Xv: gotos are evil --- src/nv_video.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nv_video.c b/src/nv_video.c index 047da6e..121f2e7 100644 --- a/src/nv_video.c +++ b/src/nv_video.c @@ -1165,6 +1165,7 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, NVAllocRec * destination_buffer; + unsigned char * video_mem_destination; if ( pPriv->TT_mem_chunk[pPriv->currentHostBuffer] ) { @@ -1276,8 +1277,7 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, } else { //GART is too small, we fallback on CPU copy for simplicity CPU_copy: - //xf86DrvMsg(0, X_INFO, "Fallback on CPU copy\n"); - unsigned char * video_mem_destination = pPriv->video_mem->map + (offset - (uint32_t)pPriv->video_mem->offset); + video_mem_destination = pPriv->video_mem->map + (offset - (uint32_t)pPriv->video_mem->offset); switch(id) { case FOURCC_YV12: -- cgit v1.2.1 From 175c2b7f7b9e45924e1de7f7ea1130fda76d02fd Mon Sep 17 00:00:00 2001 From: Arthur Huillet Date: Fri, 27 Jul 2007 19:50:48 +0200 Subject: no overlay with composite --- src/nv_video.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nv_video.c b/src/nv_video.c index 121f2e7..02d5a8d 100644 --- a/src/nv_video.c +++ b/src/nv_video.c @@ -1780,11 +1780,11 @@ NVSetupOverlayVideo(ScreenPtr pScreen) * blit adaptor the default if composite is enabled? */ #ifdef COMPOSITE -/* if (!noCompositeExtension) { + if (!noCompositeExtension) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "XV: Video overlay not available, composite enabled\n"); return NULL; - }*/ + } #endif overlayAdaptor = NV10SetupOverlayVideo(pScreen); if (overlayAdaptor) -- cgit v1.2.1 From a434cc6dd38ffa658bacf5547ec0384ec5351e9c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Sat, 28 Jul 2007 16:34:49 +1000 Subject: exa: disable compositing on big endian machines This at least allows me to see what I'm typing for now :-) --- src/nv_exa.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/nv_exa.c b/src/nv_exa.c index fde1d09..56443ba 100644 --- a/src/nv_exa.c +++ b/src/nv_exa.c @@ -620,12 +620,14 @@ Bool NVExaInit(ScreenPtr pScreen) pNv->EXADriverPtr->DoneSolid = NVExaDoneSolid; switch (pNv->Architecture) { +#if X_BYTE_ORDER == X_LITTLE_ENDIAN case NV_ARCH_40: pNv->EXADriverPtr->CheckComposite = NV30EXACheckComposite; pNv->EXADriverPtr->PrepareComposite = NV30EXAPrepareComposite; pNv->EXADriverPtr->Composite = NV30EXAComposite; pNv->EXADriverPtr->DoneComposite = NV30EXADoneComposite; break; +#endif default: if (!pNv->BlendingPossible) break; -- cgit v1.2.1 From bceef7210e44dc643a5f7a5b5683d5c434a07565 Mon Sep 17 00:00:00 2001 From: Arthur Huillet Date: Sun, 29 Jul 2007 01:54:42 +0200 Subject: Xv: fixed bugs when displayed only part of the source image (tvtime with overscan) Xv: fixed bug with overlay behaving badly when window is partly out of screen Xv: clean up NVPutImage code --- src/nv_video.c | 232 ++++++++++++++++++++++++++------------------------------- 1 file changed, 107 insertions(+), 125 deletions(-) diff --git a/src/nv_video.c b/src/nv_video.c index 02d5a8d..13aad2a 100644 --- a/src/nv_video.c +++ b/src/nv_video.c @@ -59,6 +59,7 @@ typedef struct _NVPortPrivRec { int offset; NVAllocRec * TT_mem_chunk[2]; int currentHostBuffer; + struct drm_nouveau_notifier_alloc *DMANotifier[2]; } NVPortPrivRec, *NVPortPrivPtr; #define GET_OVERLAY_PRIVATE(pNv) \ @@ -225,10 +226,6 @@ NVAllocateVideoMemory(ScrnInfoPtr pScrn, NVAllocRec *mem, int size) { NVPtr pNv = NVPTR(pScrn); - /* - We allocate in bytes, so we need to adapt. - */ - size *= (pScrn->bitsPerPixel >> 3); if(mem) { if(mem->size >= size) @@ -253,10 +250,6 @@ NVAllocateTTMemory(ScrnInfoPtr pScrn, NVAllocRec *mem, int size) { NVPtr pNv = NVPTR(pScrn); - /* - We allocate in bytes, so we need to adapt. - */ - size *= (pScrn->bitsPerPixel >> 3); if(mem) { if(mem->size >= size) @@ -421,7 +414,10 @@ NVPutOverlayImage(ScrnInfoPtr pScrn, int offset, int id, /* we always paint V4L's color key */ if (!pPriv->grabbedByV4L) REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); + { + xf86DrvMsg(0, X_INFO, "calling xf86XVFillKeyHelper at %u, colorkey is %u\n", GetTimeInMillis(), pPriv->colorKey); xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); + } } if(pNv->CurrentLayout.mode->Flags & V_DBLSCAN) { @@ -593,10 +589,6 @@ NVPutBlitImage(ScrnInfoPtr pScrn, int src_offset, int id, NVDmaStart(pNv, NvSubScaledImage, STRETCH_BLIT_FORMAT, 1); NVDmaNext (pNv, src_format); } - - NVDmaStart(pNv, NvSubScaledImage, - NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); - NVDmaNext (pNv, NvDmaTT); /* source object */ while(nbox--) { NVDmaStart(pNv, NvSubRectangle, RECT_SOLID_COLOR, 1); @@ -990,33 +982,29 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, { NVPortPrivPtr pPriv = (NVPortPrivPtr)data; NVPtr pNv = NVPTR(pScrn); - INT32 xa, xb, ya, yb; - int newSize, offset, s2offset, s3offset; - int srcPitch, srcPitch2, dstPitch; - int top, left, right, bottom, npixels, nlines, bpp; + INT32 xa = 0, xb = 0, ya = 0, yb = 0; //source box + int newSize = 0, offset = 0, s2offset = 0, s3offset = 0; //byte size of the whole source data, card VRAM offset, source offsets for U and V planes + int srcPitch = 0, srcPitch2 = 0, dstPitch = 0; //source pitch, source pitch of U and V planes in case of YV12, VRAM destination pitch + int top = 0, left = 0, right = 0, bottom = 0, npixels = 0, nlines = 0; //position of the given source data (using src_*), number of pixels and lines we are interested in Bool skip = FALSE; BoxRec dstBox; - CARD32 tmp; - int line_len; - - /* s2offset, s3offset - byte offsets into U and V plane of the - * source where copying starts. YV12 is indeed one plane of Y and two subsampled planes of U and V - * offset - byte offset to the first line of the destination. - * dst_start - byte address to the first displayed pel. - */ + CARD32 tmp = 0; + int line_len = 0; //length of a line, like npixels, but in bytes + int DMAoffset = 0; //additional VRAM offset to start the DMA copy to + NVAllocRec * destination_buffer = NULL; + unsigned char * video_mem_destination = NULL; if (pPriv->grabbedByV4L) return Success; - /* make the compiler happy */ - s2offset = s3offset = srcPitch2 = 0; - if (!pPriv->blitter) { /* overlay hardware scaler limitation */ if (src_w > (drw_w << 3)) drw_w = src_w >> 3; if (src_h > (drw_h << 3)) drw_h = src_h >> 3; } + + //xf86DrvMsg(0, X_INFO, "%s: src %hd,%hd->%hd,%hd dst %hd,%hd->%hd,%hd w %hd h %hd\n", pPriv->blitter ? "Blitter" : "Overlay", src_x, src_y, src_w, src_h, drw_x, drw_y, drw_w, drw_h, width, height); /* Clip */ xa = src_x; @@ -1041,9 +1029,7 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, } - /* determine required memory size */ - bpp = pScrn->bitsPerPixel >> 3; // bytes per pixel - + /* Set up source and destination pitch (usually the same, except for YV12 that is converted to YUY2, and some alignment considerations*/ switch(id) { case FOURCC_YV12: case FOURCC_I420: @@ -1065,9 +1051,9 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, default: return BadImplementation; } - /* dstPitch = number of bytes per row - but the allocation is done is pixel, hence the division to get the real number of bytes */ - newSize = height * dstPitch / bpp; + + + newSize = height * dstPitch; if (pPriv->doubleBuffer) // double buffering ... newSize <<= 1; // ... means double the amount of VRAM needed @@ -1078,24 +1064,26 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, return BadAlloc; offset = pPriv->video_mem->offset; + + /*The overlay supports hardware double buffering. We handle this here*/ if (pPriv->doubleBuffer) { int mask = 1 << (pPriv->currentBuffer << 2); /* overwrite the newest buffer if there's not one free */ if (nvReadVIDEO(pNv, NV_PVIDEO_BUFFER) & mask) { if (!pPriv->currentBuffer) - offset += (height + 1) * dstPitch; + offset += (height) * dstPitch; skip = TRUE; } else if (pPriv->currentBuffer) - offset += (height + 1) * dstPitch; + offset += (height) * dstPitch; } /* We need to enlarge the copied rectangle by a pixel so the HW * filtering doesn't pick up junk laying outside of the source */ - /* fixed point arithmetic */ + /* This is fixed point arithmetic, as xf86XVClipVideoHelper probably turns its parameter into fixed point values */ left = (xa - 0x00010000) >> 16; if (left < 0) left = 0; top = (ya - 0x00010000) >> 16; @@ -1105,9 +1093,12 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, bottom = (yb + 0x0001ffff) >> 16; if (bottom > height) bottom = height; + /* Reason of this call probably has to do with flushing the GPU before being able to operate on VRAM. We could get rid of it now, at least in most cases. */ if(pPriv->blitter) NVSync(pScrn); + /* Now we calculate the different values we need for the transfer : width and height of the rectangle of "interesting" data in the source buffer (usually everything, + but it may not be the case, e.g. with tvtime and overscanning. */ switch(id) { case FOURCC_YV12: case FOURCC_I420: @@ -1116,168 +1107,134 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, top &= ~1; nlines = ((bottom + 1) & ~1) - top; - offset += (left << 1) + (top * dstPitch); + DMAoffset += (left << 1) + (top * dstPitch); tmp = ((top >> 1) * srcPitch2) + (left >> 1); s2offset += tmp; s3offset += tmp; + line_len = npixels << 1; if (id == FOURCC_I420) { tmp = s2offset; s2offset = s3offset; s3offset = tmp; } - line_len = dstPitch; + buf += 0; //we do not touch it yet, because we need the base pointer to find the position of U and V planes break; case FOURCC_UYVY: case FOURCC_YUY2: left &= ~1; npixels = ((right + 1) & ~1) - left; nlines = bottom - top; - + line_len = npixels << 1; left <<= 1; buf += (top * srcPitch) + left; - offset += left + (top * dstPitch); - line_len = width << 1; + DMAoffset += left + (top * dstPitch); break; case FOURCC_RGB: npixels = right - left; nlines = bottom - top; left <<= 2; buf += (top * srcPitch) + left; - offset += left + (top * dstPitch); - line_len = width << 2; + line_len = npixels << 2; + DMAoffset += left + (top * dstPitch); break; default: return BadImplementation; } - //xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Got fence handle %lld\n", fence_id); - /*Now we take a decision regarding the way we send the data to the card. Either we use double buffering of "private" TT memory Either we rely on X's GARTScratch Either we fallback on CPU copy */ + /* Try to allocate host-side double buffers (this function will return if the memory has already been allocated)*/ pPriv->TT_mem_chunk[0] = NVAllocateTTMemory(pScrn, pPriv->TT_mem_chunk[0], newSize); pPriv->TT_mem_chunk[1] = NVAllocateTTMemory(pScrn, pPriv->TT_mem_chunk[1], newSize); - - NVAllocRec * destination_buffer; - unsigned char * video_mem_destination; - if ( pPriv->TT_mem_chunk[pPriv->currentHostBuffer] ) - { + { //if we have a private buffer destination_buffer = pPriv->TT_mem_chunk[pPriv->currentHostBuffer]; - //xf86DrvMsg(0, X_INFO, "Using private TT memory chunk #%d\n", pPriv->currentHostBuffer); + //xf86DrvMsg(0, X_INFO, "Using private mem chunk #%d\n", pPriv->currentHostBuffer); } else - { + { //otherwise we fall back of GART destination_buffer = pNv->GARTScratch; //xf86DrvMsg(0, X_INFO, "Using global GART memory chunk\n"); - //destination_buffer = NULL; } - - if ( !destination_buffer) + + if ( !destination_buffer) //if we have no GART at all goto CPU_copy; - if(nlines * line_len <= destination_buffer->size) + if(nlines * line_len <= destination_buffer->size) /*XXX: update the check*/ { unsigned char *dst = destination_buffer->map; - + int i = 0; + /* Upload to GART */ switch(id) { case FOURCC_YV12: case FOURCC_I420: - NVCopyData420(buf + (top * srcPitch) + left, buf + s2offset, buf + s3offset, dst, srcPitch, srcPitch2, - dstPitch, nlines, npixels); - + line_len, nlines, npixels); break; case FOURCC_UYVY: case FOURCC_YUY2: case FOURCC_RGB: - memcpy(dst, buf, srcPitch * nlines); + for ( i=0; i < nlines; i++) + { + memcpy(dst, buf, line_len); + dst += line_len; + buf += srcPitch; + } break; default: return BadImplementation; } - if ( !pPriv -> blitter ) - { - NVDmaStart(pNv, NvSubMemFormat, MEMFORMAT_DMA_OBJECT_IN, 2); - NVDmaNext (pNv, NvDmaTT); - NVDmaNext (pNv, NvDmaFB); - pNv->M2MFDirection = 1; + + NVDmaStart(pNv, NvSubMemFormat, MEMFORMAT_DMA_OBJECT_IN, 2); + NVDmaNext (pNv, NvDmaTT); + NVDmaNext (pNv, NvDmaFB); + pNv->M2MFDirection = 1; - /* DMA to VRAM */ + /* DMA to VRAM */ - NVDmaStart(pNv, NvSubMemFormat, - NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); - NVDmaNext (pNv, (uint32_t)destination_buffer->offset); - NVDmaNext (pNv, (uint32_t)offset); - NVDmaNext (pNv, line_len); - NVDmaNext (pNv, dstPitch); - NVDmaNext (pNv, line_len); - NVDmaNext (pNv, nlines); - NVDmaNext (pNv, (1<<8)|1); - NVDmaNext (pNv, 0); - - if ( destination_buffer == pNv->GARTScratch ) - { - NVNotifierReset(pScrn, pNv->Notifier0); - NVDmaStart(pNv, NvSubMemFormat, - NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); - NVDmaNext (pNv, 0); - } - - NVDmaStart(pNv, NvSubMemFormat, 0x100, 1); - NVDmaNext (pNv, 0); - NVDmaKickoff(pNv); + NVDmaStart(pNv, NvSubMemFormat, + NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); + NVDmaNext (pNv, (uint32_t)destination_buffer->offset); + NVDmaNext (pNv, (uint32_t)offset + DMAoffset); + NVDmaNext (pNv, line_len); + NVDmaNext (pNv, dstPitch); + NVDmaNext (pNv, line_len); + NVDmaNext (pNv, nlines); + NVDmaNext (pNv, (1<<8)|1); + NVDmaNext (pNv, 0); - if ( destination_buffer == pNv->GARTScratch ) - if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) - return FALSE; - } - else + if ( destination_buffer == pNv->GARTScratch ) { - NVDmaStart(pNv, NvSubScaledImage, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); - NVDmaNext (pNv, NvDmaTT); /* source object */ - - NVPutBlitImage(pScrn, destination_buffer->offset, id, - dstPitch, &dstBox, - xa, ya, xb, yb, - width, height, - src_w, src_h, drw_w, drw_h, - clipBoxes, pDraw); - - if ( destination_buffer == pNv->GARTScratch ) - { - NVNotifierReset(pScrn, pNv->Notifier0); - NVDmaStart(pNv, NvSubScaledImage, - NV10_IMAGE_BLIT_NOTIFY, 1); - NVDmaNext (pNv, 0); - } - - NVDmaStart(pNv, NvSubScaledImage, 0x100, 1); + NVNotifierReset(pScrn, pNv->Notifier0); + NVDmaStart(pNv, NvSubMemFormat, + NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); NVDmaNext (pNv, 0); - - NVDmaStart(pNv, NvSubScaledImage, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); - NVDmaNext (pNv, NvDmaFB); /* source object */ - NVDmaKickoff(pNv); - - if ( destination_buffer == pNv->GARTScratch ) - if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) - return FALSE; - return Success; } + + NVDmaStart(pNv, NvSubMemFormat, 0x100, 1); + NVDmaNext (pNv, 0); + NVDmaKickoff(pNv); + + if ( destination_buffer == pNv->GARTScratch ) + if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) + return FALSE; } - else { //GART is too small, we fallback on CPU copy for simplicity + else { //GART is too small, we fallback on CPU copy CPU_copy: video_mem_destination = pPriv->video_mem->map + (offset - (uint32_t)pPriv->video_mem->offset); + int i = 0; + //xf86DrvMsg(0, X_INFO, "Fallback on CPU copy\n"); switch(id) { case FOURCC_YV12: @@ -1292,7 +1249,32 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, case FOURCC_UYVY: case FOURCC_YUY2: case FOURCC_RGB: - memcpy(video_mem_destination, buf, srcPitch * nlines); + for ( i=0; i < nlines; i++) + { + int dwords = npixels << 1; + while (dwords & ~0x03) + { + *video_mem_destination = *buf; + *(video_mem_destination + 1) = *(buf + 1); + *(video_mem_destination + 2) = *(buf + 2); + *(video_mem_destination + 3) = *(buf + 3); + video_mem_destination += 4; + buf += 4; + dwords -= 4; + } + switch ( dwords ) + { + case 3: + *(video_mem_destination + 2) = *(buf + 2); + case 2: + *(video_mem_destination + 1) = *(buf + 1); + case 1: + *video_mem_destination = *buf; + } + + video_mem_destination += dstPitch - (npixels << 1); + buf += srcPitch - (npixels << 1); + } break; default: return BadImplementation; -- cgit v1.2.1 From 68070ff7309c8b1cf149490dcf537892b0bf44bc Mon Sep 17 00:00:00 2001 From: Arthur Huillet Date: Mon, 30 Jul 2007 03:27:55 +0200 Subject: Xv now manages a pool of 6 notifiers for its double buffering. Also improved the memory allocation logic. --- src/nv_dma.h | 10 ++- src/nv_video.c | 228 ++++++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 196 insertions(+), 42 deletions(-) diff --git a/src/nv_dma.h b/src/nv_dma.h index 16be1fd..fff3dc4 100644 --- a/src/nv_dma.h +++ b/src/nv_dma.h @@ -68,7 +68,15 @@ enum DMAObjects { Nv3D = 0x80000019, NvDmaFB = 0xD8000001, NvDmaTT = 0xD8000002, - NvDmaNotifier0 = 0xD8000003 + NvDmaNotifier0 = 0xD8000003, + + /*XVideo notifiers need to have consecutive handles, be careful when remapping*/ + NvDmaXvNotifier0 = 0xE8000000, + NvDmaXvNotifier1 = 0xE8000001, + NvDmaXvNotifier2 = 0xE8000002, + NvDmaXvNotifier3 = 0xE8000003, + NvDmaXvNotifier4 = 0xE8000004, + NvDmaXvNotifier5 = 0xE8000005, }; enum DMASubchannel { diff --git a/src/nv_video.c b/src/nv_video.c index 13aad2a..52a2e2f 100644 --- a/src/nv_video.c +++ b/src/nv_video.c @@ -38,6 +38,10 @@ #define NUM_BLIT_PORTS 32 +/* Value taken by pPriv -> currentHostBuffer when we failed to allocate the two private buffers in TT memory, so that we can catch this case +and attempt no other allocation afterwards (performance reasons) */ +#define NO_PRIV_HOST_BUFFER_AVAILABLE 9999 + typedef struct _NVPortPrivRec { short brightness; short contrast; @@ -62,6 +66,20 @@ typedef struct _NVPortPrivRec { struct drm_nouveau_notifier_alloc *DMANotifier[2]; } NVPortPrivRec, *NVPortPrivPtr; + +/* Xv DMA notifiers status tracing */ + +enum { +XV_DMA_NOTIFIER_NOALLOC=0, //notifier not allocated +XV_DMA_NOTIFIER_INUSE=1, +XV_DMA_NOTIFIER_FREE=2, //notifier allocated, ready for use +}; + +/* We have six notifiers available, they are not allocated at startup */ +int XvDMANotifierStatus[6]= { XV_DMA_NOTIFIER_NOALLOC , XV_DMA_NOTIFIER_NOALLOC , XV_DMA_NOTIFIER_NOALLOC , + XV_DMA_NOTIFIER_NOALLOC , XV_DMA_NOTIFIER_NOALLOC , XV_DMA_NOTIFIER_NOALLOC }; +struct drm_nouveau_notifier_alloc * XvDMANotifiers[6]; + #define GET_OVERLAY_PRIVATE(pNv) \ (NVPortPrivPtr)((pNv)->overlayAdaptor->pPortPrivates[0].ptr) @@ -212,6 +230,58 @@ NVStopOverlay (ScrnInfoPtr pScrn) nvWriteVIDEO(pNv, NV_PVIDEO_STOP, 1); } +/** + * NVXvDMANotifierAlloc + * allocates a notifier from the table of 6 we have + * + * @return a notifier instance or NULL on error + */ +static struct drm_nouveau_notifier_alloc * NVXvDMANotifierAlloc(ScrnInfoPtr pScrn) +{ +int i; +for ( i = 0; i < 6; i ++ ) + { + if ( XvDMANotifierStatus[i] == XV_DMA_NOTIFIER_INUSE ) + continue; + + if ( XvDMANotifierStatus[i] == XV_DMA_NOTIFIER_FREE ) + { + XvDMANotifierStatus[i] = XV_DMA_NOTIFIER_INUSE; + return XvDMANotifiers[i]; + } + + if ( XvDMANotifierStatus[i] == XV_DMA_NOTIFIER_NOALLOC ) + { + XvDMANotifiers[i] = NVNotifierAlloc(pScrn, NvDmaXvNotifier0 + i); + if (XvDMANotifiers[i]) + { + XvDMANotifierStatus[i] = XV_DMA_NOTIFIER_INUSE; + return XvDMANotifiers[i]; + } + else return NULL; + } + } + +return NULL; +} + +/** + * NVXvDMANotifierFree + * frees a notifier from the table of 6 we have + * + * + */ +static void NVXvDMANotifierFree(ScrnInfoPtr pScrn, struct drm_nouveau_notifier_alloc * target) +{ +int i; +for ( i = 0; i < 6; i ++ ) + { + if ( XvDMANotifiers[i] == target ) + break; + } +XvDMANotifierStatus[i] = XV_DMA_NOTIFIER_FREE; +} + /** * NVAllocateVideoMemory * allocates video memory for a given port @@ -261,32 +331,58 @@ NVAllocateTTMemory(ScrnInfoPtr pScrn, NVAllocRec *mem, int size) } /** - * NVFreeOverlayMemory - * frees memory held by the overlay port - * this function (unlike NVAllocateOverlayMemory) is "Overlay"-specific + * NVFreePortMemory + * frees memory held by a given port * - * @param pScrn screen whose overlay port wants to free memory + * @param pScrn screen whose port wants to free memory + * @param pPriv port to free memory of */ static void -NVFreeOverlayMemory(ScrnInfoPtr pScrn) +NVFreePortMemory(ScrnInfoPtr pScrn, NVPortPrivPtr pPriv) { NVPtr pNv = NVPTR(pScrn); - NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv); + //xf86DrvMsg(0, X_INFO, "Freeing port memory - TTmem chunks %p %p, notifiers %p %p\n", pPriv->TT_mem_chunk[0], pPriv->TT_mem_chunk[1], pPriv->DMANotifier[0], pPriv->DMANotifier[1]); + if(pPriv->video_mem) { NVFreeMemory(pNv, pPriv->video_mem); pPriv->video_mem = NULL; } if(pPriv->TT_mem_chunk[0]) { - NVFreeMemory(pNv, pPriv->video_mem); - pPriv->video_mem = NULL; + NVFreeMemory(pNv, pPriv->TT_mem_chunk[0]); + pPriv->TT_mem_chunk[0] = NULL; } if(pPriv->TT_mem_chunk[1]) { - NVFreeMemory(pNv, pPriv->video_mem); - pPriv->video_mem = NULL; + NVFreeMemory(pNv, pPriv->TT_mem_chunk[1]); + pPriv->TT_mem_chunk[1] = NULL; + } + + if(pPriv->DMANotifier[0]) { + NVXvDMANotifierFree(pScrn, pPriv->DMANotifier[0]); + pPriv->DMANotifier[0] = NULL; + } + + if(pPriv->DMANotifier[1]) { + NVXvDMANotifierFree(pScrn, pPriv->DMANotifier[1]); + pPriv->DMANotifier[1] = NULL; } + +} + +/** + * NVFreeOverlayMemory + * frees memory held by the overlay port + * + * @param pScrn screen whose overlay port wants to free memory + */ +static void +NVFreeOverlayMemory(ScrnInfoPtr pScrn) +{ + NVPtr pNv = NVPTR(pScrn); + NVPortPrivPtr pPriv = GET_OVERLAY_PRIVATE(pNv); + NVFreePortMemory(pScrn, pPriv); } /** @@ -298,23 +394,9 @@ NVFreeOverlayMemory(ScrnInfoPtr pScrn) static void NVFreeBlitMemory(ScrnInfoPtr pScrn) { - NVPtr pNv = NVPTR(pScrn); + NVPtr pNv = NVPTR(pScrn); NVPortPrivPtr pPriv = GET_BLIT_PRIVATE(pNv); - - if(pPriv->video_mem) { - NVFreeMemory(pNv, pPriv->video_mem); - pPriv->video_mem = NULL; - } - - if(pPriv->TT_mem_chunk[0]) { - NVFreeMemory(pNv, pPriv->video_mem); - pPriv->video_mem = NULL; - } - - if(pPriv->TT_mem_chunk[1]) { - NVFreeMemory(pNv, pPriv->video_mem); - pPriv->video_mem = NULL; - } + NVFreePortMemory(pScrn, pPriv); } /** @@ -415,7 +497,7 @@ NVPutOverlayImage(ScrnInfoPtr pScrn, int offset, int id, if (!pPriv->grabbedByV4L) REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); { - xf86DrvMsg(0, X_INFO, "calling xf86XVFillKeyHelper at %u, colorkey is %u\n", GetTimeInMillis(), pPriv->colorKey); + //xf86DrvMsg(0, X_INFO, "calling xf86XVFillKeyHelper at %u, colorkey is %u\n", GetTimeInMillis(), pPriv->colorKey); xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); } } @@ -905,7 +987,7 @@ static inline void NVCopyData420(unsigned char *src1, unsigned char *src2, s1 = src1; s2 = src2; s3 = src3; i = w; - while (i > 4) { // wouldn't it be better to write (i >= 4) ? + while (i > 4) { #if X_BYTE_ORDER == X_BIG_ENDIAN dst[0] = (s1[0] << 24) | (s1[1] << 8) | (s3[0] << 16) | s2[0]; dst[1] = (s1[2] << 24) | (s1[3] << 8) | (s3[1] << 16) | s2[1]; @@ -1147,19 +1229,69 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, Either we fallback on CPU copy */ - /* Try to allocate host-side double buffers (this function will return if the memory has already been allocated)*/ - pPriv->TT_mem_chunk[0] = NVAllocateTTMemory(pScrn, pPriv->TT_mem_chunk[0], - newSize); - pPriv->TT_mem_chunk[1] = NVAllocateTTMemory(pScrn, pPriv->TT_mem_chunk[1], - newSize); + /* Try to allocate host-side double buffers, unless we have already failed*/ + /* We take only nlines * line_len bytes - that is, only the pixel data we are interested in - because the stuff in the GART is + written contiguously */ - if ( pPriv->TT_mem_chunk[pPriv->currentHostBuffer] ) + if ( pPriv -> currentHostBuffer != NO_PRIV_HOST_BUFFER_AVAILABLE ) + { + pPriv->TT_mem_chunk[0] = NVAllocateTTMemory(pScrn, pPriv->TT_mem_chunk[0], + nlines * line_len); + if ( pPriv->TT_mem_chunk[0] ) + { + pPriv->TT_mem_chunk[1] = NVAllocateTTMemory(pScrn, pPriv->TT_mem_chunk[1], + nlines * line_len); + + if ( ! pPriv->TT_mem_chunk[1] ) + { + NVFreeMemory(pNv, pPriv->TT_mem_chunk[0]); + pPriv->TT_mem_chunk[0] = NULL; + pPriv -> currentHostBuffer = NO_PRIV_HOST_BUFFER_AVAILABLE; + //xf86DrvMsg(0, X_INFO, "Alloc 1 failed\n"); + } + } + else + { + pPriv -> currentHostBuffer = NO_PRIV_HOST_BUFFER_AVAILABLE; + //xf86DrvMsg(0, X_INFO, "Alloc 0 failed\n"); + } + } + + if ( pPriv->currentHostBuffer != NO_PRIV_HOST_BUFFER_AVAILABLE ) { //if we have a private buffer destination_buffer = pPriv->TT_mem_chunk[pPriv->currentHostBuffer]; //xf86DrvMsg(0, X_INFO, "Using private mem chunk #%d\n", pPriv->currentHostBuffer); + + /* We know where we are going to write, but we are not sure yet whether we can do it directly, because + the card could be working on the buffer for the last-but-one frame. So we check if we have a notifier ready or not. + If we do, then we must wait for it before overwriting the buffer. + Else we need one, so we call the Xv notifier allocator.*/ + if ( pPriv->DMANotifier [ pPriv->currentHostBuffer ] ) + { + //xf86DrvMsg(0, X_INFO, "Waiting for notifier %p (%d)\n", pPriv->DMANotifier[pPriv->currentHostBuffer], pPriv->currentHostBuffer); + if (!NVNotifierWaitStatus(pScrn, pPriv->DMANotifier[pPriv->currentHostBuffer], 0, 0)) + return FALSE; + } + else + { + //xf86DrvMsg(0, X_INFO, "Allocating notifier...\n"); + pPriv->DMANotifier [ pPriv->currentHostBuffer ] = NVXvDMANotifierAlloc(pScrn); + if (! pPriv->DMANotifier [ pPriv->currentHostBuffer ] ) + { /* In case we are out of notifiers (then our guy is watching 3 movies at a time!!), we fallback on global GART, and free the private buffers. + I know that's a lot of code but I believe it's necessary to properly handle all the cases*/ + xf86DrvMsg(0, X_ERROR, "Ran out of Xv notifiers!\n"); + NVFreeMemory(pNv, pPriv->TT_mem_chunk[0]); + pPriv->TT_mem_chunk[0] = NULL; + NVFreeMemory(pNv, pPriv->TT_mem_chunk[1]); + pPriv->TT_mem_chunk[1] = NULL; + pPriv -> currentHostBuffer = NO_PRIV_HOST_BUFFER_AVAILABLE; + } + //xf86DrvMsg(0, X_INFO, "Got notifier %p\n", pPriv->DMANotifier [ pPriv->currentHostBuffer ]); + } } - else - { //otherwise we fall back of GART + + if ( pPriv -> currentHostBuffer == NO_PRIV_HOST_BUFFER_AVAILABLE ) + { //otherwise we fall back on DDX's GARTScratch destination_buffer = pNv->GARTScratch; //xf86DrvMsg(0, X_INFO, "Using global GART memory chunk\n"); } @@ -1167,7 +1299,7 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, if ( !destination_buffer) //if we have no GART at all goto CPU_copy; - if(nlines * line_len <= destination_buffer->size) /*XXX: update the check*/ + if(nlines * line_len <= destination_buffer->size) { unsigned char *dst = destination_buffer->map; int i = 0; @@ -1217,14 +1349,27 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, if ( destination_buffer == pNv->GARTScratch ) { NVNotifierReset(pScrn, pNv->Notifier0); + } + else { + NVNotifierReset(pScrn, pPriv->DMANotifier[pPriv->currentHostBuffer]); NVDmaStart(pNv, NvSubMemFormat, - NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); - NVDmaNext (pNv, 0); + NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); + NVDmaNext (pNv, pPriv->DMANotifier[pPriv->currentHostBuffer]->handle); } - + + + NVDmaStart(pNv, NvSubMemFormat, + NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); + NVDmaNext (pNv, 0); + NVDmaStart(pNv, NvSubMemFormat, 0x100, 1); NVDmaNext (pNv, 0); NVDmaKickoff(pNv); + + //Put back NvDmaNotifier0 for EXA + NVDmaStart(pNv, NvSubMemFormat, + NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); + NVDmaNext (pNv, NvDmaNotifier0); if ( destination_buffer == pNv->GARTScratch ) if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) @@ -1281,7 +1426,8 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, } } - pPriv->currentHostBuffer ^= 1; + if ( pPriv->currentHostBuffer != NO_PRIV_HOST_BUFFER_AVAILABLE ) + pPriv->currentHostBuffer ^= 1; if (!skip) { if (pPriv->blitter) { -- cgit v1.2.1 From 047aa7e0a6ecce59c9be8d36c51f082c0ddaafe8 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 6 Aug 2007 00:13:35 +1000 Subject: Clamp NV_MEMORY_TO_MEMORY_FORMAT_LINE_COUNT to 2047 lines. At least NV40 can't handle values larger than this. Patch fixes hang when visiting opengl.org. --- src/nv_exa.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/nv_exa.c b/src/nv_exa.c index 56443ba..700a49a 100644 --- a/src/nv_exa.c +++ b/src/nv_exa.c @@ -297,7 +297,10 @@ NVAccelDownloadM2MF(ScrnInfoPtr pScrn, char *dst, uint64_t src_offset, if (lc > line_count) lc = line_count; } - /*XXX: and hw limitations? */ + + /* HW limitations */ + if (lc > 2047) + lc = 2047; NVDmaStart(pNv, NvSubMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); @@ -387,7 +390,10 @@ NVAccelUploadM2MF(ScrnInfoPtr pScrn, uint64_t dst_offset, const char *src, if (lc > line_count) lc = line_count; } - /*XXX: and hw limitations? */ + + /* HW limitations */ + if (lc > 2047) + lc = 2047; /* Upload to GART */ if (src_pitch == line_len) { -- cgit v1.2.1 From 59d073c9b01a8f61675b8d74f5c55f134ddfb8bf Mon Sep 17 00:00:00 2001 From: Arthur Huillet Date: Mon, 6 Aug 2007 01:37:17 +0200 Subject: Xv: waiting for last transfers to finish before freeing notifiers --- src/nv_video.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/nv_video.c b/src/nv_video.c index 52a2e2f..67a231f 100644 --- a/src/nv_video.c +++ b/src/nv_video.c @@ -349,6 +349,16 @@ NVFreePortMemory(ScrnInfoPtr pScrn, NVPortPrivPtr pPriv) pPriv->video_mem = NULL; } + if ( pPriv->TT_mem_chunk[ 0 ] && pPriv->DMANotifier [ 0 ] ) + { + NVNotifierWaitStatus(pScrn, pPriv->DMANotifier [ 0 ] , 0, 1000); + } + + if ( pPriv->TT_mem_chunk[ 1 ] && pPriv->DMANotifier [ 1 ] ) + { + NVNotifierWaitStatus(pScrn, pPriv->DMANotifier [ 1 ] , 0, 1000); + } + if(pPriv->TT_mem_chunk[0]) { NVFreeMemory(pNv, pPriv->TT_mem_chunk[0]); pPriv->TT_mem_chunk[0] = NULL; @@ -1364,13 +1374,14 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, NVDmaStart(pNv, NvSubMemFormat, 0x100, 1); NVDmaNext (pNv, 0); - NVDmaKickoff(pNv); - + //Put back NvDmaNotifier0 for EXA NVDmaStart(pNv, NvSubMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); NVDmaNext (pNv, NvDmaNotifier0); - + + NVDmaKickoff(pNv); + if ( destination_buffer == pNv->GARTScratch ) if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) return FALSE; -- cgit v1.2.1 From c7b16f6fff96ffcff8049feed2a0a9ef6de4209f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 6 Aug 2007 21:45:50 +1000 Subject: Adapt to drm 0.0.10 --- src/nv_dma.c | 2 +- src/nv_dri.c | 21 +-------------------- src/nv_driver.c | 8 ++++++++ src/nv_notifier.c | 18 +++++++++--------- src/nv_proto.h | 25 +++++++++++-------------- src/nv_type.h | 5 ++--- src/nv_video.c | 8 ++++---- 7 files changed, 36 insertions(+), 51 deletions(-) diff --git a/src/nv_dma.c b/src/nv_dma.c index 8ecda5e..ea022ee 100644 --- a/src/nv_dma.c +++ b/src/nv_dma.c @@ -263,7 +263,7 @@ Bool NVInitDma(ScrnInfoPtr pScrn) pNv->fifo.fb_ctxdma_handle = NvDmaFB; pNv->fifo.tt_ctxdma_handle = NvDmaTT; - ret = drmCommandWriteRead(pNv->drm_fd, DRM_NOUVEAU_FIFO_ALLOC, + ret = drmCommandWriteRead(pNv->drm_fd, DRM_NOUVEAU_CHANNEL_ALLOC, &pNv->fifo, sizeof(pNv->fifo)); if (ret) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, diff --git a/src/nv_dri.c b/src/nv_dri.c index c854950..0640287 100644 --- a/src/nv_dri.c +++ b/src/nv_dri.c @@ -244,7 +244,7 @@ Bool NVDRIGetVersion(ScrnInfoPtr pScrn) } /* temporary lock step versioning */ -#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 9 +#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 10 #error nouveau_drm.h doesn't match expected patchlevel, update libdrm. #endif if (pNv->pKernelDRMVersion->version_patchlevel != @@ -278,7 +278,6 @@ Bool NVDRIScreenInit(ScrnInfoPtr pScrn) ScreenPtr pScreen; pScreen = screenInfo.screens[pScrn->scrnIndex]; int drm_page_size; - int irq; if (!NVDRICheckModules(pScrn)) return FALSE; @@ -352,24 +351,6 @@ Bool NVDRIScreenInit(ScrnInfoPtr pScrn) return FALSE; } -#if 0 - pNv->IRQ = 0; -#else - /* Ask DRM to install IRQ handler */ - irq = drmGetInterruptFromBusID(pNv->drm_fd, - ((pciConfigPtr)pNv->PciInfo->thisCard)->busnum, - ((pciConfigPtr)pNv->PciInfo->thisCard)->devnum, - ((pciConfigPtr)pNv->PciInfo->thisCard)->funcnum); - - if (drmCtlInstHandler(pNv->drm_fd, irq)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to install IRQ handler\n"); - pNv->IRQ = 0; - } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "IRQ handler initialised. IRQ %d\n", irq); - pNv->IRQ = irq; - } -#endif - return TRUE; } diff --git a/src/nv_driver.c b/src/nv_driver.c index 2e8f8eb..b4c6533 100644 --- a/src/nv_driver.c +++ b/src/nv_driver.c @@ -2011,6 +2011,14 @@ NVScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (!NVDRIScreenInit(pScrn)) return FALSE; + ret = drmCommandNone(pNv->drm_fd, DRM_NOUVEAU_CARD_INIT); + if (ret) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Error initialising the nouveau kernel module: %d\n", + ret); + return FALSE; + } + /* Allocate and map memory areas we need */ if (!NVMapMem(pScrn)) return FALSE; diff --git a/src/nv_notifier.c b/src/nv_notifier.c index 70a7fcc..bb7a4f9 100644 --- a/src/nv_notifier.c +++ b/src/nv_notifier.c @@ -16,11 +16,11 @@ NVPtr pNv = NVPTR(pScrn); \ volatile uint32_t *__v = (void*)pNv->NotifierBlock + notifier->offset -struct drm_nouveau_notifier_alloc * +struct drm_nouveau_notifierobj_alloc * NVNotifierAlloc(ScrnInfoPtr pScrn, uint32_t handle) { NVPtr pNv = NVPTR(pScrn); - struct drm_nouveau_notifier_alloc *notifier; + struct drm_nouveau_notifierobj_alloc *notifier; int ret; notifier = xcalloc(1, sizeof(*notifier)); @@ -32,7 +32,7 @@ NVNotifierAlloc(ScrnInfoPtr pScrn, uint32_t handle) notifier->channel = pNv->fifo.channel; notifier->handle = handle; notifier->count = 1; - ret = drmCommandWriteRead(pNv->drm_fd, DRM_NOUVEAU_NOTIFIER_ALLOC, + ret = drmCommandWriteRead(pNv->drm_fd, DRM_NOUVEAU_NOTIFIEROBJ_ALLOC, notifier, sizeof(*notifier)); if (ret) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -47,7 +47,7 @@ NVNotifierAlloc(ScrnInfoPtr pScrn, uint32_t handle) void NVNotifierDestroy(ScrnInfoPtr pScrn, - struct drm_nouveau_notifier_alloc *notifier) + struct drm_nouveau_notifierobj_alloc *notifier) { if (notifier) { /*XXX: destroy notifier object */ @@ -57,7 +57,7 @@ NVNotifierDestroy(ScrnInfoPtr pScrn, void NVNotifierReset(ScrnInfoPtr pScrn, - struct drm_nouveau_notifier_alloc *notifier) + struct drm_nouveau_notifierobj_alloc *notifier) { NOTIFIER(n); @@ -70,7 +70,7 @@ NVNotifierReset(ScrnInfoPtr pScrn, uint32_t NVNotifierStatus(ScrnInfoPtr pScrn, - struct drm_nouveau_notifier_alloc *notifier) + struct drm_nouveau_notifierobj_alloc *notifier) { NOTIFIER(n); @@ -79,7 +79,7 @@ NVNotifierStatus(ScrnInfoPtr pScrn, uint32_t NVNotifierErrorCode(ScrnInfoPtr pScrn, - struct drm_nouveau_notifier_alloc *notifier) + struct drm_nouveau_notifierobj_alloc *notifier) { NOTIFIER(n); @@ -88,7 +88,7 @@ NVNotifierErrorCode(ScrnInfoPtr pScrn, uint32_t NVNotifierReturnVal(ScrnInfoPtr pScrn, - struct drm_nouveau_notifier_alloc *notifier) + struct drm_nouveau_notifierobj_alloc *notifier) { NOTIFIER(n); @@ -97,7 +97,7 @@ NVNotifierReturnVal(ScrnInfoPtr pScrn, Bool NVNotifierWaitStatus(ScrnInfoPtr pScrn, - struct drm_nouveau_notifier_alloc *notifier, + struct drm_nouveau_notifierobj_alloc *notifier, unsigned int status, unsigned int timeout) { NOTIFIER(n); diff --git a/src/nv_proto.h b/src/nv_proto.h index 5eac19f..9f5fbac 100644 --- a/src/nv_proto.h +++ b/src/nv_proto.h @@ -20,20 +20,17 @@ NVAllocRec *NVAllocateMemory(NVPtr pNv, int type, int size); void NVFreeMemory(NVPtr pNv, NVAllocRec *mem); /* in nv_notifier.c */ -struct drm_nouveau_notifier_alloc *NVNotifierAlloc(ScrnInfoPtr,uint32_t handle); -void NVNotifierDestroy(ScrnInfoPtr, - struct drm_nouveau_notifier_alloc *); -void NVNotifierReset(ScrnInfoPtr, - struct drm_nouveau_notifier_alloc *); -uint32_t NVNotifierStatus(ScrnInfoPtr, - struct drm_nouveau_notifier_alloc *); -uint32_t NVNotifierErrorCode(ScrnInfoPtr, - struct drm_nouveau_notifier_alloc *); -uint32_t NVNotifierReturnVal(ScrnInfoPtr, - struct drm_nouveau_notifier_alloc *); -Bool NVNotifierWaitStatus(ScrnInfoPtr, - struct drm_nouveau_notifier_alloc *, - uint32_t status, uint32_t timeout); +struct drm_nouveau_notifierobj_alloc * +NVNotifierAlloc(ScrnInfoPtr, uint32_t handle); +void NVNotifierDestroy(ScrnInfoPtr, struct drm_nouveau_notifierobj_alloc *); +void NVNotifierReset(ScrnInfoPtr, struct drm_nouveau_notifierobj_alloc *); +uint32_t NVNotifierStatus(ScrnInfoPtr, struct drm_nouveau_notifierobj_alloc *); +uint32_t NVNotifierErrorCode(ScrnInfoPtr, + struct drm_nouveau_notifierobj_alloc *); +uint32_t NVNotifierReturnVal(ScrnInfoPtr, + struct drm_nouveau_notifierobj_alloc *); +Bool NVNotifierWaitStatus(ScrnInfoPtr, struct drm_nouveau_notifierobj_alloc *, + uint32_t status, uint32_t timeout); /* in nv_dri.c */ unsigned int NVDRMGetParam(NVPtr pNv, unsigned int param); diff --git a/src/nv_type.h b/src/nv_type.h index be45799..6c3edb0 100644 --- a/src/nv_type.h +++ b/src/nv_type.h @@ -232,13 +232,12 @@ typedef struct _NVRec { int PanelTweak; Bool LVDS; - int IRQ; Bool LockedUp; volatile void * NotifierBlock; - struct drm_nouveau_notifier_alloc *Notifier0; + struct drm_nouveau_notifierobj_alloc *Notifier0; - struct drm_nouveau_fifo_alloc fifo; + struct drm_nouveau_channel_alloc fifo; CARD32 dmaPut; CARD32 dmaCurrent; CARD32 dmaFree; diff --git a/src/nv_video.c b/src/nv_video.c index 67a231f..86e2e69 100644 --- a/src/nv_video.c +++ b/src/nv_video.c @@ -63,7 +63,7 @@ typedef struct _NVPortPrivRec { int offset; NVAllocRec * TT_mem_chunk[2]; int currentHostBuffer; - struct drm_nouveau_notifier_alloc *DMANotifier[2]; + struct drm_nouveau_notifierobj_alloc *DMANotifier[2]; } NVPortPrivRec, *NVPortPrivPtr; @@ -78,7 +78,7 @@ XV_DMA_NOTIFIER_FREE=2, //notifier allocated, ready for use /* We have six notifiers available, they are not allocated at startup */ int XvDMANotifierStatus[6]= { XV_DMA_NOTIFIER_NOALLOC , XV_DMA_NOTIFIER_NOALLOC , XV_DMA_NOTIFIER_NOALLOC , XV_DMA_NOTIFIER_NOALLOC , XV_DMA_NOTIFIER_NOALLOC , XV_DMA_NOTIFIER_NOALLOC }; -struct drm_nouveau_notifier_alloc * XvDMANotifiers[6]; +struct drm_nouveau_notifierobj_alloc * XvDMANotifiers[6]; #define GET_OVERLAY_PRIVATE(pNv) \ (NVPortPrivPtr)((pNv)->overlayAdaptor->pPortPrivates[0].ptr) @@ -236,7 +236,7 @@ NVStopOverlay (ScrnInfoPtr pScrn) * * @return a notifier instance or NULL on error */ -static struct drm_nouveau_notifier_alloc * NVXvDMANotifierAlloc(ScrnInfoPtr pScrn) +static struct drm_nouveau_notifierobj_alloc * NVXvDMANotifierAlloc(ScrnInfoPtr pScrn) { int i; for ( i = 0; i < 6; i ++ ) @@ -271,7 +271,7 @@ return NULL; * * */ -static void NVXvDMANotifierFree(ScrnInfoPtr pScrn, struct drm_nouveau_notifier_alloc * target) +static void NVXvDMANotifierFree(ScrnInfoPtr pScrn, struct drm_nouveau_notifierobj_alloc * target) { int i; for ( i = 0; i < 6; i ++ ) -- cgit v1.2.1 From 4a6c2bd2bedcf9f67c3e498b1411ad58cd66199c Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Mon, 6 Aug 2007 17:29:41 +0200 Subject: Add subchannel handling code --- src/nv30_exa.c | 112 +++++++++++++++++++++++++------------------------- src/nv_accel_common.c | 73 ++++++++++++++------------------ src/nv_dma.c | 70 +++++++++++++++++++++---------- src/nv_dma.h | 17 -------- src/nv_exa.c | 42 +++++++++---------- src/nv_video.c | 26 ++++++------ src/nv_xaa.c | 46 ++++++++++----------- 7 files changed, 192 insertions(+), 194 deletions(-) diff --git a/src/nv30_exa.c b/src/nv30_exa.c index 66901d3..816aa0b 100644 --- a/src/nv30_exa.c +++ b/src/nv30_exa.c @@ -174,12 +174,12 @@ NV30_LoadVtxProg(ScrnInfoPtr pScrn, nv_shader_t *shader) if (!shader->hw_id) { shader->hw_id = next_hw_id; - NVDmaStart(pNv, NvSub3D, + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_FROM_ID, 1); NVDmaNext (pNv, (shader->hw_id)); for (i=0; isize; i+=4) { - NVDmaStart(pNv, NvSub3D, + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_VP_UPLOAD_INST0, 4); NVDmaNext (pNv, shader->data[i + 0]); @@ -190,10 +190,10 @@ NV30_LoadVtxProg(ScrnInfoPtr pScrn, nv_shader_t *shader) } } - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_PROGRAM_START_ID, 1); + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_VP_PROGRAM_START_ID, 1); NVDmaNext (pNv, (shader->hw_id)); - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_VP_IN_REG, 2); + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_VP_IN_REG, 2); NVDmaNext (pNv, shader->card_priv.NV30VP.vp_in_reg); NVDmaNext (pNv, shader->card_priv.NV30VP.vp_out_reg); } @@ -226,16 +226,16 @@ NV30_LoadFragProg(ScrnInfoPtr pScrn, nv_shader_t *shader) next_hw_id_offset = (next_hw_id_offset + 63) & ~63; } - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM, 1); + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_FP_ACTIVE_PROGRAM, 1); NVDmaNext (pNv, shader->hw_id | 1); if (pNv->Architecture == NV_30) { - NVDmaStart(pNv, NvSub3D, 0x1d60, 1); + NVDmaStart(pNv, Nv3D, 0x1d60, 1); NVDmaNext (pNv, 0); /* USES_KIL (1<<7) == 0 */ - NVDmaStart(pNv, NvSub3D, 0x1450, 1); + NVDmaStart(pNv, Nv3D, 0x1450, 1); NVDmaNext (pNv, shader->card_priv.NV30FP.num_regs << 16); } else { - NVDmaStart(pNv, NvSub3D, 0x1d60, 1); + NVDmaStart(pNv, Nv3D, 0x1d60, 1); NVDmaNext (pNv, (0<<7) /* !USES_KIL */ | (shader->card_priv.NV30FP.num_regs << 24)); } @@ -266,10 +266,10 @@ NV30_SetupBlend(ScrnInfoPtr pScrn, nv_pict_op_t *blend, Bool dest_has_alpha, } if (sblend == BF(ONE) && dblend == BF(ZERO)) { - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1); + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1); NVDmaNext (pNv, 0); } else { - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 5); + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 5); NVDmaNext (pNv, 1); NVDmaNext (pNv, (sblend << 16) | sblend); NVDmaNext (pNv, (dblend << 16) | dblend); @@ -300,7 +300,7 @@ NV30EXATexture(ScrnInfoPtr pScrn, PixmapPtr pPix, PicturePtr pPict, int unit) else card_filter = 1; - NVDmaStart(pNv, NvSub3D, + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_TX_ADDRESS_UNIT(unit), 8); NVDmaNext (pNv, NVAccelGetPixmapOffset(pPix)); NVDmaNext (pNv, (2 << 4) /* 2D */ | @@ -319,7 +319,7 @@ NV30EXATexture(ScrnInfoPtr pScrn, PixmapPtr pPix, PicturePtr pPict, int unit) 0x3fd6 /* engine lock */); NVDmaNext (pNv, (pPix->drawable.width << 16) | pPix->drawable.height); NVDmaNext (pNv, 0); /* border ARGB */ - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_TX_DEPTH_UNIT(unit), 1); + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_TX_DEPTH_UNIT(unit), 1); NVDmaNext (pNv, (1 << 20) /* depth */ | (uint32_t)exaGetPixmapPitch(pPix)); @@ -342,7 +342,7 @@ NV30_SetupSurface(ScrnInfoPtr pScrn, PixmapPtr pPix, PictFormatShort format) return FALSE; } - NVDmaStart(pNv, NvSub3D, 0x208, 3); + NVDmaStart(pNv, Nv3D, 0x208, 3); NVDmaNext (pNv, fmt->card_fmt); NVDmaNext (pNv, (uint32_t)exaGetPixmapPitch(pPix)); NVDmaNext (pNv, NVAccelGetPixmapOffset(pPix)); @@ -452,12 +452,12 @@ NV30EXAPrepareComposite(int op, PicturePtr psPict, /* Appears to be some kind of cache flush, needed here at least * sometimes.. funky text rendering otherwise :) */ - NVDmaStart(pNv, NvSub3D, 0x1fd8, 1); + NVDmaStart(pNv, Nv3D, 0x1fd8, 1); NVDmaNext (pNv, 2); - NVDmaStart(pNv, NvSub3D, 0x1fd8, 1); + NVDmaStart(pNv, Nv3D, 0x1fd8, 1); NVDmaNext (pNv, 1); - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_BEGIN_END, 1); + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_BEGIN_END, 1); NVDmaNext (pNv, 8); /* GL_QUADS */ return TRUE; @@ -486,16 +486,16 @@ NV30EXATransformCoord(PictTransformPtr t, int x, int y, float sx, float sy, } #define CV_OUTm(sx,sy,mx,my,dx,dy) do { \ - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_VTX_ATTR_2F_X(8), 4); \ + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_VTX_ATTR_2F_X(8), 4); \ NVDmaFloat(pNv, (sx)); NVDmaFloat(pNv, (sy)); \ NVDmaFloat(pNv, (mx)); NVDmaFloat(pNv, (my)); \ - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_VTX_ATTR_2I(0), 1); \ + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_VTX_ATTR_2I(0), 1); \ NVDmaNext (pNv, ((dy)<<16)|(dx)); \ } while(0) #define CV_OUT(sx,sy,dx,dy) do { \ - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_VTX_ATTR_2F_X(8), 2); \ + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_VTX_ATTR_2F_X(8), 2); \ NVDmaFloat(pNv, (sx)); NVDmaFloat(pNv, (sy)); \ - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_VTX_ATTR_2I(0), 1); \ + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_VTX_ATTR_2I(0), 1); \ NVDmaNext (pNv, ((dy)<<16)|(dx)); \ } while(0) @@ -547,7 +547,7 @@ NV30EXADoneComposite(PixmapPtr pdPix) ScrnInfoPtr pScrn = xf86Screens[pdPix->drawable.pScreen->myNum]; NVPtr pNv = NVPTR(pScrn); - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_BEGIN_END, 1); + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_BEGIN_END, 1); NVDmaNext (pNv, 0); } @@ -587,42 +587,42 @@ NVAccelInitNV40TCL(ScrnInfoPtr pScrn) have_object = TRUE; } - NVDmaSetObjectOnSubchannel(pNv, NvSub3D, Nv3D); + NVDmaSetObjectOnSubchannel(pNv, Nv3D, Nv3D); - NVDmaStart(pNv, NvSub3D, 0x180, 1); + NVDmaStart(pNv, Nv3D, 0x180, 1); NVDmaNext (pNv, NvDmaNotifier0); - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT1, 2); + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT1, 2); NVDmaNext (pNv, NvDmaFB); NVDmaNext (pNv, NvDmaFB); - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT8, 1); + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT8, 1); NVDmaNext (pNv, NvDmaFB); - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT4, 2); + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT4, 2); NVDmaNext (pNv, NvDmaFB); NVDmaNext (pNv, NvDmaFB); /* voodoo */ - NVDmaStart(pNv, NvSub3D, 0x1ea4, 3); + NVDmaStart(pNv, Nv3D, 0x1ea4, 3); NVDmaNext(pNv, 0x00000010); NVDmaNext(pNv, 0x01000100); NVDmaNext(pNv, 0xff800006); - NVDmaStart(pNv, NvSub3D, 0x1fc4, 1); + NVDmaStart(pNv, Nv3D, 0x1fc4, 1); NVDmaNext(pNv, 0x06144321); - NVDmaStart(pNv, NvSub3D, 0x1fc8, 2); + NVDmaStart(pNv, Nv3D, 0x1fc8, 2); NVDmaNext(pNv, 0xedcba987); NVDmaNext(pNv, 0x00000021); - NVDmaStart(pNv, NvSub3D, 0x1fd0, 1); + NVDmaStart(pNv, Nv3D, 0x1fd0, 1); NVDmaNext(pNv, 0x00171615); - NVDmaStart(pNv, NvSub3D, 0x1fd4, 1); + NVDmaStart(pNv, Nv3D, 0x1fd4, 1); NVDmaNext(pNv, 0x001b1a19); - NVDmaStart(pNv, NvSub3D, 0x1ef8, 1); + NVDmaStart(pNv, Nv3D, 0x1ef8, 1); NVDmaNext(pNv, 0x0020ffff); - NVDmaStart(pNv, NvSub3D, 0x1d64, 1); + NVDmaStart(pNv, Nv3D, 0x1d64, 1); NVDmaNext(pNv, 0x00d30000); - NVDmaStart(pNv, NvSub3D, 0x1e94, 1); + NVDmaStart(pNv, Nv3D, 0x1e94, 1); NVDmaNext(pNv, 0x00000001); /* identity viewport transform */ - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_OX, 8); + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_XFRM_OX, 8); NVDmaFloat(pNv, 0.0); NVDmaFloat(pNv, 0.0); NVDmaFloat(pNv, 0.0); @@ -634,63 +634,63 @@ NVAccelInitNV40TCL(ScrnInfoPtr pScrn) /* default 3D state */ /*XXX: replace with the same state that the DRI emits on startup */ - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_ENABLE, 1); + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_STENCIL_FRONT_ENABLE, 1); NVDmaNext (pNv, 0); - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_ENABLE, 1); + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_STENCIL_BACK_ENABLE, 1); NVDmaNext (pNv, 0); - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1); + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_ALPHA_FUNC_ENABLE, 1); NVDmaNext (pNv, 0); - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 2); + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_DEPTH_WRITE_ENABLE, 2); NVDmaNext (pNv, 0); /* wr disable */ NVDmaNext (pNv, 0); /* test disable */ - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_COLOR_MASK, 1); + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_COLOR_MASK, 1); NVDmaNext (pNv, 0x01010101); /* TR,TR,TR,TR */ - NVDmaStart(pNv, NvSub3D, NV40_TCL_PRIMITIVE_3D_COLOR_MASK_BUFFER123, 1); + NVDmaStart(pNv, Nv3D, NV40_TCL_PRIMITIVE_3D_COLOR_MASK_BUFFER123, 1); NVDmaNext (pNv, 0x0000fff0); - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1); + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_CULL_FACE_ENABLE, 1); NVDmaNext (pNv, 0); - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1); + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_BLEND_FUNC_ENABLE, 1); NVDmaNext (pNv, 0); - NVDmaStart(pNv, NvSub3D, + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_LOGIC_OP_ENABLE, 2); NVDmaNext (pNv, 0); NVDmaNext (pNv, 0x1503); - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_DITHER_ENABLE, 1); + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_DITHER_ENABLE, 1); NVDmaNext (pNv, 0); - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_SHADE_MODEL, 1); + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_SHADE_MODEL, 1); NVDmaNext (pNv, 0x1d01); /* GL_SMOOTH */ - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR,2); + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_POLYGON_OFFSET_FACTOR,2); NVDmaFloat(pNv, 0.0); NVDmaFloat(pNv, 0.0); - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 2); + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_POLYGON_MODE_FRONT, 2); NVDmaNext (pNv, 0x1b02); /* FRONT = GL_FILL */ NVDmaNext (pNv, 0x1b02); /* BACK = GL_FILL */ - NVDmaStart(pNv, NvSub3D, + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_POLYGON_STIPPLE_PATTERN(0), 0x20); for (i=0;i<0x20;i++) NVDmaNext(pNv, 0xFFFFFFFF); for (i=0;i<16;i++) { - NVDmaStart(pNv, NvSub3D, + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_TX_ENABLE_UNIT(i), 1); NVDmaNext(pNv, 0); } - NVDmaStart(pNv, NvSub3D, 0x1d78, 1); + NVDmaStart(pNv, Nv3D, 0x1d78, 1); NVDmaNext (pNv, 0x110); - NVDmaStart(pNv, NvSub3D, 0x0220, 1); + NVDmaStart(pNv, Nv3D, 0x0220, 1); NVDmaNext (pNv, 1); - NVDmaStart(pNv, NvSub3D, + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_DIM0, 2); NVDmaNext (pNv, (4096 << 16)); NVDmaNext (pNv, (4096 << 16)); - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS, 2); + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_SCISSOR_WIDTH_XPOS, 2); NVDmaNext (pNv, (4096 << 16)); NVDmaNext (pNv, (4096 << 16)); - NVDmaStart(pNv, NvSub3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_0, 2); + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_DIMS_0, 2); NVDmaNext (pNv, (4096 << 16)); NVDmaNext (pNv, (4096 << 16)); - NVDmaStart(pNv, NvSub3D, + NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_VIEWPORT_COLOR_BUFFER_OFS0, 2); NVDmaNext (pNv, (4095 << 16)); NVDmaNext (pNv, (4095 << 16)); diff --git a/src/nv_accel_common.c b/src/nv_accel_common.c index 51bb5a7..2c9070e 100644 --- a/src/nv_accel_common.c +++ b/src/nv_accel_common.c @@ -67,11 +67,9 @@ NVAccelInitContextSurfaces(ScrnInfoPtr pScrn) have_object = TRUE; } - NVDmaSetObjectOnSubchannel(pNv, NvSubContextSurfaces, - NvContextSurfaces); - NVDmaStart(pNv, NvSubContextSurfaces, NV04_SURFACE_DMA_NOTIFY, 1); + NVDmaStart(pNv, NvContextSurfaces, NV04_SURFACE_DMA_NOTIFY, 1); NVDmaNext (pNv, NvNullObject); - NVDmaStart(pNv, NvSubContextSurfaces, NV04_SURFACE_DMA_IMAGE_SOURCE, 2); + NVDmaStart(pNv, NvContextSurfaces, NV04_SURFACE_DMA_IMAGE_SOURCE, 2); NVDmaNext (pNv, NvDmaFB); NVDmaNext (pNv, NvDmaFB); @@ -130,7 +128,7 @@ NVAccelSetCtxSurf2D(PixmapPtr psPix, PixmapPtr pdPix, int format) ScrnInfoPtr pScrn = xf86Screens[psPix->drawable.pScreen->myNum]; NVPtr pNv = NVPTR(pScrn); - NVDmaStart(pNv, NvSubContextSurfaces, SURFACE_FORMAT, 4); + NVDmaStart(pNv, NvContextSurfaces, SURFACE_FORMAT, 4); NVDmaNext (pNv, format); NVDmaNext (pNv, ((uint32_t)exaGetPixmapPitch(pdPix) << 16) | (uint32_t)exaGetPixmapPitch(psPix)); @@ -156,12 +154,10 @@ NVAccelInitImagePattern(ScrnInfoPtr pScrn) have_object = TRUE; } - NVDmaSetObjectOnSubchannel(pNv, NvSubImagePattern, - NvImagePattern); - NVDmaStart(pNv, NvSubImagePattern, + NVDmaStart(pNv, NvImagePattern, 0x180, /*NV04_IMAGE_PATTERN_SET_DMA_NOTIFY*/ 1); NVDmaNext (pNv, NvNullObject); - NVDmaStart(pNv, NvSubImagePattern, NV04_IMAGE_PATTERN_MONO_FORMAT, 3); + NVDmaStart(pNv, NvImagePattern, NV04_IMAGE_PATTERN_MONO_FORMAT, 3); #if X_BYTE_ORDER == X_BIG_ENDIAN NVDmaNext (pNv, 2 /* NV04_IMAGE_PATTERN_BIGENDIAN/LE_M1 */); #else @@ -189,8 +185,7 @@ NVAccelInitRasterOp(ScrnInfoPtr pScrn) have_object = TRUE; } - NVDmaSetObjectOnSubchannel(pNv, NvSubRop, NvRop); - NVDmaStart(pNv, NvSubRop, NV03_PRIMITIVE_RASTER_OP_DMA_NOTIFY, 1); + NVDmaStart(pNv, NvRop, NV03_PRIMITIVE_RASTER_OP_DMA_NOTIFY, 1); NVDmaNext (pNv, NvNullObject); return TRUE; @@ -212,20 +207,19 @@ NVAccelInitRectangle(ScrnInfoPtr pScrn) have_object = TRUE; } - NVDmaSetObjectOnSubchannel(pNv, NvSubRectangle, NvRectangle); - NVDmaStart(pNv, NvSubRectangle, + NVDmaStart(pNv, NvRectangle, NV04_GDI_RECTANGLE_TEXT_SET_DMA_NOTIFY, 1); NVDmaNext (pNv, NvDmaNotifier0); - NVDmaStart(pNv, NvSubRectangle, + NVDmaStart(pNv, NvRectangle, 0x184 /*NV04_GDI_RECTANGLE_TEXT_SET_DMA_FONTS*/, 1); NVDmaNext (pNv, NvNullObject); - NVDmaStart(pNv, NvSubRectangle, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1); + NVDmaStart(pNv, NvRectangle, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1); NVDmaNext (pNv, NvContextSurfaces); - NVDmaStart(pNv, NvSubRectangle, NV04_GDI_RECTANGLE_TEXT_ROP5, 1); + NVDmaStart(pNv, NvRectangle, NV04_GDI_RECTANGLE_TEXT_ROP5, 1); NVDmaNext (pNv, NvRop); - NVDmaStart(pNv, NvSubRectangle, NV04_GDI_RECTANGLE_TEXT_PATTERN, 1); + NVDmaStart(pNv, NvRectangle, NV04_GDI_RECTANGLE_TEXT_PATTERN, 1); NVDmaNext (pNv, NvImagePattern); - NVDmaStart(pNv, NvSubRectangle, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1); + NVDmaStart(pNv, NvRectangle, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1); NVDmaNext (pNv, 1 /* ROP_AND */); return TRUE; @@ -247,18 +241,17 @@ NVAccelInitImageBlit(ScrnInfoPtr pScrn) have_object = TRUE; } - NVDmaSetObjectOnSubchannel(pNv, NvSubImageBlit, NvImageBlit); - NVDmaStart(pNv, NvSubImageBlit, NV_IMAGE_BLIT_DMA_NOTIFY, 1); + NVDmaStart(pNv, NvImageBlit, NV_IMAGE_BLIT_DMA_NOTIFY, 1); NVDmaNext (pNv, NvDmaNotifier0); - NVDmaStart(pNv, NvSubImageBlit, NV_IMAGE_BLIT_COLOR_KEY, 1); + NVDmaStart(pNv, NvImageBlit, NV_IMAGE_BLIT_COLOR_KEY, 1); NVDmaNext (pNv, NvNullObject); - NVDmaStart(pNv, NvSubImageBlit, NV_IMAGE_BLIT_SURFACE, 1); + NVDmaStart(pNv, NvImageBlit, NV_IMAGE_BLIT_SURFACE, 1); NVDmaNext (pNv, NvContextSurfaces); - NVDmaStart(pNv, NvSubImageBlit, NV_IMAGE_BLIT_CLIP_RECTANGLE, 3); + NVDmaStart(pNv, NvImageBlit, NV_IMAGE_BLIT_CLIP_RECTANGLE, 3); NVDmaNext (pNv, NvNullObject); NVDmaNext (pNv, NvImagePattern); NVDmaNext (pNv, NvRop); - NVDmaStart(pNv, NvSubImageBlit, NV_IMAGE_BLIT_OPERATION, 1); + NVDmaStart(pNv, NvImageBlit, NV_IMAGE_BLIT_OPERATION, 1); NVDmaNext (pNv, 1 /* NV_IMAGE_BLIT_OPERATION_ROP_AND */); return TRUE; @@ -293,25 +286,24 @@ NVAccelInitScaledImage(ScrnInfoPtr pScrn) have_object = TRUE; } - NVDmaSetObjectOnSubchannel(pNv, NvSubScaledImage, NvScaledImage); - NVDmaStart(pNv, NvSubScaledImage, + NVDmaStart(pNv, NvScaledImage, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_NOTIFY, 1); NVDmaNext (pNv, NvDmaNotifier0); - NVDmaStart(pNv, NvSubScaledImage, + NVDmaStart(pNv, NvScaledImage, NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1); NVDmaNext (pNv, NvDmaFB); /* source object */ - NVDmaStart(pNv, NvSubScaledImage, + NVDmaStart(pNv, NvScaledImage, NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1); NVDmaNext (pNv, NvContextSurfaces); - NVDmaStart(pNv, NvSubScaledImage, 0x188, 1); /* PATTERN */ + NVDmaStart(pNv, NvScaledImage, 0x188, 1); /* PATTERN */ NVDmaNext (pNv, NvNullObject); - NVDmaStart(pNv, NvSubScaledImage, 0x18c, 1); /* ROP */ + NVDmaStart(pNv, NvScaledImage, 0x18c, 1); /* ROP */ NVDmaNext (pNv, NvNullObject); - NVDmaStart(pNv, NvSubScaledImage, 0x190, 1); /* BETA1 */ + NVDmaStart(pNv, NvScaledImage, 0x190, 1); /* BETA1 */ NVDmaNext (pNv, NvNullObject); - NVDmaStart(pNv, NvSubScaledImage, 0x194, 1); /* BETA4 */ + NVDmaStart(pNv, NvScaledImage, 0x194, 1); /* BETA4 */ NVDmaNext (pNv, NvNullObject); - NVDmaStart(pNv, NvSubScaledImage, + NVDmaStart(pNv, NvScaledImage, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION, 1); NVDmaNext (pNv, 3 /* SRCCOPY */); @@ -332,8 +324,7 @@ NVAccelInitClipRectangle(ScrnInfoPtr pScrn) have_object = TRUE; } - NVDmaSetObjectOnSubchannel(pNv, NvSubClipRectangle, NvClipRectangle); - NVDmaStart(pNv, NvSubClipRectangle, 0x180, 1); /* DMA_NOTIFY */ + NVDmaStart(pNv, NvClipRectangle, 0x180, 1); /* DMA_NOTIFY */ NVDmaNext (pNv, NvNullObject); return TRUE; @@ -353,14 +344,13 @@ NVAccelInitSolidLine(ScrnInfoPtr pScrn) have_object = TRUE; } - NVDmaSetObjectOnSubchannel(pNv, NvSubSolidLine, NvSolidLine); - NVDmaStart(pNv, NvSubSolidLine, NV04_SOLID_LINE_CLIP_RECTANGLE, 3); + NVDmaStart(pNv, NvSolidLine, NV04_SOLID_LINE_CLIP_RECTANGLE, 3); NVDmaNext (pNv, NvClipRectangle); NVDmaNext (pNv, NvImagePattern); NVDmaNext (pNv, NvRop); - NVDmaStart(pNv, NvSubSolidLine, NV04_SOLID_LINE_SURFACE, 1); + NVDmaStart(pNv, NvSolidLine, NV04_SOLID_LINE_SURFACE, 1); NVDmaNext (pNv, NvContextSurfaces); - NVDmaStart(pNv, NvSubSolidLine, NV04_SOLID_LINE_OPERATION, 1); + NVDmaStart(pNv, NvSolidLine, NV04_SOLID_LINE_OPERATION, 1); NVDmaNext (pNv, 1); /* ROP_AND */ return TRUE; @@ -382,11 +372,10 @@ NVAccelInitMemFormat(ScrnInfoPtr pScrn) have_object = TRUE; } - NVDmaSetObjectOnSubchannel(pNv, NvSubMemFormat, NvMemFormat); - NVDmaStart(pNv, NvSubMemFormat, + NVDmaStart(pNv, NvMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); NVDmaNext (pNv, NvDmaNotifier0); - NVDmaStart(pNv, NvSubMemFormat, + NVDmaStart(pNv, NvMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_OBJECT_IN, 2); NVDmaNext (pNv, NvDmaFB); NVDmaNext (pNv, NvDmaFB); diff --git a/src/nv_dma.c b/src/nv_dma.c index ea022ee..230bdc5 100644 --- a/src/nv_dma.c +++ b/src/nv_dma.c @@ -16,6 +16,45 @@ void NVDmaKickoffCallback(NVPtr pNv) pNv->DMAKickoffCallback = NULL; } +static uint32_t subchannels[8]; + +void NVDmaStart(NVPtr pNv, uint32_t object, uint32_t tag, int size) +{ + int subchannel=-1; + int i; + /* XXX FIXME */ + ScrnInfoPtr pScrn = xf86Screens[0]; + + /* look for a subchannel already bound to that object */ + for(i=0;i<8;i++) + { + if (subchannels[i]==object) + { + subchannel=i; + break; + } + } + + /* add 2 for the potential subchannel binding */ + if((pNv)->dmaFree <= (size + 2)) + NVDmaWait(pScrn, size + 2); + + if (subchannel==-1) + { + /* bind the object */ + subchannel=rand()%8; + subchannels[subchannel]=object; + NVDEBUG("Bind object %x on subchannel %d\n", (object), (subchannel)); + NVDmaNext(pNv, (1<<18) | (subchannel<<13)); + NVDmaNext(pNv,object); + pNv->dmaFree -= (2); + } + NVDEBUG("NVDmaStart: subc=%d, cmd=%x, num=%d\n", (subchannel), (tag), (size)); + NVDmaNext(pNv, ((size) << 18) | ((subchannel) << 13) | (tag)); + pNv->dmaFree -= ((size) + 1); +} + + /* There is a HW race condition with videoram command buffers. * You can't jump to the location of your put offset. We write put * at the jump offset + SKIPS dwords with noop padding in between @@ -109,9 +148,9 @@ void NVSync(ScrnInfoPtr pScrn) /* Wait for channel to go completely idle */ NVNotifierReset(pScrn, pNv->Notifier0); - NVDmaStart(pNv, NvSubImageBlit, 0x104, 1); + NVDmaStart(pNv, NvImageBlit, 0x104, 1); NVDmaNext (pNv, 0); - NVDmaStart(pNv, NvSubImageBlit, 0x100, 1); + NVDmaStart(pNv, NvImageBlit, 0x100, 1); NVDmaNext (pNv, 0); NVDmaKickoff(pNv); if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, timeout)) @@ -141,23 +180,10 @@ void NVResetGraphics(ScrnInfoPtr pScrn) } pNv->dmaFree -= SKIPS; - NVAccelCommonInit(pScrn); + for(i=0;i<8;i++) + subchannels[i]=0; - /* EXA + XAA + Xv */ - NVDmaSetObjectOnSubchannel(pNv, NvSubContextSurfaces, NvContextSurfaces); - NVDmaSetObjectOnSubchannel(pNv, NvSubRectangle , NvRectangle ); - NVDmaSetObjectOnSubchannel(pNv, NvSubScaledImage , NvScaledImage ); - /* EXA + XAA */ - NVDmaSetObjectOnSubchannel(pNv, NvSubRop , NvRop ); - NVDmaSetObjectOnSubchannel(pNv, NvSubImagePattern, NvImagePattern ); - NVDmaSetObjectOnSubchannel(pNv, NvSubImageBlit , NvImageBlit ); - if (pNv->useEXA) { - if (pNv->GARTScratch) - NVDmaSetObjectOnSubchannel(pNv, NvSubMemFormat, NvMemFormat); - } else if (!pNv->useEXA) { - NVDmaSetObjectOnSubchannel(pNv, NvSubClipRectangle, NvClipRectangle); - NVDmaSetObjectOnSubchannel(pNv, NvSubSolidLine, NvSolidLine); - } + NVAccelCommonInit(pScrn); switch(pNv->CurrentLayout.depth) { case 24: @@ -181,20 +207,20 @@ void NVResetGraphics(ScrnInfoPtr pScrn) break; } - NVDmaStart(pNv, NvSubContextSurfaces, SURFACE_FORMAT, 4); + NVDmaStart(pNv, NvContextSurfaces, SURFACE_FORMAT, 4); NVDmaNext (pNv, surfaceFormat); NVDmaNext (pNv, pitch | (pitch << 16)); NVDmaNext (pNv, (uint32_t)pNv->FB->offset); NVDmaNext (pNv, (uint32_t)pNv->FB->offset); - NVDmaStart(pNv, NvSubImagePattern, PATTERN_FORMAT, 1); + NVDmaStart(pNv, NvImagePattern, PATTERN_FORMAT, 1); NVDmaNext (pNv, patternFormat); - NVDmaStart(pNv, NvSubRectangle, RECT_FORMAT, 1); + NVDmaStart(pNv, NvRectangle, RECT_FORMAT, 1); NVDmaNext (pNv, rectFormat); if (!pNv->useEXA) { - NVDmaStart(pNv, NvSubSolidLine, LINE_FORMAT, 1); + NVDmaStart(pNv, NvSolidLine, LINE_FORMAT, 1); NVDmaNext (pNv, lineFormat); } diff --git a/src/nv_dma.h b/src/nv_dma.h index fff3dc4..8911cc4 100644 --- a/src/nv_dma.h +++ b/src/nv_dma.h @@ -110,23 +110,6 @@ enum DMASubchannel { NVDmaNext((pNv), c.u); \ } while(0) -#define NVDmaStart(pNv, subchannel, tag, size) do { \ - if((pNv)->dmaFree <= (size)) \ - NVDmaWait(pScrn, size); \ - NVDEBUG("NVDmaStart: subc=%d, cmd=%x, num=%d\n", (subchannel), (tag), (size)); \ - NVDmaNext(pNv, ((size) << 18) | ((subchannel) << 13) | (tag)); \ - (pNv)->dmaFree -= ((size) + 1); \ -} while(0) - -#define NVDmaStart_NonInc(pNv, subchannel, tag, size) do { \ - NVDmaStart((pNv), (subchannel), (tag)|0x40000000, (size)); \ -} while(0) - -#define NVDmaSetObjectOnSubchannel(pNv, subchannel, object) do { \ - NVDmaStart(pNv, subchannel, 0, 1); \ - NVDmaNext(pNv,object); \ -} while(0) - #define SURFACE_FORMAT 0x00000300 #define SURFACE_FORMAT_Y8 0x00000001 #define SURFACE_FORMAT_X1R5G5B5 0x00000002 diff --git a/src/nv_exa.c b/src/nv_exa.c index 700a49a..d62c1e8 100644 --- a/src/nv_exa.c +++ b/src/nv_exa.c @@ -55,7 +55,7 @@ static void setM2MFDirection(ScrnInfoPtr pScrn, int dir) if (pNv->M2MFDirection != dir) { - NVDmaStart(pNv, NvSubMemFormat, MEMFORMAT_DMA_OBJECT_IN, 2); + NVDmaStart(pNv, NvMemFormat, MEMFORMAT_DMA_OBJECT_IN, 2); NVDmaNext (pNv, dir ? NvDmaTT : NvDmaFB); NVDmaNext (pNv, dir ? NvDmaFB : NvDmaTT); pNv->M2MFDirection = dir; @@ -97,11 +97,11 @@ static Bool NVExaPrepareSolid(PixmapPtr pPixmap, if (planemask != ~0 || alu != GXcopy) { if (pPixmap->drawable.bitsPerPixel == 32) return FALSE; - NVDmaStart(pNv, NvSubRectangle, 0x2fc, 1); + NVDmaStart(pNv, NvRectangle, 0x2fc, 1); NVDmaNext (pNv, 1 /* ROP_AND */); NVSetRopSolid(pScrn, alu, planemask); } else { - NVDmaStart(pNv, NvSubRectangle, 0x2fc, 1); + NVDmaStart(pNv, NvRectangle, 0x2fc, 1); NVDmaNext (pNv, 3 /* SRCCOPY */); } @@ -118,9 +118,9 @@ static Bool NVExaPrepareSolid(PixmapPtr pPixmap, if (!NVAccelSetCtxSurf2D(pPixmap, pPixmap, fmt)) return FALSE; - NVDmaStart(pNv, NvSubRectangle, RECT_FORMAT, 1); + NVDmaStart(pNv, NvRectangle, RECT_FORMAT, 1); NVDmaNext (pNv, rectFormat(&pPixmap->drawable)); - NVDmaStart(pNv, NvSubRectangle, RECT_SOLID_COLOR, 1); + NVDmaStart(pNv, NvRectangle, RECT_SOLID_COLOR, 1); NVDmaNext (pNv, fg); pNv->DMAKickoffCallback = NVDmaKickoffCallback; @@ -134,7 +134,7 @@ static void NVExaSolid (PixmapPtr pPixmap, int x1, int y1, int x2, int y2) int width = x2-x1; int height = y2-y1; - NVDmaStart(pNv, NvSubRectangle, RECT_SOLID_RECTS(0), 2); + NVDmaStart(pNv, NvRectangle, RECT_SOLID_RECTS(0), 2); NVDmaNext (pNv, (x1 << 16) | y1); NVDmaNext (pNv, (width << 16) | height); @@ -165,11 +165,11 @@ static Bool NVExaPrepareCopy(PixmapPtr pSrcPixmap, if (planemask != ~0 || alu != GXcopy) { if (pDstPixmap->drawable.bitsPerPixel == 32) return FALSE; - NVDmaStart(pNv, NvSubImageBlit, 0x2fc, 1); + NVDmaStart(pNv, NvImageBlit, 0x2fc, 1); NVDmaNext (pNv, 1 /* ROP_AND */); NVSetRopSolid(pScrn, alu, planemask); } else { - NVDmaStart(pNv, NvSubImageBlit, 0x2fc, 1); + NVDmaStart(pNv, NvImageBlit, 0x2fc, 1); NVDmaNext (pNv, 3 /* SRCCOPY */); } @@ -221,7 +221,7 @@ static void NVExaCopy(PixmapPtr pDstPixmap, inc=-1; } for (i = 0; i < width; i++) { - NVDmaStart(pNv, NvSubImageBlit, BLIT_POINT_SRC, 3); + NVDmaStart(pNv, NvImageBlit, BLIT_POINT_SRC, 3); NVDmaNext (pNv, (srcY << 16) | (srcX+xpos)); NVDmaNext (pNv, (dstY << 16) | (dstX+xpos)); NVDmaNext (pNv, (height << 16) | 1); @@ -240,7 +240,7 @@ static void NVExaCopy(PixmapPtr pDstPixmap, inc=-1; } for (i = 0; i < height; i++) { - NVDmaStart(pNv, NvSubImageBlit, BLIT_POINT_SRC, 3); + NVDmaStart(pNv, NvImageBlit, BLIT_POINT_SRC, 3); NVDmaNext (pNv, ((srcY+ypos) << 16) | srcX); NVDmaNext (pNv, ((dstY+ypos) << 16) | dstX); NVDmaNext (pNv, (1 << 16) | width); @@ -249,7 +249,7 @@ static void NVExaCopy(PixmapPtr pDstPixmap, } } else { NVDEBUG("ExaCopy: Using default path\n"); - NVDmaStart(pNv, NvSubImageBlit, BLIT_POINT_SRC, 3); + NVDmaStart(pNv, NvImageBlit, BLIT_POINT_SRC, 3); NVDmaNext (pNv, (srcY << 16) | srcX); NVDmaNext (pNv, (dstY << 16) | dstX); NVDmaNext (pNv, (height << 16) | width); @@ -302,7 +302,7 @@ NVAccelDownloadM2MF(ScrnInfoPtr pScrn, char *dst, uint64_t src_offset, if (lc > 2047) lc = 2047; - NVDmaStart(pNv, NvSubMemFormat, + NVDmaStart(pNv, NvMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); NVDmaNext (pNv, (uint32_t)src_offset); NVDmaNext (pNv, (uint32_t)pNv->GARTScratch->offset); @@ -314,10 +314,10 @@ NVAccelDownloadM2MF(ScrnInfoPtr pScrn, char *dst, uint64_t src_offset, NVDmaNext (pNv, 0); NVNotifierReset(pScrn, pNv->Notifier0); - NVDmaStart(pNv, NvSubMemFormat, + NVDmaStart(pNv, NvMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); NVDmaNext (pNv, 0); - NVDmaStart(pNv, NvSubMemFormat, 0x100, 1); + NVDmaStart(pNv, NvMemFormat, 0x100, 1); NVDmaNext (pNv, 0); NVDmaKickoff(pNv); if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) @@ -408,7 +408,7 @@ NVAccelUploadM2MF(ScrnInfoPtr pScrn, uint64_t dst_offset, const char *src, } /* DMA to VRAM */ - NVDmaStart(pNv, NvSubMemFormat, + NVDmaStart(pNv, NvMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); NVDmaNext (pNv, (uint32_t)pNv->GARTScratch->offset); NVDmaNext (pNv, (uint32_t)dst_offset); @@ -420,10 +420,10 @@ NVAccelUploadM2MF(ScrnInfoPtr pScrn, uint64_t dst_offset, const char *src, NVDmaNext (pNv, 0); NVNotifierReset(pScrn, pNv->Notifier0); - NVDmaStart(pNv, NvSubMemFormat, + NVDmaStart(pNv, NvMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); NVDmaNext (pNv, 0); - NVDmaStart(pNv, NvSubMemFormat, 0x100, 1); + NVDmaStart(pNv, NvMemFormat, 0x100, 1); NVDmaNext (pNv, 0); NVDmaKickoff(pNv); if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) @@ -524,7 +524,7 @@ static Bool NVPrepareComposite(int op, if (!NVAccelSetCtxSurf2D(pDst, pDst, dstFormat)) return FALSE; - NVDmaStart(pNv, NvSubScaledImage, STRETCH_BLIT_FORMAT, 2); + NVDmaStart(pNv, NvScaledImage, STRETCH_BLIT_FORMAT, 2); NVDmaNext (pNv, srcFormat); NVDmaNext (pNv, (op == PictOpSrc) ? STRETCH_BLIT_OPERATION_COPY : STRETCH_BLIT_OPERATION_BLEND); @@ -552,7 +552,7 @@ static void NVComposite(PixmapPtr pDst, ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; NVPtr pNv = NVPTR(pScrn); - NVDmaStart(pNv, NvSubScaledImage, STRETCH_BLIT_CLIP_POINT, 6); + NVDmaStart(pNv, NvScaledImage, STRETCH_BLIT_CLIP_POINT, 6); NVDmaNext (pNv, dstX | (dstY << 16)); NVDmaNext (pNv, width | (height << 16)); NVDmaNext (pNv, dstX | (dstY << 16)); @@ -560,7 +560,7 @@ static void NVComposite(PixmapPtr pDst, NVDmaNext (pNv, 1<<20); NVDmaNext (pNv, 1<<20); - NVDmaStart(pNv, NvSubScaledImage, STRETCH_BLIT_SRC_SIZE, 4); + NVDmaStart(pNv, NvScaledImage, STRETCH_BLIT_SRC_SIZE, 4); NVDmaNext (pNv, src_size); NVDmaNext (pNv, src_pitch); NVDmaNext (pNv, src_offset); @@ -582,7 +582,7 @@ static void NVDoneComposite (PixmapPtr pDst) else format = SURFACE_FORMAT_X8R8G8B8; - NVDmaStart(pNv, NvSubContextSurfaces, SURFACE_FORMAT, 1); + NVDmaStart(pNv, NvContextSurfaces, SURFACE_FORMAT, 1); NVDmaNext (pNv, format); exaMarkSync(pDst->drawable.pScreen); diff --git a/src/nv_video.c b/src/nv_video.c index 86e2e69..e6a07b9 100644 --- a/src/nv_video.c +++ b/src/nv_video.c @@ -636,7 +636,7 @@ NVPutBlitImage(ScrnInfoPtr pScrn, int src_offset, int id, #endif } else { if (pNv->CurrentLayout.depth == 15) { - NVDmaStart(pNv, NvSubContextSurfaces, + NVDmaStart(pNv, NvContextSurfaces, SURFACE_FORMAT, 1); NVDmaNext (pNv, SURFACE_FORMAT_X1R5G5B5); } @@ -674,19 +674,19 @@ NVPutBlitImage(ScrnInfoPtr pScrn, int src_offset, int id, } if(pNv->BlendingPossible) { - NVDmaStart(pNv, NvSubScaledImage, STRETCH_BLIT_FORMAT, 2); + NVDmaStart(pNv, NvScaledImage, STRETCH_BLIT_FORMAT, 2); NVDmaNext (pNv, src_format); NVDmaNext (pNv, STRETCH_BLIT_OPERATION_COPY); } else { - NVDmaStart(pNv, NvSubScaledImage, STRETCH_BLIT_FORMAT, 1); + NVDmaStart(pNv, NvScaledImage, STRETCH_BLIT_FORMAT, 1); NVDmaNext (pNv, src_format); } while(nbox--) { - NVDmaStart(pNv, NvSubRectangle, RECT_SOLID_COLOR, 1); + NVDmaStart(pNv, NvRectangle, RECT_SOLID_COLOR, 1); NVDmaNext (pNv, 0); - NVDmaStart(pNv, NvSubScaledImage, STRETCH_BLIT_CLIP_POINT, 6); + NVDmaStart(pNv, NvScaledImage, STRETCH_BLIT_CLIP_POINT, 6); NVDmaNext (pNv, (pbox->y1 << 16) | pbox->x1); NVDmaNext (pNv, ((pbox->y2 - pbox->y1) << 16) | (pbox->x2 - pbox->x1)); @@ -695,7 +695,7 @@ NVPutBlitImage(ScrnInfoPtr pScrn, int src_offset, int id, NVDmaNext (pNv, dsdx); NVDmaNext (pNv, dtdy); - NVDmaStart(pNv, NvSubScaledImage, STRETCH_BLIT_SRC_SIZE, 4); + NVDmaStart(pNv, NvScaledImage, STRETCH_BLIT_SRC_SIZE, 4); NVDmaNext (pNv, (height << 16) | width); NVDmaNext (pNv, src_pitch); NVDmaNext (pNv, src_offset); @@ -705,7 +705,7 @@ NVPutBlitImage(ScrnInfoPtr pScrn, int src_offset, int id, if (!pNv->useEXA) { if(pNv->CurrentLayout.depth == 15) { - NVDmaStart(pNv, NvSubContextSurfaces, + NVDmaStart(pNv, NvContextSurfaces, SURFACE_FORMAT, 1); NVDmaNext (pNv, SURFACE_FORMAT_R5G6B5); } @@ -1338,14 +1338,14 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, } - NVDmaStart(pNv, NvSubMemFormat, MEMFORMAT_DMA_OBJECT_IN, 2); + NVDmaStart(pNv, NvMemFormat, MEMFORMAT_DMA_OBJECT_IN, 2); NVDmaNext (pNv, NvDmaTT); NVDmaNext (pNv, NvDmaFB); pNv->M2MFDirection = 1; /* DMA to VRAM */ - NVDmaStart(pNv, NvSubMemFormat, + NVDmaStart(pNv, NvMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); NVDmaNext (pNv, (uint32_t)destination_buffer->offset); NVDmaNext (pNv, (uint32_t)offset + DMAoffset); @@ -1362,21 +1362,21 @@ NVPutImage(ScrnInfoPtr pScrn, short src_x, short src_y, } else { NVNotifierReset(pScrn, pPriv->DMANotifier[pPriv->currentHostBuffer]); - NVDmaStart(pNv, NvSubMemFormat, + NVDmaStart(pNv, NvMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); NVDmaNext (pNv, pPriv->DMANotifier[pPriv->currentHostBuffer]->handle); } - NVDmaStart(pNv, NvSubMemFormat, + NVDmaStart(pNv, NvMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); NVDmaNext (pNv, 0); - NVDmaStart(pNv, NvSubMemFormat, 0x100, 1); + NVDmaStart(pNv, NvMemFormat, 0x100, 1); NVDmaNext (pNv, 0); //Put back NvDmaNotifier0 for EXA - NVDmaStart(pNv, NvSubMemFormat, + NVDmaStart(pNv, NvMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); NVDmaNext (pNv, NvDmaNotifier0); diff --git a/src/nv_xaa.c b/src/nv_xaa.c index 9c32910..f5d5b09 100644 --- a/src/nv_xaa.c +++ b/src/nv_xaa.c @@ -137,7 +137,7 @@ NVSetPattern( { NVPtr pNv = NVPTR(pScrn); - NVDmaStart(pNv, NvSubImagePattern, PATTERN_COLOR_0, 4); + NVDmaStart(pNv, NvImagePattern, PATTERN_COLOR_0, 4); NVDmaNext (pNv, clr0); NVDmaNext (pNv, clr1); NVDmaNext (pNv, pat0); @@ -152,7 +152,7 @@ NVSetRopSolid(ScrnInfoPtr pScrn, CARD32 rop, CARD32 planemask) if(planemask != ~0) { NVSetPattern(pScrn, 0, planemask, ~0, ~0); if(pNv->currentRop != (rop + 32)) { - NVDmaStart(pNv, NvSubRop, ROP_SET, 1); + NVDmaStart(pNv, NvRop, ROP_SET, 1); NVDmaNext (pNv, NVCopyROP_PM[rop]); pNv->currentRop = rop + 32; } @@ -160,7 +160,7 @@ NVSetRopSolid(ScrnInfoPtr pScrn, CARD32 rop, CARD32 planemask) if (pNv->currentRop != rop) { if(pNv->currentRop >= 16) NVSetPattern(pScrn, ~0, ~0, ~0, ~0); - NVDmaStart(pNv, NvSubRop, ROP_SET, 1); + NVDmaStart(pNv, NvRop, ROP_SET, 1); NVDmaNext (pNv, NVCopyROP[rop]); pNv->currentRop = rop; } @@ -194,7 +194,7 @@ NVSubsequentScreenToScreenCopy( { NVPtr pNv = NVPTR(pScrn); - NVDmaStart(pNv, NvSubImageBlit, BLIT_POINT_SRC, 3); + NVDmaStart(pNv, NvImageBlit, BLIT_POINT_SRC, 3); NVDmaNext (pNv, (y1 << 16) | x1); NVDmaNext (pNv, (y2 << 16) | x2); NVDmaNext (pNv, (h << 16) | w); @@ -216,7 +216,7 @@ NVSetupForSolidFill( planemask |= ~0 << pNv->CurrentLayout.depth; NVSetRopSolid(pScrn, rop, planemask); - NVDmaStart(pNv, NvSubRectangle, RECT_SOLID_COLOR, 1); + NVDmaStart(pNv, NvRectangle, RECT_SOLID_COLOR, 1); NVDmaNext (pNv, color); pNv->DMAKickoffCallback = NVDmaKickoffCallback; @@ -227,7 +227,7 @@ NVSubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h) { NVPtr pNv = NVPTR(pScrn); - NVDmaStart(pNv, NvSubRectangle, RECT_SOLID_RECTS(0), 2); + NVDmaStart(pNv, NvRectangle, RECT_SOLID_RECTS(0), 2); NVDmaNext (pNv, (x << 16) | y); NVDmaNext (pNv, (w << 16) | h); @@ -253,13 +253,13 @@ NVSetupForMono8x8PatternFill ( else bg |= planemask; if (pNv->currentRop != (rop + 16)) { - NVDmaStart(pNv, NvSubRop, ROP_SET, 1); + NVDmaStart(pNv, NvRop, ROP_SET, 1); NVDmaNext (pNv, NVPatternROP[rop]); pNv->currentRop = rop + 16; } NVSetPattern(pScrn, bg, fg, patternx, patterny); - NVDmaStart(pNv, NvSubRectangle, RECT_SOLID_COLOR, 1); + NVDmaStart(pNv, NvRectangle, RECT_SOLID_COLOR, 1); NVDmaNext (pNv, fg); pNv->DMAKickoffCallback = NVDmaKickoffCallback; @@ -275,7 +275,7 @@ NVSubsequentMono8x8PatternFillRect( { NVPtr pNv = NVPTR(pScrn); - NVDmaStart(pNv, NvSubRectangle, RECT_SOLID_RECTS(0), 2); + NVDmaStart(pNv, NvRectangle, RECT_SOLID_RECTS(0), 2); NVDmaNext (pNv, (x << 16) | y); NVDmaNext (pNv, (w << 16) | h); @@ -331,7 +331,7 @@ NVSubsequentScanlineCPUToScreenColorExpandFill ( _remaining = h; if(_transparent) { - NVDmaStart(pNv, NvSubRectangle, RECT_EXPAND_ONE_COLOR_CLIP, 5); + NVDmaStart(pNv, NvRectangle, RECT_EXPAND_ONE_COLOR_CLIP, 5); NVDmaNext (pNv, (y << 16) | ((x + skipleft) & 0xFFFF)); NVDmaNext (pNv, ((y + h) << 16) | ((x + w) & 0xFFFF)); NVDmaNext (pNv, _fg_pixel); @@ -339,7 +339,7 @@ NVSubsequentScanlineCPUToScreenColorExpandFill ( NVDmaNext (pNv, (y << 16) | (x & 0xFFFF)); _color_expand_offset = RECT_EXPAND_ONE_COLOR_DATA(0); } else { - NVDmaStart(pNv, NvSubRectangle, RECT_EXPAND_TWO_COLOR_CLIP, 7); + NVDmaStart(pNv, NvRectangle, RECT_EXPAND_TWO_COLOR_CLIP, 7); NVDmaNext (pNv, (y << 16) | ((x + skipleft) & 0xFFFF)); NVDmaNext (pNv, ((y + h) << 16) | ((x + w) & 0xFFFF)); NVDmaNext (pNv, _bg_pixel); @@ -350,7 +350,7 @@ NVSubsequentScanlineCPUToScreenColorExpandFill ( _color_expand_offset = RECT_EXPAND_TWO_COLOR_DATA(0); } - NVDmaStart(pNv, NvSubRectangle, _color_expand_offset, _color_expand_dwords); + NVDmaStart(pNv, NvRectangle, _color_expand_offset, _color_expand_dwords); _storage_buffer[0] = (unsigned char*)&pNv->dmaBase[pNv->dmaCurrent]; } @@ -362,11 +362,11 @@ NVSubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno) pNv->dmaCurrent += _color_expand_dwords; if(--_remaining) { - NVDmaStart(pNv, NvSubRectangle, _color_expand_offset, _color_expand_dwords); + NVDmaStart(pNv, NvRectangle, _color_expand_offset, _color_expand_dwords); _storage_buffer[0] = (unsigned char*)&pNv->dmaBase[pNv->dmaCurrent]; } else { /* hardware bug workaround */ - NVDmaStart(pNv, NvSubImageBlit, BLIT_POINT_SRC, 1); + NVDmaStart(pNv, NvImageBlit, BLIT_POINT_SRC, 1); NVDmaNext (pNv, 0); NVDmaKickoff(pNv); } @@ -414,7 +414,7 @@ NVSubsequentScanlineImageWriteRect( NVSync(pScrn); - NVDmaStart(pNv, NvSubContextSurfaces, SURFACE_PITCH, 2); + NVDmaStart(pNv, NvContextSurfaces, SURFACE_PITCH, 2); NVDmaNext (pNv, (_image_dstpitch << 16) | image_srcpitch); NVDmaNext (pNv, pNv->ScratchBuffer->offset); } @@ -423,7 +423,7 @@ static void NVSubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno) { NVPtr pNv = NVPTR(pScrn); - NVDmaStart(pNv, NvSubImageBlit, BLIT_POINT_SRC, 3); + NVDmaStart(pNv, NvImageBlit, BLIT_POINT_SRC, 3); NVDmaNext (pNv, _image_srcpoint); NVDmaNext (pNv, _image_dstpoint); NVDmaNext (pNv, _image_size); @@ -433,7 +433,7 @@ static void NVSubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno) _image_dstpoint += (1 << 16); NVSync(pScrn); } else { - NVDmaStart(pNv, NvSubContextSurfaces, SURFACE_PITCH, 2); + NVDmaStart(pNv, NvContextSurfaces, SURFACE_PITCH, 2); NVDmaNext (pNv, _image_dstpitch | (_image_dstpitch << 16)); NVDmaNext (pNv, pNv->FB->offset); } @@ -458,9 +458,9 @@ NVSubsequentSolidHorVertLine(ScrnInfoPtr pScrn, int x, int y, int len, int dir) { NVPtr pNv = NVPTR(pScrn); - NVDmaStart(pNv, NvSubSolidLine, LINE_COLOR, 1); + NVDmaStart(pNv, NvSolidLine, LINE_COLOR, 1); NVDmaNext (pNv, _fg_pixel); - NVDmaStart(pNv, NvSubSolidLine, LINE_LINES(0), 2); + NVDmaStart(pNv, NvSolidLine, LINE_LINES(0), 2); NVDmaNext (pNv, (y << 16) | ( x & 0xffff)); if(dir == DEGREES_0) { NVDmaNext (pNv, (y << 16) | ((x + len) & 0xffff)); @@ -480,9 +480,9 @@ NVSubsequentSolidTwoPointLine( NVPtr pNv = NVPTR(pScrn); Bool drawLast = !(flags & OMIT_LAST); - NVDmaStart(pNv, NvSubSolidLine, LINE_COLOR, 1); + NVDmaStart(pNv, NvSolidLine, LINE_COLOR, 1); NVDmaNext (pNv, _fg_pixel); - NVDmaStart(pNv, NvSubSolidLine, LINE_LINES(0), drawLast ? 4 : 2); + NVDmaStart(pNv, NvSolidLine, LINE_LINES(0), drawLast ? 4 : 2); NVDmaNext (pNv, (y1 << 16) | (x1 & 0xffff)); NVDmaNext (pNv, (y2 << 16) | (x2 & 0xffff)); if(drawLast) { @@ -498,7 +498,7 @@ NVSetClippingRectangle(ScrnInfoPtr pScrn, int x1, int y1, int x2, int y2) int h = y2 - y1 + 1; int w = x2 - x1 + 1; - NVDmaStart(pNv, NvSubClipRectangle, CLIP_POINT, 2); + NVDmaStart(pNv, NvClipRectangle, CLIP_POINT, 2); NVDmaNext (pNv, (y1 << 16) | x1); NVDmaNext (pNv, (h << 16) | w); } @@ -508,7 +508,7 @@ NVDisableClipping(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - NVDmaStart(pNv, NvSubClipRectangle, CLIP_POINT, 2); + NVDmaStart(pNv, NvClipRectangle, CLIP_POINT, 2); NVDmaNext (pNv, 0); NVDmaNext (pNv, 0x7FFF7FFF); } -- cgit v1.2.1 From 71076f7947ec71b7a0f363c23f5a51ef09cdd9c0 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 7 Aug 2007 02:09:30 +1000 Subject: NVDmaSetObjectFromSubchannel doesn't exist anymore! --- src/nv30_exa.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/nv30_exa.c b/src/nv30_exa.c index 816aa0b..a3969b1 100644 --- a/src/nv30_exa.c +++ b/src/nv30_exa.c @@ -587,8 +587,6 @@ NVAccelInitNV40TCL(ScrnInfoPtr pScrn) have_object = TRUE; } - NVDmaSetObjectOnSubchannel(pNv, Nv3D, Nv3D); - NVDmaStart(pNv, Nv3D, 0x180, 1); NVDmaNext (pNv, NvDmaNotifier0); NVDmaStart(pNv, Nv3D, NV30_TCL_PRIMITIVE_3D_SET_OBJECT1, 2); -- cgit v1.2.1 From 2eab8453d73b4e7fd6c2d772d595ca5e8fa8c975 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Mon, 6 Aug 2007 18:13:13 +0200 Subject: Fix UTS/DFS when gart is smaller than transfer size. --- src/nv_exa.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/nv_exa.c b/src/nv_exa.c index d62c1e8..a2ca92f 100644 --- a/src/nv_exa.c +++ b/src/nv_exa.c @@ -335,6 +335,7 @@ NVAccelDownloadM2MF(ScrnInfoPtr pScrn, char *dst, uint64_t src_offset, } line_count -= lc; + src_offset += lc * src_pitch; } return TRUE; @@ -429,6 +430,7 @@ NVAccelUploadM2MF(ScrnInfoPtr pScrn, uint64_t dst_offset, const char *src, if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) return FALSE; + dst_offset += lc * dst_pitch; line_count -= lc; } @@ -449,12 +451,14 @@ static Bool NVUploadToScreen(PixmapPtr pDst, cpp = pDst->drawable.bitsPerPixel >> 3; if (pNv->GARTScratch) { + ErrorF("in UTSGart (%dx%d)\n",w,h); dst_offset += (y * dst_pitch) + (x * cpp); if (NVAccelUploadM2MF(pScrn, dst_offset, src, dst_pitch, src_pitch, w * cpp, h)) return TRUE; } + ErrorF("in UTSMemcpy (%dx%d)\n",w,h); dst = pDst->devPrivate.ptr + (y * dst_pitch) + (x * cpp); exaWaitSync(pDst->drawable.pScreen); if (NVAccelMemcpyRect(dst, src, h, dst_pitch, src_pitch, w*cpp)) -- cgit v1.2.1 From bf5684ba05e50fe48cce1e634caf03725fa907e6 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Mon, 6 Aug 2007 18:27:19 +0200 Subject: oops remove the debugging ErrorFs. --- src/nv_exa.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/nv_exa.c b/src/nv_exa.c index a2ca92f..8e1170c 100644 --- a/src/nv_exa.c +++ b/src/nv_exa.c @@ -451,14 +451,12 @@ static Bool NVUploadToScreen(PixmapPtr pDst, cpp = pDst->drawable.bitsPerPixel >> 3; if (pNv->GARTScratch) { - ErrorF("in UTSGart (%dx%d)\n",w,h); dst_offset += (y * dst_pitch) + (x * cpp); if (NVAccelUploadM2MF(pScrn, dst_offset, src, dst_pitch, src_pitch, w * cpp, h)) return TRUE; } - ErrorF("in UTSMemcpy (%dx%d)\n",w,h); dst = pDst->devPrivate.ptr + (y * dst_pitch) + (x * cpp); exaWaitSync(pDst->drawable.pScreen); if (NVAccelMemcpyRect(dst, src, h, dst_pitch, src_pitch, w*cpp)) -- cgit v1.2.1 From 17b65f1c2be3e609d387066d72dd8f5f7e2a6d92 Mon Sep 17 00:00:00 2001 From: Matthieu Castet Date: Mon, 6 Aug 2007 19:55:52 +0200 Subject: make XAA work on nv17 --- src/nv_accel_common.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/nv_accel_common.c b/src/nv_accel_common.c index 2c9070e..06226f6 100644 --- a/src/nv_accel_common.c +++ b/src/nv_accel_common.c @@ -221,6 +221,14 @@ NVAccelInitRectangle(ScrnInfoPtr pScrn) NVDmaNext (pNv, NvImagePattern); NVDmaStart(pNv, NvRectangle, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1); NVDmaNext (pNv, 1 /* ROP_AND */); + NVDmaStart(pNv, NvSubRectangle, + 0x304 /*NV04_GDI_RECTANGLE_TEXT_MONO_FORMAT*/, 1); + /* XXX why putting 1 like renouveau dump, swap the text */ +#if 1 || X_BYTE_ORDER == X_BIG_ENDIAN + NVDmaNext (pNv, 2 /* NV04_GDI_RECTANGLE_BIGENDIAN/LE_M1 */); +#else + NVDmaNext (pNv, 1 /* NV04_GDI_RECTANGLE_LOWENDIAN/CGA6_M1 */); +#endif return TRUE; } -- cgit v1.2.1 From 3f0a52c44697787d84d4f2cf61872e13d630f62a Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Mon, 6 Aug 2007 23:30:04 +0200 Subject: Fix explicit usage of subchannels, and remove subchannel defines altogether. --- src/nv_accel_common.c | 2 +- src/nv_dma.h | 17 ----------------- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/src/nv_accel_common.c b/src/nv_accel_common.c index 06226f6..805d698 100644 --- a/src/nv_accel_common.c +++ b/src/nv_accel_common.c @@ -221,7 +221,7 @@ NVAccelInitRectangle(ScrnInfoPtr pScrn) NVDmaNext (pNv, NvImagePattern); NVDmaStart(pNv, NvRectangle, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1); NVDmaNext (pNv, 1 /* ROP_AND */); - NVDmaStart(pNv, NvSubRectangle, + NVDmaStart(pNv, NvRectangle, 0x304 /*NV04_GDI_RECTANGLE_TEXT_MONO_FORMAT*/, 1); /* XXX why putting 1 like renouveau dump, swap the text */ #if 1 || X_BYTE_ORDER == X_BIG_ENDIAN diff --git a/src/nv_dma.h b/src/nv_dma.h index 8911cc4..3c51f1a 100644 --- a/src/nv_dma.h +++ b/src/nv_dma.h @@ -79,23 +79,6 @@ enum DMAObjects { NvDmaXvNotifier5 = 0xE8000005, }; -enum DMASubchannel { -/* EXA + XAA + Xv */ - NvSubContextSurfaces = 0, - NvSubRectangle = 1, - NvSubScaledImage = 2, -/* EXA + XAA */ - NvSubRop = 3, - NvSubImagePattern = 4, - NvSubImageBlit = 5, -/* EXA */ - NvSubMemFormat = 6, - NvSub3D = 7, -/* XAA */ - NvSubClipRectangle = 6, - NvSubSolidLine = 7, -}; - #define NVDmaNext(pNv, data) do { \ NVDEBUG("\tNVDmaNext: @0x%08x 0x%08x\n", ((pNv)->dmaCurrent),(data)); \ (pNv)->dmaBase[(pNv)->dmaCurrent++] = (data); \ -- cgit v1.2.1 From 15a680a6d715f87910b07133e1b98e2d4be9a108 Mon Sep 17 00:00:00 2001 From: Stephane Marchesin Date: Tue, 7 Aug 2007 23:42:09 +0200 Subject: Fix some overlooked hardcoded subchannels... --- src/nv_xaa.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/nv_xaa.c b/src/nv_xaa.c index f5d5b09..3c0f033 100644 --- a/src/nv_xaa.c +++ b/src/nv_xaa.c @@ -110,13 +110,13 @@ NVWaitVSync(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); - NVDmaStart(pNv, 5, 0x0000012C, 1); + NVDmaStart(pNv, NvImageBlit, 0x0000012C, 1); NVDmaNext (pNv, 0); - NVDmaStart(pNv, 5, 0x00000134, 1); + NVDmaStart(pNv, NvImageBlit, 0x00000134, 1); NVDmaNext (pNv, pNv->CRTCnumber); - NVDmaStart(pNv, 5, 0x00000100, 1); + NVDmaStart(pNv, NvImageBlit, 0x00000100, 1); NVDmaNext (pNv, 0); - NVDmaStart(pNv, 5, 0x00000130, 1); + NVDmaStart(pNv, NvImageBlit, 0x00000130, 1); NVDmaNext (pNv, 0); } -- cgit v1.2.1 From 089ff874e0a798c1b2693b5ab01cfa04c939f758 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 8 Aug 2007 10:32:08 +1000 Subject: Timeouts got lost somewhere along the way.. --- src/nv_exa.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nv_exa.c b/src/nv_exa.c index 8e1170c..d501c44 100644 --- a/src/nv_exa.c +++ b/src/nv_exa.c @@ -320,7 +320,7 @@ NVAccelDownloadM2MF(ScrnInfoPtr pScrn, char *dst, uint64_t src_offset, NVDmaStart(pNv, NvMemFormat, 0x100, 1); NVDmaNext (pNv, 0); NVDmaKickoff(pNv); - if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) + if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 2000)) return FALSE; if (dst_pitch == line_len) { @@ -427,7 +427,7 @@ NVAccelUploadM2MF(ScrnInfoPtr pScrn, uint64_t dst_offset, const char *src, NVDmaStart(pNv, NvMemFormat, 0x100, 1); NVDmaNext (pNv, 0); NVDmaKickoff(pNv); - if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) + if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 2000)) return FALSE; dst_offset += lc * dst_pitch; -- cgit v1.2.1 From 9cb4c95a4fbf38fcb8249e765ff71b2e24912244 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 8 Aug 2007 11:48:48 +1000 Subject: Add forgotten prototype --- src/nv_dma.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/nv_dma.h b/src/nv_dma.h index 3c51f1a..f96d5ef 100644 --- a/src/nv_dma.h +++ b/src/nv_dma.h @@ -79,6 +79,8 @@ enum DMAObjects { NvDmaXvNotifier5 = 0xE8000005, }; +extern void NVDmaStart(NVPtr pNv, uint32_t object, uint32_t tag, int size); + #define NVDmaNext(pNv, data) do { \ NVDEBUG("\tNVDmaNext: @0x%08x 0x%08x\n", ((pNv)->dmaCurrent),(data)); \ (pNv)->dmaBase[(pNv)->dmaCurrent++] = (data); \ -- cgit v1.2.1