raedon/r200/r300: mega-FBO commits.
authorDave Airlie <airlied@redhat.com>
Mon, 23 Mar 2009 08:27:49 +0000 (18:27 +1000)
committerDave Airlie <airlied@redhat.com>
Mon, 23 Mar 2009 08:54:06 +0000 (18:54 +1000)
Re work depth issues.
Do a lot more FBO abstactions
fixup depth/stencil buffer interactions

21 files changed:
src/mesa/drivers/dri/r200/r200_context.c
src/mesa/drivers/dri/r200/r200_context.h
src/mesa/drivers/dri/r200/r200_ioctl.c
src/mesa/drivers/dri/r200/r200_state.c
src/mesa/drivers/dri/r200/r200_state_init.c
src/mesa/drivers/dri/r300/r300_context.c
src/mesa/drivers/dri/r300/r300_ioctl.c
src/mesa/drivers/dri/r300/r300_state.c
src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h
src/mesa/drivers/dri/radeon/radeon_common.c
src/mesa/drivers/dri/radeon/radeon_common.h
src/mesa/drivers/dri/radeon/radeon_common_context.c
src/mesa/drivers/dri/radeon/radeon_common_context.h
src/mesa/drivers/dri/radeon/radeon_context.c
src/mesa/drivers/dri/radeon/radeon_context.h
src/mesa/drivers/dri/radeon/radeon_fbo.c
src/mesa/drivers/dri/radeon/radeon_ioctl.c
src/mesa/drivers/dri/radeon/radeon_screen.c
src/mesa/drivers/dri/radeon/radeon_span.c
src/mesa/drivers/dri/radeon/radeon_state.c
src/mesa/drivers/dri/radeon/radeon_state_init.c

index bf06c41..6fd0575 100644 (file)
@@ -72,6 +72,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define need_GL_EXT_blend_func_separate
 #define need_GL_NV_vertex_program
 #define need_GL_ARB_point_parameters
+#define need_GL_EXT_framebuffer_object
 #include "extension_helper.h"
 
 #define DRIVER_DATE    "20060602"
@@ -124,6 +125,7 @@ const struct dri_extension card_extensions[] =
     { "GL_EXT_blend_minmax",               GL_EXT_blend_minmax_functions },
     { "GL_EXT_blend_subtract",             NULL },
     { "GL_EXT_fog_coord",                  GL_EXT_fog_coord_functions },
+    { "GL_EXT_packed_depth_stencil",      NULL},
     { "GL_EXT_secondary_color",            GL_EXT_secondary_color_functions },
     { "GL_EXT_stencil_wrap",               NULL },
     { "GL_EXT_texture_edge_clamp",         NULL },
@@ -165,6 +167,11 @@ const struct dri_extension point_extensions[] = {
     { NULL,                                NULL }
 };
 
+const struct dri_extension mm_extensions[] = {
+  { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions },
+  { NULL, NULL }
+};
+
 extern const struct tnl_pipeline_stage _r200_render_stage;
 extern const struct tnl_pipeline_stage _r200_tcl_stage;
 
@@ -418,6 +425,9 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
    _math_matrix_set_identity( &rmesa->tmpmat );
 
    driInitExtensions( ctx, card_extensions, GL_TRUE );
+
+   if (rmesa->radeon.radeonScreen->kernel_mm)
+     driInitExtensions(ctx, mm_extensions, GL_FALSE);
    if (!(rmesa->radeon.radeonScreen->chip_flags & R200_CHIPSET_YCBCR_BROKEN)) {
      /* yuv textures don't work with some chips - R200 / rv280 okay so far
        others get the bit ordering right but don't actually do YUV-RGB conversion */
index f7bad2a..fcbe725 100644 (file)
@@ -621,21 +621,6 @@ struct r200_context {
    GLboolean texmicrotile;
 
   struct ati_fragment_shader *afs_loaded;
-
-  struct {
-      struct gl_fragment_program *bitmap_fp;
-      struct gl_vertex_program *passthrough_vp;
-
-      struct gl_fragment_program *saved_fp;
-      GLboolean saved_fp_enable;
-      struct gl_vertex_program *saved_vp;
-      GLboolean saved_vp_enable;
-
-      GLint saved_vp_x, saved_vp_y;
-      GLsizei saved_vp_width, saved_vp_height;
-      GLenum saved_matrix_mode;
-   } meta;
-
 };
 
 #define R200_CONTEXT(ctx)              ((r200ContextPtr)(ctx->DriverCtx))
index 96ed496..ccb5620 100644 (file)
@@ -41,19 +41,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "main/context.h"
 #include "swrast/swrast.h"
 
-#include "main/blend.h"
-#include "main/bufferobj.h"
-#include "main/buffers.h"
-#include "main/depth.h"
-#include "main/shaders.h"
-#include "main/texstate.h"
-#include "main/varray.h"
-#include "glapi/dispatch.h"
-#include "swrast/swrast.h"
-#include "main/stencil.h"
-#include "main/matrix.h"
-#include "main/attrib.h"
-#include "main/enable.h"
+
 
 #include "radeon_common.h"
 #include "radeon_lock.h"
@@ -70,217 +58,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define R200_TIMEOUT             512
 #define R200_IDLE_RETRY           16
 
-static void
-r200_meta_set_passthrough_transform(r200ContextPtr r200)
-{
-   GLcontext *ctx = r200->radeon.glCtx;
-
-   r200->meta.saved_vp_x = ctx->Viewport.X;
-   r200->meta.saved_vp_y = ctx->Viewport.Y;
-   r200->meta.saved_vp_width = ctx->Viewport.Width;
-   r200->meta.saved_vp_height = ctx->Viewport.Height;
-   r200->meta.saved_matrix_mode = ctx->Transform.MatrixMode;
-
-   _mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height);
-
-   _mesa_MatrixMode(GL_PROJECTION);
-   _mesa_PushMatrix();
-   _mesa_LoadIdentity();
-   _mesa_Ortho(0, ctx->DrawBuffer->Width, 0, ctx->DrawBuffer->Height, 1, -1);
-
-   _mesa_MatrixMode(GL_MODELVIEW);
-   _mesa_PushMatrix();
-   _mesa_LoadIdentity();
-}
-
-static void
-r200_meta_restore_transform(r200ContextPtr r200)
-{
-   _mesa_MatrixMode(GL_PROJECTION);
-   _mesa_PopMatrix();
-   _mesa_MatrixMode(GL_MODELVIEW);
-   _mesa_PopMatrix();
-
-   _mesa_MatrixMode(r200->meta.saved_matrix_mode);
-
-   _mesa_Viewport(r200->meta.saved_vp_x, r200->meta.saved_vp_y,
-                 r200->meta.saved_vp_width, r200->meta.saved_vp_height);
-}
-
-/**
- * Perform glClear where mask contains only color, depth, and/or stencil.
- *
- * The implementation is based on calling into Mesa to set GL state and
- * performing normal triangle rendering.  The intent of this path is to
- * have as generic a path as possible, so that any driver could make use of
- * it.
- */
-static void radeon_clear_tris(GLcontext *ctx, GLbitfield mask)
-{
-   r200ContextPtr rmesa = R200_CONTEXT(ctx);
-   GLfloat vertices[4][3];
-   GLfloat color[4][4];
-   GLfloat dst_z;
-   struct gl_framebuffer *fb = ctx->DrawBuffer;
-   int i;
-   GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE;
-   GLboolean saved_shader_program = 0;
-   unsigned int saved_active_texture;
-   
-   assert((mask & ~(BUFFER_BIT_BACK_LEFT | BUFFER_BIT_FRONT_LEFT |
-                   BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) == 0);
-
-   _mesa_PushAttrib(GL_COLOR_BUFFER_BIT |
-                   GL_CURRENT_BIT |
-                   GL_DEPTH_BUFFER_BIT |
-                   GL_ENABLE_BIT |
-                   GL_STENCIL_BUFFER_BIT |
-                   GL_TRANSFORM_BIT |
-                   GL_CURRENT_BIT);
-   _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
-   saved_active_texture = ctx->Texture.CurrentUnit;
-  
-  /* Disable existing GL state we don't want to apply to a clear. */
-   _mesa_Disable(GL_ALPHA_TEST);
-   _mesa_Disable(GL_BLEND);
-   _mesa_Disable(GL_CULL_FACE);
-   _mesa_Disable(GL_FOG);
-   _mesa_Disable(GL_POLYGON_SMOOTH);
-   _mesa_Disable(GL_POLYGON_STIPPLE);
-   _mesa_Disable(GL_POLYGON_OFFSET_FILL);
-   _mesa_Disable(GL_LIGHTING);
-   _mesa_Disable(GL_CLIP_PLANE0);
-   _mesa_Disable(GL_CLIP_PLANE1);
-   _mesa_Disable(GL_CLIP_PLANE2);
-   _mesa_Disable(GL_CLIP_PLANE3);
-   _mesa_Disable(GL_CLIP_PLANE4);
-   _mesa_Disable(GL_CLIP_PLANE5);
-   if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) {
-      saved_fp_enable = GL_TRUE;
-      _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB);
-   }
-   if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) {
-      saved_vp_enable = GL_TRUE;
-      _mesa_Disable(GL_VERTEX_PROGRAM_ARB);
-   }
-   if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) {
-      saved_shader_program = ctx->Shader.CurrentProgram->Name;
-      _mesa_UseProgramObjectARB(0);
-   }
-   
-   if (ctx->Texture._EnabledUnits != 0) {
-      int i;
-      
-      for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
-        _mesa_ActiveTextureARB(GL_TEXTURE0 + i);
-        _mesa_Disable(GL_TEXTURE_1D);
-        _mesa_Disable(GL_TEXTURE_2D);
-        _mesa_Disable(GL_TEXTURE_3D);
-        if (ctx->Extensions.ARB_texture_cube_map)
-           _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB);
-        if (ctx->Extensions.NV_texture_rectangle)
-           _mesa_Disable(GL_TEXTURE_RECTANGLE_NV);
-        if (ctx->Extensions.MESA_texture_array) {
-           _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT);
-           _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT);
-        }
-      }
-   }
-  
-   r200_meta_set_passthrough_transform(rmesa);
-   
-   for (i = 0; i < 4; i++) {
-      color[i][0] = ctx->Color.ClearColor[0];
-      color[i][1] = ctx->Color.ClearColor[1];
-      color[i][2] = ctx->Color.ClearColor[2];
-      color[i][3] = ctx->Color.ClearColor[3];
-   }
-
-   /* convert clear Z from [0,1] to NDC coord in [-1,1] */
-   dst_z = -1.0 + 2.0 * ctx->Depth.Clear;
-   
-   /* Prepare the vertices, which are the same regardless of which buffer we're
-    * drawing to.
-    */
-   vertices[0][0] = fb->_Xmin;
-   vertices[0][1] = fb->_Ymin;
-   vertices[0][2] = dst_z;
-   vertices[1][0] = fb->_Xmax;
-   vertices[1][1] = fb->_Ymin;
-   vertices[1][2] = dst_z;
-   vertices[2][0] = fb->_Xmax;
-   vertices[2][1] = fb->_Ymax;
-   vertices[2][2] = dst_z;
-   vertices[3][0] = fb->_Xmin;
-   vertices[3][1] = fb->_Ymax;
-   vertices[3][2] = dst_z;
-
-   _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &color);
-   _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), &vertices);
-   _mesa_Enable(GL_COLOR_ARRAY);
-   _mesa_Enable(GL_VERTEX_ARRAY);
-
-   while (mask != 0) {
-      GLuint this_mask = 0;
-
-      if (mask & BUFFER_BIT_BACK_LEFT)
-        this_mask = BUFFER_BIT_BACK_LEFT;
-      else if (mask & BUFFER_BIT_FRONT_LEFT)
-        this_mask = BUFFER_BIT_FRONT_LEFT;
-
-      /* Clear depth/stencil in the same pass as color. */
-      this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL));
-
-      /* Select the current color buffer and use the color write mask if
-       * we have one, otherwise don't write any color channels.
-       */
-      if (this_mask & BUFFER_BIT_FRONT_LEFT)
-        _mesa_DrawBuffer(GL_FRONT_LEFT);
-      else if (this_mask & BUFFER_BIT_BACK_LEFT)
-        _mesa_DrawBuffer(GL_BACK_LEFT);
-      else
-        _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-
-      /* Control writing of the depth clear value to depth. */
-      if (this_mask & BUFFER_BIT_DEPTH) {
-        _mesa_DepthFunc(GL_ALWAYS);
-        _mesa_Enable(GL_DEPTH_TEST);
-      } else {
-        _mesa_Disable(GL_DEPTH_TEST);
-        _mesa_DepthMask(GL_FALSE);
-      }
-
-      /* Control writing of the stencil clear value to stencil. */
-      if (this_mask & BUFFER_BIT_STENCIL) {
-        _mesa_Enable(GL_STENCIL_TEST);
-        _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
-        _mesa_StencilFuncSeparate(GL_FRONT, GL_ALWAYS, ctx->Stencil.Clear,
-                                  ctx->Stencil.WriteMask[0]);
-      } else {
-        _mesa_Disable(GL_STENCIL_TEST);
-      }
-
-      CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4));
-
-      mask &= ~this_mask;
-   }
-
-   r200_meta_restore_transform(rmesa);
-
-   _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture);
-   if (saved_fp_enable)
-      _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB);
-   if (saved_vp_enable)
-      _mesa_Enable(GL_VERTEX_PROGRAM_ARB);
-
-   if (saved_shader_program)
-      _mesa_UseProgramObjectARB(saved_shader_program);
-
-   _mesa_PopClientAttrib();
-   _mesa_PopAttrib();
-}
-
-
 static void r200UserClear(GLcontext *ctx, GLuint mask)
 {
    radeon_clear_tris(ctx, mask);
@@ -449,7 +226,7 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask )
       mask &= ~BUFFER_BIT_DEPTH;
    }
 
-   if ( (mask & BUFFER_BIT_STENCIL) && rmesa->radeon.state.stencil.hwBuffer ) {
+   if ( (mask & BUFFER_BIT_STENCIL) ) {
       flags |= RADEON_STENCIL;
       mask &= ~BUFFER_BIT_STENCIL;
    }
@@ -467,8 +244,7 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask )
       flags |= RADEON_USE_COMP_ZBUF;
 /*      if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R200)
         flags |= RADEON_USE_HIERZ; */
-      if (!(rmesa->radeon.state.stencil.hwBuffer) ||
-        ((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) &&
+      if (!((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) &&
            ((rmesa->radeon.state.stencil.clear & R200_STENCIL_WRITE_MASK) == R200_STENCIL_WRITE_MASK))) {
          flags |= RADEON_CLEAR_FASTZ;
       }
index 74824b8..ca4dee8 100644 (file)
@@ -740,7 +740,8 @@ static void r200PolygonOffset( GLcontext *ctx,
                               GLfloat factor, GLfloat units )
 {
    r200ContextPtr rmesa = R200_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 };
 
 /*    factor *= 2; */
@@ -1611,6 +1612,7 @@ void r200UpdateWindow( GLcontext *ctx )
    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) {
@@ -1625,8 +1627,8 @@ void r200UpdateWindow( GLcontext *ctx )
    float_ui32_type tx = { v[MAT_TX] + xoffset + SUBPIXEL_X };
    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] * rmesa->radeon.state.depth.scale };
-   float_ui32_type tz = { v[MAT_TZ] * rmesa->radeon.state.depth.scale };
+   float_ui32_type sz = { v[MAT_SZ] * depthScale };
+   float_ui32_type tz = { v[MAT_TZ] * depthScale };
 
    R200_STATECHANGE( rmesa, vpt );
 
@@ -2014,15 +2016,24 @@ static void r200Enable( GLcontext *ctx, GLenum cap, GLboolean state )
       break;
 
    case GL_STENCIL_TEST:
-      if ( rmesa->radeon.state.stencil.hwBuffer ) {
-        R200_STATECHANGE( rmesa, ctx );
-        if ( state ) {
-           rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  R200_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) {
+           R200_STATECHANGE( rmesa, ctx );
+           if ( state ) {
+              rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |=  R200_STENCIL_ENABLE;
+           } else {
+              rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_STENCIL_ENABLE;
+           }
         } else {
-           rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~R200_STENCIL_ENABLE;
+           FALLBACK( rmesa, R200_FALLBACK_STENCIL, state );
         }
-      } else {
-        FALLBACK( rmesa, R200_FALLBACK_STENCIL, state );
       }
       break;
 
index a71f33c..30326c2 100644 (file)
@@ -674,21 +674,15 @@ void r200InitState( r200ContextPtr rmesa )
    switch ( ctx->Visual.depthBits ) {
    case 16:
       rmesa->radeon.state.depth.clear = 0x0000ffff;
-      rmesa->radeon.state.depth.scale = 1.0 / (GLfloat)0xffff;
       rmesa->radeon.state.stencil.clear = 0x00000000;
       break;
    case 24:
    default:
       rmesa->radeon.state.depth.clear = 0x00ffffff;
-      rmesa->radeon.state.depth.scale = 1.0 / (GLfloat)0xffffff;
       rmesa->radeon.state.stencil.clear = 0xffff0000;
       break;
    }
 
-   /* Only have hw stencil when depth buffer is 24 bits deep */
-   rmesa->radeon.state.stencil.hwBuffer = ( ctx->Visual.stencilBits > 0 &&
-                                    ctx->Visual.depthBits == 24 );
-
    rmesa->radeon.Fallback = 0;
 
    rmesa->radeon.hw.max_state_size = 0;
index cf0557d..c6bd69e 100644 (file)
@@ -113,7 +113,7 @@ const struct dri_extension card_extensions[] = {
   {"GL_EXT_blend_func_separate",       GL_EXT_blend_func_separate_functions},
   {"GL_EXT_blend_minmax",              GL_EXT_blend_minmax_functions},
   {"GL_EXT_blend_subtract",            NULL},
-   { "GL_EXT_framebuffer_object",       GL_EXT_framebuffer_object_functions },
+  {"GL_EXT_packed_depth_stencil",      NULL},
   {"GL_EXT_fog_coord",                 GL_EXT_fog_coord_functions },
   {"GL_EXT_gpu_program_parameters",     GL_EXT_gpu_program_parameters_functions},
   {"GL_EXT_secondary_color",           GL_EXT_secondary_color_functions},
@@ -141,6 +141,11 @@ const struct dri_extension card_extensions[] = {
 };
 
 
+const struct dri_extension mm_extensions[] = {
+  { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions },
+  { NULL, NULL }
+};
+
 /**
  * The GL 2.0 functions are needed to make display lists work with
  * functions added by GL_ATI_separate_stencil.
@@ -421,6 +426,8 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
        ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
 
        driInitExtensions(ctx, card_extensions, GL_TRUE);
+       if (r300->radeon.radeonScreen->kernel_mm)
+         driInitExtensions(ctx, mm_extensions, GL_FALSE);
 
        if (driQueryOptionb
            (&r300->radeon.optionCache, "disable_stencil_two_side"))
index d4acbd7..71661ee 100644 (file)
@@ -66,6 +66,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define CLEARBUFFER_DEPTH      0x2
 #define CLEARBUFFER_STENCIL    0x4
 
+static void r300EmitClearState(GLcontext * ctx);
+
+static void r300UserClear(GLcontext *ctx, GLuint mask)
+{
+       radeon_clear_tris(ctx, mask);
+}
+
 static void r300ClearBuffer(r300ContextPtr r300, int flags,
                            struct radeon_renderbuffer *rrb,
                            struct radeon_renderbuffer *rrbd)
@@ -534,6 +541,47 @@ static void r300EmitClearState(GLcontext * ctx)
        }
 }
 
+static void r300KernelClear(GLcontext *ctx, GLuint flags)
+{              
+       r300ContextPtr r300 = R300_CONTEXT(ctx);
+       __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
+       struct radeon_framebuffer *rfb = dPriv->driverPrivate;
+       struct radeon_renderbuffer *rrb;
+       struct radeon_renderbuffer *rrbd;
+       int bits = 0;
+
+       /* Make sure it fits there. */
+       rcommonEnsureCmdBufSpace(&r300->radeon, 421 * 3, __FUNCTION__);
+       if (flags || bits)
+               r300EmitClearState(ctx);
+       rrbd = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH);
+       if (rrbd && (flags & BUFFER_BIT_DEPTH))
+               bits |= CLEARBUFFER_DEPTH;
+
+       if (flags & BUFFER_BIT_COLOR0) {
+               rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_COLOR0);
+               r300ClearBuffer(r300, CLEARBUFFER_COLOR, rrb, NULL);
+               bits = 0;
+       }
+               
+       if (flags & BUFFER_BIT_FRONT_LEFT) {
+               rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT);
+               r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd);
+               bits = 0;
+       }
+
+       if (flags & BUFFER_BIT_BACK_LEFT) {
+               rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_BACK_LEFT);
+               r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd);
+               bits = 0;
+       }
+
+       if (bits)
+               r300ClearBuffer(r300, bits, NULL, rrbd);
+
+       COMMIT_BATCH();
+}
+
 /**
  * Buffer clear
  */
@@ -541,16 +589,15 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask)
 {
        r300ContextPtr r300 = R300_CONTEXT(ctx);
        __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
-       struct radeon_framebuffer *rfb = dPriv->driverPrivate;
-       struct radeon_renderbuffer *rrb;
-       struct radeon_renderbuffer *rrbd;
-       int flags = 0;
-       int bits = 0;
+       const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask);
+       GLbitfield swrast_mask = 0, tri_mask = 0;
+       int i;
+       struct gl_framebuffer *fb = ctx->DrawBuffer;
 
        if (RADEON_DEBUG & DEBUG_IOCTL)
                fprintf(stderr, "r300Clear\n");
 
-       {
+       if (!r300->radeon.radeonScreen->driScreen->dri2.enabled) {
                LOCK_HARDWARE(&r300->radeon);
                UNLOCK_HARDWARE(&r300->radeon);
                if (dPriv->numClipRects == 0)
@@ -563,68 +610,52 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask)
         */
        R300_NEWPRIM(r300);
 
-       if (mask & BUFFER_BIT_FRONT_LEFT) {
-               flags |= BUFFER_BIT_FRONT_LEFT;
-               mask &= ~BUFFER_BIT_FRONT_LEFT;
-       }
+       if (colorMask == ~0)
+         tri_mask |= (mask & BUFFER_BITS_COLOR);
 
-       if (mask & BUFFER_BIT_BACK_LEFT) {
-               flags |= BUFFER_BIT_BACK_LEFT;
-               mask &= ~BUFFER_BIT_BACK_LEFT;
-       }
 
-       if (mask & BUFFER_BIT_DEPTH) {
-               bits |= CLEARBUFFER_DEPTH;
-               mask &= ~BUFFER_BIT_DEPTH;
+       /* HW stencil */
+       if (mask & BUFFER_BIT_STENCIL) {
+               tri_mask |= BUFFER_BIT_STENCIL;
        }
 
-       if ((mask & BUFFER_BIT_STENCIL) && r300->radeon.state.stencil.hwBuffer) {
-               bits |= CLEARBUFFER_STENCIL;
-               mask &= ~BUFFER_BIT_STENCIL;
+       /* HW depth */
+       if (mask & BUFFER_BIT_DEPTH) {
+         tri_mask |= BUFFER_BIT_DEPTH;
        }
 
-       if (mask & BUFFER_BIT_COLOR0) {
-               flags |= BUFFER_BIT_COLOR0;
-               mask &= ~BUFFER_BIT_COLOR0;
-       }
+       /* If we're doing a tri pass for depth/stencil, include a likely color
+        * buffer with it.
+        */
 
-       if (mask) {
-               if (RADEON_DEBUG & DEBUG_FALLBACKS)
-                       fprintf(stderr, "%s: swrast clear, mask: %x\n",
-                               __FUNCTION__, mask);
-               _swrast_Clear(ctx, mask);
+       for (i = 0; i < BUFFER_COUNT; i++) {
+         GLuint bufBit = 1 << i;
+         if ((tri_mask) & bufBit) {
+           if (!fb->Attachment[i].Renderbuffer->ClassID) {
+             tri_mask &= ~bufBit;
+             swrast_mask |= bufBit;
+           }
+         }
        }
 
-       /* Make sure it fits there. */
-       rcommonEnsureCmdBufSpace(&r300->radeon, 421 * 3, __FUNCTION__);
-       if (flags || bits)
-               r300EmitClearState(ctx);
-       rrbd = (void *)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer;
+       /* SW fallback clearing */
+       swrast_mask = mask & ~tri_mask;
 
-       if (flags & BUFFER_BIT_COLOR0) {
-               rrb = (void *)rfb->base.Attachment[BUFFER_COLOR0].Renderbuffer;
-               r300ClearBuffer(r300, CLEARBUFFER_COLOR, rrb, NULL);
-               bits = 0;
-       }
-               
-       if (flags & BUFFER_BIT_FRONT_LEFT) {
-               rrb = (void *)rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
-               r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd);
-               bits = 0;
+       if (tri_mask) {
+               if (r300->radeon.radeonScreen->kernel_mm)
+                       r300UserClear(ctx, tri_mask);
+               else
+                       r300KernelClear(ctx, tri_mask);
        }
-
-       if (flags & BUFFER_BIT_BACK_LEFT) {
-               rrb = (void *)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer;
-               r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd);
-               bits = 0;
+       if (swrast_mask) {
+               if (RADEON_DEBUG & DEBUG_FALLBACKS)
+                       fprintf(stderr, "%s: swrast clear, mask: %x\n",
+                               __FUNCTION__, swrast_mask);
+               _swrast_Clear(ctx, swrast_mask);
        }
-
-       if (bits)
-               r300ClearBuffer(r300, bits, NULL, rrbd);
-
-       COMMIT_BATCH();
 }
 
+
 void r300InitIoctlFuncs(struct dd_function_table *functions)
 {
        functions->Clear = r300Clear;
index 02f29a0..f49b43c 100644 (file)
@@ -587,8 +587,14 @@ static void r300SetDepthState(GLcontext * ctx)
 static void r300SetStencilState(GLcontext * ctx, GLboolean state)
 {
        r300ContextPtr r300 = R300_CONTEXT(ctx);
+       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 (r300->radeon.state.stencil.hwBuffer) {
+       if (hw_stencil) {
                R300_STATECHANGE(r300, zs);
                if (state) {
                        r300->hw.zs.cmd[R300_ZS_CNTL_0] |=
@@ -933,7 +939,8 @@ static void r300UpdateWindow(GLcontext * ctx)
        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;
+       const GLboolean render_to_fbo = (ctx->DrawBuffer->Name != 0);
        GLfloat y_scale, y_bias;
 
        if (render_to_fbo) {
@@ -948,8 +955,8 @@ static void r300UpdateWindow(GLcontext * ctx)
        GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X;
        GLfloat sy = v[MAT_SY] * y_scale;
        GLfloat ty = (v[MAT_TY] * y_scale) + y_bias + SUBPIXEL_Y;
-       GLfloat sz = v[MAT_SZ] * rmesa->radeon.state.depth.scale;
-       GLfloat tz = v[MAT_TZ] * rmesa->radeon.state.depth.scale;
+       GLfloat sz = v[MAT_SZ] * depthScale;
+       GLfloat tz = v[MAT_TZ] * depthScale;
 
        R300_STATECHANGE(rmesa, vpt);
 
@@ -2032,7 +2039,7 @@ static void r300ResetHwState(r300ContextPtr r300)
                fprintf(stderr, "%s\n", __FUNCTION__);
 
        radeon_firevertices(&r300->radeon);
-       r300UpdateWindow(ctx);
+       //r300UpdateWindow(ctx);
 
        r300ColorMask(ctx,
                      ctx->Color.ColorMask[RCOMP],
@@ -2207,16 +2214,6 @@ static void r300ResetHwState(r300ContextPtr r300)
        r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[1] = 0x00000000;
        r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[2] = 0xffffffff;
 
-       rrb = r300->radeon.state.depth.rrb;
-       if (rrb && rrb->bo && (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE)) {
-               /* XXX: Turn off when clearing buffers ? */
-               r300->hw.zb.cmd[R300_ZB_PITCH] |= R300_DEPTHMACROTILE_ENABLE;
-
-               if (ctx->Visual.depthBits == 24)
-                       r300->hw.zb.cmd[R300_ZB_PITCH] |=
-                           R300_DEPTHMICROTILE_TILED;
-       }
-
        r300->hw.zb_depthclearvalue.cmd[1] = 0;
 
        r300->hw.zstencil_format.cmd[2] = R300_ZTOP_DISABLE;
@@ -2530,10 +2527,6 @@ void r300InitState(r300ContextPtr r300)
        GLcontext *ctx = r300->radeon.glCtx;
        GLuint depth_fmt;
 
-       /* Only have hw stencil when depth buffer is 24 bits deep */
-       r300->radeon.state.stencil.hwBuffer = (ctx->Visual.stencilBits > 0 &&
-                                              ctx->Visual.depthBits == 24);
-
        memset(&(r300->state.texture), 0, sizeof(r300->state.texture));
 
        r300ResetHwState(r300);
index f80f0f7..42607df 100644 (file)
@@ -36,7 +36,10 @@ struct drm_radeon_gem_info {
 #endif
 
 
-
+uint32_t radeon_gem_bo_name(struct radeon_bo *dummy)
+{
+  return 0;
+}
 
 static inline void *radeon_bo_manager_gem_ctor(int fd)
 {
index 4fd54c0..9f646c4 100644 (file)
@@ -58,6 +58,21 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "tnl/t_pipeline.h"
 #include "swrast_setup/swrast_setup.h"
 
+#include "main/blend.h"
+#include "main/bufferobj.h"
+#include "main/buffers.h"
+#include "main/depth.h"
+#include "main/shaders.h"
+#include "main/texstate.h"
+#include "main/varray.h"
+#include "glapi/dispatch.h"
+#include "swrast/swrast.h"
+#include "main/stencil.h"
+#include "main/matrix.h"
+#include "main/attrib.h"
+#include "main/enable.h"
+#include "main/viewport.h"
+
 #include "dri_util.h"
 #include "vblank.h"
 
@@ -658,18 +673,20 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
                /* none */
        if (fb->Name == 0) {
                if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
-                       rrbColor = (void *)fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
+                       rrbColor = radeon_renderbuffer(fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer);
                        radeon->front_cliprects = GL_TRUE;
                } else {
-                       rrbColor = (void *)fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
+                       rrbColor = radeon_renderbuffer(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer);
                        radeon->front_cliprects = GL_FALSE;
                }
        } else {
                /* user FBO in theory */
                struct radeon_renderbuffer *rrb;
-               rrb = (void *)fb->_ColorDrawBuffers[0];
-               offset = rrb->draw_offset;
-               rrbColor = rrb;
+               rrb = radeon_renderbuffer(fb->_ColorDrawBuffers[0]);
+               if (rrb) {
+                       offset = rrb->draw_offset;
+                       rrbColor = rrb;
+               }
                radeon->constant_cliprect = GL_TRUE;
        }
 
@@ -679,9 +696,8 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
                radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DRAW_BUFFER, GL_FALSE);
 
 
-
        if (fb->_DepthBuffer && fb->_DepthBuffer->Wrapped) {
-               rrbDepth = (struct radeon_renderbuffer *)fb->_DepthBuffer->Wrapped;
+               rrbDepth = radeon_renderbuffer(fb->_DepthBuffer->Wrapped);
                if (rrbDepth && rrbDepth->bo) {
                        radeon->vtbl.fallback(ctx, RADEON_FALLBACK_DEPTH_BUFFER, GL_FALSE);
                } else {
@@ -692,16 +708,11 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
                rrbDepth = NULL;
        }
 
-       /* TODO stencil things */
        if (fb->_StencilBuffer && fb->_StencilBuffer->Wrapped) {
-               rrbStencil = (struct radeon_renderbuffer *)fb->_DepthBuffer->Wrapped;
+               rrbStencil = radeon_renderbuffer(fb->_DepthBuffer->Wrapped);
                if (rrbStencil && rrbStencil->bo) {
                        radeon->vtbl.fallback(ctx, RADEON_FALLBACK_STENCIL_BUFFER, GL_FALSE);
                        /* need to re-compute stencil hw state */
-                       if (ctx->Driver.Enable != NULL)
-                               ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled);
-                       else
-                               ctx->NewState |= _NEW_STENCIL;
                        if (!rrbDepth)
                                rrbDepth = rrbStencil;
                } else {
@@ -727,27 +738,28 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
         * Update depth test state
         */
        if (ctx->Driver.Enable) {
-               if (ctx->Depth.Test && fb->Visual.depthBits > 0) {
-                       ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_TRUE);
-               } else {
-                       ctx->Driver.Enable(ctx, GL_DEPTH_TEST, GL_FALSE);
-               }
+               ctx->Driver.Enable(ctx, GL_DEPTH_TEST,
+                                  (ctx->Depth.Test && fb->Visual.depthBits > 0));
+               ctx->Driver.Enable(ctx, GL_STENCIL_TEST,
+                                  (ctx->Stencil._Enabled && fb->Visual.stencilBits > 0));
        } else {
-               ctx->NewState |= _NEW_DEPTH;
+               ctx->NewState |= (_NEW_DEPTH | _NEW_STENCIL);
        }
        
        radeon->state.depth.rrb = rrbDepth;
-
        radeon->state.color.rrb = rrbColor;
        radeon->state.color.draw_offset = offset;
 
+#if 0
        /* update viewport since it depends on window size */
        if (ctx->Driver.Viewport) {
                ctx->Driver.Viewport(ctx, ctx->Viewport.X, ctx->Viewport.Y,
                                     ctx->Viewport.Width, ctx->Viewport.Height);
        } else {
-               ctx->NewState |= _NEW_VIEWPORT;
+       
        }
+#endif
+       ctx->NewState |= _NEW_VIEWPORT;
 
        /* Set state we know depends on drawable parameters:
         */
@@ -755,6 +767,19 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
                ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
                                    ctx->Scissor.Width, ctx->Scissor.Height);
        radeon->NewGLState |= _NEW_SCISSOR;
+
+       if (ctx->Driver.DepthRange)
+               ctx->Driver.DepthRange(ctx,
+                                      ctx->Viewport.Near,
+                                      ctx->Viewport.Far);
+
+       /* Update culling direction which changes depending on the
+        * orientation of the buffer:
+        */
+       if (ctx->Driver.FrontFace)
+               ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace);
+       else
+               ctx->NewState |= _NEW_POLYGON;
 }
 
 /**
@@ -802,10 +827,6 @@ void radeonUpdatePageFlipping(radeonContextPtr radeon)
 
 void radeon_window_moved(radeonContextPtr radeon)
 {
-       GLcontext *ctx = radeon->glCtx;
-       __DRIdrawablePrivate *dPriv = radeon->dri.drawable;
-       struct radeon_framebuffer *rfb = dPriv->driverPrivate;
-
        if (!radeon->radeonScreen->driScreen->dri2.enabled) {
                radeonUpdatePageFlipping(radeon);
        }
@@ -949,8 +970,14 @@ void radeonFinish(GLcontext * ctx)
        if (radeon->radeonScreen->kernel_mm) {
                for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
                        struct radeon_renderbuffer *rrb;
-                       rrb = (struct radeon_renderbuffer *)fb->_ColorDrawBuffers[i];
-                       if (rrb->bo)
+                       rrb = radeon_renderbuffer(fb->_ColorDrawBuffers[i]);
+                       if (rrb && rrb->bo)
+                               radeon_bo_wait(rrb->bo);
+               }
+               {
+                       struct radeon_renderbuffer *rrb;
+                       rrb = radeon_get_depthbuffer(radeon);
+                       if (rrb && rrb->bo)
                                radeon_bo_wait(rrb->bo);
                }
        } else if (radeon->do_irqs) {
@@ -1108,3 +1135,219 @@ void rcommonBeginBatch(radeonContextPtr rmesa, int n,
 
 
 
+static void
+radeon_meta_set_passthrough_transform(radeonContextPtr radeon)
+{
+   GLcontext *ctx = radeon->glCtx;
+
+   radeon->meta.saved_vp_x = ctx->Viewport.X;
+   radeon->meta.saved_vp_y = ctx->Viewport.Y;
+   radeon->meta.saved_vp_width = ctx->Viewport.Width;
+   radeon->meta.saved_vp_height = ctx->Viewport.Height;
+   radeon->meta.saved_matrix_mode = ctx->Transform.MatrixMode;
+
+   _mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height);
+
+   _mesa_MatrixMode(GL_PROJECTION);
+   _mesa_PushMatrix();
+   _mesa_LoadIdentity();
+   _mesa_Ortho(0, ctx->DrawBuffer->Width, 0, ctx->DrawBuffer->Height, 1, -1);
+
+   _mesa_MatrixMode(GL_MODELVIEW);
+   _mesa_PushMatrix();
+   _mesa_LoadIdentity();
+}
+
+static void
+radeon_meta_restore_transform(radeonContextPtr radeon)
+{
+   _mesa_MatrixMode(GL_PROJECTION);
+   _mesa_PopMatrix();
+   _mesa_MatrixMode(GL_MODELVIEW);
+   _mesa_PopMatrix();
+
+   _mesa_MatrixMode(radeon->meta.saved_matrix_mode);
+
+   _mesa_Viewport(radeon->meta.saved_vp_x, radeon->meta.saved_vp_y,
+                 radeon->meta.saved_vp_width, radeon->meta.saved_vp_height);
+}
+
+
+/**
+ * Perform glClear where mask contains only color, depth, and/or stencil.
+ *
+ * The implementation is based on calling into Mesa to set GL state and
+ * performing normal triangle rendering.  The intent of this path is to
+ * have as generic a path as possible, so that any driver could make use of
+ * it.
+ */
+
+
+void radeon_clear_tris(GLcontext *ctx, GLbitfield mask)
+{
+   radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+   GLfloat vertices[4][3];
+   GLfloat color[4][4];
+   GLfloat dst_z;
+   struct gl_framebuffer *fb = ctx->DrawBuffer;
+   int i;
+   GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE;
+   GLboolean saved_shader_program = 0;
+   unsigned int saved_active_texture;
+
+   assert((mask & ~(TRI_CLEAR_COLOR_BITS | BUFFER_BIT_DEPTH |
+                   BUFFER_BIT_STENCIL)) == 0);   
+
+   _mesa_PushAttrib(GL_COLOR_BUFFER_BIT |
+                   GL_CURRENT_BIT |
+                   GL_DEPTH_BUFFER_BIT |
+                   GL_ENABLE_BIT |
+                   GL_STENCIL_BUFFER_BIT |
+                   GL_TRANSFORM_BIT |
+                   GL_CURRENT_BIT);
+   _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
+   saved_active_texture = ctx->Texture.CurrentUnit;
+  
+  /* Disable existing GL state we don't want to apply to a clear. */
+   _mesa_Disable(GL_ALPHA_TEST);
+   _mesa_Disable(GL_BLEND);
+   _mesa_Disable(GL_CULL_FACE);
+   _mesa_Disable(GL_FOG);
+   _mesa_Disable(GL_POLYGON_SMOOTH);
+   _mesa_Disable(GL_POLYGON_STIPPLE);
+   _mesa_Disable(GL_POLYGON_OFFSET_FILL);
+   _mesa_Disable(GL_LIGHTING);
+   _mesa_Disable(GL_CLIP_PLANE0);
+   _mesa_Disable(GL_CLIP_PLANE1);
+   _mesa_Disable(GL_CLIP_PLANE2);
+   _mesa_Disable(GL_CLIP_PLANE3);
+   _mesa_Disable(GL_CLIP_PLANE4);
+   _mesa_Disable(GL_CLIP_PLANE5);
+   if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) {
+      saved_fp_enable = GL_TRUE;
+      _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB);
+   }
+   if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) {
+      saved_vp_enable = GL_TRUE;
+      _mesa_Disable(GL_VERTEX_PROGRAM_ARB);
+   }
+   if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) {
+      saved_shader_program = ctx->Shader.CurrentProgram->Name;
+      _mesa_UseProgramObjectARB(0);
+   }
+   
+   if (ctx->Texture._EnabledUnits != 0) {
+      int i;
+      
+      for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
+        _mesa_ActiveTextureARB(GL_TEXTURE0 + i);
+        _mesa_Disable(GL_TEXTURE_1D);
+        _mesa_Disable(GL_TEXTURE_2D);
+        _mesa_Disable(GL_TEXTURE_3D);
+        if (ctx->Extensions.ARB_texture_cube_map)
+           _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB);
+        if (ctx->Extensions.NV_texture_rectangle)
+           _mesa_Disable(GL_TEXTURE_RECTANGLE_NV);
+        if (ctx->Extensions.MESA_texture_array) {
+           _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT);
+           _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT);
+        }
+      }
+   }
+  
+   radeon_meta_set_passthrough_transform(rmesa);
+   
+   for (i = 0; i < 4; i++) {
+      color[i][0] = ctx->Color.ClearColor[0];
+      color[i][1] = ctx->Color.ClearColor[1];
+      color[i][2] = ctx->Color.ClearColor[2];
+      color[i][3] = ctx->Color.ClearColor[3];
+   }
+
+   /* convert clear Z from [0,1] to NDC coord in [-1,1] */
+
+   dst_z = -1.0 + 2.0 * ctx->Depth.Clear;
+   /* Prepare the vertices, which are the same regardless of which buffer we're
+    * drawing to.
+    */
+   vertices[0][0] = fb->_Xmin;
+   vertices[0][1] = fb->_Ymin;
+   vertices[0][2] = dst_z;
+   vertices[1][0] = fb->_Xmax;
+   vertices[1][1] = fb->_Ymin;
+   vertices[1][2] = dst_z;
+   vertices[2][0] = fb->_Xmax;
+   vertices[2][1] = fb->_Ymax;
+   vertices[2][2] = dst_z;
+   vertices[3][0] = fb->_Xmin;
+   vertices[3][1] = fb->_Ymax;
+   vertices[3][2] = dst_z;
+
+   _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &color);
+   _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), &vertices);
+   _mesa_Enable(GL_COLOR_ARRAY);
+   _mesa_Enable(GL_VERTEX_ARRAY);
+
+   while (mask != 0) {
+      GLuint this_mask = 0;
+      GLuint color_bit;
+
+      color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS);
+      if (color_bit != 0)
+        this_mask |= (1 << (color_bit - 1));
+
+      /* Clear depth/stencil in the same pass as color. */
+      this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL));
+
+      /* Select the current color buffer and use the color write mask if
+       * we have one, otherwise don't write any color channels.
+       */
+      if (this_mask & BUFFER_BIT_FRONT_LEFT)
+        _mesa_DrawBuffer(GL_FRONT_LEFT);
+      else if (this_mask & BUFFER_BIT_BACK_LEFT)
+        _mesa_DrawBuffer(GL_BACK_LEFT);
+      else if (color_bit != 0)
+        _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0 +
+                         (color_bit - BUFFER_COLOR0 - 1));
+      else
+        _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+
+      /* Control writing of the depth clear value to depth. */
+      if (this_mask & BUFFER_BIT_DEPTH) {
+        _mesa_DepthFunc(GL_ALWAYS);
+        _mesa_DepthMask(GL_TRUE);
+        _mesa_Enable(GL_DEPTH_TEST);
+      } else {
+        _mesa_Disable(GL_DEPTH_TEST);
+        _mesa_DepthMask(GL_FALSE);
+      }
+
+      /* Control writing of the stencil clear value to stencil. */
+      if (this_mask & BUFFER_BIT_STENCIL) {
+        _mesa_Enable(GL_STENCIL_TEST);
+        _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
+        _mesa_StencilFuncSeparate(GL_FRONT, GL_ALWAYS, ctx->Stencil.Clear,
+                                  ctx->Stencil.WriteMask[0]);
+      } else {
+        _mesa_Disable(GL_STENCIL_TEST);
+      }
+
+      CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4));
+
+      mask &= ~this_mask;
+   }
+
+   radeon_meta_restore_transform(rmesa);
+
+   _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture);
+   if (saved_fp_enable)
+      _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB);
+   if (saved_vp_enable)
+      _mesa_Enable(GL_VERTEX_PROGRAM_ARB);
+
+   if (saved_shader_program)
+      _mesa_UseProgramObjectARB(saved_shader_program);
+
+   _mesa_PopClientAttrib();
+   _mesa_PopAttrib();
+}
index c97492d..f3e2290 100644 (file)
@@ -5,6 +5,18 @@
 #include "radeon_dma.h"
 #include "radeon_texture.h"
 
+
+#define TRI_CLEAR_COLOR_BITS (BUFFER_BIT_BACK_LEFT |                   \
+                             BUFFER_BIT_FRONT_LEFT |                   \
+                             BUFFER_BIT_COLOR0 |                       \
+                             BUFFER_BIT_COLOR1 |                       \
+                             BUFFER_BIT_COLOR2 |                       \
+                             BUFFER_BIT_COLOR3 |                       \
+                             BUFFER_BIT_COLOR4 |                       \
+                             BUFFER_BIT_COLOR5 |                       \
+                             BUFFER_BIT_COLOR6 |                       \
+                             BUFFER_BIT_COLOR7)
+
 void radeonRecalcScissorRects(radeonContextPtr radeon);
 void radeonSetCliprects(radeonContextPtr radeon);
 void radeonUpdateScissor( GLcontext *ctx );
@@ -24,6 +36,8 @@ void radeonFlush(GLcontext *ctx);
 void radeonFinish(GLcontext * ctx);
 void radeonEmitState(radeonContextPtr radeon);
 
+void radeon_clear_tris(GLcontext *ctx, GLbitfield mask);
+
 void radeon_window_moved(radeonContextPtr radeon);
 void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb);
 void radeonDrawBuffer( GLcontext *ctx, GLenum mode );
@@ -35,7 +49,10 @@ void radeon_get_cliprects(radeonContextPtr radeon,
                          int *x_off, int *y_off);
 
 void radeon_fbo_init(struct radeon_context *radeon);
-struct gl_renderbuffer *
+void
+radeon_renderbuffer_set_bo(struct radeon_renderbuffer *rb,
+                          struct radeon_bo *bo);
+struct radeon_renderbuffer *
 radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv);
 static inline struct radeon_renderbuffer *radeon_renderbuffer(struct gl_renderbuffer *rb)
 {
index a818440..f335eb0 100644 (file)
@@ -392,6 +392,7 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
        struct radeon_framebuffer *draw;
        radeonContextPtr radeon;
        char *regname;
+       struct radeon_bo *depth_bo, *bo;
 
        if (RADEON_DEBUG & DEBUG_DRI)
            fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
@@ -448,7 +449,7 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
                        regname = "dri2 depth buffer";
                        break;
                case __DRI_BUFFER_STENCIL:
-                       rb = radeon_get_renderbuffer(&draw->base, BUFFER_DEPTH);
+                       rb = radeon_get_renderbuffer(&draw->base, BUFFER_STENCIL);
                        regname = "dri2 stencil buffer";
                        break;
                case __DRI_BUFFER_ACCUM:
@@ -463,25 +464,49 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
                        continue;
 
                if (rb->bo) {
-                       radeon_bo_unref(rb->bo);
-                       rb->bo = NULL;
+                       uint32_t name = radeon_gem_name_bo(rb->bo);
+                       if (name == buffers[i].name)
+                               continue;
                }
+
+               if (RADEON_DEBUG & DEBUG_DRI)
+                       fprintf(stderr,
+                               "attaching buffer %s, %d, at %d, cpp %d, pitch %d\n",
+                               regname, buffers[i].name, buffers[i].attachment,
+                               buffers[i].cpp, buffers[i].pitch);
+
                rb->cpp = buffers[i].cpp;
                rb->pitch = buffers[i].pitch;
                rb->width = drawable->w;
                rb->height = drawable->h;
                rb->has_surface = 0;
-               rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
-                                       buffers[i].name,
-                                       0,
-                                       0,
-                                       RADEON_GEM_DOMAIN_VRAM,
-                                       buffers[i].flags);
-               if (rb->bo == NULL) {
-                       fprintf(stderr, "failed to attach %s %d\n",
-                               regname, buffers[i].name);
 
+               if (buffers[i].attachment == __DRI_BUFFER_STENCIL && depth_bo) {
+                       if (RADEON_DEBUG & DEBUG_DRI)
+                               fprintf(stderr, "(reusing depth buffer as stencil)\n");
+                       bo = depth_bo;
+                       radeon_bo_ref(bo);
+               } else {
+                       bo = radeon_bo_open(radeon->radeonScreen->bom,
+                                               buffers[i].name,
+                                               0,
+                                               0,
+                                               RADEON_GEM_DOMAIN_VRAM,
+                                               buffers[i].flags);
+                       if (bo == NULL) {
+
+                               fprintf(stderr, "failed to attach %s %d\n",
+                                       regname, buffers[i].name);
+                               
+                       }
                }
+
+               if (buffers[i].attachment == __DRI_BUFFER_DEPTH)
+                       depth_bo = bo;
+
+               radeon_renderbuffer_set_bo(rb, bo);
+               radeon_bo_unref(bo);
+                   
        }
 
        driUpdateFramebufferSize(radeon->glCtx, drawable);
index 612cc97..0ce72c9 100644 (file)
@@ -123,7 +123,6 @@ struct radeon_colorbuffer_state {
 
 struct radeon_depthbuffer_state {
        GLuint clear;
-       GLfloat scale;
        struct radeon_renderbuffer *rrb;
 };
 
@@ -137,7 +136,6 @@ struct radeon_scissor_state {
 };
 
 struct radeon_stencilbuffer_state {
-       GLboolean hwBuffer;
        GLuint clear;           /* rb3d_stencilrefmask value */
 };
 
@@ -444,9 +442,23 @@ struct radeon_context {
 
    struct radeon_cmdbuf cmdbuf;
        
-       drm_clip_rect_t fboRect;
-       GLboolean constant_cliprect; /* use for FBO or DRI2 rendering */
-       GLboolean front_cliprects;
+  drm_clip_rect_t fboRect;
+  GLboolean constant_cliprect; /* use for FBO or DRI2 rendering */
+  GLboolean front_cliprects;
+
+  struct {
+      struct gl_fragment_program *bitmap_fp;
+      struct gl_vertex_program *passthrough_vp;
+
+      struct gl_fragment_program *saved_fp;
+      GLboolean saved_fp_enable;
+      struct gl_vertex_program *saved_vp;
+      GLboolean saved_vp_enable;
+
+      GLint saved_vp_x, saved_vp_y;
+      GLsizei saved_vp_width, saved_vp_height;
+      GLenum saved_matrix_mode;
+   } meta;
 
    struct {
           void (*get_lock)(radeonContextPtr radeon);
index 3f69de8..ac945ec 100644 (file)
@@ -66,6 +66,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define need_GL_EXT_blend_minmax
 #define need_GL_EXT_fog_coord
 #define need_GL_EXT_secondary_color
+#define need_GL_EXT_framebuffer_object
 #include "extension_helper.h"
 
 #define DRIVER_DATE    "20061018"
@@ -88,6 +89,7 @@ const struct dri_extension card_extensions[] =
     { "GL_EXT_blend_logic_op",             NULL },
     { "GL_EXT_blend_subtract",             GL_EXT_blend_minmax_functions },
     { "GL_EXT_fog_coord",                  GL_EXT_fog_coord_functions },
+    { "GL_EXT_packed_depth_stencil",      NULL},
     { "GL_EXT_secondary_color",            GL_EXT_secondary_color_functions },
     { "GL_EXT_stencil_wrap",               NULL },
     { "GL_EXT_texture_edge_clamp",         NULL },
@@ -104,6 +106,11 @@ const struct dri_extension card_extensions[] =
     { NULL,                                NULL }
 };
 
+const struct dri_extension mm_extensions[] = {
+  { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions },
+  { NULL, NULL }
+};
+
 extern const struct tnl_pipeline_stage _radeon_render_stage;
 extern const struct tnl_pipeline_stage _radeon_tcl_stage;
 
@@ -338,6 +345,8 @@ radeonCreateContext( const __GLcontextModes *glVisual,
    }
 
    driInitExtensions( ctx, card_extensions, GL_TRUE );
+   if (rmesa->radeon.radeonScreen->kernel_mm)
+     driInitExtensions(ctx, mm_extensions, GL_FALSE);
    if (rmesa->radeon.radeonScreen->drmSupportsCubeMapsR100)
       _mesa_enable_extension( ctx, "GL_ARB_texture_cube_map" );
    if (rmesa->radeon.glCtx->Mesa_DXTn) {
index 2015e96..5235a6e 100644 (file)
@@ -435,20 +435,6 @@ struct r100_context {
        GLuint c_textureBytes;
        GLuint c_vertexBuffers;
 
-  struct {
-      struct gl_fragment_program *bitmap_fp;
-      struct gl_vertex_program *passthrough_vp;
-
-      struct gl_fragment_program *saved_fp;
-      GLboolean saved_fp_enable;
-      struct gl_vertex_program *saved_vp;
-      GLboolean saved_vp_enable;
-
-      GLint saved_vp_x, saved_vp_y;
-      GLsizei saved_vp_width, saved_vp_height;
-      GLenum saved_matrix_mode;
-   } meta;
-
 };
 
 
index 7342f22..f914c8c 100644 (file)
@@ -54,7 +54,6 @@ radeon_new_framebuffer(GLcontext *ctx, GLuint name)
 static void
 radeon_delete_renderbuffer(struct gl_renderbuffer *rb)
 {
-  GET_CURRENT_CONTEXT(ctx);
   struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
 
   ASSERT(rrb);
@@ -62,8 +61,6 @@ radeon_delete_renderbuffer(struct gl_renderbuffer *rb)
   if (rrb && rrb->bo) {
     radeon_bo_unref(rrb->bo);
   }
-
-
   _mesa_free(rrb);
 }
 
@@ -255,7 +252,7 @@ radeon_nop_alloc_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
    return GL_FALSE;
 }
 
-struct gl_renderbuffer *
+struct radeon_renderbuffer *
 radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv)
 {
     struct radeon_renderbuffer *rrb;
@@ -325,7 +322,7 @@ radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv)
     rrb->base.GetPointer = radeon_get_pointer;
 
     rrb->bo = NULL;
-    return &rrb->base;
+    return rrb;
 }
 
 static struct gl_renderbuffer *
@@ -383,6 +380,13 @@ radeon_update_wrapper(GLcontext *ctx, struct radeon_renderbuffer *rrb,
       rrb->base.DataType = GL_UNSIGNED_BYTE;
       DBG("Render to RGBA8 texture OK\n");
    }
+   else if (texImage->TexFormat == &_mesa_texformat_argb4444) {
+      rrb->cpp = 2;
+      rrb->base._ActualFormat = GL_RGBA4;
+      rrb->base._BaseFormat = GL_RGBA;
+      rrb->base.DataType = GL_UNSIGNED_BYTE;
+      DBG("Render to RGBA4 texture OK\n");
+   }
    else if (texImage->TexFormat == &_mesa_texformat_rgb565) {
       rrb->cpp = 2;
       rrb->base._ActualFormat = GL_RGB5;
@@ -493,7 +497,7 @@ radeon_render_texture(GLcontext * ctx,
        return;
    }
 
-   fprintf(stderr,"Begin render texture tid %x tex=%u w=%d h=%d refcount=%d\n",
+   DBG("Begin render texture tid %x tex=%u w=%d h=%d refcount=%d\n",
        _glthread_GetID(),
        att->Texture->Name, newImage->Width, newImage->Height,
        rrb->base.RefCount);
@@ -558,4 +562,13 @@ void radeon_fbo_init(struct radeon_context *radeon)
 }
 
   
-  
+void radeon_renderbuffer_set_bo(struct radeon_renderbuffer *rb,
+                               struct radeon_bo *bo)
+{
+  struct radeon_bo *old;
+  old = rb->bo;
+  rb->bo = bo;
+  radeon_bo_ref(bo);
+  if (old)
+    radeon_bo_unref(old);
+}
index 22584f4..f18aa1a 100644 (file)
@@ -419,218 +419,6 @@ void radeonEmitAOS( r100ContextPtr rmesa,
  */
 #define RADEON_MAX_CLEARS      256
 
-
-
-static void
-r100_meta_set_passthrough_transform(r100ContextPtr r100)
-{
-   GLcontext *ctx = r100->radeon.glCtx;
-
-   r100->meta.saved_vp_x = ctx->Viewport.X;
-   r100->meta.saved_vp_y = ctx->Viewport.Y;
-   r100->meta.saved_vp_width = ctx->Viewport.Width;
-   r100->meta.saved_vp_height = ctx->Viewport.Height;
-   r100->meta.saved_matrix_mode = ctx->Transform.MatrixMode;
-
-   _mesa_Viewport(0, 0, ctx->DrawBuffer->Width, ctx->DrawBuffer->Height);
-
-   _mesa_MatrixMode(GL_PROJECTION);
-   _mesa_PushMatrix();
-   _mesa_LoadIdentity();
-   _mesa_Ortho(0, ctx->DrawBuffer->Width, 0, ctx->DrawBuffer->Height, 1, -1);
-
-   _mesa_MatrixMode(GL_MODELVIEW);
-   _mesa_PushMatrix();
-   _mesa_LoadIdentity();
-}
-
-static void
-r100_meta_restore_transform(r100ContextPtr r100)
-{
-   _mesa_MatrixMode(GL_PROJECTION);
-   _mesa_PopMatrix();
-   _mesa_MatrixMode(GL_MODELVIEW);
-   _mesa_PopMatrix();
-
-   _mesa_MatrixMode(r100->meta.saved_matrix_mode);
-
-   _mesa_Viewport(r100->meta.saved_vp_x, r100->meta.saved_vp_y,
-                 r100->meta.saved_vp_width, r100->meta.saved_vp_height);
-}
-
-/**
- * Perform glClear where mask contains only color, depth, and/or stencil.
- *
- * The implementation is based on calling into Mesa to set GL state and
- * performing normal triangle rendering.  The intent of this path is to
- * have as generic a path as possible, so that any driver could make use of
- * it.
- */
-static void radeon_clear_tris(GLcontext *ctx, GLbitfield mask)
-{
-   r100ContextPtr rmesa = R100_CONTEXT(ctx);
-   GLfloat vertices[4][3];
-   GLfloat color[4][4];
-   GLfloat dst_z;
-   struct gl_framebuffer *fb = ctx->DrawBuffer;
-   int i;
-   GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE;
-   GLboolean saved_shader_program = 0;
-   unsigned int saved_active_texture;
-   
-   assert((mask & ~(BUFFER_BIT_BACK_LEFT | BUFFER_BIT_FRONT_LEFT |
-                   BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) == 0);
-
-   _mesa_PushAttrib(GL_COLOR_BUFFER_BIT |
-                   GL_CURRENT_BIT |
-                   GL_DEPTH_BUFFER_BIT |
-                   GL_ENABLE_BIT |
-                   GL_STENCIL_BUFFER_BIT |
-                   GL_TRANSFORM_BIT |
-                   GL_CURRENT_BIT);
-   _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
-   saved_active_texture = ctx->Texture.CurrentUnit;
-  
-  /* Disable existing GL state we don't want to apply to a clear. */
-   _mesa_Disable(GL_ALPHA_TEST);
-   _mesa_Disable(GL_BLEND);
-   _mesa_Disable(GL_CULL_FACE);
-   _mesa_Disable(GL_FOG);
-   _mesa_Disable(GL_POLYGON_SMOOTH);
-   _mesa_Disable(GL_POLYGON_STIPPLE);
-   _mesa_Disable(GL_POLYGON_OFFSET_FILL);
-   _mesa_Disable(GL_LIGHTING);
-   _mesa_Disable(GL_CLIP_PLANE0);
-   _mesa_Disable(GL_CLIP_PLANE1);
-   _mesa_Disable(GL_CLIP_PLANE2);
-   _mesa_Disable(GL_CLIP_PLANE3);
-   _mesa_Disable(GL_CLIP_PLANE4);
-   _mesa_Disable(GL_CLIP_PLANE5);
-   if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) {
-      saved_fp_enable = GL_TRUE;
-      _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB);
-   }
-   if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) {
-      saved_vp_enable = GL_TRUE;
-      _mesa_Disable(GL_VERTEX_PROGRAM_ARB);
-   }
-   if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) {
-      saved_shader_program = ctx->Shader.CurrentProgram->Name;
-      _mesa_UseProgramObjectARB(0);
-   }
-   
-   if (ctx->Texture._EnabledUnits != 0) {
-      int i;
-      
-      for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
-        _mesa_ActiveTextureARB(GL_TEXTURE0 + i);
-        _mesa_Disable(GL_TEXTURE_1D);
-        _mesa_Disable(GL_TEXTURE_2D);
-        _mesa_Disable(GL_TEXTURE_3D);
-        if (ctx->Extensions.ARB_texture_cube_map)
-           _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB);
-        if (ctx->Extensions.NV_texture_rectangle)
-           _mesa_Disable(GL_TEXTURE_RECTANGLE_NV);
-        if (ctx->Extensions.MESA_texture_array) {
-           _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT);
-           _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT);
-        }
-      }
-   }
-  
-   r100_meta_set_passthrough_transform(rmesa);
-   
-   for (i = 0; i < 4; i++) {
-      color[i][0] = ctx->Color.ClearColor[0];
-      color[i][1] = ctx->Color.ClearColor[1];
-      color[i][2] = ctx->Color.ClearColor[2];
-      color[i][3] = ctx->Color.ClearColor[3];
-   }
-
-   /* convert clear Z from [0,1] to NDC coord in [-1,1] */
-   dst_z = -1.0 + 2.0 * ctx->Depth.Clear;
-   
-   /* Prepare the vertices, which are the same regardless of which buffer we're
-    * drawing to.
-    */
-   vertices[0][0] = fb->_Xmin;
-   vertices[0][1] = fb->_Ymin;
-   vertices[0][2] = dst_z;
-   vertices[1][0] = fb->_Xmax;
-   vertices[1][1] = fb->_Ymin;
-   vertices[1][2] = dst_z;
-   vertices[2][0] = fb->_Xmax;
-   vertices[2][1] = fb->_Ymax;
-   vertices[2][2] = dst_z;
-   vertices[3][0] = fb->_Xmin;
-   vertices[3][1] = fb->_Ymax;
-   vertices[3][2] = dst_z;
-
-   _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &color);
-   _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), &vertices);
-   _mesa_Enable(GL_COLOR_ARRAY);
-   _mesa_Enable(GL_VERTEX_ARRAY);
-
-   while (mask != 0) {
-      GLuint this_mask = 0;
-
-      if (mask & BUFFER_BIT_BACK_LEFT)
-        this_mask = BUFFER_BIT_BACK_LEFT;
-      else if (mask & BUFFER_BIT_FRONT_LEFT)
-        this_mask = BUFFER_BIT_FRONT_LEFT;
-
-      /* Clear depth/stencil in the same pass as color. */
-      this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL));
-
-      /* Select the current color buffer and use the color write mask if
-       * we have one, otherwise don't write any color channels.
-       */
-      if (this_mask & BUFFER_BIT_FRONT_LEFT)
-        _mesa_DrawBuffer(GL_FRONT_LEFT);
-      else if (this_mask & BUFFER_BIT_BACK_LEFT)
-        _mesa_DrawBuffer(GL_BACK_LEFT);
-      else
-        _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-
-      /* Control writing of the depth clear value to depth. */
-      if (this_mask & BUFFER_BIT_DEPTH) {
-        _mesa_DepthFunc(GL_ALWAYS);
-        _mesa_Enable(GL_DEPTH_TEST);
-      } else {
-        _mesa_Disable(GL_DEPTH_TEST);
-        _mesa_DepthMask(GL_FALSE);
-      }
-
-      /* Control writing of the stencil clear value to stencil. */
-      if (this_mask & BUFFER_BIT_STENCIL) {
-        _mesa_Enable(GL_STENCIL_TEST);
-        _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
-        _mesa_StencilFuncSeparate(GL_FRONT, GL_ALWAYS, ctx->Stencil.Clear,
-                                  ctx->Stencil.WriteMask[0]);
-      } else {
-        _mesa_Disable(GL_STENCIL_TEST);
-      }
-
-      CALL_DrawArrays(ctx->Exec, (GL_TRIANGLE_FAN, 0, 4));
-
-      mask &= ~this_mask;
-   }
-
-   r100_meta_restore_transform(rmesa);
-
-   _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture);
-   if (saved_fp_enable)
-      _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB);
-   if (saved_vp_enable)
-      _mesa_Enable(GL_VERTEX_PROGRAM_ARB);
-
-   if (saved_shader_program)
-      _mesa_UseProgramObjectARB(saved_shader_program);
-
-   _mesa_PopClientAttrib();
-   _mesa_PopAttrib();
-}
-
 static void radeonUserClear(GLcontext *ctx, GLuint mask)
 {
    radeon_clear_tris(ctx, mask);
@@ -795,7 +583,7 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask )
       mask &= ~BUFFER_BIT_DEPTH;
    }
 
-   if ( (mask & BUFFER_BIT_STENCIL) && rmesa->radeon.state.stencil.hwBuffer ) {
+   if ( (mask & BUFFER_BIT_STENCIL) ) {
       flags |= RADEON_STENCIL;
       mask &= ~BUFFER_BIT_STENCIL;
    }
@@ -813,8 +601,7 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask )
       flags |= RADEON_USE_COMP_ZBUF;
 /*      if (rmesa->radeon.radeonScreen->chipset & RADEON_CHIPSET_TCL) 
          flags |= RADEON_USE_HIERZ; */
-      if (!(rmesa->radeon.state.stencil.hwBuffer) ||
-        ((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) &&
+      if (((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) &&
            ((rmesa->radeon.state.stencil.clear & RADEON_STENCIL_WRITE_MASK) == RADEON_STENCIL_WRITE_MASK))) {
          flags |= RADEON_CLEAR_FASTZ;
       }
index a14a0c3..4725f38 100644 (file)
@@ -1086,6 +1086,9 @@ radeonCreateScreen2(__DRIscreenPrivate *sPriv)
    else
       screen->chip_flags |= RADEON_CLASS_R300;
 
+   if (getenv("R300_NO_TCL"))
+     screen->chip_flags &= ~RADEON_CHIPSET_TCL;
+
    i = 0;
    screen->extensions[i++] = &driCopySubBufferExtension.base;
    screen->extensions[i++] = &driFrameTrackingExtension.base;
@@ -1197,7 +1200,6 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
     const GLboolean swStencil = mesaVis->stencilBits > 0 &&
        mesaVis->depthBits != 24;
     GLenum rgbFormat = (mesaVis->redBits == 5 ? GL_RGB5 : GL_RGBA8);
-    GLenum depthFormat = GL_NONE;
     struct radeon_framebuffer *rfb;
 
     if (isPixmap)
@@ -1209,37 +1211,35 @@ radeonCreateBuffer( __DRIscreenPrivate *driScrnPriv,
 
     _mesa_initialize_framebuffer(&rfb->base, mesaVis);
 
-    if (mesaVis->depthBits == 16)
-       depthFormat = GL_DEPTH_COMPONENT16;
-    else if (mesaVis->depthBits == 24)
-       depthFormat = GL_DEPTH_COMPONENT24;
-
     /* front color renderbuffer */
-    rfb->color_rb[0] = radeon_renderbuffer(radeon_create_renderbuffer(rgbFormat, driDrawPriv));
+    rfb->color_rb[0] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
     _mesa_add_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT, &rfb->color_rb[0]->base);
     rfb->color_rb[0]->has_surface = 1;
 
     /* back color renderbuffer */
     if (mesaVis->doubleBufferMode) {
-      rfb->color_rb[1] = radeon_renderbuffer(radeon_create_renderbuffer(rgbFormat, driDrawPriv));
+      rfb->color_rb[1] = radeon_create_renderbuffer(rgbFormat, driDrawPriv);
        _mesa_add_renderbuffer(&rfb->base, BUFFER_BACK_LEFT, &rfb->color_rb[1]->base);
        rfb->color_rb[1]->has_surface = 1;
     }
 
-    /* depth renderbuffer */
-    if (depthFormat != GL_NONE) {
-      struct radeon_renderbuffer *depth = radeon_renderbuffer(
-                                                             radeon_create_renderbuffer(depthFormat, driDrawPriv));
+    if (mesaVis->depthBits == 24) {
+      if (mesaVis->stencilBits == 8) {
+       struct radeon_renderbuffer *depthStencilRb = radeon_create_renderbuffer(GL_DEPTH24_STENCIL8_EXT, driDrawPriv);
+       _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depthStencilRb->base);
+       _mesa_add_renderbuffer(&rfb->base, BUFFER_STENCIL, &depthStencilRb->base);
+       depthStencilRb->has_surface = screen->depthHasSurface;
+      } else {
+       /* depth renderbuffer */
+       struct radeon_renderbuffer *depth = radeon_create_renderbuffer(GL_DEPTH_COMPONENT24, driDrawPriv);
+       _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base);
+       depth->has_surface = screen->depthHasSurface;
+      }
+    } else if (mesaVis->depthBits == 16) {
+      /* just 16-bit depth buffer, no hw stencil */
+       struct radeon_renderbuffer *depth = radeon_create_renderbuffer(GL_DEPTH_COMPONENT16, driDrawPriv);
        _mesa_add_renderbuffer(&rfb->base, BUFFER_DEPTH, &depth->base);
        depth->has_surface = screen->depthHasSurface;
-    }
-
-    /* stencil renderbuffer */
-    if (mesaVis->stencilBits > 0 && !swStencil) {
-      struct radeon_renderbuffer *stencil = radeon_renderbuffer(
-                                                               radeon_create_renderbuffer(GL_STENCIL_INDEX8_EXT, driDrawPriv));
-       _mesa_add_renderbuffer(&rfb->base, BUFFER_STENCIL, &stencil->base);
-       stencil->has_surface = screen->depthHasSurface;
     }
 
     _mesa_add_soft_renderbuffers(&rfb->base,
index 768a51b..3d2c5da 100644 (file)
@@ -377,33 +377,64 @@ do {                                                                      \
 #include "stenciltmp.h"
 
 
-static void map_buffer(struct gl_renderbuffer *rb, GLboolean write)
+void map_unmap_rb(struct gl_renderbuffer *rb, int flag)
 {
-       struct radeon_renderbuffer *rrb = (void*)rb;
+       struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
        int r;
        
-       if (rrb->bo) {
-               r = radeon_bo_map(rrb->bo, write);
+       if (rrb == NULL || !rrb->bo)
+               return;
+
+       if (flag) {
+               r = radeon_bo_map(rrb->bo, 1);
                if (r) {
                        fprintf(stderr, "(%s) error(%d) mapping buffer.\n",
                                __FUNCTION__, r);
                }
-       }
 
-       radeonSetSpanFunctions(rrb);
+               radeonSetSpanFunctions(rrb);
+       } else {
+               radeon_bo_unmap(rrb->bo);
+               rb->GetRow = NULL;
+               rb->PutRow = NULL;
+       }
 }
 
-static void unmap_buffer(struct gl_renderbuffer *rb)
+static void
+radeon_map_unmap_buffers(GLcontext *ctx, GLboolean map)
 {
-       struct radeon_renderbuffer *rrb = (void*)rb;
+       radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+       GLuint i, j;
 
-       if (rrb->bo) {
-               radeon_bo_unmap(rrb->bo);
+       /* color draw buffers */
+       for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers; j++)
+               map_unmap_rb(ctx->DrawBuffer->_ColorDrawBuffers[j], map);
+
+       /* check for render to textures */
+       for (i = 0; i < BUFFER_COUNT; i++) {
+               struct gl_renderbuffer_attachment *att =
+                       ctx->DrawBuffer->Attachment + i;
+               struct gl_texture_object *tex = att->Texture;
+               if (tex) {
+                       /* render to texture */
+                       ASSERT(att->Renderbuffer);
+                       if (map)
+                               ctx->Driver.MapTexture(ctx, tex);
+                       else
+                               ctx->Driver.UnmapTexture(ctx, tex);
+               }
        }
-       rb->GetRow = NULL;
-       rb->PutRow = NULL;
-}
+       
+       map_unmap_rb(ctx->ReadBuffer->_ColorReadBuffer, map);
+
+       /* depth buffer (Note wrapper!) */
+       if (ctx->DrawBuffer->_DepthBuffer)
+               map_unmap_rb(ctx->DrawBuffer->_DepthBuffer->Wrapped, map);
+       
+       if (ctx->DrawBuffer->_StencilBuffer)
+               map_unmap_rb(ctx->DrawBuffer->_StencilBuffer->Wrapped, map);
 
+}
 static void radeonSpanRenderStart(GLcontext * ctx)
 {
        radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
@@ -416,18 +447,7 @@ static void radeonSpanRenderStart(GLcontext * ctx)
                        ctx->Driver.MapTexture(ctx, ctx->Texture.Unit[i]._Current);
        }
 
-       /* color draw buffers */
-       for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
-               map_buffer(ctx->DrawBuffer->_ColorDrawBuffers[i], GL_TRUE);
-       }
-
-       map_buffer(ctx->ReadBuffer->_ColorReadBuffer, GL_FALSE);
-
-       if (ctx->DrawBuffer->_DepthBuffer) {
-               map_buffer(ctx->DrawBuffer->_DepthBuffer->Wrapped, GL_TRUE);
-       }
-       if (ctx->DrawBuffer->_StencilBuffer)
-               map_buffer(ctx->DrawBuffer->_StencilBuffer->Wrapped, GL_TRUE);
+       radeon_map_unmap_buffers(ctx, 1);
 
        /* The locking and wait for idle should really only be needed in classic mode.
         * In a future memory manager based implementation, this should become
@@ -450,16 +470,7 @@ static void radeonSpanRenderFinish(GLcontext * ctx)
                        ctx->Driver.UnmapTexture(ctx, ctx->Texture.Unit[i]._Current);
        }
 
-       /* color draw buffers */
-       for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++)
-               unmap_buffer(ctx->DrawBuffer->_ColorDrawBuffers[i]);
-
-       unmap_buffer(ctx->ReadBuffer->_ColorReadBuffer);
-
-       if (ctx->DrawBuffer->_DepthBuffer)
-               unmap_buffer(ctx->DrawBuffer->_DepthBuffer->Wrapped);
-       if (ctx->DrawBuffer->_StencilBuffer)
-               unmap_buffer(ctx->DrawBuffer->_StencilBuffer->Wrapped);
+       radeon_map_unmap_buffers(ctx, 0);
 }
 
 void radeonInitSpanFuncs(GLcontext * ctx)
@@ -485,6 +496,8 @@ static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb)
                radeonInitDepthPointers_z16(&rrb->base);
        } else if (rrb->base._ActualFormat == GL_DEPTH_COMPONENT24) {
                radeonInitDepthPointers_z24_s8(&rrb->base);
+       } else if (rrb->base._ActualFormat == GL_DEPTH24_STENCIL8_EXT) {
+               radeonInitStencilPointers_z24_s8(&rrb->base);
        } else if (rrb->base._ActualFormat == GL_STENCIL_INDEX8_EXT) {
                radeonInitStencilPointers_z24_s8(&rrb->base);
        }
index 635fe43..19ff268 100644 (file)
@@ -528,7 +528,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 );
@@ -1391,6 +1392,7 @@ void radeonUpdateWindow( GLcontext *ctx )
    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) {
@@ -1405,8 +1407,8 @@ void radeonUpdateWindow( GLcontext *ctx )
    float_ui32_type tx = { v[MAT_TX] + xoffset + SUBPIXEL_X };
    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] * rmesa->radeon.state.depth.scale };
-   float_ui32_type tz = { v[MAT_TZ] * rmesa->radeon.state.depth.scale };
+   float_ui32_type sz = { v[MAT_SZ] * depthScale };
+   float_ui32_type tz = { v[MAT_TZ] * depthScale };
 
    RADEON_STATECHANGE( rmesa, vpt );
 
@@ -1800,15 +1802,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;
 
index 8b6caf1..3d0cd8d 100644 (file)
@@ -592,22 +592,16 @@ void radeonInitState( r100ContextPtr rmesa )
    switch ( ctx->Visual.depthBits ) {
    case 16:
       rmesa->radeon.state.depth.clear = 0x0000ffff;
-      rmesa->radeon.state.depth.scale = 1.0 / (GLfloat)0xffff;
       rmesa->radeon.state.stencil.clear = 0x00000000;
       break;
    case 24:
       rmesa->radeon.state.depth.clear = 0x00ffffff;
-      rmesa->radeon.state.depth.scale = 1.0 / (GLfloat)0xffffff;
       rmesa->radeon.state.stencil.clear = 0xffff0000;
       break;
    default:
       break;
    }
 
-   /* Only have hw stencil when depth buffer is 24 bits deep */
-   rmesa->radeon.state.stencil.hwBuffer = ( ctx->Visual.stencilBits > 0 &&
-                                    ctx->Visual.depthBits == 24 );
-
    rmesa->radeon.Fallback = 0;