diff options
author | Keith Whitwell <keith@tungstengraphics.com> | 2001-02-03 16:57:00 +0000 |
---|---|---|
committer | Keith Whitwell <keith@tungstengraphics.com> | 2001-02-03 16:57:00 +0000 |
commit | b3a24766fe433c5083c36d1148cfb87adfcabf9a (patch) | |
tree | a41a6baa966873554b1cf10fa475c193ad103074 | |
parent | a8760b0cba4dba438c2ea2d71202269d90145f4b (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.c | 254 | ||||
-rw-r--r-- | linux-core/i810_drm.h | 72 | ||||
-rw-r--r-- | linux-core/i810_drv.c | 1 | ||||
-rw-r--r-- | linux-core/radeon_drv.c | 1 | ||||
-rw-r--r-- | linux/drm.h | 2 | ||||
-rw-r--r-- | linux/i810_dma.c | 254 | ||||
-rw-r--r-- | linux/i810_drm.h | 72 | ||||
-rw-r--r-- | linux/i810_drv.c | 1 | ||||
-rw-r--r-- | linux/radeon_drm.h | 123 | ||||
-rw-r--r-- | linux/radeon_drv.c | 1 | ||||
-rw-r--r-- | linux/radeon_drv.h | 5 | ||||
-rw-r--r-- | linux/radeon_state.c | 603 | ||||
-rw-r--r-- | shared-core/drm.h | 2 | ||||
-rw-r--r-- | shared/drm.h | 2 |
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) |