mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-05-08 10:28:04 +02:00
support for new radeon packets
This commit is contained in:
parent
9eef7a1c13
commit
d6c8a56c2a
9 changed files with 228 additions and 282 deletions
|
|
@ -68,7 +68,8 @@
|
|||
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)] = { radeon_cp_indirect, 1, 1 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX2)] = { radeon_cp_vertex2, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CMDBUF)] = { radeon_cp_cmdbuf, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CMDBUF)] = { radeon_cp_cmdbuf, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_GETPARAM)] = { radeon_cp_getparam, 1, 0 },
|
||||
|
||||
|
||||
#include "drm_agpsupport.h"
|
||||
|
|
|
|||
|
|
@ -491,6 +491,7 @@ typedef struct drm_scatter_gather {
|
|||
#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4e, drm_radeon_texture_t)
|
||||
#define DRM_IOCTL_RADEON_VERTEX2 DRM_IOW( 0x4f, drm_radeon_vertex_t)
|
||||
#define DRM_IOCTL_RADEON_CMDBUF DRM_IOW( 0x50, drm_radeon_cmd_buffer_t)
|
||||
#define DRM_IOCTL_RADEON_GETPARAM DRM_IOWR(0x51, drm_radeon_getparam_t)
|
||||
|
||||
/* Gamma specific ioctls */
|
||||
#define DRM_IOCTL_GAMMA_INIT DRM_IOW( 0x40, drm_gamma_init_t)
|
||||
|
|
|
|||
|
|
@ -964,9 +964,7 @@ static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init )
|
|||
radeon_cp_load_microcode( dev_priv );
|
||||
radeon_cp_init_ring_buffer( dev, dev_priv );
|
||||
|
||||
#if ROTATE_BUFS
|
||||
dev_priv->last_buf = 0;
|
||||
#endif
|
||||
|
||||
dev->dev_private = (void *)dev_priv;
|
||||
|
||||
|
|
@ -1206,56 +1204,15 @@ int radeon_fullscreen( struct inode *inode, struct file *filp,
|
|||
/* ================================================================
|
||||
* Freelist management
|
||||
*/
|
||||
#define RADEON_BUFFER_USED 0xffffffff
|
||||
#define RADEON_BUFFER_FREE 0
|
||||
|
||||
#if 0
|
||||
static int radeon_freelist_init( drm_device_t *dev )
|
||||
{
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
drm_buf_t *buf;
|
||||
drm_radeon_buf_priv_t *buf_priv;
|
||||
drm_radeon_freelist_t *entry;
|
||||
int i;
|
||||
|
||||
dev_priv->head = DRM(alloc)( sizeof(drm_radeon_freelist_t),
|
||||
DRM_MEM_DRIVER );
|
||||
if ( dev_priv->head == NULL )
|
||||
return -ENOMEM;
|
||||
|
||||
memset( dev_priv->head, 0, sizeof(drm_radeon_freelist_t) );
|
||||
dev_priv->head->age = RADEON_BUFFER_USED;
|
||||
|
||||
for ( i = 0 ; i < dma->buf_count ; i++ ) {
|
||||
buf = dma->buflist[i];
|
||||
buf_priv = buf->dev_private;
|
||||
|
||||
entry = DRM(alloc)( sizeof(drm_radeon_freelist_t),
|
||||
DRM_MEM_DRIVER );
|
||||
if ( !entry ) return -ENOMEM;
|
||||
|
||||
entry->age = RADEON_BUFFER_FREE;
|
||||
entry->buf = buf;
|
||||
entry->prev = dev_priv->head;
|
||||
entry->next = dev_priv->head->next;
|
||||
if ( !entry->next )
|
||||
dev_priv->tail = entry;
|
||||
|
||||
buf_priv->discard = 0;
|
||||
buf_priv->dispatched = 0;
|
||||
buf_priv->list_entry = entry;
|
||||
|
||||
dev_priv->head->next = entry;
|
||||
|
||||
if ( dev_priv->head->next )
|
||||
dev_priv->head->next->prev = entry;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
#endif
|
||||
/* Original comment: FIXME: ROTATE_BUFS is a hack to cycle through
|
||||
* bufs until freelist code is used. Note this hides a problem with
|
||||
* the scratch register * (used to keep track of last buffer
|
||||
* completed) being written to before * the last buffer has actually
|
||||
* completed rendering.
|
||||
*
|
||||
* KW: It's also a good way to find free buffers quickly.
|
||||
*/
|
||||
|
||||
drm_buf_t *radeon_freelist_get( drm_device_t *dev )
|
||||
{
|
||||
|
|
@ -1264,57 +1221,24 @@ drm_buf_t *radeon_freelist_get( drm_device_t *dev )
|
|||
drm_radeon_buf_priv_t *buf_priv;
|
||||
drm_buf_t *buf;
|
||||
int i, t;
|
||||
#if ROTATE_BUFS
|
||||
int start;
|
||||
#endif
|
||||
|
||||
/* FIXME: Optimize -- use freelist code */
|
||||
|
||||
for ( i = 0 ; i < dma->buf_count ; i++ ) {
|
||||
buf = dma->buflist[i];
|
||||
buf_priv = buf->dev_private;
|
||||
if ( buf->pid == 0 ) {
|
||||
DRM_DEBUG( " ret buf=%d last=%d pid=0\n",
|
||||
buf->idx, dev_priv->last_buf );
|
||||
return buf;
|
||||
}
|
||||
DRM_DEBUG( " skipping buf=%d pid=%d\n",
|
||||
buf->idx, buf->pid );
|
||||
}
|
||||
|
||||
#if ROTATE_BUFS
|
||||
if ( ++dev_priv->last_buf >= dma->buf_count )
|
||||
dev_priv->last_buf = 0;
|
||||
|
||||
start = dev_priv->last_buf;
|
||||
#endif
|
||||
|
||||
for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) {
|
||||
#if 0
|
||||
/* FIXME: Disable this for now */
|
||||
u32 done_age = dev_priv->scratch[RADEON_LAST_DISPATCH];
|
||||
#else
|
||||
u32 done_age = RADEON_READ( RADEON_LAST_DISPATCH_REG );
|
||||
#endif
|
||||
#if ROTATE_BUFS
|
||||
for ( i = start ; i < dma->buf_count ; i++ ) {
|
||||
#else
|
||||
for ( i = 0 ; i < dma->buf_count ; i++ ) {
|
||||
#endif
|
||||
buf = dma->buflist[i];
|
||||
buf_priv = buf->dev_private;
|
||||
if ( buf->pending && buf_priv->age <= done_age ) {
|
||||
/* The buffer has been processed, so it
|
||||
* can now be used.
|
||||
*/
|
||||
if ( buf->pid == 0 || (buf->pending &&
|
||||
buf_priv->age <= done_age) ) {
|
||||
buf->pending = 0;
|
||||
DRM_DEBUG( " ret buf=%d last=%d age=%d done=%d\n", buf->idx, dev_priv->last_buf, buf_priv->age, done_age );
|
||||
return buf;
|
||||
}
|
||||
DRM_DEBUG( " skipping buf=%d age=%d done=%d\n",
|
||||
buf->idx, buf_priv->age,
|
||||
done_age );
|
||||
#if ROTATE_BUFS
|
||||
start = 0;
|
||||
#endif
|
||||
}
|
||||
udelay( 1 );
|
||||
}
|
||||
|
|
@ -1326,14 +1250,10 @@ drm_buf_t *radeon_freelist_get( drm_device_t *dev )
|
|||
void radeon_freelist_reset( drm_device_t *dev )
|
||||
{
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
#if ROTATE_BUFS
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
#endif
|
||||
int i;
|
||||
|
||||
#if ROTATE_BUFS
|
||||
dev_priv->last_buf = 0;
|
||||
#endif
|
||||
for ( i = 0 ; i < dma->buf_count ; i++ ) {
|
||||
drm_buf_t *buf = dma->buflist[i];
|
||||
drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
|
||||
|
|
|
|||
|
|
@ -98,8 +98,10 @@
|
|||
#define RADEON_CMD_PACKET 1 /* emit one of the register packets above */
|
||||
#define RADEON_CMD_SCALARS 2 /* emit scalar data */
|
||||
#define RADEON_CMD_VECTORS 3 /* emit vector data */
|
||||
#define RADEON_CMD_PRIMITIVE 4 /* emit a primitive from current dma buf */
|
||||
#define RADEON_CMD_DMA_DISCARD 5 /* discard current dma buf */
|
||||
#define RADEON_CMD_DMA_DISCARD 4 /* discard current dma buf */
|
||||
#define RADEON_CMD_PACKET3 5 /* emit hw packet */
|
||||
#define RADEON_CMD_PACKET3_CLIP 6 /* emit hw packet wrapped in cliprects */
|
||||
|
||||
|
||||
typedef union {
|
||||
int i;
|
||||
|
|
@ -115,9 +117,6 @@ typedef union {
|
|||
struct {
|
||||
char cmd_type, offset, stride, count;
|
||||
} vectors;
|
||||
struct {
|
||||
char cmd_type, buf_idx, pad0, pad1;
|
||||
} primitive;
|
||||
struct {
|
||||
char cmd_type, buf_idx, pad0, pad1;
|
||||
} dma;
|
||||
|
|
@ -145,7 +144,6 @@ typedef union {
|
|||
/* Byte offsets for indirect buffer data
|
||||
*/
|
||||
#define RADEON_INDEX_PRIM_OFFSET 20
|
||||
#define RADEON_HOSTDATA_BLIT_OFFSET 32
|
||||
|
||||
#define RADEON_SCRATCH_REG_OFFSET 32
|
||||
|
||||
|
|
@ -253,13 +251,6 @@ typedef struct {
|
|||
unsigned int vc_format; /* vertex format */
|
||||
} drm_radeon_prim_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned int start;
|
||||
unsigned int finish;
|
||||
unsigned int prim;
|
||||
unsigned int numverts; /* overloaded as offset/64 for elt prims */
|
||||
unsigned int vc_format; /* vertex format */
|
||||
} drm_radeon_tcl_prim_t;
|
||||
|
||||
typedef struct {
|
||||
drm_radeon_context_regs_t context;
|
||||
|
|
@ -437,4 +428,15 @@ typedef struct drm_radeon_indirect {
|
|||
int discard;
|
||||
} drm_radeon_indirect_t;
|
||||
|
||||
|
||||
/* 1.3: An ioctl to get parameters that aren't available to the 3d
|
||||
* client any other way.
|
||||
*/
|
||||
#define RADEON_PARAM_AGP_BUFFER_OFFSET 0x1
|
||||
|
||||
typedef struct drm_radeon_getparam {
|
||||
int param;
|
||||
int *value;
|
||||
} drm_radeon_getparam_t;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -68,7 +68,8 @@
|
|||
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)] = { radeon_cp_indirect, 1, 1 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX2)] = { radeon_cp_vertex2, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CMDBUF)] = { radeon_cp_cmdbuf, 1, 0 },
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CMDBUF)] = { radeon_cp_cmdbuf, 1, 0 }, \
|
||||
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_GETPARAM)] = { radeon_cp_getparam, 1, 0 },
|
||||
|
||||
|
||||
#include "drm_agpsupport.h"
|
||||
|
|
|
|||
|
|
@ -71,14 +71,7 @@ typedef struct drm_radeon_private {
|
|||
|
||||
drm_radeon_freelist_t *head;
|
||||
drm_radeon_freelist_t *tail;
|
||||
/* FIXME: ROTATE_BUFS is a hask to cycle through bufs until freelist
|
||||
code is used. Note this hides a problem with the scratch register
|
||||
(used to keep track of last buffer completed) being written to before
|
||||
the last buffer has actually completed rendering. */
|
||||
#define ROTATE_BUFS 1
|
||||
#if ROTATE_BUFS
|
||||
int last_buf;
|
||||
#endif
|
||||
volatile u32 *scratch;
|
||||
|
||||
int usec_timeout;
|
||||
|
|
@ -120,10 +113,6 @@ typedef struct drm_radeon_private {
|
|||
|
||||
typedef struct drm_radeon_buf_priv {
|
||||
u32 age;
|
||||
int prim;
|
||||
int discard;
|
||||
int dispatched;
|
||||
drm_radeon_freelist_t *list_entry;
|
||||
} drm_radeon_buf_priv_t;
|
||||
|
||||
/* radeon_cp.c */
|
||||
|
|
@ -180,6 +169,8 @@ extern int radeon_cp_vertex2( struct inode *inode, struct file *filp,
|
|||
unsigned int cmd, unsigned long arg );
|
||||
extern int radeon_cp_cmdbuf( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
extern int radeon_cp_getparam( struct inode *inode, struct file *filp,
|
||||
unsigned int cmd, unsigned long arg );
|
||||
|
||||
|
||||
|
||||
|
|
@ -467,8 +458,10 @@ extern int radeon_cp_cmdbuf( struct inode *inode, struct file *filp,
|
|||
#define RADEON_CP_PACKET3 0xC0000000
|
||||
# define RADEON_3D_RNDR_GEN_INDX_PRIM 0x00002300
|
||||
# define RADEON_WAIT_FOR_IDLE 0x00002600
|
||||
# define RADEON_3D_DRAW_VBUF 0x00002800
|
||||
# define RADEON_3D_DRAW_IMMD 0x00002900
|
||||
# define RADEON_3D_CLEAR_ZMASK 0x00003200
|
||||
# define RADEON_3D_DRAW_INDX 0x00002A00
|
||||
# define RADEON_3D_LOAD_VBPNTR 0x00002F00
|
||||
# define RADEON_CNTL_HOSTDATA_BLT 0x00009400
|
||||
# define RADEON_CNTL_PAINT_MULTI 0x00009A00
|
||||
# define RADEON_CNTL_BITBLT_MULTI 0x00009B00
|
||||
|
|
|
|||
|
|
@ -610,6 +610,40 @@ static void radeon_cp_dispatch_flip( drm_device_t *dev )
|
|||
ADVANCE_RING();
|
||||
}
|
||||
|
||||
static int bad_prim_vertex_nr( int primitive, int nr )
|
||||
{
|
||||
switch (primitive & RADEON_PRIM_TYPE_MASK) {
|
||||
case RADEON_PRIM_TYPE_NONE:
|
||||
case RADEON_PRIM_TYPE_POINT:
|
||||
return nr < 1;
|
||||
case RADEON_PRIM_TYPE_LINE:
|
||||
return (nr & 1) || nr == 0;
|
||||
case RADEON_PRIM_TYPE_LINE_STRIP:
|
||||
return nr < 2;
|
||||
case RADEON_PRIM_TYPE_TRI_LIST:
|
||||
case RADEON_PRIM_TYPE_3VRT_POINT_LIST:
|
||||
case RADEON_PRIM_TYPE_3VRT_LINE_LIST:
|
||||
case RADEON_PRIM_TYPE_RECT_LIST:
|
||||
return nr % 3 || nr == 0;
|
||||
case RADEON_PRIM_TYPE_TRI_FAN:
|
||||
case RADEON_PRIM_TYPE_TRI_STRIP:
|
||||
return nr < 3;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
unsigned int start;
|
||||
unsigned int finish;
|
||||
unsigned int prim;
|
||||
unsigned int numverts;
|
||||
unsigned int offset;
|
||||
unsigned int vc_format;
|
||||
} drm_radeon_tcl_prim_t;
|
||||
|
||||
static void radeon_cp_dispatch_vertex( drm_device_t *dev,
|
||||
drm_buf_t *buf,
|
||||
drm_radeon_tcl_prim_t *prim,
|
||||
|
|
@ -618,7 +652,6 @@ static void radeon_cp_dispatch_vertex( drm_device_t *dev,
|
|||
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
|
||||
drm_clip_rect_t box;
|
||||
int offset = dev_priv->agp_buffers_offset + buf->offset + prim->start;
|
||||
int numverts = (int)prim->numverts;
|
||||
|
|
@ -634,52 +667,12 @@ static void radeon_cp_dispatch_vertex( drm_device_t *dev,
|
|||
prim->finish,
|
||||
prim->numverts);
|
||||
|
||||
switch (prim->prim & RADEON_PRIM_TYPE_MASK) {
|
||||
case RADEON_PRIM_TYPE_NONE:
|
||||
case RADEON_PRIM_TYPE_POINT:
|
||||
if (prim->numverts < 1) {
|
||||
DRM_ERROR( "Bad nr verts for line %d\n",
|
||||
prim->numverts);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case RADEON_PRIM_TYPE_LINE:
|
||||
if ((prim->numverts & 1) || prim->numverts == 0) {
|
||||
DRM_ERROR( "Bad nr verts for line %d\n",
|
||||
prim->numverts);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case RADEON_PRIM_TYPE_LINE_STRIP:
|
||||
if (prim->numverts < 2) {
|
||||
DRM_ERROR( "Bad nr verts for line_strip %d\n",
|
||||
prim->numverts);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case RADEON_PRIM_TYPE_TRI_LIST:
|
||||
case RADEON_PRIM_TYPE_3VRT_POINT_LIST:
|
||||
case RADEON_PRIM_TYPE_3VRT_LINE_LIST:
|
||||
case RADEON_PRIM_TYPE_RECT_LIST:
|
||||
if (prim->numverts % 3 || prim->numverts == 0) {
|
||||
DRM_ERROR( "Bad nr verts for tri %d\n",
|
||||
prim->numverts);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case RADEON_PRIM_TYPE_TRI_FAN:
|
||||
case RADEON_PRIM_TYPE_TRI_STRIP:
|
||||
if (prim->numverts < 3) {
|
||||
DRM_ERROR( "Bad nr verts for strip/fan %d\n",
|
||||
prim->numverts);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR( "buffer prim %x start %x\n",
|
||||
prim->prim, prim->start );
|
||||
if (bad_prim_vertex_nr( prim->prim, prim->numverts )) {
|
||||
DRM_ERROR( "bad prim %x numverts %d\n",
|
||||
prim->prim, prim->numverts );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
do {
|
||||
/* Emit the next cliprect */
|
||||
|
|
@ -706,19 +699,17 @@ static void radeon_cp_dispatch_vertex( drm_device_t *dev,
|
|||
|
||||
i++;
|
||||
} while ( i < nbox );
|
||||
|
||||
buf_priv->dispatched = 1;
|
||||
dev_priv->sarea_priv->last_dispatch++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void radeon_cp_discard_buffer( drm_device_t *dev, drm_buf_t *buf )
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
|
||||
RING_LOCALS;
|
||||
|
||||
buf_priv->age = dev_priv->sarea_priv->last_dispatch;
|
||||
buf_priv->age = ++dev_priv->sarea_priv->last_dispatch;
|
||||
|
||||
/* Emit the vertex buffer age */
|
||||
BEGIN_RING( 2 );
|
||||
|
|
@ -727,8 +718,6 @@ static void radeon_cp_discard_buffer( drm_device_t *dev, drm_buf_t *buf )
|
|||
|
||||
buf->pending = 1;
|
||||
buf->used = 0;
|
||||
/* FIXME: Check dispatched field */
|
||||
buf_priv->dispatched = 0;
|
||||
}
|
||||
|
||||
static void radeon_cp_dispatch_indirect( drm_device_t *dev,
|
||||
|
|
@ -736,7 +725,6 @@ static void radeon_cp_dispatch_indirect( drm_device_t *dev,
|
|||
int start, int end )
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
|
||||
RING_LOCALS;
|
||||
DRM_DEBUG( "indirect: buf=%d s=0x%x e=0x%x\n",
|
||||
buf->idx, start, end );
|
||||
|
|
@ -757,8 +745,6 @@ static void radeon_cp_dispatch_indirect( drm_device_t *dev,
|
|||
data[dwords++] = RADEON_CP_PACKET2;
|
||||
}
|
||||
|
||||
buf_priv->dispatched = 1;
|
||||
|
||||
/* Fire off the indirect buffer */
|
||||
BEGIN_RING( 3 );
|
||||
|
||||
|
|
@ -768,8 +754,6 @@ static void radeon_cp_dispatch_indirect( drm_device_t *dev,
|
|||
|
||||
ADVANCE_RING();
|
||||
}
|
||||
|
||||
dev_priv->sarea_priv->last_dispatch++;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -780,67 +764,29 @@ static void radeon_cp_dispatch_indices( drm_device_t *dev,
|
|||
int nbox )
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
drm_radeon_buf_priv_t *buf_priv = elt_buf->dev_private;
|
||||
drm_clip_rect_t box;
|
||||
int offset = dev_priv->agp_buffers_offset + prim->numverts * 64;
|
||||
int offset = dev_priv->agp_buffers_offset + prim->offset;
|
||||
u32 *data;
|
||||
int dwords;
|
||||
int i = 0;
|
||||
int start = prim->start + RADEON_INDEX_PRIM_OFFSET;
|
||||
int count = (prim->finish - start) / sizeof(u16);
|
||||
|
||||
DRM_DEBUG("%s: hwprim 0x%x vfmt 0x%x %d..%d offset: %x\n",
|
||||
DRM_DEBUG("%s: hwprim 0x%x vfmt 0x%x %d..%d offset: %x nr %d\n",
|
||||
__FUNCTION__,
|
||||
prim->prim,
|
||||
prim->vc_format,
|
||||
prim->start,
|
||||
prim->finish,
|
||||
prim->numverts * 64);
|
||||
prim->offset,
|
||||
prim->numverts);
|
||||
|
||||
switch (prim->prim & RADEON_PRIM_TYPE_MASK) {
|
||||
case RADEON_PRIM_TYPE_NONE:
|
||||
case RADEON_PRIM_TYPE_POINT:
|
||||
if (count < 1) {
|
||||
DRM_ERROR( "Bad nr verts for line %d\n",
|
||||
count);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case RADEON_PRIM_TYPE_LINE:
|
||||
if ((count & 1) || count == 0) {
|
||||
DRM_ERROR( "Bad nr verts for line %d\n",
|
||||
count);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case RADEON_PRIM_TYPE_LINE_STRIP:
|
||||
if (count < 2) {
|
||||
DRM_ERROR( "Bad nr verts for line_strip %d\n",
|
||||
count);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case RADEON_PRIM_TYPE_TRI_LIST:
|
||||
case RADEON_PRIM_TYPE_3VRT_POINT_LIST:
|
||||
case RADEON_PRIM_TYPE_3VRT_LINE_LIST:
|
||||
case RADEON_PRIM_TYPE_RECT_LIST:
|
||||
if (count % 3 || count == 0) {
|
||||
DRM_ERROR( "Bad nr verts for tri %d\n", count);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case RADEON_PRIM_TYPE_TRI_FAN:
|
||||
case RADEON_PRIM_TYPE_TRI_STRIP:
|
||||
if (count < 3) {
|
||||
DRM_ERROR( "Bad nr verts for strip/fan %d\n", count);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR( "buffer prim %x start %x\n",
|
||||
prim->prim, prim->start );
|
||||
if (bad_prim_vertex_nr( prim->prim, count )) {
|
||||
DRM_ERROR( "bad prim %x count %d\n",
|
||||
prim->prim, count );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ( start >= prim->finish ||
|
||||
(prim->start & 0x7) ) {
|
||||
|
|
@ -855,7 +801,7 @@ static void radeon_cp_dispatch_indices( drm_device_t *dev,
|
|||
|
||||
data[0] = CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, dwords-2 );
|
||||
data[1] = offset;
|
||||
data[2] = RADEON_MAX_VB_VERTS;
|
||||
data[2] = prim->numverts;
|
||||
data[3] = prim->vc_format;
|
||||
data[4] = (prim->prim |
|
||||
RADEON_PRIM_WALK_IND |
|
||||
|
|
@ -878,9 +824,6 @@ static void radeon_cp_dispatch_indices( drm_device_t *dev,
|
|||
i++;
|
||||
} while ( i < nbox );
|
||||
|
||||
|
||||
buf_priv->dispatched = 1;
|
||||
dev_priv->sarea_priv->last_dispatch++;
|
||||
}
|
||||
|
||||
#define RADEON_MAX_TEXTURE_SIZE (RADEON_BUFFER_SIZE - 8 * sizeof(u32))
|
||||
|
|
@ -891,7 +834,6 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev,
|
|||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
drm_buf_t *buf;
|
||||
drm_radeon_buf_priv_t *buf_priv;
|
||||
u32 format;
|
||||
u32 *buffer;
|
||||
u8 *data;
|
||||
|
|
@ -909,8 +851,6 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev,
|
|||
tex->offset >> 10, tex->pitch, tex->format,
|
||||
image->x, image->y, image->width, image->height );
|
||||
|
||||
buf_priv = buf->dev_private;
|
||||
|
||||
/* The compiler won't optimize away a division by a variable,
|
||||
* even if the only legal values are powers of two. Thus, we'll
|
||||
* use a shift instead.
|
||||
|
|
@ -1036,7 +976,6 @@ static int radeon_cp_dispatch_texture( drm_device_t *dev,
|
|||
|
||||
buf->pid = current->pid;
|
||||
buf->used = (dwords + 8) * sizeof(u32);
|
||||
buf_priv->discard = 1;
|
||||
|
||||
radeon_cp_dispatch_indirect( dev, buf, 0, buf->used );
|
||||
radeon_cp_discard_buffer( dev, buf );
|
||||
|
|
@ -1160,7 +1099,6 @@ int radeon_cp_vertex( struct inode *inode, struct file *filp,
|
|||
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_buf_t *buf;
|
||||
drm_radeon_buf_priv_t *buf_priv;
|
||||
drm_radeon_vertex_t vertex;
|
||||
drm_radeon_tcl_prim_t prim;
|
||||
|
||||
|
|
@ -1194,7 +1132,6 @@ int radeon_cp_vertex( struct inode *inode, struct file *filp,
|
|||
VB_AGE_TEST_WITH_RETURN( dev_priv );
|
||||
|
||||
buf = dma->buflist[vertex.idx];
|
||||
buf_priv = buf->dev_private;
|
||||
|
||||
if ( buf->pid != current->pid ) {
|
||||
DRM_ERROR( "process %d using buffer owned by %d\n",
|
||||
|
|
@ -1250,7 +1187,6 @@ int radeon_cp_indices( struct inode *inode, struct file *filp,
|
|||
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_buf_t *buf;
|
||||
drm_radeon_buf_priv_t *buf_priv;
|
||||
drm_radeon_indices_t elts;
|
||||
drm_radeon_tcl_prim_t prim;
|
||||
int count;
|
||||
|
|
@ -1285,7 +1221,6 @@ int radeon_cp_indices( struct inode *inode, struct file *filp,
|
|||
VB_AGE_TEST_WITH_RETURN( dev_priv );
|
||||
|
||||
buf = dma->buflist[elts.idx];
|
||||
buf_priv = buf->dev_private;
|
||||
|
||||
if ( buf->pid != current->pid ) {
|
||||
DRM_ERROR( "process %d using buffer owned by %d\n",
|
||||
|
|
@ -1329,7 +1264,8 @@ int radeon_cp_indices( struct inode *inode, struct file *filp,
|
|||
prim.start = elts.start;
|
||||
prim.finish = elts.end;
|
||||
prim.prim = elts.prim;
|
||||
prim.numverts = 0; /* offset from start of dma buffers */
|
||||
prim.offset = 0; /* offset from start of dma buffers */
|
||||
prim.numverts = RADEON_MAX_VB_VERTS; /* duh */
|
||||
prim.vc_format = dev_priv->sarea_priv->vc_format;
|
||||
|
||||
radeon_cp_dispatch_indices( dev, buf, &prim,
|
||||
|
|
@ -1405,7 +1341,6 @@ int radeon_cp_indirect( struct inode *inode, struct file *filp,
|
|||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_buf_t *buf;
|
||||
drm_radeon_buf_priv_t *buf_priv;
|
||||
drm_radeon_indirect_t indirect;
|
||||
RING_LOCALS;
|
||||
|
||||
|
|
@ -1431,7 +1366,6 @@ int radeon_cp_indirect( struct inode *inode, struct file *filp,
|
|||
}
|
||||
|
||||
buf = dma->buflist[indirect.idx];
|
||||
buf_priv = buf->dev_private;
|
||||
|
||||
if ( buf->pid != current->pid ) {
|
||||
DRM_ERROR( "process %d using buffer owned by %d\n",
|
||||
|
|
@ -1453,7 +1387,6 @@ int radeon_cp_indirect( struct inode *inode, struct file *filp,
|
|||
VB_AGE_TEST_WITH_RETURN( dev_priv );
|
||||
|
||||
buf->used = indirect.end;
|
||||
buf_priv->discard = indirect.discard;
|
||||
|
||||
/* Wait for the 3D stream to idle before the indirect buffer
|
||||
* containing 2D acceleration commands is processed.
|
||||
|
|
@ -1486,7 +1419,6 @@ int radeon_cp_vertex2( struct inode *inode, struct file *filp,
|
|||
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
|
||||
drm_device_dma_t *dma = dev->dma;
|
||||
drm_buf_t *buf;
|
||||
drm_radeon_buf_priv_t *buf_priv;
|
||||
drm_radeon_vertex2_t vertex;
|
||||
int i;
|
||||
unsigned char laststate;
|
||||
|
|
@ -1515,7 +1447,6 @@ int radeon_cp_vertex2( struct inode *inode, struct file *filp,
|
|||
VB_AGE_TEST_WITH_RETURN( dev_priv );
|
||||
|
||||
buf = dma->buflist[vertex.idx];
|
||||
buf_priv = buf->dev_private;
|
||||
|
||||
if ( buf->pid != current->pid ) {
|
||||
DRM_ERROR( "process %d using buffer owned by %d\n",
|
||||
|
|
@ -1527,6 +1458,9 @@ int radeon_cp_vertex2( struct inode *inode, struct file *filp,
|
|||
DRM_ERROR( "sending pending buffer %d\n", vertex.idx );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
|
||||
return -EINVAL;
|
||||
|
||||
for (laststate = 0xff, i = 0 ; i < vertex.nr_prims ; i++) {
|
||||
drm_radeon_prim_t prim;
|
||||
|
|
@ -1551,14 +1485,19 @@ int radeon_cp_vertex2( struct inode *inode, struct file *filp,
|
|||
tclprim.start = prim.start;
|
||||
tclprim.finish = prim.finish;
|
||||
tclprim.prim = prim.prim;
|
||||
tclprim.numverts = prim.numverts;
|
||||
tclprim.vc_format = prim.vc_format;
|
||||
|
||||
if ( prim.prim & RADEON_PRIM_WALK_IND ) {
|
||||
tclprim.offset = prim.numverts * 64;
|
||||
tclprim.numverts = RADEON_MAX_VB_VERTS; /* duh */
|
||||
|
||||
radeon_cp_dispatch_indices( dev, buf, &tclprim,
|
||||
sarea_priv->boxes,
|
||||
sarea_priv->nbox);
|
||||
} else {
|
||||
tclprim.numverts = prim.numverts;
|
||||
tclprim.offset = 0; /* not used */
|
||||
|
||||
radeon_cp_dispatch_vertex( dev, buf, &tclprim,
|
||||
sarea_priv->boxes,
|
||||
sarea_priv->nbox);
|
||||
|
|
@ -1656,35 +1595,88 @@ static inline int radeon_emit_vectors(
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int radeon_emit_primitive(
|
||||
drm_device_t *dev,
|
||||
drm_buf_t *buf,
|
||||
drm_radeon_cmd_buffer_t *cmdbuf )
|
||||
|
||||
static int radeon_emit_packet3( drm_device_t *dev,
|
||||
drm_radeon_cmd_buffer_t *cmdbuf )
|
||||
{
|
||||
drm_radeon_tcl_prim_t prim;
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
int cmdsz, tmp;
|
||||
int *cmd = (int *)cmdbuf->buf;
|
||||
int j;
|
||||
RING_LOCALS;
|
||||
|
||||
if (cmdbuf->bufsz < sizeof(prim))
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
if (__get_user( tmp, &cmd[0]))
|
||||
return -EFAULT;
|
||||
|
||||
if (__copy_from_user(&prim, cmdbuf->buf, sizeof(prim)))
|
||||
return -EFAULT;
|
||||
|
||||
cmdsz = 2 + ((tmp & RADEON_CP_PACKET_COUNT_MASK) >> 16);
|
||||
|
||||
if ( prim.prim & RADEON_PRIM_WALK_IND ) {
|
||||
radeon_cp_dispatch_indices( dev, buf, &prim,
|
||||
cmdbuf->boxes,
|
||||
cmdbuf->nbox);
|
||||
} else {
|
||||
radeon_cp_dispatch_vertex( dev, buf, &prim,
|
||||
cmdbuf->boxes,
|
||||
cmdbuf->nbox);
|
||||
if ((tmp & 0xc0000000) != RADEON_CP_PACKET3 ||
|
||||
cmdsz * 4 > cmdbuf->bufsz)
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
BEGIN_RING( cmdsz );
|
||||
for (j = 0 ; j < cmdsz ; j++) {
|
||||
if (__get_user( tmp, &cmd[j] ))
|
||||
return -EFAULT;
|
||||
/* printk( "pk3 %d: %x\n", j, tmp); */
|
||||
OUT_RING( tmp );
|
||||
}
|
||||
ADVANCE_RING();
|
||||
|
||||
if (cmdbuf->nbox == 1)
|
||||
cmdbuf->buf += cmdsz * 4;
|
||||
cmdbuf->bufsz -= cmdsz * 4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int radeon_emit_packet3_cliprect( drm_device_t *dev,
|
||||
drm_radeon_cmd_buffer_t *cmdbuf )
|
||||
{
|
||||
drm_radeon_private_t *dev_priv = dev->dev_private;
|
||||
drm_clip_rect_t box;
|
||||
int cmdsz, tmp;
|
||||
int *cmd = (int *)cmdbuf->buf;
|
||||
drm_clip_rect_t *boxes = cmdbuf->boxes;
|
||||
int i = 0, j;
|
||||
RING_LOCALS;
|
||||
|
||||
DRM_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
if (__get_user( tmp, &cmd[0]))
|
||||
return -EFAULT;
|
||||
|
||||
cmdsz = 2 + ((tmp & RADEON_CP_PACKET_COUNT_MASK) >> 16);
|
||||
|
||||
if ((tmp & 0xc0000000) != RADEON_CP_PACKET3 ||
|
||||
cmdsz * 4 > cmdbuf->bufsz)
|
||||
return -EINVAL;
|
||||
|
||||
do {
|
||||
if ( i < cmdbuf->nbox ) {
|
||||
if (__copy_from_user( &box, &boxes[i], sizeof(box) ))
|
||||
return -EFAULT;
|
||||
radeon_emit_clip_rect( dev_priv, &box );
|
||||
}
|
||||
|
||||
BEGIN_RING( cmdsz );
|
||||
for (j = 0 ; j < cmdsz ; j++) {
|
||||
if (__get_user( tmp, &cmd[j] ))
|
||||
return -EFAULT;
|
||||
/* printk( "pk3_clip %d: %x\n", j, tmp); */
|
||||
OUT_RING( tmp );
|
||||
}
|
||||
ADVANCE_RING();
|
||||
|
||||
} while ( ++i < cmdbuf->nbox );
|
||||
|
||||
if (cmdbuf->nbox == 1)
|
||||
cmdbuf->nbox = 0;
|
||||
|
||||
cmdbuf->buf += sizeof(prim);
|
||||
cmdbuf->bufsz -= sizeof(prim);
|
||||
cmdbuf->buf += cmdsz * 4;
|
||||
cmdbuf->bufsz -= cmdsz * 4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1759,26 +1751,6 @@ int radeon_cp_cmdbuf( struct inode *inode, struct file *filp,
|
|||
}
|
||||
break;
|
||||
|
||||
case RADEON_CMD_PRIMITIVE:
|
||||
idx = header.dma.buf_idx;
|
||||
if ( idx < 0 || idx >= dma->buf_count ) {
|
||||
DRM_ERROR( "buffer index %d (of %d max)\n",
|
||||
idx, dma->buf_count - 1 );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
buf = dma->buflist[idx];
|
||||
if ( buf->pid != current->pid || buf->pending ) {
|
||||
DRM_ERROR( "bad buffer\n" );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (radeon_emit_primitive( dev, buf, &cmdbuf )) {
|
||||
DRM_ERROR("radeon_emit_primitive failed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
|
||||
case RADEON_CMD_DMA_DISCARD:
|
||||
idx = header.dma.buf_idx;
|
||||
if ( idx < 0 || idx >= dma->buf_count ) {
|
||||
|
|
@ -1796,6 +1768,20 @@ int radeon_cp_cmdbuf( struct inode *inode, struct file *filp,
|
|||
radeon_cp_discard_buffer( dev, buf );
|
||||
break;
|
||||
|
||||
case RADEON_CMD_PACKET3:
|
||||
if (radeon_emit_packet3( dev, &cmdbuf )) {
|
||||
DRM_ERROR("radeon_emit_packet3 failed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
|
||||
case RADEON_CMD_PACKET3_CLIP:
|
||||
if (radeon_emit_packet3_cliprect( dev, &cmdbuf )) {
|
||||
DRM_ERROR("radeon_emit_packet3_clip failed\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DRM_ERROR("bad cmd_type %d at %p\n",
|
||||
header.header.cmd_type,
|
||||
|
|
@ -1810,6 +1796,46 @@ int radeon_cp_cmdbuf( struct inode *inode, struct file *filp,
|
|||
|
||||
|
||||
|
||||
int radeon_cp_getparam( 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_radeon_private_t *dev_priv = dev->dev_private;
|
||||
drm_radeon_getparam_t param;
|
||||
int value;
|
||||
|
||||
if ( !dev_priv ) {
|
||||
DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ( copy_from_user( ¶m, (drm_radeon_getparam_t *)arg,
|
||||
sizeof(param) ) ) {
|
||||
DRM_ERROR("copy_from_user\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
DRM_DEBUG( __FUNCTION__": pid=%d\n", current->pid );
|
||||
|
||||
switch( param.param ) {
|
||||
case RADEON_PARAM_AGP_BUFFER_OFFSET:
|
||||
value = dev_priv->agp_buffers_offset;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ( copy_to_user( param.value, &value, sizeof(int) ) ) {
|
||||
DRM_ERROR( "copy_to_user\n" );
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -491,6 +491,7 @@ typedef struct drm_scatter_gather {
|
|||
#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4e, drm_radeon_texture_t)
|
||||
#define DRM_IOCTL_RADEON_VERTEX2 DRM_IOW( 0x4f, drm_radeon_vertex_t)
|
||||
#define DRM_IOCTL_RADEON_CMDBUF DRM_IOW( 0x50, drm_radeon_cmd_buffer_t)
|
||||
#define DRM_IOCTL_RADEON_GETPARAM DRM_IOWR(0x51, drm_radeon_getparam_t)
|
||||
|
||||
/* Gamma specific ioctls */
|
||||
#define DRM_IOCTL_GAMMA_INIT DRM_IOW( 0x40, drm_gamma_init_t)
|
||||
|
|
|
|||
|
|
@ -491,6 +491,7 @@ typedef struct drm_scatter_gather {
|
|||
#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(0x4e, drm_radeon_texture_t)
|
||||
#define DRM_IOCTL_RADEON_VERTEX2 DRM_IOW( 0x4f, drm_radeon_vertex_t)
|
||||
#define DRM_IOCTL_RADEON_CMDBUF DRM_IOW( 0x50, drm_radeon_cmd_buffer_t)
|
||||
#define DRM_IOCTL_RADEON_GETPARAM DRM_IOWR(0x51, drm_radeon_getparam_t)
|
||||
|
||||
/* Gamma specific ioctls */
|
||||
#define DRM_IOCTL_GAMMA_INIT DRM_IOW( 0x40, drm_gamma_init_t)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue