190b17f1bSmrg/* 290b17f1bSmrg * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. 390b17f1bSmrg * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved. 490b17f1bSmrg * Copyright 2006 Thomas Hellström. All Rights Reserved. 590b17f1bSmrg * 690b17f1bSmrg * Permission is hereby granted, free of charge, to any person obtaining a 790b17f1bSmrg * copy of this software and associated documentation files (the "Software"), 890b17f1bSmrg * to deal in the Software without restriction, including without limitation 990b17f1bSmrg * the rights to use, copy, modify, merge, publish, distribute, sub license, 1090b17f1bSmrg * and/or sell copies of the Software, and to permit persons to whom the 1190b17f1bSmrg * Software is furnished to do so, subject to the following conditions: 1290b17f1bSmrg * 1390b17f1bSmrg * The above copyright notice and this permission notice (including the 1490b17f1bSmrg * next paragraph) shall be included in all copies or substantial portions 1590b17f1bSmrg * of the Software. 1690b17f1bSmrg * 1790b17f1bSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1890b17f1bSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1990b17f1bSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 2090b17f1bSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 2190b17f1bSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 2290b17f1bSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 2390b17f1bSmrg * DEALINGS IN THE SOFTWARE. 2490b17f1bSmrg */ 2590b17f1bSmrg 2690b17f1bSmrg/* 2790b17f1bSmrg * 2D acceleration functions for the VIA/S3G UniChrome IGPs. 2890b17f1bSmrg * 2990b17f1bSmrg * Mostly rewritten, and modified for EXA support, by Thomas Hellström. 3090b17f1bSmrg */ 3190b17f1bSmrg 3290b17f1bSmrg#ifdef HAVE_CONFIG_H 3390b17f1bSmrg#include "config.h" 3490b17f1bSmrg#endif 3590b17f1bSmrg 3690b17f1bSmrg#include <X11/Xarch.h> 3790b17f1bSmrg#include "miline.h" 3890b17f1bSmrg 3990b17f1bSmrg#include "via_driver.h" 4090b17f1bSmrg#include "via_regs.h" 4190b17f1bSmrg#include "via_dmabuffer.h" 4290b17f1bSmrg#include "via_rop.h" 4390b17f1bSmrg 4490b17f1bSmrg/* 4590b17f1bSmrg * Emit clipping borders to the command buffer and update the 2D context 4690b17f1bSmrg * current command with clipping info. 4790b17f1bSmrg */ 4890b17f1bSmrgstatic int 4990b17f1bSmrgviaAccelClippingHelper_H2(VIAPtr pVia, int refY) 5090b17f1bSmrg{ 5190b17f1bSmrg ViaTwodContext *tdc = &pVia->td; 5290b17f1bSmrg 5390b17f1bSmrg RING_VARS; 5490b17f1bSmrg 5590b17f1bSmrg if (tdc->clipping) { 5690b17f1bSmrg refY = (refY < tdc->clipY1) ? refY : tdc->clipY1; 5790b17f1bSmrg tdc->cmd |= VIA_GEC_CLIP_ENABLE; 5890b17f1bSmrg BEGIN_RING(4); 5990b17f1bSmrg OUT_RING_H1(VIA_REG_CLIPTL, 6090b17f1bSmrg ((tdc->clipY1 - refY) << 16) | tdc->clipX1); 6190b17f1bSmrg OUT_RING_H1(VIA_REG_CLIPBR, 6290b17f1bSmrg ((tdc->clipY2 - refY) << 16) | tdc->clipX2); 6390b17f1bSmrg } else { 6490b17f1bSmrg tdc->cmd &= ~VIA_GEC_CLIP_ENABLE; 6590b17f1bSmrg } 6690b17f1bSmrg return refY; 6790b17f1bSmrg} 6890b17f1bSmrg 6990b17f1bSmrg/* 7090b17f1bSmrg * Check if we can use a planeMask and update the 2D context accordingly. 7190b17f1bSmrg */ 7290b17f1bSmrgstatic Bool 7390b17f1bSmrgviaAccelPlaneMaskHelper_H2(ViaTwodContext * tdc, CARD32 planeMask) 7490b17f1bSmrg{ 7590b17f1bSmrg CARD32 modeMask = (1 << ((1 << tdc->bytesPPShift) << 3)) - 1; 7690b17f1bSmrg CARD32 curMask = 0x00000000; 7790b17f1bSmrg CARD32 curByteMask; 7890b17f1bSmrg int i; 7990b17f1bSmrg 8090b17f1bSmrg if ((planeMask & modeMask) != modeMask) { 8190b17f1bSmrg 8290b17f1bSmrg /* Masking doesn't work in 8bpp. */ 8390b17f1bSmrg if (modeMask == 0xFF) { 8490b17f1bSmrg tdc->keyControl &= 0x0FFFFFFF; 8590b17f1bSmrg return FALSE; 8690b17f1bSmrg } 8790b17f1bSmrg 8890b17f1bSmrg /* Translate the bit planemask to a byte planemask. */ 8990b17f1bSmrg for (i = 0; i < (1 << tdc->bytesPPShift); ++i) { 9090b17f1bSmrg curByteMask = (0xFF << (i << 3)); 9190b17f1bSmrg 9290b17f1bSmrg if ((planeMask & curByteMask) == 0) { 9390b17f1bSmrg curMask |= (1 << i); 9490b17f1bSmrg } else if ((planeMask & curByteMask) != curByteMask) { 9590b17f1bSmrg tdc->keyControl &= 0x0FFFFFFF; 9690b17f1bSmrg return FALSE; 9790b17f1bSmrg } 9890b17f1bSmrg } 9990b17f1bSmrg ErrorF("DEBUG: planeMask 0x%08x, curMask 0%02x\n", 10090b17f1bSmrg (unsigned)planeMask, (unsigned)curMask); 10190b17f1bSmrg 10290b17f1bSmrg tdc->keyControl = (tdc->keyControl & 0x0FFFFFFF) | (curMask << 28); 10390b17f1bSmrg } 10490b17f1bSmrg 10590b17f1bSmrg return TRUE; 10690b17f1bSmrg} 10790b17f1bSmrg 10890b17f1bSmrg/* 10990b17f1bSmrg * Emit transparency state and color to the command buffer. 11090b17f1bSmrg */ 11190b17f1bSmrgstatic void 11290b17f1bSmrgviaAccelTransparentHelper_H2(VIAPtr pVia, CARD32 keyControl, 11390b17f1bSmrg CARD32 transColor, Bool usePlaneMask) 11490b17f1bSmrg{ 11590b17f1bSmrg ViaTwodContext *tdc = &pVia->td; 11690b17f1bSmrg 11790b17f1bSmrg RING_VARS; 11890b17f1bSmrg 11990b17f1bSmrg tdc->keyControl &= ((usePlaneMask) ? 0xF0000000 : 0x00000000); 12090b17f1bSmrg tdc->keyControl |= (keyControl & 0x0FFFFFFF); 12190b17f1bSmrg BEGIN_RING(4); 12290b17f1bSmrg OUT_RING_H1(VIA_REG_KEYCONTROL, tdc->keyControl); 12390b17f1bSmrg if (keyControl) { 12490b17f1bSmrg OUT_RING_H1(VIA_REG_SRCCOLORKEY, transColor); 12590b17f1bSmrg } 12690b17f1bSmrg} 12790b17f1bSmrg 12890b17f1bSmrg/* 12990b17f1bSmrg * Mark Sync using the 2D blitter for AGP. NoOp for PCI. 13090b17f1bSmrg * In the future one could even launch a NULL PCI DMA command 13190b17f1bSmrg * to have an interrupt generated, provided it is possible to 13290b17f1bSmrg * write to the PCI DMA engines from the AGP command stream. 13390b17f1bSmrg */ 13490b17f1bSmrgint 13590b17f1bSmrgviaAccelMarkSync_H2(ScreenPtr pScreen) 13690b17f1bSmrg{ 13790b17f1bSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 13890b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 13990b17f1bSmrg 14090b17f1bSmrg RING_VARS; 14190b17f1bSmrg 14290b17f1bSmrg ++pVia->curMarker; 14390b17f1bSmrg 14490b17f1bSmrg /* Wrap around without affecting the sign bit. */ 14590b17f1bSmrg pVia->curMarker &= 0x7FFFFFFF; 14690b17f1bSmrg 14790b17f1bSmrg if (pVia->agpDMA) { 14890b17f1bSmrg BEGIN_RING(16); 14990b17f1bSmrg OUT_RING_H1(VIA_REG_KEYCONTROL, 0x00); 15090b17f1bSmrg OUT_RING_H1(VIA_REG_GEMODE, VIA_GEM_32bpp); 15190b17f1bSmrg OUT_RING_H1(VIA_REG_DSTBASE, pVia->markerOffset >> 3); 15290b17f1bSmrg OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE); 15390b17f1bSmrg OUT_RING_H1(VIA_REG_DSTPOS, 0); 15490b17f1bSmrg OUT_RING_H1(VIA_REG_DIMENSION, 0); 15590b17f1bSmrg OUT_RING_H1(VIA_REG_FGCOLOR, pVia->curMarker); 15690b17f1bSmrg OUT_RING_H1(VIA_REG_GECMD, (0xF0 << 24) | VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT); 15790b17f1bSmrg 15890b17f1bSmrg ADVANCE_RING; 15990b17f1bSmrg } 16090b17f1bSmrg return pVia->curMarker; 16190b17f1bSmrg} 16290b17f1bSmrg 16390b17f1bSmrg/* 16490b17f1bSmrg * Exa functions. It is assumed that EXA does not exceed the blitter limits. 16590b17f1bSmrg */ 16690b17f1bSmrgBool 16790b17f1bSmrgviaExaPrepareSolid_H2(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg) 16890b17f1bSmrg{ 16990b17f1bSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen); 17090b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 17190b17f1bSmrg ViaTwodContext *tdc = &pVia->td; 17290b17f1bSmrg 17390b17f1bSmrg if (exaGetPixmapPitch(pPixmap) & 7) 17490b17f1bSmrg return FALSE; 17590b17f1bSmrg 17690b17f1bSmrg if (!viaAccelSetMode(pPixmap->drawable.depth, tdc)) 17790b17f1bSmrg return FALSE; 17890b17f1bSmrg 17990b17f1bSmrg if (!viaAccelPlaneMaskHelper_H2(tdc, planeMask)) 18090b17f1bSmrg return FALSE; 18190b17f1bSmrg 18290b17f1bSmrg viaAccelTransparentHelper_H2(pVia, 0x0, 0x0, TRUE); 18390b17f1bSmrg 18490b17f1bSmrg tdc->cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(alu); 18590b17f1bSmrg 18690b17f1bSmrg tdc->fgColor = fg; 18790b17f1bSmrg 18890b17f1bSmrg return TRUE; 18990b17f1bSmrg} 19090b17f1bSmrg 19190b17f1bSmrgvoid 19290b17f1bSmrgviaExaSolid_H2(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) 19390b17f1bSmrg{ 19490b17f1bSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen); 19590b17f1bSmrg CARD32 dstOffset = exaGetPixmapOffset(pPixmap); 19690b17f1bSmrg CARD32 dstPitch = exaGetPixmapPitch(pPixmap); 19790b17f1bSmrg int w = x2 - x1, h = y2 - y1; 19890b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 19990b17f1bSmrg ViaTwodContext *tdc = &pVia->td; 20090b17f1bSmrg 20190b17f1bSmrg RING_VARS; 20290b17f1bSmrg 20390b17f1bSmrg BEGIN_RING(14); 20490b17f1bSmrg OUT_RING_H1(VIA_REG_GEMODE, tdc->mode); 20590b17f1bSmrg OUT_RING_H1(VIA_REG_DSTBASE, dstOffset >> 3); 20690b17f1bSmrg OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE | (dstPitch >> 3) << 16); 20790b17f1bSmrg OUT_RING_H1(VIA_REG_DSTPOS, (y1 << 16) | (x1 & 0xFFFF)); 20890b17f1bSmrg OUT_RING_H1(VIA_REG_DIMENSION, ((h - 1) << 16) | (w - 1)); 20990b17f1bSmrg OUT_RING_H1(VIA_REG_FGCOLOR, tdc->fgColor); 21090b17f1bSmrg OUT_RING_H1(VIA_REG_GECMD, tdc->cmd); 21190b17f1bSmrg 21290b17f1bSmrg ADVANCE_RING; 21390b17f1bSmrg} 21490b17f1bSmrg 21590b17f1bSmrgvoid 21690b17f1bSmrgviaExaDoneSolidCopy_H2(PixmapPtr pPixmap) 21790b17f1bSmrg{ 21890b17f1bSmrg} 21990b17f1bSmrg 22090b17f1bSmrgBool 22190b17f1bSmrgviaExaPrepareCopy_H2(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, 22290b17f1bSmrg int ydir, int alu, Pixel planeMask) 22390b17f1bSmrg{ 22490b17f1bSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPixmap->drawable.pScreen); 22590b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 22690b17f1bSmrg ViaTwodContext *tdc = &pVia->td; 22790b17f1bSmrg 22890b17f1bSmrg if (pSrcPixmap->drawable.bitsPerPixel != pDstPixmap->drawable.bitsPerPixel) 22990b17f1bSmrg return FALSE; 23090b17f1bSmrg 23190b17f1bSmrg if ((tdc->srcPitch = exaGetPixmapPitch(pSrcPixmap)) & 3) 23290b17f1bSmrg return FALSE; 23390b17f1bSmrg 23490b17f1bSmrg if (exaGetPixmapPitch(pDstPixmap) & 7) 23590b17f1bSmrg return FALSE; 23690b17f1bSmrg 23790b17f1bSmrg tdc->srcOffset = exaGetPixmapOffset(pSrcPixmap); 23890b17f1bSmrg 23990b17f1bSmrg tdc->cmd = VIA_GEC_BLT | VIAACCELCOPYROP(alu); 24090b17f1bSmrg if (xdir < 0) 24190b17f1bSmrg tdc->cmd |= VIA_GEC_DECX; 24290b17f1bSmrg if (ydir < 0) 24390b17f1bSmrg tdc->cmd |= VIA_GEC_DECY; 24490b17f1bSmrg 24590b17f1bSmrg if (!viaAccelSetMode(pDstPixmap->drawable.bitsPerPixel, tdc)) 24690b17f1bSmrg return FALSE; 24790b17f1bSmrg 24890b17f1bSmrg if (!viaAccelPlaneMaskHelper_H2(tdc, planeMask)) 24990b17f1bSmrg return FALSE; 25090b17f1bSmrg viaAccelTransparentHelper_H2(pVia, 0x0, 0x0, TRUE); 25190b17f1bSmrg 25290b17f1bSmrg return TRUE; 25390b17f1bSmrg} 25490b17f1bSmrg 25590b17f1bSmrgvoid 25690b17f1bSmrgviaExaCopy_H2(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, 25790b17f1bSmrg int width, int height) 25890b17f1bSmrg{ 25990b17f1bSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPixmap->drawable.pScreen); 26090b17f1bSmrg CARD32 dstOffset = exaGetPixmapOffset(pDstPixmap), val; 26190b17f1bSmrg CARD32 dstPitch = exaGetPixmapPitch(pDstPixmap); 26290b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 26390b17f1bSmrg ViaTwodContext *tdc = &pVia->td; 26490b17f1bSmrg 26590b17f1bSmrg if (!width || !height) 26690b17f1bSmrg return; 26790b17f1bSmrg 26890b17f1bSmrg if (tdc->cmd & VIA_GEC_DECY) { 26990b17f1bSmrg srcY += height - 1; 27090b17f1bSmrg dstY += height - 1; 27190b17f1bSmrg } 27290b17f1bSmrg 27390b17f1bSmrg if (tdc->cmd & VIA_GEC_DECX) { 27490b17f1bSmrg srcX += width - 1; 27590b17f1bSmrg dstX += width - 1; 27690b17f1bSmrg } 27790b17f1bSmrg val = VIA_PITCH_ENABLE | (dstPitch >> 3) << 16 | (tdc->srcPitch >> 3); 27890b17f1bSmrg 27990b17f1bSmrg RING_VARS; 28090b17f1bSmrg 28190b17f1bSmrg BEGIN_RING(16); 28290b17f1bSmrg OUT_RING_H1(VIA_REG_GEMODE, tdc->mode); 28390b17f1bSmrg OUT_RING_H1(VIA_REG_SRCBASE, tdc->srcOffset >> 3); 28490b17f1bSmrg OUT_RING_H1(VIA_REG_DSTBASE, dstOffset >> 3); 28590b17f1bSmrg OUT_RING_H1(VIA_REG_PITCH, val); 28690b17f1bSmrg OUT_RING_H1(VIA_REG_SRCPOS, (srcY << 16) | (srcX & 0xFFFF)); 28790b17f1bSmrg OUT_RING_H1(VIA_REG_DSTPOS, (dstY << 16) | (dstX & 0xFFFF)); 28890b17f1bSmrg OUT_RING_H1(VIA_REG_DIMENSION, ((height - 1) << 16) | (width - 1)); 28990b17f1bSmrg OUT_RING_H1(VIA_REG_GECMD, tdc->cmd); 29090b17f1bSmrg 29190b17f1bSmrg ADVANCE_RING; 29290b17f1bSmrg} 29390b17f1bSmrg 29490b17f1bSmrgBool 29590b17f1bSmrgviaExaCheckComposite_H2(int op, PicturePtr pSrcPicture, 29690b17f1bSmrg PicturePtr pMaskPicture, PicturePtr pDstPicture) 29790b17f1bSmrg{ 29890b17f1bSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPicture->pDrawable->pScreen); 29990b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 30090b17f1bSmrg Via3DState *v3d = &pVia->v3d; 30190b17f1bSmrg 30290b17f1bSmrg if (!pSrcPicture->pDrawable) 30390b17f1bSmrg return FALSE; 30490b17f1bSmrg 30590b17f1bSmrg /* Reject small composites early. They are done much faster in software. */ 30690b17f1bSmrg if (!pSrcPicture->repeat && 30790b17f1bSmrg pSrcPicture->pDrawable->width * 30890b17f1bSmrg pSrcPicture->pDrawable->height < VIA_MIN_COMPOSITE) 30990b17f1bSmrg return FALSE; 31090b17f1bSmrg 31190b17f1bSmrg if (pMaskPicture && pMaskPicture->pDrawable && 31290b17f1bSmrg !pMaskPicture->repeat && 31390b17f1bSmrg pMaskPicture->pDrawable->width * 31490b17f1bSmrg pMaskPicture->pDrawable->height < VIA_MIN_COMPOSITE) 31590b17f1bSmrg return FALSE; 31690b17f1bSmrg 31790b17f1bSmrg if (pMaskPicture && pMaskPicture->repeat && 31890b17f1bSmrg pMaskPicture->repeatType != RepeatNormal) 31990b17f1bSmrg return FALSE; 32090b17f1bSmrg 32190b17f1bSmrg if (pMaskPicture && pMaskPicture->componentAlpha) { 32290b17f1bSmrg#ifdef VIA_DEBUG_COMPOSITE 32390b17f1bSmrg viaExaPrintCompositeInfo("Component Alpha operation", op, pSrcPicture, pMaskPicture, pDstPicture); 32490b17f1bSmrg#endif 32590b17f1bSmrg return FALSE; 32690b17f1bSmrg } 32790b17f1bSmrg 32890b17f1bSmrg if (!v3d->opSupported(op)) { 32990b17f1bSmrg#ifdef VIA_DEBUG_COMPOSITE 33090b17f1bSmrg viaExaPrintCompositeInfo("Operator not supported", op, pSrcPicture, pMaskPicture, pDstPicture); 33190b17f1bSmrg#endif 33290b17f1bSmrg return FALSE; 33390b17f1bSmrg } 33490b17f1bSmrg 33590b17f1bSmrg /* 33690b17f1bSmrg * FIXME: A8 destination formats are currently not supported and do not 33790b17f1bSmrg * seem supported by the hardware, although there are some leftover 33890b17f1bSmrg * register settings apparent in the via_3d_reg.h file. We need to fix this 33990b17f1bSmrg * (if important), by using component ARGB8888 operations with bitmask. 34090b17f1bSmrg */ 34190b17f1bSmrg 34290b17f1bSmrg if (!v3d->dstSupported(pDstPicture->format)) { 34390b17f1bSmrg#ifdef VIA_DEBUG_COMPOSITE 34490b17f1bSmrg viaExaPrintCompositeInfo(" Destination format not supported", op, pSrcPicture, pMaskPicture, pDstPicture); 34590b17f1bSmrg#endif 34690b17f1bSmrg return FALSE; 34790b17f1bSmrg } 34890b17f1bSmrg 34990b17f1bSmrg if (v3d->texSupported(pSrcPicture->format)) { 35090b17f1bSmrg if (pMaskPicture && (PICT_FORMAT_A(pMaskPicture->format) == 0 || 35190b17f1bSmrg !v3d->texSupported(pMaskPicture->format))) { 35290b17f1bSmrg#ifdef VIA_DEBUG_COMPOSITE 35390b17f1bSmrg viaExaPrintCompositeInfo("Mask format not supported", op, pSrcPicture, pMaskPicture, pDstPicture); 35490b17f1bSmrg#endif 35590b17f1bSmrg return FALSE; 35690b17f1bSmrg } 35790b17f1bSmrg return TRUE; 35890b17f1bSmrg } 35990b17f1bSmrg#ifdef VIA_DEBUG_COMPOSITE 36090b17f1bSmrg viaExaPrintCompositeInfo("Src format not supported", op, pSrcPicture, pMaskPicture, pDstPicture); 36190b17f1bSmrg#endif 36290b17f1bSmrg return FALSE; 36390b17f1bSmrg} 36490b17f1bSmrg 36590b17f1bSmrgstatic Bool 36690b17f1bSmrgviaIsAGP(VIAPtr pVia, PixmapPtr pPix, unsigned long *offset) 36790b17f1bSmrg{ 36890b17f1bSmrg#ifdef HAVE_DRI 36990b17f1bSmrg unsigned long offs; 37090b17f1bSmrg 37190b17f1bSmrg if (pVia->directRenderingType && !pVia->IsPCI) { 37290b17f1bSmrg offs = ((unsigned long)pPix->devPrivate.ptr 37390b17f1bSmrg - (unsigned long)pVia->agpMappedAddr); 37490b17f1bSmrg 37590b17f1bSmrg if ((offs - pVia->scratchOffset) < pVia->agpSize) { 37690b17f1bSmrg *offset = offs + pVia->agpAddr; 37790b17f1bSmrg return TRUE; 37890b17f1bSmrg } 37990b17f1bSmrg } 38090b17f1bSmrg#endif 38190b17f1bSmrg return FALSE; 38290b17f1bSmrg} 38390b17f1bSmrg 38490b17f1bSmrgstatic Bool 38590b17f1bSmrgviaExaIsOffscreen(PixmapPtr pPix) 38690b17f1bSmrg{ 38790b17f1bSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pPix->drawable.pScreen); 38890b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 38990b17f1bSmrg 39090b17f1bSmrg return ((unsigned long)pPix->devPrivate.ptr - 39190b17f1bSmrg (unsigned long) drm_bo_map(pScrn, pVia->drmmode.front_bo)) < pVia->drmmode.front_bo->size; 39290b17f1bSmrg} 39390b17f1bSmrg 39490b17f1bSmrgBool 39590b17f1bSmrgviaExaPrepareComposite_H2(int op, PicturePtr pSrcPicture, 39690b17f1bSmrg PicturePtr pMaskPicture, PicturePtr pDstPicture, 39790b17f1bSmrg PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) 39890b17f1bSmrg{ 39990b17f1bSmrg CARD32 height, width; 40090b17f1bSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pDst->drawable.pScreen); 40190b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 40290b17f1bSmrg Via3DState *v3d = &pVia->v3d; 40390b17f1bSmrg int curTex = 0; 40490b17f1bSmrg ViaTexBlendingModes srcMode; 40590b17f1bSmrg Bool isAGP; 40690b17f1bSmrg unsigned long offset; 40790b17f1bSmrg 40890b17f1bSmrg /* Workaround: EXA crash with new libcairo2 on a VIA VX800 (#298) */ 40990b17f1bSmrg /* TODO Add real source only pictures */ 41090b17f1bSmrg if (!pSrc) { 41190b17f1bSmrg ErrorF("pSrc is NULL\n"); 41290b17f1bSmrg return FALSE; 41390b17f1bSmrg } 41490b17f1bSmrg 41590b17f1bSmrg v3d->setDestination(v3d, exaGetPixmapOffset(pDst), 41690b17f1bSmrg exaGetPixmapPitch(pDst), pDstPicture->format); 41790b17f1bSmrg v3d->setCompositeOperator(v3d, op); 41890b17f1bSmrg v3d->setDrawing(v3d, 0x0c, 0xFFFFFFFF, 0x000000FF, 0xFF); 41990b17f1bSmrg 42090b17f1bSmrg viaOrder(pSrc->drawable.width, &width); 42190b17f1bSmrg viaOrder(pSrc->drawable.height, &height); 42290b17f1bSmrg 42390b17f1bSmrg /* 42490b17f1bSmrg * For one-pixel repeat mask pictures we avoid using multitexturing by 42590b17f1bSmrg * modifying the src's texture blending equation and feed the pixel 42690b17f1bSmrg * value as a constant alpha for the src's texture. Multitexturing on the 42790b17f1bSmrg * Unichromes seems somewhat slow, so this speeds up translucent windows. 42890b17f1bSmrg */ 42990b17f1bSmrg 43090b17f1bSmrg srcMode = via_src; 43190b17f1bSmrg pVia->maskP = NULL; 43290b17f1bSmrg if (pMaskPicture && 43390b17f1bSmrg (pMaskPicture->pDrawable->height == 1) && 43490b17f1bSmrg (pMaskPicture->pDrawable->width == 1) && 43590b17f1bSmrg pMaskPicture->repeat && viaExpandablePixel(pMaskPicture->format)) { 43690b17f1bSmrg pVia->maskP = pMask->devPrivate.ptr; 43790b17f1bSmrg pVia->maskFormat = pMaskPicture->format; 43890b17f1bSmrg pVia->componentAlpha = pMaskPicture->componentAlpha; 43990b17f1bSmrg srcMode = ((pMaskPicture->componentAlpha) 44090b17f1bSmrg ? via_src_onepix_comp_mask : via_src_onepix_mask); 44190b17f1bSmrg } 44290b17f1bSmrg 44390b17f1bSmrg /* 44490b17f1bSmrg * One-Pixel repeat src pictures go as solid color instead of textures. 44590b17f1bSmrg * Speeds up window shadows. 44690b17f1bSmrg */ 44790b17f1bSmrg 44890b17f1bSmrg pVia->srcP = NULL; 44990b17f1bSmrg if (pSrcPicture && pSrcPicture->repeat 45090b17f1bSmrg && (pSrcPicture->pDrawable->height == 1) 45190b17f1bSmrg && (pSrcPicture->pDrawable->width == 1) 45290b17f1bSmrg && viaExpandablePixel(pSrcPicture->format)) { 45390b17f1bSmrg pVia->srcP = pSrc->devPrivate.ptr; 45490b17f1bSmrg pVia->srcFormat = pSrcPicture->format; 45590b17f1bSmrg } 45690b17f1bSmrg 45790b17f1bSmrg /* Exa should be smart enough to eliminate this IN operation. */ 45890b17f1bSmrg if (pVia->srcP && pVia->maskP) { 45990b17f1bSmrg ErrorF("Bad one-pixel IN composite operation. " 46090b17f1bSmrg "EXA needs to be smarter.\n"); 46190b17f1bSmrg return FALSE; 46290b17f1bSmrg } 46390b17f1bSmrg 46490b17f1bSmrg if (!pVia->srcP) { 46590b17f1bSmrg offset = exaGetPixmapOffset(pSrc); 46690b17f1bSmrg isAGP = viaIsAGP(pVia, pSrc, &offset); 46790b17f1bSmrg if (!isAGP && !viaExaIsOffscreen(pSrc)) 46890b17f1bSmrg return FALSE; 46990b17f1bSmrg if (!v3d->setTexture(v3d, curTex, offset, 47090b17f1bSmrg exaGetPixmapPitch(pSrc), pVia->nPOT[curTex], 47190b17f1bSmrg 1 << width, 1 << height, pSrcPicture->format, 47290b17f1bSmrg via_repeat, via_repeat, srcMode, isAGP)) { 47390b17f1bSmrg return FALSE; 47490b17f1bSmrg } 47590b17f1bSmrg curTex++; 47690b17f1bSmrg } 47790b17f1bSmrg 47890b17f1bSmrg if (pMaskPicture && !pVia->maskP) { 47990b17f1bSmrg offset = exaGetPixmapOffset(pMask); 48090b17f1bSmrg isAGP = viaIsAGP(pVia, pMask, &offset); 48190b17f1bSmrg if (!isAGP && !viaExaIsOffscreen(pMask)) 48290b17f1bSmrg return FALSE; 48390b17f1bSmrg viaOrder(pMask->drawable.width, &width); 48490b17f1bSmrg viaOrder(pMask->drawable.height, &height); 48590b17f1bSmrg if (!v3d->setTexture(v3d, curTex, offset, 48690b17f1bSmrg exaGetPixmapPitch(pMask), pVia->nPOT[curTex], 48790b17f1bSmrg 1 << width, 1 << height, pMaskPicture->format, 48890b17f1bSmrg via_repeat, via_repeat, 48990b17f1bSmrg ((pMaskPicture->componentAlpha) 49090b17f1bSmrg ? via_comp_mask : via_mask), isAGP)) { 49190b17f1bSmrg return FALSE; 49290b17f1bSmrg } 49390b17f1bSmrg curTex++; 49490b17f1bSmrg } 49590b17f1bSmrg 49690b17f1bSmrg v3d->setFlags(v3d, curTex, FALSE, TRUE, TRUE); 49790b17f1bSmrg v3d->emitState(v3d, &pVia->cb, viaCheckUpload(pScrn, v3d)); 49890b17f1bSmrg v3d->emitClipRect(v3d, &pVia->cb, 0, 0, pDst->drawable.width, 49990b17f1bSmrg pDst->drawable.height); 50090b17f1bSmrg 50190b17f1bSmrg return TRUE; 50290b17f1bSmrg} 50390b17f1bSmrg 50490b17f1bSmrgvoid 50590b17f1bSmrgviaExaComposite_H2(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, 50690b17f1bSmrg int dstX, int dstY, int width, int height) 50790b17f1bSmrg{ 50890b17f1bSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pDst->drawable.pScreen); 50990b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 51090b17f1bSmrg Via3DState *v3d = &pVia->v3d; 51190b17f1bSmrg CARD32 col; 51290b17f1bSmrg 51390b17f1bSmrg if (pVia->maskP) { 51490b17f1bSmrg viaPixelARGB8888(pVia->maskFormat, pVia->maskP, &col); 51590b17f1bSmrg v3d->setTexBlendCol(v3d, 0, pVia->componentAlpha, col); 51690b17f1bSmrg } 51790b17f1bSmrg if (pVia->srcP) { 51890b17f1bSmrg viaPixelARGB8888(pVia->srcFormat, pVia->srcP, &col); 51990b17f1bSmrg v3d->setDrawing(v3d, 0x0c, 0xFFFFFFFF, col & 0x00FFFFFF, col >> 24); 52090b17f1bSmrg srcX = maskX; 52190b17f1bSmrg srcY = maskY; 52290b17f1bSmrg } 52390b17f1bSmrg 52490b17f1bSmrg if (pVia->maskP || pVia->srcP) 52590b17f1bSmrg v3d->emitState(v3d, &pVia->cb, viaCheckUpload(pScrn, v3d)); 52690b17f1bSmrg 52790b17f1bSmrg v3d->emitQuad(v3d, &pVia->cb, dstX, dstY, srcX, srcY, maskX, maskY, 52890b17f1bSmrg width, height); 52990b17f1bSmrg} 53090b17f1bSmrg 53190b17f1bSmrgvoid 53290b17f1bSmrgviaAccelTextureBlit(ScrnInfoPtr pScrn, unsigned long srcOffset, 53390b17f1bSmrg unsigned srcPitch, unsigned w, unsigned h, unsigned srcX, 53490b17f1bSmrg unsigned srcY, unsigned srcFormat, unsigned long dstOffset, 53590b17f1bSmrg unsigned dstPitch, unsigned dstX, unsigned dstY, 53690b17f1bSmrg unsigned dstFormat, int rotate) 53790b17f1bSmrg{ 53890b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 53990b17f1bSmrg CARD32 wOrder, hOrder; 54090b17f1bSmrg Via3DState *v3d = &pVia->v3d; 54190b17f1bSmrg 54290b17f1bSmrg viaOrder(w, &wOrder); 54390b17f1bSmrg viaOrder(h, &hOrder); 54490b17f1bSmrg 54590b17f1bSmrg v3d->setDestination(v3d, dstOffset, dstPitch, dstFormat); 54690b17f1bSmrg v3d->setDrawing(v3d, 0x0c, 0xFFFFFFFF, 0x000000FF, 0x00); 54790b17f1bSmrg v3d->setFlags(v3d, 1, TRUE, TRUE, FALSE); 54890b17f1bSmrg v3d->setTexture(v3d, 0, srcOffset, srcPitch, TRUE, 54990b17f1bSmrg 1 << wOrder, 1 << hOrder, srcFormat, 55090b17f1bSmrg via_single, via_single, via_src, FALSE); 55190b17f1bSmrg v3d->emitState(v3d, &pVia->cb, viaCheckUpload(pScrn, v3d)); 55290b17f1bSmrg v3d->emitClipRect(v3d, &pVia->cb, dstX, dstY, w, h); 55390b17f1bSmrg v3d->emitQuad(v3d, &pVia->cb, dstX, dstY, srcX, srcY, 0, 0, w, h); 55490b17f1bSmrg} 555