Multiple contexts work, providing cliprects <= MGA_NR_SAREA_CLIPRECTS

This commit is contained in:
Keith Whitwell 2000-02-10 21:45:07 +00:00
parent 4468902a7e
commit c0a9edafb3
4 changed files with 96 additions and 75 deletions

View file

@ -42,33 +42,23 @@
* 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,
int flags)
static int mgaClearBuffers(drm_device_t *dev, drm_mga_clear_t *args)
{
drm_device_dma_t *dma = dev->dma;
drm_freelist_t *freelist = &dma->bufs[MGA_DMA_BUF_ORDER].freelist;
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
drm_mga_buf_priv_t *buf_priv;
drm_buf_t *buf;
drm_dma_t d;
buf = drm_freelist_get(freelist, _DRM_DMA_WAIT);
if (!buf) return -1;
buf->pid = current->pid;
buf = dma->buflist[ args->idx ];
buf_priv = buf->dev_private;
buf_priv->dma_type = MGA_DMA_CLEAR;
buf_priv->clear_color = clear_color;
buf_priv->clear_zval = clear_depth;
buf_priv->clear_flags = flags;
buf_priv->clear_color = args->clear_color;
buf_priv->clear_zval = args->clear_depth;
buf_priv->clear_flags = args->flags;
if (!mgaCopyAndVerifyState(dev_priv, buf_priv, MGA_UPLOAD_CLIPRECTS)) {
drm_freelist_put( dev, freelist, buf );
return -EINVAL;
}
if (!mgaCopyAndVerifyState(dev_priv, buf_priv, MGA_UPLOAD_CLIPRECTS))
buf_priv->dma_type = MGA_DMA_DISCARD;
/* Make sure we restore the 3D state next time.
@ -95,26 +85,25 @@ static int mgaClearBuffers(drm_device_t *dev,
return 0;
}
int mgaSwapBuffers(drm_device_t *dev, int flags)
int mgaSwapBuffers(drm_device_t *dev, drm_mga_swap_t *args)
{
drm_device_dma_t *dma = dev->dma;
drm_freelist_t *freelist = &dma->bufs[MGA_DMA_BUF_ORDER].freelist;
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
drm_mga_buf_priv_t *buf_priv;
drm_buf_t *buf;
drm_dma_t d;
buf = drm_freelist_get(freelist, _DRM_DMA_WAIT);
if (!buf) return -1;
printk("swap buf idx %d\n", args->idx);
buf->pid = current->pid;
buf = dma->buflist[ args->idx ];
buf_priv = buf->dev_private;
buf_priv->dma_type = MGA_DMA_SWAP;
if (!mgaCopyAndVerifyState(dev_priv, buf_priv, MGA_UPLOAD_CLIPRECTS)) {
drm_freelist_put( dev, freelist, buf );
return -EINVAL;
printk("mgaCopyAndVerifyState faild for swap\n");
buf_priv->dma_type = MGA_DMA_DISCARD;
}
/* Make sure we restore the 3D state next time.
@ -134,6 +123,8 @@ int mgaSwapBuffers(drm_device_t *dev, int flags)
d.request_sizes = NULL;
d.granted_count = 0;
printk("enqueue swap buf, idx %d\n", buf->idx);
atomic_inc(&dev_priv->pending_bufs);
if((drm_dma_enqueue(dev, &d)) != 0)
atomic_dec(&dev_priv->pending_bufs);
@ -209,14 +200,10 @@ int mga_clear_bufs(struct inode *inode, struct file *filp,
drm_mga_clear_t clear;
int retcode;
return 0;
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);
retcode = mgaClearBuffers(dev, &clear);
return retcode;
}
@ -229,12 +216,11 @@ int mga_swap_bufs(struct inode *inode, struct file *filp,
drm_mga_swap_t swap;
int retcode = 0;
return 0;
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);
printk("(a) swap buf idx %d\n", swap.idx);
retcode = mgaSwapBuffers(dev, &swap);
return retcode;
}
@ -247,8 +233,8 @@ int mga_iload(struct inode *inode, struct file *filp,
drm_mga_iload_t iload;
int retcode = 0;
copy_from_user_ret(&iload, (drm_mga_iload_t *)arg,
sizeof(iload), -EFAULT);
copy_from_user_ret(&iload, (drm_mga_iload_t *)arg, sizeof(iload),
-EFAULT);
retcode = mgaIload(dev, &iload);

View file

@ -570,14 +570,14 @@ static void mga_dma_dispatch_clear( drm_device_t *dev, drm_buf_t *buf )
flags);
/* if ( flags & MGA_CLEAR_FRONT ) */
if ( flags & MGA_CLEAR_FRONT )
{
PRIMOUTREG( MGAREG_DMAPAD, 0);
PRIMOUTREG( MGAREG_DMAPAD, 0);
PRIMOUTREG(MGAREG_YDSTLEN, (pbox[i].y1<<16)|height);
PRIMOUTREG(MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1);
printk("clear front\n");
PRIMOUTREG( MGAREG_DMAPAD, 0);
PRIMOUTREG( MGAREG_DMAPAD, 0);
PRIMOUTREG(MGAREG_YDSTLEN, (pbox[i].y1<<16)|height);
PRIMOUTREG(MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1);
PRIMOUTREG( MGAREG_DMAPAD, 0);
PRIMOUTREG(MGAREG_FCOL, buf_priv->clear_color);
PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontOffset);
@ -585,12 +585,12 @@ static void mga_dma_dispatch_clear( drm_device_t *dev, drm_buf_t *buf )
}
if ( flags & MGA_CLEAR_BACK ) {
PRIMOUTREG( MGAREG_DMAPAD, 0);
PRIMOUTREG( MGAREG_DMAPAD, 0);
PRIMOUTREG(MGAREG_YDSTLEN, (pbox[i].y1<<16)|height);
PRIMOUTREG(MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1);
printk("clear back\n");
PRIMOUTREG( MGAREG_DMAPAD, 0);
PRIMOUTREG( MGAREG_DMAPAD, 0);
PRIMOUTREG(MGAREG_YDSTLEN, (pbox[i].y1<<16)|height);
PRIMOUTREG(MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1);
PRIMOUTREG( MGAREG_DMAPAD, 0);
PRIMOUTREG(MGAREG_FCOL, buf_priv->clear_color);
PRIMOUTREG(MGAREG_DSTORG, dev_priv->backOffset);
@ -599,12 +599,12 @@ static void mga_dma_dispatch_clear( drm_device_t *dev, drm_buf_t *buf )
if ( flags & MGA_CLEAR_DEPTH )
{
PRIMOUTREG( MGAREG_DMAPAD, 0);
PRIMOUTREG( MGAREG_DMAPAD, 0);
PRIMOUTREG(MGAREG_YDSTLEN, (pbox[i].y1<<16)|height);
PRIMOUTREG(MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1);
printk("clear depth\n");
PRIMOUTREG( MGAREG_DMAPAD, 0);
PRIMOUTREG( MGAREG_DMAPAD, 0);
PRIMOUTREG(MGAREG_YDSTLEN, (pbox[i].y1<<16)|height);
PRIMOUTREG(MGAREG_FXBNDRY, (pbox[i].x2<<16)|pbox[i].x1);
PRIMOUTREG( MGAREG_DMAPAD, 0);
PRIMOUTREG(MGAREG_FCOL, buf_priv->clear_zval);
PRIMOUTREG(MGAREG_DSTORG, dev_priv->depthOffset);
@ -624,6 +624,7 @@ static void mga_dma_dispatch_clear( drm_device_t *dev, drm_buf_t *buf )
static void mga_dma_dispatch_swap( drm_device_t *dev, drm_buf_t *buf )
{
drm_mga_private_t *dev_priv = dev->dev_private;
@ -640,7 +641,7 @@ static void mga_dma_dispatch_swap( drm_device_t *dev, drm_buf_t *buf )
PRIMOUTREG(MGAREG_DSTORG, dev_priv->frontOffset);
PRIMOUTREG(MGAREG_MACCESS, dev_priv->mAccess);
PRIMOUTREG(MGAREG_SRCORG, dev_priv->backOffset);
PRIMOUTREG(MGAREG_AR5, dev_priv->stride);
PRIMOUTREG(MGAREG_AR5, dev_priv->stride/2);
PRIMOUTREG( MGAREG_DMAPAD, 0);
PRIMOUTREG( MGAREG_DMAPAD, 0);
@ -649,7 +650,7 @@ static void mga_dma_dispatch_swap( drm_device_t *dev, drm_buf_t *buf )
for (i = 0 ; i < nbox; i++) {
unsigned int h = pbox[i].y2 - pbox[i].y1;
unsigned int start = pbox[i].y1 * dev_priv->stride;
unsigned int start = pbox[i].y1 * dev_priv->stride/2;
printk("dispatch swap %d,%d-%d,%d!\n",
pbox[i].x1,
@ -673,26 +674,45 @@ static void mga_dma_dispatch_swap( drm_device_t *dev, drm_buf_t *buf )
MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp);
}
static void mga_dma_dispatch_bad( drm_device_t *dev, drm_buf_t *buf )
{
drm_mga_private_t *dev_priv = dev->dev_private;
int use_agp = PDEA_pagpxfer_enable;
PRIMLOCALS;
PRIMRESET( dev_priv );
PRIMGETPTR( dev_priv );
PRIMOUTREG( MGAREG_DMAPAD, 0);
PRIMOUTREG( MGAREG_DMAPAD, 0);
PRIMOUTREG( MGAREG_DMAPAD, 0);
PRIMOUTREG( MGAREG_SOFTRAP, 0);
PRIMADVANCE(dev_priv);
MGA_WRITE(MGAREG_PRIMADDRESS, dev_priv->prim_phys_head | TT_GENERAL);
MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp);
}
/* Frees dispatch lock */
static inline void mga_dma_quiescent(drm_device_t *dev)
{
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
while(1) {
atomic_inc(&dev_priv->dispatch_lock);
if(atomic_read(&dev_priv->dispatch_lock) == 1) {
break;
} else {
atomic_dec(&dev_priv->dispatch_lock);
}
while(1) {
atomic_inc(&dev_priv->dispatch_lock);
if(atomic_read(&dev_priv->dispatch_lock) == 1) {
break;
} else {
atomic_dec(&dev_priv->dispatch_lock);
}
}
#if 1
MGA_WRITE(MGAREG_DWGSYNC, MGA_SYNC_TAG);
while(MGA_READ(MGAREG_DWGSYNC) != MGA_SYNC_TAG) ;
MGA_WRITE(MGAREG_DWGSYNC, 0);
while(MGA_READ(MGAREG_DWGSYNC) != 0) ;
MGA_WRITE(MGAREG_DWGSYNC, MGA_SYNC_TAG);
while(MGA_READ(MGAREG_DWGSYNC) != MGA_SYNC_TAG) ;
MGA_WRITE(MGAREG_DWGSYNC, 0);
while(MGA_READ(MGAREG_DWGSYNC) != 0) ;
#endif
atomic_dec(&dev_priv->dispatch_lock);
atomic_dec(&dev_priv->dispatch_lock);
}
/* Keeps dispatch lock held */
@ -730,6 +750,7 @@ static void mga_dma_service(int irq, void *device, struct pt_regs *regs)
{
drm_device_t *dev = (drm_device_t *)device;
drm_device_dma_t *dma = dev->dma;
drm_mga_private_t *dev_priv = (drm_mga_private_t *)dev->dev_private;
atomic_inc(&dev->total_irq);
@ -764,11 +785,13 @@ static int mga_do_dma(drm_device_t *dev, int locked)
printk("mga_do_dma\n");
if (test_and_set_bit(0, &dev->dma_flag)) {
printk("mga_do_dma - busy\n");
atomic_inc(&dma->total_missed_dma);
return -EBUSY;
}
if (!dma->next_buffer) {
printk("mga_do_dma - no next buffer\n");
DRM_ERROR("No next_buffer\n");
clear_bit(0, &dev->dma_flag);
return -EINVAL;
@ -779,6 +802,8 @@ static int mga_do_dma(drm_device_t *dev, int locked)
printk("context %d, buffer %d\n", buf->context, buf->idx);
if (buf->list == DRM_LIST_RECLAIM) {
printk("mga_do_dma - reclaim\n");
drm_clear_next_buffer(dev);
drm_free_buffer(dev, buf);
atomic_dec(&dev_priv->pending_bufs);
@ -798,6 +823,7 @@ static int mga_do_dma(drm_device_t *dev, int locked)
}
if (mga_dma_is_ready(dev) == 0) {
printk("mga_do_dma - not ready\n");
clear_bit(0, &dev->dma_flag);
return -EBUSY;
}
@ -807,12 +833,14 @@ static int mga_do_dma(drm_device_t *dev, int locked)
if (!locked && !drm_lock_take(&dev->lock.hw_lock->lock,
DRM_KERNEL_CONTEXT)) {
printk("mga_do_dma - didn't get lock\n");
atomic_inc(&dma->total_missed_lock);
clear_bit(0, &dev->dma_flag);
atomic_dec(&dev_priv->dispatch_lock);
return -EBUSY;
}
dma->next_queue = dev->queuelist[DRM_KERNEL_CONTEXT];
drm_clear_next_buffer(dev);
buf->pending = 1;
@ -820,6 +848,7 @@ static int mga_do_dma(drm_device_t *dev, int locked)
buf->list = DRM_LIST_PEND;
buf_priv = buf->dev_private;
printk("mga_do_dma - type %d\n", buf_priv->dma_type);
switch (buf_priv->dma_type) {
case MGA_DMA_GENERAL:
@ -840,6 +869,9 @@ static int mga_do_dma(drm_device_t *dev, int locked)
case MGA_DMA_CLEAR:
mga_dma_dispatch_clear(dev, buf);
break;
case MGA_DMA_DISCARD:
mga_dma_dispatch_bad(dev, buf);
break;
default:
printk("bad buffer type %x in dispatch\n", buf_priv->dma_type);
break;
@ -848,7 +880,8 @@ static int mga_do_dma(drm_device_t *dev, int locked)
atomic_dec(&dev_priv->pending_bufs);
if(dma->this_buffer) {
drm_free_buffer(dev, dma->this_buffer);
printk("mga_do_dma - freeing this_buffer\n");
drm_free_buffer(dev, dma->this_buffer);
}
dma->this_buffer = buf;

View file

@ -31,7 +31,7 @@ typedef struct {
#define MGA_DMA_ILOAD 3
#define MGA_DMA_CLEAR 4 /* placeholder */
#define MGA_DMA_SWAP 5 /* placeholder */
#define MGA_DMA_BAD 6
#define MGA_DMA_DISCARD 6
#define DWGREG0 0x1c00

View file

@ -170,12 +170,12 @@ typedef struct _xf86drmClipRectRec {
/* Upto 128 regions. Minimum region size of 256k.
*/
#define MGA_NR_TEX_REGIONS 128
#define MGA_MIN_LOG_TEX_GRANULARITY 18
#define MGA_LOG_MIN_TEX_REGION_SIZE 18
typedef struct {
unsigned char next, prev;
unsigned char in_use;
int age;
unsigned char next, prev;
unsigned char in_use;
int age;
} mgaTexRegion;
typedef struct
@ -200,6 +200,7 @@ typedef struct
/* Device specific ioctls:
*/
typedef struct {
int idx;
int clear_color;
int clear_depth;
int flags;
@ -207,6 +208,7 @@ typedef struct {
typedef struct {
int idx;
int flags; /* not actually used? */
} drm_mga_swap_t;