Latest development work. Should be reasonably stable with the DRIScreenInit

locking fix. Usual caveats apply to using development code.
Includes:
- ctx->Texture.Enabled to ctx->Texture.ReallyEnabled fix
- More useful information in GL_RENDERER string
- More indirect buffer support work
This commit is contained in:
Gareth Hughes 2000-10-20 00:48:07 +00:00
parent 9b1f5e1d08
commit 05ef8effbf
9 changed files with 290 additions and 22 deletions

View file

@ -37,7 +37,7 @@
#define R128_NAME "r128"
#define R128_DESC "ATI Rage 128"
#define R128_DATE "20001016"
#define R128_DATE "20001019"
#define R128_MAJOR 1
#define R128_MINOR 1
#define R128_PATCHLEVEL 0
@ -117,6 +117,7 @@ static drm_ioctl_desc_t r128_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)] = { r128_cce_swap, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)] = { r128_cce_clear, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)] = { r128_cce_blit, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_PACKET)] = { r128_cce_packet, 1, 0 },
};
#define R128_IOCTL_COUNT DRM_ARRAY_SIZE(r128_ioctls)

View file

@ -371,6 +371,7 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_R128_SWAP DRM_IO( 0x46)
#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x47, drm_r128_clear_t)
#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x48, drm_r128_vertex_t)
#define DRM_IOCTL_R128_PACKET DRM_IOWR(0x49, drm_r128_packet_t)
#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x49, drm_r128_blit_t)
#define DRM_IOCTL_R128_PACKET DRM_IOWR(0x50, drm_r128_packet_t)
#endif

View file

@ -491,7 +491,8 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init )
R128_WRITE( R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame );
dev_priv->sarea_priv->last_dispatch = 0;
R128_WRITE( R128_LAST_VB_REG, dev_priv->sarea_priv->last_dispatch );
R128_WRITE( R128_LAST_DISPATCH_REG,
dev_priv->sarea_priv->last_dispatch );
r128_cce_init_ring_buffer( dev );
r128_cce_load_microcode( dev_priv );
@ -732,11 +733,12 @@ drm_buf_t *r128_freelist_get( drm_device_t *dev )
for ( i = 0 ; i < dma->buf_count ; i++ ) {
buf = dma->buflist[i];
buf_priv = buf->dev_private;
if ( buf->pid == 0 ) return buf;
if ( buf->pid == 0 )
return buf;
}
for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) {
u32 done_age = R128_READ( R128_LAST_VB_REG );
u32 done_age = R128_READ( R128_LAST_DISPATCH_REG );
for ( i = 0 ; i < dma->buf_count ; i++ ) {
buf = dma->buflist[i];
@ -752,7 +754,7 @@ drm_buf_t *r128_freelist_get( drm_device_t *dev )
udelay( 1 );
}
DRM_ERROR( "%s: returning NULL!\n", __FUNCTION__ );
DRM_ERROR( "returning NULL!\n" );
return NULL;
}
@ -1152,7 +1154,7 @@ static int r128_cce_get_buffers( drm_device_t *dev, drm_dma_t *d )
for ( i = d->granted_count ; i < d->request_count ; i++ ) {
buf = r128_freelist_get( dev );
if ( !buf ) break;
if ( !buf ) return -EAGAIN;
buf->pid = current->pid;

View file

@ -58,6 +58,14 @@
#define R128_BACK 0x2
#define R128_DEPTH 0x4
/* Vertex/indirect buffer size
*/
#define R128_BUFFER_SIZE 16384
/* 2048x2048 @ 32bpp texture requires this many indirect buffers
*/
#define R128_MAX_BLIT_BUFFERS 256
/* Keep these small for testing.
*/
#define R128_NR_SAREA_CLIPRECTS 12
@ -195,11 +203,26 @@ typedef struct drm_r128_clear {
} drm_r128_clear_t;
typedef struct drm_r128_vertex {
int index; /* Index of vertex buffer */
int idx; /* Index of vertex buffer */
int used; /* Amount of buffer used */
int discard; /* Client finished with buffer? */
} drm_r128_vertex_t;
typedef struct drm_r128_blit_rect {
int index;
unsigned short x, y;
unsigned short width, height;
int padding;
} drm_r128_blit_rect_t;
typedef struct drm_r128_blit {
int pitch;
int offset;
int format;
drm_r128_blit_rect_t *rects;
int count;
} drm_r128_blit_t;
typedef struct drm_r128_packet {
unsigned int *buffer;
int count;

View file

@ -37,7 +37,7 @@
#define R128_NAME "r128"
#define R128_DESC "ATI Rage 128"
#define R128_DATE "20001016"
#define R128_DATE "20001019"
#define R128_MAJOR 1
#define R128_MINOR 1
#define R128_PATCHLEVEL 0
@ -117,6 +117,7 @@ static drm_ioctl_desc_t r128_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)] = { r128_cce_swap, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)] = { r128_cce_clear, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)] = { r128_cce_blit, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_R128_PACKET)] = { r128_cce_packet, 1, 0 },
};
#define R128_IOCTL_COUNT DRM_ARRAY_SIZE(r128_ioctls)

View file

@ -100,6 +100,20 @@ typedef struct drm_r128_buf_priv {
drm_r128_freelist_t *list_entry;
} drm_r128_buf_priv_t;
#define R128_BLIT_PACKET_DATA_SIZE ((R128_BUFFER_SIZE / sizeof(u32)) - 8)
typedef struct drm_r128_blit_packet {
u32 header;
u32 gui_master_cntl;
u32 dst_pitch_offset;
u32 fg_color;
u32 bg_color;
u16 x, y; /* HACK: endian specific */
u16 width, height;
u32 dwords;
u32 data[R128_BLIT_PACKET_DATA_SIZE];
} drm_r128_blit_packet_t;
/* r128_drv.c */
extern int r128_version( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
@ -143,6 +157,8 @@ extern int r128_cce_swap( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int r128_cce_vertex( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int r128_cce_blit( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
/* r128_bufs.c */
extern int r128_addbufs(struct inode *inode, struct file *filp,
@ -207,11 +223,14 @@ extern int r128_context_switch_complete(drm_device_t *dev, int new);
#define R128_CONSTANT_COLOR_C 0x1d34
#define R128_DP_GUI_MASTER_CNTL 0x146c
# define R128_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0)
# define R128_GMC_DST_PITCH_OFFSET_CNTL (1 << 1)
# define R128_GMC_BRUSH_SOLID_COLOR (13 << 4)
# define R128_GMC_BRUSH_NONE (15 << 4)
# define R128_GMC_DST_16BPP (4 << 8)
# define R128_GMC_DST_24BPP (5 << 8)
# define R128_GMC_DST_32BPP (6 << 8)
# define R128_GMC_DST_DATATYPE_SHIFT 8
# define R128_GMC_SRC_DATATYPE_COLOR (3 << 12)
# define R128_DP_SRC_SOURCE_MEMORY (2 << 24)
# define R128_DP_SRC_SOURCE_HOST_DATA (3 << 24)
@ -242,7 +261,10 @@ extern int r128_context_switch_complete(drm_device_t *dev, int new);
# define R128_FORCE_PIPE3D_CP (1 << 17)
# define R128_FORCE_RCP (1 << 18)
#define R128_PC_GUI_CTLSTAT 0x1748
#define R128_PC_NGUI_CTLSTAT 0x0184
# define R128_PC_FLUSH_GUI (3 << 0)
# define R128_PC_RI_GUI (1 << 2)
# define R128_PC_FLUSH_ALL 0x00ff
# define R128_PC_BUSY (1 << 31)
@ -289,6 +311,9 @@ extern int r128_context_switch_complete(drm_device_t *dev, int new);
#define R128_PM4_VC_FPU_SETUP 0x071c
#define R128_PM4_IW_INDOFF 0x0738
#define R128_PM4_IW_INDSIZE 0x073c
#define R128_PM4_STAT 0x07b8
# define R128_PM4_FIFOCNT_MASK 0x0fff
# define R128_PM4_BUSY (1 << 16)
@ -337,6 +362,15 @@ extern int r128_context_switch_complete(drm_device_t *dev, int new);
#define R128_CCE_VC_CNTL_PRIM_WALK_RING 0x00000030
#define R128_CCE_VC_CNTL_NUM_SHIFT 16
#define R128_DATATYPE_CI8 2
#define R128_DATATYPE_ARGB1555 3
#define R128_DATATYPE_RGB565 4
#define R128_DATATYPE_RGB888 5
#define R128_DATATYPE_ARGB8888 6
#define R128_DATATYPE_RGB332 7
#define R128_DATATYPE_RGB8 9
#define R128_DATATYPE_ARGB4444 15
/* Constants */
#define R128_AGP_OFFSET 0x02000000
@ -348,7 +382,7 @@ extern int r128_context_switch_complete(drm_device_t *dev, int new);
#define R128_MAX_USEC_TIMEOUT 100000 /* 100 ms */
#define R128_LAST_FRAME_REG R128_GUI_SCRATCH_REG0
#define R128_LAST_VB_REG R128_GUI_SCRATCH_REG1
#define R128_LAST_DISPATCH_REG R128_GUI_SCRATCH_REG1
#define R128_MAX_VB_AGE 0xffffffff

View file

@ -558,19 +558,18 @@ static void r128_cce_dispatch_vertex( drm_device_t *dev,
}
if ( buf_priv->discard ) {
buf_priv->age = dev_priv->sarea_priv->last_dispatch;
/* Emit the vertex buffer age */
BEGIN_RING( 2 );
OUT_RING( CCE_PACKET0( R128_LAST_VB_REG, 0 ) );
OUT_RING( dev_priv->sarea_priv->last_dispatch );
OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) );
OUT_RING( buf_priv->age );
ADVANCE_RING();
buf->pending = 1;
/* FIXME: Check dispatched field */
buf_priv->dispatched = 0;
buf_priv->age = dev_priv->sarea_priv->last_dispatch;
}
dev_priv->sarea_priv->last_dispatch++;
@ -586,6 +585,175 @@ static void r128_cce_dispatch_vertex( drm_device_t *dev,
}
static void r128_cce_dispatch_indirect( drm_device_t *dev, drm_buf_t *buf )
{
drm_r128_private_t *dev_priv = dev->dev_private;
drm_r128_buf_priv_t *buf_priv = buf->dev_private;
int offset = dev_priv->buffers->offset + buf->offset - dev->agp->base;
int size = ((buf->used / sizeof(u32)) + 1) & ~0x1;
RING_LOCALS;
DRM_DEBUG( "%s\n", __FUNCTION__ );
r128_update_ring_snapshot( dev_priv );
if ( buf->used ) {
DRM_DEBUG( "%s: offset=0x%x size=%d used=%d\n",
__FUNCTION__, offset, size, buf->used );
buf_priv->dispatched = 1;
/* Fire off the indirect buffer */
BEGIN_RING( 3 );
OUT_RING( CCE_PACKET0( R128_PM4_IW_INDOFF, 1 ) );
OUT_RING( offset );
OUT_RING( size );
ADVANCE_RING();
}
if ( buf_priv->discard ) {
buf_priv->age = dev_priv->sarea_priv->last_dispatch;
/* Emit the indirect buffer age */
BEGIN_RING( 2 );
OUT_RING( CCE_PACKET0( R128_LAST_DISPATCH_REG, 0 ) );
OUT_RING( buf_priv->age );
ADVANCE_RING();
buf->pending = 1;
/* FIXME: Check dispatched field */
buf_priv->dispatched = 0;
}
dev_priv->sarea_priv->last_dispatch++;
#if 0
if ( dev_priv->submit_age == R128_MAX_VB_AGE ) {
ret = r128_do_cce_idle( dev_priv );
if ( ret < 0 ) return ret;
dev_priv->submit_age = 0;
r128_freelist_reset( dev );
}
#endif
}
static int r128_cce_dispatch_blit( drm_device_t *dev,
int offset, int pitch, int format,
drm_r128_blit_rect_t *rects, int count )
{
drm_r128_private_t *dev_priv = dev->dev_private;
drm_device_dma_t *dma = dev->dma;
drm_buf_t *buf;
drm_r128_buf_priv_t *buf_priv;
drm_r128_blit_rect_t *rect;
drm_r128_blit_packet_t *blit;
int dword_shift, dwords;
int i;
RING_LOCALS;
DRM_DEBUG( "%s\n", __FUNCTION__ );
switch ( format ) {
case R128_DATATYPE_ARGB1555:
case R128_DATATYPE_RGB565:
case R128_DATATYPE_ARGB4444:
dword_shift = 1;
break;
case R128_DATATYPE_ARGB8888:
dword_shift = 0;
break;
default:
DRM_ERROR( "invalid blit format %d\n", format );
return -EINVAL;
}
/* Flush the pixel cache, and mark the contents as Read Invalid.
* This ensures no pixel data gets mixed up with the texture
* data from the host data blit, otherwise part of the texture
* image may be corrupted.
*/
BEGIN_RING( 2 );
OUT_RING( CCE_PACKET0( R128_PC_GUI_CTLSTAT, 0 ) );
OUT_RING( R128_PC_RI_GUI | R128_PC_FLUSH_GUI );
ADVANCE_RING();
/* Dispatch each of the indirect buffers.
*/
for ( i = 0 ; i < count ; i++ ) {
rect = &rects[i];
buf = dma->buflist[rect->index];
buf_priv = buf->dev_private;
if ( buf->pid != current->pid ) {
DRM_ERROR( "process %d using buffer owned by %d\n",
current->pid, buf->pid );
return -EINVAL;
}
if ( buf->pending ) {
DRM_ERROR( "sending pending buffer %d\n",
rect->index );
return -EINVAL;
}
buf_priv->discard = 1;
dwords = (rect->width * rect->height) >> dword_shift;
blit = (drm_r128_blit_packet_t *)
((char *)dev_priv->buffers->handle + buf->offset);
blit->header = CCE_PACKET3( R128_CNTL_HOSTDATA_BLT,
dwords + 6 );
blit->gui_master_cntl = ( R128_GMC_DST_PITCH_OFFSET_CNTL
| R128_GMC_BRUSH_NONE
| (format << 8)
| R128_GMC_SRC_DATATYPE_COLOR
| R128_ROP3_S
| R128_DP_SRC_SOURCE_HOST_DATA
| R128_GMC_CLR_CMP_CNTL_DIS
| R128_GMC_AUX_CLIP_DIS
| R128_GMC_WR_MSK_DIS );
blit->dst_pitch_offset = (pitch << 21) | (offset >> 5);
blit->fg_color = 0xffffffff;
blit->bg_color = 0xffffffff;
blit->x = rect->x;
blit->y = rect->y;
blit->width = rect->width;
blit->height = rect->height;
blit->dwords = dwords;
/* FIXME: This should really go in the function call...
*/
if ( dwords & 1 ) {
blit->data[dwords++] = R128_CCE_PACKET2;
}
buf->used = (dwords + 8) * sizeof(u32);
r128_cce_dispatch_indirect( dev, buf );
}
/* Flush the pixel cache after the blit completes. This ensures
* the texture data is written out to memory before rendering
* continues.
*/
BEGIN_RING( 2 );
OUT_RING( CCE_PACKET0( R128_PC_GUI_CTLSTAT, 0 ) );
OUT_RING( R128_PC_FLUSH_GUI );
ADVANCE_RING();
return 0;
}
/* ================================================================
*
*/
@ -679,15 +847,15 @@ int r128_cce_vertex( struct inode *inode, struct file *filp,
DRM_DEBUG( "%s: pid=%d index=%d used=%d discard=%d\n",
__FUNCTION__, current->pid,
vertex.index, vertex.used, vertex.discard );
vertex.idx, vertex.used, vertex.discard );
if ( vertex.index < 0 || vertex.index >= dma->buf_count ) {
if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) {
DRM_ERROR( "buffer index %d (of %d max)\n",
vertex.index, dma->buf_count - 1 );
vertex.idx, dma->buf_count - 1 );
return -EINVAL;
}
buf = dma->buflist[vertex.index];
buf = dma->buflist[vertex.idx];
buf_priv = buf->dev_private;
if ( buf->pid != current->pid ) {
@ -696,7 +864,7 @@ int r128_cce_vertex( struct inode *inode, struct file *filp,
return -EINVAL;
}
if ( buf->pending ) {
DRM_ERROR( "sending pending buffer %d\n", vertex.index );
DRM_ERROR( "sending pending buffer %d\n", vertex.idx );
return -EINVAL;
}
@ -707,3 +875,39 @@ int r128_cce_vertex( struct inode *inode, struct file *filp,
return 0;
}
int r128_cce_blit( 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_device_dma_t *dma = dev->dma;
drm_r128_blit_t blit;
drm_r128_blit_rect_t rects[R128_MAX_BLIT_BUFFERS];
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( &blit, (drm_r128_blit_t *)arg,
sizeof(blit) ) )
return -EFAULT;
DRM_DEBUG( "%s: pid=%d count=%d\n",
__FUNCTION__, current->pid, blit.count );
if ( blit.count < 0 || blit.count > dma->buf_count ) {
DRM_ERROR( "sending %d buffers (of %d max)\n",
blit.count, dma->buf_count );
return -EINVAL;
}
if ( copy_from_user( &rects, blit.rects,
blit.count * sizeof(drm_r128_blit_rect_t) ) )
return -EFAULT;
return r128_cce_dispatch_blit( dev, blit.offset, blit.pitch,
blit.format, rects, blit.count );
}

View file

@ -371,6 +371,7 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_R128_SWAP DRM_IO( 0x46)
#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x47, drm_r128_clear_t)
#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x48, drm_r128_vertex_t)
#define DRM_IOCTL_R128_PACKET DRM_IOWR(0x49, drm_r128_packet_t)
#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x49, drm_r128_blit_t)
#define DRM_IOCTL_R128_PACKET DRM_IOWR(0x50, drm_r128_packet_t)
#endif

View file

@ -371,6 +371,7 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_R128_SWAP DRM_IO( 0x46)
#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x47, drm_r128_clear_t)
#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x48, drm_r128_vertex_t)
#define DRM_IOCTL_R128_PACKET DRM_IOWR(0x49, drm_r128_packet_t)
#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x49, drm_r128_blit_t)
#define DRM_IOCTL_R128_PACKET DRM_IOWR(0x50, drm_r128_packet_t)
#endif