2 * Copyright 2000-2001 VA Linux Systems, Inc.
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 * on the rights to use, copy, modify, merge, publish, distribute, sub
9 * license, and/or sell copies of the Software, and to permit persons to whom
10 * the Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
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 * VA LINUX SYSTEMS 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
22 * OTHER DEALINGS IN THE SOFTWARE.
27 * MGA screen and context initialization / creation code.
29 * \author Keith Whitwell <keith@tungstengraphics.com>
36 #include "mga_xmesa.h"
37 #include "main/context.h"
38 #include "main/simple_list.h"
39 #include "main/imports.h"
40 #include "main/framebuffer.h"
41 #include "main/renderbuffer.h"
43 #include "swrast/swrast.h"
44 #include "swrast_setup/swrast_setup.h"
48 #include "tnl/t_pipeline.h"
50 #include "drivers/common/driverfuncs.h"
60 #include "mga_xmesa.h"
66 #include "drirenderbuffer.h"
68 #include "GL/internal/dri_interface.h"
70 #define need_GL_ARB_vertex_program
71 #define need_GL_EXT_fog_coord
72 #define need_GL_EXT_gpu_program_parameters
73 #define need_GL_EXT_secondary_color
75 #define need_GL_EXT_paletted_texture
77 #define need_GL_APPLE_vertex_array_object
78 #define need_GL_NV_vertex_program
79 #include "main/remap_helper.h"
85 PUBLIC
const char __driConfigOptions
[] =
87 DRI_CONF_SECTION_PERFORMANCE
88 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0
)
90 DRI_CONF_SECTION_QUALITY
91 DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB
)
92 DRI_CONF_COLOR_REDUCTION(DRI_CONF_COLOR_REDUCTION_DITHER
)
94 DRI_CONF_SECTION_SOFTWARE
95 DRI_CONF_ARB_VERTEX_PROGRAM(true)
96 DRI_CONF_NV_VERTEX_PROGRAM(true)
98 DRI_CONF_SECTION_DEBUG
99 DRI_CONF_NO_RAST(false)
102 static const GLuint __driNConfigOptions
= 6;
108 static const __DRIconfig
**
109 mgaFillInModes( __DRIscreen
*psp
,
110 unsigned pixel_bits
, unsigned depth_bits
,
111 unsigned stencil_bits
, GLboolean have_back_buffer
)
113 __DRIconfig
**configs
;
114 __GLcontextModes
* m
;
115 unsigned depth_buffer_factor
;
116 unsigned back_buffer_factor
;
121 /* GLX_SWAP_COPY_OML is only supported because the MGA driver doesn't
122 * support pageflipping at all.
124 static const GLenum back_buffer_modes
[] = {
125 GLX_NONE
, GLX_SWAP_UNDEFINED_OML
, GLX_SWAP_COPY_OML
128 uint8_t depth_bits_array
[3];
129 uint8_t stencil_bits_array
[3];
130 uint8_t msaa_samples_array
[1];
133 depth_bits_array
[0] = 0;
134 depth_bits_array
[1] = depth_bits
;
135 depth_bits_array
[2] = depth_bits
;
137 /* Just like with the accumulation buffer, always provide some modes
138 * with a stencil buffer. It will be a sw fallback, but some apps won't
141 stencil_bits_array
[0] = 0;
142 stencil_bits_array
[1] = 0;
143 stencil_bits_array
[2] = (stencil_bits
== 0) ? 8 : stencil_bits
;
145 msaa_samples_array
[0] = 0;
147 depth_buffer_factor
= ((depth_bits
!= 0) || (stencil_bits
!= 0)) ? 3 : 1;
148 back_buffer_factor
= (have_back_buffer
) ? 2 : 1;
150 if ( pixel_bits
== 16 ) {
152 fb_type
= GL_UNSIGNED_SHORT_5_6_5
;
156 fb_type
= GL_UNSIGNED_INT_8_8_8_8_REV
;
159 configs
= driCreateConfigs(fb_format
, fb_type
,
160 depth_bits_array
, stencil_bits_array
,
162 back_buffer_modes
, back_buffer_factor
,
163 msaa_samples_array
, 1, GL_TRUE
);
164 if (configs
== NULL
) {
165 fprintf( stderr
, "[%s:%u] Error creating FBConfig!\n",
166 __func__
, __LINE__
);
170 /* Mark the visual as slow if there are "fake" stencil bits.
172 for (i
= 0; configs
[i
]; i
++) {
173 m
= &configs
[i
]->modes
;
174 if ((m
->stencilBits
!= 0) && (m
->stencilBits
!= stencil_bits
)) {
175 m
->visualRating
= GLX_SLOW_CONFIG
;
179 return (const __DRIconfig
**) configs
;
182 const __DRIextension
*mgaScreenExtensions
[] = {
183 &driReadDrawableExtension
,
184 &driSwapControlExtension
.base
,
185 &driFrameTrackingExtension
.base
,
186 &driMediaStreamCounterExtension
.base
,
191 mgaInitDriver(__DRIscreen
*sPriv
)
193 mgaScreenPrivate
*mgaScreen
;
194 MGADRIPtr serverInfo
= (MGADRIPtr
)sPriv
->pDevPriv
;
196 if (sPriv
->devPrivSize
!= sizeof(MGADRIRec
)) {
197 fprintf(stderr
,"\nERROR! sizeof(MGADRIRec) does not match passed size from device driver\n");
201 /* Allocate the private area */
202 mgaScreen
= (mgaScreenPrivate
*)MALLOC(sizeof(mgaScreenPrivate
));
204 __driUtilMessage("Couldn't malloc screen struct");
208 mgaScreen
->sPriv
= sPriv
;
209 sPriv
->private = (void *)mgaScreen
;
211 if (sPriv
->drm_version
.minor
>= 1) {
213 drm_mga_getparam_t gp
;
215 gp
.param
= MGA_PARAM_IRQ_NR
;
216 gp
.value
= &mgaScreen
->irq
;
219 ret
= drmCommandWriteRead( sPriv
->fd
, DRM_MGA_GETPARAM
,
222 fprintf(stderr
, "drmMgaGetParam (MGA_PARAM_IRQ_NR): %d\n", ret
);
224 sPriv
->private = NULL
;
229 sPriv
->extensions
= mgaScreenExtensions
;
231 if (serverInfo
->chipset
!= MGA_CARD_TYPE_G200
&&
232 serverInfo
->chipset
!= MGA_CARD_TYPE_G400
) {
234 sPriv
->private = NULL
;
235 __driUtilMessage("Unrecognized chipset");
240 mgaScreen
->chipset
= serverInfo
->chipset
;
241 mgaScreen
->cpp
= serverInfo
->cpp
;
243 mgaScreen
->agpMode
= serverInfo
->agpMode
;
245 mgaScreen
->frontPitch
= serverInfo
->frontPitch
;
246 mgaScreen
->frontOffset
= serverInfo
->frontOffset
;
247 mgaScreen
->backOffset
= serverInfo
->backOffset
;
248 mgaScreen
->backPitch
= serverInfo
->backPitch
;
249 mgaScreen
->depthOffset
= serverInfo
->depthOffset
;
250 mgaScreen
->depthPitch
= serverInfo
->depthPitch
;
253 /* The only reason that the MMIO region needs to be accessable and the
254 * primary DMA region base address needs to be known is so that the driver
255 * can busy wait for certain DMA operations to complete (see
256 * mgaWaitForFrameCompletion in mgaioctl.c).
258 * Starting with MGA DRM version 3.2, these are completely unneeded as
259 * there is a new, in-kernel mechanism for handling the wait.
262 if (mgaScreen
->sPriv
->drm_version
.minor
< 2) {
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
;
278 (void) memset( & mgaScreen
->primary
, 0, sizeof( mgaScreen
->primary
) );
279 (void) memset( & mgaScreen
->mmio
, 0, sizeof( mgaScreen
->mmio
) );
282 mgaScreen
->textureOffset
[MGA_CARD_HEAP
] = serverInfo
->textureOffset
;
283 mgaScreen
->textureOffset
[MGA_AGP_HEAP
] = (serverInfo
->agpTextureOffset
|
284 PDEA_pagpxfer_enable
| 1);
286 mgaScreen
->textureSize
[MGA_CARD_HEAP
] = serverInfo
->textureSize
;
287 mgaScreen
->textureSize
[MGA_AGP_HEAP
] = serverInfo
->agpTextureSize
;
290 /* The texVirtual array stores the base addresses in the CPU's address
291 * space of the texture memory pools. The base address of the on-card
292 * memory pool is calculated as an offset of the base of video memory. The
293 * AGP texture pool has to be mapped into the processes address space by
297 mgaScreen
->texVirtual
[MGA_CARD_HEAP
] = (char *)(mgaScreen
->sPriv
->pFB
+
298 serverInfo
->textureOffset
);
300 if ( serverInfo
->agpTextureSize
> 0 ) {
301 if (drmMap(sPriv
->fd
, serverInfo
->agpTextureOffset
,
302 serverInfo
->agpTextureSize
,
303 (drmAddress
*)&mgaScreen
->texVirtual
[MGA_AGP_HEAP
]) != 0) {
305 sPriv
->private = NULL
;
306 __driUtilMessage("Couldn't map agptexture region");
312 /* For calculating setupdma addresses.
315 mgaScreen
->bufs
= drmMapBufs(sPriv
->fd
);
316 if (!mgaScreen
->bufs
) {
318 sPriv
->private = NULL
;
319 __driUtilMessage("Couldn't map dma buffers");
322 mgaScreen
->sarea_priv_offset
= serverInfo
->sarea_priv_offset
;
324 /* parse information in __driConfigOptions */
325 driParseOptionInfo (&mgaScreen
->optionCache
,
326 __driConfigOptions
, __driNConfigOptions
);
333 mgaDestroyScreen(__DRIscreen
*sPriv
)
335 mgaScreenPrivate
*mgaScreen
= (mgaScreenPrivate
*) sPriv
->private;
337 if (MGA_DEBUG
&DEBUG_VERBOSE_DRI
)
338 fprintf(stderr
, "mgaDestroyScreen\n");
340 drmUnmapBufs(mgaScreen
->bufs
);
343 /* free all option information */
344 driDestroyOptionInfo (&mgaScreen
->optionCache
);
347 sPriv
->private = NULL
;
351 extern const struct tnl_pipeline_stage _mga_render_stage
;
353 static const struct tnl_pipeline_stage
*mga_pipeline
[] = {
354 &_tnl_vertex_transform_stage
,
355 &_tnl_normal_transform_stage
,
356 &_tnl_lighting_stage
,
357 &_tnl_fog_coordinate_stage
,
359 &_tnl_texture_transform_stage
,
360 &_tnl_vertex_program_stage
,
362 /* REMOVE: point attenuation stage */
364 &_mga_render_stage
, /* ADD: unclipped rastersetup-to-dma */
365 /* Need new ioctl for wacceptseq */
372 static const struct dri_extension g400_extensions
[] =
374 { "GL_ARB_multitexture", NULL
},
375 { "GL_ARB_texture_env_add", NULL
},
376 { "GL_ARB_texture_env_combine", NULL
},
377 { "GL_ARB_texture_env_crossbar", NULL
},
378 { "GL_EXT_texture_env_combine", NULL
},
379 { "GL_EXT_texture_edge_clamp", NULL
},
380 { "GL_ATI_texture_env_combine3", NULL
},
384 static const struct dri_extension card_extensions
[] =
386 { "GL_ARB_texture_rectangle", NULL
},
387 { "GL_EXT_blend_logic_op", NULL
},
388 { "GL_EXT_fog_coord", GL_EXT_fog_coord_functions
},
389 /* paletted_textures currently doesn't work, but we could fix them later */
390 #if defined( need_GL_EXT_paletted_texture )
391 { "GL_EXT_shared_texture_palette", NULL
},
392 { "GL_EXT_paletted_texture", GL_EXT_paletted_texture_functions
},
394 { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions
},
395 { "GL_EXT_stencil_wrap", NULL
},
396 { "GL_APPLE_vertex_array_object", GL_APPLE_vertex_array_object_functions
},
397 { "GL_MESA_ycbcr_texture", NULL
},
398 { "GL_SGIS_generate_mipmap", NULL
},
402 static const struct dri_extension ARB_vp_extensions
[] = {
403 { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions
},
404 { "GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions
},
408 static const struct dri_extension NV_vp_extensions
[] = {
409 { "GL_NV_vertex_program", GL_NV_vertex_program_functions
},
410 { "GL_NV_vertex_program1_1", NULL
},
414 static const struct dri_debug_control debug_control
[] =
416 { "fall", DEBUG_VERBOSE_FALLBACK
},
417 { "tex", DEBUG_VERBOSE_TEXTURE
},
418 { "ioctl", DEBUG_VERBOSE_IOCTL
},
419 { "verb", DEBUG_VERBOSE_MSG
},
420 { "dri", DEBUG_VERBOSE_DRI
},
426 mgaCreateContext( gl_api api
,
427 const __GLcontextModes
*mesaVis
,
428 __DRIcontext
*driContextPriv
,
429 void *sharedContextPrivate
)
433 GLcontext
*ctx
, *shareCtx
;
435 __DRIscreen
*sPriv
= driContextPriv
->driScreenPriv
;
436 mgaScreenPrivate
*mgaScreen
= (mgaScreenPrivate
*)sPriv
->private;
437 drm_mga_sarea_t
*saPriv
= (drm_mga_sarea_t
*)(((char*)sPriv
->pSAREA
)+
438 mgaScreen
->sarea_priv_offset
);
439 struct dd_function_table functions
;
441 if (MGA_DEBUG
&DEBUG_VERBOSE_DRI
)
442 fprintf(stderr
, "mgaCreateContext\n");
444 /* allocate mga context */
445 mmesa
= (mgaContextPtr
) CALLOC(sizeof(mgaContext
));
450 /* Init default driver functions then plug in our Radeon-specific functions
451 * (the texture functions are especially important)
453 _mesa_init_driver_functions( &functions
);
454 mgaInitDriverFuncs( &functions
);
455 mgaInitTextureFuncs( &functions
);
456 mgaInitIoctlFuncs( &functions
);
458 /* Allocate the Mesa context */
459 if (sharedContextPrivate
)
460 shareCtx
= ((mgaContextPtr
) sharedContextPrivate
)->glCtx
;
463 mmesa
->glCtx
= _mesa_create_context(mesaVis
, shareCtx
,
464 &functions
, (void *) mmesa
);
469 driContextPriv
->driverPrivate
= mmesa
;
472 mmesa
->hHWContext
= driContextPriv
->hHWContext
;
473 mmesa
->driFd
= sPriv
->fd
;
474 mmesa
->driHwLock
= &sPriv
->pSAREA
->lock
;
476 mmesa
->mgaScreen
= mgaScreen
;
477 mmesa
->driScreen
= sPriv
;
478 mmesa
->sarea
= (void *)saPriv
;
480 /* Parse configuration files */
481 driParseConfigFiles (&mmesa
->optionCache
, &mgaScreen
->optionCache
,
482 sPriv
->myNum
, "mga");
484 (void) memset( mmesa
->texture_heaps
, 0, sizeof( mmesa
->texture_heaps
) );
485 make_empty_list( & mmesa
->swapped
);
487 mmesa
->nr_heaps
= mgaScreen
->texVirtual
[MGA_AGP_HEAP
] ? 2 : 1;
488 for ( i
= 0 ; i
< mmesa
->nr_heaps
; i
++ ) {
489 mmesa
->texture_heaps
[i
] = driCreateTextureHeap( i
, mmesa
,
490 mgaScreen
->textureSize
[i
],
493 (drmTextureRegionPtr
)mmesa
->sarea
->texList
[i
],
494 &mmesa
->sarea
->texAge
[i
],
496 sizeof( mgaTextureObject_t
),
497 (destroy_texture_object_t
*) mgaDestroyTexObj
);
500 /* Set the maximum texture size small enough that we can guarentee
501 * that both texture units can bind a maximal texture and have them
502 * on the card at once.
505 if ( mgaScreen
->chipset
== MGA_CARD_TYPE_G200
) {
506 ctx
->Const
.MaxTextureUnits
= 1;
507 ctx
->Const
.MaxTextureImageUnits
= 1;
508 ctx
->Const
.MaxTextureCoordUnits
= 1;
509 maxlevels
= G200_TEX_MAXLEVELS
;
513 ctx
->Const
.MaxTextureUnits
= 2;
514 ctx
->Const
.MaxTextureImageUnits
= 2;
515 ctx
->Const
.MaxTextureCoordUnits
= 2;
516 maxlevels
= G400_TEX_MAXLEVELS
;
519 driCalculateMaxTextureLevels( mmesa
->texture_heaps
,
523 11, /* max 2D texture size is 2048x2048 */
524 0, /* 3D textures unsupported. */
525 0, /* cube textures unsupported. */
526 11, /* max texture rect size is 2048x2048 */
531 ctx
->Const
.MinLineWidth
= 1.0;
532 ctx
->Const
.MinLineWidthAA
= 1.0;
533 ctx
->Const
.MaxLineWidth
= 10.0;
534 ctx
->Const
.MaxLineWidthAA
= 10.0;
535 ctx
->Const
.LineWidthGranularity
= 1.0;
537 ctx
->Const
.MaxDrawBuffers
= 1;
539 mmesa
->texture_depth
= driQueryOptioni (&mmesa
->optionCache
,
541 if (mmesa
->texture_depth
== DRI_CONF_TEXTURE_DEPTH_FB
)
542 mmesa
->texture_depth
= ( mesaVis
->rgbBits
>= 24 ) ?
543 DRI_CONF_TEXTURE_DEPTH_32
: DRI_CONF_TEXTURE_DEPTH_16
;
544 mmesa
->hw_stencil
= mesaVis
->stencilBits
&& mesaVis
->depthBits
== 24;
546 switch (mesaVis
->depthBits
) {
548 mmesa
->depth_scale
= 1.0/(GLdouble
)0xffff;
549 mmesa
->depth_clear_mask
= ~0;
550 mmesa
->ClearDepth
= 0xffff;
553 mmesa
->depth_scale
= 1.0/(GLdouble
)0xffffff;
554 if (mmesa
->hw_stencil
) {
555 mmesa
->depth_clear_mask
= 0xffffff00;
556 mmesa
->stencil_clear_mask
= 0x000000ff;
558 mmesa
->depth_clear_mask
= ~0;
559 mmesa
->ClearDepth
= 0xffffff00;
562 mmesa
->depth_scale
= 1.0/(GLdouble
)0xffffffff;
563 mmesa
->depth_clear_mask
= ~0;
564 mmesa
->ClearDepth
= 0xffffffff;
568 mmesa
->haveHwStipple
= GL_FALSE
;
569 mmesa
->RenderIndex
= -1; /* impossible value */
571 mmesa
->vertex_format
= 0;
572 mmesa
->CurrentTexObj
[0] = 0;
573 mmesa
->CurrentTexObj
[1] = 0;
574 mmesa
->tmu_source
[0] = 0;
575 mmesa
->tmu_source
[1] = 1;
577 mmesa
->texAge
[0] = 0;
578 mmesa
->texAge
[1] = 0;
580 /* Initialize the software rasterizer and helper modules.
582 _swrast_CreateContext( ctx
);
583 _vbo_CreateContext( ctx
);
584 _tnl_CreateContext( ctx
);
586 _swsetup_CreateContext( ctx
);
588 /* Install the customized pipeline:
590 _tnl_destroy_pipeline( ctx
);
591 _tnl_install_pipeline( ctx
, mga_pipeline
);
593 /* Configure swrast and T&L to match hardware characteristics:
595 _swrast_allow_pixel_fog( ctx
, GL_FALSE
);
596 _swrast_allow_vertex_fog( ctx
, GL_TRUE
);
597 _tnl_allow_pixel_fog( ctx
, GL_FALSE
);
598 _tnl_allow_vertex_fog( ctx
, GL_TRUE
);
600 mmesa
->primary_offset
= mmesa
->mgaScreen
->primary
.handle
;
602 ctx
->DriverCtx
= (void *) mmesa
;
605 driInitExtensions( ctx
, card_extensions
, GL_FALSE
);
607 if (MGA_IS_G400(MGA_CONTEXT(ctx
))) {
608 driInitExtensions( ctx
, g400_extensions
, GL_FALSE
);
611 if ( driQueryOptionb( &mmesa
->optionCache
, "arb_vertex_program" ) ) {
612 driInitExtensions(ctx
, ARB_vp_extensions
, GL_FALSE
);
615 if ( driQueryOptionb( &mmesa
->optionCache
, "nv_vertex_program" ) ) {
616 driInitExtensions( ctx
, NV_vp_extensions
, GL_FALSE
);
620 /* XXX these should really go right after _mesa_init_driver_functions() */
621 mgaDDInitStateFuncs( ctx
);
622 mgaDDInitSpanFuncs( ctx
);
623 mgaDDInitPixelFuncs( ctx
);
624 mgaDDInitTriFuncs( ctx
);
627 mgaInitState( mmesa
);
629 driContextPriv
->driverPrivate
= (void *) mmesa
;
632 MGA_DEBUG
= driParseDebugString( getenv( "MGA_DEBUG" ),
636 (*sPriv
->systemTime
->getUST
)( & mmesa
->swap_ust
);
638 if (driQueryOptionb(&mmesa
->optionCache
, "no_rast")) {
639 fprintf(stderr
, "disabling 3D acceleration\n");
640 FALLBACK(mmesa
->glCtx
, MGA_FALLBACK_DISABLE
, 1);
647 mgaDestroyContext(__DRIcontext
*driContextPriv
)
649 mgaContextPtr mmesa
= (mgaContextPtr
) driContextPriv
->driverPrivate
;
651 if (MGA_DEBUG
&DEBUG_VERBOSE_DRI
)
652 fprintf( stderr
, "[%s:%d] mgaDestroyContext start\n",
653 __FILE__
, __LINE__
);
655 assert(mmesa
); /* should never be null */
657 GLboolean release_texture_heaps
;
660 release_texture_heaps
= (mmesa
->glCtx
->Shared
->RefCount
== 1);
661 _swsetup_DestroyContext( mmesa
->glCtx
);
662 _tnl_DestroyContext( mmesa
->glCtx
);
663 _vbo_DestroyContext( mmesa
->glCtx
);
664 _swrast_DestroyContext( mmesa
->glCtx
);
666 mgaFreeVB( mmesa
->glCtx
);
668 /* free the Mesa context */
669 mmesa
->glCtx
->DriverCtx
= NULL
;
670 _mesa_destroy_context(mmesa
->glCtx
);
672 if ( release_texture_heaps
) {
673 /* This share group is about to go away, free our private
674 * texture object data.
678 for ( i
= 0 ; i
< mmesa
->nr_heaps
; i
++ ) {
679 driDestroyTextureHeap( mmesa
->texture_heaps
[ i
] );
680 mmesa
->texture_heaps
[ i
] = NULL
;
683 assert( is_empty_list( & mmesa
->swapped
) );
686 /* free the option cache */
687 driDestroyOptionCache (&mmesa
->optionCache
);
692 if (MGA_DEBUG
&DEBUG_VERBOSE_DRI
)
693 fprintf( stderr
, "[%s:%d] mgaDestroyContext done\n",
694 __FILE__
, __LINE__
);
699 mgaCreateBuffer( __DRIscreen
*driScrnPriv
,
700 __DRIdrawable
*driDrawPriv
,
701 const __GLcontextModes
*mesaVis
,
704 mgaScreenPrivate
*screen
= (mgaScreenPrivate
*) driScrnPriv
->private;
707 return GL_FALSE
; /* not implemented */
710 GLboolean swStencil
= (mesaVis
->stencilBits
> 0 &&
711 mesaVis
->depthBits
!= 24);
714 driDrawPriv
->driverPrivate
= (void *)
715 _mesa_create_framebuffer(mesaVis
,
716 GL_FALSE
, /* software depth buffer? */
718 mesaVis
->accumRedBits
> 0,
719 mesaVis
->alphaBits
> 0 );
721 struct gl_framebuffer
*fb
= _mesa_create_framebuffer(mesaVis
);
724 driRenderbuffer
*frontRb
725 = driNewRenderbuffer(MESA_FORMAT_ARGB8888
,
728 screen
->frontOffset
, screen
->frontPitch
,
730 mgaSetSpanFunctions(frontRb
, mesaVis
);
731 _mesa_add_renderbuffer(fb
, BUFFER_FRONT_LEFT
, &frontRb
->Base
);
734 if (mesaVis
->doubleBufferMode
) {
735 driRenderbuffer
*backRb
736 = driNewRenderbuffer(MESA_FORMAT_ARGB8888
,
739 screen
->backOffset
, screen
->backPitch
,
741 mgaSetSpanFunctions(backRb
, mesaVis
);
742 _mesa_add_renderbuffer(fb
, BUFFER_BACK_LEFT
, &backRb
->Base
);
745 if (mesaVis
->depthBits
== 16) {
746 driRenderbuffer
*depthRb
747 = driNewRenderbuffer(MESA_FORMAT_Z16
,
750 screen
->depthOffset
, screen
->depthPitch
,
752 mgaSetSpanFunctions(depthRb
, mesaVis
);
753 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, &depthRb
->Base
);
755 else if (mesaVis
->depthBits
== 24) {
756 /* XXX is this right? */
757 if (mesaVis
->stencilBits
) {
758 driRenderbuffer
*depthRb
759 = driNewRenderbuffer(MESA_FORMAT_Z24_S8
,
762 screen
->depthOffset
, screen
->depthPitch
,
764 mgaSetSpanFunctions(depthRb
, mesaVis
);
765 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, &depthRb
->Base
);
768 driRenderbuffer
*depthRb
769 = driNewRenderbuffer(MESA_FORMAT_Z32
,
772 screen
->depthOffset
, screen
->depthPitch
,
774 mgaSetSpanFunctions(depthRb
, mesaVis
);
775 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, &depthRb
->Base
);
778 else if (mesaVis
->depthBits
== 32) {
779 driRenderbuffer
*depthRb
780 = driNewRenderbuffer(MESA_FORMAT_Z32
,
783 screen
->depthOffset
, screen
->depthPitch
,
785 mgaSetSpanFunctions(depthRb
, mesaVis
);
786 _mesa_add_renderbuffer(fb
, BUFFER_DEPTH
, &depthRb
->Base
);
789 if (mesaVis
->stencilBits
> 0 && !swStencil
) {
790 driRenderbuffer
*stencilRb
791 = driNewRenderbuffer(MESA_FORMAT_S8
,
794 screen
->depthOffset
, screen
->depthPitch
,
796 mgaSetSpanFunctions(stencilRb
, mesaVis
);
797 _mesa_add_renderbuffer(fb
, BUFFER_STENCIL
, &stencilRb
->Base
);
800 _mesa_add_soft_renderbuffers(fb
,
801 GL_FALSE
, /* color */
802 GL_FALSE
, /* depth */
804 mesaVis
->accumRedBits
> 0,
805 GL_FALSE
, /* alpha */
807 driDrawPriv
->driverPrivate
= (void *) fb
;
810 return (driDrawPriv
->driverPrivate
!= NULL
);
816 mgaDestroyBuffer(__DRIdrawable
*driDrawPriv
)
818 _mesa_reference_framebuffer((GLframebuffer
**)(&(driDrawPriv
->driverPrivate
)), NULL
);
822 mgaSwapBuffers(__DRIdrawable
*dPriv
)
824 if (dPriv
->driContextPriv
&& dPriv
->driContextPriv
->driverPrivate
) {
827 mmesa
= (mgaContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
830 if (ctx
->Visual
.doubleBufferMode
) {
831 _mesa_notifySwapBuffers( ctx
);
832 mgaCopyBuffer( dPriv
);
835 /* XXX this shouldn't be an error but we can't handle it for now */
836 _mesa_problem(NULL
, "%s: drawable has no context!\n", __FUNCTION__
);
841 mgaUnbindContext(__DRIcontext
*driContextPriv
)
843 mgaContextPtr mmesa
= (mgaContextPtr
) driContextPriv
->driverPrivate
;
850 /* This looks buggy to me - the 'b' variable isn't used anywhere...
851 * Hmm - It seems that the drawable is already hooked in to
854 * But why are we doing context initialization here???
857 mgaMakeCurrent(__DRIcontext
*driContextPriv
,
858 __DRIdrawable
*driDrawPriv
,
859 __DRIdrawable
*driReadPriv
)
861 if (driContextPriv
) {
862 mgaContextPtr mmesa
= (mgaContextPtr
) driContextPriv
->driverPrivate
;
864 if (mmesa
->driDrawable
!= driDrawPriv
) {
865 if (driDrawPriv
->swap_interval
== (unsigned)-1) {
866 driDrawPriv
->vblFlags
= (mmesa
->mgaScreen
->irq
== 0)
868 : driGetDefaultVBlankFlags(&mmesa
->optionCache
);
870 driDrawableInitVBlank( driDrawPriv
);
873 mmesa
->driDrawable
= driDrawPriv
;
875 mmesa
->dirty_cliprects
= (MGA_FRONT
|MGA_BACK
);
878 mmesa
->driReadable
= driReadPriv
;
880 _mesa_make_current(mmesa
->glCtx
,
881 (GLframebuffer
*) driDrawPriv
->driverPrivate
,
882 (GLframebuffer
*) driReadPriv
->driverPrivate
);
885 _mesa_make_current(NULL
, NULL
, NULL
);
892 void mgaGetLock( mgaContextPtr mmesa
, GLuint flags
)
894 __DRIdrawable
*dPriv
= mmesa
->driDrawable
;
895 drm_mga_sarea_t
*sarea
= mmesa
->sarea
;
896 int me
= mmesa
->hHWContext
;
899 drmGetLock(mmesa
->driFd
, mmesa
->hHWContext
, flags
);
901 DRI_VALIDATE_DRAWABLE_INFO( mmesa
->driScreen
, dPriv
);
902 if (*(dPriv
->pStamp
) != mmesa
->lastStamp
) {
903 mmesa
->lastStamp
= *(dPriv
->pStamp
);
904 mmesa
->SetupNewInputs
|= VERT_BIT_POS
;
905 mmesa
->dirty_cliprects
= (MGA_FRONT
|MGA_BACK
);
906 mgaUpdateRects( mmesa
, (MGA_FRONT
|MGA_BACK
) );
907 driUpdateFramebufferSize(mmesa
->glCtx
, dPriv
);
910 mmesa
->dirty
|= MGA_UPLOAD_CONTEXT
| MGA_UPLOAD_CLIPRECTS
;
912 mmesa
->sarea
->dirty
|= MGA_UPLOAD_CONTEXT
;
914 if (sarea
->ctxOwner
!= me
) {
915 mmesa
->dirty
|= (MGA_UPLOAD_CONTEXT
| MGA_UPLOAD_TEX0
|
916 MGA_UPLOAD_TEX1
| MGA_UPLOAD_PIPE
);
920 for ( i
= 0 ; i
< mmesa
->nr_heaps
; i
++ ) {
921 DRI_AGE_TEXTURES( mmesa
->texture_heaps
[ i
] );
927 * This is the driver specific part of the createNewScreen entry point.
929 * \todo maybe fold this into intelInitDriver
931 * \return the __GLcontextModes supported by this driver
933 static const __DRIconfig
**mgaInitScreen(__DRIscreen
*psp
)
935 static const __DRIversion ddx_expected
= { 1, 2, 0 };
936 static const __DRIversion dri_expected
= { 4, 0, 0 };
937 static const __DRIversion drm_expected
= { 3, 0, 0 };
938 MGADRIPtr dri_priv
= (MGADRIPtr
) psp
->pDevPriv
;
940 if ( ! driCheckDriDdxDrmVersions2( "MGA",
941 &psp
->dri_version
, & dri_expected
,
942 &psp
->ddx_version
, & ddx_expected
,
943 &psp
->drm_version
, & drm_expected
) )
947 if (!mgaInitDriver(psp
))
950 return mgaFillInModes( psp
,
952 (dri_priv
->cpp
== 2) ? 16 : 24,
953 (dri_priv
->cpp
== 2) ? 0 : 8,
954 (dri_priv
->backOffset
!= dri_priv
->depthOffset
) );
959 * Get information about previous buffer swaps.
962 getSwapInfo( __DRIdrawable
*dPriv
, __DRIswapInfo
* sInfo
)
966 if ( (dPriv
== NULL
) || (dPriv
->driContextPriv
== NULL
)
967 || (dPriv
->driContextPriv
->driverPrivate
== NULL
)
968 || (sInfo
== NULL
) ) {
972 mmesa
= (mgaContextPtr
) dPriv
->driContextPriv
->driverPrivate
;
973 sInfo
->swap_count
= mmesa
->swap_count
;
974 sInfo
->swap_ust
= mmesa
->swap_ust
;
975 sInfo
->swap_missed_count
= mmesa
->swap_missed_count
;
977 sInfo
->swap_missed_usage
= (sInfo
->swap_missed_count
!= 0)
978 ? driCalculateSwapUsage( dPriv
, 0, mmesa
->swap_missed_ust
)
984 const struct __DriverAPIRec driDriverAPI
= {
985 .InitScreen
= mgaInitScreen
,
986 .DestroyScreen
= mgaDestroyScreen
,
987 .CreateContext
= mgaCreateContext
,
988 .DestroyContext
= mgaDestroyContext
,
989 .CreateBuffer
= mgaCreateBuffer
,
990 .DestroyBuffer
= mgaDestroyBuffer
,
991 .SwapBuffers
= mgaSwapBuffers
,
992 .MakeCurrent
= mgaMakeCurrent
,
993 .UnbindContext
= mgaUnbindContext
,
994 .GetSwapInfo
= getSwapInfo
,
995 .GetDrawableMSC
= driDrawableGetMSC32
,
996 .WaitForMSC
= driWaitForMSC32
,
998 .SwapBuffersMSC
= NULL
1001 /* This is the table of extensions that the loader will dlsym() for. */
1002 PUBLIC
const __DRIextension
*__driDriverExtensions
[] = {
1003 &driCoreExtension
.base
,
1004 &driLegacyExtension
.base
,