diff options
-rw-r--r-- | linux/radeon_state.c | 140 |
1 files changed, 118 insertions, 22 deletions
diff --git a/linux/radeon_state.c b/linux/radeon_state.c index 5efa447a..2f7b7c14 100644 --- a/linux/radeon_state.c +++ b/linux/radeon_state.c @@ -747,6 +747,54 @@ static void radeon_cp_dispatch_vertex( drm_device_t *dev, sarea_priv->nbox, prim->start, prim->finish, prim->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 ); + return; + } + + buf_priv->dispatched = 1; do { @@ -855,6 +903,51 @@ static void radeon_cp_dispatch_indices( drm_device_t *dev, prim->start, start, prim->finish, count, prim->numverts, offset ); + 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 %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 ); + return; + } + if ( start < prim->finish ) { buf_priv->dispatched = 1; @@ -1221,30 +1314,33 @@ int radeon_cp_vertex( struct inode *inode, struct file *filp, buf->used = vertex.count; /* not used? */ - if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { - radeon_emit_state( dev_priv, - &sarea_priv->context_state, - sarea_priv->tex_state, - sarea_priv->dirty ); + if (vertex.count) { + if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { + radeon_emit_state( dev_priv, + &sarea_priv->context_state, + sarea_priv->tex_state, + sarea_priv->dirty ); + + sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | + RADEON_UPLOAD_TEX1IMAGES | + RADEON_UPLOAD_TEX2IMAGES | + RADEON_REQUIRE_QUIESCENCE); + } - sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | - RADEON_UPLOAD_TEX1IMAGES | - RADEON_UPLOAD_TEX2IMAGES | - RADEON_REQUIRE_QUIESCENCE); + /* Build up a prim_t record: + */ + 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; + + radeon_cp_dispatch_vertex( dev, buf, &prim ); } - /* Build up a prim_t record: - */ - 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; - - radeon_cp_dispatch_vertex( dev, buf, &prim ); if (vertex.discard) { - radeon_cp_discard_buffer( dev, buf ); + radeon_cp_discard_buffer( dev, buf ); } return 0; @@ -1336,10 +1432,10 @@ int radeon_cp_indices( struct inode *inode, struct file *filp, /* Build up a prim_t record: */ prim.start = elts.start; - prim.finish = elts.end; /* unused */ + prim.finish = elts.end; prim.prim = elts.prim; prim.stateidx = 0xff; /* unused */ - prim.numverts = count; + prim.numverts = 0; /* indexed from start of dma area */ prim.vc_format = dev_priv->sarea_priv->vc_format; radeon_cp_dispatch_indices( dev, buf, &prim ); |