via_exa_h2.c revision 90b17f1b
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 RING_VARS; 17490b17f1bSmrg 17590b17f1bSmrg if (exaGetPixmapPitch(pPixmap) & 7) 17690b17f1bSmrg return FALSE; 17790b17f1bSmrg 17890b17f1bSmrg if (!viaAccelSetMode(pPixmap->drawable.depth, tdc)) 17990b17f1bSmrg return FALSE; 18090b17f1bSmrg 18190b17f1bSmrg if (!viaAccelPlaneMaskHelper_H2(tdc, planeMask)) 18290b17f1bSmrg return FALSE; 18390b17f1bSmrg 18490b17f1bSmrg viaAccelTransparentHelper_H2(pVia, 0x0, 0x0, TRUE); 18590b17f1bSmrg 18690b17f1bSmrg tdc->cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(alu); 18790b17f1bSmrg 18890b17f1bSmrg tdc->fgColor = fg; 18990b17f1bSmrg 19090b17f1bSmrg return TRUE; 19190b17f1bSmrg} 19290b17f1bSmrg 19390b17f1bSmrgvoid 19490b17f1bSmrgviaExaSolid_H2(PixmapPtr pPixmap, int x1, int y1, int x2, int y2) 19590b17f1bSmrg{ 19690b17f1bSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen); 19790b17f1bSmrg CARD32 dstOffset = exaGetPixmapOffset(pPixmap); 19890b17f1bSmrg CARD32 dstPitch = exaGetPixmapPitch(pPixmap); 19990b17f1bSmrg int w = x2 - x1, h = y2 - y1; 20090b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 20190b17f1bSmrg ViaTwodContext *tdc = &pVia->td; 20290b17f1bSmrg 20390b17f1bSmrg RING_VARS; 20490b17f1bSmrg 20590b17f1bSmrg BEGIN_RING(14); 20690b17f1bSmrg OUT_RING_H1(VIA_REG_GEMODE, tdc->mode); 20790b17f1bSmrg OUT_RING_H1(VIA_REG_DSTBASE, dstOffset >> 3); 20890b17f1bSmrg OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE | (dstPitch >> 3) << 16); 20990b17f1bSmrg OUT_RING_H1(VIA_REG_DSTPOS, (y1 << 16) | (x1 & 0xFFFF)); 21090b17f1bSmrg OUT_RING_H1(VIA_REG_DIMENSION, ((h - 1) << 16) | (w - 1)); 21190b17f1bSmrg OUT_RING_H1(VIA_REG_FGCOLOR, tdc->fgColor); 21290b17f1bSmrg OUT_RING_H1(VIA_REG_GECMD, tdc->cmd); 21390b17f1bSmrg 21490b17f1bSmrg ADVANCE_RING; 21590b17f1bSmrg} 21690b17f1bSmrg 21790b17f1bSmrgvoid 21890b17f1bSmrgviaExaDoneSolidCopy_H2(PixmapPtr pPixmap) 21990b17f1bSmrg{ 22090b17f1bSmrg} 22190b17f1bSmrg 22290b17f1bSmrgBool 22390b17f1bSmrgviaExaPrepareCopy_H2(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, 22490b17f1bSmrg int ydir, int alu, Pixel planeMask) 22590b17f1bSmrg{ 22690b17f1bSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPixmap->drawable.pScreen); 22790b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 22890b17f1bSmrg ViaTwodContext *tdc = &pVia->td; 22990b17f1bSmrg 23090b17f1bSmrg RING_VARS; 23190b17f1bSmrg 23290b17f1bSmrg if (pSrcPixmap->drawable.bitsPerPixel != pDstPixmap->drawable.bitsPerPixel) 23390b17f1bSmrg return FALSE; 23490b17f1bSmrg 23590b17f1bSmrg if ((tdc->srcPitch = exaGetPixmapPitch(pSrcPixmap)) & 3) 23690b17f1bSmrg return FALSE; 23790b17f1bSmrg 23890b17f1bSmrg if (exaGetPixmapPitch(pDstPixmap) & 7) 23990b17f1bSmrg return FALSE; 24090b17f1bSmrg 24190b17f1bSmrg tdc->srcOffset = exaGetPixmapOffset(pSrcPixmap); 24290b17f1bSmrg 24390b17f1bSmrg tdc->cmd = VIA_GEC_BLT | VIAACCELCOPYROP(alu); 24490b17f1bSmrg if (xdir < 0) 24590b17f1bSmrg tdc->cmd |= VIA_GEC_DECX; 24690b17f1bSmrg if (ydir < 0) 24790b17f1bSmrg tdc->cmd |= VIA_GEC_DECY; 24890b17f1bSmrg 24990b17f1bSmrg if (!viaAccelSetMode(pDstPixmap->drawable.bitsPerPixel, tdc)) 25090b17f1bSmrg return FALSE; 25190b17f1bSmrg 25290b17f1bSmrg if (!viaAccelPlaneMaskHelper_H2(tdc, planeMask)) 25390b17f1bSmrg return FALSE; 25490b17f1bSmrg viaAccelTransparentHelper_H2(pVia, 0x0, 0x0, TRUE); 25590b17f1bSmrg 25690b17f1bSmrg return TRUE; 25790b17f1bSmrg} 25890b17f1bSmrg 25990b17f1bSmrgvoid 26090b17f1bSmrgviaExaCopy_H2(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY, 26190b17f1bSmrg int width, int height) 26290b17f1bSmrg{ 26390b17f1bSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPixmap->drawable.pScreen); 26490b17f1bSmrg CARD32 dstOffset = exaGetPixmapOffset(pDstPixmap), val; 26590b17f1bSmrg CARD32 dstPitch = exaGetPixmapPitch(pDstPixmap); 26690b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 26790b17f1bSmrg ViaTwodContext *tdc = &pVia->td; 26890b17f1bSmrg 26990b17f1bSmrg if (!width || !height) 27090b17f1bSmrg return; 27190b17f1bSmrg 27290b17f1bSmrg if (tdc->cmd & VIA_GEC_DECY) { 27390b17f1bSmrg srcY += height - 1; 27490b17f1bSmrg dstY += height - 1; 27590b17f1bSmrg } 27690b17f1bSmrg 27790b17f1bSmrg if (tdc->cmd & VIA_GEC_DECX) { 27890b17f1bSmrg srcX += width - 1; 27990b17f1bSmrg dstX += width - 1; 28090b17f1bSmrg } 28190b17f1bSmrg val = VIA_PITCH_ENABLE | (dstPitch >> 3) << 16 | (tdc->srcPitch >> 3); 28290b17f1bSmrg 28390b17f1bSmrg RING_VARS; 28490b17f1bSmrg 28590b17f1bSmrg BEGIN_RING(16); 28690b17f1bSmrg OUT_RING_H1(VIA_REG_GEMODE, tdc->mode); 28790b17f1bSmrg OUT_RING_H1(VIA_REG_SRCBASE, tdc->srcOffset >> 3); 28890b17f1bSmrg OUT_RING_H1(VIA_REG_DSTBASE, dstOffset >> 3); 28990b17f1bSmrg OUT_RING_H1(VIA_REG_PITCH, val); 29090b17f1bSmrg OUT_RING_H1(VIA_REG_SRCPOS, (srcY << 16) | (srcX & 0xFFFF)); 29190b17f1bSmrg OUT_RING_H1(VIA_REG_DSTPOS, (dstY << 16) | (dstX & 0xFFFF)); 29290b17f1bSmrg OUT_RING_H1(VIA_REG_DIMENSION, ((height - 1) << 16) | (width - 1)); 29390b17f1bSmrg OUT_RING_H1(VIA_REG_GECMD, tdc->cmd); 29490b17f1bSmrg 29590b17f1bSmrg ADVANCE_RING; 29690b17f1bSmrg} 29790b17f1bSmrg 29890b17f1bSmrgBool 29990b17f1bSmrgviaExaCheckComposite_H2(int op, PicturePtr pSrcPicture, 30090b17f1bSmrg PicturePtr pMaskPicture, PicturePtr pDstPicture) 30190b17f1bSmrg{ 30290b17f1bSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPicture->pDrawable->pScreen); 30390b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 30490b17f1bSmrg Via3DState *v3d = &pVia->v3d; 30590b17f1bSmrg 30690b17f1bSmrg if (!pSrcPicture->pDrawable) 30790b17f1bSmrg return FALSE; 30890b17f1bSmrg 30990b17f1bSmrg /* Reject small composites early. They are done much faster in software. */ 31090b17f1bSmrg if (!pSrcPicture->repeat && 31190b17f1bSmrg pSrcPicture->pDrawable->width * 31290b17f1bSmrg pSrcPicture->pDrawable->height < VIA_MIN_COMPOSITE) 31390b17f1bSmrg return FALSE; 31490b17f1bSmrg 31590b17f1bSmrg if (pMaskPicture && pMaskPicture->pDrawable && 31690b17f1bSmrg !pMaskPicture->repeat && 31790b17f1bSmrg pMaskPicture->pDrawable->width * 31890b17f1bSmrg pMaskPicture->pDrawable->height < VIA_MIN_COMPOSITE) 31990b17f1bSmrg return FALSE; 32090b17f1bSmrg 32190b17f1bSmrg if (pMaskPicture && pMaskPicture->repeat && 32290b17f1bSmrg pMaskPicture->repeatType != RepeatNormal) 32390b17f1bSmrg return FALSE; 32490b17f1bSmrg 32590b17f1bSmrg if (pMaskPicture && pMaskPicture->componentAlpha) { 32690b17f1bSmrg#ifdef VIA_DEBUG_COMPOSITE 32790b17f1bSmrg viaExaPrintCompositeInfo("Component Alpha operation", op, pSrcPicture, pMaskPicture, pDstPicture); 32890b17f1bSmrg#endif 32990b17f1bSmrg return FALSE; 33090b17f1bSmrg } 33190b17f1bSmrg 33290b17f1bSmrg if (!v3d->opSupported(op)) { 33390b17f1bSmrg#ifdef VIA_DEBUG_COMPOSITE 33490b17f1bSmrg viaExaPrintCompositeInfo("Operator not supported", op, pSrcPicture, pMaskPicture, pDstPicture); 33590b17f1bSmrg#endif 33690b17f1bSmrg return FALSE; 33790b17f1bSmrg } 33890b17f1bSmrg 33990b17f1bSmrg /* 34090b17f1bSmrg * FIXME: A8 destination formats are currently not supported and do not 34190b17f1bSmrg * seem supported by the hardware, although there are some leftover 34290b17f1bSmrg * register settings apparent in the via_3d_reg.h file. We need to fix this 34390b17f1bSmrg * (if important), by using component ARGB8888 operations with bitmask. 34490b17f1bSmrg */ 34590b17f1bSmrg 34690b17f1bSmrg if (!v3d->dstSupported(pDstPicture->format)) { 34790b17f1bSmrg#ifdef VIA_DEBUG_COMPOSITE 34890b17f1bSmrg viaExaPrintCompositeInfo(" Destination format not supported", op, pSrcPicture, pMaskPicture, pDstPicture); 34990b17f1bSmrg#endif 35090b17f1bSmrg return FALSE; 35190b17f1bSmrg } 35290b17f1bSmrg 35390b17f1bSmrg if (v3d->texSupported(pSrcPicture->format)) { 35490b17f1bSmrg if (pMaskPicture && (PICT_FORMAT_A(pMaskPicture->format) == 0 || 35590b17f1bSmrg !v3d->texSupported(pMaskPicture->format))) { 35690b17f1bSmrg#ifdef VIA_DEBUG_COMPOSITE 35790b17f1bSmrg viaExaPrintCompositeInfo("Mask format not supported", op, pSrcPicture, pMaskPicture, pDstPicture); 35890b17f1bSmrg#endif 35990b17f1bSmrg return FALSE; 36090b17f1bSmrg } 36190b17f1bSmrg return TRUE; 36290b17f1bSmrg } 36390b17f1bSmrg#ifdef VIA_DEBUG_COMPOSITE 36490b17f1bSmrg viaExaPrintCompositeInfo("Src format not supported", op, pSrcPicture, pMaskPicture, pDstPicture); 36590b17f1bSmrg#endif 36690b17f1bSmrg return FALSE; 36790b17f1bSmrg} 36890b17f1bSmrg 36990b17f1bSmrgstatic Bool 37090b17f1bSmrgviaIsAGP(VIAPtr pVia, PixmapPtr pPix, unsigned long *offset) 37190b17f1bSmrg{ 37290b17f1bSmrg#ifdef HAVE_DRI 37390b17f1bSmrg unsigned long offs; 37490b17f1bSmrg 37590b17f1bSmrg if (pVia->directRenderingType && !pVia->IsPCI) { 37690b17f1bSmrg offs = ((unsigned long)pPix->devPrivate.ptr 37790b17f1bSmrg - (unsigned long)pVia->agpMappedAddr); 37890b17f1bSmrg 37990b17f1bSmrg if ((offs - pVia->scratchOffset) < pVia->agpSize) { 38090b17f1bSmrg *offset = offs + pVia->agpAddr; 38190b17f1bSmrg return TRUE; 38290b17f1bSmrg } 38390b17f1bSmrg } 38490b17f1bSmrg#endif 38590b17f1bSmrg return FALSE; 38690b17f1bSmrg} 38790b17f1bSmrg 38890b17f1bSmrgstatic Bool 38990b17f1bSmrgviaExaIsOffscreen(PixmapPtr pPix) 39090b17f1bSmrg{ 39190b17f1bSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pPix->drawable.pScreen); 39290b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 39390b17f1bSmrg 39490b17f1bSmrg return ((unsigned long)pPix->devPrivate.ptr - 39590b17f1bSmrg (unsigned long) drm_bo_map(pScrn, pVia->drmmode.front_bo)) < pVia->drmmode.front_bo->size; 39690b17f1bSmrg} 39790b17f1bSmrg 39890b17f1bSmrgBool 39990b17f1bSmrgviaExaPrepareComposite_H2(int op, PicturePtr pSrcPicture, 40090b17f1bSmrg PicturePtr pMaskPicture, PicturePtr pDstPicture, 40190b17f1bSmrg PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst) 40290b17f1bSmrg{ 40390b17f1bSmrg CARD32 height, width; 40490b17f1bSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pDst->drawable.pScreen); 40590b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 40690b17f1bSmrg Via3DState *v3d = &pVia->v3d; 40790b17f1bSmrg int curTex = 0; 40890b17f1bSmrg ViaTexBlendingModes srcMode; 40990b17f1bSmrg Bool isAGP; 41090b17f1bSmrg unsigned long offset; 41190b17f1bSmrg 41290b17f1bSmrg /* Workaround: EXA crash with new libcairo2 on a VIA VX800 (#298) */ 41390b17f1bSmrg /* TODO Add real source only pictures */ 41490b17f1bSmrg if (!pSrc) { 41590b17f1bSmrg ErrorF("pSrc is NULL\n"); 41690b17f1bSmrg return FALSE; 41790b17f1bSmrg } 41890b17f1bSmrg 41990b17f1bSmrg v3d->setDestination(v3d, exaGetPixmapOffset(pDst), 42090b17f1bSmrg exaGetPixmapPitch(pDst), pDstPicture->format); 42190b17f1bSmrg v3d->setCompositeOperator(v3d, op); 42290b17f1bSmrg v3d->setDrawing(v3d, 0x0c, 0xFFFFFFFF, 0x000000FF, 0xFF); 42390b17f1bSmrg 42490b17f1bSmrg viaOrder(pSrc->drawable.width, &width); 42590b17f1bSmrg viaOrder(pSrc->drawable.height, &height); 42690b17f1bSmrg 42790b17f1bSmrg /* 42890b17f1bSmrg * For one-pixel repeat mask pictures we avoid using multitexturing by 42990b17f1bSmrg * modifying the src's texture blending equation and feed the pixel 43090b17f1bSmrg * value as a constant alpha for the src's texture. Multitexturing on the 43190b17f1bSmrg * Unichromes seems somewhat slow, so this speeds up translucent windows. 43290b17f1bSmrg */ 43390b17f1bSmrg 43490b17f1bSmrg srcMode = via_src; 43590b17f1bSmrg pVia->maskP = NULL; 43690b17f1bSmrg if (pMaskPicture && 43790b17f1bSmrg (pMaskPicture->pDrawable->height == 1) && 43890b17f1bSmrg (pMaskPicture->pDrawable->width == 1) && 43990b17f1bSmrg pMaskPicture->repeat && viaExpandablePixel(pMaskPicture->format)) { 44090b17f1bSmrg pVia->maskP = pMask->devPrivate.ptr; 44190b17f1bSmrg pVia->maskFormat = pMaskPicture->format; 44290b17f1bSmrg pVia->componentAlpha = pMaskPicture->componentAlpha; 44390b17f1bSmrg srcMode = ((pMaskPicture->componentAlpha) 44490b17f1bSmrg ? via_src_onepix_comp_mask : via_src_onepix_mask); 44590b17f1bSmrg } 44690b17f1bSmrg 44790b17f1bSmrg /* 44890b17f1bSmrg * One-Pixel repeat src pictures go as solid color instead of textures. 44990b17f1bSmrg * Speeds up window shadows. 45090b17f1bSmrg */ 45190b17f1bSmrg 45290b17f1bSmrg pVia->srcP = NULL; 45390b17f1bSmrg if (pSrcPicture && pSrcPicture->repeat 45490b17f1bSmrg && (pSrcPicture->pDrawable->height == 1) 45590b17f1bSmrg && (pSrcPicture->pDrawable->width == 1) 45690b17f1bSmrg && viaExpandablePixel(pSrcPicture->format)) { 45790b17f1bSmrg pVia->srcP = pSrc->devPrivate.ptr; 45890b17f1bSmrg pVia->srcFormat = pSrcPicture->format; 45990b17f1bSmrg } 46090b17f1bSmrg 46190b17f1bSmrg /* Exa should be smart enough to eliminate this IN operation. */ 46290b17f1bSmrg if (pVia->srcP && pVia->maskP) { 46390b17f1bSmrg ErrorF("Bad one-pixel IN composite operation. " 46490b17f1bSmrg "EXA needs to be smarter.\n"); 46590b17f1bSmrg return FALSE; 46690b17f1bSmrg } 46790b17f1bSmrg 46890b17f1bSmrg if (!pVia->srcP) { 46990b17f1bSmrg offset = exaGetPixmapOffset(pSrc); 47090b17f1bSmrg isAGP = viaIsAGP(pVia, pSrc, &offset); 47190b17f1bSmrg if (!isAGP && !viaExaIsOffscreen(pSrc)) 47290b17f1bSmrg return FALSE; 47390b17f1bSmrg if (!v3d->setTexture(v3d, curTex, offset, 47490b17f1bSmrg exaGetPixmapPitch(pSrc), pVia->nPOT[curTex], 47590b17f1bSmrg 1 << width, 1 << height, pSrcPicture->format, 47690b17f1bSmrg via_repeat, via_repeat, srcMode, isAGP)) { 47790b17f1bSmrg return FALSE; 47890b17f1bSmrg } 47990b17f1bSmrg curTex++; 48090b17f1bSmrg } 48190b17f1bSmrg 48290b17f1bSmrg if (pMaskPicture && !pVia->maskP) { 48390b17f1bSmrg offset = exaGetPixmapOffset(pMask); 48490b17f1bSmrg isAGP = viaIsAGP(pVia, pMask, &offset); 48590b17f1bSmrg if (!isAGP && !viaExaIsOffscreen(pMask)) 48690b17f1bSmrg return FALSE; 48790b17f1bSmrg viaOrder(pMask->drawable.width, &width); 48890b17f1bSmrg viaOrder(pMask->drawable.height, &height); 48990b17f1bSmrg if (!v3d->setTexture(v3d, curTex, offset, 49090b17f1bSmrg exaGetPixmapPitch(pMask), pVia->nPOT[curTex], 49190b17f1bSmrg 1 << width, 1 << height, pMaskPicture->format, 49290b17f1bSmrg via_repeat, via_repeat, 49390b17f1bSmrg ((pMaskPicture->componentAlpha) 49490b17f1bSmrg ? via_comp_mask : via_mask), isAGP)) { 49590b17f1bSmrg return FALSE; 49690b17f1bSmrg } 49790b17f1bSmrg curTex++; 49890b17f1bSmrg } 49990b17f1bSmrg 50090b17f1bSmrg v3d->setFlags(v3d, curTex, FALSE, TRUE, TRUE); 50190b17f1bSmrg v3d->emitState(v3d, &pVia->cb, viaCheckUpload(pScrn, v3d)); 50290b17f1bSmrg v3d->emitClipRect(v3d, &pVia->cb, 0, 0, pDst->drawable.width, 50390b17f1bSmrg pDst->drawable.height); 50490b17f1bSmrg 50590b17f1bSmrg return TRUE; 50690b17f1bSmrg} 50790b17f1bSmrg 50890b17f1bSmrgvoid 50990b17f1bSmrgviaExaComposite_H2(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY, 51090b17f1bSmrg int dstX, int dstY, int width, int height) 51190b17f1bSmrg{ 51290b17f1bSmrg ScrnInfoPtr pScrn = xf86ScreenToScrn(pDst->drawable.pScreen); 51390b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 51490b17f1bSmrg Via3DState *v3d = &pVia->v3d; 51590b17f1bSmrg CARD32 col; 51690b17f1bSmrg 51790b17f1bSmrg if (pVia->maskP) { 51890b17f1bSmrg viaPixelARGB8888(pVia->maskFormat, pVia->maskP, &col); 51990b17f1bSmrg v3d->setTexBlendCol(v3d, 0, pVia->componentAlpha, col); 52090b17f1bSmrg } 52190b17f1bSmrg if (pVia->srcP) { 52290b17f1bSmrg viaPixelARGB8888(pVia->srcFormat, pVia->srcP, &col); 52390b17f1bSmrg v3d->setDrawing(v3d, 0x0c, 0xFFFFFFFF, col & 0x00FFFFFF, col >> 24); 52490b17f1bSmrg srcX = maskX; 52590b17f1bSmrg srcY = maskY; 52690b17f1bSmrg } 52790b17f1bSmrg 52890b17f1bSmrg if (pVia->maskP || pVia->srcP) 52990b17f1bSmrg v3d->emitState(v3d, &pVia->cb, viaCheckUpload(pScrn, v3d)); 53090b17f1bSmrg 53190b17f1bSmrg v3d->emitQuad(v3d, &pVia->cb, dstX, dstY, srcX, srcY, maskX, maskY, 53290b17f1bSmrg width, height); 53390b17f1bSmrg} 53490b17f1bSmrg 53590b17f1bSmrgvoid 53690b17f1bSmrgviaAccelTextureBlit(ScrnInfoPtr pScrn, unsigned long srcOffset, 53790b17f1bSmrg unsigned srcPitch, unsigned w, unsigned h, unsigned srcX, 53890b17f1bSmrg unsigned srcY, unsigned srcFormat, unsigned long dstOffset, 53990b17f1bSmrg unsigned dstPitch, unsigned dstX, unsigned dstY, 54090b17f1bSmrg unsigned dstFormat, int rotate) 54190b17f1bSmrg{ 54290b17f1bSmrg VIAPtr pVia = VIAPTR(pScrn); 54390b17f1bSmrg CARD32 wOrder, hOrder; 54490b17f1bSmrg Via3DState *v3d = &pVia->v3d; 54590b17f1bSmrg 54690b17f1bSmrg viaOrder(w, &wOrder); 54790b17f1bSmrg viaOrder(h, &hOrder); 54890b17f1bSmrg 54990b17f1bSmrg v3d->setDestination(v3d, dstOffset, dstPitch, dstFormat); 55090b17f1bSmrg v3d->setDrawing(v3d, 0x0c, 0xFFFFFFFF, 0x000000FF, 0x00); 55190b17f1bSmrg v3d->setFlags(v3d, 1, TRUE, TRUE, FALSE); 55290b17f1bSmrg v3d->setTexture(v3d, 0, srcOffset, srcPitch, TRUE, 55390b17f1bSmrg 1 << wOrder, 1 << hOrder, srcFormat, 55490b17f1bSmrg via_single, via_single, via_src, FALSE); 55590b17f1bSmrg v3d->emitState(v3d, &pVia->cb, viaCheckUpload(pScrn, v3d)); 55690b17f1bSmrg v3d->emitClipRect(v3d, &pVia->cb, dstX, dstY, w, h); 55790b17f1bSmrg v3d->emitQuad(v3d, &pVia->cb, dstX, dstY, srcX, srcY, 0, 0, w, h); 55890b17f1bSmrg} 559