📄 i830_dma.c
字号:
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", 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); if (dev_priv->current_page == 0) OUT_RING(dev_priv->front_offset); else OUT_RING(dev_priv->back_offset); OUT_RING((pbox->y1 << 16) | pbox->x1); OUT_RING(BR13 & 0xffff); if (dev_priv->current_page == 0) OUT_RING(dev_priv->back_offset); else OUT_RING(dev_priv->front_offset); ADVANCE_LP_RING(); }}static void i830_dma_dispatch_flip(drm_device_t * dev){ drm_i830_private_t *dev_priv = dev->dev_private; RING_LOCALS; DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n", __FUNCTION__, dev_priv->current_page, dev_priv->sarea_priv->pf_current_page); i830_kernel_lost_context(dev); if (dev_priv->do_boxes) { dev_priv->sarea_priv->perf_boxes |= I830_BOX_FLIP; i830_cp_performance_boxes(dev); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -