summaryrefslogtreecommitdiff
path: root/src/radeon_render.c
diff options
context:
space:
mode:
authorEric Anholt <anholt@freebsd.org>2004-08-04 10:05:37 +0000
committerEric Anholt <anholt@freebsd.org>2004-08-04 10:05:37 +0000
commit2efdc9f847fa9ff3096667b16df84817fc65605d (patch)
treed02a22e33c5c5aab37c3515791a20c44da1738be /src/radeon_render.c
parent1e16c66551eed750330bb74a92208c45a7112cd0 (diff)
- 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. (!)
Diffstat (limited to 'src/radeon_render.c')
-rw-r--r--src/radeon_render.c190
1 files changed, 118 insertions, 72 deletions
diff --git a/src/radeon_render.c b/src/radeon_render.c
index 73de861..7eb293d 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;