Main Page | Alphabetical List | Compound List | File List | Compound Members | File Members

D3dcache.cpp

Go to the documentation of this file.
00001 /****************************************************************************************/
00002 /*  D3DCache.cpp                                                                        */
00003 /*                                                                                      */
00004 /*  Author: John Pollard                                                                */
00005 /*  Description: D3D cache manager                                                      */
00006 /*                                                                                      */
00007 /*  The contents of this file are subject to the Genesis3D Public License               */
00008 /*  Version 1.01 (the "License"); you may not use this file except in                   */
00009 /*  compliance with the License. You may obtain a copy of the License at                */
00010 /*  http://www.genesis3d.com                                                            */
00011 /*                                                                                      */
00012 /*  Software distributed under the License is distributed on an "AS IS"                 */
00013 /*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See                */
00014 /*  the License for the specific language governing rights and limitations              */
00015 /*  under the License.                                                                  */
00016 /*                                                                                      */
00017 /*  The Original Code is Genesis3D, released March 25, 1999.                            */
00018 /*  Genesis3D Version 1.1 released November 15, 1999                                    */
00019 /*  Copyright (C) 1999 WildTangent, Inc. All Rights Reserved                            */
00020 /*                                                                                      */
00021 /****************************************************************************************/
00022 #include <Windows.h>
00023 #include <Stdio.h>
00024 #include <DDraw.h>
00025 #include <D3D.h>
00026 
00027 #include "D3DCache.h"
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 // Cache types are just the different types of textures
00037 // Texutres may vary from width/height/num miplevels/etc...
00038 // Cache types is just a way to combine them to similar types...
00039 #define D3DCACHE_MAX_CACHE_TYPES                128             
00040 
00041 //========================================================================================================
00042 //========================================================================================================
00043 typedef struct D3DCache_Type
00044 {
00045         int32                                   Log;
00046         int32                                   Width;                                          // Width/Height
00047         int32                                   Height;
00048         int32                                   NumMipLevels;
00049         int32                                   Stage;
00050         int32                                   RefCount;                                       // How many references to this cache_type
00051 
00052         DDSURFACEDESC2                  ddsd;                                           // DD surface description
00053 
00054         D3DCache_Slot                   *Slots;                                         // Cache slots for this Cache type
00055         int32                                   NumUsedSlots;                           // Number of slots being used
00056 
00057         D3DCache_Type                   *SelfCheck;
00058         D3DCache                                *Cache;
00059 } D3DCache_Type;
00060 
00061 typedef struct D3DCache
00062 {
00063         struct D3DCache                 *SelfCheck;
00064 
00065         char                                    Name[D3DCACHE_MAX_NAME];
00066 
00067         LPDIRECTDRAW4                   lpDD;                                           // DD object for the cache manager
00068 
00069         DDMemMgr_Partition              *Partition;
00070 
00071         geBoolean                               UseStages;
00072 
00073         D3DCache_Type                   CacheTypes[D3DCACHE_MAX_CACHE_TYPES];   // CacheTypes
00074 } D3DCache;
00075 
00076 typedef struct D3DCache_Slot
00077 {
00078         struct D3DCache_Slot    *SelfCheck;
00079 
00080         D3DCache_Type                   *CacheType;
00081 
00082         LPDIRECTDRAWSURFACE4    Surface;                                                // The DD surface for this slot
00083         LPDIRECT3DTEXTURE2              Texture;                                                // The texture interface to the surface
00084 
00085         uint32                                  LRU;                                                    // Current LRU for cache slot
00086                                                 
00087         void                                    *UserData;
00088 
00089 } D3DCache_Slot;
00090 
00091 //========================================================================================================
00092 //========================================================================================================
00093 
00094 //========================================================================================================
00095 //      D3DCache_Create
00096 //========================================================================================================
00097 D3DCache *D3DCache_Create(const char *Name, LPDIRECTDRAW4 lpDD, DDMemMgr_Partition *Partition, geBoolean UseStages)
00098 {
00099         D3DCache                *Cache;
00100 
00101         Cache = (D3DCache*)malloc(sizeof(D3DCache));
00102 
00103         if (!Cache)
00104                 return NULL;
00105 
00106         memset(Cache, 0, sizeof(D3DCache));
00107 
00108         Cache->lpDD = lpDD;
00109 
00110         Cache->Partition = Partition;
00111 
00112         Cache->UseStages = UseStages;
00113 
00114         Cache->SelfCheck = Cache;
00115 
00116         strcpy(Cache->Name, Name);
00117 
00118         return Cache;
00119 }
00120 
00121 //========================================================================================================
00122 //      D3DCache_Destroy
00123 //========================================================================================================
00124 void D3DCache_Destroy(D3DCache *Cache)
00125 {
00126         D3DCache_FreeAllSlots(Cache);
00127 
00128         free(Cache);
00129 }
00130 
00131 //========================================================================================================
00132 //      D3DCache_IsValid
00133 //========================================================================================================
00134 geBoolean D3DCache_IsValid(D3DCache *Cache)
00135 {
00136         if (!Cache)
00137                 return GE_FALSE;
00138 
00139         if (Cache->SelfCheck != Cache)
00140                 return GE_FALSE;
00141 
00142         return GE_TRUE;
00143 }
00144 
00145 //========================================================================================================
00146 //========================================================================================================
00147 geBoolean D3DCache_EvictAllSurfaces(D3DCache *Cache)
00148 {
00149         int32                   i;
00150         D3DCache_Type   *pCacheType;
00151 
00152 
00153         for (pCacheType = Cache->CacheTypes, i=0; i< D3DCACHE_MAX_CACHE_TYPES; i++, pCacheType++)
00154         {
00155                 D3DCache_Slot           *pSlot;
00156                 int32                           s;
00157 
00158                 if (!pCacheType->RefCount)
00159                         continue;
00160 
00161                 for (pSlot = pCacheType->Slots, s=0; s<pCacheType->NumUsedSlots; s++, pSlot++)
00162                 {
00163                         D3DCache_SlotSetUserData(pSlot, NULL);
00164                 }
00165         }
00166         
00167         return GE_TRUE;
00168 }
00169 
00170 //========================================================================================================
00171 //========================================================================================================
00172 D3DCache_Type *D3DCache_FindCacheType(D3DCache *Cache, int32 Width, int32 Height, int32 NumMipLevels, int32 Stage, const DDSURFACEDESC2 *ddsd)
00173 {
00174         int32                   i;
00175         D3DCache_Type   *pCacheType;
00176 
00177 
00178         pCacheType = Cache->CacheTypes;
00179 
00180         for (i=0; i<D3DCACHE_MAX_CACHE_TYPES; i++, pCacheType++)
00181         {
00182                 if (pCacheType->RefCount == 0)                  // Nobody is using this slot yet
00183                         continue;
00184 
00185                 if (pCacheType->Width != Width)
00186                         continue;
00187                 if (pCacheType->Height != Height)
00188                         continue;
00189 
00190                 if (pCacheType->NumMipLevels != NumMipLevels)
00191                         continue;
00192 
00193                 if (pCacheType->Stage != Stage)
00194                         continue;
00195 
00196                 if (memcmp(&pCacheType->ddsd, ddsd, sizeof(DDSURFACEDESC2)))
00197                         continue;
00198                 
00199                 return pCacheType;                                              // Found a match
00200         }
00201 
00202         return NULL;                                                            // Cache Type not found!!!
00203 }
00204 
00205 //========================================================================================================
00206 //========================================================================================================
00207 D3DCache_Type *D3DCache_InsertCacheType(D3DCache *Cache, int32 Width, int32 Height, int32 NumMipLevels, int32 Stage, const DDSURFACEDESC2 *ddsd)
00208 {
00209         int32                   i;
00210         D3DCache_Type   *pCacheType;
00211 
00212 
00213         pCacheType = Cache->CacheTypes;
00214 
00215         for (i=0; i<D3DCACHE_MAX_CACHE_TYPES; i++, pCacheType++)
00216         {
00217                 if (pCacheType->RefCount == 0)                  // Nobody is using this slot yet
00218                         break;
00219         }
00220 
00221         if (i == D3DCACHE_MAX_CACHE_TYPES)                      // No types left
00222                 return NULL;
00223 
00224         pCacheType->Width = Width;
00225         pCacheType->Height = Height;
00226         pCacheType->NumMipLevels = NumMipLevels;
00227         pCacheType->Stage = Stage;
00228         pCacheType->ddsd = *ddsd;
00229 
00230         pCacheType->SelfCheck = pCacheType;
00231         pCacheType->Cache = Cache;
00232 
00233         pCacheType->Log = GetLog(Width, Height);
00234 
00235         // Found one
00236         pCacheType->RefCount++;
00237 
00238         return pCacheType;
00239 }
00240 
00241 //========================================================================================================
00242 //========================================================================================================
00243 D3DCache_Type *D3DCache_TypeCreate(D3DCache *Cache, int32 Width, int32 Height, int32 NumMipLevels, int32 Stage, const DDSURFACEDESC2 *ddsd)
00244 {
00245         D3DCache_Type           *CacheType;
00246 
00247 
00248         CacheType = D3DCache_FindCacheType(Cache, Width, Height, NumMipLevels, Stage, ddsd);
00249 
00250         if (CacheType)
00251         {
00252                 CacheType->RefCount++;
00253                 return CacheType;
00254         }
00255 
00256         // Could not find one allready in the list, so add a new one...
00257         return D3DCache_InsertCacheType(Cache, Width, Height, NumMipLevels, Stage, ddsd);
00258 }
00259 
00260 //========================================================================================================
00261 //      D3DCache_TypeDestroy
00262 //========================================================================================================
00263 void D3DCache_TypeDestroy(D3DCache_Type *CacheType)
00264 {
00265         CacheType->RefCount--;
00266 
00267         if (CacheType->RefCount == 0)
00268         {
00269                 if (CacheType->Slots)
00270                 {
00271                         D3DCache_Slot   *pSlot;
00272                         int32                   k;
00273 
00274                         // Go through each slot, and free all the surfaces on them
00275                         for (pSlot = CacheType->Slots, k=0; k< CacheType->NumUsedSlots; k++, pSlot++)
00276                         {
00277                                 if (pSlot->Texture)
00278                                         pSlot->Texture->Release();
00279                                 if (pSlot->Surface)
00280                                         pSlot->Surface->Release();
00281                         }
00282 
00283                         free(CacheType->Slots);
00284                         CacheType->Slots = NULL;
00285                         CacheType->NumUsedSlots = 0;
00286                 }
00287         }
00288 }
00289 
00290 //========================================================================================================
00291 //      D3DCache_TypeIsValid
00292 //========================================================================================================
00293 geBoolean D3DCache_TypeIsValid(D3DCache_Type *Type)
00294 {
00295         if (!Type)
00296                 return GE_FALSE;
00297 
00298         if (Type->SelfCheck != Type)
00299                 return GE_FALSE;
00300 
00301         if (!D3DCache_IsValid(Type->Cache))
00302                 return GE_FALSE;
00303 
00304         return GE_TRUE;
00305 }
00306 
00307 //========================================================================================================
00308 //      D3DCache_FreeAllSlots
00309 //========================================================================================================
00310 geBoolean D3DCache_FreeAllSlots(D3DCache *Cache)
00311 {
00312         int32                   i;
00313         D3DCache_Type   *pCacheType;
00314 
00315 
00316         pCacheType = Cache->CacheTypes;
00317 
00318         for (i=0; i< D3DCACHE_MAX_CACHE_TYPES; i++, pCacheType++)
00319         {
00320                 D3DCache_Slot   *pSlot;
00321                 int32                   k;
00322 
00323                 if (pCacheType->RefCount == 0)
00324                         continue;
00325 
00326                 // Go through each slot, and free all the surfaces on them
00327                 for (pSlot = pCacheType->Slots, k=0; k< pCacheType->NumUsedSlots; k++, pSlot++)
00328                 {
00329                         if (pSlot->Texture)
00330                                 pSlot->Texture->Release();
00331                         if (pSlot->Surface)
00332                                 pSlot->Surface->Release();
00333                 }
00334 
00335                 if (pCacheType->Slots)
00336                         free(pCacheType->Slots);
00337 
00338                 pCacheType->Slots = NULL;
00339                 pCacheType->NumUsedSlots = 0;
00340         }
00341 
00342         DDMemMgr_PartitionReset(Cache->Partition);                      // Reset the caches memory manager
00343 
00344         return GE_TRUE;
00345 }
00346 
00347 //========================================================================================================
00348 //      D3DCache_WriteToFile
00349 //========================================================================================================
00350 geBoolean D3DCache_WriteToFile(D3DCache *Cache, const char *FileName, geBoolean Append)
00351 {
00352         int32                   i;
00353         D3DCache_Type   *pCacheType;
00354         int32                   TotalRef, TotalUsed;
00355         SYSTEMTIME              Time;
00356         FILE                    *f;
00357 
00358         if (Append)
00359                 f = fopen(FileName, "a+t");
00360         else
00361                 f = fopen(FileName, "w");
00362 
00363         if (!f)
00364                 return GE_FALSE;
00365 
00366         GetSystemTime(&Time);
00367 
00368         fprintf(f, "=======================================================\n");
00369         fprintf(f, "Date: %i/%i/%i, Time: %i:%i\n", Time.wMonth, Time.wDay, Time.wYear, Time.wHour, Time.wMinute);
00370         fprintf(f, "Cache Name: %s\n", Cache->Name);
00371         fprintf(f, "Total Mem: %5i\n", DDMemMgr_PartitionGetTotalMem(Cache->Partition));
00372         fprintf(f, "Free Mem: %5i\n", DDMemMgr_PartitionGetFreeMem(Cache->Partition));
00373         fprintf(f, " --- Slots ---\n");
00374 
00375         TotalRef = TotalUsed = 0;
00376 
00377         pCacheType = Cache->CacheTypes;
00378 
00379         for (i=0; i< D3DCACHE_MAX_CACHE_TYPES; i++, pCacheType++)
00380         {
00381                 if (!pCacheType->RefCount)
00382                         continue;
00383 
00384                 fprintf(f, "Width: %3i, Height %3i, Mips: %2i, Stage: %2i, Ref: %4i, Used: %4i\n",
00385                         pCacheType->Width, pCacheType->Height, pCacheType->NumMipLevels, pCacheType->Stage, pCacheType->RefCount, pCacheType->NumUsedSlots);
00386 
00387                 TotalRef += pCacheType->RefCount;
00388                 TotalUsed += pCacheType->NumUsedSlots;
00389         }
00390 
00391         fprintf(f, "Total Ref: %4i, Total Used: %4i\n", TotalRef, TotalUsed);
00392 
00393         fclose(f);
00394 
00395         return GE_TRUE;
00396 }
00397 
00398 static geBoolean                AppendHack = GE_FALSE;
00399 
00400 // HACK!!!!
00401 void                            D3DMain_Log(LPSTR Str, ... );
00402 //========================================================================================================
00403 //      D3DCache_AdjustSlots
00404 //========================================================================================================
00405 geBoolean D3DCache_AdjustSlots(D3DCache *Cache, const int32 *MaxTable, geBoolean UsePartition)
00406 {
00407         D3DCache_Type   *pCacheType;
00408         int32                   i, Total, NumPasses;
00409         D3DCache_FreeAllSlots(Cache);                                                   // Just get rid of everything for now...
00410         DDMemMgr_PartitionReset(Cache->Partition);                              // Reset the caches memory manager
00411         Total = 0;
00412         NumPasses = 0;
00413 
00414         while(1)
00415         {
00416                 D3DCache_Slot           *LastSlot;
00417 
00418                 LastSlot = NULL;
00419 
00420                 pCacheType = Cache->CacheTypes;
00421 
00422                 for (i=0; i< D3DCACHE_MAX_CACHE_TYPES; i++, pCacheType++)
00423                 {
00424                         D3DCache_Slot   *pSlot;
00425                         uint32                  Size, Width, Height, Result;
00426 
00427                         if (pCacheType->RefCount <= 0)
00428                                 continue;
00429 
00430                         if (pCacheType->NumUsedSlots >= pCacheType->RefCount)
00431                                 continue;                                       // This is all we need for this slot...
00432 
00433                         if (pCacheType->NumUsedSlots >= MaxTable[pCacheType->Log])
00434                                 continue;
00435 
00436                         if (!pCacheType->Slots)                 // If no slots have been allocated, allocate them now...
00437                         {
00438                                 pCacheType->Slots = (D3DCache_Slot*)malloc(sizeof(D3DCache_Type)*pCacheType->RefCount);
00439                                 memset(pCacheType->Slots, 0, sizeof(D3DCache_Type)*pCacheType->RefCount);
00440                         }
00441 
00442                         Width = pCacheType->Width;
00443                         Height = pCacheType->Height;
00444 
00445                         Size = Width*Height*(pCacheType->ddsd.ddpfPixelFormat.dwRGBBitCount>>3);  // (BitCount/8)
00446                 
00447                         if (UsePartition)
00448                         {
00449                                 if (!DDMemMgr_PartitionAllocMem(Cache->Partition, Size))
00450                                 {
00451                                         LastSlot = NULL;        // Make a complete stop
00452                                         break;                          // No more memory in the partition, stop now...
00453                                 }
00454                         }
00455 
00456                         pSlot = &pCacheType->Slots[pCacheType->NumUsedSlots];
00457                         pSlot->SelfCheck = pSlot;
00458 
00459                         pSlot->CacheType = pCacheType;
00460 
00461                         // Allocate surfaces now
00462                         Result = D3DCache_SetupSlot(Cache, pSlot, Width, Height, &pCacheType->ddsd, Cache->UseStages, pCacheType->Stage);
00463 
00464                         if (!Result)
00465                         {
00466                                 memset(pSlot, 0, sizeof(D3DCache_Slot));
00467                                 break;
00468                         }
00469                         else if (Result == -1)
00470                         {
00471                                 D3DMain_Log("D3DCache_AdjustSlots:  D3DCache_SetupSlot failed.\n");
00472                                 return GE_FALSE;
00473                         }
00474 
00475                         pCacheType->NumUsedSlots++;
00476                         Total++;
00477 
00478                         LastSlot = pSlot;
00479                 }
00480 
00481                 NumPasses++;
00482 
00483                 if (!LastSlot)          // Nothing was allocated on that pass, so assume we are out of memory
00484                         break;
00485         }
00486 
00487         pCacheType = Cache->CacheTypes;
00488         
00489         // Go through one last time, and make sure all got allocated
00490         for (i=0; i< D3DCACHE_MAX_CACHE_TYPES; i++, pCacheType++)
00491         {
00492                 if (pCacheType->RefCount <= 0)
00493                         continue;
00494 
00495                 if (pCacheType->NumUsedSlots <= 0)              
00496                 {
00497                         D3DMain_Log("D3DCache_AdjustSlots:  Out of ram creating surfaces for cache.\n");
00498                         D3DMain_Log("D3DCache_AdjustSlots:  Pick a display mode with a smaller resolution.\n");
00499                         return GE_FALSE;                        // Not all slots with refs got a texture
00500                 }
00501         }
00502 
00503         D3DCache_WriteToFile(Cache, "D3DCache.Log", AppendHack);
00504         AppendHack = GE_TRUE;
00505 
00506         return GE_TRUE;
00507 }
00508 
00509 //========================================================================================================
00510 //      D3DCache_SlotIsValid
00511 //========================================================================================================
00512 geBoolean D3DCache_SlotIsValid(D3DCache_Slot *Slot)
00513 {
00514         if (!Slot)
00515                 return GE_FALSE;
00516 
00517         if (Slot->SelfCheck != Slot)
00518                 return GE_FALSE;
00519 
00520         return GE_TRUE;
00521 }
00522 
00523 //=====================================================================================
00524 //      D3DCache_SetupSlot
00525 //
00526 //      Returns -1 on failure
00527 //      Returns 0 on out of memory
00528 //      Returns 1 on success
00529 //=====================================================================================
00530 int32 D3DCache_SetupSlot(D3DCache *Cache, D3DCache_Slot *Slot, int32 Width, int32 Height, const DDSURFACEDESC2 *SurfDesc, geBoolean UseStage, int32 Stage)
00531 {
00532         LPDIRECTDRAWSURFACE4 Surface;
00533         DDSURFACEDESC2          ddsd;
00534         HRESULT                         Hr;
00535                         
00536         memcpy(&ddsd, SurfDesc, sizeof(DDSURFACEDESC2));
00537 
00538         ddsd.dwSize = sizeof(DDSURFACEDESC2);
00539         ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
00540 
00541         if (UseStage)
00542                 ddsd.dwFlags |= DDSD_TEXTURESTAGE;
00543 
00544         ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
00545         ddsd.ddsCaps.dwCaps2 = DDSCAPS2_HINTDYNAMIC;
00546         ddsd.ddsCaps.dwCaps3 = 0;
00547         ddsd.ddsCaps.dwCaps4 = 0;
00548         ddsd.dwHeight = Width;
00549         ddsd.dwWidth = Height;
00550         ddsd.dwTextureStage = Stage;
00551         
00552         Hr = Cache->lpDD->CreateSurface(&ddsd, &Surface, NULL);
00553 
00554         if(Hr != DD_OK) 
00555         { 
00556                 if (Hr == DDERR_OUTOFVIDEOMEMORY)
00557                 {
00558                         return 0;
00559                 }
00560 
00561                 return -1;
00562         }
00563 
00564         Slot->Surface = Surface;
00565 
00566 
00567         Hr = Surface->QueryInterface(IID_IDirect3DTexture2, (void**)&Slot->Texture);  
00568 
00569         if(Hr != DD_OK) 
00570         { 
00571                 Surface->Release();
00572                 return -1;
00573         }
00574 
00575         return 1;               // All good dude
00576 }
00577 
00578 
00579 //========================================================================================================
00580 //      D3DCache_TypeFindSlot
00581 //========================================================================================================
00582 D3DCache_Slot *D3DCache_TypeFindSlot(D3DCache_Type *CacheType)
00583 {
00584         D3DCache_Slot   *pBestSlot, *pSlot;
00585         uint32                  BestLRU;
00586         int32                   i;
00587 
00588         pSlot = CacheType->Slots;
00589         pBestSlot = pSlot;
00590         BestLRU = pBestSlot->LRU;
00591 
00592         for (i=0; i< CacheType->NumUsedSlots; i++, pSlot++)
00593         {
00594                 if (pSlot->LRU < BestLRU)
00595                 {
00596                         pBestSlot = pSlot;
00597                         BestLRU = pSlot->LRU;
00598                 }
00599         }
00600 
00601         pBestSlot->LRU = 0;
00602         pBestSlot->UserData = NULL;
00603 
00604         return pBestSlot;
00605 }
00606 
00607 //========================================================================================================
00608 //      D3DCache_SlotSetUserData
00609 //========================================================================================================
00610 void D3DCache_SlotSetUserData(D3DCache_Slot *Slot, void *UserData)
00611 {
00612         Slot->UserData = UserData;
00613 }
00614 
00615 //========================================================================================================
00616 //      D3DCache_SlotGetUserData
00617 //========================================================================================================
00618 void *D3DCache_SlotGetUserData(D3DCache_Slot *Slot)
00619 {
00620         return Slot->UserData;
00621 }
00622 
00623 //========================================================================================================
00624 //      D3DCache_SlotSetLRU
00625 //========================================================================================================
00626 void D3DCache_SlotSetLRU(D3DCache_Slot *Slot, uint32 LRU)
00627 {
00628         Slot->LRU = LRU;
00629 }
00630 
00631 //========================================================================================================
00632 //      D3DCache_SlotGetLRU
00633 //========================================================================================================
00634 uint32 D3DCache_SlotGetLRU(D3DCache_Slot *Slot)
00635 {
00636         return Slot->LRU;
00637 }
00638 
00639 LPDIRECT3DTEXTURE2 D3DCache_SlotGetTexture(D3DCache_Slot *Slot)
00640 {
00641         return Slot->Texture;
00642 }
00643 
00644 LPDIRECTDRAWSURFACE4 D3DCache_SlotGetSurface(D3DCache_Slot *Slot)
00645 {
00646         return Slot->Surface;
00647 }
00648 
00649 //=====================================================================================
00650 //      Log2
00651 //      Return the log of a size
00652 //=====================================================================================
00653 uint32 Log2(uint32 P2)
00654 {
00655         uint32          p = 0;
00656         int32           i = 0;
00657         
00658         for (i = P2; i > 0; i>>=1)
00659                 p++;
00660 
00661         return (p-1);
00662 }
00663 
00664 //=====================================================================================
00665 //      SnapToPower2
00666 //      Snaps a number to a power of 2
00667 //=====================================================================================
00668 int32 SnapToPower2(int32 Width)
00669 {
00670         if (Width > 0 && Width <= 1) Width = 1;
00671         else if (Width > 1 && Width <= 2) Width = 2;
00672         else if (Width > 2 && Width <= 4) Width = 4;
00673         else if (Width > 4 && Width <= 8) Width = 8;
00674         else if (Width > 8 && Width <= 16) Width =16;
00675         else if (Width > 16 && Width <= 32) Width = 32;
00676         else if (Width > 32 && Width <= 64) Width = 64;
00677         else if (Width > 64 && Width <= 128) Width = 128;
00678         else if (Width > 128 && Width <= 256) Width = 256;
00679         else 
00680                 return -1;
00681 
00682         return Width;
00683 }
00684 
00685 //=====================================================================================
00686 //      Return the max log of a (power of 2) width and height
00687 //=====================================================================================
00688 int32 GetLog(int32 Width, int32 Height)
00689 {
00690         int32   LWidth = SnapToPower2(max(Width, Height));
00691         
00692         return Log2(LWidth);
00693 }
00694 

Generated on Tue Sep 30 12:35:33 2003 for GTestAndEngine by doxygen 1.3.2