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)