(Stephane Marchesin, me) Add support for color (framebuffer) tiling to the radeon...
authorRoland Scheidegger <rscheidegger@gmx.ch>
Wed, 26 Jan 2005 18:05:03 +0000 (18:05 +0000)
committerRoland Scheidegger <rscheidegger@gmx.ch>
Wed, 26 Jan 2005 18:05:03 +0000 (18:05 +0000)
15 files changed:
src/mesa/drivers/dri/r200/r200_ioctl.c
src/mesa/drivers/dri/r200/r200_lock.c
src/mesa/drivers/dri/r200/r200_reg.h
src/mesa/drivers/dri/r200/r200_screen.c
src/mesa/drivers/dri/r200/r200_screen.h
src/mesa/drivers/dri/r200/r200_span.c
src/mesa/drivers/dri/r200/r200_state.c
src/mesa/drivers/dri/r200/r200_state_init.c
src/mesa/drivers/dri/radeon/radeon_ioctl.c
src/mesa/drivers/dri/radeon/radeon_lock.c
src/mesa/drivers/dri/radeon/radeon_screen.c
src/mesa/drivers/dri/radeon/radeon_screen.h
src/mesa/drivers/dri/radeon/radeon_span.c
src/mesa/drivers/dri/radeon/radeon_state.c
src/mesa/drivers/dri/radeon/radeon_state_init.c

index aafa298..a7d840f 100644 (file)
@@ -568,6 +568,9 @@ void r200PageFlip( const __DRIdrawablePrivate *dPriv )
    rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset
                                           + rmesa->r200Screen->fbLocation;
    rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH]  = rmesa->state.color.drawPitch;
+   if (rmesa->sarea->tiling_enabled) {
+      rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= R200_COLOR_TILE_ENABLE;
+   }
 }
 
 
index ef4fed5..72b57ae 100644 (file)
@@ -109,6 +109,12 @@ void r200GetLock( r200ContextPtr rmesa, GLuint flags )
       rmesa->lastStamp = dPriv->lastStamp;
    }
 
+   R200_STATECHANGE( rmesa, ctx );
+   if (rmesa->sarea->tiling_enabled) {
+      rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= R200_COLOR_TILE_ENABLE;
+   }
+   else rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] &= ~R200_COLOR_TILE_ENABLE;
+
    if ( sarea->ctx_owner != rmesa->dri.hwContext ) {
       sarea->ctx_owner = rmesa->dri.hwContext;
    }
index 38378a9..c1132e5 100644 (file)
@@ -210,6 +210,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define     R200_RE_HEIGHT_SHIFT       16
 #define R200_RB3D_COLORPITCH              0x1c48 
 #define     R200_COLORPITCH_MASK         0x000001ff8
+#define     R200_COLOR_TILE_ENABLE       (1 << 16)
+#define     R200_COLOR_MICROTILE_ENABLE  (1 << 17)
 #define     R200_COLOR_ENDIAN_NO_SWAP    (0 << 18)
 #define     R200_COLOR_ENDIAN_WORD_SWAP  (1 << 18)
 #define     R200_COLOR_ENDIAN_DWORD_SWAP (2 << 18)
index a10193d..76d7016 100644 (file)
@@ -342,10 +342,11 @@ r200CreateScreen( __DRIscreenPrivate *sPriv )
         /* Check if kernel module is new enough to support cube maps */
         screen->drmSupportsCubeMaps = (sPriv->drmMinor >= 7);
         /* Check if kernel module is new enough to support blend color and
-            separate blend functions/equations */
-         screen->drmSupportsBlendColor = (sPriv->drmMinor >= 11);
-
+           separate blend functions/equations */
+        screen->drmSupportsBlendColor = (sPriv->drmMinor >= 11);
       }
+      /* Check if ddx has set up a surface reg to cover depth buffer */
+      screen->depthHasSurface = (sPriv->ddxMajor > 4);
    }
 
    screen->mmio.handle = dri_priv->registerHandle;
@@ -622,17 +623,17 @@ void * __driCreateNewScreen( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc
                             
 {
    __DRIscreenPrivate *psp;
-   static const __DRIversion ddx_expected = { 4, 0, 0 };
+   static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 };
    static const __DRIversion dri_expected = { 4, 0, 0 };
    static const __DRIversion drm_expected = { 1, 5, 0 };
 
-   if ( ! driCheckDriDdxDrmVersions2( "R200",
+   if ( ! driCheckDriDdxDrmVersions3( "R200",
                                      dri_version, & dri_expected,
                                      ddx_version, & ddx_expected,
                                      drm_version, & drm_expected ) ) {
       return NULL;
    }
-      
+
    psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
                                  ddx_version, dri_version, drm_version,
                                  frame_buffer, pSAREA, fd,
index 95633b8..42200f8 100644 (file)
@@ -97,6 +97,7 @@ typedef struct {
 
    GLboolean drmSupportsCubeMaps;       /* need radeon kernel module >=1.7 */
    GLboolean drmSupportsBlendColor;     /* need radeon kernel module >= 1.11 */
+   GLboolean depthHasSurface;
 
    /* Configuration cache with default values for all contexts */
    driOptionCache optionCache;
index 3747948..f2868cb 100644 (file)
@@ -154,6 +154,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  * 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.
+ * The chip will do address translation on its own if the surface registers
+ * are set up correctly. It is not quite enough to get it working with hyperz too...
  */
 
 #define BIT(x,b) ((x & (1<<b))>>b)
@@ -161,40 +163,50 @@ static GLuint r200_mba_z32( r200ContextPtr rmesa,
                                       GLint x, GLint y )
 {
    GLuint pitch = rmesa->r200Screen->frontPitch;
-   GLuint b = ((y & 0x7FF) >> 4) * ((pitch & 0xFFF) >> 5) + ((x & 0x7FF) >> 5);
-   GLuint a = 
-      (BIT(x,0) << 2) |
-      (BIT(y,0) << 3) |
-      (BIT(x,1) << 4) |
-      (BIT(y,1) << 5) |
-      (BIT(x,3) << 6) |
-      (BIT(x,4) << 7) |
-      (BIT(x,2) << 8) |
-      (BIT(y,2) << 9) |
-      (BIT(y,3) << 10) |
-      (((pitch & 0x20) ? (b & 0x01) : ((b & 0x01) ^ (BIT(y,4)))) << 11) |
-      ((b >> 1) << 12);
-   return a;
+   if (rmesa->r200Screen->depthHasSurface) {
+      return 4*(x + y*pitch);
+   }
+   else {
+      GLuint b = ((y & 0x7FF) >> 4) * ((pitch & 0xFFF) >> 5) + ((x & 0x7FF) >> 5);
+      GLuint a = 
+         (BIT(x,0) << 2) |
+         (BIT(y,0) << 3) |
+         (BIT(x,1) << 4) |
+         (BIT(y,1) << 5) |
+         (BIT(x,3) << 6) |
+         (BIT(x,4) << 7) |
+         (BIT(x,2) << 8) |
+         (BIT(y,2) << 9) |
+         (BIT(y,3) << 10) |
+         (((pitch & 0x20) ? (b & 0x01) : ((b & 0x01) ^ (BIT(y,4)))) << 11) |
+         ((b >> 1) << 12);
+      return a;
+   }
 }
 
 static GLuint r200_mba_z16( r200ContextPtr rmesa, GLint x, GLint y )
 {
    GLuint pitch = rmesa->r200Screen->frontPitch;
-   GLuint b = ((y & 0x7FF) >> 4) * ((pitch & 0xFFF) >> 6) + ((x & 0x7FF) >> 6);
-   GLuint a = 
-      (BIT(x,0) << 1) |
-      (BIT(y,0) << 2) |
-      (BIT(x,1) << 3) |
-      (BIT(y,1) << 4) |
-      (BIT(x,2) << 5) |
-      (BIT(x,4) << 6) |
-      (BIT(x,5) << 7) |
-      (BIT(x,3) << 8) |
-      (BIT(y,2) << 9) |
-      (BIT(y,3) << 10) |
-      (((pitch & 0x40) ? (b & 0x01) : ((b & 0x01) ^ (BIT(y,4)))) << 11) |
-      ((b >> 1) << 12);
-   return a;
+   if (rmesa->r200Screen->depthHasSurface) {
+      return 2*(x + y*pitch);
+   }
+   else {
+      GLuint b = ((y & 0x7FF) >> 4) * ((pitch & 0xFFF) >> 6) + ((x & 0x7FF) >> 6);
+      GLuint a = 
+         (BIT(x,0) << 1) |
+         (BIT(y,0) << 2) |
+         (BIT(x,1) << 3) |
+         (BIT(y,1) << 4) |
+         (BIT(x,2) << 5) |
+         (BIT(x,4) << 6) |
+         (BIT(x,5) << 7) |
+         (BIT(x,3) << 8) |
+         (BIT(y,2) << 9) |
+         (BIT(y,3) << 10) |
+         (((pitch & 0x40) ? (b & 0x01) : ((b & 0x01) ^ (BIT(y,4)))) << 11) |
+         ((b >> 1) << 12);
+      return a;
+   }
 }
 
 
index f5a4a03..b83e71e 100644 (file)
@@ -1818,6 +1818,9 @@ static void r200DrawBuffer( GLcontext *ctx, GLenum mode )
                                               rmesa->r200Screen->fbLocation)
                                              & R200_COLOROFFSET_MASK);
    rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch;
+   if (rmesa->sarea->tiling_enabled) {
+      rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= R200_COLOR_TILE_ENABLE;
+   }
 }
 
 
index 5d36a68..cdb1f4d 100644 (file)
@@ -499,6 +499,10 @@ void r200InitState( r200ContextPtr rmesa )
    rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = ((rmesa->state.color.drawPitch &
                                              R200_COLORPITCH_MASK) |
                                             R200_COLOR_ENDIAN_NO_SWAP);
+   /* (fixed size) sarea is initialized to zero afaics so can omit version check. Phew! */
+   if (rmesa->sarea->tiling_enabled) {
+      rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= R200_COLOR_TILE_ENABLE;
+   }
 
    rmesa->hw.set.cmd[SET_SE_CNTL] = (R200_FFACE_CULL_CCW |
                                     R200_BFACE_SOLID |
index 8fe0e8c..8e411bd 100644 (file)
@@ -1011,6 +1011,9 @@ void radeonPageFlip( const __DRIdrawablePrivate *dPriv )
    rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset
                                           + rmesa->radeonScreen->fbLocation;
    rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH]  = rmesa->state.color.drawPitch;
+   if (rmesa->sarea->tiling_enabled) {
+      rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= RADEON_COLOR_TILE_ENABLE;
+   }
 }
 
 
index 937a284..7dab02e 100644 (file)
@@ -116,6 +116,12 @@ void radeonGetLock( radeonContextPtr rmesa, GLuint flags )
       rmesa->lastStamp = dPriv->lastStamp;
    }
 
+   RADEON_STATECHANGE( rmesa, ctx );
+   if (rmesa->sarea->tiling_enabled) {
+      rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= RADEON_COLOR_TILE_ENABLE;
+   }
+   else rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] &= ~RADEON_COLOR_TILE_ENABLE;
+
    if ( sarea->ctx_owner != rmesa->dri.hwContext ) {
       int i;
       sarea->ctx_owner = rmesa->dri.hwContext;
index e51b729..9687b7e 100644 (file)
@@ -355,6 +355,10 @@ radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv )
    screen->depthOffset = dri_priv->depthOffset;
    screen->depthPitch  = dri_priv->depthPitch;
 
+   /* Check if ddx has set up a surface reg to cover depth buffer */
+   screen->depthHasSurface = ((sPriv->ddxMajor > 4) &&
+      (screen->chipset & RADEON_CHIPSET_TCL));
+
    screen->texOffset[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureOffset
                                       + screen->fbLocation;
    screen->texSize[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureSize;
@@ -538,11 +542,11 @@ void * __driCreateNewScreen( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc
 
 {
    __DRIscreenPrivate *psp;
-   static const __DRIversion ddx_expected = { 4, 0, 0 };
+   static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 };
    static const __DRIversion dri_expected = { 4, 0, 0 };
    static const __DRIversion drm_expected = { 1, 3, 0 };
 
-   if ( ! driCheckDriDdxDrmVersions2( "Radeon",
+   if ( ! driCheckDriDdxDrmVersions3( "Radeon",
                                      dri_version, & dri_expected,
                                      ddx_version, & ddx_expected,
                                      drm_version, & drm_expected ) ) {
index 72edec8..000e734 100644 (file)
@@ -96,6 +96,8 @@ typedef struct {
    unsigned int gart_buffer_offset;    /* offset in card memory space */
    unsigned int gart_texture_offset;   /* offset in card memory space */
 
+   GLboolean depthHasSurface;
+
    /* Configuration cache with default values for all contexts */
    driOptionCache optionCache;
 } radeonScreenRec, *radeonScreenPtr;
index 5fa02fa..38ba5a5 100644 (file)
@@ -189,46 +189,58 @@ do {                                                              \
  * 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.
+ * The chip will do address translation on its own if the surface registers
+ * are set up correctly. It is not quite enough to get it working with hyperz too...
  */
 
 static GLuint radeon_mba_z32( radeonContextPtr rmesa,
                                       GLint x, GLint y )
 {
    GLuint pitch = rmesa->radeonScreen->frontPitch;
-   GLuint ba, address = 0;                     /* a[0..1] = 0           */
+   if (rmesa->radeonScreen->depthHasSurface) {
+      return 4*(x + y*pitch);
+   }
+   else {
+      GLuint ba, address = 0;                  /* a[0..1] = 0           */
 
-   ba = (y / 16) * (pitch / 16) + (x / 16);
+      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 |= (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..]     */
+      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;
+      return address;
+   }
 }
 
 static __inline GLuint radeon_mba_z16( radeonContextPtr rmesa, GLint x, GLint y )
 {
    GLuint pitch = rmesa->radeonScreen->frontPitch;
-   GLuint ba, address = 0;                     /* a[0]    = 0           */
+   if (rmesa->radeonScreen->depthHasSurface) {
+      return 2*(x + y*pitch);
+   }
+   else {
+      GLuint ba, address = 0;                  /* a[0]    = 0           */
 
-   ba = (y / 16) * (pitch / 32) + (x / 32);
+      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..]     */
+      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;
+      return address;
+   }
 }
 
 
index ff6f8bc..06f49ea 100644 (file)
@@ -1686,6 +1686,9 @@ static void radeonDrawBuffer( GLcontext *ctx, GLenum mode )
                                               rmesa->radeonScreen->fbLocation)
                                              & RADEON_COLOROFFSET_MASK);
    rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch;
+   if (rmesa->sarea->tiling_enabled) {
+      rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= RADEON_COLOR_TILE_ENABLE;
+   }
 }
 
 static void radeonReadBuffer( GLcontext *ctx, GLenum mode )
index 8db3c88..9caa8a2 100644 (file)
@@ -385,6 +385,10 @@ void radeonInitState( radeonContextPtr rmesa )
    rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = ((rmesa->state.color.drawPitch &
                                              RADEON_COLORPITCH_MASK) |
                                             RADEON_COLOR_ENDIAN_NO_SWAP);
+   /* (fixed size) sarea is initialized to zero afaics so can omit version check. Phew! */
+   if (rmesa->sarea->tiling_enabled) {
+      rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= RADEON_COLOR_TILE_ENABLE;
+   }
 
    rmesa->hw.set.cmd[SET_SE_CNTL] = (RADEON_FFACE_CULL_CCW |
                                     RADEON_BFACE_SOLID |