Initialize vertsize correctly. Add planemask arguments for color and depth

stencil clearing.
main
Keith Whitwell 2000-08-30 22:34:28 +00:00
parent 32cebaf750
commit 926349534d
4 changed files with 120 additions and 57 deletions

View 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,

View File

@ -73,17 +73,19 @@
/* 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 {

View 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); \

View File

@ -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);
/* 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);
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, 0x80 | 0x00008000);
PRIMOUTREG(MGAREG_LEN + MGAREG_MGA_EXEC, 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();