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