b43b40e3855ad25107e889dcbcdbe68538da36b0
2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 /* fxtexman.c - 3Dfx VooDoo texture memory functions */
46 static FxU32 texBoundMask
;
48 #define FX_2MB_SPLIT 0x200000
50 static struct gl_texture_object
*fxTMFindOldestObject(fxMesaContext fxMesa
,
62 sanity(fxMesaContext fxMesa
)
64 MemRange
*tmp
, *prev
, *pos
;
67 tmp
= fxMesa
->tmFree
[0];
69 if (!tmp
->startAddr
&& !tmp
->endAddr
) {
70 fprintf(stderr
, "Textures fubar\n");
73 if (tmp
->startAddr
>= tmp
->endAddr
) {
74 fprintf(stderr
, "Node fubar\n");
77 if (prev
&& (prev
->startAddr
>= tmp
->startAddr
||
78 prev
->endAddr
> tmp
->startAddr
)) {
79 fprintf(stderr
, "Sorting fubar\n");
86 tmp
= fxMesa
->tmFree
[1];
88 if (!tmp
->startAddr
&& !tmp
->endAddr
) {
89 fprintf(stderr
, "Textures fubar\n");
92 if (tmp
->startAddr
>= tmp
->endAddr
) {
93 fprintf(stderr
, "Node fubar\n");
96 if (prev
&& (prev
->startAddr
>= tmp
->startAddr
||
97 prev
->endAddr
> tmp
->startAddr
)) {
98 fprintf(stderr
, "Sorting fubar\n");
108 fxTMNewRangeNode(fxMesaContext fxMesa
, FxU32 start
, FxU32 end
)
110 MemRange
*result
= 0;
112 if (fxMesa
->tmPool
) {
113 result
= fxMesa
->tmPool
;
114 fxMesa
->tmPool
= fxMesa
->tmPool
->next
;
117 if (!(result
= MALLOC(sizeof(MemRange
)))) {
118 fprintf(stderr
, "fxTMNewRangeNode: ERROR: out of memory!\n");
123 result
->startAddr
= start
;
124 result
->endAddr
= end
;
129 #define fxTMDeleteRangeNode(fxMesa, range) \
131 range->next = fxMesa->tmPool; \
132 fxMesa->tmPool = range; \
136 fxTMDeleteRangeNode(fxMesaContext fxMesa
, MemRange
* range
)
138 range
->next
= fxMesa
->tmPool
;
139 fxMesa
->tmPool
= range
;
144 fxTMUInit(fxMesaContext fxMesa
, int tmu
)
146 MemRange
*tmn
, *last
;
147 FxU32 start
, end
, blockstart
, blockend
, chunk
;
149 start
= grTexMinAddress(tmu
);
150 end
= grTexMaxAddress(tmu
);
152 chunk
= (fxMesa
->type
>= GR_SSTTYPE_Banshee
) ? (end
- start
) : FX_2MB_SPLIT
;
154 if (fxMesa
->verbose
) {
155 fprintf(stderr
, "Voodoo TMU%d configuration:\n", tmu
);
158 fxMesa
->freeTexMem
[tmu
] = end
- start
;
159 fxMesa
->tmFree
[tmu
] = NULL
;
163 while (blockstart
< end
) {
164 if (blockstart
+ chunk
> end
)
167 blockend
= blockstart
+ chunk
;
170 fprintf(stderr
, "Voodoo %08u-%08u\n",
171 (unsigned int) blockstart
, (unsigned int) blockend
);
173 tmn
= fxTMNewRangeNode(fxMesa
, blockstart
, blockend
);
180 fxMesa
->tmFree
[tmu
] = tmn
;
188 fxTMFindStartAddr(fxMesaContext fxMesa
, GLint tmu
, int size
)
190 MemRange
*prev
, *tmp
;
192 struct gl_texture_object
*obj
;
194 if (fxMesa
->HaveTexUma
) {
200 tmp
= fxMesa
->tmFree
[tmu
];
202 if (tmp
->endAddr
- tmp
->startAddr
>= size
) { /* Fits here */
203 result
= tmp
->startAddr
;
204 tmp
->startAddr
+= size
;
205 if (tmp
->startAddr
== tmp
->endAddr
) { /* Empty */
207 prev
->next
= tmp
->next
;
210 fxMesa
->tmFree
[tmu
] = tmp
->next
;
212 fxTMDeleteRangeNode(fxMesa
, tmp
);
214 fxMesa
->freeTexMem
[tmu
] -= size
;
220 /* No free space. Discard oldest */
221 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
222 fprintf(stderr
, "fxTMFindStartAddr: No free space. Discard oldest\n");
224 obj
= fxTMFindOldestObject(fxMesa
, tmu
);
226 fprintf(stderr
, "fxTMFindStartAddr: ERROR: No space for texture\n");
229 fxTMMoveOutTM(fxMesa
, obj
);
234 int fxTMCheckStartAddr (fxMesaContext fxMesa
, GLint tmu
, tfxTexInfo
*ti
)
239 if (fxMesa
->HaveTexUma
) {
243 size
= grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH
, &(ti
->info
));
245 tmp
= fxMesa
->tmFree
[tmu
];
247 if (tmp
->endAddr
- tmp
->startAddr
>= size
) { /* Fits here */
257 fxTMRemoveRange(fxMesaContext fxMesa
, GLint tmu
, MemRange
* range
)
259 MemRange
*tmp
, *prev
;
261 if (fxMesa
->HaveTexUma
) {
265 if (range
->startAddr
== range
->endAddr
) {
266 fxTMDeleteRangeNode(fxMesa
, range
);
269 fxMesa
->freeTexMem
[tmu
] += range
->endAddr
- range
->startAddr
;
271 tmp
= fxMesa
->tmFree
[tmu
];
273 if (range
->startAddr
> tmp
->startAddr
) {
280 /* When we create the regions, we make a split at the 2MB boundary.
281 Now we have to make sure we don't join those 2MB boundary regions
282 back together again. */
285 if (range
->endAddr
== tmp
->startAddr
286 && tmp
->startAddr
& texBoundMask
) {
288 tmp
->startAddr
= range
->startAddr
;
289 fxTMDeleteRangeNode(fxMesa
, range
);
294 if (prev
->endAddr
== range
->startAddr
295 && range
->startAddr
& texBoundMask
) {
297 prev
->endAddr
= range
->endAddr
;
298 prev
->next
= range
->next
;
299 fxTMDeleteRangeNode(fxMesa
, range
);
305 fxMesa
->tmFree
[tmu
] = range
;
309 static struct gl_texture_object
*
310 fxTMFindOldestObject(fxMesaContext fxMesa
, int tmu
)
312 GLuint age
, old
, lasttime
, bindnumber
;
313 GLfloat lowestPriority
;
315 struct gl_texture_object
*obj
, *tmp
, *lowestPriorityObj
;
317 tmp
= fxMesa
->glCtx
->Shared
->TexObjectList
;
323 lowestPriorityObj
= NULL
;
324 lowestPriority
= 1.0F
;
326 bindnumber
= fxMesa
->texBindNumber
;
328 info
= fxTMGetTexInfo(tmp
);
330 if (info
&& info
->isInTM
&&
331 ((info
->whichTMU
== tmu
) ||
332 (info
->whichTMU
== FX_TMU_BOTH
) ||
333 (info
->whichTMU
== FX_TMU_SPLIT
) ||
337 lasttime
= info
->lastTimeUsed
;
339 if (lasttime
> bindnumber
)
340 age
= bindnumber
+ (UINT_MAX
- lasttime
+ 1); /* TO DO: check wrap around */
342 age
= bindnumber
- lasttime
;
349 /* examine priority */
350 if (tmp
->Priority
< lowestPriority
) {
351 lowestPriority
= tmp
->Priority
;
352 lowestPriorityObj
= tmp
;
358 if (lowestPriorityObj
!= NULL
) {
359 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
360 fprintf(stderr
, "fxTMFindOldestObject: %d pri=%f\n", lowestPriorityObj
->Name
, lowestPriority
);
362 return lowestPriorityObj
;
365 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
367 fprintf(stderr
, "fxTMFindOldestObject: %d age=%d\n", obj
->Name
, old
);
375 fxTMAddObj(fxMesaContext fxMesa
,
376 struct gl_texture_object
*tObj
, GLint tmu
, int texmemsize
)
381 startAddr
= fxTMFindStartAddr(fxMesa
, tmu
, texmemsize
);
384 range
= fxTMNewRangeNode(fxMesa
, startAddr
, startAddr
+ texmemsize
);
388 /* External Functions */
391 fxTMMoveInTM_NoLock(fxMesaContext fxMesa
, struct gl_texture_object
*tObj
,
394 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
398 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
399 fprintf(stderr
, "fxTMMoveInTM_NoLock(%d)\n", tObj
->Name
);
402 fxMesa
->stats
.reqTexUpload
++;
404 if (!ti
->validated
) {
405 fprintf(stderr
, "fxTMMoveInTM_NoLock: INTERNAL ERROR: not validated\n");
411 if (ti
->whichTMU
== where
)
413 if (where
== FX_TMU_SPLIT
|| ti
->whichTMU
== FX_TMU_SPLIT
)
414 fxTMMoveOutTM_NoLock(fxMesa
, tObj
);
416 if (ti
->whichTMU
== FX_TMU_BOTH
)
422 if (TDFX_DEBUG
& (VERBOSE_DRIVER
| VERBOSE_TEXTURE
)) {
423 fprintf(stderr
, "fxTMMoveInTM_NoLock: downloading %p (%d) in texture memory in %d\n",
424 (void *)tObj
, tObj
->Name
, where
);
427 ti
->whichTMU
= (FxU32
) where
;
432 texmemsize
= (int)grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH
, &(ti
->info
));
433 ti
->tm
[where
] = fxTMAddObj(fxMesa
, tObj
, where
, texmemsize
);
434 fxMesa
->stats
.memTexUpload
+= texmemsize
;
436 for (i
= FX_largeLodValue(ti
->info
), l
= ti
->minLevel
;
437 i
<= FX_smallLodValue(ti
->info
); i
++, l
++) {
438 struct gl_texture_image
*texImage
= tObj
->Image
[0][l
];
439 grTexDownloadMipMapLevel(where
,
440 ti
->tm
[where
]->startAddr
,
442 FX_largeLodLog2(ti
->info
),
443 FX_aspectRatioLog2(ti
->info
),
445 GR_MIPMAPLEVELMASK_BOTH
,
450 texmemsize
= (int)grTexTextureMemRequired(GR_MIPMAPLEVELMASK_ODD
, &(ti
->info
));
451 ti
->tm
[FX_TMU0
] = fxTMAddObj(fxMesa
, tObj
, FX_TMU0
, texmemsize
);
452 fxMesa
->stats
.memTexUpload
+= texmemsize
;
454 texmemsize
= (int)grTexTextureMemRequired(GR_MIPMAPLEVELMASK_EVEN
, &(ti
->info
));
455 ti
->tm
[FX_TMU1
] = fxTMAddObj(fxMesa
, tObj
, FX_TMU1
, texmemsize
);
456 fxMesa
->stats
.memTexUpload
+= texmemsize
;
458 for (i
= FX_largeLodValue(ti
->info
), l
= ti
->minLevel
;
459 i
<= FX_smallLodValue(ti
->info
); i
++, l
++) {
460 struct gl_texture_image
*texImage
= tObj
->Image
[0][l
];
462 grTexDownloadMipMapLevel(GR_TMU0
,
463 ti
->tm
[FX_TMU0
]->startAddr
,
465 FX_largeLodLog2(ti
->info
),
466 FX_aspectRatioLog2(ti
->info
),
468 GR_MIPMAPLEVELMASK_ODD
,
471 grTexDownloadMipMapLevel(GR_TMU1
,
472 ti
->tm
[FX_TMU1
]->startAddr
,
474 FX_largeLodLog2(ti
->info
),
475 FX_aspectRatioLog2(ti
->info
),
477 GR_MIPMAPLEVELMASK_EVEN
,
482 texmemsize
= (int)grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH
, &(ti
->info
));
483 ti
->tm
[FX_TMU0
] = fxTMAddObj(fxMesa
, tObj
, FX_TMU0
, texmemsize
);
484 fxMesa
->stats
.memTexUpload
+= texmemsize
;
486 /*texmemsize = (int)grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &(ti->info));*/
487 ti
->tm
[FX_TMU1
] = fxTMAddObj(fxMesa
, tObj
, FX_TMU1
, texmemsize
);
488 fxMesa
->stats
.memTexUpload
+= texmemsize
;
490 for (i
= FX_largeLodValue(ti
->info
), l
= ti
->minLevel
;
491 i
<= FX_smallLodValue(ti
->info
); i
++, l
++) {
492 struct gl_texture_image
*texImage
= tObj
->Image
[0][l
];
493 grTexDownloadMipMapLevel(GR_TMU0
,
494 ti
->tm
[FX_TMU0
]->startAddr
,
496 FX_largeLodLog2(ti
->info
),
497 FX_aspectRatioLog2(ti
->info
),
499 GR_MIPMAPLEVELMASK_BOTH
,
502 grTexDownloadMipMapLevel(GR_TMU1
,
503 ti
->tm
[FX_TMU1
]->startAddr
,
505 FX_largeLodLog2(ti
->info
),
506 FX_aspectRatioLog2(ti
->info
),
508 GR_MIPMAPLEVELMASK_BOTH
,
513 fprintf(stderr
, "fxTMMoveInTM_NoLock: INTERNAL ERROR: wrong tmu (%d)\n", where
);
518 fxMesa
->stats
.texUpload
++;
520 ti
->isInTM
= GL_TRUE
;
525 fxTMMoveInTM(fxMesaContext fxMesa
, struct gl_texture_object
*tObj
,
529 fxTMMoveInTM_NoLock(fxMesa
, tObj
, where
);
535 fxTMReloadMipMapLevel(fxMesaContext fxMesa
, struct gl_texture_object
*tObj
,
538 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
541 struct gl_texture_image
*texImage
= tObj
->Image
[0][level
];
542 tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
544 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
545 fprintf(stderr
, "fxTMReloadMipMapLevel(%p (%d), %d)\n", (void *)tObj
, tObj
->Name
, level
);
549 assert(mml
->width
> 0);
550 assert(mml
->height
> 0);
551 assert(mml
->glideFormat
> 0);
554 if (!ti
->validated
) {
555 fprintf(stderr
, "fxTMReloadMipMapLevel: INTERNAL ERROR: not validated\n");
560 tmu
= (int) ti
->whichTMU
;
561 fxMesa
->stats
.reqTexUpload
++;
562 fxMesa
->stats
.texUpload
++;
564 lodlevel
= ti
->info
.largeLodLog2
- (level
- ti
->minLevel
);
569 grTexDownloadMipMapLevel(tmu
,
570 ti
->tm
[tmu
]->startAddr
,
572 FX_largeLodLog2(ti
->info
),
573 FX_aspectRatioLog2(ti
->info
),
575 GR_MIPMAPLEVELMASK_BOTH
, texImage
->Data
);
578 grTexDownloadMipMapLevel(GR_TMU0
,
579 ti
->tm
[GR_TMU0
]->startAddr
,
581 FX_largeLodLog2(ti
->info
),
582 FX_aspectRatioLog2(ti
->info
),
584 GR_MIPMAPLEVELMASK_ODD
, texImage
->Data
);
586 grTexDownloadMipMapLevel(GR_TMU1
,
587 ti
->tm
[GR_TMU1
]->startAddr
,
589 FX_largeLodLog2(ti
->info
),
590 FX_aspectRatioLog2(ti
->info
),
592 GR_MIPMAPLEVELMASK_EVEN
, texImage
->Data
);
595 grTexDownloadMipMapLevel(GR_TMU0
,
596 ti
->tm
[GR_TMU0
]->startAddr
,
598 FX_largeLodLog2(ti
->info
),
599 FX_aspectRatioLog2(ti
->info
),
601 GR_MIPMAPLEVELMASK_BOTH
, texImage
->Data
);
603 grTexDownloadMipMapLevel(GR_TMU1
,
604 ti
->tm
[GR_TMU1
]->startAddr
,
606 FX_largeLodLog2(ti
->info
),
607 FX_aspectRatioLog2(ti
->info
),
609 GR_MIPMAPLEVELMASK_BOTH
, texImage
->Data
);
613 fprintf(stderr
, "fxTMReloadMipMapLevel: INTERNAL ERROR: wrong tmu (%d)\n", tmu
);
620 fxTMReloadSubMipMapLevel(fxMesaContext fxMesa
,
621 struct gl_texture_object
*tObj
,
622 GLint level
, GLint yoffset
, GLint height
)
624 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
626 unsigned short *data
;
628 struct gl_texture_image
*texImage
= tObj
->Image
[0][level
];
629 tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
633 if (!ti
->validated
) {
634 fprintf(stderr
, "fxTMReloadSubMipMapLevel: INTERNAL ERROR: not validated\n");
639 tmu
= (int) ti
->whichTMU
;
640 fxTMMoveInTM(fxMesa
, tObj
, tmu
);
642 fxTexGetInfo(mml
->width
, mml
->height
,
643 &lodlevel
, NULL
, NULL
, NULL
, NULL
, NULL
);
645 if ((ti
->info
.format
== GR_TEXFMT_INTENSITY_8
) ||
646 (ti
->info
.format
== GR_TEXFMT_P_8
) ||
647 (ti
->info
.format
== GR_TEXFMT_ALPHA_8
))
648 data
= (GLushort
*) texImage
->Data
+ ((yoffset
* mml
->width
) >> 1);
650 data
= (GLushort
*) texImage
->Data
+ yoffset
* mml
->width
;
655 grTexDownloadMipMapLevelPartial(tmu
,
656 ti
->tm
[tmu
]->startAddr
,
657 FX_valueToLod(FX_lodToValue(lodlevel
)
659 FX_largeLodLog2(ti
->info
),
660 FX_aspectRatioLog2(ti
->info
),
662 GR_MIPMAPLEVELMASK_BOTH
, data
,
663 yoffset
, yoffset
+ height
- 1);
666 grTexDownloadMipMapLevelPartial(GR_TMU0
,
667 ti
->tm
[FX_TMU0
]->startAddr
,
668 FX_valueToLod(FX_lodToValue(lodlevel
)
670 FX_largeLodLog2(ti
->info
),
671 FX_aspectRatioLog2(ti
->info
),
673 GR_MIPMAPLEVELMASK_ODD
, data
,
674 yoffset
, yoffset
+ height
- 1);
676 grTexDownloadMipMapLevelPartial(GR_TMU1
,
677 ti
->tm
[FX_TMU1
]->startAddr
,
678 FX_valueToLod(FX_lodToValue(lodlevel
)
680 FX_largeLodLog2(ti
->info
),
681 FX_aspectRatioLog2(ti
->info
),
683 GR_MIPMAPLEVELMASK_EVEN
, data
,
684 yoffset
, yoffset
+ height
- 1);
687 grTexDownloadMipMapLevelPartial(GR_TMU0
,
688 ti
->tm
[FX_TMU0
]->startAddr
,
689 FX_valueToLod(FX_lodToValue(lodlevel
)
691 FX_largeLodLog2(ti
->info
),
692 FX_aspectRatioLog2(ti
->info
),
694 GR_MIPMAPLEVELMASK_BOTH
, data
,
695 yoffset
, yoffset
+ height
- 1);
697 grTexDownloadMipMapLevelPartial(GR_TMU1
,
698 ti
->tm
[FX_TMU1
]->startAddr
,
699 FX_valueToLod(FX_lodToValue(lodlevel
)
701 FX_largeLodLog2(ti
->info
),
702 FX_aspectRatioLog2(ti
->info
),
704 GR_MIPMAPLEVELMASK_BOTH
, data
,
705 yoffset
, yoffset
+ height
- 1);
708 fprintf(stderr
, "fxTMReloadSubMipMapLevel: INTERNAL ERROR: wrong tmu (%d)\n", tmu
);
715 fxTMMoveOutTM(fxMesaContext fxMesa
, struct gl_texture_object
*tObj
)
717 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
719 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
720 fprintf(stderr
, "fxTMMoveOutTM(%p (%d))\n", (void *)tObj
, tObj
->Name
);
726 switch (ti
->whichTMU
) {
729 fxTMRemoveRange(fxMesa
, (int) ti
->whichTMU
, ti
->tm
[ti
->whichTMU
]);
733 fxTMRemoveRange(fxMesa
, FX_TMU0
, ti
->tm
[FX_TMU0
]);
734 fxTMRemoveRange(fxMesa
, FX_TMU1
, ti
->tm
[FX_TMU1
]);
737 fprintf(stderr
, "fxTMMoveOutTM: INTERNAL ERROR: bad TMU (%ld)\n", ti
->whichTMU
);
742 ti
->isInTM
= GL_FALSE
;
743 ti
->whichTMU
= FX_TMU_NONE
;
747 fxTMFreeTexture(fxMesaContext fxMesa
, struct gl_texture_object
*tObj
)
749 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
752 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
753 fprintf(stderr
, "fxTMFreeTexture(%p (%d))\n", (void *)tObj
, tObj
->Name
);
756 fxTMMoveOutTM(fxMesa
, tObj
);
758 for (i
= 0; i
< MAX_TEXTURE_LEVELS
; i
++) {
759 struct gl_texture_image
*texImage
= tObj
->Image
[0][i
];
761 if (texImage
->DriverData
) {
762 FREE(texImage
->DriverData
);
763 texImage
->DriverData
= NULL
;
767 switch (ti
->whichTMU
) {
770 fxTMDeleteRangeNode(fxMesa
, ti
->tm
[ti
->whichTMU
]);
774 fxTMDeleteRangeNode(fxMesa
, ti
->tm
[FX_TMU0
]);
775 fxTMDeleteRangeNode(fxMesa
, ti
->tm
[FX_TMU1
]);
781 fxTMInit(fxMesaContext fxMesa
)
783 fxMesa
->texBindNumber
= 0;
786 if (fxMesa
->HaveTexUma
) {
787 grEnable(GR_TEXTURE_UMA_EXT
);
790 fxTMUInit(fxMesa
, FX_TMU0
);
792 if (!fxMesa
->HaveTexUma
&& fxMesa
->haveTwoTMUs
)
793 fxTMUInit(fxMesa
, FX_TMU1
);
795 texBoundMask
= (fxMesa
->type
>= GR_SSTTYPE_Banshee
) ? -1 : (FX_2MB_SPLIT
- 1);
799 fxTMClose(fxMesaContext fxMesa
)
801 MemRange
*tmp
, *next
;
803 tmp
= fxMesa
->tmPool
;
809 tmp
= fxMesa
->tmFree
[FX_TMU0
];
815 if (fxMesa
->haveTwoTMUs
) {
816 tmp
= fxMesa
->tmFree
[FX_TMU1
];
826 fxTMRestoreTextures_NoLock(fxMesaContext ctx
)
829 struct gl_texture_object
*tObj
;
832 tObj
= ctx
->glCtx
->Shared
->TexObjectList
;
834 ti
= fxTMGetTexInfo(tObj
);
835 if (ti
&& ti
->isInTM
) {
836 for (i
= 0; i
< MAX_TEXTURE_UNITS
; i
++)
837 if (ctx
->glCtx
->Texture
.Unit
[i
]._Current
== tObj
) {
838 /* Force the texture onto the board, as it could be in use */
839 where
= ti
->whichTMU
;
840 fxTMMoveOutTM_NoLock(ctx
, tObj
);
841 fxTMMoveInTM_NoLock(ctx
, tObj
, where
);
844 if (i
== MAX_TEXTURE_UNITS
) /* Mark the texture as off the board */
845 fxTMMoveOutTM_NoLock(ctx
, tObj
);
855 * Need this to provide at least one external definition.
858 extern int gl_fx_dummy_function_texman(void);
860 gl_fx_dummy_function_texman(void)