Fixed off by one errors in clipping.
[mesa.git] / src / mesa / drivers / dri / unichrome / via_ioctl.c
1 #/*
2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24 #include <stdio.h>
25 #include <unistd.h>
26
27 #include "glheader.h"
28 #include "mtypes.h"
29 #include "macros.h"
30 #include "dd.h"
31 #include "swrast/swrast.h"
32
33 #include "mm.h"
34 #include "via_context.h"
35 #include "via_ioctl.h"
36 #include "via_state.h"
37
38 #include "drm.h"
39 #include <sys/ioctl.h>
40
41 GLuint FrameCount = 0;
42 GLuint dmaLow = 0;
43 /*=* John Sheng [2003.5.31] flip *=*/
44 GLuint nFirstSwap = GL_TRUE;
45 GLuint nFirstFlip = GL_TRUE;
46 #define SetReg2DAGP(nReg, nData) { \
47 *((GLuint *)(vb)) = ((nReg) >> 2) | 0xF0000000; \
48 *((GLuint *)(vb) + 1) = (nData); \
49 vb = ((GLuint *)vb) + 2; \
50 vmesa->dmaLow +=8; \
51 }
52
53 #define DEPTH_SCALE ((1 << 16) - 1)
54
55 static void viaClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
56 GLint cx, GLint cy, GLint cw, GLint ch)
57 {
58 viaContextPtr vmesa = VIA_CONTEXT(ctx);
59 __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
60 const GLuint colorMask = *((GLuint *)&ctx->Color.ColorMask);
61 int flag = 0;
62 GLuint scrn = 0, i = 0, side = 0;
63 scrn = vmesa->saam & S_MASK;
64 side = vmesa->saam & P_MASK;
65 #ifdef DEBUG
66 if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
67 #endif
68 VIA_FIREVERTICES(vmesa);
69
70 if ((mask & DD_FRONT_LEFT_BIT) && colorMask == ~0) {
71 flag |= VIA_FRONT;
72 mask &= ~DD_FRONT_LEFT_BIT;
73 }
74
75 if ((mask & DD_BACK_LEFT_BIT) && colorMask == ~0) {
76 flag |= VIA_BACK;
77 mask &= ~DD_BACK_LEFT_BIT;
78 }
79
80 if (mask & DD_DEPTH_BIT) {
81 if (ctx->Depth.Mask)
82 flag |= VIA_DEPTH;
83 mask &= ~DD_DEPTH_BIT;
84 }
85
86 if (mask & DD_STENCIL_BIT) {
87 if (ctx->Stencil.Enabled)
88 flag |= VIA_STENCIL;
89 mask &= ~DD_STENCIL_BIT;
90 }
91
92 /*=* [DBG] make draw to front buffer *=*/
93 if(DRAW_FRONT) {
94 flag |= VIA_FRONT;
95 flag &= ~VIA_BACK;
96 }
97
98 if (flag) {
99 LOCK_HARDWARE(vmesa);
100 /* flip top to bottom */
101 cy = dPriv->h - cy - ch;
102 cx += vmesa->drawX;
103 cy += vmesa->drawY;
104
105 if (vmesa->numClipRects) {
106 int nr = MIN2(i + VIA_NR_SAREA_CLIPRECTS, vmesa->numClipRects);
107 drm_clip_rect_t *box = vmesa->pClipRects;
108 drm_clip_rect_t *b = vmesa->sarea->boxes;
109 int n = 0;
110
111 if (!vmesa->saam) {
112 if (!all) {
113 #ifdef DEBUG
114 if (VIA_DEBUG) fprintf(stderr,"!all");
115 #endif
116 for (; i < nr; i++) {
117 GLint x = box[i].x1;
118 GLint y = box[i].y1;
119 GLint w = box[i].x2 - x;
120 GLint h = box[i].y2 - y;
121
122 if (x < cx) w -= cx - x, x = cx;
123 if (y < cy) h -= cy - y, y = cy;
124 if (x + w > cx + cw) w = cx + cw - x;
125 if (y + h > cy + ch) h = cy + ch - y;
126 if (w <= 0) continue;
127 if (h <= 0) continue;
128
129 b->x1 = x;
130 b->y1 = y;
131 b->x2 = x + w;
132 b->y2 = y + h;
133 b++;
134 n++;
135 }
136 }
137 else {
138 for (; i < nr; i++) {
139 *b++ = *(drm_clip_rect_t *)&box[i];
140 n++;
141 }
142 }
143 vmesa->sarea->nbox = n;
144 }
145 else {
146 GLuint scrn = 0;
147 scrn = vmesa->saam & S_MASK;
148
149 if (scrn == S0 || scrn == S1) {
150 if (!all) {
151 for (; i < nr; i++) {
152 GLint x = box[i].x1;
153 GLint y = box[i].y1;
154 GLint w = box[i].x2 - x;
155 GLint h = box[i].y2 - y;
156
157 if (x < cx) w -= cx - x, x = cx;
158 if (y < cy) h -= cy - y, y = cy;
159 if (x + w > cx + cw) w = cx + cw - x;
160 if (y + h > cy + ch) h = cy + ch - y;
161 if (w <= 0) continue;
162 if (h <= 0) continue;
163
164 b->x1 = x;
165 b->y1 = y;
166 b->x2 = x + w;
167 b->y2 = y + h;
168 b++;
169 n++;
170 }
171 }
172 else {
173 for (; i < nr; i++) {
174 *b++ = *(drm_clip_rect_t *)&box[i];
175 n++;
176 }
177 }
178 vmesa->sarea->nbox = n;
179 }
180 /* between */
181 else {
182 if (!all) {
183 for (; i < nr; i++) {
184 GLint x = box[i].x1;
185 GLint y = box[i].y1;
186 GLint w = box[i].x2 - x;
187 GLint h = box[i].y2 - y;
188
189 if (x < cx) w -= cx - x, x = cx;
190 if (y < cy) h -= cy - y, y = cy;
191 if (x + w > cx + cw) w = cx + cw - x;
192 if (y + h > cy + ch) h = cy + ch - y;
193 if (w <= 0) continue;
194 if (h <= 0) continue;
195
196 b->x1 = x;
197 b->y1 = y;
198 b->x2 = x + w;
199 b->y2 = y + h;
200 b++;
201 n++;
202 }
203
204 }
205 else {
206 for (; i < nr; i++) {
207 *b++ = *(drm_clip_rect_t *)&box[n];
208 n++;
209 }
210 }
211 *b++ = *(drm_clip_rect_t *)vmesa->pSaamRects;
212 vmesa->sarea->nbox = n;
213 }
214 }
215
216 {
217 if (flag & VIA_FRONT) {
218
219 if (vmesa->drawType == GLX_PBUFFER_BIT)
220 viaFillFrontPBuffer(vmesa);
221 else
222 viaFillFrontBuffer(vmesa);
223
224 if (vmesa->saam && (scrn == (S0 | S1))) {
225 nr = MIN2(i + VIA_NR_SAREA_CLIPRECTS, vmesa->numSaamRects);
226 box = vmesa->pSaamRects;
227 b = vmesa->sarea->boxes;
228 n = 0;
229
230 for (i = 0; i < nr; i++) {
231 *b++ = *(drm_clip_rect_t *)&box[n];
232 n++;
233 }
234
235 vmesa->sarea->nbox = n;
236 viaFillFrontBufferSaam(vmesa);
237 }
238 }
239
240 if (flag & VIA_BACK) {
241 viaFillBackBuffer(vmesa);
242 }
243
244 if (flag & VIA_DEPTH) {
245 double depth_clamp, range = 0xffffffff;
246 if (vmesa->hasStencil == 0) {
247 if (vmesa->depthBits == 32) {
248 depth_clamp = ((double)ctx->Depth.Clear)*range;
249 viaFillDepthBuffer(vmesa, (GLuint)depth_clamp);
250 }
251 else {
252 depth_clamp = ((double)ctx->Depth.Clear)*range;
253 viaFillDepthBuffer(vmesa, (GLuint)depth_clamp);
254 }
255 }
256 else {
257 depth_clamp = ((double)ctx->Depth.Clear)*range;
258 viaFillStencilDepthBuffer(vmesa, (GLuint)depth_clamp);
259 }
260 }
261 /*=* [DBG] Fix tuxracer depth error *=*/
262 else if (flag & VIA_STENCIL) {
263 viaFillStencilBuffer(vmesa, (GLuint)ctx->Stencil.Clear);
264 }
265 }
266 }
267 UNLOCK_HARDWARE(vmesa);
268 vmesa->uploadCliprects = GL_TRUE;
269 }
270
271 if (mask)
272 _swrast_Clear(ctx, mask, all, cx, cy, cw, ch);
273 #ifdef DEBUG
274 if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
275 #endif
276 }
277
278 /*
279 * Copy the back buffer to the front buffer.
280 */
281 void viaCopyBuffer(const __DRIdrawablePrivate *dPriv)
282 {
283 viaContextPtr vmesa;
284 drm_clip_rect_t *pbox;
285 int nbox, i;
286 GLuint scrn = 0, side = 0;
287 #ifdef DEBUG
288 if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
289 #endif
290 assert(dPriv);
291 assert(dPriv->driContextPriv);
292 assert(dPriv->driContextPriv->driverPrivate);
293
294 vmesa = (viaContextPtr)dPriv->driContextPriv->driverPrivate;
295
296 VIA_FIREVERTICES(vmesa);
297 LOCK_HARDWARE(vmesa);
298
299 scrn = vmesa->saam & S_MASK;
300 side = vmesa->saam & P_MASK;
301
302 pbox = vmesa->pClipRects;
303 nbox = vmesa->numClipRects;
304
305 #ifdef DEBUG
306 if (VIA_DEBUG) fprintf(stderr, "%s %d cliprects (%d), SAAM (%d)\n",
307 __FUNCTION__, nbox, vmesa->drawType, vmesa->saam);
308 #endif
309
310
311 if (vmesa->drawType == GLX_PBUFFER_BIT) {
312 viaDoSwapPBuffers(vmesa);
313 #ifdef DEBUG
314 if (VIA_DEBUG) fprintf(stderr, "%s SwapPBuffers\n", __FUNCTION__);
315 #endif /*=* [DBG] for pbuffer *=*/
316 }
317 else {
318 GLuint scrn = 0;
319 scrn = vmesa->saam & S_MASK;
320 if (!vmesa->saam) {
321 for (i = 0; i < nbox; ) {
322 int nr = MIN2(i + VIA_NR_SAREA_CLIPRECTS, dPriv->numClipRects);
323 drm_clip_rect_t *b = (drm_clip_rect_t *)vmesa->sarea->boxes;
324
325 vmesa->sarea->nbox = nr - i;
326
327 for (; i < nr; i++)
328 *b++ = pbox[i];
329 viaDoSwapBuffers(vmesa);
330 #ifdef DEBUG
331 if (VIA_DEBUG) fprintf(stderr, "%s SwapBuffers\n", __FUNCTION__);
332 #endif
333 }
334 }
335 else if (scrn == S0 || scrn == S1) {
336 for (i = 0; i < nbox; ) {
337 int nr = MIN2(i + VIA_NR_SAREA_CLIPRECTS, vmesa->numClipRects);
338 drm_clip_rect_t *b = (drm_clip_rect_t *)vmesa->sarea->boxes;
339
340 vmesa->sarea->nbox = nr - i;
341
342 for (; i < nr; i++) {
343 *b++ = pbox[i];
344 }
345 viaDoSwapBuffers(vmesa);
346 }
347 }
348 /* between */
349 else {
350 for (i = 0; i < nbox; ) {
351 int nr = MIN2(i + VIA_NR_SAREA_CLIPRECTS, dPriv->numClipRects);
352 drm_clip_rect_t *b = (drm_clip_rect_t *)vmesa->sarea->boxes;
353
354 vmesa->sarea->nbox = nr - i;
355
356 for (; i < nr; i++)
357 *b++ = pbox[i];
358 viaDoSwapBuffers(vmesa);
359 }
360
361 pbox = vmesa->pSaamRects;
362 nbox = vmesa->numSaamRects;
363
364 for (i = 0; i < nbox; ) {
365 int nr = MIN2(i + VIA_NR_SAREA_CLIPRECTS, vmesa->numSaamRects);
366 drm_clip_rect_t *b = (drm_clip_rect_t *)vmesa->sarea->boxes;
367
368 vmesa->sarea->nbox = nr - i;
369
370 for (; i < nr; i++)
371 *b++ = pbox[i];
372
373 viaDoSwapBuffersSaam(vmesa);
374 }
375 }
376 }
377 UNLOCK_HARDWARE(vmesa);
378 vmesa->uploadCliprects = GL_TRUE;
379 #ifdef DEBUG
380 if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
381 #endif
382 }
383
384 /*
385 * XXX implement when full-screen extension is done.
386 */
387 void viaPageFlip(const __DRIdrawablePrivate *dPriv)
388 {
389 /*=* John Sheng [2003.5.31] flip *=*/
390 viaContextPtr vmesa = (viaContextPtr)dPriv->driContextPriv->driverPrivate;
391 GLuint *vb = viaCheckDma(vmesa, vmesa->sarea->nbox*56);
392 GLuint nBackBase;
393 viaBuffer buffer_tmp;
394 GLcontext *ctx;
395
396 #ifdef DEBUG
397 if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
398 #endif
399 assert(dPriv);
400 assert(dPriv->driContextPriv);
401 assert(dPriv->driContextPriv->driverPrivate);
402
403 ctx = vmesa->glCtx;
404
405 /*=* [DBG] make draw to front buffer *=*/
406 if(DRAW_FRONT)
407 return;
408
409 /* Page Flip*/
410 if(GL_FALSE) {
411 viaFlushPrimsLocked(vmesa);
412 while ((*(volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x200) & 0x2) != 0x2);
413 while (*(volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x200) & 0x2);
414 nBackBase = vmesa->back.offset >> 1;
415
416 /*if (nFirstFlip) {
417 *vb++ = HALCYON_HEADER2;
418 *vb++ = 0x00fe0000;
419 *vb++ = 0x00001004;
420 *vb++ = 0x00001004;
421 vmesa->dmaLow += 16;
422
423 nFirstFlip = GL_FALSE;
424 }
425 SetReg2DAGP(0x214, nBackBase);
426 viaFlushPrimsLocked(vmesa);*/
427 if (nFirstFlip) {
428 *((volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x43c)) = 0x00fe0000;
429 *((volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x440)) = 0x00001004;
430 nFirstFlip = GL_FALSE;
431 }
432 *((GLuint *)((GLuint)vmesa->regMMIOBase + 0x214)) = nBackBase;
433 }
434 /* Auto Swap */
435 else {
436 viaFlushPrimsLocked(vmesa);
437 vb = viaCheckDma(vmesa, vmesa->sarea->nbox*56);
438 if (nFirstSwap) {
439 *vb++ = HALCYON_HEADER2;
440 *vb++ = 0x00fe0000;
441 *vb++ = 0x0000000e;
442 *vb++ = 0x0000000e;
443 vmesa->dmaLow += 16;
444
445 nFirstSwap = GL_FALSE;
446 }
447 nBackBase = (vmesa->back.offset << 1);
448
449 *vb++ = HALCYON_HEADER2;
450 *vb++ = 0x00fe0000;
451 *vb++ = (HC_SubA_HFBBasL << 24) | (nBackBase & 0xFFFFF8) | 0x2;
452 *vb++ = (HC_SubA_HFBDrawFirst << 24) |
453 ((nBackBase & 0xFF000000) >> 24) | 0x0100;
454 vmesa->dmaLow += 16;
455 viaFlushPrimsLocked(vmesa);
456 }
457
458
459 memcpy(&buffer_tmp, &vmesa->back, sizeof(viaBuffer));
460 memcpy(&vmesa->back, &vmesa->front, sizeof(viaBuffer));
461 memcpy(&vmesa->front, &buffer_tmp, sizeof(viaBuffer));
462
463 if(vmesa->currentPage) {
464 vmesa->currentPage = 0;
465 if (vmesa->glCtx->Color._DrawDestMask[0] == __GL_BACK_BUFFER_MASK) {
466 ctx->Driver.DrawBuffer(ctx, GL_BACK);
467 }
468 else {
469 ctx->Driver.DrawBuffer(ctx, GL_FRONT);
470 }
471 }
472 else {
473 vmesa->currentPage = 1;
474 if (vmesa->glCtx->Color._DrawDestMask[0] == __GL_BACK_BUFFER_MASK) {
475 ctx->Driver.DrawBuffer(ctx, GL_BACK);
476 }
477 else {
478 ctx->Driver.DrawBuffer(ctx, GL_FRONT);
479 }
480 }
481 #ifdef DEBUG
482 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
483 #endif
484
485 }
486
487 /* This waits for *everybody* to finish rendering -- overkill.
488 */
489 void viaDmaFinish(viaContextPtr vmesa)
490 {
491 #ifdef DEBUG
492 if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
493 #endif
494 VIA_FIREVERTICES(vmesa);
495 LOCK_HARDWARE(vmesa);
496 UNLOCK_HARDWARE(vmesa);
497 #ifdef DEBUG
498 if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
499 #endif
500 }
501
502 void viaRegetLockQuiescent(viaContextPtr vmesa)
503 {
504 drmUnlock(vmesa->driFd, vmesa->hHWContext);
505 }
506
507 static int intersect_rect(drm_clip_rect_t *out,
508 drm_clip_rect_t *a,
509 drm_clip_rect_t *b)
510 {
511 *out = *a;
512
513 if (b->x1 > out->x1) out->x1 = b->x1;
514 if (b->x2 < out->x2) out->x2 = b->x2;
515 if (out->x1 >= out->x2) return 0;
516
517 if (b->y1 > out->y1) out->y1 = b->y1;
518 if (b->y2 < out->y2) out->y2 = b->y2;
519 if (out->y1 >= out->y2) return 0;
520
521 return 1;
522 }
523
524 void viaFlushPrimsLocked(viaContextPtr vmesa)
525 {
526 drm_clip_rect_t *pbox = (drm_clip_rect_t *)vmesa->pClipRects;
527 int nbox = vmesa->numClipRects;
528 drm_via_sarea_t *sarea = vmesa->sarea;
529 drm_via_flush_agp_t agpCmd;
530 drm_via_flush_sys_t sysCmd;
531 GLuint *vb = viaCheckDma(vmesa, 0);
532 int i;
533
534 if (vmesa->dmaLow == DMA_OFFSET) {
535 return;
536 }
537 if (vmesa->dmaLow > 2097152)
538 fprintf(stderr, "buffer overflow in Flush Prims = %d\n",vmesa->dmaLow);
539
540 switch (vmesa->dmaLow & 0x1F) {
541 case 8:
542 *vb++ = HC_HEADER2;
543 *vb++ = (HC_ParaType_NotTex << 16);
544 *vb++ = HC_DUMMY;
545 *vb++ = HC_DUMMY;
546 *vb++ = HC_DUMMY;
547 *vb++ = HC_DUMMY;
548 vmesa->dmaLow += 24;
549 break;
550 case 16:
551 *vb++ = HC_HEADER2;
552 *vb++ = (HC_ParaType_NotTex << 16);
553 *vb++ = HC_DUMMY;
554 *vb++ = HC_DUMMY;
555 vmesa->dmaLow += 16;
556 break;
557 case 24:
558 *vb++ = HC_HEADER2;
559 *vb++ = (HC_ParaType_NotTex << 16);
560 *vb++ = HC_DUMMY;
561 *vb++ = HC_DUMMY;
562 *vb++ = HC_DUMMY;
563 *vb++ = HC_DUMMY;
564 *vb++ = HC_DUMMY;
565 *vb++ = HC_DUMMY;
566 *vb++ = HC_DUMMY;
567 *vb++ = HC_DUMMY;
568 vmesa->dmaLow += 40;
569 break;
570 case 0:
571 break;
572 default:
573 break;
574 }
575
576 if (vmesa->useAgp) {
577 agpCmd.offset = 0x0;
578 agpCmd.size = vmesa->dmaLow;
579 agpCmd.index = vmesa->dma[vmesa->dmaIndex].index;
580 agpCmd.discard = 0;
581 }
582 else {
583 sysCmd.offset = 0x0;
584 sysCmd.size = vmesa->dmaLow;
585 sysCmd.index = (GLuint)vmesa->dma[vmesa->dmaIndex].map;
586 sysCmd.discard = 0;
587 }
588
589 sarea->vertexPrim = vmesa->hwPrimitive;
590
591 if (!nbox) {
592 if (vmesa->useAgp)
593 agpCmd.size = 0;
594 else
595 sysCmd.size = 0;
596 }
597 else if (nbox > VIA_NR_SAREA_CLIPRECTS) {
598 vmesa->uploadCliprects = GL_TRUE;
599 }
600 /*=* John Sheng [2003.5.31] flip *=*/
601 /*#ifdef DEBUG
602 if (VIA_DEBUG) {
603 GLuint i;
604 GLuint *data = (GLuint *)vmesa->dmaAddr;
605 for (i = 0; i < vmesa->dmaLow; i += 16) {
606 fprintf(stderr, "%08x ", *data++);
607 fprintf(stderr, "%08x ", *data++);
608 fprintf(stderr, "%08x ", *data++);
609 fprintf(stderr, "%08x\n", *data++);
610 }
611 fprintf(stderr, "******************************************\n");
612 }
613 #endif*/
614 if (!nbox || !vmesa->uploadCliprects) {
615 if (nbox == 1)
616 sarea->nbox = 0;
617 else
618 sarea->nbox = nbox;
619
620 if (vmesa->useAgp) {
621 agpCmd.discard = 1;
622 flush_agp(vmesa, &agpCmd);
623 }
624 else {
625 sysCmd.discard = 1;
626 flush_sys(vmesa, &sysCmd);
627 }
628 }
629 else {
630 GLuint scrn;
631 GLuint side;
632 scrn = vmesa->saam & S_MASK;
633 side = vmesa->saam & P_MASK;
634
635 for (i = 0; i < nbox; ) {
636 int nr = MIN2(i + VIA_NR_SAREA_CLIPRECTS, nbox);
637 drm_clip_rect_t *b = sarea->boxes;
638
639 if (!vmesa->saam) {
640 if (vmesa->glCtx->Scissor.Enabled) {
641 sarea->nbox = 0;
642
643 for (; i < nr; i++) {
644 b->x1 = pbox[i].x1 - vmesa->drawX;
645 b->y1 = pbox[i].y1 - vmesa->drawY;
646 b->x2 = pbox[i].x2 - vmesa->drawX;
647 b->y2 = pbox[i].y2 - vmesa->drawY;
648 if (intersect_rect(b, b, &vmesa->scissorRect)) {
649 sarea->nbox++;
650 b++;
651 }
652 }
653 if (!sarea->nbox) {
654 if (nr < nbox) continue;
655 agpCmd.size = 0;
656 }
657 }
658 else {
659 sarea->nbox = nr - i;
660 for (; i < nr; i++, b++) {
661 b->x1 = pbox[i].x1 - vmesa->drawX;
662 b->y1 = pbox[i].y1 - vmesa->drawY;
663 b->x2 = pbox[i].x2 - vmesa->drawX;
664 b->y2 = pbox[i].y2 - vmesa->drawY;
665 }
666 }
667 }
668 else if (scrn == S0 || scrn == S1){
669 if (vmesa->scissor) {
670 sarea->nbox = 0;
671 for (; i < nr; i++) {
672 b->x1 = pbox[i].x1 - vmesa->drawX;
673 b->y1 = pbox[i].y1 - vmesa->drawY;
674 b->x2 = pbox[i].x2 - vmesa->drawX;
675 b->y2 = pbox[i].y2 - vmesa->drawY;
676 if (intersect_rect(b, b, &vmesa->scissorRect)) {
677 sarea->nbox++;
678 b++;
679 }
680 }
681 if (!sarea->nbox) {
682 if (nr < nbox) continue;
683 agpCmd.size = 0;
684 }
685 }
686 else {
687 sarea->nbox = nr - i;
688 for (; i < nr; i++, b++) {
689 b->x1 = pbox[i].x1 - vmesa->drawX;
690 b->y1 = pbox[i].y1 - vmesa->drawY;
691 b->x2 = pbox[i].x2 - vmesa->drawX;
692 b->y2 = pbox[i].y2 - vmesa->drawY;
693 }
694 }
695
696 }
697 /* between */
698 else {
699 if (vmesa->scissor) {
700 sarea->nbox = 0;
701 for (; i < nr; i++) {
702 b->x1 = pbox[i].x1 - vmesa->drawX;
703 b->y1 = pbox[i].y1 - vmesa->drawY;
704 b->x2 = pbox[i].x2 - vmesa->drawX;
705 b->y2 = pbox[i].y2 - vmesa->drawY;
706
707 if (intersect_rect(b, b, &vmesa->scissorRect)) {
708 sarea->nbox++;
709 b++;
710 }
711 }
712 if (!sarea->nbox) {
713 if (nr < nbox) continue;
714 agpCmd.size = 0;
715 }
716 }
717 else {
718 sarea->nbox = nr - i;
719 for (; i < nr; i++, b++) {
720 b->x1 = pbox[i].x1 - vmesa->drawX;
721 b->y1 = pbox[i].y1 - vmesa->drawY;
722 b->x2 = pbox[i].x2 - vmesa->drawX;
723 b->y2 = pbox[i].y2 - vmesa->drawY;
724 }
725 }
726 }
727
728 if (nr == nbox) {
729 if (vmesa->useAgp) {
730 agpCmd.discard = 1;
731 flush_agp(vmesa, &agpCmd);
732 }
733 else {
734 sysCmd.discard = 1;
735 flush_sys(vmesa, &sysCmd);
736 }
737 }
738
739 if (scrn == (S0 | S1)) {
740 pbox = (drm_clip_rect_t *)vmesa->pSaamRects;
741 nbox = vmesa->numSaamRects;
742 for (i = 0; i < nbox; ) {
743 int nr = MIN2(i + VIA_NR_SAREA_CLIPRECTS, nbox);
744 drm_clip_rect_t *b = sarea->boxes;
745 if (vmesa->scissor) {
746 sarea->nbox = 0;
747 for (; i < nr; i++) {
748 b->x1 = pbox[i].x1 - vmesa->drawXSaam;
749 b->y1 = pbox[i].y1 - vmesa->drawYSaam;
750 b->x2 = pbox[i].x2 - vmesa->drawXSaam;
751 b->y2 = pbox[i].y2 - vmesa->drawYSaam;
752
753 if (intersect_rect(b, b, &vmesa->scissorRect)) {
754 sarea->nbox++;
755 b++;
756 }
757 }
758 if (!sarea->nbox) {
759 if (nr < nbox) continue;
760 agpCmd.size = 0;
761 }
762 }
763 else {
764 sarea->nbox = nr - i;
765 for (; i < nr; i++, b++) {
766 b->x1 = pbox[i].x1 - vmesa->drawXSaam;
767 b->y1 = pbox[i].y1 - vmesa->drawYSaam;
768 b->x2 = pbox[i].x2 - vmesa->drawXSaam;
769 b->y2 = pbox[i].y2 - vmesa->drawYSaam;
770 }
771 }
772 }
773 flush_agp_saam(vmesa, &agpCmd);
774 }
775 }
776 }
777 #ifdef DEBUG
778 if (VIA_DEBUG) {
779 GLuint i;
780 GLuint *data = (GLuint *)vmesa->dmaAddr;
781 for (i = 0; i < vmesa->dmaLow; i += 16) {
782 fprintf(stderr, "%08x ", *data++);
783 fprintf(stderr, "%08x ", *data++);
784 fprintf(stderr, "%08x ", *data++);
785 fprintf(stderr, "%08x\n", *data++);
786 }
787 fprintf(stderr, "******************************************\n");
788 }
789 #endif
790 /* Reset vmesa vars:
791 */
792 vmesa->dmaLow = DMA_OFFSET;
793 if (vmesa->dmaIndex) {
794 vmesa->dmaAddr = vmesa->dma[0].map;
795 vmesa->dmaHigh = vmesa->dma[0].size;
796 vmesa->dmaLastPrim = DMA_OFFSET;
797 vmesa->dmaIndex = 0;
798 }
799 else {
800 vmesa->dmaAddr = vmesa->dma[1].map;
801 vmesa->dmaHigh = vmesa->dma[1].size;
802 vmesa->dmaLastPrim = DMA_OFFSET;
803 vmesa->dmaIndex = 1;
804 }
805 }
806
807 void viaFlushPrims(viaContextPtr vmesa)
808 {
809 #ifdef DEBUG
810 if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
811 #endif
812 if (vmesa->dmaLow) {
813 LOCK_HARDWARE(vmesa);
814 viaFlushPrimsLocked(vmesa);
815 UNLOCK_HARDWARE(vmesa);
816 }
817 #ifdef DEBUG
818 if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
819 #endif
820 }
821
822 static void viaFlush(GLcontext *ctx)
823 {
824 viaContextPtr vmesa = VIA_CONTEXT(ctx);
825 #ifdef DEBUG
826 if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
827 #endif
828 VIA_FIREVERTICES(vmesa);
829 #ifdef DEBUG
830 if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
831 #endif
832 }
833
834 static void viaFinish(GLcontext *ctx)
835 {
836 #ifdef DEBUG
837 if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
838 if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
839 #endif
840 return;
841 }
842
843 static void viaClearStencil(GLcontext *ctx, int s)
844 {
845 return;
846 }
847
848 void viaInitIoctlFuncs(GLcontext *ctx)
849 {
850 ctx->Driver.Flush = viaFlush;
851 ctx->Driver.Clear = viaClear;
852 ctx->Driver.Finish = viaFinish;
853 ctx->Driver.ClearStencil = viaClearStencil;
854 }
855
856 void viaFillFrontBuffer(viaContextPtr vmesa)
857 {
858 GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offsetX, offset,i;
859 drm_clip_rect_t *b = vmesa->sarea->boxes;
860 GLuint *vb = viaCheckDma(vmesa, vmesa->sarea->nbox*48);
861 GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
862 GLuint pixel = (GLuint)vmesa->ClearColor;
863
864 offset = vmesa->viaScreen->fbOffset + (vmesa->drawY * vmesa->front.pitch + vmesa->drawX * bytePerPixel);
865 #ifdef DEBUG
866 if (VIA_DEBUG) fprintf(stderr, "Fill Front offset = %08x\n", offset);
867 #endif
868 nDestBase = offset & 0xffffffe0;
869 nDestPitch = vmesa->front.pitch;
870
871 for (i = 0; i < vmesa->sarea->nbox ; i++) {
872 nDestWidth = b->x2 - b->x1 - 1;
873 nDestHeight = b->y2 - b->y1 - 1;
874
875 if (bytePerPixel == 4)
876 offsetX = (b->x1 - vmesa->drawX) + (vmesa->drawX & 7);
877 else
878 offsetX = (b->x1 - vmesa->drawX) + (vmesa->drawX & 15);
879
880
881 if (GL_TRUE) {
882 /* GEFGCOLOR*/
883 SetReg2DAGP(0x18, pixel | 0x00000000);
884 /* GEWD*/
885 SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16));
886 /* GEDST*/
887 SetReg2DAGP(0x0C, (offsetX | ((b->y1 - vmesa->drawY) << 16)));
888 /* GEDSTBASE*/
889 SetReg2DAGP(0x34, (nDestBase >> 3));
890 /* GEPITCH*/
891 SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000);
892 /* BITBLT*/
893 SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000);
894 }
895 b++;
896 }
897
898 viaFlushPrimsLocked(vmesa);
899 }
900
901 void viaFillFrontBufferSaam(viaContextPtr vmesa)
902 {
903 GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offsetX, offset,i;
904 drm_clip_rect_t *b = vmesa->sarea->boxes;
905 GLuint *vb = viaCheckDma(vmesa, vmesa->sarea->nbox*48);
906 GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
907 GLuint pixel = (GLuint)vmesa->ClearColor;
908
909 offset = vmesa->viaScreen->fbSize +
910 (vmesa->drawYSaam * vmesa->front.pitch + vmesa->drawXSaam * bytePerPixel);
911 nDestBase = offset & 0xffffffe0;
912 nDestPitch = vmesa->front.pitch;
913
914 for (i = 0; i < vmesa->sarea->nbox ; i++) {
915 nDestWidth = b->x2 - b->x1 - 1;
916 nDestHeight = b->y2 - b->y1 - 1;
917
918 if (bytePerPixel == 4)
919 offsetX = (b->x1 - vmesa->drawXSaam) + (vmesa->drawXSaam & 7);
920 else
921 offsetX = (b->x1 - vmesa->drawXSaam) + (vmesa->drawXSaam & 15);
922
923 if (GL_TRUE) {
924 /* GEFGCOLOR*/
925 SetReg2DAGP(0x18, pixel | 0x00000000);
926 /* GEWD*/
927 SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16));
928 /* GEDST*/
929 SetReg2DAGP(0x0C, (offsetX | ((b->y1 - vmesa->drawYSaam) << 16)));
930 /* GEDSTBASE*/
931 SetReg2DAGP(0x34, (nDestBase >> 3));
932 /* GEPITCH*/
933 SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000);
934 /* BITBLT*/
935 SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000);
936 }
937 b++;
938 }
939
940 viaFlushPrimsLocked(vmesa);
941 }
942
943 void viaFillFrontPBuffer(viaContextPtr vmesa)
944 {
945 GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offsetX, offset;
946 GLuint *vb = viaCheckDma(vmesa, vmesa->sarea->nbox*48);
947 GLuint pixel = (GLuint)vmesa->ClearColor;
948
949 offset = vmesa->front.offset;
950 #ifdef DEBUG
951 if (VIA_DEBUG) fprintf(stderr, "Fill PFront offset = %08x\n", offset);
952 #endif
953 nDestBase = offset;
954 nDestPitch = vmesa->front.pitch;
955
956 nDestWidth = vmesa->driDrawable->w - 1;
957 nDestHeight = vmesa->driDrawable->h - 1;
958
959 offsetX = 0;
960
961 /* GEFGCOLOR*/
962 SetReg2DAGP(0x18, pixel | 0x00000000);
963 /* GEWD*/
964 SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16));
965 /* GEDST*/
966 SetReg2DAGP(0x0C, (offsetX | (0 << 16)));
967 /* GEDSTBASE*/
968 SetReg2DAGP(0x34, (nDestBase >> 3));
969 /* GEPITCH*/
970 SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000);
971 /* BITBLT*/
972 SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000);
973
974 viaFlushPrimsLocked(vmesa);
975 }
976
977 void viaFillBackBuffer(viaContextPtr vmesa)
978 {
979 GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offsetX, offset;
980 GLcontext *ctx = vmesa->glCtx;
981 GLuint *vb = viaCheckDma(vmesa, 48);
982 GLuint pixel = (GLuint)vmesa->ClearColor;
983 GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
984
985 offset = vmesa->back.offset;
986 #ifdef DEBUG
987 if (VIA_DEBUG) fprintf(stderr, "Fill Back offset = %08x\n", offset);
988 #endif
989 nDestBase = offset;
990 nDestPitch = vmesa->back.pitch;
991 offsetX = vmesa->drawXoff;
992
993 {
994 if (!ctx->Scissor.Enabled) {
995
996 nDestWidth = (vmesa->back.pitch / vmesa->viaScreen->bitsPerPixel * 8) - 1;
997 nDestHeight = vmesa->driDrawable->h -1;
998
999 /* GEFGCOLOR */
1000 SetReg2DAGP(0x18, pixel | 0x00000000);
1001 /* GEWD */
1002 SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16));
1003 /* GEDST */
1004 SetReg2DAGP(0x0C, (offsetX | (0 << 16)));
1005 /* GEDSTBASE */
1006 SetReg2DAGP(0x34, (nDestBase >> 3));
1007 /* GEPITCH */
1008 SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000);
1009 /* BITBLT */
1010 SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000);
1011 }
1012 /*=* John Sheng [2003.7.18] texenv *=*/
1013 else {
1014 int i;
1015 drm_clip_rect_t *b = vmesa->sarea->boxes;
1016 for (i = 0; i < vmesa->sarea->nbox ; i++) {
1017 nDestWidth = b->x2 - b->x1 - 1;
1018 nDestHeight = b->y2 - b->y1 - 1;
1019
1020 if (bytePerPixel == 4)
1021 offsetX = (b->x1 - vmesa->drawX) + (vmesa->drawX & 7);
1022 else
1023 offsetX = (b->x1 - vmesa->drawX) + (vmesa->drawX & 15);
1024
1025 /* GEFGCOLOR */
1026 SetReg2DAGP(0x18, pixel | 0x00000000);
1027 /* GEWD */
1028 SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16));
1029 /* GEDST */
1030 SetReg2DAGP(0x0C, ((offsetX + (b->x1 - vmesa->drawX)) | ((b->y1 - vmesa->drawY) << 16)));
1031 /* GEDSTBASE */
1032 SetReg2DAGP(0x34, (nDestBase >> 3));
1033 /* GEPITCH */
1034 SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000);
1035 /* BITBLT */
1036 SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000);
1037 b++;
1038 }
1039 }
1040 #ifdef DEBUG
1041 if (VIA_DEBUG) {
1042 fprintf(stderr," width = %08x\n", nDestWidth);
1043 fprintf(stderr," height = %08x\n", nDestHeight);
1044 }
1045 #endif
1046 }
1047 }
1048
1049 void viaFillStencilDepthBuffer(viaContextPtr vmesa, GLuint pixel)
1050 {
1051 GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offsetX, offset;
1052 GLuint *vb = viaCheckDma(vmesa, 80);
1053 GLuint nMask;
1054
1055 offset = vmesa->depth.offset;
1056 #ifdef DEBUG
1057 if (VIA_DEBUG) fprintf(stderr, "Fill Stencil Depth offset = %08x\n", offset);
1058 #endif
1059 nDestBase = offset;
1060 nDestPitch = vmesa->depth.pitch;
1061 offsetX = vmesa->drawXoff;
1062 pixel = pixel & 0xffffff00;
1063 nMask = 0x10000000;
1064
1065 {
1066 nDestWidth = (vmesa->depth.pitch / vmesa->depthBits * 8) - 1 - offsetX;
1067 nDestHeight = vmesa->driDrawable->h -1;
1068
1069 if (vmesa->viaScreen->bitsPerPixel == vmesa->depth.bpp) {
1070 /* GEFGCOLOR */
1071 SetReg2DAGP(0x18, pixel);
1072 /* GEMASK */
1073 SetReg2DAGP(0x2C, nMask);
1074 /* GEWD */
1075 SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16));
1076 /* GEDST */
1077 SetReg2DAGP(0x0C, (offsetX | (0 << 16)));
1078 /* GEDSTBASE */
1079 SetReg2DAGP(0x34, (nDestBase >> 3));
1080 /* GEPITCH */
1081 SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000);
1082 /* BITBLT */
1083 SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000);
1084 /* GEMASK */
1085 SetReg2DAGP(0x2C, 0x00000000);
1086 }
1087 else {
1088 GLuint EngStatus = *(vmesa->pnGEMode);
1089 /* GEMODE */
1090 SetReg2DAGP(0x04, (EngStatus & 0xFFFFFCFF) | 0x300);
1091 /* GEFGCOLOR */
1092 SetReg2DAGP(0x18, pixel);
1093 /* GEMASK */
1094 SetReg2DAGP(0x2C, nMask);
1095 /* GEWD */
1096 SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16));
1097 /* GEDST */
1098 SetReg2DAGP(0x0C, (offsetX | (0 << 16)));
1099 /* GEDSTBASE */
1100 SetReg2DAGP(0x34, (nDestBase >> 3));
1101 /* GEPITCH */
1102 SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000);
1103 /* BITBLT */
1104 SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000);
1105 /* GEMODE */
1106 SetReg2DAGP(0x04, EngStatus);
1107 /* GEMASK */
1108 SetReg2DAGP(0x2C, 0x00000000);
1109
1110 WAIT_IDLE
1111 }
1112 }
1113
1114 if (vmesa->glCtx->Color._DrawDestMask[0] == __GL_BACK_BUFFER_MASK) {
1115 viaFlushPrimsLocked(vmesa);
1116 }
1117 }
1118
1119 void viaFillStencilBuffer(viaContextPtr vmesa, GLuint pixel)
1120 {
1121 GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offsetX, offset;
1122 GLuint *vb = viaCheckDma(vmesa, 80);
1123 GLuint nMask;
1124
1125 offset = vmesa->depth.offset;
1126 #ifdef DEBUG
1127 if (VIA_DEBUG) fprintf(stderr, "Fill Stencil offset = %08x\n", offset);
1128 #endif
1129 nDestBase = offset;
1130 nDestPitch = vmesa->depth.pitch;
1131 offsetX = vmesa->drawXoff;
1132 pixel = pixel & 0x000000ff;
1133 nMask = 0xe0000000;
1134
1135 {
1136 nDestWidth = (vmesa->depth.pitch / vmesa->depthBits * 8) - 1 - offsetX;
1137 nDestHeight = vmesa->driDrawable->h -1;
1138
1139 if (vmesa->viaScreen->bitsPerPixel == vmesa->depth.bpp) {
1140 /* GEFGCOLOR */
1141 SetReg2DAGP(0x18, pixel);
1142 /* GEMASK */
1143 SetReg2DAGP(0x2C, nMask);
1144 /* GEWD */
1145 SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16));
1146 /* GEDST */
1147 SetReg2DAGP(0x0C, (offsetX | (0 << 16)));
1148 /* GEDSTBASE */
1149 SetReg2DAGP(0x34, (nDestBase >> 3));
1150 /* GEPITCH */
1151 SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000);
1152 /* BITBLT */
1153 SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000);
1154 /* GEMASK */
1155 SetReg2DAGP(0x2C, 0x00000000);
1156 }
1157 else {
1158 GLuint EngStatus = *(vmesa->pnGEMode);
1159 /* GEMODE */
1160 SetReg2DAGP(0x04, (EngStatus & 0xFFFFFCFF) | 0x300);
1161 /* GEFGCOLOR */
1162 SetReg2DAGP(0x18, pixel);
1163 /* GEMASK */
1164 SetReg2DAGP(0x2C, nMask);
1165 /* GEWD */
1166 SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16));
1167 /* GEDST */
1168 SetReg2DAGP(0x0C, (offsetX | (0 << 16)));
1169 /* GEDSTBASE */
1170 SetReg2DAGP(0x34, (nDestBase >> 3));
1171 /* GEPITCH */
1172 SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000);
1173 /* BITBLT */
1174 SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000);
1175 /* GEMODE */
1176 SetReg2DAGP(0x04, EngStatus);
1177 /* GEMASK */
1178 SetReg2DAGP(0x2C, 0x00000000);
1179 }
1180 }
1181
1182 if (vmesa->glCtx->Color._DrawDestMask[0] == __GL_BACK_BUFFER_MASK) {
1183 viaFlushPrimsLocked(vmesa);
1184 }
1185 }
1186
1187 void viaFillDepthBuffer(viaContextPtr vmesa, GLuint pixel)
1188 {
1189 GLuint nDestBase, nDestPitch, nDestWidth, nDestHeight, offsetX, offset;
1190 GLuint *vb = viaCheckDma(vmesa, 72);
1191 offset = vmesa->depth.offset;
1192 #ifdef DEBUG
1193 if (VIA_DEBUG) fprintf(stderr, "Fill Depth offset = %08x\n", offset);
1194 #endif
1195 nDestBase = offset;
1196 nDestPitch = vmesa->depth.pitch;
1197 offsetX = vmesa->drawXoff;
1198
1199 {
1200 nDestWidth = (vmesa->depth.pitch / vmesa->depthBits * 8) - 1 - offsetX;
1201 nDestHeight = vmesa->driDrawable->h -1;
1202
1203 if (vmesa->viaScreen->bitsPerPixel == vmesa->depth.bpp) {
1204 /* GEFGCOLOR */
1205 SetReg2DAGP(0x18, pixel);
1206 /* GEMASK */
1207 SetReg2DAGP(0x2C, 0x0);
1208 /* GEWD */
1209 SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16));
1210 /* GEDST */
1211 SetReg2DAGP(0x0C, (offsetX | (0 << 16)));
1212 /* GEDSTBASE */
1213 SetReg2DAGP(0x34, (nDestBase >> 3));
1214 /* GEPITCH */
1215 SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000);
1216 /* BITBLT */
1217 SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000);
1218 }
1219 /* depth = 16, color = 32 */
1220 else if (vmesa->depth.bpp == 16) {
1221 GLuint EngStatus = *(vmesa->pnGEMode);
1222
1223 /* GEMODE */
1224 SetReg2DAGP(0x04, (EngStatus & 0xFFFFFCFF) | 0x100);
1225 /* GEMASK */
1226 SetReg2DAGP(0x2C, 0x0);
1227 /* GEFGCOLOR */
1228 SetReg2DAGP(0x18, pixel);
1229 /* GEWD */
1230 SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16));
1231 /* GEDST */
1232 SetReg2DAGP(0x0C, (offsetX | (0 << 16)));
1233 /* GEDSTBASE */
1234 SetReg2DAGP(0x34, (nDestBase >> 3));
1235 /* GEPITCH */
1236 SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000);
1237 /* BITBLT */
1238 SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000);
1239 /* GEMODE */
1240 SetReg2DAGP(0x04, EngStatus);
1241 }
1242 /* depth = 32, color = 16 */
1243 else {
1244 GLuint EngStatus = *(vmesa->pnGEMode);
1245
1246 /* GEMODE */
1247 SetReg2DAGP(0x04, (EngStatus & 0xFFFFFCFF) | 0x300);
1248 /* GEMASK */
1249 SetReg2DAGP(0x2C, 0x0);
1250 /* GEFGCOLOR */
1251 SetReg2DAGP(0x18, pixel);
1252 /* GEWD */
1253 SetReg2DAGP(0x10, nDestWidth | (nDestHeight << 16));
1254 /* GEDST */
1255 SetReg2DAGP(0x0C, (offsetX | (0 << 16)));
1256 /* GEDSTBASE */
1257 SetReg2DAGP(0x34, (nDestBase >> 3));
1258 /* GEPITCH */
1259 SetReg2DAGP(0x38, (((nDestPitch >> 3) << 16) & 0x7FF0000) | 0x80000000);
1260 /* BITBLT */
1261 SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xF0000000);
1262 /* GEMODE */
1263 SetReg2DAGP(0x04, EngStatus);
1264 }
1265 }
1266
1267 if (vmesa->glCtx->Color._DrawDestMask[0] == __GL_BACK_BUFFER_MASK) {
1268 viaFlushPrimsLocked(vmesa);
1269 }
1270 }
1271
1272 void viaDoSwapBuffers(viaContextPtr vmesa)
1273 {
1274 GLuint *vb = viaCheckDma(vmesa, vmesa->sarea->nbox*56);
1275 GLuint nFrontPitch;
1276 GLuint nBackPitch;
1277 GLuint nFrontWidth, nFrontHeight, nBackWidth, nBackHeight;
1278 GLuint nFrontBase, nBackBase;
1279 GLuint nFrontOffsetX, nFrontOffsetY, nBackOffsetX, nBackOffsetY;
1280 drm_clip_rect_t *b = vmesa->sarea->boxes;
1281 GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
1282 GLuint i;
1283
1284 nFrontPitch = vmesa->front.pitch;
1285 nBackPitch = vmesa->back.pitch;
1286
1287 /* Caculate Base */
1288 nFrontBase = vmesa->viaScreen->fbOffset + (vmesa->drawY * nFrontPitch + vmesa->drawX * bytePerPixel);
1289 nBackBase = vmesa->back.offset;
1290 /* 128 bit alignment*/
1291 nFrontBase = nFrontBase & 0xffffffe0;
1292
1293 /*=* [DBG] make draw to front buffer *=*/
1294 if(DRAW_FRONT)
1295 return;
1296
1297 for (i = 0; i < vmesa->sarea->nbox; i++) {
1298 /* Width, Height */
1299 nFrontWidth = nBackWidth = b->x2 - b->x1 - 1;
1300 nFrontHeight = nBackHeight = b->y2 - b->y1 - 1;
1301 /* Offset */
1302 nFrontOffsetX = (b->x1 - vmesa->drawX) + vmesa->drawXoff;
1303 nFrontOffsetY = b->y1 - vmesa->drawY;
1304
1305 nBackOffsetX = nFrontOffsetX;
1306 nBackOffsetY = nFrontOffsetY;
1307 /* GEWD */
1308 SetReg2DAGP(0x10, nFrontWidth | (nFrontHeight << 16));
1309 /* GEDST */
1310 SetReg2DAGP(0x0C, nFrontOffsetX | (nFrontOffsetY << 16));
1311 /* GESRC */
1312 SetReg2DAGP(0x08, nBackOffsetX | (nBackOffsetY << 16));
1313 /* GEDSTBASE */
1314 SetReg2DAGP(0x34, (nFrontBase >> 3));
1315 /* GESCRBASE */
1316 SetReg2DAGP(0x30, (nBackBase >> 3));
1317 /* GEPITCH */
1318 SetReg2DAGP(0x38, (((nFrontPitch >> 3) << 16) & 0x7FF0000) | 0x80000000 |
1319 ((nBackPitch >> 3) & 0x7FF));
1320 /* BITBLT */
1321 SetReg2DAGP(0x0, 0x1 | 0xCC000000);
1322 b++;
1323 }
1324
1325 viaFlushPrimsLocked(vmesa);
1326 #ifdef DEBUG
1327 if (VIA_DEBUG) fprintf(stderr, "Do Swap Buffer\n");
1328 #endif
1329 }
1330
1331 void viaDoSwapBuffersSaam(viaContextPtr vmesa)
1332 {
1333 GLuint *vb = viaCheckDma(vmesa, vmesa->sarea->nbox*56);
1334 GLuint nFrontPitch;
1335 GLuint nBackPitch;
1336 GLuint nFrontWidth, nFrontHeight, nBackWidth, nBackHeight;
1337 GLuint nFrontBase, nBackBase;
1338 GLuint nFrontOffsetX, nFrontOffsetY, nBackOffsetX, nBackOffsetY;
1339 drm_clip_rect_t *b = vmesa->sarea->boxes;
1340 GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
1341 GLuint i;
1342
1343 nFrontPitch = vmesa->front.pitch;
1344 nBackPitch = vmesa->back.pitch;
1345
1346 /* Caculate Base */
1347 nFrontBase = vmesa->viaScreen->fbSize + (vmesa->drawYSaam * nFrontPitch + vmesa->drawXSaam * bytePerPixel);
1348 nBackBase = vmesa->back.offset;
1349 /* 128 bit alignment*/
1350 nFrontBase = nFrontBase & 0xffffffe0;
1351
1352 /*=* [DBG] make draw to front buffer *=*/
1353 if(DRAW_FRONT)
1354 return;
1355
1356 for (i = 0; i < vmesa->sarea->nbox; i++) {
1357 /* Width, Height */
1358 nFrontWidth = nBackWidth = b->x2 - b->x1 - 1;
1359 nFrontHeight = nBackHeight = b->y2 - b->y1 - 1;
1360 /* Offset */
1361 nFrontOffsetX = (b->x1 - vmesa->drawXSaam) + vmesa->drawXoff;
1362 nFrontOffsetY = b->y1 - vmesa->drawYSaam;
1363
1364 nBackOffsetX = nFrontOffsetX;
1365 nBackOffsetY = nFrontOffsetY;
1366 /* GEWD */
1367 SetReg2DAGP(0x10, nFrontWidth | (nFrontHeight << 16));
1368 /* GEDST */
1369 SetReg2DAGP(0x0C, nFrontOffsetX | (nFrontOffsetY << 16));
1370 /* GESRC */
1371 SetReg2DAGP(0x08, nBackOffsetX | (nBackOffsetY << 16));
1372 /* GEDSTBASE */
1373 SetReg2DAGP(0x34, (nFrontBase >> 3));
1374 /* GESCRBASE */
1375 SetReg2DAGP(0x30, (nBackBase >> 3));
1376 /* GEPITCH */
1377 SetReg2DAGP(0x38, (((nFrontPitch >> 3) << 16) & 0x7FF0000) | 0x80000000 |
1378 ((nBackPitch >> 3) & 0x7FF));
1379 /* BITBLT */
1380 SetReg2DAGP(0x0, 0x1 | 0xCC000000);
1381 b++;
1382 }
1383
1384 viaFlushPrimsLocked(vmesa);
1385 #ifdef DEBUG
1386 if (VIA_DEBUG) fprintf(stderr, "Do Swap Buffer\n");
1387 #endif
1388 }
1389
1390 void viaDoSwapPBuffers(viaContextPtr vmesa)
1391 {
1392 GLuint *vb = viaCheckDma(vmesa, vmesa->sarea->nbox*56);
1393 GLuint nFrontPitch;
1394 GLuint nBackPitch;
1395 GLuint nFrontWidth, nFrontHeight;
1396 GLuint nFrontBase, nBackBase;
1397 GLuint nFrontOffsetX, nFrontOffsetY, nBackOffsetX, nBackOffsetY;
1398 GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
1399
1400 nFrontPitch = vmesa->front.pitch;
1401 nBackPitch = vmesa->back.pitch;
1402
1403 /* Caculate Base */
1404 nFrontBase = vmesa->front.offset;
1405 nBackBase = vmesa->back.offset;
1406
1407 /* Width, Height */
1408 nFrontWidth = nFrontPitch / bytePerPixel;
1409 nFrontHeight = nBackPitch / bytePerPixel;
1410
1411 /* Offset */
1412 nFrontOffsetX = 0;
1413 nFrontOffsetY = 0;
1414 nBackOffsetX = nFrontOffsetX;
1415 nBackOffsetY = nFrontOffsetY;
1416 /* GEWD */
1417 SetReg2DAGP(0x10, nFrontWidth | (nFrontHeight << 16));
1418 /* GEDST */
1419 SetReg2DAGP(0x0C, nFrontOffsetX | (nFrontOffsetY << 16));
1420 /* GESRC */
1421 SetReg2DAGP(0x08, nBackOffsetX | (nBackOffsetY << 16));
1422 /* GEDSTBASE */
1423 SetReg2DAGP(0x34, (nFrontBase >> 3));
1424 /* GESCRBASE */
1425 SetReg2DAGP(0x30, (nBackBase >> 3));
1426 /* GEPITCH */
1427 SetReg2DAGP(0x38, (((nFrontPitch >> 3) << 16) & 0x7FF0000) | 0x80000000 |
1428 ((nBackPitch >> 3) & 0x7FF));
1429 /* BITBLT */
1430 SetReg2DAGP(0x0, 0x1 | 0xCC000000);
1431
1432 viaFlushPrimsLocked(vmesa);
1433 #ifdef DEBUG
1434 if (VIA_DEBUG) fprintf(stderr, "Do Swap PBuffer\n");
1435 #endif
1436 }
1437
1438
1439 int flush_agp(viaContextPtr vmesa, drm_via_flush_agp_t* agpCmd)
1440 {
1441 GLuint *pnAGPCurrentPhysStart;
1442 GLuint *pnAGPCurrentPhysEnd;
1443 GLuint *pnAGPCurrentStart;
1444 GLuint *pnAGPCurrentEnd;
1445 volatile GLuint *pnMMIOBase;
1446 volatile GLuint *pnEngBaseTranSet;
1447 volatile GLuint *pnEngBaseTranSpace;
1448 GLuint *agpBase;
1449 GLuint ofs = vmesa->dma[vmesa->dmaIndex].offset;
1450 GLuint *vb = (GLuint *)vmesa->dmaAddr;
1451 GLuint i = 0;
1452
1453 pnMMIOBase = vmesa->regMMIOBase;
1454 pnEngBaseTranSet = vmesa->regTranSet;
1455 pnEngBaseTranSpace = vmesa->regTranSpace;
1456 *pnEngBaseTranSet = (0x0010 << 16);
1457 agpBase = vmesa->agpBase;
1458
1459 if (!agpCmd->size) {
1460 return -1;
1461 }
1462
1463 {
1464 volatile GLuint *pnEngBase = vmesa->regEngineStatus;
1465 int nStatus;
1466
1467 while (1) {
1468 nStatus = *pnEngBase;
1469 if ((nStatus & 0xFFFEFFFF) == 0x00020000)
1470 break;
1471 i++;
1472 }
1473 }
1474
1475 pnAGPCurrentStart = (GLuint *)(ofs + agpCmd->offset);
1476 pnAGPCurrentEnd = (GLuint *)((GLuint)pnAGPCurrentStart + vmesa->dmaHigh);
1477 pnAGPCurrentPhysStart = (GLuint *)( (GLuint)pnAGPCurrentStart + (GLuint)agpBase );
1478 pnAGPCurrentPhysEnd = (GLuint *)( (GLuint)pnAGPCurrentEnd + (GLuint)agpBase );
1479
1480 /*=* [DBG] make draw to front buffer *=*/
1481 if(DRAW_FRONT)
1482 vmesa->glCtx->Color._DrawDestMask[0] = __GL_FRONT_BUFFER_MASK;
1483
1484 if (vmesa->glCtx->Color._DrawDestMask[0] == __GL_BACK_BUFFER_MASK) {
1485
1486 *vb++ = HC_HEADER2;
1487 *vb++ = (HC_ParaType_NotTex << 16);
1488 if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) {
1489 *vb++ = (HC_SubA_HClipTB << 24) | 0x0;
1490 *vb++ = (HC_SubA_HClipLR << 24) | 0x0;
1491 }
1492 else {
1493 *vb++ = ((HC_SubA_HClipTB << 24) | (0x0 << 12) | vmesa->driDrawable->h);
1494 *vb++ = ((HC_SubA_HClipLR << 24) | (vmesa->drawXoff << 12) | (vmesa->driDrawable->w + vmesa->drawXoff));
1495 }
1496
1497 {
1498 GLuint pitch, format, offset;
1499
1500 if (vmesa->viaScreen->bitsPerPixel == 0x20) {
1501 format = HC_HDBFM_ARGB8888;
1502 }
1503 else if (vmesa->viaScreen->bitsPerPixel == 0x10) {
1504 format = HC_HDBFM_RGB565;
1505 }
1506 else
1507 {
1508 return -1;
1509 }
1510
1511 offset = vmesa->back.offset;
1512 pitch = vmesa->back.pitch;
1513
1514 *vb++ = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF));
1515 *vb++ = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24);
1516 *vb++ = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch);
1517 *vb++ = 0xcccccccc;
1518 }
1519
1520 *pnEngBaseTranSpace = (HC_SubA_HAGPBstL << 24) |
1521 ((GLuint)(pnAGPCurrentPhysStart) & 0xFFFFFF);
1522 *pnEngBaseTranSpace = (HC_SubA_HAGPBendL << 24) |
1523 ((GLuint)(pnAGPCurrentPhysEnd) & 0xFFFFFF);
1524 *pnEngBaseTranSpace = (HC_SubA_HAGPCMNT << 24) |
1525 ((GLuint)(pnAGPCurrentPhysEnd) & 0xFF000000) >> 16 |
1526 ((GLuint)(pnAGPCurrentPhysStart) & 0xFF000000) >> 24;
1527 *pnEngBaseTranSpace = (HC_SubA_HAGPBpH << 24) |
1528 ((GLuint)((GLbyte *)pnAGPCurrentPhysStart + agpCmd->size - 4) & 0xFF000000) >> 24;
1529 *pnEngBaseTranSpace = (HC_SubA_HAGPBpL << 24) |
1530 ((GLuint)((GLbyte *)pnAGPCurrentPhysStart + agpCmd->size - 4) & 0xFFFFFF) |
1531 HC_HAGPBpID_STOP;
1532 *pnEngBaseTranSpace = (HC_SubA_HAGPCMNT << 24) |
1533 ((GLuint)(pnAGPCurrentPhysEnd) & 0xFF000000) >> 16 |
1534 ((GLuint)(pnAGPCurrentPhysStart) & 0xFF000000) >> 24 |
1535 HC_HAGPCMNT_MASK;
1536 }
1537 else {
1538 GLuint *head;
1539 GLuint clipL, clipR, clipT, clipB;
1540 drm_clip_rect_t *b = vmesa->sarea->boxes;
1541 *vb++ = HC_HEADER2;
1542 *vb++ = (HC_ParaType_NotTex << 16);
1543 head = vb;
1544
1545 *pnEngBaseTranSpace = (HC_SubA_HAGPBstL << 24) |
1546 ((GLuint)(pnAGPCurrentPhysStart) & 0xFFFFFF);
1547 *pnEngBaseTranSpace = (HC_SubA_HAGPBendL << 24) |
1548 ((GLuint)(pnAGPCurrentPhysEnd) & 0xFFFFFF);
1549 *pnEngBaseTranSpace = (HC_SubA_HAGPCMNT << 24) |
1550 ((GLuint)(pnAGPCurrentPhysEnd) & 0xFF000000) >> 16 |
1551 ((GLuint)(pnAGPCurrentPhysStart) & 0xFF000000) >> 24;
1552 *pnEngBaseTranSpace = (HC_SubA_HAGPBpH << 24) |
1553 ((GLuint)((GLbyte *)pnAGPCurrentPhysStart + agpCmd->size - 4) & 0xFF000000) >> 24;
1554 *pnEngBaseTranSpace = (HC_SubA_HAGPBpL << 24) |
1555 ((GLuint)((GLbyte *)pnAGPCurrentPhysStart + agpCmd->size - 4) & 0xFFFFFF) |
1556 HC_HAGPBpID_STOP;
1557
1558 for (i = 0; i < vmesa->sarea->nbox; i++) {
1559 if (1) {
1560 volatile GLuint *pnEngBase = vmesa->regEngineStatus;
1561 int nStatus;
1562
1563 while (1) {
1564 nStatus = *pnEngBase;
1565 if ((nStatus & 0xFFFEFFFF) == 0x00020000)
1566 break;
1567 }
1568 }
1569
1570 clipL = b->x1 + vmesa->drawXoff;
1571 clipR = b->x2;
1572 clipT = b->y1;
1573 clipB = b->y2;
1574 #ifdef DEBUG
1575 if (VIA_DEBUG) fprintf(stderr, "clip = %d\n", i);
1576 #endif
1577 if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) {
1578
1579 *vb = (HC_SubA_HClipTB << 24) | 0x0;
1580 vb++;
1581
1582 *vb = (HC_SubA_HClipLR << 24) | 0x0;
1583 vb++;
1584 }
1585 else {
1586 *vb = (HC_SubA_HClipTB << 24) | (clipT << 12) | clipB;
1587 vb++;
1588
1589 *vb = (HC_SubA_HClipLR << 24) | (clipL << 12) | clipR;
1590 vb++;
1591 }
1592
1593 {
1594 GLuint pitch, format, offset;
1595 GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
1596
1597 if (vmesa->viaScreen->bitsPerPixel == 0x20) {
1598 format = HC_HDBFM_ARGB8888;
1599 }
1600 else if (vmesa->viaScreen->bitsPerPixel == 0x10) {
1601 format = HC_HDBFM_RGB565;
1602 }
1603 else
1604 return -1;
1605
1606 pitch = vmesa->front.pitch;
1607 offset = vmesa->viaScreen->fbOffset + (vmesa->drawY * pitch + vmesa->drawX * bytePerPixel);
1608 offset = offset & 0xffffffe0;
1609
1610 *vb++ = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF));
1611 *vb++ = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24);
1612 *vb++ = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch);
1613 *vb++ = 0xcccccccc;
1614 }
1615 *pnEngBaseTranSpace = (HC_SubA_HAGPCMNT << 24) |
1616 ((GLuint)(pnAGPCurrentPhysEnd) & 0xFF000000) >> 16 |
1617 ((GLuint)(pnAGPCurrentPhysStart) & 0xFF000000) >> 24 |
1618 HC_HAGPCMNT_MASK;
1619 #ifdef DEBUG
1620 if (VIA_DEBUG) {
1621 GLuint i;
1622 GLuint *data = (GLuint *)vmesa->dmaAddr;
1623 for (i = 0; i < vmesa->dmaLow; i += 16) {
1624 fprintf(stderr, "%08x ", *data++);
1625 fprintf(stderr, "%08x ", *data++);
1626 fprintf(stderr, "%08x ", *data++);
1627 fprintf(stderr, "%08x\n", *data++);
1628 }
1629 fprintf(stderr, "******************************************\n");
1630 }
1631 #endif
1632 b++;
1633 vb = head;
1634 }
1635 }
1636
1637 #ifdef DEBUG
1638 if (VIA_DEBUG) {
1639 volatile GLuint *pnEngBase = (volatile GLuint *)((GLuint)pnMMIOBase + 0x400);
1640 int nStatus;
1641 int i = 0;
1642
1643 while (1) {
1644 nStatus = *pnEngBase;
1645 if ((nStatus & 0xFFFEFFFF) == 0x00020000) {
1646 break;
1647 }
1648 else {
1649 GLuint j;
1650 GLuint *data;
1651 /* dump current command buffer */
1652 data = (GLuint *)vmesa->dmaAddr;
1653
1654 if (i == 500000) {
1655 fprintf(stderr, "current command buffer");
1656 fprintf(stderr, "i = %d\n", i);
1657 for (j = 0; j < vmesa->dmaLow; j += 16) {
1658 fprintf(stderr, "%08x ", *data++);
1659 fprintf(stderr, "%08x ", *data++);
1660 fprintf(stderr, "%08x ", *data++);
1661 fprintf(stderr, "%08x\n", *data++);
1662 }
1663 }
1664 /* dump previous command buffer */
1665 if (vmesa->dmaIndex) {
1666 data = (GLuint *)vmesa->dma[0].map;
1667 }
1668 else {
1669 data = (GLuint *)vmesa->dma[1].map;
1670 }
1671 if (i == 500000) {
1672 fprintf(stderr, "previous command buffer");
1673 fprintf(stderr, "i = %d\n", i);
1674 for (j = 0; j < dmaLow; j += 16) {
1675 fprintf(stderr, "%08x ", *data++);
1676 fprintf(stderr, "%08x ", *data++);
1677 fprintf(stderr, "%08x ", *data++);
1678 fprintf(stderr, "%08x\n", *data++);
1679 }
1680 }
1681 }
1682 i++;
1683 }
1684 }
1685 #endif
1686 dmaLow = vmesa->dmaLow;
1687 return 0;
1688 }
1689
1690 int flush_agp_saam(viaContextPtr vmesa, drm_via_flush_agp_t* agpCmd)
1691 {
1692 GLuint *pnAGPCurrentPhysStart;
1693 GLuint *pnAGPCurrentPhysEnd;
1694 GLuint *pnAGPCurrentStart;
1695 GLuint *pnAGPCurrentEnd;
1696 volatile GLuint *pnMMIOBase;
1697 volatile GLuint *pnEngBaseTranSet;
1698 volatile GLuint *pnEngBaseTranSpace;
1699 GLuint *agpBase;
1700 GLuint ofs = vmesa->dma[vmesa->dmaIndex].offset;
1701 GLuint *vb = (GLuint *)vmesa->dmaAddr;
1702 GLuint i = 0;
1703
1704 pnMMIOBase = vmesa->regMMIOBase;
1705 pnEngBaseTranSet = vmesa->regTranSet;
1706 pnEngBaseTranSpace = vmesa->regTranSpace;
1707 *pnEngBaseTranSet = (0x0010 << 16);
1708 agpBase = vmesa->agpBase;
1709
1710 if (!agpCmd->size) {
1711 return -1;
1712 }
1713
1714 {
1715 volatile GLuint *pnEngBase = vmesa->regEngineStatus;
1716 int nStatus;
1717
1718 while (1) {
1719 nStatus = *pnEngBase;
1720 if ((nStatus & 0xFFFEFFFF) == 0x00020000)
1721 break;
1722 i++;
1723 }
1724 }
1725
1726 pnAGPCurrentStart = (GLuint *)(ofs + agpCmd->offset);
1727 pnAGPCurrentEnd = (GLuint *)((GLuint)pnAGPCurrentStart + vmesa->dmaHigh);
1728 pnAGPCurrentPhysStart = (GLuint *)( (GLuint)pnAGPCurrentStart + (GLuint)agpBase );
1729 pnAGPCurrentPhysEnd = (GLuint *)( (GLuint)pnAGPCurrentEnd + (GLuint)agpBase );
1730
1731 /*=* [DBG] make draw to front buffer *=*/
1732 if(DRAW_FRONT)
1733 vmesa->glCtx->Color._DrawDestMask[0] = __GL_FRONT_BUFFER_MASK;
1734
1735 if (vmesa->glCtx->Color._DrawDestMask[0] == __GL_BACK_BUFFER_MASK) {
1736
1737 *vb++ = HC_HEADER2;
1738 *vb++ = (HC_ParaType_NotTex << 16);
1739 if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) {
1740 *vb++ = (HC_SubA_HClipTB << 24) | 0x0;
1741 *vb++ = (HC_SubA_HClipLR << 24) | 0x0;
1742 }
1743 else {
1744 *vb++ = ((HC_SubA_HClipTB << 24) | (0x0 << 12) | vmesa->driDrawable->h);
1745 *vb++ = ((HC_SubA_HClipLR << 24) | (vmesa->drawXoff << 12) | (vmesa->driDrawable->w + vmesa->drawXoff));
1746 }
1747
1748 {
1749 GLuint pitch, format, offset;
1750
1751 if (vmesa->viaScreen->bitsPerPixel == 0x20) {
1752 format = HC_HDBFM_ARGB8888;
1753 }
1754 else if (vmesa->viaScreen->bitsPerPixel == 0x10) {
1755 format = HC_HDBFM_RGB565;
1756 }
1757 else
1758 return -1;
1759
1760 offset = vmesa->back.offset;
1761 pitch = vmesa->back.pitch;
1762
1763 *vb++ = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF));
1764 *vb++ = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24);
1765 *vb++ = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch);
1766 *vb++ = 0xcccccccc;
1767 }
1768
1769 *pnEngBaseTranSpace = (HC_SubA_HAGPBstL << 24) |
1770 ((GLuint)(pnAGPCurrentPhysStart) & 0xFFFFFF);
1771 *pnEngBaseTranSpace = (HC_SubA_HAGPBendL << 24) |
1772 ((GLuint)(pnAGPCurrentPhysEnd) & 0xFFFFFF);
1773 *pnEngBaseTranSpace = (HC_SubA_HAGPCMNT << 24) |
1774 ((GLuint)(pnAGPCurrentPhysEnd) & 0xFF000000) >> 16 |
1775 ((GLuint)(pnAGPCurrentPhysStart) & 0xFF000000) >> 24;
1776 *pnEngBaseTranSpace = (HC_SubA_HAGPBpH << 24) |
1777 ((GLuint)((GLbyte *)pnAGPCurrentPhysStart + agpCmd->size - 4) & 0xFF000000) >> 24;
1778 *pnEngBaseTranSpace = (HC_SubA_HAGPBpL << 24) |
1779 ((GLuint)((GLbyte *)pnAGPCurrentPhysStart + agpCmd->size - 4) & 0xFFFFFF) |
1780 HC_HAGPBpID_STOP;
1781 *pnEngBaseTranSpace = (HC_SubA_HAGPCMNT << 24) |
1782 ((GLuint)(pnAGPCurrentPhysEnd) & 0xFF000000) >> 16 |
1783 ((GLuint)(pnAGPCurrentPhysStart) & 0xFF000000) >> 24 |
1784 HC_HAGPCMNT_MASK;
1785 }
1786 else {
1787 GLuint *head;
1788 GLuint clipL, clipR, clipT, clipB;
1789 drm_clip_rect_t *b = vmesa->sarea->boxes;
1790 *vb++ = HC_HEADER2;
1791 *vb++ = (HC_ParaType_NotTex << 16);
1792 head = vb;
1793
1794 *pnEngBaseTranSpace = (HC_SubA_HAGPBstL << 24) |
1795 ((GLuint)(pnAGPCurrentPhysStart) & 0xFFFFFF);
1796 *pnEngBaseTranSpace = (HC_SubA_HAGPBendL << 24) |
1797 ((GLuint)(pnAGPCurrentPhysEnd) & 0xFFFFFF);
1798 *pnEngBaseTranSpace = (HC_SubA_HAGPCMNT << 24) |
1799 ((GLuint)(pnAGPCurrentPhysEnd) & 0xFF000000) >> 16 |
1800 ((GLuint)(pnAGPCurrentPhysStart) & 0xFF000000) >> 24;
1801 *pnEngBaseTranSpace = (HC_SubA_HAGPBpH << 24) |
1802 ((GLuint)((GLbyte *)pnAGPCurrentPhysStart + agpCmd->size - 4) & 0xFF000000) >> 24;
1803 *pnEngBaseTranSpace = (HC_SubA_HAGPBpL << 24) |
1804 ((GLuint)((GLbyte *)pnAGPCurrentPhysStart + agpCmd->size - 4) & 0xFFFFFF) |
1805 HC_HAGPBpID_STOP;
1806
1807 for (i = 0; i < vmesa->sarea->nbox; i++) {
1808 if (1) {
1809 volatile GLuint *pnEngBase = vmesa->regEngineStatus;
1810 int nStatus;
1811
1812 while (1) {
1813 nStatus = *pnEngBase;
1814 if ((nStatus & 0xFFFEFFFF) == 0x00020000)
1815 break;
1816 }
1817 }
1818
1819 clipL = b->x1 + vmesa->drawXoff;
1820 clipR = b->x2;
1821 clipT = b->y1;
1822 clipB = b->y2;
1823 #ifdef DEBUG
1824 if (VIA_DEBUG) fprintf(stderr, "clip = %d\n", i);
1825 #endif
1826 if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) {
1827
1828 *vb = (HC_SubA_HClipTB << 24) | 0x0;
1829 vb++;
1830
1831 *vb = (HC_SubA_HClipLR << 24) | 0x0;
1832 vb++;
1833 }
1834 else {
1835 *vb = (HC_SubA_HClipTB << 24) | (clipT << 12) | clipB;
1836 vb++;
1837
1838 *vb = (HC_SubA_HClipLR << 24) | (clipL << 12) | clipR;
1839 vb++;
1840 }
1841
1842 {
1843 GLuint pitch, format, offset;
1844 GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
1845
1846 if (vmesa->viaScreen->bitsPerPixel == 0x20) {
1847 format = HC_HDBFM_ARGB8888;
1848 }
1849 else if (vmesa->viaScreen->bitsPerPixel == 0x10) {
1850 format = HC_HDBFM_RGB565;
1851 }
1852 else
1853 return -1;
1854
1855 pitch = vmesa->front.pitch;
1856 offset = vmesa->viaScreen->fbOffset + (vmesa->drawY * pitch + vmesa->drawX * bytePerPixel);
1857 offset = offset & 0xffffffe0;
1858
1859 *vb++ = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF));
1860 *vb++ = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24);
1861 *vb++ = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch);
1862 *vb++ = 0xcccccccc;
1863 }
1864 *pnEngBaseTranSpace = (HC_SubA_HAGPCMNT << 24) |
1865 ((GLuint)(pnAGPCurrentPhysEnd) & 0xFF000000) >> 16 |
1866 ((GLuint)(pnAGPCurrentPhysStart) & 0xFF000000) >> 24 |
1867 HC_HAGPCMNT_MASK;
1868 #ifdef DEBUG
1869 if (VIA_DEBUG) {
1870 GLuint i;
1871 GLuint *data = (GLuint *)vmesa->dmaAddr;
1872 for (i = 0; i < vmesa->dmaLow; i += 16) {
1873 fprintf(stderr, "%08x ", *data++);
1874 fprintf(stderr, "%08x ", *data++);
1875 fprintf(stderr, "%08x ", *data++);
1876 fprintf(stderr, "%08x\n", *data++);
1877 }
1878 fprintf(stderr, "******************************************\n");
1879 }
1880 #endif
1881 b++;
1882 vb = head;
1883 }
1884 }
1885
1886 #ifdef DEBUG
1887 if (VIA_DEBUG) {
1888 volatile GLuint *pnEngBase = (GLuint *)((GLuint)pnMMIOBase + 0x400);
1889 int nStatus;
1890 int i = 0;
1891
1892 while (1) {
1893 nStatus = *pnEngBase;
1894 if ((nStatus & 0xFFFEFFFF) == 0x00020000) {
1895 break;
1896 }
1897 else {
1898 GLuint j;
1899 GLuint *data;
1900 /* dump current command buffer */
1901 data = (GLuint *)vmesa->dmaAddr;
1902
1903 if (i == 500000) {
1904 fprintf(stderr, "current command buffer");
1905 fprintf(stderr, "i = %d\n", i);
1906 for (j = 0; j < vmesa->dmaLow; j += 16) {
1907 fprintf(stderr, "%08x ", *data++);
1908 fprintf(stderr, "%08x ", *data++);
1909 fprintf(stderr, "%08x ", *data++);
1910 fprintf(stderr, "%08x\n", *data++);
1911 }
1912 }
1913 /* dump previous command buffer */
1914 if (vmesa->dmaIndex) {
1915 data = (GLuint *)vmesa->dma[0].map;
1916 }
1917 else {
1918 data = (GLuint *)vmesa->dma[1].map;
1919 }
1920 if (i == 500000) {
1921 fprintf(stderr, "previous command buffer");
1922 fprintf(stderr, "i = %d\n", i);
1923 for (j = 0; j < dmaLow; j += 16) {
1924 fprintf(stderr, "%08x ", *data++);
1925 fprintf(stderr, "%08x ", *data++);
1926 fprintf(stderr, "%08x ", *data++);
1927 fprintf(stderr, "%08x\n", *data++);
1928 }
1929 }
1930 }
1931 i++;
1932 }
1933 }
1934 #endif
1935 dmaLow = vmesa->dmaLow;
1936 return 0;
1937 }
1938
1939 int flush_sys(viaContextPtr vmesa, drm_via_flush_sys_t* buf)
1940
1941 {
1942 GLuint *pnBuf;
1943 GLuint *pnEnd;
1944 volatile GLuint *pnMMIOBase;
1945 volatile GLuint *pnEngBaseTranSet;
1946 volatile GLuint *pnEngBaseTranSpace;
1947 GLuint uCheck2DCmd = GL_TRUE;
1948 GLuint addr;
1949 GLuint *vb = (GLuint *)vmesa->dmaAddr;
1950 GLuint i = 0;
1951
1952 pnMMIOBase = vmesa->regMMIOBase;
1953 pnEngBaseTranSet = vmesa->regTranSet;
1954 pnEngBaseTranSpace = vmesa->regTranSpace;
1955
1956 pnBuf = (GLuint *)(buf->index + buf->offset);
1957 pnEnd = (GLuint *)((GLuint)pnBuf + buf->size);
1958
1959 /*=* [DBG] make draw to front buffer *=*/
1960 if(DRAW_FRONT)
1961 vmesa->glCtx->Color._DrawDestMask[0] = __GL_FRONT_BUFFER_MASK;
1962
1963
1964 /*=* John Sheng [2003.6.20] fix pci *=*/
1965 {
1966 volatile GLuint *pnEngBase = vmesa->regEngineStatus;
1967 int nStatus;
1968
1969 while (1) {
1970 nStatus = *pnEngBase;
1971 if ((nStatus & 0xFFFEFFFF) == 0x00020000)
1972 break;
1973 i++;
1974 }
1975 }
1976 /*=* John Sheng [2003.12.9] Tuxracer & VQ *=*/
1977 /*=* Disable VQ *=*/
1978 if (vmesa->VQEnable)
1979 {
1980 WAIT_IDLE
1981 *vmesa->regTranSet = 0x00fe0000;
1982 *vmesa->regTranSet = 0x00fe0000;
1983 *vmesa->regTranSpace = 0x00000004;
1984 *vmesa->regTranSpace = 0x40008c0f;
1985 *vmesa->regTranSpace = 0x44000000;
1986 *vmesa->regTranSpace = 0x45080c04;
1987 *vmesa->regTranSpace = 0x46800408;
1988 vmesa->VQEnable = 0;
1989 }
1990 if (vmesa->glCtx->Color._DrawDestMask[0] == __GL_BACK_BUFFER_MASK) {
1991 *vb++ = HC_HEADER2;
1992 *vb++ = (HC_ParaType_NotTex << 16);
1993
1994 if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) {
1995 *vb++ = (HC_SubA_HClipTB << 24) | 0x0;
1996 *vb++ = (HC_SubA_HClipLR << 24) | 0x0;
1997 }
1998 else {
1999 *vb++ = ((HC_SubA_HClipTB << 24) | (0x0 << 12) | vmesa->driDrawable->h);
2000 *vb++ = ((HC_SubA_HClipLR << 24) | (vmesa->drawXoff << 12) | (vmesa->driDrawable->w + vmesa->drawXoff));
2001 }
2002
2003 /*=* John Sheng [2003.6.16] fix pci path *=*/
2004 {
2005 GLuint pitch, format, offset;
2006
2007 if (vmesa->viaScreen->bitsPerPixel == 0x20) {
2008 format = HC_HDBFM_ARGB8888;
2009 }
2010 else if (vmesa->viaScreen->bitsPerPixel == 0x10) {
2011 format = HC_HDBFM_RGB565;
2012 }
2013 else
2014 return -1;
2015
2016 offset = vmesa->back.offset;
2017 pitch = vmesa->back.pitch;
2018
2019 *vb++ = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF));
2020 *vb++ = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24);
2021 *vb++ = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch);
2022 *vb++ = 0xcccccccc;
2023 }
2024
2025 while (pnBuf != pnEnd) {
2026 if (*pnBuf == HALCYON_HEADER2) {
2027 pnBuf++;
2028 if (*pnBuf == HALCYON_SUB_ADDR0) {
2029 *pnEngBaseTranSet = *pnBuf;
2030 pnBuf++;
2031 uCheck2DCmd = GL_FALSE;
2032 }
2033 else {
2034 *pnEngBaseTranSet = *pnBuf;
2035 pnBuf++;
2036 uCheck2DCmd = GL_TRUE;
2037 }
2038 }
2039 else if (uCheck2DCmd && ((*pnBuf&HALCYON_HEADER1MASK)==HALCYON_HEADER1)) {
2040 addr = ((*pnBuf)&0x0000001f) << 2;
2041 pnBuf++;
2042 *((GLuint*)((GLuint)pnMMIOBase+addr)) = *pnBuf;
2043 pnBuf++;
2044 }
2045 else if ((*pnBuf&HALCYON_FIREMASK) == HALCYON_FIRECMD) {
2046 *pnEngBaseTranSpace = *pnBuf;
2047 pnBuf++;
2048 if ((pnBuf!=pnEnd)&&((*pnBuf&HALCYON_FIREMASK)==HALCYON_FIRECMD))
2049 pnBuf++;
2050 if ((*pnBuf&HALCYON_CMDBMASK) != HC_ACMD_HCmdB)
2051 uCheck2DCmd = GL_TRUE;
2052 }
2053 else {
2054 *pnEngBaseTranSpace = *pnBuf;
2055 pnBuf++;
2056 }
2057 }
2058 }
2059 else {
2060 GLuint *head;
2061 GLuint clipL, clipR, clipT, clipB;
2062 drm_clip_rect_t *b = vmesa->sarea->boxes;
2063 GLuint *pnTmp;
2064
2065 *vb++ = HC_HEADER2;
2066 *vb++ = (HC_ParaType_NotTex << 16);
2067
2068 head = vb;
2069 pnTmp = pnBuf;
2070
2071 for (i = 0; i < vmesa->sarea->nbox; i++) {
2072 clipL = b->x1 + vmesa->drawXoff;
2073 clipR = b->x2 + vmesa->drawXoff;
2074 clipT = b->y1;
2075 clipB = b->y2;
2076
2077 if (vmesa->driDrawable->w == 0 || vmesa->driDrawable->h == 0) {
2078 *vb = (HC_SubA_HClipTB << 24) | 0x0;
2079 vb++;
2080 *vb = (HC_SubA_HClipLR << 24) | 0x0;
2081 vb++;
2082 }
2083 else {
2084 *vb = (HC_SubA_HClipTB << 24) | (clipT << 12) | clipB;
2085 vb++;
2086 *vb = (HC_SubA_HClipLR << 24) | (clipL << 12) | clipR;
2087 vb++;
2088 }
2089
2090 /*=* John Sheng [2003.6.16] fix pci path *=*/
2091 {
2092 GLuint pitch, format, offset;
2093 GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
2094
2095 if (vmesa->viaScreen->bitsPerPixel == 0x20) {
2096 format = HC_HDBFM_ARGB8888;
2097 }
2098 else if (vmesa->viaScreen->bitsPerPixel == 0x10) {
2099 format = HC_HDBFM_RGB565;
2100 }
2101 else
2102 return -1;
2103
2104 pitch = vmesa->front.pitch;
2105 offset = vmesa->viaScreen->fbOffset + (vmesa->drawY * pitch + vmesa->drawX * bytePerPixel);
2106 offset = offset & 0xffffffe0;
2107
2108 *vb++ = ((HC_SubA_HDBBasL << 24) | (offset & 0xFFFFFF));
2109 *vb++ = ((HC_SubA_HDBBasH << 24) | ((offset & 0xFF000000)) >> 24);
2110 *vb++ = ((HC_SubA_HDBFM << 24) | HC_HDBLoc_Local | format | pitch);
2111 *vb++ = 0xcccccccc;
2112 }
2113
2114 pnBuf = pnTmp;
2115
2116 while (pnBuf != pnEnd) {
2117 if (*pnBuf == HALCYON_HEADER2) {
2118 pnBuf++;
2119 if (*pnBuf == HALCYON_SUB_ADDR0) {
2120 *pnEngBaseTranSet = *pnBuf;
2121 pnBuf++;
2122 uCheck2DCmd = GL_FALSE;
2123 }
2124 else {
2125 *pnEngBaseTranSet = *pnBuf;
2126 pnBuf++;
2127 uCheck2DCmd = GL_TRUE;
2128 }
2129 }
2130 else if (uCheck2DCmd && ((*pnBuf&HALCYON_HEADER1MASK)==HALCYON_HEADER1)) {
2131 addr = ((*pnBuf)&0x0000001f) << 2;
2132 pnBuf++;
2133 *((GLuint*)((GLuint)pnMMIOBase+addr)) = *pnBuf;
2134 pnBuf++;
2135 }
2136 else if ((*pnBuf&HALCYON_FIREMASK) == HALCYON_FIRECMD) {
2137 *pnEngBaseTranSpace = *pnBuf;
2138 pnBuf++;
2139 if ((pnBuf!=pnEnd)&&((*pnBuf&HALCYON_FIREMASK)==HALCYON_FIRECMD))
2140 pnBuf++;
2141 if ((*pnBuf&HALCYON_CMDBMASK) != HC_ACMD_HCmdB)
2142 uCheck2DCmd = GL_TRUE;
2143 }
2144 else {
2145 *pnEngBaseTranSpace = *pnBuf;
2146 pnBuf++;
2147 }
2148 }
2149 b++;
2150 vb = head;
2151 }
2152 }
2153 /*=* John Sheng [2003.6.20] debug pci *=*/
2154 if (VIA_DEBUG) {
2155 GLuint *pnEngBase = (GLuint *)((GLuint)pnMMIOBase + 0x400);
2156 int nStatus;
2157 int i = 0;
2158
2159 while (1) {
2160 nStatus = *pnEngBase;
2161 if ((nStatus & 0xFFFEFFFF) == 0x00020000) {
2162 break;
2163 }
2164 else {
2165 GLuint j;
2166 GLuint *data;
2167 /*=* John Sheng [2003.12.9] Tuxracer & VQ *=*/
2168 GLuint k;
2169 GLuint *ES;
2170
2171 data = (GLuint *)vmesa->dmaAddr;
2172 ES = pnEngBase;
2173
2174 if (i == 500000) {
2175 /*=* John Sheng [2003.12.9] Tuxracer & VQ *=*/
2176 for (k =0 ; k < 35; k++) {
2177 fprintf(stderr, "%02xh - %02xh\n", k*4 + 3, k*4);
2178 fprintf(stderr, "%08x\n", *ES);
2179 ES++;
2180 }
2181 fprintf(stderr, "current command buffer");
2182 fprintf(stderr, "i = %d\n", i);
2183 for (j = 0; j < vmesa->dmaLow; j += 16) {
2184 fprintf(stderr, "%08x ", *data++);
2185 fprintf(stderr, "%08x ", *data++);
2186 fprintf(stderr, "%08x ", *data++);
2187 fprintf(stderr, "%08x\n", *data++);
2188 }
2189 }
2190 if (vmesa->dmaIndex) {
2191 data = (GLuint *)vmesa->dma[0].map;
2192 }
2193 else {
2194 data = (GLuint *)vmesa->dma[1].map;
2195 }
2196 if (i == 500000) {
2197 fprintf(stderr, "previous command buffer");
2198 fprintf(stderr, "i = %d\n", i);
2199 for (j = 0; j < dmaLow; j += 16) {
2200 fprintf(stderr, "%08x ", *data++);
2201 fprintf(stderr, "%08x ", *data++);
2202 fprintf(stderr, "%08x ", *data++);
2203 fprintf(stderr, "%08x\n", *data++);
2204 }
2205 }
2206 }
2207 i++;
2208 }
2209 }
2210 dmaLow = vmesa->dmaLow;
2211 return 0;
2212 }