summaryrefslogtreecommitdiff
path: root/linux
diff options
context:
space:
mode:
Diffstat (limited to 'linux')
-rw-r--r--linux/radeon_state.c140
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 );