Figure Managing Texture Memory.2 The size of a mipmap depends on the setting of the evenOdd flag.
Suppose we have a GrTexInfo structure with data as shown below.
The size returned by grTexTextureMemRequired() depends on the value of the evenOdd flag, as shown below.
LOD
|
width
|
height
|
number of bytes
|
GR_LOD_128
|
128
|
64
|
213 = 8192 bytes
|
GR_LOD_64
|
64
|
32
|
211 = 2048 bytes
|
GR_LOD_32
|
32
|
16
|
29 = 512 bytes
|
GR_LOD_16
|
16
|
8
|
27 = 128 bytes
|
GR_LOD_8
|
8
|
4
|
25 = 32 bytes
|
ò grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, info) returns the sum of the sizes of all 5 LODs.
8192 + 2048 + 512 + 128 + 32 = 10,912 bytes
ò grTexTextureMemRequired(GR_MIPMAPLEVELMASK_ODD, info) returns the sum of the sizes of the odd LODs: GR_LOD_128, GR_LOD_32, and GR_LOD_8.
8192 + 512 + 32 = 8,736 bytes
ò grTexTextureMemRequired(GR_MIPMAPLEVELMASK_EVEN, info) returns the sum of the sizes of the even LODs: GR_LOD_64 and GR_LOD_16.
2048 + 128 = 2,176 bytes
Two Glide functions, grTexMinAddress() and grTexMaxAddress() provide initial upper and lower bounds on texture memory for the specified TMU. They each have one argument, tmu, which selects the TMU on which to check the memory bounds.
FxU32 grTexMinAddress( GrChipID_t tmu )
FxU32 grTexMaxAddress( GrChipID_t tmu )
grTexMinAddress() and grTexMaxAddress() provide initial values for free space pointers in a Glide application. Be aware, however, that they always return the same values, regardless of whether any textures have been downloaded.
grTexMinAddress() returns the first location in texture memory into which a texture can be loaded.
grTexMaxAddress() returns the last possible 8-byte aligned address that can be used as a starting address; only the smallest possible texture can be loaded there: the 1×1 texture GR_LOD_1.
Texture memory management can be simple, sophisticated, or somewhere in between, depending on size and number of textures that will be loaded. The examples below show some straightforward techniques.
One important restriction must be mentioned: a mipmap level cannot straddle the 2Mbyte boundary in texture memory. That is, the addresses of the first and last words in the level must either both be greater or both be less than than 2 Mbytes (221). One simple way to work around this limitation is to load complete mipmaps on one side or the other, depending on the fit, as shown in Example Managing Texture Memory.2.
Example Managing Texture Memory.1 Will the mipmap fit?
This code segment illustrates a simple scenario where a single mipmap will be loaded into an empty texture memory on TMU0. Since this is the only texture that will ever be loaded, there is no need to implement a free list.
FxU32 textureSize, startAddress;
textureSize = grTexCalcMemRequired( GR_LOD_1, GR_LOD256, GR_ASPECT_1x1,
GR_TEXFMT_ARGB_1555 );
startAddress = grTexMinAddress(GR_TMU0);
if (startAddress + textureSize <= grTexMaxAddress(GR_TMU0))
download_the_texture;
Example Managing Texture Memory.2 Setting up to load several mipmaps.
This code segment gets a little more real than the one above by keeping a pointer to the next available starting address for mipmaps. To get a starting address for a texture, call the subroutine.
#define TEXMEM_2MB_EDGE 2097152
FxU32 textureSize, nextTexture, lastTexture;
/* these two lines initialize the bounds and should be part */
/* of the initialization code in the main program */
nextTexture = grTexMinAddress(GR_TMU0);
lastTexture = grTexMaxAddress(GR_TMU0)
long getStartAddress(FxU32 evenOdd, GrTexInfo *info)
{ long start;
textureSize = grTexTextureMemRequired(evenOdd, info);
start = nextTexture;
/* check for 2MB edge and space past it if necessary */
if ((start< TEXMEM_2MB_EDGE) && (start+textureSize> TEXMEM_2MB_EDGE))
start = TEXMEM_2MB_EDGE
nextTexture += textureSize;
if (nextTexture <= lastTexture) return start;
else {
nextTexture = start;
return -1;
}
}
Share with your friends: |