summaryrefslogtreecommitdiff
path: root/driver/xf86-video-ati/src/radeon_accel.c
diff options
context:
space:
mode:
authorOwain Ainsworth <oga@cvs.openbsd.org>2008-07-12 15:18:36 +0000
committerOwain Ainsworth <oga@cvs.openbsd.org>2008-07-12 15:18:36 +0000
commit97932ac707768ad1ec582f09562d0fa2e97c730b (patch)
treedcf9ba95312607942159ae2b6dd4adf4f89b4732 /driver/xf86-video-ati/src/radeon_accel.c
parent8b4789ec4c637d6a7d727e76383734c737944216 (diff)
Long awaited update of xf86-video-ati to 6.9.0.
the rage128 and mach64 drivers were split out of this driver just after the 6.8.0 release, these drivers will be commited separately. MergedFb mode is gone, so please use xrandr if you used to use it. ok matthieu@.
Diffstat (limited to 'driver/xf86-video-ati/src/radeon_accel.c')
-rw-r--r--driver/xf86-video-ati/src/radeon_accel.c537
1 files changed, 486 insertions, 51 deletions
diff --git a/driver/xf86-video-ati/src/radeon_accel.c b/driver/xf86-video-ati/src/radeon_accel.c
index 630977157..65ad33dfa 100644
--- a/driver/xf86-video-ati/src/radeon_accel.c
+++ b/driver/xf86-video-ati/src/radeon_accel.c
@@ -1,4 +1,3 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c,v 1.36 2003/11/10 18:41:22 tsi Exp $ */
/*
* Copyright 2000 ATI Technologies Inc., Markham, Ontario, and
* VA Linux Systems Inc., Fremont, California.
@@ -135,9 +134,10 @@ void RADEONWaitForFifoFunction(ScrnInfoPtr pScrn, int entries)
INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK;
if (info->fifo_slots >= entries) return;
}
- RADEONTRACE(("FIFO timed out: %u entries, stat=0x%08x\n",
- INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK,
- INREG(RADEON_RBBM_STATUS)));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "FIFO timed out: %u entries, stat=0x%08x\n",
+ (unsigned int)INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK,
+ (unsigned int)INREG(RADEON_RBBM_STATUS));
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"FIFO timed out, resetting engine...\n");
RADEONEngineReset(pScrn);
@@ -158,16 +158,32 @@ void RADEONEngineFlush(ScrnInfoPtr pScrn)
unsigned char *RADEONMMIO = info->MMIO;
int i;
- OUTREGP(RADEON_RB3D_DSTCACHE_CTLSTAT,
- RADEON_RB3D_DC_FLUSH_ALL,
- ~RADEON_RB3D_DC_FLUSH_ALL);
- for (i = 0; i < RADEON_TIMEOUT; i++) {
- if (!(INREG(RADEON_RB3D_DSTCACHE_CTLSTAT) & RADEON_RB3D_DC_BUSY))
- break;
- }
- if (i == RADEON_TIMEOUT) {
- RADEONTRACE(("DC flush timeout: %x\n",
- INREG(RADEON_RB3D_DSTCACHE_CTLSTAT)));
+ if (info->ChipFamily <= CHIP_FAMILY_RV280) {
+ OUTREGP(RADEON_RB3D_DSTCACHE_CTLSTAT,
+ RADEON_RB3D_DC_FLUSH_ALL,
+ ~RADEON_RB3D_DC_FLUSH_ALL);
+ for (i = 0; i < RADEON_TIMEOUT; i++) {
+ if (!(INREG(RADEON_RB3D_DSTCACHE_CTLSTAT) & RADEON_RB3D_DC_BUSY))
+ break;
+ }
+ if (i == RADEON_TIMEOUT) {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "DC flush timeout: %x\n",
+ (unsigned int)INREG(RADEON_RB3D_DSTCACHE_CTLSTAT));
+ }
+ } else {
+ OUTREGP(R300_DSTCACHE_CTLSTAT,
+ R300_RB2D_DC_FLUSH_ALL,
+ ~R300_RB2D_DC_FLUSH_ALL);
+ for (i = 0; i < RADEON_TIMEOUT; i++) {
+ if (!(INREG(R300_DSTCACHE_CTLSTAT) & R300_RB2D_DC_BUSY))
+ break;
+ }
+ if (i == RADEON_TIMEOUT) {
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "DC flush timeout: %x\n",
+ (unsigned int)INREG(R300_DSTCACHE_CTLSTAT));
+ }
}
}
@@ -176,10 +192,10 @@ void RADEONEngineReset(ScrnInfoPtr pScrn)
{
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
- CARD32 clock_cntl_index;
- CARD32 mclk_cntl;
- CARD32 rbbm_soft_reset;
- CARD32 host_path_cntl;
+ uint32_t clock_cntl_index;
+ uint32_t mclk_cntl;
+ uint32_t rbbm_soft_reset;
+ uint32_t host_path_cntl;
/* The following RBBM_SOFT_RESET sequence can help un-wedge
* an R300 after the command processor got stuck.
@@ -194,7 +210,7 @@ void RADEONEngineReset(ScrnInfoPtr pScrn)
RADEON_SOFT_RESET_E2 |
RADEON_SOFT_RESET_RB));
INREG(RADEON_RBBM_SOFT_RESET);
- OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset & (CARD32)
+ OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset & (uint32_t)
~(RADEON_SOFT_RESET_CP |
RADEON_SOFT_RESET_HI |
RADEON_SOFT_RESET_SE |
@@ -216,7 +232,7 @@ void RADEONEngineReset(ScrnInfoPtr pScrn)
* ASIC-version dependent, so we force all blocks on for now
*/
if (info->HasCRTC2) {
- CARD32 tmp;
+ uint32_t tmp;
tmp = INPLL(pScrn, RADEON_SCLK_CNTL);
OUTPLL(RADEON_SCLK_CNTL, ((tmp & ~RADEON_DYN_STOP_LAT_MASK) |
@@ -249,8 +265,8 @@ void RADEONEngineReset(ScrnInfoPtr pScrn)
host_path_cntl = INREG(RADEON_HOST_PATH_CNTL);
rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET);
- if (IS_R300_VARIANT) {
- CARD32 tmp;
+ if (IS_R300_VARIANT || IS_AVIVO_VARIANT) {
+ uint32_t tmp;
OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |
RADEON_SOFT_RESET_CP |
@@ -269,7 +285,7 @@ void RADEONEngineReset(ScrnInfoPtr pScrn)
RADEON_SOFT_RESET_E2 |
RADEON_SOFT_RESET_RB));
INREG(RADEON_RBBM_SOFT_RESET);
- OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset & (CARD32)
+ OUTREG(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset & (uint32_t)
~(RADEON_SOFT_RESET_CP |
RADEON_SOFT_RESET_SE |
RADEON_SOFT_RESET_RE |
@@ -283,7 +299,7 @@ void RADEONEngineReset(ScrnInfoPtr pScrn)
INREG(RADEON_HOST_PATH_CNTL);
OUTREG(RADEON_HOST_PATH_CNTL, host_path_cntl);
- if (!IS_R300_VARIANT)
+ if (!IS_R300_VARIANT && !IS_AVIVO_VARIANT)
OUTREG(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
OUTREG(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index);
@@ -297,9 +313,10 @@ void RADEONEngineRestore(ScrnInfoPtr pScrn)
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
- RADEONTRACE(("EngineRestore (%d/%d)\n",
- info->CurrentLayout.pixel_code,
- info->CurrentLayout.bitsPerPixel));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "EngineRestore (%d/%d)\n",
+ info->CurrentLayout.pixel_code,
+ info->CurrentLayout.bitsPerPixel);
/* Setup engine location. This shouldn't be necessary since we
* set them appropriately before any accel ops, but let's avoid
@@ -320,7 +337,7 @@ void RADEONEngineRestore(ScrnInfoPtr pScrn)
#endif
/* Restore SURFACE_CNTL */
- OUTREG(RADEON_SURFACE_CNTL, info->ModeReg.surface_cntl);
+ OUTREG(RADEON_SURFACE_CNTL, info->ModeReg->surface_cntl);
RADEONWaitForFifo(pScrn, 1);
OUTREG(RADEON_DEFAULT_SC_BOTTOM_RIGHT, (RADEON_DEFAULT_SC_RIGHT_MAX
@@ -348,11 +365,83 @@ void RADEONEngineInit(ScrnInfoPtr pScrn)
RADEONInfoPtr info = RADEONPTR(pScrn);
unsigned char *RADEONMMIO = info->MMIO;
- RADEONTRACE(("EngineInit (%d/%d)\n",
- info->CurrentLayout.pixel_code,
- info->CurrentLayout.bitsPerPixel));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "EngineInit (%d/%d)\n",
+ info->CurrentLayout.pixel_code,
+ info->CurrentLayout.bitsPerPixel);
- OUTREG(RADEON_RB3D_CNTL, 0);
+#ifdef XF86DRI
+ if (info->directRenderingEnabled && (IS_R300_3D || IS_R500_3D)) {
+ drmRadeonGetParam np;
+ int num_pipes;
+
+ memset(&np, 0, sizeof(np));
+ np.param = RADEON_PARAM_NUM_GB_PIPES;
+ np.value = &num_pipes;
+
+ if (drmCommandWriteRead(info->drmFD, DRM_RADEON_GETPARAM, &np,
+ sizeof(np)) < 0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Failed to determine num pipes from DRM, falling back to "
+ "manual look-up!\n");
+ info->num_gb_pipes = 0;
+ } else {
+ info->num_gb_pipes = num_pipes;
+ }
+ }
+#endif
+
+ if ((info->ChipFamily == CHIP_FAMILY_RV410) ||
+ (info->ChipFamily == CHIP_FAMILY_R420) ||
+ (info->ChipFamily == CHIP_FAMILY_RS600) ||
+ (info->ChipFamily == CHIP_FAMILY_RS690) ||
+ (info->ChipFamily == CHIP_FAMILY_RS740) ||
+ (info->ChipFamily == CHIP_FAMILY_RS400) ||
+ (info->ChipFamily == CHIP_FAMILY_RS480) ||
+ IS_R500_3D) {
+ if (info->num_gb_pipes == 0) {
+ uint32_t gb_pipe_sel = INREG(R400_GB_PIPE_SELECT);
+
+ info->num_gb_pipes = ((gb_pipe_sel >> 12) & 0x3) + 1;
+ if (IS_R500_3D)
+ OUTPLL(pScrn, R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4));
+ }
+ } else {
+ if (info->num_gb_pipes == 0) {
+ if ((info->ChipFamily == CHIP_FAMILY_R300) ||
+ (info->ChipFamily == CHIP_FAMILY_R350)) {
+ /* R3xx chips */
+ info->num_gb_pipes = 2;
+ } else {
+ /* RV3xx chips */
+ info->num_gb_pipes = 1;
+ }
+ }
+ }
+
+ if (IS_R300_3D || IS_R500_3D)
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "num pipes is %d\n", info->num_gb_pipes);
+
+ if (IS_R300_3D || IS_R500_3D) {
+ uint32_t gb_tile_config = (R300_ENABLE_TILING | R300_TILE_SIZE_16 | R300_SUBPIXEL_1_16);
+
+ switch(info->num_gb_pipes) {
+ case 2: gb_tile_config |= R300_PIPE_COUNT_R300; break;
+ case 3: gb_tile_config |= R300_PIPE_COUNT_R420_3P; break;
+ case 4: gb_tile_config |= R300_PIPE_COUNT_R420; break;
+ default:
+ case 1: gb_tile_config |= R300_PIPE_COUNT_RV350; break;
+ }
+
+ OUTREG(R300_GB_TILE_CONFIG, gb_tile_config);
+ OUTREG(RADEON_WAIT_UNTIL, RADEON_WAIT_2D_IDLECLEAN | RADEON_WAIT_3D_IDLECLEAN);
+ OUTREG(R300_DST_PIPE_CONFIG, INREG(R300_DST_PIPE_CONFIG) | R300_PIPE_AUTO_CONFIG);
+ OUTREG(R300_RB2D_DSTCACHE_MODE, (INREG(R300_RB2D_DSTCACHE_MODE) |
+ R300_DC_AUTOFLUSH_ENABLE |
+ R300_DC_DC_DISABLE_IGNORE_PE));
+ } else
+ OUTREG(RADEON_RB3D_CNTL, 0);
RADEONEngineReset(pScrn);
@@ -363,15 +452,17 @@ void RADEONEngineInit(ScrnInfoPtr pScrn)
case 24: info->datatype = 5; break;
case 32: info->datatype = 6; break;
default:
- RADEONTRACE(("Unknown depth/bpp = %d/%d (code = %d)\n",
- info->CurrentLayout.depth,
- info->CurrentLayout.bitsPerPixel,
- info->CurrentLayout.pixel_code));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Unknown depth/bpp = %d/%d (code = %d)\n",
+ info->CurrentLayout.depth,
+ info->CurrentLayout.bitsPerPixel,
+ info->CurrentLayout.pixel_code);
}
info->pitch = ((info->CurrentLayout.displayWidth / 8) *
(info->CurrentLayout.pixel_bytes == 3 ? 3 : 1));
- RADEONTRACE(("Pitch for acceleration = %d\n", info->pitch));
+ xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, RADEON_LOGLEVEL_DEBUG,
+ "Pitch for acceleration = %d\n", info->pitch);
info->dp_gui_master_cntl =
((info->datatype << RADEON_GMC_DST_DATATYPE_SHIFT)
@@ -385,8 +476,12 @@ void RADEONEngineInit(ScrnInfoPtr pScrn)
info->sc_bottom = RADEON_DEFAULT_SC_BOTTOM_MAX;
info->re_top_left = 0x00000000;
- info->re_width_height = ((0x7ff << RADEON_RE_WIDTH_SHIFT) |
- (0x7ff << RADEON_RE_HEIGHT_SHIFT));
+ if (info->ChipFamily <= CHIP_FAMILY_RV280)
+ info->re_width_height = ((0x7ff << RADEON_RE_WIDTH_SHIFT) |
+ (0x7ff << RADEON_RE_HEIGHT_SHIFT));
+ else
+ info->re_width_height = ((8191 << R300_SCISSOR_X_SHIFT) |
+ (8191 << R300_SCISSOR_Y_SHIFT));
info->aux_sc_cntl = 0x00000000;
#endif
@@ -612,11 +707,11 @@ void RADEONCPReleaseIndirect(ScrnInfoPtr pScrn)
* about tiling etc.
*/
void
-RADEONHostDataParams(ScrnInfoPtr pScrn, CARD8 *dst, CARD32 pitch, int cpp,
- CARD32 *dstPitchOff, int *x, int *y)
+RADEONHostDataParams(ScrnInfoPtr pScrn, uint8_t *dst, uint32_t pitch, int cpp,
+ uint32_t *dstPitchOff, int *x, int *y)
{
RADEONInfoPtr info = RADEONPTR( pScrn );
- CARD32 dstOffs = dst - info->FB + info->fbLocation;
+ uint32_t dstOffs = dst - (uint8_t*)info->FB + info->fbLocation;
*dstPitchOff = pitch << 16 | (dstOffs & ~RADEON_BUFFER_ALIGN) >> 10;
*y = ( dstOffs & RADEON_BUFFER_ALIGN ) / pitch;
@@ -627,21 +722,21 @@ RADEONHostDataParams(ScrnInfoPtr pScrn, CARD8 *dst, CARD32 pitch, int cpp,
* framebuffer. Returns the address where the data can be written to and sets
* the dstPitch and hpass variables as required.
*/
-CARD8*
+uint8_t*
RADEONHostDataBlit(
ScrnInfoPtr pScrn,
unsigned int cpp,
unsigned int w,
- CARD32 dstPitchOff,
- CARD32 *bufPitch,
+ uint32_t dstPitchOff,
+ uint32_t *bufPitch,
int x,
int *y,
unsigned int *h,
unsigned int *hpass
){
RADEONInfoPtr info = RADEONPTR( pScrn );
- CARD32 format, dwords;
- CARD8 *ret;
+ uint32_t format, dwords;
+ uint8_t *ret;
RING_LOCALS;
if ( *h == 0 )
@@ -714,7 +809,7 @@ RADEONHostDataBlit(
OUT_RING( *hpass << 16 | (*bufPitch / cpp) );
OUT_RING( dwords );
- ret = ( CARD8* )&__head[__count];
+ ret = ( uint8_t* )&__head[__count];
__count += dwords;
ADVANCE_RING();
@@ -725,7 +820,7 @@ RADEONHostDataBlit(
return ret;
}
-void RADEONCopySwap(CARD8 *dst, CARD8 *src, unsigned int size, int swap)
+void RADEONCopySwap(uint8_t *dst, uint8_t *src, unsigned int size, int swap)
{
switch(swap) {
case RADEON_HOST_DATA_SWAP_HDW:
@@ -780,8 +875,8 @@ void
RADEONHostDataBlitCopyPass(
ScrnInfoPtr pScrn,
unsigned int cpp,
- CARD8 *dst,
- CARD8 *src,
+ uint8_t *dst,
+ uint8_t *src,
unsigned int hpass,
unsigned int dstPitch,
unsigned int srcPitch
@@ -848,6 +943,9 @@ Bool RADEONAccelInit(ScreenPtr pScreen)
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
RADEONInfoPtr info = RADEONPTR(pScrn);
+ if (info->ChipFamily >= CHIP_FAMILY_R600)
+ return FALSE;
+
#ifdef USE_EXA
if (info->useEXA) {
# ifdef XF86DRI
@@ -907,3 +1005,340 @@ void RADEONInit3DEngine(ScrnInfoPtr pScrn)
info->XInited3D = TRUE;
}
+#ifdef USE_XAA
+#ifdef XF86DRI
+Bool
+RADEONSetupMemXAA_DRI(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ int cpp = info->CurrentLayout.pixel_bytes;
+ int depthCpp = (info->depthBits - 8) / 4;
+ int width_bytes = pScrn->displayWidth * cpp;
+ int bufferSize;
+ int depthSize;
+ int l;
+ int scanlines;
+ int texsizerequest;
+ BoxRec MemBox;
+ FBAreaPtr fbarea;
+
+ info->frontOffset = 0;
+ info->frontPitch = pScrn->displayWidth;
+ info->backPitch = pScrn->displayWidth;
+
+ /* make sure we use 16 line alignment for tiling (8 might be enough).
+ * Might need that for non-XF86DRI too?
+ */
+ if (info->allowColorTiling) {
+ bufferSize = (((pScrn->virtualY + 15) & ~15) * width_bytes
+ + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN;
+ } else {
+ bufferSize = (pScrn->virtualY * width_bytes
+ + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN;
+ }
+
+ /* Due to tiling, the Z buffer pitch must be a multiple of 32 pixels,
+ * which is always the case if color tiling is used due to color pitch
+ * but not necessarily otherwise, and its height a multiple of 16 lines.
+ */
+ info->depthPitch = (pScrn->displayWidth + 31) & ~31;
+ depthSize = ((((pScrn->virtualY + 15) & ~15) * info->depthPitch
+ * depthCpp + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN);
+
+ 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 GART aperture\n", info->gartSize);
+ 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 GART textures\n", info->gartTexSize);
+
+ /* Try for front, back, depth, and three framebuffers worth of
+ * pixmap cache. Should be enough for a fullscreen background
+ * image plus some leftovers.
+ * If the FBTexPercent option was used, try to achieve that percentage instead,
+ * but still have at least one pixmap buffer (get problems with xvideo/render
+ * otherwise probably), and never reserve more than 3 offscreen buffers as it's
+ * probably useless for XAA.
+ */
+ if (info->textureSize >= 0) {
+ texsizerequest = ((int)info->FbMapSize - 2 * bufferSize - depthSize
+ - 2 * width_bytes - 16384 - info->FbSecureSize)
+ /* first divide, then multiply or we'll get an overflow (been there...) */
+ / 100 * info->textureSize;
+ }
+ else {
+ texsizerequest = (int)info->FbMapSize / 2;
+ }
+ info->textureSize = info->FbMapSize - info->FbSecureSize - 5 * bufferSize - depthSize;
+
+ /* If that gives us less than the requested 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 < texsizerequest) {
+ info->textureSize = info->FbMapSize - 4 * bufferSize - depthSize;
+ }
+ if (info->textureSize < texsizerequest) {
+ info->textureSize = info->FbMapSize - 3 * bufferSize - depthSize;
+ }
+
+ /* If there's still no space for textures, try without pixmap cache, but
+ * never use the reserved space, the space hw cursor and PCIGART table might
+ * use.
+ */
+ if (info->textureSize < 0) {
+ info->textureSize = info->FbMapSize - 2 * bufferSize - depthSize
+ - 2 * width_bytes - 16384 - info->FbSecureSize;
+ }
+
+ /* Check to see if there is more room available after the 8192nd
+ * scanline for textures
+ */
+ /* FIXME: what's this good for? condition is pretty much impossible to meet */
+ if ((int)info->FbMapSize - 8192*width_bytes - bufferSize - depthSize
+ > info->textureSize) {
+ info->textureSize =
+ info->FbMapSize - 8192*width_bytes - bufferSize - depthSize;
+ }
+
+ /* If backbuffer is disabled, don't allocate memory for it */
+ if (info->noBackBuffer) {
+ info->textureSize += bufferSize;
+ }
+
+ /* RADEON_BUFFER_ALIGN is not sufficient for backbuffer!
+ At least for pageflip + color tiling, need to make sure it's 16 scanlines aligned,
+ otherwise the copy-from-front-to-back will fail (width_bytes * 16 will also guarantee
+ it's still 4kb aligned for tiled case). Need to round up offset (might get into cursor
+ area otherwise).
+ This might cause some space at the end of the video memory to be unused, since it
+ can't be used (?) due to that log_tex_granularity thing???
+ Could use different copyscreentoscreen function for the pageflip copies
+ (which would use different src and dst offsets) to avoid this. */
+ if (info->allowColorTiling && !info->noBackBuffer) {
+ info->textureSize = info->FbMapSize - ((info->FbMapSize - info->textureSize +
+ width_bytes * 16 - 1) / (width_bytes * 16)) * (width_bytes * 16);
+ }
+ 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;
+ }
+
+ if (info->allowColorTiling && !info->noBackBuffer) {
+ info->textureOffset = ((info->FbMapSize - info->textureSize) /
+ (width_bytes * 16)) * (width_bytes * 16);
+ }
+ else {
+ /* Reserve space for textures */
+ info->textureOffset = ((info->FbMapSize - info->textureSize +
+ RADEON_BUFFER_ALIGN) &
+ ~(uint32_t)RADEON_BUFFER_ALIGN);
+ }
+
+ /* Reserve space for the shared depth
+ * buffer.
+ */
+ info->depthOffset = ((info->textureOffset - depthSize +
+ RADEON_BUFFER_ALIGN) &
+ ~(uint32_t)RADEON_BUFFER_ALIGN);
+
+ /* Reserve space for the shared back buffer */
+ if (info->noBackBuffer) {
+ info->backOffset = info->depthOffset;
+ } else {
+ info->backOffset = ((info->depthOffset - bufferSize +
+ RADEON_BUFFER_ALIGN) &
+ ~(uint32_t)RADEON_BUFFER_ALIGN);
+ }
+
+ info->backY = info->backOffset / width_bytes;
+ info->backX = (info->backOffset - (info->backY * width_bytes)) / cpp;
+
+ scanlines = (info->FbMapSize-info->FbSecureSize) / width_bytes;
+ 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);
+ /* why oh why can't we just request modes which are guaranteed to be 16 lines
+ aligned... sigh */
+ if ((fbarea = xf86AllocateOffscreenArea(pScreen,
+ pScrn->displayWidth,
+ info->allowColorTiling ?
+ ((pScrn->virtualY + 15) & ~15)
+ - pScrn->virtualY + 2 : 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");
+ }
+
+ RADEONDRIAllocatePCIGARTTable(pScreen);
+
+ if (xf86QueryLargestOffscreenArea(pScreen, &width,
+ &height, 0, 0, 0)) {
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Largest offscreen area available: %d x %d\n",
+ width, height);
+
+ /* Lines in offscreen area needed for depth buffer and
+ * textures
+ */
+ info->depthTexLines = (scanlines
+ - info->depthOffset / width_bytes);
+ info->backLines = (scanlines
+ - info->backOffset / width_bytes
+ - info->depthTexLines);
+ info->backArea = NULL;
+ } else {
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "Unable to determine largest offscreen area "
+ "available\n");
+ return FALSE;
+ }
+ }
+
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Will use front buffer at offset 0x%x\n",
+ info->frontOffset);
+
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Will use back buffer at offset 0x%x\n",
+ info->backOffset);
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Will use depth buffer at offset 0x%x\n",
+ info->depthOffset);
+ if (info->cardType==CARD_PCIE)
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Will use %d kb for PCI GART table at offset 0x%x\n",
+ info->pciGartSize/1024, (unsigned)info->pciGartOffset);
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Will use %d kb for textures at offset 0x%x\n",
+ info->textureSize/1024, info->textureOffset);
+
+ info->frontPitchOffset = (((info->frontPitch * cpp / 64) << 22) |
+ ((info->frontOffset + info->fbLocation) >> 10));
+
+ info->backPitchOffset = (((info->backPitch * cpp / 64) << 22) |
+ ((info->backOffset + info->fbLocation) >> 10));
+
+ info->depthPitchOffset = (((info->depthPitch * depthCpp / 64) << 22) |
+ ((info->depthOffset + info->fbLocation) >> 10));
+ return TRUE;
+}
+#endif /* XF86DRI */
+
+Bool
+RADEONSetupMemXAA(int scrnIndex, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RADEONInfoPtr info = RADEONPTR(pScrn);
+ BoxRec MemBox;
+ int y2;
+
+ int width_bytes = pScrn->displayWidth * info->CurrentLayout.pixel_bytes;
+
+ MemBox.x1 = 0;
+ MemBox.y1 = 0;
+ MemBox.x2 = pScrn->displayWidth;
+ y2 = info->FbMapSize / width_bytes;
+ if (y2 >= 32768)
+ y2 = 32767; /* because MemBox.y2 is signed short */
+ MemBox.y2 = y2;
+
+ /* The acceleration engine uses 14 bit
+ * signed coordinates, so we can't have any
+ * drawable caches beyond this region.
+ */
+ if (MemBox.y2 > 8191)
+ MemBox.y2 = 8191;
+
+ 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;
+ FBAreaPtr fbarea;
+
+ 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,
+ info->allowColorTiling ?
+ ((pScrn->virtualY + 15) & ~15)
+ - pScrn->virtualY + 2 : 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);
+ }
+ return TRUE;
+ }
+}
+#endif /* USE_XAA */