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