From: Roland Scheidegger Date: Wed, 26 Jan 2005 18:05:03 +0000 (+0000) Subject: (Stephane Marchesin, me) Add support for color (framebuffer) tiling to the radeon... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a205137423e42010a025c70b05af98a6c0564f28;p=mesa.git (Stephane Marchesin, me) Add support for color (framebuffer) tiling to the radeon and r200 driver --- diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.c b/src/mesa/drivers/dri/r200/r200_ioctl.c index aafa2981bd4..a7d840f0f54 100644 --- a/src/mesa/drivers/dri/r200/r200_ioctl.c +++ b/src/mesa/drivers/dri/r200/r200_ioctl.c @@ -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; + } } diff --git a/src/mesa/drivers/dri/r200/r200_lock.c b/src/mesa/drivers/dri/r200/r200_lock.c index ef4fed52714..72b57ae5dc4 100644 --- a/src/mesa/drivers/dri/r200/r200_lock.c +++ b/src/mesa/drivers/dri/r200/r200_lock.c @@ -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; } diff --git a/src/mesa/drivers/dri/r200/r200_reg.h b/src/mesa/drivers/dri/r200/r200_reg.h index 38378a92f8c..c1132e54ab7 100644 --- a/src/mesa/drivers/dri/r200/r200_reg.h +++ b/src/mesa/drivers/dri/r200/r200_reg.h @@ -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) diff --git a/src/mesa/drivers/dri/r200/r200_screen.c b/src/mesa/drivers/dri/r200/r200_screen.c index a10193d3ae3..76d70160924 100644 --- a/src/mesa/drivers/dri/r200/r200_screen.c +++ b/src/mesa/drivers/dri/r200/r200_screen.c @@ -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, diff --git a/src/mesa/drivers/dri/r200/r200_screen.h b/src/mesa/drivers/dri/r200/r200_screen.h index 95633b8ebe5..42200f8962b 100644 --- a/src/mesa/drivers/dri/r200/r200_screen.h +++ b/src/mesa/drivers/dri/r200/r200_screen.h @@ -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; diff --git a/src/mesa/drivers/dri/r200/r200_span.c b/src/mesa/drivers/dri/r200/r200_span.c index 3747948984f..f2868cb2d21 100644 --- a/src/mesa/drivers/dri/r200/r200_span.c +++ b/src/mesa/drivers/dri/r200/r200_span.c @@ -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) @@ -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; + } } diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c index f5a4a031188..b83e71e0ec4 100644 --- a/src/mesa/drivers/dri/r200/r200_state.c +++ b/src/mesa/drivers/dri/r200/r200_state.c @@ -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; + } } diff --git a/src/mesa/drivers/dri/r200/r200_state_init.c b/src/mesa/drivers/dri/r200/r200_state_init.c index 5d36a6823ac..cdb1f4d0a05 100644 --- a/src/mesa/drivers/dri/r200/r200_state_init.c +++ b/src/mesa/drivers/dri/r200/r200_state_init.c @@ -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 | diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c index 8fe0e8c8459..8e411bdaa8f 100644 --- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c +++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c @@ -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; + } } diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.c b/src/mesa/drivers/dri/radeon/radeon_lock.c index 937a284e104..7dab02e6b52 100644 --- a/src/mesa/drivers/dri/radeon/radeon_lock.c +++ b/src/mesa/drivers/dri/radeon/radeon_lock.c @@ -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; diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index e51b72911bb..9687b7efac1 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -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 ) ) { diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.h b/src/mesa/drivers/dri/radeon/radeon_screen.h index 72edec881d4..000e7347378 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.h +++ b/src/mesa/drivers/dri/radeon/radeon_screen.h @@ -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; diff --git a/src/mesa/drivers/dri/radeon/radeon_span.c b/src/mesa/drivers/dri/radeon/radeon_span.c index 5fa02fa97ca..38ba5a50e50 100644 --- a/src/mesa/drivers/dri/radeon/radeon_span.c +++ b/src/mesa/drivers/dri/radeon/radeon_span.c @@ -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; + } } diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c index ff6f8bc7269..06f49eac5c3 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.c +++ b/src/mesa/drivers/dri/radeon/radeon_state.c @@ -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 ) diff --git a/src/mesa/drivers/dri/radeon/radeon_state_init.c b/src/mesa/drivers/dri/radeon/radeon_state_init.c index 8db3c88192a..9caa8a2b4de 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state_init.c +++ b/src/mesa/drivers/dri/radeon/radeon_state_init.c @@ -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 |