(Stephane Marchesin, me) Add support for color (framebuffer) tiling to the radeon and r200 driver

This commit is contained in:
Roland Scheidegger 2005-01-26 18:05:03 +00:00
parent 7104ce0a0e
commit a205137423
15 changed files with 125 additions and 59 deletions

View File

@ -568,6 +568,9 @@ void r200PageFlip( const __DRIdrawablePrivate *dPriv )
rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset
+ rmesa->r200Screen->fbLocation; + rmesa->r200Screen->fbLocation;
rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch; 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;
}
} }

View File

@ -109,6 +109,12 @@ void r200GetLock( r200ContextPtr rmesa, GLuint flags )
rmesa->lastStamp = dPriv->lastStamp; 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 ) { if ( sarea->ctx_owner != rmesa->dri.hwContext ) {
sarea->ctx_owner = rmesa->dri.hwContext; sarea->ctx_owner = rmesa->dri.hwContext;
} }

View 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_RE_HEIGHT_SHIFT 16
#define R200_RB3D_COLORPITCH 0x1c48 #define R200_RB3D_COLORPITCH 0x1c48
#define R200_COLORPITCH_MASK 0x000001ff8 #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_NO_SWAP (0 << 18)
#define R200_COLOR_ENDIAN_WORD_SWAP (1 << 18) #define R200_COLOR_ENDIAN_WORD_SWAP (1 << 18)
#define R200_COLOR_ENDIAN_DWORD_SWAP (2 << 18) #define R200_COLOR_ENDIAN_DWORD_SWAP (2 << 18)

View File

@ -342,10 +342,11 @@ r200CreateScreen( __DRIscreenPrivate *sPriv )
/* Check if kernel module is new enough to support cube maps */ /* Check if kernel module is new enough to support cube maps */
screen->drmSupportsCubeMaps = (sPriv->drmMinor >= 7); screen->drmSupportsCubeMaps = (sPriv->drmMinor >= 7);
/* Check if kernel module is new enough to support blend color and /* Check if kernel module is new enough to support blend color and
separate blend functions/equations */ separate blend functions/equations */
screen->drmSupportsBlendColor = (sPriv->drmMinor >= 11); 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; screen->mmio.handle = dri_priv->registerHandle;
@ -622,17 +623,17 @@ void * __driCreateNewScreen( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc
{ {
__DRIscreenPrivate *psp; __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 dri_expected = { 4, 0, 0 };
static const __DRIversion drm_expected = { 1, 5, 0 }; static const __DRIversion drm_expected = { 1, 5, 0 };
if ( ! driCheckDriDdxDrmVersions2( "R200", if ( ! driCheckDriDdxDrmVersions3( "R200",
dri_version, & dri_expected, dri_version, & dri_expected,
ddx_version, & ddx_expected, ddx_version, & ddx_expected,
drm_version, & drm_expected ) ) { drm_version, & drm_expected ) ) {
return NULL; return NULL;
} }
psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
ddx_version, dri_version, drm_version, ddx_version, dri_version, drm_version,
frame_buffer, pSAREA, fd, frame_buffer, pSAREA, fd,

View File

@ -97,6 +97,7 @@ typedef struct {
GLboolean drmSupportsCubeMaps; /* need radeon kernel module >=1.7 */ GLboolean drmSupportsCubeMaps; /* need radeon kernel module >=1.7 */
GLboolean drmSupportsBlendColor; /* need radeon kernel module >= 1.11 */ GLboolean drmSupportsBlendColor; /* need radeon kernel module >= 1.11 */
GLboolean depthHasSurface;
/* Configuration cache with default values for all contexts */ /* Configuration cache with default values for all contexts */
driOptionCache optionCache; driOptionCache optionCache;

View 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) * 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 * is calculated, and then wired with x and y to produce the final
* memory address. * 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) #define BIT(x,b) ((x & (1<<b))>>b)
@ -161,40 +163,50 @@ static GLuint r200_mba_z32( r200ContextPtr rmesa,
GLint x, GLint y ) GLint x, GLint y )
{ {
GLuint pitch = rmesa->r200Screen->frontPitch; GLuint pitch = rmesa->r200Screen->frontPitch;
GLuint b = ((y & 0x7FF) >> 4) * ((pitch & 0xFFF) >> 5) + ((x & 0x7FF) >> 5); if (rmesa->r200Screen->depthHasSurface) {
GLuint a = return 4*(x + y*pitch);
(BIT(x,0) << 2) | }
(BIT(y,0) << 3) | else {
(BIT(x,1) << 4) | GLuint b = ((y & 0x7FF) >> 4) * ((pitch & 0xFFF) >> 5) + ((x & 0x7FF) >> 5);
(BIT(y,1) << 5) | GLuint a =
(BIT(x,3) << 6) | (BIT(x,0) << 2) |
(BIT(x,4) << 7) | (BIT(y,0) << 3) |
(BIT(x,2) << 8) | (BIT(x,1) << 4) |
(BIT(y,2) << 9) | (BIT(y,1) << 5) |
(BIT(y,3) << 10) | (BIT(x,3) << 6) |
(((pitch & 0x20) ? (b & 0x01) : ((b & 0x01) ^ (BIT(y,4)))) << 11) | (BIT(x,4) << 7) |
((b >> 1) << 12); (BIT(x,2) << 8) |
return a; (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 ) static GLuint r200_mba_z16( r200ContextPtr rmesa, GLint x, GLint y )
{ {
GLuint pitch = rmesa->r200Screen->frontPitch; GLuint pitch = rmesa->r200Screen->frontPitch;
GLuint b = ((y & 0x7FF) >> 4) * ((pitch & 0xFFF) >> 6) + ((x & 0x7FF) >> 6); if (rmesa->r200Screen->depthHasSurface) {
GLuint a = return 2*(x + y*pitch);
(BIT(x,0) << 1) | }
(BIT(y,0) << 2) | else {
(BIT(x,1) << 3) | GLuint b = ((y & 0x7FF) >> 4) * ((pitch & 0xFFF) >> 6) + ((x & 0x7FF) >> 6);
(BIT(y,1) << 4) | GLuint a =
(BIT(x,2) << 5) | (BIT(x,0) << 1) |
(BIT(x,4) << 6) | (BIT(y,0) << 2) |
(BIT(x,5) << 7) | (BIT(x,1) << 3) |
(BIT(x,3) << 8) | (BIT(y,1) << 4) |
(BIT(y,2) << 9) | (BIT(x,2) << 5) |
(BIT(y,3) << 10) | (BIT(x,4) << 6) |
(((pitch & 0x40) ? (b & 0x01) : ((b & 0x01) ^ (BIT(y,4)))) << 11) | (BIT(x,5) << 7) |
((b >> 1) << 12); (BIT(x,3) << 8) |
return a; (BIT(y,2) << 9) |
(BIT(y,3) << 10) |
(((pitch & 0x40) ? (b & 0x01) : ((b & 0x01) ^ (BIT(y,4)))) << 11) |
((b >> 1) << 12);
return a;
}
} }

View File

@ -1818,6 +1818,9 @@ static void r200DrawBuffer( GLcontext *ctx, GLenum mode )
rmesa->r200Screen->fbLocation) rmesa->r200Screen->fbLocation)
& R200_COLOROFFSET_MASK); & R200_COLOROFFSET_MASK);
rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch; 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;
}
} }

View File

@ -499,6 +499,10 @@ void r200InitState( r200ContextPtr rmesa )
rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = ((rmesa->state.color.drawPitch & rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = ((rmesa->state.color.drawPitch &
R200_COLORPITCH_MASK) | R200_COLORPITCH_MASK) |
R200_COLOR_ENDIAN_NO_SWAP); 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 | rmesa->hw.set.cmd[SET_SE_CNTL] = (R200_FFACE_CULL_CCW |
R200_BFACE_SOLID | R200_BFACE_SOLID |

View File

@ -1011,6 +1011,9 @@ void radeonPageFlip( const __DRIdrawablePrivate *dPriv )
rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset
+ rmesa->radeonScreen->fbLocation; + rmesa->radeonScreen->fbLocation;
rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch; 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;
}
} }

View File

@ -116,6 +116,12 @@ void radeonGetLock( radeonContextPtr rmesa, GLuint flags )
rmesa->lastStamp = dPriv->lastStamp; 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 ) { if ( sarea->ctx_owner != rmesa->dri.hwContext ) {
int i; int i;
sarea->ctx_owner = rmesa->dri.hwContext; sarea->ctx_owner = rmesa->dri.hwContext;

View File

@ -355,6 +355,10 @@ radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv )
screen->depthOffset = dri_priv->depthOffset; screen->depthOffset = dri_priv->depthOffset;
screen->depthPitch = dri_priv->depthPitch; 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->texOffset[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureOffset
+ screen->fbLocation; + screen->fbLocation;
screen->texSize[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureSize; screen->texSize[RADEON_LOCAL_TEX_HEAP] = dri_priv->textureSize;
@ -538,11 +542,11 @@ void * __driCreateNewScreen( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc
{ {
__DRIscreenPrivate *psp; __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 dri_expected = { 4, 0, 0 };
static const __DRIversion drm_expected = { 1, 3, 0 }; static const __DRIversion drm_expected = { 1, 3, 0 };
if ( ! driCheckDriDdxDrmVersions2( "Radeon", if ( ! driCheckDriDdxDrmVersions3( "Radeon",
dri_version, & dri_expected, dri_version, & dri_expected,
ddx_version, & ddx_expected, ddx_version, & ddx_expected,
drm_version, & drm_expected ) ) { drm_version, & drm_expected ) ) {

View File

@ -96,6 +96,8 @@ typedef struct {
unsigned int gart_buffer_offset; /* offset in card memory space */ unsigned int gart_buffer_offset; /* offset in card memory space */
unsigned int gart_texture_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 */ /* Configuration cache with default values for all contexts */
driOptionCache optionCache; driOptionCache optionCache;
} radeonScreenRec, *radeonScreenPtr; } radeonScreenRec, *radeonScreenPtr;

View File

@ -189,46 +189,58 @@ do { \
* manner as the engine. In each case, the linear block address (ba) * 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 * is calculated, and then wired with x and y to produce the final
* memory address. * 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, static GLuint radeon_mba_z32( radeonContextPtr rmesa,
GLint x, GLint y ) GLint x, GLint y )
{ {
GLuint pitch = rmesa->radeonScreen->frontPitch; 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 |= (x & 0x7) << 2; /* a[2..4] = x[0..2] */
address |= (y & 0x3) << 5; /* a[5..6] = y[0..1] */ address |= (y & 0x3) << 5; /* a[5..6] = y[0..1] */
address |= address |=
(((x & 0x10) >> 2) ^ (y & 0x4)) << 5; /* a[7] = x[4] ^ y[2] */ (((x & 0x10) >> 2) ^ (y & 0x4)) << 5; /* a[7] = x[4] ^ y[2] */
address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */ address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */
address |= (y & 0x8) << 7; /* a[10] = y[3] */ address |= (y & 0x8) << 7; /* a[10] = y[3] */
address |= address |=
(((x & 0x8) << 1) ^ (y & 0x10)) << 7; /* a[11] = x[3] ^ y[4] */ (((x & 0x8) << 1) ^ (y & 0x10)) << 7; /* a[11] = x[3] ^ y[4] */
address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */ address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */
return address; return address;
}
} }
static __inline GLuint radeon_mba_z16( radeonContextPtr rmesa, GLint x, GLint y ) static __inline GLuint radeon_mba_z16( radeonContextPtr rmesa, GLint x, GLint y )
{ {
GLuint pitch = rmesa->radeonScreen->frontPitch; 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 |= (x & 0x7) << 1; /* a[1..3] = x[0..2] */
address |= (y & 0x7) << 4; /* a[4..6] = y[0..2] */ address |= (y & 0x7) << 4; /* a[4..6] = y[0..2] */
address |= (x & 0x8) << 4; /* a[7] = x[3] */ address |= (x & 0x8) << 4; /* a[7] = x[3] */
address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */ address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */
address |= (y & 0x8) << 7; /* a[10] = y[3] */ address |= (y & 0x8) << 7; /* a[10] = y[3] */
address |= ((x & 0x10) ^ (y & 0x10)) << 7; /* a[11] = x[4] ^ y[4] */ address |= ((x & 0x10) ^ (y & 0x10)) << 7; /* a[11] = x[4] ^ y[4] */
address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */ address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */
return address; return address;
}
} }

View File

@ -1686,6 +1686,9 @@ static void radeonDrawBuffer( GLcontext *ctx, GLenum mode )
rmesa->radeonScreen->fbLocation) rmesa->radeonScreen->fbLocation)
& RADEON_COLOROFFSET_MASK); & RADEON_COLOROFFSET_MASK);
rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = rmesa->state.color.drawPitch; 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 ) static void radeonReadBuffer( GLcontext *ctx, GLenum mode )

View File

@ -385,6 +385,10 @@ void radeonInitState( radeonContextPtr rmesa )
rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = ((rmesa->state.color.drawPitch & rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = ((rmesa->state.color.drawPitch &
RADEON_COLORPITCH_MASK) | RADEON_COLORPITCH_MASK) |
RADEON_COLOR_ENDIAN_NO_SWAP); 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 | rmesa->hw.set.cmd[SET_SE_CNTL] = (RADEON_FFACE_CULL_CCW |
RADEON_BFACE_SOLID | RADEON_BFACE_SOLID |