mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-05-07 19:18:04 +02:00
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:
parent
7a83054959
commit
12ddd18ce8
12 changed files with 766 additions and 1023 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
926
linux/mga_dma.c
926
linux/mga_dma.c
File diff suppressed because it is too large
Load diff
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
13
linux/mga_state.h
Normal 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
|
||||
Loading…
Add table
Reference in a new issue