summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Whitwell <keith@tungstengraphics.com>2001-02-03 16:57:00 +0000
committerKeith Whitwell <keith@tungstengraphics.com>2001-02-03 16:57:00 +0000
commitb3a24766fe433c5083c36d1148cfb87adfcabf9a (patch)
treea41a6baa966873554b1cf10fa475c193ad103074
parenta8760b0cba4dba438c2ea2d71202269d90145f4b (diff)
Support for multiple prims and states per dma buffer for i810 and radeon.
Do i810 buffer copying from inside the vertex ioctl.
-rw-r--r--linux-core/i810_dma.c254
-rw-r--r--linux-core/i810_drm.h72
-rw-r--r--linux-core/i810_drv.c1
-rw-r--r--linux-core/radeon_drv.c1
-rw-r--r--linux/drm.h2
-rw-r--r--linux/i810_dma.c254
-rw-r--r--linux/i810_drm.h72
-rw-r--r--linux/i810_drv.c1
-rw-r--r--linux/radeon_drm.h123
-rw-r--r--linux/radeon_drv.c1
-rw-r--r--linux/radeon_drv.h5
-rw-r--r--linux/radeon_state.c603
-rw-r--r--shared-core/drm.h2
-rw-r--r--shared/drm.h2
14 files changed, 666 insertions, 727 deletions
diff --git a/linux-core/i810_dma.c b/linux-core/i810_dma.c
index aa824a79..f3c24522 100644
--- a/linux-core/i810_dma.c
+++ b/linux-core/i810_dma.c
@@ -79,7 +79,8 @@
} while(0)
#define OUT_RING(n) do { \
- if (I810_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \
+ if (I810_VERBOSE) \
+ DRM_DEBUG(" OUT_RING %x: %x\n", outring, (int)(n)); \
*(volatile unsigned int *)(virt + outring) = n; \
outring += 4; \
outring &= ringmask; \
@@ -348,6 +349,9 @@ static int i810_wait_ring(drm_device_t *dev, int n)
if (ring->head != last_head)
end = jiffies + (HZ*3);
+ if (iters==1)
+ printk("wait for space in ring\n");
+
iters++;
if((signed)(end - jiffies) <= 0) {
DRM_ERROR("space: %d wanted %d\n", ring->space, n);
@@ -547,6 +551,10 @@ static void i810EmitContextVerified( drm_device_t *dev,
if (j & 1)
OUT_RING( 0 );
+/* for (i = 0 ; i < I810_CTX_SETUP_SIZE ; i++) */
+/* printk("ctxreg %d: %x\n", i, code[i]); */
+
+
ADVANCE_LP_RING();
}
@@ -579,6 +587,9 @@ static void i810EmitTexVerified( drm_device_t *dev,
if (j & 1)
OUT_RING( 0 );
+ for (i = 0 ; i < I810_TEX_SETUP_SIZE ; i++)
+ printk("texreg %d: %x\n", i, code[i]);
+
ADVANCE_LP_RING();
}
@@ -589,7 +600,7 @@ static void i810EmitDestVerified( drm_device_t *dev,
volatile unsigned int *code )
{
drm_i810_private_t *dev_priv = dev->dev_private;
- unsigned int tmp;
+ unsigned int tmp;
RING_LOCALS;
BEGIN_LP_RING( I810_DEST_SETUP_SIZE + 2 );
@@ -617,35 +628,35 @@ static void i810EmitDestVerified( drm_device_t *dev,
OUT_RING( code[I810_DESTREG_DR4] );
OUT_RING( 0 );
+ {
+/* int i; */
+/* for (i = 0 ; i < I810_DEST_SETUP_SIZE ; i++) */
+/* printk("destreg %d: %x\n", i, code[i]); */
+ }
+
ADVANCE_LP_RING();
}
-static void i810EmitState( drm_device_t *dev )
+static void i810EmitState( drm_device_t *dev,
+ drm_i810_state_t *state,
+ unsigned int dirty )
{
- drm_i810_private_t *dev_priv = dev->dev_private;
- drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
- unsigned int dirty = sarea_priv->dirty;
-
if (dirty & I810_UPLOAD_BUFFERS) {
- i810EmitDestVerified( dev, sarea_priv->BufferState );
- sarea_priv->dirty &= ~I810_UPLOAD_BUFFERS;
+ i810EmitDestVerified( dev, state->BufferSetup );
}
if (dirty & I810_UPLOAD_CTX) {
- i810EmitContextVerified( dev, sarea_priv->ContextState );
- sarea_priv->dirty &= ~I810_UPLOAD_CTX;
+ i810EmitContextVerified( dev, state->Setup );
}
if (dirty & I810_UPLOAD_TEX0) {
- i810EmitTexVerified( dev, sarea_priv->TexState[0] );
- sarea_priv->dirty &= ~I810_UPLOAD_TEX0;
+ i810EmitTexVerified( dev, state->TexSetup[0] );
}
if (dirty & I810_UPLOAD_TEX1) {
- i810EmitTexVerified( dev, sarea_priv->TexState[1] );
- sarea_priv->dirty &= ~I810_UPLOAD_TEX1;
+ i810EmitTexVerified( dev, state->TexSetup[1] );
}
}
@@ -770,13 +781,15 @@ static void i810_dma_dispatch_swap( drm_device_t *dev )
OUT_RING( start );
ADVANCE_LP_RING();
}
+
}
static void i810_dma_dispatch_vertex(drm_device_t *dev,
drm_buf_t *buf,
- int discard,
- int used)
+ drm_i810_prim_t *prim,
+ int nrprim,
+ int discard )
{
drm_i810_private_t *dev_priv = dev->dev_private;
drm_i810_buf_priv_t *buf_priv = buf->dev_private;
@@ -784,90 +797,101 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev,
drm_clip_rect_t *box = sarea_priv->boxes;
int nbox = sarea_priv->nbox;
unsigned long address = (unsigned long)buf->bus_address;
- unsigned long start = address - dev->agp->base;
- int i = 0, u;
+ unsigned long bufstart = address - dev->agp->base;
+ char *buf_virtual = (char *)buf_priv->virtual;
+ int i;
RING_LOCALS;
- i810_kernel_lost_context(dev);
-
if (nbox > I810_NR_SAREA_CLIPRECTS)
- nbox = I810_NR_SAREA_CLIPRECTS;
+ nrprim = 0;
- if (discard) {
- u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT,
- I810_BUF_HARDWARE);
- if(u != I810_BUF_CLIENT) {
- DRM_DEBUG("xxxx 2\n");
- }
- }
+ i810_kernel_lost_context(dev);
- if (used > 4*1024)
- used = 0;
+ for (i = 0 ; i < nrprim ; i++, prim++) {
+ int j = 0;
- if (sarea_priv->dirty)
- i810EmitState( dev );
+/* printk("prim %d/%d %d..%d type %x state %d dirty %d nbox %d\n", */
+/* i, nrprim, prim->start, prim->finish, prim->prim, */
+/* prim->stateidx, prim->dirty, */
+/* nbox); */
- DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n",
- address, used, nbox);
+ if ((unsigned)prim->start > 4096 ||
+ prim->start >= prim->finish ||
+ (prim->start & 0x7) != 0x4) {
+ continue;
+ }
+
+ if (prim->dirty) {
+ i810EmitState( dev,
+ &sarea_priv->state[(int)prim->stateidx],
+ prim->dirty );
+ }
- dev_priv->counter++;
- DRM_DEBUG( "dispatch counter : %ld\n", dev_priv->counter);
- DRM_DEBUG( "i810_dma_dispatch\n");
- DRM_DEBUG( "start : %lx\n", start);
- DRM_DEBUG( "used : %d\n", used);
- DRM_DEBUG( "start + used - 4 : %ld\n", start + used - 4);
+ *(int *)&buf_virtual[prim->start-4] =
+ (GFX_OP_PRIMITIVE | (((int)prim->prim) << 18) |
+ ((prim->finish - prim->start)/4-1));
+
+/* printk("op %x\n", */
+/* (GFX_OP_PRIMITIVE | (((int)prim->prim) << 18) | */
+/* ((prim->finish - prim->start)/4-1))); */
- if (buf_priv->currently_mapped == I810_BUF_MAPPED) {
- *(u32 *)buf_priv->virtual = (GFX_OP_PRIMITIVE |
- sarea_priv->vertex_prim |
- ((used/4)-2));
- if (used & 4) {
- *(u32 *)((u32)buf_priv->virtual + used) = 0;
- used += 4;
+ if (prim->finish & 0x4) {
+ *(int *)&buf_virtual[prim->finish] = 0;
+ prim->finish += 4;
}
- i810_unmap_buffer(buf);
- }
-
- if (used) {
+
+
do {
- if (i < nbox) {
+ if (j < nbox) {
BEGIN_LP_RING(4);
- OUT_RING( GFX_OP_SCISSOR | SC_UPDATE_SCISSOR |
+ OUT_RING( GFX_OP_SCISSOR |
+ SC_UPDATE_SCISSOR |
SC_ENABLE );
OUT_RING( GFX_OP_SCISSOR_INFO );
- OUT_RING( box[i].x1 | (box[i].y1<<16) );
- OUT_RING( (box[i].x2-1) | ((box[i].y2-1)<<16) );
+ OUT_RING( box[j].x1 | (box[j].y1<<16) );
+ OUT_RING( (box[j].x2-1) | ((box[j].y2-1)<<16) );
ADVANCE_LP_RING();
+ if (nbox == 1) nbox = 0;
}
BEGIN_LP_RING(4);
OUT_RING( CMD_OP_BATCH_BUFFER );
- OUT_RING( start | BB1_PROTECTED );
- OUT_RING( start + used - 4 );
+ OUT_RING( (bufstart + prim->start - 4) |
+ BB1_PROTECTED );
+ OUT_RING( (bufstart + prim->finish - 4) );
OUT_RING( 0 );
ADVANCE_LP_RING();
-
- } while (++i < nbox);
+
+/* printk("fire %x..%x\n", bufstart + prim->start - 4, */
+/* bufstart + prim->finish-4); */
+
+ } while (++j < nbox);
+
+
+ BEGIN_LP_RING(4);
+ ADVANCE_LP_RING();
}
- BEGIN_LP_RING(10);
- OUT_RING( CMD_STORE_DWORD_IDX );
- OUT_RING( 20 );
- OUT_RING( dev_priv->counter );
- OUT_RING( 0 );
if (discard) {
+ dev_priv->counter++;
+
+ (void) cmpxchg(buf_priv->in_use, I810_BUF_CLIENT,
+ I810_BUF_HARDWARE);
+
+ BEGIN_LP_RING( 8 );
+ OUT_RING( CMD_STORE_DWORD_IDX );
+ OUT_RING( 20 );
+ OUT_RING( dev_priv->counter );
OUT_RING( CMD_STORE_DWORD_IDX );
OUT_RING( buf_priv->my_use_idx );
OUT_RING( I810_BUF_FREE );
+ OUT_RING( CMD_REPORT_HEAD );
OUT_RING( 0 );
+ ADVANCE_LP_RING();
}
-
- OUT_RING( CMD_REPORT_HEAD );
- OUT_RING( 0 );
- ADVANCE_LP_RING();
}
@@ -880,13 +904,14 @@ static void i810_dma_service(int irq, void *device, struct pt_regs *regs)
atomic_inc(&dev->total_irq);
temp = I810_READ16(I810REG_INT_IDENTITY_R);
temp = temp & ~(0x6000);
- if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R,
- temp); /* Clear all interrupts */
- else
- return;
+ if(temp == 0)
+ return;
+
+ /* Clear all interrupts */
+ I810_WRITE16(I810REG_INT_IDENTITY_R, temp);
- queue_task(&dev->tq, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
+ queue_task(&dev->tq, &tq_immediate);
+ mark_bh(IMMEDIATE_BH);
}
static void i810_dma_task_queue(void *device)
@@ -954,9 +979,9 @@ int i810_irq_install(drm_device_t *dev, int irq)
}
temp = I810_READ16(I810REG_INT_ENABLE_R);
temp = temp & 0x6000;
- temp = temp | 0x0003;
- I810_WRITE16(I810REG_INT_ENABLE_R,
- temp); /* Enable bp & user interrupts */
+ temp = temp | 0x8003;
+ /* Enable error, bp & user interrupts */
+ I810_WRITE16(I810REG_INT_ENABLE_R, temp);
return 0;
}
@@ -965,9 +990,6 @@ int i810_irq_uninstall(drm_device_t *dev)
int irq;
u16 temp;
-
-/* return 0; */
-
down(&dev->struct_sem);
irq = dev->irq;
dev->irq = 0;
@@ -1264,7 +1286,7 @@ int i810_flush_ioctl(struct inode *inode, struct file *filp,
int i810_dma_vertex(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
@@ -1274,6 +1296,8 @@ int i810_dma_vertex(struct inode *inode, struct file *filp,
drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
dev_priv->sarea_priv;
drm_i810_vertex_t vertex;
+ drm_buf_t *buf;
+ drm_i810_buf_priv_t *buf_priv;
if (copy_from_user(&vertex, (drm_i810_vertex_t *)arg, sizeof(vertex)))
return -EFAULT;
@@ -1283,19 +1307,35 @@ int i810_dma_vertex(struct inode *inode, struct file *filp,
return -EINVAL;
}
- DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n",
- vertex.idx, vertex.used, vertex.discard);
+ buf = dma->buflist[ vertex.idx ];
+ buf_priv = buf->dev_private;
+
+ if (vertex.copy_size) {
+ if (vertex.copy_size > 4096)
+ return -EINVAL;
+
+ if (buf_priv->currently_mapped != I810_BUF_MAPPED)
+ return -EPERM;
+
+ if (copy_from_user(buf_priv->virtual,
+ vertex.copy_address,
+ vertex.copy_size))
+ return -EFAULT;
+ }
- i810_dma_dispatch_vertex( dev,
- dma->buflist[ vertex.idx ],
- vertex.discard, vertex.used );
+ i810_dma_dispatch_vertex( dev, buf,
+ sarea_priv->prim,
+ sarea_priv->primnr,
+ vertex.discard );
- atomic_add(vertex.used, &dma->total_bytes);
+ if (buf_priv->currently_mapped == I810_BUF_MAPPED) {
+ i810_unmap_buffer(buf);
+ }
+
atomic_inc(&dma->total_dmas);
sarea_priv->last_enqueue = dev_priv->counter-1;
sarea_priv->last_dispatch = (int) hw_status[5];
-
- return 0;
+ return 0;
}
@@ -1387,40 +1427,6 @@ int i810_getbuf(struct inode *inode, struct file *filp, unsigned int cmd,
return retcode;
}
-int i810_copybuf(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_i810_copy_t d;
- drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
- u32 *hw_status = (u32 *)dev_priv->hw_status_page;
- drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
- dev_priv->sarea_priv;
- drm_buf_t *buf;
- drm_i810_buf_priv_t *buf_priv;
- drm_device_dma_t *dma = dev->dma;
-
- if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
- DRM_ERROR("i810_dma called without lock held\n");
- return -EINVAL;
- }
-
- if (copy_from_user(&d, (drm_i810_copy_t *)arg, sizeof(d)))
- return -EFAULT;
-
- if(d.idx > dma->buf_count) return -EINVAL;
- buf = dma->buflist[ d.idx ];
- buf_priv = buf->dev_private;
- if (buf_priv->currently_mapped != I810_BUF_MAPPED) return -EPERM;
-
- if (copy_from_user(buf_priv->virtual, d.address, d.used))
- return -EFAULT;
-
- sarea_priv->last_dispatch = (int) hw_status[5];
-
- return 0;
-}
int i810_docopy(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
diff --git a/linux-core/i810_drm.h b/linux-core/i810_drm.h
index c5f51c9a..c1aea5be 100644
--- a/linux-core/i810_drm.h
+++ b/linux-core/i810_drm.h
@@ -13,19 +13,17 @@
#define I810_DMA_BUF_NR 256
#define I810_NR_SAREA_CLIPRECTS 8
-/* Each region is a minimum of 64k, and there are at most 64 of them.
+/* Each region is a minimum of 64k, and there are at most 32 of them.
*/
-#define I810_NR_TEX_REGIONS 64
+#define I810_NR_TEX_REGIONS 32
#define I810_LOG_MIN_TEX_REGION_SIZE 16
#endif
-#define I810_UPLOAD_TEX0IMAGE 0x1 /* handled clientside */
-#define I810_UPLOAD_TEX1IMAGE 0x2 /* handled clientside */
-#define I810_UPLOAD_CTX 0x4
-#define I810_UPLOAD_BUFFERS 0x8
-#define I810_UPLOAD_TEX0 0x10
-#define I810_UPLOAD_TEX1 0x20
-#define I810_UPLOAD_CLIPRECTS 0x40
+
+#define I810_UPLOAD_CTX 0x1
+#define I810_UPLOAD_BUFFERS 0x2
+#define I810_UPLOAD_TEX0 0x4
+#define I810_UPLOAD_TEX1 0x8
/* Indices into buf.Setup where various bits of state are mirrored per
@@ -88,6 +86,8 @@
#define I810_TEXREG_MCS 7 /* GFX_OP_MAP_COORD_SETS ??? */
#define I810_TEX_SETUP_SIZE 8
+/* Flags for clear ioctl
+ */
#define I810_FRONT 0x1
#define I810_BACK 0x2
#define I810_DEPTH 0x4
@@ -122,12 +122,42 @@ typedef struct _drm_i810_tex_region {
int age; /* tracked by clients to update local LRU's */
} drm_i810_tex_region_t;
+typedef struct _drm_i810_state {
+ unsigned int Setup[I810_CTX_SETUP_SIZE];
+ unsigned int BufferSetup[I810_DEST_SETUP_SIZE];
+ unsigned int TexSetup[2][I810_TEX_SETUP_SIZE];
+} drm_i810_state_t;
+
+#define PR_TRIANGLES (0x0)
+#define PR_TRISTRIP_0 (0x1)
+#define PR_TRISTRIP_1 (0x2)
+#define PR_TRIFAN (0x3)
+#define PR_POLYGON (0x4)
+#define PR_LINES (0x5)
+#define PR_LINESTRIP (0x6)
+#define PR_RECTS (0x7)
+
+typedef struct _drm_i810_prim {
+ int start;
+ int finish;
+ char prim;
+ char dirty;
+ char stateidx;
+} drm_i810_prim_t;
+
+#define I810_MAX_PRIMS 70
+#define I810_MAX_STATES 3
+
typedef struct _drm_i810_sarea {
- unsigned int ContextState[I810_CTX_SETUP_SIZE];
- unsigned int BufferState[I810_DEST_SETUP_SIZE];
- unsigned int TexState[2][I810_TEX_SETUP_SIZE];
- unsigned int dirty;
+ /* Allow multiple states and primitives per vertex buffer ioctl:
+ */
+ drm_i810_state_t state[I810_MAX_STATES];
+ drm_i810_prim_t prim[I810_MAX_PRIMS];
+ unsigned int primnr;
+
+ /* Multiple cliprects per vertex buffer ioctl:
+ */
unsigned int nbox;
drm_clip_rect_t boxes[I810_NR_SAREA_CLIPRECTS];
@@ -145,18 +175,16 @@ typedef struct _drm_i810_sarea {
* areas to kick out. There is no need to choose whether to
* kick out your own texture or someone else's - simply eject
* them all in LRU order.
- */
-
+ */
drm_i810_tex_region_t texList[I810_NR_TEX_REGIONS+1];
/* Last elt is sentinal */
int texAge; /* last time texture was uploaded */
+
int last_enqueue; /* last time a buffer was enqueued */
int last_dispatch; /* age of the most recently dispatched buffer */
int last_quiescent; /* */
int ctxOwner; /* last context to upload state */
- int vertex_prim;
-
} drm_i810_sarea_t;
typedef struct _drm_i810_clear {
@@ -166,7 +194,6 @@ typedef struct _drm_i810_clear {
} drm_i810_clear_t;
-
/* These may be placeholders if we have more cliprects than
* I810_NR_SAREA_CLIPRECTS. In that case, the client sets discard to
* false, indicating that the buffer will be dispatched again with a
@@ -174,16 +201,11 @@ typedef struct _drm_i810_clear {
*/
typedef struct _drm_i810_vertex {
int idx; /* buffer index */
- int used; /* nr bytes in use */
+ int copy_size; /* nr bytes to copy (0 if using unmap) */
+ void *copy_address; /* address to copy from */
int discard; /* client is finished with the buffer? */
} drm_i810_vertex_t;
-typedef struct _drm_i810_copy_t {
- int idx; /* buffer index */
- int used; /* nr bytes in use */
- void *address; /* Address to copy from */
-} drm_i810_copy_t;
-
typedef struct drm_i810_dma {
void *virtual;
int request_idx;
diff --git a/linux-core/i810_drv.c b/linux-core/i810_drv.c
index 7152eac3..65177555 100644
--- a/linux-core/i810_drv.c
+++ b/linux-core/i810_drv.c
@@ -111,7 +111,6 @@ static drm_ioctl_desc_t i810_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_I810_GETAGE)] = { i810_getage, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_I810_GETBUF)] = { i810_getbuf, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_I810_SWAP)] = { i810_swap_bufs, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_I810_COPY)] = { i810_copybuf, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy, 1, 0 },
};
diff --git a/linux-core/radeon_drv.c b/linux-core/radeon_drv.c
index 0113ed97..1735e262 100644
--- a/linux-core/radeon_drv.c
+++ b/linux-core/radeon_drv.c
@@ -116,7 +116,6 @@ static drm_ioctl_desc_t radeon_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_SWAP)] = { radeon_cp_swap, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CLEAR)] = { radeon_cp_clear, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX)] = { radeon_cp_vertex, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDICES)] = { radeon_cp_indices, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_BLIT)] = { radeon_cp_blit, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)]= { radeon_cp_indirect,1, 1 },
diff --git a/linux/drm.h b/linux/drm.h
index dc3d262d..8a503001 100644
--- a/linux/drm.h
+++ b/linux/drm.h
@@ -363,7 +363,6 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_I810_GETAGE DRM_IO( 0x44)
#define DRM_IOCTL_I810_GETBUF DRM_IOWR(0x45, drm_i810_dma_t)
#define DRM_IOCTL_I810_SWAP DRM_IO( 0x46)
-#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t)
#define DRM_IOCTL_I810_DOCOPY DRM_IO( 0x48)
/* Rage 128 specific ioctls */
@@ -394,7 +393,6 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_RADEON_SWAP DRM_IO( 0x47)
#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t)
#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t)
-#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t)
#define DRM_IOCTL_RADEON_BLIT DRM_IOW( 0x4b, drm_radeon_blit_t)
#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t)
#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t)
diff --git a/linux/i810_dma.c b/linux/i810_dma.c
index aa824a79..f3c24522 100644
--- a/linux/i810_dma.c
+++ b/linux/i810_dma.c
@@ -79,7 +79,8 @@
} while(0)
#define OUT_RING(n) do { \
- if (I810_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \
+ if (I810_VERBOSE) \
+ DRM_DEBUG(" OUT_RING %x: %x\n", outring, (int)(n)); \
*(volatile unsigned int *)(virt + outring) = n; \
outring += 4; \
outring &= ringmask; \
@@ -348,6 +349,9 @@ static int i810_wait_ring(drm_device_t *dev, int n)
if (ring->head != last_head)
end = jiffies + (HZ*3);
+ if (iters==1)
+ printk("wait for space in ring\n");
+
iters++;
if((signed)(end - jiffies) <= 0) {
DRM_ERROR("space: %d wanted %d\n", ring->space, n);
@@ -547,6 +551,10 @@ static void i810EmitContextVerified( drm_device_t *dev,
if (j & 1)
OUT_RING( 0 );
+/* for (i = 0 ; i < I810_CTX_SETUP_SIZE ; i++) */
+/* printk("ctxreg %d: %x\n", i, code[i]); */
+
+
ADVANCE_LP_RING();
}
@@ -579,6 +587,9 @@ static void i810EmitTexVerified( drm_device_t *dev,
if (j & 1)
OUT_RING( 0 );
+ for (i = 0 ; i < I810_TEX_SETUP_SIZE ; i++)
+ printk("texreg %d: %x\n", i, code[i]);
+
ADVANCE_LP_RING();
}
@@ -589,7 +600,7 @@ static void i810EmitDestVerified( drm_device_t *dev,
volatile unsigned int *code )
{
drm_i810_private_t *dev_priv = dev->dev_private;
- unsigned int tmp;
+ unsigned int tmp;
RING_LOCALS;
BEGIN_LP_RING( I810_DEST_SETUP_SIZE + 2 );
@@ -617,35 +628,35 @@ static void i810EmitDestVerified( drm_device_t *dev,
OUT_RING( code[I810_DESTREG_DR4] );
OUT_RING( 0 );
+ {
+/* int i; */
+/* for (i = 0 ; i < I810_DEST_SETUP_SIZE ; i++) */
+/* printk("destreg %d: %x\n", i, code[i]); */
+ }
+
ADVANCE_LP_RING();
}
-static void i810EmitState( drm_device_t *dev )
+static void i810EmitState( drm_device_t *dev,
+ drm_i810_state_t *state,
+ unsigned int dirty )
{
- drm_i810_private_t *dev_priv = dev->dev_private;
- drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
- unsigned int dirty = sarea_priv->dirty;
-
if (dirty & I810_UPLOAD_BUFFERS) {
- i810EmitDestVerified( dev, sarea_priv->BufferState );
- sarea_priv->dirty &= ~I810_UPLOAD_BUFFERS;
+ i810EmitDestVerified( dev, state->BufferSetup );
}
if (dirty & I810_UPLOAD_CTX) {
- i810EmitContextVerified( dev, sarea_priv->ContextState );
- sarea_priv->dirty &= ~I810_UPLOAD_CTX;
+ i810EmitContextVerified( dev, state->Setup );
}
if (dirty & I810_UPLOAD_TEX0) {
- i810EmitTexVerified( dev, sarea_priv->TexState[0] );
- sarea_priv->dirty &= ~I810_UPLOAD_TEX0;
+ i810EmitTexVerified( dev, state->TexSetup[0] );
}
if (dirty & I810_UPLOAD_TEX1) {
- i810EmitTexVerified( dev, sarea_priv->TexState[1] );
- sarea_priv->dirty &= ~I810_UPLOAD_TEX1;
+ i810EmitTexVerified( dev, state->TexSetup[1] );
}
}
@@ -770,13 +781,15 @@ static void i810_dma_dispatch_swap( drm_device_t *dev )
OUT_RING( start );
ADVANCE_LP_RING();
}
+
}
static void i810_dma_dispatch_vertex(drm_device_t *dev,
drm_buf_t *buf,
- int discard,
- int used)
+ drm_i810_prim_t *prim,
+ int nrprim,
+ int discard )
{
drm_i810_private_t *dev_priv = dev->dev_private;
drm_i810_buf_priv_t *buf_priv = buf->dev_private;
@@ -784,90 +797,101 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev,
drm_clip_rect_t *box = sarea_priv->boxes;
int nbox = sarea_priv->nbox;
unsigned long address = (unsigned long)buf->bus_address;
- unsigned long start = address - dev->agp->base;
- int i = 0, u;
+ unsigned long bufstart = address - dev->agp->base;
+ char *buf_virtual = (char *)buf_priv->virtual;
+ int i;
RING_LOCALS;
- i810_kernel_lost_context(dev);
-
if (nbox > I810_NR_SAREA_CLIPRECTS)
- nbox = I810_NR_SAREA_CLIPRECTS;
+ nrprim = 0;
- if (discard) {
- u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT,
- I810_BUF_HARDWARE);
- if(u != I810_BUF_CLIENT) {
- DRM_DEBUG("xxxx 2\n");
- }
- }
+ i810_kernel_lost_context(dev);
- if (used > 4*1024)
- used = 0;
+ for (i = 0 ; i < nrprim ; i++, prim++) {
+ int j = 0;
- if (sarea_priv->dirty)
- i810EmitState( dev );
+/* printk("prim %d/%d %d..%d type %x state %d dirty %d nbox %d\n", */
+/* i, nrprim, prim->start, prim->finish, prim->prim, */
+/* prim->stateidx, prim->dirty, */
+/* nbox); */
- DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n",
- address, used, nbox);
+ if ((unsigned)prim->start > 4096 ||
+ prim->start >= prim->finish ||
+ (prim->start & 0x7) != 0x4) {
+ continue;
+ }
+
+ if (prim->dirty) {
+ i810EmitState( dev,
+ &sarea_priv->state[(int)prim->stateidx],
+ prim->dirty );
+ }
- dev_priv->counter++;
- DRM_DEBUG( "dispatch counter : %ld\n", dev_priv->counter);
- DRM_DEBUG( "i810_dma_dispatch\n");
- DRM_DEBUG( "start : %lx\n", start);
- DRM_DEBUG( "used : %d\n", used);
- DRM_DEBUG( "start + used - 4 : %ld\n", start + used - 4);
+ *(int *)&buf_virtual[prim->start-4] =
+ (GFX_OP_PRIMITIVE | (((int)prim->prim) << 18) |
+ ((prim->finish - prim->start)/4-1));
+
+/* printk("op %x\n", */
+/* (GFX_OP_PRIMITIVE | (((int)prim->prim) << 18) | */
+/* ((prim->finish - prim->start)/4-1))); */
- if (buf_priv->currently_mapped == I810_BUF_MAPPED) {
- *(u32 *)buf_priv->virtual = (GFX_OP_PRIMITIVE |
- sarea_priv->vertex_prim |
- ((used/4)-2));
- if (used & 4) {
- *(u32 *)((u32)buf_priv->virtual + used) = 0;
- used += 4;
+ if (prim->finish & 0x4) {
+ *(int *)&buf_virtual[prim->finish] = 0;
+ prim->finish += 4;
}
- i810_unmap_buffer(buf);
- }
-
- if (used) {
+
+
do {
- if (i < nbox) {
+ if (j < nbox) {
BEGIN_LP_RING(4);
- OUT_RING( GFX_OP_SCISSOR | SC_UPDATE_SCISSOR |
+ OUT_RING( GFX_OP_SCISSOR |
+ SC_UPDATE_SCISSOR |
SC_ENABLE );
OUT_RING( GFX_OP_SCISSOR_INFO );
- OUT_RING( box[i].x1 | (box[i].y1<<16) );
- OUT_RING( (box[i].x2-1) | ((box[i].y2-1)<<16) );
+ OUT_RING( box[j].x1 | (box[j].y1<<16) );
+ OUT_RING( (box[j].x2-1) | ((box[j].y2-1)<<16) );
ADVANCE_LP_RING();
+ if (nbox == 1) nbox = 0;
}
BEGIN_LP_RING(4);
OUT_RING( CMD_OP_BATCH_BUFFER );
- OUT_RING( start | BB1_PROTECTED );
- OUT_RING( start + used - 4 );
+ OUT_RING( (bufstart + prim->start - 4) |
+ BB1_PROTECTED );
+ OUT_RING( (bufstart + prim->finish - 4) );
OUT_RING( 0 );
ADVANCE_LP_RING();
-
- } while (++i < nbox);
+
+/* printk("fire %x..%x\n", bufstart + prim->start - 4, */
+/* bufstart + prim->finish-4); */
+
+ } while (++j < nbox);
+
+
+ BEGIN_LP_RING(4);
+ ADVANCE_LP_RING();
}
- BEGIN_LP_RING(10);
- OUT_RING( CMD_STORE_DWORD_IDX );
- OUT_RING( 20 );
- OUT_RING( dev_priv->counter );
- OUT_RING( 0 );
if (discard) {
+ dev_priv->counter++;
+
+ (void) cmpxchg(buf_priv->in_use, I810_BUF_CLIENT,
+ I810_BUF_HARDWARE);
+
+ BEGIN_LP_RING( 8 );
+ OUT_RING( CMD_STORE_DWORD_IDX );
+ OUT_RING( 20 );
+ OUT_RING( dev_priv->counter );
OUT_RING( CMD_STORE_DWORD_IDX );
OUT_RING( buf_priv->my_use_idx );
OUT_RING( I810_BUF_FREE );
+ OUT_RING( CMD_REPORT_HEAD );
OUT_RING( 0 );
+ ADVANCE_LP_RING();
}
-
- OUT_RING( CMD_REPORT_HEAD );
- OUT_RING( 0 );
- ADVANCE_LP_RING();
}
@@ -880,13 +904,14 @@ static void i810_dma_service(int irq, void *device, struct pt_regs *regs)
atomic_inc(&dev->total_irq);
temp = I810_READ16(I810REG_INT_IDENTITY_R);
temp = temp & ~(0x6000);
- if(temp != 0) I810_WRITE16(I810REG_INT_IDENTITY_R,
- temp); /* Clear all interrupts */
- else
- return;
+ if(temp == 0)
+ return;
+
+ /* Clear all interrupts */
+ I810_WRITE16(I810REG_INT_IDENTITY_R, temp);
- queue_task(&dev->tq, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
+ queue_task(&dev->tq, &tq_immediate);
+ mark_bh(IMMEDIATE_BH);
}
static void i810_dma_task_queue(void *device)
@@ -954,9 +979,9 @@ int i810_irq_install(drm_device_t *dev, int irq)
}
temp = I810_READ16(I810REG_INT_ENABLE_R);
temp = temp & 0x6000;
- temp = temp | 0x0003;
- I810_WRITE16(I810REG_INT_ENABLE_R,
- temp); /* Enable bp & user interrupts */
+ temp = temp | 0x8003;
+ /* Enable error, bp & user interrupts */
+ I810_WRITE16(I810REG_INT_ENABLE_R, temp);
return 0;
}
@@ -965,9 +990,6 @@ int i810_irq_uninstall(drm_device_t *dev)
int irq;
u16 temp;
-
-/* return 0; */
-
down(&dev->struct_sem);
irq = dev->irq;
dev->irq = 0;
@@ -1264,7 +1286,7 @@ int i810_flush_ioctl(struct inode *inode, struct file *filp,
int i810_dma_vertex(struct inode *inode, struct file *filp,
- unsigned int cmd, unsigned long arg)
+ unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
@@ -1274,6 +1296,8 @@ int i810_dma_vertex(struct inode *inode, struct file *filp,
drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
dev_priv->sarea_priv;
drm_i810_vertex_t vertex;
+ drm_buf_t *buf;
+ drm_i810_buf_priv_t *buf_priv;
if (copy_from_user(&vertex, (drm_i810_vertex_t *)arg, sizeof(vertex)))
return -EFAULT;
@@ -1283,19 +1307,35 @@ int i810_dma_vertex(struct inode *inode, struct file *filp,
return -EINVAL;
}
- DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n",
- vertex.idx, vertex.used, vertex.discard);
+ buf = dma->buflist[ vertex.idx ];
+ buf_priv = buf->dev_private;
+
+ if (vertex.copy_size) {
+ if (vertex.copy_size > 4096)
+ return -EINVAL;
+
+ if (buf_priv->currently_mapped != I810_BUF_MAPPED)
+ return -EPERM;
+
+ if (copy_from_user(buf_priv->virtual,
+ vertex.copy_address,
+ vertex.copy_size))
+ return -EFAULT;
+ }
- i810_dma_dispatch_vertex( dev,
- dma->buflist[ vertex.idx ],
- vertex.discard, vertex.used );
+ i810_dma_dispatch_vertex( dev, buf,
+ sarea_priv->prim,
+ sarea_priv->primnr,
+ vertex.discard );
- atomic_add(vertex.used, &dma->total_bytes);
+ if (buf_priv->currently_mapped == I810_BUF_MAPPED) {
+ i810_unmap_buffer(buf);
+ }
+
atomic_inc(&dma->total_dmas);
sarea_priv->last_enqueue = dev_priv->counter-1;
sarea_priv->last_dispatch = (int) hw_status[5];
-
- return 0;
+ return 0;
}
@@ -1387,40 +1427,6 @@ int i810_getbuf(struct inode *inode, struct file *filp, unsigned int cmd,
return retcode;
}
-int i810_copybuf(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_i810_copy_t d;
- drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private;
- u32 *hw_status = (u32 *)dev_priv->hw_status_page;
- drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
- dev_priv->sarea_priv;
- drm_buf_t *buf;
- drm_i810_buf_priv_t *buf_priv;
- drm_device_dma_t *dma = dev->dma;
-
- if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
- DRM_ERROR("i810_dma called without lock held\n");
- return -EINVAL;
- }
-
- if (copy_from_user(&d, (drm_i810_copy_t *)arg, sizeof(d)))
- return -EFAULT;
-
- if(d.idx > dma->buf_count) return -EINVAL;
- buf = dma->buflist[ d.idx ];
- buf_priv = buf->dev_private;
- if (buf_priv->currently_mapped != I810_BUF_MAPPED) return -EPERM;
-
- if (copy_from_user(buf_priv->virtual, d.address, d.used))
- return -EFAULT;
-
- sarea_priv->last_dispatch = (int) hw_status[5];
-
- return 0;
-}
int i810_docopy(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
diff --git a/linux/i810_drm.h b/linux/i810_drm.h
index c5f51c9a..c1aea5be 100644
--- a/linux/i810_drm.h
+++ b/linux/i810_drm.h
@@ -13,19 +13,17 @@
#define I810_DMA_BUF_NR 256
#define I810_NR_SAREA_CLIPRECTS 8
-/* Each region is a minimum of 64k, and there are at most 64 of them.
+/* Each region is a minimum of 64k, and there are at most 32 of them.
*/
-#define I810_NR_TEX_REGIONS 64
+#define I810_NR_TEX_REGIONS 32
#define I810_LOG_MIN_TEX_REGION_SIZE 16
#endif
-#define I810_UPLOAD_TEX0IMAGE 0x1 /* handled clientside */
-#define I810_UPLOAD_TEX1IMAGE 0x2 /* handled clientside */
-#define I810_UPLOAD_CTX 0x4
-#define I810_UPLOAD_BUFFERS 0x8
-#define I810_UPLOAD_TEX0 0x10
-#define I810_UPLOAD_TEX1 0x20
-#define I810_UPLOAD_CLIPRECTS 0x40
+
+#define I810_UPLOAD_CTX 0x1
+#define I810_UPLOAD_BUFFERS 0x2
+#define I810_UPLOAD_TEX0 0x4
+#define I810_UPLOAD_TEX1 0x8
/* Indices into buf.Setup where various bits of state are mirrored per
@@ -88,6 +86,8 @@
#define I810_TEXREG_MCS 7 /* GFX_OP_MAP_COORD_SETS ??? */
#define I810_TEX_SETUP_SIZE 8
+/* Flags for clear ioctl
+ */
#define I810_FRONT 0x1
#define I810_BACK 0x2
#define I810_DEPTH 0x4
@@ -122,12 +122,42 @@ typedef struct _drm_i810_tex_region {
int age; /* tracked by clients to update local LRU's */
} drm_i810_tex_region_t;
+typedef struct _drm_i810_state {
+ unsigned int Setup[I810_CTX_SETUP_SIZE];
+ unsigned int BufferSetup[I810_DEST_SETUP_SIZE];
+ unsigned int TexSetup[2][I810_TEX_SETUP_SIZE];
+} drm_i810_state_t;
+
+#define PR_TRIANGLES (0x0)
+#define PR_TRISTRIP_0 (0x1)
+#define PR_TRISTRIP_1 (0x2)
+#define PR_TRIFAN (0x3)
+#define PR_POLYGON (0x4)
+#define PR_LINES (0x5)
+#define PR_LINESTRIP (0x6)
+#define PR_RECTS (0x7)
+
+typedef struct _drm_i810_prim {
+ int start;
+ int finish;
+ char prim;
+ char dirty;
+ char stateidx;
+} drm_i810_prim_t;
+
+#define I810_MAX_PRIMS 70
+#define I810_MAX_STATES 3
+
typedef struct _drm_i810_sarea {
- unsigned int ContextState[I810_CTX_SETUP_SIZE];
- unsigned int BufferState[I810_DEST_SETUP_SIZE];
- unsigned int TexState[2][I810_TEX_SETUP_SIZE];
- unsigned int dirty;
+ /* Allow multiple states and primitives per vertex buffer ioctl:
+ */
+ drm_i810_state_t state[I810_MAX_STATES];
+ drm_i810_prim_t prim[I810_MAX_PRIMS];
+ unsigned int primnr;
+
+ /* Multiple cliprects per vertex buffer ioctl:
+ */
unsigned int nbox;
drm_clip_rect_t boxes[I810_NR_SAREA_CLIPRECTS];
@@ -145,18 +175,16 @@ typedef struct _drm_i810_sarea {
* areas to kick out. There is no need to choose whether to
* kick out your own texture or someone else's - simply eject
* them all in LRU order.
- */
-
+ */
drm_i810_tex_region_t texList[I810_NR_TEX_REGIONS+1];
/* Last elt is sentinal */
int texAge; /* last time texture was uploaded */
+
int last_enqueue; /* last time a buffer was enqueued */
int last_dispatch; /* age of the most recently dispatched buffer */
int last_quiescent; /* */
int ctxOwner; /* last context to upload state */
- int vertex_prim;
-
} drm_i810_sarea_t;
typedef struct _drm_i810_clear {
@@ -166,7 +194,6 @@ typedef struct _drm_i810_clear {
} drm_i810_clear_t;
-
/* These may be placeholders if we have more cliprects than
* I810_NR_SAREA_CLIPRECTS. In that case, the client sets discard to
* false, indicating that the buffer will be dispatched again with a
@@ -174,16 +201,11 @@ typedef struct _drm_i810_clear {
*/
typedef struct _drm_i810_vertex {
int idx; /* buffer index */
- int used; /* nr bytes in use */
+ int copy_size; /* nr bytes to copy (0 if using unmap) */
+ void *copy_address; /* address to copy from */
int discard; /* client is finished with the buffer? */
} drm_i810_vertex_t;
-typedef struct _drm_i810_copy_t {
- int idx; /* buffer index */
- int used; /* nr bytes in use */
- void *address; /* Address to copy from */
-} drm_i810_copy_t;
-
typedef struct drm_i810_dma {
void *virtual;
int request_idx;
diff --git a/linux/i810_drv.c b/linux/i810_drv.c
index 7152eac3..65177555 100644
--- a/linux/i810_drv.c
+++ b/linux/i810_drv.c
@@ -111,7 +111,6 @@ static drm_ioctl_desc_t i810_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_I810_GETAGE)] = { i810_getage, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_I810_GETBUF)] = { i810_getbuf, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_I810_SWAP)] = { i810_swap_bufs, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_I810_COPY)] = { i810_copybuf, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_I810_DOCOPY)] = { i810_docopy, 1, 0 },
};
diff --git a/linux/radeon_drm.h b/linux/radeon_drm.h
index c5f9f66d..6cf92863 100644
--- a/linux/radeon_drm.h
+++ b/linux/radeon_drm.h
@@ -41,40 +41,27 @@
/* What needs to be changed for the current vertex buffer?
*/
#define RADEON_UPLOAD_CONTEXT 0x00000001
-#define RADEON_UPLOAD_VERTFMT 0x00000002
+#define RADEON_UPLOAD_MISC 0x00000002
#define RADEON_UPLOAD_LINE 0x00000004
#define RADEON_UPLOAD_BUMPMAP 0x00000008
#define RADEON_UPLOAD_MASKS 0x00000010
#define RADEON_UPLOAD_VIEWPORT 0x00000020
#define RADEON_UPLOAD_SETUP 0x00000040
#define RADEON_UPLOAD_TCL 0x00000080
-#define RADEON_UPLOAD_MISC 0x00000100
-#define RADEON_UPLOAD_TEX0 0x00000200
-#define RADEON_UPLOAD_TEX1 0x00000400
-#define RADEON_UPLOAD_TEX2 0x00000800
-#define RADEON_UPLOAD_TEX0IMAGES 0x00001000
-#define RADEON_UPLOAD_TEX1IMAGES 0x00002000
-#define RADEON_UPLOAD_TEX2IMAGES 0x00004000
-#define RADEON_UPLOAD_CLIPRECTS 0x00008000 /* handled client-side */
-#define RADEON_REQUIRE_QUIESCENCE 0x00010000
-#define RADEON_UPLOAD_ALL 0x0001ffff
+#define RADEON_UPLOAD_TEX0 0x00000100
+#define RADEON_UPLOAD_TEX1 0x00000200
+#define RADEON_UPLOAD_TEX2 0x00000400
+#define RADEON_UPLOAD_CONTEXT_ALL 0x000000ff
+#define RADEON_UPLOAD_ALL 0x000007ff
#define RADEON_FRONT 0x1
#define RADEON_BACK 0x2
#define RADEON_DEPTH 0x4
-/* Primitive types
- */
-#define RADEON_POINTS 0x1
-#define RADEON_LINES 0x2
-#define RADEON_LINE_STRIP 0x3
-#define RADEON_TRIANGLES 0x4
-#define RADEON_TRIANGLE_FAN 0x5
-#define RADEON_TRIANGLE_STRIP 0x6
/* Vertex/indirect buffer size
*/
-#define RADEON_BUFFER_SIZE 16384
+#define RADEON_BUFFER_SIZE 65536
/* Byte offsets for indirect buffer data
*/
@@ -88,12 +75,12 @@
#define RADEON_NR_SAREA_CLIPRECTS 12
/* There are 2 heaps (local/AGP). Each region within a heap is a
- * minimum of 64k, and there are at most 64 of them per heap.
+ * minimum of 64k, and there are at most 32 of them per heap.
*/
#define RADEON_LOCAL_TEX_HEAP 0
#define RADEON_AGP_TEX_HEAP 1
#define RADEON_NR_TEX_HEAPS 2
-#define RADEON_NR_TEX_REGIONS 64
+#define RADEON_NR_TEX_REGIONS 32
#define RADEON_LOG_TEX_GRANULARITY 16
#define RADEON_MAX_TEXTURE_LEVELS 11
@@ -108,8 +95,8 @@ typedef struct {
unsigned int alpha;
} radeon_color_regs_t;
+/* Context state */
typedef struct {
- /* Context state */
unsigned int pp_misc; /* 0x1c14 */
unsigned int pp_fog_color;
unsigned int re_solid_color;
@@ -117,47 +104,55 @@ typedef struct {
unsigned int rb3d_depthoffset;
unsigned int rb3d_depthpitch;
unsigned int rb3d_zstencilcntl;
-
unsigned int pp_cntl; /* 0x1c38 */
unsigned int rb3d_cntl;
unsigned int rb3d_coloroffset;
unsigned int re_width_height;
unsigned int rb3d_colorpitch;
- unsigned int se_cntl;
+} drm_radeon_context_state_t;
- /* Vertex format state */
- unsigned int se_coord_fmt; /* 0x1c50 */
- /* Line state */
+/* Line state */
+typedef struct {
unsigned int re_line_pattern; /* 0x1cd0 */
unsigned int re_line_state;
-
unsigned int se_line_width; /* 0x1db8 */
+} drm_radeon_line_state_t;
- /* Bumpmap state */
+/* Bumpmap state */
+typedef struct {
unsigned int pp_lum_matrix; /* 0x1d00 */
-
unsigned int pp_rot_matrix_0; /* 0x1d58 */
unsigned int pp_rot_matrix_1;
+} drm_radeon_bumpmap_state_t;
- /* Mask state */
+/* Mask state */
+typedef struct {
unsigned int rb3d_stencilrefmask; /* 0x1d7c */
unsigned int rb3d_ropcntl;
unsigned int rb3d_planemask;
+} drm_radeon_mask_state_t;
- /* Viewport state */
+/* Viewport state */
+typedef struct {
unsigned int se_vport_xscale; /* 0x1d98 */
unsigned int se_vport_xoffset;
unsigned int se_vport_yscale;
unsigned int se_vport_yoffset;
unsigned int se_vport_zscale;
unsigned int se_vport_zoffset;
+} drm_radeon_viewport_state_t;
- /* Setup state */
+/* Setup state */
+typedef struct {
+ unsigned int se_cntl;
unsigned int se_cntl_status; /* 0x2140 */
+ unsigned int se_coord_fmt; /* 0x1c50 */
+} drm_radeon_setup_state_t;
#ifdef TCL_ENABLE
- /* TCL state */
+/* TCL state */
+typedef struct {
radeon_color_regs_t se_tcl_material_emmissive; /* 0x2210 */
radeon_color_regs_t se_tcl_material_ambient;
radeon_color_regs_t se_tcl_material_diffuse;
@@ -171,12 +166,13 @@ typedef struct {
unsigned int se_tcl_texture_proc_ctl;
unsigned int se_tcl_light_model_ctl;
unsigned int se_tcl_per_light_ctl[4];
+} drm_radeon_tcl_state_t;
#endif
- /* Misc state */
- unsigned int re_top_left; /* 0x26c0 */
+/* Misc state */
+typedef struct {
unsigned int re_misc;
-} drm_radeon_context_regs_t;
+} drm_radeon_misc_state_t;
/* Setup registers for each texture unit
*/
@@ -187,9 +183,7 @@ typedef struct {
unsigned int pp_txcblend;
unsigned int pp_txablend;
unsigned int pp_tfactor;
-
unsigned int pp_border_color;
-
#ifdef CUBIC_ENABLE
unsigned int pp_cubic_faces;
unsigned int pp_cubic_offset[5];
@@ -202,15 +196,43 @@ typedef struct {
int age;
} drm_radeon_tex_region_t;
+
+typedef struct {
+ drm_radeon_context_state_t context;
+ drm_radeon_line_state_t line;
+ drm_radeon_bumpmap_state_t bumpmap;
+ drm_radeon_mask_state_t mask;
+ drm_radeon_viewport_state_t viewport;
+ drm_radeon_setup_state_t setup;
+ drm_radeon_misc_state_t misc;
+ drm_radeon_texture_regs_t texunit[RADEON_MAX_TEXTURE_UNITS];
+ int dirty;
+} drm_radeon_state_t;
+
+/* Space is crucial; there is some redunancy here:
+ */
+typedef struct {
+ unsigned int start;
+ unsigned int finish;
+ unsigned int prim:8;
+ unsigned int stateidx:8;
+ unsigned int numverts:16; /* overloaded as offset/64 for elt prims */
+ unsigned int vc_format;
+} drm_radeon_prim_t;
+
+/* Really need a bigger area to hold the primitive and state data:
+ */
+#define RADEON_MAX_PRIMS 30
+#define RADEON_MAX_STATES 2
+
+
typedef struct {
/* The channel for communication of state information to the kernel
* on firing a vertex buffer.
*/
- drm_radeon_context_regs_t context_state;
- drm_radeon_texture_regs_t tex_state[RADEON_MAX_TEXTURE_UNITS];
- unsigned int dirty;
- unsigned int vertsize;
- unsigned int vc_format;
+ drm_radeon_state_t state[RADEON_MAX_STATES];
+ drm_radeon_prim_t prim[RADEON_MAX_PRIMS];
+ unsigned int primnr;
/* The current cliprects, or a subset thereof.
*/
@@ -280,6 +302,7 @@ typedef struct drm_radeon_clear {
unsigned int flags;
int x, y, w, h;
unsigned int clear_color;
+ unsigned int clear_colormask;
unsigned int clear_depth;
union {
float f[5];
@@ -288,20 +311,10 @@ typedef struct drm_radeon_clear {
} drm_radeon_clear_t;
typedef struct drm_radeon_vertex {
- int prim;
int idx; /* Index of vertex buffer */
- int count; /* Number of vertices in buffer */
int discard; /* Client finished with buffer? */
} drm_radeon_vertex_t;
-typedef struct drm_radeon_indices {
- int prim;
- int idx;
- int start;
- int end;
- int discard; /* Client finished with buffer? */
-} drm_radeon_indices_t;
-
typedef struct drm_radeon_blit {
int idx;
int pitch;
diff --git a/linux/radeon_drv.c b/linux/radeon_drv.c
index 0113ed97..1735e262 100644
--- a/linux/radeon_drv.c
+++ b/linux/radeon_drv.c
@@ -116,7 +116,6 @@ static drm_ioctl_desc_t radeon_ioctls[] = {
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_SWAP)] = { radeon_cp_swap, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_CLEAR)] = { radeon_cp_clear, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX)] = { radeon_cp_vertex, 1, 0 },
- [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDICES)] = { radeon_cp_indices, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_BLIT)] = { radeon_cp_blit, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 },
[DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)]= { radeon_cp_indirect,1, 1 },
diff --git a/linux/radeon_drv.h b/linux/radeon_drv.h
index 06b54199..bead83e0 100644
--- a/linux/radeon_drv.h
+++ b/linux/radeon_drv.h
@@ -491,11 +491,12 @@ extern int radeon_context_switch_complete(drm_device_t *dev, int new);
#define RADEON_PRIM_TYPE_LINE_STRIP (3 << 0)
#define RADEON_PRIM_TYPE_TRI_LIST (4 << 0)
#define RADEON_PRIM_TYPE_TRI_FAN (5 << 0)
-#define RADEON_PRIM_TYPE_TRI_STRIP (6 << 0)
-#define RADEON_PRIM_TYPE_TRI_TYPE2 (7 << 0)
+#define RADEON_PRIM_TYPE_TRI_STRIP_0 (6 << 0)
+#define RADEON_PRIM_TYPE_TRI_TYPE_2 (7 << 0)
#define RADEON_PRIM_TYPE_RECT_LIST (8 << 0)
#define RADEON_PRIM_TYPE_3VRT_POINT_LIST (9 << 0)
#define RADEON_PRIM_TYPE_3VRT_LINE_LIST (10 << 0)
+#define RADEON_PRIM_TYPE_MASK 0xf
#define RADEON_PRIM_WALK_IND (1 << 4)
#define RADEON_PRIM_WALK_LIST (2 << 4)
#define RADEON_PRIM_WALK_RING (3 << 4)
diff --git a/linux/radeon_state.c b/linux/radeon_state.c
index 7bfefb2c..6ef4f15f 100644
--- a/linux/radeon_state.c
+++ b/linux/radeon_state.c
@@ -48,20 +48,16 @@ static inline void radeon_emit_clip_rect( drm_radeon_private_t *dev_priv,
box->x1, box->y1, box->x2, box->y2 );
BEGIN_RING( 4 );
-
OUT_RING( CP_PACKET0( RADEON_RE_TOP_LEFT, 0 ) );
OUT_RING( (box->y1 << 16) | box->x1 );
-
OUT_RING( CP_PACKET0( RADEON_RE_WIDTH_HEIGHT, 0 ) );
OUT_RING( ((box->y2 - 1) << 16) | (box->x2 - 1) );
-
ADVANCE_RING();
}
-static inline void radeon_emit_context( drm_radeon_private_t *dev_priv )
+static inline void radeon_emit_context( drm_radeon_private_t *dev_priv,
+ drm_radeon_context_state_t *ctx )
{
- drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
- drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
RING_LOCALS;
DRM_DEBUG( " %s\n", __FUNCTION__ );
@@ -87,177 +83,155 @@ static inline void radeon_emit_context( drm_radeon_private_t *dev_priv )
ADVANCE_RING();
}
-static inline void radeon_emit_vertfmt( drm_radeon_private_t *dev_priv )
+static inline void radeon_emit_line( drm_radeon_private_t *dev_priv,
+ drm_radeon_line_state_t *line )
{
- drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
- drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
- RING_LOCALS;
- DRM_DEBUG( " %s\n", __FUNCTION__ );
-
- BEGIN_RING( 2 );
-
- OUT_RING( CP_PACKET0( RADEON_SE_COORD_FMT, 0 ) );
- OUT_RING( ctx->se_coord_fmt );
-
- ADVANCE_RING();
-}
-
-static inline void radeon_emit_line( drm_radeon_private_t *dev_priv )
-{
- drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
- drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
RING_LOCALS;
DRM_DEBUG( " %s\n", __FUNCTION__ );
BEGIN_RING( 5 );
OUT_RING( CP_PACKET0( RADEON_RE_LINE_PATTERN, 1 ) );
- OUT_RING( ctx->re_line_pattern );
- OUT_RING( ctx->re_line_state );
+ OUT_RING( line->re_line_pattern );
+ OUT_RING( line->re_line_state );
OUT_RING( CP_PACKET0( RADEON_SE_LINE_WIDTH, 0 ) );
- OUT_RING( ctx->se_line_width );
+ OUT_RING( line->se_line_width );
ADVANCE_RING();
}
-static inline void radeon_emit_bumpmap( drm_radeon_private_t *dev_priv )
+static inline void radeon_emit_bumpmap( drm_radeon_private_t *dev_priv,
+ drm_radeon_bumpmap_state_t *bumpmap )
{
- drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
- drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
RING_LOCALS;
DRM_DEBUG( " %s\n", __FUNCTION__ );
BEGIN_RING( 5 );
OUT_RING( CP_PACKET0( RADEON_PP_LUM_MATRIX, 0 ) );
- OUT_RING( ctx->pp_lum_matrix );
+ OUT_RING( bumpmap->pp_lum_matrix );
OUT_RING( CP_PACKET0( RADEON_PP_ROT_MATRIX_0, 1 ) );
- OUT_RING( ctx->pp_rot_matrix_0 );
- OUT_RING( ctx->pp_rot_matrix_1 );
+ OUT_RING( bumpmap->pp_rot_matrix_0 );
+ OUT_RING( bumpmap->pp_rot_matrix_1 );
ADVANCE_RING();
}
-static inline void radeon_emit_masks( drm_radeon_private_t *dev_priv )
+static inline void radeon_emit_masks( drm_radeon_private_t *dev_priv,
+ drm_radeon_mask_state_t *masks )
{
- drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
- drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
RING_LOCALS;
DRM_DEBUG( " %s\n", __FUNCTION__ );
BEGIN_RING( 4 );
OUT_RING( CP_PACKET0( RADEON_RB3D_STENCILREFMASK, 2 ) );
- OUT_RING( ctx->rb3d_stencilrefmask );
- OUT_RING( ctx->rb3d_ropcntl );
- OUT_RING( ctx->rb3d_planemask );
+ OUT_RING( masks->rb3d_stencilrefmask );
+ OUT_RING( masks->rb3d_ropcntl );
+ OUT_RING( masks->rb3d_planemask );
ADVANCE_RING();
}
-static inline void radeon_emit_viewport( drm_radeon_private_t *dev_priv )
+static inline void radeon_emit_viewport( drm_radeon_private_t *dev_priv,
+ drm_radeon_viewport_state_t *viewport )
{
- drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
- drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
RING_LOCALS;
DRM_DEBUG( " %s\n", __FUNCTION__ );
BEGIN_RING( 7 );
OUT_RING( CP_PACKET0( RADEON_SE_VPORT_XSCALE, 5 ) );
- OUT_RING( ctx->se_vport_xscale );
- OUT_RING( ctx->se_vport_xoffset );
- OUT_RING( ctx->se_vport_yscale );
- OUT_RING( ctx->se_vport_yoffset );
- OUT_RING( ctx->se_vport_zscale );
- OUT_RING( ctx->se_vport_zoffset );
+ OUT_RING( viewport->se_vport_xscale );
+ OUT_RING( viewport->se_vport_xoffset );
+ OUT_RING( viewport->se_vport_yscale );
+ OUT_RING( viewport->se_vport_yoffset );
+ OUT_RING( viewport->se_vport_zscale );
+ OUT_RING( viewport->se_vport_zoffset );
ADVANCE_RING();
}
-static inline void radeon_emit_setup( drm_radeon_private_t *dev_priv )
+static inline void radeon_emit_setup( drm_radeon_private_t *dev_priv,
+ drm_radeon_setup_state_t *setup )
{
- drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
- drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
RING_LOCALS;
DRM_DEBUG( " %s\n", __FUNCTION__ );
BEGIN_RING( 4 );
OUT_RING( CP_PACKET0( RADEON_SE_CNTL, 0 ) );
- OUT_RING( ctx->se_cntl );
+ OUT_RING( setup->se_cntl );
OUT_RING( CP_PACKET0( RADEON_SE_CNTL_STATUS, 0 ) );
- OUT_RING( ctx->se_cntl_status );
+ OUT_RING( setup->se_cntl_status );
+ OUT_RING( CP_PACKET0( RADEON_SE_COORD_FMT, 0 ) );
+ OUT_RING( setup->se_coord_fmt );
ADVANCE_RING();
}
-static inline void radeon_emit_tcl( drm_radeon_private_t *dev_priv )
-{
#ifdef TCL_ENABLE
- drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
- drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
+static inline void radeon_emit_tcl( drm_radeon_private_t *dev_priv,
+ drm_radeon_tcl_state_t *tcl )
+{
RING_LOCALS;
DRM_DEBUG( " %s\n", __FUNCTION__ );
BEGIN_RING( 29 );
OUT_RING( CP_PACKET0( RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED, 27 ) );
- OUT_RING( ctx->se_tcl_material_emmissive.red );
- OUT_RING( ctx->se_tcl_material_emmissive.green );
- OUT_RING( ctx->se_tcl_material_emmissive.blue );
- OUT_RING( ctx->se_tcl_material_emmissive.alpha );
- OUT_RING( ctx->se_tcl_material_ambient.red );
- OUT_RING( ctx->se_tcl_material_ambient.green );
- OUT_RING( ctx->se_tcl_material_ambient.blue );
- OUT_RING( ctx->se_tcl_material_ambient.alpha );
- OUT_RING( ctx->se_tcl_material_diffuse.red );
- OUT_RING( ctx->se_tcl_material_diffuse.green );
- OUT_RING( ctx->se_tcl_material_diffuse.blue );
- OUT_RING( ctx->se_tcl_material_diffuse.alpha );
- OUT_RING( ctx->se_tcl_material_specular.red );
- OUT_RING( ctx->se_tcl_material_specular.green );
- OUT_RING( ctx->se_tcl_material_specular.blue );
- OUT_RING( ctx->se_tcl_material_specular.alpha );
- OUT_RING( ctx->se_tcl_shininess );
- OUT_RING( ctx->se_tcl_output_vtx_fmt );
- OUT_RING( ctx->se_tcl_output_vtx_sel );
- OUT_RING( ctx->se_tcl_matrix_select_0 );
- OUT_RING( ctx->se_tcl_matrix_select_1 );
- OUT_RING( ctx->se_tcl_ucp_vert_blend_ctl );
- OUT_RING( ctx->se_tcl_texture_proc_ctl );
- OUT_RING( ctx->se_tcl_light_model_ctl );
- for ( i = 0 ; i < 4 ; i++ ) {
- OUT_RING( ctx->se_tcl_per_light_ctl[i] );
- }
+ OUT_RING( tcl->se_tcl_material_emmissive.red );
+ OUT_RING( tcl->se_tcl_material_emmissive.green );
+ OUT_RING( tcl->se_tcl_material_emmissive.blue );
+ OUT_RING( tcl->se_tcl_material_emmissive.alpha );
+ OUT_RING( tcl->se_tcl_material_ambient.red );
+ OUT_RING( tcl->se_tcl_material_ambient.green );
+ OUT_RING( tcl->se_tcl_material_ambient.blue );
+ OUT_RING( tcl->se_tcl_material_ambient.alpha );
+ OUT_RING( tcl->se_tcl_material_diffuse.red );
+ OUT_RING( tcl->se_tcl_material_diffuse.green );
+ OUT_RING( tcl->se_tcl_material_diffuse.blue );
+ OUT_RING( tcl->se_tcl_material_diffuse.alpha );
+ OUT_RING( tcl->se_tcl_material_specular.red );
+ OUT_RING( tcl->se_tcl_material_specular.green );
+ OUT_RING( tcl->se_tcl_material_specular.blue );
+ OUT_RING( tcl->se_tcl_material_specular.alpha );
+ OUT_RING( tcl->se_tcl_shininess );
+ OUT_RING( tcl->se_tcl_output_vtx_fmt );
+ OUT_RING( tcl->se_tcl_output_vtx_sel );
+ OUT_RING( tcl->se_tcl_matrix_select_0 );
+ OUT_RING( tcl->se_tcl_matrix_select_1 );
+ OUT_RING( tcl->se_tcl_ucp_vert_blend_ctl );
+ OUT_RING( tcl->se_tcl_texture_proc_ctl );
+ OUT_RING( tcl->se_tcl_light_model_ctl );
+ OUT_RING( tcl->se_tcl_per_light_ctl[0] );
+ OUT_RING( tcl->se_tcl_per_light_ctl[1] );
+ OUT_RING( tcl->se_tcl_per_light_ctl[2] );
+ OUT_RING( tcl->se_tcl_per_light_ctl[3] );
ADVANCE_RING();
-#else
- DRM_ERROR( "TCL not enabled!\n" );
-#endif
}
+#endif
-static inline void radeon_emit_misc( drm_radeon_private_t *dev_priv )
+static inline void radeon_emit_misc( drm_radeon_private_t *dev_priv,
+ drm_radeon_misc_state_t *misc )
{
- drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
- drm_radeon_context_regs_t *ctx = &sarea_priv->context_state;
RING_LOCALS;
DRM_DEBUG( " %s\n", __FUNCTION__ );
BEGIN_RING( 2 );
OUT_RING( CP_PACKET0( RADEON_RE_MISC, 0 ) );
- OUT_RING( ctx->re_misc );
+ OUT_RING( misc->re_misc );
ADVANCE_RING();
}
-static inline void radeon_emit_tex0( drm_radeon_private_t *dev_priv )
+static inline void radeon_emit_tex0( drm_radeon_private_t *dev_priv,
+ drm_radeon_texture_regs_t *tex )
{
- drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
- drm_radeon_texture_regs_t *tex = &sarea_priv->tex_state[0];
RING_LOCALS;
DRM_DEBUG( " %s: offset=0x%x\n", __FUNCTION__, tex->pp_txoffset );
@@ -277,10 +251,9 @@ static inline void radeon_emit_tex0( drm_radeon_private_t *dev_priv )
ADVANCE_RING();
}
-static inline void radeon_emit_tex1( drm_radeon_private_t *dev_priv )
+static inline void radeon_emit_tex1( drm_radeon_private_t *dev_priv,
+ drm_radeon_texture_regs_t *tex )
{
- drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
- drm_radeon_texture_regs_t *tex = &sarea_priv->tex_state[1];
RING_LOCALS;
DRM_DEBUG( " %s: offset=0x%x\n", __FUNCTION__, tex->pp_txoffset );
@@ -300,10 +273,9 @@ static inline void radeon_emit_tex1( drm_radeon_private_t *dev_priv )
ADVANCE_RING();
}
-static inline void radeon_emit_tex2( drm_radeon_private_t *dev_priv )
+static inline void radeon_emit_tex2( drm_radeon_private_t *dev_priv,
+ drm_radeon_texture_regs_t *tex )
{
- drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
- drm_radeon_texture_regs_t *tex = &sarea_priv->tex_state[2];
RING_LOCALS;
DRM_DEBUG( " %s\n", __FUNCTION__ );
@@ -323,81 +295,79 @@ static inline void radeon_emit_tex2( drm_radeon_private_t *dev_priv )
ADVANCE_RING();
}
-static inline void radeon_emit_state( drm_radeon_private_t *dev_priv )
+static void radeon_print_dirty( const char *msg, unsigned int flags )
{
- drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
- unsigned int dirty = sarea_priv->dirty;
+ DRM_DEBUG( "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s\n",
+ msg,
+ flags,
+ (flags & RADEON_UPLOAD_CONTEXT) ? "context, " : "",
+ (flags & RADEON_UPLOAD_LINE) ? "line, " : "",
+ (flags & RADEON_UPLOAD_BUMPMAP) ? "bumpmap, " : "",
+ (flags & RADEON_UPLOAD_MASKS) ? "masks, " : "",
+ (flags & RADEON_UPLOAD_VIEWPORT) ? "viewport, " : "",
+ (flags & RADEON_UPLOAD_SETUP) ? "setup, " : "",
+ (flags & RADEON_UPLOAD_TCL) ? "tcl, " : "",
+ (flags & RADEON_UPLOAD_MISC) ? "misc, " : "",
+ (flags & RADEON_UPLOAD_TEX0) ? "tex0, " : "",
+ (flags & RADEON_UPLOAD_TEX1) ? "tex1, " : "",
+ (flags & RADEON_UPLOAD_TEX2) ? "tex2, " : "");
- DRM_DEBUG( "%s: dirty=0x%08x\n", __FUNCTION__, dirty );
+}
- if ( dirty & RADEON_UPLOAD_CONTEXT ) {
- radeon_emit_context( dev_priv );
- sarea_priv->dirty &= ~RADEON_UPLOAD_CONTEXT;
- }
+static inline void radeon_emit_state( drm_radeon_private_t *dev_priv,
+ drm_radeon_state_t *state )
+{
+ unsigned int dirty = state->dirty;
+
+ radeon_print_dirty( __FUNCTION__, dirty );
- if ( dirty & RADEON_UPLOAD_VERTFMT ) {
- radeon_emit_vertfmt( dev_priv );
- sarea_priv->dirty &= ~RADEON_UPLOAD_VERTFMT;
+ if ( dirty & RADEON_UPLOAD_CONTEXT ) {
+ radeon_emit_context( dev_priv, &state->context );
}
if ( dirty & RADEON_UPLOAD_LINE ) {
- radeon_emit_line( dev_priv );
- sarea_priv->dirty &= ~RADEON_UPLOAD_LINE;
+ radeon_emit_line( dev_priv, &state->line );
}
if ( dirty & RADEON_UPLOAD_BUMPMAP ) {
- radeon_emit_bumpmap( dev_priv );
- sarea_priv->dirty &= ~RADEON_UPLOAD_BUMPMAP;
+ radeon_emit_bumpmap( dev_priv, &state->bumpmap );
}
if ( dirty & RADEON_UPLOAD_MASKS ) {
- radeon_emit_masks( dev_priv );
- sarea_priv->dirty &= ~RADEON_UPLOAD_MASKS;
+ radeon_emit_masks( dev_priv, &state->mask );
}
if ( dirty & RADEON_UPLOAD_VIEWPORT ) {
- radeon_emit_viewport( dev_priv );
- sarea_priv->dirty &= ~RADEON_UPLOAD_VIEWPORT;
+ radeon_emit_viewport( dev_priv, &state->viewport );
}
if ( dirty & RADEON_UPLOAD_SETUP ) {
- radeon_emit_setup( dev_priv );
- sarea_priv->dirty &= ~RADEON_UPLOAD_SETUP;
+ radeon_emit_setup( dev_priv, &state->setup );
}
- if ( dirty & RADEON_UPLOAD_TCL ) {
#ifdef TCL_ENABLE
- radeon_emit_tcl( dev_priv );
-#endif
- sarea_priv->dirty &= ~RADEON_UPLOAD_TCL;
+ if ( dirty & RADEON_UPLOAD_TCL ) {
+ radeon_emit_tcl( dev_priv, &state->tcl );
}
+#endif
if ( dirty & RADEON_UPLOAD_MISC ) {
- radeon_emit_misc( dev_priv );
- sarea_priv->dirty &= ~RADEON_UPLOAD_MISC;
+ radeon_emit_misc( dev_priv, &state->misc );
}
if ( dirty & RADEON_UPLOAD_TEX0 ) {
- radeon_emit_tex0( dev_priv );
- sarea_priv->dirty &= ~RADEON_UPLOAD_TEX0;
+ radeon_emit_tex0( dev_priv, &state->texunit[0] );
}
if ( dirty & RADEON_UPLOAD_TEX1 ) {
- radeon_emit_tex1( dev_priv );
- sarea_priv->dirty &= ~RADEON_UPLOAD_TEX1;
+ radeon_emit_tex1( dev_priv, &state->texunit[1] );
}
- if ( dirty & RADEON_UPLOAD_TEX2 ) {
#if 0
- radeon_emit_tex2( dev_priv );
-#endif
- sarea_priv->dirty &= ~RADEON_UPLOAD_TEX2;
+ if ( dirty & RADEON_UPLOAD_TEX2 ) {
+ radeon_emit_tex2( dev_priv, &state->texunit[2] );
}
-
- sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES |
- RADEON_UPLOAD_TEX1IMAGES |
- RADEON_UPLOAD_TEX2IMAGES |
- RADEON_REQUIRE_QUIESCENCE);
+#endif
}
@@ -464,26 +434,6 @@ static void radeon_cp_performance_boxes( drm_radeon_private_t *dev_priv )
* CP command dispatch functions
*/
-static void radeon_print_dirty( const char *msg, unsigned int flags )
-{
- DRM_DEBUG( "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
- msg,
- flags,
- (flags & RADEON_UPLOAD_CONTEXT) ? "context, " : "",
- (flags & RADEON_UPLOAD_VERTFMT) ? "vertfmt, " : "",
- (flags & RADEON_UPLOAD_LINE) ? "line, " : "",
- (flags & RADEON_UPLOAD_BUMPMAP) ? "bumpmap, " : "",
- (flags & RADEON_UPLOAD_MASKS) ? "masks, " : "",
- (flags & RADEON_UPLOAD_VIEWPORT) ? "viewport, " : "",
- (flags & RADEON_UPLOAD_SETUP) ? "setup, " : "",
- (flags & RADEON_UPLOAD_TCL) ? "tcl, " : "",
- (flags & RADEON_UPLOAD_MISC) ? "misc, " : "",
- (flags & RADEON_UPLOAD_TEX0) ? "tex0, " : "",
- (flags & RADEON_UPLOAD_TEX1) ? "tex1, " : "",
- (flags & RADEON_UPLOAD_TEX2) ? "tex2, " : "",
- (flags & RADEON_UPLOAD_CLIPRECTS) ? "cliprects, " : "",
- (flags & RADEON_REQUIRE_QUIESCENCE) ? "quiescence, " : "" );
-}
static void radeon_cp_dispatch_clear( drm_device_t *dev,
drm_radeon_clear_t *clear )
@@ -525,14 +475,13 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev,
RADEON_WAIT_UNTIL_3D_IDLE();
OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) );
- OUT_RING( sarea_priv->context_state.rb3d_planemask );
+ OUT_RING( clear->clear_colormask );
ADVANCE_RING();
/* Make sure we restore the 3D state next time.
*/
- dev_priv->sarea_priv->dirty |= (RADEON_UPLOAD_CONTEXT |
- RADEON_UPLOAD_MASKS);
+ dev_priv->sarea_priv->ctx_owner = 0;
}
if ( flags & RADEON_FRONT ) {
@@ -580,8 +529,9 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev,
drm_radeon_depth_clear_t *depth_clear =
&dev_priv->depth_clear;
- if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) {
- radeon_emit_state( dev_priv );
+ if ( sarea_priv->state[0].dirty ) {
+ radeon_emit_state( dev_priv,
+ &sarea_priv->state[0] );
}
/* FIXME: Render a rectangle to clear the depth
@@ -625,9 +575,7 @@ static void radeon_cp_dispatch_clear( drm_device_t *dev,
/* Make sure we restore the 3D state next time.
*/
- dev_priv->sarea_priv->dirty |= (RADEON_UPLOAD_CONTEXT |
- RADEON_UPLOAD_SETUP |
- RADEON_UPLOAD_MASKS);
+ dev_priv->sarea_priv->ctx_owner = 0;
}
}
@@ -763,76 +711,74 @@ static void radeon_cp_dispatch_flip( drm_device_t *dev )
}
static void radeon_cp_dispatch_vertex( drm_device_t *dev,
- drm_buf_t *buf )
+ drm_buf_t *buf,
+ drm_radeon_prim_t *prim )
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
- int format = sarea_priv->vc_format;
- int offset = dev_priv->agp_buffers_offset + buf->offset;
- int size = buf->used;
- int prim = buf_priv->prim;
+ drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
+ int offset = dev_priv->agp_buffers_offset + buf->offset + prim->start;
+ int numverts = (int)prim->numverts;
int i = 0;
RING_LOCALS;
- DRM_DEBUG( "%s: nbox=%d\n", __FUNCTION__, sarea_priv->nbox );
- radeon_update_ring_snapshot( dev_priv );
-
- if ( 1 )
- radeon_print_dirty( "dispatch_vertex", sarea_priv->dirty );
+ DRM_DEBUG( "%s: nbox=%d %d..%d prim %x nvert %d\n",
+ __FUNCTION__, sarea_priv->nbox,
+ prim->start, prim->finish, prim->prim,
+ numverts);
- if ( buf->used ) {
- buf_priv->dispatched = 1;
+ radeon_update_ring_snapshot( dev_priv );
- if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) {
- radeon_emit_state( dev_priv );
+ buf_priv->dispatched = 1;
+
+ do {
+ /* Emit the next set of up to three cliprects */
+ if ( i < sarea_priv->nbox ) {
+ radeon_emit_clip_rect( dev_priv,
+ &sarea_priv->boxes[i] );
}
- do {
- /* Emit the next set of up to three cliprects */
- if ( i < sarea_priv->nbox ) {
- radeon_emit_clip_rect( dev_priv,
- &sarea_priv->boxes[i] );
- }
+ /* Emit the vertex buffer rendering commands */
+ BEGIN_RING( 5 );
- /* Emit the vertex buffer rendering commands */
- BEGIN_RING( 5 );
+ OUT_RING( CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, 3 ) );
+ OUT_RING( offset );
+ OUT_RING( numverts );
+ OUT_RING( prim->vc_format );
+ OUT_RING( prim->prim | RADEON_PRIM_WALK_LIST |
+ RADEON_COLOR_ORDER_RGBA |
+ RADEON_VTX_FMT_RADEON_MODE |
+ (numverts << RADEON_NUM_VERTICES_SHIFT) );
- OUT_RING( CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, 3 ) );
- OUT_RING( offset );
- OUT_RING( size );
- OUT_RING( format );
- OUT_RING( prim | RADEON_PRIM_WALK_LIST |
- RADEON_COLOR_ORDER_RGBA |
- RADEON_VTX_FMT_RADEON_MODE |
- (size << RADEON_NUM_VERTICES_SHIFT) );
+ ADVANCE_RING();
- ADVANCE_RING();
+ i++;
+ } while ( i < sarea_priv->nbox );
- i++;
- } while ( i < sarea_priv->nbox );
- }
+ dev_priv->sarea_priv->last_dispatch++;
+}
- if ( buf_priv->discard ) {
- buf_priv->age = dev_priv->sarea_priv->last_dispatch;
- /* Emit the vertex buffer age */
- BEGIN_RING( 2 );
- RADEON_DISPATCH_AGE( buf_priv->age );
- ADVANCE_RING();
+static void radeon_cp_discard_buffer( drm_device_t *dev, drm_buf_t *buf )
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
+ RING_LOCALS;
- buf->pending = 1;
- buf->used = 0;
- /* FIXME: Check dispatched field */
- buf_priv->dispatched = 0;
- }
+ radeon_update_ring_snapshot( dev_priv );
- dev_priv->sarea_priv->last_dispatch++;
+ buf_priv->age = dev_priv->sarea_priv->last_dispatch;
- sarea_priv->dirty &= ~RADEON_UPLOAD_CLIPRECTS;
- sarea_priv->nbox = 0;
-}
+ /* Emit the vertex buffer age */
+ BEGIN_RING( 2 );
+ RADEON_DISPATCH_AGE( buf_priv->age );
+ ADVANCE_RING();
+ buf->pending = 1;
+ buf->used = 0;
+ /* FIXME: Check dispatched field */
+ buf_priv->dispatched = 0;
+}
static void radeon_cp_dispatch_indirect( drm_device_t *dev,
drm_buf_t *buf,
@@ -845,7 +791,7 @@ static void radeon_cp_dispatch_indirect( drm_device_t *dev,
buf->idx, start, end );
radeon_update_ring_snapshot( dev_priv );
-
+
if ( start != end ) {
int offset = (dev_priv->agp_buffers_offset
+ buf->offset + start);
@@ -874,101 +820,78 @@ static void radeon_cp_dispatch_indirect( drm_device_t *dev,
ADVANCE_RING();
}
- if ( buf_priv->discard ) {
- buf_priv->age = dev_priv->sarea_priv->last_dispatch;
-
- /* Emit the indirect buffer age */
- BEGIN_RING( 2 );
- RADEON_DISPATCH_AGE( buf_priv->age );
- ADVANCE_RING();
-
- buf->pending = 1;
- buf->used = 0;
- /* FIXME: Check dispatched field */
- buf_priv->dispatched = 0;
- }
-
dev_priv->sarea_priv->last_dispatch++;
}
static void radeon_cp_dispatch_indices( drm_device_t *dev,
- drm_buf_t *buf,
- int start, int end,
- int count )
+ drm_buf_t *elt_buf,
+ drm_radeon_prim_t *prim )
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
+ drm_radeon_buf_priv_t *buf_priv = elt_buf->dev_private;
drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
- int format = sarea_priv->vc_format;
- int offset = dev_priv->agp_buffers_offset;
- int prim = buf_priv->prim;
+ int offset = dev_priv->agp_buffers_offset + prim->numverts * 64;
u32 *data;
int dwords;
int i = 0;
- RING_LOCALS;
- DRM_DEBUG( "indices: s=%d e=%d c=%d\n", start, end, count );
-
- radeon_update_ring_snapshot( dev_priv );
+ int start = prim->start + RADEON_INDEX_PRIM_OFFSET;
+ int count = (prim->finish - start) / sizeof(u16);
- if ( 0 )
- radeon_print_dirty( "dispatch_indices", sarea_priv->dirty );
+/* printk( "indices: start=%x/%x end=%x count=%d nv %d offset %x\n", */
+/* prim->start, start, prim->finish, count, prim->numverts, */
+/* offset); */
- if ( start != end ) {
+ radeon_update_ring_snapshot( dev_priv );
+
+ if ( start < prim->finish ) {
buf_priv->dispatched = 1;
- if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) {
- radeon_emit_state( dev_priv );
- }
-
- dwords = (end - start + 3) / sizeof(u32);
+ dwords = (prim->finish - prim->start + 3) / sizeof(u32);
- data = (u32 *)((char *)dev_priv->buffers->handle
- + buf->offset + start);
+ data = (u32 *)((char *)dev_priv->buffers->handle +
+ elt_buf->offset + prim->start);
data[0] = CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, dwords-2 );
-
data[1] = offset;
data[2] = RADEON_MAX_VB_VERTS;
- data[3] = format;
- data[4] = (prim | RADEON_PRIM_WALK_IND |
+ data[3] = prim->vc_format;
+ data[4] = (prim->prim |
+ RADEON_PRIM_WALK_IND |
RADEON_COLOR_ORDER_RGBA |
RADEON_VTX_FMT_RADEON_MODE |
(count << RADEON_NUM_VERTICES_SHIFT) );
if ( count & 0x1 ) {
+ /* unnecessary? */
data[dwords-1] &= 0x0000ffff;
}
- do {
- /* Emit the next set of up to three cliprects */
- if ( i < sarea_priv->nbox ) {
+/* printk("data[0]: %x\n", data[0]); */
+/* printk("data[1]: %x\n", data[1]); */
+/* printk("data[2]: %x\n", data[2]); */
+/* printk("data[3]: %x\n", data[3]); */
+/* printk("data[4]: %x\n", data[4]); */
+/* for (i = 0 ; i < 10 ; i++) */
+/* printk("%d: %d\n", i, ((short *)(data+5))[i]); */
+/* printk("...\n"); */
+
+ if (1)
+ do {
+ /* Emit the next set of up to three cliprects */
+ if ( i < sarea_priv->nbox ) {
radeon_emit_clip_rect( dev_priv,
&sarea_priv->boxes[i] );
}
- radeon_cp_dispatch_indirect( dev, buf, start, end );
+ radeon_cp_dispatch_indirect( dev, elt_buf,
+ prim->start,
+ prim->finish );
i++;
} while ( i < sarea_priv->nbox );
}
- if ( buf_priv->discard ) {
- buf_priv->age = dev_priv->sarea_priv->last_dispatch;
-
- /* Emit the vertex buffer age */
- BEGIN_RING( 2 );
- RADEON_DISPATCH_AGE( buf_priv->age );
- ADVANCE_RING();
-
- buf->pending = 1;
- /* FIXME: Check dispatched field */
- buf_priv->dispatched = 0;
- }
-
- dev_priv->sarea_priv->last_dispatch++;
-
- sarea_priv->dirty &= ~RADEON_UPLOAD_CLIPRECTS;
- sarea_priv->nbox = 0;
+ sarea_priv->last_dispatch++;
}
static int radeon_cp_dispatch_blit( drm_device_t *dev,
@@ -1041,8 +964,6 @@ static int radeon_cp_dispatch_blit( drm_device_t *dev,
return -EINVAL;
}
- buf_priv->discard = 1;
-
dwords = (blit->width * blit->height) >> dword_shift;
if ( !dwords ) dwords = 1;
@@ -1068,6 +989,7 @@ static int radeon_cp_dispatch_blit( drm_device_t *dev,
buf->used = (dwords + 8) * sizeof(u32);
radeon_cp_dispatch_indirect( dev, buf, 0, buf->used );
+ radeon_cp_discard_buffer( dev, buf );
/* Flush the pixel cache after the blit completes. This ensures
* the texture data is written out to memory before rendering
@@ -1158,8 +1080,7 @@ int radeon_cp_swap( struct inode *inode, struct file *filp,
if ( !dev_priv->page_flipping ) {
radeon_cp_dispatch_swap( dev );
- dev_priv->sarea_priv->dirty |= (RADEON_UPLOAD_CONTEXT |
- RADEON_UPLOAD_MASKS);
+ dev_priv->sarea_priv->ctx_owner = 0;
} else {
radeon_cp_dispatch_flip( dev );
}
@@ -1177,6 +1098,10 @@ int radeon_cp_vertex( struct inode *inode, struct file *filp,
drm_buf_t *buf;
drm_radeon_buf_priv_t *buf_priv;
drm_radeon_vertex_t vertex;
+ drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
+ int nrprim = sarea_priv->primnr;
+ drm_radeon_prim_t *prim = sarea_priv->prim;
+ int i;
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
dev->lock.pid != current->pid ) {
@@ -1192,20 +1117,15 @@ int radeon_cp_vertex( struct inode *inode, struct file *filp,
sizeof(vertex) ) )
return -EFAULT;
- DRM_DEBUG( "%s: pid=%d index=%d count=%d discard=%d\n",
+ DRM_DEBUG( "%s: pid=%d index=%d discard=%d\n",
__FUNCTION__, current->pid,
- vertex.idx, vertex.count, vertex.discard );
+ vertex.idx, vertex.discard );
if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) {
DRM_ERROR( "buffer index %d (of %d max)\n",
vertex.idx, dma->buf_count - 1 );
return -EINVAL;
}
- if ( vertex.prim < 0 ||
- vertex.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST ) {
- DRM_ERROR( "buffer prim %d\n", vertex.prim );
- return -EINVAL;
- }
VB_AGE_CHECK_WITH_RET( dev_priv );
@@ -1217,97 +1137,54 @@ int radeon_cp_vertex( struct inode *inode, struct file *filp,
current->pid, buf->pid );
return -EINVAL;
}
+
if ( buf->pending ) {
DRM_ERROR( "sending pending buffer %d\n", vertex.idx );
return -EINVAL;
}
- buf->used = vertex.count;
- buf_priv->prim = vertex.prim;
- buf_priv->discard = vertex.discard;
-
- radeon_cp_dispatch_vertex( dev, buf );
-
- return 0;
-}
-
-int radeon_cp_indices( 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_radeon_private_t *dev_priv = dev->dev_private;
- drm_device_dma_t *dma = dev->dma;
- drm_buf_t *buf;
- drm_radeon_buf_priv_t *buf_priv;
- drm_radeon_indices_t elts;
- int count;
+ radeon_update_ring_snapshot( dev_priv );
- if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) ||
- dev->lock.pid != current->pid ) {
- DRM_ERROR( "%s called without lock held\n", __FUNCTION__ );
- return -EINVAL;
- }
- if ( !dev_priv || dev_priv->is_pci ) {
- DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ );
- return -EINVAL;
- }
+ for (i = 0 ; i < nrprim ; i++, prim++) {
+ unsigned int hwprim = prim->prim & RADEON_PRIM_TYPE_MASK;
- if ( copy_from_user( &elts, (drm_radeon_indices_t *)arg,
- sizeof(elts) ) )
- return -EFAULT;
+/* printk("prim %d start %d finish %d\n", */
+/* i, prim->start, prim->finish); */
- DRM_DEBUG( "%s: pid=%d index=%d start=%d end=%d discard=%d\n",
- __FUNCTION__, current->pid,
- elts.idx, elts.start, elts.end, elts.discard );
+ if ( hwprim > RADEON_PRIM_TYPE_3VRT_LINE_LIST ) {
+ DRM_ERROR( "buffer prim %d\n", prim->prim );
+ return -EINVAL;
+ }
- if ( elts.idx < 0 || elts.idx >= dma->buf_count ) {
- DRM_ERROR( "buffer index %d (of %d max)\n",
- elts.idx, dma->buf_count - 1 );
- return -EINVAL;
- }
- if ( elts.prim < 0 ||
- elts.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST ) {
- DRM_ERROR( "buffer prim %d\n", elts.prim );
- return -EINVAL;
- }
+ if ( prim->stateidx != 0xff ) {
+ radeon_emit_state( dev_priv,
+ &sarea_priv->state[prim->stateidx] );
+ }
- VB_AGE_CHECK_WITH_RET( dev_priv );
+ if ( prim->finish <= prim->start )
+ continue;
- buf = dma->buflist[elts.idx];
- buf_priv = buf->dev_private;
+ if ( prim->start & 0x7 ) {
+ DRM_ERROR( "misaligned buffer 0x%x\n", prim->start );
+ return -EINVAL;
+ }
- if ( buf->pid != current->pid ) {
- DRM_ERROR( "process %d using buffer owned by %d\n",
- current->pid, buf->pid );
- return -EINVAL;
- }
- if ( buf->pending ) {
- DRM_ERROR( "sending pending buffer %d\n", elts.idx );
- return -EINVAL;
+ if ( prim->prim & RADEON_PRIM_WALK_IND ) {
+ radeon_cp_dispatch_indices( dev, buf, prim );
+ } else {
+ radeon_cp_dispatch_vertex( dev, buf, prim );
+ }
+
}
- count = (elts.end - elts.start) / sizeof(u16);
- elts.start -= RADEON_INDEX_PRIM_OFFSET;
-
- if ( elts.start & 0x7 ) {
- DRM_ERROR( "misaligned buffer 0x%x\n", elts.start );
- return -EINVAL;
+ if (vertex.discard) {
+ radeon_cp_discard_buffer( dev, buf );
}
- if ( elts.start < buf->used ) {
- DRM_ERROR( "no header 0x%x - 0x%x\n", elts.start, buf->used );
- return -EINVAL;
- }
-
- buf->used = elts.end;
- buf_priv->prim = elts.prim;
- buf_priv->discard = elts.discard;
-
- radeon_cp_dispatch_indices( dev, buf, elts.start, elts.end, count );
return 0;
}
+
int radeon_cp_blit( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
@@ -1426,7 +1303,6 @@ int radeon_cp_indirect( struct inode *inode, struct file *filp,
VB_AGE_CHECK_WITH_RET( dev_priv );
buf->used = indirect.end;
- buf_priv->discard = indirect.discard;
/* Wait for the 3D stream to idle before the indirect buffer
* containing 2D acceleration commands is processed.
@@ -1442,6 +1318,9 @@ int radeon_cp_indirect( struct inode *inode, struct file *filp,
* privileged clients.
*/
radeon_cp_dispatch_indirect( dev, buf, indirect.start, indirect.end );
+ if (indirect.discard) {
+ radeon_cp_discard_buffer( dev, buf );
+ }
return 0;
}
diff --git a/shared-core/drm.h b/shared-core/drm.h
index dc3d262d..8a503001 100644
--- a/shared-core/drm.h
+++ b/shared-core/drm.h
@@ -363,7 +363,6 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_I810_GETAGE DRM_IO( 0x44)
#define DRM_IOCTL_I810_GETBUF DRM_IOWR(0x45, drm_i810_dma_t)
#define DRM_IOCTL_I810_SWAP DRM_IO( 0x46)
-#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t)
#define DRM_IOCTL_I810_DOCOPY DRM_IO( 0x48)
/* Rage 128 specific ioctls */
@@ -394,7 +393,6 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_RADEON_SWAP DRM_IO( 0x47)
#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t)
#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t)
-#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t)
#define DRM_IOCTL_RADEON_BLIT DRM_IOW( 0x4b, drm_radeon_blit_t)
#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t)
#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t)
diff --git a/shared/drm.h b/shared/drm.h
index dc3d262d..8a503001 100644
--- a/shared/drm.h
+++ b/shared/drm.h
@@ -363,7 +363,6 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_I810_GETAGE DRM_IO( 0x44)
#define DRM_IOCTL_I810_GETBUF DRM_IOWR(0x45, drm_i810_dma_t)
#define DRM_IOCTL_I810_SWAP DRM_IO( 0x46)
-#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t)
#define DRM_IOCTL_I810_DOCOPY DRM_IO( 0x48)
/* Rage 128 specific ioctls */
@@ -394,7 +393,6 @@ typedef struct drm_agp_info {
#define DRM_IOCTL_RADEON_SWAP DRM_IO( 0x47)
#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t)
#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t)
-#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t)
#define DRM_IOCTL_RADEON_BLIT DRM_IOW( 0x4b, drm_radeon_blit_t)
#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t)
#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t)