(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->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;
}
}

View 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;
}

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_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)

View 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,

View 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;

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)
* 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;
}
}

View 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;
}
}

View 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 |

View 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;
}
}

View 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;

View 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 ) ) {

View 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;

View 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;
}
}

View 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 )

View 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 |