Removing some regs that are wrong and adding some comments to r300_reg.h .
[mesa.git] / src / mesa / drivers / dri / r300 / r300_state.c
index 4662a08b9522b9fcc34e5583d28ab00696b5c907..bbbf674ee1a6142cd88dde0dfbcfdd0d4d103681 100644 (file)
@@ -209,11 +209,16 @@ static void r300_set_blend_cntl(r300ContextPtr rmesa, int func, int eqn, int cbi
 {
        GLuint new_ablend, new_cblend;
 
+       #if 0
+       fprintf(stderr, "eqnA=%08x funcA=%08x eqn=%08x func=%08x cbits=%08x\n", eqnA, funcA, eqn, func, cbits);
+       #endif
        new_ablend = eqnA | funcA;
-       new_cblend = eqn | func | cbits;
-       if(rmesa->hw.bld.cmd[R300_BLD_ABLEND] == rmesa->hw.bld.cmd[R300_BLD_CBLEND]){
+       new_cblend = eqn | func;
+       if(funcA == func){
                new_cblend |=  R300_BLEND_NO_SEPARATE;
                }
+       new_cblend |= cbits;
+       
        if((new_ablend != rmesa->hw.bld.cmd[R300_BLD_ABLEND])
                || (new_cblend != rmesa->hw.bld.cmd[R300_BLD_CBLEND])){
                R300_STATECHANGE(rmesa, bld);
@@ -412,9 +417,8 @@ static void r300UpdateCulling(GLcontext* ctx)
                if (ctx->Polygon.FrontFace == GL_CW)
                        val |= R300_FRONT_FACE_CW;
                else
-                       val |= R300_FRONT_FACE_CCW;
+                       val |= R300_FRONT_FACE_CCW;             
        }
-
        r300->hw.cul.cmd[R300_CUL_CULL] = val;
 }
 
@@ -474,15 +478,8 @@ static void r300Enable(GLcontext* ctx, GLenum cap, GLboolean state)
 
        case GL_STENCIL_TEST:
 
-               {
-               static int stencil=1;
-               if(stencil){
-                       fprintf(stderr, "%s:%s - do not know how to enable stencil. Help me !\n",
-                               __FILE__, __FUNCTION__);
-                       stencil=0;
-                       }
-               }
-
+               WARN_ONCE("Do not know how to enable stencil. Help me !\n");
+               
                if (r300->state.hw_stencil) {
                        //fprintf(stderr, "Stencil %s\n", state ? "enabled" : "disabled");
                        R300_STATECHANGE(r300, zs);
@@ -501,6 +498,29 @@ static void r300Enable(GLcontext* ctx, GLenum cap, GLboolean state)
        case GL_CULL_FACE:
                r300UpdateCulling(ctx);
                break;
+               
+       case GL_POLYGON_OFFSET_POINT:
+       case GL_POLYGON_OFFSET_LINE:
+               WARN_ONCE("Don't know how to enable polygon offset point/line. Help me !\n");
+               
+               /* Something is apparently blocking these from working */
+               R300_STATECHANGE(r300, unk42B4);
+               if(state){
+                       r300->hw.unk42B4.cmd[1] |= ~(3<<0);
+               } else {
+                       r300->hw.unk42B4.cmd[1] &= (3<<0);
+               }
+               break;
+               
+       case GL_POLYGON_OFFSET_FILL:
+               R300_STATECHANGE(r300, unk42B4);
+               if(state){
+                       r300->hw.unk42B4.cmd[1] |= (3<<0);
+               } else {
+                       r300->hw.unk42B4.cmd[1] &= ~(3<<0);
+               }
+               break;
+               
        case GL_VERTEX_PROGRAM_ARB:
                //TCL_FALLBACK(rmesa->glCtx, R200_TCL_FALLBACK_TCL_DISABLE, state);
        break;
@@ -620,11 +640,126 @@ static void r300ColorMask(GLcontext* ctx,
 static void r300PointSize(GLcontext * ctx, GLfloat size)
 {
        r300ContextPtr r300 = R300_CONTEXT(ctx);
-
+       
+       /* TODO: Validate point size */
+       R300_STATECHANGE(r300, ps);
+       r300->hw.ps.cmd[R300_PS_POINTSIZE] =
+               ((int)(size * 6) << R300_POINTSIZE_X_SHIFT) |
+               ((int)(size * 6) << R300_POINTSIZE_Y_SHIFT);
+       
+#if 0 /* r200 reg? */
        /* This might need fixing later */
        R300_STATECHANGE(r300, vps);
        r300->hw.vps.cmd[R300_VPS_POINTSIZE] = r300PackFloat32(1.0);
+#endif 
+}
+
+/* =============================================================
+ * Line state
+ */
+static void r300LineWidth(GLcontext *ctx, GLfloat widthf)
+{
+       r300ContextPtr r300 = R300_CONTEXT(ctx);
+       /* IMHO mesa isnt clamping line widths according to ctx->Const.*LineWidth
+          before calling this from the dd function table.
+          Since r300ResetHwState calls these with clamped values,
+          they must be set properly. */
+       
+       R300_STATECHANGE(r300, lcntl);
+       r300->hw.lcntl.cmd[1] = (int)(widthf * 6.0);
+       /* Doesnt look very good without this... */
+       r300->hw.lcntl.cmd[1] |= R300_LINE_CNT_UNK1;
+}
+
+/*
+
+glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); :  00000091 (  1001 0001)
+glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); : 00000001 (          1)
+
+glPolygonMode(GL_FRONT, GL_LINE); :           00000111 (1 0001 0001)
+glPolygonMode(GL_FRONT, GL_POINT); :          00000101 (1 0000 0001)
+
+glPolygonMode(GL_BACK, GL_LINE); :            000000a1 (  1010 0001)
+glPolygonMode(GL_BACK, GL_POINT); :           00000021 (    10 0001)
+
+*/
+
+/* exclusive */
+#define PM_NOT_BACK   (1<<8)
+#define PM_NOT_FRONT  (1<<5)
+
+#define PM_FRONT_LINE (1<<4)
+#define PM_BACK_LINE  (1<<7)
+
+static void r300PolygonMode(GLcontext *ctx, GLenum face, GLenum mode)
+{
+       r300ContextPtr r300 = R300_CONTEXT(ctx);
+       unsigned long hw_mode=0;
+       
+       hw_mode=r300->hw.unk4288.cmd[1];
+       hw_mode |= 1; /* enables point mode by default */
+
+       switch (face) {
+       case GL_FRONT:
+               //fprintf(stderr, "front\n");
+               hw_mode &= ~PM_NOT_FRONT;
+               switch (mode) {
+               case GL_LINE:
+                       hw_mode |= PM_FRONT_LINE;
+               break;
+               case GL_POINT:
+                       hw_mode &= ~PM_FRONT_LINE;
+               break;
+               case GL_FILL: /* No idea */
+                       hw_mode = 0;
+               break;
+               }
+       break;
+       
+       case GL_BACK:
+               //fprintf(stderr, "back\n");
+               hw_mode &= ~PM_NOT_BACK;
+               switch (mode) {
+               case GL_LINE:
+                       hw_mode |= PM_BACK_LINE;
+               break;
+               case GL_POINT:
+                       hw_mode &= ~PM_BACK_LINE;
+               break;
+               case GL_FILL: /* No idea */
+                       hw_mode = 0;
+               break;
+               }
+       break;
+       
+       case GL_FRONT_AND_BACK:
+               //fprintf(stderr, "front and back\n");
+               hw_mode &= ~PM_NOT_FRONT;
+               hw_mode &= ~PM_NOT_BACK;
+               switch (mode) {
+               case GL_LINE:
+                       hw_mode |= PM_FRONT_LINE;
+                       hw_mode |= PM_BACK_LINE;
+               break;
+               case GL_POINT:
+                       hw_mode &= ~PM_FRONT_LINE;
+                       hw_mode &= ~PM_BACK_LINE;
+               break;
+               case GL_FILL:
+                       hw_mode = 0;
+               break;
+               }
+       break;
+       }
+       
+       //if( front and back fill) hw_mode=0;
+       
+       if(r300->hw.unk4288.cmd[1] != hw_mode){
+               R300_STATECHANGE(r300, unk4288);
+               r300->hw.unk4288.cmd[1] = hw_mode;
+       }
 }
+
 /* =============================================================
  * Stencil
  */
@@ -679,6 +814,9 @@ static void r300PointSize(GLcontext * ctx, GLfloat size)
                    return R300_ZS_DECR_WRAP;
        case GL_INVERT:
                    return R300_ZS_INVERT;
+       default:
+               WARN_ONCE("Do not know how to translate stencil op");
+               return R300_ZS_KEEP;
        }
 }
 
@@ -691,7 +829,7 @@ static void r300StencilFunc(GLcontext * ctx, GLenum func,
                           ValueMask[0] << R300_RB3D_ZS2_STENCIL_MASK_SHIFT));
        GLuint flag;
 
-       R200_STATECHANGE(rmesa, zs);
+       R300_STATECHANGE(rmesa, zs);
 
        rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &= ~(
                (R300_ZS_MASK << R300_RB3D_ZS1_FRONT_FUNC_SHIFT)
@@ -710,7 +848,7 @@ static void r300StencilMask(GLcontext * ctx, GLuint mask)
 {
        r300ContextPtr rmesa = R300_CONTEXT(ctx);
 
-       R200_STATECHANGE(rmesa, zs);
+       R300_STATECHANGE(rmesa, zs);
        rmesa->hw.zs.cmd[R300_ZS_CNTL_2]  &= ~(R300_ZS_MASK << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT);
        rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |= ctx->Stencil.WriteMask[0] << R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT;
 }
@@ -721,7 +859,7 @@ static void r300StencilOp(GLcontext * ctx, GLenum fail,
 {
        r300ContextPtr rmesa = R300_CONTEXT(ctx);
 
-       R200_STATECHANGE(rmesa, zs);
+       R300_STATECHANGE(rmesa, zs);
                /* It is easier to mask what's left.. */
        rmesa->hw.zs.cmd[R300_ZS_CNTL_1] &= (R300_ZS_MASK << R300_RB3D_ZS1_DEPTH_FUNC_SHIFT);
 
@@ -740,7 +878,7 @@ static void r300ClearStencil(GLcontext * ctx, GLint s)
        r300ContextPtr rmesa = R300_CONTEXT(ctx);
 
        /* Not sure whether this is correct.. */
-       R200_STATECHANGE(rmesa, zs);
+       R300_STATECHANGE(rmesa, zs);
        rmesa->hw.zs.cmd[R300_ZS_CNTL_2] =
            ((GLuint) ctx->Stencil.Clear |
             (0xff << R200_STENCIL_MASK_SHIFT) |
@@ -790,7 +928,7 @@ static void r300Viewport(GLcontext * ctx, GLint x, GLint y,
         * setting below.  Could apply deltas to rescue pipelined viewport
         * values, or keep the originals hanging around.
         */
-       R200_FIREVERTICES(R200_CONTEXT(ctx));
+       R300_FIREVERTICES(R300_CONTEXT(ctx));
        r300UpdateWindow(ctx);
 }
 
@@ -799,6 +937,25 @@ static void r300DepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval)
        r300UpdateWindow(ctx);
 }
 
+/* =============================================================
+ * Polygon state
+ */
+static void r300PolygonOffset(GLcontext * ctx, GLfloat factor, GLfloat units)
+{
+       r300ContextPtr rmesa = R300_CONTEXT(ctx);
+       GLfloat constant = units * /*rmesa->state.depth.scale*/4;
+       
+       factor *= 12; 
+
+/*    fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */
+
+       R300_STATECHANGE(rmesa, zbs);
+       rmesa->hw.zbs.cmd[R300_ZBS_T_FACTOR] = r300PackFloat32(factor);
+       rmesa->hw.zbs.cmd[R300_ZBS_T_CONSTANT] = r300PackFloat32(constant);
+       rmesa->hw.zbs.cmd[R300_ZBS_W_FACTOR] = r300PackFloat32(factor);
+       rmesa->hw.zbs.cmd[R300_ZBS_W_CONSTANT] = r300PackFloat32(constant);
+}
+
 /* Routing and texture-related */
 
 void r300_setup_routing(GLcontext *ctx, GLboolean immediate)
@@ -839,32 +996,82 @@ void r300_setup_routing(GLcontext *ctx, GLboolean immediate)
 
                /* All offsets are 0 - for use by immediate mode.
                Should change later to handle vertex buffers */
+       if(r300->current_vp!=NULL){
+
+       /* VERT_ATTRIB_WEIGHT, VERT_ATTRIB_SIX, VERT_ATTRIB_SEVEN, VERT_ATTRIB_GENERIC0,
+          VERT_ATTRIB_GENERIC1, VERT_ATTRIB_GENERIC2, VERT_ATTRIB_GENERIC3 */
+       r300->state.render_inputs = 0;
+          
+       if(r300->current_vp->inputs[VERT_ATTRIB_POS] != -1){
+               reg=r300->current_vp->inputs[VERT_ATTRIB_POS];
+               CONFIGURE_AOS(VB->ObjPtr, 0, i_coords, AOS_FORMAT_FLOAT);
+               r300->state.render_inputs |= _TNL_BIT_POS;
+       }
+       if(r300->current_vp->inputs[VERT_ATTRIB_NORMAL] != -1){
+               reg=r300->current_vp->inputs[VERT_ATTRIB_NORMAL];
+               CONFIGURE_AOS(VB->NormalPtr, 0, i_normal, AOS_FORMAT_FLOAT);
+               r300->state.render_inputs |= _TNL_BIT_NORMAL;
+       }
+       if(r300->current_vp->inputs[VERT_ATTRIB_COLOR0] != -1){
+               reg=r300->current_vp->inputs[VERT_ATTRIB_COLOR0];
+               CONFIGURE_AOS(VB->ColorPtr[0], 0, i_color[0], AOS_FORMAT_FLOAT_COLOR);
+               r300->state.render_inputs |= _TNL_BIT_COLOR0;
+       }
+       if(r300->current_vp->inputs[VERT_ATTRIB_COLOR1] != -1){
+               reg=r300->current_vp->inputs[VERT_ATTRIB_COLOR1];
+               CONFIGURE_AOS(VB->SecondaryColorPtr[0], 0, i_color[1], AOS_FORMAT_FLOAT_COLOR);
+               r300->state.render_inputs |= _TNL_BIT_COLOR1;
+       }
+       if(r300->current_vp->inputs[VERT_ATTRIB_FOG] != -1){
+               reg=r300->current_vp->inputs[VERT_ATTRIB_FOG];
+               CONFIGURE_AOS(VB->FogCoordPtr, 0, i_fog, AOS_FORMAT_FLOAT);
+               r300->state.render_inputs |= _TNL_BIT_FOG;
+       }
+       for(i=0;i < ctx->Const.MaxTextureUnits;i++) // tex 7 is last 
+               if(r300->current_vp->inputs[VERT_ATTRIB_TEX0+i] != -1){
+                       reg=r300->current_vp->inputs[VERT_ATTRIB_TEX0+i];
+                       CONFIGURE_AOS(VB->TexCoordPtr[i], 0, i_tex[i], AOS_FORMAT_FLOAT);
+                       r300->state.render_inputs |= _TNL_BIT_TEX0<<i;
+               }
+#if 0
+       if((tnl->render_inputs & _TNL_BIT_INDEX))
+               CONFIGURE_AOS(VB->IndexPtr[0], 0, i_index, AOS_FORMAT_FLOAT);
+       
+       if((tnl->render_inputs & _TNL_BIT_POINTSIZE))
+               CONFIGURE_AOS(VB->PointSizePtr, 0, i_pointsize, AOS_FORMAT_FLOAT);
+#endif 
+       }else{
+       
+       r300->state.render_inputs = tnl->render_inputs;
+       
        if(tnl->render_inputs & _TNL_BIT_POS)
                CONFIGURE_AOS(VB->ObjPtr, 0, i_coords, AOS_FORMAT_FLOAT);
        if(tnl->render_inputs & _TNL_BIT_NORMAL)
                CONFIGURE_AOS(VB->NormalPtr, 0, i_normal, AOS_FORMAT_FLOAT);
-
+       
        if(tnl->render_inputs & _TNL_BIT_COLOR0)
                CONFIGURE_AOS(VB->ColorPtr[0], 0, i_color[0], AOS_FORMAT_FLOAT_COLOR);
        if(tnl->render_inputs & _TNL_BIT_COLOR1)
                CONFIGURE_AOS(VB->SecondaryColorPtr[0], 0, i_color[1], AOS_FORMAT_FLOAT_COLOR);
-
-       if(tnl->render_inputs & _TNL_BIT_FOG)
-               CONFIGURE_AOS(VB->FogCoordPtr, 0, i_fog, AOS_FORMAT_FLOAT);
-
+       
+       /*if(tnl->render_inputs & _TNL_BIT_FOG) // Causes lock ups when immediate mode is on
+               CONFIGURE_AOS(VB->FogCoordPtr, 0, i_fog, AOS_FORMAT_FLOAT);*/
+       
        for(i=0;i < ctx->Const.MaxTextureUnits;i++)
                if(tnl->render_inputs & (_TNL_BIT_TEX0<<i))
                        CONFIGURE_AOS(VB->TexCoordPtr[i], 0, i_tex[i], AOS_FORMAT_FLOAT);
-
+       
        if(tnl->render_inputs & _TNL_BIT_INDEX)
                CONFIGURE_AOS(VB->IndexPtr[0], 0, i_index, AOS_FORMAT_FLOAT);
        if(tnl->render_inputs & _TNL_BIT_POINTSIZE)
                CONFIGURE_AOS(VB->PointSizePtr, 0, i_pointsize, AOS_FORMAT_FLOAT);
-
+       }
+       
        r300->state.aos_count=count;
 
        if (RADEON_DEBUG & DEBUG_STATE)
-               fprintf(stderr, "aos_count=%d\n", count);
+               fprintf(stderr, "aos_count=%d render_inputs=%08x\n", count, r300->state.render_inputs);
+               
 
        if(count>R300_MAX_AOS_ARRAYS){
                fprintf(stderr, "Aieee ! AOS array count exceeded !\n");
@@ -948,11 +1155,19 @@ void r300_setup_routing(GLcontext *ctx, GLboolean immediate)
        R300_STATECHANGE(r300, vic);
        r300->hw.vic.cmd[R300_VIC_CNTL_0]=0x5555;  /* Hard coded value, no idea what it means */
 
-       r300->hw.vic.cmd[R300_VIC_CNTL_1]=R300_INPUT_CNTL_POS
-                                       | R300_INPUT_CNTL_COLOR;
+       r300->hw.vic.cmd[R300_VIC_CNTL_1]=0;
+       
+       if(r300->state.render_inputs & _TNL_BIT_POS)
+               r300->hw.vic.cmd[R300_VIC_CNTL_1]|=R300_INPUT_CNTL_POS;
+       
+       if(r300->state.render_inputs & _TNL_BIT_NORMAL)
+               r300->hw.vic.cmd[R300_VIC_CNTL_1]|=R300_INPUT_CNTL_NORMAL;
+       
+       if(r300->state.render_inputs & _TNL_BIT_COLOR0)
+               r300->hw.vic.cmd[R300_VIC_CNTL_1]|=R300_INPUT_CNTL_COLOR;
 
        for(i=0;i < ctx->Const.MaxTextureUnits;i++)
-               if(ctx->Texture.Unit[i].Enabled)
+               if(r300->state.render_inputs & (_TNL_BIT_TEX0<<i))
                        r300->hw.vic.cmd[R300_VIC_CNTL_1]|=(R300_INPUT_CNTL_TC0<<i);
 
        /* Stage 3: VAP output */
@@ -962,7 +1177,7 @@ void r300_setup_routing(GLcontext *ctx, GLboolean immediate)
 
        r300->hw.vof.cmd[R300_VOF_CNTL_1]=0;
        for(i=0;i < ctx->Const.MaxTextureUnits;i++)
-               if(ctx->Texture.Unit[i].Enabled)
+               if(r300->state.render_inputs & (_TNL_BIT_TEX0<<i))
                        r300->hw.vof.cmd[R300_VOF_CNTL_1]|=(4<<(3*i));
 
 }
@@ -1087,8 +1302,7 @@ void r300_setup_textures(GLcontext *ctx)
        R300_STATECHANGE(r300, tex.format);
        R300_STATECHANGE(r300, tex.offset);
        R300_STATECHANGE(r300, tex.unknown4);
-       R300_STATECHANGE(r300, tex.unknown5);
-       //R300_STATECHANGE(r300, tex.border_color);
+       R300_STATECHANGE(r300, tex.border_color);
 
        r300->state.texture.tc_count=0;
 
@@ -1104,15 +1318,23 @@ void r300_setup_textures(GLcontext *ctx)
                exit(-1);
                }
        for(i=0;i<mtu;i++){
-               if(ctx->Texture.Unit[i].Enabled){
+               if( ((r300->state.render_inputs & (_TNL_BIT_TEX0<<i))!=0) != ((ctx->Texture.Unit[i].Enabled)!=0) ) {
+                       WARN_ONCE("Mismatch between render_inputs and ctx->Texture.Unit[i].Enabled value.\n");
+                       }
+               if(r300->state.render_inputs & (_TNL_BIT_TEX0<<i)){
                        t=r300->state.texture.unit[i].texobj;
-                       fprintf(stderr, "format=%08x\n", r300->state.texture.unit[i].format);
+                       //fprintf(stderr, "format=%08x\n", r300->state.texture.unit[i].format);
                        r300->state.texture.tc_count++;
                        if(t==NULL){
                                fprintf(stderr, "Texture unit %d enabled, but corresponding texobj is NULL, using default object.\n", i);
                                //exit(-1);
                                t=&default_tex_obj;
                                }
+                       //fprintf(stderr, "t->format=%08x\n", t->format);
+                       if((t->format & 0xffffff00)==0xffffff00){
+                               WARN_ONCE("unknown texture format (entry %x) encountered. Help me !\n", t->format & 0xff);
+                               //fprintf(stderr, "t->format=%08x\n", t->format);
+                               }
                        if (RADEON_DEBUG & DEBUG_STATE)
                                fprintf(stderr, "Activating texture unit %d\n", i);
                        max_texture_unit=i;
@@ -1126,10 +1348,8 @@ void r300_setup_textures(GLcontext *ctx)
                        //fprintf(stderr, "t->format=%08x\n", t->format);
                        r300->hw.tex.offset.cmd[R300_TEX_VALUE_0+i]=r300->radeon.radeonScreen->fbLocation+t->offset;
                        r300->hw.tex.unknown4.cmd[R300_TEX_VALUE_0+i]=0x0;
-                       r300->hw.tex.unknown5.cmd[R300_TEX_VALUE_0+i]=0x0;
-                       //r300->hw.tex.border_color.cmd[R300_TEX_VALUE_0+i]=t->pp_border_color;
+                       r300->hw.tex.border_color.cmd[R300_TEX_VALUE_0+i]=t->pp_border_color;
                        }
-
                }
        ((drm_r300_cmd_header_t*)r300->hw.tex.filter.cmd)->unchecked_state.count = max_texture_unit+1;
        ((drm_r300_cmd_header_t*)r300->hw.tex.unknown1.cmd)->unchecked_state.count = max_texture_unit+1;
@@ -1137,8 +1357,7 @@ void r300_setup_textures(GLcontext *ctx)
        ((drm_r300_cmd_header_t*)r300->hw.tex.format.cmd)->unchecked_state.count = max_texture_unit+1;
        ((drm_r300_cmd_header_t*)r300->hw.tex.offset.cmd)->unchecked_state.count = max_texture_unit+1;
        ((drm_r300_cmd_header_t*)r300->hw.tex.unknown4.cmd)->unchecked_state.count = max_texture_unit+1;
-       ((drm_r300_cmd_header_t*)r300->hw.tex.unknown5.cmd)->unchecked_state.count = max_texture_unit+1;
-       //((drm_r300_cmd_header_t*)r300->hw.tex.border_color.cmd)->unchecked_state.count = max_texture_unit+1;
+       ((drm_r300_cmd_header_t*)r300->hw.tex.border_color.cmd)->unchecked_state.count = max_texture_unit+1;
 
        if (RADEON_DEBUG & DEBUG_STATE)
                fprintf(stderr, "TX_ENABLE: %08x  max_texture_unit=%d\n", r300->hw.txe.cmd[R300_TXE_ENABLE], max_texture_unit);
@@ -1240,11 +1459,17 @@ void static inline setup_vertex_shader_fragment(r300ContextPtr r300, int dest, s
        }
 }
 
+void r300SetupVertexProgram(r300ContextPtr rmesa);
 
 void r300SetupVertexShader(r300ContextPtr rmesa)
 {
        GLcontext* ctx = rmesa->radeon.glCtx;
-
+       
+       if(rmesa->current_vp != NULL){
+               r300SetupVertexProgram(rmesa);
+               return ;
+       }       
+       
        /* Reset state, in case we don't use something */
        ((drm_r300_cmd_header_t*)rmesa->hw.vpp.cmd)->vpu.count = 0;
        ((drm_r300_cmd_header_t*)rmesa->hw.vpi.cmd)->vpu.count = 0;
@@ -1301,27 +1526,15 @@ void r300SetupVertexShader(r300ContextPtr rmesa)
 void r300SetupVertexProgram(r300ContextPtr rmesa)
 {
        GLcontext* ctx = rmesa->radeon.glCtx;
+       int inst_count;
+       int param_count;
 
        /* Reset state, in case we don't use something */
        ((drm_r300_cmd_header_t*)rmesa->hw.vpp.cmd)->vpu.count = 0;
        ((drm_r300_cmd_header_t*)rmesa->hw.vpi.cmd)->vpu.count = 0;
        ((drm_r300_cmd_header_t*)rmesa->hw.vps.cmd)->vpu.count = 0;
 
-#if 0
-/* This needs to be replaced by vertex shader generation code */
-
-
-       /* textures enabled ? */
-       if(rmesa->state.texture.tc_count>0){
-               rmesa->state.vertex_shader=SINGLE_TEXTURE_VERTEX_SHADER;
-               } else {
-               rmesa->state.vertex_shader=FLAT_COLOR_VERTEX_SHADER;
-               }
-
-
-        rmesa->state.vertex_shader.matrix[0].length=16;
-        memcpy(rmesa->state.vertex_shader.matrix[0].body.f, ctx->_ModelProjectMatrix.m, 16*4);
-#endif
+       r300VertexProgUpdateParams(ctx, rmesa->current_vp);
        
        setup_vertex_shader_fragment(rmesa, VSF_DEST_PROGRAM, &(rmesa->current_vp->program));
 
@@ -1331,15 +1544,18 @@ void r300SetupVertexProgram(r300ContextPtr rmesa)
        setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN1, &(rmesa->state.vertex_shader.unknown1));
        setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN2, &(rmesa->state.vertex_shader.unknown2));
        #endif
-
+       
+       inst_count=rmesa->current_vp->program.length/4 - 1;
+       param_count=rmesa->current_vp->params.length/4;
+                                       
        R300_STATECHANGE(rmesa, pvs);
        rmesa->hw.pvs.cmd[R300_PVS_CNTL_1]=(0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT)
-               | (rmesa->state.vertex_shader.unknown_ptr1 << R300_PVS_CNTL_1_UNKNOWN_SHIFT)
-               | (rmesa->current_vp->program.length/4 << R300_PVS_CNTL_1_PROGRAM_END_SHIFT);
+               | (inst_count/*0*/ << R300_PVS_CNTL_1_UNKNOWN_SHIFT)
+               | (inst_count << R300_PVS_CNTL_1_PROGRAM_END_SHIFT);
        rmesa->hw.pvs.cmd[R300_PVS_CNTL_2]=(0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT)
-               | (rmesa->current_vp->params.length/4 << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT);
+               | (param_count << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT);
        rmesa->hw.pvs.cmd[R300_PVS_CNTL_3]=(0/*rmesa->state.vertex_shader.unknown_ptr2*/ << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT)
-       | (rmesa->current_vp->program.length/4/*rmesa->state.vertex_shader.unknown_ptr3*/ << 0);
+       | ((inst_count-rmesa->current_vp->t2rs) /*rmesa->state.vertex_shader.unknown_ptr3*/ << 0);
 
        /* This is done for vertex shader fragments, but also needs to be done for vap_pvs,
        so I leave it as a reminder */
@@ -1349,6 +1565,112 @@ void r300SetupVertexProgram(r300ContextPtr rmesa)
        #endif
 }
 
+
+/* just a skeleton for now.. */
+void r300GenerateTexturePixelShader(r300ContextPtr r300)
+{
+       int i, mtu;
+       mtu = r300->radeon.glCtx->Const.MaxTextureUnits;
+       GLenum envMode;
+       
+       int tex_inst=0, alu_inst=0;
+       
+       for(i=0;i<mtu;i++){
+               /* No need to proliferate {} */
+               if(! (r300->state.render_inputs & (_TNL_BIT_TEX0<<i)))continue;
+               
+               envMode = r300->radeon.glCtx->Texture.Unit[i].EnvMode;
+               //fprintf(stderr, "envMode=%s\n", _mesa_lookup_enum_by_nr(envMode));
+               
+               /* Fetch textured pixel */
+               
+               r300->state.pixel_shader.program.tex.inst[tex_inst]=0x00018000;
+               tex_inst++;
+               
+               switch(r300->radeon.glCtx->Texture.Unit[i]._CurrentCombine->ModeRGB){
+                       case GL_REPLACE:
+                               WARN_ONCE("ModeA==GL_REPLACE is possibly broken.\n");
+                               r300->state.pixel_shader.program.alu.inst[alu_inst].inst0=
+                                       EASY_PFS_INSTR0(MAD, SRC0C_XYZ, ONE, ZERO);
+                       
+                               r300->state.pixel_shader.program.alu.inst[alu_inst].inst1=
+                                       EASY_PFS_INSTR1(0, 0, 0 | PFS_FLAG_CONST, 0 | PFS_FLAG_CONST, NONE, ALL);
+                               break;
+                       case GL_MODULATE:
+                               WARN_ONCE("ModeRGB==GL_MODULATE is possibly broken.\n");
+                               r300->state.pixel_shader.program.alu.inst[alu_inst].inst0=
+                                       EASY_PFS_INSTR0(MAD, SRC0C_XYZ, SRC1C_XYZ, ZERO);
+                               
+                               r300->state.pixel_shader.program.alu.inst[alu_inst].inst1=
+                                       EASY_PFS_INSTR1(0, 0, 1, 0 | PFS_FLAG_CONST, NONE, ALL);
+                               
+                               break;
+                       default:
+                               fprintf(stderr, "ModeRGB=%s is not implemented yet !\n",
+                                        _mesa_lookup_enum_by_nr(r300->radeon.glCtx->Texture.Unit[i]._CurrentCombine->ModeRGB));
+                               /* PFS_NOP */
+                               r300->state.pixel_shader.program.alu.inst[alu_inst].inst0=
+                                       EASY_PFS_INSTR0(MAD, SRC0C_XYZ, ONE, ZERO);
+                       
+                               r300->state.pixel_shader.program.alu.inst[alu_inst].inst1=
+                                       EASY_PFS_INSTR1(0, 0, 0 | PFS_FLAG_CONST, 0 | PFS_FLAG_CONST, NONE, ALL);
+                       }
+               switch(r300->radeon.glCtx->Texture.Unit[i]._CurrentCombine->ModeA){
+                       case GL_REPLACE:
+                               WARN_ONCE("ModeA==GL_REPLACE is possibly broken.\n");
+                               r300->state.pixel_shader.program.alu.inst[alu_inst].inst2=
+                                       EASY_PFS_INSTR2(MAD, SRC0A, ONE, ZERO);
+                               
+                               r300->state.pixel_shader.program.alu.inst[alu_inst].inst3=
+                                       EASY_PFS_INSTR3(0, 0, 0| PFS_FLAG_CONST, 0 | PFS_FLAG_CONST, OUTPUT);
+
+                               #if 0
+                               fprintf(stderr, "numArgsA=%d sourceA[0]=%s op=%d\n",
+                                        r300->radeon.glCtx->Texture.Unit[i]._CurrentCombine->_NumArgsA,
+                                        _mesa_lookup_enum_by_nr(r300->radeon.glCtx->Texture.Unit[i]._CurrentCombine->SourceA[0]),
+                                        r300->radeon.glCtx->Texture.Unit[i]._CurrentCombine->OperandA[0]-GL_SRC_ALPHA);
+                               #endif
+                               break;                          
+                       case GL_MODULATE:
+                               WARN_ONCE("ModeA==GL_MODULATE is possibly broken.\n");
+                               
+                               r300->state.pixel_shader.program.alu.inst[alu_inst].inst2=
+                                       EASY_PFS_INSTR2(MAD, SRC0A, SRC1A, ZERO);
+                               
+                               r300->state.pixel_shader.program.alu.inst[alu_inst].inst3=
+                                       EASY_PFS_INSTR3(0, 0, 1, 0 | PFS_FLAG_CONST, OUTPUT);
+                               
+                               break;
+                       default:
+                               fprintf(stderr, "ModeA=%s is not implemented yet !\n",
+                                        _mesa_lookup_enum_by_nr(r300->radeon.glCtx->Texture.Unit[i]._CurrentCombine->ModeA));
+                               /* PFS_NOP */
+                               r300->state.pixel_shader.program.alu.inst[alu_inst].inst2=
+                                       EASY_PFS_INSTR2(MAD, SRC0A, ONE, ZERO);
+                               
+                               r300->state.pixel_shader.program.alu.inst[alu_inst].inst3=
+                                       EASY_PFS_INSTR3(0, 0, 0 | PFS_FLAG_CONST, 0 | PFS_FLAG_CONST, OUTPUT);
+
+                       }
+                                       
+               alu_inst++;                             
+               }
+               
+       r300->state.pixel_shader.program.tex.length=tex_inst;
+       r300->state.pixel_shader.program.tex_offset=0;
+       r300->state.pixel_shader.program.tex_end=tex_inst-1;
+
+       #if 0
+       /* saturate last instruction, like i915 driver does */
+       r300->state.pixel_shader.program.alu.inst[alu_inst-1].inst0|=R300_FPI0_OUTC_SAT;
+       r300->state.pixel_shader.program.alu.inst[alu_inst-1].inst2|=R300_FPI2_OUTA_SAT;
+       #endif
+               
+       r300->state.pixel_shader.program.alu.length=alu_inst;
+       r300->state.pixel_shader.program.alu_offset=0;
+       r300->state.pixel_shader.program.alu_end=alu_inst-1;
+}
+
 void r300SetupPixelShader(r300ContextPtr rmesa)
 {
 int i,k;
@@ -1358,6 +1680,7 @@ int i,k;
        /* textures enabled ? */
        if(rmesa->state.texture.tc_count>0){
                rmesa->state.pixel_shader=SINGLE_TEXTURE_PIXEL_SHADER;
+               r300GenerateTexturePixelShader(rmesa);
                } else {
                rmesa->state.pixel_shader=FLAT_COLOR_PIXEL_SHADER;
                }
@@ -1430,6 +1753,7 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state)
        r300ResetHwState(r300);
 }
 
+void update_zbias(GLcontext * ctx, int prim);
 
 /**
  * Completely recalculates hardware state based on the Mesa state.
@@ -1467,9 +1791,9 @@ void r300ResetHwState(r300ContextPtr r300)
 
        r300UpdateCulling(ctx);
 
-       r300_setup_routing(ctx, GL_TRUE);
-
        r300UpdateTextureState(ctx);
+       
+       r300_setup_routing(ctx, GL_TRUE);
        r300_setup_textures(ctx);
        r300_setup_rs_unit(ctx);
 
@@ -1495,8 +1819,11 @@ void r300ResetHwState(r300ContextPtr r300)
 
        r300->hw.unk2134.cmd[1] = 0x00FFFFFF;
        r300->hw.unk2134.cmd[2] = 0x00000000;
-
+#ifdef MESA_BIG_ENDIAN
+       r300->hw.unk2140.cmd[1] = 0x00000002;
+#else
        r300->hw.unk2140.cmd[1] = 0x00000000;
+#endif
 
        #if 0 /* Done in setup routing */
        ((drm_r300_cmd_header_t*)r300->hw.vir[0].cmd)->unchecked_state.count = 1;
@@ -1560,13 +1887,22 @@ void r300ResetHwState(r300ContextPtr r300)
 
        r300->hw.unk4214.cmd[1] = 0x00050005;
 
+       r300PointSize(ctx, ctx->Point._Size);
+#if 0  
        r300->hw.ps.cmd[R300_PS_POINTSIZE] = (6 << R300_POINTSIZE_X_SHIFT) |
                                             (6 << R300_POINTSIZE_Y_SHIFT);
-
+#endif 
+                       
        r300->hw.unk4230.cmd[1] = 0x01800000;
        r300->hw.unk4230.cmd[2] = 0x00020006;
        r300->hw.unk4230.cmd[3] = r300PackFloat32(1.0 / 192.0);
-
+       
+       r300LineWidth(ctx, ctx->Line._Width);
+       
+#ifdef EXP_C
+       static int foobar=0;
+       r300->hw.lsf.cmd[1] = foobar++; //0x3a088889;
+#endif
        r300->hw.unk4260.cmd[1] = 0;
        r300->hw.unk4260.cmd[2] = r300PackFloat32(0.0);
        r300->hw.unk4260.cmd[3] = r300PackFloat32(1.0);
@@ -1576,7 +1912,11 @@ void r300ResetHwState(r300ContextPtr r300)
        r300->hw.unk4274.cmd[3] = 0x00000000;
        r300->hw.unk4274.cmd[4] = 0x00000000;
 
+       r300PolygonMode(ctx, GL_FRONT, ctx->Polygon.FrontMode);
+       r300PolygonMode(ctx, GL_BACK, ctx->Polygon.BackMode);
+#if 0
        r300->hw.unk4288.cmd[1] = 0x00000000;
+#endif 
        r300->hw.unk4288.cmd[2] = 0x00000001;
        r300->hw.unk4288.cmd[3] = 0x00000000;
        r300->hw.unk4288.cmd[4] = 0x00000000;
@@ -1584,15 +1924,17 @@ void r300ResetHwState(r300ContextPtr r300)
 
        r300->hw.unk42A0.cmd[1] = 0x00000000;
 
+       update_zbias(ctx, GL_TRIANGLES);/* FIXME */
+#if 0  
        r300->hw.unk42B4.cmd[1] = 0x00000000;
-
+#endif 
        r300->hw.unk42C0.cmd[1] = 0x4B7FFFFF;
        r300->hw.unk42C0.cmd[2] = 0x00000000;
 
 
        r300->hw.unk43A4.cmd[1] = 0x0000001C;
        r300->hw.unk43A4.cmd[2] = 0x2DA49525;
-
+       
        r300->hw.unk43E8.cmd[1] = 0x00FFFFFF;
 
        #if 0
@@ -1754,7 +2096,6 @@ void r300InitState(r300ContextPtr r300)
 }
 
 
-
 /**
  * Initialize driver's state callback functions
  */
@@ -1784,5 +2125,8 @@ void r300InitStateFuncs(struct dd_function_table* functions)
        functions->Viewport = r300Viewport;
        functions->DepthRange = r300DepthRange;
        functions->PointSize = r300PointSize;
+       functions->LineWidth = r300LineWidth;
+       
+       functions->PolygonOffset = r300PolygonOffset;
+       functions->PolygonMode = r300PolygonMode;
 }
-