summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichel Daenzer <michel@tungstengraphics.com>2006-10-22 17:26:28 +0200
committerMichel Daenzer <michel@tungstengraphics.com>2006-10-22 17:26:28 +0200
commit2bcb51d66edaa944379cf8c8ca1ba91fffdc20a8 (patch)
treee06b070650f553e7343a6cec3c960d393b6f4b5d
parentdabffb8335027b60ca1fc554423e196dfb9acd6d (diff)
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.
-rw-r--r--src/radeon.h2
-rw-r--r--src/radeon_commonfuncs.c5
-rw-r--r--src/radeon_exa_render.c52
-rw-r--r--src/radeon_render.c31
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);