📄 radeon_render.c
字号:
OUT_ACCEL_REG(RADEON_PP_TFACTOR_0, srccolor); OUT_ACCEL_REG(RADEON_PP_TXCBLEND_0, RADEON_COLOR_ARG_A_TFACTOR_COLOR | RADEON_COLOR_ARG_B_T0_ALPHA); OUT_ACCEL_REG(RADEON_PP_TXABLEND_0, RADEON_ALPHA_ARG_A_TFACTOR_ALPHA | RADEON_ALPHA_ARG_B_T0_ALPHA); OUT_ACCEL_REG(RADEON_SE_VTX_FMT, RADEON_SE_VTX_FMT_XY | RADEON_SE_VTX_FMT_ST0); OUT_ACCEL_REG(RADEON_RB3D_BLENDCNTL, blend_cntl); FINISH_ACCEL(); return TRUE;}static BoolFUNC_NAME(R100SetupForCPUToScreenTexture) ( ScrnInfoPtr pScrn, int op, CARD32 srcFormat, CARD32 dstFormat, CARD8 *texPtr, int texPitch, int width, int height, int flags){ RADEONInfoPtr info = RADEONPTR(pScrn); CARD32 colorformat, blend_cntl; ACCEL_PREAMBLE(); blend_cntl = RadeonGetBlendCntl(op, dstFormat); if (blend_cntl == 0) return FALSE; if (!info->XInited3D) RADEONInit3DEngine(pScrn); if (!FUNC_NAME(R100SetupTexture)(pScrn, srcFormat, texPtr, texPitch, width, height, flags)) return FALSE; colorformat = RadeonGetColorFormat(dstFormat); BEGIN_ACCEL(6); OUT_ACCEL_REG(RADEON_RB3D_CNTL, colorformat | RADEON_ALPHA_BLEND_ENABLE); OUT_ACCEL_REG(RADEON_PP_CNTL, RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE); if (srcFormat != PICT_a8) OUT_ACCEL_REG(RADEON_PP_TXCBLEND_0, RADEON_COLOR_ARG_C_T0_COLOR); else OUT_ACCEL_REG(RADEON_PP_TXCBLEND_0, RADEON_COLOR_ARG_C_ZERO); OUT_ACCEL_REG(RADEON_PP_TXABLEND_0, RADEON_ALPHA_ARG_C_T0_ALPHA); OUT_ACCEL_REG(RADEON_SE_VTX_FMT, RADEON_SE_VTX_FMT_XY | RADEON_SE_VTX_FMT_ST0); OUT_ACCEL_REG(RADEON_RB3D_BLENDCNTL, blend_cntl); FINISH_ACCEL(); return TRUE;}static voidFUNC_NAME(R100SubsequentCPUToScreenTexture) ( ScrnInfoPtr pScrn, int dstx, int dsty, int srcx, int srcy, int width, int height){ RADEONInfoPtr info = RADEONPTR(pScrn); int byteshift; CARD32 fboffset; float l, t, r, b, fl, fr, ft, fb; ACCEL_PREAMBLE(); /* Note: we can't simply set up the 3D surface at the same location as the * front buffer, because the 2048x2048 limit on coordinates may be smaller * than the (MergedFB) screen. * Can't use arbitrary offsets for color tiling */ if (info->tilingEnabled) { /* can't play tricks with x coordinate, or could we - tiling is disabled anyway in that case */ fboffset = info->fbLocation + pScrn->fbOffset + (pScrn->displayWidth * (dsty & ~15) * (pScrn->bitsPerPixel >> 3)); l = dstx; t = (dsty % 16); } else { byteshift = (pScrn->bitsPerPixel >> 4); fboffset = (info->fbLocation + pScrn->fbOffset + ((pScrn->displayWidth * dsty + dstx) << byteshift)) & ~15; l = ((dstx << byteshift) % 16) >> byteshift; t = 0.0; } r = width + l; b = height + t; fl = srcx; fr = srcx + width; ft = srcy; fb = srcy + height;#ifdef ACCEL_CP BEGIN_RING(25); OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, pScrn->displayWidth | ((info->tilingEnabled && (dsty <= pScrn->virtualY)) ? RADEON_COLOR_TILE_ENABLE : 0)); OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, fboffset); OUT_RING(CP_PACKET3(RADEON_CP_PACKET3_3D_DRAW_IMMD, 17)); /* RADEON_SE_VTX_FMT */ OUT_RING(RADEON_CP_VC_FRMT_XY | RADEON_CP_VC_FRMT_ST0); /* SE_VF_CNTL */ OUT_RING(RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN | RADEON_CP_VC_CNTL_PRIM_WALK_RING | RADEON_CP_VC_CNTL_MAOS_ENABLE | RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE | (4 << RADEON_CP_VC_CNTL_NUM_SHIFT)); OUT_RING(F_TO_DW(l)); OUT_RING(F_TO_DW(t)); OUT_RING(F_TO_DW(fl)); OUT_RING(F_TO_DW(ft)); OUT_RING(F_TO_DW(r)); OUT_RING(F_TO_DW(t)); OUT_RING(F_TO_DW(fr)); OUT_RING(F_TO_DW(ft)); OUT_RING(F_TO_DW(r)); OUT_RING(F_TO_DW(b)); OUT_RING(F_TO_DW(fr)); OUT_RING(F_TO_DW(fb)); OUT_RING(F_TO_DW(l)); OUT_RING(F_TO_DW(b)); OUT_RING(F_TO_DW(fl)); OUT_RING(F_TO_DW(fb)); OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN); ADVANCE_RING();#else BEGIN_ACCEL(20); OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, pScrn->displayWidth | ((info->tilingEnabled && (dsty <= pScrn->virtualY)) ? RADEON_COLOR_TILE_ENABLE : 0)); OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, fboffset); OUT_ACCEL_REG(RADEON_SE_VF_CNTL, RADEON_VF_PRIM_TYPE_TRIANGLE_FAN | RADEON_VF_PRIM_WALK_DATA | RADEON_VF_RADEON_MODE | (4 << RADEON_VF_NUM_VERTICES_SHIFT)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(l)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(t)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(fl)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(ft)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(r)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(t)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(fr)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(ft)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(r)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(b)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(fr)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(fb)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(l)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(b)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(fl)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(fb)); OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN); FINISH_ACCEL();#endif}static Bool FUNC_NAME(R200SetupTexture)( ScrnInfoPtr pScrn, CARD32 format, CARD8 *src, int src_pitch, unsigned int width, unsigned int height, int flags){ RADEONInfoPtr info = RADEONPTR(pScrn); CARD8 *dst; CARD32 tex_size = 0, txformat; int dst_pitch, offset, size, tex_bytepp;#ifdef ACCEL_CP CARD32 buf_pitch, dst_pitch_off; int x, y; unsigned int hpass; CARD8 *tmp_dst;#endif ACCEL_PREAMBLE(); /* render repeat is broken - fix in stable tree by falling back */ if (flags & XAA_RENDER_REPEAT) return FALSE; if ((width > 2048) || (height > 2048)) return FALSE; txformat = RadeonGetTextureFormat(format); tex_bytepp = PICT_FORMAT_BPP(format) >> 3;#ifndef ACCEL_CP#if X_BYTE_ORDER == X_BIG_ENDIAN if (!RADEONSetupRenderByteswap(pScrn, tex_bytepp)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: RADEONSetupRenderByteswap() " "failed!\n", __func__); return FALSE; }#endif#endif dst_pitch = (width * tex_bytepp + 63) & ~63; size = dst_pitch * height; if (!AllocateLinear(pScrn, size)) return FALSE; if (flags & XAA_RENDER_REPEAT) { txformat |= ATILog2(width) << R200_TXFORMAT_WIDTH_SHIFT; txformat |= ATILog2(height) << R200_TXFORMAT_HEIGHT_SHIFT; } else { tex_size = ((height - 1) << 16) | (width - 1); txformat |= RADEON_TXFORMAT_NON_POWER2; } offset = info->RenderTex->offset * pScrn->bitsPerPixel / 8; dst = (CARD8*)(info->FB + offset); /* Upload texture to card. */#ifdef ACCEL_CP RADEONHostDataParams( pScrn, dst, dst_pitch, tex_bytepp, &dst_pitch_off, &x, &y ); while ( height ) { tmp_dst = RADEONHostDataBlit( pScrn, tex_bytepp, width, dst_pitch_off, &buf_pitch, x, &y, &height, &hpass ); RADEONHostDataBlitCopyPass( pScrn, tex_bytepp, tmp_dst, src, hpass, buf_pitch, src_pitch ); src += hpass * src_pitch; } RADEON_PURGE_CACHE(); RADEON_WAIT_UNTIL_IDLE();#else if (info->accel->NeedToSync) info->accel->Sync(pScrn); while (height--) { memcpy(dst, src, width * tex_bytepp); src += src_pitch; dst += dst_pitch; }#if X_BYTE_ORDER == X_BIG_ENDIAN RADEONRestoreByteswap(info);#endif#endif /* ACCEL_CP */ BEGIN_ACCEL(6); OUT_ACCEL_REG(R200_PP_TXFORMAT_0, txformat); OUT_ACCEL_REG(R200_PP_TXFORMAT_X_0, 0); OUT_ACCEL_REG(R200_PP_TXSIZE_0, tex_size); OUT_ACCEL_REG(R200_PP_TXPITCH_0, dst_pitch - 32); OUT_ACCEL_REG(R200_PP_TXOFFSET_0, offset + info->fbLocation + pScrn->fbOffset); OUT_ACCEL_REG(R200_PP_TXFILTER_0, R200_MAG_FILTER_NEAREST | R200_MIN_FILTER_NEAREST | R200_CLAMP_S_WRAP | R200_CLAMP_T_WRAP); FINISH_ACCEL(); return TRUE;}static BoolFUNC_NAME(R200SetupForCPUToScreenAlphaTexture) ( ScrnInfoPtr pScrn, int op, CARD16 red, CARD16 green, CARD16 blue, CARD16 alpha, CARD32 maskFormat, CARD32 dstFormat, CARD8 *alphaPtr, int alphaPitch, int width, int height, int flags) { RADEONInfoPtr info = RADEONPTR(pScrn); CARD32 colorformat, srccolor, blend_cntl; ACCEL_PREAMBLE(); blend_cntl = RadeonGetBlendCntl(op, dstFormat); if (blend_cntl == 0) return FALSE; if (!info->XInited3D) RADEONInit3DEngine(pScrn); if (!FUNC_NAME(R200SetupTexture)(pScrn, maskFormat, alphaPtr, alphaPitch, width, height, flags)) return FALSE; colorformat = RadeonGetColorFormat(dstFormat); srccolor = ((alpha & 0xff00) << 16) | ((red & 0xff00) << 8) | (blue >> 8) | (green & 0xff00); BEGIN_ACCEL(10); OUT_ACCEL_REG(RADEON_RB3D_CNTL, colorformat | RADEON_ALPHA_BLEND_ENABLE); OUT_ACCEL_REG(RADEON_PP_CNTL, RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE); OUT_ACCEL_REG(R200_PP_TFACTOR_0, srccolor); OUT_ACCEL_REG(R200_PP_TXCBLEND_0, R200_TXC_ARG_A_TFACTOR_COLOR | R200_TXC_ARG_B_R0_ALPHA); OUT_ACCEL_REG(R200_PP_TXCBLEND2_0, R200_TXC_OUTPUT_REG_R0); OUT_ACCEL_REG(R200_PP_TXABLEND_0, R200_TXA_ARG_A_TFACTOR_ALPHA | R200_TXA_ARG_B_R0_ALPHA); OUT_ACCEL_REG(R200_PP_TXABLEND2_0, R200_TXA_OUTPUT_REG_R0); OUT_ACCEL_REG(R200_SE_VTX_FMT_0, 0); OUT_ACCEL_REG(R200_SE_VTX_FMT_1, (2 << R200_VTX_TEX0_COMP_CNT_SHIFT)); OUT_ACCEL_REG(RADEON_RB3D_BLENDCNTL, blend_cntl); FINISH_ACCEL(); return TRUE;}static BoolFUNC_NAME(R200SetupForCPUToScreenTexture) ( ScrnInfoPtr pScrn, int op, CARD32 srcFormat, CARD32 dstFormat, CARD8 *texPtr, int texPitch, int width, int height, int flags){ RADEONInfoPtr info = RADEONPTR(pScrn); CARD32 colorformat, blend_cntl; ACCEL_PREAMBLE(); blend_cntl = RadeonGetBlendCntl(op, dstFormat); if (blend_cntl == 0) return FALSE; if (!info->XInited3D) RADEONInit3DEngine(pScrn); if (!FUNC_NAME(R200SetupTexture)(pScrn, srcFormat, texPtr, texPitch, width, height, flags)) return FALSE; colorformat = RadeonGetColorFormat(dstFormat); BEGIN_ACCEL(9); OUT_ACCEL_REG(RADEON_RB3D_CNTL, colorformat | RADEON_ALPHA_BLEND_ENABLE); OUT_ACCEL_REG(RADEON_PP_CNTL, RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE); if (srcFormat != PICT_a8) OUT_ACCEL_REG(R200_PP_TXCBLEND_0, R200_TXC_ARG_C_R0_COLOR); else OUT_ACCEL_REG(R200_PP_TXCBLEND_0, R200_TXC_ARG_C_ZERO); OUT_ACCEL_REG(R200_PP_TXCBLEND2_0, R200_TXC_OUTPUT_REG_R0); OUT_ACCEL_REG(R200_PP_TXABLEND_0, R200_TXA_ARG_C_R0_ALPHA); OUT_ACCEL_REG(R200_PP_TXABLEND2_0, R200_TXA_OUTPUT_REG_R0); OUT_ACCEL_REG(R200_SE_VTX_FMT_0, 0); OUT_ACCEL_REG(R200_SE_VTX_FMT_1, (2 << R200_VTX_TEX0_COMP_CNT_SHIFT)); OUT_ACCEL_REG(RADEON_RB3D_BLENDCNTL, blend_cntl); FINISH_ACCEL(); return TRUE;}static voidFUNC_NAME(R200SubsequentCPUToScreenTexture) ( ScrnInfoPtr pScrn, int dstx, int dsty, int srcx, int srcy, int width, int height){ RADEONInfoPtr info = RADEONPTR(pScrn); int byteshift; CARD32 fboffset; float l, t, r, b, fl, fr, ft, fb; ACCEL_PREAMBLE(); /* Note: we can't simply set up the 3D surface at the same location as the * front buffer, because the 2048x2048 limit on coordinates may be smaller * than the (MergedFB) screen. * Can't use arbitrary offsets for color tiling */ if (info->tilingEnabled) { /* can't play tricks with x coordinate, or could we - tiling is disabled anyway in that case */ fboffset = info->fbLocation + pScrn->fbOffset + (pScrn->displayWidth * (dsty & ~15) * (pScrn->bitsPerPixel >> 3)); l = dstx; t = (dsty % 16); } else { byteshift = (pScrn->bitsPerPixel >> 4); fboffset = (info->fbLocation + pScrn->fbOffset + ((pScrn->displayWidth * dsty + dstx) << byteshift)) & ~15; l = ((dstx << byteshift) % 16) >> byteshift; t = 0.0; } r = width + l; b = height + t; fl = srcx; fr = srcx + width; ft = srcy; fb = srcy + height;#ifdef ACCEL_CP BEGIN_RING(24); OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, pScrn->displayWidth | ((info->tilingEnabled && (dsty <= pScrn->virtualY)) ? RADEON_COLOR_TILE_ENABLE : 0)); OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, fboffset); OUT_RING(CP_PACKET3(R200_CP_PACKET3_3D_DRAW_IMMD_2, 16)); /* RADEON_SE_VF_CNTL */ OUT_RING(RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN | RADEON_CP_VC_CNTL_PRIM_WALK_RING | (4 << RADEON_CP_VC_CNTL_NUM_SHIFT)); OUT_RING(F_TO_DW(l)); OUT_RING(F_TO_DW(t)); OUT_RING(F_TO_DW(fl)); OUT_RING(F_TO_DW(ft)); OUT_RING(F_TO_DW(r)); OUT_RING(F_TO_DW(t)); OUT_RING(F_TO_DW(fr)); OUT_RING(F_TO_DW(ft)); OUT_RING(F_TO_DW(r)); OUT_RING(F_TO_DW(b)); OUT_RING(F_TO_DW(fr)); OUT_RING(F_TO_DW(fb)); OUT_RING(F_TO_DW(l)); OUT_RING(F_TO_DW(b)); OUT_RING(F_TO_DW(fl)); OUT_RING(F_TO_DW(fb)); OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN); ADVANCE_RING();#else BEGIN_ACCEL(20); /* Note: we can't simply setup 3D surface at the same location as the front buffer, some apps may draw offscreen pictures out of the limitation of radeon 3D surface. */ OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, pScrn->displayWidth | ((info->tilingEnabled && (dsty <= pScrn->virtualY)) ? RADEON_COLOR_TILE_ENABLE : 0)); OUT_ACCEL_REG(RADEON_RB3D_COLOROFFSET, fboffset); OUT_ACCEL_REG(RADEON_SE_VF_CNTL, (RADEON_VF_PRIM_TYPE_QUAD_LIST | RADEON_VF_PRIM_WALK_DATA | 4 << RADEON_VF_NUM_VERTICES_SHIFT)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(l)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(t)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(fl)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(ft)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(r)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(t)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(fr)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(ft)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(r)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(b)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(fr)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(fb)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(l)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(b)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(fl)); OUT_ACCEL_REG(RADEON_SE_PORT_DATA0, F_TO_DW(fb)); OUT_ACCEL_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN); FINISH_ACCEL();#endif}#undef FUNC_NAME#endif /* USE_XAA */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -