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>
29 #include "mga_common.h"
30 #include "mga_xmesa.h"
33 #include "simple_list.h"
36 #include "swrast/swrast.h"
37 #include "swrast_setup/swrast_setup.h"
39 #include "array_cache/acache.h"
41 #include "tnl/t_pipeline.h"
43 #include "drivers/common/driverfuncs.h"
53 #include "mga_xmesa.h"
61 #include "glxextensions.h"
68 const char __driConfigOptions
[] =
70 DRI_CONF_SECTION_PERFORMANCE
71 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0
)
73 DRI_CONF_SECTION_QUALITY
74 DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB
)
75 DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER
)
78 static const GLuint __driNConfigOptions
= 3;
80 #ifdef USE_NEW_INTERFACE
81 static PFNGLXCREATECONTEXTMODES create_context_modes
= NULL
;
82 #endif /* USE_NEW_INTERFACE */
88 static int getSwapInfo( __DRIdrawablePrivate
*dPriv
, __DRIswapInfo
* sInfo
);
90 #ifdef USE_NEW_INTERFACE
91 static __GLcontextModes
* fill_in_modes( __GLcontextModes
* modes
,
94 unsigned stencil_bits
,
95 const GLenum
* db_modes
,
96 unsigned num_db_modes
,
99 static const uint8_t bits
[2][4] = {
104 static const uint32_t masks
[2][4] = {
105 { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 },
106 { 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }
111 const unsigned index
= ((pixel_bits
+ 15) / 16) - 1;
113 for ( i
= 0 ; i
< num_db_modes
; i
++ ) {
114 for ( j
= 0 ; j
< 2 ; j
++ ) {
116 modes
->redBits
= bits
[index
][0];
117 modes
->greenBits
= bits
[index
][1];
118 modes
->blueBits
= bits
[index
][2];
119 modes
->alphaBits
= bits
[index
][3];
120 modes
->redMask
= masks
[index
][0];
121 modes
->greenMask
= masks
[index
][1];
122 modes
->blueMask
= masks
[index
][2];
123 modes
->alphaMask
= masks
[index
][3];
124 modes
->rgbBits
= modes
->redBits
+ modes
->greenBits
127 modes
->accumRedBits
= 16 * j
;
128 modes
->accumGreenBits
= 16 * j
;
129 modes
->accumBlueBits
= 16 * j
;
130 modes
->accumAlphaBits
= 0;
131 modes
->visualRating
= (j
== 0) ? GLX_NONE
: GLX_SLOW_CONFIG
;
133 modes
->stencilBits
= stencil_bits
;
134 modes
->depthBits
= depth_bits
;
136 modes
->visualType
= visType
;
137 modes
->renderType
= GLX_RGBA_BIT
;
138 modes
->drawableType
= GLX_WINDOW_BIT
;
139 modes
->rgbMode
= GL_TRUE
;
141 if ( db_modes
[i
] == GLX_NONE
) {
142 modes
->doubleBufferMode
= GL_FALSE
;
145 modes
->doubleBufferMode
= GL_TRUE
;
146 modes
->swapMethod
= db_modes
[i
];
155 #endif /* USE_NEW_INTERFACE */
158 #ifdef USE_NEW_INTERFACE
159 static __GLcontextModes
*
160 mgaFillInModes( unsigned pixel_bits
, unsigned depth_bits
,
161 unsigned stencil_bits
, GLboolean have_back_buffer
)
163 __GLcontextModes
* modes
;
164 __GLcontextModes
* m
;
166 unsigned depth_buffer_factor
;
167 unsigned back_buffer_factor
;
170 /* GLX_SWAP_COPY_OML is only supported because the MGA driver doesn't
171 * support pageflipping at all.
173 static const GLenum back_buffer_modes
[] = {
174 GLX_NONE
, GLX_SWAP_UNDEFINED_OML
, GLX_SWAP_COPY_OML
177 int depth_buffer_modes
[2][2] = {
182 depth_buffer_modes
[1][0] = depth_bits
;
183 depth_buffer_modes
[1][1] = stencil_bits
;
185 depth_buffer_factor
= ((depth_bits
!= 0) || (stencil_bits
!= 0)) ? 2 : 1;
186 back_buffer_factor
= (have_back_buffer
) ? 2 : 1;
188 num_modes
= depth_buffer_factor
* back_buffer_factor
* 4;
190 modes
= (*create_context_modes
)( num_modes
, sizeof( __GLcontextModes
) );
192 for ( i
= 0 ; i
< depth_buffer_factor
; i
++ ) {
193 m
= fill_in_modes( m
, pixel_bits
,
194 depth_buffer_modes
[i
][0], depth_buffer_modes
[i
][1],
195 back_buffer_modes
, back_buffer_factor
,
199 for ( i
= 0 ; i
< depth_buffer_factor
; i
++ ) {
200 m
= fill_in_modes( m
, pixel_bits
,
201 depth_buffer_modes
[i
][0], depth_buffer_modes
[i
][1],
202 back_buffer_modes
, back_buffer_factor
,
208 #endif /* USE_NEW_INTERFACE */
212 mgaInitDriver(__DRIscreenPrivate
*sPriv
)
214 mgaScreenPrivate
*mgaScreen
;
215 MGADRIPtr serverInfo
= (MGADRIPtr
)sPriv
->pDevPriv
;
217 if ( ! driCheckDriDdxDrmVersions( sPriv
, "MGA", 4, 0, 1, 0, 3, 0 ) )
220 /* Allocate the private area */
221 mgaScreen
= (mgaScreenPrivate
*)MALLOC(sizeof(mgaScreenPrivate
));
223 __driUtilMessage("Couldn't malloc screen struct");
227 mgaScreen
->sPriv
= sPriv
;
228 sPriv
->private = (void *)mgaScreen
;
230 if (sPriv
->drmMinor
>= 1) {
234 gp
.param
= MGA_PARAM_IRQ_NR
;
235 gp
.value
= &mgaScreen
->irq
;
237 ret
= drmCommandWriteRead( sPriv
->fd
, DRM_MGA_GETPARAM
,
240 fprintf(stderr
, "drmMgaGetParam (MGA_PARAM_IRQ_NR): %d\n", ret
);
242 sPriv
->private = NULL
;
247 mgaScreen
->linecomp_sane
= (sPriv
->ddxMajor
> 1) || (sPriv
->ddxMinor
> 1)
248 || ((sPriv
->ddxMinor
== 1) && (sPriv
->ddxPatch
> 0));
250 if ( driCompareGLXAPIVersion( 20030813 ) >= 0 ) {
251 PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension
=
252 (PFNGLXSCRENABLEEXTENSIONPROC
) glXGetProcAddress( (const GLubyte
*) "__glXScrEnableExtension" );
253 void * const psc
= sPriv
->psc
->screenConfigs
;
255 if ( glx_enable_extension
!= NULL
) {
256 if ( mgaScreen
->linecomp_sane
) {
257 (*glx_enable_extension
)( psc
, "GLX_SGI_swap_control" );
258 (*glx_enable_extension
)( psc
, "GLX_SGI_video_sync" );
259 (*glx_enable_extension
)( psc
, "GLX_MESA_swap_control" );
262 (*glx_enable_extension
)( psc
, "GLX_SGI_make_current_read" );
263 (*glx_enable_extension
)( psc
, "GLX_MESA_swap_frame_usage" );
265 if ( driCompareGLXAPIVersion( 20030915 ) >= 0 ) {
266 (*glx_enable_extension
)( psc
, "GLX_SGIX_fbconfig" );
267 (*glx_enable_extension
)( psc
, "GLX_OML_swap_method" );
273 if (serverInfo
->chipset
!= MGA_CARD_TYPE_G200
&&
274 serverInfo
->chipset
!= MGA_CARD_TYPE_G400
) {
276 sPriv
->private = NULL
;
277 __driUtilMessage("Unrecognized chipset");
282 mgaScreen
->chipset
= serverInfo
->chipset
;
283 mgaScreen
->width
= serverInfo
->width
;
284 mgaScreen
->height
= serverInfo
->height
;
285 mgaScreen
->mem
= serverInfo
->mem
;
286 mgaScreen
->cpp
= serverInfo
->cpp
;
288 mgaScreen
->agpMode
= serverInfo
->agpMode
;
290 mgaScreen
->frontPitch
= serverInfo
->frontPitch
;
291 mgaScreen
->frontOffset
= serverInfo
->frontOffset
;
292 mgaScreen
->backOffset
= serverInfo
->backOffset
;
293 mgaScreen
->backPitch
= serverInfo
->backPitch
;
294 mgaScreen
->depthOffset
= serverInfo
->depthOffset
;
295 mgaScreen
->depthPitch
= serverInfo
->depthPitch
;
297 mgaScreen
->mmio
.handle
= serverInfo
->registers
.handle
;
298 mgaScreen
->mmio
.size
= serverInfo
->registers
.size
;
299 if ( drmMap( sPriv
->fd
,
300 mgaScreen
->mmio
.handle
, mgaScreen
->mmio
.size
,
301 &mgaScreen
->mmio
.map
) < 0 ) {
303 sPriv
->private = NULL
;
304 __driUtilMessage( "Couldn't map MMIO registers" );
308 mgaScreen
->primary
.handle
= serverInfo
->primary
.handle
;
309 mgaScreen
->primary
.size
= serverInfo
->primary
.size
;
310 mgaScreen
->buffers
.handle
= serverInfo
->buffers
.handle
;
311 mgaScreen
->buffers
.size
= serverInfo
->buffers
.size
;
314 mgaScreen
->agp
.handle
= serverInfo
->agp
;
315 mgaScreen
->agp
.size
= serverInfo
->agpSize
;
317 if (drmMap(sPriv
->fd
,
318 mgaScreen
->agp
.handle
,
320 (drmAddress
*)&mgaScreen
->agp
.map
) != 0)
323 sPriv
->private = NULL
;
324 __driUtilMessage("Couldn't map agp region");
329 mgaScreen
->textureOffset
[MGA_CARD_HEAP
] = serverInfo
->textureOffset
;
330 mgaScreen
->textureOffset
[MGA_AGP_HEAP
] = (serverInfo
->agpTextureOffset
|
331 PDEA_pagpxfer_enable
| 1);
333 mgaScreen
->textureSize
[MGA_CARD_HEAP
] = serverInfo
->textureSize
;
334 mgaScreen
->textureSize
[MGA_AGP_HEAP
] = serverInfo
->agpTextureSize
;
336 mgaScreen
->logTextureGranularity
[MGA_CARD_HEAP
] =
337 serverInfo
->logTextureGranularity
;
338 mgaScreen
->logTextureGranularity
[MGA_AGP_HEAP
] =
339 serverInfo
->logAgpTextureGranularity
;
341 mgaScreen
->texVirtual
[MGA_CARD_HEAP
] = (char *)(mgaScreen
->sPriv
->pFB
+
342 serverInfo
->textureOffset
);
343 if (drmMap(sPriv
->fd
,
344 serverInfo
->agpTextureOffset
,
345 serverInfo
->agpTextureSize
,
346 (drmAddress
*)&mgaScreen
->texVirtual
[MGA_AGP_HEAP
]) != 0)
349 sPriv
->private = NULL
;
350 __driUtilMessage("Couldn't map agptexture region");
355 mgaScreen
->texVirtual
[MGA_AGP_HEAP
] = (mgaScreen
->agp
.map
+
356 serverInfo
->agpTextureOffset
);
359 mgaScreen
->mAccess
= serverInfo
->mAccess
;
361 /* For calculating setupdma addresses.
363 mgaScreen
->dmaOffset
= serverInfo
->buffers
.handle
;
365 mgaScreen
->bufs
= drmMapBufs(sPriv
->fd
);
366 if (!mgaScreen
->bufs
) {
367 /*drmUnmap(mgaScreen->agp_tex.map, mgaScreen->agp_tex.size);*/
369 sPriv
->private = NULL
;
370 __driUtilMessage("Couldn't map dma buffers");
373 mgaScreen
->sarea_priv_offset
= serverInfo
->sarea_priv_offset
;
375 /* parse information in __driConfigOptions */
376 driParseOptionInfo (&mgaScreen
->optionCache
,
377 __driConfigOptions
, __driNConfigOptions
);
384 mgaDestroyScreen(__DRIscreenPrivate
*sPriv
)
386 mgaScreenPrivate
*mgaScreen
= (mgaScreenPrivate
*) sPriv
->private;
388 if (MGA_DEBUG
&DEBUG_VERBOSE_DRI
)
389 fprintf(stderr
, "mgaDestroyScreen\n");
391 /*drmUnmap(mgaScreen->agp_tex.map, mgaScreen->agp_tex.size);*/
393 /* free all option information */
394 driDestroyOptionInfo (&mgaScreen
->optionCache
);
397 sPriv
->private = NULL
;
401 extern const struct tnl_pipeline_stage _mga_render_stage
;
403 static const struct tnl_pipeline_stage
*mga_pipeline
[] = {
404 &_tnl_vertex_transform_stage
,
405 &_tnl_normal_transform_stage
,
406 &_tnl_lighting_stage
,
407 &_tnl_fog_coordinate_stage
,
409 &_tnl_texture_transform_stage
,
410 /* REMOVE: point attenuation stage */
412 &_mga_render_stage
, /* ADD: unclipped rastersetup-to-dma */
413 /* Need new ioctl for wacceptseq */
420 static const char * const g400_extensions
[] =
422 "GL_ARB_multitexture",
423 "GL_ARB_texture_env_add",
424 "GL_ARB_texture_env_combine",
425 "GL_ARB_texture_env_crossbar",
426 "GL_EXT_texture_env_combine",
427 "GL_EXT_texture_edge_clamp",
428 "GL_ATI_texture_env_combine3",
429 #if defined (MESA_packed_depth_stencil)
430 "GL_MESA_packed_depth_stencil",
435 static const char * const card_extensions
[] =
437 "GL_ARB_multisample",
438 "GL_ARB_texture_compression",
439 "GL_EXT_blend_logic_op",
441 /* paletted_textures currently doesn't work, but we could fix them later */
443 "GL_EXT_shared_texture_palette",
444 "GL_EXT_paletted_texture",
446 "GL_EXT_secondary_color",
447 "GL_EXT_stencil_wrap",
448 "GL_EXT_texture_rectangle",
449 "GL_MESA_ycbcr_texture",
450 "GL_SGIS_generate_mipmap",
451 "GL_SGIS_texture_lod",
455 static const struct dri_debug_control debug_control
[] =
457 { "fall", DEBUG_VERBOSE_FALLBACK
},
458 { "tex", DEBUG_VERBOSE_TEXTURE
},
459 { "ioctl", DEBUG_VERBOSE_IOCTL
},
460 { "verb", DEBUG_VERBOSE_MSG
},
461 { "dri", DEBUG_VERBOSE_DRI
},
467 get_ust_nop( int64_t * ust
)
475 mgaCreateContext( const __GLcontextModes
*mesaVis
,
476 __DRIcontextPrivate
*driContextPriv
,
477 void *sharedContextPrivate
)
481 GLcontext
*ctx
, *shareCtx
;
483 __DRIscreenPrivate
*sPriv
= driContextPriv
->driScreenPriv
;
484 mgaScreenPrivate
*mgaScreen
= (mgaScreenPrivate
*)sPriv
->private;
485 MGASAREAPrivPtr saPriv
=(MGASAREAPrivPtr
)(((char*)sPriv
->pSAREA
)+
486 mgaScreen
->sarea_priv_offset
);
487 struct dd_function_table functions
;
489 if (MGA_DEBUG
&DEBUG_VERBOSE_DRI
)
490 fprintf(stderr
, "mgaCreateContext\n");
492 /* allocate mga context */
493 mmesa
= (mgaContextPtr
) CALLOC(sizeof(mgaContext
));
498 /* Init default driver functions then plug in our Radeon-specific functions
499 * (the texture functions are especially important)
501 _mesa_init_driver_functions( &functions
);
502 mgaInitDriverFuncs( &functions
);
503 mgaInitTextureFuncs( &functions
);
504 mgaInitIoctlFuncs( &functions
);
506 /* Allocate the Mesa context */
507 if (sharedContextPrivate
)
508 shareCtx
= ((mgaContextPtr
) sharedContextPrivate
)->glCtx
;
511 mmesa
->glCtx
= _mesa_create_context(mesaVis
, shareCtx
,
512 &functions
, (void *) mmesa
);
517 driContextPriv
->driverPrivate
= mmesa
;
520 mmesa
->hHWContext
= driContextPriv
->hHWContext
;
521 mmesa
->driFd
= sPriv
->fd
;
522 mmesa
->driHwLock
= &sPriv
->pSAREA
->lock
;
524 mmesa
->mgaScreen
= mgaScreen
;
525 mmesa
->driScreen
= sPriv
;
526 mmesa
->sarea
= (void *)saPriv
;
528 /* Parse configuration files */
529 driParseConfigFiles (&mmesa
->optionCache
, &mgaScreen
->optionCache
,
530 sPriv
->myNum
, "mga");
532 (void) memset( mmesa
->texture_heaps
, 0, sizeof( mmesa
->texture_heaps
) );
533 make_empty_list( & mmesa
->swapped
);
535 mmesa
->nr_heaps
= mgaScreen
->texVirtual
[MGA_AGP_HEAP
] ? 2 : 1;
536 for ( i
= 0 ; i
< mmesa
->nr_heaps
; i
++ ) {
537 mmesa
->texture_heaps
[i
] = driCreateTextureHeap( i
, mmesa
,
538 mgaScreen
->textureSize
[i
],
541 mmesa
->sarea
->texList
[i
],
542 & mmesa
->sarea
->texAge
[i
],
544 sizeof( mgaTextureObject_t
),
545 (destroy_texture_object_t
*) mgaDestroyTexObj
);
548 /* Set the maximum texture size small enough that we can guarentee
549 * that both texture units can bind a maximal texture and have them
550 * on the card at once.
553 if ( mgaScreen
->chipset
== MGA_CARD_TYPE_G200
) {
554 ctx
->Const
.MaxTextureUnits
= 1;
555 ctx
->Const
.MaxTextureImageUnits
= 1;
556 ctx
->Const
.MaxTextureCoordUnits
= 1;
557 maxlevels
= G200_TEX_MAXLEVELS
;
561 ctx
->Const
.MaxTextureUnits
= 2;
562 ctx
->Const
.MaxTextureImageUnits
= 2;
563 ctx
->Const
.MaxTextureCoordUnits
= 2;
564 maxlevels
= G400_TEX_MAXLEVELS
;
567 driCalculateMaxTextureLevels( mmesa
->texture_heaps
,
571 11, /* max 2D texture size is 2048x2048 */
572 0, /* 3D textures unsupported. */
573 0, /* cube textures unsupported. */
574 11, /* max texture rect size is 2048x2048 */
578 ctx
->Const
.MinLineWidth
= 1.0;
579 ctx
->Const
.MinLineWidthAA
= 1.0;
580 ctx
->Const
.MaxLineWidth
= 10.0;
581 ctx
->Const
.MaxLineWidthAA
= 10.0;
582 ctx
->Const
.LineWidthGranularity
= 1.0;
584 mmesa
->texture_depth
= driQueryOptioni (&mmesa
->optionCache
,
586 if (mmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FB
)
587 mmesa
->texture_depth
= ( mesaVis
->rgbBits
>= 24 ) ?
588 DRI_CONF_TEXTURE_DEPTH_32
: DRI_CONF_TEXTURE_DEPTH_16
;
589 mmesa
->hw_stencil
= mesaVis
->stencilBits
&& mesaVis
->depthBits
== 24;
591 switch (mesaVis
->depthBits
) {
593 mmesa
->depth_scale
= 1.0/(GLdouble
)0xffff;
594 mmesa
->depth_clear_mask
= ~0;
595 mmesa
->ClearDepth
= 0xffff;
598 mmesa
->depth_scale
= 1.0/(GLdouble
)0xffffff;
599 if (mmesa
->hw_stencil
) {
600 mmesa
->depth_clear_mask
= 0xffffff00;
601 mmesa
->stencil_clear_mask
= 0x000000ff;
603 mmesa
->depth_clear_mask
= ~0;
604 mmesa
->ClearDepth
= 0xffffff00;
607 mmesa
->depth_scale
= 1.0/(GLdouble
)0xffffffff;
608 mmesa
->depth_clear_mask
= ~0;
609 mmesa
->ClearDepth
= 0xffffffff;
613 mmesa
->haveHwStipple
= GL_FALSE
;
614 mmesa
->RenderIndex
= -1; /* impossible value */
616 mmesa
->vertex_format
= 0;
617 mmesa
->CurrentTexObj
[0] = 0;
618 mmesa
->CurrentTexObj
[1] = 0;
619 mmesa
->tmu_source
[0] = 0;
620 mmesa
->tmu_source
[1] = 1;
622 mmesa
->texAge
[0] = 0;
623 mmesa
->texAge
[1] = 0;
625 /* Initialize the software rasterizer and helper modules.
627 _swrast_CreateContext( ctx
);
628 _ac_CreateContext( ctx
);
629 _tnl_CreateContext( ctx
);
631 _swsetup_CreateContext( ctx
);
633 /* Install the customized pipeline:
635 _tnl_destroy_pipeline( ctx
);
636 _tnl_install_pipeline( ctx
, mga_pipeline
);
638 /* Configure swrast and T&L to match hardware characteristics:
640 _swrast_allow_pixel_fog( ctx
, GL_FALSE
);
641 _swrast_allow_vertex_fog( ctx
, GL_TRUE
);
642 _tnl_allow_pixel_fog( ctx
, GL_FALSE
);
643 _tnl_allow_vertex_fog( ctx
, GL_TRUE
);
645 mmesa
->primary_offset
= mmesa
->mgaScreen
->primary
.handle
;
647 ctx
->DriverCtx
= (void *) mmesa
;
650 driInitExtensions( ctx
, card_extensions
, GL_FALSE
);
652 if (MGA_IS_G400(MGA_CONTEXT(ctx
))) {
653 driInitExtensions( ctx
, g400_extensions
, GL_FALSE
);
656 /* XXX these should really go right after _mesa_init_driver_functions() */
657 mgaDDInitStateFuncs( ctx
);
658 mgaDDInitSpanFuncs( ctx
);
659 mgaDDInitPixelFuncs( ctx
);
660 mgaDDInitTriFuncs( ctx
);
663 mgaInitState( mmesa
);
665 driContextPriv
->driverPrivate
= (void *) mmesa
;
668 MGA_DEBUG
= driParseDebugString( getenv( "MGA_DEBUG" ),
672 mmesa
->vblank_flags
= ((mmesa
->mgaScreen
->irq
== 0)
673 || !mmesa
->mgaScreen
->linecomp_sane
)
674 ? VBLANK_FLAG_NO_IRQ
: driGetDefaultVBlankFlags(&mmesa
->optionCache
);
676 mmesa
->get_ust
= (PFNGLXGETUSTPROC
) glXGetProcAddress( (const GLubyte
*) "__glXGetUST" );
677 if ( mmesa
->get_ust
== NULL
) {
678 mmesa
->get_ust
= get_ust_nop
;
681 mmesa
->get_ust
= get_ust_nop
;
684 (*mmesa
->get_ust
)( & mmesa
->swap_ust
);
690 mgaDestroyContext(__DRIcontextPrivate
*driContextPriv
)
692 mgaContextPtr mmesa
= (mgaContextPtr
) driContextPriv
->driverPrivate
;
694 if (MGA_DEBUG
&DEBUG_VERBOSE_DRI
)
695 fprintf( stderr
, "[%s:%d] mgaDestroyContext start\n",
696 __FILE__
, __LINE__
);
698 assert(mmesa
); /* should never be null */
700 GLboolean release_texture_heaps
;
703 release_texture_heaps
= (mmesa
->glCtx
->Shared
->RefCount
== 1);
704 _swsetup_DestroyContext( mmesa
->glCtx
);
705 _tnl_DestroyContext( mmesa
->glCtx
);
706 _ac_DestroyContext( mmesa
->glCtx
);
707 _swrast_DestroyContext( mmesa
->glCtx
);
709 mgaFreeVB( mmesa
->glCtx
);
711 /* free the Mesa context */
712 mmesa
->glCtx
->DriverCtx
= NULL
;
713 _mesa_destroy_context(mmesa
->glCtx
);
715 if ( release_texture_heaps
) {
716 /* This share group is about to go away, free our private
717 * texture object data.
721 for ( i
= 0 ; i
< mmesa
->nr_heaps
; i
++ ) {
722 driDestroyTextureHeap( mmesa
->texture_heaps
[ i
] );
723 mmesa
->texture_heaps
[ i
] = NULL
;
726 assert( is_empty_list( & mmesa
->swapped
) );
729 /* free the option cache */
730 driDestroyOptionCache (&mmesa
->optionCache
);
735 if (MGA_DEBUG
&DEBUG_VERBOSE_DRI
)
736 fprintf( stderr
, "[%s:%d] mgaDestroyContext done\n",
737 __FILE__
, __LINE__
);
742 mgaCreateBuffer( __DRIscreenPrivate
*driScrnPriv
,
743 __DRIdrawablePrivate
*driDrawPriv
,
744 const __GLcontextModes
*mesaVis
,
748 return GL_FALSE
; /* not implemented */
751 GLboolean swStencil
= (mesaVis
->stencilBits
> 0 &&
752 mesaVis
->depthBits
!= 24);
754 driDrawPriv
->driverPrivate
= (void *)
755 _mesa_create_framebuffer(mesaVis
,
756 GL_FALSE
, /* software depth buffer? */
758 mesaVis
->accumRedBits
> 0,
759 mesaVis
->alphaBits
> 0 );
761 return (driDrawPriv
->driverPrivate
!= NULL
);
767 mgaDestroyBuffer(__DRIdrawablePrivate
*driDrawPriv
)
769 _mesa_destroy_framebuffer((GLframebuffer
*) (driDrawPriv
->driverPrivate
));
773 mgaSwapBuffers(__DRIdrawablePrivate
*dPriv
)
775 if (dPriv
->driContextPriv
&& dPriv
->driContextPriv
->driverPrivate
) {
778 mmesa
= (mgaContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
781 if (ctx
->Visual
.doubleBufferMode
) {
782 _mesa_notifySwapBuffers( ctx
);
783 mgaCopyBuffer( dPriv
);
786 /* XXX this shouldn't be an error but we can't handle it for now */
787 _mesa_problem(NULL
, "%s: drawable has no context!\n", __FUNCTION__
);
792 mgaUnbindContext(__DRIcontextPrivate
*driContextPriv
)
794 mgaContextPtr mmesa
= (mgaContextPtr
) driContextPriv
->driverPrivate
;
802 mgaOpenCloseFullScreen(__DRIcontextPrivate
*driContextPriv
)
808 /* This looks buggy to me - the 'b' variable isn't used anywhere...
809 * Hmm - It seems that the drawable is already hooked in to
812 * But why are we doing context initialization here???
815 mgaMakeCurrent(__DRIcontextPrivate
*driContextPriv
,
816 __DRIdrawablePrivate
*driDrawPriv
,
817 __DRIdrawablePrivate
*driReadPriv
)
819 if (driContextPriv
) {
820 mgaContextPtr mmesa
= (mgaContextPtr
) driContextPriv
->driverPrivate
;
822 if (mmesa
->driDrawable
!= driDrawPriv
) {
823 driDrawableInitVBlank( driDrawPriv
, mmesa
->vblank_flags
);
824 mmesa
->driDrawable
= driDrawPriv
;
826 mmesa
->dirty_cliprects
= (MGA_FRONT
|MGA_BACK
);
827 mmesa
->mesa_drawable
= driDrawPriv
;
830 mmesa
->driReadable
= driReadPriv
;
832 _mesa_make_current2(mmesa
->glCtx
,
833 (GLframebuffer
*) driDrawPriv
->driverPrivate
,
834 (GLframebuffer
*) driReadPriv
->driverPrivate
);
836 if (!mmesa
->glCtx
->Viewport
.Width
)
837 _mesa_set_viewport(mmesa
->glCtx
, 0, 0,
838 driDrawPriv
->w
, driDrawPriv
->h
);
842 _mesa_make_current(NULL
, NULL
);
849 void mgaGetLock( mgaContextPtr mmesa
, GLuint flags
)
851 __DRIdrawablePrivate
*dPriv
= mmesa
->driDrawable
;
852 MGASAREAPrivPtr sarea
= mmesa
->sarea
;
853 int me
= mmesa
->hHWContext
;
856 drmGetLock(mmesa
->driFd
, mmesa
->hHWContext
, flags
);
858 if (*(dPriv
->pStamp
) != mmesa
->lastStamp
) {
859 mmesa
->lastStamp
= *(dPriv
->pStamp
);
860 mmesa
->SetupNewInputs
|= VERT_BIT_POS
;
861 mmesa
->dirty_cliprects
= (MGA_FRONT
|MGA_BACK
);
862 mgaUpdateRects( mmesa
, (MGA_FRONT
|MGA_BACK
) );
865 mmesa
->dirty
|= MGA_UPLOAD_CONTEXT
| MGA_UPLOAD_CLIPRECTS
;
867 mmesa
->sarea
->dirty
|= MGA_UPLOAD_CONTEXT
;
869 if (sarea
->ctxOwner
!= me
) {
870 mmesa
->dirty
|= (MGA_UPLOAD_CONTEXT
| MGA_UPLOAD_TEX0
|
871 MGA_UPLOAD_TEX1
| MGA_UPLOAD_PIPE
);
875 for ( i
= 0 ; i
< mmesa
->nr_heaps
; i
++ ) {
876 DRI_AGE_TEXTURES( mmesa
->texture_heaps
[ i
] );
879 sarea
->last_quiescent
= -1; /* just kill it for now */
883 static const struct __DriverAPIRec mgaAPI
= {
884 .InitDriver
= mgaInitDriver
,
885 .DestroyScreen
= mgaDestroyScreen
,
886 .CreateContext
= mgaCreateContext
,
887 .DestroyContext
= mgaDestroyContext
,
888 .CreateBuffer
= mgaCreateBuffer
,
889 .DestroyBuffer
= mgaDestroyBuffer
,
890 .SwapBuffers
= mgaSwapBuffers
,
891 .MakeCurrent
= mgaMakeCurrent
,
892 .UnbindContext
= mgaUnbindContext
,
893 .OpenFullScreen
= mgaOpenCloseFullScreen
,
894 .CloseFullScreen
= mgaOpenCloseFullScreen
,
895 .GetSwapInfo
= getSwapInfo
,
896 .GetMSC
= driGetMSC32
,
897 .WaitForMSC
= driWaitForMSC32
,
899 .SwapBuffersMSC
= NULL
904 * This is the bootstrap function for the driver.
905 * The __driCreateScreen name is the symbol that libGL.so fetches.
906 * Return: pointer to a __DRIscreenPrivate.
909 void *__driCreateScreen(Display
*dpy
, int scrn
, __DRIscreen
*psc
,
910 int numConfigs
, __GLXvisualConfig
*config
)
912 __DRIscreenPrivate
*psp
;
913 psp
= __driUtilCreateScreen(dpy
, scrn
, psc
, numConfigs
, config
, &mgaAPI
);
917 void *__driCreateScreen(struct DRIDriverRec
*driver
,
918 struct DRIDriverContextRec
*driverContext
)
920 __DRIscreenPrivate
*psp
;
921 psp
= __driUtilCreateScreen(driver
, driverContext
, &mgaAPI
);
928 * This is the bootstrap function for the driver. libGL supplies all of the
929 * requisite information about the system, and the driver initializes itself.
930 * This routine also fills in the linked list pointed to by \c driver_modes
931 * with the \c __GLcontextModes that the driver can support for windows or
934 * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
937 #ifdef USE_NEW_INTERFACE
938 void * __driCreateNewScreen( Display
*dpy
, int scrn
, __DRIscreen
*psc
,
939 const __GLcontextModes
* modes
,
940 const __DRIversion
* ddx_version
,
941 const __DRIversion
* dri_version
,
942 const __DRIversion
* drm_version
,
943 const __DRIframebuffer
* frame_buffer
,
944 drmAddress pSAREA
, int fd
,
945 int internal_api_version
,
946 __GLcontextModes
** driver_modes
)
949 __DRIscreenPrivate
*psp
;
951 psp
= __driUtilCreateNewScreen(dpy
, scrn
, psc
, NULL
,
952 ddx_version
, dri_version
, drm_version
,
953 frame_buffer
, pSAREA
, fd
,
954 internal_api_version
, &mgaAPI
);
957 create_context_modes
=
958 (PFNGLXCREATECONTEXTMODES
) glXGetProcAddress( (const GLubyte
*) "__glXCreateContextModes" );
959 if ( create_context_modes
!= NULL
) {
960 MGADRIPtr dri_priv
= (MGADRIPtr
) psp
->pDevPriv
;
961 *driver_modes
= mgaFillInModes( dri_priv
->cpp
* 8,
962 (dri_priv
->cpp
== 2) ? 16 : 24,
963 (dri_priv
->cpp
== 2) ? 0 : 8,
964 (dri_priv
->backOffset
!= dri_priv
->depthOffset
) );
969 #endif /* USE_NEW_INTERFACE */
973 * Get information about previous buffer swaps.
976 getSwapInfo( __DRIdrawablePrivate
*dPriv
, __DRIswapInfo
* sInfo
)
980 if ( (dPriv
== NULL
) || (dPriv
->driContextPriv
== NULL
)
981 || (dPriv
->driContextPriv
->driverPrivate
== NULL
)
982 || (sInfo
== NULL
) ) {
986 mmesa
= (mgaContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
987 sInfo
->swap_count
= mmesa
->swap_count
;
988 sInfo
->swap_ust
= mmesa
->swap_ust
;
989 sInfo
->swap_missed_count
= mmesa
->swap_missed_count
;
991 sInfo
->swap_missed_usage
= (sInfo
->swap_missed_count
!= 0)
992 ? driCalculateSwapUsage( dPriv
, 0, mmesa
->swap_missed_ust
)