1 /*
2  * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3  * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
4  * Copyright 2006 Thomas Hellström. All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sub license,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the
14  * next paragraph) shall be included in all copies or substantial portions
15  * of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23  * DEALINGS IN THE SOFTWARE.
24  */
25 
26 /*
27  * 2D acceleration functions for the VIA/S3G UniChrome IGPs.
28  *
29  * Mostly rewritten, and modified for EXA support, by Thomas Hellström.
30  */
31 
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35 
36 #include <X11/Xarch.h>
37 #include "miline.h"
38 
39 #include "via_driver.h"
40 #include "via_regs.h"
41 #include "via_dmabuffer.h"
42 #include "via_rop.h"
43 
44 /*
45  * Emit clipping borders to the command buffer and update the 2D context
46  * current command with clipping info.
47  */
48 static int
viaAccelClippingHelper_H2(VIAPtr pVia,int refY)49 viaAccelClippingHelper_H2(VIAPtr pVia, int refY)
50 {
51     ViaTwodContext *tdc = &pVia->td;
52 
53     RING_VARS;
54 
55     if (tdc->clipping) {
56         refY = (refY < tdc->clipY1) ? refY : tdc->clipY1;
57         tdc->cmd |= VIA_GEC_CLIP_ENABLE;
58         BEGIN_RING(4);
59         OUT_RING_H1(VIA_REG_CLIPTL,
60                     ((tdc->clipY1 - refY) << 16) | tdc->clipX1);
61         OUT_RING_H1(VIA_REG_CLIPBR,
62 		    ((tdc->clipY2 - refY) << 16) | tdc->clipX2);
63     } else {
64         tdc->cmd &= ~VIA_GEC_CLIP_ENABLE;
65     }
66     return refY;
67 }
68 
69 /*
70  * Check if we can use a planeMask and update the 2D context accordingly.
71  */
72 static Bool
viaAccelPlaneMaskHelper_H2(ViaTwodContext * tdc,CARD32 planeMask)73 viaAccelPlaneMaskHelper_H2(ViaTwodContext * tdc, CARD32 planeMask)
74 {
75     CARD32 modeMask = (1 << ((1 << tdc->bytesPPShift) << 3)) - 1;
76     CARD32 curMask = 0x00000000;
77     CARD32 curByteMask;
78     int i;
79 
80     if ((planeMask & modeMask) != modeMask) {
81 
82         /* Masking doesn't work in 8bpp. */
83         if (modeMask == 0xFF) {
84             tdc->keyControl &= 0x0FFFFFFF;
85             return FALSE;
86         }
87 
88         /* Translate the bit planemask to a byte planemask. */
89         for (i = 0; i < (1 << tdc->bytesPPShift); ++i) {
90             curByteMask = (0xFF << (i << 3));
91 
92             if ((planeMask & curByteMask) == 0) {
93                 curMask |= (1 << i);
94             } else if ((planeMask & curByteMask) != curByteMask) {
95                 tdc->keyControl &= 0x0FFFFFFF;
96                 return FALSE;
97             }
98         }
99         ErrorF("DEBUG: planeMask 0x%08x, curMask 0%02x\n",
100                (unsigned)planeMask, (unsigned)curMask);
101 
102         tdc->keyControl = (tdc->keyControl & 0x0FFFFFFF) | (curMask << 28);
103     }
104 
105     return TRUE;
106 }
107 
108 /*
109  * Emit transparency state and color to the command buffer.
110  */
111 static void
viaAccelTransparentHelper_H2(VIAPtr pVia,CARD32 keyControl,CARD32 transColor,Bool usePlaneMask)112 viaAccelTransparentHelper_H2(VIAPtr pVia, CARD32 keyControl,
113                           CARD32 transColor, Bool usePlaneMask)
114 {
115     ViaTwodContext *tdc = &pVia->td;
116 
117     RING_VARS;
118 
119     tdc->keyControl &= ((usePlaneMask) ? 0xF0000000 : 0x00000000);
120     tdc->keyControl |= (keyControl & 0x0FFFFFFF);
121     BEGIN_RING(4);
122     OUT_RING_H1(VIA_REG_KEYCONTROL, tdc->keyControl);
123     if (keyControl) {
124         OUT_RING_H1(VIA_REG_SRCCOLORKEY, transColor);
125     }
126 }
127 
128 /*
129  * Mark Sync using the 2D blitter for AGP. NoOp for PCI.
130  * In the future one could even launch a NULL PCI DMA command
131  * to have an interrupt generated, provided it is possible to
132  * write to the PCI DMA engines from the AGP command stream.
133  */
134 int
viaAccelMarkSync_H2(ScreenPtr pScreen)135 viaAccelMarkSync_H2(ScreenPtr pScreen)
136 {
137     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
138     VIAPtr pVia = VIAPTR(pScrn);
139 
140     RING_VARS;
141 
142     ++pVia->curMarker;
143 
144     /* Wrap around without affecting the sign bit. */
145     pVia->curMarker &= 0x7FFFFFFF;
146 
147     if (pVia->agpDMA) {
148         BEGIN_RING(16);
149         OUT_RING_H1(VIA_REG_KEYCONTROL, 0x00);
150         OUT_RING_H1(VIA_REG_GEMODE, VIA_GEM_32bpp);
151         OUT_RING_H1(VIA_REG_DSTBASE, pVia->markerOffset >> 3);
152         OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE);
153         OUT_RING_H1(VIA_REG_DSTPOS, 0);
154         OUT_RING_H1(VIA_REG_DIMENSION, 0);
155         OUT_RING_H1(VIA_REG_FGCOLOR, pVia->curMarker);
156         OUT_RING_H1(VIA_REG_GECMD, (0xF0 << 24) | VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT);
157 
158         ADVANCE_RING;
159     }
160     return pVia->curMarker;
161 }
162 
163 /*
164  * Exa functions. It is assumed that EXA does not exceed the blitter limits.
165  */
166 Bool
viaExaPrepareSolid_H2(PixmapPtr pPixmap,int alu,Pixel planeMask,Pixel fg)167 viaExaPrepareSolid_H2(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
168 {
169     ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen);
170     VIAPtr pVia = VIAPTR(pScrn);
171     ViaTwodContext *tdc = &pVia->td;
172 
173     if (exaGetPixmapPitch(pPixmap) & 7)
174         return FALSE;
175 
176     if (!viaAccelSetMode(pPixmap->drawable.depth, tdc))
177         return FALSE;
178 
179     if (!viaAccelPlaneMaskHelper_H2(tdc, planeMask))
180         return FALSE;
181 
182     viaAccelTransparentHelper_H2(pVia, 0x0, 0x0, TRUE);
183 
184     tdc->cmd = VIA_GEC_BLT | VIA_GEC_FIXCOLOR_PAT | VIAACCELPATTERNROP(alu);
185 
186     tdc->fgColor = fg;
187 
188     return TRUE;
189 }
190 
191 void
viaExaSolid_H2(PixmapPtr pPixmap,int x1,int y1,int x2,int y2)192 viaExaSolid_H2(PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
193 {
194     ScrnInfoPtr pScrn = xf86ScreenToScrn(pPixmap->drawable.pScreen);
195     CARD32 dstOffset = exaGetPixmapOffset(pPixmap);
196     CARD32 dstPitch = exaGetPixmapPitch(pPixmap);
197     int w = x2 - x1, h = y2 - y1;
198     VIAPtr pVia = VIAPTR(pScrn);
199     ViaTwodContext *tdc = &pVia->td;
200 
201     RING_VARS;
202 
203     BEGIN_RING(14);
204     OUT_RING_H1(VIA_REG_GEMODE, tdc->mode);
205     OUT_RING_H1(VIA_REG_DSTBASE, dstOffset >> 3);
206     OUT_RING_H1(VIA_REG_PITCH, VIA_PITCH_ENABLE | (dstPitch >> 3) << 16);
207     OUT_RING_H1(VIA_REG_DSTPOS, (y1 << 16) | (x1 & 0xFFFF));
208     OUT_RING_H1(VIA_REG_DIMENSION, ((h - 1) << 16) | (w - 1));
209     OUT_RING_H1(VIA_REG_FGCOLOR, tdc->fgColor);
210     OUT_RING_H1(VIA_REG_GECMD, tdc->cmd);
211 
212     ADVANCE_RING;
213 }
214 
215 void
viaExaDoneSolidCopy_H2(PixmapPtr pPixmap)216 viaExaDoneSolidCopy_H2(PixmapPtr pPixmap)
217 {
218 }
219 
220 Bool
viaExaPrepareCopy_H2(PixmapPtr pSrcPixmap,PixmapPtr pDstPixmap,int xdir,int ydir,int alu,Pixel planeMask)221 viaExaPrepareCopy_H2(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
222                         int ydir, int alu, Pixel planeMask)
223 {
224     ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPixmap->drawable.pScreen);
225     VIAPtr pVia = VIAPTR(pScrn);
226     ViaTwodContext *tdc = &pVia->td;
227 
228     if (pSrcPixmap->drawable.bitsPerPixel != pDstPixmap->drawable.bitsPerPixel)
229         return FALSE;
230 
231     if ((tdc->srcPitch = exaGetPixmapPitch(pSrcPixmap)) & 3)
232         return FALSE;
233 
234     if (exaGetPixmapPitch(pDstPixmap) & 7)
235         return FALSE;
236 
237     tdc->srcOffset = exaGetPixmapOffset(pSrcPixmap);
238 
239     tdc->cmd = VIA_GEC_BLT | VIAACCELCOPYROP(alu);
240     if (xdir < 0)
241         tdc->cmd |= VIA_GEC_DECX;
242     if (ydir < 0)
243         tdc->cmd |= VIA_GEC_DECY;
244 
245     if (!viaAccelSetMode(pDstPixmap->drawable.bitsPerPixel, tdc))
246         return FALSE;
247 
248     if (!viaAccelPlaneMaskHelper_H2(tdc, planeMask))
249         return FALSE;
250     viaAccelTransparentHelper_H2(pVia, 0x0, 0x0, TRUE);
251 
252     return TRUE;
253 }
254 
255 void
viaExaCopy_H2(PixmapPtr pDstPixmap,int srcX,int srcY,int dstX,int dstY,int width,int height)256 viaExaCopy_H2(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
257                 int width, int height)
258 {
259     ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPixmap->drawable.pScreen);
260     CARD32 dstOffset = exaGetPixmapOffset(pDstPixmap), val;
261     CARD32 dstPitch = exaGetPixmapPitch(pDstPixmap);
262     VIAPtr pVia = VIAPTR(pScrn);
263     ViaTwodContext *tdc = &pVia->td;
264 
265     if (!width || !height)
266         return;
267 
268     if (tdc->cmd & VIA_GEC_DECY) {
269         srcY += height - 1;
270         dstY += height - 1;
271     }
272 
273     if (tdc->cmd & VIA_GEC_DECX) {
274         srcX += width - 1;
275         dstX += width - 1;
276     }
277     val = VIA_PITCH_ENABLE | (dstPitch >> 3) << 16 | (tdc->srcPitch >> 3);
278 
279     RING_VARS;
280 
281     BEGIN_RING(16);
282     OUT_RING_H1(VIA_REG_GEMODE, tdc->mode);
283     OUT_RING_H1(VIA_REG_SRCBASE, tdc->srcOffset >> 3);
284     OUT_RING_H1(VIA_REG_DSTBASE, dstOffset >> 3);
285     OUT_RING_H1(VIA_REG_PITCH, val);
286     OUT_RING_H1(VIA_REG_SRCPOS, (srcY << 16) | (srcX & 0xFFFF));
287     OUT_RING_H1(VIA_REG_DSTPOS, (dstY << 16) | (dstX & 0xFFFF));
288     OUT_RING_H1(VIA_REG_DIMENSION, ((height - 1) << 16) | (width - 1));
289     OUT_RING_H1(VIA_REG_GECMD, tdc->cmd);
290 
291     ADVANCE_RING;
292 }
293 
294 Bool
viaExaCheckComposite_H2(int op,PicturePtr pSrcPicture,PicturePtr pMaskPicture,PicturePtr pDstPicture)295 viaExaCheckComposite_H2(int op, PicturePtr pSrcPicture,
296                         PicturePtr pMaskPicture, PicturePtr pDstPicture)
297 {
298     ScrnInfoPtr pScrn = xf86ScreenToScrn(pDstPicture->pDrawable->pScreen);
299     VIAPtr pVia = VIAPTR(pScrn);
300     Via3DState *v3d = &pVia->v3d;
301 
302     if (!pSrcPicture->pDrawable)
303         return FALSE;
304 
305     /* Reject small composites early. They are done much faster in software. */
306     if (!pSrcPicture->repeat &&
307         pSrcPicture->pDrawable->width *
308         pSrcPicture->pDrawable->height < VIA_MIN_COMPOSITE)
309         return FALSE;
310 
311     if (pMaskPicture && pMaskPicture->pDrawable &&
312         !pMaskPicture->repeat &&
313         pMaskPicture->pDrawable->width *
314         pMaskPicture->pDrawable->height < VIA_MIN_COMPOSITE)
315         return FALSE;
316 
317     if (pMaskPicture && pMaskPicture->repeat &&
318         pMaskPicture->repeatType != RepeatNormal)
319         return FALSE;
320 
321     if (pMaskPicture && pMaskPicture->componentAlpha) {
322 #ifdef VIA_DEBUG_COMPOSITE
323         viaExaPrintCompositeInfo("Component Alpha operation", op,  pSrcPicture, pMaskPicture, pDstPicture);
324 #endif
325         return FALSE;
326     }
327 
328     if (!v3d->opSupported(op)) {
329 #ifdef VIA_DEBUG_COMPOSITE
330         viaExaPrintCompositeInfo("Operator not supported", op, pSrcPicture, pMaskPicture, pDstPicture);
331 #endif
332         return FALSE;
333     }
334 
335     /*
336      * FIXME: A8 destination formats are currently not supported and do not
337      * seem supported by the hardware, although there are some leftover
338      * register settings apparent in the via_3d_reg.h file. We need to fix this
339      * (if important), by using component ARGB8888 operations with bitmask.
340      */
341 
342     if (!v3d->dstSupported(pDstPicture->format)) {
343 #ifdef VIA_DEBUG_COMPOSITE
344         viaExaPrintCompositeInfo(" Destination format not supported", op, pSrcPicture, pMaskPicture, pDstPicture);
345 #endif
346         return FALSE;
347     }
348 
349     if (v3d->texSupported(pSrcPicture->format)) {
350         if (pMaskPicture && (PICT_FORMAT_A(pMaskPicture->format) == 0 ||
351                              !v3d->texSupported(pMaskPicture->format))) {
352 #ifdef VIA_DEBUG_COMPOSITE
353             viaExaPrintCompositeInfo("Mask format not supported", op, pSrcPicture, pMaskPicture, pDstPicture);
354 #endif
355             return FALSE;
356         }
357         return TRUE;
358     }
359 #ifdef VIA_DEBUG_COMPOSITE
360     viaExaPrintCompositeInfo("Src format not supported", op, pSrcPicture, pMaskPicture, pDstPicture);
361 #endif
362     return FALSE;
363 }
364 
365 static Bool
viaIsAGP(VIAPtr pVia,PixmapPtr pPix,unsigned long * offset)366 viaIsAGP(VIAPtr pVia, PixmapPtr pPix, unsigned long *offset)
367 {
368 #ifdef HAVE_DRI
369     unsigned long offs;
370 
371     if (pVia->directRenderingType && !pVia->IsPCI) {
372         offs = ((unsigned long)pPix->devPrivate.ptr
373                 - (unsigned long)pVia->agpMappedAddr);
374 
375         if ((offs - pVia->scratchOffset) < pVia->agpSize) {
376             *offset = offs + pVia->agpAddr;
377             return TRUE;
378         }
379     }
380 #endif
381     return FALSE;
382 }
383 
384 static Bool
viaExaIsOffscreen(PixmapPtr pPix)385 viaExaIsOffscreen(PixmapPtr pPix)
386 {
387     ScrnInfoPtr pScrn = xf86ScreenToScrn(pPix->drawable.pScreen);
388     VIAPtr pVia = VIAPTR(pScrn);
389 
390     return ((unsigned long)pPix->devPrivate.ptr -
391             (unsigned long) drm_bo_map(pScrn, pVia->drmmode.front_bo)) < pVia->drmmode.front_bo->size;
392 }
393 
394 Bool
viaExaPrepareComposite_H2(int op,PicturePtr pSrcPicture,PicturePtr pMaskPicture,PicturePtr pDstPicture,PixmapPtr pSrc,PixmapPtr pMask,PixmapPtr pDst)395 viaExaPrepareComposite_H2(int op, PicturePtr pSrcPicture,
396                             PicturePtr pMaskPicture, PicturePtr pDstPicture,
397                             PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst)
398 {
399     CARD32 height, width;
400     ScrnInfoPtr pScrn = xf86ScreenToScrn(pDst->drawable.pScreen);
401     VIAPtr pVia = VIAPTR(pScrn);
402     Via3DState *v3d = &pVia->v3d;
403     int curTex = 0;
404     ViaTexBlendingModes srcMode;
405     Bool isAGP;
406     unsigned long offset;
407 
408     /* Workaround: EXA crash with new libcairo2 on a VIA VX800 (#298) */
409     /* TODO Add real source only pictures */
410     if (!pSrc) {
411 	    ErrorF("pSrc is NULL\n");
412 	    return FALSE;
413 	}
414 
415     v3d->setDestination(v3d, exaGetPixmapOffset(pDst),
416                         exaGetPixmapPitch(pDst), pDstPicture->format);
417     v3d->setCompositeOperator(v3d, op);
418     v3d->setDrawing(v3d, 0x0c, 0xFFFFFFFF, 0x000000FF, 0xFF);
419 
420     viaOrder(pSrc->drawable.width, &width);
421     viaOrder(pSrc->drawable.height, &height);
422 
423     /*
424      * For one-pixel repeat mask pictures we avoid using multitexturing by
425      * modifying the src's texture blending equation and feed the pixel
426      * value as a constant alpha for the src's texture. Multitexturing on the
427      * Unichromes seems somewhat slow, so this speeds up translucent windows.
428      */
429 
430     srcMode = via_src;
431     pVia->maskP = NULL;
432     if (pMaskPicture &&
433         (pMaskPicture->pDrawable->height == 1) &&
434         (pMaskPicture->pDrawable->width == 1) &&
435         pMaskPicture->repeat && viaExpandablePixel(pMaskPicture->format)) {
436         pVia->maskP = pMask->devPrivate.ptr;
437         pVia->maskFormat = pMaskPicture->format;
438         pVia->componentAlpha = pMaskPicture->componentAlpha;
439         srcMode = ((pMaskPicture->componentAlpha)
440                    ? via_src_onepix_comp_mask : via_src_onepix_mask);
441     }
442 
443     /*
444      * One-Pixel repeat src pictures go as solid color instead of textures.
445      * Speeds up window shadows.
446      */
447 
448     pVia->srcP = NULL;
449     if (pSrcPicture && pSrcPicture->repeat
450         && (pSrcPicture->pDrawable->height == 1)
451         && (pSrcPicture->pDrawable->width == 1)
452         && viaExpandablePixel(pSrcPicture->format)) {
453         pVia->srcP = pSrc->devPrivate.ptr;
454         pVia->srcFormat = pSrcPicture->format;
455     }
456 
457     /* Exa should be smart enough to eliminate this IN operation. */
458     if (pVia->srcP && pVia->maskP) {
459         ErrorF("Bad one-pixel IN composite operation. "
460                "EXA needs to be smarter.\n");
461         return FALSE;
462     }
463 
464     if (!pVia->srcP) {
465         offset = exaGetPixmapOffset(pSrc);
466         isAGP = viaIsAGP(pVia, pSrc, &offset);
467         if (!isAGP && !viaExaIsOffscreen(pSrc))
468             return FALSE;
469         if (!v3d->setTexture(v3d, curTex, offset,
470                              exaGetPixmapPitch(pSrc), pVia->nPOT[curTex],
471                              1 << width, 1 << height, pSrcPicture->format,
472                              via_repeat, via_repeat, srcMode, isAGP)) {
473             return FALSE;
474         }
475         curTex++;
476     }
477 
478     if (pMaskPicture && !pVia->maskP) {
479         offset = exaGetPixmapOffset(pMask);
480         isAGP = viaIsAGP(pVia, pMask, &offset);
481         if (!isAGP && !viaExaIsOffscreen(pMask))
482             return FALSE;
483         viaOrder(pMask->drawable.width, &width);
484         viaOrder(pMask->drawable.height, &height);
485         if (!v3d->setTexture(v3d, curTex, offset,
486                              exaGetPixmapPitch(pMask), pVia->nPOT[curTex],
487                              1 << width, 1 << height, pMaskPicture->format,
488                              via_repeat, via_repeat,
489                              ((pMaskPicture->componentAlpha)
490                               ? via_comp_mask : via_mask), isAGP)) {
491             return FALSE;
492         }
493         curTex++;
494     }
495 
496     v3d->setFlags(v3d, curTex, FALSE, TRUE, TRUE);
497     v3d->emitState(v3d, &pVia->cb, viaCheckUpload(pScrn, v3d));
498     v3d->emitClipRect(v3d, &pVia->cb, 0, 0, pDst->drawable.width,
499                       pDst->drawable.height);
500 
501     return TRUE;
502 }
503 
504 void
viaExaComposite_H2(PixmapPtr pDst,int srcX,int srcY,int maskX,int maskY,int dstX,int dstY,int width,int height)505 viaExaComposite_H2(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
506                     int dstX, int dstY, int width, int height)
507 {
508     ScrnInfoPtr pScrn = xf86ScreenToScrn(pDst->drawable.pScreen);
509     VIAPtr pVia = VIAPTR(pScrn);
510     Via3DState *v3d = &pVia->v3d;
511     CARD32 col;
512 
513     if (pVia->maskP) {
514         viaPixelARGB8888(pVia->maskFormat, pVia->maskP, &col);
515         v3d->setTexBlendCol(v3d, 0, pVia->componentAlpha, col);
516     }
517     if (pVia->srcP) {
518         viaPixelARGB8888(pVia->srcFormat, pVia->srcP, &col);
519         v3d->setDrawing(v3d, 0x0c, 0xFFFFFFFF, col & 0x00FFFFFF, col >> 24);
520         srcX = maskX;
521         srcY = maskY;
522     }
523 
524     if (pVia->maskP || pVia->srcP)
525         v3d->emitState(v3d, &pVia->cb, viaCheckUpload(pScrn, v3d));
526 
527     v3d->emitQuad(v3d, &pVia->cb, dstX, dstY, srcX, srcY, maskX, maskY,
528                   width, height);
529 }
530 
531 void
viaAccelTextureBlit(ScrnInfoPtr pScrn,unsigned long srcOffset,unsigned srcPitch,unsigned w,unsigned h,unsigned srcX,unsigned srcY,unsigned srcFormat,unsigned long dstOffset,unsigned dstPitch,unsigned dstX,unsigned dstY,unsigned dstFormat,int rotate)532 viaAccelTextureBlit(ScrnInfoPtr pScrn, unsigned long srcOffset,
533                     unsigned srcPitch, unsigned w, unsigned h, unsigned srcX,
534                     unsigned srcY, unsigned srcFormat, unsigned long dstOffset,
535                     unsigned dstPitch, unsigned dstX, unsigned dstY,
536                     unsigned dstFormat, int rotate)
537 {
538     VIAPtr pVia = VIAPTR(pScrn);
539     CARD32 wOrder, hOrder;
540     Via3DState *v3d = &pVia->v3d;
541 
542     viaOrder(w, &wOrder);
543     viaOrder(h, &hOrder);
544 
545     v3d->setDestination(v3d, dstOffset, dstPitch, dstFormat);
546     v3d->setDrawing(v3d, 0x0c, 0xFFFFFFFF, 0x000000FF, 0x00);
547     v3d->setFlags(v3d, 1, TRUE, TRUE, FALSE);
548     v3d->setTexture(v3d, 0, srcOffset, srcPitch, TRUE,
549                     1 << wOrder, 1 << hOrder, srcFormat,
550                     via_single, via_single, via_src, FALSE);
551     v3d->emitState(v3d, &pVia->cb, viaCheckUpload(pScrn, v3d));
552     v3d->emitClipRect(v3d, &pVia->cb, dstX, dstY, w, h);
553     v3d->emitQuad(v3d, &pVia->cb, dstX, dstY, srcX, srcY, 0, 0, w, h);
554 }
555