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