|
|
//========== Copyright � 2005, Valve Corporation, All rights reserved. ========
//
// Purpose:
//
//=============================================================================
#ifndef TEXTUREHEAP_H
#define TEXTUREHEAP_H
// Portal2 Console is not using due to amount of memory free on Xbox and RSX memory on PS3.
// The desired console pattern is to have a similar footprint, because PS3 does not have a streaming solution and it has enough texture memory
// the texture content choices for the consoles will be made to adapt.
// Uncomment to allow system to operate
//#define SUPPORTS_TEXTURE_STREAMING
#if defined( _X360 )
#include "locald3dtypes.h"
#include "utllinkedlist.h"
#include "filesystem.h"
#include "materialsystem/itexture.h"
typedef int TextureCacheHandle_t; #define INVALID_TEXTURECACHE_HANDLE 0
class CTextureHeap { public: CTextureHeap();
IDirect3DTexture *AllocTexture( int width, int height, int levels, DWORD usage, D3DFORMAT format, bool bNoD3DMemory, bool bCacheable ); IDirect3DCubeTexture *AllocCubeTexture( int width, int levels, DWORD usage, D3DFORMAT format, bool bNoD3DMemory ); IDirect3DVolumeTexture *AllocVolumeTexture( int width, int height, int depth, int levels, DWORD usage, D3DFORMAT format ); IDirect3DSurface *AllocRenderTargetSurface( int width, int height, D3DFORMAT format, RTMultiSampleCount360_t multiSampleCount = RT_MULTISAMPLE_NONE, int base = -1 );
// Perform the real d3d allocation, returns true if succesful, false otherwise.
// Only valid for a texture created with no d3d bits, otherwise no-op.
bool FixupAllocD3DMemory( IDirect3DBaseTexture *pTexture );
// Release header and d3d bits.
void FreeTexture( IDirect3DBaseTexture *pTexture );
// Returns the total amount of memory needed or allocated for the entire texture.
int GetSize( IDirect3DBaseTexture *pTexture ); // Returns the amount of memory needed just for the cacheable component.
int GetCacheableSize( IDirect3DBaseTexture *pTexture );
// Crunch the heap.
void Compact();
// Get current backbuffer multisample type
D3DMULTISAMPLE_TYPE GetBackBufferMultiSampleType();
// Query to determine if the texture is managed by cacheing.
bool IsTextureCacheManaged( IDirect3DBaseTexture *pD3DTexture ); bool IsBaseAllocated( IDirect3DBaseTexture *pD3DTexture ); bool IsTextureResident( IDirect3DBaseTexture *pD3DTexture );
// update the lru for a texture. returns false if the high mipmpa is not valid
bool TouchTexture( class CXboxTexture *pXboxTexture ); void SetCacheableTextureParams( IDirect3DBaseTexture *pD3DTexture, const char *pFilename, int mipSkipCount ); void FlushTextureCache(); void SpewTextureCache(); int GetCacheableHeapSize();
private: bool RestoreCacheableTexture( IDirect3DBaseTexture *pD3DTexture );
CUtlFixedLinkedList< IDirect3DBaseTexture* > m_TextureCache; };
#if defined( SUPPORTS_TEXTURE_STREAMING )
#define BASEPOOL1024_SIZE ( 12*1024*1024 ) // 1024x1024 DXT5
#define BASEPOOL512_SIZE ( 12*1024*1024 ) // 1024x1024 DXT1
#define BASEPOOL256_SIZE ( 16*1024*1024 ) // 512x512 DXT5
#define BASEPOOL128_SIZE ( 16*1024*1024 ) // 512x512 DXT1
#define BASEPOOL64_SIZE ( 4*1024*1024 ) // 256x256 DXT5
#define BASEPOOL32_SIZE ( 4*1024*1024 ) // 256x256 DXT1
#else
#define BASEPOOL1024_SIZE 0
#define BASEPOOL512_SIZE 0
#define BASEPOOL256_SIZE 0
#define BASEPOOL128_SIZE 0
#define BASEPOOL64_SIZE 0
#define BASEPOOL32_SIZE 0
#endif
enum TextureAllocator_t { TA_BASEPOOL_1024, // 1024K = 1024x1024 DXT5 Mip0
TA_BASEPOOL_512, // 512K = 1024x1024 DXT1 Mip0
TA_BASEPOOL_256, // 256K = 512x512 DXT5 Mip0
TA_BASEPOOL_128, // 128K = 512x512 DXT1 Mip0
TA_BASEPOOL_64, // 64K = 256x256 DXT5 Mip0
TA_BASEPOOL_32, // 32K = 256x256 DXT1 Mip0
TA_MIXED, TA_STANDARD, TA_MAX };
enum TextureLoadError_t { TEXLOADERROR_NONE = 0, TEXLOADERROR_FILEOPEN = -1, TEXLOADERROR_READING = -2, };
struct THBaseInfo_t { THBaseInfo_t() { m_tcHandle = INVALID_TEXTURECACHE_HANDLE; m_hFilename = NULL; m_hAsyncControl = NULL; m_nFrameCount = 0; m_nBaseSize = 0; m_nMipSize = 0; m_nMipSkipCount = 0; m_bBaseAllocated = false; m_bMipAllocated = false; m_BaseValid = 0; }
TextureAllocator_t m_fAllocator;
// for cacheable tetxures
TextureCacheHandle_t m_tcHandle; FileNameHandle_t m_hFilename; FSAsyncControl_t m_hAsyncControl;
// for age, tracks which frame a texture was touched, fastest GPU non-blocking technique
int m_nFrameCount;
// base and mip are both non-zero for cacheable textures, which require mips
// a non-cacheable texture only has a non-zero base, regardless of its mips
unsigned int m_nBaseSize; unsigned int m_nMipSize;
// used for texture restoration, the top mip
int m_nMipSkipCount;
// tracks when valid for rendering, r/w across threads
CInterlockedInt m_BaseValid;
// tracks when valid for i/o loading
bool m_bBaseAllocated : 1; // tracks when mip is a true seperate allocation, used to resolve offset or pointer
bool m_bMipAllocated : 1; };
//-----------------------------------------------------------------------------
// Get Texture HW bases
//-----------------------------------------------------------------------------
inline void *GetD3DTextureBasePtr( IDirect3DBaseTexture* pTex ) { return (void *)( (unsigned int)pTex->Format.BaseAddress << 12 ); } inline void *GetD3DTextureMipPtr( IDirect3DBaseTexture* pTex ) { // could be an offset or a pointer, state dependant
return (void *)( (unsigned int)pTex->Format.MipAddress << 12 ); }
extern CTextureHeap g_TextureHeap;
struct THInfo_t : public THBaseInfo_t { // Mixed heap info
int nLogicalBytes; int nBytes; bool bFree:1; bool bNonTexture:1;
THInfo_t *pPrev, *pNext; };
class CXboxTexture : public IDirect3DTexture, public THInfo_t { public: CXboxTexture() : bImmobile( false ) { }
bool CanRelocate() { return ( !bImmobile && !IsBusy() ); }
bool bImmobile; };
class CXboxCubeTexture : public IDirect3DCubeTexture, public THBaseInfo_t { };
class CXboxVolumeTexture : public IDirect3DVolumeTexture, public THBaseInfo_t { };
#endif
#endif // TEXTUREHEAP_H
|