Moved some code from savageCreateContext to savageInitDriver, where it
[mesa.git] / src / mesa / drivers / dri / savage / savage_xmesa.c
1 /*
2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25
26 #ifdef GLX_DIRECT_RENDERING
27
28 #include <X11/Xlibint.h>
29 #include <stdio.h>
30
31 #include "savagecontext.h"
32 #include "context.h"
33 #include "matrix.h"
34
35 #include "simple_list.h"
36
37 #include "utils.h"
38
39 #include "swrast/swrast.h"
40 #include "swrast_setup/swrast_setup.h"
41 #include "tnl/tnl.h"
42 #include "array_cache/acache.h"
43
44 #include "tnl/t_pipeline.h"
45
46 #include "drivers/common/driverfuncs.h"
47
48 #include "savagedd.h"
49 #include "savagestate.h"
50 #include "savagetex.h"
51 #include "savagespan.h"
52 #include "savagetris.h"
53 #include "savageioctl.h"
54 #include "savage_bci.h"
55
56 #include "savage_dri.h"
57
58 #include "savagedma.h"
59
60 #ifdef USE_NEW_INTERFACE
61 static PFNGLXCREATECONTEXTMODES create_context_modes = NULL;
62 #endif /* USE_NEW_INTERFACE */
63
64 #ifndef SAVAGE_DEBUG
65 int SAVAGE_DEBUG = (0
66 /* | DEBUG_ALWAYS_SYNC */
67 /* | DEBUG_VERBOSE_RING */
68 /* | DEBUG_VERBOSE_OUTREG */
69 /* | DEBUG_VERBOSE_MSG */
70 /* | DEBUG_NO_OUTRING */
71 /* | DEBUG_NO_OUTREG */
72 /* | DEBUG_VERBOSE_API */
73 /* | DEBUG_VERBOSE_2D */
74 /* | DEBUG_VERBOSE_DRI */
75 /* | DEBUG_VALIDATE_RING */
76 /* | DEBUG_VERBOSE_IOCTL */
77 );
78 #endif
79
80
81 /*For time caculating test*/
82 #if defined(DEBUG_TIME) && DEBUG_TIME
83 struct timeval tv_s,tv_f;
84 unsigned long time_sum=0;
85 struct timeval tv_s1,tv_f1;
86 #endif
87
88 static const char *const card_extensions[] =
89 {
90 "GL_ARB_multitexture",
91 "GL_EXT_texture_lod_bias",
92 "GL_EXT_texture_env_add",
93 NULL
94 };
95
96 /* this is first function called in dirver*/
97
98 static GLboolean
99 savageInitDriver(__DRIscreenPrivate *sPriv)
100 {
101 savageScreenPrivate *savageScreen;
102 SAVAGEDRIPtr gDRIPriv = (SAVAGEDRIPtr)sPriv->pDevPriv;
103
104
105 /* Allocate the private area */
106 savageScreen = (savageScreenPrivate *)Xmalloc(sizeof(savageScreenPrivate));
107 if (!savageScreen)
108 return GL_FALSE;
109
110 savageScreen->driScrnPriv = sPriv;
111 sPriv->private = (void *)savageScreen;
112
113 savageScreen->chipset=gDRIPriv->chipset;
114 savageScreen->width=gDRIPriv->width;
115 savageScreen->height=gDRIPriv->height;
116 savageScreen->mem=gDRIPriv->mem;
117 savageScreen->cpp=gDRIPriv->cpp;
118 savageScreen->zpp=gDRIPriv->zpp;
119 savageScreen->frontPitch=gDRIPriv->frontPitch;
120 savageScreen->frontOffset=gDRIPriv->frontOffset;
121 savageScreen->frontBitmapDesc = gDRIPriv->frontBitmapDesc;
122
123 if (gDRIPriv->cpp == 4)
124 savageScreen->frontFormat = DV_PF_8888;
125 else
126 savageScreen->frontFormat = DV_PF_565;
127
128 savageScreen->backOffset = gDRIPriv->backOffset;
129 savageScreen->backBitmapDesc = gDRIPriv->backBitmapDesc;
130 savageScreen->depthOffset=gDRIPriv->depthOffset;
131 savageScreen->depthBitmapDesc = gDRIPriv->depthBitmapDesc;
132 #if 0
133 savageScreen->backPitch = gDRIPriv->auxPitch;
134 savageScreen->backPitchBits = gDRIPriv->auxPitchBits;
135 #endif
136 savageScreen->textureOffset[SAVAGE_CARD_HEAP] =
137 gDRIPriv->textureOffset;
138 savageScreen->textureSize[SAVAGE_CARD_HEAP] =
139 gDRIPriv->textureSize;
140 savageScreen->logTextureGranularity[SAVAGE_CARD_HEAP] =
141 gDRIPriv->logTextureGranularity;
142
143 savageScreen->textureOffset[SAVAGE_AGP_HEAP] =
144 gDRIPriv->agpTextures.handle;
145 savageScreen->textureSize[SAVAGE_AGP_HEAP] =
146 gDRIPriv->agpTextures.size;
147 savageScreen->logTextureGranularity[SAVAGE_AGP_HEAP] =
148 gDRIPriv->logAgpTextureGranularity;
149
150 savageScreen->back.handle = gDRIPriv->backbuffer;
151 savageScreen->back.size = gDRIPriv->backbufferSize;
152 savageScreen->back.map =
153 (drmAddress)(((unsigned int)sPriv->pFB)+gDRIPriv->backOffset);
154
155 savageScreen->depth.handle = gDRIPriv->depthbuffer;
156 savageScreen->depth.size = gDRIPriv->depthbufferSize;
157
158 savageScreen->depth.map =
159 (drmAddress)(((unsigned int)sPriv->pFB)+gDRIPriv->depthOffset);
160
161 savageScreen->sarea_priv_offset = gDRIPriv->sarea_priv_offset;
162
163 savageScreen->texVirtual[SAVAGE_CARD_HEAP] =
164 (drmAddress)(((unsigned int)sPriv->pFB)+gDRIPriv->textureOffset);
165
166 if (drmMap(sPriv->fd,
167 gDRIPriv->registers.handle,
168 gDRIPriv->registers.size,
169 (drmAddress *)&(gDRIPriv->registers.map)) != 0)
170 {
171 Xfree(savageScreen);
172 sPriv->private = NULL;
173 return GL_FALSE;
174 }
175
176 if (drmMap(sPriv->fd,
177 gDRIPriv->agpTextures.handle,
178 gDRIPriv->agpTextures.size,
179 (drmAddress *)&(gDRIPriv->agpTextures.map)) != 0)
180 {
181 Xfree(savageScreen);
182 sPriv->private = NULL;
183 return GL_FALSE;
184 }
185
186 /* agp texture*/
187 savageScreen->texVirtual[SAVAGE_AGP_HEAP] =
188 (drmAddress)(gDRIPriv->agpTextures.map);
189
190 gDRIPriv->BCIcmdBuf.map = (drmAddress *)
191 ((unsigned int)gDRIPriv->registers.map+0x00010000);
192
193 savageScreen->aperture.handle = gDRIPriv->aperture.handle;
194 savageScreen->aperture.size = gDRIPriv->aperture.size;
195 if (drmMap(sPriv->fd,
196 savageScreen->aperture.handle,
197 savageScreen->aperture.size,
198 (drmAddress *)&savageScreen->aperture.map) != 0)
199 {
200 Xfree(savageScreen);
201 sPriv->private = NULL;
202 return GL_FALSE;
203 }
204
205 #if 0
206 savageDDFastPathInit();
207 savageDDTrifuncInit();
208 savageDDSetupInit();
209 #endif
210 return GL_TRUE;
211 }
212
213 /* Accessed by dlsym from dri_mesa_init.c
214 */
215 static void
216 savageDestroyScreen(__DRIscreenPrivate *sPriv)
217 {
218 savageScreenPrivate *savageScreen = (savageScreenPrivate *)sPriv->private;
219
220
221 Xfree(savageScreen);
222 sPriv->private = NULL;
223 }
224
225 #if 0
226 GLvisual *XMesaCreateVisual(Display *dpy,
227 __DRIscreenPrivate *driScrnPriv,
228 const XVisualInfo *visinfo,
229 const __GLXvisualConfig *config)
230 {
231 /* Drivers may change the args to _mesa_create_visual() in order to
232 * setup special visuals.
233 */
234 return _mesa_create_visual( config->rgba,
235 config->doubleBuffer,
236 config->stereo,
237 _mesa_bitcount(visinfo->red_mask),
238 _mesa_bitcount(visinfo->green_mask),
239 _mesa_bitcount(visinfo->blue_mask),
240 config->alphaSize,
241 0, /* index bits */
242 config->depthSize,
243 config->stencilSize,
244 config->accumRedSize,
245 config->accumGreenSize,
246 config->accumBlueSize,
247 config->accumAlphaSize,
248 0 /* num samples */ );
249 }
250 #endif
251
252
253 static GLboolean
254 savageCreateContext( const __GLcontextModes *mesaVis,
255 __DRIcontextPrivate *driContextPriv,
256 void *sharedContextPrivate )
257 {
258 GLcontext *ctx, *shareCtx;
259 savageContextPtr imesa;
260 __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
261 struct dd_function_table functions;
262 SAVAGEDRIPtr gDRIPriv = (SAVAGEDRIPtr)sPriv->pDevPriv;
263 savageScreenPrivate *savageScreen = (savageScreenPrivate *)sPriv->private;
264 drm_savage_sarea_t *saPriv=(drm_savage_sarea_t *)(((char*)sPriv->pSAREA)+
265 savageScreen->sarea_priv_offset);
266 GLuint maxTextureSize, minTextureSize, maxTextureLevels;
267 int i;
268 imesa = (savageContextPtr)Xcalloc(sizeof(savageContext), 1);
269 if (!imesa) {
270 return GL_FALSE;
271 }
272
273 /* Init default driver functions then plug in savage-specific texture
274 * functions that are needed as early as during context creation. */
275 _mesa_init_driver_functions( &functions );
276 savageDDInitTextureFuncs( &functions );
277
278 /* Allocate the Mesa context */
279 if (sharedContextPrivate)
280 shareCtx = ((savageContextPtr) sharedContextPrivate)->glCtx;
281 else
282 shareCtx = NULL;
283 ctx = _mesa_create_context(mesaVis, shareCtx, &functions, imesa);
284 if (!ctx) {
285 Xfree(imesa);
286 return GL_FALSE;
287 }
288 driContextPriv->driverPrivate = imesa;
289
290 if (savageScreen->chipset >= S3_SAVAGE4)
291 ctx->Const.MaxTextureUnits = 2;
292 else
293 ctx->Const.MaxTextureUnits = 1;
294 ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits;
295 ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits;
296
297 /* Set the maximum texture size small enough that we can guarentee
298 * that all texture units can bind a maximal texture and have them
299 * in memory at once.
300 */
301 if (savageScreen->textureSize[SAVAGE_CARD_HEAP] >
302 savageScreen->textureSize[SAVAGE_AGP_HEAP]) {
303 maxTextureSize = savageScreen->textureSize[SAVAGE_CARD_HEAP];
304 minTextureSize = savageScreen->textureSize[SAVAGE_AGP_HEAP];
305 } else {
306 maxTextureSize = savageScreen->textureSize[SAVAGE_AGP_HEAP];
307 minTextureSize = savageScreen->textureSize[SAVAGE_CARD_HEAP];
308 }
309 if (ctx->Const.MaxTextureUnits == 2) {
310 /* How to distribute two maximum sized textures to two texture heaps?
311 * If the smaller heap is less then half the size of the bigger one
312 * then the maximum size is half the size of the bigger heap.
313 * Otherwise it's the size of the smaller heap. */
314 if (minTextureSize < maxTextureSize / 2)
315 maxTextureSize = maxTextureSize / 2;
316 else
317 maxTextureSize = minTextureSize;
318 }
319 for (maxTextureLevels = 1; maxTextureLevels <= 11; ++maxTextureLevels) {
320 GLuint size = 1 << maxTextureLevels;
321 size *= size * 4; /* 4 bytes per texel */
322 size = size * 4/3; /* all mipmap levels together take roughly
323 4/3 the size of the biggest level */
324 if (size > maxTextureSize)
325 break;
326 }
327 ctx->Const.MaxTextureLevels = maxTextureLevels;
328 assert (ctx->Const.MaxTextureLevels > 6); /*spec requires at least 64x64*/
329
330 #if 0
331 ctx->Const.MinLineWidth = 1.0;
332 ctx->Const.MinLineWidthAA = 1.0;
333 ctx->Const.MaxLineWidth = 3.0;
334 ctx->Const.MaxLineWidthAA = 3.0;
335 ctx->Const.LineWidthGranularity = 1.0;
336 #endif
337
338 /* Dri stuff
339 */
340 imesa->hHWContext = driContextPriv->hHWContext;
341 imesa->driFd = sPriv->fd;
342 imesa->driHwLock = &sPriv->pSAREA->lock;
343
344 imesa->savageScreen = savageScreen;
345 imesa->driScreen = sPriv;
346 imesa->sarea = saPriv;
347 imesa->glBuffer = NULL;
348
349 /* DMA buffer */
350
351 /*The shadow pointer*/
352 imesa->shadowPointer =
353 (volatile GLuint *)((((GLuint)(&saPriv->shadow_status)) + 31) & 0xffffffe0L) ;
354 /* here we use eventTag1 because eventTag0 is used by HWXvMC*/
355 imesa->eventTag1 = (volatile GLuint *)(imesa->shadowPointer + 6);
356 /* imesa->eventTag1=(volatile GLuint *)(imesa->MMIO_BASE+0x48c04);*/
357 imesa->shadowCounter = MAX_SHADOWCOUNTER;
358 imesa->shadowStatus = GL_TRUE;/*Will judge by 2d message */
359
360 imesa->MMIO_BASE = (GLuint)gDRIPriv->registers.map;
361 imesa->BCIBase= (GLuint)gDRIPriv->BCIcmdBuf.map;
362 for(i=0;i<5;i++)
363 {
364 imesa->apertureBase[i] = ((GLuint)savageScreen->aperture.map +
365 0x01000000 * i );
366 }
367
368 imesa->aperturePitch = gDRIPriv->aperturePitch;
369
370
371 /* change texHeap initialize to support two kind of texture heap*/
372 /* here is some parts of initialization, others in InitDriver() */
373
374 imesa->lastTexHeap = savageScreen->texVirtual[SAVAGE_AGP_HEAP] ? 2 : 1;
375
376 /*allocate texHeap for multi-tex*/
377 {
378 int i;
379
380 for(i=0;i<SAVAGE_NR_TEX_HEAPS;i++)
381 {
382 imesa->texHeap[i] = mmInit( 0, savageScreen->textureSize[i] );
383 make_empty_list(&imesa->TexObjList[i]);
384 }
385
386 make_empty_list(&imesa->SwappedOut);
387 }
388
389 imesa->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24;
390 imesa->depth_scale = (imesa->savageScreen->zpp == 2) ?
391 (1.0F/0x10000):(1.0F/0x1000000);
392
393 imesa->vertex_dma_buffer = NULL;
394
395 /* Uninitialized vertex format. Force setting the vertex state in
396 * savageRenderStart.
397 */
398 imesa->vertex_size = 0;
399
400 /* Utah stuff
401 */
402 imesa->new_state = ~0;
403 imesa->RenderIndex = ~0;
404 imesa->dirty = ~0;
405 imesa->lostContext = GL_TRUE;
406 imesa->TextureMode = ctx->Texture.Unit[0].EnvMode;
407 imesa->CurrentTexObj[0] = 0;
408 imesa->CurrentTexObj[1] = 0;
409 imesa->texAge[SAVAGE_CARD_HEAP]=0;
410 imesa->texAge[SAVAGE_AGP_HEAP]=0;
411
412 /* Initialize the software rasterizer and helper modules.
413 */
414 _swrast_CreateContext( ctx );
415 _ac_CreateContext( ctx );
416 _tnl_CreateContext( ctx );
417
418 _swsetup_CreateContext( ctx );
419
420 /* Install the customized pipeline:
421 */
422 #if 0
423 _tnl_destroy_pipeline( ctx );
424 _tnl_install_pipeline( ctx, savage_pipeline );
425 #endif
426
427 /* Configure swrast to match hardware characteristics:
428 */
429 _tnl_allow_pixel_fog( ctx, GL_FALSE );
430 _tnl_allow_vertex_fog( ctx, GL_TRUE );
431 _swrast_allow_pixel_fog( ctx, GL_FALSE );
432 _swrast_allow_vertex_fog( ctx, GL_TRUE );
433
434 ctx->DriverCtx = (void *) imesa;
435 imesa->glCtx = ctx;
436 if (savageDMAInit(imesa) == GL_FALSE)
437 return GL_FALSE;
438
439 driInitExtensions( ctx, card_extensions, GL_TRUE );
440
441 savageDDInitStateFuncs( ctx );
442 savageDDInitSpanFuncs( ctx );
443 savageDDInitDriverFuncs( ctx );
444 savageDDInitIoctlFuncs( ctx );
445 savageInitTriFuncs( ctx );
446
447 savageDDInitState( imesa );
448
449 driContextPriv->driverPrivate = (void *) imesa;
450
451 return GL_TRUE;
452 }
453
454 static void
455 savageDestroyContext(__DRIcontextPrivate *driContextPriv)
456 {
457 savageContextPtr imesa = (savageContextPtr) driContextPriv->driverPrivate;
458
459 assert (imesa); /* should never be NULL */
460 if (imesa) {
461 savageTextureObjectPtr next_t, t;
462
463 FLUSH_BATCH(imesa);
464
465 /* update for multi-tex*/
466 {
467 int i;
468 for(i=0;i<SAVAGE_NR_TEX_HEAPS;i++)
469 foreach_s (t, next_t, &(imesa->TexObjList[i]))
470 savageDestroyTexObj(imesa, t);
471 }
472 foreach_s (t, next_t, &(imesa->SwappedOut))
473 savageDestroyTexObj(imesa, t);
474 /*free the dma buffer*/
475 savageDMAClose(imesa);
476 _swsetup_DestroyContext(imesa->glCtx );
477 _tnl_DestroyContext( imesa->glCtx );
478 _ac_DestroyContext( imesa->glCtx );
479 _swrast_DestroyContext( imesa->glCtx );
480
481 /* free the Mesa context */
482 imesa->glCtx->DriverCtx = NULL;
483 _mesa_destroy_context(imesa->glCtx);
484
485 /* no longer use vertex_dma_buf*/
486 Xfree(imesa);
487 }
488 }
489
490 static GLboolean
491 savageCreateBuffer( __DRIscreenPrivate *driScrnPriv,
492 __DRIdrawablePrivate *driDrawPriv,
493 const __GLcontextModes *mesaVis,
494 GLboolean isPixmap)
495 {
496 if (isPixmap) {
497 return GL_FALSE; /* not implemented */
498 }
499 else {
500 GLboolean swStencil = mesaVis->stencilBits > 0 && mesaVis->depthBits != 24;
501 driDrawPriv->driverPrivate = (void *)
502 _mesa_create_framebuffer(mesaVis,
503 GL_FALSE, /* software depth buffer? */
504 swStencil,
505 mesaVis->accumRedBits > 0,
506 mesaVis->alphaBits > 0 );
507
508 return (driDrawPriv->driverPrivate != NULL);
509 }
510 }
511
512 static void
513 savageDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
514 {
515 _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate));
516 }
517
518 #if 0
519 void XMesaSwapBuffers(__DRIdrawablePrivate *driDrawPriv)
520 {
521 /* XXX should do swap according to the buffer, not the context! */
522 savageContextPtr imesa = savageCtx;
523
524 FLUSH_VB( imesa->glCtx, "swap buffers" );
525 savageSwapBuffers(imesa);
526 }
527 #endif
528
529 void savageXMesaSetFrontClipRects( savageContextPtr imesa )
530 {
531 __DRIdrawablePrivate *dPriv = imesa->driDrawable;
532
533 imesa->numClipRects = dPriv->numClipRects;
534 imesa->pClipRects = dPriv->pClipRects;
535 imesa->dirty |= SAVAGE_UPLOAD_CLIPRECTS;
536 imesa->drawX = dPriv->x;
537 imesa->drawY = dPriv->y;
538
539 savageEmitDrawingRectangle( imesa );
540 }
541
542
543 void savageXMesaSetBackClipRects( savageContextPtr imesa )
544 {
545 __DRIdrawablePrivate *dPriv = imesa->driDrawable;
546
547 if (dPriv->numBackClipRects == 0)
548 {
549
550
551 imesa->numClipRects = dPriv->numClipRects;
552 imesa->pClipRects = dPriv->pClipRects;
553 imesa->drawX = dPriv->x;
554 imesa->drawY = dPriv->y;
555 } else {
556
557
558 imesa->numClipRects = dPriv->numBackClipRects;
559 imesa->pClipRects = dPriv->pBackClipRects;
560 imesa->drawX = dPriv->backX;
561 imesa->drawY = dPriv->backY;
562 }
563
564 savageEmitDrawingRectangle( imesa );
565 imesa->dirty |= SAVAGE_UPLOAD_CLIPRECTS;
566
567
568 }
569
570
571 static void savageXMesaWindowMoved( savageContextPtr imesa )
572 {
573 if (0)
574 fprintf(stderr, "savageXMesaWindowMoved\n\n");
575
576 switch (imesa->glCtx->Color._DrawDestMask[0]) {
577 case DD_FRONT_LEFT_BIT:
578 savageXMesaSetFrontClipRects( imesa );
579 break;
580 case DD_BACK_LEFT_BIT:
581 savageXMesaSetBackClipRects( imesa );
582 break;
583 default:
584 break;
585 }
586 }
587
588
589 static GLboolean
590 savageUnbindContext(__DRIcontextPrivate *driContextPriv)
591 {
592 savageContextPtr savage = (savageContextPtr) driContextPriv->driverPrivate;
593 if (savage)
594 savage->dirty = ~0;
595
596 return GL_TRUE;
597 }
598
599 #if 0
600 static GLboolean
601 savageOpenFullScreen(__DRIcontextPrivate *driContextPriv)
602 {
603
604
605
606 if (driContextPriv) {
607 savageContextPtr imesa = (savageContextPtr) driContextPriv->driverPrivate;
608 imesa->IsFullScreen = GL_TRUE;
609 imesa->backup_frontOffset = imesa->savageScreen->frontOffset;
610 imesa->backup_backOffset = imesa->savageScreen->backOffset;
611 imesa->backup_frontBitmapDesc = imesa->savageScreen->frontBitmapDesc;
612 imesa->savageScreen->frontBitmapDesc = imesa->savageScreen->backBitmapDesc;
613 imesa->toggle = TARGET_BACK;
614 }
615
616 return GL_TRUE;
617 }
618
619 static GLboolean
620 savageCloseFullScreen(__DRIcontextPrivate *driContextPriv)
621 {
622
623 if (driContextPriv) {
624 savageContextPtr imesa = (savageContextPtr) driContextPriv->driverPrivate;
625 WAIT_IDLE_EMPTY;
626 imesa->IsFullScreen = GL_FALSE;
627 imesa->savageScreen->frontOffset = imesa->backup_frontOffset;
628 imesa->savageScreen->backOffset = imesa->backup_backOffset;
629 imesa->savageScreen->frontBitmapDesc = imesa->backup_frontBitmapDesc;
630 }
631 return GL_TRUE;
632 }
633 #endif
634
635 static GLboolean
636 savageMakeCurrent(__DRIcontextPrivate *driContextPriv,
637 __DRIdrawablePrivate *driDrawPriv,
638 __DRIdrawablePrivate *driReadPriv)
639 {
640 if (driContextPriv) {
641 savageContextPtr imesa = (savageContextPtr) driContextPriv->driverPrivate;
642
643 imesa->driReadable = driReadPriv;
644 imesa->driDrawable = driDrawPriv;
645 imesa->mesa_drawable = driDrawPriv;
646 imesa->dirty = ~0;
647
648 _mesa_make_current2(imesa->glCtx,
649 (GLframebuffer *) driDrawPriv->driverPrivate,
650 (GLframebuffer *) driReadPriv->driverPrivate);
651
652 savageXMesaWindowMoved( imesa );
653 }
654 else
655 {
656 _mesa_make_current(NULL, NULL);
657 }
658 return GL_TRUE;
659 }
660
661
662 void savageGetLock( savageContextPtr imesa, GLuint flags )
663 {
664 __DRIdrawablePrivate *dPriv = imesa->driDrawable;
665 __DRIscreenPrivate *sPriv = imesa->driScreen;
666 drm_savage_sarea_t *sarea = imesa->sarea;
667 int me = imesa->hHWContext;
668 int stamp = dPriv->lastStamp;
669 int heap;
670
671
672
673 /* We know there has been contention.
674 */
675 drmGetLock(imesa->driFd, imesa->hHWContext, flags);
676
677
678 /* Note contention for throttling hint
679 */
680 imesa->any_contend = 1;
681
682 /* If the window moved, may need to set a new cliprect now.
683 *
684 * NOTE: This releases and regains the hw lock, so all state
685 * checking must be done *after* this call:
686 */
687 DRI_VALIDATE_DRAWABLE_INFO(sPriv, dPriv);
688
689
690
691
692 /* If we lost context, need to dump all registers to hardware.
693 * Note that we don't care about 2d contexts, even if they perform
694 * accelerated commands, so the DRI locking in the X server is even
695 * more broken than usual.
696 */
697 if (sarea->ctxOwner != me) {
698 imesa->dirty |= (SAVAGE_UPLOAD_CTX |
699 SAVAGE_UPLOAD_CLIPRECTS |
700 SAVAGE_UPLOAD_TEX0 |
701 SAVAGE_UPLOAD_TEX1);
702 imesa->lostContext = GL_TRUE;
703 sarea->ctxOwner = me;
704 }
705
706 /* Shared texture managment - if another client has played with
707 * texture space, figure out which if any of our textures have been
708 * ejected, and update our global LRU.
709 */
710 /*frank just for compiling,texAge,texList,AGP*/
711
712 for(heap= 0 ;heap < imesa->lastTexHeap ; heap++)
713 {
714 if (sarea->texAge[heap] != imesa->texAge[heap]) {
715 int sz = 1 << (imesa->savageScreen->logTextureGranularity[heap]);
716 int idx, nr = 0;
717
718 /* Have to go right round from the back to ensure stuff ends up
719 * LRU in our local list...
720 */
721 for (idx = sarea->texList[heap][SAVAGE_NR_TEX_REGIONS].prev ;
722 idx != SAVAGE_NR_TEX_REGIONS && nr < SAVAGE_NR_TEX_REGIONS ;
723 idx = sarea->texList[heap][idx].prev, nr++)
724 {
725 if (sarea->texList[heap][idx].age > imesa->texAge[heap])
726 {
727 savageTexturesGone(imesa, heap ,idx * sz, sz,
728 sarea->texList[heap][idx].in_use);
729 }
730 }
731
732 if (nr == SAVAGE_NR_TEX_REGIONS)
733 {
734 savageTexturesGone(imesa, heap, 0,
735 imesa->savageScreen->textureSize[heap], 0);
736 savageResetGlobalLRU( imesa , heap );
737 }
738
739 imesa->dirty |= SAVAGE_UPLOAD_TEX0IMAGE;
740 imesa->dirty |= SAVAGE_UPLOAD_TEX1IMAGE;
741 imesa->texAge[heap] = sarea->texAge[heap];
742 }
743 } /* end of for loop */
744
745 if (dPriv->lastStamp != stamp)
746 savageXMesaWindowMoved( imesa );
747
748
749
750 }
751
752
753
754 static const struct __DriverAPIRec savageAPI = {
755 savageInitDriver,
756 savageDestroyScreen,
757 savageCreateContext,
758 savageDestroyContext,
759 savageCreateBuffer,
760 savageDestroyBuffer,
761 savageSwapBuffers,
762 savageMakeCurrent,
763 savageUnbindContext
764 };
765
766
767
768 #ifndef DRI_NEW_INTERFACE_ONLY
769 /*
770 * This is the (old) bootstrap function for the driver.
771 * The __driCreateScreen name is the symbol that libGL.so fetches.
772 * Return: pointer to a __DRIscreenPrivate.
773 */
774 void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
775 int numConfigs, __GLXvisualConfig *config)
776 {
777 __DRIscreenPrivate *psp;
778 psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &savageAPI);
779 return (void *) psp;
780 }
781 #endif /* DRI_NEW_INTERFACE_ONLY */
782
783
784
785 #ifdef USE_NEW_INTERFACE
786 static __GLcontextModes *
787 savageFillInModes( unsigned pixel_bits, unsigned depth_bits,
788 unsigned stencil_bits, GLboolean have_back_buffer )
789 {
790 __GLcontextModes * modes;
791 __GLcontextModes * m;
792 unsigned num_modes;
793 unsigned depth_buffer_factor;
794 unsigned back_buffer_factor;
795 GLenum fb_format;
796 GLenum fb_type;
797
798 /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
799 * enough to add support. Basically, if a context is created with an
800 * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
801 * will never be used.
802 *
803 * FK: What about drivers that don't use page flipping? Could they
804 * just expose GLX_SWAP_COPY_OML?
805 */
806 static const GLenum back_buffer_modes[] = {
807 GLX_NONE, GLX_SWAP_UNDEFINED_OML /*, GLX_SWAP_COPY_OML */
808 };
809
810 u_int8_t depth_bits_array[2];
811 u_int8_t stencil_bits_array[2];
812
813
814 depth_bits_array[0] = depth_bits;
815 depth_bits_array[1] = depth_bits;
816
817 /* Just like with the accumulation buffer, always provide some modes
818 * with a stencil buffer. It will be a sw fallback, but some apps won't
819 * care about that.
820 */
821 stencil_bits_array[0] = 0;
822 stencil_bits_array[1] = (stencil_bits == 0) ? 8 : stencil_bits;
823
824 depth_buffer_factor = ((depth_bits != 0) || (stencil_bits != 0)) ? 2 : 1;
825 back_buffer_factor = (have_back_buffer) ? 2 : 1;
826
827 num_modes = depth_buffer_factor * back_buffer_factor * 4;
828
829 if ( pixel_bits == 16 ) {
830 fb_format = GL_RGB;
831 fb_type = GL_UNSIGNED_SHORT_5_6_5;
832 }
833 else {
834 fb_format = GL_BGR;
835 fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
836 }
837
838 modes = (*create_context_modes)( num_modes, sizeof( __GLcontextModes ) );
839 m = modes;
840 if ( ! driFillInModes( & m, fb_format, fb_type,
841 depth_bits_array, stencil_bits_array, depth_buffer_factor,
842 back_buffer_modes, back_buffer_factor,
843 GLX_TRUE_COLOR ) ) {
844 fprintf( stderr, "[%s:%u] Error creating FBConfig!\n",
845 __func__, __LINE__ );
846 return NULL;
847 }
848
849 if ( ! driFillInModes( & m, fb_format, fb_type,
850 depth_bits_array, stencil_bits_array, depth_buffer_factor,
851 back_buffer_modes, back_buffer_factor,
852 GLX_DIRECT_COLOR ) ) {
853 fprintf( stderr, "[%s:%u] Error creating FBConfig!\n",
854 __func__, __LINE__ );
855 return NULL;
856 }
857
858 /* Mark the visual as slow if there are "fake" stencil bits.
859 */
860 for ( m = modes ; m != NULL ; m = m->next ) {
861 if ( (m->stencilBits != 0) && (m->stencilBits != stencil_bits) ) {
862 m->visualRating = GLX_SLOW_CONFIG;
863 }
864 }
865
866 return modes;
867 }
868
869
870 /**
871 * This is the bootstrap function for the driver. libGL supplies all of the
872 * requisite information about the system, and the driver initializes itself.
873 * This routine also fills in the linked list pointed to by \c driver_modes
874 * with the \c __GLcontextModes that the driver can support for windows or
875 * pbuffers.
876 *
877 * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on
878 * failure.
879 */
880 void * __driCreateNewScreen( __DRInativeDisplay *dpy, int scrn, __DRIscreen *psc,
881 const __GLcontextModes * modes,
882 const __DRIversion * ddx_version,
883 const __DRIversion * dri_version,
884 const __DRIversion * drm_version,
885 const __DRIframebuffer * frame_buffer,
886 drmAddress pSAREA, int fd,
887 int internal_api_version,
888 __GLcontextModes ** driver_modes )
889
890 {
891 __DRIscreenPrivate *psp;
892 static const __DRIversion ddx_expected = { 1, 0, 0 };
893 static const __DRIversion dri_expected = { 4, 0, 0 };
894 static const __DRIversion drm_expected = { 1, 0, 0 };
895
896
897 if ( ! driCheckDriDdxDrmVersions2( "Savage",
898 dri_version, & dri_expected,
899 ddx_version, & ddx_expected,
900 drm_version, & drm_expected ) ) {
901 return NULL;
902 }
903
904 psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL,
905 ddx_version, dri_version, drm_version,
906 frame_buffer, pSAREA, fd,
907 internal_api_version, &savageAPI);
908 if ( psp != NULL ) {
909 create_context_modes = (PFNGLXCREATECONTEXTMODES)
910 glXGetProcAddress( (const GLubyte *) "__glXCreateContextModes" );
911 if ( create_context_modes != NULL ) {
912 SAVAGEDRIPtr dri_priv = (SAVAGEDRIPtr)psp->pDevPriv;
913 *driver_modes = savageFillInModes( dri_priv->cpp*8,
914 (dri_priv->cpp == 2) ? 16 : 24,
915 (dri_priv->cpp == 2) ? 0 : 8,
916 (dri_priv->backOffset != dri_priv->depthOffset) );
917 }
918 }
919
920 return (void *) psp;
921 }
922 #endif /* USE_NEW_INTERFACE */
923
924 #endif