mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-05-07 19:18:04 +02:00
Multiple contexts work, providing cliprects <= MGA_NR_SAREA_CLIPRECTS
This commit is contained in:
parent
4468902a7e
commit
c0a9edafb3
4 changed files with 96 additions and 75 deletions
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue