i830_dri.c
来自「是由intel提供的针对intel显卡915以上系列的linux驱动」· C语言 代码 · 共 1,519 行 · 第 1/3 页
C
1,519 行
I830SelectBuffer(pScrn, I830_SELECT_BACK); I830SubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); pbox++; } /* Clear the depth buffer - uses 0xffff rather than 0. */ pbox = REGION_RECTS(prgn); nbox = REGION_NUM_RECTS(prgn); I830SelectBuffer(pScrn, I830_SELECT_DEPTH); switch (pScrn->bitsPerPixel) { case 16: I830SetupForSolidFill(pScrn, 0xffff, GXcopy, -1); break; case 32: I830SetupForSolidFill(pScrn, 0xffffff, GXcopy, -1); break; } while (nbox--) { I830SubsequentSolidFillRect(pScrn, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); pbox++; } I830SelectBuffer(pScrn, I830_SELECT_FRONT); pI830->AccelInfoRec->NeedToSync = TRUE;}/* This routine is a modified form of XAADoBitBlt with the calls to * ScreenToScreenBitBlt built in. My routine has the prgnSrc as source * instead of destination. My origin is upside down so the ydir cases * are reversed. */static voidI830DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, RegionPtr prgnSrc, CARD32 index){ ScreenPtr pScreen = pParent->drawable.pScreen; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); BoxPtr pboxTmp, pboxNext, pboxBase; DDXPointPtr pptTmp, pptNew2; int xdir, ydir;#if 0 int screenwidth = pScrn->virtualX; int screenheight = pScrn->virtualY;#else int screenwidth = pScreen->width; int screenheight = pScreen->height;#endif BoxPtr pbox = REGION_RECTS(prgnSrc); int nbox = REGION_NUM_RECTS(prgnSrc); BoxPtr pboxNew1 = 0; BoxPtr pboxNew2 = 0; DDXPointPtr pptNew1 = 0; DDXPointPtr pptSrc = &ptOldOrg; int dx = pParent->drawable.x - ptOldOrg.x; int dy = pParent->drawable.y - ptOldOrg.y; /* If the copy will overlap in Y, reverse the order */ if (dy > 0) { ydir = -1; if (nbox > 1) { /* Keep ordering in each band, reverse order of bands */ pboxNew1 = (BoxPtr) ALLOCATE_LOCAL(sizeof(BoxRec) * nbox); if (!pboxNew1) return; pptNew1 = (DDXPointPtr) ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox); if (!pptNew1) { DEALLOCATE_LOCAL(pboxNew1); return; } pboxBase = pboxNext = pbox + nbox - 1; while (pboxBase >= pbox) { while ((pboxNext >= pbox) && (pboxBase->y1 == pboxNext->y1)) pboxNext--; pboxTmp = pboxNext + 1; pptTmp = pptSrc + (pboxTmp - pbox); while (pboxTmp <= pboxBase) { *pboxNew1++ = *pboxTmp++; *pptNew1++ = *pptTmp++; } pboxBase = pboxNext; } pboxNew1 -= nbox; pbox = pboxNew1; pptNew1 -= nbox; pptSrc = pptNew1; } } else { /* No changes required */ ydir = 1; } /* If the regions will overlap in X, reverse the order */ if (dx > 0) { xdir = -1; if (nbox > 1) { /*reverse orderof rects in each band */ pboxNew2 = (BoxPtr) ALLOCATE_LOCAL(sizeof(BoxRec) * nbox); pptNew2 = (DDXPointPtr) ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox); if (!pboxNew2 || !pptNew2) { if (pptNew2) DEALLOCATE_LOCAL(pptNew2); if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2); if (pboxNew1) { DEALLOCATE_LOCAL(pptNew1); DEALLOCATE_LOCAL(pboxNew1); } return; } pboxBase = pboxNext = pbox; while (pboxBase < pbox + nbox) { while ((pboxNext < pbox + nbox) && (pboxNext->y1 == pboxBase->y1)) pboxNext++; pboxTmp = pboxNext; pptTmp = pptSrc + (pboxTmp - pbox); while (pboxTmp != pboxBase) { *pboxNew2++ = *--pboxTmp; *pptNew2++ = *--pptTmp; } pboxBase = pboxNext; } pboxNew2 -= nbox; pbox = pboxNew2; pptNew2 -= nbox; pptSrc = pptNew2; } } else { /* No changes are needed */ xdir = 1; } /* SelectBuffer isn't really a good concept for the i810. */ I830EmitFlush(pScrn); I830SetupForScreenToScreenCopy(pScrn, xdir, ydir, GXcopy, -1, -1); for (; nbox--; pbox++) { int x1 = pbox->x1; int y1 = pbox->y1; int destx = x1 + dx; int desty = y1 + dy; int w = pbox->x2 - x1 + 1; int h = pbox->y2 - y1 + 1; if (destx < 0) x1 -= destx, w += destx, destx = 0; if (desty < 0) y1 -= desty, h += desty, desty = 0; if (destx + w > screenwidth) w = screenwidth - destx; if (desty + h > screenheight) h = screenheight - desty; if (w <= 0) continue; if (h <= 0) continue; if (I810_DEBUG & DEBUG_VERBOSE_DRI) ErrorF("MoveBuffers %d,%d %dx%d dx: %d dy: %d\n", x1, y1, w, h, dx, dy); I830SelectBuffer(pScrn, I830_SELECT_BACK); I830SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h); I830SelectBuffer(pScrn, I830_SELECT_DEPTH); I830SubsequentScreenToScreenCopy(pScrn, x1, y1, destx, desty, w, h); } I830SelectBuffer(pScrn, I830_SELECT_FRONT); I830EmitFlush(pScrn); if (pboxNew2) { DEALLOCATE_LOCAL(pptNew2); DEALLOCATE_LOCAL(pboxNew2); } if (pboxNew1) { DEALLOCATE_LOCAL(pptNew1); DEALLOCATE_LOCAL(pboxNew1); } pI830->AccelInfoRec->NeedToSync = TRUE;}/* Initialize the first context */voidI830EmitInvarientState(ScrnInfoPtr pScrn){ I830Ptr pI830 = I830PTR(pScrn); CARD32 ctx_addr; ctx_addr = pI830->ContextMem.Start; /* Align to a 2k boundry */ ctx_addr = ((ctx_addr + 2048 - 1) / 2048) * 2048; { BEGIN_LP_RING(2); OUT_RING(MI_SET_CONTEXT); OUT_RING(ctx_addr | CTXT_NO_RESTORE | CTXT_PALETTE_SAVE_DISABLE | CTXT_PALETTE_RESTORE_DISABLE); ADVANCE_LP_RING(); }}/* Fullscreen hooks. The DRI fullscreen mode can probably be removed * as it adds little or nothing above the mechanism below. (and isn't * widely used) */static BoolI830DRIOpenFullScreen(ScreenPtr pScreen){ return TRUE;}static BoolI830DRICloseFullScreen(ScreenPtr pScreen){ return TRUE;}/* Use callbacks from dri.c to support pageflipping mode for a single * 3d context without need for any specific full-screen extension. * * Also see tdfx driver for example of using these callbacks to * allocate and free 3d-specific memory on demand. *//* Use the miext/shadow module to maintain a list of dirty rectangles. * These are blitted to the back buffer to keep both buffers clean * during page-flipping when the 3d application isn't fullscreen. * * Unlike most use of the shadow code, both buffers are in video * memory. * * An alternative to this would be to organize for all on-screen * drawing operations to be duplicated for the two buffers. That * might be faster, but seems like a lot more work... */#if 0/* This should be done *before* XAA syncs, * Otherwise will have to sync again??? */static voidI830DRIShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf){ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); RegionPtr damage = &pBuf->damage; int i, num = REGION_NUM_RECTS(damage); BoxPtr pbox = REGION_RECTS(damage); drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScreen); int cmd, br13; /* Don't want to do this when no 3d is active and pages are * right-way-round : */ if (!pSAREAPriv->pf_active && pSAREAPriv->pf_current_page == 0) return; br13 = (pScrn->displayWidth * pI830->cpp) | (0xcc << 16); if (pScrn->bitsPerPixel == 32) { cmd = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB); br13 |= 3 << 24; } else { cmd = (XY_SRC_COPY_BLT_CMD); br13 |= 1 << 24; } for (i = 0 ; i < num ; i++, pbox++) { 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(pI830->BackBuffer.Start); OUT_RING((pbox->y1 << 16) | pbox->x1); OUT_RING(br13 & 0xffff); OUT_RING(pI830->FrontBuffer.Start); ADVANCE_LP_RING(); }}#endifstatic voidI830EnablePageFlip(ScreenPtr pScreen){ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScreen); pSAREAPriv->pf_enabled = pI830->allowPageFlip; pSAREAPriv->pf_active = 0; if (pI830->allowPageFlip) { int br13 = (pScrn->displayWidth * pI830->cpp) | (0xcc << 16); BEGIN_LP_RING(8); if (pScrn->bitsPerPixel == 32) { OUT_RING(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB); br13 |= 3 << 24; } else { OUT_RING(XY_SRC_COPY_BLT_CMD); br13 |= 1 << 24; } OUT_RING(br13); OUT_RING(0); OUT_RING((pScrn->virtualY << 16) | pScrn->virtualX); OUT_RING(pI830->BackBuffer.Start); OUT_RING(0); OUT_RING(br13 & 0xffff); OUT_RING(pI830->FrontBuffer.Start); ADVANCE_LP_RING(); pSAREAPriv->pf_active = 1; }}static voidI830DisablePageFlip(ScreenPtr pScreen){ drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScreen); pSAREAPriv->pf_active = 0;}static voidI830DRITransitionSingleToMulti3d(ScreenPtr pScreen){ /* Tell the clients not to pageflip. How? * -- Field in sarea, plus bumping the window counters. * -- DRM needs to cope with Front-to-Back swapbuffers. */ I830DisablePageFlip(pScreen);}static voidI830DRITransitionMultiToSingle3d(ScreenPtr pScreen){ /* Let the remaining 3d app start page flipping again. */ I830EnablePageFlip(pScreen);}static voidI830DRITransitionTo3d(ScreenPtr pScreen){ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); I830EnablePageFlip(pScreen); pI830->have3DWindows = 1;}static voidI830DRITransitionTo2d(ScreenPtr pScreen){ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; I830Ptr pI830 = I830PTR(pScrn); drmI830Sarea *sPriv = (drmI830Sarea *) DRIGetSAREAPrivate(pScreen); /* Try flipping back to the front page if necessary */ if (sPriv->pf_current_page == 1) drmCommandNone(pI830->drmSubFD, DRM_I830_FLIP); /* Shut down shadowing if we've made it back to the front page: */ if (sPriv->pf_current_page == 0) { I830DisablePageFlip(pScreen); } pI830->have3DWindows = 0;}/** * Update the SAREA fields with the most recent values. * This gets called after the screen orientation/rotation changes. */BoolI830UpdateDRIBuffers(ScrnInfoPtr pScrn, drmI830Sarea *sarea){ I830Ptr pI830 = I830PTR(pScrn); ScreenPtr pScreen = pScrn->pScreen; Bool success; I830DRIUnmapScreenRegions(pScrn, sarea); if (pI830->rotation == RR_Rotate_0) { sarea->front_offset = pI830->FrontBuffer.Start; /* Don't use FrontBuffer.Size here as it includes the pixmap cache area * Instead, calculate the entire framebuffer. */ sarea->front_size = pI830->displayWidth * pScrn->virtualY * pI830->cpp; } else { /* Need to deal with rotated2 once we have dual head DRI */ sarea->front_offset = pI830->RotatedMem.Start; sarea->front_size = pI830->RotatedMem.Size; } xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[drm] init sarea width,height = %d x %d (pitch %d)\n", pScreen->width, pScreen->height,pScrn->displayWidth); sarea->width = pScreen->width; sarea->height = pScreen->height; sarea->back_offset = pI830->BackBuffer.Start; sarea->back_size = pI830->BackBuffer.Size; sarea->depth_offset = pI830->DepthBuffer.Start; sarea->depth_size = pI830->DepthBuffer.Size; sarea->tex_offset = pI830->TexMem.Start; sarea->tex_size = pI830->TexMem.Size; sarea->log_tex_granularity = pI830->TexGranularity; sarea->pitch = pScrn->displayWidth; sarea->virtualX = pScrn->virtualX; sarea->virtualY = pScrn->virtualY; switch (pI830->rotation) { case RR_Rotate_0: sarea->rotation = 0; break; case RR_Rotate_90: sarea->rotation = 90; break; case RR_Rotate_180: sarea->rotation = 180; break; case RR_Rotate_270: sarea->rotation = 270; break; default: sarea->rotation = 0; } if (pI830->rotation == RR_Rotate_0) { sarea->rotated_offset = -1; sarea->rotated_size = 0; } else { sarea->rotated_offset = pI830->FrontBuffer.Start; sarea->rotated_size = pI830->FrontBuffer.Size; } /* This is the original pitch */ sarea->rotated_pitch = pI830->displayWidth; success = I830DRIMapScreenRegions(pScrn, sarea); I830InitTextureHeap(pScrn, sarea); return success;}BoolI830DRILock(ScrnInfoPtr pScrn){ I830Ptr pI830 = I830PTR(pScrn); if (pI830->directRenderingEnabled && !pI830->LockHeld) { DRILock(screenInfo.screens[pScrn->scrnIndex], 0); pI830->LockHeld = 1; I830RefreshRing(pScrn); return TRUE; } else return FALSE;}voidI830DRIUnlock(ScrnInfoPtr pScrn){ I830Ptr pI830 = I830PTR(pScrn); if (pI830->directRenderingEnabled && pI830->LockHeld) { DRIUnlock(screenInfo.screens[pScrn->scrnIndex]); pI830->LockHeld = 0; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?