xf86-video-ati: Branch 'master' - 5 commits

Michel Daenzer daenzer at kemper.freedesktop.org
Mon Jun 19 09:00:41 EEST 2006


 man/radeon.man         |   18 +++++++
 src/radeon.h           |    7 ++
 src/radeon_dri.c       |   24 +++++----
 src/radeon_driver.c    |  108 ++++++++++++++++++++++++++++++++++--------
 src/radeon_exa.c       |    3 -
 src/radeon_exa_funcs.c |  126 ++++++++++++++++++++++++++++++++++++++++++++++---
 6 files changed, 248 insertions(+), 38 deletions(-)

New commits:
diff-tree 79d1c573133e64ddf4446b6bb0eaab4a5a6c73ab (from 2bcdc7cfd013bd457d35f927390e5cc3544f30f1)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sun Jun 18 17:39:09 2006 +0200

    Implement accelerated EXA DownloadFromScreen hook.
    
    x11perf -getimage numbers only increase by about 20-30% on my PowerBook with an
    M9, but by about 100 times(!) with a PCIe X550. I suspect the former could
    perform better with PCI as opposed to AGP transfers, which would also remove
    the need to disable this by default with AGP.

diff --git a/man/radeon.man b/man/radeon.man
index ba2ae84..9dc75fc 100644
--- a/man/radeon.man
+++ b/man/radeon.man
@@ -506,6 +506,15 @@ the Render and Composite extensions, but
 possibly unstable.  The default is
 .B XAA.
 .TP
+.BI "Option \*qAccelDFS\*q \*q" boolean \*q
+Use or don't use accelerated EXA DownloadFromScreen hook when possible (only
+when Direct Rendering is enabled, e.g.).
+Default:
+.B off
+with AGP due to issues with GPU->host transfers with some AGP bridges,
+.B on
+otherwise.
+.TP
 .BI "Option \*qFBTexPercent\*q \*q" integer \*q
 Amount of video RAM to reserve for OpenGL textures, in percent. With EXA, the
 remainder of video RAM is reserved for EXA offscreen management. Specifying 0
diff --git a/src/radeon.h b/src/radeon.h
index 06b3409..8e77313 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -334,7 +334,8 @@ typedef struct {
     unsigned long     LinearAddr;       /* Frame buffer physical address     */
     unsigned long     MMIOAddr;         /* MMIO region physical address      */
     unsigned long     BIOSAddr;         /* BIOS physical address             */
-    unsigned int      fbLocation;
+    CARD32            fbLocation;
+    CARD32            gartLocation;
     CARD32            mc_fb_location;
     CARD32            mc_agp_location;
 
@@ -416,6 +417,9 @@ typedef struct {
 #define EXA_ENGINEMODE_UNKNOWN 0
 #define EXA_ENGINEMODE_2D      1
 #define EXA_ENGINEMODE_3D      2
+#ifdef XF86DRI
+    Bool              accelDFS;
+#endif
 #endif
 #ifdef USE_XAA
     XAAInfoRecPtr     accel;
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index ff2dba7..5a20ac6 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -162,6 +162,9 @@ typedef enum {
     OPTION_XV_DMA,
     OPTION_FBTEX_PERCENT,
     OPTION_DEPTH_BITS,
+#ifdef USE_EXA
+    OPTION_ACCEL_DFS,
+#endif
 #endif
     OPTION_PANEL_OFF,
     OPTION_DDC_MODE,
@@ -227,6 +230,9 @@ static const OptionInfoRec RADEONOptions
     { OPTION_XV_DMA,         "DMAForXv",         OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_FBTEX_PERCENT,  "FBTexPercent",     OPTV_INTEGER, {0}, FALSE },
     { OPTION_DEPTH_BITS,     "DepthBits",        OPTV_INTEGER, {0}, FALSE },
+#ifdef USE_EXA
+    { OPTION_ACCEL_DFS,      "AccelDFS",         OPTV_BOOLEAN, {0}, FALSE },
+#endif
 #endif
     { OPTION_PANEL_OFF,      "PanelOff",         OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_DDC_MODE,       "DDCMode",          OPTV_BOOLEAN, {0}, FALSE },
@@ -5941,21 +5947,36 @@ _X_EXPORT Bool RADEONScreenInit(int scrn
 #ifdef USE_EXA
     if (info->useEXA) {
 #ifdef XF86DRI
-	/* Reserve approx. half of offscreen memory for local textures by
-	 * default, can be overridden with Option "FBTexPercent".
-	 * Round down to a whole number of texture regions.
-	 */
-	info->textureSize = 50;
+	MessageType from = X_DEFAULT;
 
-	if (xf86GetOptValInteger(info->Options, OPTION_FBTEX_PERCENT,
-				 &(info->textureSize))) {
-	    if (info->textureSize < 0 || info->textureSize > 100) {
-		xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-			   "Illegal texture memory percentage: %dx, setting to default 50%%\n",
-			   info->textureSize);
-		info->textureSize = 50;
+	if (hasDRI) {
+	    info->accelDFS = info->cardType != CARD_AGP;
+
+	    if (xf86GetOptValInteger(info->Options, OPTION_ACCEL_DFS,
+				     &info->accelDFS)) {
+		from = X_CONFIG;
+	    }
+
+	    /* Reserve approx. half of offscreen memory for local textures by
+	     * default, can be overridden with Option "FBTexPercent".
+	     * Round down to a whole number of texture regions.
+	     */
+	    info->textureSize = 50;
+
+	    if (xf86GetOptValInteger(info->Options, OPTION_FBTEX_PERCENT,
+				     &(info->textureSize))) {
+		if (info->textureSize < 0 || info->textureSize > 100) {
+		    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+			       "Illegal texture memory percentage: %dx, setting to default 50%%\n",
+			       info->textureSize);
+		    info->textureSize = 50;
+		}
 	    }
 	}
+
+	xf86DrvMsg(pScrn->scrnIndex, from,
+		   "%ssing accelerated EXA DownloadFromScreen hook\n",
+		   info->accelDFS ? "U" : "Not u");
 #endif /* XF86DRI */
 
 	if (!RADEONSetupMemEXA(pScreen))
@@ -6350,6 +6371,26 @@ static void RADEONAdjustMemMapRegisters(
 	    if (fb_loc_changed)
 		    RADEONRestoreMemMapRegisters(pScrn, save);
     }
+
+    if (info->accelDFS)
+    {
+	drmRadeonGetParam gp;
+	int gart_base;
+
+	memset(&gp, 0, sizeof(gp));
+	gp.param = RADEON_PARAM_GART_BASE;
+	gp.value = &gart_base;
+
+	if (drmCommandWriteRead(info->drmFD, DRM_RADEON_GETPARAM, &gp,
+				sizeof(gp)) < 0) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "Failed to determine GART area MC location, not using "
+		       "accelerated DownloadFromScreen hook!\n");
+	    info->accelDFS = FALSE;
+	} else {
+	    info->gartLocation = gart_base;
+	}
+    }
 }
 
 /* Write common registers */
diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c
index 77cffcf..bc22147 100644
--- a/src/radeon_exa_funcs.c
+++ b/src/radeon_exa_funcs.c
@@ -1,6 +1,7 @@
 /*
  * Copyright 2005 Eric Anholt
  * Copyright 2005 Benjamin Herrenschmidt
+ * Copyright 2006 Tungsten Graphics, Inc.
  * All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
@@ -26,6 +27,7 @@
  *    Eric Anholt <anholt at FreeBSD.org>
  *    Zack Rusin <zrusin at trolltech.com>
  *    Benjamin Herrenschmidt <benh at kernel.crashing.org>
+ *    Michel Dänzer <michel at tungstengraphics.com>
  *
  */
 
@@ -287,27 +289,141 @@ FUNC_NAME(RADEONUploadToScreen)(PixmapPt
     return TRUE;
 }
 
+#ifdef ACCEL_CP
+/* Emit blit with arbitrary source and destination offsets and pitches */
+static void
+RADEONBlitChunk(ScrnInfoPtr pScrn, CARD32 datatype, CARD32 src_pitch_offset,
+		CARD32 dst_pitch_offset, int srcX, int srcY, int dstX, int dstY,
+		int w, int h)
+{
+    RADEONInfoPtr info = RADEONPTR(pScrn);
+    ACCEL_PREAMBLE();
+
+    BEGIN_ACCEL(6);
+    OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL,
+		  RADEON_GMC_DST_PITCH_OFFSET_CNTL |
+		  RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
+		  RADEON_GMC_BRUSH_NONE |
+		  (datatype << 8) |
+		  RADEON_GMC_SRC_DATATYPE_COLOR |
+		  RADEON_ROP3_S |
+		  RADEON_DP_SRC_SOURCE_MEMORY |
+		  RADEON_GMC_CLR_CMP_CNTL_DIS |
+		  RADEON_GMC_WR_MSK_DIS);
+    OUT_ACCEL_REG(RADEON_SRC_PITCH_OFFSET, src_pitch_offset);
+    OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, dst_pitch_offset);
+    OUT_ACCEL_REG(RADEON_SRC_Y_X, (srcY << 16) | srcX);
+    OUT_ACCEL_REG(RADEON_DST_Y_X, (dstY << 16) | dstX);
+    OUT_ACCEL_REG(RADEON_DST_HEIGHT_WIDTH, (h << 16) | w);
+    FINISH_ACCEL();
+}
+#endif
+
 static Bool
 FUNC_NAME(RADEONDownloadFromScreen)(PixmapPtr pSrc, int x, int y, int w, int h,
 				    char *dst, int dst_pitch)
 {
-#if X_BYTE_ORDER == X_BIG_ENDIAN
+#if defined(ACCEL_CP) || X_BYTE_ORDER == X_BIG_ENDIAN
     RINFO_FROM_SCREEN(pSrc->drawable.pScreen);
+#endif
+#if X_BYTE_ORDER == X_BIG_ENDIAN
     unsigned char *RADEONMMIO = info->MMIO;
     unsigned int swapper = info->ModeReg.surface_cntl &
 	    ~(RADEON_NONSURF_AP0_SWP_32BPP | RADEON_NONSURF_AP1_SWP_32BPP |
 	      RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP1_SWP_16BPP);
 #endif
-    unsigned char *src	     = pSrc->devPrivate.ptr;
+    CARD8	  *src	     = pSrc->devPrivate.ptr;
     int		   src_pitch = exaGetPixmapPitch(pSrc);
     int		   bpp	     = pSrc->drawable.bitsPerPixel;
+#ifdef ACCEL_CP
+    CARD32 datatype, src_pitch_offset, scratch_pitch = (w * bpp/8 + 63) & ~63, scratch_off = 0;
+    drmBufPtr scratch;
+#endif
 
     TRACE;
 
+#ifdef ACCEL_CP
     /*
-     * This is currently done without DMA until I have ironed out the
-     * various endian issues with R300 among others
+     * Try to accelerate download. Use an indirect buffer as scratch space,
+     * blitting the bits to one half while copying them out of the other one and
+     * then swapping the halves.
      */
+    if (info->accelDFS && bpp != 24 && RADEONGetDatatypeBpp(bpp, &datatype) &&
+	RADEONGetPixmapOffsetPitch(pSrc, &src_pitch_offset) &&
+	(scratch = RADEONCPGetBuffer(pScrn)))
+    {
+	int swap = RADEON_HOST_DATA_SWAP_NONE, wpass = w * bpp / 8;
+	int hpass = min(h, scratch->total/2 / scratch_pitch);
+	CARD32 scratch_pitch_offset = scratch_pitch << 16
+				    | (info->gartLocation + info->bufStart
+				       + scratch->idx * scratch->total) >> 10;
+	drmRadeonIndirect indirect;
+	ACCEL_PREAMBLE();
+
+	RADEON_SWITCH_TO_2D();
+
+	/* Kick the first blit as early as possible */
+	RADEONBlitChunk(pScrn, datatype, src_pitch_offset, scratch_pitch_offset,
+			x, y, 0, 0, w, hpass);
+	FLUSH_RING();
+
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+	switch (bpp) {
+	case 16:
+	  swap = RADEON_HOST_DATA_SWAP_16BIT;
+	  break;
+	case 32:
+	  swap = RADEON_HOST_DATA_SWAP_32BIT;
+	  break;
+	}
+#endif
+
+	while (h) {
+	    int oldhpass = hpass;
+
+	    src = (CARD8*)scratch->address + scratch_off;
+
+	    y += oldhpass;
+	    h -= oldhpass;
+	    hpass = min(h, scratch->total/2 / scratch_pitch);
+
+	    /* Prepare next blit if anything's left */
+	    if (hpass) {
+		scratch_off = scratch->total/2 - scratch_off;
+		RADEONBlitChunk(pScrn, datatype, src_pitch_offset, scratch_pitch_offset + (scratch_off >> 10),
+				x, y, 0, 0, w, hpass);
+	    }
+
+	    /* Wait for previous blit to complete */
+	    RADEONWaitForIdleMMIO(pScrn);
+
+	    /* Kick next blit */
+	    if (hpass)
+		FLUSH_RING();
+
+	    /* Copy out data from previous blit */
+	    if (wpass == scratch_pitch && wpass == dst_pitch) {
+		RADEONCopySwap((CARD8*)dst, src, wpass * oldhpass, swap);
+		dst += dst_pitch * oldhpass;
+	    } else while (oldhpass--) {
+		RADEONCopySwap((CARD8*)dst, src, wpass, swap);
+		src += scratch_pitch;
+		dst += dst_pitch;
+	    }
+	}
+
+	indirect.idx = scratch->idx;
+	indirect.start = indirect.end = 0;
+	indirect.discard = 1;
+
+	drmCommandWriteRead(info->drmFD, DRM_RADEON_INDIRECT,
+			    &indirect, sizeof(drmRadeonIndirect));
+
+	return TRUE;
+    }
+#endif
+
+    /* Can't accelerate download */
     exaWaitSync(pSrc->drawable.pScreen);
 
 #if X_BYTE_ORDER == X_BIG_ENDIAN
diff-tree 2bcdc7cfd013bd457d35f927390e5cc3544f30f1 (from 25a5ccb63a9e3074b4c8eaf48844877d84ff76bb)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sun Jun 18 16:01:00 2006 +0200

    Remove #include <fbdevhw.h>, not used here.

diff --git a/src/radeon_exa_funcs.c b/src/radeon_exa_funcs.c
index 16d3f5d..77cffcf 100644
--- a/src/radeon_exa_funcs.c
+++ b/src/radeon_exa_funcs.c
@@ -56,8 +56,6 @@
 
 #include "exa.h"
 
-#include "fbdevhw.h"
-
 static void
 FUNC_NAME(RADEONSync)(ScreenPtr pScreen, int marker)
 {
diff-tree 25a5ccb63a9e3074b4c8eaf48844877d84ff76bb (from 8fcc436f19f9c1371295af2d0c45608fb43c584b)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sun Jun 18 15:26:55 2006 +0200

    Prefer visuals with stencil when it's hardware acclerated.
    
    Also make the formatting of the if statements consistent.

diff --git a/src/radeon_dri.c b/src/radeon_dri.c
index 1e0d544..b644659 100644
--- a/src/radeon_dri.c
+++ b/src/radeon_dri.c
@@ -163,10 +163,12 @@ static Bool RADEONInitVisualConfigs(Scre
 		pConfigs[i].stereo             = FALSE;
 		pConfigs[i].bufferSize         = 16;
 		pConfigs[i].depthSize          = info->depthBits;
-		if (stencil)
+		if (pConfigs[i].depthSize == 24 ? (RADEON_USE_STENCIL - stencil)
+						: stencil) {
 		    pConfigs[i].stencilSize    = 8;
-		else
+		} else {
 		    pConfigs[i].stencilSize    = 0;
+		}
 		pConfigs[i].auxBuffers         = 0;
 		pConfigs[i].level              = 0;
 		if (accum ||
@@ -247,7 +249,8 @@ static Bool RADEONInitVisualConfigs(Scre
 		pConfigs[i].stereo             = FALSE;
 		pConfigs[i].bufferSize         = 32;
 		pConfigs[i].depthSize          = info->depthBits;
-		if (stencil) {
+		if (pConfigs[i].depthSize == 24 ? (RADEON_USE_STENCIL - stencil)
+						: stencil) {
 		    pConfigs[i].stencilSize    = 8;
 		} else {
 		    pConfigs[i].stencilSize    = 0;
diff-tree 8fcc436f19f9c1371295af2d0c45608fb43c584b (from c8366d7b457565a06acdf6b40c5448c7f13f1641)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sun Jun 18 15:16:08 2006 +0200

    Take part of the blame for the radeon driver.

diff --git a/man/radeon.man b/man/radeon.man
index 55f83ad..ba2ae84 100644
--- a/man/radeon.man
+++ b/man/radeon.man
@@ -613,6 +613,7 @@ Kevin E. Martin          \fIkem at freedesk
 Alan Hourihane           \fIalanh at fairlite.demon.co.uk\fP
 Marc Aurele La France    \fItsi at xfree86.org\fP
 Benjamin Herrenschmidt   \fIbenh at kernel.crashing.org\fP
+Michel Dänzer            \fImichel at tungstengraphics.com\fP
 Alex Deucher             \fIalexdeucher at gmail.com\fP
 Bogdan D.                \fIbogdand at users.sourceforge.net\fP
 Eric Anholt              \fIeric at anholt.net\fP
diff-tree c8366d7b457565a06acdf6b40c5448c7f13f1641 (from 23a21d00db6f3b88b54c44648f968018a03677d3)
Author: Michel Dänzer <michel at tungstengraphics.com>
Date:   Sun Jun 18 14:24:14 2006 +0200

    Add Option "DepthBits".
    
    This allows getting higher depth buffer precision and stencil hardware
    acceleration in depth 16 or saving some video RAM at the cost of these features
    in depth 24.

diff --git a/man/radeon.man b/man/radeon.man
index 2bbd431..55f83ad 100644
--- a/man/radeon.man
+++ b/man/radeon.man
@@ -518,6 +518,14 @@ reserved for textures to the amount spec
 Default:
 .B 50.
 .TP
+.BI "Option \*qDepthBits\*q \*q" integer \*q
+Precision in bits per pixel of the shared depth buffer used for 3D acceleration.
+Valid values are 16 and 24. When this is 24, there will also be a hardware
+accelerated stencil buffer, but the combined depth/stencil buffer will take up
+twice as much video RAM as when it's 16.
+Default:
+.B The same as the screen depth.
+.TP
 .BI "Option \*qDMAForXv\*q \*q" boolean \*q
 Try or don't try to use DMA for Xv image transfers. This will reduce CPU
 usage when playing big videos like DVDs, but may cause instabilities.
diff --git a/src/radeon.h b/src/radeon.h
index 7f1e0ad..06b3409 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -584,6 +584,7 @@ typedef struct {
     int               backPitch;
     int               depthOffset;
     int               depthPitch;
+    int               depthBits;
     int               textureOffset;
     int               textureSize;
     int               log2TexGran;
diff --git a/src/radeon_dri.c b/src/radeon_dri.c
index bbc858a..1e0d544 100644
--- a/src/radeon_dri.c
+++ b/src/radeon_dri.c
@@ -162,14 +162,15 @@ static Bool RADEONInitVisualConfigs(Scre
 		    pConfigs[i].doubleBuffer   = FALSE;
 		pConfigs[i].stereo             = FALSE;
 		pConfigs[i].bufferSize         = 16;
-		pConfigs[i].depthSize          = 16;
+		pConfigs[i].depthSize          = info->depthBits;
 		if (stencil)
 		    pConfigs[i].stencilSize    = 8;
 		else
 		    pConfigs[i].stencilSize    = 0;
 		pConfigs[i].auxBuffers         = 0;
 		pConfigs[i].level              = 0;
-		if (accum || stencil) {
+		if (accum ||
+		    (pConfigs[i].stencilSize && pConfigs[i].depthSize == 16)) {
 		   pConfigs[i].visualRating    = GLX_SLOW_CONFIG;
 		} else {
 		   pConfigs[i].visualRating    = GLX_NONE;
@@ -245,16 +246,16 @@ static Bool RADEONInitVisualConfigs(Scre
 		    pConfigs[i].doubleBuffer   = FALSE;
 		pConfigs[i].stereo             = FALSE;
 		pConfigs[i].bufferSize         = 32;
+		pConfigs[i].depthSize          = info->depthBits;
 		if (stencil) {
-		    pConfigs[i].depthSize      = 24;
 		    pConfigs[i].stencilSize    = 8;
 		} else {
-		    pConfigs[i].depthSize      = 24;
 		    pConfigs[i].stencilSize    = 0;
 		}
 		pConfigs[i].auxBuffers         = 0;
 		pConfigs[i].level              = 0;
-		if (accum) {
+		if (accum ||
+		    (pConfigs[i].stencilSize && pConfigs[i].depthSize == 16)) {
 		   pConfigs[i].visualRating    = GLX_SLOW_CONFIG;
 		} else {
 		   pConfigs[i].visualRating    = GLX_NONE;
@@ -1061,14 +1062,14 @@ static int RADEONDRIKernelInit(RADEONInf
     drmInfo.usec_timeout        = info->CPusecTimeout;
 
     drmInfo.fb_bpp              = info->CurrentLayout.pixel_code;
-    drmInfo.depth_bpp           = info->CurrentLayout.pixel_code;
+    drmInfo.depth_bpp           = (info->depthBits - 8) * 2;
 
     drmInfo.front_offset        = info->frontOffset;
     drmInfo.front_pitch         = info->frontPitch * cpp;
     drmInfo.back_offset         = info->backOffset;
     drmInfo.back_pitch          = info->backPitch * cpp;
     drmInfo.depth_offset        = info->depthOffset;
-    drmInfo.depth_pitch         = info->depthPitch * cpp;
+    drmInfo.depth_pitch         = info->depthPitch * drmInfo.depth_bpp / 8;
 
     drmInfo.fb_offset           = info->fbHandle;
     drmInfo.mmio_offset         = info->registerHandle;
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 54a868a..ff2dba7 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -161,6 +161,7 @@ typedef enum {
     OPTION_NO_BACKBUFFER,
     OPTION_XV_DMA,
     OPTION_FBTEX_PERCENT,
+    OPTION_DEPTH_BITS,
 #endif
     OPTION_PANEL_OFF,
     OPTION_DDC_MODE,
@@ -225,6 +226,7 @@ static const OptionInfoRec RADEONOptions
     { OPTION_NO_BACKBUFFER,  "NoBackBuffer",     OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_XV_DMA,         "DMAForXv",         OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_FBTEX_PERCENT,  "FBTexPercent",     OPTV_INTEGER, {0}, FALSE },
+    { OPTION_DEPTH_BITS,     "DepthBits",        OPTV_INTEGER, {0}, FALSE },
 #endif
     { OPTION_PANEL_OFF,      "PanelOff",         OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_DDC_MODE,       "DDCMode",          OPTV_BOOLEAN, {0}, FALSE },
@@ -5364,6 +5366,7 @@ Bool RADEONSetupMemXAA_DRI(int scrnIndex
     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;
@@ -5394,7 +5397,7 @@ Bool RADEONSetupMemXAA_DRI(int scrnIndex
      */
     info->depthPitch = (pScrn->displayWidth + 31) & ~31;
     depthSize = ((((pScrn->virtualY + 15) & ~15) * info->depthPitch
-		  * cpp + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN);
+		  * depthCpp + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN);
 
     switch (info->CPMode) {
     case RADEON_DEFAULT_CP_PIO_MODE:
@@ -5620,7 +5623,7 @@ Bool RADEONSetupMemXAA_DRI(int scrnIndex
     info->backPitchOffset = (((info->backPitch * cpp / 64) << 22) |
 			     ((info->backOffset + info->fbLocation) >> 10));
 
-    info->depthPitchOffset = (((info->depthPitch * cpp / 64) << 22) |
+    info->depthPitchOffset = (((info->depthPitch * depthCpp / 64) << 22) |
 			      ((info->depthOffset + info->fbLocation) >> 10));
     return TRUE;
 }
@@ -5755,6 +5758,26 @@ _X_EXPORT Bool RADEONScreenInit(int scrn
     miSetPixmapDepths ();
 
 #ifdef XF86DRI
+    if (info->directRenderingEnabled) {
+	MessageType from;
+
+	info->depthBits = pScrn->depth;
+
+	from = xf86GetOptValInteger(info->Options, OPTION_DEPTH_BITS,
+				    &info->depthBits)
+	     ? X_CONFIG : X_DEFAULT;
+
+	if (info->depthBits != 16 && info->depthBits != 24) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+		       "Value for Option \"DepthBits\" must be 16 or 24\n");
+	    info->depthBits = pScrn->depth;
+	    from = X_DEFAULT;
+	}
+
+	xf86DrvMsg(pScrn->scrnIndex, from,
+		   "Using %d bit depth buffer\n", info->depthBits);
+    }
+
     /* Setup DRI after visuals have been established, but before fbScreenInit is
      * called.  fbScreenInit will eventually call the driver's InitGLXVisuals
      * call back. */
@@ -6810,10 +6833,14 @@ void RADEONChangeSurfaces(ScrnInfoPtr pS
   
     RADEONInfoPtr  info  = RADEONPTR(pScrn);
     int cpp = info->CurrentLayout.pixel_bytes;
+    int depthCpp = (info->depthBits - 8) / 4;
     /* depth/front/back pitch must be identical (and the same as displayWidth) */
     int width_bytes = pScrn->displayWidth * cpp;
     int bufferSize = ((((pScrn->virtualY + 15) & ~15) * width_bytes
         + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN);
+    int depth_width_bytes = pScrn->displayWidth * depthCpp;
+    int depthBufferSize = ((((pScrn->virtualY + 15) & ~15) * depth_width_bytes
+        + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN);
     unsigned int depth_pattern, color_pattern, swap_pattern;
 
     if (!info->allowColorTiling)
@@ -6833,19 +6860,19 @@ void RADEONChangeSurfaces(ScrnInfoPtr pS
 #endif
     if (info->ChipFamily < CHIP_FAMILY_R200) {
 	color_pattern = RADEON_SURF_TILE_COLOR_MACRO;
-	if (cpp == 2)
+	if (depthCpp == 2)
 	    depth_pattern = RADEON_SURF_TILE_DEPTH_16BPP;
 	else
 	    depth_pattern = RADEON_SURF_TILE_DEPTH_32BPP;
     } else if (IS_R300_VARIANT) {
        color_pattern = R300_SURF_TILE_COLOR_MACRO;
-       if (cpp == 2)
+       if (depthCpp == 2)
            depth_pattern = R300_SURF_TILE_COLOR_MACRO;
        else
            depth_pattern = R300_SURF_TILE_COLOR_MACRO | R300_SURF_TILE_DEPTH_32BPP;
     } else {
 	color_pattern = R200_SURF_TILE_COLOR_MACRO;
-	if (cpp == 2)
+	if (depthCpp == 2)
 	    depth_pattern = R200_SURF_TILE_DEPTH_16BPP;
 	else
 	    depth_pattern = R200_SURF_TILE_DEPTH_32BPP;
@@ -6904,12 +6931,12 @@ void RADEONChangeSurfaces(ScrnInfoPtr pS
 	    (info->ChipFamily != CHIP_FAMILY_RS100) ||
 	    (info->ChipFamily != CHIP_FAMILY_RS200))) {
 	    drmRadeonSurfaceAlloc drmsurfalloc;
-	    drmsurfalloc.size = bufferSize;
+	    drmsurfalloc.size = depthBufferSize;
 	    drmsurfalloc.address = info->depthOffset;
             if (IS_R300_VARIANT)
-                drmsurfalloc.flags = swap_pattern | (width_bytes / 8) | depth_pattern;
+                drmsurfalloc.flags = swap_pattern | (depth_width_bytes / 8) | depth_pattern;
             else
-                drmsurfalloc.flags = swap_pattern | (width_bytes / 16) | depth_pattern;
+                drmsurfalloc.flags = swap_pattern | (depth_width_bytes / 16) | depth_pattern;
 	    retvalue = drmCommandWrite(info->drmFD, DRM_RADEON_SURF_ALLOC,
 		&drmsurfalloc, sizeof(drmsurfalloc));
 	    if (retvalue < 0)
diff --git a/src/radeon_exa.c b/src/radeon_exa.c
index 8070da1..0cf86f5 100644
--- a/src/radeon_exa.c
+++ b/src/radeon_exa.c
@@ -367,6 +367,7 @@ Bool RADEONSetupMemEXA (ScreenPtr pScree
     ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
     RADEONInfoPtr info = RADEONPTR(pScrn);
     int cpp = info->CurrentLayout.pixel_bytes;
+    int depthCpp = (info->depthBits - 8) / 4;
     int l;
     int next, screen_size;
     int byteStride = pScrn->displayWidth * cpp;
@@ -435,7 +436,7 @@ Bool RADEONSetupMemEXA (ScreenPtr pScree
 	 * handle tiling.
 	 */
 	info->depthPitch = RADEON_ALIGN(pScrn->displayWidth, 32);
-	depth_size = RADEON_ALIGN(pScrn->virtualY, 16) * info->depthPitch * cpp;
+	depth_size = RADEON_ALIGN(pScrn->virtualY, 16) * info->depthPitch * depthCpp;
 	next = RADEON_ALIGN(info->exa->offScreenBase, RADEON_BUFFER_ALIGN);
 	if (next + depth_size <= info->exa->memorySize)
 	{



More information about the xorg-commit mailing list