gallium: fix refcount bug introduced in eb20e2984
[mesa.git] / src / mesa / drivers / dri / i915 / intel_ioctl.c
index 2fa88b52014500a663a9691d617287e2950bd5a1..aa7c6d106ceb4b70b742946147dd15fe05c75d30 100644 (file)
@@ -3,12 +3,33 @@
  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
  * All Rights Reserved.
  * 
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
  **************************************************************************/
 
 
 #include <stdio.h>
 #include <unistd.h>
 #include <errno.h>
+#include <sched.h>
 
 #include "mtypes.h"
 #include "context.h"
 #include "intel_batchbuffer.h"
 #include "drm.h"
 
+uint32_t intelGetLastFrame (intelContextPtr intel) 
+{
+   int ret;
+   uint32_t frame;
+   drm_i915_getparam_t gp;
+   
+   gp.param = I915_PARAM_LAST_DISPATCH;
+   gp.value = (int *)&frame;
+   ret = drmCommandWriteRead( intel->driFd, DRM_I915_GETPARAM,
+                             &gp, sizeof(gp) );
+   return frame;
+}
 
-
-static int intelEmitIrqLocked( intelContextPtr intel )
+int intelEmitIrqLocked( intelContextPtr intel )
 {
    drmI830IrqEmit ie;
    int ret, seq;
@@ -44,18 +76,17 @@ static int intelEmitIrqLocked( intelContextPtr intel )
    return seq;
 }
 
-static void intelWaitIrq( intelContextPtr intel, int seq )
+void intelWaitIrq( intelContextPtr intel, int seq )
 {
-   drmI830IrqWait iw;
    int ret;
       
    if (0)
       fprintf(stderr, "%s %d\n", __FUNCTION__, seq );
 
-   iw.irq_seq = seq;
+   intel->iw.irq_seq = seq;
         
    do {
-      ret = drmCommandWrite( intel->driFd, DRM_I830_IRQ_WAIT, &iw, sizeof(iw) );
+     ret = drmCommandWrite( intel->driFd, DRM_I830_IRQ_WAIT, &intel->iw, sizeof(intel->iw) );
    } while (ret == -EAGAIN || ret == -EINTR);
 
    if ( ret ) {
@@ -87,7 +118,7 @@ void intel_dump_batchbuffer( long offset,
    fprintf(stderr, "\n\n\nSTART BATCH (%d dwords):\n", count);
    for (i = 0; i < count/4; i += 4) 
       fprintf(stderr, "\t0x%x: 0x%08x 0x%08x 0x%08x 0x%08x\n", 
-             offset + i*4, ptr[i], ptr[i+1], ptr[i+2], ptr[i+3]);
+             (unsigned int)offset + i*4, ptr[i], ptr[i+1], ptr[i+2], ptr[i+3]);
    fprintf(stderr, "END BATCH\n\n\n");
 }
 
@@ -109,7 +140,7 @@ void intelRefillBatchLocked( intelContextPtr intel, GLboolean allow_unlock )
       fprintf(stderr, "%s: now using half %d\n", __FUNCTION__, buf);
 
    intel->batch.start_offset = intel->alloc.offset + buf * half;
-   intel->batch.ptr = (char *)intel->alloc.ptr + buf * half;
+   intel->batch.ptr = (unsigned char *)intel->alloc.ptr + buf * half;
    intel->batch.size = half - 8;
    intel->batch.space = half - 8;
    assert(intel->batch.space >= 0);
@@ -128,21 +159,21 @@ void intelFlushBatchLocked( intelContextPtr intel,
    assert(intel->locked);
 
    if (0)
-      fprintf(stderr, "%s used %d of %d offset %x..%x refill %d\n",
+      fprintf(stderr, "%s used %d of %d offset %x..%x refill %d (started in %s)\n",
              __FUNCTION__, 
              (intel->batch.size - intel->batch.space), 
              intel->batch.size,
              intel->batch.start_offset,
              intel->batch.start_offset + 
              (intel->batch.size - intel->batch.space), 
-             refill);
+             refill,
+             intel->batch.func);
 
    /* Throw away non-effective packets.  Won't work once we have
     * hardware contexts which would preserve statechanges beyond a
     * single buffer.
     */
    if (intel->numClipRects == 0 && !ignore_cliprects) {
-      intel->batch.space = intel->batch.size;
       
       /* Without this yeild, an application with no cliprects can hog
        * the hardware.  Without unlocking, the effect is much worse -
@@ -157,10 +188,18 @@ void intelFlushBatchLocked( intelContextPtr intel,
       /* Note that any state thought to have been emitted actually
        * hasn't:
        */
+      intel->batch.ptr -= (intel->batch.size - intel->batch.space);
+      intel->batch.space = intel->batch.size;
       intel->vtbl.lost_hardware( intel ); 
    }
 
    if (intel->batch.space != intel->batch.size) {
+
+      if (intel->sarea->ctxOwner != intel->hHWContext) {
+        intel->perf_boxes |= I830_BOX_LOST_CONTEXT;
+        intel->sarea->ctxOwner = intel->hHWContext;
+      }
+
       batch.start = intel->batch.start_offset;
       batch.used = intel->batch.size - intel->batch.space;
       batch.cliprects = intel->pClipRects;
@@ -188,13 +227,6 @@ void intelFlushBatchLocked( intelContextPtr intel,
                                 (int *)(intel->batch.ptr - batch.used),
                                 batch.used );
 
-      if (0)
-        fprintf(stderr, "%s: 0x%x..0x%x DR4: %x cliprects: %d\n",
-                __FUNCTION__, 
-                batch.start, 
-                batch.start + batch.used,
-                batch.DR4, batch.num_cliprects);
-
       intel->batch.start_offset += batch.used;
       intel->batch.size -= batch.used;
 
@@ -225,7 +257,7 @@ void intelFlushBatchLocked( intelContextPtr intel,
         }
       } else {
         drmI830CmdBuffer cmd;
-        cmd.buf = intel->alloc.ptr + batch.start;
+        cmd.buf = (char *)intel->alloc.ptr + batch.start;
         cmd.sz = batch.used;
         cmd.DR1 = batch.DR1;
         cmd.DR4 = batch.DR4;
@@ -246,6 +278,12 @@ void intelFlushBatchLocked( intelContextPtr intel,
       /* FIXME: use hardware contexts to avoid 'losing' hardware after
        * each buffer flush.
        */
+      if (intel->batch.contains_geometry) 
+        assert(intel->batch.last_emit_state == intel->batch.counter);
+
+      intel->batch.counter++;
+      intel->batch.contains_geometry = 0;
+      intel->batch.func = 0;
       intel->vtbl.lost_hardware( intel );
    }
 
@@ -266,11 +304,6 @@ void intelFlushBatch( intelContextPtr intel, GLboolean refill )
 }
 
 
-
-
-
-
-
 void intelWaitForIdle( intelContextPtr intel )
 {   
    if (0)
@@ -287,7 +320,28 @@ void intelWaitForIdle( intelContextPtr intel )
 }
 
 
+/**
+ * Check if we need to rotate/warp the front color buffer to the
+ * rotated screen.  We generally need to do this when we get a glFlush
+ * or glFinish after drawing to the front color buffer.
+ */
+static void
+intelCheckFrontRotate(GLcontext *ctx)
+{
+   intelContextPtr intel = INTEL_CONTEXT( ctx );
+   if (intel->ctx.DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT) {
+      intelScreenPrivate *screen = intel->intelScreen;
+      if (screen->current_rotation != 0) {
+         __DRIdrawablePrivate *dPriv = intel->driDrawable;
+         intelRotateWindow(intel, dPriv, BUFFER_BIT_FRONT_LEFT);
+      }
+   }
+}
+
 
+/**
+ * NOT directly called via glFlush.
+ */
 void intelFlush( GLcontext *ctx )
 {
    intelContextPtr intel = INTEL_CONTEXT( ctx );
@@ -301,16 +355,27 @@ void intelFlush( GLcontext *ctx )
       intelFlushBatch( intel, GL_FALSE );
 }
 
+
+/**
+ * Called via glFlush.
+ */
+void intelglFlush( GLcontext *ctx )
+{
+   intelFlush(ctx);
+   intelCheckFrontRotate(ctx);
+}
+
+
 void intelFinish( GLcontext *ctx  ) 
 {
    intelContextPtr intel = INTEL_CONTEXT( ctx );
    intelFlush( ctx );
    intelWaitForIdle( intel );
+   intelCheckFrontRotate(ctx);
 }
 
 
-void intelClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
-               GLint cx, GLint cy, GLint cw, GLint ch)
+void intelClear(GLcontext *ctx, GLbitfield mask)
 {
    intelContextPtr intel = INTEL_CONTEXT( ctx );
    const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
@@ -326,53 +391,62 @@ void intelClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
     */
    intelFlush( &intel->ctx );
 
-   if (mask & DD_FRONT_LEFT_BIT) {
+   if (mask & BUFFER_BIT_FRONT_LEFT) {
       if (colorMask == ~0) {
-        blit_mask |= DD_FRONT_LEFT_BIT;
+        blit_mask |= BUFFER_BIT_FRONT_LEFT;
       } 
       else {
-        tri_mask |= DD_FRONT_LEFT_BIT;
+        tri_mask |= BUFFER_BIT_FRONT_LEFT;
       }
    }
 
-   if (mask & DD_BACK_LEFT_BIT) {
+   if (mask & BUFFER_BIT_BACK_LEFT) {
       if (colorMask == ~0) {
-        blit_mask |= DD_BACK_LEFT_BIT;
+        blit_mask |= BUFFER_BIT_BACK_LEFT;
       } 
       else {
-        tri_mask |= DD_BACK_LEFT_BIT;
+        tri_mask |= BUFFER_BIT_BACK_LEFT;
       }
    }
 
-   if (mask & DD_DEPTH_BIT) {
-      blit_mask |= DD_DEPTH_BIT;
+   if (mask & BUFFER_BIT_DEPTH) {
+      blit_mask |= BUFFER_BIT_DEPTH;
    }
 
-   if (mask & DD_STENCIL_BIT) {
+   if (mask & BUFFER_BIT_STENCIL) {
       if (!intel->hw_stencil) {
-        swrast_mask |= DD_STENCIL_BIT;
+        swrast_mask |= BUFFER_BIT_STENCIL;
       }
-      else if (ctx->Stencil.WriteMask[0] != 0xff) {
-        tri_mask |= DD_STENCIL_BIT;
+      else if ((ctx->Stencil.WriteMask[0] & 0xff) != 0xff) {
+        tri_mask |= BUFFER_BIT_STENCIL;
       } 
       else {
-        blit_mask |= DD_STENCIL_BIT;
+        blit_mask |= BUFFER_BIT_STENCIL;
       }
    }
 
-   swrast_mask |= (mask & DD_ACCUM_BIT);
+   swrast_mask |= (mask & BUFFER_BIT_ACCUM);
 
    if (blit_mask) 
-      intelClearWithBlit( ctx, blit_mask, all, cx, cy, cw, ch );
+      intelClearWithBlit( ctx, blit_mask, 0, 0, 0, 0, 0);
 
    if (tri_mask) 
-      intel->vtbl.clear_with_tris( intel, tri_mask, all, cx, cy, cw, ch);
+      intel->vtbl.clear_with_tris( intel, tri_mask, 0, 0, 0, 0, 0);
 
    if (swrast_mask)
-      _swrast_Clear( ctx, swrast_mask, all, cx, cy, cw, ch );
+      _swrast_Clear( ctx, swrast_mask );
 }
 
 
+void
+intelRotateWindow(intelContextPtr intel, __DRIdrawablePrivate *dPriv,
+                  GLuint srcBuffer)
+{
+   if (intel->vtbl.rotate_window) {
+      intel->vtbl.rotate_window(intel, dPriv, srcBuffer);
+   }
+}
+
 
 void *intelAllocateAGP( intelContextPtr intel, GLsizei size )
 {
@@ -536,7 +610,7 @@ GLuint intelAgpOffsetFromVirtual( intelContextPtr intel, const GLvoid *pointer )
    if (offset < 0 || offset > intel->intelScreen->tex.size)
       return ~0;
    else
-      return intel->intelScreen->textureOffset + offset;
+      return intel->intelScreen->tex.offset + offset;
 }