Fix backwards compatibility bug, add tests for good numbers of
authorKeith Whitwell <keith@tungstengraphics.com>
Fri, 8 Mar 2002 16:03:37 +0000 (16:03 +0000)
committerKeith Whitwell <keith@tungstengraphics.com>
Fri, 8 Mar 2002 16:03:37 +0000 (16:03 +0000)
    vertices/prim.

linux/radeon_state.c

index 5efa447..2f7b7c1 100644 (file)
@@ -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 );