diff options
author | Keith Whitwell <keith@tungstengraphics.com> | 2002-02-22 20:01:09 +0000 |
---|---|---|
committer | Keith Whitwell <keith@tungstengraphics.com> | 2002-02-22 20:01:09 +0000 |
commit | 36f6fb67f4b8cb41ae1f0686bdb4b1b5cb304414 (patch) | |
tree | 513597191673bc9d39e195b0686ba01267f848ee | |
parent | ccc1b6edec56a28a77767a1f070655e6fb0a955c (diff) |
Fix backwards compatibility on tcl branch. Add checks on number of vertices
per primitive.
-rw-r--r-- | linux/radeon_drm.h | 23 | ||||
-rw-r--r-- | linux/radeon_drv.h | 12 | ||||
-rw-r--r-- | linux/radeon_state.c | 172 |
3 files changed, 174 insertions, 33 deletions
diff --git a/linux/radeon_drm.h b/linux/radeon_drm.h index e858e02b5..f553203a4 100644 --- a/linux/radeon_drm.h +++ b/linux/radeon_drm.h @@ -131,6 +131,17 @@ typedef union { /* Primitive types */ +#define RADEON_CP_VC_CNTL_PRIM_TYPE_NONE 0x00000000 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_POINT 0x00000001 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_LINE 0x00000002 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_LINE_STRIP 0x00000003 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST 0x00000004 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN 0x00000005 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP 0x00000006 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_TYPE_2 0x00000007 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST 0x00000008 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_POINT_LIST 0x00000009 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST 0x0000000a #define RADEON_POINTS 0x1 #define RADEON_LINES 0x2 #define RADEON_LINE_STRIP 0x3 @@ -247,13 +258,21 @@ typedef struct { typedef struct { unsigned int start; unsigned int finish; - unsigned int prim; - unsigned int stateidx:16; + unsigned int prim:8; + unsigned int stateidx:8; unsigned int numverts:16; /* overloaded as offset/64 for elt prims */ 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; drm_radeon_texture_regs_t tex[RADEON_MAX_TEXTURE_UNITS]; drm_radeon_context2_regs_t context2; diff --git a/linux/radeon_drv.h b/linux/radeon_drv.h index c6b77daf7..47e234b0b 100644 --- a/linux/radeon_drv.h +++ b/linux/radeon_drv.h @@ -710,7 +710,7 @@ do { \ #define RADEON_VERBOSE 0 -#define RING_LOCALS int write; unsigned int mask; volatile u32 *ring; +#define RING_LOCALS int write, _nr; unsigned int mask; volatile u32 *ring; #define BEGIN_RING( n ) do { \ if ( RADEON_VERBOSE ) { \ @@ -720,7 +720,7 @@ do { \ if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \ radeon_wait_ring( dev_priv, (n) * sizeof(u32) ); \ } \ - dev_priv->ring.space -= (n) * sizeof(u32); \ + _nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \ ring = dev_priv->ring.start; \ write = dev_priv->ring.tail; \ mask = dev_priv->ring.tail_mask; \ @@ -732,7 +732,13 @@ do { \ write, dev_priv->ring.tail ); \ } \ radeon_flush_write_combine(); \ - dev_priv->ring.tail = write; \ + if (((dev_priv->ring.tail + _nr) & mask) != write) { \ + DRM_ERROR( \ + "ADVANCE_RING(): mismatch: nr: %x write: %x\n", \ + ((dev_priv->ring.tail + _nr) & mask), \ + write); \ + } else \ + dev_priv->ring.tail = write; \ RADEON_WRITE( RADEON_CP_RB_WPTR, write ); \ } while (0) diff --git a/linux/radeon_state.c b/linux/radeon_state.c index 5ce676407..aa6f426da 100644 --- a/linux/radeon_state.c +++ b/linux/radeon_state.c @@ -605,7 +605,7 @@ static void radeon_cp_dispatch_flip( drm_device_t *dev ) static void radeon_cp_dispatch_vertex( drm_device_t *dev, drm_buf_t *buf, - drm_radeon_prim_t *prim, + drm_radeon_tcl_prim_t *prim, drm_clip_rect_t *boxes, int nbox ) @@ -628,13 +628,54 @@ static void radeon_cp_dispatch_vertex( drm_device_t *dev, /* prim->numverts, */ /* prim->stateidx); */ - if ( /* (prim->start & 0x7) || */ - (prim->prim & RADEON_PRIM_TYPE_MASK) > - RADEON_PRIM_TYPE_3VRT_LINE_LIST ) { + switch (prim->prim & RADEON_PRIM_TYPE_MASK) { + case RADEON_CP_VC_CNTL_PRIM_TYPE_NONE: + case RADEON_CP_VC_CNTL_PRIM_TYPE_POINT: + if (prim->numverts < 1) { + DRM_ERROR( "Bad nr verts for line %d\n", + prim->numverts); + return; + } + break; + case RADEON_CP_VC_CNTL_PRIM_TYPE_LINE: + if (prim->numverts & 1) { + DRM_ERROR( "Bad nr verts for line %d\n", + prim->numverts); + return; + } + break; + case RADEON_CP_VC_CNTL_PRIM_TYPE_LINE_STRIP: + if (prim->numverts < 2) { + DRM_ERROR( "Bad nr verts for line_strip %d\n", + prim->numverts); + return; + } + break; + case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST: + case RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_POINT_LIST: + case RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST: + case RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST: + if (prim->numverts % 3) { + DRM_ERROR( "Bad nr verts for tri %d\n", + prim->numverts); + return; + } + break; + case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN: + case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP: + if (prim->numverts < 3) { + DRM_ERROR( "Bad nr verts for strip/fan %d\n", + prim->numverts); + return; + } + break; + case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_TYPE_2: + default: + /* don't understand this one */ DRM_ERROR( "buffer prim %x start %x\n", prim->prim, prim->start ); return; - } + } do { /* Emit the next cliprect */ @@ -709,6 +750,7 @@ static void radeon_cp_dispatch_indirect( drm_device_t *dev, u32 *data = (u32 *) ((char *)dev_priv->buffers->handle + buf->offset + start); +/* printk("ODD DWORDS!!!\n\n\n"); */ data[dwords++] = RADEON_CP_PACKET2; } @@ -722,6 +764,9 @@ static void radeon_cp_dispatch_indirect( drm_device_t *dev, OUT_RING( dwords ); ADVANCE_RING(); + +/* radeon_do_cp_idle( dev_priv ); */ + } dev_priv->sarea_priv->last_dispatch++; @@ -730,7 +775,7 @@ static void radeon_cp_dispatch_indirect( drm_device_t *dev, static void radeon_cp_dispatch_indices( drm_device_t *dev, drm_buf_t *elt_buf, - drm_radeon_prim_t *prim, + drm_radeon_tcl_prim_t *prim, drm_clip_rect_t *boxes, int nbox ) { @@ -752,10 +797,55 @@ static void radeon_cp_dispatch_indices( drm_device_t *dev, /* prim->numverts, */ /* prim->stateidx); */ + switch (prim->prim & RADEON_PRIM_TYPE_MASK) { + case RADEON_CP_VC_CNTL_PRIM_TYPE_NONE: + case RADEON_CP_VC_CNTL_PRIM_TYPE_POINT: + if (count < 1) { + DRM_ERROR( "Bad nr verts for line %d\n", + count); + return; + } + break; + case RADEON_CP_VC_CNTL_PRIM_TYPE_LINE: + if (count & 1) { + DRM_ERROR( "Bad nr verts for line %d\n", + count); + return; + } + break; + case RADEON_CP_VC_CNTL_PRIM_TYPE_LINE_STRIP: + if (count < 2) { + DRM_ERROR( "Bad nr verts for line_strip %d\n", + count); + return; + } + break; + case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST: + case RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_POINT_LIST: + case RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST: + case RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST: + if (count % 3) { + DRM_ERROR( "Bad nr verts for tri %d\n", count); + return; + } + break; + case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN: + case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP: + if (count < 3) { + DRM_ERROR( "Bad nr verts for strip/fan %d\n", count); + return; + } + break; + case RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_TYPE_2: + default: + /* don't understand this one */ + DRM_ERROR( "buffer prim %x start %x\n", + prim->prim, prim->start ); + return; + } + if ( start >= prim->finish || - (prim->start & 0x7) || - (prim->prim & RADEON_PRIM_TYPE_MASK) > - RADEON_PRIM_TYPE_3VRT_LINE_LIST ) { + (prim->start & 0x7) ) { DRM_ERROR( "buffer prim %d\n", prim->prim ); return; } @@ -775,10 +865,12 @@ static void radeon_cp_dispatch_indices( drm_device_t *dev, RADEON_VTX_FMT_RADEON_MODE | (count << RADEON_NUM_VERTICES_SHIFT) ); +#if 0 if ( count & 0x1 ) { /* unnecessary? */ data[dwords-1] &= 0x0000ffff; } +#endif do { if ( i < nbox ) { @@ -1079,7 +1171,7 @@ int radeon_cp_vertex( struct inode *inode, struct file *filp, drm_buf_t *buf; drm_radeon_buf_priv_t *buf_priv; drm_radeon_vertex_t vertex; - drm_radeon_prim_t prim; + drm_radeon_tcl_prim_t prim; LOCK_TEST_WITH_RETURN( dev ); @@ -1142,7 +1234,6 @@ int radeon_cp_vertex( struct inode *inode, struct file *filp, prim.start = 0; prim.finish = vertex.count; /* unused */ prim.prim = vertex.prim; - prim.stateidx = 0xff; /* unused */ prim.numverts = vertex.count; prim.vc_format = dev_priv->sarea_priv->vc_format; @@ -1167,7 +1258,7 @@ int radeon_cp_indices( struct inode *inode, struct file *filp, drm_buf_t *buf; drm_radeon_buf_priv_t *buf_priv; drm_radeon_indices_t elts; - drm_radeon_prim_t prim; + drm_radeon_tcl_prim_t prim; int count; LOCK_TEST_WITH_RETURN( dev ); @@ -1244,7 +1335,6 @@ int radeon_cp_indices( struct inode *inode, struct file *filp, prim.start = elts.start; prim.finish = elts.end; /* unused */ prim.prim = elts.prim; - prim.stateidx = 0xff; /* unused */ prim.numverts = count; prim.vc_format = dev_priv->sarea_priv->vc_format; @@ -1446,6 +1536,7 @@ int radeon_cp_vertex2( struct inode *inode, struct file *filp, for (laststate = 0xff, i = 0 ; i < vertex.nr_prims ; i++) { drm_radeon_prim_t prim; + drm_radeon_tcl_prim_t tclprim; if ( copy_from_user( &prim, &vertex.prim[i], sizeof(prim) ) ) return -EFAULT; @@ -1463,12 +1554,18 @@ int radeon_cp_vertex2( struct inode *inode, struct file *filp, laststate = prim.stateidx; } + 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 ) { - radeon_cp_dispatch_indices( dev, buf, &prim, + radeon_cp_dispatch_indices( dev, buf, &tclprim, sarea_priv->boxes, sarea_priv->nbox); } else { - radeon_cp_dispatch_vertex( dev, buf, &prim, + radeon_cp_dispatch_vertex( dev, buf, &tclprim, sarea_priv->boxes, sarea_priv->nbox); } @@ -1527,7 +1624,7 @@ static inline int radeon_emit_scalars( int start = header.scalars.offset; int stride = header.scalars.stride; RING_LOCALS; - DRM_DEBUG( " %s\n", __FUNCTION__ ); +/* printk( " %s\n", __FUNCTION__ ); */ BEGIN_RING( 3+sz ); OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) ); @@ -1558,17 +1655,22 @@ static inline int radeon_emit_vectors( /* printk( " %s (start %x stride %d count %d)\n", __FUNCTION__, */ /* start, stride, sz); */ - BEGIN_RING( 3+sz ); - OUT_RING( CP_PACKET0( RADEON_SE_TCL_VECTOR_INDX_REG, 0 ) ); - OUT_RING( start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT)); - OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_VECTOR_DATA_REG, (sz-1) ) ); - for ( i = 0 ; i < sz ; i++ ) { - if (__get_user( tmp, &data[i] )) - return -EFAULT; +/* if (start == 122) { */ +/* printk("skipping GLT\n"); */ +/* } else */ + { + BEGIN_RING( 3+sz ); + OUT_RING( CP_PACKET0( RADEON_SE_TCL_VECTOR_INDX_REG, 0 ) ); + OUT_RING( start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT)); + OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_VECTOR_DATA_REG, (sz-1) ) ); + for ( i = 0 ; i < sz ; i++ ) { + if (__get_user( tmp, &data[i] )) + return -EFAULT; /* printk("%d: %x\n", i, tmp); */ - OUT_RING( tmp ); - } - ADVANCE_RING(); + OUT_RING( tmp ); + } + ADVANCE_RING(); + } cmdbuf->buf += sz * sizeof(int); cmdbuf->bufsz -= sz * sizeof(int); @@ -1580,7 +1682,7 @@ static int radeon_emit_primitive( drm_buf_t *buf, drm_radeon_cmd_buffer_t *cmdbuf ) { - drm_radeon_prim_t prim; + drm_radeon_tcl_prim_t prim; if (cmdbuf->bufsz < sizeof(prim)) return -EFAULT; @@ -1589,6 +1691,16 @@ static int radeon_emit_primitive( return -EFAULT; +/* printk( "%s: hwprim 0x%x vfmt 0x%x %d..%d %d verts \n", */ +/* __FUNCTION__, */ +/* prim.prim, */ +/* prim.vc_format, */ +/* prim.start, */ +/* prim.finish, */ +/* (prim.prim & RADEON_PRIM_WALK_IND) */ +/* ? ((prim.finish-prim.start-20)/2) */ +/* : prim.numverts); */ + if ( prim.prim & RADEON_PRIM_WALK_IND ) { radeon_cp_dispatch_indices( dev, buf, &prim, cmdbuf->boxes, @@ -1604,6 +1716,10 @@ static int radeon_emit_primitive( cmdbuf->buf += sizeof(prim); cmdbuf->bufsz -= sizeof(prim); + + +/* printk( "%s: DONE\n", __FUNCTION__); */ + return 0; } @@ -1655,7 +1771,7 @@ int radeon_cp_cmdbuf( struct inode *inode, struct file *filp, DRM_ERROR("__get_user %p\n", cmdbuf.buf); return -EFAULT; } -/* printk("cmdbuf.buf: %x/%x\n", cmdbuf.buf, header.i); */ +/* printk("cmdbuf.buf: %x/%x\n", cmdbuf.buf, header.i); */ cmdbuf.buf += sizeof(header); cmdbuf.bufsz -= sizeof(header); |