d83c7e3a6259547e5f0fd8004593a54885e6becd
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
)
236 MemRange
*prev
, *tmp
;
238 struct gl_texture_object
*obj
;
240 if (fxMesa
->HaveTexUma
) {
244 size
= grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH
, &(ti
->info
));
246 tmp
= fxMesa
->tmFree
[tmu
];
248 if (tmp
->endAddr
- tmp
->startAddr
>= size
) { /* Fits here */
258 fxTMRemoveRange(fxMesaContext fxMesa
, GLint tmu
, MemRange
* range
)
260 MemRange
*tmp
, *prev
;
262 if (fxMesa
->HaveTexUma
) {
266 if (range
->startAddr
== range
->endAddr
) {
267 fxTMDeleteRangeNode(fxMesa
, range
);
270 fxMesa
->freeTexMem
[tmu
] += range
->endAddr
- range
->startAddr
;
272 tmp
= fxMesa
->tmFree
[tmu
];
274 if (range
->startAddr
> tmp
->startAddr
) {
281 /* When we create the regions, we make a split at the 2MB boundary.
282 Now we have to make sure we don't join those 2MB boundary regions
283 back together again. */
286 if (range
->endAddr
== tmp
->startAddr
287 && tmp
->startAddr
& texBoundMask
) {
289 tmp
->startAddr
= range
->startAddr
;
290 fxTMDeleteRangeNode(fxMesa
, range
);
295 if (prev
->endAddr
== range
->startAddr
296 && range
->startAddr
& texBoundMask
) {
298 prev
->endAddr
= range
->endAddr
;
299 prev
->next
= range
->next
;
300 fxTMDeleteRangeNode(fxMesa
, range
);
306 fxMesa
->tmFree
[tmu
] = range
;
310 static struct gl_texture_object
*
311 fxTMFindOldestObject(fxMesaContext fxMesa
, int tmu
)
313 GLuint age
, old
, lasttime
, bindnumber
;
314 GLfloat lowestPriority
;
316 struct gl_texture_object
*obj
, *tmp
, *lowestPriorityObj
;
318 tmp
= fxMesa
->glCtx
->Shared
->TexObjectList
;
324 lowestPriorityObj
= NULL
;
325 lowestPriority
= 1.0F
;
327 bindnumber
= fxMesa
->texBindNumber
;
329 info
= fxTMGetTexInfo(tmp
);
331 if (info
&& info
->isInTM
&&
332 ((info
->whichTMU
== tmu
) ||
333 (info
->whichTMU
== FX_TMU_BOTH
) ||
334 (info
->whichTMU
== FX_TMU_SPLIT
) ||
338 lasttime
= info
->lastTimeUsed
;
340 if (lasttime
> bindnumber
)
341 age
= bindnumber
+ (UINT_MAX
- lasttime
+ 1); /* TO DO: check wrap around */
343 age
= bindnumber
- lasttime
;
350 /* examine priority */
351 if (tmp
->Priority
< lowestPriority
) {
352 lowestPriority
= tmp
->Priority
;
353 lowestPriorityObj
= tmp
;
359 if (lowestPriorityObj
!= NULL
) {
360 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
361 fprintf(stderr
, "fxTMFindOldestObject: %d pri=%f\n", lowestPriorityObj
->Name
, lowestPriority
);
363 return lowestPriorityObj
;
366 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
368 fprintf(stderr
, "fxTMFindOldestObject: %d age=%d\n", obj
->Name
, old
);
376 fxTMAddObj(fxMesaContext fxMesa
,
377 struct gl_texture_object
*tObj
, GLint tmu
, int texmemsize
)
382 startAddr
= fxTMFindStartAddr(fxMesa
, tmu
, texmemsize
);
385 range
= fxTMNewRangeNode(fxMesa
, startAddr
, startAddr
+ texmemsize
);
389 /* External Functions */
392 fxTMMoveInTM_NoLock(fxMesaContext fxMesa
, struct gl_texture_object
*tObj
,
395 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
399 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
400 fprintf(stderr
, "fxTMMoveInTM_NoLock(%d)\n", tObj
->Name
);
403 fxMesa
->stats
.reqTexUpload
++;
405 if (!ti
->validated
) {
406 fprintf(stderr
, "fxTMMoveInTM_NoLock: INTERNAL ERROR: not validated\n");
412 if (ti
->whichTMU
== where
)
414 if (where
== FX_TMU_SPLIT
|| ti
->whichTMU
== FX_TMU_SPLIT
)
415 fxTMMoveOutTM_NoLock(fxMesa
, tObj
);
417 if (ti
->whichTMU
== FX_TMU_BOTH
)
423 if (TDFX_DEBUG
& (VERBOSE_DRIVER
| VERBOSE_TEXTURE
)) {
424 fprintf(stderr
, "fxTMMoveInTM_NoLock: downloading %p (%d) in texture memory in %d\n",
425 (void *)tObj
, tObj
->Name
, where
);
428 ti
->whichTMU
= (FxU32
) where
;
433 texmemsize
= (int)grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH
, &(ti
->info
));
434 ti
->tm
[where
] = fxTMAddObj(fxMesa
, tObj
, where
, texmemsize
);
435 fxMesa
->stats
.memTexUpload
+= texmemsize
;
437 for (i
= FX_largeLodValue(ti
->info
), l
= ti
->minLevel
;
438 i
<= FX_smallLodValue(ti
->info
); i
++, l
++) {
439 struct gl_texture_image
*texImage
= tObj
->Image
[0][l
];
440 grTexDownloadMipMapLevel(where
,
441 ti
->tm
[where
]->startAddr
,
443 FX_largeLodLog2(ti
->info
),
444 FX_aspectRatioLog2(ti
->info
),
446 GR_MIPMAPLEVELMASK_BOTH
,
451 texmemsize
= (int)grTexTextureMemRequired(GR_MIPMAPLEVELMASK_ODD
, &(ti
->info
));
452 ti
->tm
[FX_TMU0
] = fxTMAddObj(fxMesa
, tObj
, FX_TMU0
, texmemsize
);
453 fxMesa
->stats
.memTexUpload
+= texmemsize
;
455 texmemsize
= (int)grTexTextureMemRequired(GR_MIPMAPLEVELMASK_EVEN
, &(ti
->info
));
456 ti
->tm
[FX_TMU1
] = fxTMAddObj(fxMesa
, tObj
, FX_TMU1
, texmemsize
);
457 fxMesa
->stats
.memTexUpload
+= texmemsize
;
459 for (i
= FX_largeLodValue(ti
->info
), l
= ti
->minLevel
;
460 i
<= FX_smallLodValue(ti
->info
); i
++, l
++) {
461 struct gl_texture_image
*texImage
= tObj
->Image
[0][l
];
463 grTexDownloadMipMapLevel(GR_TMU0
,
464 ti
->tm
[FX_TMU0
]->startAddr
,
466 FX_largeLodLog2(ti
->info
),
467 FX_aspectRatioLog2(ti
->info
),
469 GR_MIPMAPLEVELMASK_ODD
,
472 grTexDownloadMipMapLevel(GR_TMU1
,
473 ti
->tm
[FX_TMU1
]->startAddr
,
475 FX_largeLodLog2(ti
->info
),
476 FX_aspectRatioLog2(ti
->info
),
478 GR_MIPMAPLEVELMASK_EVEN
,
483 texmemsize
= (int)grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH
, &(ti
->info
));
484 ti
->tm
[FX_TMU0
] = fxTMAddObj(fxMesa
, tObj
, FX_TMU0
, texmemsize
);
485 fxMesa
->stats
.memTexUpload
+= texmemsize
;
487 /*texmemsize = (int)grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &(ti->info));*/
488 ti
->tm
[FX_TMU1
] = fxTMAddObj(fxMesa
, tObj
, FX_TMU1
, texmemsize
);
489 fxMesa
->stats
.memTexUpload
+= texmemsize
;
491 for (i
= FX_largeLodValue(ti
->info
), l
= ti
->minLevel
;
492 i
<= FX_smallLodValue(ti
->info
); i
++, l
++) {
493 struct gl_texture_image
*texImage
= tObj
->Image
[0][l
];
494 grTexDownloadMipMapLevel(GR_TMU0
,
495 ti
->tm
[FX_TMU0
]->startAddr
,
497 FX_largeLodLog2(ti
->info
),
498 FX_aspectRatioLog2(ti
->info
),
500 GR_MIPMAPLEVELMASK_BOTH
,
503 grTexDownloadMipMapLevel(GR_TMU1
,
504 ti
->tm
[FX_TMU1
]->startAddr
,
506 FX_largeLodLog2(ti
->info
),
507 FX_aspectRatioLog2(ti
->info
),
509 GR_MIPMAPLEVELMASK_BOTH
,
514 fprintf(stderr
, "fxTMMoveInTM_NoLock: INTERNAL ERROR: wrong tmu (%d)\n", where
);
519 fxMesa
->stats
.texUpload
++;
521 ti
->isInTM
= GL_TRUE
;
526 fxTMMoveInTM(fxMesaContext fxMesa
, struct gl_texture_object
*tObj
,
530 fxTMMoveInTM_NoLock(fxMesa
, tObj
, where
);
536 fxTMReloadMipMapLevel(fxMesaContext fxMesa
, struct gl_texture_object
*tObj
,
539 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
542 struct gl_texture_image
*texImage
= tObj
->Image
[0][level
];
543 tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
545 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
546 fprintf(stderr
, "fxTMReloadMipMapLevel(%p (%d), %d)\n", (void *)tObj
, tObj
->Name
, level
);
550 assert(mml
->width
> 0);
551 assert(mml
->height
> 0);
552 assert(mml
->glideFormat
> 0);
555 if (!ti
->validated
) {
556 fprintf(stderr
, "fxTMReloadMipMapLevel: INTERNAL ERROR: not validated\n");
561 tmu
= (int) ti
->whichTMU
;
562 fxMesa
->stats
.reqTexUpload
++;
563 fxMesa
->stats
.texUpload
++;
565 lodlevel
= ti
->info
.largeLodLog2
- (level
- ti
->minLevel
);
570 grTexDownloadMipMapLevel(tmu
,
571 ti
->tm
[tmu
]->startAddr
,
573 FX_largeLodLog2(ti
->info
),
574 FX_aspectRatioLog2(ti
->info
),
576 GR_MIPMAPLEVELMASK_BOTH
, texImage
->Data
);
579 grTexDownloadMipMapLevel(GR_TMU0
,
580 ti
->tm
[GR_TMU0
]->startAddr
,
582 FX_largeLodLog2(ti
->info
),
583 FX_aspectRatioLog2(ti
->info
),
585 GR_MIPMAPLEVELMASK_ODD
, texImage
->Data
);
587 grTexDownloadMipMapLevel(GR_TMU1
,
588 ti
->tm
[GR_TMU1
]->startAddr
,
590 FX_largeLodLog2(ti
->info
),
591 FX_aspectRatioLog2(ti
->info
),
593 GR_MIPMAPLEVELMASK_EVEN
, texImage
->Data
);
596 grTexDownloadMipMapLevel(GR_TMU0
,
597 ti
->tm
[GR_TMU0
]->startAddr
,
599 FX_largeLodLog2(ti
->info
),
600 FX_aspectRatioLog2(ti
->info
),
602 GR_MIPMAPLEVELMASK_BOTH
, texImage
->Data
);
604 grTexDownloadMipMapLevel(GR_TMU1
,
605 ti
->tm
[GR_TMU1
]->startAddr
,
607 FX_largeLodLog2(ti
->info
),
608 FX_aspectRatioLog2(ti
->info
),
610 GR_MIPMAPLEVELMASK_BOTH
, texImage
->Data
);
614 fprintf(stderr
, "fxTMReloadMipMapLevel: INTERNAL ERROR: wrong tmu (%d)\n", tmu
);
621 fxTMReloadSubMipMapLevel(fxMesaContext fxMesa
,
622 struct gl_texture_object
*tObj
,
623 GLint level
, GLint yoffset
, GLint height
)
625 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
627 unsigned short *data
;
629 struct gl_texture_image
*texImage
= tObj
->Image
[0][level
];
630 tfxMipMapLevel
*mml
= FX_MIPMAP_DATA(texImage
);
634 if (!ti
->validated
) {
635 fprintf(stderr
, "fxTMReloadSubMipMapLevel: INTERNAL ERROR: not validated\n");
640 tmu
= (int) ti
->whichTMU
;
641 fxTMMoveInTM(fxMesa
, tObj
, tmu
);
643 fxTexGetInfo(mml
->width
, mml
->height
,
644 &lodlevel
, NULL
, NULL
, NULL
, NULL
, NULL
);
646 if ((ti
->info
.format
== GR_TEXFMT_INTENSITY_8
) ||
647 (ti
->info
.format
== GR_TEXFMT_P_8
) ||
648 (ti
->info
.format
== GR_TEXFMT_ALPHA_8
))
649 data
= (GLushort
*) texImage
->Data
+ ((yoffset
* mml
->width
) >> 1);
651 data
= (GLushort
*) texImage
->Data
+ yoffset
* mml
->width
;
656 grTexDownloadMipMapLevelPartial(tmu
,
657 ti
->tm
[tmu
]->startAddr
,
658 FX_valueToLod(FX_lodToValue(lodlevel
)
660 FX_largeLodLog2(ti
->info
),
661 FX_aspectRatioLog2(ti
->info
),
663 GR_MIPMAPLEVELMASK_BOTH
, data
,
664 yoffset
, yoffset
+ height
- 1);
667 grTexDownloadMipMapLevelPartial(GR_TMU0
,
668 ti
->tm
[FX_TMU0
]->startAddr
,
669 FX_valueToLod(FX_lodToValue(lodlevel
)
671 FX_largeLodLog2(ti
->info
),
672 FX_aspectRatioLog2(ti
->info
),
674 GR_MIPMAPLEVELMASK_ODD
, data
,
675 yoffset
, yoffset
+ height
- 1);
677 grTexDownloadMipMapLevelPartial(GR_TMU1
,
678 ti
->tm
[FX_TMU1
]->startAddr
,
679 FX_valueToLod(FX_lodToValue(lodlevel
)
681 FX_largeLodLog2(ti
->info
),
682 FX_aspectRatioLog2(ti
->info
),
684 GR_MIPMAPLEVELMASK_EVEN
, data
,
685 yoffset
, yoffset
+ height
- 1);
688 grTexDownloadMipMapLevelPartial(GR_TMU0
,
689 ti
->tm
[FX_TMU0
]->startAddr
,
690 FX_valueToLod(FX_lodToValue(lodlevel
)
692 FX_largeLodLog2(ti
->info
),
693 FX_aspectRatioLog2(ti
->info
),
695 GR_MIPMAPLEVELMASK_BOTH
, data
,
696 yoffset
, yoffset
+ height
- 1);
698 grTexDownloadMipMapLevelPartial(GR_TMU1
,
699 ti
->tm
[FX_TMU1
]->startAddr
,
700 FX_valueToLod(FX_lodToValue(lodlevel
)
702 FX_largeLodLog2(ti
->info
),
703 FX_aspectRatioLog2(ti
->info
),
705 GR_MIPMAPLEVELMASK_BOTH
, data
,
706 yoffset
, yoffset
+ height
- 1);
709 fprintf(stderr
, "fxTMReloadSubMipMapLevel: INTERNAL ERROR: wrong tmu (%d)\n", tmu
);
716 fxTMMoveOutTM(fxMesaContext fxMesa
, struct gl_texture_object
*tObj
)
718 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
720 if (TDFX_DEBUG
& VERBOSE_DRIVER
) {
721 fprintf(stderr
, "fxTMMoveOutTM(%p (%d))\n", (void *)tObj
, tObj
->Name
);
727 switch (ti
->whichTMU
) {
730 fxTMRemoveRange(fxMesa
, (int) ti
->whichTMU
, ti
->tm
[ti
->whichTMU
]);
734 fxTMRemoveRange(fxMesa
, FX_TMU0
, ti
->tm
[FX_TMU0
]);
735 fxTMRemoveRange(fxMesa
, FX_TMU1
, ti
->tm
[FX_TMU1
]);
738 fprintf(stderr
, "fxTMMoveOutTM: INTERNAL ERROR: bad TMU (%ld)\n", ti
->whichTMU
);
743 ti
->isInTM
= GL_FALSE
;
744 ti
->whichTMU
= FX_TMU_NONE
;
748 fxTMFreeTexture(fxMesaContext fxMesa
, struct gl_texture_object
*tObj
)
750 tfxTexInfo
*ti
= fxTMGetTexInfo(tObj
);
753 if (TDFX_DEBUG
& VERBOSE_TEXTURE
) {
754 fprintf(stderr
, "fxTMFreeTexture(%p (%d))\n", (void *)tObj
, tObj
->Name
);
757 fxTMMoveOutTM(fxMesa
, tObj
);
759 for (i
= 0; i
< MAX_TEXTURE_LEVELS
; i
++) {
760 struct gl_texture_image
*texImage
= tObj
->Image
[0][i
];
762 if (texImage
->DriverData
) {
763 FREE(texImage
->DriverData
);
764 texImage
->DriverData
= NULL
;
768 switch (ti
->whichTMU
) {
771 fxTMDeleteRangeNode(fxMesa
, ti
->tm
[ti
->whichTMU
]);
775 fxTMDeleteRangeNode(fxMesa
, ti
->tm
[FX_TMU0
]);
776 fxTMDeleteRangeNode(fxMesa
, ti
->tm
[FX_TMU1
]);
782 fxTMInit(fxMesaContext fxMesa
)
784 fxMesa
->texBindNumber
= 0;
787 if (fxMesa
->HaveTexUma
) {
788 grEnable(GR_TEXTURE_UMA_EXT
);
791 fxTMUInit(fxMesa
, FX_TMU0
);
793 if (!fxMesa
->HaveTexUma
&& fxMesa
->haveTwoTMUs
)
794 fxTMUInit(fxMesa
, FX_TMU1
);
796 texBoundMask
= (fxMesa
->type
>= GR_SSTTYPE_Banshee
) ? -1 : (FX_2MB_SPLIT
- 1);
800 fxTMClose(fxMesaContext fxMesa
)
802 MemRange
*tmp
, *next
;
804 tmp
= fxMesa
->tmPool
;
810 tmp
= fxMesa
->tmFree
[FX_TMU0
];
816 if (fxMesa
->haveTwoTMUs
) {
817 tmp
= fxMesa
->tmFree
[FX_TMU1
];
827 fxTMRestoreTextures_NoLock(fxMesaContext ctx
)
830 struct gl_texture_object
*tObj
;
833 tObj
= ctx
->glCtx
->Shared
->TexObjectList
;
835 ti
= fxTMGetTexInfo(tObj
);
836 if (ti
&& ti
->isInTM
) {
837 for (i
= 0; i
< MAX_TEXTURE_UNITS
; i
++)
838 if (ctx
->glCtx
->Texture
.Unit
[i
]._Current
== tObj
) {
839 /* Force the texture onto the board, as it could be in use */
840 where
= ti
->whichTMU
;
841 fxTMMoveOutTM_NoLock(ctx
, tObj
);
842 fxTMMoveInTM_NoLock(ctx
, tObj
, where
);
845 if (i
== MAX_TEXTURE_UNITS
) /* Mark the texture as off the board */
846 fxTMMoveOutTM_NoLock(ctx
, tObj
);
856 * Need this to provide at least one external definition.
859 extern int gl_fx_dummy_function_texman(void);
861 gl_fx_dummy_function_texman(void)