📄 radeon_exa_funcs.c
字号:
#endif w *= bpp / 8; dst += (x * bpp / 8) + (y * dst_pitch); while (h--) { memcpy(dst, src, w); src += src_pitch; dst += dst_pitch; }#if X_BYTE_ORDER == X_BIG_ENDIAN /* restore byte swapping */ OUTREG(RADEON_SURFACE_CNTL, info->ModeReg.surface_cntl);#endif return TRUE;}#ifdef ACCEL_CP/* Emit blit with arbitrary source and destination offsets and pitches */static voidRADEONBlitChunk(ScrnInfoPtr pScrn, CARD32 datatype, CARD32 src_pitch_offset, CARD32 dst_pitch_offset, int srcX, int srcY, int dstX, int dstY, int w, int h){ RADEONInfoPtr info = RADEONPTR(pScrn); ACCEL_PREAMBLE(); BEGIN_ACCEL(6); OUT_ACCEL_REG(RADEON_DP_GUI_MASTER_CNTL, RADEON_GMC_DST_PITCH_OFFSET_CNTL | RADEON_GMC_SRC_PITCH_OFFSET_CNTL | RADEON_GMC_BRUSH_NONE | (datatype << 8) | RADEON_GMC_SRC_DATATYPE_COLOR | RADEON_ROP3_S | RADEON_DP_SRC_SOURCE_MEMORY | RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS); OUT_ACCEL_REG(RADEON_SRC_PITCH_OFFSET, src_pitch_offset); OUT_ACCEL_REG(RADEON_DST_PITCH_OFFSET, dst_pitch_offset); OUT_ACCEL_REG(RADEON_SRC_Y_X, (srcY << 16) | srcX); OUT_ACCEL_REG(RADEON_DST_Y_X, (dstY << 16) | dstX); OUT_ACCEL_REG(RADEON_DST_HEIGHT_WIDTH, (h << 16) | w); FINISH_ACCEL();}#endifstatic BoolFUNC_NAME(RADEONDownloadFromScreen)(PixmapPtr pSrc, int x, int y, int w, int h, char *dst, int dst_pitch){#if defined(ACCEL_CP) || X_BYTE_ORDER == X_BIG_ENDIAN RINFO_FROM_SCREEN(pSrc->drawable.pScreen);#endif#if X_BYTE_ORDER == X_BIG_ENDIAN unsigned char *RADEONMMIO = info->MMIO; unsigned int swapper = info->ModeReg.surface_cntl & ~(RADEON_NONSURF_AP0_SWP_32BPP | RADEON_NONSURF_AP1_SWP_32BPP | RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP1_SWP_16BPP);#endif CARD8 *src = pSrc->devPrivate.ptr; int src_pitch = exaGetPixmapPitch(pSrc); int bpp = pSrc->drawable.bitsPerPixel;#ifdef ACCEL_CP CARD32 datatype, src_pitch_offset, scratch_pitch = (w * bpp/8 + 63) & ~63, scratch_off = 0; drmBufPtr scratch;#endif TRACE;#ifdef ACCEL_CP /* * Try to accelerate download. Use an indirect buffer as scratch space, * blitting the bits to one half while copying them out of the other one and * then swapping the halves. */ if (info->accelDFS && bpp != 24 && RADEONGetDatatypeBpp(bpp, &datatype) && RADEONGetPixmapOffsetPitch(pSrc, &src_pitch_offset) && (scratch = RADEONCPGetBuffer(pScrn))) { int swap = RADEON_HOST_DATA_SWAP_NONE, wpass = w * bpp / 8; int hpass = min(h, scratch->total/2 / scratch_pitch); CARD32 scratch_pitch_offset = scratch_pitch << 16 | (info->gartLocation + info->bufStart + scratch->idx * scratch->total) >> 10; drmRadeonIndirect indirect; ACCEL_PREAMBLE(); RADEON_SWITCH_TO_2D(); /* Kick the first blit as early as possible */ RADEONBlitChunk(pScrn, datatype, src_pitch_offset, scratch_pitch_offset, x, y, 0, 0, w, hpass); FLUSH_RING();#if X_BYTE_ORDER == X_BIG_ENDIAN switch (bpp) { case 16: swap = RADEON_HOST_DATA_SWAP_16BIT; break; case 32: swap = RADEON_HOST_DATA_SWAP_32BIT; break; }#endif while (h) { int oldhpass = hpass, i = 0; src = (CARD8*)scratch->address + scratch_off; y += oldhpass; h -= oldhpass; hpass = min(h, scratch->total/2 / scratch_pitch); /* Prepare next blit if anything's left */ if (hpass) { scratch_off = scratch->total/2 - scratch_off; RADEONBlitChunk(pScrn, datatype, src_pitch_offset, scratch_pitch_offset + (scratch_off >> 10), x, y, 0, 0, w, hpass); } /* * Wait for previous blit to complete. * * XXX: Doing here essentially the same things this ioctl does in * the DRM results in corruption with 'small' transfers, apparently * because the data doesn't actually land in system RAM before the * memcpy. I suspect the ioctl helps mostly due to its latency; what * we'd really need is a way to reliably wait for the host interface * to be done with pushing the data to the host. */ while ((drmCommandNone(info->drmFD, DRM_RADEON_CP_IDLE) == -EBUSY) && (i++ < RADEON_TIMEOUT)) ; /* Kick next blit */ if (hpass) FLUSH_RING(); /* Copy out data from previous blit */ if (wpass == scratch_pitch && wpass == dst_pitch) { RADEONCopySwap((CARD8*)dst, src, wpass * oldhpass, swap); dst += dst_pitch * oldhpass; } else while (oldhpass--) { RADEONCopySwap((CARD8*)dst, src, wpass, swap); src += scratch_pitch; dst += dst_pitch; } } indirect.idx = scratch->idx; indirect.start = indirect.end = 0; indirect.discard = 1; drmCommandWriteRead(info->drmFD, DRM_RADEON_INDIRECT, &indirect, sizeof(drmRadeonIndirect)); return TRUE; }#endif /* Can't accelerate download */ exaWaitSync(pSrc->drawable.pScreen);#if X_BYTE_ORDER == X_BIG_ENDIAN switch(bpp) { case 15: case 16: swapper |= RADEON_NONSURF_AP0_SWP_16BPP | RADEON_NONSURF_AP1_SWP_16BPP; break; case 24: case 32: swapper |= RADEON_NONSURF_AP0_SWP_32BPP | RADEON_NONSURF_AP1_SWP_32BPP; break; } OUTREG(RADEON_SURFACE_CNTL, swapper);#endif src += (x * bpp / 8) + (y * src_pitch); w *= bpp / 8; while (h--) { memcpy(dst, src, w); src += src_pitch; dst += dst_pitch; }#if X_BYTE_ORDER == X_BIG_ENDIAN /* restore byte swapping */ OUTREG(RADEON_SURFACE_CNTL, info->ModeReg.surface_cntl);#endif return TRUE;}Bool FUNC_NAME(RADEONDrawInit)(ScreenPtr pScreen){ RINFO_FROM_SCREEN(pScreen); if (info->exa == NULL) { xf86DrvMsg(pScreen->myNum, X_ERROR, "Memory map not set up\n"); return FALSE; } info->exa->exa_major = 2; info->exa->exa_minor = 0; info->exa->PrepareSolid = FUNC_NAME(RADEONPrepareSolid); info->exa->Solid = FUNC_NAME(RADEONSolid); info->exa->DoneSolid = FUNC_NAME(RADEONDoneSolid); info->exa->PrepareCopy = FUNC_NAME(RADEONPrepareCopy); info->exa->Copy = FUNC_NAME(RADEONCopy); info->exa->DoneCopy = FUNC_NAME(RADEONDoneCopy); info->exa->WaitMarker = FUNC_NAME(RADEONSync); info->exa->UploadToScreen = FUNC_NAME(RADEONUploadToScreen); info->exa->DownloadFromScreen = FUNC_NAME(RADEONDownloadFromScreen);#if X_BYTE_ORDER == X_BIG_ENDIAN info->exa->PrepareAccess = RADEONPrepareAccess; info->exa->FinishAccess = RADEONFinishAccess;#endif /* X_BYTE_ORDER == X_BIG_ENDIAN */ info->exa->flags = EXA_OFFSCREEN_PIXMAPS; info->exa->pixmapOffsetAlign = RADEON_BUFFER_ALIGN + 1; info->exa->pixmapPitchAlign = 64; info->exa->maxX = 2047; info->exa->maxY = 2047;#ifdef RENDER if (info->RenderAccel) { if (info->ChipFamily >= CHIP_FAMILY_R300) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Render acceleration " "unsupported on R300 type cards and newer.\n"); } else if ((info->ChipFamily == CHIP_FAMILY_RV250) || (info->ChipFamily == CHIP_FAMILY_RV280) || (info->ChipFamily == CHIP_FAMILY_RS300) || (info->ChipFamily == CHIP_FAMILY_R200)) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Render acceleration " "enabled for R200 type cards.\n"); info->exa->CheckComposite = R200CheckComposite; info->exa->PrepareComposite = FUNC_NAME(R200PrepareComposite); info->exa->Composite = FUNC_NAME(RadeonComposite); info->exa->DoneComposite = RadeonDoneComposite; } else { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Render acceleration " "enabled for R100 type cards.\n"); info->exa->CheckComposite = R100CheckComposite; info->exa->PrepareComposite = FUNC_NAME(R100PrepareComposite); info->exa->Composite = FUNC_NAME(RadeonComposite); info->exa->DoneComposite = RadeonDoneComposite; } }#endif RADEONEngineInit(pScrn); if (!exaDriverInit(pScreen, info->exa)) { xfree(info->exa); return FALSE; } exaMarkSync(pScreen); return TRUE;}#undef FUNC_NAME
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -