Generating texture names on startup
This commit is contained in:
parent
717a5bd03c
commit
3b6147c73f
|
@ -16,7 +16,9 @@
|
||||||
TexDB::Record* TexDB::Record::s_FreeRecords = NULL;
|
TexDB::Record* TexDB::Record::s_FreeRecords = NULL;
|
||||||
TexDB::RecordArray* TexDB::Record::s_RecordArrays = NULL;
|
TexDB::RecordArray* TexDB::Record::s_RecordArrays = NULL;
|
||||||
TexDB::SubRecord* TexDB::SubRecord::s_FreeSubRecords = NULL;
|
TexDB::SubRecord* TexDB::SubRecord::s_FreeSubRecords = NULL;
|
||||||
|
TexDB::SubRecordArray* TexDB::SubRecord::s_SubRecordArrays = NULL;
|
||||||
int TexDB::RecordArraySize = 16;
|
int TexDB::RecordArraySize = 16;
|
||||||
|
int TexDB::textureNamesCount = 1;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// Construction/Destruction
|
// Construction/Destruction
|
||||||
|
@ -36,20 +38,34 @@ TexDB::TexDB(unsigned int MemorySize)
|
||||||
m_texmem_2_record = static_cast<Record**>(AllocBuffer(MemorySize >> 3, sizeof(Record*)));
|
m_texmem_2_record = static_cast<Record**>(AllocBuffer(MemorySize >> 3, sizeof(Record*)));
|
||||||
memset(m_texmem_2_record, 0, (MemorySize >> 3) * sizeof(Record*));
|
memset(m_texmem_2_record, 0, (MemorySize >> 3) * sizeof(Record*));
|
||||||
#endif
|
#endif
|
||||||
// Prealloc Reocrds proportional to the amount of tex memory
|
// Prealloc records proportional to the amount of tex memory
|
||||||
RecordArraySize = MemorySize / (1024 * 1024) * 256; // preallocate 256 records per mb
|
RecordArraySize = MemorySize / (1024 * 1024) * 256; // preallocate 256 records per mb
|
||||||
|
// Number of texture names to be allocaed by default (See GL_PALETTE_EXT path in PGTexture::MakeReady)
|
||||||
|
// This may allocate more texture names than needed if the condition is true
|
||||||
|
textureNamesCount = OpenGL.ColorAlphaUnit2 == 0
|
||||||
|
&& OpenGL.FogTextureUnit >= GL_TEXTURE1_ARB
|
||||||
|
&& InternalConfig.EXT_paletted_texture
|
||||||
|
? 2 : 1;
|
||||||
// Prealloc some texdb records to avoid out of memory problems later
|
// Prealloc some texdb records to avoid out of memory problems later
|
||||||
TexDB::Record::Init();
|
TexDB::Record::Init();
|
||||||
|
if (InternalConfig.GenerateSubTextures)
|
||||||
|
{
|
||||||
|
TexDB::SubRecord::Init();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TexDB::~TexDB( void )
|
TexDB::~TexDB( void )
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
delete[] m_first;
|
delete[] m_first;
|
||||||
TexDB::SubRecord::Cleanup();
|
|
||||||
#ifdef OPTIMISE_TEXTURE_LOOKUP
|
#ifdef OPTIMISE_TEXTURE_LOOKUP
|
||||||
if (m_texmem_2_record) FreeBuffer(m_texmem_2_record);
|
if (m_texmem_2_record) FreeBuffer(m_texmem_2_record);
|
||||||
#endif
|
#endif
|
||||||
|
if (InternalConfig.GenerateSubTextures)
|
||||||
|
{
|
||||||
|
TexDB::SubRecord::Cleanup();
|
||||||
|
}
|
||||||
|
TexDB::Record::Cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
TexDB::Record* TexDB::Find(FxU32 startAddress, const GrTexInfo *info, FxU32 hash, bool *pal_change, SubTexCoord_t* subtexcoords) const
|
TexDB::Record* TexDB::Find(FxU32 startAddress, const GrTexInfo *info, FxU32 hash, bool *pal_change, SubTexCoord_t* subtexcoords) const
|
||||||
|
@ -320,6 +336,19 @@ void TexDB::Clear( void )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Must be called right after the OpenGL context has been built
|
||||||
|
void TexDB::initOpenGL(void)
|
||||||
|
{
|
||||||
|
Record::initOpenGL();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must be called before destroying the OpenGL context
|
||||||
|
void TexDB::cleanupOpenGL(void)
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
Record::cleanupOpenGL();
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////
|
||||||
// TexDB::Record Class implementation
|
// TexDB::Record Class implementation
|
||||||
///////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////
|
||||||
|
@ -347,6 +376,49 @@ void TexDB::Record::Cleanup()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Init free chunks with OpenGL stuff
|
||||||
|
void TexDB::Record::initOpenGL(void)
|
||||||
|
{
|
||||||
|
glReportErrors("TexDB::Record::initOpenGL");
|
||||||
|
|
||||||
|
RecordArray* ra = s_RecordArrays;
|
||||||
|
// Only the first chunk of free records is initialised,
|
||||||
|
// so this has to be called each time new records have been allocated
|
||||||
|
if (ra)
|
||||||
|
{
|
||||||
|
const GLfloat one = 1.0f;
|
||||||
|
for(int i = 0; i < RecordArraySize; i++)
|
||||||
|
{
|
||||||
|
// Pre-generate texture names (unused when using subtextures)
|
||||||
|
GLuint* num = &s_RecordArrays->records[i].texNum;
|
||||||
|
glGenTextures(TexDB::textureNamesCount, &num[0]);
|
||||||
|
glPrioritizeTextures(TexDB::textureNamesCount, &num[0], &one);
|
||||||
|
glReportError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TexDB::Record::cleanupOpenGL(void)
|
||||||
|
{
|
||||||
|
glReportErrors("TexDB::Record::cleanupOpenGL");
|
||||||
|
|
||||||
|
RecordArray* ra = s_RecordArrays;
|
||||||
|
while (ra)
|
||||||
|
{
|
||||||
|
// Delete pre-generated texture names
|
||||||
|
for(int i = 0; i < RecordArraySize; i++)
|
||||||
|
{
|
||||||
|
glDeleteTextures(textureNamesCount, &ra->records[i].texNum);
|
||||||
|
glReportError();
|
||||||
|
ra->records[i].texNum =
|
||||||
|
ra->records[i].tex2Num = 0;
|
||||||
|
}
|
||||||
|
ra = ra->next;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void TexDB::Record::AllocRecords()
|
void TexDB::Record::AllocRecords()
|
||||||
{
|
{
|
||||||
#ifdef OGL_UTEX_MEM
|
#ifdef OGL_UTEX_MEM
|
||||||
|
@ -368,6 +440,7 @@ void* TexDB::Record::operator new(size_t s)
|
||||||
if (s_FreeRecords == NULL)
|
if (s_FreeRecords == NULL)
|
||||||
{
|
{
|
||||||
AllocRecords();
|
AllocRecords();
|
||||||
|
initOpenGL();
|
||||||
}
|
}
|
||||||
p = s_FreeRecords;
|
p = s_FreeRecords;
|
||||||
s_FreeRecords = p->next;
|
s_FreeRecords = p->next;
|
||||||
|
@ -388,34 +461,11 @@ void TexDB::Record::operator delete(void* p)
|
||||||
|
|
||||||
TexDB::Record::Record(TexDB::TextureMode texturemode)
|
TexDB::Record::Record(TexDB::TextureMode texturemode)
|
||||||
{
|
{
|
||||||
if (texturemode <= Two)
|
|
||||||
{
|
|
||||||
GLfloat one;
|
|
||||||
glGenTextures(1, &texNum);
|
|
||||||
glPrioritizeTextures(1, &texNum, &one);
|
|
||||||
if (texturemode == TexDB::Two )
|
|
||||||
{
|
|
||||||
glGenTextures(1, &tex2Num);
|
|
||||||
glPrioritizeTextures(1, &tex2Num, &one);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tex2Num = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TexDB::Record::~Record(void)
|
TexDB::Record::~Record(void)
|
||||||
{
|
{
|
||||||
if (subrecords == NULL)
|
if (subrecords)
|
||||||
{
|
|
||||||
glDeleteTextures(1, &texNum);
|
|
||||||
if (tex2Num != 0)
|
|
||||||
{
|
|
||||||
glDeleteTextures(1, &tex2Num);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
SubRecord* next = this->subrecords;
|
SubRecord* next = this->subrecords;
|
||||||
for (SubRecord* s = next; next != NULL; s = next)
|
for (SubRecord* s = next; next != NULL; s = next)
|
||||||
|
@ -458,25 +508,83 @@ void TexDB::Record::WipeInside(const SubTexCoord_t* subtexcoords)
|
||||||
// TexDB::SubRecord Class implementation
|
// TexDB::SubRecord Class implementation
|
||||||
///////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
TexDB::SubRecord::SubRecord(TexDB::TextureMode texturemode)
|
void TexDB::SubRecord::Init()
|
||||||
{
|
{
|
||||||
glGenTextures(1, &texNum);
|
// Alloc a couple of subrecords in advance
|
||||||
if (texturemode == TexDB::SubTextureTwo)
|
AllocSubRecords();
|
||||||
{
|
|
||||||
glGenTextures(1, &tex2Num);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tex2Num = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TexDB::SubRecord::~SubRecord( void )
|
void TexDB::SubRecord::Cleanup()
|
||||||
{
|
{
|
||||||
glDeleteTextures(1, &texNum);
|
SubRecordArray* sra = s_SubRecordArrays;
|
||||||
if (tex2Num != 0)
|
while (sra)
|
||||||
{
|
{
|
||||||
glDeleteTextures(1, &tex2Num);
|
SubRecordArray* next = sra->next;
|
||||||
|
FreeObject(sra);
|
||||||
|
#ifdef OGL_UTEX_MEM
|
||||||
|
GlideMsg("Freed TexDB subrecord array at 0x%x\n", sra);
|
||||||
|
#endif
|
||||||
|
sra = next;
|
||||||
|
}
|
||||||
|
s_SubRecordArrays = NULL;
|
||||||
|
s_FreeSubRecords = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TexDB::SubRecord::initOpenGL()
|
||||||
|
{
|
||||||
|
glReportErrors("TexDB::SubRecord::initOpenGL");
|
||||||
|
|
||||||
|
SubRecordArray* sra = s_SubRecordArrays;
|
||||||
|
// Only the first chunk of free records is initialised,
|
||||||
|
// so this has to be called each time new records have been allocated
|
||||||
|
if (sra)
|
||||||
|
{
|
||||||
|
const GLfloat one = 1.0f;
|
||||||
|
for(int i = 0; i < RecordArraySize; i++)
|
||||||
|
{
|
||||||
|
// Pre-generate texture names (unused when using subtextures)
|
||||||
|
GLuint* num = &s_SubRecordArrays->subrecords[i].texNum;
|
||||||
|
glGenTextures(TexDB::textureNamesCount, num);
|
||||||
|
glPrioritizeTextures(TexDB::textureNamesCount, num, &one);
|
||||||
|
glReportError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TexDB::SubRecord::cleanupOpenGL()
|
||||||
|
{
|
||||||
|
glReportErrors("TexDB::SubRecord::cleanupOpenGL");
|
||||||
|
|
||||||
|
SubRecordArray* sra = s_SubRecordArrays;
|
||||||
|
while (sra)
|
||||||
|
{
|
||||||
|
// Delete pre-generated texture names
|
||||||
|
for(int i = 0; i < RecordArraySize; i++)
|
||||||
|
{
|
||||||
|
glDeleteTextures(textureNamesCount, &sra->subrecords[i].texNum);
|
||||||
|
glReportError();
|
||||||
|
sra->subrecords[i].texNum =
|
||||||
|
sra->subrecords[i].tex2Num = 0;
|
||||||
|
}
|
||||||
|
sra = sra->next;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TexDB::SubRecord::AllocSubRecords()
|
||||||
|
{
|
||||||
|
#ifdef OGL_UTEX_MEM
|
||||||
|
GlideMsg("Allocating TexDB record array with %d entries\n", RecordArraySize);
|
||||||
|
#endif
|
||||||
|
SubRecordArray* next = s_SubRecordArrays ? s_SubRecordArrays->next : NULL;
|
||||||
|
s_SubRecordArrays = static_cast<SubRecordArray*>(AllocObject(sizeof(SubRecordArray) + (RecordArraySize -1) * sizeof(SubRecord)));
|
||||||
|
s_SubRecordArrays->next = next;
|
||||||
|
for(int i = 0; i < RecordArraySize; i++)
|
||||||
|
{
|
||||||
|
s_SubRecordArrays->subrecords[i].next = s_FreeSubRecords;
|
||||||
|
s_FreeSubRecords = &s_SubRecordArrays->subrecords[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -485,45 +593,30 @@ void* TexDB::SubRecord::operator new(size_t s)
|
||||||
SubRecord* p;
|
SubRecord* p;
|
||||||
if (s_FreeSubRecords == NULL)
|
if (s_FreeSubRecords == NULL)
|
||||||
{
|
{
|
||||||
p = reinterpret_cast<SubRecord*>(NewPtrSys(s));
|
AllocSubRecords();
|
||||||
#ifdef OGL_UTEX_MEM
|
initOpenGL();
|
||||||
GlideMsg("Allocated TexDB subrecord at 0x%x\n", p);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
p = s_FreeSubRecords;
|
||||||
{
|
s_FreeSubRecords = p->next;
|
||||||
p = s_FreeSubRecords;
|
|
||||||
s_FreeSubRecords = p->next;
|
|
||||||
#ifdef OGL_UTEX_MEM
|
#ifdef OGL_UTEX_MEM
|
||||||
GlideMsg("Using TexDB subrecord at 0x%x\n", p);
|
GlideMsg("Using TexDB subrecord at 0x%x\n", p);
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexDB::SubRecord::operator delete(void* p)
|
void TexDB::SubRecord::operator delete(void* p)
|
||||||
{
|
{
|
||||||
#ifdef OGL_UTEX_MEM
|
#ifdef OGL_UTEX_MEM
|
||||||
GlideMsg("Moving TexDB subrecord at 0x%x to free-list\n", p);
|
GlideMsg("Moving TexDB subrecord at 0x%x to free list\n", p);
|
||||||
#endif
|
#endif
|
||||||
// reinterpret_cast<TexDB::SubRecord*>(p)->next = s_FreeSubRecords;
|
reinterpret_cast<TexDB::SubRecord*>(p)->next = s_FreeSubRecords;
|
||||||
SubRecord* s = reinterpret_cast<TexDB::SubRecord*>(p);
|
s_FreeSubRecords = reinterpret_cast<TexDB::SubRecord*>(p);
|
||||||
s->next = s_FreeSubRecords;
|
|
||||||
s_FreeSubRecords = s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TexDB::SubRecord::Cleanup()
|
TexDB::SubRecord::SubRecord(TexDB::TextureMode texturemode)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TexDB::SubRecord::~SubRecord( void )
|
||||||
{
|
{
|
||||||
SubRecord* s = s_FreeSubRecords;
|
|
||||||
while (s)
|
|
||||||
{
|
|
||||||
#ifdef OGL_UTEX_MEM
|
|
||||||
GlideMsg("Deleting TexDB subrecord at 0x%x\n", s);
|
|
||||||
#endif
|
|
||||||
SubRecord* next = s->next;
|
|
||||||
DisposePtr(reinterpret_cast<Ptr>(s));
|
|
||||||
s = next;
|
|
||||||
}
|
|
||||||
s_FreeSubRecords = NULL;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
class TexDB
|
class TexDB
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void Clear( void );
|
|
||||||
enum TextureMode
|
enum TextureMode
|
||||||
{
|
{
|
||||||
One = 0,
|
One = 0,
|
||||||
|
@ -38,8 +37,14 @@ public:
|
||||||
SubTextureOne = 2,
|
SubTextureOne = 2,
|
||||||
SubTextureTwo = 3
|
SubTextureTwo = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SubRecordArray;
|
||||||
struct SubRecord
|
struct SubRecord
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
|
static SubRecord* s_FreeSubRecords;
|
||||||
|
static SubRecordArray* s_SubRecordArrays;
|
||||||
|
static void AllocSubRecords();
|
||||||
public:
|
public:
|
||||||
SubRecord *next;
|
SubRecord *next;
|
||||||
public:
|
public:
|
||||||
|
@ -67,12 +72,19 @@ public:
|
||||||
};
|
};
|
||||||
void* operator new(size_t s);
|
void* operator new(size_t s);
|
||||||
void operator delete(void* p);
|
void operator delete(void* p);
|
||||||
|
static void Init();
|
||||||
static void Cleanup();
|
static void Cleanup();
|
||||||
static SubRecord* s_FreeSubRecords;
|
static void initOpenGL();
|
||||||
|
static void cleanupOpenGL();
|
||||||
private:
|
private:
|
||||||
void* operator new[](size_t s); // not used so we don't need an implementation
|
void* operator new[](size_t s); // not used so we don't need an implementation
|
||||||
void operator delete[](void* p);
|
void operator delete[](void* p);
|
||||||
};
|
};
|
||||||
|
struct SubRecordArray
|
||||||
|
{
|
||||||
|
SubRecordArray* next;
|
||||||
|
SubRecord subrecords[1];
|
||||||
|
};
|
||||||
|
|
||||||
struct RecordArray;
|
struct RecordArray;
|
||||||
class Record
|
class Record
|
||||||
|
@ -111,21 +123,28 @@ public:
|
||||||
void operator delete(void* p);
|
void operator delete(void* p);
|
||||||
static void Init();
|
static void Init();
|
||||||
static void Cleanup();
|
static void Cleanup();
|
||||||
|
static void initOpenGL();
|
||||||
|
static void cleanupOpenGL();
|
||||||
private:
|
private:
|
||||||
void* operator new[](size_t s); // not used so we don't need an implementation
|
void* operator new[](size_t s); // not used so we don't need an implementation
|
||||||
void operator delete[](void* p); // not used so we don't need an implementation
|
void operator delete[](void* p); // not used so we don't need an implementation
|
||||||
};
|
};
|
||||||
static int RecordArraySize;
|
|
||||||
struct RecordArray
|
struct RecordArray
|
||||||
{
|
{
|
||||||
RecordArray* next;
|
RecordArray* next;
|
||||||
Record records[1];
|
Record records[1];
|
||||||
};
|
};
|
||||||
|
TexDB(unsigned int MemorySize);
|
||||||
|
virtual ~TexDB(void);
|
||||||
|
void Clear(void);
|
||||||
|
void initOpenGL();
|
||||||
|
void cleanupOpenGL();
|
||||||
Record* Add(FxU32 startAddress, FxU32 endAddress, const GrTexInfo *info, FxU32 hash, TexDB::TextureMode texturemode, const SubTexCoord_t* subtexcoords);
|
Record* Add(FxU32 startAddress, FxU32 endAddress, const GrTexInfo *info, FxU32 hash, TexDB::TextureMode texturemode, const SubTexCoord_t* subtexcoords);
|
||||||
Record* Find(FxU32 startAddress, const GrTexInfo *info, FxU32 hash, bool *pal_change, SubTexCoord_t* subtexcoords) const;
|
Record* Find(FxU32 startAddress, const GrTexInfo *info, FxU32 hash, bool *pal_change, SubTexCoord_t* subtexcoords) const;
|
||||||
void WipeRange(FxU32 startAddress, FxU32 endAddress, FxU32 hash);
|
void WipeRange(FxU32 startAddress, FxU32 endAddress, FxU32 hash);
|
||||||
TexDB(unsigned int MemorySize);
|
static int RecordArraySize;
|
||||||
virtual ~TexDB(void);
|
protected:
|
||||||
|
static int textureNamesCount;
|
||||||
private:
|
private:
|
||||||
unsigned int numberOfTexSections;
|
unsigned int numberOfTexSections;
|
||||||
Record** m_first;
|
Record** m_first;
|
||||||
|
|
|
@ -296,6 +296,7 @@ grSstWinOpen(FxU32 hwnd,
|
||||||
// Initialise the frame buffer emulation
|
// Initialise the frame buffer emulation
|
||||||
RenderInitialize();
|
RenderInitialize();
|
||||||
s_Framebuffer.initialise(&Glide.FrameBuffer, &Glide.TempBuffer);
|
s_Framebuffer.initialise(&Glide.FrameBuffer, &Glide.TempBuffer);
|
||||||
|
Textures->initOpenGL();
|
||||||
|
|
||||||
#ifdef OGL_DONE
|
#ifdef OGL_DONE
|
||||||
GlideMsg( "----Start of grSstWinOpen()\n" );
|
GlideMsg( "----Start of grSstWinOpen()\n" );
|
||||||
|
@ -543,7 +544,7 @@ grSstWinClose( void )
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Textures->Clear();
|
Textures->cleanupOpenGL();
|
||||||
GLExtensionsCleanup();
|
GLExtensionsCleanup();
|
||||||
RenderFree();
|
RenderFree();
|
||||||
FinaliseOpenGLWindow();
|
FinaliseOpenGLWindow();
|
||||||
|
|
Loading…
Reference in New Issue