From 2bcb51d66edaa944379cf8c8ca1ba91fffdc20a8 Mon Sep 17 00:00:00 2001 From: Michel Daenzer Date: Sun, 22 Oct 2006 17:26:28 +0200 Subject: Bug #6756: Attempt to fix repeat picture acceleration. Always use normalized texture coordinates on R200 and fall back if a POT texture pitch doesn't match the HW's implicit pitch. --- src/radeon.h | 2 ++ src/radeon_commonfuncs.c | 5 +++-- src/radeon_exa_render.c | 52 ++++++++++++++++++++++++++++++++++++++---------- src/radeon_render.c | 31 +++++++++++++++++++---------- 4 files changed, 67 insertions(+), 23 deletions(-) diff --git a/src/radeon.h b/src/radeon.h index 7ff86f9..a7b0dfd 100644 --- a/src/radeon.h +++ b/src/radeon.h @@ -742,6 +742,8 @@ typedef struct { /* Render */ Bool RenderAccel; + unsigned short texW[2]; + unsigned short texH[2]; #ifdef USE_XAA FBLinearPtr RenderTex; void (*RenderCallback)(ScrnInfoPtr); diff --git a/src/radeon_commonfuncs.c b/src/radeon_commonfuncs.c index 84ce19c..70f7ddc 100644 --- a/src/radeon_commonfuncs.c +++ b/src/radeon_commonfuncs.c @@ -55,6 +55,8 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn) RADEONInfoPtr info = RADEONPTR(pScrn); ACCEL_PREAMBLE(); + info->texW[0] = info->texH[0] = info->texW[1] = info->texH[1] = 1; + if (info->ChipFamily >= CHIP_FAMILY_R300) { /* Unimplemented */ } else if ((info->ChipFamily == CHIP_FAMILY_RV250) || @@ -72,8 +74,7 @@ static void FUNC_NAME(RADEONInit3DEngine)(ScrnInfoPtr pScrn) OUT_ACCEL_REG(R200_PP_TXMULTI_CTL_0, 0); OUT_ACCEL_REG(R200_SE_VTX_STATE_CNTL, 0); OUT_ACCEL_REG(R200_RE_CNTL, 0x0); - /* XXX: correct? Want it to be like RADEON_VTX_ST?_NONPARAMETRIC */ - OUT_ACCEL_REG(R200_SE_VTE_CNTL, R200_VTX_ST_DENORMALIZED); + OUT_ACCEL_REG(R200_SE_VTE_CNTL, 0); OUT_ACCEL_REG(R200_SE_VAP_CNTL, R200_VAP_FORCE_W_TO_ONE | R200_VAP_VF_MAX_VTX_NUM); FINISH_ACCEL(); diff --git a/src/radeon_exa_render.c b/src/radeon_exa_render.c index 98b8dfd..d0a7216 100644 --- a/src/radeon_exa_render.c +++ b/src/radeon_exa_render.c @@ -246,12 +246,19 @@ static Bool FUNC_NAME(R100TextureSetup)(PicturePtr pPict, PixmapPtr pPix, txoffset |= RADEON_TXO_MACRO_TILE; if (pPict->repeat) { + if (((w * pPix->drawable.bitsPerPixel / 8 + 31) & ~31) != txpitch) + RADEON_FALLBACK(("Width %d and pitch %u not compatible for repeat\n", + w, (unsigned)txpitch)); + txformat |= RADEONLog2(w) << RADEON_TXFORMAT_WIDTH_SHIFT; txformat |= RADEONLog2(h) << RADEON_TXFORMAT_HEIGHT_SHIFT; - } else + } else txformat |= RADEON_TXFORMAT_NON_POWER2; txformat |= unit << 24; /* RADEON_TXFORMAT_ST_ROUTE_STQX */ - + + info->texW[unit] = 1; + info->texH[unit] = 1; + switch (pPict->filter) { case PictFilterNearest: txfilter = (RADEON_MAG_FILTER_NEAREST | RADEON_MIN_FILTER_NEAREST); @@ -499,12 +506,19 @@ static Bool FUNC_NAME(R200TextureSetup)(PicturePtr pPict, PixmapPtr pPix, txoffset |= R200_TXO_MACRO_TILE; if (pPict->repeat) { + if (((w * pPix->drawable.bitsPerPixel / 8 + 31) & ~31) != txpitch) + RADEON_FALLBACK(("Width %d and pitch %u not compatible for repeat\n", + w, (unsigned)txpitch)); + txformat |= RADEONLog2(w) << R200_TXFORMAT_WIDTH_SHIFT; txformat |= RADEONLog2(h) << R200_TXFORMAT_HEIGHT_SHIFT; } else txformat |= R200_TXFORMAT_NON_POWER2; txformat |= unit << R200_TXFORMAT_ST_ROUTE_SHIFT; + info->texW[unit] = w; + info->texH[unit] = h; + switch (pPict->filter) { case PictFilterNearest: txfilter = (R200_MAG_FILTER_NEAREST | @@ -791,11 +805,6 @@ static void FUNC_NAME(RadeonComposite)(PixmapPtr pDst, (4 << RADEON_CP_VC_CNTL_NUM_SHIFT)); } - VTX_OUT(dstX, dstY, srcX, srcY, maskX, maskY); - VTX_OUT(dstX, dstY + h, srcX, srcYend, maskX, maskYend); - VTX_OUT(dstX + w, dstY + h, srcXend, srcYend, maskXend, maskYend); - VTX_OUT(dstX + w, dstY, srcXend, srcY, maskXend, maskY); - ADVANCE_RING(); #else /* ACCEL_CP */ BEGIN_ACCEL(1 + VTX_REG_COUNT * 4); if (info->ChipFamily < CHIP_FAMILY_R200) { @@ -808,11 +817,32 @@ static void FUNC_NAME(RadeonComposite)(PixmapPtr pDst, RADEON_VF_PRIM_WALK_DATA | 4 << RADEON_VF_NUM_VERTICES_SHIFT)); } +#endif + + if (info->texW[0] == 1 && info->texH[0] == 1 && + info->texW[1] == 1 && info->texH[1] == 1) { + VTX_OUT(dstX, dstY, srcX, srcY, maskX, maskY); + VTX_OUT(dstX, dstY + h, srcX, srcYend, maskX, maskYend); + VTX_OUT(dstX + w, dstY + h, srcXend, srcYend, maskXend, maskYend); + VTX_OUT(dstX + w, dstY, srcXend, srcY, maskXend, maskY); + } else { + VTX_OUT((float)dstX, (float)dstY, + (float)srcX / info->texW[0], (float)srcY / info->texH[0], + (float)maskX / info->texW[1], (float)maskY / info->texH[1]); + VTX_OUT((float)dstX, (float)(dstY + h), + (float)srcX / info->texW[0], (float)srcYend / info->texH[0], + (float)maskX / info->texW[1], (float)maskYend / info->texH[1]); + VTX_OUT((float)(dstX + w), (float)(dstY + h), + (float)srcXend / info->texW[0], (float)srcYend / info->texH[0], + (float)maskXend / info->texW[1], (float)maskYend / info->texH[1]); + VTX_OUT((float)(dstX + w), (float)dstY, + (float)srcXend / info->texW[0], (float)srcY / info->texH[0], + (float)maskXend / info->texW[1], (float)maskY / info->texH[1]); + } - VTX_OUT(dstX, dstY, srcX, srcY, maskX, maskY); - VTX_OUT(dstX, dstY + h, srcX, srcYend, maskX, maskYend); - VTX_OUT(dstX + w, dstY + h, srcXend, srcYend, maskXend, maskYend); - VTX_OUT(dstX + w, dstY, srcXend, srcY, maskXend, maskY); +#ifdef ACCEL_CP + ADVANCE_RING(); +#else FINISH_ACCEL(); #endif /* !ACCEL_CP */ diff --git a/src/radeon_render.c b/src/radeon_render.c index 9e3529e..054e60f 100644 --- a/src/radeon_render.c +++ b/src/radeon_render.c @@ -398,6 +398,13 @@ static Bool FUNC_NAME(R100SetupTexture)( txformat = RadeonGetTextureFormat(format); tex_bytepp = PICT_FORMAT_BPP(format) >> 3; + dst_pitch = (width * tex_bytepp + 63) & ~63; + size = dst_pitch * height; + + if ((flags & XAA_RENDER_REPEAT) && + (((width * tex_bytepp + 31) & ~31) != dst_pitch)) + return FALSE; + #ifndef ACCEL_CP #if X_BYTE_ORDER == X_BIG_ENDIAN @@ -410,9 +417,6 @@ static Bool FUNC_NAME(R100SetupTexture)( #endif - dst_pitch = (width * tex_bytepp + 63) & ~63; - size = dst_pitch * height; - if (!AllocateLinear(pScrn, size)) return FALSE; @@ -731,6 +735,13 @@ static Bool FUNC_NAME(R200SetupTexture)( txformat = RadeonGetTextureFormat(format); tex_bytepp = PICT_FORMAT_BPP(format) >> 3; + dst_pitch = (width * tex_bytepp + 63) & ~63; + size = dst_pitch * height; + + if ((flags & XAA_RENDER_REPEAT) && + (((width * tex_bytepp + 31) & ~31) != dst_pitch)) + return FALSE; + #ifndef ACCEL_CP #if X_BYTE_ORDER == X_BIG_ENDIAN @@ -743,9 +754,6 @@ static Bool FUNC_NAME(R200SetupTexture)( #endif - dst_pitch = (width * tex_bytepp + 63) & ~63; - size = dst_pitch * height; - if (!AllocateLinear(pScrn, size)) return FALSE; @@ -757,6 +765,9 @@ static Bool FUNC_NAME(R200SetupTexture)( txformat |= RADEON_TXFORMAT_NON_POWER2; } + info->texW[0] = width; + info->texH[0] = height; + offset = info->RenderTex->offset * pScrn->bitsPerPixel / 8; dst = (CARD8*)(info->FB + offset); @@ -956,10 +967,10 @@ FUNC_NAME(R200SubsequentCPUToScreenTexture) ( r = width + l; b = height + t; - fl = srcx; - fr = srcx + width; - ft = srcy; - fb = srcy + height; + fl = (float)srcx / info->texW[0]; + fr = (float)(srcx + width) / info->texW[0]; + ft = (float)srcy / info->texH[0]; + fb = (float)(srcy + height) / info->texH[0]; #ifdef ACCEL_CP BEGIN_RING(24); -- cgit v1.2.3