📄 r128_state.c
字号:
kfree( x ); kfree( y ); return -ENOMEM; } if ( copy_from_user( buffer, depth->buffer, depth->n * sizeof(u32) ) ) { kfree( x ); kfree( y ); kfree( buffer ); return -EFAULT; } if ( depth->mask ) { mask = kmalloc( depth->n * sizeof(u8), 0 ); if ( mask == NULL ) { kfree( x ); kfree( y ); kfree( buffer ); return -ENOMEM; } if ( copy_from_user( mask, depth->mask, depth->n * sizeof(u8) ) ) { kfree( x ); kfree( y ); kfree( buffer ); kfree( mask ); return -EFAULT; } for ( i = 0 ; i < count ; i++ ) { if ( mask[i] ) { BEGIN_RING( 6 ); OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | R128_GMC_BRUSH_SOLID_COLOR | depth_bpp | R128_GMC_SRC_DATATYPE_COLOR | R128_ROP3_P | R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_WR_MSK_DIS ); OUT_RING( dev_priv->depth_pitch_offset_c ); OUT_RING( buffer[i] ); OUT_RING( (x[i] << 16) | y[i] ); OUT_RING( (1 << 16) | 1 ); ADVANCE_RING(); } } kfree( mask ); } else { for ( i = 0 ; i < count ; i++ ) { BEGIN_RING( 6 ); OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | R128_GMC_BRUSH_SOLID_COLOR | depth_bpp | R128_GMC_SRC_DATATYPE_COLOR | R128_ROP3_P | R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_WR_MSK_DIS ); OUT_RING( dev_priv->depth_pitch_offset_c ); OUT_RING( buffer[i] ); OUT_RING( (x[i] << 16) | y[i] ); OUT_RING( (1 << 16) | 1 ); ADVANCE_RING(); } } kfree( x ); kfree( y ); kfree( buffer ); return 0;}static int r128_cce_dispatch_read_span( drm_device_t *dev, drm_r128_depth_t *depth ){ drm_r128_private_t *dev_priv = dev->dev_private; int count, x, y; u32 depth_bpp; RING_LOCALS; DRM_DEBUG( "%s\n", __FUNCTION__ ); r128_update_ring_snapshot( dev_priv ); switch ( dev_priv->depth_bpp ) { case 16: depth_bpp = R128_GMC_DST_16BPP; break; case 24: case 32: depth_bpp = R128_GMC_DST_32BPP; break; default: return -EINVAL; } count = depth->n; if ( copy_from_user( &x, depth->x, sizeof(x) ) ) { return -EFAULT; } if ( copy_from_user( &y, depth->y, sizeof(y) ) ) { return -EFAULT; } BEGIN_RING( 7 ); OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) ); OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL | R128_GMC_DST_PITCH_OFFSET_CNTL | R128_GMC_BRUSH_NONE | depth_bpp | R128_GMC_SRC_DATATYPE_COLOR | R128_ROP3_S | R128_DP_SRC_SOURCE_MEMORY | R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_WR_MSK_DIS ); OUT_RING( dev_priv->depth_pitch_offset_c ); OUT_RING( dev_priv->span_pitch_offset_c ); OUT_RING( (x << 16) | y ); OUT_RING( (0 << 16) | 0 ); OUT_RING( (count << 16) | 1 ); ADVANCE_RING(); return 0;}static int r128_cce_dispatch_read_pixels( drm_device_t *dev, drm_r128_depth_t *depth ){ drm_r128_private_t *dev_priv = dev->dev_private; int count, *x, *y; u32 depth_bpp; int i; RING_LOCALS; DRM_DEBUG( "%s\n", __FUNCTION__ ); r128_update_ring_snapshot( dev_priv ); switch ( dev_priv->depth_bpp ) { case 16: depth_bpp = R128_GMC_DST_16BPP; break; case 24: case 32: depth_bpp = R128_GMC_DST_32BPP; break; default: return -EINVAL; } count = depth->n; if ( count > dev_priv->depth_pitch ) { count = dev_priv->depth_pitch; } x = kmalloc( count * sizeof(*x), 0 ); if ( x == NULL ) { return -ENOMEM; } y = kmalloc( count * sizeof(*y), 0 ); if ( y == NULL ) { kfree( x ); return -ENOMEM; } if ( copy_from_user( x, depth->x, count * sizeof(int) ) ) { kfree( x ); kfree( y ); return -EFAULT; } if ( copy_from_user( y, depth->y, count * sizeof(int) ) ) { kfree( x ); kfree( y ); return -EFAULT; } for ( i = 0 ; i < count ; i++ ) { BEGIN_RING( 7 ); OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) ); OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL | R128_GMC_DST_PITCH_OFFSET_CNTL | R128_GMC_BRUSH_NONE | depth_bpp | R128_GMC_SRC_DATATYPE_COLOR | R128_ROP3_S | R128_DP_SRC_SOURCE_MEMORY | R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_WR_MSK_DIS ); OUT_RING( dev_priv->depth_pitch_offset_c ); OUT_RING( dev_priv->span_pitch_offset_c ); OUT_RING( (x[i] << 16) | y[i] ); OUT_RING( (i << 16) | 0 ); OUT_RING( (1 << 16) | 1 ); ADVANCE_RING(); } kfree( x ); kfree( y ); return 0;}/* ================================================================ * Polygon stipple */static void r128_cce_dispatch_stipple( drm_device_t *dev, u32 *stipple ){ drm_r128_private_t *dev_priv = dev->dev_private; int i; RING_LOCALS; DRM_DEBUG( "%s\n", __FUNCTION__ ); r128_update_ring_snapshot( dev_priv ); BEGIN_RING( 33 ); OUT_RING( CCE_PACKET0( R128_BRUSH_DATA0, 31 ) ); for ( i = 0 ; i < 32 ; i++ ) { OUT_RING( stipple[i] ); } ADVANCE_RING();}/* ================================================================ * IOCTL functions */int r128_cce_clear( 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_r128_private_t *dev_priv = dev->dev_private; drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; drm_r128_clear_t clear; DRM_DEBUG( "%s\n", __FUNCTION__ ); if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || dev->lock.pid != current->pid ) { DRM_ERROR( "r128_cce_clear called without lock held\n" ); return -EINVAL; } if ( copy_from_user( &clear, (drm_r128_clear_t *) arg, sizeof(clear) ) ) return -EFAULT; if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS ) sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS; r128_cce_dispatch_clear( dev, clear.flags, clear.x, clear.y, clear.w, clear.h, clear.clear_color, clear.clear_depth ); /* Make sure we restore the 3D state next time. */ dev_priv->sarea_priv->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; return 0;}int r128_cce_swap( 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_r128_private_t *dev_priv = dev->dev_private; drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; DRM_DEBUG( "%s\n", __FUNCTION__ ); if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || dev->lock.pid != current->pid ) { DRM_ERROR( "r128_cce_swap called without lock held\n" ); return -EINVAL; } if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS ) sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS; r128_cce_dispatch_swap( dev ); /* Make sure we restore the 3D state next time. */ dev_priv->sarea_priv->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; return 0;}int r128_cce_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_r128_private_t *dev_priv = dev->dev_private; drm_device_dma_t *dma = dev->dma; drm_buf_t *buf; drm_r128_buf_priv_t *buf_priv; drm_r128_vertex_t vertex; 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; } if ( copy_from_user( &vertex, (drm_r128_vertex_t *)arg, sizeof(vertex) ) ) return -EFAULT; DRM_DEBUG( "%s: pid=%d index=%d count=%d discard=%d\n", __FUNCTION__, current->pid, vertex.idx, vertex.count, 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 > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 ) { DRM_ERROR( "buffer prim %d\n", vertex.prim ); return -EINVAL; } buf = dma->buflist[vertex.idx]; buf_priv = buf->dev_private; 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", vertex.idx ); return -EINVAL; } buf->used = vertex.count; buf_priv->prim = vertex.prim; buf_priv->discard = vertex.discard; r128_cce_dispatch_vertex( dev, buf ); return 0;}int r128_cce_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_r128_private_t *dev_priv = dev->dev_private; drm_device_dma_t *dma = dev->dma; drm_buf_t *buf; drm_r128_buf_priv_t *buf_priv; drm_r128_indices_t elts; int count; 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; } if ( copy_from_user( &elts, (drm_r128_indices_t *)arg, sizeof(elts) ) ) return -EFAULT; DRM_DEBUG( "%s: pid=%d buf=%d s=%d e=%d d=%d\n", __FUNCTION__, current->pid, elts.idx, elts.start, elts.end, elts.discard ); 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 > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 ) { DRM_ERROR( "buffer prim %d\n", elts.prim ); return -EINVAL; } buf = dma->buflist[elts.idx]; buf_priv = buf->dev_private; 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; } count = (elts.end - elts.start) / sizeof(u16); elts.start -= R128_INDEX_PRIM_OFFSET; if ( elts.start & 0x7 ) { DRM_ERROR( "misaligned buffer 0x%x\n", elts.start ); return -EINVAL; } 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; r128_cce_dispatch_indices( dev, buf, elts.start, elts.end, count ); return 0;}int r128_cce_blit( 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_device_dma_t *dma = dev->dma; drm_r128_blit_t blit; 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 ( copy_from_user( &blit, (drm_r128_blit_t *)arg, sizeof(blit) ) ) return -EFAULT; DRM_DEBUG( "%s: pid=%d index=%d\n", __FUNCTION__, current->pid, blit.idx ); if ( blit.idx < 0 || blit.idx >= dma->buf_count ) { DRM_ERROR( "buffer index %d (of %d max)\n", blit.idx, dma->buf_count - 1 ); return -EINVAL; } return r128_cce_dispatch_blit( dev, &blit );}int r128_cce_depth( 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_r128_depth_t depth; 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 ( copy_from_user( &depth, (drm_r128_depth_t *)arg, sizeof(depth) ) ) return -EFAULT; switch ( depth.func ) { case R128_WRITE_SPAN: return r128_cce_dispatch_write_span( dev, &depth ); case R128_WRITE_PIXELS: return r128_cce_dispatch_write_pixels( dev, &depth ); case R128_READ_SPAN: return r128_cce_dispatch_read_span( dev, &depth ); case R128_READ_PIXELS: return r128_cce_dispatch_read_pixels( dev, &depth ); } return -EINVAL;}int r128_cce_stipple( 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_r128_stipple_t stipple; u32 mask[32]; 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 ( copy_from_user( &stipple, (drm_r128_stipple_t *)arg, sizeof(stipple) ) ) return -EFAULT; if ( copy_from_user( &mask, stipple.mask, 32 * sizeof(u32) ) ) return -EFAULT; r128_cce_dispatch_stipple( dev, mask ); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -