Philipp Klaus Krause wrote:
Roland found out how to do bigger aliased points on r200 hardware a long
time ago. AFAIK the patch was never applied since people failed to see
it's importance.

3D modellers use points to mark the currently selected vertices. A
maximum point size of 1 means they are invisible with today's screen
resolutions. This makes the r200 DRI driver useless for 3D modelling
with those applications. Bigger point sizes are really necessary!

Roland's patch supported only aliased points, but since the maximum
point sizes for aliased and antialised points can be different that
would never cause a software fallback. I know that the popular free
wings3d modeller uses only aliased points and think that it's the same
with other 3d modellers.
Ok here's a patch. It needs a semi-recent drm. It is downright trivial, all points with size != 1.0 are simply rendered with the point sprite primitive. Up to size 2047.0 - that should be enough for everyone :-).
No point parameters or point sprites for now.
In fact it would be possible to do it without a new drm - since the hardware can clamp the point size. But I'm not too sure if it's a good idea to do the point size calculation with unconfigured inputs and then simply clamping the result. One thing which is slightly confusing though is the register name, R200_SE_TCL_POINT_SPRITE_CNTL seems to imply this only works when using hw tcl. Now I don't doubt the point attenuation calculation will only work when using hw tcl, but I can't see a reason why the selection bit would not work with sw tcl (and I'd hope the point sprite tex coord generation would work with sw tcl too, otherwise there'd be a big problem when for some other reason there's a tcl fallback - it's impossible to manually attach 4 sets of tex coords to a single vertex I guess). Works fine for me with tcl_mode=0, but I don't have hardware which doesn't have tcl hardware (only IGP 9100 family doesn't have tcl). If it doesn't work there we'd need to submit the point size as a vertex parameter (which has the nice side-effect of getting ARB_point_parameter for free for the sw tcl case).

Roland
Index: r200_cmdbuf.c
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r200/r200_cmdbuf.c,v
retrieving revision 1.17
diff -u -r1.17 r200_cmdbuf.c
--- r200_cmdbuf.c       12 Sep 2005 21:20:10 -0000      1.17
+++ r200_cmdbuf.c       30 Sep 2005 22:55:49 -0000
@@ -108,6 +108,7 @@
    for (i = 0; i < 6; ++i)
        insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.ucp[i] );
    /* FIXME: is this a good place to insert that atom ? */
+   insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.spr );
    insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.prf );
 }
 
Index: r200_context.c
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r200/r200_context.c,v
retrieving revision 1.51
diff -u -r1.51 r200_context.c
--- r200_context.c      12 Sep 2005 21:20:10 -0000      1.51
+++ r200_context.c      30 Sep 2005 22:55:49 -0000
@@ -400,12 +400,19 @@
 
    ctx->Const.MaxTextureMaxAnisotropy = 16.0;
 
-   /* No wide points.
+   /* No wide AA points.
     */
    ctx->Const.MinPointSize = 1.0;
    ctx->Const.MinPointSizeAA = 1.0;
-   ctx->Const.MaxPointSize = 1.0;
    ctx->Const.MaxPointSizeAA = 1.0;
+   ctx->Const.PointSizeGranularity = 0.0625;
+   if (rmesa->r200Screen->drmSupportsPointSprites)
+      ctx->Const.MaxPointSize = 2047.0;
+   else
+      ctx->Const.MaxPointSize = 1.0;
+
+   /* mesa initialization problem - _mesa_init_point was already called */
+   ctx->Point.MaxSize = ctx->Const.MaxPointSize;
 
    ctx->Const.MinLineWidth = 1.0;
    ctx->Const.MinLineWidthAA = 1.0;
Index: r200_context.h
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r200/r200_context.h,v
retrieving revision 1.33
diff -u -r1.33 r200_context.h
--- r200_context.h      12 Sep 2005 21:20:10 -0000      1.33
+++ r200_context.h      30 Sep 2005 22:55:50 -0000
@@ -397,6 +397,11 @@
 #define VTX_STATE_CNTL          8
 #define VTX_STATE_SIZE          9
 
+/* SPR - point sprite state
+ */
+#define SPR_CMD_0             0
+#define SPR_POINT_SPRITE_CNTL 1
+#define SPR_STATE_SIZE        2
 
 #define VTX_COLOR(v,n)   (((v)>>(R200_VTX_COLOR_0_SHIFT+(n)*2))&\
                          R200_VTX_COLOR_MASK)
@@ -559,6 +564,7 @@
    struct r200_state_atom prf;
    struct r200_state_atom afs[2];
    struct r200_state_atom atf;
+   struct r200_state_atom spr;
 
    int max_state_size; /* Number of bytes necessary for a full state emit. */
    GLboolean is_dirty, all_dirty;
Index: r200_screen.c
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r200/r200_screen.c,v
retrieving revision 1.49
diff -u -r1.49 r200_screen.c
--- r200_screen.c       12 Sep 2005 21:20:10 -0000      1.49
+++ r200_screen.c       30 Sep 2005 22:55:50 -0000
@@ -360,6 +360,7 @@
         screen->drmSupportsBlendColor = (sPriv->drmMinor >= 11);
         screen->drmSupportsTriPerf = (sPriv->drmMinor >= 16);
         screen->drmSupportsFragShader = (sPriv->drmMinor >= 18);
+        screen->drmSupportsPointSprites = (sPriv->drmMinor >= 13);
 
       }
       /* Check if ddx has set up a surface reg to cover depth buffer */
Index: r200_screen.h
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r200/r200_screen.h,v
retrieving revision 1.16
diff -u -r1.16 r200_screen.h
--- r200_screen.h       12 Sep 2005 21:20:10 -0000      1.16
+++ r200_screen.h       30 Sep 2005 22:55:50 -0000
@@ -98,6 +98,7 @@
    GLboolean drmSupportsBlendColor;     /* need radeon kernel module >= 1.11 */
    GLboolean drmSupportsTriPerf;        /* need radeon kernel module >= 1.16 */
    GLboolean drmSupportsFragShader;     /* need radeon kernel module >= 1.18 */
+   GLboolean drmSupportsPointSprites;   /* need radeon kernel module >= 1.13 */
    GLboolean depthHasSurface;
 
    /* Configuration cache with default values for all contexts */
Index: r200_state.c
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r200/r200_state.c,v
retrieving revision 1.38
diff -u -r1.38 r200_state.c
--- r200_state.c        14 Sep 2005 00:42:33 -0000      1.38
+++ r200_state.c        30 Sep 2005 22:55:51 -0000
@@ -689,7 +689,11 @@
  */
 static void r200PointSize( GLcontext *ctx, GLfloat size )
 {
-   if (0) fprintf(stderr, "%s: %f\n", __FUNCTION__, size );
+   r200ContextPtr rmesa = R200_CONTEXT(ctx);
+
+   R200_STATECHANGE( rmesa, cst );
+   rmesa->hw.cst.cmd[CST_RE_POINTSIZE] &= ~0xffff;
+   rmesa->hw.cst.cmd[CST_RE_POINTSIZE] |= ((GLuint)(ctx->Point.Size * 16.0));
 }
 
 /* =============================================================
@@ -1982,10 +1986,10 @@
       }
       break;
 
-      /* Pointsize registers on r200 don't seem to do anything.  Maybe
-       * have to pass pointsizes as vertex parameters?  In any case,
-       * setting pointmin == pointsizemax == 1.0, and doing nothing
-       * for aa is enough to satisfy conform.
+      /* Pointsize registers on r200 only work for point sprites, and point 
smooth
+       * doesn't work for point sprites (and isn't needed for 1.0 sized aa 
points).
+       * In any case, setting pointmin == pointsizemax == 1.0 for aa points
+       * is enough to satisfy conform.
        */
    case GL_POINT_SMOOTH:
       break;
Index: r200_state_init.c
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r200/r200_state_init.c,v
retrieving revision 1.24
diff -u -r1.24 r200_state_init.c
--- r200_state_init.c   12 Sep 2005 21:20:10 -0000      1.24
+++ r200_state_init.c   30 Sep 2005 22:55:52 -0000
@@ -352,6 +352,10 @@
    else {
       ALLOC_STATE( prf, never, PRF_STATE_SIZE, "PRF/performance-tri", 0 );
    }
+   if (rmesa->r200Screen->drmSupportsPointSprites)
+      ALLOC_STATE( spr, always, SPR_STATE_SIZE, "SPR/pointsprite", 0 );
+   else
+      ALLOC_STATE (spr, never, SPR_STATE_SIZE, "SPR/pointsprite", 0 );
 
    r200SetUpAtomList( rmesa );
 
@@ -436,6 +440,7 @@
    rmesa->hw.vtx.cmd[VTX_CMD_2] = cmdpkt(R200_EMIT_SE_VTX_STATE_CNTL);
    rmesa->hw.vte.cmd[VTE_CMD_0] = cmdpkt(R200_EMIT_VTE_CNTL);
    rmesa->hw.prf.cmd[PRF_CMD_0] = cmdpkt(R200_EMIT_PP_TRI_PERF_CNTL);
+   rmesa->hw.spr.cmd[SPR_CMD_0] = cmdpkt(R200_EMIT_TCL_POINT_SPRITE_CNTL);
    rmesa->hw.mtl[0].cmd[MTL_CMD_0] = 
       cmdvec( R200_VS_MAT_0_EMISS, 1, 16 );
    rmesa->hw.mtl[0].cmd[MTL_CMD_1] = 
@@ -640,7 +645,8 @@
       rmesa->hw.cst.cmd[CST_SE_VAP_CNTL_STATUS] |= (1<<8);
    }
 
-   rmesa->hw.cst.cmd[CST_RE_POINTSIZE] = 0x100010;
+   rmesa->hw.cst.cmd[CST_RE_POINTSIZE] =
+      (((GLuint)(ctx->Const.MaxPointSize * 16.0)) << R200_MAXPOINTSIZE_SHIFT) 
| 0x10;
    rmesa->hw.cst.cmd[CST_SE_TCL_INPUT_VTX_0] =
       (0x0 << R200_VERTEX_POSITION_ADDR__SHIFT);
    rmesa->hw.cst.cmd[CST_SE_TCL_INPUT_VTX_1] =
@@ -869,6 +875,8 @@
    rmesa->hw.eye.cmd[EYE_Z] = IEEE_ONE;
    rmesa->hw.eye.cmd[EYE_RESCALE_FACTOR] = IEEE_ONE;
 
+   rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] = R200_POINTSIZE_SEL_STATE;
+
    r200LightingSpaceChange( ctx );
    
    rmesa->hw.all_dirty = GL_TRUE;
Index: r200_swtcl.c
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r200/r200_swtcl.c,v
retrieving revision 1.27
diff -u -r1.27 r200_swtcl.c
--- r200_swtcl.c        1 Sep 2005 03:50:54 -0000       1.27
+++ r200_swtcl.c        30 Sep 2005 22:55:52 -0000
@@ -340,18 +340,24 @@
 /**************************************************************************/
 
 
-static const GLuint reduced_hw_prim[GL_POLYGON+1] = {
-   R200_VF_PRIM_POINTS,
-   R200_VF_PRIM_LINES,
-   R200_VF_PRIM_LINES,
-   R200_VF_PRIM_LINES,
-   R200_VF_PRIM_TRIANGLES,
-   R200_VF_PRIM_TRIANGLES,
-   R200_VF_PRIM_TRIANGLES,
-   R200_VF_PRIM_TRIANGLES,
-   R200_VF_PRIM_TRIANGLES,
-   R200_VF_PRIM_TRIANGLES
-};
+static INLINE GLuint reduced_hw_prim( GLcontext *ctx, GLuint prim)
+{
+   switch (prim) {
+   case GL_POINTS:
+      return (ctx->_TriangleCaps & DD_POINT_SIZE) ?
+        R200_VF_PRIM_POINT_SPRITES : R200_VF_PRIM_POINTS;
+   case GL_LINES:
+   /* fallthrough */
+   case GL_LINE_LOOP:
+   /* fallthrough */
+   case GL_LINE_STRIP:
+      return R200_VF_PRIM_LINES;
+   default:
+   /* all others reduced to triangles */
+      return R200_VF_PRIM_TRIANGLES;
+   }
+}
+
 
 static void r200RasterPrimitive( GLcontext *ctx, GLuint hwprim );
 static void r200RenderPrimitive( GLcontext *ctx, GLenum prim );
@@ -496,7 +502,7 @@
  *                Helpers for rendering unfilled primitives            *
  ***********************************************************************/
 
-#define RASTERIZE(x) r200RasterPrimitive( ctx, reduced_hw_prim[x] )
+#define RASTERIZE(x) r200RasterPrimitive( ctx, reduced_hw_prim(ctx, x) )
 #define RENDER_PRIMITIVE rmesa->swtcl.render_primitive
 #undef TAG
 #define TAG(x) x
@@ -631,7 +637,7 @@
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
    rmesa->swtcl.render_primitive = prim;
    if (prim < GL_TRIANGLES || !(ctx->_TriangleCaps & DD_TRI_UNFILLED)) 
-      r200RasterPrimitive( ctx, reduced_hw_prim[prim] );
+      r200RasterPrimitive( ctx, reduced_hw_prim(ctx, prim) );
 }
 
 static void r200RenderFinish( GLcontext *ctx )
Index: r200_tcl.c
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r200/r200_tcl.c,v
retrieving revision 1.22
diff -u -r1.22 r200_tcl.c
--- r200_tcl.c  9 Sep 2005 12:51:38 -0000       1.22
+++ r200_tcl.c  30 Sep 2005 22:55:53 -0000
@@ -68,7 +68,8 @@
 #define HAVE_ELTS        1
 
 
-#define HW_POINTS           R200_VF_PRIM_POINTS
+#define HW_POINTS           ((ctx->_TriangleCaps & DD_POINT_SIZE) ? \
+                               R200_VF_PRIM_POINT_SPRITES : 
R200_VF_PRIM_POINTS)
 #define HW_LINES            R200_VF_PRIM_LINES
 #define HW_LINE_LOOP        0
 #define HW_LINE_STRIP       R200_VF_PRIM_LINE_STRIP

Reply via email to