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

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