5a6f18a16904e7044c45cffa9f7f674d263e3408
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 %s configuration:\n",
156 (tmu
== FX_TMU0
) ? "TMU0" : "TMU1");
157 fprintf(stderr
, "Voodoo Lower texture memory address (%u)\n",
158 (unsigned int) start
);
159 fprintf(stderr
, "Voodoo Higher texture memory address (%u)\n",
161 fprintf(stderr
, "Voodoo Splitting Texture memory in %luMB blocks:\n", chunk
>> 20);
164 fxMesa
->freeTexMem
[tmu
] = end
- start
;
165 fxMesa
->tmFree
[tmu
] = NULL
;
169 while (blockstart
< end
) {
170 if (blockstart
+ chunk
> end
)
173 blockend
= blockstart
+ chunk
;
176 fprintf(stderr
, "Voodoo %07u-%07u\n",
177 (unsigned int) blockstart
, (unsigned int) blockend
);
179 tmn
= fxTMNewRangeNode(fxMesa
, blockstart
, blockend
);
186 fxMesa
->tmFree
[tmu
] = tmn
;
194 fxTMFindStartAddr(fxMesaContext fxMesa
, GLint tmu
, int size
)
196 MemRange
*prev
, *tmp
;
198 struct gl_texture_object
*obj
;
200 if (fxMesa
->HaveTexUma
) {
206 tmp
= fxMesa
->tmFree
[tmu
];
208 if (tmp
->endAddr
- tmp
->startAddr
>= size
) { /* Fits here */
209 result
= tmp
->startAddr
;
210 tmp
->startAddr
+= size
;
211 if (tmp
->startAddr
== tmp
->endAddr
) { /* Empty */
213 prev
->next
= tmp
->next
;
216 fxMesa
->tmFree
[tmu
] = tmp
->next
;
218 fxTMDeleteRangeNode(fxMesa
, tmp
);
220 fxMesa
->freeTexMem
[tmu
] -= size
;
226 /* No free space. Discard oldest */
227 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
228 fprintf(stderr
, "fxTMFindStartAddr: No free space. Discard oldest\n");
230 obj
= fxTMFindOldestObject(fxMesa
, tmu
);
232 fprintf(stderr
, "fxTMFindStartAddr: ERROR: No space for texture\n");
235 fxTMMoveOutTM(fxMesa
, obj
);
240 int fxTMCheckStartAddr (fxMesaContext fxMesa
, GLint tmu
, tfxTexInfo
*ti
)
242 MemRange
*prev
, *tmp
;
244 struct gl_texture_object
*obj
;
246 if (fxMesa
->HaveTexUma
) {
250 size
= grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH
, &(ti
->info
));
252 tmp
= fxMesa
->tmFree
[tmu
];
254 if (tmp
->endAddr
- tmp
->startAddr
>= size
) { /* Fits here */
264 fxTMRemoveRange(fxMesaContext fxMesa
, GLint tmu
, MemRange
* range
)
266 MemRange
*tmp
, *prev
;
268 if (fxMesa
->HaveTexUma
) {
272 if (range
->startAddr
== range
->endAddr
) {
273 fxTMDeleteRangeNode(fxMesa
, range
);
276 fxMesa
->freeTexMem
[tmu
] += range
->endAddr
- range
->startAddr
;
278 tmp
= fxMesa
->tmFree
[tmu
];
280 if (range
->startAddr
> tmp
->startAddr
) {
287 /* When we create the regions, we make a split at the 2MB boundary.
288 Now we have to make sure we don't join those 2MB boundary regions
289 back together again. */
292 if (range
->endAddr
== tmp
->startAddr
293 && tmp
->startAddr
& texBoundMask
) {
295 tmp
->startAddr
= range
->startAddr
;
296 fxTMDeleteRangeNode(fxMesa
, range
);
301 if (prev
->endAddr
== range
->startAddr
302 && range
->startAddr
& texBoundMask
) {
304 prev
->endAddr
= range
->endAddr
;
305 prev
->next
= range
->next
;
306 fxTMDeleteRangeNode(fxMesa
, range
);
312 fxMesa
->tmFree
[tmu
] = range
;
316 static struct gl_texture_object
*
317 fxTMFindOldestObject(fxMesaContext fxMesa
, int tmu
)
319 GLuint age
, old
, lasttime
, bindnumber
;
320 GLfloat lowestPriority
;
322 struct gl_texture_object
*obj
, *tmp
, *lowestPriorityObj
;
324 tmp
= fxMesa
->glCtx
->Shared
->TexObjectList
;
330 lowestPriorityObj
= NULL
;
331 lowestPriority
= 1.0F
;
333 bindnumber
= fxMesa
->texBindNumber
;
335 info
= fxTMGetTexInfo(tmp
);
337 if (info
&& info
->isInTM
&&
338 ((info
->whichTMU
== tmu
) ||
339 (info
->whichTMU
== FX_TMU_BOTH
) ||
340 (info
->whichTMU
== FX_TMU_SPLIT
) ||
344 lasttime
= info
->lastTimeUsed
;
346 if (lasttime
> bindnumber
)
347 age
= bindnumber
+ (UINT_MAX
- lasttime
+ 1); /* TO DO: check wrap around */
349 age
= bindnumber
- lasttime
;
356 /* examine priority */
357 if (tmp
->Priority
< lowestPriority
) {
358 lowestPriority
= tmp
->Priority
;
359 lowestPriorityObj
= tmp
;
365 if (lowestPriorityObj
!= NULL
) {
366 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
367 fprintf(stderr
, "fxTMFindOldestObject: %d pri=%f\n", lowestPriorityObj
->Name
, lowestPriority
);
369 return lowestPriorityObj
;
372 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
374 fprintf(stderr
, "fxTMFindOldestObject: %d age=%d\n", obj
->Name
, old
);
382 fxTMAddObj(fxMesaContext fxMesa
,
383 struct gl_texture_object
*tObj
, GLint tmu
, int texmemsize
)
388 startAddr
= fxTMFindStartAddr(fxMesa
, tmu
, texmemsize
);
391 range
= fxTMNewRangeNode(fxMesa
, startAddr
, startAddr
+ texmemsize
);
395 /* External Functions */
398 fxTMMoveInTM_NoLock(fxMesaContext fxMesa
, struct gl_texture_object
*tObj
,
401 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
405 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
406 fprintf(stderr
, "fxTMMoveInTM_NoLock(%d)\n", tObj
->Name
);
409 fxMesa
->stats
.reqTexUpload
++;
411 if (!ti
->validated
) {
412 fprintf(stderr
, "fxTMMoveInTM_NoLock: INTERNAL ERROR: not validated\n");
418 if (ti
->whichTMU
== where
)
420 if (where
== FX_TMU_SPLIT
|| ti
->whichTMU
== FX_TMU_SPLIT
)
421 fxTMMoveOutTM_NoLock(fxMesa
, tObj
);
423 if (ti
->whichTMU
== FX_TMU_BOTH
)
429 if (TDFX_DEBUG
& (VERBOSE_DRIVER
| VERBOSE_TEXTURE
)) {
430 fprintf(stderr
, "fxTMMoveInTM_NoLock: downloading %p (%d) in texture memory in %d\n",
431 (void *)tObj
, tObj
->Name
, where
);
434 ti
->whichTMU
= (FxU32
) where
;
439 texmemsize
= (int)grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH
, &(ti
->info
));
440 ti
->tm
[where
] = fxTMAddObj(fxMesa
, tObj
, where
, texmemsize
);
441 fxMesa
->stats
.memTexUpload
+= texmemsize
;
443 for (i
= FX_largeLodValue(ti
->info
), l
= ti
->minLevel
;
444 i
<= FX_smallLodValue(ti
->info
); i
++, l
++) {
445 struct gl_texture_image
*texImage
= tObj
->Image
[0][l
];
446 grTexDownloadMipMapLevel(where
,
447 ti
->tm
[where
]->startAddr
,
449 FX_largeLodLog2(ti
->info
),
450 FX_aspectRatioLog2(ti
->info
),
452 GR_MIPMAPLEVELMASK_BOTH
,
457 texmemsize
= (int)grTexTextureMemRequired(GR_MIPMAPLEVELMASK_ODD
, &(ti
->info
));
458 ti
->tm
[FX_TMU0
] = fxTMAddObj(fxMesa
, tObj
, FX_TMU0
, texmemsize
);
459 fxMesa
->stats
.memTexUpload
+= texmemsize
;
461 texmemsize
= (int)grTexTextureMemRequired(GR_MIPMAPLEVELMASK_EVEN
, &(ti
->info
));
462 ti
->tm
[FX_TMU1
] = fxTMAddObj(fxMesa
, tObj
, FX_TMU1
, texmemsize
);
463 fxMesa
->stats
.memTexUpload
+= texmemsize
;
465 for (i
= FX_largeLodValue(ti
->info
), l
= ti
->minLevel
;
466 i
<= FX_smallLodValue(ti
->info
); i
++, l
++) {
467 struct gl_texture_image
*texImage
= tObj
->Image
[0][l
];
469 grTexDownloadMipMapLevel(GR_TMU0
,
470 ti
->tm
[FX_TMU0
]->startAddr
,
472 FX_largeLodLog2(ti
->info
),
473 FX_aspectRatioLog2(ti
->info
),
475 GR_MIPMAPLEVELMASK_ODD
,
478 grTexDownloadMipMapLevel(GR_TMU1
,
479 ti
->tm
[FX_TMU1
]->startAddr
,
481 FX_largeLodLog2(ti
->info
),
482 FX_aspectRatioLog2(ti
->info
),
484 GR_MIPMAPLEVELMASK_EVEN
,
489 texmemsize
= (int)grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH
, &(ti
->info
));
490 ti
->tm
[FX_TMU0
] = fxTMAddObj(fxMesa
, tObj
, FX_TMU0
, texmemsize
);
491 fxMesa
->stats
.memTexUpload
+= texmemsize
;
493 /*texmemsize = (int)grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &(ti->info));*/
494 ti
->tm
[FX_TMU1
] = fxTMAddObj(fxMesa
, tObj
, FX_TMU1
, texmemsize
);
495 fxMesa
->stats
.memTexUpload
+= texmemsize
; /* ZZZ: required? */
497 for (i
= FX_largeLodValue(ti
->info
), l
= ti
->minLevel
;
498 i
<= FX_smallLodValue(ti
->info
); i
++, l
++) {
499 struct gl_texture_image
*texImage
= tObj
->Image
[0][l
];
500 grTexDownloadMipMapLevel(GR_TMU0
,
501 ti
->tm
[FX_TMU0
]->startAddr
,
503 FX_largeLodLog2(ti
->info
),
504 FX_aspectRatioLog2(ti
->info
),
506 GR_MIPMAPLEVELMASK_BOTH
,
509 grTexDownloadMipMapLevel(GR_TMU1
,
510 ti
->tm
[FX_TMU1
]->startAddr
,
512 FX_largeLodLog2(ti
->info
),
513 FX_aspectRatioLog2(ti
->info
),
515 GR_MIPMAPLEVELMASK_BOTH
,
520 fprintf(stderr
, "fxTMMoveInTM_NoLock: INTERNAL ERROR: wrong tmu (%d)\n", where
);
525 fxMesa
->stats
.texUpload
++;
527 ti
->isInTM
= GL_TRUE
;
532 fxTMMoveInTM(fxMesaContext fxMesa
, struct gl_texture_object
*tObj
,
536 fxTMMoveInTM_NoLock(fxMesa
, tObj
, where
);
542 fxTMReloadMipMapLevel(fxMesaContext fxMesa
, struct gl_texture_object
*tObj
,
545 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
548 struct gl_texture_image
*texImage
= tObj
->Image
[0][level
];
549 tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
551 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
552 fprintf(stderr
, "fxTMReloadMipMapLevel(%p (%d), %d)\n", (void *)tObj
, tObj
->Name
, level
);
556 assert(mml
->width
> 0);
557 assert(mml
->height
> 0);
558 assert(mml
->glideFormat
> 0);
560 if (!ti
->validated
) {
561 fprintf(stderr
, "fxTMReloadMipMapLevel: INTERNAL ERROR: not validated\n");
566 tmu
= (int) ti
->whichTMU
;
569 * We get here by (see Tex[Sub]Image2D), thus we are in TMU.
570 * Also, we just set the correct TMU above. fxTMMoveInTM will
571 * bail early, so don't bother...
573 fxTMMoveInTM(fxMesa
, tObj
, tmu
);
575 fxMesa
->stats
.reqTexUpload
++;
576 fxMesa
->stats
.texUpload
++;
579 lodlevel
= ti
->info
.largeLodLog2
- (level
- ti
->minLevel
);
584 grTexDownloadMipMapLevel(tmu
,
585 ti
->tm
[tmu
]->startAddr
,
587 FX_largeLodLog2(ti
->info
),
588 FX_aspectRatioLog2(ti
->info
),
590 GR_MIPMAPLEVELMASK_BOTH
, texImage
->Data
);
593 grTexDownloadMipMapLevel(GR_TMU0
,
594 ti
->tm
[GR_TMU0
]->startAddr
,
596 FX_largeLodLog2(ti
->info
),
597 FX_aspectRatioLog2(ti
->info
),
599 GR_MIPMAPLEVELMASK_ODD
, texImage
->Data
);
601 grTexDownloadMipMapLevel(GR_TMU1
,
602 ti
->tm
[GR_TMU1
]->startAddr
,
604 FX_largeLodLog2(ti
->info
),
605 FX_aspectRatioLog2(ti
->info
),
607 GR_MIPMAPLEVELMASK_EVEN
, texImage
->Data
);
610 grTexDownloadMipMapLevel(GR_TMU0
,
611 ti
->tm
[GR_TMU0
]->startAddr
,
613 FX_largeLodLog2(ti
->info
),
614 FX_aspectRatioLog2(ti
->info
),
616 GR_MIPMAPLEVELMASK_BOTH
, texImage
->Data
);
618 grTexDownloadMipMapLevel(GR_TMU1
,
619 ti
->tm
[GR_TMU1
]->startAddr
,
621 FX_largeLodLog2(ti
->info
),
622 FX_aspectRatioLog2(ti
->info
),
624 GR_MIPMAPLEVELMASK_BOTH
, texImage
->Data
);
628 fprintf(stderr
, "fxTMReloadMipMapLevel: INTERNAL ERROR: wrong tmu (%d)\n", tmu
);
635 fxTMReloadSubMipMapLevel(fxMesaContext fxMesa
,
636 struct gl_texture_object
*tObj
,
637 GLint level
, GLint yoffset
, GLint height
)
639 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
641 unsigned short *data
;
643 struct gl_texture_image
*texImage
= tObj
->Image
[0][level
];
644 tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
648 if (!ti
->validated
) {
649 fprintf(stderr
, "fxTMReloadSubMipMapLevel: INTERNAL ERROR: not validated\n");
654 tmu
= (int) ti
->whichTMU
;
655 fxTMMoveInTM(fxMesa
, tObj
, tmu
);
657 fxTexGetInfo(mml
->width
, mml
->height
,
658 &lodlevel
, NULL
, NULL
, NULL
, NULL
, NULL
);
660 if ((ti
->info
.format
== GR_TEXFMT_INTENSITY_8
) ||
661 (ti
->info
.format
== GR_TEXFMT_P_8
) ||
662 (ti
->info
.format
== GR_TEXFMT_ALPHA_8
))
663 data
= (GLushort
*) texImage
->Data
+ ((yoffset
* mml
->width
) >> 1);
665 data
= (GLushort
*) texImage
->Data
+ yoffset
* mml
->width
;
670 grTexDownloadMipMapLevelPartial(tmu
,
671 ti
->tm
[tmu
]->startAddr
,
672 FX_valueToLod(FX_lodToValue(lodlevel
)
674 FX_largeLodLog2(ti
->info
),
675 FX_aspectRatioLog2(ti
->info
),
677 GR_MIPMAPLEVELMASK_BOTH
, data
,
678 yoffset
, yoffset
+ height
- 1);
681 grTexDownloadMipMapLevelPartial(GR_TMU0
,
682 ti
->tm
[FX_TMU0
]->startAddr
,
683 FX_valueToLod(FX_lodToValue(lodlevel
)
685 FX_largeLodLog2(ti
->info
),
686 FX_aspectRatioLog2(ti
->info
),
688 GR_MIPMAPLEVELMASK_ODD
, data
,
689 yoffset
, yoffset
+ height
- 1);
691 grTexDownloadMipMapLevelPartial(GR_TMU1
,
692 ti
->tm
[FX_TMU1
]->startAddr
,
693 FX_valueToLod(FX_lodToValue(lodlevel
)
695 FX_largeLodLog2(ti
->info
),
696 FX_aspectRatioLog2(ti
->info
),
698 GR_MIPMAPLEVELMASK_EVEN
, data
,
699 yoffset
, yoffset
+ height
- 1);
702 grTexDownloadMipMapLevelPartial(GR_TMU0
,
703 ti
->tm
[FX_TMU0
]->startAddr
,
704 FX_valueToLod(FX_lodToValue(lodlevel
)
706 FX_largeLodLog2(ti
->info
),
707 FX_aspectRatioLog2(ti
->info
),
709 GR_MIPMAPLEVELMASK_BOTH
, data
,
710 yoffset
, yoffset
+ height
- 1);
712 grTexDownloadMipMapLevelPartial(GR_TMU1
,
713 ti
->tm
[FX_TMU1
]->startAddr
,
714 FX_valueToLod(FX_lodToValue(lodlevel
)
716 FX_largeLodLog2(ti
->info
),
717 FX_aspectRatioLog2(ti
->info
),
719 GR_MIPMAPLEVELMASK_BOTH
, data
,
720 yoffset
, yoffset
+ height
- 1);
723 fprintf(stderr
, "fxTMReloadSubMipMapLevel: INTERNAL ERROR: wrong tmu (%d)\n", tmu
);
730 fxTMMoveOutTM(fxMesaContext fxMesa
, struct gl_texture_object
*tObj
)
732 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
734 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
735 fprintf(stderr
, "fxTMMoveOutTM(%p (%d))\n", (void *)tObj
, tObj
->Name
);
741 switch (ti
->whichTMU
) {
744 fxTMRemoveRange(fxMesa
, (int) ti
->whichTMU
, ti
->tm
[ti
->whichTMU
]);
748 fxTMRemoveRange(fxMesa
, FX_TMU0
, ti
->tm
[FX_TMU0
]);
749 fxTMRemoveRange(fxMesa
, FX_TMU1
, ti
->tm
[FX_TMU1
]);
752 fprintf(stderr
, "fxTMMoveOutTM: INTERNAL ERROR: bad TMU (%ld)\n", ti
->whichTMU
);
757 ti
->isInTM
= GL_FALSE
;
758 ti
->whichTMU
= FX_TMU_NONE
;
762 fxTMFreeTexture(fxMesaContext fxMesa
, struct gl_texture_object
*tObj
)
764 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
767 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
768 fprintf(stderr
, "fxTMFreeTexture(%p (%d))\n", (void *)tObj
, tObj
->Name
);
771 fxTMMoveOutTM(fxMesa
, tObj
);
773 for (i
= 0; i
< MAX_TEXTURE_LEVELS
; i
++) {
774 struct gl_texture_image
*texImage
= tObj
->Image
[0][i
];
776 if (texImage
->DriverData
) {
777 FREE(texImage
->DriverData
);
778 texImage
->DriverData
= NULL
;
782 switch (ti
->whichTMU
) {
785 fxTMDeleteRangeNode(fxMesa
, ti
->tm
[ti
->whichTMU
]);
789 fxTMDeleteRangeNode(fxMesa
, ti
->tm
[FX_TMU0
]);
790 fxTMDeleteRangeNode(fxMesa
, ti
->tm
[FX_TMU1
]);
796 fxTMInit(fxMesaContext fxMesa
)
798 fxMesa
->texBindNumber
= 0;
801 if (fxMesa
->HaveTexUma
) {
802 grEnable(GR_TEXTURE_UMA_EXT
);
805 fxTMUInit(fxMesa
, FX_TMU0
);
807 if (!fxMesa
->HaveTexUma
&& fxMesa
->haveTwoTMUs
)
808 fxTMUInit(fxMesa
, FX_TMU1
);
810 texBoundMask
= (fxMesa
->type
>= GR_SSTTYPE_Banshee
) ? -1 : (FX_2MB_SPLIT
- 1);
814 fxTMClose(fxMesaContext fxMesa
)
816 MemRange
*tmp
, *next
;
818 tmp
= fxMesa
->tmPool
;
824 tmp
= fxMesa
->tmFree
[FX_TMU0
];
830 if (fxMesa
->haveTwoTMUs
) {
831 tmp
= fxMesa
->tmFree
[FX_TMU1
];
841 fxTMRestoreTextures_NoLock(fxMesaContext ctx
)
844 struct gl_texture_object
*tObj
;
847 tObj
= ctx
->glCtx
->Shared
->TexObjectList
;
849 ti
= fxTMGetTexInfo(tObj
);
850 if (ti
&& ti
->isInTM
) {
851 for (i
= 0; i
< MAX_TEXTURE_UNITS
; i
++)
852 if (ctx
->glCtx
->Texture
.Unit
[i
]._Current
== tObj
) {
853 /* Force the texture onto the board, as it could be in use */
854 where
= ti
->whichTMU
;
855 fxTMMoveOutTM_NoLock(ctx
, tObj
);
856 fxTMMoveInTM_NoLock(ctx
, tObj
, where
);
859 if (i
== MAX_TEXTURE_UNITS
) /* Mark the texture as off the board */
860 fxTMMoveOutTM_NoLock(ctx
, tObj
);
870 * Need this to provide at least one external definition.
873 extern int gl_fx_dummy_function_texman(void);
875 gl_fx_dummy_function_texman(void)