mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-05-07 19:18:04 +02:00
multictx with arbitary number of cliprects
This commit is contained in:
parent
c0a9edafb3
commit
6a54cedbf1
8 changed files with 104 additions and 56 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue