merge unichrome changes from branch
[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 "state.h"
37 #include "simple_list.h"
38 #include "extensions.h"
39
40 #include "swrast/swrast.h"
41 #include "swrast_setup/swrast_setup.h"
42 #include "tnl/tnl.h"
43 #include "array_cache/acache.h"
44
45 #include "tnl/t_pipeline.h"
46
47 #include "drivers/common/driverfuncs.h"
48
49 #include "via_screen.h"
50 #include "via_dri.h"
51
52 #include "via_state.h"
53 #include "via_tex.h"
54 #include "via_span.h"
55 #include "via_tris.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 "20041215"
63
64 #include "vblank.h"
65 #include "utils.h"
66
67 GLuint VIA_DEBUG = 0;
68
69 /**
70 * Return various strings for \c glGetString.
71 *
72 * \sa glGetString
73 */
74 static const GLubyte *viaGetString(GLcontext *ctx, GLenum name)
75 {
76 static char buffer[128];
77 unsigned offset;
78
79
80 switch (name) {
81 case GL_VENDOR:
82 return (GLubyte *)"VIA Technology";
83
84 case GL_RENDERER: {
85 static const char * const chipset_names[] = {
86 "UniChrome",
87 "CastleRock (CLE266)",
88 "UniChrome (KM400)",
89 "UniChrome (K8M800)",
90 "UniChrome (PM8x0/CN400)",
91 };
92 struct via_context *vmesa = VIA_CONTEXT(ctx);
93 unsigned id = vmesa->viaScreen->deviceID;
94
95 offset = driGetRendererString( buffer,
96 chipset_names[(id > VIA_PM800) ? 0 : id],
97 DRIVER_DATE, 0 );
98 return (GLubyte *)buffer;
99 }
100
101 default:
102 return NULL;
103 }
104 }
105
106
107 /**
108 * Calculate a width that satisfies the hardware's alignment requirements.
109 * On the Unichrome hardware, each scanline must be aligned to a multiple of
110 * 16 pixels.
111 *
112 * \param width Minimum buffer width, in pixels.
113 *
114 * \returns A pixel width that meets the alignment requirements.
115 */
116 static __inline__ unsigned
117 buffer_align( unsigned width )
118 {
119 return (width + 0x0f) & ~0x0f;
120 }
121
122
123 /**
124 * Calculate the framebuffer parameters for all buffers (front, back, depth,
125 * and stencil) associated with the specified context.
126 *
127 * \warning
128 * This function also calls \c AllocateBuffer to actually allocate the
129 * buffers.
130 *
131 * \sa AllocateBuffer
132 */
133 static GLboolean
134 calculate_buffer_parameters( struct via_context *vmesa )
135 {
136 const unsigned shift = vmesa->viaScreen->bitsPerPixel / 16;
137 const unsigned extra = 32;
138 unsigned w;
139 unsigned h;
140
141 /* Allocate front-buffer */
142 if (vmesa->drawType == GLX_PBUFFER_BIT) {
143 w = vmesa->driDrawable->w;
144 h = vmesa->driDrawable->h;
145
146 vmesa->front.bpp = vmesa->viaScreen->bitsPerPixel;
147 vmesa->front.pitch = buffer_align( w ) << shift;
148 vmesa->front.size = vmesa->front.pitch * h;
149
150 if (vmesa->front.map)
151 via_free_draw_buffer(vmesa, &vmesa->front);
152 if (!via_alloc_draw_buffer(vmesa, &vmesa->front))
153 return GL_FALSE;
154
155 } else {
156 w = vmesa->viaScreen->width;
157 h = vmesa->viaScreen->height;
158
159 vmesa->front.bpp = vmesa->viaScreen->bitsPerPixel;
160 vmesa->front.pitch = buffer_align( w ) << shift;
161 vmesa->front.size = vmesa->front.pitch * h;
162 if (getenv("ALTERNATE_SCREEN"))
163 vmesa->front.offset = vmesa->front.size;
164 else
165 vmesa->front.offset = 0;
166 vmesa->front.map = (char *) vmesa->driScreen->pFB;
167 }
168
169
170 /* Allocate back-buffer */
171 if (vmesa->hasBack) {
172 vmesa->back.bpp = vmesa->viaScreen->bitsPerPixel;
173 vmesa->back.pitch = (buffer_align( vmesa->driDrawable->w ) << shift);
174 vmesa->back.pitch += extra;
175 vmesa->back.pitch = MIN2(vmesa->back.pitch, vmesa->front.pitch);
176 vmesa->back.size = vmesa->back.pitch * vmesa->driDrawable->h;
177 if (vmesa->back.map)
178 via_free_draw_buffer(vmesa, &vmesa->back);
179 if (!via_alloc_draw_buffer(vmesa, &vmesa->back))
180 return GL_FALSE;
181 }
182 else {
183 if (vmesa->back.map)
184 via_free_draw_buffer(vmesa, &vmesa->back);
185 (void) memset( &vmesa->back, 0, sizeof( vmesa->back ) );
186 }
187
188
189 /* Allocate depth-buffer */
190 if ( vmesa->hasStencil || vmesa->hasDepth ) {
191 vmesa->depth.bpp = vmesa->depthBits;
192 if (vmesa->depth.bpp == 24)
193 vmesa->depth.bpp = 32;
194
195 vmesa->depth.pitch = (buffer_align( vmesa->driDrawable->w ) *
196 (vmesa->depth.bpp/8)) + extra;
197 vmesa->depth.size = vmesa->depth.pitch * vmesa->driDrawable->h;
198
199 if (vmesa->depth.map)
200 via_free_draw_buffer(vmesa, &vmesa->depth);
201 if (!via_alloc_draw_buffer(vmesa, &vmesa->depth)) {
202 return GL_FALSE;
203 }
204 }
205 else {
206 if (vmesa->depth.map)
207 via_free_draw_buffer(vmesa, &vmesa->depth);
208 (void) memset( & vmesa->depth, 0, sizeof( vmesa->depth ) );
209 }
210
211 if( vmesa->viaScreen->width == vmesa->driDrawable->w &&
212 vmesa->viaScreen->height == vmesa->driDrawable->h ) {
213 vmesa->doPageFlip = vmesa->allowPageFlip;
214 assert(vmesa->back.pitch == vmesa->front.pitch);
215 }
216 else
217 vmesa->doPageFlip = GL_FALSE;
218
219 return GL_TRUE;
220 }
221
222
223 void viaReAllocateBuffers(GLframebuffer *drawbuffer)
224 {
225 GET_CURRENT_CONTEXT(ctx);
226 struct via_context *vmesa = VIA_CONTEXT(ctx);
227
228 _swrast_alloc_buffers( drawbuffer );
229 calculate_buffer_parameters( vmesa );
230 }
231
232 static void viaBufferSize(GLframebuffer *buffer, GLuint *width, GLuint *height)
233 {
234 GET_CURRENT_CONTEXT(ctx);
235 struct via_context *vmesa = VIA_CONTEXT(ctx);
236 *width = vmesa->driDrawable->w;
237 *height = vmesa->driDrawable->h;
238 }
239
240 /* Extension strings exported by the Unichrome driver.
241 */
242 static const char * const card_extensions[] =
243 {
244 "GL_ARB_multitexture",
245 "GL_ARB_point_parameters",
246 "GL_ARB_texture_env_add",
247 "GL_ARB_texture_env_combine",
248 /* "GL_ARB_texture_env_dot3", */
249 "GL_ARB_texture_mirrored_repeat",
250 "GL_EXT_stencil_wrap",
251 "GL_EXT_texture_env_combine",
252 /* "GL_EXT_texture_env_dot3", */
253 "GL_EXT_texture_lod_bias",
254 "GL_EXT_secondary_color",
255 "GL_EXT_fog_coord",
256 "GL_NV_blend_square",
257 NULL
258 };
259
260 extern const struct tnl_pipeline_stage _via_fastrender_stage;
261 extern const struct tnl_pipeline_stage _via_render_stage;
262
263 static const struct tnl_pipeline_stage *via_pipeline[] = {
264 &_tnl_vertex_transform_stage,
265 &_tnl_normal_transform_stage,
266 &_tnl_lighting_stage,
267 &_tnl_fog_coordinate_stage,
268 &_tnl_texgen_stage,
269 &_tnl_texture_transform_stage,
270 /* REMOVE: point attenuation stage */
271 #if 1
272 &_via_fastrender_stage, /* ADD: unclipped rastersetup-to-dma */
273 #endif
274 &_tnl_render_stage,
275 0,
276 };
277
278
279 static const struct dri_debug_control debug_control[] =
280 {
281 { "fall", DEBUG_FALLBACKS },
282 { "tex", DEBUG_TEXTURE },
283 { "ioctl", DEBUG_IOCTL },
284 { "prim", DEBUG_PRIMS },
285 { "vert", DEBUG_VERTS },
286 { "state", DEBUG_STATE },
287 { "verb", DEBUG_VERBOSE },
288 { "dri", DEBUG_DRI },
289 { "dma", DEBUG_DMA },
290 { "san", DEBUG_SANITY },
291 { "sync", DEBUG_SYNC },
292 { "sleep", DEBUG_SLEEP },
293 { "pix", DEBUG_PIXEL },
294 { "2d", DEBUG_2D },
295 { NULL, 0 }
296 };
297
298
299 static GLboolean
300 AllocateDmaBuffer(const GLvisual *visual, struct via_context *vmesa)
301 {
302 if (vmesa->dma)
303 via_free_dma_buffer(vmesa);
304
305 if (!via_alloc_dma_buffer(vmesa))
306 return GL_FALSE;
307
308 vmesa->dmaLow = 0;
309 vmesa->dmaCliprectAddr = ~0;
310 return GL_TRUE;
311 }
312
313 static void
314 FreeBuffer(struct via_context *vmesa)
315 {
316 if (vmesa->front.map && vmesa->drawType == GLX_PBUFFER_BIT)
317 via_free_draw_buffer(vmesa, &vmesa->front);
318
319 if (vmesa->back.map)
320 via_free_draw_buffer(vmesa, &vmesa->back);
321
322 if (vmesa->depth.map)
323 via_free_draw_buffer(vmesa, &vmesa->depth);
324
325 if (vmesa->breadcrumb.map)
326 via_free_draw_buffer(vmesa, &vmesa->breadcrumb);
327
328 if (vmesa->dma)
329 via_free_dma_buffer(vmesa);
330 }
331
332 static int
333 get_ust_nop( int64_t * ust )
334 {
335 *ust = 1;
336 return 0;
337 }
338
339 GLboolean
340 viaCreateContext(const __GLcontextModes *mesaVis,
341 __DRIcontextPrivate *driContextPriv,
342 void *sharedContextPrivate)
343 {
344 GLcontext *ctx, *shareCtx;
345 struct via_context *vmesa;
346 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
347 viaScreenPrivate *viaScreen = (viaScreenPrivate *)sPriv->private;
348 drm_via_sarea_t *saPriv = (drm_via_sarea_t *)
349 (((GLubyte *)sPriv->pSAREA) + viaScreen->sareaPrivOffset);
350 struct dd_function_table functions;
351
352 /* Allocate via context */
353 vmesa = (struct via_context *) CALLOC_STRUCT(via_context);
354 if (!vmesa) {
355 return GL_FALSE;
356 }
357
358 /* Parse configuration files.
359 */
360 driParseConfigFiles (&vmesa->optionCache, &viaScreen->optionCache,
361 sPriv->myNum, "via");
362
363 /* pick back buffer */
364 vmesa->hasBack = mesaVis->doubleBufferMode;
365
366 switch(mesaVis->depthBits) {
367 case 0:
368 vmesa->hasDepth = GL_FALSE;
369 vmesa->depthBits = 0;
370 vmesa->depth_max = 1.0;
371 break;
372 case 16:
373 vmesa->hasDepth = GL_TRUE;
374 vmesa->depthBits = mesaVis->depthBits;
375 vmesa->have_hw_stencil = GL_FALSE;
376 vmesa->depth_max = (GLfloat)0xffff;
377 vmesa->depth_clear_mask = 0xf << 28;
378 vmesa->ClearDepth = 0xffff;
379 vmesa->polygon_offset_scale = 1.0 / vmesa->depth_max;
380 break;
381 case 24:
382 vmesa->hasDepth = GL_TRUE;
383 vmesa->depthBits = mesaVis->depthBits;
384 vmesa->depth_max = (GLfloat) 0xffffff;
385 vmesa->depth_clear_mask = 0xe << 28;
386 vmesa->ClearDepth = 0xffffff00;
387
388 assert(mesaVis->haveStencilBuffer);
389 assert(mesaVis->stencilBits == 8);
390
391 vmesa->have_hw_stencil = GL_TRUE;
392 vmesa->stencilBits = mesaVis->stencilBits;
393 vmesa->stencil_clear_mask = 0x1 << 28;
394 vmesa->polygon_offset_scale = 2.0 / vmesa->depth_max;
395 break;
396 case 32:
397 vmesa->hasDepth = GL_TRUE;
398 vmesa->depthBits = mesaVis->depthBits;
399 assert(!mesaVis->haveStencilBuffer);
400 vmesa->have_hw_stencil = GL_FALSE;
401 vmesa->depth_max = (GLfloat)0xffffffff;
402 vmesa->depth_clear_mask = 0xf << 28;
403 vmesa->ClearDepth = 0xffffffff;
404 vmesa->polygon_offset_scale = 2.0 / vmesa->depth_max;
405 break;
406 default:
407 assert(0);
408 break;
409 }
410
411 make_empty_list(&vmesa->freed_tex_buffers);
412 make_empty_list(&vmesa->tex_image_list[VIA_MEM_VIDEO]);
413 make_empty_list(&vmesa->tex_image_list[VIA_MEM_AGP]);
414 make_empty_list(&vmesa->tex_image_list[VIA_MEM_SYSTEM]);
415
416 _mesa_init_driver_functions(&functions);
417 viaInitTextureFuncs(&functions);
418
419 /* Allocate the Mesa context */
420 if (sharedContextPrivate)
421 shareCtx = ((struct via_context *) sharedContextPrivate)->glCtx;
422 else
423 shareCtx = NULL;
424
425 vmesa->glCtx = _mesa_create_context(mesaVis, shareCtx, &functions,
426 (void*) vmesa);
427
428 vmesa->shareCtx = shareCtx;
429
430 if (!vmesa->glCtx) {
431 FREE(vmesa);
432 return GL_FALSE;
433 }
434 driContextPriv->driverPrivate = vmesa;
435
436 ctx = vmesa->glCtx;
437
438 ctx->Const.MaxTextureLevels = 10;
439 ctx->Const.MaxTextureUnits = 2;
440 ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits;
441 ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits;
442
443 ctx->Const.MinLineWidth = 1.0;
444 ctx->Const.MinLineWidthAA = 1.0;
445 ctx->Const.MaxLineWidth = 1.0;
446 ctx->Const.MaxLineWidthAA = 1.0;
447 ctx->Const.LineWidthGranularity = 1.0;
448
449 ctx->Const.MinPointSize = 1.0;
450 ctx->Const.MinPointSizeAA = 1.0;
451 ctx->Const.MaxPointSize = 1.0;
452 ctx->Const.MaxPointSizeAA = 1.0;
453 ctx->Const.PointSizeGranularity = 1.0;
454
455 ctx->Driver.GetBufferSize = viaBufferSize;
456 /* ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; *//* FIXME ?? */
457 ctx->Driver.GetString = viaGetString;
458
459 ctx->DriverCtx = (void *)vmesa;
460 vmesa->glCtx = ctx;
461
462 /* Initialize the software rasterizer and helper modules.
463 */
464 _swrast_CreateContext(ctx);
465 _ac_CreateContext(ctx);
466 _tnl_CreateContext(ctx);
467 _swsetup_CreateContext(ctx);
468
469 /* Install the customized pipeline:
470 */
471 _tnl_destroy_pipeline(ctx);
472 _tnl_install_pipeline(ctx, via_pipeline);
473
474 /* Configure swrast and T&L to match hardware characteristics:
475 */
476 _swrast_allow_pixel_fog(ctx, GL_FALSE);
477 _swrast_allow_vertex_fog(ctx, GL_TRUE);
478 _tnl_allow_pixel_fog(ctx, GL_FALSE);
479 _tnl_allow_vertex_fog(ctx, GL_TRUE);
480
481 /* vmesa->display = dpy; */
482 vmesa->display = sPriv->display;
483
484 vmesa->hHWContext = driContextPriv->hHWContext;
485 vmesa->driFd = sPriv->fd;
486 vmesa->driHwLock = &sPriv->pSAREA->lock;
487
488 vmesa->viaScreen = viaScreen;
489 vmesa->driScreen = sPriv;
490 vmesa->sarea = saPriv;
491
492 vmesa->renderIndex = ~0;
493 vmesa->setupIndex = ~0;
494 vmesa->hwPrimitive = GL_POLYGON+1;
495
496 /* KW: Hardwire this. Was previously set bogusly in
497 * viaCreateBuffer. Needs work before PBUFFER can be used:
498 */
499 vmesa->drawType = GLX_WINDOW_BIT;
500
501
502 _math_matrix_ctr(&vmesa->ViewportMatrix);
503
504 /* Do this early, before VIA_FLUSH_DMA can be called:
505 */
506 if (!AllocateDmaBuffer(mesaVis, vmesa)) {
507 fprintf(stderr ,"AllocateDmaBuffer fail\n");
508 FreeBuffer(vmesa);
509 FREE(vmesa);
510 return GL_FALSE;
511 }
512
513 /* Allocate a small piece of fb memory for synchronization:
514 */
515 vmesa->breadcrumb.bpp = 32;
516 vmesa->breadcrumb.pitch = buffer_align( 64 ) << 2;
517 vmesa->breadcrumb.size = vmesa->breadcrumb.pitch;
518
519 if (!via_alloc_draw_buffer(vmesa, &vmesa->breadcrumb)) {
520 fprintf(stderr ,"AllocateDmaBuffer fail\n");
521 FreeBuffer(vmesa);
522 FREE(vmesa);
523 return GL_FALSE;
524 }
525
526 driInitExtensions( ctx, card_extensions, GL_TRUE );
527 viaInitStateFuncs(ctx);
528 viaInitTriFuncs(ctx);
529 viaInitSpanFuncs(ctx);
530 viaInitIoctlFuncs(ctx);
531 viaInitState(ctx);
532
533 if (getenv("VIA_DEBUG"))
534 VIA_DEBUG = driParseDebugString( getenv( "VIA_DEBUG" ),
535 debug_control );
536
537 if (getenv("VIA_NO_RAST"))
538 FALLBACK(vmesa, VIA_FALLBACK_USER_DISABLE, 1);
539
540 /* I don't understand why this isn't working:
541 */
542 vmesa->vblank_flags =
543 vmesa->viaScreen->irqEnabled ?
544 driGetDefaultVBlankFlags(&vmesa->optionCache) : VBLANK_FLAG_NO_IRQ;
545
546 /* Hack this up in its place:
547 */
548 vmesa->vblank_flags = (getenv("VIA_VSYNC") ?
549 VBLANK_FLAG_SYNC : VBLANK_FLAG_NO_IRQ);
550
551 if (getenv("VIA_PAGEFLIP"))
552 vmesa->allowPageFlip = 1;
553
554 vmesa->get_ust =
555 (PFNGLXGETUSTPROC) glXGetProcAddress( (const GLubyte *) "__glXGetUST" );
556 if ( vmesa->get_ust == NULL ) {
557 vmesa->get_ust = get_ust_nop;
558 }
559 vmesa->get_ust( &vmesa->swap_ust );
560
561
562 vmesa->regMMIOBase = (GLuint *)((GLuint)viaScreen->reg);
563 vmesa->pnGEMode = (GLuint *)((GLuint)viaScreen->reg + 0x4);
564 vmesa->regEngineStatus = (GLuint *)((GLuint)viaScreen->reg + 0x400);
565 vmesa->regTranSet = (GLuint *)((GLuint)viaScreen->reg + 0x43C);
566 vmesa->regTranSpace = (GLuint *)((GLuint)viaScreen->reg + 0x440);
567 vmesa->agpBase = viaScreen->agpBase;
568
569 return GL_TRUE;
570 }
571
572 void
573 viaDestroyContext(__DRIcontextPrivate *driContextPriv)
574 {
575 GET_CURRENT_CONTEXT(ctx);
576 struct via_context *vmesa =
577 (struct via_context *)driContextPriv->driverPrivate;
578 struct via_context *current = ctx ? VIA_CONTEXT(ctx) : NULL;
579 assert(vmesa); /* should never be null */
580
581 /* check if we're deleting the currently bound context */
582 if (vmesa == current) {
583 VIA_FLUSH_DMA(vmesa);
584 _mesa_make_current2(NULL, NULL, NULL);
585 }
586
587 if (vmesa) {
588 viaWaitIdle(vmesa);
589 if (vmesa->doPageFlip) {
590 LOCK_HARDWARE(vmesa);
591 if (vmesa->pfCurrentOffset != 0) {
592 fprintf(stderr, "%s - reset pf\n", __FUNCTION__);
593 viaResetPageFlippingLocked(vmesa);
594 }
595 UNLOCK_HARDWARE(vmesa);
596 }
597
598 _swsetup_DestroyContext(vmesa->glCtx);
599 _tnl_DestroyContext(vmesa->glCtx);
600 _ac_DestroyContext(vmesa->glCtx);
601 _swrast_DestroyContext(vmesa->glCtx);
602 /* free the Mesa context */
603 _mesa_destroy_context(vmesa->glCtx);
604 /* release our data */
605 FreeBuffer(vmesa);
606
607 assert (is_empty_list(&vmesa->tex_image_list[VIA_MEM_AGP]));
608 assert (is_empty_list(&vmesa->tex_image_list[VIA_MEM_VIDEO]));
609 assert (is_empty_list(&vmesa->tex_image_list[VIA_MEM_SYSTEM]));
610 assert (is_empty_list(&vmesa->freed_tex_buffers));
611
612 FREE(vmesa);
613 }
614 }
615
616
617 void viaXMesaWindowMoved(struct via_context *vmesa)
618 {
619 __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
620 GLuint bytePerPixel = vmesa->viaScreen->bitsPerPixel >> 3;
621
622 if (!dPriv)
623 return;
624
625 switch (vmesa->glCtx->Color._DrawDestMask[0]) {
626 case DD_FRONT_LEFT_BIT:
627 if (dPriv->numBackClipRects == 0) {
628 vmesa->numClipRects = dPriv->numClipRects;
629 vmesa->pClipRects = dPriv->pClipRects;
630 }
631 else {
632 vmesa->numClipRects = dPriv->numBackClipRects;
633 vmesa->pClipRects = dPriv->pBackClipRects;
634 }
635 break;
636 case DD_BACK_LEFT_BIT:
637 vmesa->numClipRects = dPriv->numClipRects;
638 vmesa->pClipRects = dPriv->pClipRects;
639 break;
640 default:
641 vmesa->numClipRects = 0;
642 break;
643 }
644
645 if (vmesa->drawW != dPriv->w ||
646 vmesa->drawH != dPriv->h)
647 calculate_buffer_parameters( vmesa );
648
649 vmesa->drawXoff = (GLuint)(((dPriv->x * bytePerPixel) & 0x1f) /
650 bytePerPixel);
651 vmesa->drawX = dPriv->x - vmesa->drawXoff;
652 vmesa->drawY = dPriv->y;
653 vmesa->drawW = dPriv->w;
654 vmesa->drawH = dPriv->h;
655
656 vmesa->front.orig = (vmesa->front.offset +
657 vmesa->drawY * vmesa->front.pitch +
658 vmesa->drawX * bytePerPixel);
659
660 vmesa->front.origMap = (vmesa->front.map +
661 vmesa->drawY * vmesa->front.pitch +
662 vmesa->drawX * bytePerPixel);
663
664 vmesa->back.orig = vmesa->back.offset;
665 vmesa->depth.orig = vmesa->depth.offset;
666 vmesa->back.origMap = vmesa->back.map;
667 vmesa->depth.origMap = vmesa->depth.map;
668
669 viaCalcViewport(vmesa->glCtx);
670 }
671
672 GLboolean
673 viaUnbindContext(__DRIcontextPrivate *driContextPriv)
674 {
675 return GL_TRUE;
676 }
677
678 GLboolean
679 viaMakeCurrent(__DRIcontextPrivate *driContextPriv,
680 __DRIdrawablePrivate *driDrawPriv,
681 __DRIdrawablePrivate *driReadPriv)
682 {
683 if (VIA_DEBUG & DEBUG_DRI) {
684 fprintf(stderr, "driContextPriv = %08x\n", (GLuint)driContextPriv);
685 fprintf(stderr, "driDrawPriv = %08x\n", (GLuint)driDrawPriv);
686 fprintf(stderr, "driReadPriv = %08x\n", (GLuint)driReadPriv);
687 }
688
689 if (driContextPriv) {
690 struct via_context *vmesa =
691 (struct via_context *)driContextPriv->driverPrivate;
692 GLcontext *ctx = vmesa->glCtx;
693
694 if ( vmesa->driDrawable != driDrawPriv ) {
695 driDrawableInitVBlank( driDrawPriv, vmesa->vblank_flags );
696 vmesa->driDrawable = driDrawPriv;
697 if ( ! calculate_buffer_parameters( vmesa ) ) {
698 return GL_FALSE;
699 }
700 ctx->Driver.DrawBuffer( ctx, ctx->Color.DrawBuffer[0] );
701 }
702
703 _mesa_make_current2(vmesa->glCtx,
704 (GLframebuffer *)driDrawPriv->driverPrivate,
705 (GLframebuffer *)driReadPriv->driverPrivate);
706
707 viaXMesaWindowMoved(vmesa);
708 ctx->Driver.Scissor(vmesa->glCtx,
709 vmesa->glCtx->Scissor.X,
710 vmesa->glCtx->Scissor.Y,
711 vmesa->glCtx->Scissor.Width,
712 vmesa->glCtx->Scissor.Height);
713 }
714 else {
715 _mesa_make_current(0,0);
716 }
717
718 return GL_TRUE;
719 }
720
721 void viaGetLock(struct via_context *vmesa, GLuint flags)
722 {
723 __DRIdrawablePrivate *dPriv = vmesa->driDrawable;
724 __DRIscreenPrivate *sPriv = vmesa->driScreen;
725
726 drmGetLock(vmesa->driFd, vmesa->hHWContext, flags);
727
728 DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv );
729
730 if (vmesa->sarea->ctxOwner != vmesa->hHWContext) {
731 vmesa->sarea->ctxOwner = vmesa->hHWContext;
732 vmesa->newEmitState = ~0;
733 }
734
735 if (vmesa->lastStamp != dPriv->lastStamp) {
736 viaXMesaWindowMoved(vmesa);
737 vmesa->lastStamp = dPriv->lastStamp;
738 }
739
740 if (vmesa->doPageFlip &&
741 vmesa->pfCurrentOffset != vmesa->sarea->pfCurrentOffset) {
742 fprintf(stderr, "%s - reset pf\n", __FUNCTION__);
743 viaResetPageFlippingLocked(vmesa);
744 }
745 }
746
747
748 void
749 viaSwapBuffers(__DRIdrawablePrivate *drawablePrivate)
750 {
751 __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *)drawablePrivate;
752
753 if (dPriv &&
754 dPriv->driContextPriv &&
755 dPriv->driContextPriv->driverPrivate) {
756 struct via_context *vmesa =
757 (struct via_context *)dPriv->driContextPriv->driverPrivate;
758 GLcontext *ctx = vmesa->glCtx;
759
760 if (ctx->Visual.doubleBufferMode) {
761 _mesa_notifySwapBuffers(ctx);
762 if (vmesa->doPageFlip) {
763 viaPageFlip(dPriv);
764 }
765 else {
766 viaCopyBuffer(dPriv);
767 }
768 }
769 else
770 VIA_FLUSH_DMA(vmesa);
771 }
772 else {
773 _mesa_problem(NULL, "viaSwapBuffers: drawable has no context!\n");
774 }
775 }