2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
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:
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
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.
28 * \author John Sheng (presumably of either VIA Technologies or S3 Graphics)
29 * \author Others at VIA Technologies?
30 * \author Others at S3 Graphics?
37 #include "simple_list.h"
38 #include "extensions.h"
39 #include "framebuffer.h"
40 #include "renderbuffer.h"
42 #include "swrast/swrast.h"
43 #include "swrast_setup/swrast_setup.h"
45 #include "array_cache/acache.h"
47 #include "tnl/t_pipeline.h"
49 #include "drivers/common/driverfuncs.h"
51 #include "via_screen.h"
54 #include "via_state.h"
58 #include "via_ioctl.h"
63 #include "drirenderbuffer.h"
65 #define need_GL_ARB_multisample
66 #define need_GL_ARB_point_parameters
67 #define need_GL_EXT_fog_coord
68 #define need_GL_EXT_secondary_color
69 #include "extension_helper.h"
71 #define DRIVER_DATE "20050526"
79 * Return various strings for \c glGetString.
83 static const GLubyte
*viaGetString(GLcontext
*ctx
, GLenum name
)
85 static char buffer
[128];
91 return (GLubyte
*)"VIA Technology";
94 static const char * const chipset_names
[] = {
96 "CastleRock (CLE266)",
99 "UniChrome (PM8x0/CN400)",
101 struct via_context
*vmesa
= VIA_CONTEXT(ctx
);
102 unsigned id
= vmesa
->viaScreen
->deviceID
;
104 offset
= driGetRendererString( buffer
,
105 chipset_names
[(id
> VIA_PM800
) ? 0 : id
],
107 return (GLubyte
*)buffer
;
117 * Calculate a width that satisfies the hardware's alignment requirements.
118 * On the Unichrome hardware, each scanline must be aligned to a multiple of
121 * \param width Minimum buffer width, in pixels.
123 * \returns A pixel width that meets the alignment requirements.
125 static __inline__
unsigned
126 buffer_align( unsigned width
)
128 return (width
+ 0x0f) & ~0x0f;
133 viaDeleteRenderbuffer(struct gl_renderbuffer
*rb
)
135 /* Don't free() since we're contained in via_context struct. */
139 viaRenderbufferStorage(GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
140 GLenum internalFormat
, GLuint width
, GLuint height
)
144 rb
->InternalFormat
= internalFormat
;
150 viaInitRenderbuffer(struct gl_renderbuffer
*rb
, GLenum format
)
152 const GLuint name
= 0;
154 _mesa_init_renderbuffer(rb
, name
);
156 /* Make sure we're using a null-valued GetPointer routine */
157 assert(rb
->GetPointer(NULL
, rb
, 0, 0) == NULL
);
159 rb
->InternalFormat
= format
;
161 if (format
== GL_RGBA
) {
163 rb
->_BaseFormat
= GL_RGBA
;
164 rb
->DataType
= GL_UNSIGNED_BYTE
;
166 else if (format
== GL_DEPTH_COMPONENT16
) {
168 rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
169 /* we always Get/Put 32-bit Z values */
170 rb
->DataType
= GL_UNSIGNED_INT
;
172 else if (format
== GL_DEPTH_COMPONENT24
) {
174 rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
175 /* we always Get/Put 32-bit Z values */
176 rb
->DataType
= GL_UNSIGNED_INT
;
180 ASSERT(format
== GL_STENCIL_INDEX8
);
181 rb
->_BaseFormat
= GL_STENCIL_INDEX
;
182 rb
->DataType
= GL_UNSIGNED_BYTE
;
185 rb
->Delete
= viaDeleteRenderbuffer
;
186 rb
->AllocStorage
= viaRenderbufferStorage
;
191 * Calculate the framebuffer parameters for all buffers (front, back, depth,
192 * and stencil) associated with the specified context.
195 * This function also calls \c AllocateBuffer to actually allocate the
201 calculate_buffer_parameters( struct via_context
*vmesa
,
202 struct gl_framebuffer
*fb
)
204 const unsigned shift
= vmesa
->viaScreen
->bitsPerPixel
/ 16;
205 const unsigned extra
= 32;
209 /* Normally, the renderbuffer would be added to the framebuffer just once
210 * when the framebuffer was created. The VIA driver is a bit funny
211 * though in that the front/back/depth renderbuffers are in the per-context
213 * That should be fixed someday.
216 if (!vmesa
->front
.Base
.InternalFormat
) {
217 /* do one-time init for the renderbuffers */
218 viaInitRenderbuffer(&vmesa
->front
.Base
, GL_RGBA
);
219 viaSetSpanFunctions(&vmesa
->front
, &fb
->Visual
);
220 _mesa_add_renderbuffer(fb
, BUFFER_FRONT_LEFT
, &vmesa
->front
.Base
);
222 if (fb
->Visual
.doubleBufferMode
) {
223 viaInitRenderbuffer(&vmesa
->back
.Base
, GL_RGBA
);
224 viaSetSpanFunctions(&vmesa
->back
, &fb
->Visual
);
225 _mesa_add_renderbuffer(fb
, BUFFER_BACK_LEFT
, &vmesa
->back
.Base
);
228 if (vmesa
->glCtx
->Visual
.depthBits
> 0) {
229 viaInitRenderbuffer(&vmesa
->depth
.Base
,
230 (vmesa
->glCtx
->Visual
.depthBits
== 16
231 ? GL_DEPTH_COMPONENT16
: GL_DEPTH_COMPONENT24
));
232 viaSetSpanFunctions(&vmesa
->depth
, &fb
->Visual
);
233 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, &vmesa
->depth
.Base
);
236 if (vmesa
->glCtx
->Visual
.stencilBits
> 0) {
237 viaInitRenderbuffer(&vmesa
->stencil
.Base
, GL_STENCIL_INDEX8_EXT
);
238 viaSetSpanFunctions(&vmesa
->stencil
, &fb
->Visual
);
239 _mesa_add_renderbuffer(fb
, BUFFER_STENCIL
, &vmesa
->stencil
.Base
);
243 assert(vmesa
->front
.Base
.InternalFormat
);
244 assert(vmesa
->front
.Base
.AllocStorage
);
245 if (fb
->Visual
.doubleBufferMode
) {
246 assert(fb
->Attachment
[BUFFER_BACK_LEFT
].Renderbuffer
);
247 assert(vmesa
->front
.Base
.AllocStorage
);
249 if (fb
->Visual
.depthBits
) {
250 assert(fb
->Attachment
[BUFFER_DEPTH
].Renderbuffer
);
251 assert(vmesa
->depth
.Base
.AllocStorage
);
255 /* Allocate front-buffer */
256 if (vmesa
->drawType
== GLX_PBUFFER_BIT
) {
257 w
= vmesa
->driDrawable
->w
;
258 h
= vmesa
->driDrawable
->h
;
260 vmesa
->front
.bpp
= vmesa
->viaScreen
->bitsPerPixel
;
261 vmesa
->front
.pitch
= buffer_align( w
) << shift
; /* bytes, not pixels */
262 vmesa
->front
.size
= vmesa
->front
.pitch
* h
;
264 if (vmesa
->front
.map
)
265 via_free_draw_buffer(vmesa
, &vmesa
->front
);
266 if (!via_alloc_draw_buffer(vmesa
, &vmesa
->front
))
270 w
= vmesa
->viaScreen
->width
;
271 h
= vmesa
->viaScreen
->height
;
273 vmesa
->front
.bpp
= vmesa
->viaScreen
->bitsPerPixel
;
274 vmesa
->front
.pitch
= buffer_align( w
) << shift
; /* bytes, not pixels */
275 vmesa
->front
.size
= vmesa
->front
.pitch
* h
;
276 if (getenv("ALTERNATE_SCREEN"))
277 vmesa
->front
.offset
= vmesa
->front
.size
;
279 vmesa
->front
.offset
= 0;
280 vmesa
->front
.map
= (char *) vmesa
->driScreen
->pFB
;
284 /* Allocate back-buffer */
285 if (vmesa
->hasBack
) {
286 vmesa
->back
.bpp
= vmesa
->viaScreen
->bitsPerPixel
;
287 vmesa
->back
.pitch
= (buffer_align( vmesa
->driDrawable
->w
) << shift
);
288 vmesa
->back
.pitch
+= extra
;
289 vmesa
->back
.pitch
= MIN2(vmesa
->back
.pitch
, vmesa
->front
.pitch
);
290 vmesa
->back
.size
= vmesa
->back
.pitch
* vmesa
->driDrawable
->h
;
292 via_free_draw_buffer(vmesa
, &vmesa
->back
);
293 if (!via_alloc_draw_buffer(vmesa
, &vmesa
->back
))
298 via_free_draw_buffer(vmesa
, &vmesa
->back
);
299 (void) memset( &vmesa
->back
, 0, sizeof( vmesa
->back
) );
303 /* Allocate depth-buffer */
304 if ( vmesa
->hasStencil
|| vmesa
->hasDepth
) {
305 vmesa
->depth
.bpp
= vmesa
->depthBits
;
306 if (vmesa
->depth
.bpp
== 24)
307 vmesa
->depth
.bpp
= 32;
309 vmesa
->depth
.pitch
= (buffer_align( vmesa
->driDrawable
->w
) *
310 (vmesa
->depth
.bpp
/8)) + extra
;
311 vmesa
->depth
.size
= vmesa
->depth
.pitch
* vmesa
->driDrawable
->h
;
313 if (vmesa
->depth
.map
)
314 via_free_draw_buffer(vmesa
, &vmesa
->depth
);
315 if (!via_alloc_draw_buffer(vmesa
, &vmesa
->depth
)) {
320 if (vmesa
->depth
.map
)
321 via_free_draw_buffer(vmesa
, &vmesa
->depth
);
322 (void) memset( & vmesa
->depth
, 0, sizeof( vmesa
->depth
) );
325 /* stencil buffer is same as depth buffer */
326 vmesa
->stencil
.handle
= vmesa
->depth
.handle
;
327 vmesa
->stencil
.size
= vmesa
->depth
.size
;
328 vmesa
->stencil
.offset
= vmesa
->depth
.offset
;
329 vmesa
->stencil
.index
= vmesa
->depth
.index
;
330 vmesa
->stencil
.pitch
= vmesa
->depth
.pitch
;
331 vmesa
->stencil
.bpp
= vmesa
->depth
.bpp
;
332 vmesa
->stencil
.map
= vmesa
->depth
.map
;
333 vmesa
->stencil
.orig
= vmesa
->depth
.orig
;
334 vmesa
->stencil
.origMap
= vmesa
->depth
.origMap
;
336 if( vmesa
->viaScreen
->width
== vmesa
->driDrawable
->w
&&
337 vmesa
->viaScreen
->height
== vmesa
->driDrawable
->h
) {
338 vmesa
->doPageFlip
= vmesa
->allowPageFlip
;
339 assert(vmesa
->back
.pitch
== vmesa
->front
.pitch
);
342 vmesa
->doPageFlip
= GL_FALSE
;
348 void viaReAllocateBuffers(GLcontext
*ctx
, GLframebuffer
*drawbuffer
,
349 GLuint width
, GLuint height
)
351 struct via_context
*vmesa
= VIA_CONTEXT(ctx
);
353 calculate_buffer_parameters( vmesa
, drawbuffer
);
355 _mesa_resize_framebuffer(ctx
, drawbuffer
, width
, height
);
358 static void viaBufferSize(GLframebuffer
*buffer
, GLuint
*width
, GLuint
*height
)
360 GET_CURRENT_CONTEXT(ctx
);
361 struct via_context
*vmesa
= VIA_CONTEXT(ctx
);
362 *width
= vmesa
->driDrawable
->w
;
363 *height
= vmesa
->driDrawable
->h
;
366 /* Extension strings exported by the Unichrome driver.
368 const struct dri_extension card_extensions
[] =
370 { "GL_ARB_multisample", GL_ARB_multisample_functions
},
371 { "GL_ARB_multitexture", NULL
},
372 { "GL_ARB_point_parameters", GL_ARB_point_parameters_functions
},
373 { "GL_ARB_texture_env_add", NULL
},
374 { "GL_ARB_texture_env_combine", NULL
},
375 /* { "GL_ARB_texture_env_dot3", NULL }, */
376 { "GL_ARB_texture_mirrored_repeat", NULL
},
377 { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions
},
378 { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions
},
379 { "GL_EXT_stencil_wrap", NULL
},
380 { "GL_EXT_texture_env_combine", NULL
},
381 /* { "GL_EXT_texture_env_dot3", NULL }, */
382 { "GL_EXT_texture_lod_bias", NULL
},
383 { "GL_NV_blend_square", NULL
},
387 extern const struct tnl_pipeline_stage _via_fastrender_stage
;
388 extern const struct tnl_pipeline_stage _via_render_stage
;
390 static const struct tnl_pipeline_stage
*via_pipeline
[] = {
391 &_tnl_vertex_transform_stage
,
392 &_tnl_normal_transform_stage
,
393 &_tnl_lighting_stage
,
394 &_tnl_fog_coordinate_stage
,
396 &_tnl_texture_transform_stage
,
397 /* REMOVE: point attenuation stage */
399 &_via_fastrender_stage
, /* ADD: unclipped rastersetup-to-dma */
406 static const struct dri_debug_control debug_control
[] =
408 { "fall", DEBUG_FALLBACKS
},
409 { "tex", DEBUG_TEXTURE
},
410 { "ioctl", DEBUG_IOCTL
},
411 { "prim", DEBUG_PRIMS
},
412 { "vert", DEBUG_VERTS
},
413 { "state", DEBUG_STATE
},
414 { "verb", DEBUG_VERBOSE
},
415 { "dri", DEBUG_DRI
},
416 { "dma", DEBUG_DMA
},
417 { "san", DEBUG_SANITY
},
418 { "sync", DEBUG_SYNC
},
419 { "sleep", DEBUG_SLEEP
},
420 { "pix", DEBUG_PIXEL
},
427 AllocateDmaBuffer(struct via_context
*vmesa
)
430 via_free_dma_buffer(vmesa
);
432 if (!via_alloc_dma_buffer(vmesa
))
436 vmesa
->dmaCliprectAddr
= ~0;
441 FreeBuffer(struct via_context
*vmesa
)
443 if (vmesa
->front
.map
&& vmesa
->drawType
== GLX_PBUFFER_BIT
)
444 via_free_draw_buffer(vmesa
, &vmesa
->front
);
447 via_free_draw_buffer(vmesa
, &vmesa
->back
);
449 if (vmesa
->depth
.map
)
450 via_free_draw_buffer(vmesa
, &vmesa
->depth
);
452 if (vmesa
->breadcrumb
.map
)
453 via_free_draw_buffer(vmesa
, &vmesa
->breadcrumb
);
456 via_free_dma_buffer(vmesa
);
461 viaCreateContext(const __GLcontextModes
*visual
,
462 __DRIcontextPrivate
*driContextPriv
,
463 void *sharedContextPrivate
)
465 GLcontext
*ctx
, *shareCtx
;
466 struct via_context
*vmesa
;
467 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
468 viaScreenPrivate
*viaScreen
= (viaScreenPrivate
*)sPriv
->private;
469 drm_via_sarea_t
*saPriv
= (drm_via_sarea_t
*)
470 (((GLubyte
*)sPriv
->pSAREA
) + viaScreen
->sareaPrivOffset
);
471 struct dd_function_table functions
;
473 /* Allocate via context */
474 vmesa
= (struct via_context
*) CALLOC_STRUCT(via_context
);
479 /* Parse configuration files.
481 driParseConfigFiles (&vmesa
->optionCache
, &viaScreen
->optionCache
,
482 sPriv
->myNum
, "via");
484 /* pick back buffer */
485 vmesa
->hasBack
= visual
->doubleBufferMode
;
487 switch(visual
->depthBits
) {
489 vmesa
->hasDepth
= GL_FALSE
;
490 vmesa
->depthBits
= 0;
491 vmesa
->depth_max
= 1.0;
494 vmesa
->hasDepth
= GL_TRUE
;
495 vmesa
->depthBits
= visual
->depthBits
;
496 vmesa
->have_hw_stencil
= GL_FALSE
;
497 vmesa
->depth_max
= (GLfloat
)0xffff;
498 vmesa
->depth_clear_mask
= 0xf << 28;
499 vmesa
->ClearDepth
= 0xffff;
500 vmesa
->polygon_offset_scale
= 1.0 / vmesa
->depth_max
;
503 vmesa
->hasDepth
= GL_TRUE
;
504 vmesa
->depthBits
= visual
->depthBits
;
505 vmesa
->depth_max
= (GLfloat
) 0xffffff;
506 vmesa
->depth_clear_mask
= 0xe << 28;
507 vmesa
->ClearDepth
= 0xffffff00;
509 assert(visual
->haveStencilBuffer
);
510 assert(visual
->stencilBits
== 8);
512 vmesa
->have_hw_stencil
= GL_TRUE
;
513 vmesa
->stencilBits
= visual
->stencilBits
;
514 vmesa
->stencil_clear_mask
= 0x1 << 28;
515 vmesa
->polygon_offset_scale
= 2.0 / vmesa
->depth_max
;
518 vmesa
->hasDepth
= GL_TRUE
;
519 vmesa
->depthBits
= visual
->depthBits
;
520 assert(!visual
->haveStencilBuffer
);
521 vmesa
->have_hw_stencil
= GL_FALSE
;
522 vmesa
->depth_max
= (GLfloat
)0xffffffff;
523 vmesa
->depth_clear_mask
= 0xf << 28;
524 vmesa
->ClearDepth
= 0xffffffff;
525 vmesa
->polygon_offset_scale
= 2.0 / vmesa
->depth_max
;
532 make_empty_list(&vmesa
->freed_tex_buffers
);
533 make_empty_list(&vmesa
->tex_image_list
[VIA_MEM_VIDEO
]);
534 make_empty_list(&vmesa
->tex_image_list
[VIA_MEM_AGP
]);
535 make_empty_list(&vmesa
->tex_image_list
[VIA_MEM_SYSTEM
]);
537 _mesa_init_driver_functions(&functions
);
538 viaInitTextureFuncs(&functions
);
540 /* Allocate the Mesa context */
541 if (sharedContextPrivate
)
542 shareCtx
= ((struct via_context
*) sharedContextPrivate
)->glCtx
;
546 vmesa
->glCtx
= _mesa_create_context(visual
, shareCtx
, &functions
,
549 vmesa
->shareCtx
= shareCtx
;
555 driContextPriv
->driverPrivate
= vmesa
;
559 ctx
->Const
.MaxTextureLevels
= 10;
560 ctx
->Const
.MaxTextureUnits
= 2;
561 ctx
->Const
.MaxTextureImageUnits
= ctx
->Const
.MaxTextureUnits
;
562 ctx
->Const
.MaxTextureCoordUnits
= ctx
->Const
.MaxTextureUnits
;
564 ctx
->Const
.MinLineWidth
= 1.0;
565 ctx
->Const
.MinLineWidthAA
= 1.0;
566 ctx
->Const
.MaxLineWidth
= 1.0;
567 ctx
->Const
.MaxLineWidthAA
= 1.0;
568 ctx
->Const
.LineWidthGranularity
= 1.0;
570 ctx
->Const
.MinPointSize
= 1.0;
571 ctx
->Const
.MinPointSizeAA
= 1.0;
572 ctx
->Const
.MaxPointSize
= 1.0;
573 ctx
->Const
.MaxPointSizeAA
= 1.0;
574 ctx
->Const
.PointSizeGranularity
= 1.0;
576 ctx
->Driver
.GetBufferSize
= viaBufferSize
;
577 /* ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; *//* FIXME ?? */
578 ctx
->Driver
.GetString
= viaGetString
;
580 ctx
->DriverCtx
= (void *)vmesa
;
583 /* Initialize the software rasterizer and helper modules.
585 _swrast_CreateContext(ctx
);
586 _ac_CreateContext(ctx
);
587 _tnl_CreateContext(ctx
);
588 _swsetup_CreateContext(ctx
);
590 /* Install the customized pipeline:
592 _tnl_destroy_pipeline(ctx
);
593 _tnl_install_pipeline(ctx
, via_pipeline
);
595 /* Configure swrast and T&L to match hardware characteristics:
597 _swrast_allow_pixel_fog(ctx
, GL_FALSE
);
598 _swrast_allow_vertex_fog(ctx
, GL_TRUE
);
599 _tnl_allow_pixel_fog(ctx
, GL_FALSE
);
600 _tnl_allow_vertex_fog(ctx
, GL_TRUE
);
602 /* vmesa->display = dpy; */
603 vmesa
->display
= sPriv
->display
;
605 vmesa
->hHWContext
= driContextPriv
->hHWContext
;
606 vmesa
->driFd
= sPriv
->fd
;
607 vmesa
->driHwLock
= &sPriv
->pSAREA
->lock
;
609 vmesa
->viaScreen
= viaScreen
;
610 vmesa
->driScreen
= sPriv
;
611 vmesa
->sarea
= saPriv
;
613 vmesa
->renderIndex
= ~0;
614 vmesa
->setupIndex
= ~0;
615 vmesa
->hwPrimitive
= GL_POLYGON
+1;
617 /* KW: Hardwire this. Was previously set bogusly in
618 * viaCreateBuffer. Needs work before PBUFFER can be used:
620 vmesa
->drawType
= GLX_WINDOW_BIT
;
623 _math_matrix_ctr(&vmesa
->ViewportMatrix
);
625 /* Do this early, before VIA_FLUSH_DMA can be called:
627 if (!AllocateDmaBuffer(vmesa
)) {
628 fprintf(stderr
,"AllocateDmaBuffer fail\n");
634 /* Allocate a small piece of fb memory for synchronization:
636 vmesa
->breadcrumb
.bpp
= 32;
637 vmesa
->breadcrumb
.pitch
= buffer_align( 64 ) << 2;
638 vmesa
->breadcrumb
.size
= vmesa
->breadcrumb
.pitch
;
640 if (!via_alloc_draw_buffer(vmesa
, &vmesa
->breadcrumb
)) {
641 fprintf(stderr
,"AllocateDmaBuffer fail\n");
647 driInitExtensions( ctx
, card_extensions
, GL_TRUE
);
648 viaInitStateFuncs(ctx
);
649 viaInitTriFuncs(ctx
);
650 viaInitSpanFuncs(ctx
);
651 viaInitIoctlFuncs(ctx
);
654 if (getenv("VIA_DEBUG"))
655 VIA_DEBUG
= driParseDebugString( getenv( "VIA_DEBUG" ),
658 if (getenv("VIA_NO_RAST"))
659 FALLBACK(vmesa
, VIA_FALLBACK_USER_DISABLE
, 1);
661 /* I don't understand why this isn't working:
663 vmesa
->vblank_flags
=
664 vmesa
->viaScreen
->irqEnabled
?
665 driGetDefaultVBlankFlags(&vmesa
->optionCache
) : VBLANK_FLAG_NO_IRQ
;
667 /* Hack this up in its place:
669 vmesa
->vblank_flags
= (getenv("VIA_VSYNC") ?
670 VBLANK_FLAG_SYNC
: VBLANK_FLAG_NO_IRQ
);
672 if (getenv("VIA_PAGEFLIP"))
673 vmesa
->allowPageFlip
= 1;
675 (*dri_interface
->getUST
)( &vmesa
->swap_ust
);
678 vmesa
->regMMIOBase
= (GLuint
*)((GLuint
)viaScreen
->reg
);
679 vmesa
->pnGEMode
= (GLuint
*)((GLuint
)viaScreen
->reg
+ 0x4);
680 vmesa
->regEngineStatus
= (GLuint
*)((GLuint
)viaScreen
->reg
+ 0x400);
681 vmesa
->regTranSet
= (GLuint
*)((GLuint
)viaScreen
->reg
+ 0x43C);
682 vmesa
->regTranSpace
= (GLuint
*)((GLuint
)viaScreen
->reg
+ 0x440);
683 vmesa
->agpBase
= viaScreen
->agpBase
;
689 viaDestroyContext(__DRIcontextPrivate
*driContextPriv
)
691 GET_CURRENT_CONTEXT(ctx
);
692 struct via_context
*vmesa
=
693 (struct via_context
*)driContextPriv
->driverPrivate
;
694 struct via_context
*current
= ctx
? VIA_CONTEXT(ctx
) : NULL
;
695 assert(vmesa
); /* should never be null */
697 /* check if we're deleting the currently bound context */
698 if (vmesa
== current
) {
699 VIA_FLUSH_DMA(vmesa
);
700 _mesa_make_current(NULL
, NULL
, NULL
);
705 if (vmesa
->doPageFlip
) {
706 LOCK_HARDWARE(vmesa
);
707 if (vmesa
->pfCurrentOffset
!= 0) {
708 fprintf(stderr
, "%s - reset pf\n", __FUNCTION__
);
709 viaResetPageFlippingLocked(vmesa
);
711 UNLOCK_HARDWARE(vmesa
);
714 _swsetup_DestroyContext(vmesa
->glCtx
);
715 _tnl_DestroyContext(vmesa
->glCtx
);
716 _ac_DestroyContext(vmesa
->glCtx
);
717 _swrast_DestroyContext(vmesa
->glCtx
);
718 /* free the Mesa context */
719 _mesa_destroy_context(vmesa
->glCtx
);
720 /* release our data */
723 assert (is_empty_list(&vmesa
->tex_image_list
[VIA_MEM_AGP
]));
724 assert (is_empty_list(&vmesa
->tex_image_list
[VIA_MEM_VIDEO
]));
725 assert (is_empty_list(&vmesa
->tex_image_list
[VIA_MEM_SYSTEM
]));
726 assert (is_empty_list(&vmesa
->freed_tex_buffers
));
733 void viaXMesaWindowMoved(struct via_context
*vmesa
)
735 __DRIdrawablePrivate
*dPriv
= vmesa
->driDrawable
;
736 GLuint bytePerPixel
= vmesa
->viaScreen
->bitsPerPixel
>> 3;
741 switch (vmesa
->glCtx
->DrawBuffer
->_ColorDrawBufferMask
[0]) {
742 case BUFFER_BIT_BACK_LEFT
:
743 if (dPriv
->numBackClipRects
== 0) {
744 vmesa
->numClipRects
= dPriv
->numClipRects
;
745 vmesa
->pClipRects
= dPriv
->pClipRects
;
748 vmesa
->numClipRects
= dPriv
->numBackClipRects
;
749 vmesa
->pClipRects
= dPriv
->pBackClipRects
;
752 case BUFFER_BIT_FRONT_LEFT
:
753 vmesa
->numClipRects
= dPriv
->numClipRects
;
754 vmesa
->pClipRects
= dPriv
->pClipRects
;
757 vmesa
->numClipRects
= 0;
761 if (vmesa
->drawW
!= dPriv
->w
||
762 vmesa
->drawH
!= dPriv
->h
)
763 calculate_buffer_parameters( vmesa
, vmesa
->glCtx
->DrawBuffer
);
765 vmesa
->drawXoff
= (GLuint
)(((dPriv
->x
* bytePerPixel
) & 0x1f) /
767 vmesa
->drawX
= dPriv
->x
- vmesa
->drawXoff
;
768 vmesa
->drawY
= dPriv
->y
;
769 vmesa
->drawW
= dPriv
->w
;
770 vmesa
->drawH
= dPriv
->h
;
772 vmesa
->front
.orig
= (vmesa
->front
.offset
+
773 vmesa
->drawY
* vmesa
->front
.pitch
+
774 vmesa
->drawX
* bytePerPixel
);
776 vmesa
->front
.origMap
= (vmesa
->front
.map
+
777 vmesa
->drawY
* vmesa
->front
.pitch
+
778 vmesa
->drawX
* bytePerPixel
);
780 vmesa
->back
.orig
= vmesa
->back
.offset
;
781 vmesa
->depth
.orig
= vmesa
->depth
.offset
;
782 vmesa
->back
.origMap
= vmesa
->back
.map
;
783 vmesa
->depth
.origMap
= vmesa
->depth
.map
;
785 viaCalcViewport(vmesa
->glCtx
);
789 viaUnbindContext(__DRIcontextPrivate
*driContextPriv
)
795 viaMakeCurrent(__DRIcontextPrivate
*driContextPriv
,
796 __DRIdrawablePrivate
*driDrawPriv
,
797 __DRIdrawablePrivate
*driReadPriv
)
799 if (VIA_DEBUG
& DEBUG_DRI
) {
800 fprintf(stderr
, "driContextPriv = %08x\n", (GLuint
)driContextPriv
);
801 fprintf(stderr
, "driDrawPriv = %08x\n", (GLuint
)driDrawPriv
);
802 fprintf(stderr
, "driReadPriv = %08x\n", (GLuint
)driReadPriv
);
805 if (driContextPriv
) {
806 struct via_context
*vmesa
=
807 (struct via_context
*)driContextPriv
->driverPrivate
;
808 GLcontext
*ctx
= vmesa
->glCtx
;
809 struct gl_framebuffer
*drawBuffer
, *readBuffer
;
811 drawBuffer
= (GLframebuffer
*)driDrawPriv
->driverPrivate
;
812 readBuffer
= (GLframebuffer
*)driReadPriv
->driverPrivate
;
814 if ( vmesa
->driDrawable
!= driDrawPriv
) {
815 driDrawableInitVBlank( driDrawPriv
, vmesa
->vblank_flags
);
816 vmesa
->driDrawable
= driDrawPriv
;
817 if ( ! calculate_buffer_parameters( vmesa
, drawBuffer
) ) {
822 _mesa_make_current(vmesa
->glCtx
, drawBuffer
, readBuffer
);
824 ctx
->Driver
.DrawBuffer( ctx
, ctx
->Color
.DrawBuffer
[0] );
826 viaXMesaWindowMoved(vmesa
);
827 ctx
->Driver
.Scissor(vmesa
->glCtx
,
828 vmesa
->glCtx
->Scissor
.X
,
829 vmesa
->glCtx
->Scissor
.Y
,
830 vmesa
->glCtx
->Scissor
.Width
,
831 vmesa
->glCtx
->Scissor
.Height
);
834 _mesa_make_current(NULL
, NULL
, NULL
);
840 void viaGetLock(struct via_context
*vmesa
, GLuint flags
)
842 __DRIdrawablePrivate
*dPriv
= vmesa
->driDrawable
;
843 __DRIscreenPrivate
*sPriv
= vmesa
->driScreen
;
845 drmGetLock(vmesa
->driFd
, vmesa
->hHWContext
, flags
);
847 DRI_VALIDATE_DRAWABLE_INFO( sPriv
, dPriv
);
849 if (vmesa
->sarea
->ctxOwner
!= vmesa
->hHWContext
) {
850 vmesa
->sarea
->ctxOwner
= vmesa
->hHWContext
;
851 vmesa
->newEmitState
= ~0;
854 if (vmesa
->lastStamp
!= dPriv
->lastStamp
) {
855 viaXMesaWindowMoved(vmesa
);
856 driUpdateFramebufferSize(vmesa
->glCtx
, dPriv
);
857 vmesa
->newEmitState
= ~0;
858 vmesa
->lastStamp
= dPriv
->lastStamp
;
861 if (vmesa
->doPageFlip
&&
862 vmesa
->pfCurrentOffset
!= vmesa
->sarea
->pfCurrentOffset
) {
863 fprintf(stderr
, "%s - reset pf\n", __FUNCTION__
);
864 viaResetPageFlippingLocked(vmesa
);
870 viaSwapBuffers(__DRIdrawablePrivate
*drawablePrivate
)
872 __DRIdrawablePrivate
*dPriv
= (__DRIdrawablePrivate
*)drawablePrivate
;
875 dPriv
->driContextPriv
&&
876 dPriv
->driContextPriv
->driverPrivate
) {
877 struct via_context
*vmesa
=
878 (struct via_context
*)dPriv
->driContextPriv
->driverPrivate
;
879 GLcontext
*ctx
= vmesa
->glCtx
;
881 _mesa_notifySwapBuffers(ctx
);
883 if (ctx
->Visual
.doubleBufferMode
) {
884 if (vmesa
->doPageFlip
) {
888 viaCopyBuffer(dPriv
);
892 VIA_FLUSH_DMA(vmesa
);
895 _mesa_problem(NULL
, "viaSwapBuffers: drawable has no context!\n");