97577fca26afb87300c7874318fe4480b200e385
1 /* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the
30 * Thank you for your contribution, David!
32 * Please make note of the above copyright/license statement. If you
33 * contributed code or bug fixes to this code under the previous (GNU
34 * Library) license and object to the new license, your code will be
35 * removed at your request. Please see the Mesa docs/COPYRIGHT file
36 * for more information.
38 * Additional Mesa/3Dfx driver developers:
39 * Daryll Strauss <daryll@precisioninsight.com>
40 * Keith Whitwell <keith@precisioninsight.com>
42 * See fxapi.h for more revision/author details.
46 /* fxtexman.c - 3Dfx VooDoo texture memory functions */
57 static tfxTMFreeNode
*fxTMNewTMFreeNode(FxU32 start
, FxU32 end
)
61 if(!(tmn
=MALLOC(sizeof(tfxTMFreeNode
)))) {
62 fprintf(stderr
,"fx Driver: out of memory !\n");
68 tmn
->startAddress
=start
;
74 /* Notice this uses grTex{Min,Max}Address directly with FX_ because it
75 is only used during initialization where the lock is already held. */
76 static void fxTMUInit(fxMesaContext fxMesa
, int tmu
)
78 tfxTMFreeNode
*tmn
,*tmntmp
;
79 FxU32 start
,end
,blockstart
,blockend
;
81 start
=FX_grTexMinAddress(tmu
);
82 end
=FX_grTexMaxAddress(tmu
);
85 fprintf(stderr
,"%s configuration:",(tmu
==FX_TMU0
) ? "TMU0" : "TMU1");
86 fprintf(stderr
," Lower texture memory address (%u)\n",(unsigned int)start
);
87 fprintf(stderr
," Higher texture memory address (%u)\n",(unsigned int)end
);
88 fprintf(stderr
," Splitting Texture memory in 2Mb blocks:\n");
91 fxMesa
->freeTexMem
[tmu
]=end
-start
;
92 fxMesa
->tmFree
[tmu
]=NULL
;
93 fxMesa
->tmAlloc
[tmu
]=NULL
;
96 while(blockstart
<=end
) {
97 if(blockstart
+0x1fffff>end
)
100 blockend
=blockstart
+0x1fffff;
103 fprintf(stderr
," %07u-%07u\n",(unsigned int)blockstart
,(unsigned int)blockend
);
105 tmn
=fxTMNewTMFreeNode(blockstart
,blockend
);
107 if(fxMesa
->tmFree
[tmu
]) {
108 for(tmntmp
=fxMesa
->tmFree
[tmu
];tmntmp
->next
!=NULL
;tmntmp
=tmntmp
->next
){};
111 fxMesa
->tmFree
[tmu
]=tmn
;
113 blockstart
+=0x1fffff+1;
117 void fxTMInit(fxMesaContext fxMesa
)
119 fxTMUInit(fxMesa
,FX_TMU0
);
121 if(fxMesa
->haveTwoTMUs
)
122 fxTMUInit(fxMesa
,FX_TMU1
);
124 fxMesa
->texBindNumber
=0;
127 static struct gl_texture_object
*fxTMFindOldestTMBlock(fxMesaContext fxMesa
,
128 tfxTMAllocNode
*tmalloc
,
129 GLuint texbindnumber
)
131 GLuint age
,oldestage
,lasttimeused
;
132 struct gl_texture_object
*oldesttexobj
;
135 oldesttexobj
=tmalloc
->tObj
;
139 lasttimeused
=((tfxTexInfo
*)(tmalloc
->tObj
->DriverData
))->tmi
.lastTimeUsed
;
141 if(lasttimeused
>texbindnumber
)
142 age
=texbindnumber
+(UINT_MAX
-lasttimeused
+1); /* TO DO: check */
144 age
=texbindnumber
-lasttimeused
;
148 oldesttexobj
=tmalloc
->tObj
;
151 tmalloc
=tmalloc
->next
;
157 static GLboolean
fxTMFreeOldTMBlock(fxMesaContext fxMesa
, GLint tmu
)
159 struct gl_texture_object
*oldesttexobj
;
161 if(!fxMesa
->tmAlloc
[tmu
])
164 oldesttexobj
=fxTMFindOldestTMBlock(fxMesa
,fxMesa
->tmAlloc
[tmu
],fxMesa
->texBindNumber
);
166 fxTMMoveOutTM(fxMesa
,oldesttexobj
);
171 static tfxTMFreeNode
*fxTMExtractTMFreeBlock(tfxTMFreeNode
*tmfree
, int texmemsize
,
172 GLboolean
*success
, FxU32
*startadr
)
176 /* TO DO: cut recursion */
183 blocksize
=(int)tmfree
->endAddress
-(int)tmfree
->startAddress
+1;
185 if(blocksize
==texmemsize
) {
186 tfxTMFreeNode
*nexttmfree
;
189 *startadr
=tmfree
->startAddress
;
191 nexttmfree
=tmfree
->next
;
197 if(blocksize
>texmemsize
) {
199 *startadr
=tmfree
->startAddress
;
201 tmfree
->startAddress
+=texmemsize
;
206 tmfree
->next
=fxTMExtractTMFreeBlock(tmfree
->next
,texmemsize
,success
,startadr
);
211 static tfxTMAllocNode
*fxTMGetTMBlock(fxMesaContext fxMesa
, struct gl_texture_object
*tObj
,
212 GLint tmu
, int texmemsize
)
214 tfxTMFreeNode
*newtmfree
;
215 tfxTMAllocNode
*newtmalloc
;
219 for(;;) { /* TO DO: improve performaces */
220 newtmfree
=fxTMExtractTMFreeBlock(fxMesa
->tmFree
[tmu
],texmemsize
,&success
,&startadr
);
223 fxMesa
->tmFree
[tmu
]=newtmfree
;
225 fxMesa
->freeTexMem
[tmu
]-=texmemsize
;
227 if(!(newtmalloc
=MALLOC(sizeof(tfxTMAllocNode
)))) {
228 fprintf(stderr
,"fx Driver: out of memory !\n");
233 newtmalloc
->next
=fxMesa
->tmAlloc
[tmu
];
234 newtmalloc
->startAddress
=startadr
;
235 newtmalloc
->endAddress
=startadr
+texmemsize
-1;
236 newtmalloc
->tObj
=tObj
;
238 fxMesa
->tmAlloc
[tmu
]=newtmalloc
;
243 if(!fxTMFreeOldTMBlock(fxMesa
,tmu
)) {
244 fprintf(stderr
,"fx Driver: internal error in fxTMGetTMBlock()\n");
245 fprintf(stderr
," TMU: %d Size: %d\n",tmu
,texmemsize
);
253 void fxTMMoveInTM_NoLock(fxMesaContext fxMesa
, struct gl_texture_object
*tObj
, GLint where
)
255 tfxTexInfo
*ti
=(tfxTexInfo
*)tObj
->DriverData
;
259 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
260 fprintf(stderr
,"fxmesa: fxTMMoveInTM(%d)\n",tObj
->Name
);
263 fxMesa
->stats
.reqTexUpload
++;
266 fprintf(stderr
,"fx Driver: internal error in fxTMMoveInTM() -> not validated\n");
274 if (MESA_VERBOSE
&(VERBOSE_DRIVER
|VERBOSE_TEXTURE
)) {
275 fprintf(stderr
,"fxmesa: downloading %x (%d) in texture memory in %d\n",(GLuint
)tObj
,tObj
->Name
,where
);
278 ti
->tmi
.whichTMU
=(FxU32
)where
;
283 texmemsize
=(int)FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_BOTH
,
285 ti
->tmi
.tm
[where
]=fxTMGetTMBlock(fxMesa
,tObj
,where
,texmemsize
);
286 fxMesa
->stats
.memTexUpload
+=texmemsize
;
288 for(i
=FX_largeLodValue(ti
->info
),l
=ti
->minLevel
;i
<=FX_smallLodValue(ti
->info
);i
++,l
++)
289 FX_grTexDownloadMipMapLevel_NoLock(where
,
290 ti
->tmi
.tm
[where
]->startAddress
,
292 FX_largeLodLog2(ti
->info
),
293 FX_aspectRatioLog2(ti
->info
),
295 GR_MIPMAPLEVELMASK_BOTH
,
296 ti
->tmi
.mipmapLevel
[l
].data
);
298 case FX_TMU_SPLIT
: /* TO DO: alternate even/odd TMU0/TMU1 */
299 texmemsize
=(int)FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_ODD
,
301 ti
->tmi
.tm
[FX_TMU0
]=fxTMGetTMBlock(fxMesa
,tObj
,FX_TMU0
,texmemsize
);
302 fxMesa
->stats
.memTexUpload
+=texmemsize
;
304 texmemsize
=(int)FX_grTexTextureMemRequired_NoLock(GR_MIPMAPLEVELMASK_EVEN
,
306 ti
->tmi
.tm
[FX_TMU1
]=fxTMGetTMBlock(fxMesa
,tObj
,FX_TMU1
,texmemsize
);
307 fxMesa
->stats
.memTexUpload
+=texmemsize
;
309 for(i
=FX_largeLodValue(ti
->info
),l
=ti
->minLevel
;i
<=FX_smallLodValue(ti
->info
);i
++,l
++) {
310 FX_grTexDownloadMipMapLevel_NoLock(GR_TMU0
,
311 ti
->tmi
.tm
[FX_TMU0
]->startAddress
,
313 FX_largeLodLog2(ti
->info
),
314 FX_aspectRatioLog2(ti
->info
),
316 GR_MIPMAPLEVELMASK_ODD
,
317 ti
->tmi
.mipmapLevel
[l
].data
);
319 FX_grTexDownloadMipMapLevel_NoLock(GR_TMU1
,
320 ti
->tmi
.tm
[FX_TMU1
]->startAddress
,
322 FX_largeLodLog2(ti
->info
),
323 FX_aspectRatioLog2(ti
->info
),
325 GR_MIPMAPLEVELMASK_EVEN
,
326 ti
->tmi
.mipmapLevel
[l
].data
);
330 fprintf(stderr
,"fx Driver: internal error in fxTMMoveInTM() -> wrong tmu (%d)\n",where
);
335 fxMesa
->stats
.texUpload
++;
337 ti
->tmi
.isInTM
=GL_TRUE
;
340 void fxTMMoveInTM(fxMesaContext fxMesa
, struct gl_texture_object
*tObj
, GLint where
) {
342 fxTMMoveInTM_NoLock(fxMesa
, tObj
, where
);
346 void fxTMReloadMipMapLevel(fxMesaContext fxMesa
, struct gl_texture_object
*tObj
, GLint level
)
348 tfxTexInfo
*ti
=(tfxTexInfo
*)tObj
->DriverData
;
353 fprintf(stderr
,"fx Driver: internal error in fxTMReloadMipMapLevel() -> not validated\n");
358 tmu
=(int)ti
->tmi
.whichTMU
;
359 fxTMMoveInTM(fxMesa
,tObj
,tmu
);
361 fxTexGetInfo(ti
->tmi
.mipmapLevel
[0].width
,ti
->tmi
.mipmapLevel
[0].height
,
362 &lodlevel
,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
);
367 FX_grTexDownloadMipMapLevel(tmu
,
368 ti
->tmi
.tm
[tmu
]->startAddress
,FX_valueToLod(FX_lodToValue(lodlevel
)+level
),
369 FX_largeLodLog2(ti
->info
),FX_aspectRatioLog2(ti
->info
),
370 ti
->info
.format
,GR_MIPMAPLEVELMASK_BOTH
,
371 ti
->tmi
.mipmapLevel
[level
].data
);
373 case FX_TMU_SPLIT
: /* TO DO: alternate even/odd TMU0/TMU1 */
374 FX_grTexDownloadMipMapLevel(GR_TMU0
,
375 ti
->tmi
.tm
[GR_TMU0
]->startAddress
,FX_valueToLod(FX_lodToValue(lodlevel
)+level
),
376 FX_largeLodLog2(ti
->info
),FX_aspectRatioLog2(ti
->info
),
377 ti
->info
.format
,GR_MIPMAPLEVELMASK_ODD
,
378 ti
->tmi
.mipmapLevel
[level
].data
);
380 FX_grTexDownloadMipMapLevel(GR_TMU1
,
381 ti
->tmi
.tm
[GR_TMU1
]->startAddress
,FX_valueToLod(FX_lodToValue(lodlevel
)+level
),
382 FX_largeLodLog2(ti
->info
),FX_aspectRatioLog2(ti
->info
),
383 ti
->info
.format
,GR_MIPMAPLEVELMASK_EVEN
,
384 ti
->tmi
.mipmapLevel
[level
].data
);
387 fprintf(stderr
,"fx Driver: internal error in fxTMReloadMipMapLevel() -> wrong tmu (%d)\n",tmu
);
393 void fxTMReloadSubMipMapLevel(fxMesaContext fxMesa
, struct gl_texture_object
*tObj
,
394 GLint level
, GLint yoffset
, GLint height
)
396 tfxTexInfo
*ti
=(tfxTexInfo
*)tObj
->DriverData
;
398 unsigned short *data
;
402 fprintf(stderr
,"fx Driver: internal error in fxTMReloadSubMipMapLevel() -> not validated\n");
407 tmu
=(int)ti
->tmi
.whichTMU
;
408 fxTMMoveInTM(fxMesa
,tObj
,tmu
);
410 fxTexGetInfo(ti
->tmi
.mipmapLevel
[0].width
,ti
->tmi
.mipmapLevel
[0].height
,
411 &lodlevel
,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
,NULL
);
413 if((ti
->info
.format
==GR_TEXFMT_INTENSITY_8
) ||
414 (ti
->info
.format
==GR_TEXFMT_P_8
) ||
415 (ti
->info
.format
==GR_TEXFMT_ALPHA_8
))
416 data
=ti
->tmi
.mipmapLevel
[level
].data
+((yoffset
*ti
->tmi
.mipmapLevel
[level
].width
)>>1);
418 data
=ti
->tmi
.mipmapLevel
[level
].data
+yoffset
*ti
->tmi
.mipmapLevel
[level
].width
;
423 FX_grTexDownloadMipMapLevelPartial(tmu
,
424 ti
->tmi
.tm
[tmu
]->startAddress
,FX_valueToLod(FX_lodToValue(lodlevel
)+level
),
425 FX_largeLodLog2(ti
->info
),FX_aspectRatioLog2(ti
->info
),
426 ti
->info
.format
,GR_MIPMAPLEVELMASK_BOTH
,
428 yoffset
,yoffset
+height
-1);
430 case FX_TMU_SPLIT
: /* TO DO: alternate even/odd TMU0/TMU1 */
431 FX_grTexDownloadMipMapLevelPartial(GR_TMU0
,
432 ti
->tmi
.tm
[FX_TMU0
]->startAddress
,FX_valueToLod(FX_lodToValue(lodlevel
)+level
),
433 FX_largeLodLog2(ti
->info
),FX_aspectRatioLog2(ti
->info
),
434 ti
->info
.format
,GR_MIPMAPLEVELMASK_ODD
,
436 yoffset
,yoffset
+height
-1);
438 FX_grTexDownloadMipMapLevelPartial(GR_TMU1
,
439 ti
->tmi
.tm
[FX_TMU1
]->startAddress
,FX_valueToLod(FX_lodToValue(lodlevel
)+level
),
440 FX_largeLodLog2(ti
->info
),FX_aspectRatioLog2(ti
->info
),
441 ti
->info
.format
,GR_MIPMAPLEVELMASK_EVEN
,
443 yoffset
,yoffset
+height
-1);
446 fprintf(stderr
,"fx Driver: internal error in fxTMReloadSubMipMapLevel() -> wrong tmu (%d)\n",tmu
);
452 static tfxTMAllocNode
*fxTMFreeTMAllocBlock(tfxTMAllocNode
*tmalloc
,
453 tfxTMAllocNode
*tmunalloc
)
458 if(tmalloc
==tmunalloc
) {
459 tfxTMAllocNode
*newtmalloc
;
461 newtmalloc
=tmalloc
->next
;
467 tmalloc
->next
=fxTMFreeTMAllocBlock(tmalloc
->next
,tmunalloc
);
472 static tfxTMFreeNode
*fxTMAddTMFree(tfxTMFreeNode
*tmfree
, FxU32 startadr
, FxU32 endadr
)
475 return fxTMNewTMFreeNode(startadr
,endadr
);
477 if((endadr
+1==tmfree
->startAddress
) && (tmfree
->startAddress
& 0x1fffff)) {
478 tmfree
->startAddress
=startadr
;
483 if((startadr
-1==tmfree
->endAddress
) && (startadr
& 0x1fffff)) {
484 tmfree
->endAddress
=endadr
;
486 if((tmfree
->next
&& (endadr
+1==tmfree
->next
->startAddress
) &&
487 (tmfree
->next
->startAddress
& 0x1fffff))) {
488 tfxTMFreeNode
*nexttmfree
;
490 tmfree
->endAddress
=tmfree
->next
->endAddress
;
492 nexttmfree
=tmfree
->next
->next
;
495 tmfree
->next
=nexttmfree
;
502 if(startadr
<tmfree
->startAddress
) {
503 tfxTMFreeNode
*newtmfree
;
505 newtmfree
=fxTMNewTMFreeNode(startadr
,endadr
);
506 newtmfree
->next
=tmfree
;
511 tmfree
->next
=fxTMAddTMFree(tmfree
->next
,startadr
,endadr
);
516 static void fxTMFreeTMBlock(fxMesaContext fxMesa
, GLint tmu
, tfxTMAllocNode
*tmalloc
)
518 FxU32 startadr
,endadr
;
520 startadr
=tmalloc
->startAddress
;
521 endadr
=tmalloc
->endAddress
;
523 fxMesa
->tmAlloc
[tmu
]=fxTMFreeTMAllocBlock(fxMesa
->tmAlloc
[tmu
],tmalloc
);
525 fxMesa
->tmFree
[tmu
]=fxTMAddTMFree(fxMesa
->tmFree
[tmu
],startadr
,endadr
);
527 fxMesa
->freeTexMem
[tmu
]+=endadr
-startadr
+1;
530 void fxTMMoveOutTM(fxMesaContext fxMesa
, struct gl_texture_object
*tObj
)
532 tfxTexInfo
*ti
=(tfxTexInfo
*)tObj
->DriverData
;
534 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
535 fprintf(stderr
,"fxmesa: fxTMMoveOutTM(%x (%d))\n",(GLuint
)tObj
,tObj
->Name
);
541 switch(ti
->tmi
.whichTMU
) {
544 fxTMFreeTMBlock(fxMesa
,(int)ti
->tmi
.whichTMU
,ti
->tmi
.tm
[ti
->tmi
.whichTMU
]);
547 fxTMFreeTMBlock(fxMesa
,FX_TMU0
,ti
->tmi
.tm
[FX_TMU0
]);
548 fxTMFreeTMBlock(fxMesa
,FX_TMU1
,ti
->tmi
.tm
[FX_TMU1
]);
551 fprintf(stderr
,"fx Driver: internal error in fxTMMoveOutTM()\n");
556 ti
->tmi
.whichTMU
=FX_TMU_NONE
;
557 ti
->tmi
.isInTM
=GL_FALSE
;
560 void fxTMFreeTexture(fxMesaContext fxMesa
, struct gl_texture_object
*tObj
)
562 tfxTexInfo
*ti
=(tfxTexInfo
*)tObj
->DriverData
;
565 fxTMMoveOutTM(fxMesa
,tObj
);
567 for(i
=0;i
<MAX_TEXTURE_LEVELS
;i
++) {
568 if(ti
->tmi
.mipmapLevel
[i
].used
&&
569 ti
->tmi
.mipmapLevel
[i
].translated
)
570 FREE(ti
->tmi
.mipmapLevel
[i
].data
);
572 (void)ti
->tmi
.mipmapLevel
[i
].data
;
576 void fxTMFreeAllFreeNode(tfxTMFreeNode
*fn
)
582 fxTMFreeAllFreeNode(fn
->next
);
587 void fxTMFreeAllAllocNode(tfxTMAllocNode
*an
)
593 fxTMFreeAllAllocNode(an
->next
);
598 void fxTMClose(fxMesaContext fxMesa
)
600 fxTMFreeAllFreeNode(fxMesa
->tmFree
[FX_TMU0
]);
601 fxTMFreeAllAllocNode(fxMesa
->tmAlloc
[FX_TMU0
]);
602 fxMesa
->tmFree
[FX_TMU0
] = NULL
;
603 fxMesa
->tmAlloc
[FX_TMU0
] = NULL
;
604 if(fxMesa
->haveTwoTMUs
) {
605 fxTMFreeAllFreeNode(fxMesa
->tmFree
[FX_TMU1
]);
606 fxTMFreeAllAllocNode(fxMesa
->tmAlloc
[FX_TMU1
]);
607 fxMesa
->tmFree
[FX_TMU1
] = NULL
;
608 fxMesa
->tmAlloc
[FX_TMU1
] = NULL
;
612 void fxTMRestore_NoLock(fxMesaContext fxMesa
, struct gl_texture_object
*tObj
)
614 tfxTexInfo
*ti
=(tfxTexInfo
*)tObj
->DriverData
;
617 if (MESA_VERBOSE
&VERBOSE_DRIVER
) {
618 fprintf(stderr
,"fxmesa: fxRestore(%d)\n",tObj
->Name
);
621 if (!ti
->validated
) {
622 fprintf(stderr
,"fxDriver: internal error in fxRestore -> not validated\n");
627 where
=ti
->tmi
.whichTMU
;
628 if (MESA_VERBOSE
&(VERBOSE_DRIVER
|VERBOSE_TEXTURE
)) {
629 fprintf(stderr
,"fxmesa: reloading %x (%d) in texture memory in %d\n",(GLuint
)tObj
,tObj
->Name
,where
);
635 for (i
=FX_largeLodValue_NoLock(ti
->info
), l
=ti
->minLevel
;
636 i
<=FX_smallLodValue_NoLock(ti
->info
);
638 if (ti
->tmi
.mipmapLevel
[l
].data
)
639 FX_grTexDownloadMipMapLevel_NoLock(where
,
640 ti
->tmi
.tm
[where
]->startAddress
,
642 FX_largeLodLog2(ti
->info
),
643 FX_aspectRatioLog2(ti
->info
),
645 GR_MIPMAPLEVELMASK_BOTH
,
646 ti
->tmi
.mipmapLevel
[l
].data
);
648 case FX_TMU_SPLIT
: /* TO DO: alternate even/odd TMU0/TMU1 */
649 for (i
=FX_largeLodValue_NoLock(ti
->info
),l
=ti
->minLevel
;
650 i
<=FX_smallLodValue_NoLock(ti
->info
);
652 if (ti
->tmi
.mipmapLevel
[l
].data
)
653 FX_grTexDownloadMipMapLevel_NoLock(GR_TMU0
,
654 ti
->tmi
.tm
[FX_TMU0
]->startAddress
,
656 FX_largeLodLog2(ti
->info
),
657 FX_aspectRatioLog2(ti
->info
),
659 GR_MIPMAPLEVELMASK_ODD
,
660 ti
->tmi
.mipmapLevel
[l
].data
);
661 if (ti
->tmi
.mipmapLevel
[l
].data
)
662 FX_grTexDownloadMipMapLevel_NoLock(GR_TMU1
,
663 ti
->tmi
.tm
[FX_TMU1
]->startAddress
,
665 FX_largeLodLog2(ti
->info
),
666 FX_aspectRatioLog2(ti
->info
),
668 GR_MIPMAPLEVELMASK_EVEN
,
669 ti
->tmi
.mipmapLevel
[l
].data
);
673 fprintf(stderr
,"fxDriver: internal error in fxRestore -> bad tmu (%d)\n",
681 fxTMRestoreTextures(fxMesaContext ctx
) {
683 struct gl_texture_object
*tObj
;
686 tObj
=ctx
->glCtx
->Shared
->TexObjectList
;
688 ti
=(tfxTexInfo
*)tObj
->DriverData
;
689 if (ti
&& ti
->tmi
.isInTM
) {
690 for (i
=0; i
<MAX_TEXTURE_UNITS
; i
++)
691 if (ctx
->glCtx
->Texture
.Unit
[i
].Current
==tObj
) {
692 /* Force the texture onto the board, as it could be in use */
693 fxTMRestore_NoLock(ctx
, tObj
);
696 if (i
==MAX_TEXTURE_UNITS
) /* Mark the texture as off the board */
697 fxTMMoveOutTM(ctx
, tObj
);
701 ctx
->lastUnitsMode
=0;
702 fxSetupTexture_NoLock(ctx
->glCtx
);
709 * Need this to provide at least one external definition.
712 int gl_fx_dummy_function_texman(void)