Files
Jedi-Academy/codemp/win32/xbox_texture_man.h
2013-04-04 14:32:05 -07:00

256 lines
6.4 KiB
C++

/*
* UNPUBLISHED -- Rights reserved under the copyright laws of the
* United States. Use of a copyright notice is precautionary only and
* does not imply publication or disclosure.
*
* THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION
* OF VICARIOUS VISIONS, INC. ANY DUPLICATION, MODIFICATION,
* DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR
* EXPRESS WRITTEN PERMISSION OF VICARIOUS VISIONS, INC.
*/
#ifndef __XBOX_TEXTURE_MAN_H__
#define __XBOX_TEXTURE_MAN_H__
#include "glw_win_dx8.h"
#include <xtl.h>
// Texture allocator that never frees anything, just grows until it's totally reset:
class StaticTextureAllocator
{
public:
StaticTextureAllocator( void ) { }
void Initialize( unsigned long size )
{
base = (unsigned char *) D3D_AllocContiguousMemory( size, 0 );
allocPoint = 0;
poolSize = size;
maxAlloc = 0;
}
// No bookkeeping necessary, texNum is unused:
void *Allocate( unsigned long size, GLuint texNum )
{
#ifndef FINAL_BUILD
assert( allocPoint + size <= poolSize );
if( allocPoint + size > poolSize )
throw "Static texture pool full";
#endif
// Current location:
void *retVal = base + allocPoint;
// Advance, then round up:
allocPoint += size;
allocPoint = (allocPoint + 127) & ~127;
#ifndef FINAL_BUILD
if( allocPoint > maxAlloc )
maxAlloc = allocPoint;
#endif
return retVal;
}
void Reset( void )
{
// Just move our allocation marker back to the start:
allocPoint = 0;
}
private:
unsigned char *base;
unsigned long allocPoint;
unsigned long poolSize;
unsigned long maxAlloc;
};
class SwappingTextureAllocator
{
private:
struct allocatedTexture_t
{
GLuint texNum; // Index for textureXlat
unsigned char *data; // Pointer to data
};
void _swapAllTexturesToDisk( void )
{
for( int i = 0; i < numTextures; ++i )
{
GLuint texNum = allocatedTextures[i].texNum;
// Get the TextureInfo *
glwstate_t::texturexlat_t::iterator it =
glw_state->textureXlat.find( texNum );
glwstate_t::TextureInfo *info = &it->second;
//If texture has already been written out, don't write it again.
if(info->fileOffset != -1) {
info->inMemory = false;
continue;
}
// Stall until the GPU is done with it:
info->mipmap->BlockUntilNotBusy();
//File pointer may have been moved by a read. Set it to the
//proper position.
if(SetFilePointer(fileHandle, fileOffset, NULL, FILE_BEGIN) ==
INVALID_SET_FILE_POINTER) {
throw "Couldn't seek end of file";
}
// Write the old texture out to disk:
DWORD bytesWritten = 0;
if( !WriteFile( fileHandle, allocatedTextures[i].data,
info->size, &bytesWritten, NULL ) ||
(bytesWritten != info->size) )
throw "Couldn't write file";
// Mark texture as not in memory anymore:
info->inMemory = false;
//Set file offset so we can find the texture later.
info->fileOffset = fileOffset;
//Increment for the next file.
fileOffset += info->size;
}
ResetMemory();
}
void ResetMemory( void )
{
allocPoint = 0;
numTextures = 0;
}
public:
SwappingTextureAllocator( void ) { }
void Initialize( unsigned long size )
{
base = (unsigned char *) D3D_AllocContiguousMemory( size, 0 );
poolSize = size;
fileHandle = INVALID_HANDLE_VALUE;
Reset();
}
// Allocate enough space for size - it's used for texture texNum:
void *Allocate( unsigned long size, GLuint texNum )
{
// Check for fullness - make room
if( allocPoint + size > poolSize )
{
Com_Printf( "Swapping all model textures to disk!\n" );
_swapAllTexturesToDisk();
}
// Current location:
void *retVal = base + allocPoint;
// Advance, then round up:
allocPoint += size;
allocPoint = (allocPoint + 127) & ~127;
// Make a note of this texture:
allocatedTextures[numTextures].data = (unsigned char *) retVal;
allocatedTextures[numTextures].texNum = texNum;
++numTextures;
return retVal;
}
// This should only be called when it's already been determined that the
// requested texture isn't in memory. This makes room (if necessary)
// and then re-loads it, fixing up the TextureInfo that goes with it
void Fetch( GLuint texNum )
{
glwstate_t::texturexlat_t::iterator i =
glw_state->textureXlat.find( texNum );
glwstate_t::TextureInfo *info = &i->second;
unsigned char *newData = (unsigned char *) Allocate( info->size, texNum );
//Seek to proper file position.
if(SetFilePointer(fileHandle, info->fileOffset, NULL, FILE_BEGIN) ==
INVALID_SET_FILE_POINTER) {
throw "Couldn't seek for reading";
}
// Find the data that goes with this texture on disk:
DWORD bytesRead = 0;
if( !ReadFile( fileHandle, newData, info->size, &bytesRead, NULL ) ||
(bytesRead != info->size) )
throw "Couldn't read file";
// I'm getting errors with locked textures here. How!? Try to make it work,
// figure out what the fuck is wrong later: VVFIXME
if( info->mipmap->IsBusy() )
info->mipmap->BlockUntilNotBusy();
// Fix up the texture data and other info:
info->mipmap->Data = 0;
info->mipmap->Register( newData );
info->inMemory = true;
}
void Reset( void )
{
ResetMemory();
if(fileHandle != INVALID_HANDLE_VALUE) {
CloseHandle(fileHandle);
}
fileHandle = CreateFile( "z:\\skintextures",
GENERIC_WRITE | GENERIC_READ, 0,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if( fileHandle == INVALID_HANDLE_VALUE )
throw "Couldn't create texture swap file";
fileOffset = 0;
}
// This forces all textures in memory to disk, so that the next frame or
// so will re-load whatever's needed. It's only useful in situations where
// you know that you're going to cache-miss on a bunch of textures, then
// run out of space, and have to re-load them again. (Good when going in
// and out of the in-game UI) ?
void Flush( void )
{
_swapAllTexturesToDisk();
}
// Just a little helper for the memory manager to see how much of the pool is used:
unsigned long Size( void )
{
return allocPoint;
}
private:
unsigned char *base;
unsigned long poolSize;
unsigned long allocPoint;
unsigned long fileOffset;
HANDLE fileHandle;
allocatedTexture_t allocatedTextures[4096];
int numTextures;
};
// Global texture allocators:
extern StaticTextureAllocator gStaticTextures;
extern SwappingTextureAllocator gSkinTextures;
extern void BeginSkinTextures( void );
extern void EndSkinTextures( void );
#endif