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