Hi,

while working on the savage driver I found two problems. One with
tnl/t_vb_render.c, the other one with tnl_dd/t_dd_tritmp.h. Both started
since I use different hardware primitives for quads and
triangles/polygons.

TAG(quad) in t_dd_tritmp.h calls RASTERIZE( GL_TRIANGLES ) directly
before QUAD( (v[0]), (v[1]), (v[2]), (v[3]) ). RASTERIZE should be
called with GL_QUADS so that the driver selects the correct hardware
primitive. Also I believe that we could use the same condition as in
TAG(triangle), namely

      if (DO_UNFILLED)
         RASTERIZE( GL_QUADS );

I wonder when this condition will be true anyway. But without this
RASTERIZE is called for every single quad!

The second problem is in t_vb_render.c with clipped primitives. When a
clipped primitive is rendered the PrimitiveNotify callback gets called
with GL_POLYGON. When the next unclipped primitive is drawn we have to
call PrimitiveNotify again with the original primitive type.

The attached patch fixes both problems. I'm going to apply this to the
savage-2-0-0-branch in DRI CVS. It looks like Mesa-newtree has the same
problems. Should I commit it there too.

Regards,
  Felix

------------    __\|/__    ___     ___       -------------------------
 Felix       ___\_e -_/___/ __\___/ __\_____   You can do anything,
   Kühling  (_____\Ä/____/ /_____/ /________)  just not everything
 [EMAIL PROTECTED]       \___/   \___/   U        at the same time.
--- ./tnl/t_vb_render.c.~1.9.~  2003-04-03 23:30:38.000000000 +0200
+++ ./tnl/t_vb_render.c 2003-12-19 21:37:05.000000000 +0100
@@ -99,20 +99,32 @@
 do {                                           \
    GLubyte c1 = mask[v1], c2 = mask[v2];       \
    GLubyte ormask = c1|c2;                     \
-   if (!ormask)                                        \
+   if (!ormask)        {                               \
+      if (lastClipped) {                       \
+         tnl->Driver.Render.PrimitiveNotify( ctx, prim );      \
+         lastClipped = GL_FALSE;               \
+      }                                                \
       LineFunc( ctx, v1, v2 );                 \
-   else if (!(c1 & c2 & 0x3f))                 \
+   } else if (!(c1 & c2 & 0x3f)) {             \
       clip_line_4( ctx, v1, v2, ormask );      \
+      lastClipped = GL_TRUE;                   \
+   }                                           \
 } while (0)
 
 #define RENDER_TRI( v1, v2, v3 )                       \
 do {                                                   \
    GLubyte c1 = mask[v1], c2 = mask[v2], c3 = mask[v3];        \
    GLubyte ormask = c1|c2|c3;                          \
-   if (!ormask)                                                \
+   if (!ormask)        {                                       \
+      if (lastClipped) {                               \
+         tnl->Driver.Render.PrimitiveNotify( ctx, prim );      \
+         lastClipped = GL_FALSE;                       \
+      }                                                        \
       TriangleFunc( ctx, v1, v2, v3 );                 \
-   else if (!(c1 & c2 & c3 & 0x3f))                    \
+   } else if (!(c1 & c2 & c3 & 0x3f)) {                        \
       clip_tri_4( ctx, v1, v2, v3, ormask );           \
+      lastClipped = GL_TRUE;                           \
+   }                                                   \
 } while (0)
 
 #define RENDER_QUAD( v1, v2, v3, v4 )                  \
@@ -120,10 +132,16 @@
    GLubyte c1 = mask[v1], c2 = mask[v2];               \
    GLubyte c3 = mask[v3], c4 = mask[v4];               \
    GLubyte ormask = c1|c2|c3|c4;                       \
-   if (!ormask)                                                \
+   if (!ormask)        {                                       \
+      if (lastClipped) {                               \
+         tnl->Driver.Render.PrimitiveNotify( ctx, prim );      \
+         lastClipped = GL_FALSE;                       \
+      }                                                        \
       QuadFunc( ctx, v1, v2, v3, v4 );                 \
-   else if (!(c1 & c2 & c3 & c4 & 0x3f))               \
+   } else if (!(c1 & c2 & c3 & c4 & 0x3f)) {           \
       clip_quad_4( ctx, v1, v2, v3, v4, ormask );      \
+      lastClipped = GL_TRUE;                           \
+   }                                                   \
 } while (0)
 
 
@@ -137,11 +155,16 @@
    const triangle_func TriangleFunc = tnl->Driver.Render.Triangle;     \
    const quad_func QuadFunc = tnl->Driver.Render.Quad;         \
    const GLboolean stipple = ctx->Line.StippleFlag;            \
+   GLenum prim;                                                        \
+   GLboolean lastClipped = GL_FALSE;                           \
    (void) (LineFunc && TriangleFunc && QuadFunc);              \
-   (void) elt; (void) mask; (void) sz; (void) stipple;
+   (void) elt; (void) mask; (void) sz; (void) stipple; (void) lastClipped;
 
 #define TAG(x) clip_##x##_verts
-#define INIT(x) tnl->Driver.Render.PrimitiveNotify( ctx, x )
+#define INIT(x) do {                                             \
+                   tnl->Driver.Render.PrimitiveNotify( ctx, x ); \
+                   prim = x;                                     \
+                } while (0)
 #define RESET_STIPPLE if (stipple) tnl->Driver.Render.ResetLineStipple( ctx )
 #define RESET_OCCLUSION ctx->OcclusionResult = GL_TRUE
 #define PRESERVE_VB_DEFS
--- ./tnl_dd/t_dd_tritmp.h.~1.8.~       2003-04-03 23:30:43.000000000 +0200
+++ ./tnl_dd/t_dd_tritmp.h      2003-12-19 20:57:38.000000000 +0100
@@ -526,7 +526,8 @@
         VERT_Z_ADD(v[2], offset);
         VERT_Z_ADD(v[3], offset);
       }
-      RASTERIZE( GL_TRIANGLES );
+      if (DO_UNFILLED)
+        RASTERIZE( GL_QUADS );
       QUAD( (v[0]), (v[1]), (v[2]), (v[3]) );
    }
 

Reply via email to