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