Make the drivers using the common texmem code work with NewTextureObject
[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 #ifndef MGA_DEBUG
81 int MGA_DEBUG = 0;
82 #endif
83
84 static int getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo );
85
86 static GLboolean
87 mgaInitDriver(__DRIscreenPrivate *sPriv)
88 {
89 mgaScreenPrivate *mgaScreen;
90 MGADRIPtr serverInfo = (MGADRIPtr)sPriv->pDevPriv;
91
92 if ( ! driCheckDriDdxDrmVersions( sPriv, "MGA", 4, 0, 1, 0, 3, 0 ) )
93 return GL_FALSE;
94
95 /* Allocate the private area */
96 mgaScreen = (mgaScreenPrivate *)MALLOC(sizeof(mgaScreenPrivate));
97 if (!mgaScreen) {
98 __driUtilMessage("Couldn't malloc screen struct");
99 return GL_FALSE;
100 }
101
102 mgaScreen->sPriv = sPriv;
103 sPriv->private = (void *)mgaScreen;
104
105 if (sPriv->drmMinor >= 1) {
106 int ret;
107 drmMGAGetParam gp;
108
109 gp.param = MGA_PARAM_IRQ_NR;
110 gp.value = &mgaScreen->irq;
111
112 ret = drmCommandWriteRead( sPriv->fd, DRM_MGA_GETPARAM,
113 &gp, sizeof(gp));
114 if (ret) {
115 fprintf(stderr, "drmMgaGetParam (MGA_PARAM_IRQ_NR): %d\n", ret);
116 FREE(mgaScreen);
117 sPriv->private = NULL;
118 return GL_FALSE;
119 }
120 }
121
122 mgaScreen->linecomp_sane = (sPriv->ddxMajor > 1) || (sPriv->ddxMinor > 1)
123 || ((sPriv->ddxMinor == 1) && (sPriv->ddxPatch > 0));
124 #ifndef _SOLO
125 if ( driCompareGLXAPIVersion( 20030813 ) >= 0 ) {
126 PFNGLXSCRENABLEEXTENSIONPROC glx_enable_extension =
127 (PFNGLXSCRENABLEEXTENSIONPROC) glXGetProcAddress( (const GLubyte *) "__glXScrEnableExtension" );
128 void * const psc = sPriv->psc->screenConfigs;
129
130 if ( glx_enable_extension != NULL ) {
131 if ( mgaScreen->linecomp_sane ) {
132 (*glx_enable_extension)( psc, "GLX_SGI_swap_control" );
133 (*glx_enable_extension)( psc, "GLX_SGI_video_sync" );
134 (*glx_enable_extension)( psc, "GLX_MESA_swap_control" );
135 }
136
137 (*glx_enable_extension)( psc, "GLX_SGI_make_current_read" );
138 (*glx_enable_extension)( psc, "GLX_MESA_swap_frame_usage" );
139 }
140 }
141 #endif
142
143 if (serverInfo->chipset != MGA_CARD_TYPE_G200 &&
144 serverInfo->chipset != MGA_CARD_TYPE_G400) {
145 FREE(mgaScreen);
146 sPriv->private = NULL;
147 __driUtilMessage("Unrecognized chipset");
148 return GL_FALSE;
149 }
150
151
152 mgaScreen->chipset = serverInfo->chipset;
153 mgaScreen->width = serverInfo->width;
154 mgaScreen->height = serverInfo->height;
155 mgaScreen->mem = serverInfo->mem;
156 mgaScreen->cpp = serverInfo->cpp;
157
158 mgaScreen->agpMode = serverInfo->agpMode;
159
160 mgaScreen->frontPitch = serverInfo->frontPitch;
161 mgaScreen->frontOffset = serverInfo->frontOffset;
162 mgaScreen->backOffset = serverInfo->backOffset;
163 mgaScreen->backPitch = serverInfo->backPitch;
164 mgaScreen->depthOffset = serverInfo->depthOffset;
165 mgaScreen->depthPitch = serverInfo->depthPitch;
166
167 mgaScreen->mmio.handle = serverInfo->registers.handle;
168 mgaScreen->mmio.size = serverInfo->registers.size;
169 if ( drmMap( sPriv->fd,
170 mgaScreen->mmio.handle, mgaScreen->mmio.size,
171 &mgaScreen->mmio.map ) < 0 ) {
172 FREE( mgaScreen );
173 sPriv->private = NULL;
174 __driUtilMessage( "Couldn't map MMIO registers" );
175 return GL_FALSE;
176 }
177
178 mgaScreen->primary.handle = serverInfo->primary.handle;
179 mgaScreen->primary.size = serverInfo->primary.size;
180 mgaScreen->buffers.handle = serverInfo->buffers.handle;
181 mgaScreen->buffers.size = serverInfo->buffers.size;
182
183 #if 0
184 mgaScreen->agp.handle = serverInfo->agp;
185 mgaScreen->agp.size = serverInfo->agpSize;
186
187 if (drmMap(sPriv->fd,
188 mgaScreen->agp.handle,
189 mgaScreen->agp.size,
190 (drmAddress *)&mgaScreen->agp.map) != 0)
191 {
192 Xfree(mgaScreen);
193 sPriv->private = NULL;
194 __driUtilMessage("Couldn't map agp region");
195 return GL_FALSE;
196 }
197 #endif
198
199 mgaScreen->textureOffset[MGA_CARD_HEAP] = serverInfo->textureOffset;
200 mgaScreen->textureOffset[MGA_AGP_HEAP] = (serverInfo->agpTextureOffset |
201 PDEA_pagpxfer_enable | 1);
202
203 mgaScreen->textureSize[MGA_CARD_HEAP] = serverInfo->textureSize;
204 mgaScreen->textureSize[MGA_AGP_HEAP] = serverInfo->agpTextureSize;
205
206 mgaScreen->logTextureGranularity[MGA_CARD_HEAP] =
207 serverInfo->logTextureGranularity;
208 mgaScreen->logTextureGranularity[MGA_AGP_HEAP] =
209 serverInfo->logAgpTextureGranularity;
210
211 mgaScreen->texVirtual[MGA_CARD_HEAP] = (char *)(mgaScreen->sPriv->pFB +
212 serverInfo->textureOffset);
213 if (drmMap(sPriv->fd,
214 serverInfo->agpTextureOffset,
215 serverInfo->agpTextureSize,
216 (drmAddress *)&mgaScreen->texVirtual[MGA_AGP_HEAP]) != 0)
217 {
218 FREE(mgaScreen);
219 sPriv->private = NULL;
220 __driUtilMessage("Couldn't map agptexture region");
221 return GL_FALSE;
222 }
223
224 #if 0
225 mgaScreen->texVirtual[MGA_AGP_HEAP] = (mgaScreen->agp.map +
226 serverInfo->agpTextureOffset);
227 #endif
228
229 mgaScreen->mAccess = serverInfo->mAccess;
230
231 /* For calculating setupdma addresses.
232 */
233 mgaScreen->dmaOffset = serverInfo->buffers.handle;
234
235 mgaScreen->bufs = drmMapBufs(sPriv->fd);
236 if (!mgaScreen->bufs) {
237 /*drmUnmap(mgaScreen->agp_tex.map, mgaScreen->agp_tex.size);*/
238 FREE(mgaScreen);
239 sPriv->private = NULL;
240 __driUtilMessage("Couldn't map dma buffers");
241 return GL_FALSE;
242 }
243 mgaScreen->sarea_priv_offset = serverInfo->sarea_priv_offset;
244
245 /* parse information in __driConfigOptions */
246 driParseOptionInfo (&mgaScreen->optionCache,
247 __driConfigOptions, __driNConfigOptions);
248
249 return GL_TRUE;
250 }
251
252
253 static void
254 mgaDestroyScreen(__DRIscreenPrivate *sPriv)
255 {
256 mgaScreenPrivate *mgaScreen = (mgaScreenPrivate *) sPriv->private;
257
258 if (MGA_DEBUG&DEBUG_VERBOSE_DRI)
259 fprintf(stderr, "mgaDestroyScreen\n");
260
261 /*drmUnmap(mgaScreen->agp_tex.map, mgaScreen->agp_tex.size);*/
262
263 /* free all option information */
264 driDestroyOptionInfo (&mgaScreen->optionCache);
265
266 FREE(mgaScreen);
267 sPriv->private = NULL;
268 }
269
270
271 extern const struct tnl_pipeline_stage _mga_render_stage;
272
273 static const struct tnl_pipeline_stage *mga_pipeline[] = {
274 &_tnl_vertex_transform_stage,
275 &_tnl_normal_transform_stage,
276 &_tnl_lighting_stage,
277 &_tnl_fog_coordinate_stage,
278 &_tnl_texgen_stage,
279 &_tnl_texture_transform_stage,
280 /* REMOVE: point attenuation stage */
281 #if 0
282 &_mga_render_stage, /* ADD: unclipped rastersetup-to-dma */
283 /* Need new ioctl for wacceptseq */
284 #endif
285 &_tnl_render_stage,
286 0,
287 };
288
289
290 static const char * const g400_extensions[] =
291 {
292 "GL_ARB_multitexture",
293 "GL_ARB_texture_env_add",
294 "GL_ARB_texture_env_combine",
295 "GL_ARB_texture_env_crossbar",
296 "GL_EXT_texture_env_combine",
297 "GL_EXT_texture_edge_clamp",
298 "GL_ATI_texture_env_combine3",
299 #if defined (MESA_packed_depth_stencil)
300 "GL_MESA_packed_depth_stencil",
301 #endif
302 NULL
303 };
304
305 static const char * const card_extensions[] =
306 {
307 "GL_ARB_multisample",
308 "GL_ARB_texture_compression",
309 "GL_EXT_blend_logic_op",
310 "GL_EXT_fog_coord",
311 /* paletted_textures currently doesn't work, but we could fix them later */
312 #if 0
313 "GL_EXT_shared_texture_palette",
314 "GL_EXT_paletted_texture",
315 #endif
316 "GL_EXT_secondary_color",
317 "GL_EXT_stencil_wrap",
318 "GL_EXT_texture_rectangle",
319 "GL_MESA_ycbcr_texture",
320 "GL_SGIS_generate_mipmap",
321 "GL_SGIS_texture_lod",
322 NULL
323 };
324
325 static const struct dri_debug_control debug_control[] =
326 {
327 { "fall", DEBUG_VERBOSE_FALLBACK },
328 { "tex", DEBUG_VERBOSE_TEXTURE },
329 { "ioctl", DEBUG_VERBOSE_IOCTL },
330 { "verb", DEBUG_VERBOSE_MSG },
331 { "dri", DEBUG_VERBOSE_DRI },
332 { NULL, 0 }
333 };
334
335
336 static int
337 get_ust_nop( int64_t * ust )
338 {
339 *ust = 1;
340 return 0;
341 }
342
343
344 static GLboolean
345 mgaCreateContext( const __GLcontextModes *mesaVis,
346 __DRIcontextPrivate *driContextPriv,
347 void *sharedContextPrivate )
348 {
349 int i;
350 unsigned maxlevels;
351 GLcontext *ctx, *shareCtx;
352 mgaContextPtr mmesa;
353 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
354 mgaScreenPrivate *mgaScreen = (mgaScreenPrivate *)sPriv->private;
355 MGASAREAPrivPtr saPriv=(MGASAREAPrivPtr)(((char*)sPriv->pSAREA)+
356 mgaScreen->sarea_priv_offset);
357 struct dd_function_table functions;
358
359 if (MGA_DEBUG&DEBUG_VERBOSE_DRI)
360 fprintf(stderr, "mgaCreateContext\n");
361
362 /* allocate mga context */
363 mmesa = (mgaContextPtr) CALLOC(sizeof(mgaContext));
364 if (!mmesa) {
365 return GL_FALSE;
366 }
367
368 /* Init default driver functions then plug in our Radeon-specific functions
369 * (the texture functions are especially important)
370 */
371 _mesa_init_driver_functions( &functions );
372 mgaInitDriverFuncs( &functions );
373 mgaInitTextureFuncs( &functions );
374 mgaInitIoctlFuncs( &functions );
375
376 /* Allocate the Mesa context */
377 if (sharedContextPrivate)
378 shareCtx = ((mgaContextPtr) sharedContextPrivate)->glCtx;
379 else
380 shareCtx = NULL;
381 mmesa->glCtx = _mesa_create_context(mesaVis, shareCtx,
382 &functions, (void *) mmesa);
383 if (!mmesa->glCtx) {
384 FREE(mmesa);
385 return GL_FALSE;
386 }
387 driContextPriv->driverPrivate = mmesa;
388
389 /* Init mga state */
390 mmesa->hHWContext = driContextPriv->hHWContext;
391 mmesa->driFd = sPriv->fd;
392 mmesa->driHwLock = &sPriv->pSAREA->lock;
393
394 mmesa->mgaScreen = mgaScreen;
395 mmesa->driScreen = sPriv;
396 mmesa->sarea = (void *)saPriv;
397
398 /* Parse configuration files */
399 driParseConfigFiles (&mmesa->optionCache, &mgaScreen->optionCache,
400 sPriv->myNum, "mga");
401
402 (void) memset( mmesa->texture_heaps, 0, sizeof( mmesa->texture_heaps ) );
403 make_empty_list( & mmesa->swapped );
404
405 mmesa->nr_heaps = mgaScreen->texVirtual[MGA_AGP_HEAP] ? 2 : 1;
406 for ( i = 0 ; i < mmesa->nr_heaps ; i++ ) {
407 mmesa->texture_heaps[i] = driCreateTextureHeap( i, mmesa,
408 mgaScreen->textureSize[i],
409 6,
410 MGA_NR_TEX_REGIONS,
411 mmesa->sarea->texList[i],
412 & mmesa->sarea->texAge[i],
413 & mmesa->swapped,
414 sizeof( mgaTextureObject_t ),
415 (destroy_texture_object_t *) mgaDestroyTexObj );
416 }
417
418 /* Set the maximum texture size small enough that we can guarentee
419 * that both texture units can bind a maximal texture and have them
420 * on the card at once.
421 */
422 ctx = mmesa->glCtx;
423 if ( mgaScreen->chipset == MGA_CARD_TYPE_G200 ) {
424 ctx->Const.MaxTextureUnits = 1;
425 ctx->Const.MaxTextureImageUnits = 1;
426 ctx->Const.MaxTextureCoordUnits = 1;
427 maxlevels = G200_TEX_MAXLEVELS;
428
429 }
430 else {
431 ctx->Const.MaxTextureUnits = 2;
432 ctx->Const.MaxTextureImageUnits = 2;
433 ctx->Const.MaxTextureCoordUnits = 2;
434 maxlevels = G400_TEX_MAXLEVELS;
435 }
436
437 driCalculateMaxTextureLevels( mmesa->texture_heaps,
438 mmesa->nr_heaps,
439 & ctx->Const,
440 4,
441 11, /* max 2D texture size is 2048x2048 */
442 0, /* 3D textures unsupported. */
443 0, /* cube textures unsupported. */
444 11, /* max texture rect size is 2048x2048 */
445 maxlevels,
446 GL_FALSE );
447
448 ctx->Const.MinLineWidth = 1.0;
449 ctx->Const.MinLineWidthAA = 1.0;
450 ctx->Const.MaxLineWidth = 10.0;
451 ctx->Const.MaxLineWidthAA = 10.0;
452 ctx->Const.LineWidthGranularity = 1.0;
453
454 mmesa->texture_depth = driQueryOptioni (&mmesa->optionCache,
455 "texture_depth");
456 if (mmesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FB)
457 mmesa->texture_depth = ( mesaVis->rgbBits >= 24 ) ?
458 DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
459 mmesa->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24;
460
461 switch (mesaVis->depthBits) {
462 case 16:
463 mmesa->depth_scale = 1.0/(GLdouble)0xffff;
464 mmesa->depth_clear_mask = ~0;
465 mmesa->ClearDepth = 0xffff;
466 break;
467 case 24:
468 mmesa->depth_scale = 1.0/(GLdouble)0xffffff;
469 if (mmesa->hw_stencil) {
470 mmesa->depth_clear_mask = 0xffffff00;
471 mmesa->stencil_clear_mask = 0x000000ff;
472 } else
473 mmesa->depth_clear_mask = ~0;
474 mmesa->ClearDepth = 0xffffff00;
475 break;
476 case 32:
477 mmesa->depth_scale = 1.0/(GLdouble)0xffffffff;
478 mmesa->depth_clear_mask = ~0;
479 mmesa->ClearDepth = 0xffffffff;
480 break;
481 };
482
483 mmesa->haveHwStipple = GL_FALSE;
484 mmesa->RenderIndex = -1; /* impossible value */
485 mmesa->dirty = ~0;
486 mmesa->vertex_format = 0;
487 mmesa->CurrentTexObj[0] = 0;
488 mmesa->CurrentTexObj[1] = 0;
489 mmesa->tmu_source[0] = 0;
490 mmesa->tmu_source[1] = 1;
491
492 mmesa->texAge[0] = 0;
493 mmesa->texAge[1] = 0;
494
495 /* Initialize the software rasterizer and helper modules.
496 */
497 _swrast_CreateContext( ctx );
498 _ac_CreateContext( ctx );
499 _tnl_CreateContext( ctx );
500
501 _swsetup_CreateContext( ctx );
502
503 /* Install the customized pipeline:
504 */
505 _tnl_destroy_pipeline( ctx );
506 _tnl_install_pipeline( ctx, mga_pipeline );
507
508 /* Configure swrast to match hardware characteristics:
509 */
510 _swrast_allow_pixel_fog( ctx, GL_FALSE );
511 _swrast_allow_vertex_fog( ctx, GL_TRUE );
512
513 mmesa->primary_offset = mmesa->mgaScreen->primary.handle;
514
515 ctx->DriverCtx = (void *) mmesa;
516 mmesa->glCtx = ctx;
517
518 driInitExtensions( ctx, card_extensions, GL_FALSE );
519
520 if (MGA_IS_G400(MGA_CONTEXT(ctx))) {
521 driInitExtensions( ctx, g400_extensions, GL_FALSE );
522 }
523
524 /* XXX these should really go right after _mesa_init_driver_functions() */
525 mgaDDInitStateFuncs( ctx );
526 mgaDDInitSpanFuncs( ctx );
527 mgaDDInitPixelFuncs( ctx );
528 mgaDDInitTriFuncs( ctx );
529
530 mgaInitVB( ctx );
531 mgaInitState( mmesa );
532
533 driContextPriv->driverPrivate = (void *) mmesa;
534
535 #if DO_DEBUG
536 MGA_DEBUG = driParseDebugString( getenv( "MGA_DEBUG" ),
537 debug_control );
538 #endif
539
540 mmesa->vblank_flags = ((mmesa->mgaScreen->irq == 0)
541 || !mmesa->mgaScreen->linecomp_sane)
542 ? VBLANK_FLAG_NO_IRQ : driGetDefaultVBlankFlags(&mmesa->optionCache);
543 #ifndef _SOLO
544 mmesa->get_ust = (PFNGLXGETUSTPROC) glXGetProcAddress( (const GLubyte *) "__glXGetUST" );
545 if ( mmesa->get_ust == NULL ) {
546 mmesa->get_ust = get_ust_nop;
547 }
548 #else
549 mmesa->get_ust = get_ust_nop;
550 #endif
551
552 (*mmesa->get_ust)( & mmesa->swap_ust );
553
554 return GL_TRUE;
555 }
556
557 static void
558 mgaDestroyContext(__DRIcontextPrivate *driContextPriv)
559 {
560 mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate;
561
562 if (MGA_DEBUG&DEBUG_VERBOSE_DRI)
563 fprintf( stderr, "[%s:%d] mgaDestroyContext start\n",
564 __FILE__, __LINE__ );
565
566 assert(mmesa); /* should never be null */
567 if (mmesa) {
568 GLboolean release_texture_heaps;
569
570
571 release_texture_heaps = (mmesa->glCtx->Shared->RefCount == 1);
572 _swsetup_DestroyContext( mmesa->glCtx );
573 _tnl_DestroyContext( mmesa->glCtx );
574 _ac_DestroyContext( mmesa->glCtx );
575 _swrast_DestroyContext( mmesa->glCtx );
576
577 mgaFreeVB( mmesa->glCtx );
578
579 /* free the Mesa context */
580 mmesa->glCtx->DriverCtx = NULL;
581 _mesa_destroy_context(mmesa->glCtx);
582
583 if ( release_texture_heaps ) {
584 /* This share group is about to go away, free our private
585 * texture object data.
586 */
587 int i;
588
589 for ( i = 0 ; i < mmesa->nr_heaps ; i++ ) {
590 driDestroyTextureHeap( mmesa->texture_heaps[ i ] );
591 mmesa->texture_heaps[ i ] = NULL;
592 }
593
594 assert( is_empty_list( & mmesa->swapped ) );
595 }
596
597 /* free the option cache */
598 driDestroyOptionCache (&mmesa->optionCache);
599
600 FREE(mmesa);
601 }
602
603 if (MGA_DEBUG&DEBUG_VERBOSE_DRI)
604 fprintf( stderr, "[%s:%d] mgaDestroyContext done\n",
605 __FILE__, __LINE__ );
606 }
607
608
609 static GLboolean
610 mgaCreateBuffer( __DRIscreenPrivate *driScrnPriv,
611 __DRIdrawablePrivate *driDrawPriv,
612 const __GLcontextModes *mesaVis,
613 GLboolean isPixmap )
614 {
615 if (isPixmap) {
616 return GL_FALSE; /* not implemented */
617 }
618 else {
619 GLboolean swStencil = (mesaVis->stencilBits > 0 &&
620 mesaVis->depthBits != 24);
621
622 driDrawPriv->driverPrivate = (void *)
623 _mesa_create_framebuffer(mesaVis,
624 GL_FALSE, /* software depth buffer? */
625 swStencil,
626 mesaVis->accumRedBits > 0,
627 mesaVis->alphaBits > 0 );
628
629 return (driDrawPriv->driverPrivate != NULL);
630 }
631 }
632
633
634 static void
635 mgaDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
636 {
637 _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
638 }
639
640 static void
641 mgaSwapBuffers(__DRIdrawablePrivate *dPriv)
642 {
643 if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
644 mgaContextPtr mmesa;
645 GLcontext *ctx;
646 mmesa = (mgaContextPtr) dPriv->driContextPriv->driverPrivate;
647 ctx = mmesa->glCtx;
648
649 if (ctx->Visual.doubleBufferMode) {
650 _mesa_notifySwapBuffers( ctx );
651 mgaCopyBuffer( dPriv );
652 }
653 } else {
654 /* XXX this shouldn't be an error but we can't handle it for now */
655 _mesa_problem(NULL, "%s: drawable has no context!\n", __FUNCTION__);
656 }
657 }
658
659 static GLboolean
660 mgaUnbindContext(__DRIcontextPrivate *driContextPriv)
661 {
662 mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate;
663 if (mmesa)
664 mmesa->dirty = ~0;
665
666 return GL_TRUE;
667 }
668
669 static GLboolean
670 mgaOpenCloseFullScreen(__DRIcontextPrivate *driContextPriv)
671 {
672 return GL_TRUE;
673 }
674
675
676 /* This looks buggy to me - the 'b' variable isn't used anywhere...
677 * Hmm - It seems that the drawable is already hooked in to
678 * driDrawablePriv.
679 *
680 * But why are we doing context initialization here???
681 */
682 static GLboolean
683 mgaMakeCurrent(__DRIcontextPrivate *driContextPriv,
684 __DRIdrawablePrivate *driDrawPriv,
685 __DRIdrawablePrivate *driReadPriv)
686 {
687 if (driContextPriv) {
688 mgaContextPtr mmesa = (mgaContextPtr) driContextPriv->driverPrivate;
689
690 if (mmesa->driDrawable != driDrawPriv) {
691 driDrawableInitVBlank( driDrawPriv, mmesa->vblank_flags );
692 mmesa->driDrawable = driDrawPriv;
693 mmesa->dirty = ~0;
694 mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK);
695 mmesa->mesa_drawable = driDrawPriv;
696 }
697
698 mmesa->driReadable = driReadPriv;
699
700 _mesa_make_current2(mmesa->glCtx,
701 (GLframebuffer *) driDrawPriv->driverPrivate,
702 (GLframebuffer *) driReadPriv->driverPrivate);
703
704 if (!mmesa->glCtx->Viewport.Width)
705 _mesa_set_viewport(mmesa->glCtx, 0, 0,
706 driDrawPriv->w, driDrawPriv->h);
707
708 }
709 else {
710 _mesa_make_current(NULL, NULL);
711 }
712
713 return GL_TRUE;
714 }
715
716
717 void mgaGetLock( mgaContextPtr mmesa, GLuint flags )
718 {
719 __DRIdrawablePrivate *dPriv = mmesa->driDrawable;
720 MGASAREAPrivPtr sarea = mmesa->sarea;
721 int me = mmesa->hHWContext;
722 int i;
723
724 drmGetLock(mmesa->driFd, mmesa->hHWContext, flags);
725
726 if (*(dPriv->pStamp) != mmesa->lastStamp) {
727 mmesa->lastStamp = *(dPriv->pStamp);
728 mmesa->SetupNewInputs |= VERT_BIT_POS;
729 mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK);
730 mgaUpdateRects( mmesa, (MGA_FRONT|MGA_BACK) );
731 }
732
733 mmesa->dirty |= MGA_UPLOAD_CONTEXT | MGA_UPLOAD_CLIPRECTS;
734
735 mmesa->sarea->dirty |= MGA_UPLOAD_CONTEXT;
736
737 if (sarea->ctxOwner != me) {
738 mmesa->dirty |= (MGA_UPLOAD_CONTEXT | MGA_UPLOAD_TEX0 |
739 MGA_UPLOAD_TEX1 | MGA_UPLOAD_PIPE);
740 sarea->ctxOwner=me;
741 }
742
743 for ( i = 0 ; i < mmesa->nr_heaps ; i++ ) {
744 DRI_AGE_TEXTURES( mmesa->texture_heaps[ i ] );
745 }
746
747 sarea->last_quiescent = -1; /* just kill it for now */
748 }
749
750
751 static const struct __DriverAPIRec mgaAPI = {
752 .InitDriver = mgaInitDriver,
753 .DestroyScreen = mgaDestroyScreen,
754 .CreateContext = mgaCreateContext,
755 .DestroyContext = mgaDestroyContext,
756 .CreateBuffer = mgaCreateBuffer,
757 .DestroyBuffer = mgaDestroyBuffer,
758 .SwapBuffers = mgaSwapBuffers,
759 .MakeCurrent = mgaMakeCurrent,
760 .UnbindContext = mgaUnbindContext,
761 .OpenFullScreen = mgaOpenCloseFullScreen,
762 .CloseFullScreen = mgaOpenCloseFullScreen,
763 .GetSwapInfo = getSwapInfo,
764 .GetMSC = driGetMSC32,
765 .WaitForMSC = driWaitForMSC32,
766 .WaitForSBC = NULL,
767 .SwapBuffersMSC = NULL
768 };
769
770
771 /*
772 * This is the bootstrap function for the driver.
773 * The __driCreateScreen name is the symbol that libGL.so fetches.
774 * Return: pointer to a __DRIscreenPrivate.
775 */
776 #ifndef _SOLO
777 void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
778 int numConfigs, __GLXvisualConfig *config)
779 {
780 __DRIscreenPrivate *psp;
781 psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &mgaAPI);
782 return (void *) psp;
783 }
784 #else
785 void *__driCreateScreen(struct DRIDriverRec *driver,
786 struct DRIDriverContextRec *driverContext)
787 {
788 __DRIscreenPrivate *psp;
789 psp = __driUtilCreateScreen(driver, driverContext, &mgaAPI);
790 return (void *) psp;
791 }
792 #endif
793
794
795 /**
796 * Get information about previous buffer swaps.
797 */
798 static int
799 getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
800 {
801 mgaContextPtr mmesa;
802
803 if ( (dPriv == NULL) || (dPriv->driContextPriv == NULL)
804 || (dPriv->driContextPriv->driverPrivate == NULL)
805 || (sInfo == NULL) ) {
806 return -1;
807 }
808
809 mmesa = (mgaContextPtr) dPriv->driContextPriv->driverPrivate;
810 sInfo->swap_count = mmesa->swap_count;
811 sInfo->swap_ust = mmesa->swap_ust;
812 sInfo->swap_missed_count = mmesa->swap_missed_count;
813
814 sInfo->swap_missed_usage = (sInfo->swap_missed_count != 0)
815 ? driCalculateSwapUsage( dPriv, 0, mmesa->swap_missed_ust )
816 : 0.0;
817
818 return 0;
819 }