On Thu, Jul 17, 2003 at 08:03:47AM -0500, Keith Whitwell wrote:
> Ian Romanick wrote:
> >Keith Whitwell wrote:
> >
> >>
> >>
> >>As you state, the trouble with this patch is that all rasterization 
> >>falls back to software when poinsize != 1, even if no points are 
> >>actually rendered.
> >>
> >>To get good behaviour you really need to do something a little different.
> >>
> >>First, yes, you will want a rasterization fallback for points.  That 
> >>means at least you have to turn of HW TCL when (pointsize != 1), 
> >>otherwise you won't find it so easy to catch points with the existing 
> >>infrastructure.  (We could try & get fancy, but let's keep it simpler).
> >>
> >>Then, have a look at radeonChooseRenderState() in radeon_swtcl.c.  In 
> >>here you will need to figure out how to hook in a software 
> >>rasterization fallback *only* for points.  This isn't something the 
> >>radeon driver currently does, but other drivers *do*.  Take a look at 
> >>the equivalent function in the mga driver  -- mgaChooseRenderState() 
> >>-- which does hook in per-primitive-type fallbacks.
> >
> >
> >Shouldn't it be possible to simulate large (or small) points by 
> >replacing them with a polygon?  There would be some trickery involved to 
> >get it right, but I'd thing that on TCL hardware this would be a much 
> >better way to go.  Could this be done by adding another pipeline stage? 
> > I've kind of permanently kept this issue on my back-burner, but it 
> >seems to be heating up lately. :)  Maybe it's time to stir the pot...
> 
> Yep, in fact emitting a polygon in this fallback is probably a better idea 
> (and easier) than trying to go to software rendering.  In fact all the old 
> drivers do it this way -- emit two triangles in the point routine.
> 
> Keith
> 
Attached is another point size patch. Thanks for taking the time to look
through my first patch. This one uses per-primitive fallbacks as you suggested.

I originally had radeon_point_fallback calling swrast but this caused a lot of
rendering glitches (I'm fairly certain the Z-buffer format was responsible).
Currently I'm altering the reduced_hw_prim and hw_prim values and emitting two
triangles when the fallback is in effect.

So far it seems to be a big improvement from the original hack but it's still a
work in progress.
  
Dylan
Index: xc/lib/GL/mesa/src/drv/radeon/radeon_context.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c,v
retrieving revision 1.39
diff -u -r1.39 radeon_context.c
--- xc/lib/GL/mesa/src/drv/radeon/radeon_context.c      10 Jun 2003 18:50:43 -0000     
 1.39
+++ xc/lib/GL/mesa/src/drv/radeon/radeon_context.c      19 Jul 2003 14:26:04 -0000
@@ -318,11 +318,12 @@
 
    /* No wide points.
     */
+   /*
    ctx->Const.MinPointSize = 1.0;
    ctx->Const.MinPointSizeAA = 1.0;
    ctx->Const.MaxPointSize = 1.0;
    ctx->Const.MaxPointSizeAA = 1.0;
-
+   */
    ctx->Const.MinLineWidth = 1.0;
    ctx->Const.MinLineWidthAA = 1.0;
    ctx->Const.MaxLineWidth = 10.0;
Index: xc/lib/GL/mesa/src/drv/radeon/radeon_state.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c,v
retrieving revision 1.29
diff -u -r1.29 radeon_state.c
--- xc/lib/GL/mesa/src/drv/radeon/radeon_state.c        9 Jun 2003 23:13:22 -0000      
 1.29
+++ xc/lib/GL/mesa/src/drv/radeon/radeon_state.c        19 Jul 2003 14:26:10 -0000
@@ -622,6 +622,25 @@
 
 
 /* =============================================================
+ * Point state
+ */
+static void radeonPointSize( GLcontext *ctx, GLfloat size )
+{
+   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+   /* I'm going to use Mesa's point size != 1.0 flag for consistency. It really
+    * should be changed to allow for floating point variability.
+    */
+   TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_UNFILLED, (ctx->_TriangleCaps & 
DD_POINT_SIZE) != 0);
+   if (rmesa->TclFallback) {
+      radeonChooseRenderState( ctx );
+      /* I'm not sure if I need to call this, but it won't hurt much.
+       */
+      radeonChooseVertexState( ctx );
+   }
+}
+
+
+/* =============================================================
  * Polygon state
  */
 
@@ -2135,6 +2154,7 @@
    ctx->Driver.LineStipple              = radeonLineStipple;
    ctx->Driver.LineWidth                = radeonLineWidth;
    ctx->Driver.LogicOpcode             = radeonLogicOpCode;
+   ctx->Driver.PointSize                = radeonPointSize;
    ctx->Driver.PolygonMode             = radeonPolygonMode;
 
    if (RADEON_CONTEXT(ctx)->dri.drmMinor > 1)
Index: xc/lib/GL/mesa/src/drv/radeon/radeon_swtcl.c
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_swtcl.c,v
retrieving revision 1.19
diff -u -r1.19 radeon_swtcl.c
--- xc/lib/GL/mesa/src/drv/radeon/radeon_swtcl.c        10 Jun 2003 18:50:46 -0000     
 1.19
+++ xc/lib/GL/mesa/src/drv/radeon/radeon_swtcl.c        19 Jul 2003 14:26:14 -0000
@@ -531,7 +531,7 @@
 #define HAVE_POLYGONS    0
 #define HAVE_ELTS        1
 
-static const GLuint hw_prim[GL_POLYGON+1] = {
+static GLuint hw_prim[GL_POLYGON+1] = {
    RADEON_CP_VC_CNTL_PRIM_TYPE_POINT,
    RADEON_CP_VC_CNTL_PRIM_TYPE_LINE,
    0,
@@ -701,7 +701,7 @@
            return GL_TRUE;     /* too many vertices */
    }
 
-   for (i = 0 ; !(flags & PRIM_LAST) ; i += length)
+   for (i = VB->FirstPrimitive ; !(flags & PRIM_LAST) ; i += length)
    {
       flags = VB->Primitive[i];
       length = VB->PrimitiveLength[i];
@@ -898,7 +898,7 @@
 /**************************************************************************/
 
 
-static const GLuint reduced_hw_prim[GL_POLYGON+1] = {
+static GLuint reduced_hw_prim[GL_POLYGON+1] = {
    RADEON_CP_VC_CNTL_PRIM_TYPE_POINT,
    RADEON_CP_VC_CNTL_PRIM_TYPE_LINE,
    RADEON_CP_VC_CNTL_PRIM_TYPE_LINE,
@@ -944,7 +944,72 @@
 #define QUAD( a, b, c, d ) radeon_quad( rmesa, a, b, c, d )
 #define TRI( a, b, c )     radeon_triangle( rmesa, a, b, c )
 #define LINE( a, b )       radeon_line( rmesa, a, b )
-#define POINT( a )         radeon_point( rmesa, a )
+#define POINT( a )                          \
+do {                                        \
+   if (DO_FALLBACK) {                       \
+      radeon_fallback_point( rmesa, a );    \
+   } else {                                 \
+      radeon_point( rmesa, a );             \
+   }                                        \
+} while (0)
+
+/***********************************************************************
+ *              Fallback to swrast for basic primitives                *
+ ***********************************************************************/
+
+static __inline void radeon_fallback_point( radeonContextPtr rmesa, 
+                                           radeonVertexPtr tmp )
+{
+   GLfloat sx = rmesa->glCtx->Point._Size / (GLfloat)rmesa->glCtx->Viewport.Width;
+   GLfloat sy = rmesa->glCtx->Point._Size / (GLfloat)rmesa->glCtx->Viewport.Height;
+   int vertex_size = rmesa->swtcl.vertex_size;
+   GLuint *vb = radeonAllocDmaLowVerts( rmesa, 6, 4 * vertex_size );
+   int j;
+
+   /* Draw a point as two triangles.
+    */
+   *(float *)&vb[0] = tmp->v.x - sx;
+   *(float *)&vb[1] = tmp->v.y - sy;
+   for (j = 2 ; j < vertex_size ; j++)
+      vb[j] = tmp->ui[j];
+   vb += vertex_size;
+
+   *(float *)&vb[0] = tmp->v.x + sx;
+   *(float *)&vb[1] = tmp->v.y - sy;
+   for (j = 2 ; j < vertex_size ; j++)
+      vb[j] = tmp->ui[j];
+   vb += vertex_size;
+
+   *(float *)&vb[0] = tmp->v.x + sx;
+   *(float *)&vb[1] = tmp->v.y + sy;
+   for (j = 2 ; j < vertex_size ; j++)
+      vb[j] = tmp->ui[j];
+   vb += vertex_size;
+
+   *(float *)&vb[0] = tmp->v.x + sx;
+   *(float *)&vb[1] = tmp->v.y + sy;
+   for (j = 2 ; j < vertex_size ; j++)
+      vb[j] = tmp->ui[j];
+   vb += vertex_size;
+
+   *(float *)&vb[0] = tmp->v.x - sx;
+   *(float *)&vb[1] = tmp->v.y + sy;
+   for (j = 2 ; j < vertex_size ; j++)
+      vb[j] = tmp->ui[j];
+   vb += vertex_size;
+
+   *(float *)&vb[0] = tmp->v.x - sx;
+   *(float *)&vb[1] = tmp->v.y - sy;
+   for (j = 2 ; j < vertex_size ; j++) 
+      vb[j] = tmp->ui[j];
+   /*
+   GLcontext *ctx = rmesa->glCtx;
+   SWvertex v[1];
+   radeon_translate_vertex( ctx, v0, &v[0] );
+   _swrast_Point( ctx, &v[0] );
+   */
+}
+
 
 /***********************************************************************
  *              Build render functions from dd templates               *
@@ -953,8 +1018,8 @@
 #define RADEON_TWOSIDE_BIT     0x01
 #define RADEON_UNFILLED_BIT    0x02
 #define RADEON_OFFSET_BIT      0x04 /* drmMinor == 1 */
-#define RADEON_MAX_TRIFUNC     0x08
-
+#define RADEON_FALLBACK_BIT     0x08 /* DD_POINT_SIZE */
+#define RADEON_MAX_TRIFUNC     0x10
 
 static struct {
    points_func         points;
@@ -964,7 +1029,7 @@
 } rast_tab[RADEON_MAX_TRIFUNC];
 
 
-#define DO_FALLBACK  0
+#define DO_FALLBACK (IND & RADEON_FALLBACK_BIT)
 #define DO_OFFSET   (IND & RADEON_OFFSET_BIT)
 #define DO_UNFILLED (IND & RADEON_UNFILLED_BIT)
 #define DO_TWOSIDE  (IND & RADEON_TWOSIDE_BIT)
@@ -1025,6 +1090,7 @@
 #define RASTERIZE(x) radeonRasterPrimitive( ctx, reduced_hw_prim[x] )
 #define RENDER_PRIMITIVE rmesa->swtcl.render_primitive
 #undef TAG
+#define IND (0)
 #define TAG(x) x
 #include "tnl_dd/t_dd_unfilled.h"
 #undef IND
@@ -1034,7 +1100,6 @@
  *                      Generate GL render functions                   *
  ***********************************************************************/
 
-
 #define IND (0)
 #define TAG(x) x
 #include "tnl_dd/t_dd_tritmp.h"
@@ -1067,6 +1132,38 @@
 #define TAG(x) x##_twoside_unfilled_offset
 #include "tnl_dd/t_dd_tritmp.h"
 
+#define IND (RADEON_FALLBACK_BIT)
+#define TAG(x) x##_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (RADEON_TWOSIDE_BIT|RADEON_FALLBACK_BIT)
+#define TAG(x) x##_twoside_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (RADEON_UNFILLED_BIT|RADEON_FALLBACK_BIT)
+#define TAG(x) x##_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (RADEON_TWOSIDE_BIT|RADEON_UNFILLED_BIT|RADEON_FALLBACK_BIT)
+#define TAG(x) x##_twoside_unfilled_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (RADEON_OFFSET_BIT|RADEON_FALLBACK_BIT)
+#define TAG(x) x##_offset_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (RADEON_TWOSIDE_BIT|RADEON_OFFSET_BIT|RADEON_FALLBACK_BIT)
+#define TAG(x) x##_twoside_offset_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND (RADEON_UNFILLED_BIT|RADEON_OFFSET_BIT|RADEON_FALLBACK_BIT)
+#define TAG(x) x##_unfilled_offset_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
+#define IND 
(RADEON_TWOSIDE_BIT|RADEON_UNFILLED_BIT|RADEON_OFFSET_BIT|RADEON_FALLBACK_BIT)
+#define TAG(x) x##_twoside_unfilled_offset_fallback
+#include "tnl_dd/t_dd_tritmp.h"
+
 
 static void init_rast_tab( void )
 {
@@ -1078,6 +1175,14 @@
    init_twoside_offset();
    init_unfilled_offset();
    init_twoside_unfilled_offset();
+   init_fallback();
+   init_twoside_fallback();
+   init_unfilled_fallback();
+   init_twoside_unfilled_fallback();
+   init_offset_fallback();
+   init_twoside_offset_fallback();
+   init_unfilled_offset_fallback();
+   init_twoside_unfilled_offset_fallback();
 }
 
 /**********************************************************************/
@@ -1138,6 +1243,18 @@
    if (flags & DD_TRI_UNFILLED)      index |= RADEON_UNFILLED_BIT;
    if ((flags & DD_TRI_OFFSET) &&
        rmesa->dri.drmMinor == 1)  index |= RADEON_OFFSET_BIT;
+
+
+   if (flags & DD_POINT_SIZE) {
+          index |= RADEON_FALLBACK_BIT;
+          reduced_hw_prim[0] = RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST;
+          hw_prim[0] = RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST;
+          /*  rmesa->swtcl.draw_point = radeon_fallback_point; */
+   } else {
+          reduced_hw_prim[0] = RADEON_CP_VC_CNTL_PRIM_TYPE_POINT;
+          hw_prim[0] = RADEON_CP_VC_CNTL_PRIM_TYPE_POINT;
+          /*      rmesa->swtcl.draw_point = radeon_point; */
+   }
 
    if (index != rmesa->swtcl.RenderIndex) {
       tnl->Driver.Render.Points = rast_tab[index].points;
Index: xc/lib/GL/mesa/src/drv/radeon/radeon_tcl.h
===================================================================
RCS file: /cvsroot/dri/xc/xc/lib/GL/mesa/src/drv/radeon/radeon_tcl.h,v
retrieving revision 1.5
diff -u -r1.5 radeon_tcl.h
--- xc/lib/GL/mesa/src/drv/radeon/radeon_tcl.h  10 Jun 2003 18:50:47 -0000      1.5
+++ xc/lib/GL/mesa/src/drv/radeon/radeon_tcl.h  19 Jul 2003 14:26:15 -0000
@@ -60,6 +60,7 @@
 #define RADEON_TCL_FALLBACK_TEXRECT_0         0x100 /* texture rectangle */
 #define RADEON_TCL_FALLBACK_TEXRECT_1         0x200 /* texture rectangle */
 #define RADEON_TCL_FALLBACK_TEXRECT_2         0x400 /* texture rectangle */
+#define RADEON_TCL_FALLBACK_POINT_SIZE        0x800 /* point size != 1.0 */
 
 #define RADEON_MAX_TCL_VERTSIZE (15*4)
 

Reply via email to