Fixed off by one errors in clipping.
[mesa.git] / src / mesa / drivers / dri / unichrome / via_context.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
25 /**
26 * \file via_context.c
27 *
28 * \author John Sheng (presumably of either VIA Technologies or S3 Graphics)
29 * \author Others at VIA Technologies?
30 * \author Others at S3 Graphics?
31 */
32
33 #include "glheader.h"
34 #include "context.h"
35 #include "matrix.h"
36 #include "simple_list.h"
37 #include "extensions.h"
38
39 #include "swrast/swrast.h"
40 #include "swrast_setup/swrast_setup.h"
41 #include "tnl/tnl.h"
42 #include "array_cache/acache.h"
43
44 #include "tnl/t_pipeline.h"
45
46 #include "drivers/common/driverfuncs.h"
47
48 #include "via_screen.h"
49 #include "via_dri.h"
50
51 #include "via_state.h"
52 #include "via_tex.h"
53 #include "via_span.h"
54 #include "via_tris.h"
55 #include "via_vb.h"
56 #include "via_ioctl.h"
57 #include "via_fb.h"
58 #include "via_regs.h"
59
60 #include <stdio.h>
61 #include "macros.h"
62
63 #define DRIVER_DATE "20040923"
64
65 #include "utils.h"
66
67 viaContextPtr current_mesa;
68 GLuint VIA_DEBUG = 0;
69 GLuint DRAW_FRONT = 0;
70 #define DMA_SIZE 2
71 GLuint VIA_PERFORMANCE = 0;
72 #ifdef PERFORMANCE_MEASURE
73 GLuint busy = 0;
74 GLuint idle = 0;
75 hash_element hash_table[HASH_TABLE_SIZE][HASH_TABLE_DEPTH];
76 #endif
77 /*=* John Sheng [2003.5.31] agp tex *=*/
78 extern GLuint agpFullCount;
79
80 static GLboolean
81 AllocateBuffer(viaContextPtr vmesa)
82 {
83 vmesa->front_base = vmesa->driScreen->pFB;
84 if (vmesa->drawType == GLX_PBUFFER_BIT) {
85 if (vmesa->front.map)
86 via_free_front_buffer(vmesa);
87 if (!via_alloc_front_buffer(vmesa))
88 return GL_FALSE;
89 }
90
91 if (vmesa->hasBack) {
92 if (vmesa->back.map)
93 via_free_back_buffer(vmesa);
94 if (!via_alloc_back_buffer(vmesa))
95 return GL_FALSE;
96 }
97
98 if (vmesa->hasDepth || vmesa->hasStencil) {
99 if (vmesa->depth.map)
100 via_free_depth_buffer(vmesa);
101 if (!via_alloc_depth_buffer(vmesa)) {
102 via_free_depth_buffer(vmesa);
103 return GL_FALSE;
104 }
105 }
106
107 return GL_TRUE;
108 }
109
110 /**
111 * Return various strings for \c glGetString.
112 *
113 * \sa glGetString
114 */
115 static const GLubyte *viaGetString(GLcontext *ctx, GLenum name)
116 {
117 static char buffer[128];
118 unsigned offset;
119
120
121 switch (name) {
122 case GL_VENDOR:
123 return (GLubyte *)"VIA Technology";
124
125 case GL_RENDERER: {
126 static const char * const chipset_names[] = {
127 "UniChrome",
128 "CastleRock (CLE266)",
129 "UniChrome (KM400)",
130 "UniChrome (K8M800)",
131 "UniChrome (PM8x0/CN400)",
132 };
133 const viaContext * const via = VIA_CONTEXT(ctx);
134 const unsigned id = via->viaScreen->deviceID;
135
136 offset = driGetRendererString( buffer,
137 chipset_names[(id > VIA_PM800) ? 0 : id],
138 DRIVER_DATE, 0 );
139 return (GLubyte *)buffer;
140 }
141
142 default:
143 return NULL;
144 }
145 }
146
147
148 /**
149 * Calculate a width that satisfies the hardware's alignment requirements.
150 * On the Unichrome hardware, each scanline must be aligned to a multiple of
151 * 16 pixels.
152 *
153 * \param width Minimum buffer width, in pixels.
154 *
155 * \returns A pixel width that meets the alignment requirements.
156 */
157 static __inline__ unsigned
158 buffer_align( unsigned width )
159 {
160 return (width + 0x0f) & ~0x0f;
161 }
162
163
164 /**
165 * Calculate the framebuffer parameters for all buffers (front, back, depth,
166 * and stencil) associated with the specified context.
167 *
168 * \warning
169 * This function also calls \c AllocateBuffer to actually allocate the
170 * buffers.
171 *
172 * \sa AllocateBuffer
173 */
174 static GLboolean
175 calculate_buffer_parameters( viaContextPtr vmesa )
176 {
177 const unsigned shift = vmesa->viaScreen->bitsPerPixel / 16;
178 const unsigned extra = (vmesa->drawType == GLX_PBUFFER_BIT) ? 0 : 32;
179 unsigned w;
180 unsigned h;
181
182 if (vmesa->drawType == GLX_PBUFFER_BIT) {
183 w = vmesa->driDrawable->w;
184 h = vmesa->driDrawable->h;
185 }
186 else {
187 w = vmesa->viaScreen->width;
188 h = vmesa->viaScreen->height;
189
190 vmesa->front.offset = 0;
191 vmesa->front.map = (char *) vmesa->driScreen->pFB;
192 }
193
194 vmesa->front.pitch = buffer_align( w ) << shift;
195 vmesa->front.size = vmesa->front.pitch * h;
196
197
198 /* Allocate back-buffer */
199
200 vmesa->back.pitch = (buffer_align( vmesa->driDrawable->w ) << shift)
201 + extra;
202 vmesa->back.size = vmesa->back.pitch * vmesa->driDrawable->h;
203
204 #ifdef DEBUG
205 if (VIA_DEBUG) fprintf(stderr, "viaMakeCurrent backbuffer: w = %d h = %d bpp = %d sizs = %d\n",
206 vmesa->back.pitch,
207 vmesa->driDrawable->h,
208 8 << shift,
209 vmesa->back.size);
210 #endif
211
212 /* Allocate depth-buffer */
213 if ( vmesa->hasStencil || vmesa->hasDepth ) {
214 const unsigned dShift = (vmesa->hasStencil)
215 ? 2 : (vmesa->depthBits / 16);
216
217 vmesa->depth.pitch = (buffer_align( vmesa->driDrawable->w ) << dShift)
218 + extra;
219 vmesa->depth.bpp = 8 << dShift;
220 vmesa->depth.size = vmesa->depth.pitch * vmesa->driDrawable->h;
221 }
222 else {
223 (void) memset( & vmesa->depth, 0, sizeof( vmesa->depth ) );
224 }
225
226 #ifdef DEBUG
227 if (VIA_DEBUG) fprintf(stderr, "viaMakeCurrent depthbuffer: w = %d h = %d bpp = %d sizs = %d\n",
228 vmesa->depth.pitch,
229 vmesa->driDrawable->h,
230 vmesa->depth.bpp,
231 vmesa->depth.size);
232 #endif
233
234 /*=* John Sheng [2003.5.31] flip *=*/
235 if( (vmesa->viaScreen->width == vmesa->driDrawable->w)
236 && (vmesa->viaScreen->height == vmesa->driDrawable->h) ) {
237 vmesa->doPageFlip = GL_FALSE;
238 vmesa->currentPage = 0;
239 vmesa->back.pitch = vmesa->front.pitch;
240 }
241
242 if (!AllocateBuffer(vmesa)) {
243 FREE(vmesa);
244 return GL_FALSE;
245 }
246
247 return GL_TRUE;
248 }
249
250
251 void viaReAllocateBuffers(GLframebuffer *drawbuffer)
252 {
253 GLcontext *ctx;
254 viaContextPtr vmesa = current_mesa;
255
256 ctx = vmesa->glCtx;
257 ctx->DrawBuffer->Width = drawbuffer->Width;
258 ctx->DrawBuffer->Height = drawbuffer->Height;
259
260 #ifdef DEBUG
261 if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
262 #endif
263 ctx->DrawBuffer->Accum = 0;
264
265 vmesa->driDrawable->w = ctx->DrawBuffer->Width;
266 vmesa->driDrawable->h = ctx->DrawBuffer->Height;
267
268 LOCK_HARDWARE(vmesa);
269 calculate_buffer_parameters( vmesa );
270 UNLOCK_HARDWARE(vmesa);
271
272 #ifdef DEBUG
273 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
274 #endif
275 }
276 static void viaBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height)
277
278 {
279 /* MESA5.0 */
280 viaContextPtr vmesa = current_mesa;
281 *width = vmesa->driDrawable->w;
282 *height = vmesa->driDrawable->h;
283 }
284
285 /* Extension strings exported by the Unichrome driver.
286 */
287 static const char * const card_extensions[] =
288 {
289 "GL_ARB_multitexture",
290 "GL_ARB_point_parameters",
291 "GL_ARB_texture_env_add",
292 "GL_ARB_texture_env_combine",
293 "GL_ARB_texture_env_dot3",
294 "GL_ARB_texture_mirrored_repeat",
295 "GL_EXT_stencil_wrap",
296 "GL_EXT_texture_env_combine",
297 "GL_EXT_texture_env_dot3",
298 "GL_EXT_texture_lod_bias",
299 "GL_NV_blend_square",
300 NULL
301 };
302
303 extern const struct tnl_pipeline_stage _via_fastrender_stage;
304 extern const struct tnl_pipeline_stage _via_render_stage;
305
306 static const struct tnl_pipeline_stage *via_pipeline[] = {
307 &_tnl_vertex_transform_stage,
308 &_tnl_normal_transform_stage,
309 &_tnl_lighting_stage,
310 &_tnl_fog_coordinate_stage,
311 &_tnl_texgen_stage,
312 &_tnl_texture_transform_stage,
313 /* REMOVE: point attenuation stage */
314 #if 1
315 &_via_fastrender_stage, /* ADD: unclipped rastersetup-to-dma */
316 &_via_render_stage, /* ADD: modification from _tnl_render_stage */
317 #endif
318 &_tnl_render_stage,
319 0,
320 };
321
322
323 static GLboolean
324 AllocateDmaBuffer(const GLvisual *visual, viaContextPtr vmesa)
325 {
326 #ifdef DEBUG
327 if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
328 #endif
329 if (vmesa->dma[0].map && vmesa->dma[1].map)
330 via_free_dma_buffer(vmesa);
331
332 if (!via_alloc_dma_buffer(vmesa)) {
333 if (vmesa->front.map)
334 via_free_front_buffer(vmesa);
335 if (vmesa->back.map)
336 via_free_back_buffer(vmesa);
337 if (vmesa->depth.map)
338 via_free_depth_buffer(vmesa);
339
340 return GL_FALSE;
341 }
342 #ifdef DEBUG
343 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
344 #endif
345 return GL_TRUE;
346 }
347
348 static void
349 InitVertexBuffer(viaContextPtr vmesa)
350 {
351 GLuint *addr;
352
353 addr = (GLuint *)vmesa->dma[0].map;
354 *addr = 0xF210F110;
355 *addr = (HC_ParaType_NotTex << 16);
356 *addr = 0xcccccccc;
357 *addr = 0xdddddddd;
358
359 addr = (GLuint *)vmesa->dma[1].map;
360 *addr = 0xF210F110;
361 *addr = (HC_ParaType_NotTex << 16);
362 *addr = 0xcccccccc;
363 *addr = 0xdddddddd;
364
365 vmesa->dmaIndex = 0;
366 vmesa->dmaLow = DMA_OFFSET;
367 vmesa->dmaHigh = vmesa->dma[0].size;
368 vmesa->dmaAddr = (unsigned char *)vmesa->dma[0].map;
369 vmesa->dmaLastPrim = vmesa->dmaLow;
370 }
371
372 static void
373 FreeBuffer(viaContextPtr vmesa)
374 {
375 if (vmesa->front.map)
376 via_free_front_buffer(vmesa);
377
378 if (vmesa->back.map)
379 via_free_back_buffer(vmesa);
380
381 if (vmesa->depth.map)
382 via_free_depth_buffer(vmesa);
383
384 if (vmesa->dma[0].map && vmesa->dma[1].map)
385 via_free_dma_buffer(vmesa);
386 }
387
388 GLboolean
389 viaCreateContext(const __GLcontextModes *mesaVis,
390 __DRIcontextPrivate *driContextPriv,
391 void *sharedContextPrivate)
392 {
393 GLcontext *ctx, *shareCtx;
394 viaContextPtr vmesa;
395 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
396 viaScreenPrivate *viaScreen = (viaScreenPrivate *)sPriv->private;
397 drm_via_sarea_t *saPriv = (drm_via_sarea_t *)
398 (((GLubyte *)sPriv->pSAREA) + viaScreen->sareaPrivOffset);
399 struct dd_function_table functions;
400
401 /* Allocate via context */
402 vmesa = (viaContextPtr) CALLOC_STRUCT(via_context_t);
403 if (!vmesa) {
404 return GL_FALSE;
405 }
406 #ifdef DEBUG
407 if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
408 #endif
409 current_mesa = vmesa;
410 /* pick back buffer */
411 if (mesaVis->doubleBufferMode) {
412 vmesa->hasBack = GL_TRUE;
413 }
414 else {
415 vmesa->hasBack = GL_FALSE;
416 }
417 /* pick z buffer */
418 if (mesaVis->haveDepthBuffer) {
419 vmesa->hasDepth = GL_TRUE;
420 vmesa->depthBits = mesaVis->depthBits;
421 }
422 else {
423 vmesa->hasDepth = GL_FALSE;
424 vmesa->depthBits = 0;
425 }
426 /* pick stencil buffer */
427 if (mesaVis->haveStencilBuffer) {
428 vmesa->hasStencil = GL_TRUE;
429 vmesa->stencilBits = mesaVis->stencilBits;
430 }
431 else {
432 vmesa->hasStencil = GL_FALSE;
433 vmesa->stencilBits = 0;
434 }
435
436 _mesa_init_driver_functions(&functions);
437 viaInitTextureFuncs(&functions);
438
439 /* Allocate the Mesa context */
440 if (sharedContextPrivate)
441 shareCtx = ((viaContextPtr) sharedContextPrivate)->glCtx;
442 else
443 shareCtx = NULL;
444
445 vmesa->glCtx = _mesa_create_context(mesaVis, shareCtx, &functions, (void*) vmesa);
446
447 vmesa->shareCtx = shareCtx;
448
449 if (!vmesa->glCtx) {
450 FREE(vmesa);
451 return GL_FALSE;
452 }
453 driContextPriv->driverPrivate = vmesa;
454
455 ctx = vmesa->glCtx;
456
457 /* check */
458 /*=* John Sheng [2003.7.2] for visual config number can't excess 8 *=*/
459 /*if (viaScreen->textureSize < 2 * 1024 * 1024) {
460 ctx->Const.MaxTextureLevels = 9;
461 }
462 else if (viaScreen->textureSize < 8 * 1024 * 1024) {
463 ctx->Const.MaxTextureLevels = 10;
464 }
465 else {
466 ctx->Const.MaxTextureLevels = 11;
467 }*/
468 ctx->Const.MaxTextureLevels = 11;
469
470 ctx->Const.MaxTextureUnits = 2;
471 ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits;
472 ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits;
473
474 ctx->Const.MinLineWidth = 1.0;
475 ctx->Const.MinLineWidthAA = 1.0;
476 ctx->Const.MaxLineWidth = 3.0;
477 ctx->Const.MaxLineWidthAA = 3.0;
478 ctx->Const.LineWidthGranularity = 1.0;
479
480 ctx->Const.MinPointSize = 1.0;
481 ctx->Const.MinPointSizeAA = 1.0;
482 ctx->Const.MaxPointSize = 3.0;
483 ctx->Const.MaxPointSizeAA = 3.0;
484 ctx->Const.PointSizeGranularity = 1.0;
485
486 ctx->Driver.GetBufferSize = viaBufferSize;
487 /* ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; *//* FIXME ?? */
488 ctx->Driver.GetString = viaGetString;
489
490 ctx->DriverCtx = (void *)vmesa;
491 vmesa->glCtx = ctx;
492
493 /* Initialize the software rasterizer and helper modules.
494 */
495 _swrast_CreateContext(ctx);
496 _ac_CreateContext(ctx);
497 _tnl_CreateContext(ctx);
498 _swsetup_CreateContext(ctx);
499
500 /* Install the customized pipeline:
501 */
502 _tnl_destroy_pipeline(ctx);
503 _tnl_install_pipeline(ctx, via_pipeline);
504
505 /* Configure swrast and T&L to match hardware characteristics:
506 */
507 _swrast_allow_pixel_fog(ctx, GL_FALSE);
508 _swrast_allow_vertex_fog(ctx, GL_TRUE);
509 _tnl_allow_pixel_fog(ctx, GL_FALSE);
510 _tnl_allow_vertex_fog(ctx, GL_TRUE);
511
512 /* vmesa->display = dpy; */
513 vmesa->display = sPriv->display;
514
515 vmesa->hHWContext = driContextPriv->hHWContext;
516 vmesa->driFd = sPriv->fd;
517 vmesa->driHwLock = &sPriv->pSAREA->lock;
518
519 vmesa->viaScreen = viaScreen;
520 vmesa->driScreen = sPriv;
521 vmesa->sarea = saPriv;
522 vmesa->glBuffer = NULL;
523
524 vmesa->texHeap = mmInit(0, viaScreen->textureSize);
525 vmesa->stippleInHw = 1;
526 vmesa->renderIndex = ~0;
527 vmesa->dirty = VIA_UPLOAD_ALL;
528 vmesa->uploadCliprects = GL_TRUE;
529 vmesa->needUploadAllState = 1;
530
531 make_empty_list(&vmesa->TexObjList);
532 make_empty_list(&vmesa->SwappedOut);
533
534 vmesa->CurrentTexObj[0] = 0;
535 vmesa->CurrentTexObj[1] = 0;
536
537 vmesa->dma[0].size = DMA_SIZE * 1024 * 1024;
538 vmesa->dma[1].size = DMA_SIZE * 1024 * 1024;
539
540 _math_matrix_ctr(&vmesa->ViewportMatrix);
541
542 driInitExtensions( ctx, card_extensions, GL_TRUE );
543 viaInitStateFuncs(ctx);
544 viaInitTextures(ctx);
545 viaInitTriFuncs(ctx);
546 viaInitSpanFuncs(ctx);
547 viaInitIoctlFuncs(ctx);
548 viaInitVB(ctx);
549 viaInitState(ctx);
550
551 if (getenv("VIA_DEBUG"))
552 VIA_DEBUG = 1;
553 else
554 VIA_DEBUG = 0;
555
556 if (getenv("DRAW_FRONT"))
557 DRAW_FRONT = 1;
558 else
559 DRAW_FRONT = 0;
560
561 #ifdef PERFORMANCE_MEASURE
562 if (getenv("VIA_PERFORMANCE"))
563 VIA_PERFORMANCE = 1;
564 else
565 VIA_PERFORMANCE = 0;
566
567 {
568 int i, j;
569 for (i = 0; i < HASH_TABLE_SIZE; i++) {
570 for (j = 0; j < HASH_TABLE_DEPTH; j ++) {
571 hash_table[i][j].count = 0;
572 sprintf(hash_table[i][j].func, "%s", "NULL");
573 }
574 }
575 }
576 #endif
577
578 if (!AllocateDmaBuffer(mesaVis, vmesa)) {
579 fprintf(stderr ,"AllocateDmaBuffer fail\n");
580 FREE(vmesa);
581 return GL_FALSE;
582 }
583
584 InitVertexBuffer(vmesa);
585
586 vmesa->regMMIOBase = (GLuint *)((GLuint)viaScreen->reg);
587 vmesa->pnGEMode = (GLuint *)((GLuint)viaScreen->reg + 0x4);
588 vmesa->regEngineStatus = (GLuint *)((GLuint)viaScreen->reg + 0x400);
589 vmesa->regTranSet = (GLuint *)((GLuint)viaScreen->reg + 0x43C);
590 vmesa->regTranSpace = (GLuint *)((GLuint)viaScreen->reg + 0x440);
591 vmesa->agpBase = viaScreen->agpBase;
592 #ifdef DEBUG
593 if (VIA_DEBUG) {
594 fprintf(stderr, "regEngineStatus = %x\n", *vmesa->regEngineStatus);
595 }
596
597 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
598 #endif
599 {
600 #ifndef USE_XINERAMA
601 vmesa->saam = 0;
602 #else
603 GLboolean saam = XineramaIsActive(vmesa->display);
604 int count = 0, fbSize;
605
606 if (saam && vmesa->viaScreen->drixinerama) {
607 vmesa->xsi = XineramaQueryScreens(vmesa->display, &count);
608 /* Test RightOf or Down */
609 if (vmesa->xsi[0].x_org == 0 && vmesa->xsi[0].y_org == 0) {
610 if (vmesa->xsi[1].x_org == vmesa->xsi[1].width) {
611 vmesa->saam = RightOf;
612 }
613 else {
614 vmesa->saam = Down;
615 }
616 }
617 /* Test LeftOf or Up */
618 else if (vmesa->xsi[0].x_org == vmesa->xsi[0].width) {
619 vmesa->saam = LeftOf;
620 }
621 else if (vmesa->xsi[0].y_org == vmesa->xsi[0].height) {
622 vmesa->saam = Up;
623 }
624 else
625 vmesa->saam = 0;
626
627
628 fbSize = vmesa->viaScreen->fbSize;
629 }
630 else
631 vmesa->saam = 0;
632 #endif
633 }
634
635 vmesa->pSaamRects = (drm_clip_rect_t *) malloc(sizeof(drm_clip_rect_t));
636 return GL_TRUE;
637 }
638
639 void
640 viaDestroyContext(__DRIcontextPrivate *driContextPriv)
641 {
642 viaContextPtr vmesa = (viaContextPtr)driContextPriv->driverPrivate;
643 /*=* John Sheng [2003.12.9] Tuxracer & VQ *=*/
644 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
645 viaScreenPrivate *viaScreen = (viaScreenPrivate *)sPriv->private;
646 #ifdef DEBUG
647 if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
648 #endif
649 assert(vmesa); /* should never be null */
650 viaFlushPrimsLocked(vmesa);
651 WAIT_IDLE
652 /*=* John Sheng [2003.12.9] Tuxracer & VQ *=*/
653 /* Enable VQ */
654 if (viaScreen->VQEnable) {
655 *vmesa->regTranSet = 0x00fe0000;
656 *vmesa->regTranSet = 0x00fe0000;
657 *vmesa->regTranSpace = 0x00000006;
658 *vmesa->regTranSpace = 0x40008c0f;
659 *vmesa->regTranSpace = 0x44000000;
660 *vmesa->regTranSpace = 0x45080c04;
661 *vmesa->regTranSpace = 0x46800408;
662 }
663 if (vmesa) {
664 /*=* John Sheng [2003.5.31] flip *=*/
665 if(vmesa->doPageFlip) {
666 *((volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x43c)) = 0x00fe0000;
667 *((volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x440)) = 0x00001004;
668 WAIT_IDLE
669 *((volatile GLuint *)((GLuint)vmesa->regMMIOBase + 0x214)) = 0;
670 }
671 /*=* John Sheng [2003.5.31] agp tex *=*/
672 if(VIA_DEBUG) fprintf(stderr, "agpFullCount = %d\n", agpFullCount);
673
674 _swsetup_DestroyContext(vmesa->glCtx);
675 _tnl_DestroyContext(vmesa->glCtx);
676 _ac_DestroyContext(vmesa->glCtx);
677 _swrast_DestroyContext(vmesa->glCtx);
678 viaFreeVB(vmesa->glCtx);
679 FreeBuffer(vmesa);
680 /* free the Mesa context */
681 _mesa_destroy_context(vmesa->glCtx);
682 vmesa->glCtx->DriverCtx = NULL;
683 FREE(vmesa);
684 }
685
686 P_M_R;
687
688 #ifdef PERFORMANCE_MEASURE
689 if (VIA_PERFORMANCE) fprintf(stderr, "idle = %d\n", idle);
690 if (VIA_PERFORMANCE) fprintf(stderr, "busy = %d\n", busy);
691 #endif
692 #ifdef DEBUG
693 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
694 #endif
695 }
696
697 void viaXMesaSetFrontClipRects(viaContextPtr vmesa)
698 {
699 __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
700
701 vmesa->numClipRects = dPriv->numClipRects;
702 vmesa->pClipRects = dPriv->pClipRects;
703 vmesa->drawX = dPriv->x;
704 vmesa->drawY = dPriv->y;
705 vmesa->drawW = dPriv->w;
706 vmesa->drawH = dPriv->h;
707
708 viaEmitDrawingRectangle(vmesa);
709 vmesa->uploadCliprects = GL_TRUE;
710 }
711
712 void viaXMesaSetBackClipRects(viaContextPtr vmesa)
713 {
714 __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
715 /*=* John Sheng [2003.6.9] fix glxgears dirty screen */
716 /*if (vmesa->saam) {*/
717 vmesa->numClipRects = dPriv->numClipRects;
718 vmesa->pClipRects = dPriv->pClipRects;
719 vmesa->drawX = dPriv->x;
720 vmesa->drawY = dPriv->y;
721 vmesa->drawW = dPriv->w;
722 vmesa->drawH = dPriv->h;
723 /*}
724 else {
725 if (dPriv->numBackClipRects == 0) {
726 vmesa->numClipRects = dPriv->numClipRects;
727 vmesa->pClipRects = dPriv->pClipRects;
728 vmesa->drawX = dPriv->x;
729 vmesa->drawY = dPriv->y;
730 vmesa->drawW = dPriv->w;
731 vmesa->drawH = dPriv->h;
732 }
733 else {
734 vmesa->numClipRects = dPriv->numBackClipRects;
735 vmesa->pClipRects = dPriv->pBackClipRects;
736 vmesa->drawX = dPriv->backX;
737 vmesa->drawY = dPriv->backY;
738 vmesa->drawW = dPriv->w;
739 vmesa->drawH = dPriv->h;
740 }
741 }*/
742 viaEmitDrawingRectangle(vmesa);
743 vmesa->uploadCliprects = GL_TRUE;
744 }
745
746 void viaXMesaWindowMoved(viaContextPtr vmesa)
747 {
748 GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
749 #ifdef USE_XINERAMA
750 GLuint side = 0;
751 __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
752 #endif
753
754 switch (vmesa->glCtx->Color._DrawDestMask[0]) {
755 case __GL_FRONT_BUFFER_MASK:
756 viaXMesaSetFrontClipRects(vmesa);
757 break;
758 case __GL_BACK_BUFFER_MASK:
759 viaXMesaSetBackClipRects(vmesa);
760 break;
761 default:
762 break;
763 }
764
765 #ifndef USE_XINERAMA
766 vmesa->viaScreen->fbOffset = 0;
767 vmesa->saam &= ~S1;
768 vmesa->saam |= S0;
769 #else
770 side = vmesa->saam & P_MASK;
771
772 switch (side) {
773 case RightOf:
774 /* full in screen 1 */
775 if (vmesa->drawX >= vmesa->xsi[0].width) {
776 vmesa->viaScreen->fbOffset = vmesa->viaScreen->fbSize;
777 vmesa->drawX = vmesa->drawX - vmesa->xsi[1].width;
778 vmesa->numClipRects = dPriv->numBackClipRects;
779 vmesa->pClipRects = dPriv->pBackClipRects;
780 vmesa->drawX = dPriv->backX;
781 vmesa->drawY = dPriv->backY;
782 vmesa->saam &= ~S0;
783 vmesa->saam |= S1;
784 }
785 /* full in screen 0 */
786 else if ((vmesa->drawX + vmesa->drawW) <= vmesa->xsi[0].width) {
787 vmesa->viaScreen->fbOffset = 0;
788 vmesa->saam &= ~S1;
789 vmesa->saam |= S0;
790 }
791 /* between screen 0 && screen 1 */
792 else {
793 vmesa->numSaamRects = dPriv->numBackClipRects;
794 vmesa->pSaamRects = dPriv->pBackClipRects;
795 vmesa->drawXSaam = dPriv->backX;
796 vmesa->drawYSaam = dPriv->backY;
797 vmesa->viaScreen->fbOffset = 0;
798 vmesa->saam |= S0;
799 vmesa->saam |= S1;
800 }
801 break;
802 case LeftOf:
803 /* full in screen 1 */
804 if (vmesa->drawX + vmesa->drawW <= 0) {
805 vmesa->viaScreen->fbOffset = vmesa->viaScreen->fbSize;
806 vmesa->drawX = vmesa->drawX + vmesa->xsi[1].width;
807 vmesa->numClipRects = dPriv->numBackClipRects;
808 vmesa->pClipRects = dPriv->pBackClipRects;
809 vmesa->drawX = dPriv->backX;
810 vmesa->drawY = dPriv->backY;
811 vmesa->saam &= ~S0;
812 vmesa->saam |= S1;
813 }
814 /* full in screen 0 */
815 else if (vmesa->drawX >= 0) {
816 vmesa->viaScreen->fbOffset = 0;
817 vmesa->saam &= ~S1;
818 vmesa->saam |= S0;
819 }
820 /* between screen 0 && screen 1 */
821 else {
822 vmesa->numSaamRects = dPriv->numBackClipRects;
823 vmesa->pSaamRects = dPriv->pBackClipRects;
824 vmesa->drawXSaam = dPriv->backX;
825 vmesa->drawYSaam = dPriv->backY;
826 vmesa->viaScreen->fbOffset = 0;
827 vmesa->saam |= S0;
828 vmesa->saam |= S1;
829 }
830 break;
831 case Down :
832 /* full in screen 1 */
833 if (vmesa->drawY >= vmesa->xsi[0].height) {
834 vmesa->viaScreen->fbOffset = vmesa->viaScreen->fbSize;
835 vmesa->drawY = vmesa->drawY - vmesa->xsi[1].height;
836 vmesa->numClipRects = dPriv->numBackClipRects;
837 vmesa->pClipRects = dPriv->pBackClipRects;
838 vmesa->drawX = dPriv->backX;
839 vmesa->drawY = dPriv->backY;
840 vmesa->saam &= ~S0;
841 vmesa->saam |= S1;
842 }
843 /* full in screen 0 */
844 else if ((vmesa->drawY + vmesa->drawH) <= vmesa->xsi[0].height) {
845 vmesa->viaScreen->fbOffset = 0;
846 vmesa->saam &= ~S1;
847 vmesa->saam |= S0;
848 }
849 /* between screen 0 && screen 1 */
850 else {
851 vmesa->numSaamRects = dPriv->numBackClipRects;
852 vmesa->pSaamRects = dPriv->pBackClipRects;
853 vmesa->drawXSaam = dPriv->backX;
854 vmesa->drawYSaam = dPriv->backY;
855 vmesa->viaScreen->fbOffset = 0;
856 vmesa->saam |= S0;
857 vmesa->saam |= S1;
858 }
859 break;
860 case Up :
861 /* full in screen 1 */
862 if ((vmesa->drawY + vmesa->drawH) <= 0) {
863 vmesa->viaScreen->fbOffset = vmesa->viaScreen->fbSize;
864 vmesa->drawY = vmesa->drawY + vmesa->xsi[1].height;
865 vmesa->numClipRects = dPriv->numBackClipRects;
866 vmesa->pClipRects = dPriv->pBackClipRects;
867 vmesa->drawX = dPriv->backX;
868 vmesa->drawY = dPriv->backY;
869 vmesa->saam &= ~S0;
870 vmesa->saam |= S1;
871 }
872 /* full in screen 0 */
873 else if (vmesa->drawY >= 0) {
874 vmesa->viaScreen->fbOffset = 0;
875 vmesa->saam &= ~S1;
876 vmesa->saam |= S0;
877 }
878 /* between screen 0 && screen 1 */
879 else {
880 vmesa->numSaamRects = dPriv->numBackClipRects;
881 vmesa->pSaamRects = dPriv->pBackClipRects;
882 vmesa->drawXSaam = dPriv->backX;
883 vmesa->drawYSaam = dPriv->backY;
884 vmesa->viaScreen->fbOffset = 0;
885 vmesa->saam |= S0;
886 vmesa->saam |= S1;
887 }
888 break;
889 default:
890 vmesa->viaScreen->fbOffset = 0;
891 }
892 #endif
893
894 {
895 GLuint pitch, offset;
896 pitch = vmesa->front.pitch;
897 offset = vmesa->viaScreen->fbOffset + (vmesa->drawY * pitch + vmesa->drawX * bytePerPixel);
898 vmesa->drawXoff = (GLuint)((offset & 0x1f) / bytePerPixel);
899 if (vmesa->saam) {
900 if (vmesa->pSaamRects) {
901 offset = vmesa->viaScreen->fbOffset + (vmesa->pSaamRects[0].y1 * pitch +
902 vmesa->pSaamRects[0].x1 * bytePerPixel);
903 vmesa->drawXoffSaam = (GLuint)((offset & 0x1f) / bytePerPixel);
904 }
905 else
906 vmesa->drawXoffSaam = 0;
907 }
908 else
909 vmesa->drawXoffSaam = 0;
910 }
911
912 vmesa->glCtx->Driver.Viewport(vmesa->glCtx,0 ,0 ,0 ,0);
913 }
914
915 GLboolean
916 viaUnbindContext(__DRIcontextPrivate *driContextPriv)
917 {
918 #ifdef DEBUG
919 if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
920 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
921 #endif
922 return GL_TRUE;
923 }
924
925 GLboolean
926 viaMakeCurrent(__DRIcontextPrivate *driContextPriv,
927 __DRIdrawablePrivate *driDrawPriv,
928 __DRIdrawablePrivate *driReadPriv)
929 {
930 #ifdef DEBUG
931 if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
932
933 if (VIA_DEBUG) {
934 fprintf(stderr, "driContextPriv = %08x\n", (GLuint)driContextPriv);
935 fprintf(stderr, "driContextPriv = %08x\n", (GLuint)driDrawPriv);
936 fprintf(stderr, "driContextPriv = %08x\n", (GLuint)driReadPriv);
937 }
938 #endif
939
940 if (driContextPriv) {
941 viaContextPtr vmesa = (viaContextPtr)driContextPriv->driverPrivate;
942
943 current_mesa = vmesa;
944
945 #ifdef DEBUG
946 if (VIA_DEBUG) fprintf(stderr, "viaScreen->bitsPerPixel = %d\n", viaScreen->bitsPerPixel);
947 if (VIA_DEBUG) fprintf(stderr, "viaMakeCurrent: w = %d\n", vmesa->driDrawable->w);
948 #endif
949
950 vmesa->driDrawable = driDrawPriv;
951 if ( ! calculate_buffer_parameters( vmesa ) ) {
952 return GL_FALSE;
953 }
954
955 _mesa_make_current2(vmesa->glCtx,
956 (GLframebuffer *)driDrawPriv->driverPrivate,
957 (GLframebuffer *)driReadPriv->driverPrivate);
958 #ifdef DEBUG
959 if (VIA_DEBUG) fprintf(stderr, "Context %d MakeCurrent\n", vmesa->hHWContext);
960 #endif
961 viaXMesaWindowMoved(vmesa);
962 if (!vmesa->glCtx->Viewport.Width)
963 _mesa_set_viewport(vmesa->glCtx, 0, 0,
964 driDrawPriv->w, driDrawPriv->h);
965 }
966 else {
967 _mesa_make_current(0,0);
968 }
969
970 #ifdef DEBUG
971 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
972 #endif
973 return GL_TRUE;
974 }
975
976 void viaGetLock(viaContextPtr vmesa, GLuint flags)
977 {
978 __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
979 __DRIscreenPrivate *sPriv = vmesa->driScreen;
980 drm_via_sarea_t *sarea = vmesa->sarea;
981 int me = vmesa->hHWContext;
982 __DRIdrawablePrivate *pdp;
983 __DRIscreenPrivate *psp;
984 pdp = dPriv;
985 psp = sPriv;
986 #ifdef DEBUG
987 if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
988 if (VIA_DEBUG) fprintf(stderr, "drmGetLock - in\n");
989 #endif
990 drmGetLock(vmesa->driFd, vmesa->hHWContext, flags);
991
992 do {
993 DRM_UNLOCK(psp->fd, &psp->pSAREA->lock,
994 pdp->driContextPriv->hHWContext);
995 DRM_SPINLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
996 __driUtilUpdateDrawableInfo(dPriv);
997 DRM_SPINUNLOCK(&psp->pSAREA->drawable_lock, psp->drawLockID);
998 DRM_LIGHT_LOCK(psp->fd, &psp->pSAREA->lock,
999 pdp->driContextPriv->hHWContext);
1000 } while (0);
1001
1002 if (sarea->ctxOwner != me) {
1003 vmesa->uploadCliprects = GL_TRUE;
1004 sarea->ctxOwner = me;
1005 }
1006
1007 viaXMesaWindowMoved(vmesa);
1008 #ifdef DEBUG
1009 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
1010 #endif
1011 }
1012
1013 void viaLock(viaContextPtr vmesa, GLuint flags)
1014 {
1015 __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
1016 __DRIscreenPrivate *sPriv = vmesa->driScreen;
1017
1018 if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
1019
1020 /*=* John Sheng [2003.6.16] for xf43 */
1021 if(dPriv->pStamp == NULL)
1022 dPriv->pStamp = &dPriv->lastStamp;
1023
1024 if (*(dPriv->pStamp) != dPriv->lastStamp || vmesa->saam) {
1025 GLuint scrn;
1026 scrn = vmesa->saam & S_MASK;
1027
1028 DRM_SPINLOCK(&sPriv->pSAREA->drawable_lock, sPriv->drawLockID);
1029
1030 if (scrn == S1)
1031 __driUtilUpdateDrawableInfo(dPriv);
1032 else
1033 DRI_VALIDATE_DRAWABLE_INFO_ONCE(dPriv);
1034
1035 viaXMesaWindowMoved(vmesa);
1036 DRM_SPINUNLOCK(&sPriv->pSAREA->drawable_lock, sPriv->drawLockID);
1037 }
1038
1039 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
1040
1041 return;
1042 }
1043
1044 void viaUnLock(viaContextPtr vmesa, GLuint flags)
1045 {
1046 drm_via_sarea_t *sarea = vmesa->sarea;
1047 int me = vmesa->hHWContext;
1048
1049 #ifdef DEBUG
1050 if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
1051 if (VIA_DEBUG) fprintf(stderr, "sarea->ctxOwner = %d\n", sarea->ctxOwner);
1052 if (VIA_DEBUG) fprintf(stderr, "me = %d\n", me);
1053 #endif
1054 if (sarea->ctxOwner == me) {
1055 sarea->ctxOwner = 0;
1056 }
1057 #ifdef DEBUG
1058 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
1059 #endif
1060 }
1061
1062 void
1063 viaSwapBuffers(__DRIdrawablePrivate *drawablePrivate)
1064 {
1065 __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *)drawablePrivate;
1066 #ifdef DEBUG
1067 if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
1068 #endif
1069 if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
1070 viaContextPtr vmesa;
1071 GLcontext *ctx;
1072
1073 vmesa = (viaContextPtr)dPriv->driContextPriv->driverPrivate;
1074 ctx = vmesa->glCtx;
1075 if (ctx->Visual.doubleBufferMode) {
1076 _mesa_notifySwapBuffers(ctx);
1077 if (vmesa->doPageFlip) {
1078 viaPageFlip(dPriv);
1079 }
1080 else {
1081 viaCopyBuffer(dPriv);
1082 }
1083 }
1084 else
1085 VIA_FIREVERTICES(vmesa);
1086 }
1087 else {
1088 _mesa_problem(NULL, "viaSwapBuffers: drawable has no context!\n");
1089 }
1090 #ifdef DEBUG
1091 if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
1092 #endif
1093 }