summaryrefslogtreecommitdiff
path: root/linux/mga_state.c
diff options
context:
space:
mode:
authorKeith Whitwell <keith@tungstengraphics.com>2000-08-30 22:34:28 +0000
committerKeith Whitwell <keith@tungstengraphics.com>2000-08-30 22:34:28 +0000
commit926349534d4a20b8dc4f795e41055540ad48d112 (patch)
tree2b0e678708ba7dc3a625abdb625989dc609bfef9 /linux/mga_state.c
parent32cebaf750b82639822f5f50d0aa8a4417595ada (diff)
Initialize vertsize correctly. Add planemask arguments for color and depth
stencil clearing.
Diffstat (limited to 'linux/mga_state.c')
-rw-r--r--linux/mga_state.c143
1 files changed, 100 insertions, 43 deletions
diff --git a/linux/mga_state.c b/linux/mga_state.c
index 5a9c7632..c8963964 100644
--- a/linux/mga_state.c
+++ b/linux/mga_state.c
@@ -39,11 +39,11 @@
*/
#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();