- Fixed polygon stipple. Was still using SubmitPackets...

- Implemented HW-assisted depth span functions. All access to the depth
    buffer is done via the engine, so we don't have to worry about the
    differences between linear and tiled memory.
- Implemented significantly more 3D-friendly static partitioning of
    offscreen memory. 2D still gets enough pixmap cache to be performant.
    For example, 800x600@16bpp texture memory goes from ~3mb to 11.5mb on a
    16mb card.
This commit is contained in:
Gareth Hughes 2000-12-01 15:39:32 +00:00
parent aa1a793f55
commit 7950295132
9 changed files with 530 additions and 50 deletions

View file

@ -37,10 +37,10 @@
#define R128_NAME "r128" #define R128_NAME "r128"
#define R128_DESC "ATI Rage 128" #define R128_DESC "ATI Rage 128"
#define R128_DATE "20001129" #define R128_DATE "20001201"
#define R128_MAJOR 2 #define R128_MAJOR 2
#define R128_MINOR 0 #define R128_MINOR 1
#define R128_PATCHLEVEL 1 #define R128_PATCHLEVEL 0
static drm_device_t r128_device; static drm_device_t r128_device;
drm_ctx_t r128_res_ctx; drm_ctx_t r128_res_ctx;
@ -119,6 +119,8 @@ static drm_ioctl_desc_t r128_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)] = { r128_cce_indices, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)] = { r128_cce_indices, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)] = { r128_cce_blit, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)] = { r128_cce_blit, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_DEPTH)] = { r128_cce_depth, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_PACKET)] = { r128_cce_packet, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_R128_PACKET)] = { r128_cce_packet, 1, 0 },
}; };
#define R128_IOCTL_COUNT DRM_ARRAY_SIZE(r128_ioctls) #define R128_IOCTL_COUNT DRM_ARRAY_SIZE(r128_ioctls)

View file

@ -374,7 +374,9 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t) #define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t)
#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t) #define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t)
#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t) #define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t)
#define DRM_IOCTL_R128_PACKET DRM_IOWR(0x4c, drm_r128_packet_t) #define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4c, drm_r128_depth_t)
#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t)
#define DRM_IOCTL_R128_PACKET DRM_IOWR(0x4e, drm_r128_packet_t)
/* SiS specific ioctls */ /* SiS specific ioctls */
#define SIS_IOCTL_FB_ALLOC DRM_IOWR( 0x44, drm_sis_mem_t) #define SIS_IOCTL_FB_ALLOC DRM_IOWR( 0x44, drm_sis_mem_t)

View file

@ -437,18 +437,13 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
dev_priv->fb_bpp = init->fb_bpp; dev_priv->fb_bpp = init->fb_bpp;
dev_priv->front_offset = init->front_offset; dev_priv->front_offset = init->front_offset;
dev_priv->front_pitch = init->front_pitch; dev_priv->front_pitch = init->front_pitch;
dev_priv->front_x = init->front_x;
dev_priv->front_y = init->front_y;
dev_priv->back_offset = init->back_offset; dev_priv->back_offset = init->back_offset;
dev_priv->back_pitch = init->back_pitch; dev_priv->back_pitch = init->back_pitch;
dev_priv->back_x = init->back_x;
dev_priv->back_y = init->back_y;
dev_priv->depth_bpp = init->depth_bpp; dev_priv->depth_bpp = init->depth_bpp;
dev_priv->depth_offset = init->depth_offset; dev_priv->depth_offset = init->depth_offset;
dev_priv->depth_pitch = init->depth_pitch; dev_priv->depth_pitch = init->depth_pitch;
dev_priv->depth_x = init->depth_x; dev_priv->span_offset = init->span_offset;
dev_priv->depth_y = init->depth_y;
dev_priv->front_pitch_offset_c = (((dev_priv->front_pitch/8) << 21) | dev_priv->front_pitch_offset_c = (((dev_priv->front_pitch/8) << 21) |
(dev_priv->front_offset >> 5)); (dev_priv->front_offset >> 5));
@ -457,6 +452,8 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
dev_priv->depth_pitch_offset_c = (((dev_priv->depth_pitch/8) << 21) | dev_priv->depth_pitch_offset_c = (((dev_priv->depth_pitch/8) << 21) |
(dev_priv->depth_offset >> 5) | (dev_priv->depth_offset >> 5) |
R128_DST_TILE); R128_DST_TILE);
dev_priv->span_pitch_offset_c = (((dev_priv->depth_pitch/8) << 21) |
(dev_priv->span_offset >> 5));
/* FIXME: We want multiple shared areas, including one shared /* FIXME: We want multiple shared areas, including one shared
* only by the X Server and kernel module. * only by the X Server and kernel module.

View file

@ -94,7 +94,7 @@
#define R128_LOCAL_TEX_HEAP 0 #define R128_LOCAL_TEX_HEAP 0
#define R128_AGP_TEX_HEAP 1 #define R128_AGP_TEX_HEAP 1
#define R128_NR_TEX_HEAPS 2 #define R128_NR_TEX_HEAPS 2
#define R128_NR_TEX_REGIONS 16 #define R128_NR_TEX_REGIONS 64
#define R128_LOG_TEX_GRANULARITY 16 #define R128_LOG_TEX_GRANULARITY 16
#define R128_NR_CONTEXT_REGS 12 #define R128_NR_CONTEXT_REGS 12
@ -196,12 +196,10 @@ typedef struct drm_r128_init {
unsigned int fb_bpp; unsigned int fb_bpp;
unsigned int front_offset, front_pitch; unsigned int front_offset, front_pitch;
unsigned int front_x, front_y;
unsigned int back_offset, back_pitch; unsigned int back_offset, back_pitch;
unsigned int back_x, back_y;
unsigned int depth_bpp; unsigned int depth_bpp;
unsigned int depth_offset, depth_pitch; unsigned int depth_offset, depth_pitch;
unsigned int depth_x, depth_y; unsigned int span_offset;
unsigned int fb_offset; unsigned int fb_offset;
unsigned int mmio_offset; unsigned int mmio_offset;
@ -249,6 +247,24 @@ typedef struct drm_r128_blit {
unsigned short width, height; unsigned short width, height;
} drm_r128_blit_t; } drm_r128_blit_t;
typedef struct drm_r128_depth {
enum {
R128_WRITE_SPAN = 0x01,
R128_WRITE_PIXELS = 0x02,
R128_READ_SPAN = 0x03,
R128_READ_PIXELS = 0x04
} func;
int n;
int *x;
int *y;
unsigned int *buffer;
unsigned char *mask;
} drm_r128_depth_t;
typedef struct drm_r128_stipple {
unsigned int *mask;
} drm_r128_stipple_t;
typedef struct drm_r128_packet { typedef struct drm_r128_packet {
unsigned int *buffer; unsigned int *buffer;
int count; int count;

View file

@ -37,10 +37,10 @@
#define R128_NAME "r128" #define R128_NAME "r128"
#define R128_DESC "ATI Rage 128" #define R128_DESC "ATI Rage 128"
#define R128_DATE "20001129" #define R128_DATE "20001201"
#define R128_MAJOR 2 #define R128_MAJOR 2
#define R128_MINOR 0 #define R128_MINOR 1
#define R128_PATCHLEVEL 1 #define R128_PATCHLEVEL 0
static drm_device_t r128_device; static drm_device_t r128_device;
drm_ctx_t r128_res_ctx; drm_ctx_t r128_res_ctx;
@ -119,6 +119,8 @@ static drm_ioctl_desc_t r128_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)] = { r128_cce_indices, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)] = { r128_cce_indices, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)] = { r128_cce_blit, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)] = { r128_cce_blit, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_DEPTH)] = { r128_cce_depth, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_PACKET)] = { r128_cce_packet, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_R128_PACKET)] = { r128_cce_packet, 1, 0 },
}; };
#define R128_IOCTL_COUNT DRM_ARRAY_SIZE(r128_ioctls) #define R128_IOCTL_COUNT DRM_ARRAY_SIZE(r128_ioctls)

View file

@ -73,22 +73,18 @@ typedef struct drm_r128_private {
unsigned int fb_bpp; unsigned int fb_bpp;
unsigned int front_offset; unsigned int front_offset;
unsigned int front_pitch; unsigned int front_pitch;
unsigned int front_x;
unsigned int front_y;
unsigned int back_offset; unsigned int back_offset;
unsigned int back_pitch; unsigned int back_pitch;
unsigned int back_x;
unsigned int back_y;
unsigned int depth_bpp; unsigned int depth_bpp;
unsigned int depth_offset; unsigned int depth_offset;
unsigned int depth_pitch; unsigned int depth_pitch;
unsigned int depth_x; unsigned int span_offset;
unsigned int depth_y;
u32 front_pitch_offset_c; u32 front_pitch_offset_c;
u32 back_pitch_offset_c; u32 back_pitch_offset_c;
u32 depth_pitch_offset_c; u32 depth_pitch_offset_c;
u32 span_pitch_offset_c;
drm_map_t *sarea; drm_map_t *sarea;
drm_map_t *fb; drm_map_t *fb;
@ -154,6 +150,10 @@ extern int r128_cce_indices( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg ); unsigned int cmd, unsigned long arg );
extern int r128_cce_blit( struct inode *inode, struct file *filp, extern int r128_cce_blit( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg ); unsigned int cmd, unsigned long arg );
extern int r128_cce_depth( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int r128_cce_stipple( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
/* r128_bufs.c */ /* r128_bufs.c */
extern int r128_addbufs(struct inode *inode, struct file *filp, extern int r128_addbufs(struct inode *inode, struct file *filp,
@ -208,6 +208,7 @@ extern int r128_context_switch_complete(drm_device_t *dev, int new);
#define R128_AUX3_SC_TOP 0x168c #define R128_AUX3_SC_TOP 0x168c
#define R128_AUX3_SC_BOTTOM 0x1690 #define R128_AUX3_SC_BOTTOM 0x1690
#define R128_BRUSH_DATA0 0x1480
#define R128_BUS_CNTL 0x0030 #define R128_BUS_CNTL 0x0030
# define R128_BUS_MASTER_DIS (1 << 6) # define R128_BUS_MASTER_DIS (1 << 6)
@ -425,7 +426,7 @@ extern int R128_READ_PLL(drm_device_t *dev, int addr);
#define R128_VERBOSE 0 #define R128_VERBOSE 0
#define RING_LOCALS int write; unsigned int mask; volatile u32 *ring; #define RING_LOCALS int write; unsigned int tail_mask; volatile u32 *ring;
#define BEGIN_RING( n ) do { \ #define BEGIN_RING( n ) do { \
if ( R128_VERBOSE ) { \ if ( R128_VERBOSE ) { \
@ -438,7 +439,7 @@ extern int R128_READ_PLL(drm_device_t *dev, int addr);
dev_priv->ring.space -= n * sizeof(u32); \ dev_priv->ring.space -= n * sizeof(u32); \
ring = dev_priv->ring.start; \ ring = dev_priv->ring.start; \
write = dev_priv->ring.tail; \ write = dev_priv->ring.tail; \
mask = dev_priv->ring.tail_mask; \ tail_mask = dev_priv->ring.tail_mask; \
} while (0) } while (0)
#define ADVANCE_RING() do { \ #define ADVANCE_RING() do { \
@ -457,7 +458,7 @@ extern int R128_READ_PLL(drm_device_t *dev, int addr);
(unsigned int)(x), write ); \ (unsigned int)(x), write ); \
} \ } \
ring[write++] = x; \ ring[write++] = x; \
write &= mask; \ write &= tail_mask; \
} while (0) } while (0)
#define R128_PERFORMANCE_BOXES 0 #define R128_PERFORMANCE_BOXES 0

View file

@ -534,10 +534,10 @@ static void r128_cce_dispatch_swap( drm_device_t *dev )
OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL
| R128_GMC_DST_PITCH_OFFSET_CNTL | R128_GMC_DST_PITCH_OFFSET_CNTL
| R128_GMC_BRUSH_NONE | R128_GMC_BRUSH_NONE
| R128_GMC_SRC_DATATYPE_COLOR
| R128_DP_SRC_SOURCE_MEMORY
| fb_bpp | fb_bpp
| R128_GMC_SRC_DATATYPE_COLOR
| R128_ROP3_S | R128_ROP3_S
| R128_DP_SRC_SOURCE_MEMORY
| R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_CLR_CMP_CNTL_DIS
| R128_GMC_AUX_CLIP_DIS | R128_GMC_AUX_CLIP_DIS
| R128_GMC_WR_MSK_DIS ); | R128_GMC_WR_MSK_DIS );
@ -550,12 +550,12 @@ static void r128_cce_dispatch_swap( drm_device_t *dev )
OUT_RING( (x << 16) | y ); OUT_RING( (x << 16) | y );
OUT_RING( (w << 16) | h ); OUT_RING( (w << 16) | h );
#else #else
OUT_RING( dev_priv->depth_pitch_offset_c & ~R128_DST_TILE ); OUT_RING( dev_priv->depth_pitch_offset_c /*& ~R128_DST_TILE*/ );
OUT_RING( dev_priv->front_pitch_offset_c ); OUT_RING( dev_priv->front_pitch_offset_c );
OUT_RING( (0 << 16) | 0 ); OUT_RING( (0 << 16) | 0 );
OUT_RING( (0 << 16) | 0 ); OUT_RING( (0 << 16) | 0 );
OUT_RING( (1024 << 16) | 768 ); OUT_RING( (800 << 16) | 600 );
#endif #endif
ADVANCE_RING(); ADVANCE_RING();
@ -581,9 +581,7 @@ static void r128_cce_dispatch_vertex( drm_device_t *dev,
drm_r128_private_t *dev_priv = dev->dev_private; drm_r128_private_t *dev_priv = dev->dev_private;
drm_r128_buf_priv_t *buf_priv = buf->dev_private; drm_r128_buf_priv_t *buf_priv = buf->dev_private;
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
int vertsize = sarea_priv->vertsize;
int format = sarea_priv->vc_format; int format = sarea_priv->vc_format;
int index = buf->idx;
int offset = dev_priv->buffers->offset + buf->offset - dev->agp->base; int offset = dev_priv->buffers->offset + buf->offset - dev->agp->base;
int size = buf->used; int size = buf->used;
int prim = buf_priv->prim; int prim = buf_priv->prim;
@ -691,21 +689,6 @@ static void r128_cce_dispatch_indirect( drm_device_t *dev,
data[dwords++] = R128_CCE_PACKET2; data[dwords++] = R128_CCE_PACKET2;
} }
DRM_DEBUG( "indirect: offset=0x%x dwords=%d\n",
offset, dwords );
if ( 0 ) {
u32 *data = (u32 *)
((char *)dev_priv->buffers->handle
+ buf->offset + start);
int i;
DRM_INFO( "data = %p\n", data );
for ( i = 0 ; i < dwords ; i++ ) {
DRM_INFO( "data[0x%x] = 0x%08x\n",
i, data[i] );
}
}
buf_priv->dispatched = 1; buf_priv->dispatched = 1;
/* Fire off the indirect buffer */ /* Fire off the indirect buffer */
@ -941,7 +924,422 @@ static int r128_cce_dispatch_blit( drm_device_t *dev,
/* ================================================================ /* ================================================================
* * Tiled depth buffer management
*/
static int r128_cce_dispatch_write_span( drm_device_t *dev,
drm_r128_depth_t *depth )
{
drm_r128_private_t *dev_priv = dev->dev_private;
int count, x, y;
u32 *buffer;
u8 *mask;
u32 depth_bpp;
int i;
RING_LOCALS;
DRM_DEBUG( "%s\n", __FUNCTION__ );
r128_update_ring_snapshot( dev_priv );
switch ( dev_priv->depth_bpp ) {
case 16:
depth_bpp = R128_GMC_DST_16BPP;
break;
case 24:
depth_bpp = R128_GMC_DST_32BPP;
break;
case 32:
depth_bpp = R128_GMC_DST_32BPP;
break;
default:
return -EINVAL;
}
count = depth->n;
if ( copy_from_user( &x, depth->x, sizeof(x) ) ) {
return -EFAULT;
}
if ( copy_from_user( &y, depth->y, sizeof(y) ) ) {
return -EFAULT;
}
buffer = kmalloc( depth->n * sizeof(u32), 0 );
if ( buffer == NULL )
return -ENOMEM;
if ( copy_from_user( buffer, depth->buffer,
depth->n * sizeof(u32) ) ) {
kfree( buffer );
return -EFAULT;
}
if ( depth->mask ) {
mask = kmalloc( depth->n * sizeof(u8), 0 );
if ( mask == NULL ) {
kfree( buffer );
return -ENOMEM;
}
if ( copy_from_user( mask, depth->mask,
depth->n * sizeof(u8) ) ) {
kfree( buffer );
kfree( mask );
return -EFAULT;
}
for ( i = 0 ; i < count ; i++, x++ ) {
if ( mask[i] ) {
BEGIN_RING( 6 );
OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI,
4 ) );
OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
| R128_GMC_BRUSH_SOLID_COLOR
| depth_bpp
| R128_GMC_SRC_DATATYPE_COLOR
| R128_ROP3_P
| R128_GMC_CLR_CMP_CNTL_DIS
| R128_GMC_WR_MSK_DIS );
OUT_RING( dev_priv->depth_pitch_offset_c );
OUT_RING( buffer[i] );
OUT_RING( (x << 16) | y );
OUT_RING( (1 << 16) | 1 );
ADVANCE_RING();
}
}
kfree( mask );
} else {
for ( i = 0 ; i < count ; i++, x++ ) {
BEGIN_RING( 6 );
OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
| R128_GMC_BRUSH_SOLID_COLOR
| depth_bpp
| R128_GMC_SRC_DATATYPE_COLOR
| R128_ROP3_P
| R128_GMC_CLR_CMP_CNTL_DIS
| R128_GMC_WR_MSK_DIS );
OUT_RING( dev_priv->depth_pitch_offset_c );
OUT_RING( buffer[i] );
OUT_RING( (x << 16) | y );
OUT_RING( (1 << 16) | 1 );
ADVANCE_RING();
}
}
kfree( buffer );
return 0;
}
static int r128_cce_dispatch_write_pixels( drm_device_t *dev,
drm_r128_depth_t *depth )
{
drm_r128_private_t *dev_priv = dev->dev_private;
int count, *x, *y;
u32 *buffer;
u8 *mask;
u32 depth_bpp;
int i;
RING_LOCALS;
DRM_DEBUG( "%s\n", __FUNCTION__ );
r128_update_ring_snapshot( dev_priv );
switch ( dev_priv->depth_bpp ) {
case 16:
depth_bpp = R128_GMC_DST_16BPP;
break;
case 24:
depth_bpp = R128_GMC_DST_32BPP;
break;
case 32:
depth_bpp = R128_GMC_DST_32BPP;
break;
default:
return -EINVAL;
}
count = depth->n;
x = kmalloc( count * sizeof(*x), 0 );
if ( x == NULL ) {
return -ENOMEM;
}
y = kmalloc( count * sizeof(*y), 0 );
if ( y == NULL ) {
kfree( x );
return -ENOMEM;
}
if ( copy_from_user( x, depth->x, count * sizeof(int) ) ) {
kfree( x );
kfree( y );
return -EFAULT;
}
if ( copy_from_user( y, depth->y, count * sizeof(int) ) ) {
kfree( x );
kfree( y );
return -EFAULT;
}
buffer = kmalloc( depth->n * sizeof(u32), 0 );
if ( buffer == NULL ) {
kfree( x );
kfree( y );
return -ENOMEM;
}
if ( copy_from_user( buffer, depth->buffer,
depth->n * sizeof(u32) ) ) {
kfree( x );
kfree( y );
kfree( buffer );
return -EFAULT;
}
if ( depth->mask ) {
mask = kmalloc( depth->n * sizeof(u8), 0 );
if ( mask == NULL ) {
kfree( x );
kfree( y );
kfree( buffer );
return -ENOMEM;
}
if ( copy_from_user( mask, depth->mask,
depth->n * sizeof(u8) ) ) {
kfree( x );
kfree( y );
kfree( buffer );
kfree( mask );
return -EFAULT;
}
for ( i = 0 ; i < count ; i++ ) {
if ( mask[i] ) {
BEGIN_RING( 6 );
OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI,
4 ) );
OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
| R128_GMC_BRUSH_SOLID_COLOR
| depth_bpp
| R128_GMC_SRC_DATATYPE_COLOR
| R128_ROP3_P
| R128_GMC_CLR_CMP_CNTL_DIS
| R128_GMC_WR_MSK_DIS );
OUT_RING( dev_priv->depth_pitch_offset_c );
OUT_RING( buffer[i] );
OUT_RING( (x[i] << 16) | y[i] );
OUT_RING( (1 << 16) | 1 );
ADVANCE_RING();
}
}
kfree( mask );
} else {
for ( i = 0 ; i < count ; i++ ) {
BEGIN_RING( 6 );
OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) );
OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL
| R128_GMC_BRUSH_SOLID_COLOR
| depth_bpp
| R128_GMC_SRC_DATATYPE_COLOR
| R128_ROP3_P
| R128_GMC_CLR_CMP_CNTL_DIS
| R128_GMC_WR_MSK_DIS );
OUT_RING( dev_priv->depth_pitch_offset_c );
OUT_RING( buffer[i] );
OUT_RING( (x[i] << 16) | y[i] );
OUT_RING( (1 << 16) | 1 );
ADVANCE_RING();
}
}
kfree( x );
kfree( y );
kfree( buffer );
return 0;
}
static int r128_cce_dispatch_read_span( drm_device_t *dev,
drm_r128_depth_t *depth )
{
drm_r128_private_t *dev_priv = dev->dev_private;
int count, x, y;
u32 depth_bpp;
RING_LOCALS;
DRM_DEBUG( "%s\n", __FUNCTION__ );
r128_update_ring_snapshot( dev_priv );
switch ( dev_priv->depth_bpp ) {
case 16:
depth_bpp = R128_GMC_DST_16BPP;
break;
case 24:
depth_bpp = R128_GMC_DST_32BPP;
break;
case 32:
depth_bpp = R128_GMC_DST_32BPP;
break;
default:
return -EINVAL;
}
count = depth->n;
if ( copy_from_user( &x, depth->x, sizeof(x) ) ) {
return -EFAULT;
}
if ( copy_from_user( &y, depth->y, sizeof(y) ) ) {
return -EFAULT;
}
BEGIN_RING( 7 );
OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL
| R128_GMC_DST_PITCH_OFFSET_CNTL
| R128_GMC_BRUSH_NONE
| depth_bpp
| R128_GMC_SRC_DATATYPE_COLOR
| R128_ROP3_S
| R128_DP_SRC_SOURCE_MEMORY
| R128_GMC_CLR_CMP_CNTL_DIS
| R128_GMC_WR_MSK_DIS );
OUT_RING( dev_priv->depth_pitch_offset_c );
OUT_RING( dev_priv->span_pitch_offset_c );
OUT_RING( (x << 16) | y );
OUT_RING( (0 << 16) | 0 );
OUT_RING( (count << 16) | 1 );
ADVANCE_RING();
return 0;
}
static int r128_cce_dispatch_read_pixels( drm_device_t *dev,
drm_r128_depth_t *depth )
{
drm_r128_private_t *dev_priv = dev->dev_private;
int count, *x, *y;
u32 depth_bpp;
int i;
RING_LOCALS;
DRM_DEBUG( "%s\n", __FUNCTION__ );
r128_update_ring_snapshot( dev_priv );
switch ( dev_priv->depth_bpp ) {
case 16:
depth_bpp = R128_GMC_DST_16BPP;
break;
case 24:
depth_bpp = R128_GMC_DST_32BPP;
break;
case 32:
depth_bpp = R128_GMC_DST_32BPP;
break;
default:
return -EINVAL;
}
count = depth->n;
if ( count > dev_priv->depth_pitch ) {
count = dev_priv->depth_pitch;
}
x = kmalloc( count * sizeof(*x), 0 );
if ( x == NULL ) {
return -ENOMEM;
}
y = kmalloc( count * sizeof(*y), 0 );
if ( y == NULL ) {
kfree( x );
return -ENOMEM;
}
if ( copy_from_user( x, depth->x, count * sizeof(int) ) ) {
kfree( x );
kfree( y );
return -EFAULT;
}
if ( copy_from_user( y, depth->y, count * sizeof(int) ) ) {
kfree( x );
kfree( y );
return -EFAULT;
}
for ( i = 0 ; i < count ; i++ ) {
BEGIN_RING( 7 );
OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) );
OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL
| R128_GMC_DST_PITCH_OFFSET_CNTL
| R128_GMC_BRUSH_NONE
| depth_bpp
| R128_GMC_SRC_DATATYPE_COLOR
| R128_ROP3_S
| R128_DP_SRC_SOURCE_MEMORY
| R128_GMC_CLR_CMP_CNTL_DIS
| R128_GMC_WR_MSK_DIS );
OUT_RING( dev_priv->depth_pitch_offset_c );
OUT_RING( dev_priv->span_pitch_offset_c );
OUT_RING( (x[i] << 16) | y[i] );
OUT_RING( (i << 16) | 0 );
OUT_RING( (1 << 16) | 1 );
ADVANCE_RING();
}
kfree( x );
kfree( y );
return 0;
}
/* ================================================================
* Polygon stipple
*/
static void r128_cce_dispatch_stipple( drm_device_t *dev, u32 *stipple )
{
drm_r128_private_t *dev_priv = dev->dev_private;
int i;
RING_LOCALS;
DRM_DEBUG( "%s\n", __FUNCTION__ );
r128_update_ring_snapshot( dev_priv );
BEGIN_RING( 33 );
OUT_RING( CCE_PACKET0( R128_BRUSH_DATA0, 31 ) );
for ( i = 0 ; i < 32 ; i++ ) {
OUT_RING( stipple[i] );
}
ADVANCE_RING();
}
/* ================================================================
* IOCTL functions
*/ */
int r128_cce_clear( struct inode *inode, struct file *filp, int r128_cce_clear( struct inode *inode, struct file *filp,
@ -1172,3 +1570,61 @@ int r128_cce_blit( struct inode *inode, struct file *filp,
return r128_cce_dispatch_blit( dev, &blit ); return r128_cce_dispatch_blit( dev, &blit );
} }
int r128_cce_depth( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_r128_depth_t depth;
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
dev->lock.pid != current->pid ) {
DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
return -EINVAL;
}
if ( copy_from_user( &depth, (drm_r128_depth_t *)arg,
sizeof(depth) ) )
return -EFAULT;
switch ( depth.func ) {
case R128_WRITE_SPAN:
return r128_cce_dispatch_write_span( dev, &depth );
case R128_WRITE_PIXELS:
return r128_cce_dispatch_write_pixels( dev, &depth );
case R128_READ_SPAN:
return r128_cce_dispatch_read_span( dev, &depth );
case R128_READ_PIXELS:
return r128_cce_dispatch_read_pixels( dev, &depth );
}
return -EINVAL;
}
int r128_cce_stipple( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_r128_stipple_t stipple;
u32 mask[32];
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
dev->lock.pid != current->pid ) {
DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
return -EINVAL;
}
if ( copy_from_user( &stipple, (drm_r128_stipple_t *)arg,
sizeof(stipple) ) )
return -EFAULT;
if ( copy_from_user( &mask, stipple.mask,
32 * sizeof(u32) ) )
return -EFAULT;
r128_cce_dispatch_stipple( dev, mask );
return 0;
}

View file

@ -374,7 +374,9 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t) #define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t)
#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t) #define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t)
#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t) #define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t)
#define DRM_IOCTL_R128_PACKET DRM_IOWR(0x4c, drm_r128_packet_t) #define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4c, drm_r128_depth_t)
#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t)
#define DRM_IOCTL_R128_PACKET DRM_IOWR(0x4e, drm_r128_packet_t)
/* SiS specific ioctls */ /* SiS specific ioctls */
#define SIS_IOCTL_FB_ALLOC DRM_IOWR( 0x44, drm_sis_mem_t) #define SIS_IOCTL_FB_ALLOC DRM_IOWR( 0x44, drm_sis_mem_t)

View file

@ -374,7 +374,9 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t) #define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t)
#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t) #define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t)
#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t) #define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t)
#define DRM_IOCTL_R128_PACKET DRM_IOWR(0x4c, drm_r128_packet_t) #define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4c, drm_r128_depth_t)
#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t)
#define DRM_IOCTL_R128_PACKET DRM_IOWR(0x4e, drm_r128_packet_t)
/* SiS specific ioctls */ /* SiS specific ioctls */
#define SIS_IOCTL_FB_ALLOC DRM_IOWR( 0x44, drm_sis_mem_t) #define SIS_IOCTL_FB_ALLOC DRM_IOWR( 0x44, drm_sis_mem_t)