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)