radeon/r300: Code clean up and logic fix.
[mesa.git] / src / mesa / drivers / dri / radeon / radeon_state.c
index 86d872030bc096224a872332c5f306997088fe2b..56f82bdb0b62191466a4626e8bc49494a5ca4d5f 100644 (file)
@@ -40,6 +40,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "main/state.h"
 #include "main/context.h"
 #include "main/framebuffer.h"
+#include "main/simple_list.h"
 
 #include "vbo/vbo.h"
 #include "tnl/tnl.h"
@@ -47,6 +48,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "swrast_setup/swrast_setup.h"
 
 #include "radeon_context.h"
+#include "radeon_mipmap_tree.h"
 #include "radeon_ioctl.h"
 #include "radeon_state.h"
 #include "radeon_tcl.h"
@@ -148,7 +150,7 @@ static void radeonBlendFuncSeparate( GLcontext *ctx,
                                     GLenum sfactorA, GLenum dfactorA )
 {
    r100ContextPtr rmesa = R100_CONTEXT(ctx);
-   GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] & 
+   GLuint b = rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] &
       ~(RADEON_SRC_BLEND_MASK | RADEON_DST_BLEND_MASK);
    GLboolean fallback = GL_FALSE;
 
@@ -391,7 +393,7 @@ static void radeonFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param )
         rmesa->hw.fog.cmd[FOG_D] = d.i;
       }
       break;
-   case GL_FOG_COLOR: 
+   case GL_FOG_COLOR:
       RADEON_STATECHANGE( rmesa, ctx );
       UNCLAMPED_FLOAT_TO_RGB_CHAN( col, ctx->Fog.Color );
       rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~RADEON_FOG_COLOR_MASK;
@@ -457,6 +459,10 @@ static void radeonFrontFace( GLcontext *ctx, GLenum mode )
    RADEON_STATECHANGE( rmesa, tcl );
    rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_CULL_FRONT_IS_CCW;
 
+   /* Winding is inverted when rendering to FBO */
+   if (ctx->DrawBuffer && ctx->DrawBuffer->Name)
+      mode = (mode == GL_CW) ? GL_CCW : GL_CW;
+
    switch ( mode ) {
    case GL_CW:
       rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_FFACE_CULL_CW;
@@ -494,7 +500,7 @@ static void radeonLineStipple( GLcontext *ctx, GLint factor, GLushort pattern )
    r100ContextPtr rmesa = R100_CONTEXT(ctx);
 
    RADEON_STATECHANGE( rmesa, lin );
-   rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] = 
+   rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] =
       ((((GLuint)factor & 0xff) << 16) | ((GLuint)pattern));
 }
 
@@ -507,11 +513,18 @@ static void radeonColorMask( GLcontext *ctx,
                             GLboolean b, GLboolean a )
 {
    r100ContextPtr rmesa = R100_CONTEXT(ctx);
-   GLuint mask = radeonPackColor( rmesa->radeon.radeonScreen->cpp,
-                                 ctx->Color.ColorMask[RCOMP],
-                                 ctx->Color.ColorMask[GCOMP],
-                                 ctx->Color.ColorMask[BCOMP],
-                                 ctx->Color.ColorMask[ACOMP] );
+   struct radeon_renderbuffer *rrb;
+   GLuint mask;
+
+   rrb = radeon_get_colorbuffer(&rmesa->radeon);
+   if (!rrb)
+     return;
+
+   mask = radeonPackColor( rrb->cpp,
+                          ctx->Color.ColorMask[RCOMP],
+                          ctx->Color.ColorMask[GCOMP],
+                          ctx->Color.ColorMask[BCOMP],
+                          ctx->Color.ColorMask[ACOMP] );
 
    if ( rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK] != mask ) {
       RADEON_STATECHANGE( rmesa, msk );
@@ -528,7 +541,8 @@ static void radeonPolygonOffset( GLcontext *ctx,
                                 GLfloat factor, GLfloat units )
 {
    r100ContextPtr rmesa = R100_CONTEXT(ctx);
-   float_ui32_type constant =  { units * rmesa->radeon.state.depth.scale };
+   const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
+   float_ui32_type constant =  { units * depthScale };
    float_ui32_type factoru = { factor };
 
    RADEON_STATECHANGE( rmesa, zbs );
@@ -556,7 +570,7 @@ static void radeonPolygonStipple( GLcontext *ctx, const GLubyte *mask )
    /* FIXME: Use window x,y offsets into stipple RAM.
     */
    stipple.mask = rmesa->state.stipple.mask;
-   drmCommandWrite( rmesa->radeon.dri.fd, DRM_RADEON_STIPPLE, 
+   drmCommandWrite( rmesa->radeon.dri.fd, DRM_RADEON_STIPPLE,
                     &stipple, sizeof(drm_radeon_stipple_t) );
    UNLOCK_HARDWARE( &rmesa->radeon );
 }
@@ -567,7 +581,7 @@ static void radeonPolygonMode( GLcontext *ctx, GLenum face, GLenum mode )
    GLboolean flag = (ctx->_TriangleCaps & DD_TRI_UNFILLED) != 0;
 
    /* Can't generally do unfilled via tcl, but some good special
-    * cases work. 
+    * cases work.
     */
    TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_UNFILLED, flag);
    if (rmesa->radeon.TclFallback) {
@@ -615,7 +629,7 @@ static void radeonUpdateSpecular( GLcontext *ctx )
       rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_DIFFUSE;
       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
       p |=  RADEON_SPECULAR_ENABLE;
-      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= 
+      rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &=
         ~RADEON_DIFFUSE_SPECULAR_COMBINE;
    }
    else if (ctx->Light.Enabled) {
@@ -645,7 +659,7 @@ static void radeonUpdateSpecular( GLcontext *ctx )
            RADEON_TCL_COMPUTE_SPECULAR) != 0;
       }
    }
+
    TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_FOGCOORDSPEC, flag);
 
    if (NEED_SECONDARY_COLOR(ctx)) {
@@ -661,7 +675,7 @@ static void radeonUpdateSpecular( GLcontext *ctx )
 
    /* Update vertex/render formats
     */
-   if (rmesa->radeon.TclFallback) { 
+   if (rmesa->radeon.TclFallback) {
       radeonChooseRenderState( ctx );
       radeonChooseVertexState( ctx );
    }
@@ -673,7 +687,7 @@ static void radeonUpdateSpecular( GLcontext *ctx )
  */
 
 
-/* Update on colormaterial, material emmissive/ambient, 
+/* Update on colormaterial, material emmissive/ambient,
  * lightmodel.globalambient
  */
 static void update_global_ambient( GLcontext *ctx )
@@ -686,23 +700,23 @@ static void update_global_ambient( GLcontext *ctx )
     */
    if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &
        ((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |
-       (3 << RADEON_AMBIENT_SOURCE_SHIFT))) == 0) 
+       (3 << RADEON_AMBIENT_SOURCE_SHIFT))) == 0)
    {
-      COPY_3V( &fcmd[GLT_RED], 
+      COPY_3V( &fcmd[GLT_RED],
               ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION]);
       ACC_SCALE_3V( &fcmd[GLT_RED],
                   ctx->Light.Model.Ambient,
                   ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT]);
-   } 
+   }
    else
    {
       COPY_3V( &fcmd[GLT_RED], ctx->Light.Model.Ambient );
    }
-   
+
    RADEON_DB_STATECHANGE(rmesa, &rmesa->hw.glt);
 }
 
-/* Update on change to 
+/* Update on change to
  *    - light[p].colors
  *    - light[p].enabled
  */
@@ -716,10 +730,10 @@ static void update_light_colors( GLcontext *ctx, GLuint p )
       r100ContextPtr rmesa = R100_CONTEXT(ctx);
       float *fcmd = (float *)RADEON_DB_STATE( lit[p] );
 
-      COPY_4V( &fcmd[LIT_AMBIENT_RED], l->Ambient );    
+      COPY_4V( &fcmd[LIT_AMBIENT_RED], l->Ambient );
       COPY_4V( &fcmd[LIT_DIFFUSE_RED], l->Diffuse );
       COPY_4V( &fcmd[LIT_SPECULAR_RED], l->Specular );
-      
+
       RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] );
    }
 }
@@ -733,7 +747,7 @@ static void check_twoside_fallback( GLcontext *ctx )
 
    if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) {
       if (ctx->Light.ColorMaterialEnabled &&
-         (ctx->Light.ColorMaterialBitmask & BACK_MATERIAL_BITS) != 
+         (ctx->Light.ColorMaterialBitmask & BACK_MATERIAL_BITS) !=
          ((ctx->Light.ColorMaterialBitmask & FRONT_MATERIAL_BITS)<<1))
         fallback = GL_TRUE;
       else {
@@ -741,7 +755,7 @@ static void check_twoside_fallback( GLcontext *ctx )
            if (memcmp( ctx->Light.Material.Attrib[i],
                        ctx->Light.Material.Attrib[i+1],
                        sizeof(GLfloat)*4) != 0) {
-              fallback = GL_TRUE;  
+              fallback = GL_TRUE;
               break;
            }
       }
@@ -759,8 +773,8 @@ static void radeonColorMaterial( GLcontext *ctx, GLenum face, GLenum mode )
       light_model_ctl1 &= ~((3 << RADEON_EMISSIVE_SOURCE_SHIFT) |
                           (3 << RADEON_AMBIENT_SOURCE_SHIFT) |
                           (3 << RADEON_DIFFUSE_SOURCE_SHIFT) |
-                          (3 << RADEON_SPECULAR_SOURCE_SHIFT)); 
-   
+                          (3 << RADEON_SPECULAR_SOURCE_SHIFT));
+
    if (ctx->Light.ColorMaterialEnabled) {
       GLuint mask = ctx->Light.ColorMaterialBitmask;
 
@@ -781,7 +795,7 @@ static void radeonColorMaterial( GLcontext *ctx, GLenum face, GLenum mode )
         light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
                             RADEON_AMBIENT_SOURCE_SHIFT);
       }
-        
+
       if (mask & MAT_BIT_FRONT_DIFFUSE) {
         light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
                             RADEON_DIFFUSE_SOURCE_SHIFT);
@@ -790,7 +804,7 @@ static void radeonColorMaterial( GLcontext *ctx, GLenum face, GLenum mode )
         light_model_ctl1 |= (RADEON_LM_SOURCE_STATE_MULT <<
                             RADEON_DIFFUSE_SOURCE_SHIFT);
       }
-   
+
       if (mask & MAT_BIT_FRONT_SPECULAR) {
         light_model_ctl1 |= (RADEON_LM_SOURCE_VERTEX_DIFFUSE <<
                             RADEON_SPECULAR_SOURCE_SHIFT);
@@ -808,10 +822,10 @@ static void radeonColorMaterial( GLcontext *ctx, GLenum face, GLenum mode )
                   (RADEON_LM_SOURCE_STATE_MULT << RADEON_DIFFUSE_SOURCE_SHIFT) |
                   (RADEON_LM_SOURCE_STATE_MULT << RADEON_SPECULAR_SOURCE_SHIFT);
    }
-   
+
       if (light_model_ctl1 != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]) {
         RADEON_STATECHANGE( rmesa, tcl );
-        rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = light_model_ctl1;      
+        rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = light_model_ctl1;
    }
 }
 
@@ -821,14 +835,14 @@ void radeonUpdateMaterial( GLcontext *ctx )
    GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
    GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( mtl );
    GLuint mask = ~0;
-   
+
    if (ctx->Light.ColorMaterialEnabled)
       mask &= ~ctx->Light.ColorMaterialBitmask;
 
    if (RADEON_DEBUG & DEBUG_STATE)
       fprintf(stderr, "%s\n", __FUNCTION__);
 
-      
+
    if (mask & MAT_BIT_FRONT_EMISSION) {
       fcmd[MTL_EMMISSIVE_RED]   = mat[MAT_ATTRIB_FRONT_EMISSION][0];
       fcmd[MTL_EMMISSIVE_GREEN] = mat[MAT_ATTRIB_FRONT_EMISSION][1];
@@ -871,14 +885,14 @@ void radeonUpdateMaterial( GLcontext *ctx )
  *       _VP_inf_norm
  *       _h_inf_norm
  *       _Position
- *       _NormDirection
+ *       _NormSpotDirection
  *       _ModelViewInvScale
  *       _NeedEyeCoords
  *       _EyeZDir
  *
  * which are calculated in light.c and are correct for the current
  * lighting space (model or eye), hence dependencies on _NEW_MODELVIEW
- * and _MESA_NEW_NEED_EYE_COORDS.  
+ * and _MESA_NEW_NEED_EYE_COORDS.
  */
 static void update_light( GLcontext *ctx )
 {
@@ -895,12 +909,12 @@ static void update_light( GLcontext *ctx )
         tmp &= ~RADEON_LIGHT_IN_MODELSPACE;
       else
         tmp |= RADEON_LIGHT_IN_MODELSPACE;
-      
+
 
       /* Leave this test disabled: (unexplained q3 lockup) (even with
          new packets)
       */
-      if (tmp != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]) 
+      if (tmp != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL])
       {
         RADEON_STATECHANGE( rmesa, tcl );
         rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] = tmp;
@@ -924,17 +938,17 @@ static void update_light( GLcontext *ctx )
         if (ctx->Light.Light[p].Enabled) {
            struct gl_light *l = &ctx->Light.Light[p];
            GLfloat *fcmd = (GLfloat *)RADEON_DB_STATE( lit[p] );
-           
+
            if (l->EyePosition[3] == 0.0) {
-              COPY_3FV( &fcmd[LIT_POSITION_X], l->_VP_inf_norm ); 
-              COPY_3FV( &fcmd[LIT_DIRECTION_X], l->_h_inf_norm ); 
+              COPY_3FV( &fcmd[LIT_POSITION_X], l->_VP_inf_norm );
+              COPY_3FV( &fcmd[LIT_DIRECTION_X], l->_h_inf_norm );
               fcmd[LIT_POSITION_W] = 0;
               fcmd[LIT_DIRECTION_W] = 0;
            } else {
               COPY_4V( &fcmd[LIT_POSITION_X], l->_Position );
-              fcmd[LIT_DIRECTION_X] = -l->_NormDirection[0];
-              fcmd[LIT_DIRECTION_Y] = -l->_NormDirection[1];
-              fcmd[LIT_DIRECTION_Z] = -l->_NormDirection[2];
+              fcmd[LIT_DIRECTION_X] = -l->_NormSpotDirection[0];
+              fcmd[LIT_DIRECTION_Y] = -l->_NormSpotDirection[1];
+              fcmd[LIT_DIRECTION_Z] = -l->_NormSpotDirection[2];
               fcmd[LIT_DIRECTION_W] = 0;
            }
 
@@ -951,26 +965,26 @@ static void radeonLightfv( GLcontext *ctx, GLenum light,
    GLint p = light - GL_LIGHT0;
    struct gl_light *l = &ctx->Light.Light[p];
    GLfloat *fcmd = (GLfloat *)rmesa->hw.lit[p].cmd;
-   
+
 
    switch (pname) {
-   case GL_AMBIENT:            
+   case GL_AMBIENT:
    case GL_DIFFUSE:
    case GL_SPECULAR:
       update_light_colors( ctx, p );
       break;
 
-   case GL_SPOT_DIRECTION: 
-      /* picked up in update_light */  
+   case GL_SPOT_DIRECTION:
+      /* picked up in update_light */
       break;
 
    case GL_POSITION: {
-      /* positions picked up in update_light, but can do flag here */  
+      /* positions picked up in update_light, but can do flag here */
       GLuint flag;
       GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
 
       /* FIXME: Set RANGE_ATTEN only when needed */
-      if (p&1) 
+      if (p&1)
         flag = RADEON_LIGHT_1_IS_LOCAL;
       else
         flag = RADEON_LIGHT_0_IS_LOCAL;
@@ -1062,7 +1076,7 @@ static void radeonLightfv( GLcontext *ctx, GLenum light,
    }
 }
 
-                 
+
 
 
 static void radeonLightModelfv( GLcontext *ctx, GLenum pname,
@@ -1071,7 +1085,7 @@ static void radeonLightModelfv( GLcontext *ctx, GLenum pname,
    r100ContextPtr rmesa = R100_CONTEXT(ctx);
 
    switch (pname) {
-      case GL_LIGHT_MODEL_AMBIENT: 
+      case GL_LIGHT_MODEL_AMBIENT:
         update_global_ambient( ctx );
         break;
 
@@ -1245,14 +1259,14 @@ static void radeonStencilOpSeparate( GLcontext *ctx, GLenum face, GLenum fail,
    /* radeon 7200 have stencil bug, DEC and INC_WRAP will actually both do DEC_WRAP,
       and DEC_WRAP (and INVERT) will do INVERT. No way to get correct INC_WRAP and DEC,
       but DEC_WRAP can be fixed by using DEC and INC_WRAP at least use INC. */
-   
+
    GLuint tempRADEON_STENCIL_FAIL_DEC_WRAP;
    GLuint tempRADEON_STENCIL_FAIL_INC_WRAP;
    GLuint tempRADEON_STENCIL_ZFAIL_DEC_WRAP;
    GLuint tempRADEON_STENCIL_ZFAIL_INC_WRAP;
    GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP;
    GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP;
-   
+
    if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_BROKEN_STENCIL) {
       tempRADEON_STENCIL_FAIL_DEC_WRAP = RADEON_STENCIL_FAIL_DEC;
       tempRADEON_STENCIL_FAIL_INC_WRAP = RADEON_STENCIL_FAIL_INC;
@@ -1269,7 +1283,7 @@ static void radeonStencilOpSeparate( GLcontext *ctx, GLenum face, GLenum fail,
       tempRADEON_STENCIL_ZPASS_DEC_WRAP = RADEON_STENCIL_ZPASS_DEC_WRAP;
       tempRADEON_STENCIL_ZPASS_INC_WRAP = RADEON_STENCIL_ZPASS_INC_WRAP;
    }
-   
+
    RADEON_STATECHANGE( rmesa, ctx );
    rmesa->hw.ctx.cmd[CTX_RB3D_ZSTENCILCNTL] &= ~(RADEON_STENCIL_FAIL_MASK |
                                               RADEON_STENCIL_ZFAIL_MASK |
@@ -1361,7 +1375,7 @@ static void radeonClearStencil( GLcontext *ctx, GLint s )
 {
    r100ContextPtr rmesa = R100_CONTEXT(ctx);
 
-   rmesa->radeon.state.stencil.clear = 
+   rmesa->radeon.state.stencil.clear =
       ((GLuint) (ctx->Stencil.Clear & 0xff) |
        (0xff << RADEON_STENCIL_MASK_SHIFT) |
        ((ctx->Stencil.WriteMask[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT));
@@ -1386,19 +1400,29 @@ static void radeonClearStencil( GLcontext *ctx, GLint s )
 void radeonUpdateWindow( GLcontext *ctx )
 {
    r100ContextPtr rmesa = R100_CONTEXT(ctx);
-   __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable;
+   __DRIdrawablePrivate *dPriv = radeon_get_drawable(&rmesa->radeon);
    GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0;
    GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0;
    const GLfloat *v = ctx->Viewport._WindowMap.m;
+   const GLboolean render_to_fbo = (ctx->DrawBuffer ? (ctx->DrawBuffer->Name != 0) : 0);
+   const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
+   GLfloat y_scale, y_bias;
+
+   if (render_to_fbo) {
+      y_scale = 1.0;
+      y_bias = 0;
+   } else {
+      y_scale = -1.0;
+      y_bias = yoffset;
+   }
 
    float_ui32_type sx = { v[MAT_SX] };
    float_ui32_type tx = { v[MAT_TX] + xoffset + SUBPIXEL_X };
-   float_ui32_type sy = { - v[MAT_SY] };
-   float_ui32_type ty = { (- v[MAT_TY]) + yoffset + SUBPIXEL_Y };
-   float_ui32_type sz = { v[MAT_SZ] * rmesa->radeon.state.depth.scale };
-   float_ui32_type tz = { v[MAT_TZ] * rmesa->radeon.state.depth.scale };
+   float_ui32_type sy = { v[MAT_SY] * y_scale };
+   float_ui32_type ty = { (v[MAT_TY] * y_scale) + y_bias + SUBPIXEL_Y };
+   float_ui32_type sz = { v[MAT_SZ] * depthScale };
+   float_ui32_type tz = { v[MAT_TZ] * depthScale };
 
-   radeon_firevertices(&rmesa->radeon);
    RADEON_STATECHANGE( rmesa, vpt );
 
    rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE]  = sx.ui32;
@@ -1418,6 +1442,8 @@ static void radeonViewport( GLcontext *ctx, GLint x, GLint y,
     * values, or keep the originals hanging around.
     */
    radeonUpdateWindow( ctx );
+
+   radeon_viewport(ctx, x, y, width, height);
 }
 
 static void radeonDepthRange( GLcontext *ctx, GLclampd nearval,
@@ -1429,7 +1455,7 @@ static void radeonDepthRange( GLcontext *ctx, GLclampd nearval,
 void radeonUpdateViewportOffset( GLcontext *ctx )
 {
    r100ContextPtr rmesa = R100_CONTEXT(ctx);
-   __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable;
+   __DRIdrawablePrivate *dPriv = radeon_get_drawable(&rmesa->radeon);
    GLfloat xoffset = (GLfloat)dPriv->x;
    GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h;
    const GLfloat *v = ctx->Viewport._WindowMap.m;
@@ -1459,8 +1485,8 @@ void radeonUpdateViewportOffset( GLcontext *ctx )
                 RADEON_STIPPLE_Y_OFFSET_MASK);
 
          /* add magic offsets, then invert */
-         stx = 31 - ((rmesa->radeon.dri.drawable->x - 1) & RADEON_STIPPLE_COORD_MASK);
-         sty = 31 - ((rmesa->radeon.dri.drawable->y + rmesa->radeon.dri.drawable->h - 1)
+         stx = 31 - ((dPriv->x - 1) & RADEON_STIPPLE_COORD_MASK);
+         sty = 31 - ((dPriv->y + dPriv->h - 1)
                      & RADEON_STIPPLE_COORD_MASK);
 
          m |= ((stx << RADEON_STIPPLE_X_OFFSET_SHIFT) |
@@ -1486,11 +1512,17 @@ static void radeonClearColor( GLcontext *ctx, const GLfloat color[4] )
 {
    r100ContextPtr rmesa = R100_CONTEXT(ctx);
    GLubyte c[4];
+   struct radeon_renderbuffer *rrb;
+
+   rrb = radeon_get_colorbuffer(&rmesa->radeon);
+   if (!rrb)
+     return;
+     
    CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
    CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
    CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
    CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
-   rmesa->radeon.state.color.clear = radeonPackColor( rmesa->radeon.radeonScreen->cpp,
+   rmesa->radeon.state.color.clear = radeonPackColor( rrb->cpp,
                                               c[0], c[1], c[2], c[3] );
 }
 
@@ -1532,49 +1564,6 @@ static void radeonLogicOpCode( GLcontext *ctx, GLenum opcode )
    rmesa->hw.msk.cmd[MSK_RB3D_ROPCNTL] = radeon_rop_tab[rop];
 }
 
-
-/**
- * Called via glDrawBuffer.
- */
-static void radeonDrawBuffer( GLcontext *ctx, GLenum mode )
-{
-   r100ContextPtr rmesa = R100_CONTEXT(ctx);
-
-   if (RADEON_DEBUG & DEBUG_DRI)
-      fprintf(stderr, "%s %s\n", __FUNCTION__,
-             _mesa_lookup_enum_by_nr( mode ));
-
-   radeon_firevertices(&rmesa->radeon);        /* don't pipeline cliprect changes */
-
-   if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) {
-      /* 0 (GL_NONE) buffers or multiple color drawing buffers */
-      FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE );
-      return;
-   }
-
-   switch ( ctx->DrawBuffer->_ColorDrawBufferIndexes[0] ) {
-   case BUFFER_FRONT_LEFT:
-   case BUFFER_BACK_LEFT:
-      FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_FALSE );
-      break;
-   default:
-      FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE );
-      return;
-   }
-
-   radeonSetCliprects( &rmesa->radeon );
-   radeonUpdatePageFlipping(&rmesa->radeon);
-   /* We'll set the drawing engine's offset/pitch parameters later
-    * when we update other state.
-    */
-}
-
-static void radeonReadBuffer( GLcontext *ctx, GLenum mode )
-{
-   /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
-}
-
-
 /* =============================================================
  * State enable/disable
  */
@@ -1642,7 +1631,7 @@ static void radeonEnable( GLcontext *ctx, GLenum cap, GLboolean state )
    case GL_CLIP_PLANE2:
    case GL_CLIP_PLANE3:
    case GL_CLIP_PLANE4:
-   case GL_CLIP_PLANE5: 
+   case GL_CLIP_PLANE5:
       p = cap-GL_CLIP_PLANE0;
       RADEON_STATECHANGE( rmesa, tcl );
       if (state) {
@@ -1707,13 +1696,13 @@ static void radeonEnable( GLcontext *ctx, GLenum cap, GLboolean state )
    case GL_LIGHT7:
       RADEON_STATECHANGE(rmesa, tcl);
       p = cap - GL_LIGHT0;
-      if (p&1) 
+      if (p&1)
         flag = (RADEON_LIGHT_1_ENABLE |
-                RADEON_LIGHT_1_ENABLE_AMBIENT | 
+                RADEON_LIGHT_1_ENABLE_AMBIENT |
                 RADEON_LIGHT_1_ENABLE_SPECULAR);
       else
         flag = (RADEON_LIGHT_0_ENABLE |
-                RADEON_LIGHT_0_ENABLE_AMBIENT | 
+                RADEON_LIGHT_0_ENABLE_AMBIENT |
                 RADEON_LIGHT_0_ENABLE_SPECULAR);
 
       if (state)
@@ -1721,7 +1710,7 @@ static void radeonEnable( GLcontext *ctx, GLenum cap, GLboolean state )
       else
         rmesa->hw.tcl.cmd[p/2 + TCL_PER_LIGHT_CTL_0] &= ~flag;
 
-      /* 
+      /*
        */
       update_light_colors( ctx, p );
       break;
@@ -1759,7 +1748,7 @@ static void radeonEnable( GLcontext *ctx, GLenum cap, GLboolean state )
         rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
       }
       break;
-      
+
    case GL_NORMALIZE:
       RADEON_STATECHANGE( rmesa, tcl );
       if ( state ) {
@@ -1832,15 +1821,24 @@ static void radeonEnable( GLcontext *ctx, GLenum cap, GLboolean state )
       break;
 
    case GL_STENCIL_TEST:
-      if ( rmesa->radeon.state.stencil.hwBuffer ) {
-        RADEON_STATECHANGE( rmesa, ctx );
-        if ( state ) {
-           rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_STENCIL_ENABLE;
+      {
+        GLboolean hw_stencil = GL_FALSE;
+        if (ctx->DrawBuffer) {
+           struct radeon_renderbuffer *rrbStencil
+              = radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL);
+           hw_stencil = (rrbStencil && rrbStencil->bo);
+        }
+
+        if (hw_stencil) {
+           RADEON_STATECHANGE( rmesa, ctx );
+           if ( state ) {
+              rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  RADEON_STENCIL_ENABLE;
+           } else {
+              rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_STENCIL_ENABLE;
+           }
         } else {
-           rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_STENCIL_ENABLE;
+           FALLBACK( rmesa, RADEON_FALLBACK_STENCIL, state );
         }
-      } else {
-        FALLBACK( rmesa, RADEON_FALLBACK_STENCIL, state );
       }
       break;
 
@@ -1850,7 +1848,7 @@ static void radeonEnable( GLcontext *ctx, GLenum cap, GLboolean state )
    case GL_TEXTURE_GEN_T:
       /* Picked up in radeonUpdateTextureState.
        */
-      rmesa->recheck_texgen[ctx->Texture.CurrentUnit] = GL_TRUE; 
+      rmesa->recheck_texgen[ctx->Texture.CurrentUnit] = GL_TRUE;
       break;
 
    case GL_COLOR_SUM_EXT:
@@ -1884,7 +1882,7 @@ static void radeonLightingSpaceChange( GLcontext *ctx )
       rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
    }
 
-   if (RADEON_DEBUG & DEBUG_STATE) 
+   if (RADEON_DEBUG & DEBUG_STATE)
       fprintf(stderr, "%s %d AFTER %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
              rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
 }
@@ -2064,43 +2062,60 @@ static void update_texturematrix( GLcontext *ctx )
    }
 }
 
-
-/**
- * Tell the card where to render (offset, pitch).
- * Effected by glDrawBuffer, etc
- */
-void
-radeonUpdateDrawBuffer(GLcontext *ctx)
+static GLboolean r100ValidateBuffers(GLcontext *ctx)
 {
    r100ContextPtr rmesa = R100_CONTEXT(ctx);
-   struct gl_framebuffer *fb = ctx->DrawBuffer;
    struct radeon_renderbuffer *rrb;
+   int i, ret;
 
-   if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
-     /* draw to front */
-     rrb = (void *) fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
-   } else if (fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) {
-     /* draw to back */
-     rrb = (void *) fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
-   } else {
-     /* drawing to multiple buffers, or none */
-     return;
+   radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs);
+
+   rrb = radeon_get_colorbuffer(&rmesa->radeon);
+   /* color buffer */
+   if (rrb && rrb->bo) {
+     radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
+                                      0, RADEON_GEM_DOMAIN_VRAM);
    }
 
-   assert(rrb);
-   assert(rrb->pitch);
+   /* depth buffer */
+   rrb = radeon_get_depthbuffer(&rmesa->radeon);
+   /* color buffer */
+   if (rrb && rrb->bo) {
+     radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, rrb->bo,
+                                      0, RADEON_GEM_DOMAIN_VRAM);
+   }
 
-   RADEON_STATECHANGE( rmesa, ctx );
-}
+   for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) {
+      radeonTexObj *t;
+
+      if (!ctx->Texture.Unit[i]._ReallyEnabled)
+        continue;
 
+      t = rmesa->state.texture.unit[i].texobj;
+      if (t->image_override && t->bo)
+       radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->bo,
+                          RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
+      else if (t->mt->bo)
+       radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, t->mt->bo,
+                          RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
+   }
+
+   ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, first_elem(&rmesa->radeon.dma.reserved)->bo, RADEON_GEM_DOMAIN_GTT, 0);
+   if (ret)
+       return GL_FALSE;
+   return GL_TRUE;
+}
 
-void radeonValidateState( GLcontext *ctx )
+GLboolean radeonValidateState( GLcontext *ctx )
 {
    r100ContextPtr rmesa = R100_CONTEXT(ctx);
    GLuint new_state = rmesa->radeon.NewGLState;
 
-   if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) {
-     radeonUpdateDrawBuffer(ctx);
+   if (new_state & _NEW_BUFFERS) {
+     _mesa_update_framebuffer(ctx);
+     /* this updates the DrawBuffer's Width/Height if it's a FBO */
+     _mesa_update_draw_buffer_bounds(ctx);
+     RADEON_STATECHANGE(rmesa, ctx);
    }
 
    if (new_state & _NEW_TEXTURE) {
@@ -2108,9 +2123,13 @@ void radeonValidateState( GLcontext *ctx )
       new_state |= rmesa->radeon.NewGLState; /* may add TEXTURE_MATRIX */
    }
 
+   /* we need to do a space check here */
+   if (!r100ValidateBuffers(ctx))
+     return GL_FALSE;
+
    /* Need an event driven matrix update?
     */
-   if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION)) 
+   if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION))
       upload_matrix( rmesa, ctx->_ModelProjectMatrix.m, MODEL_PROJ );
 
    /* Need these for lighting (shouldn't upload otherwise)
@@ -2134,12 +2153,14 @@ void radeonValidateState( GLcontext *ctx )
    /* emit all active clip planes if projection matrix changes.
     */
    if (new_state & (_NEW_PROJECTION)) {
-      if (ctx->Transform.ClipPlanesEnabled) 
+      if (ctx->Transform.ClipPlanesEnabled)
         radeonUpdateClipPlanes( ctx );
    }
 
 
    rmesa->radeon.NewGLState = 0;
+
+   return GL_TRUE;
 }
 
 
@@ -2161,8 +2182,8 @@ static GLboolean check_material( GLcontext *ctx )
    TNLcontext *tnl = TNL_CONTEXT(ctx);
    GLint i;
 
-   for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT; 
-       i < _TNL_ATTRIB_MAT_BACK_INDEXES; 
+   for (i = _TNL_ATTRIB_MAT_FRONT_AMBIENT;
+       i < _TNL_ATTRIB_MAT_BACK_INDEXES;
        i++)
       if (tnl->vb.AttribPtr[i] &&
          tnl->vb.AttribPtr[i]->stride)
@@ -2170,7 +2191,7 @@ static GLboolean check_material( GLcontext *ctx )
 
    return GL_FALSE;
 }
-      
+
 
 static void radeonWrapRunPipeline( GLcontext *ctx )
 {
@@ -2183,7 +2204,8 @@ static void radeonWrapRunPipeline( GLcontext *ctx )
    /* Validate state:
     */
    if (rmesa->radeon.NewGLState)
-      radeonValidateState( ctx );
+      if (!radeonValidateState( ctx ))
+        FALLBACK(rmesa, RADEON_FALLBACK_TEXTURE, GL_TRUE);
 
    has_material = (ctx->Light.Enabled && check_material( ctx ));
 
@@ -2192,7 +2214,7 @@ static void radeonWrapRunPipeline( GLcontext *ctx )
    }
 
    /* Run the pipeline.
-    */ 
+    */
    _tnl_run_pipeline( ctx );
 
    if (has_material) {