added _tnl_allow_vertex/pixel_fog() calls
[mesa.git] / src / mesa / drivers / dri / mga / mga_xmesa.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c,v 1.19 2003/03/26 20:43:49 tsi Exp $ */
2 /*
3 * Copyright 2000-2001 VA Linux Systems, Inc.
4 * All Rights Reserved.
5 *
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:
12 *
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
15 * Software.
16 *
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.
24 *
25 * Authors:
26 * Keith Whitwell <keith@tungstengraphics.com>
27 */
28
29 #include "mga_common.h"
30 #include "mga_xmesa.h"
31 #include "context.h"
32 #include "matrix.h"
33 #include "simple_list.h"
34 #include "imports.h"
35
36 #include "swrast/swrast.h"
37 #include "swrast_setup/swrast_setup.h"
38 #include "tnl/tnl.h"
39 #include "array_cache/acache.h"
40
41 #include "tnl/t_pipeline.h"
42
43 #include "drivers/common/driverfuncs.h"
44
45 #include "mgadd.h"
46 #include "mgastate.h"
47 #include "mgatex.h"
48 #include "mgaspan.h"
49 #include "mgaioctl.h"
50 #include "mgatris.h"
51 #include "mgavb.h"
52 #include "mgapixel.h"
53 #include "mga_xmesa.h"
54 #include "mga_dri.h"
55
56
57 #include "utils.h"
58 #include "vblank.h"
59
60 #ifndef _SOLO
61 #include "glxextensions.h"
62 #endif
63
64 /* MGA configuration
65 */
66 #include "xmlpool.h"
67
68 const char __driConfigOptions[] =
69 DRI_CONF_BEGIN
70 DRI_CONF_SECTION_PERFORMANCE
71 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
72 DRI_CONF_SECTION_END
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)
76 DRI_CONF_SECTION_END
77 DRI_CONF_END;
78 static const GLuint __driNConfigOptions = 3;
79
80 #ifdef USE_NEW_INTERFACE
81 static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
82 #endif /* USE_NEW_INTERFACE */
83
84 #ifndef MGA_DEBUG
85 int MGA_DEBUG = 0;
86 #endif
87
88 static int getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo );
89
90 #ifdef USE_NEW_INTERFACE
91 static __GLcontextModes * fill_in_modes( __GLcontextModes * modes,
92 unsigned pixel_bits,
93 unsigned depth_bits,
94 unsigned stencil_bits,
95 const GLenum * db_modes,
96 unsigned num_db_modes,
97 int visType )
98 {
99 static const uint8_t bits[2][4] = {
100 { 5, 6, 5, 0 },
101 { 8, 8, 8, 0 }
102 };
103
104 static const uint32_t masks[2][4] = {
105 { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 },
106 { 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }
107 };
108
109 unsigned i;
110 unsigned j;
111 const unsigned index = ((pixel_bits + 15) / 16) - 1;
112
113 for ( i = 0 ; i < num_db_modes ; i++ ) {
114 for ( j = 0 ; j < 2 ; j++ ) {
115
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
125 + modes->blueBits;
126
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;
132
133 modes->stencilBits = stencil_bits;
134 modes->depthBits = depth_bits;
135
136 modes->visualType = visType;
137 modes->renderType = GLX_RGBA_BIT;
138 modes->drawableType = GLX_WINDOW_BIT;
139 modes->rgbMode = GL_TRUE;
140
141 if ( db_modes[i] == GLX_NONE ) {
142 modes->doubleBufferMode = GL_FALSE;
143 }
144 else {
145 modes->doubleBufferMode = GL_TRUE;
146 modes->swapMethod = db_modes[i];
147 }
148
149 modes = modes->next;
150 }
151 }
152
153 return modes;
154 }
155 #endif /* USE_NEW_INTERFACE */
156
157
158 #ifdef USE_NEW_INTERFACE
159 static __GLcontextModes *
160 mgaFillInModes( unsigned pixel_bits, unsigned depth_bits,
161 unsigned stencil_bits, GLboolean have_back_buffer )
162 {
163 __GLcontextModes * modes;
164 __GLcontextModes * m;
165 unsigned num_modes;
166 unsigned depth_buffer_factor;
167 unsigned back_buffer_factor;
168 unsigned i;
169
170 /* GLX_SWAP_COPY_OML is only supported because the MGA driver doesn't
171 * support pageflipping at all.
172 */
173 static const GLenum back_buffer_modes[] = {
174 GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
175 };
176
177 int depth_buffer_modes[2][2] = {
178 { 0, 0 },
179 { 0, 0 }
180 };
181
182 depth_buffer_modes[1][0] = depth_bits;
183 depth_buffer_modes[1][1] = stencil_bits;
184
185 depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 2 : 1;
186 back_buffer_factor = (have_back_buffer) ? 2 : 1;
187
188 num_modes = depth_buffer_factor * back_buffer_factor * 4;
189
190 modes = (*create_context_modes)( num_modes, sizeof( __GLcontextModes ) );
191 m = modes;
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,
196 GLX_TRUE_COLOR );
197 }
198
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,
203 GLX_DIRECT_COLOR );
204 }
205
206 return modes;
207 }
208 #endif /* USE_NEW_INTERFACE */
209
210
211 static GLboolean
212 mgaInitDriver(__DRIscreenPrivate *sPriv)
213 {
214 mgaScreenPrivate *mgaScreen;
215 MGADRIPtr serverInfo = (MGADRIPtr)sPriv->pDevPriv;
216
217 if ( ! driCheckDriDdxDrmVersions( sPriv, "MGA", 4, 0, 1, 0, 3, 0 ) )
218 return GL_FALSE;
219
220 /* Allocate the private area */
221 mgaScreen = (mgaScreenPrivate *)MALLOC(sizeof(mgaScreenPrivate));
222 if (!mgaScreen) {
223 __driUtilMessage("Couldn't malloc screen struct");
224 return GL_FALSE;
225 }
226
227 mgaScreen->sPriv = sPriv;
228 sPriv->private = (void *)mgaScreen;
229
230 if (sPriv->drmMinor >= 1) {
231 int ret;
232 drmMGAGetParam gp;
233
234 gp.param = MGA_PARAM_IRQ_NR;
235 gp.value = &mgaScreen->irq;
236
237 ret = drmCommandWriteRead( sPriv->fd, DRM_MGA_GETPARAM,
238 &gp, sizeof(gp));
239 if (ret) {
240 fprintf(stderr, "drmMgaGetParam (MGA_PARAM_IRQ_NR): %d\n", ret);
241 FREE(mgaScreen);
242 sPriv->private = NULL;
243 return GL_FALSE;
244 }
245 }
246
247 mgaScreen->linecomp_sane = (sPriv->ddxMajor > 1) || (sPriv->ddxMinor > 1)
248 || ((sPriv->ddxMinor == 1) && (sPriv->ddxPatch > 0));
249 #ifndef _SOLO
250 if ( driCompareGLXAPIVersion( 20030813 ) >= 0 ) {
251 PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
252 (PFNGLXSCRENABLEEXTENSIONPROC) glXGetProcAddress( (const GLubyte *) "__glXScrEnableExtension" );
253 void * const psc = sPriv->psc->screenConfigs;
254
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" );
260 }
261
262 (*glx_enable_extension)( psc, "GLX_SGI_make_current_read" );
263 (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
264
265 if ( driCompareGLXAPIVersion( 20030915 ) >= 0 ) {
266 (*glx_enable_extension)( psc, "GLX_SGIX_fbconfig" );
267 (*glx_enable_extension)( psc, "GLX_OML_swap_method" );
268 }
269 }
270 }
271 #endif
272
273 if (serverInfo->chipset != MGA_CARD_TYPE_G200 &&
274 serverInfo->chipset != MGA_CARD_TYPE_G400) {
275 FREE(mgaScreen);
276 sPriv->private = NULL;
277 __driUtilMessage("Unrecognized chipset");
278 return GL_FALSE;
279 }
280
281
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;
287
288 mgaScreen->agpMode = serverInfo->agpMode;
289
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;
296
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 ) {
302 FREE( mgaScreen );
303 sPriv->private = NULL;
304 __driUtilMessage( "Couldn't map MMIO registers" );
305 return GL_FALSE;
306 }
307
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;
312
313 #if 0
314 mgaScreen->agp.handle = serverInfo->agp;
315 mgaScreen->agp.size = serverInfo->agpSize;
316
317 if (drmMap(sPriv->fd,
318 mgaScreen->agp.handle,
319 mgaScreen->agp.size,
320 (drmAddress *)&mgaScreen->agp.map) != 0)
321 {
322 Xfree(mgaScreen);
323 sPriv->private = NULL;
324 __driUtilMessage("Couldn't map agp region");
325 return GL_FALSE;
326 }
327 #endif
328
329 mgaScreen->textureOffset[MGA_CARD_HEAP] = serverInfo->textureOffset;
330 mgaScreen->textureOffset[MGA_AGP_HEAP] = (serverInfo->agpTextureOffset |
331 PDEA_pagpxfer_enable | 1);
332
333 mgaScreen->textureSize[MGA_CARD_HEAP] = serverInfo->textureSize;
334 mgaScreen->textureSize[MGA_AGP_HEAP] = serverInfo->agpTextureSize;
335
336 mgaScreen->logTextureGranularity[MGA_CARD_HEAP] =
337 serverInfo->logTextureGranularity;
338 mgaScreen->logTextureGranularity[MGA_AGP_HEAP] =
339 serverInfo->logAgpTextureGranularity;
340
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)
347 {
348 FREE(mgaScreen);
349 sPriv->private = NULL;
350 __driUtilMessage("Couldn't map agptexture region");
351 return GL_FALSE;
352 }
353
354 #if 0
355 mgaScreen->texVirtual[MGA_AGP_HEAP] = (mgaScreen->agp.map +
356 serverInfo->agpTextureOffset);
357 #endif
358
359 mgaScreen->mAccess = serverInfo->mAccess;
360
361 /* For calculating setupdma addresses.
362 */
363 mgaScreen->dmaOffset = serverInfo->buffers.handle;
364
365 mgaScreen->bufs = drmMapBufs(sPriv->fd);
366 if (!mgaScreen->bufs) {
367 /*drmUnmap(mgaScreen->agp_tex.map, mgaScreen->agp_tex.size);*/
368 FREE(mgaScreen);
369 sPriv->private = NULL;
370 __driUtilMessage("Couldn't map dma buffers");
371 return GL_FALSE;
372 }
373 mgaScreen->sarea_priv_offset = serverInfo->sarea_priv_offset;
374
375 /* parse information in __driConfigOptions */
376 driParseOptionInfo (&mgaScreen->optionCache,
377 __driConfigOptions, __driNConfigOptions);
378
379 return GL_TRUE;
380 }
381
382
383 static void
384 mgaDestroyScreen(__DRIscreenPrivate *sPriv)
385 {
386 mgaScreenPrivate *mgaScreen = (mgaScreenPrivate *) sPriv->private;
387
388 if (MGA_DEBUG&DEBUG_VERBOSE_DRI)
389 fprintf(stderr, "mgaDestroyScreen\n");
390
391 /*drmUnmap(mgaScreen->agp_tex.map, mgaScreen->agp_tex.size);*/
392
393 /* free all option information */
394 driDestroyOptionInfo (&mgaScreen->optionCache);
395
396 FREE(mgaScreen);
397 sPriv->private = NULL;
398 }
399
400
401 extern const struct tnl_pipeline_stage _mga_render_stage;
402
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,
408 &_tnl_texgen_stage,
409 &_tnl_texture_transform_stage,
410 /* REMOVE: point attenuation stage */
411 #if 0
412 &_mga_render_stage, /* ADD: unclipped rastersetup-to-dma */
413 /* Need new ioctl for wacceptseq */
414 #endif
415 &_tnl_render_stage,
416 0,
417 };
418
419
420 static const char * const g400_extensions[] =
421 {
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",
431 #endif
432 NULL
433 };
434
435 static const char * const card_extensions[] =
436 {
437 "GL_ARB_multisample",
438 "GL_ARB_texture_compression",
439 "GL_EXT_blend_logic_op",
440 "GL_EXT_fog_coord",
441 /* paletted_textures currently doesn't work, but we could fix them later */
442 #if 0
443 "GL_EXT_shared_texture_palette",
444 "GL_EXT_paletted_texture",
445 #endif
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",
452 NULL
453 };
454
455 static const struct dri_debug_control debug_control[] =
456 {
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 },
462 { NULL, 0 }
463 };
464
465
466 static int
467 get_ust_nop( int64_t * ust )
468 {
469 *ust = 1;
470 return 0;
471 }
472
473
474 static GLboolean
475 mgaCreateContext( const __GLcontextModes *mesaVis,
476 __DRIcontextPrivate *driContextPriv,
477 void *sharedContextPrivate )
478 {
479 int i;
480 unsigned maxlevels;
481 GLcontext *ctx, *shareCtx;
482 mgaContextPtr mmesa;
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;
488
489 if (MGA_DEBUG&DEBUG_VERBOSE_DRI)
490 fprintf(stderr, "mgaCreateContext\n");
491
492 /* allocate mga context */
493 mmesa = (mgaContextPtr) CALLOC(sizeof(mgaContext));
494 if (!mmesa) {
495 return GL_FALSE;
496 }
497
498 /* Init default driver functions then plug in our Radeon-specific functions
499 * (the texture functions are especially important)
500 */
501 _mesa_init_driver_functions( &functions );
502 mgaInitDriverFuncs( &functions );
503 mgaInitTextureFuncs( &functions );
504 mgaInitIoctlFuncs( &functions );
505
506 /* Allocate the Mesa context */
507 if (sharedContextPrivate)
508 shareCtx = ((mgaContextPtr) sharedContextPrivate)->glCtx;
509 else
510 shareCtx = NULL;
511 mmesa->glCtx = _mesa_create_context(mesaVis, shareCtx,
512 &functions, (void *) mmesa);
513 if (!mmesa->glCtx) {
514 FREE(mmesa);
515 return GL_FALSE;
516 }
517 driContextPriv->driverPrivate = mmesa;
518
519 /* Init mga state */
520 mmesa->hHWContext = driContextPriv->hHWContext;
521 mmesa->driFd = sPriv->fd;
522 mmesa->driHwLock = &sPriv->pSAREA->lock;
523
524 mmesa->mgaScreen = mgaScreen;
525 mmesa->driScreen = sPriv;
526 mmesa->sarea = (void *)saPriv;
527
528 /* Parse configuration files */
529 driParseConfigFiles (&mmesa->optionCache, &mgaScreen->optionCache,
530 sPriv->myNum, "mga");
531
532 (void) memset( mmesa->texture_heaps, 0, sizeof( mmesa->texture_heaps ) );
533 make_empty_list( & mmesa->swapped );
534
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],
539 6,
540 MGA_NR_TEX_REGIONS,
541 mmesa->sarea->texList[i],
542 & mmesa->sarea->texAge[i],
543 & mmesa->swapped,
544 sizeof( mgaTextureObject_t ),
545 (destroy_texture_object_t *) mgaDestroyTexObj );
546 }
547
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.
551 */
552 ctx = mmesa->glCtx;
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;
558
559 }
560 else {
561 ctx->Const.MaxTextureUnits = 2;
562 ctx->Const.MaxTextureImageUnits = 2;
563 ctx->Const.MaxTextureCoordUnits = 2;
564 maxlevels = G400_TEX_MAXLEVELS;
565 }
566
567 driCalculateMaxTextureLevels( mmesa->texture_heaps,
568 mmesa->nr_heaps,
569 & ctx->Const,
570 4,
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 */
575 maxlevels,
576 GL_FALSE );
577
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;
583
584 mmesa->texture_depth = driQueryOptioni (&mmesa->optionCache,
585 "texture_depth");
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;
590
591 switch (mesaVis->depthBits) {
592 case 16:
593 mmesa->depth_scale = 1.0/(GLdouble)0xffff;
594 mmesa->depth_clear_mask = ~0;
595 mmesa->ClearDepth = 0xffff;
596 break;
597 case 24:
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;
602 } else
603 mmesa->depth_clear_mask = ~0;
604 mmesa->ClearDepth = 0xffffff00;
605 break;
606 case 32:
607 mmesa->depth_scale = 1.0/(GLdouble)0xffffffff;
608 mmesa->depth_clear_mask = ~0;
609 mmesa->ClearDepth = 0xffffffff;
610 break;
611 };
612
613 mmesa->haveHwStipple = GL_FALSE;
614 mmesa->RenderIndex = -1; /* impossible value */
615 mmesa->dirty = ~0;
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;
621
622 mmesa->texAge[0] = 0;
623 mmesa->texAge[1] = 0;
624
625 /* Initialize the software rasterizer and helper modules.
626 */
627 _swrast_CreateContext( ctx );
628 _ac_CreateContext( ctx );
629 _tnl_CreateContext( ctx );
630
631 _swsetup_CreateContext( ctx );
632
633 /* Install the customized pipeline:
634 */
635 _tnl_destroy_pipeline( ctx );
636 _tnl_install_pipeline( ctx, mga_pipeline );
637
638 /* Configure swrast and T&L to match hardware characteristics:
639 */
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 );
644
645 mmesa->primary_offset = mmesa->mgaScreen->primary.handle;
646
647 ctx->DriverCtx = (void *) mmesa;
648 mmesa->glCtx = ctx;
649
650 driInitExtensions( ctx, card_extensions, GL_FALSE );
651
652 if (MGA_IS_G400(MGA_CONTEXT(ctx))) {
653 driInitExtensions( ctx, g400_extensions, GL_FALSE );
654 }
655
656 /* XXX these should really go right after _mesa_init_driver_functions() */
657 mgaDDInitStateFuncs( ctx );
658 mgaDDInitSpanFuncs( ctx );
659 mgaDDInitPixelFuncs( ctx );
660 mgaDDInitTriFuncs( ctx );
661
662 mgaInitVB( ctx );
663 mgaInitState( mmesa );
664
665 driContextPriv->driverPrivate = (void *) mmesa;
666
667 #if DO_DEBUG
668 MGA_DEBUG = driParseDebugString( getenv( "MGA_DEBUG" ),
669 debug_control );
670 #endif
671
672 mmesa->vblank_flags = ((mmesa->mgaScreen->irq == 0)
673 || !mmesa->mgaScreen->linecomp_sane)
674 ? VBLANK_FLAG_NO_IRQ : driGetDefaultVBlankFlags(&mmesa->optionCache);
675 #ifndef _SOLO
676 mmesa->get_ust = (PFNGLXGETUSTPROC) glXGetProcAddress( (const GLubyte *) "__glXGetUST" );
677 if ( mmesa->get_ust == NULL ) {
678 mmesa->get_ust = get_ust_nop;
679 }
680 #else
681 mmesa->get_ust = get_ust_nop;
682 #endif
683
684 (*mmesa->get_ust)( & mmesa->swap_ust );
685
686 return GL_TRUE;
687 }
688
689 static void
690 mgaDestroyContext(__DRIcontextPrivate *driContextPriv)
691 {
692 mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate;
693
694 if (MGA_DEBUG&DEBUG_VERBOSE_DRI)
695 fprintf( stderr, "[%s:%d] mgaDestroyContext start\n",
696 __FILE__, __LINE__ );
697
698 assert(mmesa); /* should never be null */
699 if (mmesa) {
700 GLboolean release_texture_heaps;
701
702
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 );
708
709 mgaFreeVB( mmesa->glCtx );
710
711 /* free the Mesa context */
712 mmesa->glCtx->DriverCtx = NULL;
713 _mesa_destroy_context(mmesa->glCtx);
714
715 if ( release_texture_heaps ) {
716 /* This share group is about to go away, free our private
717 * texture object data.
718 */
719 int i;
720
721 for ( i = 0 ; i < mmesa->nr_heaps ; i++ ) {
722 driDestroyTextureHeap( mmesa->texture_heaps[ i ] );
723 mmesa->texture_heaps[ i ] = NULL;
724 }
725
726 assert( is_empty_list( & mmesa->swapped ) );
727 }
728
729 /* free the option cache */
730 driDestroyOptionCache (&mmesa->optionCache);
731
732 FREE(mmesa);
733 }
734
735 if (MGA_DEBUG&DEBUG_VERBOSE_DRI)
736 fprintf( stderr, "[%s:%d] mgaDestroyContext done\n",
737 __FILE__, __LINE__ );
738 }
739
740
741 static GLboolean
742 mgaCreateBuffer( __DRIscreenPrivate *driScrnPriv,
743 __DRIdrawablePrivate *driDrawPriv,
744 const __GLcontextModes *mesaVis,
745 GLboolean isPixmap )
746 {
747 if (isPixmap) {
748 return GL_FALSE; /* not implemented */
749 }
750 else {
751 GLboolean swStencil = (mesaVis->stencilBits > 0 &&
752 mesaVis->depthBits != 24);
753
754 driDrawPriv->driverPrivate = (void *)
755 _mesa_create_framebuffer(mesaVis,
756 GL_FALSE, /* software depth buffer? */
757 swStencil,
758 mesaVis->accumRedBits > 0,
759 mesaVis->alphaBits > 0 );
760
761 return (driDrawPriv->driverPrivate != NULL);
762 }
763 }
764
765
766 static void
767 mgaDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
768 {
769 _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
770 }
771
772 static void
773 mgaSwapBuffers(__DRIdrawablePrivate *dPriv)
774 {
775 if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
776 mgaContextPtr mmesa;
777 GLcontext *ctx;
778 mmesa = (mgaContextPtr) dPriv->driContextPriv->driverPrivate;
779 ctx = mmesa->glCtx;
780
781 if (ctx->Visual.doubleBufferMode) {
782 _mesa_notifySwapBuffers( ctx );
783 mgaCopyBuffer( dPriv );
784 }
785 } else {
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__);
788 }
789 }
790
791 static GLboolean
792 mgaUnbindContext(__DRIcontextPrivate *driContextPriv)
793 {
794 mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate;
795 if (mmesa)
796 mmesa->dirty = ~0;
797
798 return GL_TRUE;
799 }
800
801 static GLboolean
802 mgaOpenCloseFullScreen(__DRIcontextPrivate *driContextPriv)
803 {
804 return GL_TRUE;
805 }
806
807
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
810 * driDrawablePriv.
811 *
812 * But why are we doing context initialization here???
813 */
814 static GLboolean
815 mgaMakeCurrent(__DRIcontextPrivate *driContextPriv,
816 __DRIdrawablePrivate *driDrawPriv,
817 __DRIdrawablePrivate *driReadPriv)
818 {
819 if (driContextPriv) {
820 mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate;
821
822 if (mmesa->driDrawable != driDrawPriv) {
823 driDrawableInitVBlank( driDrawPriv, mmesa->vblank_flags );
824 mmesa->driDrawable = driDrawPriv;
825 mmesa->dirty = ~0;
826 mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK);
827 mmesa->mesa_drawable = driDrawPriv;
828 }
829
830 mmesa->driReadable = driReadPriv;
831
832 _mesa_make_current2(mmesa->glCtx,
833 (GLframebuffer *) driDrawPriv->driverPrivate,
834 (GLframebuffer *) driReadPriv->driverPrivate);
835
836 if (!mmesa->glCtx->Viewport.Width)
837 _mesa_set_viewport(mmesa->glCtx, 0, 0,
838 driDrawPriv->w, driDrawPriv->h);
839
840 }
841 else {
842 _mesa_make_current(NULL, NULL);
843 }
844
845 return GL_TRUE;
846 }
847
848
849 void mgaGetLock( mgaContextPtr mmesa, GLuint flags )
850 {
851 __DRIdrawablePrivate *dPriv = mmesa->driDrawable;
852 MGASAREAPrivPtr sarea = mmesa->sarea;
853 int me = mmesa->hHWContext;
854 int i;
855
856 drmGetLock(mmesa->driFd, mmesa->hHWContext, flags);
857
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) );
863 }
864
865 mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_CLIPRECTS;
866
867 mmesa->sarea->dirty |= MGA_UPLOAD_CONTEXT;
868
869 if (sarea->ctxOwner != me) {
870 mmesa->dirty |= (MGA_UPLOAD_CONTEXT | MGA_UPLOAD_TEX0 |
871 MGA_UPLOAD_TEX1 | MGA_UPLOAD_PIPE);
872 sarea->ctxOwner=me;
873 }
874
875 for ( i = 0 ; i < mmesa->nr_heaps ; i++ ) {
876 DRI_AGE_TEXTURES( mmesa->texture_heaps[ i ] );
877 }
878
879 sarea->last_quiescent = -1; /* just kill it for now */
880 }
881
882
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,
898 .WaitForSBC = NULL,
899 .SwapBuffersMSC = NULL
900 };
901
902
903 /*
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.
907 */
908 #ifndef _SOLO
909 void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
910 int numConfigs, __GLXvisualConfig *config)
911 {
912 __DRIscreenPrivate *psp;
913 psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &mgaAPI);
914 return (void *) psp;
915 }
916 #else
917 void *__driCreateScreen(struct DRIDriverRec *driver,
918 struct DRIDriverContextRec *driverContext)
919 {
920 __DRIscreenPrivate *psp;
921 psp = __driUtilCreateScreen(driver, driverContext, &mgaAPI);
922 return (void *) psp;
923 }
924 #endif
925
926
927 /**
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
932 * pbuffers.
933 *
934 * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
935 * failure.
936 */
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 )
947
948 {
949 __DRIscreenPrivate *psp;
950
951 psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
952 ddx_version, dri_version, drm_version,
953 frame_buffer, pSAREA, fd,
954 internal_api_version, &mgaAPI);
955
956
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) );
965 }
966
967 return (void *) psp;
968 }
969 #endif /* USE_NEW_INTERFACE */
970
971
972 /**
973 * Get information about previous buffer swaps.
974 */
975 static int
976 getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
977 {
978 mgaContextPtr mmesa;
979
980 if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL)
981 || (dPriv->driContextPriv->driverPrivate == NULL)
982 || (sInfo == NULL) ) {
983 return -1;
984 }
985
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;
990
991 sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
992 ? driCalculateSwapUsage( dPriv, 0, mmesa->swap_missed_ust )
993 : 0.0;
994
995 return 0;
996 }