Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Copyright 2003 Eric Anholt
- * Copyright 2003 Anders Carlsson
- * Copyright 2006 Joseph Garvin
- * Copyright 2012 Connor Behan
- * 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:
- * Eric Anholt <anholt@FreeBSD.org>
- * Anders Carlsson <andersca@gnome.org>
- * Joseph Garvin <joseph.h.garvin@gmail.com>
- * Connor Behan <connor.behan@gmail.com>
- *
- */
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #include "r128.h"
- #include "exa.h"
- #include "r128_reg.h"
- #include "xf86.h"
- static struct {
- int rop;
- int pattern;
- } R128_ROP[] = {
- { R128_ROP3_ZERO, R128_ROP3_ZERO }, /* GXclear */
- { R128_ROP3_DSa, R128_ROP3_DPa }, /* Gxand */
- { R128_ROP3_SDna, R128_ROP3_PDna }, /* GXandReverse */
- { R128_ROP3_S, R128_ROP3_P }, /* GXcopy */
- { R128_ROP3_DSna, R128_ROP3_DPna }, /* GXandInverted */
- { R128_ROP3_D, R128_ROP3_D }, /* GXnoop */
- { R128_ROP3_DSx, R128_ROP3_DPx }, /* GXxor */
- { R128_ROP3_DSo, R128_ROP3_DPo }, /* GXor */
- { R128_ROP3_DSon, R128_ROP3_DPon }, /* GXnor */
- { R128_ROP3_DSxn, R128_ROP3_PDxn }, /* GXequiv */
- { R128_ROP3_Dn, R128_ROP3_Dn }, /* GXinvert */
- { R128_ROP3_SDno, R128_ROP3_PDno }, /* GXorReverse */
- { R128_ROP3_Sn, R128_ROP3_Pn }, /* GXcopyInverted */
- { R128_ROP3_DSno, R128_ROP3_DPno }, /* GXorInverted */
- { R128_ROP3_DSan, R128_ROP3_DPan }, /* GXnand */
- { R128_ROP3_ONE, R128_ROP3_ONE } /* GXset */
- };
- #ifdef RENDER
- static struct {
- Bool dst_alpha;
- Bool src_alpha;
- CARD32 blendctl;
- } R128BlendOp[] = {
- /* Clear */
- {0, 0, R128_SBLEND_ZERO | R128_DBLEND_ZERO},
- /* Src */
- {0, 0, R128_SBLEND_ONE | R128_DBLEND_ZERO},
- /* Dst */
- {0, 0, R128_SBLEND_ZERO | R128_DBLEND_ONE},
- /* Over */
- {0, 1, R128_SBLEND_ONE | R128_DBLEND_INV_SRC_ALPHA},
- /* OverReverse */
- {1, 0, R128_SBLEND_INV_DST_ALPHA | R128_DBLEND_ONE},
- /* In */
- {1, 0, R128_SBLEND_DST_ALPHA | R128_DBLEND_ZERO},
- /* InReverse */
- {0, 1, R128_SBLEND_ZERO | R128_DBLEND_SRC_ALPHA},
- /* Out */
- {1, 0, R128_SBLEND_INV_DST_ALPHA | R128_DBLEND_ZERO},
- /* OutReverse */
- {0, 1, R128_SBLEND_ZERO | R128_DBLEND_INV_SRC_ALPHA},
- /* Atop */
- {1, 1, R128_SBLEND_DST_ALPHA | R128_DBLEND_INV_SRC_ALPHA},
- /* AtopReverse */
- {1, 1, R128_SBLEND_INV_DST_ALPHA | R128_DBLEND_SRC_ALPHA},
- /* Xor */
- {1, 1, R128_SBLEND_INV_DST_ALPHA | R128_DBLEND_INV_SRC_ALPHA},
- /* Add */
- {0, 0, R128_SBLEND_ONE | R128_DBLEND_ONE},
- };
- static int widths[2] = {1,1};
- static int heights[2] = {1,1};
- static Bool is_transform[2];
- static PictTransform *transform[2];
- typedef union { float f; CARD32 i; } fi_type;
- /* If it was okay to not be paranoid about a simple cast, I guess they wouldn't have made this. */
- static inline CARD32
- R128FloatAsInt(float val)
- {
- fi_type fi;
- fi.f = val;
- return fi.i;
- }
- #define VTX_RING_COUNT 8
- #define VTX_OUT(_dstX, _dstY, _srcX, _srcY, _maskX, _maskY) \
- do { \
- OUTREG(0, R128FloatAsInt(_dstX)); \
- OUTREG(0, R128FloatAsInt(((float)(_dstY)) + 0.125)); \
- OUTREG(0, R128FloatAsInt(0.0)); \
- OUTREG(0, R128FloatAsInt(1.0)); \
- OUTREG(0, R128FloatAsInt((((float)(_srcX)) + 0.5) / (widths[0]))); \
- OUTREG(0, R128FloatAsInt((((float)(_srcY)) + 0.5) / (heights[0]))); \
- OUTREG(0, R128FloatAsInt((((float)(_maskX)) + 0.5) / (widths[1]))); \
- OUTREG(0, R128FloatAsInt((((float)(_maskY)) + 0.5) / (heights[1])));\
- } while (0)
- #define VTX_CCE_OUT(_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) / (widths[0]))); \
- OUT_RING(R128FloatAsInt((((float)(_srcY)) + 0.5) / (heights[0]))); \
- OUT_RING(R128FloatAsInt((((float)(_maskX)) + 0.5) / (widths[1]))); \
- OUT_RING(R128FloatAsInt((((float)(_maskY)) + 0.5) / (heights[1]))); \
- } while (0)
- 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 = xf86Screens[pScreen->myNum];
- R128InfoPtr info = R128PTR(pScrn);
- PixmapPtr pPix = pScreen->CreatePixmap(pScreen, 1, 1, 32, 0);
- exaMoveInPixmap(pPix);
- if (!exaDrawableIsOffscreen(&pPix->drawable)) {
- pScreen->DestroyPixmap(pPix);
- return NULL;
- }
- memcpy(info->ExaDriver->memoryBase + exaGetPixmapOffset(pPix), &solid, 4);
- return pPix;
- }
- /* XXX: Extra rejection criteria to make tests pass -- possibly card specific! */
- static Bool
- R128Quirks(PicturePtr pMaskPicture, PicturePtr pSrcPicture, int op)
- {
- if (pMaskPicture->format == PICT_r5g6b5 && pSrcPicture->format == PICT_r5g6b5) {
- switch (op) {
- case PictOpClear:
- case PictOpSrc:
- case PictOpIn:
- case PictOpOut:
- case PictOpOutReverse:
- case PictOpOver:
- case PictOpAtop:
- case PictOpAdd:
- case PictOpXor:
- return FALSE;
- default:
- return TRUE;
- }
- }
- return TRUE;
- }
- /* Sometimes one list is supported, sometimes the other list is */
- static Bool
- R128GetDatatypePict1(uint32_t format, uint32_t *type)
- {
- switch(format) {
- case PICT_r5g6b5:
- *type = R128_DATATYPE_RGB565;
- return TRUE;
- case PICT_a1r5g5b5:
- 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_r5g6b5:
- *type = R128_DATATYPE_RGB565;
- return TRUE;
- case PICT_a1r5g5b5:
- *type = R128_DATATYPE_ARGB1555;
- return TRUE;
- case PICT_a4r4g4b4:
- *type = R128_DATATYPE_ARGB4444;
- return TRUE;
- default:
- return FALSE;
- }
- }
- #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.
- */
- Bool R128GetDatatypeBpp(int bpp, uint32_t *type)
- {
- switch (bpp) {
- case 8:
- *type = R128_DATATYPE_CI8;
- return TRUE;
- case 16:
- *type = R128_DATATYPE_RGB565;
- return TRUE;
- case 24:
- *type = R128_DATATYPE_CI8;
- return TRUE;
- case 32:
- *type = R128_DATATYPE_ARGB8888;
- return TRUE;
- default:
- return FALSE;
- }
- }
- static Bool R128GetOffsetPitch(PixmapPtr pPix, int bpp, uint32_t *pitch_offset,
- unsigned int offset, unsigned int pitch)
- {
- ScreenPtr pScreen = pPix->drawable.pScreen;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- R128InfoPtr info = R128PTR(pScrn);
- if (pitch > 16320 || pitch % info->ExaDriver->pixmapPitchAlign != 0) {
- R128TRACE(("Bad pitch 0x%08x\n", pitch));
- return FALSE;
- }
- if (offset % info->ExaDriver->pixmapOffsetAlign != 0) {
- R128TRACE(("Bad offset 0x%08x\n", offset));
- return FALSE;
- }
- *pitch_offset = ((pitch / bpp) << 21) | (offset >> 5);
- return TRUE;
- }
- Bool R128GetPixmapOffsetPitch(PixmapPtr pPix, uint32_t *pitch_offset)
- {
- uint32_t pitch, offset;
- int bpp;
- bpp = pPix->drawable.bitsPerPixel;
- if (bpp == 24)
- bpp = 8;
- offset = exaGetPixmapOffset(pPix);
- pitch = exaGetPixmapPitch(pPix);
- return R128GetOffsetPitch(pPix, bpp, pitch_offset, offset, pitch);
- }
- static void Emit2DState(ScrnInfoPtr pScrn)
- {
- R128InfoPtr info = R128PTR(pScrn);
- int has_src = info->state_2d.src_pitch_offset;
- unsigned char *R128MMIO = info->MMIO;
- R128WaitForFifo(pScrn, (has_src ? 10 : 9));
- OUTREG(R128_DEFAULT_SC_BOTTOM_RIGHT, info->state_2d.default_sc_bottom_right);
- OUTREG(R128_DP_GUI_MASTER_CNTL, info->state_2d.dp_gui_master_cntl);
- OUTREG(R128_DP_BRUSH_FRGD_CLR, info->state_2d.dp_brush_frgd_clr);
- OUTREG(R128_DP_BRUSH_BKGD_CLR, info->state_2d.dp_brush_bkgd_clr);
- OUTREG(R128_DP_SRC_FRGD_CLR, info->state_2d.dp_src_frgd_clr);
- OUTREG(R128_DP_SRC_BKGD_CLR, info->state_2d.dp_src_bkgd_clr);
- OUTREG(R128_DP_WRITE_MASK, info->state_2d.dp_write_mask);
- OUTREG(R128_DP_CNTL, info->state_2d.dp_cntl);
- OUTREG(R128_DST_PITCH_OFFSET, info->state_2d.dst_pitch_offset);
- if (has_src) OUTREG(R128_SRC_PITCH_OFFSET, info->state_2d.src_pitch_offset);
- }
- static void EmitCCE2DState(ScrnInfoPtr pScrn)
- {
- R128InfoPtr info = R128PTR(pScrn);
- int has_src = info->state_2d.src_pitch_offset;
- RING_LOCALS;
- R128CCE_REFRESH( pScrn, info );
- BEGIN_RING( (has_src ? 20 : 18) );
- OUT_RING_REG( R128_DEFAULT_SC_BOTTOM_RIGHT, info->state_2d.default_sc_bottom_right );
- OUT_RING_REG( R128_DP_GUI_MASTER_CNTL, info->state_2d.dp_gui_master_cntl );
- OUT_RING_REG( R128_DP_BRUSH_FRGD_CLR, info->state_2d.dp_brush_frgd_clr );
- OUT_RING_REG( R128_DP_BRUSH_BKGD_CLR, info->state_2d.dp_brush_bkgd_clr );
- OUT_RING_REG( R128_DP_SRC_FRGD_CLR, info->state_2d.dp_src_frgd_clr );
- OUT_RING_REG( R128_DP_SRC_BKGD_CLR, info->state_2d.dp_src_bkgd_clr );
- OUT_RING_REG( R128_DP_WRITE_MASK, info->state_2d.dp_write_mask );
- OUT_RING_REG( R128_DP_CNTL, info->state_2d.dp_cntl );
- OUT_RING_REG( R128_DST_PITCH_OFFSET, info->state_2d.dst_pitch_offset );
- if (has_src) OUT_RING_REG( R128_SRC_PITCH_OFFSET, info->state_2d.src_pitch_offset );
- ADVANCE_RING();
- }
- /* EXA Callbacks */
- static Bool
- R128PrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg)
- {
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- R128InfoPtr info = R128PTR(pScrn);
- int bpp = pPixmap->drawable.bitsPerPixel;
- uint32_t datatype, dst_pitch_offset;
- if (!R128GetDatatypeBpp(bpp, &datatype)) {
- R128TRACE(("R128GetDatatypeBpp failed\n"));
- return FALSE;
- }
- if (!R128GetPixmapOffsetPitch(pPixmap, &dst_pitch_offset)) {
- R128TRACE(("R128GetPixmapOffsetPitch failed\n"));
- return FALSE;
- }
- if (info->state_2d.in_use) return FALSE;
- info->state_2d.in_use = TRUE;
- info->state_2d.default_sc_bottom_right = (R128_DEFAULT_SC_RIGHT_MAX | R128_DEFAULT_SC_BOTTOM_MAX);
- 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_gui_master_cntl = (R128_GMC_DST_PITCH_OFFSET_CNTL |
- R128_GMC_BRUSH_SOLID_COLOR |
- (datatype >> 8) |
- R128_GMC_SRC_DATATYPE_COLOR |
- R128_ROP[alu].pattern |
- R128_GMC_CLR_CMP_CNTL_DIS);
- info->state_2d.dp_brush_frgd_clr = fg;
- info->state_2d.dp_cntl = (R128_DST_X_LEFT_TO_RIGHT | R128_DST_Y_TOP_TO_BOTTOM);
- info->state_2d.dp_write_mask = planemask;
- info->state_2d.dst_pitch_offset = dst_pitch_offset;
- info->state_2d.src_pitch_offset = 0;
- #ifdef R128DRI
- if (info->directRenderingEnabled) {
- EmitCCE2DState(pScrn);
- } else
- #endif
- {
- Emit2DState(pScrn);
- }
- return TRUE;
- }
- static void
- R128Solid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
- {
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- R128InfoPtr info = R128PTR(pScrn);
- unsigned char *R128MMIO = info->MMIO;
- R128WaitForFifo(pScrn, 2);
- OUTREG(R128_DST_Y_X, (y1 << 16) | x1);
- OUTREG(R128_DST_WIDTH_HEIGHT, ((x2-x1) << 16) | (y2-y1));
- }
- #define R128DoneSolid R128Done
- void
- R128DoPrepareCopy(ScrnInfoPtr pScrn, uint32_t src_pitch_offset,
- uint32_t dst_pitch_offset, uint32_t datatype, int alu, Pixel planemask)
- {
- R128InfoPtr info = R128PTR(pScrn);
- info->state_2d.in_use = TRUE;
- info->state_2d.dp_gui_master_cntl = (R128_GMC_DST_PITCH_OFFSET_CNTL |
- R128_GMC_SRC_PITCH_OFFSET_CNTL |
- R128_GMC_BRUSH_NONE |
- (datatype >> 8) |
- R128_GMC_SRC_DATATYPE_COLOR |
- R128_ROP[alu].rop |
- R128_DP_SRC_SOURCE_MEMORY |
- R128_GMC_CLR_CMP_CNTL_DIS);
- info->state_2d.dp_cntl = ((info->xdir >= 0 ? R128_DST_X_LEFT_TO_RIGHT : 0) |
- (info->ydir >= 0 ? R128_DST_Y_TOP_TO_BOTTOM : 0));
- 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 = planemask;
- 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);
- #ifdef R128DRI
- if (info->directRenderingEnabled) {
- EmitCCE2DState(pScrn);
- } else
- #endif
- {
- Emit2DState(pScrn);
- }
- }
- static Bool
- R128PrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, int ydir, int alu, Pixel planemask)
- {
- ScreenPtr pScreen = pSrcPixmap->drawable.pScreen;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- R128InfoPtr info = R128PTR(pScrn);
- int bpp = pDstPixmap->drawable.bitsPerPixel;
- uint32_t datatype, src_pitch_offset, dst_pitch_offset;
- if (!R128GetDatatypeBpp(bpp, &datatype)) {
- R128TRACE(("R128GetDatatypeBpp failed\n"));
- return FALSE;
- }
- if (!R128GetPixmapOffsetPitch(pSrcPixmap, &src_pitch_offset)) {
- R128TRACE(("R128GetPixmapOffsetPitch source failed\n"));
- return FALSE;
- }
- if (!R128GetPixmapOffsetPitch(pDstPixmap, &dst_pitch_offset)) {
- R128TRACE(("R128GetPixmapOffsetPitch dest failed\n"));
- return FALSE;
- }
- if (info->state_2d.in_use) return FALSE;
- info->xdir = xdir;
- info->ydir = ydir;
- R128DoPrepareCopy(pScrn, src_pitch_offset, dst_pitch_offset, datatype, alu, planemask);
- return TRUE;
- }
- static void
- R128Copy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, int width, int height)
- {
- ScreenPtr pScreen = pDstPixmap->drawable.pScreen;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- R128InfoPtr info = R128PTR(pScrn);
- unsigned char *R128MMIO = info->MMIO;
- if (info->xdir < 0) srcX += width - 1, dstX += width - 1;
- if (info->ydir < 0) srcY += height - 1, dstY += height - 1;
- R128WaitForFifo(pScrn, 3);
- OUTREG(R128_SRC_Y_X, (srcY << 16) | srcX);
- OUTREG(R128_DST_Y_X, (dstY << 16) | dstX);
- OUTREG(R128_DST_HEIGHT_WIDTH, (height << 16) | width);
- }
- #define R128DoneCopy R128Done
- #ifdef RENDER
- static Bool
- R128CheckCompositeTexture(PicturePtr pPict, PicturePtr pDstPict, int op, Bool trying_solid)
- {
- ScreenPtr pScreen = pDstPict->pDrawable->pScreen;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- R128InfoPtr info = R128PTR(pScrn);
- int w, h;
- unsigned int repeatType = pPict->repeat ? pPict->repeatType : RepeatNone;
- uint32_t tmp1;
- if (!trying_solid || !(pPict->format == PICT_a8 || pPict->format == PICT_a8r8g8b8)) {
- if (!R128GetDatatypePict2(pPict->format, &tmp1)) return FALSE;
- }
- if (pPict->pDrawable) {
- w = pPict->pDrawable->width;
- 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
- R128CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture)
- {
- ScreenPtr pScreen = pDstPicture->pDrawable->pScreen;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- R128InfoPtr info = R128PTR(pScrn);
- PixmapPtr pSrcPixmap, pDstPixmap;
- uint32_t tmp1;
- Bool trying_solid = FALSE;
- /* Check for unsupported compositing operations. */
- if (op >= sizeof(R128BlendOp) / sizeof(R128BlendOp[0])) {
- R128TRACE(("Unsupported Composite op 0x%x\n", op));
- return FALSE;
- }
- /* The radeon driver says that a bug requires 2047 instead of 2048 and r128 uses 1024 so... */
- pDstPixmap = R128GetDrawablePixmap(pDstPicture->pDrawable);
- if (pDstPixmap->drawable.width > 1023 || pDstPixmap->drawable.height > 1023) {
- 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 > 1023 || pSrcPixmap->drawable.height > 1023) {
- 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;
- } else {
- R128TRACE(("One of those\n"));
- trying_solid = TRUE;
- }
- 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 > 1023 || pMaskPixmap->drawable.height > 1023) {
- 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 (!R128Quirks(pMaskPicture, pSrcPicture, op)) return FALSE;
- if (!R128CheckCompositeTexture(pMaskPicture, pDstPicture, op, trying_solid)) return FALSE;
- }
- if (!R128CheckCompositeTexture(pSrcPicture, pDstPicture, op, trying_solid)) 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 = xf86Screens[pScreen->myNum];
- R128InfoPtr info = R128PTR(pScrn);
- int w, h;
- int 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 (trying_solid && pPict->format == PICT_a8r8g8b8) {
- *tex_cntl_c = R128_DATATYPE_RGB8;
- } else if (trying_solid && pPict->format == PICT_a8) {
- *tex_cntl_c = R128_DATATYPE_Y8;
- } else {
- 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;
- }
- /* R128MinBits returns -1 for value of 0 */
- l2w = R128MinBits(w - 1) + 1;
- l2h = R128MinBits(h - 1) + 1;
- l2p = R128MinBits(pitch / bytepp);
- 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;
- widths[unit] = 1 << l2w;
- heights[unit] = 1 << l2h;
- *txsize |= l2p << (R128_TEX_PITCH_SHIFT + shift);
- *txsize |= ((l2w > l2h) ? l2w : l2h) << (R128_TEX_SIZE_SHIFT + shift);
- *txsize |= l2h << (R128_TEX_HEIGHT_SHIFT + shift);
- if (pPict->transform != 0) {
- is_transform[unit] = TRUE;
- transform[unit] = pPict->transform;
- } else {
- is_transform[unit] = FALSE;
- }
- return TRUE;
- }
- static Bool
- R128PrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
- PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
- {
- ScreenPtr pScreen = pDst->drawable.pScreen;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- R128InfoPtr info = R128PTR(pScrn);
- unsigned char *R128MMIO = info->MMIO;
- Bool add_src = FALSE;
- Bool add_msk = FALSE;
- uint32_t txsize = 0, prim_tex_cntl_c, sec_tex_cntl_c = 0, dstDatatype;
- uint32_t dst_pitch_offset, color_factor, in_color_factor, alpha_comb;
- uint32_t blend_cntl;
- 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 && !pMask) {
- pMask = R128SolidPixmap(pScreen, cpu_to_le32(pMaskPicture->pSourcePict->solidFill.color));
- if (!pMask) {
- if (!pSrcPicture->pDrawable)
- pScreen->DestroyPixmap(pSrc);
- R128TRACE(("Failed to create solid scratch pixmap\n"));
- return FALSE;
- }
- add_msk = TRUE;
- }
- if (!R128TextureSetup(pSrcPicture, pSrc, 0, &txsize, &prim_tex_cntl_c, add_src)) return FALSE;
- if (pMask != NULL) {
- if (!R128TextureSetup(pMaskPicture, pMask, 1, &txsize, &sec_tex_cntl_c, add_src)) return FALSE;
- } else {
- is_transform[1] = FALSE;
- }
- if (!R128GetPixmapOffsetPitch(pDst, &dst_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;
- blend_cntl = R128BlendOp[op].blendctl;
- if (PICT_FORMAT_A(pDstPicture->format) == 0 && R128BlendOp[op].dst_alpha) {
- if ((blend_cntl & R128_SBLEND_MASK) == R128_SBLEND_DST_ALPHA)
- blend_cntl = (blend_cntl & ~R128_SBLEND_MASK) | R128_SBLEND_ONE;
- else if ((blend_cntl & R128_SBLEND_MASK) == R128_SBLEND_INV_DST_ALPHA)
- blend_cntl = (blend_cntl & ~R128_SBLEND_MASK) | R128_SBLEND_ZERO;
- }
- R128WaitForFifo(pScrn, 21);
- OUTREG(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);
- OUTREG(R128_DST_PITCH_OFFSET, dst_pitch_offset);
- OUTREG(R128_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 << 16) |
- 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);
- OUTREG(R128_MISC_3D_STATE_CNTL_REG,
- R128_MISC_SCALE_3D_TEXMAP_SHADE |
- R128_MISC_SCALE_PIX_REPLICATE |
- R128_ALPHA_COMB_ADD_CLAMP |
- blend_cntl);
- OUTREG(R128_TEX_CNTL_C,
- R128_TEXMAP_ENABLE |
- ((pMask != NULL) ? R128_SEC_TEXMAP_ENABLE : 0) |
- R128_ALPHA_ENABLE |
- R128_TEX_CACHE_FLUSH);
- OUTREG(R128_PC_GUI_CTLSTAT, R128_PC_FLUSH_GUI);
- /* 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.
- */
- OUTREG(0, CCE_PACKET0(R128_PRIM_TEX_CNTL_C, 13));
- OUTREG(0, 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;
- OUTREG(0, R128_COMB_COPY |
- color_factor |
- R128_INPUT_FACTOR_INT_COLOR |
- alpha_comb |
- R128_ALPHA_FACTOR_TEX_ALPHA |
- R128_INP_FACTOR_A_CONST_ALPHA);
- OUTREG(0, 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++)
- OUTREG(0, ((CARD8 *)pSrc->devPrivate.ptr - info->ExaDriver->memoryBase));
- if (pMask != NULL) {
- R128WaitForFifo(pScrn, 14);
- OUTREG(0, CCE_PACKET0(R128_SEC_TEX_CNTL_C, 12));
- OUTREG(0, 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;
- }
- OUTREG(0, 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++)
- OUTREG(0, ((CARD8 *)pMask->devPrivate.ptr - info->ExaDriver->memoryBase));
- }
- return TRUE;
- }
- static void
- R128Composite(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 = xf86Screens[pScreen->myNum];
- R128InfoPtr info = R128PTR(pScrn);
- unsigned char *R128MMIO = info->MMIO;
- int srcXend, srcYend, maskXend, maskYend;
- PictVector v;
- srcXend = srcX + w;
- srcYend = srcY + h;
- maskXend = maskX + w;
- maskYend = maskY + h;
- if (is_transform[0]) {
- v.vector[0] = IntToxFixed(srcX);
- v.vector[1] = IntToxFixed(srcY);
- v.vector[2] = xFixed1;
- PictureTransformPoint(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(transform[0], &v);
- srcXend = xFixedToInt(v.vector[0]);
- srcYend = xFixedToInt(v.vector[1]);
- }
- if (is_transform[1]) {
- v.vector[0] = IntToxFixed(maskX);
- v.vector[1] = IntToxFixed(maskY);
- v.vector[2] = xFixed1;
- PictureTransformPoint(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(transform[1], &v);
- maskXend = xFixedToInt(v.vector[0]);
- maskYend = xFixedToInt(v.vector[1]);
- }
- R128WaitForFifo(pScrn, 3 + 4 * VTX_RING_COUNT);
- OUTREG(0, CCE_PACKET3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 2 + 4 * VTX_RING_COUNT - 1));
- OUTREG(0, R128_CCE_VC_FRMT_RHW |
- R128_CCE_VC_FRMT_S_T |
- R128_CCE_VC_FRMT_S2_T2);
- OUTREG(0, R128_CCE_VC_CNTL_PRIM_TYPE_TRI_FAN |
- R128_CCE_VC_CNTL_PRIM_WALK_RING |
- (4 << R128_CCE_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);
- }
- #define R128DoneComposite R128Done
- #endif
- static void
- R128Sync(ScreenPtr pScreen, int marker)
- {
- R128WaitForIdle(xf86Screens[pScreen->myNum]);
- }
- static void
- R128Done(PixmapPtr pPixmap)
- {
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- R128InfoPtr info = R128PTR(pScrn);
- info->state_2d.in_use = FALSE;
- #ifdef RENDER
- if (info->state_2d.src_pix) {
- pScreen->DestroyPixmap(info->state_2d.src_pix);
- info->state_2d.src_pix = NULL;
- R128TRACE(("Did it\n"));
- }
- if (info->state_2d.msk_pix) {
- pScreen->DestroyPixmap(info->state_2d.msk_pix);
- info->state_2d.msk_pix = NULL;
- }
- #endif
- }
- #ifdef R128DRI
- #define R128CCEPrepareSolid R128PrepareSolid
- static void
- R128CCESolid(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
- {
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- R128InfoPtr info = R128PTR(pScrn);
- RING_LOCALS;
- R128CCE_REFRESH( pScrn, info );
- BEGIN_RING( 4 );
- OUT_RING_REG( R128_DST_Y_X, (y1 << 16) | x1 );
- OUT_RING_REG( R128_DST_WIDTH_HEIGHT, ((x2-x1) << 16) | (y2-y1) );
- ADVANCE_RING();
- }
- #define R128CCEDoneSolid R128Done
- #define R128CCEPrepareCopy R128PrepareCopy
- static void
- R128CCECopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
- int width, int height)
- {
- ScreenPtr pScreen = pDstPixmap->drawable.pScreen;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- R128InfoPtr info = R128PTR(pScrn);
- RING_LOCALS;
- R128CCE_REFRESH( pScrn, info );
- if (info->xdir < 0) srcX += width - 1, dstX += width - 1;
- if (info->ydir < 0) srcY += height - 1, dstY += height - 1;
- BEGIN_RING( 6 );
- OUT_RING_REG( R128_SRC_Y_X, (srcY << 16) | srcX );
- OUT_RING_REG( R128_DST_Y_X, (dstY << 16) | dstX );
- OUT_RING_REG( R128_DST_HEIGHT_WIDTH, (height << 16) | width );
- ADVANCE_RING();
- }
- #define R128CCEDoneCopy R128Done
- #ifdef RENDER
- #define R128CCECheckComposite R128CheckComposite
- static Bool
- R128CCEPrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
- PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
- {
- ScreenPtr pScreen = pDst->drawable.pScreen;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- R128InfoPtr info = R128PTR(pScrn);
- 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 dst_pitch_offset, color_factor, in_color_factor, alpha_comb;
- uint32_t blend_cntl;
- 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;
- R128TRACE(("Doing it, %d\n", op));
- }
- if (pMaskPicture && !pMask) {
- pMask = R128SolidPixmap(pScreen, cpu_to_le32(pMaskPicture->pSourcePict->solidFill.color));
- if (!pMask) {
- if (!pSrcPicture->pDrawable)
- pScreen->DestroyPixmap(pSrc);
- R128TRACE(("Failed to create solid scratch pixmap\n"));
- return FALSE;
- }
- add_msk = TRUE;
- }
- if (!R128TextureSetup(pSrcPicture, pSrc, 0, &txsize, &prim_tex_cntl_c, add_src)) return FALSE;
- if (pMask != NULL) {
- if (!R128TextureSetup(pMaskPicture, pMask, 1, &txsize, &sec_tex_cntl_c, add_src)) return FALSE;
- } else {
- is_transform[1] = FALSE;
- }
- if (!R128GetPixmapOffsetPitch(pDst, &dst_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;
- blend_cntl = R128BlendOp[op].blendctl;
- if (PICT_FORMAT_A(pDstPicture->format) == 0 && R128BlendOp[op].dst_alpha) {
- if ((blend_cntl & R128_SBLEND_MASK) == R128_SBLEND_DST_ALPHA)
- blend_cntl = (blend_cntl & ~R128_SBLEND_MASK) | R128_SBLEND_ONE;
- else if ((blend_cntl & R128_SBLEND_MASK) == R128_SBLEND_INV_DST_ALPHA)
- blend_cntl = (blend_cntl & ~R128_SBLEND_MASK) | R128_SBLEND_ZERO;
- }
- R128CCE_REFRESH( pScrn, info );
- BEGIN_RING( 12 );
- 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_DST_PITCH_OFFSET, dst_pitch_offset);
- OUT_RING_REG(R128_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 << 16) |
- 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);
- 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_REG_PRIM_TEX_CNTL_C,
- * R128_REG_PRIM_TEXTURE_COMBINE_CNTL_C,
- * R128_REG_TEX_SIZE_PITCH_C,
- * R128_REG_PRIM_TEX_0_OFFSET_C - R128_REG_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(((CARD8 *)pSrc->devPrivate.ptr - info->ExaDriver->memoryBase));
- ADVANCE_RING();
- if (pMask != NULL) {
- BEGIN_RING( 14 );
- /* R128_REG_SEC_TEX_CNTL_C,
- * R128_REG_SEC_TEXTURE_COMBINE_CNTL_C,
- * R128_REG_SEC_TEX_0_OFFSET_C - R128_REG_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(((CARD8 *)pMask->devPrivate.ptr - info->ExaDriver->memoryBase));
- ADVANCE_RING();
- }
- return TRUE;
- }
- 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 = xf86Screens[pScreen->myNum];
- 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 (is_transform[0]) {
- v.vector[0] = IntToxFixed(srcX);
- v.vector[1] = IntToxFixed(srcY);
- v.vector[2] = xFixed1;
- PictureTransformPoint(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(transform[0], &v);
- srcXend = xFixedToInt(v.vector[0]);
- srcYend = xFixedToInt(v.vector[1]);
- }
- if (is_transform[1]) {
- v.vector[0] = IntToxFixed(maskX);
- v.vector[1] = IntToxFixed(maskY);
- v.vector[2] = xFixed1;
- PictureTransformPoint(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(transform[1], &v);
- maskXend = xFixedToInt(v.vector[0]);
- maskYend = xFixedToInt(v.vector[1]);
- }
- R128CCE_REFRESH( pScrn, info );
- BEGIN_RING( 3 + 4 * VTX_RING_COUNT );
- OUT_RING(CCE_PACKET3(R128_CCE_PACKET3_3D_RNDR_GEN_PRIM, 2 + 4 * VTX_RING_COUNT - 1));
- OUT_RING(R128_CCE_VC_FRMT_RHW |
- R128_CCE_VC_FRMT_S_T |
- R128_CCE_VC_FRMT_S2_T2);
- OUT_RING(R128_CCE_VC_CNTL_PRIM_TYPE_TRI_FAN |
- R128_CCE_VC_CNTL_PRIM_WALK_RING |
- (4 << R128_CCE_VC_CNTL_NUM_SHIFT));
- VTX_CCE_OUT(dstX, dstY, srcX, srcY, maskX, maskY);
- VTX_CCE_OUT(dstX, dstY + h, srcX, srcYend, maskX, maskYend);
- VTX_CCE_OUT(dstX + w, dstY + h, srcXend, srcYend, maskXend, maskYend);
- VTX_CCE_OUT(dstX + w, dstY, srcXend, srcY, maskXend, maskY);
- ADVANCE_RING();
- }
- #define R128CCEDoneComposite R128Done
- #endif
- static void
- R128CCESync(ScreenPtr pScreen, int marker)
- {
- R128CCEWaitForIdle(xf86Screens[pScreen->myNum]);
- }
- #endif
- Bool
- R128EXAInit(ScreenPtr pScreen)
- {
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- R128InfoPtr info = R128PTR(pScrn);
- info->ExaDriver->exa_major = EXA_VERSION_MAJOR;
- info->ExaDriver->exa_minor = EXA_VERSION_MINOR;
- info->ExaDriver->memoryBase = info->FB + pScrn->fbOffset;
- info->ExaDriver->flags = EXA_OFFSCREEN_PIXMAPS | EXA_OFFSCREEN_ALIGN_POT;
- #if EXA_VERSION_MAJOR > 2 || (EXA_VERSION_MAJOR == 2 && EXA_VERSION_MINOR >= 3)
- info->ExaDriver->maxPitchBytes = 16320;
- #endif
- /* Pitch alignment is in sets of 8 pixels, and we need to cover 32bpp, so it's 32 bytes */
- info->ExaDriver->pixmapPitchAlign = 32;
- info->ExaDriver->pixmapOffsetAlign = 32;
- info->ExaDriver->maxX = 2048;
- info->ExaDriver->maxY = 2048;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Setting up EXA callbacks\n");
- #ifdef R128DRI
- if (info->directRenderingEnabled) {
- info->ExaDriver->PrepareSolid = R128CCEPrepareSolid;
- info->ExaDriver->Solid = R128CCESolid;
- info->ExaDriver->DoneSolid = R128CCEDoneSolid;
- info->ExaDriver->PrepareCopy = R128CCEPrepareCopy;
- info->ExaDriver->Copy = R128CCECopy;
- info->ExaDriver->DoneCopy = R128CCEDoneCopy;
- #ifdef RENDER
- info->ExaDriver->CheckComposite = R128CCECheckComposite;
- info->ExaDriver->PrepareComposite = R128CCEPrepareComposite;
- info->ExaDriver->Composite = R128CCEComposite;
- info->ExaDriver->DoneComposite = R128CCEDoneComposite;
- #endif
- info->ExaDriver->WaitMarker = R128CCESync;
- } else
- #endif
- {
- info->ExaDriver->PrepareSolid = R128PrepareSolid;
- info->ExaDriver->Solid = R128Solid;
- info->ExaDriver->DoneSolid = R128DoneSolid;
- info->ExaDriver->PrepareCopy = R128PrepareCopy;
- info->ExaDriver->Copy = R128Copy;
- info->ExaDriver->DoneCopy = R128DoneCopy;
- #ifdef RENDER
- info->ExaDriver->CheckComposite = R128CheckComposite;
- info->ExaDriver->PrepareComposite = R128PrepareComposite;
- info->ExaDriver->Composite = R128Composite;
- info->ExaDriver->DoneComposite = R128DoneComposite;
- #endif
- info->ExaDriver->WaitMarker = R128Sync;
- }
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Initalizing 2D acceleration engine...\n");
- R128EngineInit(pScrn);
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Initializing EXA driver...\n");
- if (!exaDriverInit(pScreen, info->ExaDriver)) {
- free(info->ExaDriver);
- return FALSE;
- }
- exaMarkSync(pScreen);
- return TRUE;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement