From 2efdc9f847fa9ff3096667b16df84817fc65605d Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Wed, 4 Aug 2004 10:05:37 +0000 Subject: - Add two new XAA hooks, SetupForCPUToScreenTexture2 and SetupForCPUToScreenAlphaTexture2. These add a dstFormat argument after the previous format argument, which the driver needs to use to properly set up the destination format. Two new arrays are added for the list of destination formats supported that correspond to the previous format arrays for sources. - Make Render acceleration only occur when the new hook for that acceleration type is supplied and the dst format list is set, along with the src format list being set. Without knowing the destination format, the Render acceleration couldn't properly support all the destinations it might encounter. - Bump XAA module minor version. - Update the Radeon Render acceleration to use the new hooks when the XAA module is sufficiently new. Fix a bug in the src/dst alpha booleans for ops, and use them to set blend_cntl to support destinations without alpha. Add missing PICT_a1r5g5b5 texture format, and add list terminator. (!) --- src/radeon_accelfuncs.c | 46 ++++++------ src/radeon_driver.c | 13 +++- src/radeon_render.c | 190 ++++++++++++++++++++++++++++++------------------ 3 files changed, 150 insertions(+), 99 deletions(-) diff --git a/src/radeon_accelfuncs.c b/src/radeon_accelfuncs.c index d9185a05..3d69b3f8 100644 --- a/src/radeon_accelfuncs.c +++ b/src/radeon_accelfuncs.c @@ -1348,60 +1348,60 @@ FUNC_NAME(RADEONAccelInit)(ScreenPtr pScreen, XAAInfoRecPtr a) | BIT_ORDER_IN_BYTE_LSBFIRST); #endif -#if defined(RENDER) && defined(XF86DRI) +#if defined(RENDER) +#if defined(XF86DRI) if (info->RenderAccel && info->directRenderingEnabled && - ((pScrn->bitsPerPixel == 32) || (pScrn->bitsPerPixel == 16))) { + info->xaaReq.minorversion >= 2) { /* XXX: The non-CP vertex dispatch doesn't seem to work. */ - /* XXX: We are actually violating Render semantics with this, but it - * can't be helped with current XAA. With Render you can make the - * Picture have whatever r/g/b/a masks you want, pretty much. - * We're forced to assume window pictures as destinations are of the - * common types of PICT_r5g6b5 for 16bpp and PICT_a8r8g8b8 for 32bpp, - * due to the lack of a dst format arg to the Setup functions. - * PICT_x8r8g8b8 is certainly almost as likely for 32bpp though, because - * XRenderFindStandardFormat(dpy, PictStandardRGB24) returns it. - */ a->CPUToScreenAlphaTextureFlags = XAA_RENDER_POWER_OF_2_TILE_ONLY; a->CPUToScreenAlphaTextureFormats = RADEONTextureFormats; + a->CPUToScreenAlphaTextureDstFormats = RADEONDstFormats; a->CPUToScreenTextureFlags = XAA_RENDER_POWER_OF_2_TILE_ONLY; a->CPUToScreenTextureFormats = RADEONTextureFormats; + a->CPUToScreenTextureDstFormats = RADEONDstFormats; if (IS_R300_VARIANT) { xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Render acceleration " - "unsupported on Radeon 9500/9700 and newer.\n"); - return; + "unsupported on Radeon 9500/9700 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)) { - a->SetupForCPUToScreenAlphaTexture = + a->SetupForCPUToScreenAlphaTexture2 = FUNC_NAME(R200SetupForCPUToScreenAlphaTexture); a->SubsequentCPUToScreenAlphaTexture = FUNC_NAME(R200SubsequentCPUToScreenTexture); - a->SetupForCPUToScreenTexture = + a->SetupForCPUToScreenTexture2 = FUNC_NAME(R200SetupForCPUToScreenTexture); a->SubsequentCPUToScreenTexture = FUNC_NAME(R200SubsequentCPUToScreenTexture); } else { - a->SetupForCPUToScreenAlphaTexture = + a->SetupForCPUToScreenAlphaTexture2 = FUNC_NAME(R100SetupForCPUToScreenAlphaTexture); a->SubsequentCPUToScreenAlphaTexture = FUNC_NAME(R100SubsequentCPUToScreenTexture); - a->SetupForCPUToScreenTexture = + a->SetupForCPUToScreenTexture2 = FUNC_NAME(R100SetupForCPUToScreenTexture); a->SubsequentCPUToScreenTexture = FUNC_NAME(R100SubsequentCPUToScreenTexture); } - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Render acceleration enabled\n"); - } else { - info->RenderAccel = FALSE; + } else +#endif /* XF86DRI */ + if (info->RenderAccel) + { + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Render acceleration currently " + "requires the DRI.\n"); } -#else /* RENDER && XF86DRI */ - info->RenderAccel = FALSE; -#endif /* RENDER && XF86DRI */ + + if (!a->SetupForCPUToScreenAlphaTexture2 && !a->SetupForCPUToScreenTexture2) + info->RenderAccel = FALSE; + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Render acceleration %s\n", + info->RenderAccel ? "enabled" : "disabled"); +#endif /* RENDER */ } #undef FUNC_NAME diff --git a/src/radeon_driver.c b/src/radeon_driver.c index f4fdae10..b5e62736 100644 --- a/src/radeon_driver.c +++ b/src/radeon_driver.c @@ -3834,16 +3834,21 @@ static Bool RADEONPreInitAccel(ScrnInfoPtr pScrn) int errmaj = 0, errmin = 0; info->xaaReq.majorversion = 1; - info->xaaReq.minorversion = 1; + info->xaaReq.minorversion = 2; if (!LoadSubModule(pScrn->module, "xaa", NULL, NULL, NULL, &info->xaaReq, &errmaj, &errmin)) { - info->xaaReq.minorversion = 0; + info->xaaReq.minorversion = 1; if (!LoadSubModule(pScrn->module, "xaa", NULL, NULL, NULL, &info->xaaReq, &errmaj, &errmin)) { - LoaderErrorMsg(NULL, "xaa", errmaj, errmin); - return FALSE; + info->xaaReq.minorversion = 0; + + if (!LoadSubModule(pScrn->module, "xaa", NULL, NULL, NULL, + &info->xaaReq, &errmaj, &errmin)) { + LoaderErrorMsg(NULL, "xaa", errmaj, errmin); + return FALSE; + } } } xf86LoaderReqSymLists(xaaSymbols, NULL); diff --git a/src/radeon_render.c b/src/radeon_render.c index 73de8611..7eb293de 100644 --- a/src/radeon_render.c +++ b/src/radeon_render.c @@ -62,7 +62,7 @@ static const struct blendinfo RadeonBlendOp[] = { {0, 0, RADEON_SRC_BLEND_GL_ONE | RADEON_DST_BLEND_GL_ONE}, /* Saturate */ - {0, 1, RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE | + {1, 1, RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE | RADEON_DST_BLEND_GL_ONE}, {0, 0, 0}, {0, 0, 0}, @@ -121,39 +121,89 @@ static CARD32 RADEONTextureFormats[] = { PICT_a8, PICT_x8r8g8b8, PICT_r5g6b5, + PICT_a1r5g5b5, PICT_x1r5g5b5, + 0 }; -static void RadeonGetTextureFormat(CARD32 format, CARD32 *txformat, int *bytepp) +static CARD32 RADEONDstFormats[] = { + PICT_a8r8g8b8, + PICT_x8r8g8b8, + PICT_r5g6b5, + PICT_a1r5g5b5, + PICT_x1r5g5b5, + 0 +}; + +static CARD32 +RadeonGetTextureFormat(CARD32 format) { switch (format) { case PICT_a8r8g8b8: - *txformat = RADEON_TXFORMAT_ARGB8888 | RADEON_TXFORMAT_ALPHA_IN_MAP; - *bytepp = 4; - break; + return RADEON_TXFORMAT_ARGB8888 | RADEON_TXFORMAT_ALPHA_IN_MAP; case PICT_a8: - *txformat = RADEON_TXFORMAT_I8 | RADEON_TXFORMAT_ALPHA_IN_MAP; - *bytepp = 1; - break; + return RADEON_TXFORMAT_I8 | RADEON_TXFORMAT_ALPHA_IN_MAP; + case PICT_x8r8g8b8: + return RADEON_TXFORMAT_ARGB8888; + case PICT_r5g6b5: + return RADEON_TXFORMAT_RGB565; + case PICT_a1r5g5b5: + return RADEON_TXFORMAT_ARGB1555 | RADEON_TXFORMAT_ALPHA_IN_MAP; + case PICT_x1r5g5b5: + return RADEON_TXFORMAT_ARGB1555; + default: + return 0; + } +} + +static CARD32 +RadeonGetColorFormat(CARD32 format) +{ + switch (format) { + case PICT_a8r8g8b8: case PICT_x8r8g8b8: - *txformat = RADEON_TXFORMAT_ARGB8888; - *bytepp = 4; - break; + return RADEON_COLOR_FORMAT_ARGB8888; case PICT_r5g6b5: - *txformat = RADEON_TXFORMAT_RGB565; - *bytepp = 2; - break; + return RADEON_COLOR_FORMAT_RGB565; case PICT_a1r5g5b5: - *txformat = RADEON_TXFORMAT_ARGB1555 | RADEON_TXFORMAT_ALPHA_IN_MAP; - *bytepp = 2; - break; case PICT_x1r5g5b5: - *txformat = RADEON_TXFORMAT_ARGB1555; - *bytepp = 2; - break; + return RADEON_COLOR_FORMAT_ARGB1555; + default: + return 0; } } +/* Returns a RADEON_RB3D_BLENDCNTL value, or 0 if the operation is not + * supported + */ +static CARD32 +RadeonGetBlendCntl(CARD8 op, CARD32 dstFormat) +{ + CARD32 blend_cntl; + + if (op >= RadeonOpMax || RadeonBlendOp[op].blend_cntl == 0) + return 0; + + blend_cntl = RadeonBlendOp[op].blend_cntl; + + if (RadeonBlendOp[op].dst_alpha && !PICT_FORMAT_A(dstFormat)) { + CARD32 srcblend = blend_cntl & RADEON_SRC_BLEND_MASK; + + /* If there's no destination alpha channel, we need to wire the blending + * to treat the alpha channel as always 1. + */ + if (srcblend == RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA || + srcblend == RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE) + blend_cntl = (blend_cntl & ~RADEON_SRC_BLEND_MASK) | + RADEON_SRC_BLEND_GL_ZERO; + else if (srcblend == RADEON_SRC_BLEND_GL_DST_ALPHA) + blend_cntl = (blend_cntl & ~RADEON_SRC_BLEND_MASK) | + RADEON_SRC_BLEND_GL_ONE; + } + + return blend_cntl; +} + static __inline__ CARD32 F_TO_DW(float val) { union { @@ -305,8 +355,9 @@ static void FUNC_NAME(RadeonInit3DEngine)(ScrnInfoPtr pScrn) FINISH_ACCEL(); } -static Bool FUNC_NAME(R100SetupTexture)(ScrnInfoPtr pScrn, - int format, +static Bool FUNC_NAME(R100SetupTexture)( + ScrnInfoPtr pScrn, + CARD32 format, CARD8 *src, int src_pitch, int width, @@ -322,7 +373,8 @@ static Bool FUNC_NAME(R100SetupTexture)(ScrnInfoPtr pScrn, if ((width > 2048) || (height > 2048)) return FALSE; - RadeonGetTextureFormat(format, &txformat, &tex_bytepp); + txformat = RadeonGetTextureFormat(format); + tex_bytepp = PICT_FORMAT_BPP(format) >> 3; dst_pitch = (width * tex_bytepp + 31) & ~31; size = dst_pitch * height; @@ -374,7 +426,8 @@ FUNC_NAME(R100SetupForCPUToScreenAlphaTexture) ( CARD16 green, CARD16 blue, CARD16 alpha, - int alphaFormat, + CARD32 maskFormat, + CARD32 dstFormat, CARD8 *alphaPtr, int alphaPitch, int width, @@ -383,26 +436,24 @@ FUNC_NAME(R100SetupForCPUToScreenAlphaTexture) ( ) { RADEONInfoPtr info = RADEONPTR(pScrn); - CARD32 format, srccolor; + CARD32 colorformat, srccolor, blend_cntl; ACCEL_PREAMBLE(); - if (op >= RadeonOpMax || RadeonBlendOp[op].blend_cntl == 0) + blend_cntl = RadeonGetBlendCntl(op, dstFormat); + if (blend_cntl == 0) return FALSE; - if (!FUNC_NAME(R100SetupTexture)(pScrn, alphaFormat, alphaPtr, alphaPitch, + if (!FUNC_NAME(R100SetupTexture)(pScrn, maskFormat, alphaPtr, alphaPitch, width, height, flags)) return FALSE; - if (pScrn->bitsPerPixel == 32) - format = RADEON_COLOR_FORMAT_ARGB8888; - else - format = RADEON_COLOR_FORMAT_RGB565; + colorformat = RadeonGetColorFormat(dstFormat); srccolor = ((alpha & 0xff00) << 16) | ((red & 0xff00) << 8) | (blue >> 8) | (green & 0xff00); BEGIN_ACCEL(8); - OUT_ACCEL_REG(RADEON_RB3D_CNTL, format | RADEON_ALPHA_BLEND_ENABLE); + OUT_ACCEL_REG(RADEON_RB3D_CNTL, colorformat | RADEON_ALPHA_BLEND_ENABLE); OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, pScrn->displayWidth); OUT_ACCEL_REG(RADEON_PP_CNTL, RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE); @@ -413,8 +464,7 @@ FUNC_NAME(R100SetupForCPUToScreenAlphaTexture) ( 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, - RadeonBlendOp[op].blend_cntl); + OUT_ACCEL_REG(RADEON_RB3D_BLENDCNTL, blend_cntl); FINISH_ACCEL(); return TRUE; @@ -425,7 +475,8 @@ static Bool FUNC_NAME(R100SetupForCPUToScreenTexture) ( ScrnInfoPtr pScrn, int op, - int texFormat, + CARD32 srcFormat, + CARD32 dstFormat, CARD8 *texPtr, int texPitch, int width, @@ -434,35 +485,32 @@ FUNC_NAME(R100SetupForCPUToScreenTexture) ( ) { RADEONInfoPtr info = RADEONPTR(pScrn); - CARD32 format; + CARD32 colorformat, blend_cntl; ACCEL_PREAMBLE(); - if (op >= RadeonOpMax || RadeonBlendOp[op].blend_cntl == 0) + blend_cntl = RadeonGetBlendCntl(op, dstFormat); + if (blend_cntl == 0) return FALSE; - if (!FUNC_NAME(R100SetupTexture)(pScrn, texFormat, texPtr, texPitch, width, + if (!FUNC_NAME(R100SetupTexture)(pScrn, srcFormat, texPtr, texPitch, width, height, flags)) return FALSE; - if (pScrn->bitsPerPixel == 32) - format = RADEON_COLOR_FORMAT_ARGB8888; - else - format = RADEON_COLOR_FORMAT_RGB565; + colorformat = RadeonGetColorFormat(dstFormat); BEGIN_ACCEL(7); - OUT_ACCEL_REG(RADEON_RB3D_CNTL, format | RADEON_ALPHA_BLEND_ENABLE); + OUT_ACCEL_REG(RADEON_RB3D_CNTL, colorformat | RADEON_ALPHA_BLEND_ENABLE); OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, pScrn->displayWidth); OUT_ACCEL_REG(RADEON_PP_CNTL, RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE); - if (texFormat != PICT_a8) + 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, - RadeonBlendOp[op].blend_cntl); + OUT_ACCEL_REG(RADEON_RB3D_BLENDCNTL, blend_cntl); FINISH_ACCEL(); return TRUE; @@ -578,8 +626,9 @@ FUNC_NAME(R100SubsequentCPUToScreenTexture) ( } -static Bool FUNC_NAME(R200SetupTexture)(ScrnInfoPtr pScrn, - int format, +static Bool FUNC_NAME(R200SetupTexture)( + ScrnInfoPtr pScrn, + CARD32 format, CARD8 *src, int src_pitch, int width, @@ -595,7 +644,8 @@ static Bool FUNC_NAME(R200SetupTexture)(ScrnInfoPtr pScrn, if ((width > 2048) || (height > 2048)) return FALSE; - RadeonGetTextureFormat(format, &txformat, &tex_bytepp); + txformat = RadeonGetTextureFormat(format); + tex_bytepp = PICT_FORMAT_BPP(format) >> 3; dst_pitch = (width * tex_bytepp + 31) & ~31; size = dst_pitch * height; @@ -648,7 +698,8 @@ FUNC_NAME(R200SetupForCPUToScreenAlphaTexture) ( CARD16 green, CARD16 blue, CARD16 alpha, - int alphaFormat, + CARD32 maskFormat, + CARD32 dstFormat, CARD8 *alphaPtr, int alphaPitch, int width, @@ -657,26 +708,24 @@ FUNC_NAME(R200SetupForCPUToScreenAlphaTexture) ( ) { RADEONInfoPtr info = RADEONPTR(pScrn); - CARD32 format, srccolor; + CARD32 colorformat, srccolor, blend_cntl; ACCEL_PREAMBLE(); - if (op >= RadeonOpMax || RadeonBlendOp[op].blend_cntl == 0) + blend_cntl = RadeonGetBlendCntl(op, dstFormat); + if (blend_cntl == 0) return FALSE; - if (!FUNC_NAME(R200SetupTexture)(pScrn, alphaFormat, alphaPtr, alphaPitch, + if (!FUNC_NAME(R200SetupTexture)(pScrn, maskFormat, alphaPtr, alphaPitch, width, height, flags)) return FALSE; - if (pScrn->bitsPerPixel == 32) - format = RADEON_COLOR_FORMAT_ARGB8888; - else - format = RADEON_COLOR_FORMAT_RGB565; + colorformat = RadeonGetColorFormat(dstFormat); srccolor = ((alpha & 0xff00) << 16) | ((red & 0xff00) << 8) | (blue >> 8) | (green & 0xff00); BEGIN_ACCEL(11); - OUT_ACCEL_REG(RADEON_RB3D_CNTL, format | RADEON_ALPHA_BLEND_ENABLE); + OUT_ACCEL_REG(RADEON_RB3D_CNTL, colorformat | RADEON_ALPHA_BLEND_ENABLE); OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, pScrn->displayWidth); OUT_ACCEL_REG(RADEON_PP_CNTL, RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE); @@ -689,8 +738,7 @@ FUNC_NAME(R200SetupForCPUToScreenAlphaTexture) ( 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, - RadeonBlendOp[op].blend_cntl); + OUT_ACCEL_REG(RADEON_RB3D_BLENDCNTL, blend_cntl); FINISH_ACCEL(); return TRUE; @@ -700,7 +748,8 @@ static Bool FUNC_NAME(R200SetupForCPUToScreenTexture) ( ScrnInfoPtr pScrn, int op, - int texFormat, + CARD32 srcFormat, + CARD32 dstFormat, CARD8 *texPtr, int texPitch, int width, @@ -709,27 +758,25 @@ FUNC_NAME(R200SetupForCPUToScreenTexture) ( ) { RADEONInfoPtr info = RADEONPTR(pScrn); - CARD32 format; + CARD32 colorformat, blend_cntl; ACCEL_PREAMBLE(); - if (op >= RadeonOpMax || RadeonBlendOp[op].blend_cntl == 0) + blend_cntl = RadeonGetBlendCntl(op, dstFormat); + if (blend_cntl == 0) return FALSE; - if (!FUNC_NAME(R200SetupTexture)(pScrn, texFormat, texPtr, texPitch, width, + if (!FUNC_NAME(R200SetupTexture)(pScrn, srcFormat, texPtr, texPitch, width, height, flags)) return FALSE; - if (pScrn->bitsPerPixel == 32) - format = RADEON_COLOR_FORMAT_ARGB8888; - else - format = RADEON_COLOR_FORMAT_RGB565; + colorformat = RadeonGetColorFormat(dstFormat); BEGIN_ACCEL(10); - OUT_ACCEL_REG(RADEON_RB3D_CNTL, format | RADEON_ALPHA_BLEND_ENABLE); + OUT_ACCEL_REG(RADEON_RB3D_CNTL, colorformat | RADEON_ALPHA_BLEND_ENABLE); OUT_ACCEL_REG(RADEON_RB3D_COLORPITCH, pScrn->displayWidth); OUT_ACCEL_REG(RADEON_PP_CNTL, RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE); - if (texFormat != PICT_a8) + 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); @@ -738,8 +785,7 @@ FUNC_NAME(R200SetupForCPUToScreenTexture) ( 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, - RadeonBlendOp[op].blend_cntl); + OUT_ACCEL_REG(RADEON_RB3D_BLENDCNTL, blend_cntl); FINISH_ACCEL(); return TRUE; -- cgit v1.2.3