Commit ecd1dcbe authored by Dave Airlie's avatar Dave Airlie

drm: upgrade radeon driver to 1.15

add support for texture micro tiling on radeon/r200. 
Add support for r100 cube maps (since it also requires a version bump).

From: Roland Scheidegger <rscheidegger_lists@hispeed.ch>
Signed-off-by: default avatarDave Airlie <airlied@linux.ie>
parent 9b35a67b
...@@ -146,8 +146,13 @@ ...@@ -146,8 +146,13 @@
#define RADEON_EMIT_PP_TEX_SIZE_2 75 #define RADEON_EMIT_PP_TEX_SIZE_2 75
#define R200_EMIT_RB3D_BLENDCOLOR 76 #define R200_EMIT_RB3D_BLENDCOLOR 76
#define R200_EMIT_TCL_POINT_SPRITE_CNTL 77 #define R200_EMIT_TCL_POINT_SPRITE_CNTL 77
#define RADEON_MAX_STATE_PACKETS 78 #define RADEON_EMIT_PP_CUBIC_FACES_0 78
#define RADEON_EMIT_PP_CUBIC_OFFSETS_T0 79
#define RADEON_EMIT_PP_CUBIC_FACES_1 80
#define RADEON_EMIT_PP_CUBIC_OFFSETS_T1 81
#define RADEON_EMIT_PP_CUBIC_FACES_2 82
#define RADEON_EMIT_PP_CUBIC_OFFSETS_T2 83
#define RADEON_MAX_STATE_PACKETS 84
/* Commands understood by cmd_buffer ioctl. More can be added but /* Commands understood by cmd_buffer ioctl. More can be added but
* obviously these can't be removed or changed: * obviously these can't be removed or changed:
......
...@@ -78,9 +78,11 @@ ...@@ -78,9 +78,11 @@
* - Add hyperz support, add hyperz flags to clear ioctl. * - Add hyperz support, add hyperz flags to clear ioctl.
* 1.14- Add support for color tiling * 1.14- Add support for color tiling
* - Add R100/R200 surface allocation/free support * - Add R100/R200 surface allocation/free support
* 1.15- Add support for texture micro tiling
* - Add support for r100 cube maps
*/ */
#define DRIVER_MAJOR 1 #define DRIVER_MAJOR 1
#define DRIVER_MINOR 14 #define DRIVER_MINOR 15
#define DRIVER_PATCHLEVEL 0 #define DRIVER_PATCHLEVEL 0
#define GET_RING_HEAD(dev_priv) DRM_READ32( (dev_priv)->ring_rptr, 0 ) #define GET_RING_HEAD(dev_priv) DRM_READ32( (dev_priv)->ring_rptr, 0 )
...@@ -795,6 +797,12 @@ extern int radeon_postcleanup( struct drm_device *dev ); ...@@ -795,6 +797,12 @@ extern int radeon_postcleanup( struct drm_device *dev );
#define RADEON_PP_TEX_SIZE_1 0x1d0c #define RADEON_PP_TEX_SIZE_1 0x1d0c
#define RADEON_PP_TEX_SIZE_2 0x1d14 #define RADEON_PP_TEX_SIZE_2 0x1d14
#define RADEON_PP_CUBIC_FACES_0 0x1d24
#define RADEON_PP_CUBIC_FACES_1 0x1d28
#define RADEON_PP_CUBIC_FACES_2 0x1d2c
#define RADEON_PP_CUBIC_OFFSET_T0_0 0x1dd0 /* bits [31:5] */
#define RADEON_PP_CUBIC_OFFSET_T1_0 0x1e00
#define RADEON_PP_CUBIC_OFFSET_T2_0 0x1e14
#define SE_VAP_CNTL__TCL_ENA_MASK 0x00000001 #define SE_VAP_CNTL__TCL_ENA_MASK 0x00000001
#define SE_VAP_CNTL__FORCE_W_TO_ONE_MASK 0x00010000 #define SE_VAP_CNTL__FORCE_W_TO_ONE_MASK 0x00010000
......
...@@ -126,6 +126,22 @@ static __inline__ int radeon_check_and_fixup_packets( drm_radeon_private_t *dev_ ...@@ -126,6 +126,22 @@ static __inline__ int radeon_check_and_fixup_packets( drm_radeon_private_t *dev_
break; break;
} }
case RADEON_EMIT_PP_CUBIC_OFFSETS_T0:
case RADEON_EMIT_PP_CUBIC_OFFSETS_T1:
case RADEON_EMIT_PP_CUBIC_OFFSETS_T2:{
int i;
for (i = 0; i < 5; i++) {
if (radeon_check_and_fixup_offset(dev_priv,
filp_priv,
&data[i])) {
DRM_ERROR
("Invalid R100 cubic texture offset\n");
return DRM_ERR(EINVAL);
}
}
}
break;
case RADEON_EMIT_RB3D_COLORPITCH: case RADEON_EMIT_RB3D_COLORPITCH:
case RADEON_EMIT_RE_LINE_PATTERN: case RADEON_EMIT_RE_LINE_PATTERN:
case RADEON_EMIT_SE_LINE_WIDTH: case RADEON_EMIT_SE_LINE_WIDTH:
...@@ -1482,6 +1498,7 @@ static int radeon_cp_dispatch_texture( DRMFILE filp, ...@@ -1482,6 +1498,7 @@ static int radeon_cp_dispatch_texture( DRMFILE filp,
int size, dwords, tex_width, blit_width; int size, dwords, tex_width, blit_width;
u32 height; u32 height;
int i; int i;
u32 texpitch, microtile;
RING_LOCALS; RING_LOCALS;
DRM_GET_PRIV_WITH_RETURN( filp_priv, filp ); DRM_GET_PRIV_WITH_RETURN( filp_priv, filp );
...@@ -1544,6 +1561,16 @@ static int radeon_cp_dispatch_texture( DRMFILE filp, ...@@ -1544,6 +1561,16 @@ static int radeon_cp_dispatch_texture( DRMFILE filp,
DRM_ERROR( "invalid texture format %d\n", tex->format ); DRM_ERROR( "invalid texture format %d\n", tex->format );
return DRM_ERR(EINVAL); return DRM_ERR(EINVAL);
} }
texpitch = tex->pitch;
if ((texpitch << 22) & RADEON_DST_TILE_MICRO) {
microtile = 1;
if (tex_width < 64) {
texpitch &= ~(RADEON_DST_TILE_MICRO >> 22);
/* we got tiled coordinates, untile them */
image->x *= 2;
}
}
else microtile = 0;
DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width, tex->height, blit_width ); DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width, tex->height, blit_width );
...@@ -1596,7 +1623,7 @@ static int radeon_cp_dispatch_texture( DRMFILE filp, ...@@ -1596,7 +1623,7 @@ static int radeon_cp_dispatch_texture( DRMFILE filp,
RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_CLR_CMP_CNTL_DIS |
RADEON_GMC_WR_MSK_DIS); RADEON_GMC_WR_MSK_DIS);
buffer[2] = (tex->pitch << 22) | (tex->offset >> 10); buffer[2] = (texpitch << 22) | (tex->offset >> 10);
buffer[3] = 0xffffffff; buffer[3] = 0xffffffff;
buffer[4] = 0xffffffff; buffer[4] = 0xffffffff;
buffer[5] = (image->y << 16) | image->x; buffer[5] = (image->y << 16) | image->x;
...@@ -1604,30 +1631,110 @@ static int radeon_cp_dispatch_texture( DRMFILE filp, ...@@ -1604,30 +1631,110 @@ static int radeon_cp_dispatch_texture( DRMFILE filp,
buffer[7] = dwords; buffer[7] = dwords;
buffer += 8; buffer += 8;
if ( tex_width >= 32 ) {
/* Texture image width is larger than the minimum, so we
* can upload it directly. if (microtile) {
*/ /* texture micro tiling in use, minimum texture width is thus 16 bytes.
if ( DRM_COPY_FROM_USER( buffer, data, however, we cannot use blitter directly for texture width < 64 bytes,
dwords * sizeof(u32) ) ) { since minimum tex pitch is 64 bytes and we need this to match
DRM_ERROR( "EFAULT on data, %d dwords\n", the texture width, otherwise the blitter will tile it wrong.
dwords ); Thus, tiling manually in this case. Additionally, need to special
return DRM_ERR(EFAULT); case tex height = 1, since our actual image will have height 2
and we need to ensure we don't read beyond the texture size
from user space. */
if (tex->height == 1) {
if (tex_width >= 64 || tex_width <= 16) {
if (DRM_COPY_FROM_USER(buffer, data,
tex_width * sizeof(u32))) {
DRM_ERROR("EFAULT on pad, %d bytes\n",
tex_width);
return DRM_ERR(EFAULT);
}
} else if (tex_width == 32) {
if (DRM_COPY_FROM_USER(buffer, data, 16)) {
DRM_ERROR("EFAULT on pad, %d bytes\n",
tex_width);
return DRM_ERR(EFAULT);
}
if (DRM_COPY_FROM_USER(buffer + 8, data + 16, 16)) {
DRM_ERROR("EFAULT on pad, %d bytes\n",
tex_width);
return DRM_ERR(EFAULT);
}
}
} else if (tex_width >= 64 || tex_width == 16) {
if (DRM_COPY_FROM_USER(buffer, data,
dwords * sizeof(u32))) {
DRM_ERROR("EFAULT on data, %d dwords\n",
dwords);
return DRM_ERR(EFAULT);
}
} else if (tex_width < 16) {
for (i = 0; i < tex->height; i++) {
if (DRM_COPY_FROM_USER(buffer, data, tex_width)) {
DRM_ERROR("EFAULT on pad, %d bytes\n",
tex_width);
return DRM_ERR(EFAULT);
}
buffer += 4;
data += tex_width;
}
} else if (tex_width == 32) {
/* TODO: make sure this works when not fitting in one buffer
(i.e. 32bytes x 2048...) */
for (i = 0; i < tex->height; i += 2) {
if (DRM_COPY_FROM_USER(buffer, data, 16)) {
DRM_ERROR("EFAULT on pad, %d bytes\n",
tex_width);
return DRM_ERR(EFAULT);
}
data += 16;
if (DRM_COPY_FROM_USER(buffer + 8, data, 16)) {
DRM_ERROR("EFAULT on pad, %d bytes\n",
tex_width);
return DRM_ERR(EFAULT);
}
data += 16;
if (DRM_COPY_FROM_USER(buffer + 4, data, 16)) {
DRM_ERROR("EFAULT on pad, %d bytes\n",
tex_width);
return DRM_ERR(EFAULT);
}
data += 16;
if (DRM_COPY_FROM_USER(buffer + 12, data, 16)) {
DRM_ERROR("EFAULT on pad, %d bytes\n",
tex_width);
return DRM_ERR(EFAULT);
}
data += 16;
buffer += 16;
}
} }
} else { }
/* Texture image width is less than the minimum, so we else {
* need to pad out each image scanline to the minimum if (tex_width >= 32) {
* width. /* Texture image width is larger than the minimum, so we
*/ * can upload it directly.
for ( i = 0 ; i < tex->height ; i++ ) { */
if ( DRM_COPY_FROM_USER( buffer, data, if (DRM_COPY_FROM_USER(buffer, data,
tex_width ) ) { dwords * sizeof(u32))) {
DRM_ERROR( "EFAULT on pad, %d bytes\n", DRM_ERROR("EFAULT on data, %d dwords\n",
tex_width ); dwords);
return DRM_ERR(EFAULT); return DRM_ERR(EFAULT);
} }
buffer += 8; } else {
data += tex_width; /* Texture image width is less than the minimum, so we
* need to pad out each image scanline to the minimum
* width.
*/
for (i = 0 ; i < tex->height ; i++) {
if (DRM_COPY_FROM_USER(buffer, data, tex_width )) {
DRM_ERROR("EFAULT on pad, %d bytes\n", tex_width);
return DRM_ERR(EFAULT);
}
buffer += 8;
data += tex_width;
}
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment