Minor extension string tweaks. Added support for vertex program extensions.
[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 <stdlib.h>
30 #include "drm.h"
31 #include "mga_drm.h"
32 #include "mga_xmesa.h"
33 #include "context.h"
34 #include "matrix.h"
35 #include "simple_list.h"
36 #include "imports.h"
37
38 #include "swrast/swrast.h"
39 #include "swrast_setup/swrast_setup.h"
40 #include "tnl/tnl.h"
41 #include "array_cache/acache.h"
42
43 #include "tnl/t_pipeline.h"
44
45 #include "drivers/common/driverfuncs.h"
46
47 #include "mgadd.h"
48 #include "mgastate.h"
49 #include "mgatex.h"
50 #include "mgaspan.h"
51 #include "mgaioctl.h"
52 #include "mgatris.h"
53 #include "mgavb.h"
54 #include "mgapixel.h"
55 #include "mga_xmesa.h"
56 #include "mga_dri.h"
57
58
59 #include "utils.h"
60 #include "vblank.h"
61
62 #include "extensions.h"
63
64 #include "GL/internal/dri_interface.h"
65
66 /* MGA configuration
67 */
68 #include "xmlpool.h"
69
70 const char __driConfigOptions[] =
71 DRI_CONF_BEGIN
72 DRI_CONF_SECTION_PERFORMANCE
73 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
74 DRI_CONF_SECTION_END
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)
78 DRI_CONF_SECTION_END
79 DRI_CONF_SECTION_SOFTWARE
80 DRI_CONF_ARB_VERTEX_PROGRAM(true)
81 DRI_CONF_NV_VERTEX_PROGRAM(true)
82 DRI_CONF_SECTION_END
83 DRI_CONF_END;
84 static const GLuint __driNConfigOptions = 5;
85
86 #ifdef USE_NEW_INTERFACE
87 static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
88 #endif /* USE_NEW_INTERFACE */
89
90 #ifndef MGA_DEBUG
91 int MGA_DEBUG = 0;
92 #endif
93
94 static int getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo );
95
96 #ifdef USE_NEW_INTERFACE
97 static __GLcontextModes * fill_in_modes( __GLcontextModes * modes,
98 unsigned pixel_bits,
99 unsigned depth_bits,
100 unsigned stencil_bits,
101 const GLenum * db_modes,
102 unsigned num_db_modes,
103 int visType )
104 {
105 static const uint8_t bits[2][4] = {
106 { 5, 6, 5, 0 },
107 { 8, 8, 8, 0 }
108 };
109
110 static const uint32_t masks[2][4] = {
111 { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 },
112 { 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }
113 };
114
115 unsigned i;
116 unsigned j;
117 const unsigned index = ((pixel_bits + 15) / 16) - 1;
118
119 for ( i = 0 ; i < num_db_modes ; i++ ) {
120 for ( j = 0 ; j < 2 ; j++ ) {
121
122 modes->redBits = bits[index][0];
123 modes->greenBits = bits[index][1];
124 modes->blueBits = bits[index][2];
125 modes->alphaBits = bits[index][3];
126 modes->redMask = masks[index][0];
127 modes->greenMask = masks[index][1];
128 modes->blueMask = masks[index][2];
129 modes->alphaMask = masks[index][3];
130 modes->rgbBits = modes->redBits + modes->greenBits
131 + modes->blueBits;
132
133 modes->accumRedBits = 16 * j;
134 modes->accumGreenBits = 16 * j;
135 modes->accumBlueBits = 16 * j;
136 modes->accumAlphaBits = (masks[index][3] != 0) ? 16 * j : 0;
137 modes->visualRating = (j == 0) ? GLX_NONE : GLX_SLOW_CONFIG;
138
139 modes->stencilBits = stencil_bits;
140 modes->depthBits = depth_bits;
141
142 modes->visualType = visType;
143 modes->renderType = GLX_RGBA_BIT;
144 modes->drawableType = GLX_WINDOW_BIT;
145 modes->rgbMode = GL_TRUE;
146
147 if ( db_modes[i] == GLX_NONE ) {
148 modes->doubleBufferMode = GL_FALSE;
149 }
150 else {
151 modes->doubleBufferMode = GL_TRUE;
152 modes->swapMethod = db_modes[i];
153 }
154
155 modes = modes->next;
156 }
157 }
158
159 return modes;
160 }
161 #endif /* USE_NEW_INTERFACE */
162
163
164 #ifdef USE_NEW_INTERFACE
165 static __GLcontextModes *
166 mgaFillInModes( unsigned pixel_bits, unsigned depth_bits,
167 unsigned stencil_bits, GLboolean have_back_buffer )
168 {
169 __GLcontextModes * modes;
170 __GLcontextModes * m;
171 unsigned num_modes;
172 unsigned depth_buffer_factor;
173 unsigned back_buffer_factor;
174 unsigned i;
175
176 /* GLX_SWAP_COPY_OML is only supported because the MGA driver doesn't
177 * support pageflipping at all.
178 */
179 static const GLenum back_buffer_modes[] = {
180 GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
181 };
182
183 int depth_buffer_modes[2][2];
184
185
186 depth_buffer_modes[0][0] = depth_bits;
187 depth_buffer_modes[1][0] = depth_bits;
188
189 /* Just like with the accumulation buffer, always provide some modes
190 * with a stencil buffer. It will be a sw fallback, but some apps won't
191 * care about that.
192 */
193 depth_buffer_modes[0][1] = 0;
194 depth_buffer_modes[1][1] = (stencil_bits == 0) ? 8 : stencil_bits;
195
196 depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 2 : 1;
197 back_buffer_factor = (have_back_buffer) ? 2 : 1;
198
199 num_modes = depth_buffer_factor * back_buffer_factor * 4;
200
201 modes = (*create_context_modes)( num_modes, sizeof( __GLcontextModes ) );
202 m = modes;
203 for ( i = 0 ; i < depth_buffer_factor ; i++ ) {
204 m = fill_in_modes( m, pixel_bits,
205 depth_buffer_modes[i][0], depth_buffer_modes[i][1],
206 back_buffer_modes, back_buffer_factor,
207 GLX_TRUE_COLOR );
208 }
209
210 for ( i = 0 ; i < depth_buffer_factor ; i++ ) {
211 m = fill_in_modes( m, pixel_bits,
212 depth_buffer_modes[i][0], depth_buffer_modes[i][1],
213 back_buffer_modes, back_buffer_factor,
214 GLX_DIRECT_COLOR );
215 }
216
217 /* Mark the visual as slow if there are "fake" stencil bits.
218 */
219 for ( m = modes ; m != NULL ; m = m->next ) {
220 if ( (m->stencilBits != 0) && (m->stencilBits != stencil_bits) ) {
221 m->visualRating = GLX_SLOW_CONFIG;
222 }
223 }
224
225 return modes;
226 }
227 #endif /* USE_NEW_INTERFACE */
228
229
230 static GLboolean
231 mgaInitDriver(__DRIscreenPrivate *sPriv)
232 {
233 mgaScreenPrivate *mgaScreen;
234 MGADRIPtr serverInfo = (MGADRIPtr)sPriv->pDevPriv;
235
236
237 /* Allocate the private area */
238 mgaScreen = (mgaScreenPrivate *)MALLOC(sizeof(mgaScreenPrivate));
239 if (!mgaScreen) {
240 __driUtilMessage("Couldn't malloc screen struct");
241 return GL_FALSE;
242 }
243
244 mgaScreen->sPriv = sPriv;
245 sPriv->private = (void *)mgaScreen;
246
247 if (sPriv->drmMinor >= 1) {
248 int ret;
249 drm_mga_getparam_t gp;
250
251 gp.param = MGA_PARAM_IRQ_NR;
252 gp.value = &mgaScreen->irq;
253 mgaScreen->irq = 0;
254
255 ret = drmCommandWriteRead( sPriv->fd, DRM_MGA_GETPARAM,
256 &gp, sizeof(gp));
257 if (ret) {
258 fprintf(stderr, "drmMgaGetParam (MGA_PARAM_IRQ_NR): %d\n", ret);
259 FREE(mgaScreen);
260 sPriv->private = NULL;
261 return GL_FALSE;
262 }
263 }
264
265 mgaScreen->linecomp_sane = (sPriv->ddxMajor > 1) || (sPriv->ddxMinor > 1)
266 || ((sPriv->ddxMinor == 1) && (sPriv->ddxPatch > 0));
267
268 if ( driCompareGLXAPIVersion( 20030813 ) >= 0 ) {
269 PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
270 (PFNGLXSCRENABLEEXTENSIONPROC) glXGetProcAddress( (const GLubyte *) "__glXScrEnableExtension" );
271 void * const psc = sPriv->psc->screenConfigs;
272
273 if ( glx_enable_extension != NULL ) {
274 if ( mgaScreen->linecomp_sane ) {
275 (*glx_enable_extension)( psc, "GLX_SGI_swap_control" );
276 (*glx_enable_extension)( psc, "GLX_SGI_video_sync" );
277 (*glx_enable_extension)( psc, "GLX_MESA_swap_control" );
278 }
279
280 (*glx_enable_extension)( psc, "GLX_SGI_make_current_read" );
281 (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
282
283 if ( driCompareGLXAPIVersion( 20030915 ) >= 0 ) {
284 (*glx_enable_extension)( psc, "GLX_SGIX_fbconfig" );
285 (*glx_enable_extension)( psc, "GLX_OML_swap_method" );
286 }
287 }
288 }
289
290 if (serverInfo->chipset != MGA_CARD_TYPE_G200 &&
291 serverInfo->chipset != MGA_CARD_TYPE_G400) {
292 FREE(mgaScreen);
293 sPriv->private = NULL;
294 __driUtilMessage("Unrecognized chipset");
295 return GL_FALSE;
296 }
297
298
299 mgaScreen->chipset = serverInfo->chipset;
300 mgaScreen->width = serverInfo->width;
301 mgaScreen->height = serverInfo->height;
302 mgaScreen->mem = serverInfo->mem;
303 mgaScreen->cpp = serverInfo->cpp;
304
305 mgaScreen->agpMode = serverInfo->agpMode;
306
307 mgaScreen->frontPitch = serverInfo->frontPitch;
308 mgaScreen->frontOffset = serverInfo->frontOffset;
309 mgaScreen->backOffset = serverInfo->backOffset;
310 mgaScreen->backPitch = serverInfo->backPitch;
311 mgaScreen->depthOffset = serverInfo->depthOffset;
312 mgaScreen->depthPitch = serverInfo->depthPitch;
313
314 mgaScreen->mmio.handle = serverInfo->registers.handle;
315 mgaScreen->mmio.size = serverInfo->registers.size;
316 if ( drmMap( sPriv->fd,
317 mgaScreen->mmio.handle, mgaScreen->mmio.size,
318 &mgaScreen->mmio.map ) < 0 ) {
319 FREE( mgaScreen );
320 sPriv->private = NULL;
321 __driUtilMessage( "Couldn't map MMIO registers" );
322 return GL_FALSE;
323 }
324
325 mgaScreen->primary.handle = serverInfo->primary.handle;
326 mgaScreen->primary.size = serverInfo->primary.size;
327 mgaScreen->buffers.handle = serverInfo->buffers.handle;
328 mgaScreen->buffers.size = serverInfo->buffers.size;
329
330 #if 0
331 mgaScreen->agp.handle = serverInfo->agp;
332 mgaScreen->agp.size = serverInfo->agpSize;
333
334 if (drmMap(sPriv->fd,
335 mgaScreen->agp.handle,
336 mgaScreen->agp.size,
337 (drmAddress *)&mgaScreen->agp.map) != 0)
338 {
339 Xfree(mgaScreen);
340 sPriv->private = NULL;
341 __driUtilMessage("Couldn't map agp region");
342 return GL_FALSE;
343 }
344 #endif
345
346 mgaScreen->textureOffset[MGA_CARD_HEAP] = serverInfo->textureOffset;
347 mgaScreen->textureOffset[MGA_AGP_HEAP] = (serverInfo->agpTextureOffset |
348 PDEA_pagpxfer_enable | 1);
349
350 mgaScreen->textureSize[MGA_CARD_HEAP] = serverInfo->textureSize;
351 mgaScreen->textureSize[MGA_AGP_HEAP] = serverInfo->agpTextureSize;
352
353 mgaScreen->logTextureGranularity[MGA_CARD_HEAP] =
354 serverInfo->logTextureGranularity;
355 mgaScreen->logTextureGranularity[MGA_AGP_HEAP] =
356 serverInfo->logAgpTextureGranularity;
357
358 mgaScreen->texVirtual[MGA_CARD_HEAP] = (char *)(mgaScreen->sPriv->pFB +
359 serverInfo->textureOffset);
360 if (drmMap(sPriv->fd,
361 serverInfo->agpTextureOffset,
362 serverInfo->agpTextureSize,
363 (drmAddress *)&mgaScreen->texVirtual[MGA_AGP_HEAP]) != 0)
364 {
365 FREE(mgaScreen);
366 sPriv->private = NULL;
367 __driUtilMessage("Couldn't map agptexture region");
368 return GL_FALSE;
369 }
370
371 #if 0
372 mgaScreen->texVirtual[MGA_AGP_HEAP] = (mgaScreen->agp.map +
373 serverInfo->agpTextureOffset);
374 #endif
375
376 mgaScreen->mAccess = serverInfo->mAccess;
377
378 /* For calculating setupdma addresses.
379 */
380 mgaScreen->dmaOffset = serverInfo->buffers.handle;
381
382 mgaScreen->bufs = drmMapBufs(sPriv->fd);
383 if (!mgaScreen->bufs) {
384 /*drmUnmap(mgaScreen->agp_tex.map, mgaScreen->agp_tex.size);*/
385 FREE(mgaScreen);
386 sPriv->private = NULL;
387 __driUtilMessage("Couldn't map dma buffers");
388 return GL_FALSE;
389 }
390 mgaScreen->sarea_priv_offset = serverInfo->sarea_priv_offset;
391
392 /* parse information in __driConfigOptions */
393 driParseOptionInfo (&mgaScreen->optionCache,
394 __driConfigOptions, __driNConfigOptions);
395
396 return GL_TRUE;
397 }
398
399
400 static void
401 mgaDestroyScreen(__DRIscreenPrivate *sPriv)
402 {
403 mgaScreenPrivate *mgaScreen = (mgaScreenPrivate *) sPriv->private;
404
405 if (MGA_DEBUG&DEBUG_VERBOSE_DRI)
406 fprintf(stderr, "mgaDestroyScreen\n");
407
408 drmUnmapBufs(mgaScreen->bufs);
409
410 /*drmUnmap(mgaScreen->agp_tex.map, mgaScreen->agp_tex.size);*/
411
412 /* free all option information */
413 driDestroyOptionInfo (&mgaScreen->optionCache);
414
415 FREE(mgaScreen);
416 sPriv->private = NULL;
417 }
418
419
420 extern const struct tnl_pipeline_stage _mga_render_stage;
421
422 static const struct tnl_pipeline_stage *mga_pipeline[] = {
423 &_tnl_vertex_transform_stage,
424 &_tnl_normal_transform_stage,
425 &_tnl_lighting_stage,
426 &_tnl_fog_coordinate_stage,
427 &_tnl_texgen_stage,
428 &_tnl_texture_transform_stage,
429 &_tnl_vertex_program_stage,
430
431 /* REMOVE: point attenuation stage */
432 #if 0
433 &_mga_render_stage, /* ADD: unclipped rastersetup-to-dma */
434 /* Need new ioctl for wacceptseq */
435 #endif
436 &_tnl_render_stage,
437 0,
438 };
439
440
441 static const char * const g400_extensions[] =
442 {
443 "GL_ARB_multitexture",
444 "GL_ARB_texture_env_add",
445 "GL_ARB_texture_env_combine",
446 "GL_ARB_texture_env_crossbar",
447 "GL_EXT_texture_env_combine",
448 "GL_EXT_texture_edge_clamp",
449 "GL_ATI_texture_env_combine3",
450 #if defined (MESA_packed_depth_stencil)
451 "GL_MESA_packed_depth_stencil",
452 #endif
453 NULL
454 };
455
456 static const char * const card_extensions[] =
457 {
458 "GL_ARB_multisample",
459 "GL_ARB_texture_compression",
460 "GL_ARB_texture_rectangle",
461 "GL_EXT_blend_logic_op",
462 "GL_EXT_fog_coord",
463 "GL_EXT_multi_draw_arrays",
464 /* paletted_textures currently doesn't work, but we could fix them later */
465 #if 0
466 "GL_EXT_shared_texture_palette",
467 "GL_EXT_paletted_texture",
468 #endif
469 "GL_EXT_secondary_color",
470 "GL_EXT_stencil_wrap",
471 "GL_MESA_ycbcr_texture",
472 "GL_SGIS_generate_mipmap",
473 NULL
474 };
475
476 static const struct dri_debug_control debug_control[] =
477 {
478 { "fall", DEBUG_VERBOSE_FALLBACK },
479 { "tex", DEBUG_VERBOSE_TEXTURE },
480 { "ioctl", DEBUG_VERBOSE_IOCTL },
481 { "verb", DEBUG_VERBOSE_MSG },
482 { "dri", DEBUG_VERBOSE_DRI },
483 { NULL, 0 }
484 };
485
486
487 static int
488 get_ust_nop( int64_t * ust )
489 {
490 *ust = 1;
491 return 0;
492 }
493
494
495 static GLboolean
496 mgaCreateContext( const __GLcontextModes *mesaVis,
497 __DRIcontextPrivate *driContextPriv,
498 void *sharedContextPrivate )
499 {
500 int i;
501 unsigned maxlevels;
502 GLcontext *ctx, *shareCtx;
503 mgaContextPtr mmesa;
504 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
505 mgaScreenPrivate *mgaScreen = (mgaScreenPrivate *)sPriv->private;
506 drm_mga_sarea_t *saPriv = (drm_mga_sarea_t *)(((char*)sPriv->pSAREA)+
507 mgaScreen->sarea_priv_offset);
508 struct dd_function_table functions;
509
510 if (MGA_DEBUG&DEBUG_VERBOSE_DRI)
511 fprintf(stderr, "mgaCreateContext\n");
512
513 /* allocate mga context */
514 mmesa = (mgaContextPtr) CALLOC(sizeof(mgaContext));
515 if (!mmesa) {
516 return GL_FALSE;
517 }
518
519 /* Init default driver functions then plug in our Radeon-specific functions
520 * (the texture functions are especially important)
521 */
522 _mesa_init_driver_functions( &functions );
523 mgaInitDriverFuncs( &functions );
524 mgaInitTextureFuncs( &functions );
525 mgaInitIoctlFuncs( &functions );
526
527 /* Allocate the Mesa context */
528 if (sharedContextPrivate)
529 shareCtx = ((mgaContextPtr) sharedContextPrivate)->glCtx;
530 else
531 shareCtx = NULL;
532 mmesa->glCtx = _mesa_create_context(mesaVis, shareCtx,
533 &functions, (void *) mmesa);
534 if (!mmesa->glCtx) {
535 FREE(mmesa);
536 return GL_FALSE;
537 }
538 driContextPriv->driverPrivate = mmesa;
539
540 /* Init mga state */
541 mmesa->hHWContext = driContextPriv->hHWContext;
542 mmesa->driFd = sPriv->fd;
543 mmesa->driHwLock = &sPriv->pSAREA->lock;
544
545 mmesa->mgaScreen = mgaScreen;
546 mmesa->driScreen = sPriv;
547 mmesa->sarea = (void *)saPriv;
548
549 /* Parse configuration files */
550 driParseConfigFiles (&mmesa->optionCache, &mgaScreen->optionCache,
551 sPriv->myNum, "mga");
552
553 (void) memset( mmesa->texture_heaps, 0, sizeof( mmesa->texture_heaps ) );
554 make_empty_list( & mmesa->swapped );
555
556 mmesa->nr_heaps = mgaScreen->texVirtual[MGA_AGP_HEAP] ? 2 : 1;
557 for ( i = 0 ; i < mmesa->nr_heaps ; i++ ) {
558 mmesa->texture_heaps[i] = driCreateTextureHeap( i, mmesa,
559 mgaScreen->textureSize[i],
560 6,
561 MGA_NR_TEX_REGIONS,
562 (drmTextureRegionPtr)mmesa->sarea->texList[i],
563 &mmesa->sarea->texAge[i],
564 &mmesa->swapped,
565 sizeof( mgaTextureObject_t ),
566 (destroy_texture_object_t *) mgaDestroyTexObj );
567 }
568
569 /* Set the maximum texture size small enough that we can guarentee
570 * that both texture units can bind a maximal texture and have them
571 * on the card at once.
572 */
573 ctx = mmesa->glCtx;
574 if ( mgaScreen->chipset == MGA_CARD_TYPE_G200 ) {
575 ctx->Const.MaxTextureUnits = 1;
576 ctx->Const.MaxTextureImageUnits = 1;
577 ctx->Const.MaxTextureCoordUnits = 1;
578 maxlevels = G200_TEX_MAXLEVELS;
579
580 }
581 else {
582 ctx->Const.MaxTextureUnits = 2;
583 ctx->Const.MaxTextureImageUnits = 2;
584 ctx->Const.MaxTextureCoordUnits = 2;
585 maxlevels = G400_TEX_MAXLEVELS;
586 }
587
588 driCalculateMaxTextureLevels( mmesa->texture_heaps,
589 mmesa->nr_heaps,
590 & ctx->Const,
591 4,
592 11, /* max 2D texture size is 2048x2048 */
593 0, /* 3D textures unsupported. */
594 0, /* cube textures unsupported. */
595 11, /* max texture rect size is 2048x2048 */
596 maxlevels,
597 GL_FALSE );
598
599 ctx->Const.MinLineWidth = 1.0;
600 ctx->Const.MinLineWidthAA = 1.0;
601 ctx->Const.MaxLineWidth = 10.0;
602 ctx->Const.MaxLineWidthAA = 10.0;
603 ctx->Const.LineWidthGranularity = 1.0;
604
605 mmesa->texture_depth = driQueryOptioni (&mmesa->optionCache,
606 "texture_depth");
607 if (mmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
608 mmesa->texture_depth = ( mesaVis->rgbBits >= 24 ) ?
609 DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
610 mmesa->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24;
611
612 switch (mesaVis->depthBits) {
613 case 16:
614 mmesa->depth_scale = 1.0/(GLdouble)0xffff;
615 mmesa->depth_clear_mask = ~0;
616 mmesa->ClearDepth = 0xffff;
617 break;
618 case 24:
619 mmesa->depth_scale = 1.0/(GLdouble)0xffffff;
620 if (mmesa->hw_stencil) {
621 mmesa->depth_clear_mask = 0xffffff00;
622 mmesa->stencil_clear_mask = 0x000000ff;
623 } else
624 mmesa->depth_clear_mask = ~0;
625 mmesa->ClearDepth = 0xffffff00;
626 break;
627 case 32:
628 mmesa->depth_scale = 1.0/(GLdouble)0xffffffff;
629 mmesa->depth_clear_mask = ~0;
630 mmesa->ClearDepth = 0xffffffff;
631 break;
632 };
633
634 mmesa->haveHwStipple = GL_FALSE;
635 mmesa->RenderIndex = -1; /* impossible value */
636 mmesa->dirty = ~0;
637 mmesa->vertex_format = 0;
638 mmesa->CurrentTexObj[0] = 0;
639 mmesa->CurrentTexObj[1] = 0;
640 mmesa->tmu_source[0] = 0;
641 mmesa->tmu_source[1] = 1;
642
643 mmesa->texAge[0] = 0;
644 mmesa->texAge[1] = 0;
645
646 /* Initialize the software rasterizer and helper modules.
647 */
648 _swrast_CreateContext( ctx );
649 _ac_CreateContext( ctx );
650 _tnl_CreateContext( ctx );
651
652 _swsetup_CreateContext( ctx );
653
654 /* Install the customized pipeline:
655 */
656 _tnl_destroy_pipeline( ctx );
657 _tnl_install_pipeline( ctx, mga_pipeline );
658
659 /* Configure swrast and T&L to match hardware characteristics:
660 */
661 _swrast_allow_pixel_fog( ctx, GL_FALSE );
662 _swrast_allow_vertex_fog( ctx, GL_TRUE );
663 _tnl_allow_pixel_fog( ctx, GL_FALSE );
664 _tnl_allow_vertex_fog( ctx, GL_TRUE );
665
666 mmesa->primary_offset = mmesa->mgaScreen->primary.handle;
667
668 ctx->DriverCtx = (void *) mmesa;
669 mmesa->glCtx = ctx;
670
671 driInitExtensions( ctx, card_extensions, GL_FALSE );
672
673 if (MGA_IS_G400(MGA_CONTEXT(ctx))) {
674 driInitExtensions( ctx, g400_extensions, GL_FALSE );
675 }
676
677 if ( driQueryOptionb( &mmesa->optionCache, "arb_vertex_program" ) ) {
678 _mesa_enable_extension( ctx, "GL_ARB_vertex_program" );
679 }
680
681 if ( driQueryOptionb( &mmesa->optionCache, "nv_vertex_program" ) ) {
682 _mesa_enable_extension( ctx, "GL_NV_vertex_program" );
683 _mesa_enable_extension( ctx, "GL_NV_vertex_program1_1" );
684 }
685
686
687 /* XXX these should really go right after _mesa_init_driver_functions() */
688 mgaDDInitStateFuncs( ctx );
689 mgaDDInitSpanFuncs( ctx );
690 mgaDDInitPixelFuncs( ctx );
691 mgaDDInitTriFuncs( ctx );
692
693 mgaInitVB( ctx );
694 mgaInitState( mmesa );
695
696 driContextPriv->driverPrivate = (void *) mmesa;
697
698 #if DO_DEBUG
699 MGA_DEBUG = driParseDebugString( getenv( "MGA_DEBUG" ),
700 debug_control );
701 #endif
702
703 mmesa->vblank_flags = ((mmesa->mgaScreen->irq == 0)
704 || !mmesa->mgaScreen->linecomp_sane)
705 ? VBLANK_FLAG_NO_IRQ : driGetDefaultVBlankFlags(&mmesa->optionCache);
706
707 mmesa->get_ust = (PFNGLXGETUSTPROC) glXGetProcAddress( (const GLubyte *) "__glXGetUST" );
708 if ( mmesa->get_ust == NULL ) {
709 mmesa->get_ust = get_ust_nop;
710 }
711
712 (*mmesa->get_ust)( & mmesa->swap_ust );
713
714 return GL_TRUE;
715 }
716
717 static void
718 mgaDestroyContext(__DRIcontextPrivate *driContextPriv)
719 {
720 mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate;
721
722 if (MGA_DEBUG&DEBUG_VERBOSE_DRI)
723 fprintf( stderr, "[%s:%d] mgaDestroyContext start\n",
724 __FILE__, __LINE__ );
725
726 assert(mmesa); /* should never be null */
727 if (mmesa) {
728 GLboolean release_texture_heaps;
729
730
731 release_texture_heaps = (mmesa->glCtx->Shared->RefCount == 1);
732 _swsetup_DestroyContext( mmesa->glCtx );
733 _tnl_DestroyContext( mmesa->glCtx );
734 _ac_DestroyContext( mmesa->glCtx );
735 _swrast_DestroyContext( mmesa->glCtx );
736
737 mgaFreeVB( mmesa->glCtx );
738
739 /* free the Mesa context */
740 mmesa->glCtx->DriverCtx = NULL;
741 _mesa_destroy_context(mmesa->glCtx);
742
743 if ( release_texture_heaps ) {
744 /* This share group is about to go away, free our private
745 * texture object data.
746 */
747 int i;
748
749 for ( i = 0 ; i < mmesa->nr_heaps ; i++ ) {
750 driDestroyTextureHeap( mmesa->texture_heaps[ i ] );
751 mmesa->texture_heaps[ i ] = NULL;
752 }
753
754 assert( is_empty_list( & mmesa->swapped ) );
755 }
756
757 /* free the option cache */
758 driDestroyOptionCache (&mmesa->optionCache);
759
760 FREE(mmesa);
761 }
762
763 if (MGA_DEBUG&DEBUG_VERBOSE_DRI)
764 fprintf( stderr, "[%s:%d] mgaDestroyContext done\n",
765 __FILE__, __LINE__ );
766 }
767
768
769 static GLboolean
770 mgaCreateBuffer( __DRIscreenPrivate *driScrnPriv,
771 __DRIdrawablePrivate *driDrawPriv,
772 const __GLcontextModes *mesaVis,
773 GLboolean isPixmap )
774 {
775 if (isPixmap) {
776 return GL_FALSE; /* not implemented */
777 }
778 else {
779 GLboolean swStencil = (mesaVis->stencilBits > 0 &&
780 mesaVis->depthBits != 24);
781
782 driDrawPriv->driverPrivate = (void *)
783 _mesa_create_framebuffer(mesaVis,
784 GL_FALSE, /* software depth buffer? */
785 swStencil,
786 mesaVis->accumRedBits > 0,
787 mesaVis->alphaBits > 0 );
788
789 return (driDrawPriv->driverPrivate != NULL);
790 }
791 }
792
793
794 static void
795 mgaDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
796 {
797 _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
798 }
799
800 static void
801 mgaSwapBuffers(__DRIdrawablePrivate *dPriv)
802 {
803 if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
804 mgaContextPtr mmesa;
805 GLcontext *ctx;
806 mmesa = (mgaContextPtr) dPriv->driContextPriv->driverPrivate;
807 ctx = mmesa->glCtx;
808
809 if (ctx->Visual.doubleBufferMode) {
810 _mesa_notifySwapBuffers( ctx );
811 mgaCopyBuffer( dPriv );
812 }
813 } else {
814 /* XXX this shouldn't be an error but we can't handle it for now */
815 _mesa_problem(NULL, "%s: drawable has no context!\n", __FUNCTION__);
816 }
817 }
818
819 static GLboolean
820 mgaUnbindContext(__DRIcontextPrivate *driContextPriv)
821 {
822 mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate;
823 if (mmesa)
824 mmesa->dirty = ~0;
825
826 return GL_TRUE;
827 }
828
829 /* This looks buggy to me - the 'b' variable isn't used anywhere...
830 * Hmm - It seems that the drawable is already hooked in to
831 * driDrawablePriv.
832 *
833 * But why are we doing context initialization here???
834 */
835 static GLboolean
836 mgaMakeCurrent(__DRIcontextPrivate *driContextPriv,
837 __DRIdrawablePrivate *driDrawPriv,
838 __DRIdrawablePrivate *driReadPriv)
839 {
840 if (driContextPriv) {
841 mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate;
842
843 if (mmesa->driDrawable != driDrawPriv) {
844 driDrawableInitVBlank( driDrawPriv, mmesa->vblank_flags );
845 mmesa->driDrawable = driDrawPriv;
846 mmesa->dirty = ~0;
847 mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK);
848 mmesa->mesa_drawable = driDrawPriv;
849 }
850
851 mmesa->driReadable = driReadPriv;
852
853 _mesa_make_current2(mmesa->glCtx,
854 (GLframebuffer *) driDrawPriv->driverPrivate,
855 (GLframebuffer *) driReadPriv->driverPrivate);
856
857 if (!mmesa->glCtx->Viewport.Width)
858 _mesa_set_viewport(mmesa->glCtx, 0, 0,
859 driDrawPriv->w, driDrawPriv->h);
860
861 }
862 else {
863 _mesa_make_current(NULL, NULL);
864 }
865
866 return GL_TRUE;
867 }
868
869
870 void mgaGetLock( mgaContextPtr mmesa, GLuint flags )
871 {
872 __DRIdrawablePrivate *dPriv = mmesa->driDrawable;
873 drm_mga_sarea_t *sarea = mmesa->sarea;
874 int me = mmesa->hHWContext;
875 int i;
876
877 drmGetLock(mmesa->driFd, mmesa->hHWContext, flags);
878
879 if (*(dPriv->pStamp) != mmesa->lastStamp) {
880 mmesa->lastStamp = *(dPriv->pStamp);
881 mmesa->SetupNewInputs |= VERT_BIT_POS;
882 mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK);
883 mgaUpdateRects( mmesa, (MGA_FRONT|MGA_BACK) );
884 }
885
886 mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_CLIPRECTS;
887
888 mmesa->sarea->dirty |= MGA_UPLOAD_CONTEXT;
889
890 if (sarea->ctxOwner != me) {
891 mmesa->dirty |= (MGA_UPLOAD_CONTEXT | MGA_UPLOAD_TEX0 |
892 MGA_UPLOAD_TEX1 | MGA_UPLOAD_PIPE);
893 sarea->ctxOwner=me;
894 }
895
896 for ( i = 0 ; i < mmesa->nr_heaps ; i++ ) {
897 DRI_AGE_TEXTURES( mmesa->texture_heaps[ i ] );
898 }
899
900 sarea->last_quiescent = -1; /* just kill it for now */
901 }
902
903
904 static const struct __DriverAPIRec mgaAPI = {
905 .InitDriver = mgaInitDriver,
906 .DestroyScreen = mgaDestroyScreen,
907 .CreateContext = mgaCreateContext,
908 .DestroyContext = mgaDestroyContext,
909 .CreateBuffer = mgaCreateBuffer,
910 .DestroyBuffer = mgaDestroyBuffer,
911 .SwapBuffers = mgaSwapBuffers,
912 .MakeCurrent = mgaMakeCurrent,
913 .UnbindContext = mgaUnbindContext,
914 .GetSwapInfo = getSwapInfo,
915 .GetMSC = driGetMSC32,
916 .WaitForMSC = driWaitForMSC32,
917 .WaitForSBC = NULL,
918 .SwapBuffersMSC = NULL
919 };
920
921
922 /*
923 * This is the bootstrap function for the driver.
924 * The __driCreateScreen name is the symbol that libGL.so fetches.
925 * Return: pointer to a __DRIscreenPrivate.
926 */
927 #if !defined(DRI_NEW_INTERFACE_ONLY)
928 void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
929 int numConfigs, __GLXvisualConfig *config)
930 {
931 __DRIscreenPrivate *psp;
932 psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &mgaAPI);
933 return (void *) psp;
934 }
935 #endif /* !defined(DRI_NEW_INTERFACE_ONLY) */
936
937
938 /**
939 * This is the bootstrap function for the driver. libGL supplies all of the
940 * requisite information about the system, and the driver initializes itself.
941 * This routine also fills in the linked list pointed to by \c driver_modes
942 * with the \c __GLcontextModes that the driver can support for windows or
943 * pbuffers.
944 *
945 * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
946 * failure.
947 */
948 #ifdef USE_NEW_INTERFACE
949 void * __driCreateNewScreen( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
950 const __GLcontextModes * modes,
951 const __DRIversion * ddx_version,
952 const __DRIversion * dri_version,
953 const __DRIversion * drm_version,
954 const __DRIframebuffer * frame_buffer,
955 drmAddress pSAREA, int fd,
956 int internal_api_version,
957 __GLcontextModes ** driver_modes )
958
959 {
960 __DRIscreenPrivate *psp;
961 static const __DRIversion ddx_expected = { 1, 0, 0 };
962 static const __DRIversion dri_expected = { 4, 0, 0 };
963 static const __DRIversion drm_expected = { 3, 0, 0 };
964
965 if ( ! driCheckDriDdxDrmVersions2( "MGA",
966 dri_version, & dri_expected,
967 ddx_version, & ddx_expected,
968 drm_version, & drm_expected ) ) {
969 return NULL;
970 }
971
972 psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
973 ddx_version, dri_version, drm_version,
974 frame_buffer, pSAREA, fd,
975 internal_api_version, &mgaAPI);
976 if ( psp != NULL ) {
977 create_context_modes = (PFNGLXCREATECONTEXTMODES)
978 glXGetProcAddress( (const GLubyte *) "__glXCreateContextModes" );
979 if ( create_context_modes != NULL ) {
980 MGADRIPtr dri_priv = (MGADRIPtr) psp->pDevPriv;
981 *driver_modes = mgaFillInModes( dri_priv->cpp * 8,
982 (dri_priv->cpp == 2) ? 16 : 24,
983 (dri_priv->cpp == 2) ? 0 : 8,
984 (dri_priv->backOffset != dri_priv->depthOffset) );
985 }
986 }
987
988 return (void *) psp;
989 }
990 #endif /* USE_NEW_INTERFACE */
991
992
993 /**
994 * Get information about previous buffer swaps.
995 */
996 static int
997 getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
998 {
999 mgaContextPtr mmesa;
1000
1001 if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL)
1002 || (dPriv->driContextPriv->driverPrivate == NULL)
1003 || (sInfo == NULL) ) {
1004 return -1;
1005 }
1006
1007 mmesa = (mgaContextPtr) dPriv->driContextPriv->driverPrivate;
1008 sInfo->swap_count = mmesa->swap_count;
1009 sInfo->swap_ust = mmesa->swap_ust;
1010 sInfo->swap_missed_count = mmesa->swap_missed_count;
1011
1012 sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
1013 ? driCalculateSwapUsage( dPriv, 0, mmesa->swap_missed_ust )
1014 : 0.0;
1015
1016 return 0;
1017 }