[PATCH] Merging Render code into r128_exa.c
Connor Behan
connor.behan at gmail.com
Mon Aug 22 02:13:28 UTC 2016
On 19/08/16 04:20 AM, Kevin Brace wrote:
> Signed-off-by: Kevin Brace <kevinbrace at gmx.com>
> ---
What's wrong with keeping the two separate files? FWIW, I got the idea
to do this from the mach64 driver.
> src/Makefile.am | 1 -
> src/r128_exa.c | 675 ++++++++++++++++++++++++++++++++++++++++++++++-
> src/r128_exa_render.c | 705 --------------------------------------------------
> 3 files changed, 674 insertions(+), 707 deletions(-)
> delete mode 100644 src/r128_exa_render.c
>
> diff --git a/src/Makefile.am b/src/Makefile.am
> index 05fbe6c..b60636b 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -54,5 +54,4 @@ EXTRA_DIST = \
> r128_reg.h \
> r128_sarea.h \
> r128_version.h \
> - r128_exa_render.c \
> atipcirename.h
> diff --git a/src/r128_exa.c b/src/r128_exa.c
> index 2a628a8..e29ec57 100644
> --- a/src/r128_exa.c
> +++ b/src/r128_exa.c
> @@ -1,6 +1,9 @@
> /*
> + * Copyright 2003 Eric Anholt
> + * Copyright 2003 Anders Carlsson
> * Copyright 2006 Joseph Garvin
> * Copyright 2012 Connor Behan
> + * Copyright 2012 Michel D�nzer
> * All Rights Reserved.
> *
> * Permission is hereby granted, free of charge, to any person obtaining a
> @@ -23,8 +26,11 @@
> * SOFTWARE.
> *
> * Authors:
> + * Anders Carlsson <andersca at gnome.org>
> + * Eric Anholt <anholt at FreeBSD.org>
> * Joseph Garvin <joseph.h.garvin at gmail.com>
> * Connor Behan <connor.behan at gmail.com>
> + * Michel D�nzer <michel.daenzer at amd.com>
> *
> */
>
> @@ -61,6 +67,42 @@ static struct {
> { R128_ROP3_ONE, R128_ROP3_ONE } /* GXset */
> };
>
> +#ifdef RENDER
> +static struct {
> + Bool dst_alpha;
> + Bool src_alpha;
> + uint32_t sblend;
> + uint32_t dblend;
> +} R128BlendOp[] = {
> + /* Clear */
> + {0, 0, R128_ALPHA_BLEND_ZERO , R128_ALPHA_BLEND_ZERO},
> + /* Src */
> + {0, 0, R128_ALPHA_BLEND_ONE , R128_ALPHA_BLEND_ZERO},
> + /* Dst */
> + {0, 0, R128_ALPHA_BLEND_ZERO , R128_ALPHA_BLEND_ONE},
> + /* Over */
> + {0, 1, R128_ALPHA_BLEND_ONE , R128_ALPHA_BLEND_INVSRCALPHA},
> + /* OverReverse */
> + {1, 0, R128_ALPHA_BLEND_INVDSTALPHA , R128_ALPHA_BLEND_ONE},
> + /* In */
> + {1, 0, R128_ALPHA_BLEND_DSTALPHA , R128_ALPHA_BLEND_ZERO},
> + /* InReverse */
> + {0, 1, R128_ALPHA_BLEND_ZERO , R128_ALPHA_BLEND_SRCALPHA},
> + /* Out */
> + {1, 0, R128_ALPHA_BLEND_INVDSTALPHA , R128_ALPHA_BLEND_ZERO},
> + /* OutReverse */
> + {0, 1, R128_ALPHA_BLEND_ZERO , R128_ALPHA_BLEND_INVSRCALPHA},
> + /* Atop */
> + {1, 1, R128_ALPHA_BLEND_DSTALPHA , R128_ALPHA_BLEND_INVSRCALPHA},
> + /* AtopReverse */
> + {1, 1, R128_ALPHA_BLEND_INVDSTALPHA , R128_ALPHA_BLEND_SRCALPHA},
> + /* Xor */
> + {1, 1, R128_ALPHA_BLEND_INVDSTALPHA , R128_ALPHA_BLEND_INVSRCALPHA},
> + /* Add */
> + {0, 0, R128_ALPHA_BLEND_ONE , R128_ALPHA_BLEND_ONE},
> +};
> +#endif
> +
> /* Assumes that depth 15 and 16 can be used as depth 16, which is okay since we
> * require src and dest datatypes to be equal.
> */
> @@ -405,7 +447,638 @@ R128CCESync(ScreenPtr pScreen, int marker)
> }
>
> #ifdef RENDER
> -#include "r128_exa_render.c"
> +static Bool
> +R128TransformAffineOrScaled(PictTransformPtr t)
> +{
> + if (t == NULL) return TRUE;
> +
> + /* the shaders don't handle scaling either */
> + return t->matrix[2][0] == 0 && t->matrix[2][1] == 0 && t->matrix[2][2] == IntToxFixed(1);
> +}
> +
> +static PixmapPtr
> +R128GetDrawablePixmap(DrawablePtr pDrawable)
> +{
> + if (pDrawable->type == DRAWABLE_WINDOW)
> + return pDrawable->pScreen->GetWindowPixmap((WindowPtr)pDrawable);
> + else
> + return (PixmapPtr)pDrawable;
> +}
> +
> +static PixmapPtr
> +R128SolidPixmap(ScreenPtr pScreen, uint32_t solid)
> +{
> + ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
> + R128InfoPtr info = R128PTR(pScrn);
> + PixmapPtr pPix = pScreen->CreatePixmap(pScreen, 1, 1, 32, 0);
> +
> + exaMoveInPixmap(pPix);
> + if (!exaDrawableIsOffscreen(&pPix->drawable)) {
> + pScreen->DestroyPixmap(pPix);
> + return NULL;
> + }
> + info->ExaDriver->WaitMarker(pScreen, 0);
> +
> +#if X_BYTE_ORDER == X_BIG_ENDIAN
> + if (pScrn->bitsPerPixel == 32)
> + R128CopySwap(info->ExaDriver->memoryBase + exaGetPixmapOffset(pPix), (uint8_t*)&solid, 4,
> + APER_0_BIG_ENDIAN_32BPP_SWAP);
> + else if (pScrn->bitsPerPixel == 16)
> + R128CopySwap(info->ExaDriver->memoryBase + exaGetPixmapOffset(pPix), (uint8_t*)&solid, 4,
> + APER_0_BIG_ENDIAN_16BPP_SWAP);
> + else
> + /* Fall through for 8 bpp */
> +#endif
> + memcpy(info->ExaDriver->memoryBase + exaGetPixmapOffset(pPix), &solid, 4);
> +
> + return pPix;
> +}
> +
> +static Bool
> +R128GetDatatypePict1(uint32_t format, uint32_t *type)
> +{
> + switch(format) {
> + case PICT_r5g6b5:
> + *type = R128_DATATYPE_RGB565;
> + return TRUE;
> + case PICT_x1r5g5b5:
> + *type = R128_DATATYPE_ARGB1555;
> + return TRUE;
> + case PICT_x8r8g8b8:
> + *type = R128_DATATYPE_ARGB8888;
> + return TRUE;
> + default:
> + return FALSE;
> + }
> +}
> +
> +static Bool
> +R128GetDatatypePict2(uint32_t format, uint32_t *type)
> +{
> + switch(format) {
> + case PICT_a8:
> + *type = R128_DATATYPE_RGB8;
> + return TRUE;
> + case PICT_r5g6b5:
> + *type = R128_DATATYPE_RGB565;
> + return TRUE;
> + case PICT_a8r8g8b8:
> + *type = R128_DATATYPE_ARGB8888;
> + return TRUE;
> + default:
> + return FALSE;
> + }
> +}
> +
> +static Bool
> +R128CheckCompositeTexture(PicturePtr pPict, PicturePtr pDstPict, int op)
> +{
> +#if R128_DEBUG
> + ScreenPtr pScreen = pDstPict->pDrawable->pScreen;
> + ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
> +#endif
> +
> + unsigned int repeatType = pPict->repeat ? pPict->repeatType : RepeatNone;
> + uint32_t tmp1;
> +
> + if (!R128GetDatatypePict2(pPict->format, &tmp1)) return FALSE;
> +
> + if (pPict->pDrawable) {
> + int w = pPict->pDrawable->width;
> + int h = pPict->pDrawable->height;
> +
> + if (pPict->repeat && ((w & (w - 1)) != 0 || (h & (h - 1)) != 0)) {
> + R128TRACE(("NPOT repeat unsupported (%dx%d)\n", w, h));
> + return FALSE;
> + }
> + }
> +
> + if (pPict->filter != PictFilterNearest && pPict->filter != PictFilterBilinear) {
> + R128TRACE(("Unsupported filter 0x%x\n", pPict->filter));
> + return FALSE;
> + }
> +
> + /* The radeon driver has a long explanation about this part that I don't really understand */
> + if (pPict->transform != 0 && repeatType == RepeatNone && PICT_FORMAT_A(pPict->format) == 0) {
> + if (!(((op == PictOpSrc) || (op == PictOpClear)) && (PICT_FORMAT_A(pDstPict->format) == 0))) {
> + R128TRACE(("REPEAT_NONE unsupported for transformed xRGB source\n"));
> + return FALSE;
> + }
> + }
> + if (!R128TransformAffineOrScaled(pPict->transform)) {
> + R128TRACE(("Non-affine transforms not supported\n"));
> + return FALSE;
> + }
> +
> + return TRUE;
> +}
> +
> +static Bool
> +R128CCECheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture)
> +{
> +#if R128_DEBUG
> + ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
> + ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
> +#endif
> +
> + PixmapPtr pSrcPixmap, pDstPixmap;
> + uint32_t tmp1;
> +
> + /* Check for unsupported compositing operations. */
> + if (op >= sizeof(R128BlendOp) / sizeof(R128BlendOp[0])) {
> + R128TRACE(("Unsupported Composite op 0x%x\n", op));
> + return FALSE;
> + }
> +
> + pDstPixmap = R128GetDrawablePixmap(pDstPicture->pDrawable);
> + if (pDstPixmap->drawable.width > 1024 || pDstPixmap->drawable.height > 1024) {
> + R128TRACE(("Dest w/h too large (%d,%d).\n", pDstPixmap->drawable.width, pDstPixmap->drawable.height));
> + return FALSE;
> + }
> +
> + if (pSrcPicture->pDrawable) {
> + pSrcPixmap = R128GetDrawablePixmap(pSrcPicture->pDrawable);
> + if (pSrcPixmap->drawable.width > 1024 || pSrcPixmap->drawable.height > 1024) {
> + R128TRACE(("Source w/h too large (%d,%d).\n", pSrcPixmap->drawable.width, pSrcPixmap->drawable.height));
> + return FALSE;
> + }
> + } else if (pSrcPicture->pSourcePict->type != SourcePictTypeSolidFill) {
> + R128TRACE(("Gradient pictures not supported yet\n"));
> + return FALSE;
> + }
> +
> + if (pDstPicture->format == PICT_a8) {
> + if (R128BlendOp[op].src_alpha || R128BlendOp[op].dst_alpha || pMaskPicture != NULL) {
> + R128TRACE(("Alpha blending unsupported with A8 dst?\n"));
> + return FALSE;
> + }
> + } else {
> + if (!R128GetDatatypePict1(pDstPicture->format, &tmp1)) return FALSE;
> + }
> +
> + if (pMaskPicture) {
> + PixmapPtr pMaskPixmap;
> +
> + if (pMaskPicture->pDrawable) {
> + pMaskPixmap = R128GetDrawablePixmap(pMaskPicture->pDrawable);
> + if (pMaskPixmap->drawable.width > 1024 || pMaskPixmap->drawable.height > 1024) {
> + R128TRACE(("Mask w/h too large (%d,%d).\n", pMaskPixmap->drawable.width, pMaskPixmap->drawable.height));
> + return FALSE;
> + }
> + } else if (pMaskPicture->pSourcePict->type != SourcePictTypeSolidFill) {
> + R128TRACE(("Gradient pictures not supported yet\n"));
> + return FALSE;
> + }
> +
> + if (pMaskPicture->componentAlpha && R128BlendOp[op].src_alpha) {
> + R128TRACE(("Component alpha not supported with source alpha blending\n"));
> + return FALSE;
> + }
> +
> + if (!R128CheckCompositeTexture(pMaskPicture, pDstPicture, op)) return FALSE;
> + }
> +
> + if (!R128CheckCompositeTexture(pSrcPicture, pDstPicture, op)) return FALSE;
> + return TRUE;
> +}
> +
> +static Bool
> +R128TextureSetup(PicturePtr pPict, PixmapPtr pPix, int unit, uint32_t *txsize, uint32_t *tex_cntl_c, Bool trying_solid)
> +{
> + ScreenPtr pScreen = pPix->drawable.pScreen;
> + ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
> + R128InfoPtr info = R128PTR(pScrn);
> +
> + int w, h, bytepp, shift, l2w, l2h, l2p, pitch;
> +
> + if (pPict->pDrawable) {
> + w = pPict->pDrawable->width;
> + h = pPict->pDrawable->height;
> + } else {
> + w = h = 1;
> + }
> +
> + pitch = exaGetPixmapPitch(pPix);
> + if ((pitch & (pitch - 1)) != 0) {
> + R128TRACE(("NPOT pitch 0x%x unsupported\n", pitch));
> + return FALSE;
> + }
> +
> + if (!R128GetDatatypePict2(pPict->format, tex_cntl_c)) return FALSE;
> +
> + bytepp = PICT_FORMAT_BPP(pPict->format) / 8;
> + *tex_cntl_c |= R128_MIP_MAP_DISABLE;
> +
> + if (pPict->filter == PictFilterBilinear) {
> + *tex_cntl_c |= R128_MIN_BLEND_LINEAR | R128_MAG_BLEND_LINEAR;
> + } else if (pPict->filter == PictFilterNearest) {
> + *tex_cntl_c |= R128_MIN_BLEND_NEAREST | R128_MAG_BLEND_NEAREST;
> + } else {
> + R128TRACE(("Bad filter 0x%x\n", pPict->filter));
> + return FALSE;
> + }
> +
> + if (unit == 0) {
> + shift = 0;
> + } else {
> + shift = 16;
> + *tex_cntl_c |= R128_SEC_SELECT_SEC_ST;
> + }
> +
> + l2w = R128MinBits(w) - 1;
> + l2h = R128MinBits(h) - 1;
> + l2p = R128MinBits(pitch / bytepp) - 1;
> +
> + if (pPict->repeat && w == 1 && h == 1) {
> + l2p = 0;
> + } else if (pPict->repeat && l2p != l2w) {
> + R128TRACE(("Repeat not supported for pitch != width\n"));
> + return FALSE;
> + }
> +
> + l2w = l2p;
> + /* This is required to handle NPOT height */
> + if ((unit == 1) || (unit == 0 && !pPict->repeat && !trying_solid)) l2h++;
> +
> + info->state_2d.widths[unit] = 1 << l2w;
> + info->state_2d.heights[unit] = 1 << l2h;
> + *txsize |= l2p << (R128_TEX_PITCH_SHIFT + shift);
> + *txsize |= ((w > h) ? l2w : l2h) << (R128_TEX_SIZE_SHIFT + shift);
> + *txsize |= l2h << (R128_TEX_HEIGHT_SHIFT + shift);
> +
> + if (pPict->transform != 0) {
> + info->state_2d.is_transform[unit] = TRUE;
> + info->state_2d.transform[unit] = pPict->transform;
> + } else {
> + info->state_2d.is_transform[unit] = FALSE;
> + }
> +
> + return TRUE;
> +}
> +
> +/* The composite preparation commands that are the same every time can
> + * just be written once.
> + */
> +#define COMPOSITE_SETUP() \
> +do { \
> + BEGIN_RING( 10 ); \
> + \
> + OUT_RING_REG(R128_SCALE_3D_CNTL, \
> + R128_SCALE_3D_TEXMAP_SHADE | \
> + R128_SCALE_PIX_REPLICATE | \
> + R128_TEX_CACHE_SPLIT | \
> + R128_TEX_MAP_ALPHA_IN_TEXTURE | \
> + R128_TEX_CACHE_LINE_SIZE_4QW); \
> + OUT_RING_REG(R128_SETUP_CNTL, \
> + R128_COLOR_GOURAUD | \
> + R128_PRIM_TYPE_TRI | \
> + R128_TEXTURE_ST_MULT_W | \
> + R128_STARTING_VERTEX_1 | \
> + R128_ENDING_VERTEX_3 | \
> + R128_SUB_PIX_4BITS); \
> + OUT_RING_REG(R128_PM4_VC_FPU_SETUP, \
> + R128_FRONT_DIR_CCW | \
> + R128_BACKFACE_SOLID | \
> + R128_FRONTFACE_SOLID | \
> + R128_FPU_COLOR_GOURAUD | \
> + R128_FPU_SUB_PIX_4BITS | \
> + R128_FPU_MODE_3D | \
> + R128_TRAP_BITS_DISABLE | \
> + R128_XFACTOR_2 | \
> + R128_YFACTOR_2 | \
> + R128_FLAT_SHADE_VERTEX_OGL | \
> + R128_FPU_ROUND_TRUNCATE | \
> + R128_WM_SEL_8DW); \
> + OUT_RING_REG(R128_PLANE_3D_MASK_C, 0xffffffff); \
> + OUT_RING_REG(R128_CONSTANT_COLOR_C, 0xff000000); \
> + \
> + ADVANCE_RING(); \
> +} while(0)
> +
> +static Bool
> +R128CCEPrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
> + PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
> +{
> + ScreenPtr pScreen = pDst->drawable.pScreen;
> + ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
> + R128InfoPtr info = R128PTR(pScrn);
> + unsigned char *R128MMIO = info->MMIO;
> + RING_LOCALS;
> +
> + Bool add_src = FALSE;
> + Bool add_msk = FALSE;
> + uint32_t txsize = 0, prim_tex_cntl_c, sec_tex_cntl_c = 0, dstDatatype;
> + uint32_t src_pitch_offset, dst_pitch_offset, color_factor, in_color_factor, alpha_comb;
> + uint32_t sblend, dblend, blend_cntl, window_offset;
> + int i;
> +
> + if (pDstPicture->format == PICT_a8) {
> + if (R128BlendOp[op].dst_alpha) {
> + R128TRACE(("Can't dst alpha blend A8\n"));
> + return FALSE;
> + }
> + dstDatatype = R128_DATATYPE_Y8;
> + } else {
> + if (!R128GetDatatypePict1(pDstPicture->format, &dstDatatype)) return FALSE;
> + }
> +
> + if (!pSrc) {
> + pSrc = R128SolidPixmap(pScreen, cpu_to_le32(pSrcPicture->pSourcePict->solidFill.color));
> + if (!pSrc) {
> + R128TRACE(("Failed to create solid scratch pixmap\n"));
> + return FALSE;
> + }
> + add_src = TRUE;
> + }
> + if (pMaskPicture) {
> + info->state_2d.has_mask = TRUE;
> + if (!pMask) {
> + pMask = R128SolidPixmap(pScreen, cpu_to_le32(pMaskPicture->pSourcePict->solidFill.color));
> + if (!pMask) {
> + if (!pSrcPicture->pDrawable)
> + pScreen->DestroyPixmap(pSrc);
> + info->state_2d.has_mask = FALSE;
> + R128TRACE(("Failed to create solid scratch pixmap\n"));
> + return FALSE;
> + }
> + add_msk = TRUE;
> + }
> + } else {
> + info->state_2d.has_mask = FALSE;
> + }
> +
> + if (!R128TextureSetup(pSrcPicture, pSrc, 0, &txsize, &prim_tex_cntl_c, (add_src || add_msk))) return FALSE;
> +
> + if (pMask != NULL) {
> + info->state_2d.has_mask = TRUE;
> + if (!R128TextureSetup(pMaskPicture, pMask, 1, &txsize, &sec_tex_cntl_c, (add_src || add_msk))) return FALSE;
> + } else {
> + info->state_2d.has_mask = FALSE;
> + info->state_2d.is_transform[1] = FALSE;
> + }
> +
> + if (!R128GetPixmapOffsetPitch(pDst, &dst_pitch_offset)) return FALSE;
> + if (!R128GetPixmapOffsetPitch(pSrc, &src_pitch_offset)) return FALSE;
> +
> + info->state_2d.in_use = TRUE;
> + if (add_src) info->state_2d.src_pix = pSrc;
> + if (add_msk) info->state_2d.msk_pix = pMask;
> + sblend = R128BlendOp[op].sblend;
> + dblend = R128BlendOp[op].dblend;
> + if (PICT_FORMAT_A(pDstPicture->format) == 0 && R128BlendOp[op].dst_alpha) {
> + if (sblend == R128_ALPHA_BLEND_DSTALPHA)
> + sblend = R128_ALPHA_BLEND_ONE;
> + else if (sblend == R128_ALPHA_BLEND_INVDSTALPHA)
> + sblend = R128_ALPHA_BLEND_ZERO;
> + }
> + blend_cntl = (sblend << R128_ALPHA_BLEND_SRC_SHIFT) |
> + (dblend << R128_ALPHA_BLEND_DST_SHIFT);
> +
> + R128CCE_REFRESH( pScrn, info );
> +
> + if (!info->state_2d.composite_setup) {
> + COMPOSITE_SETUP();
> + info->state_2d.composite_setup = TRUE;
> + }
> +
> + /* We cannot guarantee that this register will stay zero - DRI needs it too. */
> + if (info->have3DWindows)
> + info->ExaDriver->WaitMarker(pScreen, 0);
> + window_offset = INREG(R128_WINDOW_XY_OFFSET);
> + info->state_2d.x_offset = (window_offset & 0xfff00000) >> R128_WINDOW_X_SHIFT;
> + info->state_2d.y_offset = (window_offset & 0x000fffff) >> R128_WINDOW_Y_SHIFT;
> +
> + info->state_2d.dp_gui_master_cntl = (R128_GMC_DST_PITCH_OFFSET_CNTL |
> + R128_GMC_BRUSH_SOLID_COLOR |
> + (dstDatatype >> 8) |
> + R128_GMC_SRC_DATATYPE_COLOR |
> + R128_ROP[3].rop |
> + R128_DP_SRC_SOURCE_MEMORY |
> + R128_GMC_3D_FCN_EN |
> + R128_GMC_CLR_CMP_CNTL_DIS |
> + R128_GMC_AUX_CLIP_DIS |
> + R128_GMC_WR_MSK_DIS);
> + info->state_2d.dp_cntl = (R128_DST_X_LEFT_TO_RIGHT | R128_DST_Y_TOP_TO_BOTTOM);
> + info->state_2d.dp_brush_frgd_clr = 0xffffffff;
> + info->state_2d.dp_brush_bkgd_clr = 0x00000000;
> + info->state_2d.dp_src_frgd_clr = 0xffffffff;
> + info->state_2d.dp_src_bkgd_clr = 0x00000000;
> + info->state_2d.dp_write_mask = 0xffffffff;
> + info->state_2d.dst_pitch_offset = dst_pitch_offset;
> + info->state_2d.src_pitch_offset = src_pitch_offset;
> + info->state_2d.default_sc_bottom_right = (R128_DEFAULT_SC_RIGHT_MAX | R128_DEFAULT_SC_BOTTOM_MAX);
> + EmitCCE2DState(pScrn);
> +
> + BEGIN_RING( 6 );
> + OUT_RING_REG(R128_MISC_3D_STATE_CNTL_REG,
> + R128_MISC_SCALE_3D_TEXMAP_SHADE |
> + R128_MISC_SCALE_PIX_REPLICATE |
> + R128_ALPHA_COMB_ADD_CLAMP |
> + blend_cntl);
> + OUT_RING_REG(R128_TEX_CNTL_C,
> + R128_TEXMAP_ENABLE |
> + ((pMask != NULL) ? R128_SEC_TEXMAP_ENABLE : 0) |
> + R128_ALPHA_ENABLE |
> + R128_TEX_CACHE_FLUSH);
> + OUT_RING_REG(R128_PC_GUI_CTLSTAT, R128_PC_FLUSH_GUI);
> + ADVANCE_RING();
> +
> + /* IN operator: Without a mask, only the first texture unit is enabled.
> + * With a mask, we put the source in the first unit and have it pass
> + * through as input to the 2nd. The 2nd unit takes the incoming source
> + * pixel and modulates it with either the alpha or each of the channels
> + * in the mask, depending on componentAlpha.
> + */
> + BEGIN_RING( 15 );
> + /* R128_PRIM_TEX_CNTL_C,
> + * R128_PRIM_TEXTURE_COMBINE_CNTL_C,
> + * R128_TEX_SIZE_PITCH_C,
> + * R128_PRIM_TEX_0_OFFSET_C - R128_PRIM_TEX_10_OFFSET_C
> + */
> + OUT_RING(CCE_PACKET0(R128_PRIM_TEX_CNTL_C, 13));
> + OUT_RING(prim_tex_cntl_c);
> +
> + /* If this is the only stage and the dest is a8, route the alpha result
> + * to the color (red channel, in particular), too. Otherwise, be sure
> + * to zero out color channels of an a8 source.
> + */
> + if (pMaskPicture == NULL && pDstPicture->format == PICT_a8)
> + color_factor = R128_COLOR_FACTOR_ALPHA;
> + else if (pSrcPicture->format == PICT_a8)
> + color_factor = R128_COLOR_FACTOR_CONST_COLOR;
> + else
> + color_factor = R128_COLOR_FACTOR_TEX;
> +
> + if (PICT_FORMAT_A(pSrcPicture->format) == 0)
> + alpha_comb = R128_COMB_ALPHA_COPY_INP;
> + else
> + alpha_comb = R128_COMB_ALPHA_DIS;
> +
> + OUT_RING(R128_COMB_COPY |
> + color_factor |
> + R128_INPUT_FACTOR_INT_COLOR |
> + alpha_comb |
> + R128_ALPHA_FACTOR_TEX_ALPHA |
> + R128_INP_FACTOR_A_CONST_ALPHA);
> + OUT_RING(txsize);
> + /* We could save some output by only writing the offset register that
> + * will actually be used. On the other hand, this is easy.
> + */
> + for (i = 0; i <= 10; i++)
> + OUT_RING(exaGetPixmapOffset(pSrc));
> + ADVANCE_RING();
> +
> + if (pMask != NULL) {
> + BEGIN_RING( 14 );
> + /* R128_SEC_TEX_CNTL_C,
> + * R128_SEC_TEXTURE_COMBINE_CNTL_C,
> + * R128_SEC_TEX_0_OFFSET_C - R128_SEC_TEX_10_OFFSET_C
> + */
> + OUT_RING(CCE_PACKET0(R128_SEC_TEX_CNTL_C, 12));
> + OUT_RING(sec_tex_cntl_c);
> +
> + if (pDstPicture->format == PICT_a8) {
> + color_factor = R128_COLOR_FACTOR_ALPHA;
> + in_color_factor = R128_INPUT_FACTOR_PREV_ALPHA;
> + } else if (pMaskPicture->componentAlpha) {
> + color_factor = R128_COLOR_FACTOR_TEX;
> + in_color_factor = R128_INPUT_FACTOR_PREV_COLOR;
> + } else {
> + color_factor = R128_COLOR_FACTOR_ALPHA;
> + in_color_factor = R128_INPUT_FACTOR_PREV_COLOR;
> + }
> +
> + OUT_RING(R128_COMB_MODULATE |
> + color_factor |
> + in_color_factor |
> + R128_COMB_ALPHA_MODULATE |
> + R128_ALPHA_FACTOR_TEX_ALPHA |
> + R128_INP_FACTOR_A_PREV_ALPHA);
> + for (i = 0; i <= 10; i++)
> + OUT_RING(exaGetPixmapOffset(pMask));
> + ADVANCE_RING();
> + }
> +
> + return TRUE;
> +}
> +
> +typedef union { float f; uint32_t i; } fi_type;
> +
> +static inline uint32_t
> +R128FloatAsInt(float val)
> +{
> + fi_type fi;
> +
> + fi.f = val;
> + return fi.i;
> +}
> +
> +#define VTX_OUT_MASK(_dstX, _dstY, _srcX, _srcY, _maskX, _maskY) \
> +do { \
> + OUT_RING(R128FloatAsInt((_dstX))); \
> + OUT_RING(R128FloatAsInt(((float)(_dstY)) + 0.125)); \
> + OUT_RING(R128FloatAsInt(0.0)); \
> + OUT_RING(R128FloatAsInt(1.0)); \
> + OUT_RING(R128FloatAsInt((((float)(_srcX)) + 0.5) / (info->state_2d.widths[0]))); \
> + OUT_RING(R128FloatAsInt((((float)(_srcY)) + 0.5) / (info->state_2d.heights[0]))); \
> + OUT_RING(R128FloatAsInt((((float)(_maskX)) + 0.5) / (info->state_2d.widths[1]))); \
> + OUT_RING(R128FloatAsInt((((float)(_maskY)) + 0.5) / (info->state_2d.heights[1]))); \
> +} while (0)
> +
> +#define VTX_OUT(_dstX, _dstY, _srcX, _srcY) \
> +do { \
> + OUT_RING(R128FloatAsInt((_dstX))); \
> + OUT_RING(R128FloatAsInt(((float)(_dstY)) + 0.125)); \
> + OUT_RING(R128FloatAsInt(0.0)); \
> + OUT_RING(R128FloatAsInt(1.0)); \
> + OUT_RING(R128FloatAsInt((((float)(_srcX)) + 0.5) / (info->state_2d.widths[0]))); \
> + OUT_RING(R128FloatAsInt((((float)(_srcY)) + 0.5) / (info->state_2d.heights[0]))); \
> +} while (0)
> +
> +static void
> +R128CCEComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int w, int h)
> +{
> + ScreenPtr pScreen = pDst->drawable.pScreen;
> + ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
> + R128InfoPtr info = R128PTR(pScrn);
> + RING_LOCALS;
> +
> + int srcXend, srcYend, maskXend, maskYend;
> + PictVector v;
> +
> + srcXend = srcX + w;
> + srcYend = srcY + h;
> + maskXend = maskX + w;
> + maskYend = maskY + h;
> + if (info->state_2d.is_transform[0]) {
> + v.vector[0] = IntToxFixed(srcX);
> + v.vector[1] = IntToxFixed(srcY);
> + v.vector[2] = xFixed1;
> + PictureTransformPoint(info->state_2d.transform[0], &v);
> + srcX = xFixedToInt(v.vector[0]);
> + srcY = xFixedToInt(v.vector[1]);
> + v.vector[0] = IntToxFixed(srcXend);
> + v.vector[1] = IntToxFixed(srcYend);
> + v.vector[2] = xFixed1;
> + PictureTransformPoint(info->state_2d.transform[0], &v);
> + srcXend = xFixedToInt(v.vector[0]);
> + srcYend = xFixedToInt(v.vector[1]);
> + }
> + if (info->state_2d.is_transform[1]) {
> + v.vector[0] = IntToxFixed(maskX);
> + v.vector[1] = IntToxFixed(maskY);
> + v.vector[2] = xFixed1;
> + PictureTransformPoint(info->state_2d.transform[1], &v);
> + maskX = xFixedToInt(v.vector[0]);
> + maskY = xFixedToInt(v.vector[1]);
> + v.vector[0] = IntToxFixed(maskXend);
> + v.vector[1] = IntToxFixed(maskYend);
> + v.vector[2] = xFixed1;
> + PictureTransformPoint(info->state_2d.transform[1], &v);
> + maskXend = xFixedToInt(v.vector[0]);
> + maskYend = xFixedToInt(v.vector[1]);
> + }
> +
> + dstX -= info->state_2d.x_offset;
> + dstY -= info->state_2d.y_offset;
> +
> + R128CCE_REFRESH( pScrn, info );
> +
> + if (info->state_2d.has_mask) {
> + BEGIN_RING( 3 + 4 * 8 );
> + OUT_RING(CCE_PACKET3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 1 + 4 * 8));
> +
> + OUT_RING(R128_CCE_VC_FRMT_RHW |
> + R128_CCE_VC_FRMT_S_T |
> + R128_CCE_VC_FRMT_S2_T2);
> + } else {
> + BEGIN_RING( 3 + 4 * 6 );
> + OUT_RING(CCE_PACKET3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 1 + 4 * 6));
> +
> + OUT_RING(R128_CCE_VC_FRMT_RHW |
> + R128_CCE_VC_FRMT_S_T);
> + }
> +
> + OUT_RING(R128_CCE_VC_CNTL_PRIM_TYPE_TRI_FAN |
> + R128_CCE_VC_CNTL_PRIM_WALK_RING |
> + (4 << R128_CCE_VC_CNTL_NUM_SHIFT));
> +
> + if (info->state_2d.has_mask) {
> + VTX_OUT_MASK(dstX, dstY, srcX, srcY, maskX, maskY);
> + VTX_OUT_MASK(dstX, dstY + h, srcX, srcYend, maskX, maskYend);
> + VTX_OUT_MASK(dstX + w, dstY + h, srcXend, srcYend, maskXend, maskYend);
> + VTX_OUT_MASK(dstX + w, dstY, srcXend, srcY, maskXend, maskY);
> + } else {
> + VTX_OUT(dstX, dstY, srcX, srcY);
> + VTX_OUT(dstX, dstY + h, srcX, srcYend);
> + VTX_OUT(dstX + w, dstY + h, srcXend, srcYend);
> + VTX_OUT(dstX + w, dstY, srcXend, srcY);
> + }
> +
> + ADVANCE_RING();
> +}
> +
> +#define R128CCEDoneComposite R128Done
> #endif
>
> #endif
> diff --git a/src/r128_exa_render.c b/src/r128_exa_render.c
> deleted file mode 100644
> index b9601ee..0000000
> --- a/src/r128_exa_render.c
> +++ /dev/null
> @@ -1,705 +0,0 @@
> -/*
> - * Copyright 2003 Eric Anholt
> - * Copyright 2003 Anders Carlsson
> - * Copyright 2012 Connor Behan
> - * Copyright 2012 Michel D�nzer
> - * All Rights Reserved.
> - *
> - * Permission is hereby granted, free of charge, to any person obtaining a
> - * copy of this software and associated documentation files (the "Software"),
> - * to deal in the Software without restriction, including without limitation
> - * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> - * and/or sell copies of the Software, and to permit persons to whom the
> - * Software is furnished to do so, subject to the following conditions:
> - *
> - * The above copyright notice and this permission notice (including the next
> - * paragraph) shall be included in all copies or substantial portions of the
> - * Software.
> - *
> - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
> - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> - * SOFTWARE.
> - *
> - * Authors:
> - * Anders Carlsson <andersca at gnome.org>
> - * Eric Anholt <anholt at FreeBSD.org>
> - * Connor Behan <connor.behan at gmail.com>
> - * Michel D�nzer <michel.daenzer at amd.com>
> - *
> - */
> -
> -/* The following is based on the kdrive ATI driver. */
> -
> -#include <stdio.h>
> -#include <string.h>
> -
> -static struct {
> - Bool dst_alpha;
> - Bool src_alpha;
> - uint32_t sblend;
> - uint32_t dblend;
> -} R128BlendOp[] = {
> - /* Clear */
> - {0, 0, R128_ALPHA_BLEND_ZERO , R128_ALPHA_BLEND_ZERO},
> - /* Src */
> - {0, 0, R128_ALPHA_BLEND_ONE , R128_ALPHA_BLEND_ZERO},
> - /* Dst */
> - {0, 0, R128_ALPHA_BLEND_ZERO , R128_ALPHA_BLEND_ONE},
> - /* Over */
> - {0, 1, R128_ALPHA_BLEND_ONE , R128_ALPHA_BLEND_INVSRCALPHA},
> - /* OverReverse */
> - {1, 0, R128_ALPHA_BLEND_INVDSTALPHA , R128_ALPHA_BLEND_ONE},
> - /* In */
> - {1, 0, R128_ALPHA_BLEND_DSTALPHA , R128_ALPHA_BLEND_ZERO},
> - /* InReverse */
> - {0, 1, R128_ALPHA_BLEND_ZERO , R128_ALPHA_BLEND_SRCALPHA},
> - /* Out */
> - {1, 0, R128_ALPHA_BLEND_INVDSTALPHA , R128_ALPHA_BLEND_ZERO},
> - /* OutReverse */
> - {0, 1, R128_ALPHA_BLEND_ZERO , R128_ALPHA_BLEND_INVSRCALPHA},
> - /* Atop */
> - {1, 1, R128_ALPHA_BLEND_DSTALPHA , R128_ALPHA_BLEND_INVSRCALPHA},
> - /* AtopReverse */
> - {1, 1, R128_ALPHA_BLEND_INVDSTALPHA , R128_ALPHA_BLEND_SRCALPHA},
> - /* Xor */
> - {1, 1, R128_ALPHA_BLEND_INVDSTALPHA , R128_ALPHA_BLEND_INVSRCALPHA},
> - /* Add */
> - {0, 0, R128_ALPHA_BLEND_ONE , R128_ALPHA_BLEND_ONE},
> -};
> -
> -static Bool
> -R128TransformAffineOrScaled(PictTransformPtr t)
> -{
> - if (t == NULL) return TRUE;
> -
> - /* the shaders don't handle scaling either */
> - return t->matrix[2][0] == 0 && t->matrix[2][1] == 0 && t->matrix[2][2] == IntToxFixed(1);
> -}
> -
> -static PixmapPtr
> -R128GetDrawablePixmap(DrawablePtr pDrawable)
> -{
> - if (pDrawable->type == DRAWABLE_WINDOW)
> - return pDrawable->pScreen->GetWindowPixmap((WindowPtr)pDrawable);
> - else
> - return (PixmapPtr)pDrawable;
> -}
> -
> -static PixmapPtr
> -R128SolidPixmap(ScreenPtr pScreen, uint32_t solid)
> -{
> - ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
> - R128InfoPtr info = R128PTR(pScrn);
> - PixmapPtr pPix = pScreen->CreatePixmap(pScreen, 1, 1, 32, 0);
> -
> - exaMoveInPixmap(pPix);
> - if (!exaDrawableIsOffscreen(&pPix->drawable)) {
> - pScreen->DestroyPixmap(pPix);
> - return NULL;
> - }
> - info->ExaDriver->WaitMarker(pScreen, 0);
> -
> -#if X_BYTE_ORDER == X_BIG_ENDIAN
> - if (pScrn->bitsPerPixel == 32)
> - R128CopySwap(info->ExaDriver->memoryBase + exaGetPixmapOffset(pPix), (uint8_t*)&solid, 4,
> - APER_0_BIG_ENDIAN_32BPP_SWAP);
> - else if (pScrn->bitsPerPixel == 16)
> - R128CopySwap(info->ExaDriver->memoryBase + exaGetPixmapOffset(pPix), (uint8_t*)&solid, 4,
> - APER_0_BIG_ENDIAN_16BPP_SWAP);
> - else
> - /* Fall through for 8 bpp */
> -#endif
> - memcpy(info->ExaDriver->memoryBase + exaGetPixmapOffset(pPix), &solid, 4);
> -
> - return pPix;
> -}
> -
> -static Bool
> -R128GetDatatypePict1(uint32_t format, uint32_t *type)
> -{
> - switch(format) {
> - case PICT_r5g6b5:
> - *type = R128_DATATYPE_RGB565;
> - return TRUE;
> - case PICT_x1r5g5b5:
> - *type = R128_DATATYPE_ARGB1555;
> - return TRUE;
> - case PICT_x8r8g8b8:
> - *type = R128_DATATYPE_ARGB8888;
> - return TRUE;
> - default:
> - return FALSE;
> - }
> -}
> -
> -static Bool
> -R128GetDatatypePict2(uint32_t format, uint32_t *type)
> -{
> - switch(format) {
> - case PICT_a8:
> - *type = R128_DATATYPE_RGB8;
> - return TRUE;
> - case PICT_r5g6b5:
> - *type = R128_DATATYPE_RGB565;
> - return TRUE;
> - case PICT_a8r8g8b8:
> - *type = R128_DATATYPE_ARGB8888;
> - return TRUE;
> - default:
> - return FALSE;
> - }
> -}
> -
> -static Bool
> -R128CheckCompositeTexture(PicturePtr pPict, PicturePtr pDstPict, int op)
> -{
> -#if R128_DEBUG
> - ScreenPtr pScreen = pDstPict->pDrawable->pScreen;
> - ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
> -#endif
> -
> - unsigned int repeatType = pPict->repeat ? pPict->repeatType : RepeatNone;
> - uint32_t tmp1;
> -
> - if (!R128GetDatatypePict2(pPict->format, &tmp1)) return FALSE;
> -
> - if (pPict->pDrawable) {
> - int w = pPict->pDrawable->width;
> - int h = pPict->pDrawable->height;
> -
> - if (pPict->repeat && ((w & (w - 1)) != 0 || (h & (h - 1)) != 0)) {
> - R128TRACE(("NPOT repeat unsupported (%dx%d)\n", w, h));
> - return FALSE;
> - }
> - }
> -
> - if (pPict->filter != PictFilterNearest && pPict->filter != PictFilterBilinear) {
> - R128TRACE(("Unsupported filter 0x%x\n", pPict->filter));
> - return FALSE;
> - }
> -
> - /* The radeon driver has a long explanation about this part that I don't really understand */
> - if (pPict->transform != 0 && repeatType == RepeatNone && PICT_FORMAT_A(pPict->format) == 0) {
> - if (!(((op == PictOpSrc) || (op == PictOpClear)) && (PICT_FORMAT_A(pDstPict->format) == 0))) {
> - R128TRACE(("REPEAT_NONE unsupported for transformed xRGB source\n"));
> - return FALSE;
> - }
> - }
> - if (!R128TransformAffineOrScaled(pPict->transform)) {
> - R128TRACE(("Non-affine transforms not supported\n"));
> - return FALSE;
> - }
> -
> - return TRUE;
> -}
> -
> -static Bool
> -R128CCECheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture)
> -{
> -#if R128_DEBUG
> - ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
> - ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
> -#endif
> -
> - PixmapPtr pSrcPixmap, pDstPixmap;
> - uint32_t tmp1;
> -
> - /* Check for unsupported compositing operations. */
> - if (op >= sizeof(R128BlendOp) / sizeof(R128BlendOp[0])) {
> - R128TRACE(("Unsupported Composite op 0x%x\n", op));
> - return FALSE;
> - }
> -
> - pDstPixmap = R128GetDrawablePixmap(pDstPicture->pDrawable);
> - if (pDstPixmap->drawable.width > 1024 || pDstPixmap->drawable.height > 1024) {
> - R128TRACE(("Dest w/h too large (%d,%d).\n", pDstPixmap->drawable.width, pDstPixmap->drawable.height));
> - return FALSE;
> - }
> -
> - if (pSrcPicture->pDrawable) {
> - pSrcPixmap = R128GetDrawablePixmap(pSrcPicture->pDrawable);
> - if (pSrcPixmap->drawable.width > 1024 || pSrcPixmap->drawable.height > 1024) {
> - R128TRACE(("Source w/h too large (%d,%d).\n", pSrcPixmap->drawable.width, pSrcPixmap->drawable.height));
> - return FALSE;
> - }
> - } else if (pSrcPicture->pSourcePict->type != SourcePictTypeSolidFill) {
> - R128TRACE(("Gradient pictures not supported yet\n"));
> - return FALSE;
> - }
> -
> - if (pDstPicture->format == PICT_a8) {
> - if (R128BlendOp[op].src_alpha || R128BlendOp[op].dst_alpha || pMaskPicture != NULL) {
> - R128TRACE(("Alpha blending unsupported with A8 dst?\n"));
> - return FALSE;
> - }
> - } else {
> - if (!R128GetDatatypePict1(pDstPicture->format, &tmp1)) return FALSE;
> - }
> -
> - if (pMaskPicture) {
> - PixmapPtr pMaskPixmap;
> -
> - if (pMaskPicture->pDrawable) {
> - pMaskPixmap = R128GetDrawablePixmap(pMaskPicture->pDrawable);
> - if (pMaskPixmap->drawable.width > 1024 || pMaskPixmap->drawable.height > 1024) {
> - R128TRACE(("Mask w/h too large (%d,%d).\n", pMaskPixmap->drawable.width, pMaskPixmap->drawable.height));
> - return FALSE;
> - }
> - } else if (pMaskPicture->pSourcePict->type != SourcePictTypeSolidFill) {
> - R128TRACE(("Gradient pictures not supported yet\n"));
> - return FALSE;
> - }
> -
> - if (pMaskPicture->componentAlpha && R128BlendOp[op].src_alpha) {
> - R128TRACE(("Component alpha not supported with source alpha blending\n"));
> - return FALSE;
> - }
> -
> - if (!R128CheckCompositeTexture(pMaskPicture, pDstPicture, op)) return FALSE;
> - }
> -
> - if (!R128CheckCompositeTexture(pSrcPicture, pDstPicture, op)) return FALSE;
> - return TRUE;
> -}
> -
> -static Bool
> -R128TextureSetup(PicturePtr pPict, PixmapPtr pPix, int unit, uint32_t *txsize, uint32_t *tex_cntl_c, Bool trying_solid)
> -{
> - ScreenPtr pScreen = pPix->drawable.pScreen;
> - ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
> - R128InfoPtr info = R128PTR(pScrn);
> -
> - int w, h, bytepp, shift, l2w, l2h, l2p, pitch;
> -
> - if (pPict->pDrawable) {
> - w = pPict->pDrawable->width;
> - h = pPict->pDrawable->height;
> - } else {
> - w = h = 1;
> - }
> -
> - pitch = exaGetPixmapPitch(pPix);
> - if ((pitch & (pitch - 1)) != 0) {
> - R128TRACE(("NPOT pitch 0x%x unsupported\n", pitch));
> - return FALSE;
> - }
> -
> - if (!R128GetDatatypePict2(pPict->format, tex_cntl_c)) return FALSE;
> -
> - bytepp = PICT_FORMAT_BPP(pPict->format) / 8;
> - *tex_cntl_c |= R128_MIP_MAP_DISABLE;
> -
> - if (pPict->filter == PictFilterBilinear) {
> - *tex_cntl_c |= R128_MIN_BLEND_LINEAR | R128_MAG_BLEND_LINEAR;
> - } else if (pPict->filter == PictFilterNearest) {
> - *tex_cntl_c |= R128_MIN_BLEND_NEAREST | R128_MAG_BLEND_NEAREST;
> - } else {
> - R128TRACE(("Bad filter 0x%x\n", pPict->filter));
> - return FALSE;
> - }
> -
> - if (unit == 0) {
> - shift = 0;
> - } else {
> - shift = 16;
> - *tex_cntl_c |= R128_SEC_SELECT_SEC_ST;
> - }
> -
> - l2w = R128MinBits(w) - 1;
> - l2h = R128MinBits(h) - 1;
> - l2p = R128MinBits(pitch / bytepp) - 1;
> -
> - if (pPict->repeat && w == 1 && h == 1) {
> - l2p = 0;
> - } else if (pPict->repeat && l2p != l2w) {
> - R128TRACE(("Repeat not supported for pitch != width\n"));
> - return FALSE;
> - }
> -
> - l2w = l2p;
> - /* This is required to handle NPOT height */
> - if ((unit == 1) || (unit == 0 && !pPict->repeat && !trying_solid)) l2h++;
> -
> - info->state_2d.widths[unit] = 1 << l2w;
> - info->state_2d.heights[unit] = 1 << l2h;
> - *txsize |= l2p << (R128_TEX_PITCH_SHIFT + shift);
> - *txsize |= ((w > h) ? l2w : l2h) << (R128_TEX_SIZE_SHIFT + shift);
> - *txsize |= l2h << (R128_TEX_HEIGHT_SHIFT + shift);
> -
> - if (pPict->transform != 0) {
> - info->state_2d.is_transform[unit] = TRUE;
> - info->state_2d.transform[unit] = pPict->transform;
> - } else {
> - info->state_2d.is_transform[unit] = FALSE;
> - }
> -
> - return TRUE;
> -}
> -
> -/* The composite preparation commands that are the same every time can
> - * just be written once.
> - */
> -#define COMPOSITE_SETUP() \
> -do { \
> - BEGIN_RING( 10 ); \
> - \
> - OUT_RING_REG(R128_SCALE_3D_CNTL, \
> - R128_SCALE_3D_TEXMAP_SHADE | \
> - R128_SCALE_PIX_REPLICATE | \
> - R128_TEX_CACHE_SPLIT | \
> - R128_TEX_MAP_ALPHA_IN_TEXTURE | \
> - R128_TEX_CACHE_LINE_SIZE_4QW); \
> - OUT_RING_REG(R128_SETUP_CNTL, \
> - R128_COLOR_GOURAUD | \
> - R128_PRIM_TYPE_TRI | \
> - R128_TEXTURE_ST_MULT_W | \
> - R128_STARTING_VERTEX_1 | \
> - R128_ENDING_VERTEX_3 | \
> - R128_SUB_PIX_4BITS); \
> - OUT_RING_REG(R128_PM4_VC_FPU_SETUP, \
> - R128_FRONT_DIR_CCW | \
> - R128_BACKFACE_SOLID | \
> - R128_FRONTFACE_SOLID | \
> - R128_FPU_COLOR_GOURAUD | \
> - R128_FPU_SUB_PIX_4BITS | \
> - R128_FPU_MODE_3D | \
> - R128_TRAP_BITS_DISABLE | \
> - R128_XFACTOR_2 | \
> - R128_YFACTOR_2 | \
> - R128_FLAT_SHADE_VERTEX_OGL | \
> - R128_FPU_ROUND_TRUNCATE | \
> - R128_WM_SEL_8DW); \
> - OUT_RING_REG(R128_PLANE_3D_MASK_C, 0xffffffff); \
> - OUT_RING_REG(R128_CONSTANT_COLOR_C, 0xff000000); \
> - \
> - ADVANCE_RING(); \
> -} while(0)
> -
> -static Bool
> -R128CCEPrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
> - PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
> -{
> - ScreenPtr pScreen = pDst->drawable.pScreen;
> - ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
> - R128InfoPtr info = R128PTR(pScrn);
> - unsigned char *R128MMIO = info->MMIO;
> - RING_LOCALS;
> -
> - Bool add_src = FALSE;
> - Bool add_msk = FALSE;
> - uint32_t txsize = 0, prim_tex_cntl_c, sec_tex_cntl_c = 0, dstDatatype;
> - uint32_t src_pitch_offset, dst_pitch_offset, color_factor, in_color_factor, alpha_comb;
> - uint32_t sblend, dblend, blend_cntl, window_offset;
> - int i;
> -
> - if (pDstPicture->format == PICT_a8) {
> - if (R128BlendOp[op].dst_alpha) {
> - R128TRACE(("Can't dst alpha blend A8\n"));
> - return FALSE;
> - }
> - dstDatatype = R128_DATATYPE_Y8;
> - } else {
> - if (!R128GetDatatypePict1(pDstPicture->format, &dstDatatype)) return FALSE;
> - }
> -
> - if (!pSrc) {
> - pSrc = R128SolidPixmap(pScreen, cpu_to_le32(pSrcPicture->pSourcePict->solidFill.color));
> - if (!pSrc) {
> - R128TRACE(("Failed to create solid scratch pixmap\n"));
> - return FALSE;
> - }
> - add_src = TRUE;
> - }
> - if (pMaskPicture) {
> - info->state_2d.has_mask = TRUE;
> - if (!pMask) {
> - pMask = R128SolidPixmap(pScreen, cpu_to_le32(pMaskPicture->pSourcePict->solidFill.color));
> - if (!pMask) {
> - if (!pSrcPicture->pDrawable)
> - pScreen->DestroyPixmap(pSrc);
> - info->state_2d.has_mask = FALSE;
> - R128TRACE(("Failed to create solid scratch pixmap\n"));
> - return FALSE;
> - }
> - add_msk = TRUE;
> - }
> - } else {
> - info->state_2d.has_mask = FALSE;
> - }
> -
> - if (!R128TextureSetup(pSrcPicture, pSrc, 0, &txsize, &prim_tex_cntl_c, (add_src || add_msk))) return FALSE;
> -
> - if (pMask != NULL) {
> - info->state_2d.has_mask = TRUE;
> - if (!R128TextureSetup(pMaskPicture, pMask, 1, &txsize, &sec_tex_cntl_c, (add_src || add_msk))) return FALSE;
> - } else {
> - info->state_2d.has_mask = FALSE;
> - info->state_2d.is_transform[1] = FALSE;
> - }
> -
> - if (!R128GetPixmapOffsetPitch(pDst, &dst_pitch_offset)) return FALSE;
> - if (!R128GetPixmapOffsetPitch(pSrc, &src_pitch_offset)) return FALSE;
> -
> - info->state_2d.in_use = TRUE;
> - if (add_src) info->state_2d.src_pix = pSrc;
> - if (add_msk) info->state_2d.msk_pix = pMask;
> - sblend = R128BlendOp[op].sblend;
> - dblend = R128BlendOp[op].dblend;
> - if (PICT_FORMAT_A(pDstPicture->format) == 0 && R128BlendOp[op].dst_alpha) {
> - if (sblend == R128_ALPHA_BLEND_DSTALPHA)
> - sblend = R128_ALPHA_BLEND_ONE;
> - else if (sblend == R128_ALPHA_BLEND_INVDSTALPHA)
> - sblend = R128_ALPHA_BLEND_ZERO;
> - }
> - blend_cntl = (sblend << R128_ALPHA_BLEND_SRC_SHIFT) |
> - (dblend << R128_ALPHA_BLEND_DST_SHIFT);
> -
> - R128CCE_REFRESH( pScrn, info );
> -
> - if (!info->state_2d.composite_setup) {
> - COMPOSITE_SETUP();
> - info->state_2d.composite_setup = TRUE;
> - }
> -
> - /* We cannot guarantee that this register will stay zero - DRI needs it too. */
> - if (info->have3DWindows)
> - info->ExaDriver->WaitMarker(pScreen, 0);
> - window_offset = INREG(R128_WINDOW_XY_OFFSET);
> - info->state_2d.x_offset = (window_offset & 0xfff00000) >> R128_WINDOW_X_SHIFT;
> - info->state_2d.y_offset = (window_offset & 0x000fffff) >> R128_WINDOW_Y_SHIFT;
> -
> - info->state_2d.dp_gui_master_cntl = (R128_GMC_DST_PITCH_OFFSET_CNTL |
> - R128_GMC_BRUSH_SOLID_COLOR |
> - (dstDatatype >> 8) |
> - R128_GMC_SRC_DATATYPE_COLOR |
> - R128_ROP[3].rop |
> - R128_DP_SRC_SOURCE_MEMORY |
> - R128_GMC_3D_FCN_EN |
> - R128_GMC_CLR_CMP_CNTL_DIS |
> - R128_GMC_AUX_CLIP_DIS |
> - R128_GMC_WR_MSK_DIS);
> - info->state_2d.dp_cntl = (R128_DST_X_LEFT_TO_RIGHT | R128_DST_Y_TOP_TO_BOTTOM);
> - info->state_2d.dp_brush_frgd_clr = 0xffffffff;
> - info->state_2d.dp_brush_bkgd_clr = 0x00000000;
> - info->state_2d.dp_src_frgd_clr = 0xffffffff;
> - info->state_2d.dp_src_bkgd_clr = 0x00000000;
> - info->state_2d.dp_write_mask = 0xffffffff;
> - info->state_2d.dst_pitch_offset = dst_pitch_offset;
> - info->state_2d.src_pitch_offset = src_pitch_offset;
> - info->state_2d.default_sc_bottom_right = (R128_DEFAULT_SC_RIGHT_MAX | R128_DEFAULT_SC_BOTTOM_MAX);
> - EmitCCE2DState(pScrn);
> -
> - BEGIN_RING( 6 );
> - OUT_RING_REG(R128_MISC_3D_STATE_CNTL_REG,
> - R128_MISC_SCALE_3D_TEXMAP_SHADE |
> - R128_MISC_SCALE_PIX_REPLICATE |
> - R128_ALPHA_COMB_ADD_CLAMP |
> - blend_cntl);
> - OUT_RING_REG(R128_TEX_CNTL_C,
> - R128_TEXMAP_ENABLE |
> - ((pMask != NULL) ? R128_SEC_TEXMAP_ENABLE : 0) |
> - R128_ALPHA_ENABLE |
> - R128_TEX_CACHE_FLUSH);
> - OUT_RING_REG(R128_PC_GUI_CTLSTAT, R128_PC_FLUSH_GUI);
> - ADVANCE_RING();
> -
> - /* IN operator: Without a mask, only the first texture unit is enabled.
> - * With a mask, we put the source in the first unit and have it pass
> - * through as input to the 2nd. The 2nd unit takes the incoming source
> - * pixel and modulates it with either the alpha or each of the channels
> - * in the mask, depending on componentAlpha.
> - */
> - BEGIN_RING( 15 );
> - /* R128_PRIM_TEX_CNTL_C,
> - * R128_PRIM_TEXTURE_COMBINE_CNTL_C,
> - * R128_TEX_SIZE_PITCH_C,
> - * R128_PRIM_TEX_0_OFFSET_C - R128_PRIM_TEX_10_OFFSET_C
> - */
> - OUT_RING(CCE_PACKET0(R128_PRIM_TEX_CNTL_C, 13));
> - OUT_RING(prim_tex_cntl_c);
> -
> - /* If this is the only stage and the dest is a8, route the alpha result
> - * to the color (red channel, in particular), too. Otherwise, be sure
> - * to zero out color channels of an a8 source.
> - */
> - if (pMaskPicture == NULL && pDstPicture->format == PICT_a8)
> - color_factor = R128_COLOR_FACTOR_ALPHA;
> - else if (pSrcPicture->format == PICT_a8)
> - color_factor = R128_COLOR_FACTOR_CONST_COLOR;
> - else
> - color_factor = R128_COLOR_FACTOR_TEX;
> -
> - if (PICT_FORMAT_A(pSrcPicture->format) == 0)
> - alpha_comb = R128_COMB_ALPHA_COPY_INP;
> - else
> - alpha_comb = R128_COMB_ALPHA_DIS;
> -
> - OUT_RING(R128_COMB_COPY |
> - color_factor |
> - R128_INPUT_FACTOR_INT_COLOR |
> - alpha_comb |
> - R128_ALPHA_FACTOR_TEX_ALPHA |
> - R128_INP_FACTOR_A_CONST_ALPHA);
> - OUT_RING(txsize);
> - /* We could save some output by only writing the offset register that
> - * will actually be used. On the other hand, this is easy.
> - */
> - for (i = 0; i <= 10; i++)
> - OUT_RING(exaGetPixmapOffset(pSrc));
> - ADVANCE_RING();
> -
> - if (pMask != NULL) {
> - BEGIN_RING( 14 );
> - /* R128_SEC_TEX_CNTL_C,
> - * R128_SEC_TEXTURE_COMBINE_CNTL_C,
> - * R128_SEC_TEX_0_OFFSET_C - R128_SEC_TEX_10_OFFSET_C
> - */
> - OUT_RING(CCE_PACKET0(R128_SEC_TEX_CNTL_C, 12));
> - OUT_RING(sec_tex_cntl_c);
> -
> - if (pDstPicture->format == PICT_a8) {
> - color_factor = R128_COLOR_FACTOR_ALPHA;
> - in_color_factor = R128_INPUT_FACTOR_PREV_ALPHA;
> - } else if (pMaskPicture->componentAlpha) {
> - color_factor = R128_COLOR_FACTOR_TEX;
> - in_color_factor = R128_INPUT_FACTOR_PREV_COLOR;
> - } else {
> - color_factor = R128_COLOR_FACTOR_ALPHA;
> - in_color_factor = R128_INPUT_FACTOR_PREV_COLOR;
> - }
> -
> - OUT_RING(R128_COMB_MODULATE |
> - color_factor |
> - in_color_factor |
> - R128_COMB_ALPHA_MODULATE |
> - R128_ALPHA_FACTOR_TEX_ALPHA |
> - R128_INP_FACTOR_A_PREV_ALPHA);
> - for (i = 0; i <= 10; i++)
> - OUT_RING(exaGetPixmapOffset(pMask));
> - ADVANCE_RING();
> - }
> -
> - return TRUE;
> -}
> -
> -typedef union { float f; uint32_t i; } fi_type;
> -
> -static inline uint32_t
> -R128FloatAsInt(float val)
> -{
> - fi_type fi;
> -
> - fi.f = val;
> - return fi.i;
> -}
> -
> -#define VTX_OUT_MASK(_dstX, _dstY, _srcX, _srcY, _maskX, _maskY) \
> -do { \
> - OUT_RING(R128FloatAsInt((_dstX))); \
> - OUT_RING(R128FloatAsInt(((float)(_dstY)) + 0.125)); \
> - OUT_RING(R128FloatAsInt(0.0)); \
> - OUT_RING(R128FloatAsInt(1.0)); \
> - OUT_RING(R128FloatAsInt((((float)(_srcX)) + 0.5) / (info->state_2d.widths[0]))); \
> - OUT_RING(R128FloatAsInt((((float)(_srcY)) + 0.5) / (info->state_2d.heights[0]))); \
> - OUT_RING(R128FloatAsInt((((float)(_maskX)) + 0.5) / (info->state_2d.widths[1]))); \
> - OUT_RING(R128FloatAsInt((((float)(_maskY)) + 0.5) / (info->state_2d.heights[1]))); \
> -} while (0)
> -
> -#define VTX_OUT(_dstX, _dstY, _srcX, _srcY) \
> -do { \
> - OUT_RING(R128FloatAsInt((_dstX))); \
> - OUT_RING(R128FloatAsInt(((float)(_dstY)) + 0.125)); \
> - OUT_RING(R128FloatAsInt(0.0)); \
> - OUT_RING(R128FloatAsInt(1.0)); \
> - OUT_RING(R128FloatAsInt((((float)(_srcX)) + 0.5) / (info->state_2d.widths[0]))); \
> - OUT_RING(R128FloatAsInt((((float)(_srcY)) + 0.5) / (info->state_2d.heights[0]))); \
> -} while (0)
> -
> -static void
> -R128CCEComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, int dstX, int dstY, int w, int h)
> -{
> - ScreenPtr pScreen = pDst->drawable.pScreen;
> - ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
> - R128InfoPtr info = R128PTR(pScrn);
> - RING_LOCALS;
> -
> - int srcXend, srcYend, maskXend, maskYend;
> - PictVector v;
> -
> - srcXend = srcX + w;
> - srcYend = srcY + h;
> - maskXend = maskX + w;
> - maskYend = maskY + h;
> - if (info->state_2d.is_transform[0]) {
> - v.vector[0] = IntToxFixed(srcX);
> - v.vector[1] = IntToxFixed(srcY);
> - v.vector[2] = xFixed1;
> - PictureTransformPoint(info->state_2d.transform[0], &v);
> - srcX = xFixedToInt(v.vector[0]);
> - srcY = xFixedToInt(v.vector[1]);
> - v.vector[0] = IntToxFixed(srcXend);
> - v.vector[1] = IntToxFixed(srcYend);
> - v.vector[2] = xFixed1;
> - PictureTransformPoint(info->state_2d.transform[0], &v);
> - srcXend = xFixedToInt(v.vector[0]);
> - srcYend = xFixedToInt(v.vector[1]);
> - }
> - if (info->state_2d.is_transform[1]) {
> - v.vector[0] = IntToxFixed(maskX);
> - v.vector[1] = IntToxFixed(maskY);
> - v.vector[2] = xFixed1;
> - PictureTransformPoint(info->state_2d.transform[1], &v);
> - maskX = xFixedToInt(v.vector[0]);
> - maskY = xFixedToInt(v.vector[1]);
> - v.vector[0] = IntToxFixed(maskXend);
> - v.vector[1] = IntToxFixed(maskYend);
> - v.vector[2] = xFixed1;
> - PictureTransformPoint(info->state_2d.transform[1], &v);
> - maskXend = xFixedToInt(v.vector[0]);
> - maskYend = xFixedToInt(v.vector[1]);
> - }
> -
> - dstX -= info->state_2d.x_offset;
> - dstY -= info->state_2d.y_offset;
> -
> - R128CCE_REFRESH( pScrn, info );
> -
> - if (info->state_2d.has_mask) {
> - BEGIN_RING( 3 + 4 * 8 );
> - OUT_RING(CCE_PACKET3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 1 + 4 * 8));
> -
> - OUT_RING(R128_CCE_VC_FRMT_RHW |
> - R128_CCE_VC_FRMT_S_T |
> - R128_CCE_VC_FRMT_S2_T2);
> - } else {
> - BEGIN_RING( 3 + 4 * 6 );
> - OUT_RING(CCE_PACKET3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 1 + 4 * 6));
> -
> - OUT_RING(R128_CCE_VC_FRMT_RHW |
> - R128_CCE_VC_FRMT_S_T);
> - }
> -
> - OUT_RING(R128_CCE_VC_CNTL_PRIM_TYPE_TRI_FAN |
> - R128_CCE_VC_CNTL_PRIM_WALK_RING |
> - (4 << R128_CCE_VC_CNTL_NUM_SHIFT));
> -
> - if (info->state_2d.has_mask) {
> - VTX_OUT_MASK(dstX, dstY, srcX, srcY, maskX, maskY);
> - VTX_OUT_MASK(dstX, dstY + h, srcX, srcYend, maskX, maskYend);
> - VTX_OUT_MASK(dstX + w, dstY + h, srcXend, srcYend, maskXend, maskYend);
> - VTX_OUT_MASK(dstX + w, dstY, srcXend, srcY, maskXend, maskY);
> - } else {
> - VTX_OUT(dstX, dstY, srcX, srcY);
> - VTX_OUT(dstX, dstY + h, srcX, srcYend);
> - VTX_OUT(dstX + w, dstY + h, srcXend, srcYend);
> - VTX_OUT(dstX + w, dstY, srcXend, srcY);
> - }
> -
> - ADVANCE_RING();
> -}
> -
> -#define R128CCEDoneComposite R128Done
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: OpenPGP digital signature
URL: <https://lists.x.org/archives/xorg-driver-ati/attachments/20160821/58ff238f/attachment-0001.sig>
More information about the xorg-driver-ati
mailing list