1 /* $XFree86: xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c,v 1.19 2003/03/26 20:43:49 tsi Exp $ */
3 * Copyright 2000-2001 VA Linux Systems, Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * on the rights to use, copy, modify, merge, publish, distribute, sub
10 * license, and/or sell copies of the Software, and to permit persons to whom
11 * the Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
26 * Keith Whitwell <keith@tungstengraphics.com>
32 #include "mga_xmesa.h"
35 #include "simple_list.h"
38 #include "swrast/swrast.h"
39 #include "swrast_setup/swrast_setup.h"
41 #include "array_cache/acache.h"
43 #include "tnl/t_pipeline.h"
45 #include "drivers/common/driverfuncs.h"
55 #include "mga_xmesa.h"
62 #include "extensions.h"
64 #include "GL/internal/dri_interface.h"
70 PUBLIC
const char __driConfigOptions
[] =
72 DRI_CONF_SECTION_PERFORMANCE
73 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0
)
75 DRI_CONF_SECTION_QUALITY
76 DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB
)
77 DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER
)
79 DRI_CONF_SECTION_SOFTWARE
80 DRI_CONF_ARB_VERTEX_PROGRAM(true)
81 DRI_CONF_NV_VERTEX_PROGRAM(true)
84 static const GLuint __driNConfigOptions
= 5;
86 #ifdef USE_NEW_INTERFACE
87 static PFNGLXCREATECONTEXTMODES create_context_modes
= NULL
;
88 #endif /* USE_NEW_INTERFACE */
94 static int getSwapInfo( __DRIdrawablePrivate
*dPriv
, __DRIswapInfo
* sInfo
);
96 #ifdef USE_NEW_INTERFACE
97 static __GLcontextModes
*
98 mgaFillInModes( unsigned pixel_bits
, unsigned depth_bits
,
99 unsigned stencil_bits
, GLboolean have_back_buffer
)
101 __GLcontextModes
* modes
;
102 __GLcontextModes
* m
;
104 unsigned depth_buffer_factor
;
105 unsigned back_buffer_factor
;
109 /* GLX_SWAP_COPY_OML is only supported because the MGA driver doesn't
110 * support pageflipping at all.
112 static const GLenum back_buffer_modes
[] = {
113 GLX_NONE
, GLX_SWAP_UNDEFINED_OML
, GLX_SWAP_COPY_OML
116 u_int8_t depth_bits_array
[3];
117 u_int8_t stencil_bits_array
[3];
120 depth_bits_array
[0] = 0;
121 depth_bits_array
[1] = depth_bits
;
122 depth_bits_array
[2] = depth_bits
;
124 /* Just like with the accumulation buffer, always provide some modes
125 * with a stencil buffer. It will be a sw fallback, but some apps won't
128 stencil_bits_array
[0] = 0;
129 stencil_bits_array
[1] = 0;
130 stencil_bits_array
[2] = (stencil_bits
== 0) ? 8 : stencil_bits
;
132 depth_buffer_factor
= ((depth_bits
!= 0) || (stencil_bits
!= 0)) ? 3 : 1;
133 back_buffer_factor
= (have_back_buffer
) ? 2 : 1;
135 num_modes
= depth_buffer_factor
* back_buffer_factor
* 4;
137 if ( pixel_bits
== 16 ) {
139 fb_type
= GL_UNSIGNED_SHORT_5_6_5
;
143 fb_type
= GL_UNSIGNED_INT_8_8_8_8_REV
;
146 modes
= (*create_context_modes
)( num_modes
, sizeof( __GLcontextModes
) );
148 if ( ! driFillInModes( & m
, fb_format
, fb_type
,
149 depth_bits_array
, stencil_bits_array
, depth_buffer_factor
,
150 back_buffer_modes
, back_buffer_factor
,
152 fprintf( stderr
, "[%s:%u] Error creating FBConfig!\n",
153 __func__
, __LINE__
);
157 if ( ! driFillInModes( & m
, fb_format
, fb_type
,
158 depth_bits_array
, stencil_bits_array
, depth_buffer_factor
,
159 back_buffer_modes
, back_buffer_factor
,
160 GLX_DIRECT_COLOR
) ) {
161 fprintf( stderr
, "[%s:%u] Error creating FBConfig!\n",
162 __func__
, __LINE__
);
166 /* Mark the visual as slow if there are "fake" stencil bits.
168 for ( m
= modes
; m
!= NULL
; m
= m
->next
) {
169 if ( (m
->stencilBits
!= 0) && (m
->stencilBits
!= stencil_bits
) ) {
170 m
->visualRating
= GLX_SLOW_CONFIG
;
176 #endif /* USE_NEW_INTERFACE */
180 mgaInitDriver(__DRIscreenPrivate
*sPriv
)
182 mgaScreenPrivate
*mgaScreen
;
183 MGADRIPtr serverInfo
= (MGADRIPtr
)sPriv
->pDevPriv
;
186 /* Allocate the private area */
187 mgaScreen
= (mgaScreenPrivate
*)MALLOC(sizeof(mgaScreenPrivate
));
189 __driUtilMessage("Couldn't malloc screen struct");
193 mgaScreen
->sPriv
= sPriv
;
194 sPriv
->private = (void *)mgaScreen
;
196 if (sPriv
->drmMinor
>= 1) {
198 drm_mga_getparam_t gp
;
200 gp
.param
= MGA_PARAM_IRQ_NR
;
201 gp
.value
= &mgaScreen
->irq
;
204 ret
= drmCommandWriteRead( sPriv
->fd
, DRM_MGA_GETPARAM
,
207 fprintf(stderr
, "drmMgaGetParam (MGA_PARAM_IRQ_NR): %d\n", ret
);
209 sPriv
->private = NULL
;
214 mgaScreen
->linecomp_sane
= (sPriv
->ddxMajor
> 1) || (sPriv
->ddxMinor
> 1)
215 || ((sPriv
->ddxMinor
== 1) && (sPriv
->ddxPatch
> 0));
217 if ( driCompareGLXAPIVersion( 20030813 ) >= 0 ) {
218 PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension
=
219 (PFNGLXSCRENABLEEXTENSIONPROC
) glXGetProcAddress( (const GLubyte
*) "__glXScrEnableExtension" );
220 void * const psc
= sPriv
->psc
->screenConfigs
;
222 if ( glx_enable_extension
!= NULL
) {
223 if ( mgaScreen
->linecomp_sane
) {
224 (*glx_enable_extension
)( psc
, "GLX_SGI_swap_control" );
225 (*glx_enable_extension
)( psc
, "GLX_SGI_video_sync" );
226 (*glx_enable_extension
)( psc
, "GLX_MESA_swap_control" );
229 (*glx_enable_extension
)( psc
, "GLX_SGI_make_current_read" );
230 (*glx_enable_extension
)( psc
, "GLX_MESA_swap_frame_usage" );
232 if ( driCompareGLXAPIVersion( 20030915 ) >= 0 ) {
233 (*glx_enable_extension
)( psc
, "GLX_SGIX_fbconfig" );
234 (*glx_enable_extension
)( psc
, "GLX_OML_swap_method" );
239 if (serverInfo
->chipset
!= MGA_CARD_TYPE_G200
&&
240 serverInfo
->chipset
!= MGA_CARD_TYPE_G400
) {
242 sPriv
->private = NULL
;
243 __driUtilMessage("Unrecognized chipset");
248 mgaScreen
->chipset
= serverInfo
->chipset
;
249 mgaScreen
->width
= serverInfo
->width
;
250 mgaScreen
->height
= serverInfo
->height
;
251 mgaScreen
->mem
= serverInfo
->mem
;
252 mgaScreen
->cpp
= serverInfo
->cpp
;
254 mgaScreen
->agpMode
= serverInfo
->agpMode
;
256 mgaScreen
->frontPitch
= serverInfo
->frontPitch
;
257 mgaScreen
->frontOffset
= serverInfo
->frontOffset
;
258 mgaScreen
->backOffset
= serverInfo
->backOffset
;
259 mgaScreen
->backPitch
= serverInfo
->backPitch
;
260 mgaScreen
->depthOffset
= serverInfo
->depthOffset
;
261 mgaScreen
->depthPitch
= serverInfo
->depthPitch
;
263 mgaScreen
->mmio
.handle
= serverInfo
->registers
.handle
;
264 mgaScreen
->mmio
.size
= serverInfo
->registers
.size
;
265 if ( drmMap( sPriv
->fd
,
266 mgaScreen
->mmio
.handle
, mgaScreen
->mmio
.size
,
267 &mgaScreen
->mmio
.map
) < 0 ) {
269 sPriv
->private = NULL
;
270 __driUtilMessage( "Couldn't map MMIO registers" );
274 mgaScreen
->primary
.handle
= serverInfo
->primary
.handle
;
275 mgaScreen
->primary
.size
= serverInfo
->primary
.size
;
276 mgaScreen
->buffers
.handle
= serverInfo
->buffers
.handle
;
277 mgaScreen
->buffers
.size
= serverInfo
->buffers
.size
;
280 mgaScreen
->agp
.handle
= serverInfo
->agp
;
281 mgaScreen
->agp
.size
= serverInfo
->agpSize
;
283 if (drmMap(sPriv
->fd
,
284 mgaScreen
->agp
.handle
,
286 (drmAddress
*)&mgaScreen
->agp
.map
) != 0)
289 sPriv
->private = NULL
;
290 __driUtilMessage("Couldn't map agp region");
295 mgaScreen
->textureOffset
[MGA_CARD_HEAP
] = serverInfo
->textureOffset
;
296 mgaScreen
->textureOffset
[MGA_AGP_HEAP
] = (serverInfo
->agpTextureOffset
|
297 PDEA_pagpxfer_enable
| 1);
299 mgaScreen
->textureSize
[MGA_CARD_HEAP
] = serverInfo
->textureSize
;
300 mgaScreen
->textureSize
[MGA_AGP_HEAP
] = serverInfo
->agpTextureSize
;
302 mgaScreen
->logTextureGranularity
[MGA_CARD_HEAP
] =
303 serverInfo
->logTextureGranularity
;
304 mgaScreen
->logTextureGranularity
[MGA_AGP_HEAP
] =
305 serverInfo
->logAgpTextureGranularity
;
307 mgaScreen
->texVirtual
[MGA_CARD_HEAP
] = (char *)(mgaScreen
->sPriv
->pFB
+
308 serverInfo
->textureOffset
);
309 if (drmMap(sPriv
->fd
,
310 serverInfo
->agpTextureOffset
,
311 serverInfo
->agpTextureSize
,
312 (drmAddress
*)&mgaScreen
->texVirtual
[MGA_AGP_HEAP
]) != 0)
315 sPriv
->private = NULL
;
316 __driUtilMessage("Couldn't map agptexture region");
321 mgaScreen
->texVirtual
[MGA_AGP_HEAP
] = (mgaScreen
->agp
.map
+
322 serverInfo
->agpTextureOffset
);
325 mgaScreen
->mAccess
= serverInfo
->mAccess
;
327 /* For calculating setupdma addresses.
329 mgaScreen
->dmaOffset
= serverInfo
->buffers
.handle
;
331 mgaScreen
->bufs
= drmMapBufs(sPriv
->fd
);
332 if (!mgaScreen
->bufs
) {
333 /*drmUnmap(mgaScreen->agp_tex.map, mgaScreen->agp_tex.size);*/
335 sPriv
->private = NULL
;
336 __driUtilMessage("Couldn't map dma buffers");
339 mgaScreen
->sarea_priv_offset
= serverInfo
->sarea_priv_offset
;
341 /* parse information in __driConfigOptions */
342 driParseOptionInfo (&mgaScreen
->optionCache
,
343 __driConfigOptions
, __driNConfigOptions
);
350 mgaDestroyScreen(__DRIscreenPrivate
*sPriv
)
352 mgaScreenPrivate
*mgaScreen
= (mgaScreenPrivate
*) sPriv
->private;
354 if (MGA_DEBUG
&DEBUG_VERBOSE_DRI
)
355 fprintf(stderr
, "mgaDestroyScreen\n");
357 drmUnmapBufs(mgaScreen
->bufs
);
359 /*drmUnmap(mgaScreen->agp_tex.map, mgaScreen->agp_tex.size);*/
361 /* free all option information */
362 driDestroyOptionInfo (&mgaScreen
->optionCache
);
365 sPriv
->private = NULL
;
369 extern const struct tnl_pipeline_stage _mga_render_stage
;
371 static const struct tnl_pipeline_stage
*mga_pipeline
[] = {
372 &_tnl_vertex_transform_stage
,
373 &_tnl_normal_transform_stage
,
374 &_tnl_lighting_stage
,
375 &_tnl_fog_coordinate_stage
,
377 &_tnl_texture_transform_stage
,
378 &_tnl_vertex_program_stage
,
380 /* REMOVE: point attenuation stage */
382 &_mga_render_stage
, /* ADD: unclipped rastersetup-to-dma */
383 /* Need new ioctl for wacceptseq */
390 static const char * const g400_extensions
[] =
392 "GL_ARB_multitexture",
393 "GL_ARB_texture_env_add",
394 "GL_ARB_texture_env_combine",
395 "GL_ARB_texture_env_crossbar",
396 "GL_EXT_texture_env_combine",
397 "GL_EXT_texture_edge_clamp",
398 "GL_ATI_texture_env_combine3",
399 #if defined (MESA_packed_depth_stencil)
400 "GL_MESA_packed_depth_stencil",
405 static const char * const card_extensions
[] =
407 "GL_ARB_multisample",
408 "GL_ARB_texture_compression",
409 "GL_ARB_texture_rectangle",
410 "GL_EXT_blend_logic_op",
412 "GL_EXT_multi_draw_arrays",
413 /* paletted_textures currently doesn't work, but we could fix them later */
415 "GL_EXT_shared_texture_palette",
416 "GL_EXT_paletted_texture",
418 "GL_EXT_secondary_color",
419 "GL_EXT_stencil_wrap",
420 "GL_MESA_ycbcr_texture",
421 "GL_SGIS_generate_mipmap",
425 static const struct dri_debug_control debug_control
[] =
427 { "fall", DEBUG_VERBOSE_FALLBACK
},
428 { "tex", DEBUG_VERBOSE_TEXTURE
},
429 { "ioctl", DEBUG_VERBOSE_IOCTL
},
430 { "verb", DEBUG_VERBOSE_MSG
},
431 { "dri", DEBUG_VERBOSE_DRI
},
437 get_ust_nop( int64_t * ust
)
445 mgaCreateContext( const __GLcontextModes
*mesaVis
,
446 __DRIcontextPrivate
*driContextPriv
,
447 void *sharedContextPrivate
)
451 GLcontext
*ctx
, *shareCtx
;
453 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
454 mgaScreenPrivate
*mgaScreen
= (mgaScreenPrivate
*)sPriv
->private;
455 drm_mga_sarea_t
*saPriv
= (drm_mga_sarea_t
*)(((char*)sPriv
->pSAREA
)+
456 mgaScreen
->sarea_priv_offset
);
457 struct dd_function_table functions
;
459 if (MGA_DEBUG
&DEBUG_VERBOSE_DRI
)
460 fprintf(stderr
, "mgaCreateContext\n");
462 /* allocate mga context */
463 mmesa
= (mgaContextPtr
) CALLOC(sizeof(mgaContext
));
468 /* Init default driver functions then plug in our Radeon-specific functions
469 * (the texture functions are especially important)
471 _mesa_init_driver_functions( &functions
);
472 mgaInitDriverFuncs( &functions
);
473 mgaInitTextureFuncs( &functions
);
474 mgaInitIoctlFuncs( &functions
);
476 /* Allocate the Mesa context */
477 if (sharedContextPrivate
)
478 shareCtx
= ((mgaContextPtr
) sharedContextPrivate
)->glCtx
;
481 mmesa
->glCtx
= _mesa_create_context(mesaVis
, shareCtx
,
482 &functions
, (void *) mmesa
);
487 driContextPriv
->driverPrivate
= mmesa
;
490 mmesa
->hHWContext
= driContextPriv
->hHWContext
;
491 mmesa
->driFd
= sPriv
->fd
;
492 mmesa
->driHwLock
= &sPriv
->pSAREA
->lock
;
494 mmesa
->mgaScreen
= mgaScreen
;
495 mmesa
->driScreen
= sPriv
;
496 mmesa
->sarea
= (void *)saPriv
;
498 /* Parse configuration files */
499 driParseConfigFiles (&mmesa
->optionCache
, &mgaScreen
->optionCache
,
500 sPriv
->myNum
, "mga");
502 (void) memset( mmesa
->texture_heaps
, 0, sizeof( mmesa
->texture_heaps
) );
503 make_empty_list( & mmesa
->swapped
);
505 mmesa
->nr_heaps
= mgaScreen
->texVirtual
[MGA_AGP_HEAP
] ? 2 : 1;
506 for ( i
= 0 ; i
< mmesa
->nr_heaps
; i
++ ) {
507 mmesa
->texture_heaps
[i
] = driCreateTextureHeap( i
, mmesa
,
508 mgaScreen
->textureSize
[i
],
511 (drmTextureRegionPtr
)mmesa
->sarea
->texList
[i
],
512 &mmesa
->sarea
->texAge
[i
],
514 sizeof( mgaTextureObject_t
),
515 (destroy_texture_object_t
*) mgaDestroyTexObj
);
518 /* Set the maximum texture size small enough that we can guarentee
519 * that both texture units can bind a maximal texture and have them
520 * on the card at once.
523 if ( mgaScreen
->chipset
== MGA_CARD_TYPE_G200
) {
524 ctx
->Const
.MaxTextureUnits
= 1;
525 ctx
->Const
.MaxTextureImageUnits
= 1;
526 ctx
->Const
.MaxTextureCoordUnits
= 1;
527 maxlevels
= G200_TEX_MAXLEVELS
;
531 ctx
->Const
.MaxTextureUnits
= 2;
532 ctx
->Const
.MaxTextureImageUnits
= 2;
533 ctx
->Const
.MaxTextureCoordUnits
= 2;
534 maxlevels
= G400_TEX_MAXLEVELS
;
537 driCalculateMaxTextureLevels( mmesa
->texture_heaps
,
541 11, /* max 2D texture size is 2048x2048 */
542 0, /* 3D textures unsupported. */
543 0, /* cube textures unsupported. */
544 11, /* max texture rect size is 2048x2048 */
548 ctx
->Const
.MinLineWidth
= 1.0;
549 ctx
->Const
.MinLineWidthAA
= 1.0;
550 ctx
->Const
.MaxLineWidth
= 10.0;
551 ctx
->Const
.MaxLineWidthAA
= 10.0;
552 ctx
->Const
.LineWidthGranularity
= 1.0;
554 mmesa
->texture_depth
= driQueryOptioni (&mmesa
->optionCache
,
556 if (mmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FB
)
557 mmesa
->texture_depth
= ( mesaVis
->rgbBits
>= 24 ) ?
558 DRI_CONF_TEXTURE_DEPTH_32
: DRI_CONF_TEXTURE_DEPTH_16
;
559 mmesa
->hw_stencil
= mesaVis
->stencilBits
&& mesaVis
->depthBits
== 24;
561 switch (mesaVis
->depthBits
) {
563 mmesa
->depth_scale
= 1.0/(GLdouble
)0xffff;
564 mmesa
->depth_clear_mask
= ~0;
565 mmesa
->ClearDepth
= 0xffff;
568 mmesa
->depth_scale
= 1.0/(GLdouble
)0xffffff;
569 if (mmesa
->hw_stencil
) {
570 mmesa
->depth_clear_mask
= 0xffffff00;
571 mmesa
->stencil_clear_mask
= 0x000000ff;
573 mmesa
->depth_clear_mask
= ~0;
574 mmesa
->ClearDepth
= 0xffffff00;
577 mmesa
->depth_scale
= 1.0/(GLdouble
)0xffffffff;
578 mmesa
->depth_clear_mask
= ~0;
579 mmesa
->ClearDepth
= 0xffffffff;
583 mmesa
->haveHwStipple
= GL_FALSE
;
584 mmesa
->RenderIndex
= -1; /* impossible value */
586 mmesa
->vertex_format
= 0;
587 mmesa
->CurrentTexObj
[0] = 0;
588 mmesa
->CurrentTexObj
[1] = 0;
589 mmesa
->tmu_source
[0] = 0;
590 mmesa
->tmu_source
[1] = 1;
592 mmesa
->texAge
[0] = 0;
593 mmesa
->texAge
[1] = 0;
595 /* Initialize the software rasterizer and helper modules.
597 _swrast_CreateContext( ctx
);
598 _ac_CreateContext( ctx
);
599 _tnl_CreateContext( ctx
);
601 _swsetup_CreateContext( ctx
);
603 /* Install the customized pipeline:
605 _tnl_destroy_pipeline( ctx
);
606 _tnl_install_pipeline( ctx
, mga_pipeline
);
608 /* Configure swrast and T&L to match hardware characteristics:
610 _swrast_allow_pixel_fog( ctx
, GL_FALSE
);
611 _swrast_allow_vertex_fog( ctx
, GL_TRUE
);
612 _tnl_allow_pixel_fog( ctx
, GL_FALSE
);
613 _tnl_allow_vertex_fog( ctx
, GL_TRUE
);
615 mmesa
->primary_offset
= mmesa
->mgaScreen
->primary
.handle
;
617 ctx
->DriverCtx
= (void *) mmesa
;
620 driInitExtensions( ctx
, card_extensions
, GL_FALSE
);
622 if (MGA_IS_G400(MGA_CONTEXT(ctx
))) {
623 driInitExtensions( ctx
, g400_extensions
, GL_FALSE
);
626 if ( driQueryOptionb( &mmesa
->optionCache
, "arb_vertex_program" ) ) {
627 _mesa_enable_extension( ctx
, "GL_ARB_vertex_program" );
630 if ( driQueryOptionb( &mmesa
->optionCache
, "nv_vertex_program" ) ) {
631 _mesa_enable_extension( ctx
, "GL_NV_vertex_program" );
632 _mesa_enable_extension( ctx
, "GL_NV_vertex_program1_1" );
636 /* XXX these should really go right after _mesa_init_driver_functions() */
637 mgaDDInitStateFuncs( ctx
);
638 mgaDDInitSpanFuncs( ctx
);
639 mgaDDInitPixelFuncs( ctx
);
640 mgaDDInitTriFuncs( ctx
);
643 mgaInitState( mmesa
);
645 driContextPriv
->driverPrivate
= (void *) mmesa
;
648 MGA_DEBUG
= driParseDebugString( getenv( "MGA_DEBUG" ),
652 mmesa
->vblank_flags
= ((mmesa
->mgaScreen
->irq
== 0)
653 || !mmesa
->mgaScreen
->linecomp_sane
)
654 ? VBLANK_FLAG_NO_IRQ
: driGetDefaultVBlankFlags(&mmesa
->optionCache
);
656 mmesa
->get_ust
= (PFNGLXGETUSTPROC
) glXGetProcAddress( (const GLubyte
*) "__glXGetUST" );
657 if ( mmesa
->get_ust
== NULL
) {
658 mmesa
->get_ust
= get_ust_nop
;
661 (*mmesa
->get_ust
)( & mmesa
->swap_ust
);
667 mgaDestroyContext(__DRIcontextPrivate
*driContextPriv
)
669 mgaContextPtr mmesa
= (mgaContextPtr
) driContextPriv
->driverPrivate
;
671 if (MGA_DEBUG
&DEBUG_VERBOSE_DRI
)
672 fprintf( stderr
, "[%s:%d] mgaDestroyContext start\n",
673 __FILE__
, __LINE__
);
675 assert(mmesa
); /* should never be null */
677 GLboolean release_texture_heaps
;
680 release_texture_heaps
= (mmesa
->glCtx
->Shared
->RefCount
== 1);
681 _swsetup_DestroyContext( mmesa
->glCtx
);
682 _tnl_DestroyContext( mmesa
->glCtx
);
683 _ac_DestroyContext( mmesa
->glCtx
);
684 _swrast_DestroyContext( mmesa
->glCtx
);
686 mgaFreeVB( mmesa
->glCtx
);
688 /* free the Mesa context */
689 mmesa
->glCtx
->DriverCtx
= NULL
;
690 _mesa_destroy_context(mmesa
->glCtx
);
692 if ( release_texture_heaps
) {
693 /* This share group is about to go away, free our private
694 * texture object data.
698 for ( i
= 0 ; i
< mmesa
->nr_heaps
; i
++ ) {
699 driDestroyTextureHeap( mmesa
->texture_heaps
[ i
] );
700 mmesa
->texture_heaps
[ i
] = NULL
;
703 assert( is_empty_list( & mmesa
->swapped
) );
706 /* free the option cache */
707 driDestroyOptionCache (&mmesa
->optionCache
);
712 if (MGA_DEBUG
&DEBUG_VERBOSE_DRI
)
713 fprintf( stderr
, "[%s:%d] mgaDestroyContext done\n",
714 __FILE__
, __LINE__
);
719 mgaCreateBuffer( __DRIscreenPrivate
*driScrnPriv
,
720 __DRIdrawablePrivate
*driDrawPriv
,
721 const __GLcontextModes
*mesaVis
,
725 return GL_FALSE
; /* not implemented */
728 GLboolean swStencil
= (mesaVis
->stencilBits
> 0 &&
729 mesaVis
->depthBits
!= 24);
731 driDrawPriv
->driverPrivate
= (void *)
732 _mesa_create_framebuffer(mesaVis
,
733 GL_FALSE
, /* software depth buffer? */
735 mesaVis
->accumRedBits
> 0,
736 mesaVis
->alphaBits
> 0 );
738 return (driDrawPriv
->driverPrivate
!= NULL
);
744 mgaDestroyBuffer(__DRIdrawablePrivate
*driDrawPriv
)
746 _mesa_destroy_framebuffer((GLframebuffer
*) (driDrawPriv
->driverPrivate
));
750 mgaSwapBuffers(__DRIdrawablePrivate
*dPriv
)
752 if (dPriv
->driContextPriv
&& dPriv
->driContextPriv
->driverPrivate
) {
755 mmesa
= (mgaContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
758 if (ctx
->Visual
.doubleBufferMode
) {
759 _mesa_notifySwapBuffers( ctx
);
760 mgaCopyBuffer( dPriv
);
763 /* XXX this shouldn't be an error but we can't handle it for now */
764 _mesa_problem(NULL
, "%s: drawable has no context!\n", __FUNCTION__
);
769 mgaUnbindContext(__DRIcontextPrivate
*driContextPriv
)
771 mgaContextPtr mmesa
= (mgaContextPtr
) driContextPriv
->driverPrivate
;
778 /* This looks buggy to me - the 'b' variable isn't used anywhere...
779 * Hmm - It seems that the drawable is already hooked in to
782 * But why are we doing context initialization here???
785 mgaMakeCurrent(__DRIcontextPrivate
*driContextPriv
,
786 __DRIdrawablePrivate
*driDrawPriv
,
787 __DRIdrawablePrivate
*driReadPriv
)
789 if (driContextPriv
) {
790 mgaContextPtr mmesa
= (mgaContextPtr
) driContextPriv
->driverPrivate
;
792 if (mmesa
->driDrawable
!= driDrawPriv
) {
793 driDrawableInitVBlank( driDrawPriv
, mmesa
->vblank_flags
);
794 mmesa
->driDrawable
= driDrawPriv
;
796 mmesa
->dirty_cliprects
= (MGA_FRONT
|MGA_BACK
);
797 mmesa
->mesa_drawable
= driDrawPriv
;
800 mmesa
->driReadable
= driReadPriv
;
802 _mesa_make_current2(mmesa
->glCtx
,
803 (GLframebuffer
*) driDrawPriv
->driverPrivate
,
804 (GLframebuffer
*) driReadPriv
->driverPrivate
);
807 _mesa_make_current(NULL
, NULL
);
814 void mgaGetLock( mgaContextPtr mmesa
, GLuint flags
)
816 __DRIdrawablePrivate
*dPriv
= mmesa
->driDrawable
;
817 drm_mga_sarea_t
*sarea
= mmesa
->sarea
;
818 int me
= mmesa
->hHWContext
;
821 drmGetLock(mmesa
->driFd
, mmesa
->hHWContext
, flags
);
823 if (*(dPriv
->pStamp
) != mmesa
->lastStamp
) {
824 mmesa
->lastStamp
= *(dPriv
->pStamp
);
825 mmesa
->SetupNewInputs
|= VERT_BIT_POS
;
826 mmesa
->dirty_cliprects
= (MGA_FRONT
|MGA_BACK
);
827 mgaUpdateRects( mmesa
, (MGA_FRONT
|MGA_BACK
) );
830 mmesa
->dirty
|= MGA_UPLOAD_CONTEXT
| MGA_UPLOAD_CLIPRECTS
;
832 mmesa
->sarea
->dirty
|= MGA_UPLOAD_CONTEXT
;
834 if (sarea
->ctxOwner
!= me
) {
835 mmesa
->dirty
|= (MGA_UPLOAD_CONTEXT
| MGA_UPLOAD_TEX0
|
836 MGA_UPLOAD_TEX1
| MGA_UPLOAD_PIPE
);
840 for ( i
= 0 ; i
< mmesa
->nr_heaps
; i
++ ) {
841 DRI_AGE_TEXTURES( mmesa
->texture_heaps
[ i
] );
844 sarea
->last_quiescent
= -1; /* just kill it for now */
848 static const struct __DriverAPIRec mgaAPI
= {
849 .InitDriver
= mgaInitDriver
,
850 .DestroyScreen
= mgaDestroyScreen
,
851 .CreateContext
= mgaCreateContext
,
852 .DestroyContext
= mgaDestroyContext
,
853 .CreateBuffer
= mgaCreateBuffer
,
854 .DestroyBuffer
= mgaDestroyBuffer
,
855 .SwapBuffers
= mgaSwapBuffers
,
856 .MakeCurrent
= mgaMakeCurrent
,
857 .UnbindContext
= mgaUnbindContext
,
858 .GetSwapInfo
= getSwapInfo
,
859 .GetMSC
= driGetMSC32
,
860 .WaitForMSC
= driWaitForMSC32
,
862 .SwapBuffersMSC
= NULL
867 * This is the bootstrap function for the driver.
868 * The __driCreateScreen name is the symbol that libGL.so fetches.
869 * Return: pointer to a __DRIscreenPrivate.
871 #if !defined(DRI_NEW_INTERFACE_ONLY)
872 void *__driCreateScreen(Display
*dpy
, int scrn
, __DRIscreen
*psc
,
873 int numConfigs
, __GLXvisualConfig
*config
)
875 __DRIscreenPrivate
*psp
;
876 psp
= __driUtilCreateScreen(dpy
, scrn
, psc
, numConfigs
, config
, &mgaAPI
);
879 #endif /* !defined(DRI_NEW_INTERFACE_ONLY) */
883 * This is the bootstrap function for the driver. libGL supplies all of the
884 * requisite information about the system, and the driver initializes itself.
885 * This routine also fills in the linked list pointed to by \c driver_modes
886 * with the \c __GLcontextModes that the driver can support for windows or
889 * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
892 #ifdef USE_NEW_INTERFACE
894 void * __driCreateNewScreen( __DRInativeDisplay
*dpy
, int scrn
, __DRIscreen
*psc
,
895 const __GLcontextModes
* modes
,
896 const __DRIversion
* ddx_version
,
897 const __DRIversion
* dri_version
,
898 const __DRIversion
* drm_version
,
899 const __DRIframebuffer
* frame_buffer
,
900 drmAddress pSAREA
, int fd
,
901 int internal_api_version
,
902 __GLcontextModes
** driver_modes
)
905 __DRIscreenPrivate
*psp
;
906 static const __DRIversion ddx_expected
= { 1, 0, 0 };
907 static const __DRIversion dri_expected
= { 4, 0, 0 };
908 static const __DRIversion drm_expected
= { 3, 0, 0 };
910 if ( ! driCheckDriDdxDrmVersions2( "MGA",
911 dri_version
, & dri_expected
,
912 ddx_version
, & ddx_expected
,
913 drm_version
, & drm_expected
) ) {
917 psp
= __driUtilCreateNewScreen(dpy
, scrn
, psc
, NULL
,
918 ddx_version
, dri_version
, drm_version
,
919 frame_buffer
, pSAREA
, fd
,
920 internal_api_version
, &mgaAPI
);
922 create_context_modes
= (PFNGLXCREATECONTEXTMODES
)
923 glXGetProcAddress( (const GLubyte
*) "__glXCreateContextModes" );
924 if ( create_context_modes
!= NULL
) {
925 MGADRIPtr dri_priv
= (MGADRIPtr
) psp
->pDevPriv
;
926 *driver_modes
= mgaFillInModes( dri_priv
->cpp
* 8,
927 (dri_priv
->cpp
== 2) ? 16 : 24,
928 (dri_priv
->cpp
== 2) ? 0 : 8,
929 (dri_priv
->backOffset
!= dri_priv
->depthOffset
) );
935 #endif /* USE_NEW_INTERFACE */
939 * Get information about previous buffer swaps.
942 getSwapInfo( __DRIdrawablePrivate
*dPriv
, __DRIswapInfo
* sInfo
)
946 if ( (dPriv
== NULL
) || (dPriv
->driContextPriv
== NULL
)
947 || (dPriv
->driContextPriv
->driverPrivate
== NULL
)
948 || (sInfo
== NULL
) ) {
952 mmesa
= (mgaContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
953 sInfo
->swap_count
= mmesa
->swap_count
;
954 sInfo
->swap_ust
= mmesa
->swap_ust
;
955 sInfo
->swap_missed_count
= mmesa
->swap_missed_count
;
957 sInfo
->swap_missed_usage
= (sInfo
->swap_missed_count
!= 0)
958 ? driCalculateSwapUsage( dPriv
, 0, mmesa
->swap_missed_ust
)