Some fixes
[mesa.git] / src / mesa / drivers / dri / r200 / r200_ioctl.c
index edb6079d7e64864984ee21bebfc79a9b8bbae237..ad43158d64afef2e247740d8317597032a5ac39e 100644 (file)
@@ -59,11 +59,41 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 static void r200WaitForIdle( r200ContextPtr rmesa );
 
 
+/* At this point we were in FlushCmdBufLocked but we had lost our context, so
+ * we need to unwire our current cmdbuf, hook the one with the saved state in
+ * it, flush it, and then put the current one back.  This is so commands at the
+ * start of a cmdbuf can rely on the state being kept from the previous one.
+ */
+static void r200BackUpAndEmitLostStateLocked( r200ContextPtr rmesa )
+{
+   GLuint nr_released_bufs;
+   struct r200_store saved_store;
+
+   if (rmesa->backup_store.cmd_used == 0)
+      return;
+
+   if (R200_DEBUG & DEBUG_STATE)
+      fprintf(stderr, "Emitting backup state on lost context\n");
+
+   rmesa->lost_context = GL_FALSE;
+
+   nr_released_bufs = rmesa->dma.nr_released_bufs;
+   saved_store = rmesa->store;
+   rmesa->dma.nr_released_bufs = 0;
+   rmesa->store = rmesa->backup_store;
+   r200FlushCmdBufLocked( rmesa, __FUNCTION__ );
+   rmesa->dma.nr_released_bufs = nr_released_bufs;
+   rmesa->store = saved_store;
+}
+
 int r200FlushCmdBufLocked( r200ContextPtr rmesa, const char * caller )
 {
    int ret, i;
    drm_radeon_cmd_buffer_t cmd;
 
+   if (rmesa->lost_context)
+      r200BackUpAndEmitLostStateLocked( rmesa );
+
    if (R200_DEBUG & DEBUG_IOCTL) {
       fprintf(stderr, "%s from %s\n", __FUNCTION__, caller); 
 
@@ -132,7 +162,8 @@ int r200FlushCmdBufLocked( r200ContextPtr rmesa, const char * caller )
    rmesa->store.statenr = 0;
    rmesa->store.cmd_used = 0;
    rmesa->dma.nr_released_bufs = 0;
-   rmesa->lost_context = 1;    
+   rmesa->save_on_next_emit = 1;
+
    return ret;
 }
 
@@ -257,7 +288,7 @@ void r200ReleaseDmaRegion( r200ContextPtr rmesa,
       rmesa->dma.nr_released_bufs++;
    }
 
-   region->buf = 0;
+   region->buf = NULL;
    region->start = 0;
 }
 
@@ -312,11 +343,11 @@ void r200AllocDmaRegionVerts( r200ContextPtr rmesa,
  * SwapBuffers with client-side throttling
  */
 
-static uint32_t r200GetLastFrame(r200ContextPtr rmesa)
+static u_int32_t r200GetLastFrame(r200ContextPtr rmesa)
 {
    drm_radeon_getparam_t gp;
    int ret;
-   uint32_t frame;
+   u_int32_t frame;
 
    gp.param = RADEON_PARAM_LAST_FRAME;
    gp.value = (int *)&frame;
@@ -452,7 +483,7 @@ void r200CopyBuffer( const __DRIdrawablePrivate *dPriv )
    }
 
    UNLOCK_HARDWARE( rmesa );
-   rmesa->lost_context = 1;
+   rmesa->hw.all_dirty = GL_TRUE;
 
    rmesa->swap_count++;
    (*rmesa->get_ust)( & ust );
@@ -537,6 +568,9 @@ void r200PageFlip( const __DRIdrawablePrivate *dPriv )
    rmesa->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = rmesa->state.color.drawOffset
                                           + rmesa->r200Screen->fbLocation;
    rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH]  = rmesa->state.color.drawPitch;
+   if (rmesa->sarea->tiling_enabled) {
+      rmesa->hw.ctx.cmd[CTX_RB3D_COLORPITCH] |= R200_COLOR_TILE_ENABLE;
+   }
 }
 
 
@@ -564,33 +598,28 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
         return;
    }
 
-   r200EmitState( rmesa );
-
-   /* Need to cope with lostcontext here as kernel relies on
-    * some residual state:
-    */
-   R200_FIREVERTICES( rmesa ); 
+   r200Flush( ctx );
 
-   if ( mask & DD_FRONT_LEFT_BIT ) {
+   if ( mask & BUFFER_BIT_FRONT_LEFT ) {
       flags |= RADEON_FRONT;
       color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
-      mask &= ~DD_FRONT_LEFT_BIT;
+      mask &= ~BUFFER_BIT_FRONT_LEFT;
    }
 
-   if ( mask & DD_BACK_LEFT_BIT ) {
+   if ( mask & BUFFER_BIT_BACK_LEFT ) {
       flags |= RADEON_BACK;
       color_mask = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
-      mask &= ~DD_BACK_LEFT_BIT;
+      mask &= ~BUFFER_BIT_BACK_LEFT;
    }
 
-   if ( mask & DD_DEPTH_BIT ) {
-      if ( ctx->Depth.Mask ) flags |= RADEON_DEPTH; /* FIXME: ??? */
-      mask &= ~DD_DEPTH_BIT;
+   if ( mask & BUFFER_BIT_DEPTH ) {
+      flags |= RADEON_DEPTH;
+      mask &= ~BUFFER_BIT_DEPTH;
    }
 
-   if ( (mask & DD_STENCIL_BIT) && rmesa->state.stencil.hwBuffer ) {
+   if ( (mask & BUFFER_BIT_STENCIL) && rmesa->state.stencil.hwBuffer ) {
       flags |= RADEON_STENCIL;
-      mask &= ~DD_STENCIL_BIT;
+      mask &= ~BUFFER_BIT_STENCIL;
    }
 
    if ( mask ) {
@@ -602,6 +631,17 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
    if ( !flags ) 
       return;
 
+   if (rmesa->using_hyperz) {
+      flags |= RADEON_USE_COMP_ZBUF;
+/*      if (rmesa->r200Screen->chipset & R200_CHIPSET_REAL_R200)
+        flags |= RADEON_USE_HIERZ; */
+      if (!(rmesa->state.stencil.hwBuffer) ||
+        ((flags & RADEON_DEPTH) && (flags & RADEON_STENCIL) &&
+           ((rmesa->state.stencil.clear & R200_STENCIL_WRITE_MASK) == R200_STENCIL_WRITE_MASK))) {
+         flags |= RADEON_CLEAR_FASTZ;
+      }
+   }
+
    /* Flip top to bottom */
    cx += dPriv->x;
    cy  = dPriv->y + dPriv->h - cy - ch;
@@ -638,6 +678,8 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
       }
    }
 
+   /* Send current state to the hardware */
+   r200FlushCmdBufLocked( rmesa, __FUNCTION__ );
 
    for ( i = 0 ; i < dPriv->numClipRects ; ) {
       GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, dPriv->numClipRects );
@@ -679,7 +721,7 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
 
       clear.flags       = flags;
       clear.clear_color = rmesa->state.color.clear;
-      clear.clear_depth = 0;   /* not used */
+      clear.clear_depth = rmesa->state.depth.clear;    /* needed for hyperz */
       clear.color_mask  = rmesa->hw.msk.cmd[MSK_RB3D_PLANEMASK];
       clear.depth_mask  = rmesa->state.stencil.clear;
       clear.depth_boxes = depth_boxes;
@@ -706,7 +748,7 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
    }
 
    UNLOCK_HARDWARE( rmesa );
-   rmesa->lost_context = 1;
+   rmesa->hw.all_dirty = GL_TRUE;
 }
 
 
@@ -747,8 +789,7 @@ void r200Flush( GLcontext *ctx )
    if (rmesa->dma.flush)
       rmesa->dma.flush( rmesa );
 
-   if (!is_empty_list(&rmesa->hw.dirty)) 
-      r200EmitState( rmesa );
+   r200EmitState( rmesa );
    
    if (rmesa->store.cmd_used)
       r200FlushCmdBuf( rmesa, __FUNCTION__ );
@@ -782,7 +823,7 @@ void r200Finish( GLcontext *ctx )
  * the kernel data structures, and the current context to get the
  * device fd.
  */
-void *r200AllocateMemoryMESA(Display *dpy, int scrn, GLsizei size,
+void *r200AllocateMemoryMESA(__DRInativeDisplay *dpy, int scrn, GLsizei size,
                             GLfloat readfreq, GLfloat writefreq, 
                             GLfloat priority)
 {
@@ -827,11 +868,11 @@ void *r200AllocateMemoryMESA(Display *dpy, int scrn, GLsizei size,
 
 
 /* Called via glXFreeMemoryMESA() */
-void r200FreeMemoryMESA(Display *dpy, int scrn, GLvoid *pointer)
+void r200FreeMemoryMESA(__DRInativeDisplay *dpy, int scrn, GLvoid *pointer)
 {
    GET_CURRENT_CONTEXT(ctx);
    r200ContextPtr rmesa;
-   int region_offset;
+   ptrdiff_t region_offset;
    drm_radeon_mem_free_t memfree;
    int ret;
 
@@ -867,7 +908,7 @@ void r200FreeMemoryMESA(Display *dpy, int scrn, GLvoid *pointer)
 }
 
 /* Called via glXGetMemoryOffsetMESA() */
-GLuint r200GetMemoryOffsetMESA(Display *dpy, int scrn, const GLvoid *pointer)
+GLuint r200GetMemoryOffsetMESA(__DRInativeDisplay *dpy, int scrn, const GLvoid *pointer)
 {
    GET_CURRENT_CONTEXT(ctx);
    r200ContextPtr rmesa;
@@ -889,11 +930,10 @@ GLuint r200GetMemoryOffsetMESA(Display *dpy, int scrn, const GLvoid *pointer)
    return card_offset - rmesa->r200Screen->gart_base;
 }
 
-
 GLboolean r200IsGartMemory( r200ContextPtr rmesa, const GLvoid *pointer,
                           GLint size )
 {
-   int offset = (char *)pointer - (char *)rmesa->r200Screen->gartTextures.map;
+   ptrdiff_t offset = (char *)pointer - (char *)rmesa->r200Screen->gartTextures.map;
    int valid = (size >= 0 &&
                offset >= 0 &&
                offset + size < rmesa->r200Screen->gartTextures.size);
@@ -907,7 +947,7 @@ GLboolean r200IsGartMemory( r200ContextPtr rmesa, const GLvoid *pointer,
 
 GLuint r200GartOffsetFromVirtual( r200ContextPtr rmesa, const GLvoid *pointer )
 {
-   int offset = (char *)pointer - (char *)rmesa->r200Screen->gartTextures.map;
+   ptrdiff_t offset = (char *)pointer - (char *)rmesa->r200Screen->gartTextures.map;
 
    if (offset < 0 || offset > rmesa->r200Screen->gartTextures.size)
       return ~0;