multictx with arbitary number of cliprects

This commit is contained in:
Keith Whitwell 2000-02-11 01:11:13 +00:00
parent c0a9edafb3
commit 6a54cedbf1
8 changed files with 104 additions and 56 deletions

View file

@ -105,9 +105,10 @@ static drm_ioctl_desc_t mga_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)] = { mga_dma_init, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_swap_bufs, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_clear_bufs, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_swap_bufs, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_clear_bufs, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_iload, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_vertex, 1, 1 },
};
#define MGA_IOCTL_COUNT DRM_ARRAY_SIZE(mga_ioctls)

View file

@ -104,8 +104,6 @@ int mgaSwapBuffers(drm_device_t *dev, drm_mga_swap_t *args)
buf_priv->dma_type = MGA_DMA_DISCARD;
}
/* Make sure we restore the 3D state next time.
*/
dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CTX;
@ -192,6 +190,48 @@ static int mgaIload(drm_device_t *dev, drm_mga_iload_t *args)
}
static int mgaDmaVertex(drm_device_t *dev, drm_mga_vertex_t *args)
{
drm_device_dma_t *dma = dev->dma;
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 = dma->buflist[ args->idx ];
printk("mgaDmaVertex idx %d used %d\n", args->idx, buf->used);
buf_priv = buf->dev_private;
buf_priv->dma_type = MGA_DMA_VERTEX;
buf_priv->vertex_real_idx = args->real_idx;
buf->used = args->real_used;
if (!mgaCopyAndVerifyState(dev_priv, buf_priv, ~0))
buf_priv->dma_type = MGA_DMA_DISCARD;
d.context = DRM_KERNEL_CONTEXT;
d.send_count = 1;
d.send_indices = &buf->idx;
d.send_sizes = &buf->used;
d.flags = 0;
d.request_count = 0;
d.request_size = 0;
d.request_indices = NULL;
d.request_sizes = NULL;
d.granted_count = 0;
atomic_inc(&dev_priv->pending_bufs);
if((drm_dma_enqueue(dev, &d)) != 0)
atomic_dec(&dev_priv->pending_bufs);
mga_dma_schedule(dev, 1);
return 0;
}
int mga_clear_bufs(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
@ -241,6 +281,23 @@ int mga_iload(struct inode *inode, struct file *filp,
return retcode;
}
int mga_vertex(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_vertex_t vertex;
int retcode = 0;
copy_from_user_ret(&vertex, (drm_mga_vertex_t *)arg, sizeof(vertex),
-EFAULT);
retcode = mgaDmaVertex(dev, &vertex);
return retcode;
}
int mga_dma(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
@ -261,42 +318,21 @@ int mga_dma(struct inode *inode, struct file *filp, unsigned int cmd,
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...
/* Please don't send us buffers.
*/
if (d.send_count < 0 || d.send_count > 1) {
DRM_ERROR("Process %d trying to send %d buffers (max 1)\n",
if (d.send_count != 0) {
DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n",
current->pid, d.send_count);
return -EINVAL;
}
/* But it *is* used to request buffers for all types of dma:
/* We'll send you buffers.
*/
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) {
int idx = d.send_indices[0];
drm_mga_buf_priv_t *buf_priv = dma->buflist[ idx ]->dev_private;
drm_mga_private_t *dev_priv = dev->dev_private;
buf_priv->dma_type = MGA_DMA_VERTEX;
/* Snapshot the relevent bits of the sarea...
*/
if (!mgaCopyAndVerifyState( dev_priv, buf_priv, ~0 ))
dma->buflist[ idx ]->used = 0;
atomic_inc(&dev_priv->pending_bufs);
retcode = drm_dma_enqueue(dev, &d);
if(retcode != 0)
atomic_dec(&dev_priv->pending_bufs);
mga_dma_schedule(dev, 1);
}
d.granted_count = 0;

View file

@ -316,7 +316,6 @@ static void __mga_iload_small(drm_device_t *dev,
{
drm_mga_private_t *dev_priv = dev->dev_private;
drm_mga_buf_priv_t *buf_priv = buf->dev_private;
/* drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; */
unsigned long address = (unsigned long)buf->bus_address;
int length = buf->used;
int y1 = buf_priv->boxes[0].y1;
@ -356,11 +355,6 @@ static void __mga_iload_small(drm_device_t *dev,
PRIMOUTREG(MGAREG_SOFTRAP, 0);
PRIMADVANCE(dev_priv);
#if 0
/* For now we need to set this in the ioctl */
sarea_priv->dirty |= MGASAREA_NEW_CONTEXT;
#endif
MGA_WRITE(MGAREG_PRIMADDRESS, dev_priv->prim_phys_head | TT_GENERAL);
MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp);
}
@ -371,7 +365,6 @@ static void __mga_iload_xy(drm_device_t *dev,
{
drm_mga_private_t *dev_priv = dev->dev_private;
drm_mga_buf_priv_t *buf_priv = buf->dev_private;
/* drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv; */
unsigned long address = (unsigned long)buf->bus_address;
int length = buf->used;
int y1 = buf_priv->boxes[0].y1;
@ -429,10 +422,6 @@ static void __mga_iload_xy(drm_device_t *dev,
PRIMOUTREG(MGAREG_DMAPAD, 0);
PRIMOUTREG(MGAREG_SOFTRAP, 0);
PRIMADVANCE(dev_priv);
#if 0
/* For now we need to set this in the ioctl */
sarea_priv->dirty |= MGASAREA_NEW_CONTEXT;
#endif
MGA_WRITE(MGAREG_PRIMADDRESS, dev_priv->prim_phys_head | TT_GENERAL);
MGA_WRITE(MGAREG_PRIMEND, (phys_head + num_dwords * 4) | use_agp);
@ -460,10 +449,12 @@ static void mga_dma_dispatch_iload(drm_device_t *dev, drm_buf_t *buf)
static void mga_dma_dispatch_vertex(drm_device_t *dev, drm_buf_t *buf)
{
drm_mga_private_t *dev_priv = dev->dev_private;
drm_mga_buf_priv_t *buf_priv = buf->dev_private;
unsigned long address = (unsigned long)buf->bus_address;
int length = buf->used;
drm_buf_t *real_buf = dev->dma->buflist[ buf_priv->vertex_real_idx ];
unsigned long address = (unsigned long)real_buf->bus_address;
int length = buf->used; /* this is correct */
int use_agp = PDEA_pagpxfer_enable;
int i, count;
PRIMLOCALS;
@ -476,7 +467,6 @@ static void mga_dma_dispatch_vertex(drm_device_t *dev, drm_buf_t *buf)
mgaEmitState( dev_priv, buf_priv );
printk("dispatch vertex addr 0x%lx, length 0x%x nbox %d\n",
address, length, buf_priv->nbox);
@ -490,15 +480,16 @@ static void mga_dma_dispatch_vertex(drm_device_t *dev, drm_buf_t *buf)
PRIMOUTREG( MGAREG_SECADDRESS, ((__u32)address) | TT_VERTEX);
PRIMOUTREG( MGAREG_SECEND, (((__u32)(address + length)) |
use_agp));
PRIMADVANCE( dev_priv );
PRIMOUTREG( MGAREG_DMAPAD, 0);
PRIMOUTREG( MGAREG_DMAPAD, 0);
PRIMOUTREG( MGAREG_DMAPAD, 0);
PRIMOUTREG( MGAREG_SOFTRAP, 0);
PRIMADVANCE(dev_priv);
}
PRIMGETPTR( 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);

View file

@ -20,12 +20,14 @@ typedef struct {
unsigned short clear_zval;
unsigned int clear_flags;
unsigned int vertex_real_idx;
unsigned int nbox;
xf86drmClipRectRec boxes[MGA_NR_SAREA_CLIPRECTS];
} drm_mga_buf_priv_t;
#define MGA_DMA_GENERAL 0
#define MGA_DMA_GENERAL 0 /* not used */
#define MGA_DMA_VERTEX 1
#define MGA_DMA_SETUP 2
#define MGA_DMA_ILOAD 3

View file

@ -154,7 +154,7 @@ typedef struct _xf86drmClipRectRec {
#define MGA_UPLOAD_TEX0IMAGE 0x10
#define MGA_UPLOAD_TEX1IMAGE 0x20
#define MGA_UPLOAD_2D 0x40
#define MGA_REQUIRE_QUIESCENT 0x80
#define MGA_REQUIRE_QUIESCENT 0x80 /* handled client-side */
#define MGA_UPLOAD_CLIPRECTS 0x100
@ -209,7 +209,6 @@ typedef struct {
typedef struct {
int idx;
int flags; /* not actually used? */
} drm_mga_swap_t;
typedef struct {
@ -221,8 +220,24 @@ typedef struct {
} drm_mga_iload_t;
/* These may be placeholders if we have more cliprects than
* MGA_NR_SAREA_CLIPRECTS. In that case, idx != real_idx; idx is
* the number of a bogus buffer, real_idx is the real buffer to be
* rendered multiple times.
*
* This is a hack to work around the 'generalized gamma driver'
* known as the drm.
*/
typedef struct {
int idx; /* buffer to queue and free on completion */
int real_idx; /* buffer to execute */
int real_used; /* buf->used in for real buffer */
} drm_mga_vertex_t;
#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t)
#define DRM_IOCTL_MGA_SWAP DRM_IOW( 0x41, drm_mga_swap_t)
#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x42, drm_mga_clear_t)
#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t)
#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x44, drm_mga_vertex_t)
#endif

View file

@ -105,9 +105,10 @@ static drm_ioctl_desc_t mga_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_MGA_INIT)] = { mga_dma_init, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_swap_bufs, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_clear_bufs, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_MGA_SWAP)] = { mga_swap_bufs, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_MGA_CLEAR)] = { mga_clear_bufs, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_MGA_ILOAD)] = { mga_iload, 1, 1 },
[DRM_IOCTL_NR(DRM_IOCTL_MGA_VERTEX)] = { mga_vertex, 1, 1 },
};
#define MGA_IOCTL_COUNT DRM_ARRAY_SIZE(mga_ioctls)

View file

@ -122,6 +122,8 @@ extern int mga_swap_bufs(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int mga_iload(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int mga_vertex(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
/* mga_context.c */
extern int mga_resctx(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);

View file

@ -57,8 +57,8 @@ void mgaEmitClipRect( drm_mga_private_t *dev_priv, xf86drmClipRectRec *box )
}
PRIMOUTREG( MGAREG_CXBNDRY, ((box->x2)<<16)|(box->x1) );
PRIMOUTREG( MGAREG_YTOP, box->y1 * dev_priv->stride );
PRIMOUTREG( MGAREG_YBOT, box->y2 * dev_priv->stride );
PRIMOUTREG( MGAREG_YTOP, box->y1 * dev_priv->stride/2 );
PRIMOUTREG( MGAREG_YBOT, box->y2 * dev_priv->stride/2 );
PRIMOUTREG( MGAREG_DMAPAD, 0 );
PRIMADVANCE( dev_priv );