Change to copy state snapshots for each TT_VERTEX buffer.

Change to make sure only a single dma queue is in use. Removed PRIORITY and
    a bunch of other non-relevent dma code.
General cleanup of mga_dma.c
This commit is contained in:
Keith Whitwell 2000-02-06 18:50:35 +00:00
parent 7a83054959
commit 12ddd18ce8
12 changed files with 766 additions and 1023 deletions

View file

@ -262,8 +262,7 @@ typedef struct drm_buf {
} list; /* Which list we're on */
int type; /* push into dev_priv? */
void *dev_priv;
void *dev_private;
#if DRM_DMA_HISTOGRAM
@ -704,6 +703,12 @@ extern int drm_lock_free(drm_device_t *dev,
unsigned int context);
extern int drm_finish(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
/* Let a driver manage a single queue efficiently:
*/
extern int drm_flush_queue(drm_device_t *dev, int context);
extern int drm_flush_unblock_queue(drm_device_t *dev, int context);
extern int drm_flush_unblock(drm_device_t *dev, int context,
drm_lock_flags_t flags);
extern int drm_flush_block_and_flush(drm_device_t *dev, int context,

View file

@ -199,9 +199,7 @@ static int mga_setup(drm_device_t *dev)
dev->last_checked = 0;
init_timer(&dev->timer);
init_waitqueue_head(&dev->context_wait);
#if DRM_DMA_HISTO
memset(&dev->histo, 0, sizeof(dev->histo));
#endif
dev->ctx_start = 0;
dev->lck_start = 0;
@ -572,16 +570,11 @@ int mga_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
atomic_inc(&dev->total_contends);
drm_lock_transfer(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT);
mga_dma_schedule(dev, 1);
if (!dev->context_flag) {
if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
DRM_KERNEL_CONTEXT)) {
DRM_ERROR("\n");
}
if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
DRM_KERNEL_CONTEXT)) {
DRM_ERROR("\n");
}
#if DRM_DMA_HISTOGRAM
atomic_inc(&dev->histo.lhld[drm_histogram_slot(get_cycles()
- dev->lck_start)]);
#endif
return 0;
}

View file

@ -262,8 +262,7 @@ typedef struct drm_buf {
} list; /* Which list we're on */
int type; /* push into dev_priv? */
void *dev_priv;
void *dev_private;
#if DRM_DMA_HISTOGRAM
@ -704,6 +703,12 @@ extern int drm_lock_free(drm_device_t *dev,
unsigned int context);
extern int drm_finish(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
/* Let a driver manage a single queue efficiently:
*/
extern int drm_flush_queue(drm_device_t *dev, int context);
extern int drm_flush_unblock_queue(drm_device_t *dev, int context);
extern int drm_flush_unblock(drm_device_t *dev, int context,
drm_lock_flags_t flags);
extern int drm_flush_block_and_flush(drm_device_t *dev, int context,

View file

@ -117,7 +117,7 @@ int drm_lock_free(drm_device_t *dev,
return 0;
}
static int drm_flush_queue(drm_device_t *dev, int context)
int drm_flush_queue(drm_device_t *dev, int context)
{
DECLARE_WAITQUEUE(entry, current);
int ret = 0;
@ -151,7 +151,7 @@ static int drm_flush_queue(drm_device_t *dev, int context)
return ret;
}
static int drm_flush_unblock_queue(drm_device_t *dev, int context)
int drm_flush_unblock_queue(drm_device_t *dev, int context)
{
drm_queue_t *q = dev->queuelist[context];

View file

@ -33,8 +33,10 @@
#define __NO_VERSION__
#include "drmP.h"
#include "mga_drv.h"
#include "mga_dma.h"
#include "linux/un.h"
int mga_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
@ -110,6 +112,7 @@ int mga_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd,
entry->buf_size = size;
entry->page_order = page_order;
offset = 0;
while(entry->buf_count < count) {
buf = &entry->buflist[entry->buf_count];
@ -128,6 +131,10 @@ int mga_addbufs_agp(struct inode *inode, struct file *filp, unsigned int cmd,
buf->pending = 0;
init_waitqueue_head(&buf->dma_wait);
buf->pid = 0;
buf->dev_private = drm_alloc(sizeof(drm_mga_buf_priv_t), DRM_MEM_BUFS);
#if DRM_DMA_HISTOGRAM
buf->time_queued = 0;
buf->time_dispatched = 0;

View file

@ -34,6 +34,7 @@
#include "mga_drv.h"
#include "mgareg_flags.h"
#include "mga_dma.h"
#include "mga_state.h"
#define MGA_CLEAR_CMD (DC_opcod_trap | DC_arzero_enable | \
DC_sgnzero_enable | DC_shftzero_enable | \
@ -48,6 +49,12 @@
DC_pattern_disable | DC_transc_disable | \
DC_clipdis_enable) \
/* Build and queue a TT_GENERAL secondary buffer to do the clears.
* With Jeff's ringbuffer idea, it might make sense if there are only
* one or two cliprects to emit straight to the primary buffer.
*/
static int mgaClearBuffers(drm_device_t *dev,
int clear_color,
int clear_depth,
@ -61,7 +68,7 @@ static int mgaClearBuffers(drm_device_t *dev,
int nbox = sarea_priv->nbox;
drm_buf_t *buf;
drm_dma_t d;
int order = 10; /* ??? */
int order = 10; /* ??? what orders do we have ???*/
DMALOCALS;
@ -119,6 +126,8 @@ static int mgaClearBuffers(drm_device_t *dev,
*/
sarea_priv->dirty |= MGASAREA_NEW_CONTEXT;
((drm_mga_buf_priv_t *)buf->dev_private)->dma_type = MGA_DMA_GENERAL;
d.context = DRM_KERNEL_CONTEXT;
d.send_count = 1;
d.send_indices = &buf->idx;
@ -131,6 +140,7 @@ static int mgaClearBuffers(drm_device_t *dev,
d.granted_count = 0;
drm_dma_enqueue(dev, &d);
mga_dma_schedule(dev, 1);
return 0;
}
@ -186,6 +196,8 @@ int mgaSwapBuffers(drm_device_t *dev, int flags)
*/
sarea_priv->dirty |= MGASAREA_NEW_CONTEXT;
((drm_mga_buf_priv_t *)buf->dev_private)->dma_type = MGA_DMA_GENERAL;
d.context = DRM_KERNEL_CONTEXT;
d.send_count = 1;
d.send_indices = &buf->idx;
@ -198,56 +210,148 @@ int mgaSwapBuffers(drm_device_t *dev, int flags)
d.granted_count = 0;
drm_dma_enqueue(dev, &d);
mga_dma_schedule(dev, 1);
return 0;
}
static int mgaIload( drm_device_t *dev, drm_mga_iload_t *args )
{
return 0;
}
/* Necessary? Not necessary??
*/
static int check_lock( void )
{
return 1;
}
int mga_clear_bufs(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_mga_clear_t clear;
int retcode;
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_mga_clear_t clear;
int retcode;
copy_from_user_ret(&clear, (drm_mga_clear_t *)arg,
sizeof(clear), -EFAULT);
copy_from_user_ret(&clear, (drm_mga_clear_t *)arg,
sizeof(clear), -EFAULT);
retcode = mgaClearBuffers(dev, clear.clear_color,
clear.clear_depth,
clear.flags);
/* if (!check_lock( dev )) */
/* return -EIEIO; */
retcode = mgaClearBuffers(dev, clear.clear_color,
clear.clear_depth,
clear.flags);
return retcode;
return retcode;
}
int mga_swap_bufs(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_mga_swap_t swap;
int retcode = 0;
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_mga_swap_t swap;
int retcode = 0;
/* if (!check_lock( dev )) */
/* return -EIEIO; */
copy_from_user_ret(&swap, (drm_mga_swap_t *)arg,
sizeof(swap), -EFAULT);
copy_from_user_ret(&swap, (drm_mga_swap_t *)arg,
sizeof(swap), -EFAULT);
retcode = mgaSwapBuffers(dev, swap.flags);
retcode = mgaSwapBuffers(dev, swap.flags);
return retcode;
return retcode;
}
int mga_iload(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_mga_iload_t iload;
int retcode = 0;
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_mga_iload_t iload;
int retcode = 0;
copy_from_user_ret(&iload, (drm_mga_iload_t *)arg,
sizeof(iload), -EFAULT);
/* if (!check_lock( dev )) */
/* return -EIEIO; */
copy_from_user_ret(&iload, (drm_mga_iload_t *)arg,
sizeof(iload), -EFAULT);
retcode = mgaIload(dev, &iload);
retcode = mgaIload(dev, &iload);
return retcode;
return retcode;
}
int mga_dma(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_device_dma_t *dma = dev->dma;
int retcode = 0;
drm_dma_t d;
copy_from_user_ret(&d, (drm_dma_t *)arg, sizeof(d), -EFAULT);
DRM_DEBUG("%d %d: %d send, %d req\n",
current->pid, d.context, d.send_count, d.request_count);
/* Per-context queues are unworkable if you are trying to do
* state management from the client.
*/
d.context = DRM_KERNEL_CONTEXT;
d.flags &= ~_DRM_DMA_WHILE_LOCKED;
/* Maybe multiple buffers is useful for iload...
* But this ioctl is only for *despatching* vertex data...
*/
if (d.send_count < 0 || d.send_count > 1) {
DRM_ERROR("Process %d trying to send %d buffers (max 1)\n",
current->pid, d.send_count);
return -EINVAL;
}
/* But it *is* used to request buffers for all types of dma:
*/
if (d.request_count < 0 || d.request_count > dma->buf_count) {
DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
current->pid, d.request_count, dma->buf_count);
return -EINVAL;
}
if (d.send_count) {
drm_mga_buf_priv_t *buf_priv = d.buflist[0]->dev_private;
drm_mga_private_t *dev_priv = dev->dev_private;
buf_priv->dma_type = MGA_DMA_VERTEX;
/* if (!check_lock( dev )) */
/* return -EIEIO; */
/* Snapshot the relevent bits of the sarea...
*/
mgaCopyAndVerifyState( dev );
retcode = drm_dma_enqueue(dev, &d);
mga_dma_schedule(dev, 1);
}
d.granted_count = 0;
if (!retcode && d.request_count) {
retcode = drm_dma_get_buffers(dev, &d);
}
DRM_DEBUG("%d returning, granted = %d\n",
current->pid, d.granted_count);
copy_to_user_ret((drm_dma_t *)arg, &d, sizeof(d), -EFAULT);
return retcode;
}

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,31 @@
#ifndef MGA_DMA_H
#define MGA_DMA_H
#include "mga_drm_public.h"
/* Isn't this fun. This has to be fixed asap by emitting primary
* dma commands in the 'do_dma' ioctl.
*/
typedef struct {
int dma_type;
unsigned int ContextState[MGA_CTX_SETUP_SIZE];
unsigned int TexState[2][MGA_TEX_SETUP_SIZE];
unsigned int WarpPipe;
unsigned int dirty;
unsigned int nbox;
xf86drmClipRectRec boxes[MGA_NR_SAREA_CLIPRECTS];
} drm_mga_buf_priv_t;
#define MGA_DMA_GENERAL 0
#define MGA_DMA_VERTEX 1
#define MGA_DMA_SETUP 2
#define MGA_DMA_ILOAD 3
#define DWGREG0 0x1c00
#define DWGREG0_END 0x1dff
@ -40,18 +65,40 @@
} \
}while (0)
/* Not used for emitting state, as we assume the state will always fit
* in a single buffer.
*
* For clip/swap -- choose a maximum number of cliprects so that a single
* buffer is always sufficient?
*
* For vertex cliprects -- ???
/* Primary buffer versions of above -- pretty similar really.
*/
#define CHECK_OVERFLOW(length) do { \
if (buf->total - buf->used < length * 4) \
mga_prim_overflow(dev); \
}while(0)
#define PRIMLOCALS u8 tempIndex[4]; u32 *dma_ptr; u32 phys_head; \
int outcount, num_dwords
#define PRIMRESET(dev_priv) do { \
dev_priv->prim_num_dwords = 0; \
dev_priv->current_dma_ptr = dev_priv->prim_head; \
} while (0)
#define PRIMGETPTR(dev_priv) do { \
dma_ptr = dev_priv->current_dma_ptr; \
phys_head = dev_priv->prim_phys_head; \
num_dwords = dev_priv->prim_num_dwords; \
outcount = 0; \
} while (0)
#define PRIMADVANCE(dev_priv) do { \
dev_priv->prim_num_dwords = num_dwords; \
dev_priv->current_dma_ptr = dma_ptr; \
} while (0)
#define PRIMOUTREG(reg, val) do { \
tempIndex[outcount]=ADRINDEX(reg); \
dma_ptr[1+outcount] = val; \
if( ++outcount == 4) { \
outcount = 0; \
dma_ptr[0] = *(u32 *)tempIndex; \
dma_ptr+=5; \
num_dwords += 5; \
} \
}while (0)
#endif

View file

@ -92,6 +92,13 @@ typedef struct drm_mga_init {
int sgram;
int chipset;
mgaWarpIndex WarpIndex[MGA_MAX_WARP_PIPES];
/* Redundant?
*/
int frontOrg;
int backOrg;
int depthOrg;
int mAccess;
} drm_mga_init_t;
@ -108,28 +115,28 @@ typedef struct _xf86drmClipRectRec {
#define MGA_CLEAR_BACKBUFFER 0x2
#define MGA_CLEAR_DEPTHBUFFER 0x4
typedef struct drm_mga_clear {
typedef struct {
int clear_color;
int clear_depth;
int flags;
} drm_mga_clear_t;
typedef struct drm_mga_swap {
typedef struct {
int flags; /* not actually used? */
} drm_mga_swap_t;
/* These were context regs, but are constant under the DRI:
*/
#define MGA_CONST_PITCH 0 /* constant */
#define MGA_CONST_ZORG 7 /* constant */
typedef struct {
unsigned int destOrg;
unsigned int mAccess;
unsigned int pitch;
unsigned int x,y,width,height;
} drm_mga_iload_t;
/* Each context has a state:
*/
#define MGA_CTXREG_DSTORG 0 /* top of either front or backbuffer */
#define MGA_CTXREG_MACCESS 1 /* constant -- except for fog enable */
#define MGA_CTXREG_PLNWT 2 /* */
#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
@ -138,40 +145,13 @@ typedef struct drm_mga_swap {
#define MGA_CTXREG_TDUAL1 8
#define MGA_CTX_SETUP_SIZE 9
/* Clipper registers - these #defines aren't used.
*/
#define MGA_CLIPREG_CXBNDRY 0
#define MGA_CLIPREG_YTOP 1
#define MGA_CLIPREG_YBOT 2
/* Do we restore the server state ourselves, or let the X server do
* it after contention? The contended case seems hard to find
* in WakeupHandler.
*
* We need to at least *know* the X server state in order to emit
* swapbuffers and clear-front-buffer requests.
*
* This state is *constant*:
*/
#define MGA_2DREG_YDSTORG 0
#define MGA_2DREG_MACCESS 1
#define MGA_2DREG_PITCH 2
#define MGA_2DREG_DSTORG 3
#define MGA_2DREG_DWGCTL 4
#define MGA_2DREG_CXBNDRY 5
#define MGA_2DREG_YTOP 6
#define MGA_2DREG_YBOT 7
#define MGA_2DREG_PLNWT 8 /* write mask -- must be restored */
#define MGA_2D_SETUP_SIZE 9
/* Each texture unit has a state:
*/
#define MGA_TEXREG_CTL 0
#define MGA_TEXREG_CTL2 1
#define MGA_TEXREG_FILTER 2
#define MGA_TEXREG_BORDERCOL 3
#define MGA_TEXREG_ORG 4 /* insecure -- validate? */
#define MGA_TEXREG_ORG 4 /* validated */
#define MGA_TEXREG_ORG1 5
#define MGA_TEXREG_ORG2 6
#define MGA_TEXREG_ORG3 7
@ -181,35 +161,44 @@ typedef struct drm_mga_swap {
#define MGA_TEX_SETUP_SIZE 11
/* Keep this small for testing
*/
#define MGA_NR_SAREA_CLIPRECTS 2
/* Not useful?
/* What needs to be changed for the current vertex dma buffer?
*/
#define MGASAREA_NEW_CONTEXT 0x1
#define MGASAREA_NEW_TEX0 0x2
#define MGASAREA_NEW_TEX1 0x4
#define MGASAREA_NEW_PIPE 0x8
#define MGASAREA_NEW_2D_CONTEXT 0x10 /* does it ever happen? */
/* Keep this small for testing
*/
#define MGA_NR_SAREA_CLIPRECTS 2
typedef struct _drm_mga_sarea {
unsigned int ServerState[MGA_2D_SETUP_SIZE];
/* Upto 128 regions. Minimum region size of 256k.
*/
#define MGA_NR_TEX_REGIONS 128
#define MGA_MIN_LOG_TEX_GRANULARITY 18
typedef struct {
unsigned char next, prev;
unsigned char in_use;
int age;
} mgaTexRegion;
typedef struct
{
unsigned int ContextState[MGA_CTX_SETUP_SIZE];
unsigned int Tex0State[MGA_TEX_SETUP_SIZE];
unsigned int Tex1State[MGA_TEX_SETUP_SIZE];
unsigned int TexState[2][MGA_TEX_SETUP_SIZE];
unsigned int WarpPipe;
unsigned int dirty;
unsigned int nbox;
xf86drmClipRectRec boxes[MGA_NR_SAREA_CLIPRECTS];
int CtxOwner; /* kernel doesn't touch from here down */
int TexOwner;
} drm_mga_sarea_t;
/* kernel doesn't touch from here down */
int ctxOwner;
mgaTexRegion texList[MGA_NR_TEX_REGIONS+1];
int texAge;
} drm_mga_sarea_t;

View file

@ -199,9 +199,7 @@ static int mga_setup(drm_device_t *dev)
dev->last_checked = 0;
init_timer(&dev->timer);
init_waitqueue_head(&dev->context_wait);
#if DRM_DMA_HISTO
memset(&dev->histo, 0, sizeof(dev->histo));
#endif
dev->ctx_start = 0;
dev->lck_start = 0;
@ -572,16 +570,11 @@ int mga_unlock(struct inode *inode, struct file *filp, unsigned int cmd,
atomic_inc(&dev->total_contends);
drm_lock_transfer(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT);
mga_dma_schedule(dev, 1);
if (!dev->context_flag) {
if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
DRM_KERNEL_CONTEXT)) {
DRM_ERROR("\n");
}
if (drm_lock_free(dev, &dev->lock.hw_lock->lock,
DRM_KERNEL_CONTEXT)) {
DRM_ERROR("\n");
}
#if DRM_DMA_HISTOGRAM
atomic_inc(&dev->histo.lhld[drm_histogram_slot(get_cycles()
- dev->lck_start)]);
#endif
return 0;
}

View file

@ -35,16 +35,14 @@
#include "mga_drv.h"
#include "mgareg_flags.h"
#include "mga_dma.h"
#include "mga_state.h"
#include "drm.h"
#if 0
/* How does this work???
*/
int mgaEmitClipRect(drm_device_t *dev, xf86drmClipRectRec *box)
void mgaEmitClipRect( drm_mga_private_t *dev_priv, xf86drmClipRectRec *box )
{
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int *regs = sarea_priv->ContextState;
PRIMLOCALS;
PRIMGETPTR( dev_priv );
/* The G400 seems to have an issue with the second WARP not
* stalling clipper register writes. This bothers me, but the only
@ -52,328 +50,313 @@ int mgaEmitClipRect(drm_device_t *dev, xf86drmClipRectRec *box)
* circumstances is by inserting TWO dwgsync commands.
*/
if (dev_priv->chipset == MGA_CARD_TYPE_G400) {
DMAOUTREG( MGAREG_DWGSYNC, 0 );
DMAOUTREG( MGAREG_DWGSYNC, 0 );
PRIMOUTREG( MGAREG_DWGSYNC, 0 );
PRIMOUTREG( MGAREG_DWGSYNC, 0 );
}
DMAOUTREG( MGAREG_CXBNDRY, ((box->x2)<<16)|(box->x1) );
DMAOUTREG( MGAREG_YTOP, box->y1 * dev_priv->pitch );
DMAOUTREG( MGAREG_YBOT, box->y2 * dev_priv->pitch );
DMAADVANCE();
return 0;
PRIMOUTREG( MGAREG_CXBNDRY, ((box->x2)<<16)|(box->x1) );
PRIMOUTREG( MGAREG_YTOP, box->y1 * dev_priv->stride );
PRIMOUTREG( MGAREG_YBOT, box->y2 * dev_priv->stride );
PRIMADVANCE( dev_priv );
}
#endif
static int mgaEmitContext(drm_device_t *dev, drm_buf_t *buf)
static void mgaEmitContext(drm_mga_private_t *dev_priv,
drm_mga_buf_priv_t *buf_priv)
{
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int *regs = sarea_priv->ContextState;
DMALOCALS;
unsigned int *regs = buf_priv->ContextState;
PRIMLOCALS;
/* Disallow all write destinations except the front and backbuffer.
*/
if (regs[MGA_CTXREG_DSTORG] != dev_priv->frontOrg &&
regs[MGA_CTXREG_DSTORG] != dev_priv->backOrg)
return -1;
DMAGETPTR( buf );
DMAOUTREG( MGAREG_DSTORG, regs[MGA_CTXREG_DSTORG] );
DMAOUTREG( MGAREG_MACCESS, regs[MGA_CTXREG_MACCESS] );
DMAOUTREG( MGAREG_PLNWT, regs[MGA_CTXREG_PLNWT] );
DMAOUTREG( MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL] );
DMAOUTREG( MGAREG_ALPHACTRL, regs[MGA_CTXREG_ALPHACTRL] );
DMAOUTREG( MGAREG_FOGCOL, regs[MGA_CTXREG_FOGCOLOR] );
DMAOUTREG( MGAREG_WFLAG, regs[MGA_CTXREG_WFLAG] );
PRIMGETPTR( dev_priv );
PRIMOUTREG( MGAREG_DSTORG, regs[MGA_CTXREG_DSTORG] );
PRIMOUTREG( MGAREG_MACCESS, regs[MGA_CTXREG_MACCESS] );
PRIMOUTREG( MGAREG_PLNWT, regs[MGA_CTXREG_PLNWT] );
PRIMOUTREG( MGAREG_DWGCTL, regs[MGA_CTXREG_DWGCTL] );
PRIMOUTREG( MGAREG_ALPHACTRL, regs[MGA_CTXREG_ALPHACTRL] );
PRIMOUTREG( MGAREG_FOGCOL, regs[MGA_CTXREG_FOGCOLOR] );
PRIMOUTREG( MGAREG_WFLAG, regs[MGA_CTXREG_WFLAG] );
if (dev_priv->chipset == MGA_CARD_TYPE_G400) {
DMAOUTREG( MGAREG_WFLAG1, regs[MGA_CTXREG_WFLAG] );
DMAOUTREG( MGAREG_TDUALSTAGE0, regs[MGA_CTXREG_TDUAL0] );
DMAOUTREG( MGAREG_TDUALSTAGE1, regs[MGA_CTXREG_TDUAL1] );
PRIMOUTREG( MGAREG_WFLAG1, regs[MGA_CTXREG_WFLAG] );
PRIMOUTREG( MGAREG_TDUALSTAGE0, regs[MGA_CTXREG_TDUAL0] );
PRIMOUTREG( MGAREG_TDUALSTAGE1, regs[MGA_CTXREG_TDUAL1] );
}
DMAADVANCE( buf );
return 0;
PRIMADVANCE( dev_priv );
}
/* The texture state routines are quite similar, but are a real mess
* when integrated into a single function.
*/
static int mgaG200EmitTex(drm_device_t *dev, drm_buf_t *buf)
static void mgaG200EmitTex( drm_mga_private_t *dev_priv,
drm_mga_buf_priv_t *buf_priv )
{
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int *regs = sarea_priv->Tex0State;
unsigned int *regs = buf_priv->TexState[0];
PRIMLOCALS;
DMALOCALS;
/* Disallow texture reads from PCI space.
*/
if ((regs[MGA_TEXREG_ORG] & 0x3) == 0x1)
return -1;
DMAGETPTR( buf );
DMAOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] );
DMAOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL] );
DMAOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER] );
DMAOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL] );
DMAOUTREG(MGAREG_TEXORG, regs[MGA_TEXREG_ORG] );
DMAOUTREG(MGAREG_TEXORG1, regs[MGA_TEXREG_ORG1] );
DMAOUTREG(MGAREG_TEXORG2, regs[MGA_TEXREG_ORG2] );
DMAOUTREG(MGAREG_TEXORG3, regs[MGA_TEXREG_ORG3] );
DMAOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4] );
DMAOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH] );
DMAOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] );
PRIMGETPTR( dev_priv );
PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] );
PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL] );
PRIMOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER] );
PRIMOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL] );
PRIMOUTREG(MGAREG_TEXORG, regs[MGA_TEXREG_ORG] );
PRIMOUTREG(MGAREG_TEXORG1, regs[MGA_TEXREG_ORG1] );
PRIMOUTREG(MGAREG_TEXORG2, regs[MGA_TEXREG_ORG2] );
PRIMOUTREG(MGAREG_TEXORG3, regs[MGA_TEXREG_ORG3] );
PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4] );
PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH] );
PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] );
DMAOUTREG(0x2d00 + 24*4, regs[MGA_TEXREG_WIDTH] );
DMAOUTREG(0x2d00 + 34*4, regs[MGA_TEXREG_HEIGHT] );
PRIMOUTREG(0x2d00 + 24*4, regs[MGA_TEXREG_WIDTH] );
PRIMOUTREG(0x2d00 + 34*4, regs[MGA_TEXREG_HEIGHT] );
DMAADVANCE( buf );
return 0;
PRIMADVANCE( dev_priv );
}
static int mgaG400EmitTex0( drm_device_t *dev, drm_buf_t *buf )
static void mgaG400EmitTex0( drm_mga_private_t *dev_priv,
drm_mga_buf_priv_t *buf_priv )
{
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int *regs = sarea_priv->Tex0State;
int multitex = sarea_priv->WarpPipe & MGA_T2;
unsigned int *regs = buf_priv->TexState[0];
int multitex = buf_priv->WarpPipe & MGA_T2;
DMALOCALS;
DMAGETPTR( buf );
PRIMLOCALS;
PRIMGETPTR( dev_priv );
/* Disallow texture reads from PCI space.
*/
if ((regs[MGA_TEXREG_ORG] & 0x3) == 0x1)
return -1;
DMAOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] );
DMAOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL] );
DMAOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER] );
DMAOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL] );
DMAOUTREG(MGAREG_TEXORG, regs[MGA_TEXREG_ORG] );
DMAOUTREG(MGAREG_TEXORG1, regs[MGA_TEXREG_ORG1] );
DMAOUTREG(MGAREG_TEXORG2, regs[MGA_TEXREG_ORG2] );
DMAOUTREG(MGAREG_TEXORG3, regs[MGA_TEXREG_ORG3] );
DMAOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4] );
DMAOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH] );
DMAOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] );
PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] );
PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL] );
PRIMOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER] );
PRIMOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL] );
PRIMOUTREG(MGAREG_TEXORG, regs[MGA_TEXREG_ORG] );
PRIMOUTREG(MGAREG_TEXORG1, regs[MGA_TEXREG_ORG1] );
PRIMOUTREG(MGAREG_TEXORG2, regs[MGA_TEXREG_ORG2] );
PRIMOUTREG(MGAREG_TEXORG3, regs[MGA_TEXREG_ORG3] );
PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4] );
PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH] );
PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] );
DMAOUTREG(0x2d00 + 49*4, 0);
DMAOUTREG(0x2d00 + 57*4, 0);
DMAOUTREG(0x2d00 + 53*4, 0);
DMAOUTREG(0x2d00 + 61*4, 0);
PRIMOUTREG(0x2d00 + 49*4, 0);
PRIMOUTREG(0x2d00 + 57*4, 0);
PRIMOUTREG(0x2d00 + 53*4, 0);
PRIMOUTREG(0x2d00 + 61*4, 0);
if (!multitex) {
DMAOUTREG(0x2d00 + 52*4, 0x40 );
DMAOUTREG(0x2d00 + 60*4, 0x40 );
PRIMOUTREG(0x2d00 + 52*4, 0x40 );
PRIMOUTREG(0x2d00 + 60*4, 0x40 );
}
DMAOUTREG(0x2d00 + 54*4, regs[MGA_TEXREG_WIDTH] | 0x40 );
DMAOUTREG(0x2d00 + 62*4, regs[MGA_TEXREG_HEIGHT] | 0x40 );
PRIMOUTREG(0x2d00 + 54*4, regs[MGA_TEXREG_WIDTH] | 0x40 );
PRIMOUTREG(0x2d00 + 62*4, regs[MGA_TEXREG_HEIGHT] | 0x40 );
DMAADVANCE( buf );
return 0;
PRIMADVANCE( dev_priv );
}
#define TMC_map1_enable 0x80000000
static int mgaG400EmitTex1( drm_device_t *dev, drm_buf_t *buf )
static void mgaG400EmitTex1( drm_mga_private_t *dev_priv,
drm_mga_buf_priv_t *buf_priv )
{
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int *regs = sarea_priv->Tex1State;
unsigned int *regs = sarea_priv->TexState[1];
DMALOCALS;
DMAGETPTR(buf);
PRIMLOCALS;
PRIMGETPTR(dev_priv);
/* Disallow texture reads from PCI space.
*/
if ((regs[MGA_TEXREG_ORG] & 0x3) == 0x1)
return -1;
DMAOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] | TMC_map1_enable);
DMAOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL] );
DMAOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER] );
DMAOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL] );
DMAOUTREG(MGAREG_TEXORG, regs[MGA_TEXREG_ORG] );
DMAOUTREG(MGAREG_TEXORG1, regs[MGA_TEXREG_ORG1] );
DMAOUTREG(MGAREG_TEXORG2, regs[MGA_TEXREG_ORG2] );
DMAOUTREG(MGAREG_TEXORG3, regs[MGA_TEXREG_ORG3] );
DMAOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4] );
DMAOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH] );
DMAOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] );
PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] | TMC_map1_enable);
PRIMOUTREG(MGAREG_TEXCTL, regs[MGA_TEXREG_CTL] );
PRIMOUTREG(MGAREG_TEXFILTER, regs[MGA_TEXREG_FILTER] );
PRIMOUTREG(MGAREG_TEXBORDERCOL, regs[MGA_TEXREG_BORDERCOL] );
PRIMOUTREG(MGAREG_TEXORG, regs[MGA_TEXREG_ORG] );
PRIMOUTREG(MGAREG_TEXORG1, regs[MGA_TEXREG_ORG1] );
PRIMOUTREG(MGAREG_TEXORG2, regs[MGA_TEXREG_ORG2] );
PRIMOUTREG(MGAREG_TEXORG3, regs[MGA_TEXREG_ORG3] );
PRIMOUTREG(MGAREG_TEXORG4, regs[MGA_TEXREG_ORG4] );
PRIMOUTREG(MGAREG_TEXWIDTH, regs[MGA_TEXREG_WIDTH] );
PRIMOUTREG(MGAREG_TEXHEIGHT, regs[MGA_TEXREG_HEIGHT] );
DMAOUTREG(0x2d00 + 49*4, 0);
DMAOUTREG(0x2d00 + 57*4, 0);
DMAOUTREG(0x2d00 + 53*4, 0);
DMAOUTREG(0x2d00 + 61*4, 0);
PRIMOUTREG(0x2d00 + 49*4, 0);
PRIMOUTREG(0x2d00 + 57*4, 0);
PRIMOUTREG(0x2d00 + 53*4, 0);
PRIMOUTREG(0x2d00 + 61*4, 0);
DMAOUTREG(0x2d00 + 52*4, regs[MGA_TEXREG_WIDTH] | 0x40 );
DMAOUTREG(0x2d00 + 60*4, regs[MGA_TEXREG_HEIGHT] | 0x40 );
PRIMOUTREG(0x2d00 + 52*4, regs[MGA_TEXREG_WIDTH] | 0x40 );
PRIMOUTREG(0x2d00 + 60*4, regs[MGA_TEXREG_HEIGHT] | 0x40 );
DMAOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] );
PRIMOUTREG(MGAREG_TEXCTL2, regs[MGA_TEXREG_CTL2] );
DMAADVANCE( buf );
return 0;
PRIMADVANCE( dev_priv );
}
/* WIADDR might not work in sec bufs, might need to use
* the primary buffer
*/
static int mgaG400EmitPipe(drm_device_t *dev, drm_buf_t *buf)
static void mgaG400EmitPipe(drm_mga_private_t *dev_priv,
drm_mga_buf_priv_t *buf_priv)
{
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int pipe = sarea_priv->WarpPipe;
float fParam = 12800.0f;
DMALOCALS;
PRIMLOCALS;
if (pipe > MGA_MAX_G400_PIPES)
return -1;
DMAGETPTR(buf);
DMAOUTREG(MGAREG_WIADDR2, WIA_wmode_suspend);
PRIMGETPTR(dev_priv);
PRIMOUTREG(MGAREG_WIADDR2, WIA_wmode_suspend);
/* Establish vertex size.
*/
if (pipe & MGA_T2) {
DMAOUTREG(MGAREG_WVRTXSZ, 0x00001e09);
DMAOUTREG(MGAREG_WACCEPTSEQ, 0x1e000000);
PRIMOUTREG(MGAREG_WVRTXSZ, 0x00001e09);
PRIMOUTREG(MGAREG_WACCEPTSEQ, 0x1e000000);
} else {
DMAOUTREG(MGAREG_WVRTXSZ, 0x00001807);
DMAOUTREG(MGAREG_WACCEPTSEQ, 0x18000000);
PRIMOUTREG(MGAREG_WVRTXSZ, 0x00001807);
PRIMOUTREG(MGAREG_WACCEPTSEQ, 0x18000000);
}
DMAOUTREG(MGAREG_WFLAG, 0);
DMAOUTREG(MGAREG_WFLAG1, 0);
PRIMOUTREG(MGAREG_WFLAG, 0);
PRIMOUTREG(MGAREG_WFLAG1, 0);
DMAOUTREG(0x2d00 + 56*4, *((u32 *)(&fParam)));
DMAOUTREG(MGAREG_DMAPAD, 0);
DMAOUTREG(MGAREG_DMAPAD, 0);
PRIMOUTREG(0x2d00 + 56*4, *((u32 *)(&fParam)));
PRIMOUTREG(MGAREG_DMAPAD, 0);
PRIMOUTREG(MGAREG_DMAPAD, 0);
DMAOUTREG(0x2d00 + 49*4, 0); /* Tex stage 0 */
DMAOUTREG(0x2d00 + 57*4, 0); /* Tex stage 0 */
DMAOUTREG(0x2d00 + 53*4, 0); /* Tex stage 1 */
DMAOUTREG(0x2d00 + 61*4, 0); /* Tex stage 1 */
PRIMOUTREG(0x2d00 + 49*4, 0); /* Tex stage 0 */
PRIMOUTREG(0x2d00 + 57*4, 0); /* Tex stage 0 */
PRIMOUTREG(0x2d00 + 53*4, 0); /* Tex stage 1 */
PRIMOUTREG(0x2d00 + 61*4, 0); /* Tex stage 1 */
DMAOUTREG(0x2d00 + 54*4, 0x40); /* Tex stage 0 : w */
DMAOUTREG(0x2d00 + 62*4, 0x40); /* Tex stage 0 : h */
DMAOUTREG(0x2d00 + 52*4, 0x40); /* Tex stage 1 : w */
DMAOUTREG(0x2d00 + 60*4, 0x40); /* Tex stage 1 : h */
PRIMOUTREG(0x2d00 + 54*4, 0x40); /* Tex stage 0 : w */
PRIMOUTREG(0x2d00 + 62*4, 0x40); /* Tex stage 0 : h */
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 */
DMAOUTREG(MGAREG_DMAPAD, 0xffffffff);
DMAOUTREG(MGAREG_DMAPAD, 0xffffffff);
DMAOUTREG(MGAREG_DMAPAD, 0xffffffff);
DMAOUTREG(MGAREG_WIADDR2, (dev_priv->WarpIndex[pipe].phys_addr |
PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
PRIMOUTREG(MGAREG_WIADDR2, (dev_priv->WarpIndex[pipe].phys_addr |
WIA_wmode_start | WIA_wagp_agp));
DMAADVANCE(buf);
return 0;
PRIMADVANCE(dev_priv);
}
static int mgaG200EmitPipe( drm_device_t *dev, drm_buf_t *buf )
static void mgaG200EmitPipe( drm_mga_private_t *dev_priv,
drm_mga_buf_priv_t *buf_priv )
{
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int pipe = sarea_priv->WarpPipe;
DMALOCALS;
if (pipe > MGA_MAX_G200_PIPES)
return -1;
PRIMLOCALS;
DMAGETPTR(buf);
DMAOUTREG(MGAREG_WIADDR, WIA_wmode_suspend);
DMAOUTREG(MGAREG_WVRTXSZ, 7);
DMAOUTREG(MGAREG_WFLAG, 0);
DMAOUTREG(0x2d00 + 24*4, 0); /* tex w/h */
PRIMGETPTR(dev_priv);
PRIMOUTREG(MGAREG_WIADDR, WIA_wmode_suspend);
PRIMOUTREG(MGAREG_WVRTXSZ, 7);
PRIMOUTREG(MGAREG_WFLAG, 0);
PRIMOUTREG(0x2d00 + 24*4, 0); /* tex w/h */
DMAOUTREG(0x2d00 + 25*4, 0x100);
DMAOUTREG(0x2d00 + 34*4, 0); /* tex w/h */
DMAOUTREG(0x2d00 + 42*4, 0xFFFF);
DMAOUTREG(0x2d00 + 60*4, 0xFFFF);
PRIMOUTREG(0x2d00 + 25*4, 0x100);
PRIMOUTREG(0x2d00 + 34*4, 0); /* tex w/h */
PRIMOUTREG(0x2d00 + 42*4, 0xFFFF);
PRIMOUTREG(0x2d00 + 60*4, 0xFFFF);
/* Dma pading required due to hw bug */
DMAOUTREG(MGAREG_DMAPAD, 0xffffffff);
DMAOUTREG(MGAREG_DMAPAD, 0xffffffff);
DMAOUTREG(MGAREG_DMAPAD, 0xffffffff);
DMAOUTREG(MGAREG_WIADDR, (dev_priv->WarpIndex[pipe].phys_addr |
PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
PRIMOUTREG(MGAREG_DMAPAD, 0xffffffff);
PRIMOUTREG(MGAREG_WIADDR, (dev_priv->WarpIndex[pipe].phys_addr |
WIA_wmode_start | WIA_wagp_agp));
DMAADVANCE(buf);
PRIMADVANCE(dev_priv);
}
void mgaEmitState( drm_mga_private_t *dev_priv, drm_mga_buf_priv_t *buf_priv )
{
unsigned int dirty = buf_priv->dirty;
if (dev_priv->chipset == MGA_CARD_TYPE_G400) {
if (dirty & MGASAREA_NEW_CONTEXT)
mgaEmitContext( dev_priv, buf_priv );
if (dirty & MGASAREA_NEW_TEX1)
mgaG400EmitTex1( dev_priv, buf_priv );
if (dirty & MGASAREA_NEW_TEX0)
mgaG400EmitTex0( dev_priv, buf_priv );
if (dirty & MGASAREA_NEW_PIPE)
mgaG400EmitPipe( dev_priv, buf_priv );
} else {
if (dirty & MGASAREA_NEW_CONTEXT)
mgaEmitContext( dev_priv, buf_priv );
if (dirty & MGASAREA_NEW_TEX0)
mgaG200EmitTex( dev_priv, buf_priv );
if (dirty & MGASAREA_NEW_PIPE)
mgaG200EmitPipe( dev_priv, buf_priv );
}
}
/* Disallow all write destinations except the front and backbuffer.
*/
static int mgaCopyContext(drm_mga_private_t *dev_priv,
drm_mga_buf_priv_t *buf_priv)
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int *regs = sarea_priv->ContextState;
if (regs[MGA_CTXREG_DSTORG] != dev_priv->frontOrg &&
regs[MGA_CTXREG_DSTORG] != dev_priv->backOrg)
return -1;
memcpy(buf_priv->ContextState, sarea_priv->ContextState,
sizeof(buf_priv->ContextState));
return 0;
}
void mgaEmitState( drm_device_t *dev )
/* Disallow texture reads from PCI space.
*/
static int mgaCopyTex(drm_mga_private_t *dev_priv,
drm_mga_buf_priv_t *buf_priv,
int unit)
{
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
if ((sarea_priv->TexState[unit][MGA_TEXREG_ORG] & 0x3) == 0x1)
return -1;
memcpy(buf_priv->TexState[unit], sarea_priv->TexState[unit],
sizeof(buf_priv->TexState[0]));
return 0;
}
int mgaCopyAndVerifyState( drm_mga_private_t *dev_priv,
drm_mga_buf_priv_t *buf_priv )
{
drm_buf_t *buf;
drm_device_dma_t *dma = dev->dma;
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int dirty = sarea_priv->dirty ;
int rv = 0;
int order = 1; /* ???? */
buf_priv->dirty = sarea_priv->dirty;
buf_priv->WarpPipe = sarea_priv->WarpPipe;
/* Put all state onto a single buffer.
*/
buf = drm_freelist_get(&dma->bufs[order].freelist,_DRM_DMA_WAIT);
if (dirty & MGASAREA_NEW_CONTEXT)
rv |= mgaCopyContext( dev_priv, buf_priv );
if (dirty & MGASAREA_NEW_TEX0)
rv |= mgaCopyTex( dev_priv, buf_priv, 0 );
if (dev_priv->chipset == MGA_CARD_TYPE_G400) {
if (dirty & MGASAREA_NEW_CONTEXT)
rv |= mgaEmitContext( dev, buf );
if (dev_priv->chipset == MGA_CARD_TYPE_G400)
{
if (dirty & MGASAREA_NEW_TEX1)
rv |= mgaG400EmitTex1( dev, buf );
rv |= mgaCopyTex( dev_priv, buf_priv, 1 );
if (dirty & MGASAREA_NEW_TEX0)
rv |= mgaG400EmitTex0( dev, buf );
if (dirty & MGASAREA_NEW_PIPE)
rv |= mgaG400EmitPipe( dev, buf );
} else {
if (dirty & MGASAREA_NEW_CONTEXT)
rv |= mgaEmitContext( dev, buf );
if (dirty & MGASAREA_NEW_TEX0)
rv |= mgaG200EmitTex( dev, buf );
rv |= (buf_priv->WarpPipe > MGA_MAX_G400_PIPES);
}
else
{
if (dirty & MGASAREA_NEW_PIPE)
rv |= mgaG200EmitPipe( dev, buf );
rv |= (buf_priv->WarpPipe > MGA_MAX_G200_PIPES);
}
if (rv == 0) {
drm_dma_t d;
sarea_priv->dirty = 0;
d.context = DRM_KERNEL_CONTEXT;
d.send_count = 1;
d.send_indices = &buf->idx;
d.send_sizes = &buf->used;
d.flags = _DRM_DMA_GENERAL;
d.request_count = 0;
d.request_size = 0;
d.request_indices = NULL;
d.request_sizes = NULL;
d.granted_count = 0;
drm_dma_enqueue(dev, &d);
} else {
/* Won't render anything till we get a good state from a
* client.
*/
sarea_priv->dirty = ~0;
drm_freelist_put( dev, &dma->bufs[order].freelist, buf );
}
return rv == 0;
}

13
linux/mga_state.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef MGA_STATE_H
#define MGA_STATE_H
#include "mga_drv.h"
int mgaCopyAndVerifyState( drm_mga_private_t *dev_priv,
drm_mga_buf_priv_t *buf_priv );
void mgaEmitClipRect( drm_mga_private_t *dev_priv, xf86drmClipRectRec *box );
void mgaEmitState( drm_mga_private_t *dev_priv, drm_mga_buf_priv_t *buf_priv );
#endif