- FIX: flickering
authorNicolai Haehnle <prefect_@gmx.net>
Sun, 17 Oct 2004 20:26:06 +0000 (20:26 +0000)
committerNicolai Haehnle <prefect_@gmx.net>
Sun, 17 Oct 2004 20:26:06 +0000 (20:26 +0000)
- Scissor support works now

12 files changed:
src/mesa/drivers/dri/r300/r200_context.h
src/mesa/drivers/dri/r300/r200_state.h
src/mesa/drivers/dri/r300/r300_cmdbuf.c
src/mesa/drivers/dri/r300/r300_context.c
src/mesa/drivers/dri/r300/r300_state.c
src/mesa/drivers/dri/r300/r300_state.h
src/mesa/drivers/dri/r300/radeon_context.c
src/mesa/drivers/dri/r300/radeon_context.h
src/mesa/drivers/dri/r300/radeon_lock.c
src/mesa/drivers/dri/r300/radeon_span.c
src/mesa/drivers/dri/r300/radeon_state.c
src/mesa/drivers/dri/r300/radeon_state.h

index b5ba1f9..bc4ac00 100644 (file)
@@ -80,15 +80,6 @@ struct r200_depthbuffer_state {
        GLfloat scale;
 };
 
-struct r200_scissor_state {
-       drm_clip_rect_t rect;
-       GLboolean enabled;
-
-       GLuint numClipRects;    /* Cliprects active */
-       GLuint numAllocedClipRects;     /* Cliprects available */
-       drm_clip_rect_t *pClipRects;
-};
-
 struct r200_stencilbuffer_state {
        GLboolean hwBuffer;
        GLuint clear;           /* rb3d_stencilrefmask value */
@@ -502,7 +493,6 @@ struct r200_state {
         */
        struct r200_colorbuffer_state color;
        struct r200_depthbuffer_state depth;
-       struct r200_scissor_state scissor;
        struct r200_stencilbuffer_state stencil;
        struct r200_stipple_state stipple;
        struct r200_texture_state texture;
index cba8e49..3e1a9c8 100644 (file)
@@ -45,7 +45,6 @@ extern void r200InitTnlFuncs(GLcontext * ctx);
 
 extern void r200UpdateMaterial(GLcontext * ctx);
 
-extern void r200RecalcScissorRects(r200ContextPtr rmesa);
 extern void r200UpdateViewportOffset(GLcontext * ctx);
 extern void r200UpdateWindow(GLcontext * ctx);
 
index 7d124d7..7c68f33 100644 (file)
@@ -80,17 +80,13 @@ int r300FlushCmdBuf(r300ContextPtr r300, const char* caller)
        cmd.buf = (char*)(r300->cmdbuf.cmd_buf + start);
        cmd.bufsz = (r300->cmdbuf.count_used - start) * 4;
 
-#if 0 // TODO: scissors
-       if (rmesa->state.scissor.enabled) {
-               cmd.nbox = rmesa->state.scissor.numClipRects;
-               cmd.boxes = (drm_clip_rect_t *) rmesa->state.scissor.pClipRects;
+       if (r300->radeon.state.scissor.enabled) {
+               cmd.nbox = r300->radeon.state.scissor.numClipRects;
+               cmd.boxes = (drm_clip_rect_t *)r300->radeon.state.scissor.pClipRects;
        } else {
-#endif
                cmd.nbox = r300->radeon.numClipRects;
-               cmd.boxes = (drm_clip_rect_t *) r300->radeon.pClipRects;
-#if 0
+               cmd.boxes = (drm_clip_rect_t *)r300->radeon.pClipRects;
        }
-#endif
 
        if (cmd.nbox) {
                ret = drmCommandWrite(r300->radeon.dri.fd,
index 271ea17..6e98bd1 100644 (file)
@@ -156,7 +156,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
        assert(screen);
 
        /* Allocate the R300 context */
-       r300 = (r300ContextPtr) CALLOC(sizeof(*r300));
+       r300 = (r300ContextPtr)CALLOC(sizeof(*r300));
        if (!r300)
                return GL_FALSE;
 
@@ -172,7 +172,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
         */
        _mesa_init_driver_functions(&functions);
        r300InitIoctlFuncs(&functions);
-       //r200InitStateFuncs(&functions);
+       r300InitStateFuncs(&functions);
        //r200InitTextureFuncs(&functions);
 
        if (!radeonInitContext(&r300->radeon, &functions,
@@ -296,9 +296,7 @@ void r300DestroyContext(__DRIcontextPrivate * driContextPriv)
 
                r300DestroyCmdBuf(r300);
 
-               /* free the Mesa context */
-               r300->radeon.glCtx->DriverCtx = NULL;
-               _mesa_destroy_context(r300->radeon.glCtx);
+               radeonCleanupContext(&r300->radeon);
 
                /* free the option cache */
                driDestroyOptionCache(&r300->radeon.optionCache);
index 43cfe2b..9c5138c 100644 (file)
@@ -37,6 +37,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "glheader.h"
 #include "state.h"
 #include "imports.h"
+#include "enums.h"
 #include "macros.h"
 #include "context.h"
 #include "dd.h"
@@ -49,6 +50,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "tnl/tnl.h"
 
 #include "radeon_ioctl.h"
+#include "radeon_state.h"
 #include "r300_context.h"
 #include "r300_ioctl.h"
 #include "r300_state.h"
@@ -57,6 +59,24 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 
 /**
+ * Handle glEnable()/glDisable().
+ */
+static void r300Enable(GLcontext* ctx, GLenum cap, GLboolean state)
+{
+       if (RADEON_DEBUG & DEBUG_STATE)
+               fprintf(stderr, "%s( %s = %s )\n", __FUNCTION__,
+                       _mesa_lookup_enum_by_nr(cap),
+                       state ? "GL_TRUE" : "GL_FALSE");
+
+       switch (cap) {
+       default:
+               radeonEnable(ctx, cap, state);
+               return;
+       }
+}
+
+
+/**
  * Called by Mesa after an internal state update.
  */
 static void r300InvalidateState(GLcontext * ctx, GLuint new_state)
@@ -317,6 +337,7 @@ void r300ResetHwState(r300ContextPtr r300)
 }
 
 
+
 /**
  * Calculate initial hardware state and register state functions.
  * Assumes that the command buffer and state atoms have been
@@ -324,12 +345,20 @@ void r300ResetHwState(r300ContextPtr r300)
  */
 void r300InitState(r300ContextPtr r300)
 {
-       struct dd_function_table* functions;
+       radeonInitState(&r300->radeon);
 
        r300ResetHwState(r300);
+}
+
+
+/**
+ * Initialize driver's state callback functions
+ */
+void r300InitStateFuncs(struct dd_function_table* functions)
+{
+       radeonInitStateFuncs(functions);
 
-       /* Setup state functions */
-       functions = &r300->radeon.glCtx->Driver;
        functions->UpdateState = r300InvalidateState;
+       functions->Enable= r300Enable;
 }
 
index 59d76e3..9c945c4 100644 (file)
@@ -44,6 +44,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
        } while(0)
 
 extern void r300ResetHwState(r300ContextPtr r300);
+
 extern void r300InitState(r300ContextPtr r300);
+extern void r300InitStateFuncs(struct dd_function_table* functions);
 
 #endif /* __R300_STATE_H__ */
index d04045d..b2cb9cf 100644 (file)
@@ -207,6 +207,23 @@ GLboolean radeonInitContext(radeonContextPtr radeon,
 
 
 /**
+ * Cleanup common context fields.
+ * Called by r200DestroyContext/r300DestroyContext
+ */
+void radeonCleanupContext(radeonContextPtr radeon)
+{
+       /* free the Mesa context */
+       radeon->glCtx->DriverCtx = NULL;
+       _mesa_destroy_context(radeon->glCtx);
+
+       if (radeon->state.scissor.pClipRects) {
+               FREE(radeon->state.scissor.pClipRects);
+               radeon->state.scissor.pClipRects = 0;
+       }
+}
+
+
+/**
  * Swap front and back buffer.
  */
 void radeonSwapBuffers(__DRIdrawablePrivate * dPriv)
index d51cf4c..b3661cd 100644 (file)
@@ -113,6 +113,15 @@ struct radeon_dri_mirror {
 /**
  * Derived state for internal purposes.
  */
+struct radeon_scissor_state {
+       drm_clip_rect_t rect;
+       GLboolean enabled;
+
+       GLuint numClipRects;    /* Cliprects active */
+       GLuint numAllocedClipRects;     /* Cliprects available */
+       drm_clip_rect_t *pClipRects;
+};
+
 struct radeon_colorbuffer_state {
        GLuint clear;
        GLint drawOffset, drawPitch;
@@ -125,6 +134,7 @@ struct radeon_pixel_state {
 struct radeon_state {
        struct radeon_colorbuffer_state color;
        struct radeon_pixel_state pixel;
+       struct radeon_scissor_state scissor;
 };
 
 /**
@@ -187,6 +197,7 @@ extern GLboolean radeonInitContext(radeonContextPtr radeon,
                                   const __GLcontextModes * glVisual,
                                   __DRIcontextPrivate * driContextPriv,
                                   void *sharedContextPrivate);
+extern void radeonCleanupContext(radeonContextPtr radeon);
 extern GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
                                   __DRIdrawablePrivate * driDrawPriv,
                                   __DRIdrawablePrivate * driReadPriv);
index 79b7c5a..4579bc4 100644 (file)
@@ -53,7 +53,7 @@ static void radeonUpdatePageFlipping(radeonContextPtr radeon)
 
        radeon->doPageFlip = radeon->sarea->pfState;
 
-       use_back = (radeon->glCtx->Color._DrawDestMask == DD_BACK_LEFT_BIT);
+       use_back = (radeon->glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT);
        use_back ^= (radeon->sarea->pfCurrentPage == 1);
 
        if (use_back) {
@@ -82,7 +82,7 @@ static void r200RegainedLock(r200ContextPtr r200)
                r200->hw.ctx.cmd[CTX_RB3D_COLORPITCH] =
                        r200->radeon.state.color.drawPitch;
 
-               if (r200->radeon.glCtx->Color._DrawDestMask == DD_BACK_LEFT_BIT)
+               if (r200->radeon.glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT)
                        radeonSetCliprects(&r200->radeon, GL_BACK_LEFT);
                else
                        radeonSetCliprects(&r200->radeon, GL_FRONT_LEFT);
@@ -102,14 +102,12 @@ static void r300RegainedLock(radeonContextPtr radeon)
        if (radeon->lastStamp != dPriv->lastStamp) {
                radeonUpdatePageFlipping(radeon);
 
-               if (radeon->glCtx->Color._DrawDestMask == DD_BACK_LEFT_BIT)
+               if (radeon->glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT)
                        radeonSetCliprects(radeon, GL_BACK_LEFT);
                else
                        radeonSetCliprects(radeon, GL_FRONT_LEFT);
 
-#if 0
-               r200UpdateViewportOffset(r200->radeon.glCtx);
-#endif
+               radeonUpdateScissor(radeon->glCtx);
                radeon->lastStamp = dPriv->lastStamp;
        }
 
index 7b54875..93c4da9 100644 (file)
@@ -330,53 +330,46 @@ static void radeonSetBuffer(GLcontext * ctx,
                          GLframebuffer * colorBuffer, GLuint bufferBit)
 {
        radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+       int buffer;
 
        switch (bufferBit) {
        case DD_FRONT_LEFT_BIT:
-               if (radeon->doPageFlip && radeon->sarea->pfCurrentPage == 1) {
-                       radeon->state.pixel.readOffset =
-                           radeon->radeonScreen->backOffset;
-                       radeon->state.pixel.readPitch =
-                           radeon->radeonScreen->backPitch;
-                       radeon->state.color.drawOffset =
-                           radeon->radeonScreen->backOffset;
-                       radeon->state.color.drawPitch =
-                           radeon->radeonScreen->backPitch;
-               } else {
-                       radeon->state.pixel.readOffset =
-                           radeon->radeonScreen->frontOffset;
-                       radeon->state.pixel.readPitch =
-                           radeon->radeonScreen->frontPitch;
-                       radeon->state.color.drawOffset =
-                           radeon->radeonScreen->frontOffset;
-                       radeon->state.color.drawPitch =
-                           radeon->radeonScreen->frontPitch;
-               }
+               buffer = 0;
                break;
+
        case DD_BACK_LEFT_BIT:
-               if (radeon->doPageFlip && radeon->sarea->pfCurrentPage == 1) {
-                       radeon->state.pixel.readOffset =
-                           radeon->radeonScreen->frontOffset;
-                       radeon->state.pixel.readPitch =
-                           radeon->radeonScreen->frontPitch;
-                       radeon->state.color.drawOffset =
-                           radeon->radeonScreen->frontOffset;
-                       radeon->state.color.drawPitch =
-                           radeon->radeonScreen->frontPitch;
-               } else {
-                       radeon->state.pixel.readOffset =
-                           radeon->radeonScreen->backOffset;
-                       radeon->state.pixel.readPitch =
-                           radeon->radeonScreen->backPitch;
-                       radeon->state.color.drawOffset =
-                           radeon->radeonScreen->backOffset;
-                       radeon->state.color.drawPitch =
-                           radeon->radeonScreen->backPitch;
-               }
+               buffer = 1;
                break;
+
        default:
                _mesa_problem(ctx, "Bad bufferBit in %s", __FUNCTION__);
-               break;
+               return;
+       }
+
+       if (radeon->doPageFlip && radeon->sarea->pfCurrentPage == 1)
+               buffer ^= 1;
+
+       fprintf(stderr, "%s: using %s buffer\n", __FUNCTION__,
+               buffer ? "back" : "front");
+
+       if (buffer) {
+               radeon->state.pixel.readOffset =
+                       radeon->radeonScreen->backOffset;
+               radeon->state.pixel.readPitch =
+                       radeon->radeonScreen->backPitch;
+               radeon->state.color.drawOffset =
+                       radeon->radeonScreen->backOffset;
+               radeon->state.color.drawPitch =
+                       radeon->radeonScreen->backPitch;
+       } else {
+               radeon->state.pixel.readOffset =
+                       radeon->radeonScreen->frontOffset;
+               radeon->state.pixel.readPitch =
+                       radeon->radeonScreen->frontPitch;
+               radeon->state.color.drawOffset =
+                       radeon->radeonScreen->frontOffset;
+               radeon->state.color.drawPitch =
+                       radeon->radeonScreen->frontPitch;
        }
 }
 
index 19af781..0cacbb5 100644 (file)
@@ -50,6 +50,106 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "radeon_ioctl.h"
 #include "radeon_state.h"
 #include "r200_state.h"
+#include "r300_ioctl.h"
+
+
+/* =============================================================
+ * Scissoring
+ */
+
+static GLboolean intersect_rect(drm_clip_rect_t * out,
+                               drm_clip_rect_t * a, drm_clip_rect_t * b)
+{
+       *out = *a;
+       if (b->x1 > out->x1)
+               out->x1 = b->x1;
+       if (b->y1 > out->y1)
+               out->y1 = b->y1;
+       if (b->x2 < out->x2)
+               out->x2 = b->x2;
+       if (b->y2 < out->y2)
+               out->y2 = b->y2;
+       if (out->x1 >= out->x2)
+               return GL_FALSE;
+       if (out->y1 >= out->y2)
+               return GL_FALSE;
+       return GL_TRUE;
+}
+
+void radeonRecalcScissorRects(radeonContextPtr radeon)
+{
+       drm_clip_rect_t *out;
+       int i;
+
+       /* Grow cliprect store?
+        */
+       if (radeon->state.scissor.numAllocedClipRects < radeon->numClipRects) {
+               while (radeon->state.scissor.numAllocedClipRects <
+                      radeon->numClipRects) {
+                       radeon->state.scissor.numAllocedClipRects += 1; /* zero case */
+                       radeon->state.scissor.numAllocedClipRects *= 2;
+               }
+
+               if (radeon->state.scissor.pClipRects)
+                       FREE(radeon->state.scissor.pClipRects);
+
+               radeon->state.scissor.pClipRects =
+                   MALLOC(radeon->state.scissor.numAllocedClipRects *
+                          sizeof(drm_clip_rect_t));
+
+               if (radeon->state.scissor.pClipRects == NULL) {
+                       radeon->state.scissor.numAllocedClipRects = 0;
+                       return;
+               }
+       }
+
+       out = radeon->state.scissor.pClipRects;
+       radeon->state.scissor.numClipRects = 0;
+
+       for (i = 0; i < radeon->numClipRects; i++) {
+               if (intersect_rect(out,
+                                  &radeon->pClipRects[i],
+                                  &radeon->state.scissor.rect)) {
+                       radeon->state.scissor.numClipRects++;
+                       out++;
+               }
+       }
+}
+
+void radeonUpdateScissor(GLcontext* ctx)
+{
+       radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+
+       assert(radeon->state.scissor.enabled == ctx->Scissor.Enabled);
+
+       if (radeon->dri.drawable) {
+               __DRIdrawablePrivate *dPriv = radeon->dri.drawable;
+               int x1 = dPriv->x + ctx->Scissor.X;
+               int y1 = dPriv->y + dPriv->h - (ctx->Scissor.Y + ctx->Scissor.Height);
+
+               radeon->state.scissor.rect.x1 = x1;
+               radeon->state.scissor.rect.y1 = y1;
+               radeon->state.scissor.rect.x2 = x1 + ctx->Scissor.Width - 1;
+               radeon->state.scissor.rect.y2 = y1 + ctx->Scissor.Height - 1;
+
+               radeonRecalcScissorRects(radeon);
+       }
+}
+
+static void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+{
+       radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+
+       if (ctx->Scissor.Enabled) {
+               /* We don't pipeline cliprect changes */
+               if (IS_FAMILY_R200(radeon))
+                       R200_FIREVERTICES((r200ContextPtr)radeon);
+               else
+                       r300Flush(ctx);
+
+               radeonUpdateScissor(ctx);
+       }
+}
 
 
 /**
@@ -77,12 +177,69 @@ void radeonSetCliprects(radeonContextPtr radeon, GLenum mode)
                break;
        default:
                fprintf(stderr, "bad mode in radeonSetCliprects\n");
+               radeon->numClipRects = 0;
+               radeon->pClipRects = 0;
+               return;
+       }
+
+       if (radeon->state.scissor.enabled)
+               radeonRecalcScissorRects(radeon);
+}
+
+
+/**
+ * Handle common enable bits.
+ * Called as a fallback by r200Enable/r300Enable.
+ */
+void radeonEnable(GLcontext* ctx, GLenum cap, GLboolean state)
+{
+       radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+
+       switch(cap) {
+       case GL_SCISSOR_TEST:
+               /* We don't pipeline cliprect & scissor changes */
+               if (IS_FAMILY_R200(radeon))
+                       R200_FIREVERTICES((r200ContextPtr)radeon);
+               else
+                       r300Flush(ctx);
+
+               radeon->state.scissor.enabled = state;
+               radeonUpdateScissor(ctx);
+               break;
+
+       default:
                return;
        }
+}
 
-       if (IS_FAMILY_R200(radeon)) {
-               if (((r200ContextPtr)radeon)->state.scissor.enabled)
-                       r200RecalcScissorRects((r200ContextPtr)radeon);
+
+/**
+ * Initialize default state.
+ * This function is called once at context init time from
+ * r200InitState/r300InitState
+ */
+void radeonInitState(radeonContextPtr radeon)
+{
+       radeon->Fallback = 0;
+
+       if (radeon->glCtx->Visual.doubleBufferMode && radeon->sarea->pfCurrentPage == 0) {
+               radeon->state.color.drawOffset = radeon->radeonScreen->backOffset;
+               radeon->state.color.drawPitch = radeon->radeonScreen->backPitch;
+       } else {
+               radeon->state.color.drawOffset = radeon->radeonScreen->frontOffset;
+               radeon->state.color.drawPitch = radeon->radeonScreen->frontPitch;
        }
+
+       radeon->state.pixel.readOffset = radeon->state.color.drawOffset;
+       radeon->state.pixel.readPitch = radeon->state.color.drawPitch;
 }
 
+
+/**
+ * Initialize common state functions.
+ * Called by r200InitStateFuncs/r300InitStateFuncs
+ */
+void radeonInitStateFuncs(struct dd_function_table *functions)
+{
+       functions->Scissor = radeonScissor;
+}
index 8b2698d..636bf5d 100644 (file)
@@ -1,9 +1,5 @@
 /*
-Copyright (C) The Weather Channel, Inc.  2002.  All Rights Reserved.
-
-The Weather Channel (TM) funded Tungsten Graphics to develop the
-initial release of the Radeon 8500 driver under the XFree86 license.
-This notice must be preserved.
+Copyright (C) 2004 Nicolai Haehnle.  All Rights Reserved.
 
 Permission is hereby granted, free of charge, to any person obtaining
 a copy of this software and associated documentation files (the
@@ -29,7 +25,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 /*
  * Authors:
- *   Keith Whitwell <keith@tungstengraphics.com>
+ *   Nicolai Haehnle <prefect_@gmx.net>
  */
 
 #ifndef __RADEON_STATE_H__
@@ -37,6 +33,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #include "radeon_context.h"
 
+extern void radeonRecalcScissorRects(radeonContextPtr radeon);
 extern void radeonSetCliprects(radeonContextPtr radeon, GLenum mode);
+extern void radeonUpdateScissor(GLcontext* ctx);
+
+extern void radeonEnable(GLcontext* ctx, GLenum cap, GLboolean state);
+
+extern void radeonInitState(radeonContextPtr radeon);
+extern void radeonInitStateFuncs(struct dd_function_table* functions);
 
 #endif