Merge branch 'mesa_7_5_branch'
[mesa.git] / src / mesa / drivers / dri / r300 / r300_ioctl.c
index eb5003791183692c51f1d11bf5d4ba50a2c550a7..104079b4dbe9789c47c01b2519705f9fcb89c636 100644 (file)
@@ -46,9 +46,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "main/context.h"
 #include "swrast/swrast.h"
 
-#include "radeon_buffer.h"
+#include "radeon_common.h"
+#include "radeon_lock.h"
 #include "r300_context.h"
-#include "radeon_ioctl.h"
 #include "r300_ioctl.h"
 #include "r300_cmdbuf.h"
 #include "r300_state.h"
@@ -66,13 +66,20 @@ 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)
 {
        BATCH_LOCALS(&r300->radeon);
        GLcontext *ctx = r300->radeon.glCtx;
-       __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
+       __DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon);
        GLuint cbpitch = 0;
        r300ContextPtr rmesa = r300;
 
@@ -94,12 +101,12 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags,
        }
 
        /* TODO in bufmgr */
-       cp_wait(r300, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
-       end_3d(rmesa);
+       cp_wait(&r300->radeon, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
+       end_3d(&rmesa->radeon);
 
        if (flags & CLEARBUFFER_COLOR) {
                assert(rrb != 0);
-               BEGIN_BATCH_NO_AUTOSTATE(4);
+               BEGIN_BATCH_NO_AUTOSTATE(6);
                OUT_BATCH_REGSEQ(R300_RB3D_COLOROFFSET0, 1);
                OUT_BATCH_RELOC(0, rrb->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
                OUT_BATCH_REGVAL(R300_RB3D_COLORPITCH0, cbpitch);
@@ -115,7 +122,7 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags,
                if (rrbd->bo->flags & RADEON_BO_FLAGS_MICRO_TILE){
             cbpitch |= R300_DEPTHMICROTILE_TILED;
         }
-               BEGIN_BATCH_NO_AUTOSTATE(4);
+               BEGIN_BATCH_NO_AUTOSTATE(6);
                OUT_BATCH_REGSEQ(R300_ZB_DEPTHOFFSET, 1);
                OUT_BATCH_RELOC(0, rrbd->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
                OUT_BATCH_REGVAL(R300_ZB_DEPTHPITCH, cbpitch);
@@ -159,43 +166,43 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags,
                             R300_S_FRONT_ZFAIL_OP_SHIFT);
                }
 
-        OUT_BATCH_REGSEQ(R300_ZB_CNTL, 3);
+               OUT_BATCH_REGSEQ(R300_ZB_CNTL, 3);
                OUT_BATCH(t1);
                OUT_BATCH(t2);
                OUT_BATCH(((ctx->Stencil.WriteMask[0] & R300_STENCILREF_MASK) <<
                    R300_STENCILWRITEMASK_SHIFT) |
                          (ctx->Stencil.Clear & R300_STENCILREF_MASK));
-        END_BATCH();
+               END_BATCH();
        }
 
-    if (!rmesa->radeon.radeonScreen->kernel_mm) {
-       BEGIN_BATCH_NO_AUTOSTATE(9);
-       OUT_BATCH(cmdpacket3(r300->radeon.radeonScreen, R300_CMD_PACKET3_CLEAR));
-       OUT_BATCH_FLOAT32(dPriv->w / 2.0);
-           OUT_BATCH_FLOAT32(dPriv->h / 2.0);
-       OUT_BATCH_FLOAT32(ctx->Depth.Clear);
-           OUT_BATCH_FLOAT32(1.0);
-       OUT_BATCH_FLOAT32(ctx->Color.ClearColor[0]);
-           OUT_BATCH_FLOAT32(ctx->Color.ClearColor[1]);
-       OUT_BATCH_FLOAT32(ctx->Color.ClearColor[2]);
-           OUT_BATCH_FLOAT32(ctx->Color.ClearColor[3]);
-       END_BATCH();
-    } else {
-        OUT_BATCH(CP_PACKET3(R200_3D_DRAW_IMMD_2, 8));
-        OUT_BATCH(R300_PRIM_TYPE_POINT | R300_PRIM_WALK_RING |
-                  (1 << R300_PRIM_NUM_VERTICES_SHIFT));
-       OUT_BATCH_FLOAT32(dPriv->w / 2.0);
-           OUT_BATCH_FLOAT32(dPriv->h / 2.0);
-       OUT_BATCH_FLOAT32(ctx->Depth.Clear);
-           OUT_BATCH_FLOAT32(1.0);
-       OUT_BATCH_FLOAT32(ctx->Color.ClearColor[0]);
-           OUT_BATCH_FLOAT32(ctx->Color.ClearColor[1]);
-       OUT_BATCH_FLOAT32(ctx->Color.ClearColor[2]);
-           OUT_BATCH_FLOAT32(ctx->Color.ClearColor[3]);
-    }
+       if (!rmesa->radeon.radeonScreen->kernel_mm) {
+               BEGIN_BATCH_NO_AUTOSTATE(9);
+               OUT_BATCH(cmdpacket3(r300->radeon.radeonScreen, R300_CMD_PACKET3_CLEAR));
+               OUT_BATCH_FLOAT32(dPriv->w / 2.0);
+               OUT_BATCH_FLOAT32(dPriv->h / 2.0);
+               OUT_BATCH_FLOAT32(ctx->Depth.Clear);
+               OUT_BATCH_FLOAT32(1.0);
+               OUT_BATCH_FLOAT32(ctx->Color.ClearColor[0]);
+               OUT_BATCH_FLOAT32(ctx->Color.ClearColor[1]);
+               OUT_BATCH_FLOAT32(ctx->Color.ClearColor[2]);
+               OUT_BATCH_FLOAT32(ctx->Color.ClearColor[3]);
+               END_BATCH();
+       } else {
+               OUT_BATCH(CP_PACKET3(R200_3D_DRAW_IMMD_2, 8));
+               OUT_BATCH(R300_PRIM_TYPE_POINT | R300_PRIM_WALK_RING |
+                         (1 << R300_PRIM_NUM_VERTICES_SHIFT));
+               OUT_BATCH_FLOAT32(dPriv->w / 2.0);
+               OUT_BATCH_FLOAT32(dPriv->h / 2.0);
+               OUT_BATCH_FLOAT32(ctx->Depth.Clear);
+               OUT_BATCH_FLOAT32(1.0);
+               OUT_BATCH_FLOAT32(ctx->Color.ClearColor[0]);
+               OUT_BATCH_FLOAT32(ctx->Color.ClearColor[1]);
+               OUT_BATCH_FLOAT32(ctx->Color.ClearColor[2]);
+               OUT_BATCH_FLOAT32(ctx->Color.ClearColor[3]);
+       }
 
        r300EmitCacheFlush(rmesa);
-       cp_wait(rmesa, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
+       cp_wait(&r300->radeon, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
 
        R300_STATECHANGE(r300, cb);
        R300_STATECHANGE(r300, cmk);
@@ -206,14 +213,13 @@ static void r300EmitClearState(GLcontext * ctx)
 {
        r300ContextPtr r300 = R300_CONTEXT(ctx);
        BATCH_LOCALS(&r300->radeon);
-       __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
+       __DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon);
        int i;
-       int has_tcl = 1;
+       int has_tcl;
        int is_r500 = 0;
        GLuint vap_cntl;
 
-       if (!(r300->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL))
-               has_tcl = 0;
+       has_tcl = r300->options.hw_tcl_enabled;
 
        if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515)
                is_r500 = 1;
@@ -393,7 +399,7 @@ static void r300EmitClearState(GLcontext * ctx)
                R300_STATECHANGE(r300, fp);
                R300_STATECHANGE(r300, r500fp);
 
-               BEGIN_BATCH(14);
+               BEGIN_BATCH(7);
                OUT_BATCH_REGSEQ(R500_US_CONFIG, 2);
                OUT_BATCH(R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO);
                OUT_BATCH(0x0);
@@ -441,7 +447,7 @@ static void r300EmitClearState(GLcontext * ctx)
                        R500_ALU_RGBA_G_SWIZ_0 |
                        R500_ALU_RGBA_B_SWIZ_0 |
                        R500_ALU_RGBA_A_SWIZ_0;
-               
+
                r500fp.cmd[7] = 0;
                emit_r500fp(ctx, &r500fp);
        }
@@ -528,27 +534,72 @@ static void r300EmitClearState(GLcontext * ctx)
                                       PVS_SRC_SELECT_FORCE_0,
                                       PVS_SRC_REG_INPUT, VSF_FLAG_NONE);
                vpu.cmd[8] = 0x0;
+
+               r300->vap_flush_needed = GL_TRUE;
                emit_vpu(ctx, &vpu);
        }
 }
 
+static void r300KernelClear(GLcontext *ctx, GLuint flags)
+{
+       r300ContextPtr r300 = R300_CONTEXT(ctx);
+       __DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon);
+       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 (rrbd && (flags & BUFFER_BIT_STENCIL))
+               bits |= CLEARBUFFER_STENCIL;
+
+       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
  */
 static void r300Clear(GLcontext * ctx, GLbitfield mask)
 {
        r300ContextPtr r300 = R300_CONTEXT(ctx);
-       __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
-       GLframebuffer *fb = dPriv->driverPrivate;
-       struct radeon_renderbuffer *rrb;
-       struct radeon_renderbuffer *rrbd;
-       int flags = 0;
-       int bits = 0;
+       __DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon);
+       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)
@@ -561,76 +612,55 @@ 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;
+       /* HW stencil */
+       if (mask & BUFFER_BIT_STENCIL) {
+               tri_mask |= BUFFER_BIT_STENCIL;
        }
 
+       /* HW depth */
        if (mask & BUFFER_BIT_DEPTH) {
-               bits |= CLEARBUFFER_DEPTH;
-               mask &= ~BUFFER_BIT_DEPTH;
+               tri_mask |= BUFFER_BIT_DEPTH;
        }
 
-       if ((mask & BUFFER_BIT_STENCIL) && r300->radeon.state.stencil.hwBuffer) {
-               bits |= CLEARBUFFER_STENCIL;
-               mask &= ~BUFFER_BIT_STENCIL;
-       }
+       /* 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 *)fb->Attachment[BUFFER_DEPTH].Renderbuffer;
+       /* SW fallback clearing */
+       swrast_mask = mask & ~tri_mask;
 
-       if (flags & BUFFER_BIT_FRONT_LEFT) {
-               rrb = (void *)fb->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 *)fb->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 r300Flush(GLcontext * ctx)
-{
-       r300ContextPtr rmesa = R300_CONTEXT(ctx);
-
-       if (RADEON_DEBUG & DEBUG_IOCTL)
-               fprintf(stderr, "%s\n", __FUNCTION__);
-
-    if (rmesa->swtcl.flush) {
-        rmesa->swtcl.flush(rmesa);
-    }
-
-       if (rmesa->radeon.cmdbuf.cs->cdw) {
-               rcommonFlushCmdBuf(&rmesa->radeon, __FUNCTION__);
-       }
-}
 
 void r300InitIoctlFuncs(struct dd_function_table *functions)
 {
        functions->Clear = r300Clear;
        functions->Finish = radeonFinish;
-       functions->Flush = r300Flush;
+       functions->Flush = radeonFlush;
 }