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?
33 #include "main/glheader.h"
34 #include "main/context.h"
35 #include "main/formats.h"
36 #include "main/simple_list.h"
37 #include "main/framebuffer.h"
38 #include "main/renderbuffer.h"
40 #include "swrast/swrast.h"
41 #include "swrast_setup/swrast_setup.h"
45 #include "tnl/t_pipeline.h"
47 #include "drivers/common/driverfuncs.h"
49 #include "via_screen.h"
52 #include "via_state.h"
56 #include "via_ioctl.h"
60 #include "main/macros.h"
61 #include "drirenderbuffer.h"
63 #define need_GL_ARB_point_parameters
64 #define need_GL_EXT_fog_coord
65 #define need_GL_EXT_secondary_color
66 #include "main/remap_helper.h"
74 * Return various strings for \c glGetString.
78 static const GLubyte
*viaGetString(struct gl_context
*ctx
, GLenum name
)
80 static char buffer
[128];
86 return (GLubyte
*)"VIA Technology";
89 static const char * const chipset_names
[] = {
91 "CastleRock (CLE266)",
94 "UniChrome (PM8x0/CN400)",
96 struct via_context
*vmesa
= VIA_CONTEXT(ctx
);
97 unsigned id
= vmesa
->viaScreen
->deviceID
;
99 offset
= driGetRendererString( buffer
,
100 chipset_names
[(id
> VIA_PM800
) ? 0 : id
],
102 return (GLubyte
*)buffer
;
112 * Calculate a width that satisfies the hardware's alignment requirements.
113 * On the Unichrome hardware, each scanline must be aligned to a multiple of
116 * \param width Minimum buffer width, in pixels.
118 * \returns A pixel width that meets the alignment requirements.
120 static INLINE
unsigned
121 buffer_align( unsigned width
)
123 return (width
+ 0x0f) & ~0x0f;
128 viaDeleteRenderbuffer(struct gl_renderbuffer
*rb
)
130 /* Don't free() since we're contained in via_context struct. */
134 viaRenderbufferStorage(struct gl_context
*ctx
, struct gl_renderbuffer
*rb
,
135 GLenum internalFormat
, GLuint width
, GLuint height
)
139 rb
->InternalFormat
= internalFormat
;
145 viaInitRenderbuffer(struct via_renderbuffer
*vrb
, GLenum format
,
146 __DRIdrawable
*dPriv
)
148 const GLuint name
= 0;
149 struct gl_renderbuffer
*rb
= & vrb
->Base
;
152 _mesa_init_renderbuffer(rb
, name
);
154 /* Make sure we're using a null-valued GetPointer routine */
155 assert(rb
->GetPointer(NULL
, rb
, 0, 0) == NULL
);
157 rb
->InternalFormat
= format
;
159 if (format
== GL_RGBA
) {
161 rb
->_BaseFormat
= GL_RGBA
;
162 rb
->Format
= MESA_FORMAT_ARGB8888
;
163 rb
->DataType
= GL_UNSIGNED_BYTE
;
165 else if (format
== GL_DEPTH_COMPONENT16
) {
167 rb
->_BaseFormat
= GL_DEPTH_COMPONENT
;
168 /* we always Get/Put 32-bit Z values */
169 rb
->Format
= MESA_FORMAT_Z16
;
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
->Format
= MESA_FORMAT_Z32
;
177 rb
->DataType
= GL_UNSIGNED_INT
;
181 ASSERT(format
== GL_STENCIL_INDEX8_EXT
);
182 rb
->_BaseFormat
= GL_STENCIL_INDEX
;
183 rb
->Format
= MESA_FORMAT_S8
;
184 rb
->DataType
= GL_UNSIGNED_BYTE
;
187 rb
->Delete
= viaDeleteRenderbuffer
;
188 rb
->AllocStorage
= viaRenderbufferStorage
;
193 * Calculate the framebuffer parameters for all buffers (front, back, depth,
194 * and stencil) associated with the specified context.
197 * This function also calls \c AllocateBuffer to actually allocate the
203 calculate_buffer_parameters(struct via_context
*vmesa
,
204 struct gl_framebuffer
*fb
,
205 __DRIdrawable
*dPriv
)
207 const unsigned shift
= vmesa
->viaScreen
->bitsPerPixel
/ 16;
208 const unsigned extra
= 32;
212 /* Normally, the renderbuffer would be added to the framebuffer just once
213 * when the framebuffer was created. The VIA driver is a bit funny
214 * though in that the front/back/depth renderbuffers are in the per-context
216 * That should be fixed someday.
219 if (!vmesa
->front
.Base
.InternalFormat
) {
220 /* do one-time init for the renderbuffers */
221 viaInitRenderbuffer(&vmesa
->front
, GL_RGBA
, dPriv
);
222 viaSetSpanFunctions(&vmesa
->front
, &fb
->Visual
);
223 _mesa_add_renderbuffer(fb
, BUFFER_FRONT_LEFT
, &vmesa
->front
.Base
);
225 if (fb
->Visual
.doubleBufferMode
) {
226 viaInitRenderbuffer(&vmesa
->back
, GL_RGBA
, dPriv
);
227 viaSetSpanFunctions(&vmesa
->back
, &fb
->Visual
);
228 _mesa_add_renderbuffer(fb
, BUFFER_BACK_LEFT
, &vmesa
->back
.Base
);
231 if (vmesa
->glCtx
->Visual
.depthBits
> 0) {
232 viaInitRenderbuffer(&vmesa
->depth
,
233 (vmesa
->glCtx
->Visual
.depthBits
== 16
234 ? GL_DEPTH_COMPONENT16
: GL_DEPTH_COMPONENT24
),
236 viaSetSpanFunctions(&vmesa
->depth
, &fb
->Visual
);
237 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, &vmesa
->depth
.Base
);
240 if (vmesa
->glCtx
->Visual
.stencilBits
> 0) {
241 viaInitRenderbuffer(&vmesa
->stencil
, GL_STENCIL_INDEX8_EXT
,
243 viaSetSpanFunctions(&vmesa
->stencil
, &fb
->Visual
);
244 _mesa_add_renderbuffer(fb
, BUFFER_STENCIL
, &vmesa
->stencil
.Base
);
248 assert(vmesa
->front
.Base
.InternalFormat
);
249 assert(vmesa
->front
.Base
.AllocStorage
);
250 if (fb
->Visual
.doubleBufferMode
) {
251 assert(vmesa
->back
.Base
.AllocStorage
);
253 if (fb
->Visual
.depthBits
) {
254 assert(vmesa
->depth
.Base
.AllocStorage
);
258 /* Allocate front-buffer */
259 if (vmesa
->drawType
== GLX_PBUFFER_BIT
) {
260 w
= vmesa
->driDrawable
->w
;
261 h
= vmesa
->driDrawable
->h
;
263 vmesa
->front
.bpp
= vmesa
->viaScreen
->bitsPerPixel
;
264 vmesa
->front
.pitch
= buffer_align( w
) << shift
; /* bytes, not pixels */
265 vmesa
->front
.size
= vmesa
->front
.pitch
* h
;
267 if (vmesa
->front
.map
)
268 via_free_draw_buffer(vmesa
, &vmesa
->front
);
269 if (!via_alloc_draw_buffer(vmesa
, &vmesa
->front
))
273 w
= vmesa
->viaScreen
->width
;
274 h
= vmesa
->viaScreen
->height
;
276 vmesa
->front
.bpp
= vmesa
->viaScreen
->bitsPerPixel
;
277 vmesa
->front
.pitch
= buffer_align( w
) << shift
; /* bytes, not pixels */
278 vmesa
->front
.size
= vmesa
->front
.pitch
* h
;
279 if (getenv("ALTERNATE_SCREEN"))
280 vmesa
->front
.offset
= vmesa
->front
.size
;
282 vmesa
->front
.offset
= 0;
283 vmesa
->front
.map
= (char *) vmesa
->driScreen
->pFB
;
287 /* Allocate back-buffer */
288 if (vmesa
->hasBack
) {
289 vmesa
->back
.bpp
= vmesa
->viaScreen
->bitsPerPixel
;
290 vmesa
->back
.pitch
= (buffer_align( vmesa
->driDrawable
->w
) << shift
);
291 vmesa
->back
.pitch
+= extra
;
292 vmesa
->back
.pitch
= MIN2(vmesa
->back
.pitch
, vmesa
->front
.pitch
);
293 vmesa
->back
.size
= vmesa
->back
.pitch
* vmesa
->driDrawable
->h
;
295 via_free_draw_buffer(vmesa
, &vmesa
->back
);
296 if (!via_alloc_draw_buffer(vmesa
, &vmesa
->back
))
301 via_free_draw_buffer(vmesa
, &vmesa
->back
);
302 (void) memset( &vmesa
->back
, 0, sizeof( vmesa
->back
) );
306 /* Allocate depth-buffer */
307 if ( vmesa
->hasStencil
|| vmesa
->hasDepth
) {
308 vmesa
->depth
.bpp
= vmesa
->depthBits
;
309 if (vmesa
->depth
.bpp
== 24)
310 vmesa
->depth
.bpp
= 32;
312 vmesa
->depth
.pitch
= (buffer_align( vmesa
->driDrawable
->w
) *
313 (vmesa
->depth
.bpp
/8)) + extra
;
314 vmesa
->depth
.size
= vmesa
->depth
.pitch
* vmesa
->driDrawable
->h
;
316 if (vmesa
->depth
.map
)
317 via_free_draw_buffer(vmesa
, &vmesa
->depth
);
318 if (!via_alloc_draw_buffer(vmesa
, &vmesa
->depth
)) {
323 if (vmesa
->depth
.map
)
324 via_free_draw_buffer(vmesa
, &vmesa
->depth
);
325 (void) memset( & vmesa
->depth
, 0, sizeof( vmesa
->depth
) );
328 /* stencil buffer is same as depth buffer */
329 vmesa
->stencil
.handle
= vmesa
->depth
.handle
;
330 vmesa
->stencil
.size
= vmesa
->depth
.size
;
331 vmesa
->stencil
.offset
= vmesa
->depth
.offset
;
332 vmesa
->stencil
.index
= vmesa
->depth
.index
;
333 vmesa
->stencil
.pitch
= vmesa
->depth
.pitch
;
334 vmesa
->stencil
.bpp
= vmesa
->depth
.bpp
;
335 vmesa
->stencil
.map
= vmesa
->depth
.map
;
336 vmesa
->stencil
.orig
= vmesa
->depth
.orig
;
337 vmesa
->stencil
.origMap
= vmesa
->depth
.origMap
;
339 if( vmesa
->viaScreen
->width
== vmesa
->driDrawable
->w
&&
340 vmesa
->viaScreen
->height
== vmesa
->driDrawable
->h
) {
341 vmesa
->doPageFlip
= vmesa
->allowPageFlip
;
342 if (vmesa
->hasBack
) {
343 assert(vmesa
->back
.pitch
== vmesa
->front
.pitch
);
347 vmesa
->doPageFlip
= GL_FALSE
;
353 void viaReAllocateBuffers(struct gl_context
*ctx
, struct gl_framebuffer
*drawbuffer
,
354 GLuint width
, GLuint height
)
356 struct via_context
*vmesa
= VIA_CONTEXT(ctx
);
358 calculate_buffer_parameters(vmesa
, drawbuffer
, vmesa
->driDrawable
);
360 _mesa_resize_framebuffer(ctx
, drawbuffer
, width
, height
);
363 /* Extension strings exported by the Unichrome driver.
365 static const struct dri_extension card_extensions
[] =
367 { "GL_ARB_multitexture", NULL
},
368 { "GL_ARB_point_parameters", GL_ARB_point_parameters_functions
},
369 { "GL_ARB_texture_env_add", NULL
},
370 { "GL_ARB_texture_env_combine", NULL
},
371 /* { "GL_ARB_texture_env_dot3", NULL }, */
372 { "GL_ARB_texture_mirrored_repeat", NULL
},
373 { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions
},
374 { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions
},
375 { "GL_EXT_stencil_wrap", NULL
},
376 { "GL_EXT_texture_env_combine", NULL
},
377 /* { "GL_EXT_texture_env_dot3", NULL }, */
378 { "GL_EXT_texture_lod_bias", NULL
},
379 { "GL_NV_blend_square", NULL
},
383 extern const struct tnl_pipeline_stage _via_fastrender_stage
;
384 extern const struct tnl_pipeline_stage _via_render_stage
;
386 static const struct tnl_pipeline_stage
*via_pipeline
[] = {
387 &_tnl_vertex_transform_stage
,
388 &_tnl_normal_transform_stage
,
389 &_tnl_lighting_stage
,
390 &_tnl_fog_coordinate_stage
,
392 &_tnl_texture_transform_stage
,
393 /* REMOVE: point attenuation stage */
395 &_via_fastrender_stage
, /* ADD: unclipped rastersetup-to-dma */
402 static const struct dri_debug_control debug_control
[] =
404 { "fall", DEBUG_FALLBACKS
},
405 { "tex", DEBUG_TEXTURE
},
406 { "ioctl", DEBUG_IOCTL
},
407 { "prim", DEBUG_PRIMS
},
408 { "vert", DEBUG_VERTS
},
409 { "state", DEBUG_STATE
},
410 { "verb", DEBUG_VERBOSE
},
411 { "dri", DEBUG_DRI
},
412 { "dma", DEBUG_DMA
},
413 { "san", DEBUG_SANITY
},
414 { "sync", DEBUG_SYNC
},
415 { "sleep", DEBUG_SLEEP
},
416 { "pix", DEBUG_PIXEL
},
423 AllocateDmaBuffer(struct via_context
*vmesa
)
426 via_free_dma_buffer(vmesa
);
428 if (!via_alloc_dma_buffer(vmesa
))
432 vmesa
->dmaCliprectAddr
= ~0;
437 FreeBuffer(struct via_context
*vmesa
)
439 if (vmesa
->front
.map
&& vmesa
->drawType
== GLX_PBUFFER_BIT
)
440 via_free_draw_buffer(vmesa
, &vmesa
->front
);
443 via_free_draw_buffer(vmesa
, &vmesa
->back
);
445 if (vmesa
->depth
.map
)
446 via_free_draw_buffer(vmesa
, &vmesa
->depth
);
448 if (vmesa
->breadcrumb
.map
)
449 via_free_draw_buffer(vmesa
, &vmesa
->breadcrumb
);
452 via_free_dma_buffer(vmesa
);
457 viaCreateContext(gl_api api
,
458 const struct gl_config
*visual
,
459 __DRIcontext
*driContextPriv
,
460 void *sharedContextPrivate
)
462 struct gl_context
*ctx
, *shareCtx
;
463 struct via_context
*vmesa
;
464 __DRIscreen
*sPriv
= driContextPriv
->driScreenPriv
;
465 viaScreenPrivate
*viaScreen
= (viaScreenPrivate
*)sPriv
->private;
466 drm_via_sarea_t
*saPriv
= (drm_via_sarea_t
*)
467 (((GLubyte
*)sPriv
->pSAREA
) + viaScreen
->sareaPrivOffset
);
468 struct dd_function_table functions
;
470 /* Allocate via context */
471 vmesa
= (struct via_context
*) CALLOC_STRUCT(via_context
);
476 /* Parse configuration files.
478 driParseConfigFiles (&vmesa
->optionCache
, &viaScreen
->optionCache
,
479 sPriv
->myNum
, "unichrome");
481 /* pick back buffer */
482 vmesa
->hasBack
= visual
->doubleBufferMode
;
484 switch(visual
->depthBits
) {
486 vmesa
->hasDepth
= GL_FALSE
;
487 vmesa
->depthBits
= 0;
488 vmesa
->depth_max
= 1.0;
491 vmesa
->hasDepth
= GL_TRUE
;
492 vmesa
->depthBits
= visual
->depthBits
;
493 vmesa
->have_hw_stencil
= GL_FALSE
;
494 vmesa
->depth_max
= (GLfloat
)0xffff;
495 vmesa
->depth_clear_mask
= 0xf << 28;
496 vmesa
->ClearDepth
= 0xffff;
497 vmesa
->polygon_offset_scale
= 1.0 / vmesa
->depth_max
;
500 vmesa
->hasDepth
= GL_TRUE
;
501 vmesa
->depthBits
= visual
->depthBits
;
502 vmesa
->depth_max
= (GLfloat
) 0xffffff;
503 vmesa
->depth_clear_mask
= 0xe << 28;
504 vmesa
->ClearDepth
= 0xffffff00;
506 assert(visual
->haveStencilBuffer
);
507 assert(visual
->stencilBits
== 8);
509 vmesa
->have_hw_stencil
= GL_TRUE
;
510 vmesa
->stencilBits
= visual
->stencilBits
;
511 vmesa
->stencil_clear_mask
= 0x1 << 28;
512 vmesa
->polygon_offset_scale
= 2.0 / vmesa
->depth_max
;
515 vmesa
->hasDepth
= GL_TRUE
;
516 vmesa
->depthBits
= visual
->depthBits
;
517 assert(!visual
->haveStencilBuffer
);
518 vmesa
->have_hw_stencil
= GL_FALSE
;
519 vmesa
->depth_max
= (GLfloat
)0xffffffff;
520 vmesa
->depth_clear_mask
= 0xf << 28;
521 vmesa
->ClearDepth
= 0xffffffff;
522 vmesa
->polygon_offset_scale
= 2.0 / vmesa
->depth_max
;
529 make_empty_list(&vmesa
->freed_tex_buffers
);
530 make_empty_list(&vmesa
->tex_image_list
[VIA_MEM_VIDEO
]);
531 make_empty_list(&vmesa
->tex_image_list
[VIA_MEM_AGP
]);
532 make_empty_list(&vmesa
->tex_image_list
[VIA_MEM_SYSTEM
]);
534 _mesa_init_driver_functions(&functions
);
535 viaInitTextureFuncs(&functions
);
537 /* Allocate the Mesa context */
538 if (sharedContextPrivate
)
539 shareCtx
= ((struct via_context
*) sharedContextPrivate
)->glCtx
;
543 vmesa
->glCtx
= _mesa_create_context(API_OPENGL
, visual
, shareCtx
, &functions
,
546 vmesa
->shareCtx
= shareCtx
;
552 driContextPriv
->driverPrivate
= vmesa
;
556 if (driQueryOptionb(&vmesa
->optionCache
, "excess_mipmap"))
557 ctx
->Const
.MaxTextureLevels
= 11;
559 ctx
->Const
.MaxTextureLevels
= 10;
561 ctx
->Const
.MaxTextureUnits
= 2;
562 ctx
->Const
.MaxTextureImageUnits
= ctx
->Const
.MaxTextureUnits
;
563 ctx
->Const
.MaxTextureCoordUnits
= ctx
->Const
.MaxTextureUnits
;
565 ctx
->Const
.MinLineWidth
= 1.0;
566 ctx
->Const
.MinLineWidthAA
= 1.0;
567 ctx
->Const
.MaxLineWidth
= 1.0;
568 ctx
->Const
.MaxLineWidthAA
= 1.0;
569 ctx
->Const
.LineWidthGranularity
= 1.0;
571 ctx
->Const
.MinPointSize
= 1.0;
572 ctx
->Const
.MinPointSizeAA
= 1.0;
573 ctx
->Const
.MaxPointSize
= 1.0;
574 ctx
->Const
.MaxPointSizeAA
= 1.0;
575 ctx
->Const
.PointSizeGranularity
= 1.0;
577 ctx
->Const
.MaxDrawBuffers
= 1;
579 ctx
->Driver
.GetString
= viaGetString
;
581 ctx
->DriverCtx
= (void *)vmesa
;
584 /* Initialize the software rasterizer and helper modules.
586 _swrast_CreateContext(ctx
);
587 _vbo_CreateContext(ctx
);
588 _tnl_CreateContext(ctx
);
589 _swsetup_CreateContext(ctx
);
591 /* Install the customized pipeline:
593 _tnl_destroy_pipeline(ctx
);
594 _tnl_install_pipeline(ctx
, via_pipeline
);
596 /* Configure swrast and T&L to match hardware characteristics:
598 _swrast_allow_pixel_fog(ctx
, GL_FALSE
);
599 _swrast_allow_vertex_fog(ctx
, GL_TRUE
);
600 _tnl_allow_pixel_fog(ctx
, GL_FALSE
);
601 _tnl_allow_vertex_fog(ctx
, GL_TRUE
);
603 vmesa
->hHWContext
= driContextPriv
->hHWContext
;
604 vmesa
->driFd
= sPriv
->fd
;
605 vmesa
->driHwLock
= &sPriv
->pSAREA
->lock
;
607 vmesa
->viaScreen
= viaScreen
;
608 vmesa
->driScreen
= sPriv
;
609 vmesa
->sarea
= saPriv
;
611 vmesa
->renderIndex
= ~0;
612 vmesa
->setupIndex
= ~0;
613 vmesa
->hwPrimitive
= GL_POLYGON
+1;
615 /* KW: Hardwire this. Was previously set bogusly in
616 * viaCreateBuffer. Needs work before PBUFFER can be used:
618 vmesa
->drawType
= GLX_WINDOW_BIT
;
621 _math_matrix_ctr(&vmesa
->ViewportMatrix
);
623 /* Do this early, before VIA_FLUSH_DMA can be called:
625 if (!AllocateDmaBuffer(vmesa
)) {
626 fprintf(stderr
,"AllocateDmaBuffer fail\n");
632 /* Allocate a small piece of fb memory for synchronization:
634 vmesa
->breadcrumb
.bpp
= 32;
635 vmesa
->breadcrumb
.pitch
= buffer_align( 64 ) << 2;
636 vmesa
->breadcrumb
.size
= vmesa
->breadcrumb
.pitch
;
638 if (!via_alloc_draw_buffer(vmesa
, &vmesa
->breadcrumb
)) {
639 fprintf(stderr
,"AllocateDmaBuffer fail\n");
645 driInitExtensions( ctx
, card_extensions
, GL_TRUE
);
646 viaInitStateFuncs(ctx
);
647 viaInitTriFuncs(ctx
);
648 viaInitSpanFuncs(ctx
);
649 viaInitIoctlFuncs(ctx
);
652 if (getenv("VIA_DEBUG"))
653 VIA_DEBUG
= driParseDebugString( getenv( "VIA_DEBUG" ),
656 if (getenv("VIA_NO_RAST") ||
657 driQueryOptionb(&vmesa
->optionCache
, "no_rast"))
658 FALLBACK(vmesa
, VIA_FALLBACK_USER_DISABLE
, 1);
660 if (getenv("VIA_PAGEFLIP"))
661 vmesa
->allowPageFlip
= 1;
663 (*sPriv
->systemTime
->getUST
)( &vmesa
->swap_ust
);
666 vmesa
->regMMIOBase
= (GLuint
*)((unsigned long)viaScreen
->reg
);
667 vmesa
->pnGEMode
= (GLuint
*)((unsigned long)viaScreen
->reg
+ 0x4);
668 vmesa
->regEngineStatus
= (GLuint
*)((unsigned long)viaScreen
->reg
+ 0x400);
669 vmesa
->regTranSet
= (GLuint
*)((unsigned long)viaScreen
->reg
+ 0x43C);
670 vmesa
->regTranSpace
= (GLuint
*)((unsigned long)viaScreen
->reg
+ 0x440);
671 vmesa
->agpBase
= viaScreen
->agpBase
;
678 viaDestroyContext(__DRIcontext
*driContextPriv
)
680 GET_CURRENT_CONTEXT(ctx
);
681 struct via_context
*vmesa
=
682 (struct via_context
*)driContextPriv
->driverPrivate
;
683 struct via_context
*current
= ctx
? VIA_CONTEXT(ctx
) : NULL
;
685 assert(vmesa
); /* should never be null */
687 if (vmesa
->driDrawable
) {
688 viaWaitIdle(vmesa
, GL_FALSE
);
690 if (vmesa
->doPageFlip
) {
691 LOCK_HARDWARE(vmesa
);
692 if (vmesa
->pfCurrentOffset
!= 0) {
693 fprintf(stderr
, "%s - reset pf\n", __FUNCTION__
);
694 viaResetPageFlippingLocked(vmesa
);
696 UNLOCK_HARDWARE(vmesa
);
700 /* check if we're deleting the currently bound context */
701 if (vmesa
== current
) {
702 VIA_FLUSH_DMA(vmesa
);
703 _mesa_make_current(NULL
, NULL
, NULL
);
706 _swsetup_DestroyContext(vmesa
->glCtx
);
707 _tnl_DestroyContext(vmesa
->glCtx
);
708 _vbo_DestroyContext(vmesa
->glCtx
);
709 _swrast_DestroyContext(vmesa
->glCtx
);
710 /* free the Mesa context */
711 _mesa_destroy_context(vmesa
->glCtx
);
712 /* release our data */
715 assert (is_empty_list(&vmesa
->tex_image_list
[VIA_MEM_AGP
]));
716 assert (is_empty_list(&vmesa
->tex_image_list
[VIA_MEM_VIDEO
]));
717 assert (is_empty_list(&vmesa
->tex_image_list
[VIA_MEM_SYSTEM
]));
718 assert (is_empty_list(&vmesa
->freed_tex_buffers
));
720 driDestroyOptionCache(&vmesa
->optionCache
);
726 void viaXMesaWindowMoved(struct via_context
*vmesa
)
728 __DRIdrawable
*const drawable
= vmesa
->driDrawable
;
729 __DRIdrawable
*const readable
= vmesa
->driReadable
;
730 struct via_renderbuffer
* draw_buffer
;
731 struct via_renderbuffer
* read_buffer
;
732 GLuint bytePerPixel
= vmesa
->viaScreen
->bitsPerPixel
>> 3;
737 draw_buffer
= (struct via_renderbuffer
*) drawable
->driverPrivate
;
738 read_buffer
= (struct via_renderbuffer
*) readable
->driverPrivate
;
740 switch (vmesa
->glCtx
->DrawBuffer
->_ColorDrawBufferIndexes
[0]) {
741 case BUFFER_BACK_LEFT
:
742 if (drawable
->numBackClipRects
== 0) {
743 vmesa
->numClipRects
= drawable
->numClipRects
;
744 vmesa
->pClipRects
= drawable
->pClipRects
;
747 vmesa
->numClipRects
= drawable
->numBackClipRects
;
748 vmesa
->pClipRects
= drawable
->pBackClipRects
;
751 case BUFFER_FRONT_LEFT
:
752 vmesa
->numClipRects
= drawable
->numClipRects
;
753 vmesa
->pClipRects
= drawable
->pClipRects
;
756 vmesa
->numClipRects
= 0;
760 if ((draw_buffer
->drawW
!= drawable
->w
)
761 || (draw_buffer
->drawH
!= drawable
->h
)) {
762 calculate_buffer_parameters(vmesa
, vmesa
->glCtx
->DrawBuffer
,
766 draw_buffer
->drawX
= drawable
->x
;
767 draw_buffer
->drawY
= drawable
->y
;
768 draw_buffer
->drawW
= drawable
->w
;
769 draw_buffer
->drawH
= drawable
->h
;
771 if (drawable
!= readable
) {
772 if ((read_buffer
->drawW
!= readable
->w
)
773 || (read_buffer
->drawH
!= readable
->h
)) {
774 calculate_buffer_parameters(vmesa
, vmesa
->glCtx
->ReadBuffer
,
778 read_buffer
->drawX
= readable
->x
;
779 read_buffer
->drawY
= readable
->y
;
780 read_buffer
->drawW
= readable
->w
;
781 read_buffer
->drawH
= readable
->h
;
784 vmesa
->front
.orig
= (vmesa
->front
.offset
+
785 draw_buffer
->drawY
* vmesa
->front
.pitch
+
786 draw_buffer
->drawX
* bytePerPixel
);
788 vmesa
->front
.origMap
= (vmesa
->front
.map
+
789 draw_buffer
->drawY
* vmesa
->front
.pitch
+
790 draw_buffer
->drawX
* bytePerPixel
);
792 vmesa
->back
.orig
= (vmesa
->back
.offset
+
793 draw_buffer
->drawY
* vmesa
->back
.pitch
+
794 draw_buffer
->drawX
* bytePerPixel
);
796 vmesa
->back
.origMap
= (vmesa
->back
.map
+
797 draw_buffer
->drawY
* vmesa
->back
.pitch
+
798 draw_buffer
->drawX
* bytePerPixel
);
800 vmesa
->depth
.orig
= (vmesa
->depth
.offset
+
801 draw_buffer
->drawY
* vmesa
->depth
.pitch
+
802 draw_buffer
->drawX
* bytePerPixel
);
804 vmesa
->depth
.origMap
= (vmesa
->depth
.map
+
805 draw_buffer
->drawY
* vmesa
->depth
.pitch
+
806 draw_buffer
->drawX
* bytePerPixel
);
808 viaCalcViewport(vmesa
->glCtx
);
812 viaUnbindContext(__DRIcontext
*driContextPriv
)
818 viaMakeCurrent(__DRIcontext
*driContextPriv
,
819 __DRIdrawable
*driDrawPriv
,
820 __DRIdrawable
*driReadPriv
)
822 if (VIA_DEBUG
& DEBUG_DRI
) {
823 fprintf(stderr
, "driContextPriv = %016lx\n", (unsigned long)driContextPriv
);
824 fprintf(stderr
, "driDrawPriv = %016lx\n", (unsigned long)driDrawPriv
);
825 fprintf(stderr
, "driReadPriv = %016lx\n", (unsigned long)driReadPriv
);
828 if (driContextPriv
) {
829 struct via_context
*vmesa
=
830 (struct via_context
*)driContextPriv
->driverPrivate
;
831 struct gl_context
*ctx
= vmesa
->glCtx
;
832 struct gl_framebuffer
*drawBuffer
, *readBuffer
;
834 drawBuffer
= (struct gl_framebuffer
*)driDrawPriv
->driverPrivate
;
835 readBuffer
= (struct gl_framebuffer
*)driReadPriv
->driverPrivate
;
837 if ((vmesa
->driDrawable
!= driDrawPriv
)
838 || (vmesa
->driReadable
!= driReadPriv
)) {
839 if (driDrawPriv
->swap_interval
== (unsigned)-1) {
840 driDrawPriv
->vblFlags
=
841 vmesa
->viaScreen
->irqEnabled
?
842 driGetDefaultVBlankFlags(&vmesa
->optionCache
) :
845 driDrawableInitVBlank(driDrawPriv
);
848 vmesa
->driDrawable
= driDrawPriv
;
849 vmesa
->driReadable
= driReadPriv
;
851 if ((drawBuffer
->Width
!= driDrawPriv
->w
)
852 || (drawBuffer
->Height
!= driDrawPriv
->h
)) {
853 _mesa_resize_framebuffer(ctx
, drawBuffer
,
854 driDrawPriv
->w
, driDrawPriv
->h
);
855 drawBuffer
->Initialized
= GL_TRUE
;
858 if (!calculate_buffer_parameters(vmesa
, drawBuffer
, driDrawPriv
)) {
862 if (driDrawPriv
!= driReadPriv
) {
863 if ((readBuffer
->Width
!= driReadPriv
->w
)
864 || (readBuffer
->Height
!= driReadPriv
->h
)) {
865 _mesa_resize_framebuffer(ctx
, readBuffer
,
866 driReadPriv
->w
, driReadPriv
->h
);
867 readBuffer
->Initialized
= GL_TRUE
;
870 if (!calculate_buffer_parameters(vmesa
, readBuffer
, driReadPriv
)) {
876 _mesa_make_current(vmesa
->glCtx
, drawBuffer
, readBuffer
);
878 ctx
->Driver
.DrawBuffer( ctx
, ctx
->Color
.DrawBuffer
[0] );
880 viaXMesaWindowMoved(vmesa
);
881 ctx
->Driver
.Scissor(vmesa
->glCtx
,
882 vmesa
->glCtx
->Scissor
.X
,
883 vmesa
->glCtx
->Scissor
.Y
,
884 vmesa
->glCtx
->Scissor
.Width
,
885 vmesa
->glCtx
->Scissor
.Height
);
888 _mesa_make_current(NULL
, NULL
, NULL
);
894 void viaGetLock(struct via_context
*vmesa
, GLuint flags
)
896 __DRIdrawable
*dPriv
= vmesa
->driDrawable
;
897 __DRIscreen
*sPriv
= vmesa
->driScreen
;
899 drmGetLock(vmesa
->driFd
, vmesa
->hHWContext
, flags
);
901 DRI_VALIDATE_DRAWABLE_INFO(sPriv
, dPriv
);
902 if (dPriv
!= vmesa
->driReadable
) {
903 DRI_VALIDATE_DRAWABLE_INFO(sPriv
, vmesa
->driReadable
);
906 if (vmesa
->sarea
->ctxOwner
!= vmesa
->hHWContext
) {
907 vmesa
->sarea
->ctxOwner
= vmesa
->hHWContext
;
908 vmesa
->newEmitState
= ~0;
911 if (vmesa
->lastStamp
!= dPriv
->lastStamp
) {
912 viaXMesaWindowMoved(vmesa
);
913 driUpdateFramebufferSize(vmesa
->glCtx
, dPriv
);
914 vmesa
->newEmitState
= ~0;
915 vmesa
->lastStamp
= dPriv
->lastStamp
;
918 if (vmesa
->doPageFlip
&&
919 vmesa
->pfCurrentOffset
!= vmesa
->sarea
->pfCurrentOffset
) {
920 fprintf(stderr
, "%s - reset pf\n", __FUNCTION__
);
921 viaResetPageFlippingLocked(vmesa
);
927 viaSwapBuffers(__DRIdrawable
*drawablePrivate
)
929 __DRIdrawable
*dPriv
= (__DRIdrawable
*)drawablePrivate
;
932 dPriv
->driContextPriv
&&
933 dPriv
->driContextPriv
->driverPrivate
) {
934 struct via_context
*vmesa
=
935 (struct via_context
*)dPriv
->driContextPriv
->driverPrivate
;
936 struct gl_context
*ctx
= vmesa
->glCtx
;
938 _mesa_notifySwapBuffers(ctx
);
940 if (ctx
->Visual
.doubleBufferMode
) {
941 if (vmesa
->doPageFlip
) {
945 viaCopyBuffer(dPriv
);
949 VIA_FLUSH_DMA(vmesa
);
952 _mesa_problem(NULL
, "viaSwapBuffers: drawable has no context!\n");