diff options
Diffstat (limited to 'xc/programs/Xserver')
5 files changed, 665 insertions, 345 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c index 24838a0a3..1f2fe0ac7 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c @@ -1656,170 +1656,170 @@ Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) /* Memory manager setup */ #ifdef XF86DRI if (info->directRenderingEnabled) { - FBAreaPtr fbarea; - int width_bytes = (pScrn->displayWidth * - info->CurrentLayout.pixel_bytes); - int cpp = info->CurrentLayout.pixel_bytes; - int bufferSize = pScrn->virtualY * width_bytes; - int l, total; - int scanlines; - - switch (info->CCEMode) { - case R128_DEFAULT_CCE_PIO_MODE: - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in PIO mode\n"); - break; - case R128_DEFAULT_CCE_BM_MODE: - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in BM mode\n"); - break; - default: - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in UNKNOWN mode\n"); - break; - } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %d MB AGP aperture\n", info->agpSize); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %d MB for the ring buffer\n", info->ringSize); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %d MB for vertex/indirect buffers\n", info->bufSize); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %d MB for AGP textures\n", info->agpTexSize); - - /* Try for front, back, depth, and two framebuffers worth of - * pixmap cache. Should be enough for a fullscreen background - * image plus some leftovers. - */ - info->textureSize = info->FbMapSize - 5 * bufferSize; - - /* If that gives us less than half the available memory, let's - * be greedy and grab some more. Sorry, I care more about 3D - * performance than playing nicely, and you'll get around a full - * framebuffer's worth of pixmap cache anyway. - */ - if ( info->textureSize < (int)info->FbMapSize / 2 ) { - info->textureSize = info->FbMapSize - 4 * bufferSize; - } - if ( info->textureSize > 0 ) { - l = R128MinBits((info->textureSize-1) / R128_NR_TEX_REGIONS); - if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY; - - /* Round the texture size up to the nearest whole number of - * texture regions. Again, be greedy about this, don't - * round down. - */ - info->log2TexGran = l; - info->textureSize = ((info->textureSize >> l) + 1) << l; - } else { - info->textureSize = 0; - } - - total = info->FbMapSize - info->textureSize; - scanlines = total / width_bytes; - if (scanlines > 8191) scanlines = 8191; - - /* Recalculate the texture offset and size to accomodate any - * rounding to a whole number of scanlines. - * FIXME: Is this actually needed? - */ - info->textureOffset = scanlines * width_bytes; - info->textureSize = info->FbMapSize - info->textureOffset; - - /* Set a minimum usable local texture heap size. This will fit - * two 256x256x32bpp textures. - */ - if ( info->textureSize < 512 * 1024 ) { - info->textureOffset = 0; - info->textureSize = 0; - } - - MemBox.x1 = 0; - MemBox.y1 = 0; - MemBox.x2 = pScrn->displayWidth; - MemBox.y2 = scanlines; - - if (!xf86InitFBManager(pScreen, &MemBox)) { - xf86DrvMsg(scrnIndex, X_ERROR, - "Memory manager initialization to (%d,%d) (%d,%d) failed\n", - MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); - return FALSE; - } else { - int width, height; - - xf86DrvMsg(scrnIndex, X_INFO, - "Memory manager initialized to (%d,%d) (%d,%d)\n", - MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); - if ((fbarea = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth, - 2, 0, NULL, NULL, NULL))) { - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved area from (%d,%d) to (%d,%d)\n", - fbarea->box.x1, fbarea->box.y1, - fbarea->box.x2, fbarea->box.y2); - } else { - xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n"); - } - if (xf86QueryLargestOffscreenArea(pScreen, &width, - &height, 0, 0, 0)) { - xf86DrvMsg(scrnIndex, X_INFO, - "Largest offscreen area available: %d x %d\n", - width, height); - } - } + FBAreaPtr fbarea; + int width_bytes = (pScrn->displayWidth * + info->CurrentLayout.pixel_bytes); + int cpp = info->CurrentLayout.pixel_bytes; + int bufferSize = pScrn->virtualY * width_bytes; + int l, total; + int scanlines; + + switch (info->CCEMode) { + case R128_DEFAULT_CCE_PIO_MODE: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in PIO mode\n"); + break; + case R128_DEFAULT_CCE_BM_MODE: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in BM mode\n"); + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in UNKNOWN mode\n"); + break; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB AGP aperture\n", info->agpSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for the ring buffer\n", info->ringSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for vertex/indirect buffers\n", info->bufSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for AGP textures\n", info->agpTexSize); + + /* Try for front, back, depth, and two framebuffers worth of + * pixmap cache. Should be enough for a fullscreen background + * image plus some leftovers. + */ + info->textureSize = info->FbMapSize - 5 * bufferSize; + + /* If that gives us less than half the available memory, let's + * be greedy and grab some more. Sorry, I care more about 3D + * performance than playing nicely, and you'll get around a full + * framebuffer's worth of pixmap cache anyway. + */ + if (info->textureSize < (int)info->FbMapSize / 2) { + info->textureSize = info->FbMapSize - 4 * bufferSize; + } + + if (info->textureSize > 0) { + l = R128MinBits((info->textureSize-1) / R128_NR_TEX_REGIONS); + if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY; + + /* Round the texture size up to the nearest whole number of + * texture regions. Again, be greedy about this, don't + * round down. + */ + info->log2TexGran = l; + info->textureSize = (info->textureSize >> l) << l; + } else { + info->textureSize = 0; + } + + /* Set a minimum usable local texture heap size. This will fit + * two 256x256x32bpp textures. + */ + if (info->textureSize < 512 * 1024) { + info->textureOffset = 0; + info->textureSize = 0; + } + + total = info->FbMapSize - info->textureSize; + scanlines = total / width_bytes; + if (scanlines > 8191) scanlines = 8191; + + /* Recalculate the texture offset and size to accomodate any + * rounding to a whole number of scanlines. + */ + info->textureOffset = scanlines * width_bytes; + + MemBox.x1 = 0; + MemBox.y1 = 0; + MemBox.x2 = pScrn->displayWidth; + MemBox.y2 = scanlines; + + if (!xf86InitFBManager(pScreen, &MemBox)) { + xf86DrvMsg(scrnIndex, X_ERROR, + "Memory manager initialization to (%d,%d) (%d,%d) failed\n", + MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); + return FALSE; + } else { + int width, height; + + xf86DrvMsg(scrnIndex, X_INFO, + "Memory manager initialized to (%d,%d) (%d,%d)\n", + MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); + if ((fbarea = xf86AllocateOffscreenArea(pScreen, + pScrn->displayWidth, + 2, 0, NULL, NULL, NULL))) { + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved area from (%d,%d) to (%d,%d)\n", + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + } else { + xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n"); + } + if (xf86QueryLargestOffscreenArea(pScreen, &width, + &height, 0, 0, 0)) { + xf86DrvMsg(scrnIndex, X_INFO, + "Largest offscreen area available: %d x %d\n", + width, height); + } + } /* Allocate the shared back buffer */ - if ((fbarea = xf86AllocateOffscreenArea(pScreen, - pScrn->virtualX, - pScrn->virtualY, - 32, NULL, NULL, NULL))) { - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved back buffer from (%d,%d) to (%d,%d)\n", - fbarea->box.x1, fbarea->box.y1, - fbarea->box.x2, fbarea->box.y2); - - info->backX = fbarea->box.x1; - info->backY = fbarea->box.y1; - info->backOffset = (fbarea->box.y1 * width_bytes + - fbarea->box.x1 * cpp); - info->backPitch = pScrn->displayWidth; - } else { - xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve back buffer\n"); - info->backX = -1; - info->backY = -1; - info->backOffset = -1; - info->backPitch = -1; - } + if ((fbarea = xf86AllocateOffscreenArea(pScreen, + pScrn->virtualX, + pScrn->virtualY, + 32, NULL, NULL, NULL))) { + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved back buffer from (%d,%d) to (%d,%d)\n", + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + + info->backX = fbarea->box.x1; + info->backY = fbarea->box.y1; + info->backOffset = (fbarea->box.y1 * width_bytes + + fbarea->box.x1 * cpp); + info->backPitch = pScrn->displayWidth; + } else { + xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve back buffer\n"); + info->backX = -1; + info->backY = -1; + info->backOffset = -1; + info->backPitch = -1; + } /* Allocate the shared depth buffer */ - if ((fbarea = xf86AllocateOffscreenArea(pScreen, - pScrn->virtualX, - pScrn->virtualY + 1, - 32, NULL, NULL, NULL))) { - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved depth buffer from (%d,%d) to (%d,%d)\n", - fbarea->box.x1, fbarea->box.y1, - fbarea->box.x2, fbarea->box.y2); - - info->depthX = fbarea->box.x1; - info->depthY = fbarea->box.y1; - info->depthOffset = (fbarea->box.y1 * width_bytes + - fbarea->box.x1 * cpp); - info->depthPitch = pScrn->displayWidth; - info->spanOffset = ((fbarea->box.y2 - 1) * width_bytes + - fbarea->box.x1 * cpp); - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved depth span from (%d,%d) offset 0x%x\n", - fbarea->box.x1, fbarea->box.y2 - 1, info->spanOffset); - } else { - xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve depth buffer\n"); - info->depthX = -1; - info->depthY = -1; - info->depthOffset = -1; - info->depthPitch = -1; - info->spanOffset = -1; - } - - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved %d kb for textures at offset 0x%x\n", - info->textureSize/1024, total); + if ((fbarea = xf86AllocateOffscreenArea(pScreen, + pScrn->virtualX, + pScrn->virtualY + 1, + 32, NULL, NULL, NULL))) { + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved depth buffer from (%d,%d) to (%d,%d)\n", + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + + info->depthX = fbarea->box.x1; + info->depthY = fbarea->box.y1; + info->depthOffset = (fbarea->box.y1 * width_bytes + + fbarea->box.x1 * cpp); + info->depthPitch = pScrn->displayWidth; + info->spanOffset = ((fbarea->box.y2 - 1) * width_bytes + + fbarea->box.x1 * cpp); + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved depth span from (%d,%d) offset 0x%x\n", + fbarea->box.x1, fbarea->box.y2 - 1, info->spanOffset); + } else { + xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve depth buffer\n"); + info->depthX = -1; + info->depthY = -1; + info->depthOffset = -1; + info->depthPitch = -1; + info->spanOffset = -1; + } + + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved %d kb for textures at offset 0x%x\n", + info->textureSize/1024, info->textureOffset); } else #endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c index 4572c766b..26da62ba1 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c @@ -1062,8 +1062,15 @@ drmBufPtr RADEONCPGetBuffer( ScrnInfoPtr pScrn ) int size = 0; int ret, i = 0; - /* We obviously don't need this... */ - dma.context = 0xcafebabe /* driContextPriv->hHWContext */; +#if 0 + /* FIXME: pScrn->pScreen has not been initialized when this is first + called from RADEONSelectBuffer via RADEONDRICPInit. We could use + the screen index from pScrn, which is initialized, and then get + the screen from screenInfo.screens[index], but that is a hack. */ + dma.context = DRIGetContext(pScrn->pScreen); +#else + dma.context = 0x00000001; /* This is the X server's context */ +#endif dma.send_count = 0; dma.send_list = NULL; dma.send_sizes = NULL; @@ -1150,9 +1157,6 @@ void RADEONCPReleaseIndirect( ScrnInfoPtr pScrn ) start, buffer->used, 1 ); } - -/* FIXME: When direct rendering is enabled, we should use the CP to - draw 2D commands */ static void RADEONCPAccelInit(ScrnInfoPtr pScrn, XAAInfoRecPtr a) { RADEONInfoPtr info = RADEONPTR(pScrn); diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c index edaec9095..dd5fa4251 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c @@ -313,16 +313,124 @@ static void RADEONDRISwapContext(ScreenPtr pScreen, DRISyncType syncType, } } +#if 0 +/* The Radeon has depth tiling on all the time, so we have to convert + * the x,y coordinates into the memory bus address (mba) in the same + * manner as the engine. In each case, the linear block address (ba) + * is calculated, and then wired with x and y to produce the final + * memory address. + */ +static CARD32 radeon_mba_z16(RADEONInfoPtr info, + int x, int y) +{ + CARD32 pitch = info->frontPitch; + CARD32 ba, address = 0; /* a[0] = 0 */ + + ba = (y / 16) * (pitch / 32) + (x / 32); + + address |= (x & 0x7) << 1; /* a[1..3] = x[0..2] */ + address |= (y & 0x7) << 4; /* a[4..6] = y[0..2] */ + address |= (x & 0x8) << 4; /* a[7] = x[3] */ + address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */ + address |= (y & 0x8) << 7; /* a[10] = y[3] */ + address |= ((x & 0x10) ^ (y & 0x10)) << 7; /* a[11] = x[4] ^ y[4] */ + address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */ + + return address; +} + +static CARD32 radeon_mba_z32(RADEONInfoPtr info, + int x, int y) +{ + CARD32 pitch = info->frontPitch; + CARD32 ba, address = 0; /* a[0..1] = 0 */ + + ba = (y / 16) * (pitch / 16) + (x / 16); + + address |= (x & 0x7) << 2; /* a[2..4] = x[0..2] */ + address |= (y & 0x3) << 5; /* a[5..6] = y[0..1] */ + address |= + (((x & 0x10) >> 2) ^ (y & 0x4)) << 5; /* a[7] = x[4] ^ y[2] */ + address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */ + + address |= (y & 0x8) << 7; /* a[10] = y[3] */ + address |= + (((x & 0x8) << 1) ^ (y & 0x10)) << 7; /* a[11] = x[3] ^ y[4] */ + address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */ + + return address; +} + +/* 16-bit depth buffer functions */ +#define WRITE_DEPTH16(_x, _y, d) \ + *(CARD16 *)(buf + radeon_mba_z16(info, (_x), (_y))) = (d) + +#define READ_DEPTH16(d, _x, _y) \ + (d) = *(CARD16 *)(buf + radeon_mba_z16(info, (_x), (_y))) + +/* 24 bit depth, 8 bit stencil depthbuffer functions */ +#define WRITE_DEPTH32(_x, _y, d) \ +do { \ + CARD32 tmp = *(CARD32 *)(buf + radeon_mba_z32(info, (_x), (_y))); \ + tmp &= 0xff000000; \ + tmp |= ((d) & 0x00ffffff); \ + *(CARD32 *)(buf + radeon_mba_z32(info, (_x), (_y))) = tmp; \ +} while (0) + +#define READ_DEPTH32(d, _x, _y) \ + d = *(CARD32 *)(buf + radeon_mba_z32(info, (_x), (_y))) & 0x00ffffff + +/* Screen to screen copy of data in the depth buffer */ +static void RADEONScreenToScreenCopyDepth(ScrnInfoPtr pScrn, + int x1, int y1, + int x2, int y2, + int w, int h) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + int xstart, xend, xdir; + int ystart, yend, ydir; + int x, y, d; + unsigned char *buf = info->FB + info->depthOffset; + + if (x1 < x2) xdir = -1, xstart = w-1, xend = 0; + else xdir = 1, xstart = 0, xend = w-1; + + if (y1 < y2) ydir = -1, ystart = h-1, yend = 0; + else ydir = 1, ystart = 0, yend = h-1; + + switch (pScrn->bitsPerPixel) { + case 16: + for (x = xstart; x != xend; x += xdir) { + for (y = ystart; y != yend; y += ydir) { + READ_DEPTH16(d, x1+x, y1+y); + WRITE_DEPTH16(x2+x, y2+y, d); + } + } + break; + case 32: + for (x = xstart; x != xend; x += xdir) { + for (y = ystart; y != yend; y += ydir) { + READ_DEPTH32(d, x1+x, y1+y); + WRITE_DEPTH32(x2+x, y2+y, d); + } + } + break; + default: break; + } +} +#endif + /* Initialize the state of the back and depth buffers. */ static void RADEONDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index) { /* FIXME: This routine needs to have acceleration turned on */ - ScreenPtr pScreen = pWin->drawable.pScreen; - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - RADEONInfoPtr info = RADEONPTR(pScrn); - BoxPtr pbox, pboxSave; - int nbox, nboxSave; - int depth; + ScreenPtr pScreen = pWin->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONSAREAPrivPtr pSAREAPriv; + BoxPtr pbox; + int nbox; + int depth; /* FIXME: This should be based on the __GLXvisualConfig info */ switch (pScrn->bitsPerPixel) { @@ -337,30 +445,45 @@ static void RADEONDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index) /* FIXME: Only initialize the back and depth buffers for contexts that request them */ - pboxSave = pbox = REGION_RECTS(prgn); - nboxSave = nbox = REGION_NUM_RECTS(prgn); + FLUSH_RING(); + + pSAREAPriv = (RADEONSAREAPrivPtr)DRIGetSAREAPrivate(pScreen); + + pbox = REGION_RECTS(prgn); + nbox = REGION_NUM_RECTS(prgn); - (*info->accel->SetupForSolidFill)(pScrn, 0, GXcopy, -1); - RADEONSelectBuffer(pScrn, RADEON_BACK); for (; nbox; nbox--, pbox++) { - (*info->accel->SubsequentSolidFillRect)(pScrn, - pbox->x1, - pbox->y1, - pbox->x2 - pbox->x1, - pbox->y2 - pbox->y1); + int ret; + + /* drmRadeonClear uses the clip rects to draw instead of the + rect passed to it; however, it uses the rect for the depth + clears */ + pSAREAPriv->boxes[0].x1 = pbox->x1; + pSAREAPriv->boxes[0].x2 = pbox->x2; + pSAREAPriv->boxes[0].y1 = pbox->y1; + pSAREAPriv->boxes[0].y2 = pbox->y2; + pSAREAPriv->nbox = 1; + + ret = drmRadeonClear(info->drmFD, + DRM_RADEON_BACK | DRM_RADEON_DEPTH, + pbox->x1, + pbox->y1, + pbox->x2 - pbox->x1, + pbox->y2 - pbox->y1, + 0, depth); + if (ret) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "DRIInitBuffers timed out, resetting engine...\n"); + RADEONEngineReset(pScrn); + RADEONEngineRestore(pScrn); + RADEONCP_RESET(pScrn, info); + RADEONCP_START(pScrn, info); + return; + } } - pbox = pboxSave; - nbox = nboxSave; - - (*info->accel->SetupForSolidFill)(pScrn, depth, GXcopy, -1); - RADEONSelectBuffer(pScrn, RADEON_DEPTH); - for (; nbox; nbox--, pbox++) - (*info->accel->SubsequentSolidFillRect)(pScrn, - pbox->x1, - pbox->y1, - pbox->x2 - pbox->x1, - pbox->y2 - pbox->y1); + /* Mark the X server as the last context owner */ + pSAREAPriv->ctxOwner = DRIGetContext(pScreen); RADEONSelectBuffer(pScrn, RADEON_FRONT); info->accel->NeedToSync = TRUE; @@ -498,10 +621,13 @@ static void RADEONDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, destx, desty, w, h); RADEONSelectBuffer(pScrn, RADEON_DEPTH); - (*info->accel->SubsequentScreenToScreenCopy)(pScrn, - x1, y1, - destx, desty, - w, h); +#if 0 + /* FIXME: This is disabled because it is much too slow */ + RADEONScreenToScreenCopyDepth(pScrn, + x1, y1, + destx, desty, + w, h); +#endif } RADEONSelectBuffer(pScrn, RADEON_FRONT); @@ -806,7 +932,7 @@ static Bool RADEONDRIBufInit(RADEONInfoPtr info, ScreenPtr pScreen) /* Initialize the CP state, and start the CP (if used by the X server) */ static void RADEONDRICPInit(ScrnInfoPtr pScrn) { - RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONInfoPtr info = RADEONPTR(pScrn); /* Turn on bus mastering */ info->BusCntl &= ~RADEON_BUS_MASTER_DIS; @@ -816,6 +942,192 @@ static void RADEONDRICPInit(ScrnInfoPtr pScrn) RADEONSelectBuffer(pScrn, RADEON_FRONT); } +/* Initialize the DRI specific hardware state stored in the SAREA. + Currently, this involves setting up the 3D hardware state. */ +static void RADEONDRISAREAInit(ScreenPtr pScreen, + RADEONSAREAPrivPtr pSAREAPriv) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + radeon_context_regs_t *ctx; + radeon_texture_regs_t *tex; + CARD32 color_fmt, depth_fmt; + int i; + + switch (info->CurrentLayout.pixel_code) { + case 16: + color_fmt = RADEON_COLOR_FORMAT_RGB565; + depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z; + break; + case 32: + color_fmt = RADEON_COLOR_FORMAT_ARGB8888; + depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z; + break; + default: + xf86DrvMsg(pScreen->myNum, X_ERROR, + "RADEONDRISAREAInit failed: Unsupported depth (%d bpp)\n", + info->CurrentLayout.pixel_code); + return; + } + + /* Initialize the context state */ + ctx = &pSAREAPriv->ContextState; + + ctx->pp_misc = (RADEON_ALPHA_TEST_PASS | + RADEON_CHROMA_FUNC_FAIL | + RADEON_CHROMA_KEY_NEAREST | + RADEON_SHADOW_FUNC_EQUAL | + RADEON_SHADOW_PASS_1 | + RADEON_RIGHT_HAND_CUBE_OGL); + + ctx->pp_fog_color = ((0x00000000 & RADEON_FOG_COLOR_MASK) | + RADEON_FOG_VERTEX | + RADEON_FOG_USE_DEPTH); + + ctx->re_solid_color = 0x00000000; + + ctx->rb3d_blendcntl = (RADEON_SRC_BLEND_GL_ONE | + RADEON_DST_BLEND_GL_ZERO ); + + ctx->rb3d_depthoffset = info->depthOffset; + + ctx->rb3d_depthpitch = ((info->depthPitch & RADEON_DEPTHPITCH_MASK) | + RADEON_DEPTH_ENDIAN_NO_SWAP); + + ctx->rb3d_zstencilcntl = (depth_fmt | + RADEON_Z_TEST_LESS | + RADEON_STENCIL_TEST_ALWAYS | + RADEON_STENCIL_S_FAIL_KEEP | + RADEON_STENCIL_ZPASS_KEEP | + RADEON_STENCIL_ZFAIL_KEEP | + RADEON_Z_WRITE_ENABLE); + + ctx->pp_cntl = (RADEON_SCISSOR_ENABLE | + RADEON_ANTI_ALIAS_NONE); + + ctx->rb3d_cntl = (RADEON_PLANE_MASK_ENABLE | + color_fmt | + RADEON_ZBLOCK16); + + ctx->rb3d_coloroffset = (info->backOffset & RADEON_COLOROFFSET_MASK); + + ctx->re_width_height = ((0x7ff << RADEON_RE_WIDTH_SHIFT) | + (0x7ff << RADEON_RE_HEIGHT_SHIFT)); + + ctx->rb3d_colorpitch = ((info->backPitch & RADEON_COLORPITCH_MASK) | + RADEON_COLOR_ENDIAN_NO_SWAP); + + ctx->se_cntl = (RADEON_FFACE_CULL_CW | + RADEON_BFACE_SOLID | + RADEON_FFACE_SOLID | + RADEON_FLAT_SHADE_VTX_LAST | + RADEON_DIFFUSE_SHADE_GOURAUD | + RADEON_ALPHA_SHADE_GOURAUD | + RADEON_SPECULAR_SHADE_GOURAUD | + RADEON_FOG_SHADE_GOURAUD | + RADEON_VPORT_XY_XFORM_ENABLE | + RADEON_VTX_PIX_CENTER_OGL | + RADEON_ROUND_MODE_TRUNC | + RADEON_ROUND_PREC_8TH_PIX); + + ctx->se_coord_fmt = (RADEON_VTX_XY_PRE_MULT_1_OVER_W0 | + RADEON_VTX_Z_PRE_MULT_1_OVER_W0 | + RADEON_TEX1_W_ROUTING_USE_Q1); + + ctx->re_line_pattern = ((0x0000 & RADEON_LINE_PATTERN_MASK) | + (0 << RADEON_LINE_REPEAT_COUNT_SHIFT) | + (0 << RADEON_LINE_PATTERN_START_SHIFT) | + RADEON_LINE_PATTERN_LITTLE_BIT_ORDER); + + ctx->re_line_state = ((0 << RADEON_LINE_CURRENT_PTR_SHIFT) | + (0 << RADEON_LINE_CURRENT_COUNT_SHIFT)); + + ctx->se_line_width = 0x0000000; + + ctx->pp_lum_matrix = 0x00000000; + + ctx->pp_rot_matrix_0 = 0x00000000; + ctx->pp_rot_matrix_1 = 0x00000000; + + ctx->rb3d_stencilrefmask = ((0x00 << RADEON_STENCIL_REF_SHIFT) | + (0xff << RADEON_STENCIL_MASK_SHIFT) | + (0xff << RADEON_STENCIL_WRITEMASK_SHIFT)); + + ctx->rb3d_ropcntl = 0x00000000; + ctx->rb3d_planemask = 0xffffffff; + + ctx->se_vport_xscale = 0x00000000; + ctx->se_vport_xoffset = 0x00000000; + ctx->se_vport_yscale = 0x00000000; + ctx->se_vport_yoffset = 0x00000000; + ctx->se_vport_zscale = 0x00000000; + ctx->se_vport_zoffset = 0x00000000; + + ctx->se_cntl_status = (RADEON_VC_NO_SWAP | + RADEON_TCL_BYPASS); + +#ifdef TCL_ENABLE + /* FIXME: Obviously these need to be properly initialized */ + ctx->se_tcl_material_emmissive.red = 0x00000000; + ctx->se_tcl_material_emmissive.green = 0x00000000; + ctx->se_tcl_material_emmissive.blue = 0x00000000; + ctx->se_tcl_material_emmissive.alpha = 0x00000000; + + ctx->se_tcl_material_ambient.red = 0x00000000; + ctx->se_tcl_material_ambient.green = 0x00000000; + ctx->se_tcl_material_ambient.blue = 0x00000000; + ctx->se_tcl_material_ambient.alpha = 0x00000000; + + ctx->se_tcl_material_diffuse.red = 0x00000000; + ctx->se_tcl_material_diffuse.green = 0x00000000; + ctx->se_tcl_material_diffuse.blue = 0x00000000; + ctx->se_tcl_material_diffuse.alpha = 0x00000000; + + ctx->se_tcl_material_specular.red = 0x00000000; + ctx->se_tcl_material_specular.green = 0x00000000; + ctx->se_tcl_material_specular.blue = 0x00000000; + ctx->se_tcl_material_specular.alpha = 0x00000000; + + ctx->se_tcl_shininess = 0x00000000; + ctx->se_tcl_output_vtx_fmt = 0x00000000; + ctx->se_tcl_output_vtx_sel = 0x00000000; + ctx->se_tcl_matrix_select_0 = 0x00000000; + ctx->se_tcl_matrix_select_1 = 0x00000000; + ctx->se_tcl_ucp_vert_blend_ctl = 0x00000000; + ctx->se_tcl_texture_proc_ctl = 0x00000000; + ctx->se_tcl_light_model_ctl = 0x00000000; + for ( i = 0 ; i < 4 ; i++ ) { + ctx->se_tcl_per_light_ctl[i] = 0x00000000; + } +#endif + + ctx->re_top_left = ((0 << RADEON_RE_LEFT_SHIFT) | + (0 << RADEON_RE_TOP_SHIFT) ); + + ctx->re_misc = ((0 << RADEON_STIPPLE_X_OFFSET_SHIFT) | + (0 << RADEON_STIPPLE_Y_OFFSET_SHIFT) | + RADEON_STIPPLE_LITTLE_BIT_ORDER); + + /* Initialize the texture state */ + for (i = 0; i < RADEON_MAX_TEXTURE_UNITS; i++) { + tex = &pSAREAPriv->TexState[i]; + + tex->pp_txfilter = 0x00000000; + tex->pp_txformat = 0x00000000; + tex->pp_txoffset = 0x00000000; + tex->pp_txcblend = 0x00000000; + tex->pp_txablend = 0x00000000; + tex->pp_tfactor = 0x00000000; + tex->pp_border_color = 0x00000000; + } + + /* Mark the context as dirty */ + pSAREAPriv->dirty = RADEON_UPLOAD_ALL; + + /* Mark the X server as the last context owner */ + pSAREAPriv->ctxOwner = DRIGetContext(pScreen); +} + /* Initialize the screen-specific data structures for the DRI and the Radeon. This is the main entry point to the device-specific initialization code. It calls device-independent DRI functions to @@ -1032,6 +1344,7 @@ Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen) /* Initialize the SAREA private data structure */ pSAREAPriv = (RADEONSAREAPrivPtr)DRIGetSAREAPrivate(pScreen); memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); + RADEONDRISAREAInit(pScreen, pSAREAPriv); pRADEONDRI = (RADEONDRIPtr)info->pDRIInfo->devPrivate; diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h index d4c71aaba..b8116355e 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h @@ -55,7 +55,8 @@ #define RADEON_CARD_TYPE_RADEON 1 -#define RADEON_BUFFER_ALIGN 4096 +/* Buffer are aligned on 4096 byte boundaries */ +#define RADEON_BUFFER_ALIGN 0x00000fff #define RADEONCP_USE_RING_BUFFER(m) \ (((m) == RADEON_CSQ_PRIBM_INDDIS) || \ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c index bdf39e83a..5e3007ba2 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c @@ -1561,154 +1561,156 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) /* Memory manager setup */ #ifdef XF86DRI if (info->directRenderingEnabled) { - FBAreaPtr fbarea; - int width_bytes = (pScrn->displayWidth * - info->CurrentLayout.pixel_bytes); - int cpp = info->CurrentLayout.pixel_bytes; - int bufferSize = pScrn->virtualY * width_bytes; - int l, total; - int scanlines; - - info->frontOffset = 0; - info->frontPitch = pScrn->displayWidth; - - switch (info->CPMode) { - case RADEON_DEFAULT_CP_PIO_MODE: - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in PIO mode\n"); - break; - case RADEON_DEFAULT_CP_BM_MODE: - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in BM mode\n"); - break; - default: - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in UNKNOWN mode\n"); - break; - } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %d MB AGP aperture\n", info->agpSize); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %d MB for the ring buffer\n", info->ringSize); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %d MB for vertex/indirect buffers\n", info->bufSize); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %d MB for AGP textures\n", info->agpTexSize); - - /* Try for front, back, depth, and three framebuffers worth of - * pixmap cache. Should be enough for a fullscreen background - * image plus some leftovers. - */ - info->textureSize = info->FbMapSize - 6 * bufferSize; - - /* If that gives us less than half the available memory, let's - * be greedy and grab some more. Sorry, I care more about 3D - * performance than playing nicely, and you'll get around a full - * framebuffer's worth of pixmap cache anyway. - */ - if ( info->textureSize < (int)info->FbMapSize / 2 ) { - info->textureSize = info->FbMapSize - 5 * bufferSize; - } - if ( info->textureSize < (int)info->FbMapSize / 2 ) { - info->textureSize = info->FbMapSize - 4 * bufferSize; - } - - if ( info->textureSize > 0 ) { - l = RADEONMinBits((info->textureSize-1) / RADEON_NR_TEX_REGIONS); - if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY; - - /* Round the texture size up to the nearest whole number of - * texture regions. Again, be greedy about this, don't - * round down. - */ - info->log2TexGran = l; - info->textureSize = ((info->textureSize >> l) + 1) << l; - } else { - info->textureSize = 0; - } - - total = (info->FbMapSize - info->textureSize - - 2 * bufferSize + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN; - scanlines = total / width_bytes; - if (scanlines > 8191) scanlines = 8191; - - xf86DrvMsg(scrnIndex, X_INFO, - "total=0x%x tex=0x%x buf=0x%x rem=0x%x\n", - info->FbMapSize, info->textureSize, bufferSize, total); - - MemBox.x1 = 0; - MemBox.y1 = 0; - MemBox.x2 = pScrn->displayWidth; - MemBox.y2 = scanlines; - - if (!xf86InitFBManager(pScreen, &MemBox)) { - xf86DrvMsg(scrnIndex, X_ERROR, - "Memory manager initialization to (%d,%d) (%d,%d) failed\n", - MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); - return FALSE; - } else { - int width, height; - - xf86DrvMsg(scrnIndex, X_INFO, - "Memory manager initialized to (%d,%d) (%d,%d)\n", - MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); - if ((fbarea = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth, - 2, 0, NULL, NULL, NULL))) { - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved area from (%d,%d) to (%d,%d)\n", - fbarea->box.x1, fbarea->box.y1, - fbarea->box.x2, fbarea->box.y2); - } else { - xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n"); - } - if (xf86QueryLargestOffscreenArea(pScreen, &width, - &height, 0, 0, 0)) { - xf86DrvMsg(scrnIndex, X_INFO, - "Largest offscreen area available: %d x %d\n", - width, height); - } - } - - /* Recalculate the texture offset and size to accomodate any - * rounding to a whole number of scanlines. - * FIXME: Is this actually needed? - */ - info->textureOffset = scanlines * width_bytes; - info->textureSize = info->FbMapSize - info->textureOffset; - - /* Set a minimum usable local texture heap size. This will fit - * two 256x256x32bpp textures. - */ - if ( info->textureSize < 512 * 1024 ) { - info->textureOffset = 0; - info->textureSize = 0; - } - - /* Allocate the shared back buffer */ - info->backOffset = total; - info->backPitch = pScrn->displayWidth; - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved back buffer at offset 0x%x\n", - info->backOffset); - - /* Allocate the shared depth buffer */ - info->depthOffset = (info->backOffset + bufferSize + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN; - info->depthPitch = pScrn->displayWidth; - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved depth buffer at offset 0x%x\n", - info->depthOffset); - - info->textureOffset = (info->depthOffset + bufferSize + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN; - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved %d kb for textures at offset 0x%x\n", - info->textureSize/1024, info->textureOffset); - - info->frontPitchOffset = (((info->frontPitch * cpp / 64) << 22) | - (info->frontOffset >> 10)); - - info->backPitchOffset = (((info->backPitch * cpp / 64) << 22) | - (info->backOffset >> 10)); - - info->depthPitchOffset = (((info->depthPitch * cpp / 64) << 22) | - (info->depthOffset >> 10)); + FBAreaPtr fbarea; + int width_bytes = (pScrn->displayWidth * + info->CurrentLayout.pixel_bytes); + int cpp = info->CurrentLayout.pixel_bytes; + int bufferSize = ((pScrn->virtualY * width_bytes + RADEON_BUFFER_ALIGN) + & ~RADEON_BUFFER_ALIGN); + int l; + int scanlines; + + info->frontOffset = 0; + info->frontPitch = pScrn->displayWidth; + + switch (info->CPMode) { + case RADEON_DEFAULT_CP_PIO_MODE: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in PIO mode\n"); + break; + case RADEON_DEFAULT_CP_BM_MODE: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in BM mode\n"); + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CP in UNKNOWN mode\n"); + break; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB AGP aperture\n", info->agpSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for the ring buffer\n", info->ringSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for vertex/indirect buffers\n", info->bufSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for AGP textures\n", info->agpTexSize); + + /* Try for front, back, depth, and three framebuffers worth of + * pixmap cache. Should be enough for a fullscreen background + * image plus some leftovers. + */ + info->textureSize = info->FbMapSize - 6 * bufferSize; + + /* If that gives us less than half the available memory, let's + * be greedy and grab some more. Sorry, I care more about 3D + * performance than playing nicely, and you'll get around a full + * framebuffer's worth of pixmap cache anyway. + */ + if (info->textureSize < (int)info->FbMapSize / 2) { + info->textureSize = info->FbMapSize - 5 * bufferSize; + } + if (info->textureSize < (int)info->FbMapSize / 2) { + info->textureSize = info->FbMapSize - 4 * bufferSize; + } + + /* Check to see if there is more room available after the 8192nd + scanline for textures */ + if (info->FbMapSize - 8192*width_bytes - bufferSize*2 + > info->textureSize) { + info->textureSize = + info->FbMapSize - 8192*width_bytes - bufferSize*2; + } + + if (info->textureSize > 0) { + l = RADEONMinBits((info->textureSize-1) / RADEON_NR_TEX_REGIONS); + if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY; + + /* Round the texture size up to the nearest whole number of + * texture regions. Again, be greedy about this, don't + * round down. + */ + info->log2TexGran = l; + info->textureSize = (info->textureSize >> l) << l; + } else { + info->textureSize = 0; + } + + /* Set a minimum usable local texture heap size. This will fit + * two 256x256x32bpp textures. + */ + if (info->textureSize < 512 * 1024) { + info->textureOffset = 0; + info->textureSize = 0; + } + + /* Reserve space for textures */ + info->textureOffset = (info->FbMapSize - info->textureSize + + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN; + + /* Reserve space for the shared depth buffer */ + info->depthOffset = (info->textureOffset - bufferSize + + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN; + info->depthPitch = pScrn->displayWidth; + + /* Reserve space for the shared back buffer */ + info->backOffset = (info->depthOffset - bufferSize + + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN; + info->backPitch = pScrn->displayWidth; + + scanlines = info->backOffset / width_bytes - 1; + if (scanlines > 8191) scanlines = 8191; + + MemBox.x1 = 0; + MemBox.y1 = 0; + MemBox.x2 = pScrn->displayWidth; + MemBox.y2 = scanlines; + + if (!xf86InitFBManager(pScreen, &MemBox)) { + xf86DrvMsg(scrnIndex, X_ERROR, + "Memory manager initialization to (%d,%d) (%d,%d) failed\n", + MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); + return FALSE; + } else { + int width, height; + + xf86DrvMsg(scrnIndex, X_INFO, + "Memory manager initialized to (%d,%d) (%d,%d)\n", + MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); + if ((fbarea = xf86AllocateOffscreenArea(pScreen, + pScrn->displayWidth, + 2, 0, NULL, NULL, NULL))) { + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved area from (%d,%d) to (%d,%d)\n", + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + } else { + xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n"); + } + if (xf86QueryLargestOffscreenArea(pScreen, &width, + &height, 0, 0, 0)) { + xf86DrvMsg(scrnIndex, X_INFO, + "Largest offscreen area available: %d x %d\n", + width, height); + } + } + + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved back buffer at offset 0x%x\n", + info->backOffset); + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved depth buffer at offset 0x%x\n", + info->depthOffset); + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved %d kb for textures at offset 0x%x\n", + info->textureSize/1024, info->textureOffset); + + info->frontPitchOffset = (((info->frontPitch * cpp / 64) << 22) | + (info->frontOffset >> 10)); + + info->backPitchOffset = (((info->backPitch * cpp / 64) << 22) | + (info->backOffset >> 10)); + + info->depthPitchOffset = (((info->depthPitch * cpp / 64) << 22) | + (info->depthOffset >> 10)); } else #endif |