📄 i830_dma.c
字号:
j++; } else { DRM_ERROR("Skipping %d\n", i); } } OUT_RING( STATE3D_CONST_BLEND_COLOR_CMD ); OUT_RING( code[I830_CTXREG_BLENDCOLR] ); j += 2; for ( i = I830_CTXREG_VF ; i < I830_CTXREG_MCSB0 ; i++ ) { tmp = code[i]; if ((tmp & (7<<29)) == CMD_3D && (tmp & (0x1f<<24)) < (0x1d<<24)) { OUT_RING( tmp ); j++; } else { DRM_ERROR("Skipping %d\n", i); } } OUT_RING( STATE3D_MAP_COORD_SETBIND_CMD ); OUT_RING( code[I830_CTXREG_MCSB1] ); j += 2; if (j & 1) OUT_RING( 0 ); ADVANCE_LP_RING();}static void i830EmitTexVerified( drm_device_t *dev, unsigned int *code ) { drm_i830_private_t *dev_priv = dev->dev_private; int i, j = 0; unsigned int tmp; RING_LOCALS; if (code[I830_TEXREG_MI0] == GFX_OP_MAP_INFO || (code[I830_TEXREG_MI0] & ~(0xf*LOAD_TEXTURE_MAP0)) == (STATE3D_LOAD_STATE_IMMEDIATE_2|4)) { BEGIN_LP_RING( I830_TEX_SETUP_SIZE ); OUT_RING( code[I830_TEXREG_MI0] ); /* TM0LI */ OUT_RING( code[I830_TEXREG_MI1] ); /* TM0S0 */ OUT_RING( code[I830_TEXREG_MI2] ); /* TM0S1 */ OUT_RING( code[I830_TEXREG_MI3] ); /* TM0S2 */ OUT_RING( code[I830_TEXREG_MI4] ); /* TM0S3 */ OUT_RING( code[I830_TEXREG_MI5] ); /* TM0S4 */ 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(); } else printk("rejected packet %x\n", code[0]);}static void i830EmitTexBlendVerified( drm_device_t *dev, unsigned int *code, unsigned int num){ drm_i830_private_t *dev_priv = dev->dev_private; int i, j = 0; unsigned int tmp; RING_LOCALS; if (!num) return; BEGIN_LP_RING( num + 1 ); 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; return; 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); /* KW: WHERE IS THE ADVANCE_LP_RING? This is effectively a noop! */}/* Need to do some additional checking when setting the dest buffer. */static void i830EmitDestVerified( drm_device_t *dev, unsigned int *code ) { drm_i830_private_t *dev_priv = dev->dev_private; unsigned int tmp; RING_LOCALS; BEGIN_LP_RING( I830_DEST_SETUP_SIZE + 10 ); tmp = code[I830_DESTREG_CBUFADDR]; if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) { if (((int)outring) & 8) { OUT_RING(0); OUT_RING(0); } 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( 0 ); 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 ); OUT_RING( 0 ); } else { DRM_ERROR("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_ERROR("bad scissor enable\n"); OUT_RING( 0 ); } OUT_RING( GFX_OP_SCISSOR_RECT ); OUT_RING( code[I830_DESTREG_SR1] ); OUT_RING( code[I830_DESTREG_SR2] ); OUT_RING( 0 ); ADVANCE_LP_RING();}static void i830EmitStippleVerified( drm_device_t *dev, unsigned int *code ) { drm_i830_private_t *dev_priv = dev->dev_private; RING_LOCALS; BEGIN_LP_RING( 2 ); OUT_RING( GFX_OP_STIPPLE ); OUT_RING( code[1] ); 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; DRM_DEBUG("%s %x\n", __FUNCTION__, 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); } /* 1.3: */#if 0 if (dirty & I830_UPLOAD_TEX_PALETTE_N(2)) { i830EmitTexPalette(dev, sarea_priv->Palette2[0], 0, 0); sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(2); } if (dirty & I830_UPLOAD_TEX_PALETTE_N(3)) { i830EmitTexPalette(dev, sarea_priv->Palette2[1], 1, 0); sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(2); }#endif } /* 1.3: */ if (dirty & I830_UPLOAD_STIPPLE) { i830EmitStippleVerified( dev, sarea_priv->StippleState); sarea_priv->dirty &= ~I830_UPLOAD_STIPPLE; } if (dirty & I830_UPLOAD_TEX2) { i830EmitTexVerified( dev, sarea_priv->TexState2 ); sarea_priv->dirty &= ~I830_UPLOAD_TEX2; } if (dirty & I830_UPLOAD_TEX3) { i830EmitTexVerified( dev, sarea_priv->TexState3 ); sarea_priv->dirty &= ~I830_UPLOAD_TEX3; } if (dirty & I830_UPLOAD_TEXBLEND2) { i830EmitTexBlendVerified( dev, sarea_priv->TexBlendState2, sarea_priv->TexBlendStateWordsUsed2); sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND2; } if (dirty & I830_UPLOAD_TEXBLEND3) { i830EmitTexBlendVerified( dev, sarea_priv->TexBlendState3, sarea_priv->TexBlendStateWordsUsed3); sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND3; }}/* ================================================================ * Performance monitoring functions */static void i830_fill_box( drm_device_t *dev, int x, int y, int w, int h, int r, int g, int b ){ drm_i830_private_t *dev_priv = dev->dev_private; u32 color; unsigned int BR13, CMD; RING_LOCALS; BR13 = (0xF0 << 16) | (dev_priv->pitch * dev_priv->cpp) | (1<<24); CMD = XY_COLOR_BLT_CMD; x += dev_priv->sarea_priv->boxes[0].x1; y += dev_priv->sarea_priv->boxes[0].y1; if (dev_priv->cpp == 4) { BR13 |= (1<<25); CMD |= (XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB); color = (((0xff) << 24) | (r << 16) | (g << 8) | b); } else { color = (((r & 0xf8) << 8) | ((g & 0xfc) << 3) | ((b & 0xf8) >> 3)); } BEGIN_LP_RING( 6 ); OUT_RING( CMD ); OUT_RING( BR13 ); OUT_RING( (y << 16) | x ); OUT_RING( ((y+h) << 16) | (x+w) ); if ( dev_priv->current_page == 1 ) { OUT_RING( dev_priv->front_offset ); } else { OUT_RING( dev_priv->back_offset ); } OUT_RING( color ); ADVANCE_LP_RING();}static void i830_cp_performance_boxes( drm_device_t *dev ){ drm_i830_private_t *dev_priv = dev->dev_private; /* Purple box for page flipping */ if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_FLIP ) i830_fill_box( dev, 4, 4, 8, 8, 255, 0, 255 ); /* Red box if we have to wait for idle at any point */ if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_WAIT ) i830_fill_box( dev, 16, 4, 8, 8, 255, 0, 0 ); /* Blue box: lost context? */ if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_LOST_CONTEXT ) i830_fill_box( dev, 28, 4, 8, 8, 0, 0, 255 ); /* Yellow box for texture swaps */ if ( dev_priv->sarea_priv->perf_boxes & I830_BOX_TEXTURE_LOAD ) i830_fill_box( dev, 40, 4, 8, 8, 255, 255, 0 ); /* Green box if hardware never idles (as far as we can tell) */ if ( !(dev_priv->sarea_priv->perf_boxes & I830_BOX_RING_EMPTY) ) i830_fill_box( dev, 64, 4, 8, 8, 0, 255, 0 ); /* Draw bars indicating number of buffers allocated * (not a great measure, easily confused) */ if (dev_priv->dma_used) { int bar = dev_priv->dma_used / 10240; if (bar > 100) bar = 100; if (bar < 1) bar = 1; i830_fill_box( dev, 4, 16, bar, 4, 196, 128, 128 ); dev_priv->dma_used = 0; } dev_priv->sarea_priv->perf_boxes = 0;}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; if ( dev_priv->current_page == 1 ) { unsigned int tmp = flags; flags &= ~(I830_FRONT | I830_BACK); if ( tmp & I830_FRONT ) flags |= I830_BACK; if ( tmp & I830_BACK ) flags |= I830_FRONT; } 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( dev_priv->front_offset ); 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 i; unsigned int CMD, BR13; RING_LOCALS; DRM_DEBUG("swapbuffers\n"); i830_kernel_lost_context(dev); if (dev_priv->do_boxes) i830_cp_performance_boxes( dev ); 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; } 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",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -