implement ARB_point_parameters and ARB_point_sprite on r200. The code is nearly the...
authorRoland Scheidegger <rscheidegger@gmx.ch>
Fri, 13 Oct 2006 22:10:05 +0000 (22:10 +0000)
committerRoland Scheidegger <rscheidegger@gmx.ch>
Fri, 13 Oct 2006 22:10:05 +0000 (22:10 +0000)
src/mesa/drivers/dri/r200/r200_cmdbuf.c
src/mesa/drivers/dri/r200/r200_context.c
src/mesa/drivers/dri/r200/r200_context.h
src/mesa/drivers/dri/r200/r200_reg.h
src/mesa/drivers/dri/r200/r200_state.c
src/mesa/drivers/dri/r200/r200_state_init.c
src/mesa/drivers/dri/r200/r200_swtcl.c
src/mesa/drivers/dri/r200/r200_tcl.c
src/mesa/drivers/dri/r200/r200_tex.c
src/mesa/drivers/dri/radeon/radeon_screen.c

index 91737d2d33c21e461f33b80520754124d4ddba3d..2920ceafd303812db99c1e2aa5551226f07798e8 100644 (file)
@@ -107,8 +107,8 @@ void r200SetUpAtomList( r200ContextPtr rmesa )
       insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.mtl[i] );
    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.ptp );
    insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.prf );
    insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.pvs );
    insert_at_tail( &rmesa->hw.atomlist, &rmesa->hw.vpp[0] );
index 37abaa38de8e6a2252f170466f40f8a8b942f749..2e55ac1f50e03f961fd21bd5ece92e868d6e9c7f 100644 (file)
@@ -75,6 +75,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define need_GL_EXT_blend_equation_separate
 #define need_GL_EXT_blend_func_separate
 #define need_GL_NV_vertex_program
+#define need_GL_ARB_point_parameters
 #include "extension_helper.h"
 
 #define DRIVER_DATE    "20060602"
@@ -170,7 +171,7 @@ const struct dri_extension blend_extensions[] = {
     { "GL_EXT_blend_func_separate",        GL_EXT_blend_func_separate_functions },
     { NULL,                                NULL }
 };
-                                                        
+
 const struct dri_extension ARB_vp_extension[] = {
     { "GL_ARB_vertex_program",             GL_ARB_vertex_program_functions }
 };
@@ -183,6 +184,12 @@ const struct dri_extension ATI_fs_extension[] = {
     { "GL_ATI_fragment_shader",            GL_ATI_fragment_shader_functions }
 };
 
+const struct dri_extension point_extensions[] = {
+    { "GL_ARB_point_sprite",               NULL },
+    { "GL_ARB_point_parameters",           GL_ARB_point_parameters_functions },
+    { NULL,                                NULL }
+};
+
 extern const struct tnl_pipeline_stage _r200_render_stage;
 extern const struct tnl_pipeline_stage _r200_tcl_stage;
 
@@ -200,9 +207,9 @@ static const struct tnl_pipeline_stage *r200_pipeline[] = {
    &_tnl_fog_coordinate_stage,
    &_tnl_texgen_stage,
    &_tnl_texture_transform_stage,
+   &_tnl_point_attenuation_stage,
    &_tnl_arb_vertex_program_stage,
    &_tnl_vertex_program_stage,
-
    /* Try again to go to tcl? 
     *     - no good for asymmetric-twoside (do with multipass)
     *     - no good for asymmetric-unfilled (do with multipass)
@@ -485,6 +492,8 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
 
    if ((ctx->Const.MaxTextureUnits == 6) && rmesa->r200Screen->drmSupportsFragShader)
       driInitSingleExtension( ctx, ATI_fs_extension );
+   if (rmesa->r200Screen->drmSupportsPointSprites)
+      driInitExtensions( ctx, point_extensions, GL_FALSE );
 #if 0
    r200InitDriverFuncs( ctx );
    r200InitIoctlFuncs( ctx );
index b7ee33aa6c988d2d83e0c0a3523420fd60060d23..0d252eceafa56f375202c6d8e28fbf7ea1ea8390 100644 (file)
@@ -445,9 +445,29 @@ struct r200_state_atom {
 
 /* SPR - point sprite state
  */
-#define SPR_CMD_0             0
-#define SPR_POINT_SPRITE_CNTL 1
-#define SPR_STATE_SIZE        2
+#define SPR_CMD_0              0
+#define SPR_POINT_SPRITE_CNTL  1
+#define SPR_STATE_SIZE         2
+
+#define PTP_CMD_0              0
+#define PTP_VPORT_SCALE_0      1
+#define PTP_VPORT_SCALE_1      2
+#define PTP_VPORT_SCALE_PTSIZE 3
+#define PTP_VPORT_SCALE_3      4
+#define PTP_CMD_1              5
+#define PTP_ATT_CONST_QUAD     6
+#define PTP_ATT_CONST_LIN      7
+#define PTP_ATT_CONST_CON      8
+#define PTP_ATT_CONST_3        9
+#define PTP_EYE_X             10
+#define PTP_EYE_Y             11
+#define PTP_EYE_Z             12
+#define PTP_EYE_3             13
+#define PTP_CLAMP_MIN         14
+#define PTP_CLAMP_MAX         15
+#define PTP_CLAMP_2           16
+#define PTP_CLAMP_3           17
+#define PTP_STATE_SIZE        18
 
 #define VTX_COLOR(v,n)   (((v)>>(R200_VTX_COLOR_0_SHIFT+(n)*2))&\
                          R200_VTX_COLOR_MASK)
@@ -614,6 +634,7 @@ struct r200_hw_state {
    struct r200_state_atom vpp[2];
    struct r200_state_atom atf;
    struct r200_state_atom spr;
+   struct r200_state_atom ptp;
 
    int max_state_size; /* Number of bytes necessary for a full state emit. */
    GLboolean is_dirty, all_dirty;
index dab08a9eb730198b18810f59a97f36f293a35c45..a88ea4cec264c9f912882d1131fd99dcf80d533d 100644 (file)
@@ -250,6 +250,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define     R200_ZBIAS_ENABLE_LINE      (1 << 17)
 #define     R200_ZBIAS_ENABLE_TRI       (1 << 18)
 #define     R200_WIDELINE_ENABLE        (1 << 20)
+#define     R200_DISC_FOG_SHADE_SOLID   (0 << 24)
+#define     R200_DISC_FOG_SHADE_FLAT    (1 << 24)
+#define     R200_DISC_FOG_SHADE_GOURAUD (2 << 24)
+#define     R200_DISC_FOG_SHADE_MASK    (3 << 24)
 #define     R200_VTX_PIX_CENTER_D3D     (0 << 27)
 #define     R200_VTX_PIX_CENTER_OGL     (1 << 27)
 #define     R200_ROUND_MODE_TRUNC       (0 << 28)
@@ -659,7 +663,25 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define     R200_CULL_FRONT                     (1<<29)
 #define     R200_CULL_BACK                      (1<<30)
 #define R200_SE_TCL_POINT_SPRITE_CNTL     0x22c4
-#define     R200_POINTSIZE_SEL_STATE            (1<<16)
+#define     R200_PS_MULT_PVATTENCONST           (0<<0)
+#define     R200_PS_MULT_PVATTEN                (1<<0)
+#define     R200_PS_MULT_ATTENCONST             (2<<0)
+#define     R200_PS_MULT_PVCONST                (3<<0)
+#define     R200_PS_MULT_CONST                  (4<<0)
+#define     R200_PS_MULT_MASK                   (7<<0)
+#define     R200_PS_LIN_ATT_ZERO                (1<<3)
+#define     R200_PS_USE_MODEL_EYE_VEC           (1<<4)
+#define     R200_PS_ATT_ALPHA                   (1<<5)
+#define     R200_PS_UCP_MODE_MASK               (3<<6)
+#define     R200_PS_GEN_TEX_0                   (1<<8)
+#define     R200_PS_GEN_TEX_1                   (1<<9)
+#define     R200_PS_GEN_TEX_2                   (1<<10)
+#define     R200_PS_GEN_TEX_3                   (1<<11)
+#define     R200_PS_GEN_TEX_4                   (1<<12)
+#define     R200_PS_GEN_TEX_5                   (1<<13)
+#define     R200_PS_GEN_TEX_0_SHIFT             (8)
+#define     R200_PS_GEN_TEX_MASK                (0x3f<<8)
+#define     R200_PS_SE_SEL_STATE                (1<<16)
 /* gap */
 /* taken from r300, see comments there */
 #define R200_VAP_PVS_CNTL_1                 0x22d0
index ac9e20e28ad398f811f5caa08af26000eedd3d78..3eb0aec441de556f4591b6233b43516433d6f62a 100644 (file)
@@ -686,10 +686,80 @@ static void r200FrontFace( GLcontext *ctx, GLenum mode )
 static void r200PointSize( GLcontext *ctx, GLfloat size )
 {
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
+   GLfloat *fcmd = (GLfloat *)rmesa->hw.ptp.cmd;
 
    R200_STATECHANGE( rmesa, cst );
+   R200_STATECHANGE( rmesa, ptp );
    rmesa->hw.cst.cmd[CST_RE_POINTSIZE] &= ~0xffff;
    rmesa->hw.cst.cmd[CST_RE_POINTSIZE] |= ((GLuint)(ctx->Point.Size * 16.0));
+/* this is the size param of the point size calculation (point size reg value
+   is not used when calculation is active). */
+   fcmd[PTP_VPORT_SCALE_PTSIZE] = ctx->Point.Size;
+}
+
+static void r200PointParameter( GLcontext *ctx, GLenum pname, const GLfloat *params)
+{
+   r200ContextPtr rmesa = R200_CONTEXT(ctx);
+   GLfloat *fcmd = (GLfloat *)rmesa->hw.ptp.cmd;
+
+   switch (pname) {
+   case GL_POINT_SIZE_MIN:
+   /* Can clamp both in tcl and setup - just set both (as does fglrx) */
+      R200_STATECHANGE( rmesa, lin );
+      R200_STATECHANGE( rmesa, ptp );
+      rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] &= 0xffff;
+      rmesa->hw.lin.cmd[LIN_SE_LINE_WIDTH] |= (GLuint)(ctx->Point.MinSize * 16.0) << 16;
+      fcmd[PTP_CLAMP_MIN] = ctx->Point.MinSize;
+      break;
+   case GL_POINT_SIZE_MAX:
+      R200_STATECHANGE( rmesa, cst );
+      R200_STATECHANGE( rmesa, ptp );
+      rmesa->hw.cst.cmd[CST_RE_POINTSIZE] &= 0xffff;
+      rmesa->hw.cst.cmd[CST_RE_POINTSIZE] |= (GLuint)(ctx->Point.MaxSize * 16.0) << 16;
+      fcmd[PTP_CLAMP_MAX] = ctx->Point.MaxSize;
+      break;
+   case GL_POINT_DISTANCE_ATTENUATION:
+      R200_STATECHANGE( rmesa, vtx );
+      R200_STATECHANGE( rmesa, spr );
+      R200_STATECHANGE( rmesa, ptp );
+      GLfloat *fcmd = (GLfloat *)rmesa->hw.ptp.cmd;
+      rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] &=
+        ~(R200_PS_MULT_MASK | R200_PS_LIN_ATT_ZERO | R200_PS_SE_SEL_STATE);
+      /* can't rely on ctx->Point._Attenuated here and test for NEW_POINT in
+        r200ValidateState looks like overkill */
+      if (ctx->Point.Params[0] != 1.0 ||
+         ctx->Point.Params[1] != 0.0 ||
+         ctx->Point.Params[2] != 0.0 ||
+         (ctx->VertexProgram.Enabled && ctx->VertexProgram.PointSizeEnabled)) {
+        /* all we care for vp would be the ps_se_sel_state setting */
+        fcmd[PTP_ATT_CONST_QUAD] = ctx->Point.Params[2];
+        fcmd[PTP_ATT_CONST_LIN] = ctx->Point.Params[1];
+        fcmd[PTP_ATT_CONST_CON] = ctx->Point.Params[0];
+        rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] |= R200_PS_MULT_ATTENCONST;
+        if (ctx->Point.Params[1] == 0.0)
+           rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] |= R200_PS_LIN_ATT_ZERO;
+/* FIXME: setting this here doesn't look quite ok - we only want to do
+          that if we're actually drawing points probably */
+        rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] |= R200_OUTPUT_PT_SIZE;
+        rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] |= R200_VTX_POINT_SIZE;
+      }
+      else {
+        rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] |=
+           R200_PS_SE_SEL_STATE | R200_PS_MULT_CONST;
+        rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL] &= ~R200_OUTPUT_PT_SIZE;
+        rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_0] &= ~R200_VTX_POINT_SIZE;
+      }
+      break;
+   case GL_POINT_FADE_THRESHOLD_SIZE:
+      /* don't support multisampling, so doesn't matter. */
+      break;
+   /* can't do these but don't need them.
+   case GL_POINT_SPRITE_R_MODE_NV:
+   case GL_POINT_SPRITE_COORD_ORIGIN: */
+   default:
+      fprintf(stderr, "bad pname parameter in r200PointParameter\n");
+      return;
+   }
 }
 
 /* =============================================================
@@ -1382,20 +1452,23 @@ static void r200ShadeModel( GLcontext *ctx, GLenum mode )
    s &= ~(R200_DIFFUSE_SHADE_MASK |
          R200_ALPHA_SHADE_MASK |
          R200_SPECULAR_SHADE_MASK |
-         R200_FOG_SHADE_MASK);
+         R200_FOG_SHADE_MASK |
+         R200_DISC_FOG_SHADE_MASK);
 
    switch ( mode ) {
    case GL_FLAT:
       s |= (R200_DIFFUSE_SHADE_FLAT |
            R200_ALPHA_SHADE_FLAT |
            R200_SPECULAR_SHADE_FLAT |
-           R200_FOG_SHADE_FLAT);
+           R200_FOG_SHADE_FLAT |
+           R200_DISC_FOG_SHADE_FLAT);
       break;
    case GL_SMOOTH:
       s |= (R200_DIFFUSE_SHADE_GOURAUD |
            R200_ALPHA_SHADE_GOURAUD |
            R200_SPECULAR_SHADE_GOURAUD |
-           R200_FOG_SHADE_GOURAUD);
+           R200_FOG_SHADE_GOURAUD |
+           R200_DISC_FOG_SHADE_GOURAUD);
       break;
    default:
       return;
@@ -2032,6 +2105,19 @@ static void r200Enable( GLcontext *ctx, GLenum cap, GLboolean state )
       break;
 #endif
 
+   case GL_POINT_SPRITE_ARB:
+      R200_STATECHANGE( rmesa, spr );
+      if ( state ) {
+        int i;
+        for (i = 0; i < 6; i++) {
+           rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] |=
+               ctx->Point.CoordReplace[i] << (R200_PS_GEN_TEX_0_SHIFT + i);
+        }
+      } else {
+        rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] &= ~R200_PS_GEN_TEX_MASK;
+      }
+      break;
+
    case GL_POLYGON_OFFSET_FILL:
       R200_STATECHANGE( rmesa, set );
       if ( state ) {
@@ -2165,6 +2251,11 @@ static void r200Enable( GLcontext *ctx, GLenum cap, GLboolean state )
       else {
         /* picked up later */
       }
+      r200PointParameter( ctx, GL_POINT_DISTANCE_ATTENUATION, NULL );
+      break;
+
+   case GL_VERTEX_PROGRAM_POINT_SIZE_ARB:
+      r200PointParameter( ctx, GL_POINT_DISTANCE_ATTENUATION, NULL );
       break;
 
    case GL_FRAGMENT_SHADER_ATI:
@@ -2516,6 +2607,7 @@ void r200InitStateFuncs( struct dd_function_table *functions )
    functions->PolygonMode              = r200PolygonMode;
    functions->PolygonOffset            = r200PolygonOffset;
    functions->PolygonStipple           = r200PolygonStipple;
+   functions->PointParameterfv         = r200PointParameter;
    functions->PointSize                        = r200PointSize;
    functions->RenderMode               = r200RenderMode;
    functions->Scissor                  = r200Scissor;
index ffca7ea5fa16a97c0f33f9699f5b02fcbad4084e..d95a80c7bbc6ee8778c9aaf6b051c0a241f1122b 100644 (file)
@@ -398,10 +398,14 @@ void r200InitState( r200ContextPtr rmesa )
    else {
       ALLOC_STATE( prf, never, PRF_STATE_SIZE, "PRF/performance-tri", 0 );
    }
-   if (rmesa->r200Screen->drmSupportsPointSprites)
+   if (rmesa->r200Screen->drmSupportsPointSprites) {
       ALLOC_STATE( spr, always, SPR_STATE_SIZE, "SPR/pointsprite", 0 );
-   else
+      ALLOC_STATE( ptp, tcl, PTP_STATE_SIZE, "PTP/pointparams", 0 );
+   }
+   else {
       ALLOC_STATE (spr, never, SPR_STATE_SIZE, "SPR/pointsprite", 0 );
+      ALLOC_STATE (ptp, never, PTP_STATE_SIZE, "PTP/pointparams", 0 );
+   }
 
    r200SetUpAtomList( rmesa );
 
@@ -546,6 +550,11 @@ void r200InitState( r200ContextPtr rmesa )
         cmdvec( R200_VS_UCP_ADDR + i, 1, 4 );
    }
 
+   rmesa->hw.ptp.cmd[PTP_CMD_0] =
+      cmdvec( R200_VS_PNT_SPRITE_VPORT_SCALE, 1, 4 );
+   rmesa->hw.ptp.cmd[PTP_CMD_1] =
+      cmdvec( R200_VS_PNT_SPRITE_ATT_CONST, 1, 12 );
+
    /* Initial Harware state:
     */
    rmesa->hw.ctx.cmd[CTX_PP_MISC] = (R200_ALPHA_TEST_PASS
@@ -653,6 +662,7 @@ void r200InitState( r200ContextPtr rmesa )
                                     R200_ALPHA_SHADE_GOURAUD |
                                     R200_SPECULAR_SHADE_GOURAUD |
                                     R200_FOG_SHADE_GOURAUD |
+                                    R200_DISC_FOG_SHADE_GOURAUD |
                                     R200_VTX_PIX_CENTER_OGL |
                                     R200_ROUND_MODE_TRUNC |
                                     R200_ROUND_PREC_8TH_PIX);
@@ -931,7 +941,31 @@ void r200InitState( r200ContextPtr rmesa )
    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;
+   rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] =
+      R200_PS_SE_SEL_STATE | R200_PS_MULT_CONST;
+
+   /* ptp_eye is presumably used to calculate the attenuation wrt a different
+      location? In any case, since point attenuation triggers _needeyecoords,
+      it is constant. Probably ignored as long as R200_PS_USE_MODEL_EYE_VEC
+      isn't set */
+   rmesa->hw.ptp.cmd[PTP_EYE_X] = 0;
+   rmesa->hw.ptp.cmd[PTP_EYE_Y] = 0;
+   rmesa->hw.ptp.cmd[PTP_EYE_Z] = IEEE_ONE | 0x80000000; /* -1.0 */
+   rmesa->hw.ptp.cmd[PTP_EYE_3] = 0;
+   /* no idea what the ptp_vport_scale values are good for, except the
+      PTSIZE one - hopefully doesn't matter */
+   rmesa->hw.ptp.cmd[PTP_VPORT_SCALE_0] = IEEE_ONE;
+   rmesa->hw.ptp.cmd[PTP_VPORT_SCALE_1] = IEEE_ONE;
+   rmesa->hw.ptp.cmd[PTP_VPORT_SCALE_PTSIZE] = IEEE_ONE;
+   rmesa->hw.ptp.cmd[PTP_VPORT_SCALE_3] = IEEE_ONE;
+   rmesa->hw.ptp.cmd[PTP_ATT_CONST_QUAD] = 0;
+   rmesa->hw.ptp.cmd[PTP_ATT_CONST_LIN] = 0;
+   rmesa->hw.ptp.cmd[PTP_ATT_CONST_CON] = IEEE_ONE;
+   rmesa->hw.ptp.cmd[PTP_ATT_CONST_3] = 0;
+   rmesa->hw.ptp.cmd[PTP_CLAMP_MIN] = IEEE_ONE;
+   rmesa->hw.ptp.cmd[PTP_CLAMP_MAX] = 0x44ffe000; /* 2047 */
+   rmesa->hw.ptp.cmd[PTP_CLAMP_2] = 0;
+   rmesa->hw.ptp.cmd[PTP_CLAMP_3] = 0;
 
    r200LightingSpaceChange( ctx );
 
index aa78f3828685db0b15e05d851e487f1dc0e63fe6..c14a275f7a3063b95a16c7f2d33af1ff634a3d57 100644 (file)
@@ -117,6 +117,11 @@ static void r200SetVertexFormat( GLcontext *ctx )
       offset = 3;
    }
 
+   if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_POINTSIZE )) {
+      EMIT_ATTR( _TNL_ATTRIB_POINTSIZE, EMIT_1F, R200_VTX_POINT_SIZE );
+      offset += 1;
+   }
+
    rmesa->swtcl.coloroffset = offset;
 #if MESA_LITTLE_ENDIAN 
    EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4UB_4F_RGBA, (R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT) );
@@ -349,7 +354,9 @@ static INLINE GLuint reduced_hw_prim( GLcontext *ctx, GLuint prim)
 {
    switch (prim) {
    case GL_POINTS:
-      return (ctx->_TriangleCaps & DD_POINT_SIZE) ?
+      return (ctx->Point.PointSprite ||
+        ((ctx->_TriangleCaps & (DD_POINT_SIZE | DD_POINT_ATTEN)) &&
+        !(ctx->_TriangleCaps & (DD_POINT_SMOOTH)))) ?
         R200_VF_PRIM_POINT_SPRITES : R200_VF_PRIM_POINTS;
    case GL_LINES:
    /* fallthrough */
@@ -632,6 +639,17 @@ static void r200RasterPrimitive( GLcontext *ctx, GLuint hwprim )
    r200ContextPtr rmesa = R200_CONTEXT(ctx);
 
    if (rmesa->swtcl.hw_primitive != hwprim) {
+      /* need to disable perspective-correct texturing for point sprites */
+      if ((hwprim & 0xf) == R200_VF_PRIM_POINT_SPRITES && ctx->Point.PointSprite) {
+        if (rmesa->hw.set.cmd[SET_RE_CNTL] & R200_PERSPECTIVE_ENABLE) {
+           R200_STATECHANGE( rmesa, set );
+           rmesa->hw.set.cmd[SET_RE_CNTL] &= ~R200_PERSPECTIVE_ENABLE;
+        }
+      }
+      else if (!(rmesa->hw.set.cmd[SET_RE_CNTL] & R200_PERSPECTIVE_ENABLE)) {
+        R200_STATECHANGE( rmesa, set );
+        rmesa->hw.set.cmd[SET_RE_CNTL] |= R200_PERSPECTIVE_ENABLE;
+      }
       R200_NEWPRIM( rmesa );
       rmesa->swtcl.hw_primitive = hwprim;
    }
index 18b5458a97bed2f7adc441bd1631c349ebc3025e..8f50cd99ad135b38ed4243f64dbc4e24fb0a6352 100644 (file)
@@ -68,7 +68,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define HAVE_ELTS        1
 
 
-#define HW_POINTS           ((ctx->_TriangleCaps & DD_POINT_SIZE) ? \
+#define HW_POINTS           ((ctx->Point.PointSprite || \
+                               ((ctx->_TriangleCaps & (DD_POINT_SIZE | DD_POINT_ATTEN)) && \
+                               !(ctx->_TriangleCaps & (DD_POINT_SMOOTH)))) ? \
                                R200_VF_PRIM_POINT_SPRITES : R200_VF_PRIM_POINTS)
 #define HW_LINES            R200_VF_PRIM_LINES
 #define HW_LINE_LOOP        0
@@ -268,6 +270,17 @@ void r200TclPrimitive( GLcontext *ctx,
 
    if (newprim != rmesa->tcl.hw_primitive ||
        !discrete_prim[hw_prim&0xf]) {
+      /* need to disable perspective-correct texturing for point sprites */
+      if ((prim & PRIM_MODE_MASK) == GL_POINTS && ctx->Point.PointSprite) {
+        if (rmesa->hw.set.cmd[SET_RE_CNTL] & R200_PERSPECTIVE_ENABLE) {
+           R200_STATECHANGE( rmesa, set );
+           rmesa->hw.set.cmd[SET_RE_CNTL] &= ~R200_PERSPECTIVE_ENABLE;
+        }
+      }
+      else if (!(rmesa->hw.set.cmd[SET_RE_CNTL] & R200_PERSPECTIVE_ENABLE)) {
+        R200_STATECHANGE( rmesa, set );
+        rmesa->hw.set.cmd[SET_RE_CNTL] |= R200_PERSPECTIVE_ENABLE;
+      }
       R200_NEWPRIM( rmesa );
       rmesa->tcl.hw_primitive = newprim;
    }
@@ -447,7 +460,7 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx,
         out_vtxfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT;
         out_compsel |= R200_OUTPUT_COLOR_1;
       }
-      /* FIXME: probably not everything is set up for fogc and psiz to work correctly */
+      /* FIXME: probably not everything is set up for fogc to work correctly */
       if (vp_out & (1 << VERT_RESULT_FOGC)) {
         out_vtxfmt0 |= R200_VTX_DISCRETE_FOG;
          out_compsel |= R200_OUTPUT_DISCRETE_FOG;
index b3da8cd580b6b6ca9916fabd0d8a0e54acd32726..2cfbf3510b990a26f03d2766b6874039fda1ab7d 100644 (file)
@@ -115,7 +115,7 @@ static void r200SetTexWrap( r200TexObjPtr t, GLenum swrap, GLenum twrap, GLenum
       t->pp_txfilter |= R200_CLAMP_T_CLAMP_LAST;
       break;
    case GL_CLAMP_TO_BORDER:
-      t->pp_txfilter |= R200_CLAMP_T_CLAMP_GL | R200_BORDER_MODE_D3D;
+      t->pp_txfilter |= R200_CLAMP_T_CLAMP_GL;
       is_clamp_to_border = GL_TRUE;
       break;
    case GL_MIRRORED_REPEAT:
@@ -1005,7 +1005,16 @@ static void r200TexEnv( GLcontext *ctx, GLenum target,
       }
       break;
    }
-
+   case GL_COORD_REPLACE_ARB:
+      if (ctx->Point.PointSprite) {
+        R200_STATECHANGE( rmesa, spr );
+        if ((GLenum)param[0]) {
+           rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] |= R200_PS_GEN_TEX_0 << unit;
+        } else {
+           rmesa->hw.spr.cmd[SPR_POINT_SPRITE_CNTL] &= ~(R200_PS_GEN_TEX_0 << unit);
+        }
+      }
+      break;
    default:
       return;
    }
index 140d848d9ae877167f140a11a3b719db3ade6160..5cfa792cdb376f97978f49b0b372214538f65a62 100644 (file)
@@ -130,6 +130,7 @@ extern const struct dri_extension blend_extensions[];
 extern const struct dri_extension ARB_vp_extension[];
 extern const struct dri_extension NV_vp_extension[];
 extern const struct dri_extension ATI_fs_extension[];
+extern const struct dri_extension point_extensions[];
 
 #elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
 
@@ -1042,6 +1043,7 @@ __driCreateNewScreen_20050727( __DRInativeDisplay *dpy,
       driInitSingleExtension( NULL, ARB_vp_extension );
       driInitSingleExtension( NULL, NV_vp_extension );
       driInitSingleExtension( NULL, ATI_fs_extension );
+      driInitExtensions( NULL, point_extensions, GL_FALSE );
 #endif
    }