Initialize vertsize correctly. Add planemask arguments for color and depth
authorKeith Whitwell <keith@tungstengraphics.com>
Wed, 30 Aug 2000 22:34:28 +0000 (22:34 +0000)
committerKeith Whitwell <keith@tungstengraphics.com>
Wed, 30 Aug 2000 22:34:28 +0000 (22:34 +0000)
    stencil clearing.

linux/mga_dma.c
linux/mga_drm.h
linux/mga_drv.h
linux/mga_state.c

index bbfa949..4b86122 100644 (file)
@@ -388,7 +388,7 @@ void mga_fire_primary(drm_device_t *dev, drm_mga_prim_buf_t *prim)
        /* We never check for overflow, b/c there is always room */
        PRIMPTR(prim);
        if(num_dwords <= 0) {
-               DRM_DEBUG("num_dwords == 0 when dispatched\n");
+               DRM_ERROR("num_dwords == 0 when dispatched\n");
                goto out_prim_wait;
        }
        PRIMOUTREG( MGAREG_DMAPAD, 0);
@@ -770,6 +770,7 @@ static int mga_dma_initialize(drm_device_t *dev, drm_mga_init_t *init) {
        init_waitqueue_head(&dev_priv->flush_queue);
        init_waitqueue_head(&dev_priv->buf_queue);
        dev_priv->WarpPipe = 0xff000000;
+       dev_priv->vertexsize = 0;
 
        DRM_DEBUG("chipset: %d ucode_size: %d backOffset: %x depthOffset: %x\n",
                  dev_priv->chipset, dev_priv->warp_ucode_size, 
index e75e91a..52cf776 100644 (file)
 
 /* 3d state excluding texture units:
  */
-#define MGA_CTXREG_DSTORG   0  /* validated */
-#define MGA_CTXREG_MACCESS  1  
-#define MGA_CTXREG_PLNWT    2  
-#define MGA_CTXREG_DWGCTL    3 
-#define MGA_CTXREG_ALPHACTRL 4
-#define MGA_CTXREG_FOGCOLOR  5
-#define MGA_CTXREG_WFLAG     6
-#define MGA_CTXREG_TDUAL0    7
-#define MGA_CTXREG_TDUAL1    8
-#define MGA_CTXREG_FCOL      9
-#define MGA_CTX_SETUP_SIZE   10
+#define MGA_CTXREG_DSTORG     0        /* validated */
+#define MGA_CTXREG_MACCESS    1        
+#define MGA_CTXREG_PLNWT      2        
+#define MGA_CTXREG_DWGCTL     3        
+#define MGA_CTXREG_ALPHACTRL  4
+#define MGA_CTXREG_FOGCOLOR   5
+#define MGA_CTXREG_WFLAG      6
+#define MGA_CTXREG_TDUAL0     7
+#define MGA_CTXREG_TDUAL1     8
+#define MGA_CTXREG_FCOL       9
+#define MGA_CTXREG_STENCIL    10
+#define MGA_CTXREG_STENCILCTL 11
+#define MGA_CTX_SETUP_SIZE    12
 
 /* 2d state
  */
@@ -233,6 +235,7 @@ typedef struct _drm_mga_sarea {
        /* Mechanism to validate card state.
         */
        int ctxOwner;
+       int vertexsize;
 } drm_mga_sarea_t;     
 
 /* Device specific ioctls:
@@ -241,6 +244,8 @@ typedef struct _drm_mga_clear {
        unsigned int clear_color;
        unsigned int clear_depth;
        unsigned int flags;
+       unsigned int clear_depth_mask;
+       unsigned int clear_color_mask;
 } drm_mga_clear_t;
 
 typedef struct _drm_mga_swap {
index f49bd0f..0a6a13b 100644 (file)
@@ -82,6 +82,7 @@ typedef struct _drm_mga_private {
        int use_agp;
        drm_mga_warp_index_t WarpIndex[MGA_MAX_G400_PIPES];
        unsigned int WarpPipe;
+       unsigned int vertexsize;
        atomic_t pending_bufs;
        void *status_page;
        unsigned long real_status_page;
@@ -212,13 +213,12 @@ typedef struct {
 #define PRIM_OVERFLOW(dev, dev_priv, length) do {                         \
        drm_mga_prim_buf_t *tmp_buf =                                      \
                dev_priv->prim_bufs[dev_priv->current_prim_idx];           \
-       if( test_bit(MGA_BUF_NEEDS_OVERFLOW,                               \
-                 &tmp_buf->buffer_status)) {                              \
+       if( test_bit(MGA_BUF_NEEDS_OVERFLOW, &tmp_buf->buffer_status)) {   \
                mga_advance_primary(dev);                                  \
                mga_dma_schedule(dev, 1);                                  \
                tmp_buf = dev_priv->prim_bufs[dev_priv->current_prim_idx]; \
        } else if( tmp_buf->max_dwords - tmp_buf->num_dwords < length ||   \
-           tmp_buf->sec_used > MGA_DMA_BUF_NR/2) {                        \
+                  tmp_buf->sec_used > MGA_DMA_BUF_NR/2) {                 \
                set_bit(MGA_BUF_FORCE_FIRE, &tmp_buf->buffer_status);      \
                mga_advance_primary(dev);                                  \
                mga_dma_schedule(dev, 1);                                  \
index 5a9c763..c896396 100644 (file)
  */
 
 #define MGAEMITCLIP_SIZE 10
-#define MGAEMITCTX_SIZE 15
+#define MGAEMITCTX_SIZE 20
 #define MGAG200EMITTEX_SIZE 20
 #define MGAG400EMITTEX0_SIZE 30
 #define MGAG400EMITTEX1_SIZE 25
-#define MGAG400EMITPIPE_SIZE 50
+#define MGAG400EMITPIPE_SIZE 55
 #define MGAG200EMITPIPE_SIZE 15
 
 #define MAX_STATE_SIZE ((MGAEMITCLIP_SIZE * MGA_NR_SAREA_CLIPRECTS) + \
@@ -89,7 +89,7 @@ static void mgaEmitContext(drm_mga_private_t * dev_priv)
        PRIMLOCALS;
        DRM_DEBUG("%s\n", __FUNCTION__);
 
-       /* This takes a max of 15 dwords */
+       /* This takes a max of 20 dwords */
        PRIMGETPTR(dev_priv);
 
        PRIMOUTREG(MGAREG_DSTORG, regs[MGA_CTXREG_DSTORG]);
@@ -107,6 +107,11 @@ static void mgaEmitContext(drm_mga_private_t * dev_priv)
                PRIMOUTREG(MGAREG_TDUALSTAGE0, regs[MGA_CTXREG_TDUAL0]);
                PRIMOUTREG(MGAREG_TDUALSTAGE1, regs[MGA_CTXREG_TDUAL1]);
                PRIMOUTREG(MGAREG_FCOL, regs[MGA_CTXREG_FCOL]);
+               
+               PRIMOUTREG(MGAREG_STENCIL, regs[MGA_CTXREG_STENCIL]);
+               PRIMOUTREG(MGAREG_STENCILCTL, regs[MGA_CTXREG_STENCILCTL]);
+               PRIMOUTREG(MGAREG_DMAPAD, 0);
+               PRIMOUTREG(MGAREG_DMAPAD, 0);
        } else {
                PRIMOUTREG(MGAREG_FCOL, regs[MGA_CTXREG_FCOL]);
                PRIMOUTREG(MGAREG_DMAPAD, 0);
@@ -151,11 +156,13 @@ static void mgaG200EmitTex(drm_mga_private_t * dev_priv)
        PRIMADVANCE(dev_priv);
 }
 
+#define TMC_dualtex_enable             0x80            
+
 static void mgaG400EmitTex0(drm_mga_private_t * dev_priv)
 {
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
        unsigned int *regs = sarea_priv->TexState[0];
-       int multitex = sarea_priv->WarpPipe & MGA_T2;
+       int multitex = regs[MGA_TEXREG_CTL2] & TMC_dualtex_enable;
        PRIMLOCALS;
        DRM_DEBUG("%s\n", __FUNCTION__);
 
@@ -163,7 +170,9 @@ static void mgaG400EmitTex0(drm_mga_private_t * dev_priv)
 
        /* This takes a max of 30 dwords */
 
-       PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] | 0x00008000);
+       PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] 
+                  | 0x00008000 
+          );
        PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL]);
        PRIMOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER]);
        PRIMOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL]);
@@ -183,7 +192,7 @@ static void mgaG400EmitTex0(drm_mga_private_t * dev_priv)
        PRIMOUTREG(0x2d00 + 61 * 4, 0);
        PRIMOUTREG(MGAREG_DMAPAD, 0);
 
-       if (!multitex) {
+       if (!multitex || 1) {
                PRIMOUTREG(0x2d00 + 52 * 4, 0x40);
                PRIMOUTREG(0x2d00 + 60 * 4, 0x40);
                PRIMOUTREG(MGAREG_DMAPAD, 0);
@@ -200,10 +209,10 @@ static void mgaG400EmitTex0(drm_mga_private_t * dev_priv)
 
 #define TMC_map1_enable                0x80000000
 
-static void mgaG400EmitTex1(drm_mga_private_t * dev_priv)
+static void mgaG400EmitTex1(drm_mga_private_t * dev_priv, int source )
 {
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
-       unsigned int *regs = sarea_priv->TexState[1];
+       unsigned int *regs = sarea_priv->TexState[source];
        PRIMLOCALS;
        DRM_DEBUG("%s\n", __FUNCTION__);
 
@@ -211,8 +220,8 @@ static void mgaG400EmitTex1(drm_mga_private_t * dev_priv)
 
        /* This takes 25 dwords */
 
-       PRIMOUTREG(MGAREG_TEXCTL2,
-                  regs[MGA_TEXREG_CTL2] | TMC_map1_enable | 0x00008000);
+       PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] | TMC_map1_enable | 
+                  0x00008000);
        PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL]);
        PRIMOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER]);
        PRIMOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL]);
@@ -245,6 +254,8 @@ static void mgaG400EmitPipe(drm_mga_private_t * dev_priv)
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
        unsigned int pipe = sarea_priv->WarpPipe;
        float fParam = 12800.0f;
+       int multitex = (sarea_priv->TexState[0][MGA_TEXREG_CTL2] & 
+                       TMC_dualtex_enable);
        PRIMLOCALS;
        DRM_DEBUG("%s\n", __FUNCTION__);
 
@@ -259,7 +270,31 @@ static void mgaG400EmitPipe(drm_mga_private_t * dev_priv)
        PRIMOUTREG(MGAREG_DMAPAD, 0);
        PRIMOUTREG(MGAREG_DMAPAD, 0);
 
-       if (pipe & MGA_T2) {
+       if (sarea_priv->vertexsize == 10) {
+               PRIMOUTREG(MGAREG_YDST, 0);
+               PRIMOUTREG(MGAREG_FXLEFT, 0);
+               PRIMOUTREG(MGAREG_FXRIGHT, 1);
+               PRIMOUTREG(MGAREG_DWGCTL, MGA_FLUSH_CMD);
+
+               PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 1);
+               PRIMOUTREG(MGAREG_DMAPAD, 0);
+               PRIMOUTREG(MGAREG_DWGSYNC, 0x7000);
+               PRIMOUTREG(MGAREG_DMAPAD, 0);
+                       
+               if (multitex) {
+                       PRIMOUTREG(MGAREG_TEXCTL2, 0 
+                                  | 0x00008000
+                               );
+                       PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0);
+                       PRIMOUTREG(MGAREG_TEXCTL2, 0x80 | 0x00008000);
+                       PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0);
+               } else {
+                       PRIMOUTREG(MGAREG_TEXCTL2, 0 | 0x00008000);
+                       PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0);
+                       PRIMOUTREG(MGAREG_TEXCTL2, 0 | 0x00008000);
+                       PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0);
+               }
+
                PRIMOUTREG(MGAREG_WVRTXSZ, 0x00001e09);
                PRIMOUTREG(MGAREG_DMAPAD, 0);
                PRIMOUTREG(MGAREG_DMAPAD, 0);
@@ -270,23 +305,21 @@ static void mgaG400EmitPipe(drm_mga_private_t * dev_priv)
                PRIMOUTREG(MGAREG_WACCEPTSEQ, 0);
                PRIMOUTREG(MGAREG_WACCEPTSEQ, 0x1e000000);
        } else {
-               if (dev_priv->WarpPipe & MGA_T2) {
-                       /* Flush the WARP pipe */
-                       PRIMOUTREG(MGAREG_YDST, 0);
-                       PRIMOUTREG(MGAREG_FXLEFT, 0);
-                       PRIMOUTREG(MGAREG_FXRIGHT, 1);
-                       PRIMOUTREG(MGAREG_DWGCTL, MGA_FLUSH_CMD);
-
-                       PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 1);
-                       PRIMOUTREG(MGAREG_DMAPAD, 0);
-                       PRIMOUTREG(MGAREG_DWGSYNC, 0x7000);
-                       PRIMOUTREG(MGAREG_DMAPAD, 0);
+               /* Flush the WARP pipe */
+               PRIMOUTREG(MGAREG_YDST, 0);
+               PRIMOUTREG(MGAREG_FXLEFT, 0);
+               PRIMOUTREG(MGAREG_FXRIGHT, 1);
+               PRIMOUTREG(MGAREG_DWGCTL, MGA_FLUSH_CMD);
 
-                       PRIMOUTREG(MGAREG_TEXCTL2, 0 | 0x00008000);
-                       PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0);
-                       PRIMOUTREG(MGAREG_TEXCTL2, 0x80 | 0x00008000);
-                       PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0);
-               }
+               PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 1);
+               PRIMOUTREG(MGAREG_DMAPAD, 0);
+               PRIMOUTREG(MGAREG_DWGSYNC, 0x7000);
+               PRIMOUTREG(MGAREG_DMAPAD, 0);
+
+               PRIMOUTREG(MGAREG_TEXCTL2, 0 | 0x00008000);
+               PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0);
+               PRIMOUTREG(MGAREG_TEXCTL2, 0 | 0x00008000);
+               PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 0);
 
                PRIMOUTREG(MGAREG_WVRTXSZ, 0x00001807);
                PRIMOUTREG(MGAREG_DMAPAD, 0);
@@ -314,13 +347,16 @@ static void mgaG400EmitPipe(drm_mga_private_t * dev_priv)
        PRIMOUTREG(0x2d00 + 52 * 4, 0x40);      /* Tex stage 1 : w */
        PRIMOUTREG(0x2d00 + 60 * 4, 0x40);      /* Tex stage 1 : h */
 
-       /* Dma pading required due to hw bug */
-       PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
-       PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
-       PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
-       PRIMOUTREG(MGAREG_WIADDR2,
-                  (u32) (dev_priv->WarpIndex[pipe].
-                         phys_addr | WIA_wmode_start | WIA_wagp_agp));
+       if (dev_priv->WarpPipe != pipe || 1) {
+               /* Dma pading required due to hw bug */
+               PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
+               PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
+               PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
+               PRIMOUTREG(MGAREG_WIADDR2,
+                          (u32) (dev_priv->WarpIndex[pipe].phys_addr |
+                                 WIA_wmode_start | WIA_wagp_agp));
+       }
+
        PRIMADVANCE(dev_priv);
 }
 
@@ -363,11 +399,20 @@ static void mgaEmitState(drm_mga_private_t * dev_priv)
        DRM_DEBUG("%s\n", __FUNCTION__);
 
        if (dev_priv->chipset == MGA_CARD_TYPE_G400) {
-               int multitex = sarea_priv->WarpPipe & MGA_T2;
+               int multitex = (sarea_priv->TexState[0][MGA_TEXREG_CTL2] & 
+                               TMC_dualtex_enable);
 
-               if (sarea_priv->WarpPipe != dev_priv->WarpPipe) {
+               dirty = ~0; 
+
+               if (dirty & MGA_UPLOAD_PIPE
+/*                 && (sarea_priv->WarpPipe != dev_priv->WarpPipe || */
+/*                     sarea_priv->vertexsize != dev_priv->vertexsize) */
+                  )
+               {
                        mgaG400EmitPipe(dev_priv);
                        dev_priv->WarpPipe = sarea_priv->WarpPipe;
+                       dev_priv->vertexsize = sarea_priv->vertexsize;
+                       sarea_priv->dirty &= ~MGA_UPLOAD_PIPE;
                }
 
                if (dirty & MGA_UPLOAD_CTX) {
@@ -380,8 +425,11 @@ static void mgaEmitState(drm_mga_private_t * dev_priv)
                        sarea_priv->dirty &= ~MGA_UPLOAD_TEX0;
                }
 
-               if ((dirty & MGA_UPLOAD_TEX1) && multitex) {
-                       mgaG400EmitTex1(dev_priv);
+               if (dirty & MGA_UPLOAD_TEX1) {
+                       if (multitex)
+                               mgaG400EmitTex1(dev_priv, 1);
+                       else
+                               mgaG400EmitTex1(dev_priv, 0);
                        sarea_priv->dirty &= ~MGA_UPLOAD_TEX1;
                }
        } else {
@@ -558,6 +606,9 @@ static void mga_dma_dispatch_vertex(drm_device_t * dev, drm_buf_t * buf)
                PRIM_OVERFLOW(dev, dev_priv,
                              (MAX_STATE_SIZE + (5 * MGA_NR_SAREA_CLIPRECTS)));
                mgaEmitState(dev_priv);
+
+/*             length = dev_priv->vertexsize * 3 * 4; */
+
                do {
                        if (i < sarea_priv->nbox) {
                                DRM_DEBUG("idx %d Emit box %d/%d:"
@@ -644,6 +695,7 @@ static void mga_dma_dispatch_indices(drm_device_t * dev,
                                    SETADD_mode_vertlist));
                        PRIMOUTREG(MGAREG_SETUPEND,
                                   ((address + end) | use_agp));
+/*                                ((address + start + 12) | use_agp)); */
                        PRIMADVANCE(dev_priv);
                } while (++i < sarea_priv->nbox);
        }
@@ -658,7 +710,9 @@ static void mga_dma_dispatch_indices(drm_device_t * dev,
 
 static void mga_dma_dispatch_clear(drm_device_t * dev, int flags,
                                   unsigned int clear_color,
-                                  unsigned int clear_zval)
+                                  unsigned int clear_zval,
+                                  unsigned int clear_colormask,
+                                  unsigned int clear_depthmask)
 {
        drm_mga_private_t *dev_priv = dev->dev_private;
        drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
@@ -687,7 +741,7 @@ static void mga_dma_dispatch_clear(drm_device_t * dev, int flags,
                if (flags & MGA_FRONT) {
                        DRM_DEBUG("clear front\n");
                        PRIMOUTREG(MGAREG_DMAPAD, 0);
-                       PRIMOUTREG(MGAREG_DMAPAD, 0);
+                       PRIMOUTREG(MGAREG_PLNWT, clear_colormask);
                        PRIMOUTREG(MGAREG_YDSTLEN,
                                   (pbox[i].y1 << 16) | height);
                        PRIMOUTREG(MGAREG_FXBNDRY,
@@ -702,7 +756,7 @@ static void mga_dma_dispatch_clear(drm_device_t * dev, int flags,
                if (flags & MGA_BACK) {
                        DRM_DEBUG("clear back\n");
                        PRIMOUTREG(MGAREG_DMAPAD, 0);
-                       PRIMOUTREG(MGAREG_DMAPAD, 0);
+                       PRIMOUTREG(MGAREG_PLNWT, clear_colormask);
                        PRIMOUTREG(MGAREG_YDSTLEN,
                                   (pbox[i].y1 << 16) | height);
                        PRIMOUTREG(MGAREG_FXBNDRY,
@@ -717,7 +771,7 @@ static void mga_dma_dispatch_clear(drm_device_t * dev, int flags,
                if (flags & MGA_DEPTH) {
                        DRM_DEBUG("clear depth\n");
                        PRIMOUTREG(MGAREG_DMAPAD, 0);
-                       PRIMOUTREG(MGAREG_DMAPAD, 0);
+                       PRIMOUTREG(MGAREG_PLNWT, clear_depthmask);
                        PRIMOUTREG(MGAREG_YDSTLEN,
                                   (pbox[i].y1 << 16) | height);
                        PRIMOUTREG(MGAREG_FXBNDRY,
@@ -818,7 +872,10 @@ int mga_clear_bufs(struct inode *inode, struct file *filp,
         */
        dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CTX;
        mga_dma_dispatch_clear(dev, clear.flags,
-                              clear.clear_color, clear.clear_depth);
+                              clear.clear_color, 
+                              clear.clear_depth,
+                              clear.clear_color_mask,
+                              clear.clear_depth_mask);
        PRIMUPDATE(dev_priv);
 #ifdef __i386__
        mga_flush_write_combine();