mesa: lift default symlinks target into Makefile.template
[mesa.git] / src / mesa / drivers / dri / r300 / r300_ioctl.c
index d1cf57959fad2db52dcc510082b4a3f5b860dd07..5cb04e2bb6d3036245f1bc512a5bd52fe199c7f7 100644 (file)
@@ -44,6 +44,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "main/imports.h"
 #include "main/macros.h"
 #include "main/context.h"
+#include "main/simple_list.h"
 #include "swrast/swrast.h"
 
 #include "radeon_common.h"
@@ -55,7 +56,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "r300_vertprog.h"
 #include "radeon_reg.h"
 #include "r300_emit.h"
-#include "r300_fragprog.h"
 #include "r300_context.h"
 
 #include "vblank.h"
@@ -66,17 +66,79 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define CLEARBUFFER_DEPTH      0x2
 #define CLEARBUFFER_STENCIL    0x4
 
+#if 1
+
+/**
+ * Fragment program helper macros
+ */
+
+/* Produce unshifted source selectors */
+#define FP_TMP(idx) (idx)
+#define FP_CONST(idx) ((idx) | (1 << 5))
+
+/* Produce source/dest selector dword */
+#define FP_SELC_MASK_NO                0
+#define FP_SELC_MASK_X         1
+#define FP_SELC_MASK_Y         2
+#define FP_SELC_MASK_XY                3
+#define FP_SELC_MASK_Z         4
+#define FP_SELC_MASK_XZ                5
+#define FP_SELC_MASK_YZ                6
+#define FP_SELC_MASK_XYZ       7
+
+#define FP_SELC(destidx,regmask,outmask,src0,src1,src2) \
+       (((destidx) << R300_ALU_DSTC_SHIFT) |           \
+        (FP_SELC_MASK_##regmask << 23) |               \
+        (FP_SELC_MASK_##outmask << 26) |               \
+        ((src0) << R300_ALU_SRC0C_SHIFT) |             \
+        ((src1) << R300_ALU_SRC1C_SHIFT) |             \
+        ((src2) << R300_ALU_SRC2C_SHIFT))
+
+#define FP_SELA_MASK_NO                0
+#define FP_SELA_MASK_W         1
+
+#define FP_SELA(destidx,regmask,outmask,src0,src1,src2) \
+       (((destidx) << R300_ALU_DSTA_SHIFT) |           \
+        (FP_SELA_MASK_##regmask << 23) |               \
+        (FP_SELA_MASK_##outmask << 24) |               \
+        ((src0) << R300_ALU_SRC0A_SHIFT) |             \
+        ((src1) << R300_ALU_SRC1A_SHIFT) |             \
+        ((src2) << R300_ALU_SRC2A_SHIFT))
+
+/* Produce unshifted argument selectors */
+#define FP_ARGC(source)        R300_ALU_ARGC_##source
+#define FP_ARGA(source) R300_ALU_ARGA_##source
+#define FP_ABS(arg) ((arg) | (1 << 6))
+#define FP_NEG(arg) ((arg) ^ (1 << 5))
+
+/* Produce instruction dword */
+#define FP_INSTRC(opcode,arg0,arg1,arg2) \
+       (R300_ALU_OUTC_##opcode |               \
+       ((arg0) << R300_ALU_ARG0C_SHIFT) |      \
+       ((arg1) << R300_ALU_ARG1C_SHIFT) |      \
+       ((arg2) << R300_ALU_ARG2C_SHIFT))
+
+#define FP_INSTRA(opcode,arg0,arg1,arg2) \
+       (R300_ALU_OUTA_##opcode |               \
+       ((arg0) << R300_ALU_ARG0A_SHIFT) |      \
+       ((arg1) << R300_ALU_ARG1A_SHIFT) |      \
+       ((arg2) << R300_ALU_ARG2A_SHIFT))
+
+#endif
+
+static void r300EmitClearState(GLcontext * ctx);
+
 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;
 
-       if (RADEON_DEBUG & DEBUG_IOCTL)
+       if (RADEON_DEBUG & RADEON_IOCTL)
                fprintf(stderr, "%s: buffer %p (%i,%i %ix%i)\n",
                        __FUNCTION__, rrb, dPriv->x, dPriv->y,
                        dPriv->w, dPriv->h);
@@ -107,18 +169,21 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags,
        }
 #if 1
        if (flags & (CLEARBUFFER_DEPTH | CLEARBUFFER_STENCIL)) {
-               assert(rrbd != 0);
-               cbpitch = (rrbd->pitch / rrbd->cpp);
+               uint32_t zbpitch = (rrbd->pitch / rrbd->cpp);
                if (rrbd->bo->flags & RADEON_BO_FLAGS_MACRO_TILE){
-                       cbpitch |= R300_DEPTHMACROTILE_ENABLE;
+                       zbpitch |= R300_DEPTHMACROTILE_ENABLE;
         }
                if (rrbd->bo->flags & RADEON_BO_FLAGS_MICRO_TILE){
-            cbpitch |= R300_DEPTHMICROTILE_TILED;
+            zbpitch |= R300_DEPTHMICROTILE_TILED;
         }
                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);
+               OUT_BATCH_REGSEQ(R300_ZB_DEPTHPITCH, 1);
+               if (!r300->radeon.radeonScreen->kernel_mm)
+                       OUT_BATCH(zbpitch);
+               else
+                       OUT_BATCH_RELOC(zbpitch, rrbd->bo, zbpitch, 0, RADEON_GEM_DOMAIN_VRAM, 0);
                END_BATCH();
        }
 #endif
@@ -193,7 +258,7 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags,
                OUT_BATCH_FLOAT32(ctx->Color.ClearColor[2]);
                OUT_BATCH_FLOAT32(ctx->Color.ClearColor[3]);
        }
-       
+
        r300EmitCacheFlush(rmesa);
        cp_wait(&r300->radeon, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
 
@@ -206,14 +271,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;
@@ -441,9 +505,17 @@ 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);
+               if (r300->radeon.radeonScreen->kernel_mm) {
+                       emit_r500fp(ctx, &r500fp);
+               } else {
+                       int dwords = r500fp.check(ctx,&r500fp);
+                       BEGIN_BATCH_NO_AUTOSTATE(dwords);
+                       OUT_BATCH_TABLE(r500fp.cmd, dwords);
+                       END_BATCH();
+               }
+
        }
 
        BEGIN_BATCH(2);
@@ -487,6 +559,7 @@ static void r300EmitClearState(GLcontext * ctx)
         struct radeon_state_atom vpu;
         uint32_t _cmd[10];
                R300_STATECHANGE(r300, pvs);
+               R300_STATECHANGE(r300, vap_flush);
                R300_STATECHANGE(r300, vpi);
 
                BEGIN_BATCH(4);
@@ -507,12 +580,12 @@ static void r300EmitClearState(GLcontext * ctx)
                                          0, 0xf, PVS_DST_REG_OUT);
                vpu.cmd[2] = PVS_SRC_OPERAND(0, PVS_SRC_SELECT_X, PVS_SRC_SELECT_Y,
                                       PVS_SRC_SELECT_Z, PVS_SRC_SELECT_W,
-                                      PVS_SRC_REG_INPUT, VSF_FLAG_NONE);
+                                      PVS_SRC_REG_INPUT, NEGATE_NONE);
                vpu.cmd[3] = PVS_SRC_OPERAND(0, PVS_SRC_SELECT_FORCE_0,
                                       PVS_SRC_SELECT_FORCE_0,
                                       PVS_SRC_SELECT_FORCE_0,
                                       PVS_SRC_SELECT_FORCE_0,
-                                      PVS_SRC_REG_INPUT, VSF_FLAG_NONE);
+                                      PVS_SRC_REG_INPUT, NEGATE_NONE);
                vpu.cmd[4] = 0x0;
 
                vpu.cmd[5] = PVS_OP_DST_OPERAND(VE_ADD, GL_FALSE, GL_FALSE, 1, 0xf,
@@ -520,90 +593,95 @@ static void r300EmitClearState(GLcontext * ctx)
                vpu.cmd[6] = PVS_SRC_OPERAND(1, PVS_SRC_SELECT_X,
                                       PVS_SRC_SELECT_Y, PVS_SRC_SELECT_Z,
                                       PVS_SRC_SELECT_W, PVS_SRC_REG_INPUT,
-
-                                      VSF_FLAG_NONE);
+                                      NEGATE_NONE);
                vpu.cmd[7] = PVS_SRC_OPERAND(1, PVS_SRC_SELECT_FORCE_0,
                                       PVS_SRC_SELECT_FORCE_0,
                                       PVS_SRC_SELECT_FORCE_0,
                                       PVS_SRC_SELECT_FORCE_0,
-                                      PVS_SRC_REG_INPUT, VSF_FLAG_NONE);
+                                      PVS_SRC_REG_INPUT, NEGATE_NONE);
                vpu.cmd[8] = 0x0;
 
-               r300->vap_flush_needed = GL_TRUE;
-               emit_vpu(ctx, &vpu);
+               if (r300->radeon.radeonScreen->kernel_mm) {
+                       int dwords = r300->hw.vap_flush.check(ctx,&r300->hw.vap_flush);
+                       BEGIN_BATCH_NO_AUTOSTATE(dwords);
+                       OUT_BATCH_TABLE(r300->hw.vap_flush.cmd, dwords);
+                       END_BATCH();
+                       emit_vpu(ctx, &vpu);
+               } else {
+                       int dwords = vpu.check(ctx,&vpu);
+                       BEGIN_BATCH_NO_AUTOSTATE(dwords);
+                       OUT_BATCH_TABLE(vpu.cmd, dwords);
+                       END_BATCH();
+               }
+
        }
 }
 
-/**
- * Buffer clear
- */
-static void r300Clear(GLcontext * ctx, GLbitfield mask)
+static int r300KernelClear(GLcontext *ctx, GLuint flags)
 {
        r300ContextPtr r300 = R300_CONTEXT(ctx);
-       __DRIdrawablePrivate *dPriv = r300->radeon.dri.drawable;
+       __DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon);
        struct radeon_framebuffer *rfb = dPriv->driverPrivate;
        struct radeon_renderbuffer *rrb;
        struct radeon_renderbuffer *rrbd;
-       int flags = 0;
-       int bits = 0;
-
-       if (RADEON_DEBUG & DEBUG_IOCTL)
-               fprintf(stderr, "r300Clear\n");
+       int bits = 0, ret;
 
-       {
-               LOCK_HARDWARE(&r300->radeon);
-               UNLOCK_HARDWARE(&r300->radeon);
-               if (dPriv->numClipRects == 0)
-                       return;
-       }
-
-       /* Flush swtcl vertices if necessary, because we will change hardware
-        * state during clear. See also the state-related comment in
-        * r300EmitClearState.
-        */
-       R300_NEWPRIM(r300);
+       /* Make sure it fits there. */
+       radeon_cs_space_reset_bos(r300->radeon.cmdbuf.cs);
 
-       if (mask & BUFFER_BIT_FRONT_LEFT) {
-               flags |= BUFFER_BIT_FRONT_LEFT;
-               mask &= ~BUFFER_BIT_FRONT_LEFT;
+       if (flags & BUFFER_BIT_COLOR0) {
+               rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_COLOR0);
+               radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs,
+                                                 rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM);
        }
 
-       if (mask & BUFFER_BIT_BACK_LEFT) {
-               flags |= BUFFER_BIT_BACK_LEFT;
-               mask &= ~BUFFER_BIT_BACK_LEFT;
+       if (flags & BUFFER_BIT_FRONT_LEFT) {
+               rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT);
+               radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs,
+                                                 rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM);
        }
 
-       if (mask & BUFFER_BIT_DEPTH) {
-               bits |= CLEARBUFFER_DEPTH;
-               mask &= ~BUFFER_BIT_DEPTH;
+       if (flags & BUFFER_BIT_BACK_LEFT) {
+               rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_BACK_LEFT);
+               radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs,
+                                                 rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM);
        }
 
-       if ((mask & BUFFER_BIT_STENCIL) && r300->radeon.state.stencil.hwBuffer) {
-               bits |= CLEARBUFFER_STENCIL;
-               mask &= ~BUFFER_BIT_STENCIL;
+       rrbd = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH);
+       if (rrbd) {
+               radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs,
+                                                 rrbd->bo, 0, RADEON_GEM_DOMAIN_VRAM);
        }
 
-       if (mask) {
-               if (RADEON_DEBUG & DEBUG_FALLBACKS)
-                       fprintf(stderr, "%s: swrast clear, mask: %x\n",
-                               __FUNCTION__, mask);
-               _swrast_Clear(ctx, mask);
-       }
+       ret = radeon_cs_space_check(r300->radeon.cmdbuf.cs);
+       if (ret)
+         return -1;
 
-       /* Make sure it fits there. */
        rcommonEnsureCmdBufSpace(&r300->radeon, 421 * 3, __FUNCTION__);
        if (flags || bits)
                r300EmitClearState(ctx);
-       rrbd = (void *)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer;
+
+       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 = (void *)rfb->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
+               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 = (void *)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer;
+               rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_BACK_LEFT);
                r300ClearBuffer(r300, bits | CLEARBUFFER_COLOR, rrb, rrbd);
                bits = 0;
        }
@@ -612,6 +690,88 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask)
                r300ClearBuffer(r300, bits, NULL, rrbd);
 
        COMMIT_BATCH();
+       return 0;
+}
+
+/**
+ * Buffer clear
+ */
+static void r300Clear(GLcontext * ctx, GLbitfield mask)
+{
+       r300ContextPtr r300 = R300_CONTEXT(ctx);
+       __DRIdrawablePrivate *dPriv = radeon_get_drawable(&r300->radeon);
+       const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask);
+       GLbitfield swrast_mask = 0, tri_mask = 0;
+       int i, ret;
+       struct gl_framebuffer *fb = ctx->DrawBuffer;
+
+       if (RADEON_DEBUG & RADEON_IOCTL)
+               fprintf(stderr, "r300Clear\n");
+
+       if (!r300->radeon.radeonScreen->driScreen->dri2.enabled) {
+               LOCK_HARDWARE(&r300->radeon);
+               UNLOCK_HARDWARE(&r300->radeon);
+               if (dPriv->numClipRects == 0)
+                       return;
+       }
+
+       /* Flush swtcl vertices if necessary, because we will change hardware
+        * state during clear. See also the state-related comment in
+        * r300EmitClearState.
+        */
+       R300_NEWPRIM(r300);
+
+       if (colorMask == ~0)
+         tri_mask |= (mask & BUFFER_BITS_COLOR);
+       else
+         tri_mask |= (mask & (BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT));
+
+
+       /* HW stencil */
+       if (mask & BUFFER_BIT_STENCIL) {
+               tri_mask |= BUFFER_BIT_STENCIL;
+       }
+
+       /* HW depth */
+       if (mask & BUFFER_BIT_DEPTH) {
+               tri_mask |= BUFFER_BIT_DEPTH;
+       }
+
+       /* If we're doing a tri pass for depth/stencil, include a likely color
+        * buffer with it.
+        */
+
+       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;
+           }
+         }
+       }
+
+       /* SW fallback clearing */
+       swrast_mask = mask & ~tri_mask;
+
+       ret = 0;
+       if (tri_mask) {
+               if (r300->radeon.radeonScreen->kernel_mm)
+                       radeonUserClear(ctx, tri_mask);
+               else {
+                       /* if kernel clear fails due to size restraints fallback */
+                       ret = r300KernelClear(ctx, tri_mask);
+                       if (ret < 0)
+                               swrast_mask |= tri_mask;
+               }
+       }
+
+       if (swrast_mask) {
+               if (RADEON_DEBUG & RADEON_FALLBACKS)
+                       fprintf(stderr, "%s: swrast clear, mask: %x\n",
+                               __FUNCTION__, swrast_mask);
+               _swrast_Clear(ctx, swrast_mask);
+       }
 }
 
 void r300InitIoctlFuncs(struct dd_function_table *functions)