diff options
author | Keith Whitwell <keith@tungstengraphics.com> | 2000-04-13 17:02:19 +0000 |
---|---|---|
committer | Keith Whitwell <keith@tungstengraphics.com> | 2000-04-13 17:02:19 +0000 |
commit | 312641cc7b9f747526f0e9495fb45f70c10e0f55 (patch) | |
tree | 7cb3e934aeaf7ae54c3297e241b7c8ff37e248b4 | |
parent | 5aa43c056c7686174da60e72cf9c667d04220b17 (diff) |
Kernel portions of the i810 security model - verification and emission of
state, verification of vertex buffers, implementation of swap and
clear.
-rw-r--r-- | linux-core/i810_dma.c | 486 | ||||
-rw-r--r-- | linux-core/i810_drm.h | 122 | ||||
-rw-r--r-- | linux-core/i810_drv.c | 3 | ||||
-rw-r--r-- | linux-core/i810_drv.h | 36 | ||||
-rw-r--r-- | linux/Makefile.linux | 250 | ||||
-rw-r--r-- | linux/drm.h | 3 | ||||
-rw-r--r-- | linux/i810_dma.c | 486 | ||||
-rw-r--r-- | linux/i810_drm.h | 122 | ||||
-rw-r--r-- | linux/i810_drv.c | 3 | ||||
-rw-r--r-- | linux/i810_drv.h | 36 | ||||
-rw-r--r-- | linux/mga_drm.h | 7 | ||||
-rw-r--r-- | shared-core/drm.h | 3 | ||||
-rw-r--r-- | shared/drm.h | 3 |
13 files changed, 1288 insertions, 272 deletions
diff --git a/linux-core/i810_dma.c b/linux-core/i810_dma.c index c940f5cd..5c85a4dc 100644 --- a/linux-core/i810_dma.c +++ b/linux-core/i810_dma.c @@ -37,8 +37,9 @@ #include <linux/interrupt.h> /* For task queue support */ -#define I810_BUF_FREE 1 -#define I810_BUF_USED 0 +#define I810_BUF_FREE 2 +#define I810_BUF_CLIENT 1 +#define I810_BUF_HARDWARE 0 #define I810_BUF_UNMAPPED 0 #define I810_BUF_MAPPED 1 @@ -94,7 +95,7 @@ static inline void i810_print_status_page(drm_device_t *dev) DRM_DEBUG( "hw_status: Reserved : %x\n", temp[3]); DRM_DEBUG( "hw_status: Driver Counter : %d\n", temp[5]); for(i = 6; i < dma->buf_count + 6; i++) { - DRM_DEBUG( "buffer status idx : %d used: %d\n", i - 6, temp[i]); + DRM_DEBUG( "buffer status idx : %d used: %d\n", i - 6, temp[i]); } } @@ -111,7 +112,7 @@ static drm_buf_t *i810_freelist_get(drm_device_t *dev) drm_i810_buf_priv_t *buf_priv = buf->dev_private; /* In use is already a pointer */ used = cmpxchg(buf_priv->in_use, I810_BUF_FREE, - I810_BUF_USED); + I810_BUF_CLIENT); if(used == I810_BUF_FREE) { return buf; } @@ -129,8 +130,8 @@ static int i810_freelist_put(drm_device_t *dev, drm_buf_t *buf) int used; /* In use is already a pointer */ - used = cmpxchg(buf_priv->in_use, I810_BUF_USED, I810_BUF_FREE); - if(used != I810_BUF_USED) { + used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_FREE); + if(used != I810_BUF_CLIENT) { DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx); return -EINVAL; } @@ -218,7 +219,8 @@ static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d, retcode = i810_map_buffer(buf, filp); if(retcode) { i810_freelist_put(dev, buf); - DRM_DEBUG("mapbuf failed in %s retcode %d\n", __FUNCTION__, retcode); + DRM_DEBUG("mapbuf failed in %s retcode %d\n", + __FUNCTION__, retcode); goto out_get_buf; } buf->pid = current->pid; @@ -260,7 +262,10 @@ static void i810_free_page(drm_device_t *dev, unsigned long page) static int i810_dma_cleanup(drm_device_t *dev) { + drm_device_dma_t *dma = dev->dma; + if(dev->dev_private) { + int i; drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; @@ -276,6 +281,12 @@ static int i810_dma_cleanup(drm_device_t *dev) drm_free(dev->dev_private, sizeof(drm_i810_private_t), DRM_MEM_DRIVER); dev->dev_private = NULL; + + for (i = 0; i < dma->buf_count; i++) { + drm_buf_t *buf = dma->buflist[ i ]; + drm_i810_buf_priv_t *buf_priv = buf->dev_private; + drm_ioremapfree(buf_priv->kernel_virtual, buf->total); + } } return 0; } @@ -325,9 +336,9 @@ static int i810_freelist_init(drm_device_t *dev) { drm_device_dma_t *dma = dev->dma; drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; - u8 *hw_status = (u8 *)dev_priv->hw_status_page; - int i; int my_idx = 24; + u32 *hw_status = (u32 *)(dev_priv->hw_status_page + my_idx); + int i; if(dma->buf_count > 1019) { /* Not enough space in the status page for the freelist */ @@ -338,11 +349,14 @@ static int i810_freelist_init(drm_device_t *dev) drm_buf_t *buf = dma->buflist[ i ]; drm_i810_buf_priv_t *buf_priv = buf->dev_private; - buf_priv->in_use = hw_status + my_idx; - DRM_DEBUG("buf_priv->in_use : %p\n", buf_priv->in_use); - *buf_priv->in_use = I810_BUF_FREE; + buf_priv->in_use = hw_status++; buf_priv->my_use_idx = my_idx; my_idx += 4; + + *buf_priv->in_use = I810_BUF_FREE; + + buf_priv->kernel_virtual = drm_ioremap(buf->bus_address, + buf->total); } return 0; } @@ -376,9 +390,11 @@ static int i810_dma_initialize(drm_device_t *dev, dev_priv->ring.Start = init->ring_start; dev_priv->ring.End = init->ring_end; dev_priv->ring.Size = init->ring_size; + dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base + init->ring_start, init->ring_size); + dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; if (dev_priv->ring.virtual_start == NULL) { @@ -387,6 +403,17 @@ static int i810_dma_initialize(drm_device_t *dev, " ring buffer\n"); return -ENOMEM; } + + dev_priv->w = init->w; + dev_priv->h = init->h; + dev_priv->pitch = init->pitch; + dev_priv->back_offset = init->back_offset; + dev_priv->depth_offset = init->depth_offset; + + dev_priv->front_di1 = init->front_offset | init->pitch_bits; + dev_priv->back_di1 = init->back_offset | init->pitch_bits; + dev_priv->zi1 = init->depth_offset | init->pitch_bits; + /* Program Hardware Status Page */ dev_priv->hw_status_page = i810_alloc_page(dev); @@ -441,40 +468,274 @@ int i810_dma_init(struct inode *inode, struct file *filp, return retcode; } -static void i810_dma_dispatch_general(drm_device_t *dev, drm_buf_t *buf, - int used ) + + +/* Most efficient way to verify state for the i810 is as it is + * emitted. Non-conformant state is silently dropped. + * + * Use 'volatile' & local var tmp to force the emitted values to be + * identical to the verified ones. + */ +static void i810EmitContextVerified( drm_device_t *dev, + volatile unsigned int *code ) +{ + drm_i810_private_t *dev_priv = dev->dev_private; + int i, j = 0; + unsigned int tmp; + RING_LOCALS; + + BEGIN_LP_RING( I810_CTX_SETUP_SIZE ); + + OUT_RING( GFX_OP_COLOR_FACTOR ); + OUT_RING( code[I810_CTXREG_CF1] ); + + OUT_RING( GFX_OP_STIPPLE ); + OUT_RING( code[I810_CTXREG_ST1] ); + + for ( i = 4 ; i < I810_CTX_SETUP_SIZE ; i++ ) { + tmp = code[i]; + + if ((tmp & (7<<29)) == (3<<29) && + (tmp & (0x1f<<24)) < (0x1d<<24)) + { + OUT_RING( tmp ); + j++; + } + else + DRM_DEBUG("bad cmd %x\n", tmp); + } + + if (j & 1) + OUT_RING( 0 ); + + ADVANCE_LP_RING(); +} + + +static void i810EmitTexVerified( drm_device_t *dev, + volatile unsigned int *code ) +{ + drm_i810_private_t *dev_priv = dev->dev_private; + int i, j = 0; + unsigned int tmp; + RING_LOCALS; + + BEGIN_LP_RING( I810_TEX_SETUP_SIZE ); + + OUT_RING( GFX_OP_MAP_INFO ); + OUT_RING( code[I810_TEXREG_MI1] ); + OUT_RING( code[I810_TEXREG_MI2] ); + OUT_RING( code[I810_TEXREG_MI3] ); + + for ( i = 4 ; i < I810_TEX_SETUP_SIZE ; i++ ) { + tmp = code[i]; + + if ((tmp & (7<<29)) == (3<<29) && + (tmp & (0x1f<<24)) < (0x1d<<24)) + { + OUT_RING( tmp ); + j++; + } + else + DRM_DEBUG("bad cmd %x\n", tmp); + } + + if (j & 1) + OUT_RING( 0 ); + + ADVANCE_LP_RING(); +} + +/* Need to do some additional checking when setting the dest buffer. + */ +static void i810EmitDestVerified( drm_device_t *dev, + volatile unsigned int *code ) +{ + drm_i810_private_t *dev_priv = dev->dev_private; + unsigned int tmp; + RING_LOCALS; + + BEGIN_LP_RING( I810_DEST_SETUP_SIZE + 2 ); + + tmp = code[I810_DESTREG_DI1]; + if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) { + OUT_RING( CMD_OP_DESTBUFFER_INFO ); + OUT_RING( tmp ); + } else + DRM_DEBUG("bad di1 %x (allow %x or %x)\n", + tmp, dev_priv->front_di1, dev_priv->back_di1); + + /* invarient: + */ + OUT_RING( CMD_OP_Z_BUFFER_INFO ); + OUT_RING( dev_priv->zi1 ); + + OUT_RING( GFX_OP_DESTBUFFER_VARS ); + OUT_RING( code[I810_DESTREG_DV1] ); + + OUT_RING( GFX_OP_DRAWRECT_INFO ); + OUT_RING( code[I810_DESTREG_DR1] ); + OUT_RING( code[I810_DESTREG_DR2] ); + OUT_RING( code[I810_DESTREG_DR3] ); + OUT_RING( code[I810_DESTREG_DR4] ); + OUT_RING( 0 ); + + ADVANCE_LP_RING(); +} + + + +static void i810EmitState( drm_device_t *dev ) { - drm_i810_private_t *dev_priv = dev->dev_private; - drm_i810_buf_priv_t *buf_priv = buf->dev_private; - unsigned long address = (unsigned long)buf->bus_address; - unsigned long start = address - dev->agp->base; - RING_LOCALS; + 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; - dev_priv->counter++; - DRM_DEBUG( "dispatch counter : %ld\n", dev_priv->counter); - DRM_DEBUG( "i810_dma_dispatch\n"); - DRM_DEBUG( "start : 0x%lx\n", start); - DRM_DEBUG( "used : 0x%x\n", used); - DRM_DEBUG( "start + used - 4 : 0x%lx\n", start + used - 4); - i810_kernel_lost_context(dev); + if (dirty & I810_UPLOAD_BUFFERS) { + i810EmitDestVerified( dev, sarea_priv->BufferState ); + sarea_priv->dirty &= ~I810_UPLOAD_BUFFERS; + } - BEGIN_LP_RING(10); - OUT_RING( CMD_OP_BATCH_BUFFER ); - OUT_RING( start | BB1_PROTECTED ); - OUT_RING( start + used - 4 ); - 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 ); - ADVANCE_LP_RING(); - if(buf_priv->currently_mapped == I810_BUF_MAPPED) { - i810_unmap_buffer(buf); + if (dirty & I810_UPLOAD_CTX) { + i810EmitContextVerified( dev, sarea_priv->ContextState ); + sarea_priv->dirty &= ~I810_UPLOAD_CTX; + } + + if (dirty & I810_UPLOAD_TEX0) { + i810EmitTexVerified( dev, sarea_priv->TexState[0] ); + sarea_priv->dirty &= ~I810_UPLOAD_TEX0; + } + + if (dirty & I810_UPLOAD_TEX1) { + i810EmitTexVerified( dev, sarea_priv->TexState[1] ); + sarea_priv->dirty &= ~I810_UPLOAD_TEX1; + } +} + + + +/* need to verify + */ +static void i810_dma_dispatch_clear( drm_device_t *dev, int flags, + unsigned int clear_color, + unsigned int clear_zval ) +{ + drm_i810_private_t *dev_priv = dev->dev_private; + drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; + int nbox = sarea_priv->nbox; + drm_clip_rect_t *pbox = sarea_priv->boxes; + int pitch = dev_priv->pitch; + int cpp = 2; + int i; + RING_LOCALS; + + i810_kernel_lost_context(dev); + + if (nbox > I810_NR_SAREA_CLIPRECTS) + nbox = I810_NR_SAREA_CLIPRECTS; + + for (i = 0 ; i < nbox ; i++, pbox++) { + unsigned int x = pbox->x1; + unsigned int y = pbox->y1; + unsigned int width = (pbox->x2 - x) * cpp; + unsigned int height = pbox->y2 - y; + unsigned int start = y * pitch + x * cpp; + + if (pbox->x1 > pbox->x2 || + pbox->y1 > pbox->y2 || + pbox->x2 > dev_priv->w || + pbox->y2 > dev_priv->h) + continue; + + if ( flags & I810_FRONT ) { + DRM_DEBUG("clear front\n"); + BEGIN_LP_RING( 6 ); + OUT_RING( BR00_BITBLT_CLIENT | + BR00_OP_COLOR_BLT | 0x3 ); + OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch ); + OUT_RING( (height << 16) | width ); + OUT_RING( start ); + OUT_RING( clear_color ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + } + + if ( flags & I810_BACK ) { + DRM_DEBUG("clear back\n"); + BEGIN_LP_RING( 6 ); + OUT_RING( BR00_BITBLT_CLIENT | + BR00_OP_COLOR_BLT | 0x3 ); + OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch ); + OUT_RING( (height << 16) | width ); + OUT_RING( dev_priv->back_offset + start ); + OUT_RING( clear_color ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + } + + if ( flags & I810_DEPTH ) { + DRM_DEBUG("clear depth\n"); + BEGIN_LP_RING( 6 ); + OUT_RING( BR00_BITBLT_CLIENT | + BR00_OP_COLOR_BLT | 0x3 ); + OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch ); + OUT_RING( (height << 16) | width ); + OUT_RING( dev_priv->depth_offset + start ); + OUT_RING( clear_zval ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + } + } +} + +static void i810_dma_dispatch_swap( drm_device_t *dev ) +{ + drm_i810_private_t *dev_priv = dev->dev_private; + drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; + int nbox = sarea_priv->nbox; + drm_clip_rect_t *pbox = sarea_priv->boxes; + int pitch = dev_priv->pitch; + int cpp = 2; + int ofs = dev_priv->back_offset; + int i; + RING_LOCALS; + + DRM_DEBUG("swapbuffers\n"); + + i810_kernel_lost_context(dev); + + if (nbox > I810_NR_SAREA_CLIPRECTS) + nbox = I810_NR_SAREA_CLIPRECTS; + + for (i = 0 ; i < nbox; i++, pbox++) + { + unsigned int w = pbox->x2 - pbox->x1; + unsigned int h = pbox->y2 - pbox->y1; + unsigned int dst = pbox->x1*cpp + pbox->y1*pitch; + unsigned int start = ofs + dst; + + if (pbox->x1 > pbox->x2 || + pbox->y1 > pbox->y2 || + pbox->x2 > dev_priv->w || + pbox->y2 > dev_priv->h) + continue; + + DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n", + pbox[i].x1, pbox[i].y1, + pbox[i].x2, pbox[i].y2); + + BEGIN_LP_RING( 6 ); + OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4 ); + OUT_RING( pitch | (0xCC << 16)); + OUT_RING( (h << 16) | (w * cpp)); + OUT_RING( dst ); + OUT_RING( pitch ); + OUT_RING( start ); + ADVANCE_LP_RING(); } } + static void i810_dma_dispatch_vertex(drm_device_t *dev, drm_buf_t *buf, int discard, @@ -487,14 +748,26 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev, int nbox = sarea_priv->nbox; unsigned long address = (unsigned long)buf->bus_address; unsigned long start = address - dev->agp->base; - int i = 0; + int i = 0, u; RING_LOCALS; - + i810_kernel_lost_context(dev); + if (nbox > I810_NR_SAREA_CLIPRECTS) nbox = I810_NR_SAREA_CLIPRECTS; - - DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n", + + if (discard) { + u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, + I810_BUF_HARDWARE); + if(u != I810_BUF_CLIENT) { + DRM_DEBUG("xxxx 2\n"); + } + } + + if (sarea_priv->dirty) + i810EmitState( dev ); + + DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n", address, used, nbox); dev_priv->counter++; @@ -503,16 +776,24 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev, DRM_DEBUG( "start : %lx\n", start); DRM_DEBUG( "used : %d\n", used); DRM_DEBUG( "start + used - 4 : %ld\n", start + used - 4); - i810_kernel_lost_context(dev); if (used) { + *(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; + } + do { if (i < nbox) { BEGIN_LP_RING(4); 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].x1 | (box[i].y1<<16) ); OUT_RING( (box[i].x2-1) | ((box[i].y2-1)<<16) ); ADVANCE_LP_RING(); } @@ -543,6 +824,7 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev, OUT_RING( CMD_REPORT_HEAD ); OUT_RING( 0 ); ADVANCE_LP_RING(); + if(buf_priv->currently_mapped == I810_BUF_MAPPED) { i810_unmap_buffer(buf); } @@ -711,8 +993,8 @@ static inline void i810_dma_quiescent_emit(drm_device_t *dev) RING_LOCALS; i810_kernel_lost_context(dev); - BEGIN_LP_RING(4); + BEGIN_LP_RING(4); OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE ); OUT_RING( CMD_REPORT_HEAD ); OUT_RING( GFX_OP_USER_INTERRUPT ); @@ -794,23 +1076,17 @@ void i810_reclaim_buffers(drm_device_t *dev, pid_t pid) int i; if (!dma) return; - if(dev->dev_private == NULL) return; - if(dma->buflist == NULL) return; + if (!dev->dev_private) return; + if (!dma->buflist) return; + i810_flush_queue(dev); for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[ i ]; drm_i810_buf_priv_t *buf_priv = buf->dev_private; - /* Only buffers that need to get reclaimed ever - * get set to free - */ if (buf->pid == pid && buf_priv) { - cmpxchg(buf_priv->in_use, - I810_BUF_USED, I810_BUF_FREE); - if(buf_priv->currently_mapped == I810_BUF_MAPPED) { - buf_priv->currently_mapped = I810_BUF_UNMAPPED; - } + *(buf_priv->in_use) = I810_BUF_FREE; } } } @@ -900,90 +1176,80 @@ int i810_flush_ioctl(struct inode *inode, struct file *filp, return 0; } -static int i810DmaGeneral(drm_device_t *dev, drm_i810_general_t *args) -{ - drm_device_dma_t *dma = dev->dma; - drm_buf_t *buf = dma->buflist[ args->idx ]; - - if (!args->used) { - i810_freelist_put(dev, buf); - } else { - i810_dma_dispatch_general( dev, buf, args->used ); - atomic_add(args->used, &dma->total_bytes); - atomic_inc(&dma->total_dmas); - } - return 0; -} - -static int i810DmaVertex(drm_device_t *dev, drm_i810_vertex_t *args) -{ - drm_device_dma_t *dma = dev->dma; - drm_buf_t *buf = dma->buflist[ args->idx ]; - i810_dma_dispatch_vertex( dev, buf, args->discard, args->used ); - atomic_add(args->used, &dma->total_bytes); - atomic_inc(&dma->total_dmas); - return 0; -} -int i810_dma_general(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +int i810_dma_vertex(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - drm_i810_general_t general; - drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + drm_device_dma_t *dma = dev->dma; + 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_i810_vertex_t vertex; - int retcode = 0; - - copy_from_user_ret(&general, (drm_i810_general_t *)arg, sizeof(general), + copy_from_user_ret(&vertex, (drm_i810_vertex_t *)arg, sizeof(vertex), -EFAULT); - DRM_DEBUG("i810 dma general idx %d used %d\n", - general.idx, general.used); - if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { - DRM_ERROR("i810_dma_general called without lock held\n"); + DRM_ERROR("i810_dma_vertex called without lock held\n"); return -EINVAL; } - retcode = i810DmaGeneral(dev, &general); + DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n", + vertex.idx, vertex.used, vertex.discard); + + i810_dma_dispatch_vertex( dev, + dma->buflist[ vertex.idx ], + vertex.discard, vertex.used ); + + atomic_add(vertex.used, &dma->total_bytes); + atomic_inc(&dma->total_dmas); sarea_priv->last_enqueue = dev_priv->counter-1; sarea_priv->last_dispatch = (int) hw_status[5]; - return retcode; + return 0; } -int i810_dma_vertex(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + + +int i810_clear_bufs(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_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_i810_vertex_t vertex; - int retcode = 0; + drm_i810_clear_t clear; - copy_from_user_ret(&vertex, (drm_i810_vertex_t *)arg, sizeof(vertex), + copy_from_user_ret(&clear, (drm_i810_clear_t *)arg, sizeof(clear), -EFAULT); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { - DRM_ERROR("i810_dma_vertex called without lock held\n"); + DRM_ERROR("i810_clear_bufs called without lock held\n"); return -EINVAL; } - DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n", - vertex.idx, vertex.used, vertex.discard); + i810_dma_dispatch_clear( dev, clear.flags, + clear.clear_color, + clear.clear_depth ); + return 0; +} - retcode = i810DmaVertex(dev, &vertex); - sarea_priv->last_enqueue = dev_priv->counter-1; - sarea_priv->last_dispatch = (int) hw_status[5]; +int i810_swap_bufs(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; - return retcode; + DRM_DEBUG("i810_swap_bufs\n"); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_swap_buf called without lock held\n"); + return -EINVAL; + } + + i810_dma_dispatch_swap( dev ); + return 0; } int i810_getage(struct inode *inode, struct file *filp, unsigned int cmd, diff --git a/linux-core/i810_drm.h b/linux-core/i810_drm.h index 7e435879..4c8e09f6 100644 --- a/linux-core/i810_drm.h +++ b/linux-core/i810_drm.h @@ -5,35 +5,112 @@ * if you change them, you must change the defines in the Xserver. */ -/* Might one day want to support the client-side ringbuffer code again. - */ #ifndef _I810_DEFINES_ #define _I810_DEFINES_ -#define I810_USE_BATCH 1 #define I810_DMA_BUF_ORDER 12 #define I810_DMA_BUF_SZ (1<<I810_DMA_BUF_ORDER) #define I810_DMA_BUF_NR 256 -#define I810_NR_SAREA_CLIPRECTS 2 +#define I810_NR_SAREA_CLIPRECTS 8 /* Each region is a minimum of 64k, and there are at most 64 of them. */ - #define I810_NR_TEX_REGIONS 64 #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 + + +/* Indices into buf.Setup where various bits of state are mirrored per + * context and per buffer. These can be fired at the card as a unit, + * or in a piecewise fashion as required. + */ + +/* Destbuffer state + * - backbuffer linear offset and pitch -- invarient in the current dri + * - zbuffer linear offset and pitch -- also invarient + * - drawing origin in back and depth buffers. + * + * Keep the depth/back buffer state here to acommodate private buffers + * in the future. + */ +#define I810_DESTREG_DI0 0 /* CMD_OP_DESTBUFFER_INFO (2 dwords) */ +#define I810_DESTREG_DI1 1 +#define I810_DESTREG_DV0 2 /* GFX_OP_DESTBUFFER_VARS (2 dwords) */ +#define I810_DESTREG_DV1 3 +#define I810_DESTREG_DR0 4 /* GFX_OP_DRAWRECT_INFO (4 dwords) */ +#define I810_DESTREG_DR1 5 +#define I810_DESTREG_DR2 6 +#define I810_DESTREG_DR3 7 +#define I810_DESTREG_DR4 8 +#define I810_DEST_SETUP_SIZE 10 + +/* Context state + */ +#define I810_CTXREG_CF0 0 /* GFX_OP_COLOR_FACTOR */ +#define I810_CTXREG_CF1 1 +#define I810_CTXREG_ST0 2 /* GFX_OP_STIPPLE */ +#define I810_CTXREG_ST1 3 +#define I810_CTXREG_VF 4 /* GFX_OP_VERTEX_FMT */ +#define I810_CTXREG_MT 5 /* GFX_OP_MAP_TEXELS */ +#define I810_CTXREG_MC0 6 /* GFX_OP_MAP_COLOR_STAGES - stage 0 */ +#define I810_CTXREG_MC1 7 /* GFX_OP_MAP_COLOR_STAGES - stage 1 */ +#define I810_CTXREG_MC2 8 /* GFX_OP_MAP_COLOR_STAGES - stage 2 */ +#define I810_CTXREG_MA0 9 /* GFX_OP_MAP_ALPHA_STAGES - stage 0 */ +#define I810_CTXREG_MA1 10 /* GFX_OP_MAP_ALPHA_STAGES - stage 1 */ +#define I810_CTXREG_MA2 11 /* GFX_OP_MAP_ALPHA_STAGES - stage 2 */ +#define I810_CTXREG_SDM 12 /* GFX_OP_SRC_DEST_MONO */ +#define I810_CTXREG_FOG 13 /* GFX_OP_FOG_COLOR */ +#define I810_CTXREG_B1 14 /* GFX_OP_BOOL_1 */ +#define I810_CTXREG_B2 15 /* GFX_OP_BOOL_2 */ +#define I810_CTXREG_LCS 16 /* GFX_OP_LINEWIDTH_CULL_SHADE_MODE */ +#define I810_CTXREG_PV 17 /* GFX_OP_PV_RULE -- Invarient! */ +#define I810_CTXREG_ZA 18 /* GFX_OP_ZBIAS_ALPHAFUNC */ +#define I810_CTXREG_AA 19 /* GFX_OP_ANTIALIAS */ +#define I810_CTX_SETUP_SIZE 20 + +/* Texture state (per tex unit) + */ +#define I810_TEXREG_MI0 0 /* GFX_OP_MAP_INFO (4 dwords) */ +#define I810_TEXREG_MI1 1 +#define I810_TEXREG_MI2 2 +#define I810_TEXREG_MI3 3 +#define I810_TEXREG_MF 4 /* GFX_OP_MAP_FILTER */ +#define I810_TEXREG_MLC 5 /* GFX_OP_MAP_LOD_CTL */ +#define I810_TEXREG_MLL 6 /* GFX_OP_MAP_LOD_LIMITS */ +#define I810_TEXREG_MCS 7 /* GFX_OP_MAP_COORD_SETS ??? */ +#define I810_TEX_SETUP_SIZE 8 + +#define I810_FRONT 0x1 +#define I810_BACK 0x2 +#define I810_DEPTH 0x4 + + typedef struct _drm_i810_init { - enum { - I810_INIT_DMA = 0x01, - I810_CLEANUP_DMA = 0x02 + enum { + I810_INIT_DMA = 0x01, + I810_CLEANUP_DMA = 0x02 } func; - int ring_map_idx; - int buffer_map_idx; + int ring_map_idx; + int buffer_map_idx; int sarea_priv_offset; - unsigned long ring_start; - unsigned long ring_end; - unsigned long ring_size; + unsigned int ring_start; + unsigned int ring_end; + unsigned int ring_size; + unsigned int front_offset; + unsigned int back_offset; + unsigned int depth_offset; + unsigned int w; + unsigned int h; + unsigned int pitch; + unsigned int pitch_bits; } drm_i810_init_t; /* Warning: If you change the SAREA structure you must change the Xserver @@ -46,6 +123,11 @@ typedef struct _drm_i810_tex_region { } drm_i810_tex_region_t; 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; + unsigned int nbox; drm_clip_rect_t boxes[I810_NR_SAREA_CLIPRECTS]; @@ -72,12 +154,18 @@ typedef struct _drm_i810_sarea { 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_general { - int idx; - int used; -} drm_i810_general_t; +typedef struct _drm_i810_clear { + int clear_color; + int clear_depth; + int flags; +} 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 diff --git a/linux-core/i810_drv.c b/linux-core/i810_drv.c index 03585bdf..75b402da 100644 --- a/linux-core/i810_drv.c +++ b/linux-core/i810_drv.c @@ -107,10 +107,11 @@ static drm_ioctl_desc_t i810_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_I810_INIT)] = { i810_dma_init, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_I810_VERTEX)] = { i810_dma_vertex, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_I810_DMA)] = { i810_dma_general,1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_I810_CLEAR)] = { i810_clear_bufs, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_I810_FLUSH)] = { i810_flush_ioctl,1, 0 }, [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 }, }; #define I810_IOCTL_COUNT DRM_ARRAY_SIZE(i810_ioctls) diff --git a/linux-core/i810_drv.h b/linux-core/i810_drv.h index e775d1b6..671489d3 100644 --- a/linux-core/i810_drv.h +++ b/linux-core/i810_drv.h @@ -55,6 +55,15 @@ typedef struct drm_i810_private { atomic_t flush_done; wait_queue_head_t flush_queue; /* Processes waiting until flush */ + + + + u32 front_di1, back_di1, zi1; + + int back_offset; + int depth_offset; + int w, h; + int pitch; } drm_i810_private_t; /* i810_drv.c */ @@ -128,11 +137,9 @@ typedef struct drm_i810_buf_priv { int my_use_idx; int currently_mapped; void *virtual; + void *kernel_virtual; } drm_i810_buf_priv_t; -#define I810_DMA_GENERAL 0 -#define I810_DMA_VERTEX 1 -#define I810_DMA_DISCARD 2 /* not used */ #define I810_VERBOSE 0 @@ -140,9 +147,11 @@ typedef struct drm_i810_buf_priv { int i810_dma_vertex(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -int i810_dma_general(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); +int i810_swap_bufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +int i810_clear_bufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); #define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) #define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) @@ -196,5 +205,22 @@ int i810_dma_general(struct inode *inode, struct file *filp, #define SCI_YMAX_MASK (0xffff<<16) #define SCI_XMAX_MASK (0xffff<<0) +#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0) +#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) +#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x2) +#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0) +#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3)) +#define GFX_OP_PRIMITIVE ((0x3<<29)|(0x1f<<24)) + +#define CMD_OP_Z_BUFFER_INFO ((0x0<<29)|(0x16<<23)) +#define CMD_OP_DESTBUFFER_INFO ((0x0<<29)|(0x15<<23)) + +#define BR00_BITBLT_CLIENT 0x40000000 +#define BR00_OP_COLOR_BLT 0x10000000 +#define BR00_OP_SRC_COPY_BLT 0x10C00000 +#define BR13_SOLID_PATTERN 0x80000000 + + + #endif diff --git a/linux/Makefile.linux b/linux/Makefile.linux index 1db7a81f..1a34ad0c 100644 --- a/linux/Makefile.linux +++ b/linux/Makefile.linux @@ -190,3 +190,253 @@ $(PROGOBJS): $(PROGHEADERS) clean: rm -f *.o *.a *.po *~ core $(PROGS) +# DO NOT DELETE + +agpsupport.o: drmP.h +auth.o: drmP.h +bufs.o: drmP.h /usr/include/linux/un.h +context.o: drmP.h +ctxbitmap.o: drmP.h +dma.o: drmP.h /usr/include/linux/interrupt.h /usr/include/linux/kernel.h +dma.o: /usr/include/asm/bitops.h /usr/include/asm/atomic.h +dma.o: /usr/include/asm/hardirq.h /usr/include/linux/threads.h +dma.o: /usr/include/asm/softirq.h +drawable.o: drmP.h +drm.o: /usr/include/asm/ioctl.h mga_drm.h i810_drm.h +drmstat.o: /usr/include/stdio.h /usr/include/features.h +drmstat.o: /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h +drmstat.o: /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h +drmstat.o: /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h +drmstat.o: /usr/include/bits/types.h /usr/include/libio.h +drmstat.o: /usr/include/_G_config.h /usr/include/bits/stdio_lim.h +drmstat.o: /usr/include/stdlib.h /usr/include/sys/types.h /usr/include/time.h +drmstat.o: /usr/include/endian.h /usr/include/bits/endian.h +drmstat.o: /usr/include/sys/select.h /usr/include/bits/select.h +drmstat.o: /usr/include/bits/sigset.h /usr/include/sys/sysmacros.h +drmstat.o: /usr/include/alloca.h /usr/include/unistd.h +drmstat.o: /usr/include/bits/posix_opt.h /usr/include/bits/confname.h +drmstat.o: /usr/include/getopt.h /usr/include/sys/time.h +drmstat.o: /usr/include/bits/time.h /usr/include/sys/mman.h +drmstat.o: /usr/include/bits/mman.h /usr/include/strings.h +drmstat.o: /usr/include/errno.h /usr/include/bits/errno.h +drmstat.o: /usr/include/linux/errno.h /usr/include/asm/errno.h +drmstat.o: /usr/include/signal.h /usr/include/bits/signum.h +drmstat.o: /usr/include/bits/siginfo.h /usr/include/bits/sigaction.h +drmstat.o: /usr/include/bits/sigcontext.h /usr/include/asm/sigcontext.h +drmstat.o: /usr/include/bits/sigstack.h /usr/include/fcntl.h +drmstat.o: /usr/include/bits/fcntl.h xf86drm.h +fops.o: drmP.h /usr/include/linux/poll.h /usr/include/asm/poll.h +gamma_dma.o: drmP.h gamma_drv.h /usr/include/linux/interrupt.h +gamma_dma.o: /usr/include/linux/kernel.h /usr/include/asm/bitops.h +gamma_dma.o: /usr/include/asm/atomic.h /usr/include/asm/hardirq.h +gamma_dma.o: /usr/include/linux/threads.h /usr/include/asm/softirq.h +gamma_drv.o: drmP.h gamma_drv.h +i810_bufs.o: drmP.h i810_drv.h /usr/include/linux/un.h +i810_context.o: /usr/include/linux/sched.h /usr/include/asm/param.h +i810_context.o: /usr/include/linux/binfmts.h /usr/include/linux/ptrace.h +i810_context.o: /usr/include/asm/ptrace.h /usr/include/linux/capability.h +i810_context.o: /usr/include/linux/types.h /usr/include/linux/config.h +i810_context.o: /usr/include/linux/autoconf.h +i810_context.o: /usr/include/linux/posix_types.h /usr/include/linux/stddef.h +i810_context.o: /usr/include/asm/posix_types.h /usr/include/asm/types.h +i810_context.o: /usr/include/linux/fs.h /usr/include/linux/linkage.h +i810_context.o: /usr/include/linux/limits.h /usr/include/linux/wait.h +i810_context.o: /usr/include/linux/vfs.h /usr/include/asm/statfs.h +i810_context.o: /usr/include/linux/net.h /usr/include/linux/socket.h +i810_context.o: /usr/include/asm/socket.h /usr/include/asm/sockios.h +i810_context.o: /usr/include/linux/sockios.h /usr/include/linux/uio.h +i810_context.o: /usr/include/linux/kdev_t.h /usr/include/linux/ioctl.h +i810_context.o: /usr/include/asm/ioctl.h /usr/include/linux/list.h +i810_context.o: /usr/include/linux/dcache.h /usr/include/linux/stat.h +i810_context.o: /usr/include/linux/cache.h /usr/include/asm/cache.h +i810_context.o: /usr/include/asm/atomic.h /usr/include/asm/bitops.h +i810_context.o: /usr/include/linux/personality.h /usr/include/linux/threads.h +i810_context.o: /usr/include/linux/kernel.h /usr/include/linux/times.h +i810_context.o: /usr/include/linux/timex.h /usr/include/asm/timex.h +i810_context.o: /usr/include/asm/msr.h /usr/include/asm/system.h +i810_context.o: /usr/include/asm/segment.h /usr/include/linux/bitops.h +i810_context.o: /usr/include/asm/semaphore.h /usr/include/asm/rwlock.h +i810_context.o: /usr/include/asm/page.h /usr/include/linux/smp.h +i810_context.o: /usr/include/linux/tty.h /usr/include/linux/sem.h +i810_context.o: /usr/include/linux/ipc.h /usr/include/asm/ipcbuf.h +i810_context.o: /usr/include/asm/sembuf.h /usr/include/linux/signal.h +i810_context.o: /usr/include/asm/signal.h /usr/include/asm/siginfo.h +i810_context.o: /usr/include/linux/securebits.h /usr/include/linux/time.h +i810_context.o: /usr/include/linux/param.h /usr/include/linux/resource.h +i810_context.o: /usr/include/asm/resource.h /usr/include/linux/timer.h +i810_context.o: /usr/include/asm/processor.h /usr/include/asm/vm86.h +i810_context.o: /usr/include/asm/math_emu.h /usr/include/asm/sigcontext.h +i810_context.o: drmP.h i810_drv.h +i810_dma.o: drmP.h i810_drv.h /usr/include/linux/interrupt.h +i810_dma.o: /usr/include/linux/kernel.h /usr/include/asm/bitops.h +i810_dma.o: /usr/include/asm/atomic.h /usr/include/asm/hardirq.h +i810_dma.o: /usr/include/linux/threads.h /usr/include/asm/softirq.h +i810_drv.o: drmP.h i810_drv.h +i810_state.o: drmP.h i810_drv.h drm.h /usr/include/asm/ioctl.h mga_drm.h +i810_state.o: i810_drm.h +init.o: drmP.h +ioctl.o: drmP.h +lists.o: drmP.h +lock.o: drmP.h +memory.o: drmP.h +mga_bufs.o: drmP.h mga_drv.h /usr/include/linux/un.h +mga_context.o: /usr/include/linux/sched.h /usr/include/asm/param.h +mga_context.o: /usr/include/linux/binfmts.h /usr/include/linux/ptrace.h +mga_context.o: /usr/include/asm/ptrace.h /usr/include/linux/capability.h +mga_context.o: /usr/include/linux/types.h /usr/include/linux/config.h +mga_context.o: /usr/include/linux/autoconf.h /usr/include/linux/posix_types.h +mga_context.o: /usr/include/linux/stddef.h /usr/include/asm/posix_types.h +mga_context.o: /usr/include/asm/types.h /usr/include/linux/fs.h +mga_context.o: /usr/include/linux/linkage.h /usr/include/linux/limits.h +mga_context.o: /usr/include/linux/wait.h /usr/include/linux/vfs.h +mga_context.o: /usr/include/asm/statfs.h /usr/include/linux/net.h +mga_context.o: /usr/include/linux/socket.h /usr/include/asm/socket.h +mga_context.o: /usr/include/asm/sockios.h /usr/include/linux/sockios.h +mga_context.o: /usr/include/linux/uio.h /usr/include/linux/kdev_t.h +mga_context.o: /usr/include/linux/ioctl.h /usr/include/asm/ioctl.h +mga_context.o: /usr/include/linux/list.h /usr/include/linux/dcache.h +mga_context.o: /usr/include/linux/stat.h /usr/include/linux/cache.h +mga_context.o: /usr/include/asm/cache.h /usr/include/asm/atomic.h +mga_context.o: /usr/include/asm/bitops.h /usr/include/linux/personality.h +mga_context.o: /usr/include/linux/threads.h /usr/include/linux/kernel.h +mga_context.o: /usr/include/linux/times.h /usr/include/linux/timex.h +mga_context.o: /usr/include/asm/timex.h /usr/include/asm/msr.h +mga_context.o: /usr/include/asm/system.h /usr/include/asm/segment.h +mga_context.o: /usr/include/linux/bitops.h /usr/include/asm/semaphore.h +mga_context.o: /usr/include/asm/rwlock.h /usr/include/asm/page.h +mga_context.o: /usr/include/linux/smp.h /usr/include/linux/tty.h +mga_context.o: /usr/include/linux/sem.h /usr/include/linux/ipc.h +mga_context.o: /usr/include/asm/ipcbuf.h /usr/include/asm/sembuf.h +mga_context.o: /usr/include/linux/signal.h /usr/include/asm/signal.h +mga_context.o: /usr/include/asm/siginfo.h /usr/include/linux/securebits.h +mga_context.o: /usr/include/linux/time.h /usr/include/linux/param.h +mga_context.o: /usr/include/linux/resource.h /usr/include/asm/resource.h +mga_context.o: /usr/include/linux/timer.h /usr/include/asm/processor.h +mga_context.o: /usr/include/asm/vm86.h /usr/include/asm/math_emu.h +mga_context.o: /usr/include/asm/sigcontext.h drmP.h mga_drv.h +mga_dma.o: drmP.h mga_drv.h /usr/include/linux/interrupt.h +mga_dma.o: /usr/include/linux/kernel.h /usr/include/asm/bitops.h +mga_dma.o: /usr/include/asm/atomic.h /usr/include/asm/hardirq.h +mga_dma.o: /usr/include/linux/threads.h /usr/include/asm/softirq.h +mga_drv.o: drmP.h mga_drv.h +mga_state.o: drmP.h mga_drv.h drm.h /usr/include/asm/ioctl.h mga_drm.h +mga_state.o: i810_drm.h +picker.o: /usr/include/linux/autoconf.h /usr/include/linux/version.h +proc.o: drmP.h +sigio.o: /usr/include/unistd.h /usr/include/features.h +sigio.o: /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h +sigio.o: /usr/include/bits/posix_opt.h /usr/include/bits/types.h +sigio.o: /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h +sigio.o: /usr/include/bits/confname.h /usr/include/getopt.h +sigio.o: /usr/include/signal.h /usr/include/bits/sigset.h +sigio.o: /usr/include/bits/signum.h /usr/include/time.h +sigio.o: /usr/include/bits/siginfo.h /usr/include/bits/sigaction.h +sigio.o: /usr/include/bits/sigcontext.h /usr/include/asm/sigcontext.h +sigio.o: /usr/include/bits/sigstack.h /usr/include/fcntl.h +sigio.o: /usr/include/bits/fcntl.h /usr/include/sys/types.h +sigio.o: /usr/include/endian.h /usr/include/bits/endian.h +sigio.o: /usr/include/sys/select.h /usr/include/bits/select.h +sigio.o: /usr/include/sys/sysmacros.h /usr/include/sys/time.h +sigio.o: /usr/include/bits/time.h /usr/include/errno.h +sigio.o: /usr/include/bits/errno.h /usr/include/linux/errno.h +sigio.o: /usr/include/asm/errno.h /usr/include/stdio.h +sigio.o: /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h +sigio.o: /usr/include/libio.h /usr/include/_G_config.h +sigio.o: /usr/include/bits/stdio_lim.h /usr/include/string.h +tdfx_context.o: /usr/include/linux/sched.h /usr/include/asm/param.h +tdfx_context.o: /usr/include/linux/binfmts.h /usr/include/linux/ptrace.h +tdfx_context.o: /usr/include/asm/ptrace.h /usr/include/linux/capability.h +tdfx_context.o: /usr/include/linux/types.h /usr/include/linux/config.h +tdfx_context.o: /usr/include/linux/autoconf.h +tdfx_context.o: /usr/include/linux/posix_types.h /usr/include/linux/stddef.h +tdfx_context.o: /usr/include/asm/posix_types.h /usr/include/asm/types.h +tdfx_context.o: /usr/include/linux/fs.h /usr/include/linux/linkage.h +tdfx_context.o: /usr/include/linux/limits.h /usr/include/linux/wait.h +tdfx_context.o: /usr/include/linux/vfs.h /usr/include/asm/statfs.h +tdfx_context.o: /usr/include/linux/net.h /usr/include/linux/socket.h +tdfx_context.o: /usr/include/asm/socket.h /usr/include/asm/sockios.h +tdfx_context.o: /usr/include/linux/sockios.h /usr/include/linux/uio.h +tdfx_context.o: /usr/include/linux/kdev_t.h /usr/include/linux/ioctl.h +tdfx_context.o: /usr/include/asm/ioctl.h /usr/include/linux/list.h +tdfx_context.o: /usr/include/linux/dcache.h /usr/include/linux/stat.h +tdfx_context.o: /usr/include/linux/cache.h /usr/include/asm/cache.h +tdfx_context.o: /usr/include/asm/atomic.h /usr/include/asm/bitops.h +tdfx_context.o: /usr/include/linux/personality.h /usr/include/linux/threads.h +tdfx_context.o: /usr/include/linux/kernel.h /usr/include/linux/times.h +tdfx_context.o: /usr/include/linux/timex.h /usr/include/asm/timex.h +tdfx_context.o: /usr/include/asm/msr.h /usr/include/asm/system.h +tdfx_context.o: /usr/include/asm/segment.h /usr/include/linux/bitops.h +tdfx_context.o: /usr/include/asm/semaphore.h /usr/include/asm/rwlock.h +tdfx_context.o: /usr/include/asm/page.h /usr/include/linux/smp.h +tdfx_context.o: /usr/include/linux/tty.h /usr/include/linux/sem.h +tdfx_context.o: /usr/include/linux/ipc.h /usr/include/asm/ipcbuf.h +tdfx_context.o: /usr/include/asm/sembuf.h /usr/include/linux/signal.h +tdfx_context.o: /usr/include/asm/signal.h /usr/include/asm/siginfo.h +tdfx_context.o: /usr/include/linux/securebits.h /usr/include/linux/time.h +tdfx_context.o: /usr/include/linux/param.h /usr/include/linux/resource.h +tdfx_context.o: /usr/include/asm/resource.h /usr/include/linux/timer.h +tdfx_context.o: /usr/include/asm/processor.h /usr/include/asm/vm86.h +tdfx_context.o: /usr/include/asm/math_emu.h /usr/include/asm/sigcontext.h +tdfx_context.o: drmP.h tdfx_drv.h +tdfx_drv.o: drmP.h tdfx_drv.h +vm.o: drmP.h +xf86_OSproc.o: /usr/include/X11/Xfuncproto.h +xf86drm.o: /usr/include/stdio.h /usr/include/features.h +xf86drm.o: /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h +xf86drm.o: /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h +xf86drm.o: /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h +xf86drm.o: /usr/include/bits/types.h /usr/include/libio.h +xf86drm.o: /usr/include/_G_config.h /usr/include/bits/stdio_lim.h +xf86drm.o: /usr/include/stdlib.h /usr/include/sys/types.h /usr/include/time.h +xf86drm.o: /usr/include/endian.h /usr/include/bits/endian.h +xf86drm.o: /usr/include/sys/select.h /usr/include/bits/select.h +xf86drm.o: /usr/include/bits/sigset.h /usr/include/sys/sysmacros.h +xf86drm.o: /usr/include/alloca.h /usr/include/unistd.h +xf86drm.o: /usr/include/bits/posix_opt.h /usr/include/bits/confname.h +xf86drm.o: /usr/include/getopt.h /usr/include/string.h /usr/include/ctype.h +xf86drm.o: /usr/include/fcntl.h /usr/include/bits/fcntl.h +xf86drm.o: /usr/include/errno.h /usr/include/bits/errno.h +xf86drm.o: /usr/include/linux/errno.h /usr/include/asm/errno.h +xf86drm.o: /usr/include/signal.h /usr/include/bits/signum.h +xf86drm.o: /usr/include/bits/siginfo.h /usr/include/bits/sigaction.h +xf86drm.o: /usr/include/bits/sigcontext.h /usr/include/asm/sigcontext.h +xf86drm.o: /usr/include/bits/sigstack.h /usr/include/sys/stat.h +xf86drm.o: /usr/include/bits/stat.h /usr/include/sys/ioctl.h +xf86drm.o: /usr/include/bits/ioctls.h /usr/include/asm/ioctls.h +xf86drm.o: /usr/include/asm/ioctl.h /usr/include/bits/ioctl-types.h +xf86drm.o: /usr/include/sys/ttydefaults.h /usr/include/sys/mman.h +xf86drm.o: /usr/include/bits/mman.h /usr/include/sys/time.h +xf86drm.o: /usr/include/bits/time.h xf86drm.h drm.h mga_drm.h i810_drm.h +xf86drmHash.o: xf86drm.h /usr/include/stdio.h /usr/include/features.h +xf86drmHash.o: /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h +xf86drmHash.o: /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h +xf86drmHash.o: /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h +xf86drmHash.o: /usr/include/bits/types.h /usr/include/libio.h +xf86drmHash.o: /usr/include/_G_config.h /usr/include/bits/stdio_lim.h +xf86drmHash.o: /usr/include/stdlib.h /usr/include/sys/types.h +xf86drmHash.o: /usr/include/time.h /usr/include/endian.h +xf86drmHash.o: /usr/include/bits/endian.h /usr/include/sys/select.h +xf86drmHash.o: /usr/include/bits/select.h /usr/include/bits/sigset.h +xf86drmHash.o: /usr/include/sys/sysmacros.h /usr/include/alloca.h +xf86drmRandom.o: xf86drm.h /usr/include/stdio.h /usr/include/features.h +xf86drmRandom.o: /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h +xf86drmRandom.o: /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h +xf86drmRandom.o: /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h +xf86drmRandom.o: /usr/include/bits/types.h /usr/include/libio.h +xf86drmRandom.o: /usr/include/_G_config.h /usr/include/bits/stdio_lim.h +xf86drmRandom.o: /usr/include/stdlib.h /usr/include/sys/types.h +xf86drmRandom.o: /usr/include/time.h /usr/include/endian.h +xf86drmRandom.o: /usr/include/bits/endian.h /usr/include/sys/select.h +xf86drmRandom.o: /usr/include/bits/select.h /usr/include/bits/sigset.h +xf86drmRandom.o: /usr/include/sys/sysmacros.h /usr/include/alloca.h +xf86drmSL.o: xf86drm.h /usr/include/stdio.h /usr/include/features.h +xf86drmSL.o: /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h +xf86drmSL.o: /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h +xf86drmSL.o: /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h +xf86drmSL.o: /usr/include/bits/types.h /usr/include/libio.h +xf86drmSL.o: /usr/include/_G_config.h /usr/include/bits/stdio_lim.h +xf86drmSL.o: /usr/include/stdlib.h /usr/include/sys/types.h +xf86drmSL.o: /usr/include/time.h /usr/include/endian.h +xf86drmSL.o: /usr/include/bits/endian.h /usr/include/sys/select.h +xf86drmSL.o: /usr/include/bits/select.h /usr/include/bits/sigset.h +xf86drmSL.o: /usr/include/sys/sysmacros.h /usr/include/alloca.h diff --git a/linux/drm.h b/linux/drm.h index 86ab0410..d196d912 100644 --- a/linux/drm.h +++ b/linux/drm.h @@ -345,8 +345,9 @@ typedef struct drm_agp_info { /* I810 specific ioctls */ #define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t) #define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t) -#define DRM_IOCTL_I810_DMA DRM_IOW( 0x42, drm_i810_general_t) +#define DRM_IOCTL_I810_CLEAR DRM_IOW( 0x42, drm_i810_clear_t) #define DRM_IOCTL_I810_FLUSH DRM_IO ( 0x43) #define DRM_IOCTL_I810_GETAGE DRM_IO ( 0x44) #define DRM_IOCTL_I810_GETBUF DRM_IOW( 0x45, drm_i810_dma_t) +#define DRM_IOCTL_I810_SWAP DRM_IO ( 0x46) #endif diff --git a/linux/i810_dma.c b/linux/i810_dma.c index c940f5cd..5c85a4dc 100644 --- a/linux/i810_dma.c +++ b/linux/i810_dma.c @@ -37,8 +37,9 @@ #include <linux/interrupt.h> /* For task queue support */ -#define I810_BUF_FREE 1 -#define I810_BUF_USED 0 +#define I810_BUF_FREE 2 +#define I810_BUF_CLIENT 1 +#define I810_BUF_HARDWARE 0 #define I810_BUF_UNMAPPED 0 #define I810_BUF_MAPPED 1 @@ -94,7 +95,7 @@ static inline void i810_print_status_page(drm_device_t *dev) DRM_DEBUG( "hw_status: Reserved : %x\n", temp[3]); DRM_DEBUG( "hw_status: Driver Counter : %d\n", temp[5]); for(i = 6; i < dma->buf_count + 6; i++) { - DRM_DEBUG( "buffer status idx : %d used: %d\n", i - 6, temp[i]); + DRM_DEBUG( "buffer status idx : %d used: %d\n", i - 6, temp[i]); } } @@ -111,7 +112,7 @@ static drm_buf_t *i810_freelist_get(drm_device_t *dev) drm_i810_buf_priv_t *buf_priv = buf->dev_private; /* In use is already a pointer */ used = cmpxchg(buf_priv->in_use, I810_BUF_FREE, - I810_BUF_USED); + I810_BUF_CLIENT); if(used == I810_BUF_FREE) { return buf; } @@ -129,8 +130,8 @@ static int i810_freelist_put(drm_device_t *dev, drm_buf_t *buf) int used; /* In use is already a pointer */ - used = cmpxchg(buf_priv->in_use, I810_BUF_USED, I810_BUF_FREE); - if(used != I810_BUF_USED) { + used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_FREE); + if(used != I810_BUF_CLIENT) { DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx); return -EINVAL; } @@ -218,7 +219,8 @@ static int i810_dma_get_buffer(drm_device_t *dev, drm_i810_dma_t *d, retcode = i810_map_buffer(buf, filp); if(retcode) { i810_freelist_put(dev, buf); - DRM_DEBUG("mapbuf failed in %s retcode %d\n", __FUNCTION__, retcode); + DRM_DEBUG("mapbuf failed in %s retcode %d\n", + __FUNCTION__, retcode); goto out_get_buf; } buf->pid = current->pid; @@ -260,7 +262,10 @@ static void i810_free_page(drm_device_t *dev, unsigned long page) static int i810_dma_cleanup(drm_device_t *dev) { + drm_device_dma_t *dma = dev->dma; + if(dev->dev_private) { + int i; drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private; @@ -276,6 +281,12 @@ static int i810_dma_cleanup(drm_device_t *dev) drm_free(dev->dev_private, sizeof(drm_i810_private_t), DRM_MEM_DRIVER); dev->dev_private = NULL; + + for (i = 0; i < dma->buf_count; i++) { + drm_buf_t *buf = dma->buflist[ i ]; + drm_i810_buf_priv_t *buf_priv = buf->dev_private; + drm_ioremapfree(buf_priv->kernel_virtual, buf->total); + } } return 0; } @@ -325,9 +336,9 @@ static int i810_freelist_init(drm_device_t *dev) { drm_device_dma_t *dma = dev->dma; drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; - u8 *hw_status = (u8 *)dev_priv->hw_status_page; - int i; int my_idx = 24; + u32 *hw_status = (u32 *)(dev_priv->hw_status_page + my_idx); + int i; if(dma->buf_count > 1019) { /* Not enough space in the status page for the freelist */ @@ -338,11 +349,14 @@ static int i810_freelist_init(drm_device_t *dev) drm_buf_t *buf = dma->buflist[ i ]; drm_i810_buf_priv_t *buf_priv = buf->dev_private; - buf_priv->in_use = hw_status + my_idx; - DRM_DEBUG("buf_priv->in_use : %p\n", buf_priv->in_use); - *buf_priv->in_use = I810_BUF_FREE; + buf_priv->in_use = hw_status++; buf_priv->my_use_idx = my_idx; my_idx += 4; + + *buf_priv->in_use = I810_BUF_FREE; + + buf_priv->kernel_virtual = drm_ioremap(buf->bus_address, + buf->total); } return 0; } @@ -376,9 +390,11 @@ static int i810_dma_initialize(drm_device_t *dev, dev_priv->ring.Start = init->ring_start; dev_priv->ring.End = init->ring_end; dev_priv->ring.Size = init->ring_size; + dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base + init->ring_start, init->ring_size); + dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; if (dev_priv->ring.virtual_start == NULL) { @@ -387,6 +403,17 @@ static int i810_dma_initialize(drm_device_t *dev, " ring buffer\n"); return -ENOMEM; } + + dev_priv->w = init->w; + dev_priv->h = init->h; + dev_priv->pitch = init->pitch; + dev_priv->back_offset = init->back_offset; + dev_priv->depth_offset = init->depth_offset; + + dev_priv->front_di1 = init->front_offset | init->pitch_bits; + dev_priv->back_di1 = init->back_offset | init->pitch_bits; + dev_priv->zi1 = init->depth_offset | init->pitch_bits; + /* Program Hardware Status Page */ dev_priv->hw_status_page = i810_alloc_page(dev); @@ -441,40 +468,274 @@ int i810_dma_init(struct inode *inode, struct file *filp, return retcode; } -static void i810_dma_dispatch_general(drm_device_t *dev, drm_buf_t *buf, - int used ) + + +/* Most efficient way to verify state for the i810 is as it is + * emitted. Non-conformant state is silently dropped. + * + * Use 'volatile' & local var tmp to force the emitted values to be + * identical to the verified ones. + */ +static void i810EmitContextVerified( drm_device_t *dev, + volatile unsigned int *code ) +{ + drm_i810_private_t *dev_priv = dev->dev_private; + int i, j = 0; + unsigned int tmp; + RING_LOCALS; + + BEGIN_LP_RING( I810_CTX_SETUP_SIZE ); + + OUT_RING( GFX_OP_COLOR_FACTOR ); + OUT_RING( code[I810_CTXREG_CF1] ); + + OUT_RING( GFX_OP_STIPPLE ); + OUT_RING( code[I810_CTXREG_ST1] ); + + for ( i = 4 ; i < I810_CTX_SETUP_SIZE ; i++ ) { + tmp = code[i]; + + if ((tmp & (7<<29)) == (3<<29) && + (tmp & (0x1f<<24)) < (0x1d<<24)) + { + OUT_RING( tmp ); + j++; + } + else + DRM_DEBUG("bad cmd %x\n", tmp); + } + + if (j & 1) + OUT_RING( 0 ); + + ADVANCE_LP_RING(); +} + + +static void i810EmitTexVerified( drm_device_t *dev, + volatile unsigned int *code ) +{ + drm_i810_private_t *dev_priv = dev->dev_private; + int i, j = 0; + unsigned int tmp; + RING_LOCALS; + + BEGIN_LP_RING( I810_TEX_SETUP_SIZE ); + + OUT_RING( GFX_OP_MAP_INFO ); + OUT_RING( code[I810_TEXREG_MI1] ); + OUT_RING( code[I810_TEXREG_MI2] ); + OUT_RING( code[I810_TEXREG_MI3] ); + + for ( i = 4 ; i < I810_TEX_SETUP_SIZE ; i++ ) { + tmp = code[i]; + + if ((tmp & (7<<29)) == (3<<29) && + (tmp & (0x1f<<24)) < (0x1d<<24)) + { + OUT_RING( tmp ); + j++; + } + else + DRM_DEBUG("bad cmd %x\n", tmp); + } + + if (j & 1) + OUT_RING( 0 ); + + ADVANCE_LP_RING(); +} + +/* Need to do some additional checking when setting the dest buffer. + */ +static void i810EmitDestVerified( drm_device_t *dev, + volatile unsigned int *code ) +{ + drm_i810_private_t *dev_priv = dev->dev_private; + unsigned int tmp; + RING_LOCALS; + + BEGIN_LP_RING( I810_DEST_SETUP_SIZE + 2 ); + + tmp = code[I810_DESTREG_DI1]; + if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) { + OUT_RING( CMD_OP_DESTBUFFER_INFO ); + OUT_RING( tmp ); + } else + DRM_DEBUG("bad di1 %x (allow %x or %x)\n", + tmp, dev_priv->front_di1, dev_priv->back_di1); + + /* invarient: + */ + OUT_RING( CMD_OP_Z_BUFFER_INFO ); + OUT_RING( dev_priv->zi1 ); + + OUT_RING( GFX_OP_DESTBUFFER_VARS ); + OUT_RING( code[I810_DESTREG_DV1] ); + + OUT_RING( GFX_OP_DRAWRECT_INFO ); + OUT_RING( code[I810_DESTREG_DR1] ); + OUT_RING( code[I810_DESTREG_DR2] ); + OUT_RING( code[I810_DESTREG_DR3] ); + OUT_RING( code[I810_DESTREG_DR4] ); + OUT_RING( 0 ); + + ADVANCE_LP_RING(); +} + + + +static void i810EmitState( drm_device_t *dev ) { - drm_i810_private_t *dev_priv = dev->dev_private; - drm_i810_buf_priv_t *buf_priv = buf->dev_private; - unsigned long address = (unsigned long)buf->bus_address; - unsigned long start = address - dev->agp->base; - RING_LOCALS; + 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; - dev_priv->counter++; - DRM_DEBUG( "dispatch counter : %ld\n", dev_priv->counter); - DRM_DEBUG( "i810_dma_dispatch\n"); - DRM_DEBUG( "start : 0x%lx\n", start); - DRM_DEBUG( "used : 0x%x\n", used); - DRM_DEBUG( "start + used - 4 : 0x%lx\n", start + used - 4); - i810_kernel_lost_context(dev); + if (dirty & I810_UPLOAD_BUFFERS) { + i810EmitDestVerified( dev, sarea_priv->BufferState ); + sarea_priv->dirty &= ~I810_UPLOAD_BUFFERS; + } - BEGIN_LP_RING(10); - OUT_RING( CMD_OP_BATCH_BUFFER ); - OUT_RING( start | BB1_PROTECTED ); - OUT_RING( start + used - 4 ); - 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 ); - ADVANCE_LP_RING(); - if(buf_priv->currently_mapped == I810_BUF_MAPPED) { - i810_unmap_buffer(buf); + if (dirty & I810_UPLOAD_CTX) { + i810EmitContextVerified( dev, sarea_priv->ContextState ); + sarea_priv->dirty &= ~I810_UPLOAD_CTX; + } + + if (dirty & I810_UPLOAD_TEX0) { + i810EmitTexVerified( dev, sarea_priv->TexState[0] ); + sarea_priv->dirty &= ~I810_UPLOAD_TEX0; + } + + if (dirty & I810_UPLOAD_TEX1) { + i810EmitTexVerified( dev, sarea_priv->TexState[1] ); + sarea_priv->dirty &= ~I810_UPLOAD_TEX1; + } +} + + + +/* need to verify + */ +static void i810_dma_dispatch_clear( drm_device_t *dev, int flags, + unsigned int clear_color, + unsigned int clear_zval ) +{ + drm_i810_private_t *dev_priv = dev->dev_private; + drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; + int nbox = sarea_priv->nbox; + drm_clip_rect_t *pbox = sarea_priv->boxes; + int pitch = dev_priv->pitch; + int cpp = 2; + int i; + RING_LOCALS; + + i810_kernel_lost_context(dev); + + if (nbox > I810_NR_SAREA_CLIPRECTS) + nbox = I810_NR_SAREA_CLIPRECTS; + + for (i = 0 ; i < nbox ; i++, pbox++) { + unsigned int x = pbox->x1; + unsigned int y = pbox->y1; + unsigned int width = (pbox->x2 - x) * cpp; + unsigned int height = pbox->y2 - y; + unsigned int start = y * pitch + x * cpp; + + if (pbox->x1 > pbox->x2 || + pbox->y1 > pbox->y2 || + pbox->x2 > dev_priv->w || + pbox->y2 > dev_priv->h) + continue; + + if ( flags & I810_FRONT ) { + DRM_DEBUG("clear front\n"); + BEGIN_LP_RING( 6 ); + OUT_RING( BR00_BITBLT_CLIENT | + BR00_OP_COLOR_BLT | 0x3 ); + OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch ); + OUT_RING( (height << 16) | width ); + OUT_RING( start ); + OUT_RING( clear_color ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + } + + if ( flags & I810_BACK ) { + DRM_DEBUG("clear back\n"); + BEGIN_LP_RING( 6 ); + OUT_RING( BR00_BITBLT_CLIENT | + BR00_OP_COLOR_BLT | 0x3 ); + OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch ); + OUT_RING( (height << 16) | width ); + OUT_RING( dev_priv->back_offset + start ); + OUT_RING( clear_color ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + } + + if ( flags & I810_DEPTH ) { + DRM_DEBUG("clear depth\n"); + BEGIN_LP_RING( 6 ); + OUT_RING( BR00_BITBLT_CLIENT | + BR00_OP_COLOR_BLT | 0x3 ); + OUT_RING( BR13_SOLID_PATTERN | (0xF0 << 16) | pitch ); + OUT_RING( (height << 16) | width ); + OUT_RING( dev_priv->depth_offset + start ); + OUT_RING( clear_zval ); + OUT_RING( 0 ); + ADVANCE_LP_RING(); + } + } +} + +static void i810_dma_dispatch_swap( drm_device_t *dev ) +{ + drm_i810_private_t *dev_priv = dev->dev_private; + drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv; + int nbox = sarea_priv->nbox; + drm_clip_rect_t *pbox = sarea_priv->boxes; + int pitch = dev_priv->pitch; + int cpp = 2; + int ofs = dev_priv->back_offset; + int i; + RING_LOCALS; + + DRM_DEBUG("swapbuffers\n"); + + i810_kernel_lost_context(dev); + + if (nbox > I810_NR_SAREA_CLIPRECTS) + nbox = I810_NR_SAREA_CLIPRECTS; + + for (i = 0 ; i < nbox; i++, pbox++) + { + unsigned int w = pbox->x2 - pbox->x1; + unsigned int h = pbox->y2 - pbox->y1; + unsigned int dst = pbox->x1*cpp + pbox->y1*pitch; + unsigned int start = ofs + dst; + + if (pbox->x1 > pbox->x2 || + pbox->y1 > pbox->y2 || + pbox->x2 > dev_priv->w || + pbox->y2 > dev_priv->h) + continue; + + DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n", + pbox[i].x1, pbox[i].y1, + pbox[i].x2, pbox[i].y2); + + BEGIN_LP_RING( 6 ); + OUT_RING( BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4 ); + OUT_RING( pitch | (0xCC << 16)); + OUT_RING( (h << 16) | (w * cpp)); + OUT_RING( dst ); + OUT_RING( pitch ); + OUT_RING( start ); + ADVANCE_LP_RING(); } } + static void i810_dma_dispatch_vertex(drm_device_t *dev, drm_buf_t *buf, int discard, @@ -487,14 +748,26 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev, int nbox = sarea_priv->nbox; unsigned long address = (unsigned long)buf->bus_address; unsigned long start = address - dev->agp->base; - int i = 0; + int i = 0, u; RING_LOCALS; - + i810_kernel_lost_context(dev); + if (nbox > I810_NR_SAREA_CLIPRECTS) nbox = I810_NR_SAREA_CLIPRECTS; - - DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n", + + if (discard) { + u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, + I810_BUF_HARDWARE); + if(u != I810_BUF_CLIENT) { + DRM_DEBUG("xxxx 2\n"); + } + } + + if (sarea_priv->dirty) + i810EmitState( dev ); + + DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n", address, used, nbox); dev_priv->counter++; @@ -503,16 +776,24 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev, DRM_DEBUG( "start : %lx\n", start); DRM_DEBUG( "used : %d\n", used); DRM_DEBUG( "start + used - 4 : %ld\n", start + used - 4); - i810_kernel_lost_context(dev); if (used) { + *(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; + } + do { if (i < nbox) { BEGIN_LP_RING(4); 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].x1 | (box[i].y1<<16) ); OUT_RING( (box[i].x2-1) | ((box[i].y2-1)<<16) ); ADVANCE_LP_RING(); } @@ -543,6 +824,7 @@ static void i810_dma_dispatch_vertex(drm_device_t *dev, OUT_RING( CMD_REPORT_HEAD ); OUT_RING( 0 ); ADVANCE_LP_RING(); + if(buf_priv->currently_mapped == I810_BUF_MAPPED) { i810_unmap_buffer(buf); } @@ -711,8 +993,8 @@ static inline void i810_dma_quiescent_emit(drm_device_t *dev) RING_LOCALS; i810_kernel_lost_context(dev); - BEGIN_LP_RING(4); + BEGIN_LP_RING(4); OUT_RING( INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE ); OUT_RING( CMD_REPORT_HEAD ); OUT_RING( GFX_OP_USER_INTERRUPT ); @@ -794,23 +1076,17 @@ void i810_reclaim_buffers(drm_device_t *dev, pid_t pid) int i; if (!dma) return; - if(dev->dev_private == NULL) return; - if(dma->buflist == NULL) return; + if (!dev->dev_private) return; + if (!dma->buflist) return; + i810_flush_queue(dev); for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[ i ]; drm_i810_buf_priv_t *buf_priv = buf->dev_private; - /* Only buffers that need to get reclaimed ever - * get set to free - */ if (buf->pid == pid && buf_priv) { - cmpxchg(buf_priv->in_use, - I810_BUF_USED, I810_BUF_FREE); - if(buf_priv->currently_mapped == I810_BUF_MAPPED) { - buf_priv->currently_mapped = I810_BUF_UNMAPPED; - } + *(buf_priv->in_use) = I810_BUF_FREE; } } } @@ -900,90 +1176,80 @@ int i810_flush_ioctl(struct inode *inode, struct file *filp, return 0; } -static int i810DmaGeneral(drm_device_t *dev, drm_i810_general_t *args) -{ - drm_device_dma_t *dma = dev->dma; - drm_buf_t *buf = dma->buflist[ args->idx ]; - - if (!args->used) { - i810_freelist_put(dev, buf); - } else { - i810_dma_dispatch_general( dev, buf, args->used ); - atomic_add(args->used, &dma->total_bytes); - atomic_inc(&dma->total_dmas); - } - return 0; -} - -static int i810DmaVertex(drm_device_t *dev, drm_i810_vertex_t *args) -{ - drm_device_dma_t *dma = dev->dma; - drm_buf_t *buf = dma->buflist[ args->idx ]; - i810_dma_dispatch_vertex( dev, buf, args->discard, args->used ); - atomic_add(args->used, &dma->total_bytes); - atomic_inc(&dma->total_dmas); - return 0; -} -int i810_dma_general(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) +int i810_dma_vertex(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) { drm_file_t *priv = filp->private_data; drm_device_t *dev = priv->dev; - drm_i810_general_t general; - drm_i810_private_t *dev_priv = (drm_i810_private_t *)dev->dev_private; + drm_device_dma_t *dma = dev->dma; + 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_i810_vertex_t vertex; - int retcode = 0; - - copy_from_user_ret(&general, (drm_i810_general_t *)arg, sizeof(general), + copy_from_user_ret(&vertex, (drm_i810_vertex_t *)arg, sizeof(vertex), -EFAULT); - DRM_DEBUG("i810 dma general idx %d used %d\n", - general.idx, general.used); - if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { - DRM_ERROR("i810_dma_general called without lock held\n"); + DRM_ERROR("i810_dma_vertex called without lock held\n"); return -EINVAL; } - retcode = i810DmaGeneral(dev, &general); + DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n", + vertex.idx, vertex.used, vertex.discard); + + i810_dma_dispatch_vertex( dev, + dma->buflist[ vertex.idx ], + vertex.discard, vertex.used ); + + atomic_add(vertex.used, &dma->total_bytes); + atomic_inc(&dma->total_dmas); sarea_priv->last_enqueue = dev_priv->counter-1; sarea_priv->last_dispatch = (int) hw_status[5]; - return retcode; + return 0; } -int i810_dma_vertex(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg) + + +int i810_clear_bufs(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_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_i810_vertex_t vertex; - int retcode = 0; + drm_i810_clear_t clear; - copy_from_user_ret(&vertex, (drm_i810_vertex_t *)arg, sizeof(vertex), + copy_from_user_ret(&clear, (drm_i810_clear_t *)arg, sizeof(clear), -EFAULT); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { - DRM_ERROR("i810_dma_vertex called without lock held\n"); + DRM_ERROR("i810_clear_bufs called without lock held\n"); return -EINVAL; } - DRM_DEBUG("i810 dma vertex, idx %d used %d discard %d\n", - vertex.idx, vertex.used, vertex.discard); + i810_dma_dispatch_clear( dev, clear.flags, + clear.clear_color, + clear.clear_depth ); + return 0; +} - retcode = i810DmaVertex(dev, &vertex); - sarea_priv->last_enqueue = dev_priv->counter-1; - sarea_priv->last_dispatch = (int) hw_status[5]; +int i810_swap_bufs(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; - return retcode; + DRM_DEBUG("i810_swap_bufs\n"); + if(!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("i810_swap_buf called without lock held\n"); + return -EINVAL; + } + + i810_dma_dispatch_swap( dev ); + return 0; } int i810_getage(struct inode *inode, struct file *filp, unsigned int cmd, diff --git a/linux/i810_drm.h b/linux/i810_drm.h index 7e435879..4c8e09f6 100644 --- a/linux/i810_drm.h +++ b/linux/i810_drm.h @@ -5,35 +5,112 @@ * if you change them, you must change the defines in the Xserver. */ -/* Might one day want to support the client-side ringbuffer code again. - */ #ifndef _I810_DEFINES_ #define _I810_DEFINES_ -#define I810_USE_BATCH 1 #define I810_DMA_BUF_ORDER 12 #define I810_DMA_BUF_SZ (1<<I810_DMA_BUF_ORDER) #define I810_DMA_BUF_NR 256 -#define I810_NR_SAREA_CLIPRECTS 2 +#define I810_NR_SAREA_CLIPRECTS 8 /* Each region is a minimum of 64k, and there are at most 64 of them. */ - #define I810_NR_TEX_REGIONS 64 #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 + + +/* Indices into buf.Setup where various bits of state are mirrored per + * context and per buffer. These can be fired at the card as a unit, + * or in a piecewise fashion as required. + */ + +/* Destbuffer state + * - backbuffer linear offset and pitch -- invarient in the current dri + * - zbuffer linear offset and pitch -- also invarient + * - drawing origin in back and depth buffers. + * + * Keep the depth/back buffer state here to acommodate private buffers + * in the future. + */ +#define I810_DESTREG_DI0 0 /* CMD_OP_DESTBUFFER_INFO (2 dwords) */ +#define I810_DESTREG_DI1 1 +#define I810_DESTREG_DV0 2 /* GFX_OP_DESTBUFFER_VARS (2 dwords) */ +#define I810_DESTREG_DV1 3 +#define I810_DESTREG_DR0 4 /* GFX_OP_DRAWRECT_INFO (4 dwords) */ +#define I810_DESTREG_DR1 5 +#define I810_DESTREG_DR2 6 +#define I810_DESTREG_DR3 7 +#define I810_DESTREG_DR4 8 +#define I810_DEST_SETUP_SIZE 10 + +/* Context state + */ +#define I810_CTXREG_CF0 0 /* GFX_OP_COLOR_FACTOR */ +#define I810_CTXREG_CF1 1 +#define I810_CTXREG_ST0 2 /* GFX_OP_STIPPLE */ +#define I810_CTXREG_ST1 3 +#define I810_CTXREG_VF 4 /* GFX_OP_VERTEX_FMT */ +#define I810_CTXREG_MT 5 /* GFX_OP_MAP_TEXELS */ +#define I810_CTXREG_MC0 6 /* GFX_OP_MAP_COLOR_STAGES - stage 0 */ +#define I810_CTXREG_MC1 7 /* GFX_OP_MAP_COLOR_STAGES - stage 1 */ +#define I810_CTXREG_MC2 8 /* GFX_OP_MAP_COLOR_STAGES - stage 2 */ +#define I810_CTXREG_MA0 9 /* GFX_OP_MAP_ALPHA_STAGES - stage 0 */ +#define I810_CTXREG_MA1 10 /* GFX_OP_MAP_ALPHA_STAGES - stage 1 */ +#define I810_CTXREG_MA2 11 /* GFX_OP_MAP_ALPHA_STAGES - stage 2 */ +#define I810_CTXREG_SDM 12 /* GFX_OP_SRC_DEST_MONO */ +#define I810_CTXREG_FOG 13 /* GFX_OP_FOG_COLOR */ +#define I810_CTXREG_B1 14 /* GFX_OP_BOOL_1 */ +#define I810_CTXREG_B2 15 /* GFX_OP_BOOL_2 */ +#define I810_CTXREG_LCS 16 /* GFX_OP_LINEWIDTH_CULL_SHADE_MODE */ +#define I810_CTXREG_PV 17 /* GFX_OP_PV_RULE -- Invarient! */ +#define I810_CTXREG_ZA 18 /* GFX_OP_ZBIAS_ALPHAFUNC */ +#define I810_CTXREG_AA 19 /* GFX_OP_ANTIALIAS */ +#define I810_CTX_SETUP_SIZE 20 + +/* Texture state (per tex unit) + */ +#define I810_TEXREG_MI0 0 /* GFX_OP_MAP_INFO (4 dwords) */ +#define I810_TEXREG_MI1 1 +#define I810_TEXREG_MI2 2 +#define I810_TEXREG_MI3 3 +#define I810_TEXREG_MF 4 /* GFX_OP_MAP_FILTER */ +#define I810_TEXREG_MLC 5 /* GFX_OP_MAP_LOD_CTL */ +#define I810_TEXREG_MLL 6 /* GFX_OP_MAP_LOD_LIMITS */ +#define I810_TEXREG_MCS 7 /* GFX_OP_MAP_COORD_SETS ??? */ +#define I810_TEX_SETUP_SIZE 8 + +#define I810_FRONT 0x1 +#define I810_BACK 0x2 +#define I810_DEPTH 0x4 + + typedef struct _drm_i810_init { - enum { - I810_INIT_DMA = 0x01, - I810_CLEANUP_DMA = 0x02 + enum { + I810_INIT_DMA = 0x01, + I810_CLEANUP_DMA = 0x02 } func; - int ring_map_idx; - int buffer_map_idx; + int ring_map_idx; + int buffer_map_idx; int sarea_priv_offset; - unsigned long ring_start; - unsigned long ring_end; - unsigned long ring_size; + unsigned int ring_start; + unsigned int ring_end; + unsigned int ring_size; + unsigned int front_offset; + unsigned int back_offset; + unsigned int depth_offset; + unsigned int w; + unsigned int h; + unsigned int pitch; + unsigned int pitch_bits; } drm_i810_init_t; /* Warning: If you change the SAREA structure you must change the Xserver @@ -46,6 +123,11 @@ typedef struct _drm_i810_tex_region { } drm_i810_tex_region_t; 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; + unsigned int nbox; drm_clip_rect_t boxes[I810_NR_SAREA_CLIPRECTS]; @@ -72,12 +154,18 @@ typedef struct _drm_i810_sarea { 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_general { - int idx; - int used; -} drm_i810_general_t; +typedef struct _drm_i810_clear { + int clear_color; + int clear_depth; + int flags; +} 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 diff --git a/linux/i810_drv.c b/linux/i810_drv.c index 03585bdf..75b402da 100644 --- a/linux/i810_drv.c +++ b/linux/i810_drv.c @@ -107,10 +107,11 @@ static drm_ioctl_desc_t i810_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_I810_INIT)] = { i810_dma_init, 1, 1 }, [DRM_IOCTL_NR(DRM_IOCTL_I810_VERTEX)] = { i810_dma_vertex, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_I810_DMA)] = { i810_dma_general,1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_I810_CLEAR)] = { i810_clear_bufs, 1, 0 }, [DRM_IOCTL_NR(DRM_IOCTL_I810_FLUSH)] = { i810_flush_ioctl,1, 0 }, [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 }, }; #define I810_IOCTL_COUNT DRM_ARRAY_SIZE(i810_ioctls) diff --git a/linux/i810_drv.h b/linux/i810_drv.h index e775d1b6..671489d3 100644 --- a/linux/i810_drv.h +++ b/linux/i810_drv.h @@ -55,6 +55,15 @@ typedef struct drm_i810_private { atomic_t flush_done; wait_queue_head_t flush_queue; /* Processes waiting until flush */ + + + + u32 front_di1, back_di1, zi1; + + int back_offset; + int depth_offset; + int w, h; + int pitch; } drm_i810_private_t; /* i810_drv.c */ @@ -128,11 +137,9 @@ typedef struct drm_i810_buf_priv { int my_use_idx; int currently_mapped; void *virtual; + void *kernel_virtual; } drm_i810_buf_priv_t; -#define I810_DMA_GENERAL 0 -#define I810_DMA_VERTEX 1 -#define I810_DMA_DISCARD 2 /* not used */ #define I810_VERBOSE 0 @@ -140,9 +147,11 @@ typedef struct drm_i810_buf_priv { int i810_dma_vertex(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg); -int i810_dma_general(struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg); +int i810_swap_bufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +int i810_clear_bufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); #define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23)) #define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23)) @@ -196,5 +205,22 @@ int i810_dma_general(struct inode *inode, struct file *filp, #define SCI_YMAX_MASK (0xffff<<16) #define SCI_XMAX_MASK (0xffff<<0) +#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0) +#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16)) +#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x2) +#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0) +#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3)) +#define GFX_OP_PRIMITIVE ((0x3<<29)|(0x1f<<24)) + +#define CMD_OP_Z_BUFFER_INFO ((0x0<<29)|(0x16<<23)) +#define CMD_OP_DESTBUFFER_INFO ((0x0<<29)|(0x15<<23)) + +#define BR00_BITBLT_CLIENT 0x40000000 +#define BR00_OP_COLOR_BLT 0x10000000 +#define BR00_OP_SRC_COPY_BLT 0x10C00000 +#define BR13_SOLID_PATTERN 0x80000000 + + + #endif diff --git a/linux/mga_drm.h b/linux/mga_drm.h index 12a858e7..eb8c434a 100644 --- a/linux/mga_drm.h +++ b/linux/mga_drm.h @@ -37,6 +37,7 @@ */ #ifndef _MGA_DEFINES_ #define _MGA_DEFINES_ + #define MGA_F 0x1 /* fog */ #define MGA_A 0x2 /* alpha */ #define MGA_S 0x4 /* specular */ @@ -61,11 +62,11 @@ #define MGA_MAX_G400_PIPES 16 #define MGA_MAX_G200_PIPES 8 /* no multitex */ - #define MGA_MAX_WARP_PIPES MGA_MAX_G400_PIPES #define MGA_CARD_TYPE_G200 1 #define MGA_CARD_TYPE_G400 2 + #define MGA_FRONT 0x1 #define MGA_BACK 0x2 #define MGA_DEPTH 0x4 @@ -110,8 +111,8 @@ #define MGA_UPLOAD_TEX0 0x2 #define MGA_UPLOAD_TEX1 0x4 #define MGA_UPLOAD_PIPE 0x8 -#define MGA_UPLOAD_TEX0IMAGE 0x10 -#define MGA_UPLOAD_TEX1IMAGE 0x20 +#define MGA_UPLOAD_TEX0IMAGE 0x10 /* handled client-side */ +#define MGA_UPLOAD_TEX1IMAGE 0x20 /* handled client-side */ #define MGA_UPLOAD_2D 0x40 #define MGA_WAIT_AGE 0x80 /* handled client-side */ #define MGA_UPLOAD_CLIPRECTS 0x100 /* handled client-side */ diff --git a/shared-core/drm.h b/shared-core/drm.h index 86ab0410..d196d912 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -345,8 +345,9 @@ typedef struct drm_agp_info { /* I810 specific ioctls */ #define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t) #define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t) -#define DRM_IOCTL_I810_DMA DRM_IOW( 0x42, drm_i810_general_t) +#define DRM_IOCTL_I810_CLEAR DRM_IOW( 0x42, drm_i810_clear_t) #define DRM_IOCTL_I810_FLUSH DRM_IO ( 0x43) #define DRM_IOCTL_I810_GETAGE DRM_IO ( 0x44) #define DRM_IOCTL_I810_GETBUF DRM_IOW( 0x45, drm_i810_dma_t) +#define DRM_IOCTL_I810_SWAP DRM_IO ( 0x46) #endif diff --git a/shared/drm.h b/shared/drm.h index 86ab0410..d196d912 100644 --- a/shared/drm.h +++ b/shared/drm.h @@ -345,8 +345,9 @@ typedef struct drm_agp_info { /* I810 specific ioctls */ #define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t) #define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t) -#define DRM_IOCTL_I810_DMA DRM_IOW( 0x42, drm_i810_general_t) +#define DRM_IOCTL_I810_CLEAR DRM_IOW( 0x42, drm_i810_clear_t) #define DRM_IOCTL_I810_FLUSH DRM_IO ( 0x43) #define DRM_IOCTL_I810_GETAGE DRM_IO ( 0x44) #define DRM_IOCTL_I810_GETBUF DRM_IOW( 0x45, drm_i810_dma_t) +#define DRM_IOCTL_I810_SWAP DRM_IO ( 0x46) #endif |