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