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