📄 i830_dma.c
字号:
dev_priv->back_pitch = init->back_pitch; dev_priv->depth_pitch = init->depth_pitch; /* Program Hardware Status Page */ dev_priv->hw_status_page = pci_alloc_consistent(dev->pdev, PAGE_SIZE, &dev_priv->dma_status_page); if(dev_priv->hw_status_page == NULL) { dev->dev_private = (void *)dev_priv; i830_dma_cleanup(dev); DRM_ERROR("Can not allocate hardware status page\n"); return -ENOMEM; } memset(dev_priv->hw_status_page, 0, PAGE_SIZE); DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page); I830_WRITE(0x02080, dev_priv->dma_status_page); DRM_DEBUG("Enabled hardware status page\n"); /* Now we need to init our freelist */ if(i830_freelist_init(dev, dev_priv) != 0) { dev->dev_private = (void *)dev_priv; i830_dma_cleanup(dev); DRM_ERROR("Not enough space in the status page for" " the freelist\n"); return -ENOMEM; } dev->dev_private = (void *)dev_priv; return 0;}int i830_dma_init(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_i830_private_t *dev_priv; drm_i830_init_t init; int retcode = 0; if (copy_from_user(&init, (drm_i830_init_t *)arg, sizeof(init))) return -EFAULT; switch(init.func) { case I830_INIT_DMA: dev_priv = DRM(alloc)(sizeof(drm_i830_private_t), DRM_MEM_DRIVER); if(dev_priv == NULL) return -ENOMEM; retcode = i830_dma_initialize(dev, dev_priv, &init); break; case I830_CLEANUP_DMA: retcode = i830_dma_cleanup(dev); break; default: retcode = -EINVAL; break; } return retcode;}/* Most efficient way to verify state for the i830 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 i830EmitContextVerified( drm_device_t *dev, volatile unsigned int *code ){ drm_i830_private_t *dev_priv = dev->dev_private; int i, j = 0; unsigned int tmp; RING_LOCALS; BEGIN_LP_RING( I830_CTX_SETUP_SIZE ); for ( i = 0 ; i < I830_CTX_SETUP_SIZE ; i++ ) { tmp = code[i];#if 0 if ((tmp & (7<<29)) == (3<<29) && (tmp & (0x1f<<24)) < (0x1d<<24)) { OUT_RING( tmp ); j++; } else { printk("Skipping %d\n", i); }#else OUT_RING( tmp ); j++;#endif } if (j & 1) OUT_RING( 0 ); ADVANCE_LP_RING();}static void i830EmitTexVerified( drm_device_t *dev, volatile unsigned int *code ) { drm_i830_private_t *dev_priv = dev->dev_private; int i, j = 0; unsigned int tmp; RING_LOCALS; BEGIN_LP_RING( I830_TEX_SETUP_SIZE ); OUT_RING( GFX_OP_MAP_INFO ); OUT_RING( code[I830_TEXREG_MI1] ); OUT_RING( code[I830_TEXREG_MI2] ); OUT_RING( code[I830_TEXREG_MI3] ); OUT_RING( code[I830_TEXREG_MI4] ); OUT_RING( code[I830_TEXREG_MI5] ); for ( i = 6 ; i < I830_TEX_SETUP_SIZE ; i++ ) { tmp = code[i]; OUT_RING( tmp ); j++; } if (j & 1) OUT_RING( 0 ); ADVANCE_LP_RING();}static void i830EmitTexBlendVerified( drm_device_t *dev, volatile unsigned int *code, volatile unsigned int num){ drm_i830_private_t *dev_priv = dev->dev_private; int i, j = 0; unsigned int tmp; RING_LOCALS; BEGIN_LP_RING( num ); for ( i = 0 ; i < num ; i++ ) { tmp = code[i]; OUT_RING( tmp ); j++; } if (j & 1) OUT_RING( 0 ); ADVANCE_LP_RING();}static void i830EmitTexPalette( drm_device_t *dev, unsigned int *palette, int number, int is_shared ){ drm_i830_private_t *dev_priv = dev->dev_private; int i; RING_LOCALS; BEGIN_LP_RING( 258 ); if(is_shared == 1) { OUT_RING(CMD_OP_MAP_PALETTE_LOAD | MAP_PALETTE_NUM(0) | MAP_PALETTE_BOTH); } else { OUT_RING(CMD_OP_MAP_PALETTE_LOAD | MAP_PALETTE_NUM(number)); } for(i = 0; i < 256; i++) { OUT_RING(palette[i]); } OUT_RING(0);}/* Need to do some additional checking when setting the dest buffer. */static void i830EmitDestVerified( drm_device_t *dev, volatile unsigned int *code ) { drm_i830_private_t *dev_priv = dev->dev_private; unsigned int tmp; RING_LOCALS; BEGIN_LP_RING( I830_DEST_SETUP_SIZE + 6 ); tmp = code[I830_DESTREG_CBUFADDR]; if (tmp == dev_priv->front_di1) { /* Don't use fence when front buffer rendering */ OUT_RING( CMD_OP_DESTBUFFER_INFO ); OUT_RING( BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) ); OUT_RING( tmp ); OUT_RING( CMD_OP_DESTBUFFER_INFO ); OUT_RING( BUF_3D_ID_DEPTH | BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp)); OUT_RING( dev_priv->zi1 ); } else if(tmp == dev_priv->back_di1) { OUT_RING( CMD_OP_DESTBUFFER_INFO ); OUT_RING( BUF_3D_ID_COLOR_BACK | BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) | BUF_3D_USE_FENCE); OUT_RING( tmp ); OUT_RING( CMD_OP_DESTBUFFER_INFO ); OUT_RING( BUF_3D_ID_DEPTH | BUF_3D_USE_FENCE | BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp)); OUT_RING( dev_priv->zi1 ); } else { DRM_DEBUG("bad di1 %x (allow %x or %x)\n", tmp, dev_priv->front_di1, dev_priv->back_di1); } /* invarient: */ OUT_RING( GFX_OP_DESTBUFFER_VARS ); OUT_RING( code[I830_DESTREG_DV1] ); OUT_RING( GFX_OP_DRAWRECT_INFO ); OUT_RING( code[I830_DESTREG_DR1] ); OUT_RING( code[I830_DESTREG_DR2] ); OUT_RING( code[I830_DESTREG_DR3] ); OUT_RING( code[I830_DESTREG_DR4] ); /* Need to verify this */ tmp = code[I830_DESTREG_SENABLE]; if((tmp & ~0x3) == GFX_OP_SCISSOR_ENABLE) { OUT_RING( tmp ); } else { DRM_DEBUG("bad scissor enable\n"); OUT_RING( 0 ); } OUT_RING( code[I830_DESTREG_SENABLE] ); OUT_RING( GFX_OP_SCISSOR_RECT ); OUT_RING( code[I830_DESTREG_SR1] ); OUT_RING( code[I830_DESTREG_SR2] ); ADVANCE_LP_RING();}static void i830EmitState( drm_device_t *dev ){ drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv; unsigned int dirty = sarea_priv->dirty; if (dirty & I830_UPLOAD_BUFFERS) { i830EmitDestVerified( dev, sarea_priv->BufferState ); sarea_priv->dirty &= ~I830_UPLOAD_BUFFERS; } if (dirty & I830_UPLOAD_CTX) { i830EmitContextVerified( dev, sarea_priv->ContextState ); sarea_priv->dirty &= ~I830_UPLOAD_CTX; } if (dirty & I830_UPLOAD_TEX0) { i830EmitTexVerified( dev, sarea_priv->TexState[0] ); sarea_priv->dirty &= ~I830_UPLOAD_TEX0; } if (dirty & I830_UPLOAD_TEX1) { i830EmitTexVerified( dev, sarea_priv->TexState[1] ); sarea_priv->dirty &= ~I830_UPLOAD_TEX1; } if (dirty & I830_UPLOAD_TEXBLEND0) { i830EmitTexBlendVerified( dev, sarea_priv->TexBlendState[0], sarea_priv->TexBlendStateWordsUsed[0]); sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND0; } if (dirty & I830_UPLOAD_TEXBLEND1) { i830EmitTexBlendVerified( dev, sarea_priv->TexBlendState[1], sarea_priv->TexBlendStateWordsUsed[1]); sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND1; } if (dirty & I830_UPLOAD_TEX_PALETTE_SHARED) { i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 1); } else { if (dirty & I830_UPLOAD_TEX_PALETTE_N(0)) { i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 0); sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(0); } if (dirty & I830_UPLOAD_TEX_PALETTE_N(1)) { i830EmitTexPalette(dev, sarea_priv->Palette[1], 1, 0); sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(1); } }}static void i830_dma_dispatch_clear( drm_device_t *dev, int flags, unsigned int clear_color, unsigned int clear_zval, unsigned int clear_depthmask){ drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_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 = dev_priv->cpp; int i; unsigned int BR13, CMD, D_CMD; RING_LOCALS; i830_kernel_lost_context(dev); switch(cpp) { case 2: BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24); D_CMD = CMD = XY_COLOR_BLT_CMD; break; case 4: BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24) | (1<<25); CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB); D_CMD = XY_COLOR_BLT_CMD; if(clear_depthmask & 0x00ffffff) D_CMD |= XY_COLOR_BLT_WRITE_RGB; if(clear_depthmask & 0xff000000) D_CMD |= XY_COLOR_BLT_WRITE_ALPHA; break; default: BR13 = (0xF0 << 16) | (pitch * cpp) | (1<<24); D_CMD = CMD = XY_COLOR_BLT_CMD; break; } if (nbox > I830_NR_SAREA_CLIPRECTS) nbox = I830_NR_SAREA_CLIPRECTS; for (i = 0 ; i < nbox ; i++, pbox++) { if (pbox->x1 > pbox->x2 || pbox->y1 > pbox->y2 || pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h) continue; if ( flags & I830_FRONT ) { DRM_DEBUG("clear front\n"); BEGIN_LP_RING( 6 ); OUT_RING( CMD ); OUT_RING( BR13 ); OUT_RING( (pbox->y1 << 16) | pbox->x1 ); OUT_RING( (pbox->y2 << 16) | pbox->x2 ); OUT_RING( 0 ); OUT_RING( clear_color ); ADVANCE_LP_RING(); } if ( flags & I830_BACK ) { DRM_DEBUG("clear back\n"); BEGIN_LP_RING( 6 ); OUT_RING( CMD ); OUT_RING( BR13 ); OUT_RING( (pbox->y1 << 16) | pbox->x1 ); OUT_RING( (pbox->y2 << 16) | pbox->x2 ); OUT_RING( dev_priv->back_offset ); OUT_RING( clear_color ); ADVANCE_LP_RING(); } if ( flags & I830_DEPTH ) { DRM_DEBUG("clear depth\n"); BEGIN_LP_RING( 6 ); OUT_RING( D_CMD ); OUT_RING( BR13 ); OUT_RING( (pbox->y1 << 16) | pbox->x1 ); OUT_RING( (pbox->y2 << 16) | pbox->x2 ); OUT_RING( dev_priv->depth_offset ); OUT_RING( clear_zval ); ADVANCE_LP_RING(); } }}static void i830_dma_dispatch_swap( drm_device_t *dev ){ drm_i830_private_t *dev_priv = dev->dev_private; drm_i830_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 = dev_priv->cpp; int ofs = dev_priv->back_offset; int i; unsigned int CMD, BR13; RING_LOCALS; DRM_DEBUG("swapbuffers\n"); switch(cpp) { case 2: BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24); CMD = XY_SRC_COPY_BLT_CMD; break; case 4: BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24) | (1<<25); CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB); break; default: BR13 = (pitch * cpp) | (0xCC << 16) | (1<<24); CMD = XY_SRC_COPY_BLT_CMD; break; } i830_kernel_lost_context(dev); if (nbox > I830_NR_SAREA_CLIPRECTS) nbox = I830_NR_SAREA_CLIPRECTS; for (i = 0 ; i < nbox; i++, pbox++) { 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->x1, pbox->y1, pbox->x2, pbox->y2); BEGIN_LP_RING( 8 ); OUT_RING( CMD ); OUT_RING( BR13 ); OUT_RING( (pbox->y1 << 16) | pbox->x1 ); OUT_RING( (pbox->y2 << 16) | pbox->x2 ); OUT_RING( 0 /* front ofs always zero */ ); OUT_RING( (pbox->y1 << 16) | pbox->x1 ); OUT_RING( BR13 & 0xffff ); OUT_RING( ofs ); ADVANCE_LP_RING(); }}static void i830_dma_dispatch_vertex(drm_device_t *dev, drm_buf_t *buf, int discard, int used)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -