Fixing and enabling elt buffers by default.
[mesa.git] / src / mesa / drivers / dri / r300 / r300_render.c
index ff20da39d28737c7c96255309a52e0695435bff5..3653af9a5d6838fc989fdab59aa68af213dd81ab 100644 (file)
@@ -58,62 +58,6 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "r300_maos.h"
 #include "r300_emit.h"
 
-/* Turns out we might not need this after all... */
-void update_zbias(GLcontext * ctx, int prim)
-{
-    r300ContextPtr rmesa = R300_CONTEXT(ctx);
-    int enabled = 0;
-    uint32_t values[4];
-    //return ;
-    switch(prim & PRIM_MODE_MASK) {
-       case GL_POINTS:
-               if(ctx->Polygon.OffsetPoint == GL_TRUE)
-                       enabled=1;
-               break;          
-       case GL_LINES:
-       case GL_LINE_STRIP:
-       case GL_LINE_LOOP:
-               if(ctx->Polygon.OffsetLine == GL_TRUE)
-                       enabled=1;
-               break;
-       case GL_TRIANGLES:
-       case GL_TRIANGLE_STRIP:
-       case GL_TRIANGLE_FAN:
-       case GL_QUADS:
-       case GL_QUAD_STRIP:
-       case GL_POLYGON:
-               if(ctx->Polygon.OffsetFill == GL_TRUE)
-                       enabled=1;
-               break;
-       default:
-               fprintf(stderr, "%s:%s Do not know how to handle primitive %02x - help me !\n",
-                       __FILE__, __FUNCTION__,
-                       prim & PRIM_MODE_MASK);
-           
-    }
-    
-    if(enabled){
-           values[0]=values[2]=r300PackFloat32(ctx->Polygon.OffsetFactor * 12.0);
-           values[1]=values[3]=r300PackFloat32(ctx->Polygon.OffsetUnits * 4.0);
-    }else{
-           values[0]=values[2]=r300PackFloat32(0.0);
-           values[1]=values[3]=r300PackFloat32(0.0);
-    }
-    
-    if(values[0] != rmesa->hw.zbs.cmd[R300_ZBS_T_FACTOR] ||
-       values[1] != rmesa->hw.zbs.cmd[R300_ZBS_T_CONSTANT] ||
-       values[2] != rmesa->hw.zbs.cmd[R300_ZBS_W_FACTOR] ||
-       values[3] != rmesa->hw.zbs.cmd[R300_ZBS_W_CONSTANT]){
-
-              R300_STATECHANGE(rmesa, zbs);
-              rmesa->hw.zbs.cmd[R300_ZBS_T_FACTOR] = values[0];
-              rmesa->hw.zbs.cmd[R300_ZBS_T_CONSTANT] = values[1];
-              rmesa->hw.zbs.cmd[R300_ZBS_W_FACTOR] = values[2];
-              rmesa->hw.zbs.cmd[R300_ZBS_W_CONSTANT] = values[3];
-           
-    }
-}
-
 /**********************************************************************
 *                     Hardware rasterization
 *
@@ -127,14 +71,14 @@ static int r300_get_primitive_type(r300ContextPtr rmesa, GLcontext *ctx, int pri
    struct vertex_buffer *VB = &tnl->vb;
    GLuint i;
    int type=-1;
-   
+
        switch (prim & PRIM_MODE_MASK) {
        case GL_POINTS:
                type=R300_VAP_VF_CNTL__PRIM_POINTS;
-               break;          
+               break;
        case GL_LINES:
                type=R300_VAP_VF_CNTL__PRIM_LINES;
-               break;          
+               break;
        case GL_LINE_STRIP:
                type=R300_VAP_VF_CNTL__PRIM_LINE_STRIP;
                break;
@@ -169,7 +113,7 @@ static int r300_get_primitive_type(r300ContextPtr rmesa, GLcontext *ctx, int pri
    return type;
 }
 
-static int r300_get_num_verts(r300ContextPtr rmesa, 
+static int r300_get_num_verts(r300ContextPtr rmesa,
        GLcontext *ctx,
        int num_verts,
        int prim)
@@ -179,16 +123,16 @@ static int r300_get_num_verts(r300ContextPtr rmesa,
    GLuint i;
    int type=-1, verts_off=0;
    char *name="UNKNOWN";
-   
+
        switch (prim & PRIM_MODE_MASK) {
        case GL_POINTS:
                name="P";
                verts_off = 0;
-               break;          
+               break;
        case GL_LINES:
                name="L";
                verts_off = num_verts % 2;
-               break;          
+               break;
        case GL_LINE_STRIP:
                name="LS";
                if(num_verts < 2)
@@ -236,16 +180,16 @@ static int r300_get_num_verts(r300ContextPtr rmesa,
                return -1;
                break;
        }
-       
+
        if(num_verts - verts_off == 0){
                WARN_ONCE("user error: Need more than %d vertices to draw primitive %s !\n", num_verts, name);
                return 0;
        }
-       
+
        if(verts_off > 0){
                WARN_ONCE("user error: %d is not a valid number of vertices for primitive %s !\n", num_verts, name);
        }
-       
+
        return num_verts - verts_off;
 }
 
@@ -254,12 +198,12 @@ void dump_inputs(GLcontext *ctx, int render_inputs)
        int k;
        fprintf(stderr, "inputs:");
        fprintf(stderr, "%08x ", render_inputs);
-       
+
        if(render_inputs & _TNL_BIT_POS)
                fprintf(stderr, "_TNL_BIT_POS ");
        if(render_inputs & _TNL_BIT_NORMAL)
                fprintf(stderr, "_TNL_BIT_NORMAL ");
-               
+
                /* color components */
        if(render_inputs & _TNL_BIT_COLOR0)
                fprintf(stderr, "_TNL_BIT_COLOR0 ");
@@ -268,26 +212,26 @@ void dump_inputs(GLcontext *ctx, int render_inputs)
 
        if(render_inputs & _TNL_BIT_FOG)
                fprintf(stderr, "_TNL_BIT_FOG ");
-                                       
+
                /* texture coordinates */
        for(k=0;k < ctx->Const.MaxTextureUnits;k++)
                if(render_inputs & (_TNL_BIT_TEX0<<k))
                        fprintf(stderr, "_TNL_BIT_TEX%d ", k);
-               
+
        if(render_inputs & _TNL_BIT_INDEX)
                fprintf(stderr, "_TNL_BIT_INDEX ");
        if(render_inputs & _TNL_BIT_POINTSIZE)
                fprintf(stderr, "_TNL_BIT_POINTSIZE ");
-       
+
        fprintf(stderr, "\n");
 }
 
-/* This function compiles GL context into state registers that 
+/* This function compiles GL context into state registers that
    describe data routing inside of R300 pipeline.
-   
+
    In particular, it programs input_route, output_vtx_fmt, texture
    unit configuration and gb_output_vtx_fmt
-   
+
    This function encompasses setup_AOS() from r300_lib.c
 */
 
@@ -311,7 +255,7 @@ static GLfloat default_vector[4]={0.0, 0.0, 0.0, 1.0};
 
 /* Immediate implementation - vertex data is sent via command stream */
 
-static void r300_render_immediate_primitive(r300ContextPtr rmesa, 
+static void r300_render_immediate_primitive(r300ContextPtr rmesa,
        GLcontext *ctx,
        int start,
        int end,
@@ -322,19 +266,19 @@ static void r300_render_immediate_primitive(r300ContextPtr rmesa,
    GLuint i, render_inputs;
    int k, type, num_verts;
    LOCAL_VARS
-                  
+
    type=r300_get_primitive_type(rmesa, ctx, prim);
    num_verts=r300_get_num_verts(rmesa, ctx, end-start, prim);
-   
-               #if 0
-               fprintf(stderr,"ObjPtr: size=%d stride=%d\n", 
+
+#if 0
+               fprintf(stderr,"ObjPtr: size=%d stride=%d\n",
                        VB->ObjPtr->size, VB->ObjPtr->stride);
-               fprintf(stderr,"ColorPtr[0]: size=%d stride=%d\n", 
+               fprintf(stderr,"ColorPtr[0]: size=%d stride=%d\n",
                        VB->ColorPtr[0]->size, VB->ColorPtr[0]->stride);
-               fprintf(stderr,"TexCoordPtr[0]: size=%d stride=%d\n", 
+               fprintf(stderr,"TexCoordPtr[0]: size=%d stride=%d\n",
                        VB->TexCoordPtr[0]->size, VB->TexCoordPtr[0]->stride);
-               #endif
-   
+#endif
+
    if(type<0 || num_verts <= 0)return;
 
    if(!VB->ObjPtr){
@@ -344,7 +288,7 @@ static void r300_render_immediate_primitive(r300ContextPtr rmesa,
    /* A packet cannot have more than 16383 data words.. */
    if((num_verts*4*rmesa->state.aos_count)>16380){
        WARN_ONCE("Too many vertices to paint. Fix me !\n");
-       return;         
+       return;
        }
 
    //fprintf(stderr, "aos_count=%d start=%d end=%d\n", rmesa->state.aos_count, start, end);
@@ -353,7 +297,7 @@ static void r300_render_immediate_primitive(r300ContextPtr rmesa,
        WARN_ONCE("Aeiee ! aos_count==0, while it shouldn't. Skipping rendering\n");
        return;
        }
-  
+
    render_inputs = rmesa->state.render_inputs;
 
    if(!render_inputs){
@@ -362,31 +306,31 @@ static void r300_render_immediate_primitive(r300ContextPtr rmesa,
        }
 
        //dump_inputs(ctx, render_inputs); return ;
-       
+
    start_immediate_packet(num_verts, type, 4*rmesa->state.aos_count);
 
        for(i=start;i<start+num_verts;i++){
-               #if 0
-               fprintf(stderr, "* (%f %f %f %f) (%f %f %f %f)\n", 
+#if 0
+               fprintf(stderr, "* (%f %f %f %f) (%f %f %f %f)\n",
                        VEC_ELT(VB->ObjPtr, GLfloat, i)[0],
                        VEC_ELT(VB->ObjPtr, GLfloat, i)[1],
                        VEC_ELT(VB->ObjPtr, GLfloat, i)[2],
                        VEC_ELT(VB->ObjPtr, GLfloat, i)[3],
-                       
+
                        VEC_ELT(VB->ColorPtr[0], GLfloat, i)[0],
                        VEC_ELT(VB->ColorPtr[0], GLfloat, i)[1],
                        VEC_ELT(VB->ColorPtr[0], GLfloat, i)[2],
                        VEC_ELT(VB->ColorPtr[0], GLfloat, i)[3]
                        );
-               #endif
-               
-               
+#endif
+
+
                /* coordinates */
                if(render_inputs & _TNL_BIT_POS)
                        output_vector(VB->ObjPtr, i);
                if(render_inputs & _TNL_BIT_NORMAL)
                        output_vector(VB->NormalPtr, i);
-               
+
                /* color components */
                if(render_inputs & _TNL_BIT_COLOR0)
                        output_vector(VB->ColorPtr[0], i);
@@ -395,12 +339,12 @@ static void r300_render_immediate_primitive(r300ContextPtr rmesa,
 
 /*             if(render_inputs & _TNL_BIT_FOG) // Causes lock ups when immediate mode is on
                        output_vector(VB->FogCoordPtr, i);*/
-                                       
+
                /* texture coordinates */
                for(k=0;k < ctx->Const.MaxTextureUnits;k++)
                        if(render_inputs & (_TNL_BIT_TEX0<<k))
                                output_vector(VB->TexCoordPtr[k], i);
-               
+
                if(render_inputs & _TNL_BIT_INDEX)
                        output_vector(VB->IndexPtr[0], i);
                if(render_inputs & _TNL_BIT_POINTSIZE)
@@ -421,59 +365,59 @@ static GLboolean r300_run_immediate_render(GLcontext *ctx,
    struct gl_texture_object *to=ctx->Texture.Unit[0].Current2D;
    r300TexObjPtr t=to->DriverData;
    LOCAL_VARS
-       
-  
+
+
    /* Update texture state - needs to be done only when actually changed..
       All the time for now.. */
 
 
        if (RADEON_DEBUG == DEBUG_PRIMS)
                fprintf(stderr, "%s\n", __FUNCTION__);
-               
-   #if 1 /* we need this, somehow */
+
+#if 1 /* we need this, somehow */
    /* Flush state - make sure command buffer is nice and large */
    r300Flush(ctx);
    /* Make sure we have enough space */
-   #else
+#else
    /* Count is very imprecize, but should be good upper bound */
    r300EnsureCmdBufSpace(rmesa, rmesa->hw.max_state_size + 4+2+30
        +VB->PrimitiveCount*(1+8)+VB->Count*4*rmesa->state.texture.tc_count+4, __FUNCTION__);
-   #endif
-     
+#endif
+
    /* needed before starting 3d operation .. */
    reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
        e32(0x0000000a);
-   
+
    reg_start(0x4f18,0);
        e32(0x00000003);
-       
-   
-       #if 0 /* looks like the Z offset issue got fixed */
+
+
+#if 0 /* looks like the Z offset issue got fixed */
    rmesa->hw.vte.cmd[1] = R300_VPORT_X_SCALE_ENA
                                | R300_VPORT_X_OFFSET_ENA
                                | R300_VPORT_Y_SCALE_ENA
                                | R300_VPORT_Y_OFFSET_ENA
                                | R300_VTX_W0_FMT;
    R300_STATECHANGE(rmesa, vte);
-       #endif
-   
-       
-      
+#endif
+
+
+
    /* Magic register - note it is right after 20b0 */
 
-   
+
    if(rmesa->state.texture.tc_count>0){
        reg_start(0x20b4,0);
                e32(0x0000000c);
-   
+
        }
-               
+
    r300EmitState(rmesa);
-   
-   #if 0
+
+#if 0
    reg_start(R300_RB3D_COLORMASK, 0);
        e32(0xf);
-   
+
    vsf_start_fragment(0x406, 4);
    efloat(0.0);
    efloat(0.0);
@@ -485,15 +429,15 @@ static GLboolean r300_run_immediate_render(GLcontext *ctx,
    efloat(0.0);
    efloat(0.0);
    efloat(1.0);
-   #endif
-   
+#endif
+
 /* Setup INPUT_ROUTE and INPUT_CNTL */
        r300EmitArrays(ctx, GL_TRUE);
 
 /* Why do we need this for immediate mode?? Vertex processor needs it to know proper regs */
 //     r300EmitLOAD_VBPNTR(rmesa, 0);
 /* Okay, it seems I misunderstood something, EmitAOS does the same thing */
-       r300EmitAOS(rmesa, 0);
+       r300EmitAOS(rmesa, rmesa->state.aos_count, 0);
 
    for(i=0; i < VB->PrimitiveCount; i++){
        GLuint prim = VB->Primitive[i].mode;
@@ -502,60 +446,45 @@ static GLboolean r300_run_immediate_render(GLcontext *ctx,
 
        r300_render_immediate_primitive(rmesa, ctx, start, start + length, prim);
        }
-       
+
     /* This sequence is required after any 3d drawing packet
       I suspect it work arounds a bug (or deficiency) in hardware */
-  
+
    reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
        e32(0x0000000a);
-   
+
    reg_start(0x4f18,0);
        e32(0x00000003);
-         
+
    return GL_FALSE;
 }
 
 /* vertex buffer implementation */
-void emit_elts(GLcontext * ctx, GLuint *elts, int oec, int ec);
-
-#    define R300_EB_UNK1_SHIFT 24
-#    define R300_EB_UNK1 (0x80<<24)
-#    define R300_EB_UNK2 0x0810
-
-unsigned long get_num_elts(unsigned long count)
-{
-       unsigned long magic_1;
-       
-       /* round up elt count so that magic_1 is 0 (divisable by 4)*/
-       return (count+3) & (~3);
-       //return count - (count % 4);
-}
 
 static void inline fire_EB(PREFIX unsigned long addr, int vertex_count, int type)
 {
        LOCAL_VARS
-       unsigned long magic_1;
-       unsigned char magic1_tbl[4]={ 0, 6, 4, 2 };
-
-       magic_1 = magic1_tbl[vertex_count % 4];
-
-       if(magic_1 != 0){
-               WARN_ONCE("Dont know how to handle this yet!\n");
+       unsigned long addr_a;
+       
+       if(addr & 1){
+               WARN_ONCE("Badly aligned buffer\n");
                return ;
        }
+       addr_a = 0; /*addr & 0x1c;*/
        
        check_space(6);
        
        start_packet3(RADEON_CP_PACKET3_3D_DRAW_INDX_2, 0);
+       /* TODO: R300_VAP_VF_CNTL__INDEX_SIZE_32bit . */
        e32(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (vertex_count<<16) | type);
-       
+
        start_packet3(RADEON_CP_PACKET3_INDX_BUFFER, 2);
-       e32(R300_EB_UNK1 | (magic_1 << 16) | R300_EB_UNK2);
-       e32(addr);
-       e32(((vertex_count+1) / 2) + magic_1);
+       e32(R300_EB_UNK1 | (addr_a << 16) | R300_EB_UNK2);
+       e32(addr /*& 0xffffffe3*/);
+       e32((vertex_count+1)/2 /*+ addr_a/4*/); /* Total number of dwords needed? */
 }
 
-static void r300_render_vb_primitive(r300ContextPtr rmesa, 
+static void r300_render_vb_primitive(r300ContextPtr rmesa,
        GLcontext *ctx,
        int start,
        int end,
@@ -566,23 +495,38 @@ static void r300_render_vb_primitive(r300ContextPtr rmesa,
    LOCAL_VARS
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    struct vertex_buffer *VB = &tnl->vb;
-   
+   int i;
+
    type=r300_get_primitive_type(rmesa, ctx, prim);
    num_verts=r300_get_num_verts(rmesa, ctx, end-start, prim);
-   
+
    if(type<0 || num_verts <= 0)return;
-   
+
    if(rmesa->state.Elts){
-       unsigned long elt_count;
-       
-       WARN_ONCE("Rendering with elts\n");
+       r300EmitAOS(rmesa, rmesa->state.aos_count, 0);
+#if 0
+       start_index32_packet(num_verts, type);
+       for(i=0; i < num_verts; i++)
+               e32(rmesa->state.Elts[start+i]); /* start ? */
+#else
+       WARN_ONCE("Rendering with elt buffers\n");
+       if(num_verts == 1){
+               start_index32_packet(num_verts, type);
+               e32(rmesa->state.Elts[start]);
+               return;
+       }
        
-       elt_count=get_num_elts(num_verts);
-       //emit_elts(ctx, rmesa->state.Elts, VB->Count, get_num_elts(VB->Count));
-       emit_elts(ctx, rmesa->state.Elts+start, num_verts, elt_count);
-       fire_EB(PASS_PREFIX rsp->gartTextures.handle/*rmesa->state.elt_ao.aos_offset*/, elt_count, type);
-   }else
+       if(num_verts > 65535){ /* not implemented yet */
+               WARN_ONCE("Too many elts\n");
+               return;
+       }
+       r300EmitElts(ctx, rmesa->state.Elts+start, num_verts);
+       fire_EB(PASS_PREFIX GET_START(&(rmesa->state.elt_dma)), num_verts, type);
+#endif
+   }else{
+          r300EmitAOS(rmesa, rmesa->state.aos_count, start);
           fire_AOS(PASS_PREFIX num_verts, type);
+   }
 }
 
 static GLboolean r300_run_vb_render(GLcontext *ctx,
@@ -593,28 +537,23 @@ static GLboolean r300_run_vb_render(GLcontext *ctx,
    struct vertex_buffer *VB = &tnl->vb;
    int i, j;
    LOCAL_VARS
-       
-       if (RADEON_DEBUG == DEBUG_PRIMS)
+   
+       if (RADEON_DEBUG & DEBUG_PRIMS)
                fprintf(stderr, "%s\n", __FUNCTION__);
+       
 
-   
        r300ReleaseArrays(ctx);
        r300EmitArrays(ctx, GL_FALSE);
        //dump_inputs(ctx, rmesa->state.render_inputs);
-#if 0 /* Cant do this here yet due to magic_1 */
-       if(rmesa->state.Elts)
-               emit_elts(ctx, rmesa->state.Elts, /*600*/VB->Count, get_num_elts(/*600*/VB->Count));
-#endif 
-       
+
 //     LOCK_HARDWARE(&(rmesa->radeon));
 
        reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
        e32(0x0000000a);
-   
+
        reg_start(0x4f18,0);
        e32(0x00000003);
-
-       r300EmitState(rmesa);           
+       r300EmitState(rmesa);
 
        rmesa->state.Elts = VB->Elts;
 
@@ -622,24 +561,22 @@ static GLboolean r300_run_vb_render(GLcontext *ctx,
                GLuint prim = VB->Primitive[i].mode;
                GLuint start = VB->Primitive[i].start;
                GLuint length = VB->Primitive[i].count;
-
-               r300EmitAOS(rmesa, rmesa->state.aos_count, start);   
-
+               
                r300_render_vb_primitive(rmesa, ctx, start, start + length, prim);
        }
 
        reg_start(R300_RB3D_DSTCACHE_CTLSTAT,0);
        e32(0x0000000a);
-  
+
        reg_start(0x4f18,0);
        e32(0x00000003);
 
 //     end_3d(PASS_PREFIX_VOID);
-   
+
    /* Flush state - we are done drawing.. */
 //     r300FlushCmdBufLocked(rmesa, __FUNCTION__);
 //     radeonWaitForIdleLocked(&(rmesa->radeon));
-   
+
 //     UNLOCK_HARDWARE(&(rmesa->radeon));
        return GL_FALSE;
 }
@@ -657,21 +594,21 @@ static GLboolean r300_run_render(GLcontext *ctx,
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    struct vertex_buffer *VB = &tnl->vb;
    GLuint i;
-       
-       if (RADEON_DEBUG == DEBUG_PRIMS)
+
+       if (RADEON_DEBUG & DEBUG_PRIMS)
                fprintf(stderr, "%s\n", __FUNCTION__);
-       
-       
-   #if 1
-       
-       #if 1
-        return r300_run_immediate_render(ctx, stage);
-       #else 
-        return r300_run_vb_render(ctx, stage);
-       #endif
-   #else
+
+
+#if 1
+
+#if 0
+               return r300_run_immediate_render(ctx, stage);
+#else
+               return r300_run_vb_render(ctx, stage);
+#endif
+#else
        return GL_TRUE;
-   #endif
+#endif
 
 #if 0
    mgaContextPtr mmesa = MGA_CONTEXT(ctx);
@@ -739,39 +676,46 @@ static void r300_check_render(GLcontext *ctx, struct tnl_pipeline_stage *stage)
                stage->active = GL_FALSE;
                return;
        }
-       
-       // I failed to figure out how dither works in hardware,
-       // let's just ignore it for now
-       //FALLBACK_IF(ctx->Color.DitherFlag);
-       
+               
+
        /* I'm almost certain I forgot something here */
-       #if 0 /* This should work now.. */
+#if 0 /* These should work now.. */
+       FALLBACK_IF(ctx->Color.DitherFlag);
        FALLBACK_IF(ctx->Color.AlphaEnabled); // GL_ALPHA_TEST
        FALLBACK_IF(ctx->Color.BlendEnabled); // GL_BLEND
-       #endif
-       //FALLBACK_IF(ctx->Fog.Enabled); // GL_FOG disable as swtcl doesnt seem to support this
-       FALLBACK_IF(ctx->Line.SmoothFlag); // GL_LINE_SMOOTH
-       FALLBACK_IF(ctx->Line.StippleFlag); // GL_LINE_STIPPLE
-       FALLBACK_IF(ctx->Point.SmoothFlag); // GL_POINT_SMOOTH
-       if (ctx->Extensions.NV_point_sprite || ctx->Extensions.ARB_point_sprite)
-               FALLBACK_IF(ctx->Point.PointSprite); // GL_POINT_SPRITE_NV
+       FALLBACK_IF(ctx->Polygon.OffsetFill); // GL_POLYGON_OFFSET_FILL
+#endif
        //FALLBACK_IF(ctx->Polygon.OffsetPoint); // GL_POLYGON_OFFSET_POINT
        //FALLBACK_IF(ctx->Polygon.OffsetLine); // GL_POLYGON_OFFSET_LINE
-       //FALLBACK_IF(ctx->Polygon.OffsetFill); // GL_POLYGON_OFFSET_FILL
-       //if(ctx->Polygon.OffsetFill)WARN_ONCE("Polygon.OffsetFill not implemented, ignoring\n");
-       FALLBACK_IF(ctx->Polygon.SmoothFlag); // GL_POLYGON_SMOOTH
-       FALLBACK_IF(ctx->Polygon.StippleFlag); // GL_POLYGON_STIPPLE
        //FALLBACK_IF(ctx->Stencil.Enabled); // GL_STENCIL_TEST
-       FALLBACK_IF(ctx->Multisample.Enabled); // GL_MULTISAMPLE_ARB
        
+       //FALLBACK_IF(ctx->Fog.Enabled); // GL_FOG disable as swtcl doesnt seem to support this
+       //FALLBACK_IF(ctx->Polygon.SmoothFlag); // GL_POLYGON_SMOOTH disabling to get blender going
+       FALLBACK_IF(ctx->Polygon.StippleFlag); // GL_POLYGON_STIPPLE
+       FALLBACK_IF(ctx->Multisample.Enabled); // GL_MULTISAMPLE_ARB
+
+#if 0 /* ut2k3 fails to start if this is on */
        /* One step at a time - let one texture pass.. */
        for (i = 1; i < ctx->Const.MaxTextureUnits; i++)
                FALLBACK_IF(ctx->Texture.Unit[i].Enabled);
-
+#endif 
+       
+       /* Assumed factor reg is found but pattern is still missing */
+       //FALLBACK_IF(ctx->Line.StippleFlag); // GL_LINE_STIPPLE disabling to get blender going
+       
+       /* HW doesnt appear to directly support these */
+       //FALLBACK_IF(ctx->Line.SmoothFlag); // GL_LINE_SMOOTH disabling to get blender going
+       FALLBACK_IF(ctx->Point.SmoothFlag); // GL_POINT_SMOOTH
+       /* Rest could be done with vertex fragments */
+       if (ctx->Extensions.NV_point_sprite || ctx->Extensions.ARB_point_sprite)
+               FALLBACK_IF(ctx->Point.PointSprite); // GL_POINT_SPRITE_NV
+       //GL_POINT_DISTANCE_ATTENUATION_ARB
+       //GL_POINT_FADE_THRESHOLD_SIZE_ARB
+       
        /* let r300_run_render do its job */
-       #if 0  
+#if 0
        stage->active = GL_FALSE;
-       #endif
+#endif
 }
 
 
@@ -791,3 +735,50 @@ const struct tnl_pipeline_stage _r300_render_stage = {
        r300_check_render,      /* check */
        r300_run_render         /* run */
 };
+       
+static GLboolean r300_run_tcl_render(GLcontext *ctx,
+                                struct tnl_pipeline_stage *stage)
+{
+   r300ContextPtr rmesa = R300_CONTEXT(ctx);
+   TNLcontext *tnl = TNL_CONTEXT(ctx);
+   struct vertex_buffer *VB = &tnl->vb;
+   GLuint i;
+
+       if (RADEON_DEBUG & DEBUG_PRIMS)
+               fprintf(stderr, "%s\n", __FUNCTION__);
+
+       return r300_run_vb_render(ctx, stage);
+}
+
+static void r300_check_tcl_render(GLcontext *ctx, struct tnl_pipeline_stage *stage)
+{
+       r300ContextPtr r300 = R300_CONTEXT(ctx);
+       int i;
+
+       if (RADEON_DEBUG & DEBUG_STATE)
+               fprintf(stderr, "%s\n", __FUNCTION__);
+
+       /* We only support rendering in hardware for now */
+       if (ctx->RenderMode != GL_RENDER) {
+               stage->active = GL_FALSE;
+               return;
+       }
+       if(VERTPROG_ACTIVE(ctx)) {
+               stage->active = GL_TRUE;
+               stage->inputs = ctx->VertexProgram.Current->InputsRead;
+       } else {
+               stage->active = GL_FALSE;
+       }
+}
+
+const struct tnl_pipeline_stage _r300_tcl_stage = {
+       "r300 tcl",
+       _NEW_ALL,               /* re-check (always re-check for now) */
+       0,                      /* re-run (always runs) */
+       GL_TRUE,                /* active */
+       0, 0,                   /* inputs (set in check_render), outputs */
+       0, 0,                   /* changed_inputs, private */
+       dtr,                    /* destructor */
+       r300_check_tcl_render,  /* check */
+       r300_run_tcl_render     /* run */
+};