Merge commit 'origin/gallium-0.1' into gallium-0.2
[mesa.git] / src / mesa / drivers / dri / r300 / radeon_ioctl.c
index af489e2a8429763db2fcd5802664055143494341..36502eb42de9882c576d65e225974d9b6b107d14 100644 (file)
@@ -35,22 +35,18 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <sched.h>
 #include <errno.h>
 
-#include "glheader.h"
-#include "imports.h"
-#include "macros.h"
-#include "context.h"
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "main/macros.h"
+#include "main/context.h"
 #include "swrast/swrast.h"
-#include "r200_context.h"
 #include "r300_context.h"
-#include "r200_state.h"
 #include "radeon_ioctl.h"
-#include "r200_ioctl.h"
 #include "r300_ioctl.h"
-#include "r200_tcl.h"
-#include "r200_sanity.h"
 #include "r300_state.h"
 #include "radeon_reg.h"
 
+#include "drirenderbuffer.h"
 #include "vblank.h"
 
 static void radeonWaitForIdle(radeonContextPtr radeon);
@@ -78,6 +74,25 @@ static uint32_t radeonGetLastFrame(radeonContextPtr radeon)
        return frame;
 }
 
+uint32_t radeonGetAge(radeonContextPtr radeon)
+{
+       drm_radeon_getparam_t gp;
+       int ret;
+       uint32_t age;
+
+       gp.param = RADEON_PARAM_LAST_CLEAR;
+       gp.value = (int *)&age;
+       ret = drmCommandWriteRead(radeon->dri.fd, DRM_RADEON_GETPARAM,
+                                 &gp, sizeof(gp));
+       if (ret) {
+               fprintf(stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__,
+                       ret);
+               exit(1);
+       }
+
+       return age;
+}
+
 static void radeonEmitIrqLocked(radeonContextPtr radeon)
 {
        drm_radeon_irq_emit_t ie;
@@ -100,7 +115,7 @@ static void radeonWaitIrq(radeonContextPtr radeon)
        do {
                ret = drmCommandWrite(radeon->dri.fd, DRM_RADEON_IRQ_WAIT,
                                      &radeon->iw, sizeof(radeon->iw));
-       } while (ret && (errno == EINTR || errno == EAGAIN));
+       } while (ret && (errno == EINTR || errno == EBUSY));
 
        if (ret) {
                fprintf(stderr, "%s: drmRadeonIrqWait: %d\n", __FUNCTION__,
@@ -142,12 +157,14 @@ static void radeonWaitForFrameCompletion(radeonContextPtr radeon)
 
 /* Copy the back color buffer to the front color buffer.
  */
-void radeonCopyBuffer(const __DRIdrawablePrivate * dPriv)
+void radeonCopyBuffer(__DRIdrawablePrivate * dPriv,
+                     const drm_clip_rect_t      * rect)
 {
        radeonContextPtr radeon;
        GLint nbox, i, ret;
        GLboolean missed_target;
        int64_t ust;
+       __DRIscreenPrivate *psp = dPriv->driScreenPriv;
 
        assert(dPriv);
        assert(dPriv->driContextPriv);
@@ -160,10 +177,7 @@ void radeonCopyBuffer(const __DRIdrawablePrivate * dPriv)
                        (void *)radeon->glCtx);
        }
 
-       if (IS_FAMILY_R200(radeon))
-               R200_FIREVERTICES((r200ContextPtr)radeon);
-       else
-               r300Flush(radeon->glCtx);
+       r300Flush(radeon->glCtx);
 
        LOCK_HARDWARE(radeon);
 
@@ -171,10 +185,12 @@ void radeonCopyBuffer(const __DRIdrawablePrivate * dPriv)
         * request at a time.
         */
        radeonWaitForFrameCompletion(radeon);
-       UNLOCK_HARDWARE(radeon);
-       driWaitForVBlank(dPriv, &radeon->vbl_seq, radeon->vblank_flags,
-                        &missed_target);
-       LOCK_HARDWARE(radeon);
+       if (!rect)
+       {
+           UNLOCK_HARDWARE(radeon);
+           driWaitForVBlank(dPriv, &missed_target);
+           LOCK_HARDWARE(radeon);
+       }
 
        nbox = dPriv->numClipRects;     /* must be in locked region */
 
@@ -184,12 +200,33 @@ void radeonCopyBuffer(const __DRIdrawablePrivate * dPriv)
                drm_clip_rect_t *b = radeon->sarea->boxes;
                GLint n = 0;
 
-               for (; i < nr; i++) {
-                       *b++ = box[i];
-                       n++;
+               for ( ; i < nr ; i++ ) {
+
+                   *b = box[i];
+
+                   if (rect)
+                   {
+                       if (rect->x1 > b->x1)
+                           b->x1 = rect->x1;
+                       if (rect->y1 > b->y1)
+                           b->y1 = rect->y1;
+                       if (rect->x2 < b->x2)
+                           b->x2 = rect->x2;
+                       if (rect->y2 < b->y2)
+                           b->y2 = rect->y2;
+
+                       if (b->x1 >= b->x2 || b->y1 >= b->y2)
+                           continue;
+                   }
+
+                   b++;
+                   n++;
                }
                radeon->sarea->nbox = n;
 
+               if (!n)
+                  continue;
+
                ret = drmCommandNone(radeon->dri.fd, DRM_RADEON_SWAP);
 
                if (ret) {
@@ -201,29 +238,29 @@ void radeonCopyBuffer(const __DRIdrawablePrivate * dPriv)
        }
 
        UNLOCK_HARDWARE(radeon);
+       if (!rect)
+       {
+           ((r300ContextPtr)radeon)->hw.all_dirty = GL_TRUE;
 
-       if (IS_FAMILY_R200(radeon))
-               ((r200ContextPtr)radeon)->hw.all_dirty = GL_TRUE;
-       else
-               ((r300ContextPtr)radeon)->hw.all_dirty = GL_TRUE;
-
-       radeon->swap_count++;
-       (*dri_interface->getUST) (&ust);
-       if (missed_target) {
+           radeon->swap_count++;
+           (*psp->systemTime->getUST) (&ust);
+           if (missed_target) {
                radeon->swap_missed_count++;
                radeon->swap_missed_ust = ust - radeon->swap_ust;
-       }
+           }
 
-       radeon->swap_ust = ust;
+           radeon->swap_ust = ust;
 
-       sched_yield();
+           sched_yield();
+       }
 }
 
-void radeonPageFlip(const __DRIdrawablePrivate * dPriv)
+void radeonPageFlip(__DRIdrawablePrivate * dPriv)
 {
        radeonContextPtr radeon;
        GLint ret;
        GLboolean missed_target;
+       __DRIscreenPrivate *psp = dPriv->driScreenPriv;
 
        assert(dPriv);
        assert(dPriv->driContextPriv);
@@ -236,10 +273,7 @@ void radeonPageFlip(const __DRIdrawablePrivate * dPriv)
                        radeon->sarea->pfCurrentPage);
        }
 
-       if (IS_FAMILY_R200(radeon))
-               R200_FIREVERTICES((r200ContextPtr)radeon);
-       else
-               r300Flush(radeon->glCtx);
+       r300Flush(radeon->glCtx);
        LOCK_HARDWARE(radeon);
 
        if (!dPriv->numClipRects) {
@@ -262,11 +296,10 @@ void radeonPageFlip(const __DRIdrawablePrivate * dPriv)
         */
        radeonWaitForFrameCompletion(radeon);
        UNLOCK_HARDWARE(radeon);
-       driWaitForVBlank(dPriv, &radeon->vbl_seq, radeon->vblank_flags,
-                        &missed_target);
+       driWaitForVBlank(dPriv, &missed_target);
        if (missed_target) {
                radeon->swap_missed_count++;
-               (void)(*dri_interface->getUST) (&radeon->swap_missed_ust);
+               (void)(*psp->systemTime->getUST) (&radeon->swap_missed_ust);
        }
        LOCK_HARDWARE(radeon);
 
@@ -280,7 +313,10 @@ void radeonPageFlip(const __DRIdrawablePrivate * dPriv)
        }
 
        radeon->swap_count++;
-       (void)(*dri_interface->getUST) (&radeon->swap_ust);
+       (void)(*psp->systemTime->getUST) (&radeon->swap_ust);
+
+        driFlipRenderbuffers(radeon->glCtx->WinSysDrawBuffer, 
+                             radeon->sarea->pfCurrentPage);
 
        if (radeon->sarea->pfCurrentPage == 1) {
                radeon->state.color.drawOffset = radeon->radeonScreen->frontOffset;
@@ -290,15 +326,7 @@ void radeonPageFlip(const __DRIdrawablePrivate * dPriv)
                radeon->state.color.drawPitch = radeon->radeonScreen->backPitch;
        }
 
-       if (IS_FAMILY_R200(radeon)) {
-               r200ContextPtr r200 = (r200ContextPtr)radeon;
-
-               R200_STATECHANGE(r200, ctx);
-               r200->hw.ctx.cmd[CTX_RB3D_COLOROFFSET] = radeon->state.color.drawOffset
-                       + radeon->radeonScreen->fbLocation;
-               r200->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = radeon->state.color.drawPitch;
-       }
-       if (IS_FAMILY_R300(radeon)) {
+       if (IS_R300_CLASS(radeon->radeonScreen)) {
                r300ContextPtr r300 = (r300ContextPtr)radeon;
                R300_STATECHANGE(r300, cb);
                r300->hw.cb.cmd[R300_CB_OFFSET] = r300->radeon.state.color.drawOffset + 
@@ -328,7 +356,7 @@ void radeonWaitForIdleLocked(radeonContextPtr radeon)
 
        if (ret < 0) {
                UNLOCK_HARDWARE(radeon);
-               fprintf(stderr, "Error: R200 timed out... exiting\n");
+               fprintf(stderr, "Error: R300 timed out... exiting\n");
                exit(-1);
        }
 }
@@ -344,12 +372,8 @@ void radeonFlush(GLcontext * ctx)
 {
        radeonContextPtr radeon = RADEON_CONTEXT(ctx);
 
-       if (IS_FAMILY_R300(radeon))
+       if (IS_R300_CLASS(radeon->radeonScreen))
                r300Flush(ctx);
-#if R200_MERGED
-       else
-               r200Flush(ctx);
-#endif 
 }