fixed texture memory usage calculation in graphics threaded

Conflicts:

	src/engine/client/graphics_threaded.cpp
This commit is contained in:
oy 2012-10-06 23:31:02 +02:00
parent 7eddbe0dc9
commit 71af97a5e3
4 changed files with 89 additions and 56 deletions

View file

@ -133,7 +133,7 @@ void CCommandProcessorFragment_OpenGL::SetState(const CCommandBuffer::SState &St
if(State.m_Texture >= 0 && State.m_Texture < CCommandBuffer::MAX_TEXTURES)
{
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, m_aTextures[State.m_Texture]);
glBindTexture(GL_TEXTURE_2D, m_aTextures[State.m_Texture].m_Tex);
}
else
glDisable(GL_TEXTURE_2D);
@ -158,9 +158,14 @@ void CCommandProcessorFragment_OpenGL::SetState(const CCommandBuffer::SState &St
glOrtho(State.m_ScreenTL.x, State.m_ScreenBR.x, State.m_ScreenBR.y, State.m_ScreenTL.y, 1.0f, 10.f);
}
void CCommandProcessorFragment_OpenGL::Cmd_Init(const SCommand_Init *pCommand)
{
m_pTextureMemoryUsage = pCommand->m_pTextureMemoryUsage;
}
void CCommandProcessorFragment_OpenGL::Cmd_Texture_Update(const CCommandBuffer::SCommand_Texture_Update *pCommand)
{
glBindTexture(GL_TEXTURE_2D, m_aTextures[pCommand->m_Slot]);
glBindTexture(GL_TEXTURE_2D, m_aTextures[pCommand->m_Slot].m_Tex);
glTexSubImage2D(GL_TEXTURE_2D, 0, pCommand->m_X, pCommand->m_Y, pCommand->m_Width, pCommand->m_Height,
TexFormatToOpenGLFormat(pCommand->m_Format), GL_UNSIGNED_BYTE, pCommand->m_pData);
mem_free(pCommand->m_pData);
@ -168,7 +173,8 @@ void CCommandProcessorFragment_OpenGL::Cmd_Texture_Update(const CCommandBuffer::
void CCommandProcessorFragment_OpenGL::Cmd_Texture_Destroy(const CCommandBuffer::SCommand_Texture_Destroy *pCommand)
{
glDeleteTextures(1, &m_aTextures[pCommand->m_Slot]);
glDeleteTextures(1, &m_aTextures[pCommand->m_Slot].m_Tex);
*m_pTextureMemoryUsage -= m_aTextures[pCommand->m_Slot].m_MemSize;
}
void CCommandProcessorFragment_OpenGL::Cmd_Texture_Create(const CCommandBuffer::SCommand_Texture_Create *pCommand)
@ -186,8 +192,8 @@ void CCommandProcessorFragment_OpenGL::Cmd_Texture_Create(const CCommandBuffer::
default: StoreOglformat = GL_COMPRESSED_RGBA_ARB;
}
}
glGenTextures(1, &m_aTextures[pCommand->m_Slot]);
glBindTexture(GL_TEXTURE_2D, m_aTextures[pCommand->m_Slot]);
glGenTextures(1, &m_aTextures[pCommand->m_Slot].m_Tex);
glBindTexture(GL_TEXTURE_2D, m_aTextures[pCommand->m_Slot].m_Tex);
if(pCommand->m_Flags&CCommandBuffer::TEXFLAG_NOMIPMAPS)
{
@ -202,6 +208,18 @@ void CCommandProcessorFragment_OpenGL::Cmd_Texture_Create(const CCommandBuffer::
gluBuild2DMipmaps(GL_TEXTURE_2D, StoreOglformat, pCommand->m_Width, pCommand->m_Height, Oglformat, GL_UNSIGNED_BYTE, pCommand->m_pData);
}
// calculate memory usage
int Width = pCommand->m_Width;
int Height = pCommand->m_Height;
m_aTextures[pCommand->m_Slot].m_MemSize = Width*Height*pCommand->m_PixelSize;
while(Width > 2 && Height > 2)
{
Width>>=1;
Height>>=1;
m_aTextures[pCommand->m_Slot].m_MemSize += Width*Height*pCommand->m_PixelSize;
}
*m_pTextureMemoryUsage += m_aTextures[pCommand->m_Slot].m_MemSize;
mem_free(pCommand->m_pData);
}
@ -273,12 +291,14 @@ void CCommandProcessorFragment_OpenGL::Cmd_Screenshot(const CCommandBuffer::SCom
CCommandProcessorFragment_OpenGL::CCommandProcessorFragment_OpenGL()
{
mem_zero(m_aTextures, sizeof(m_aTextures));
m_pTextureMemoryUsage = 0;
}
bool CCommandProcessorFragment_OpenGL::RunCommand(const CCommandBuffer::SCommand * pBaseCommand)
{
switch(pBaseCommand->m_Cmd)
{
case CMD_INIT: Cmd_Init(static_cast<const SCommand_Init *>(pBaseCommand)); break;
case CCommandBuffer::CMD_TEXTURE_CREATE: Cmd_Texture_Create(static_cast<const CCommandBuffer::SCommand_Texture_Create *>(pBaseCommand)); break;
case CCommandBuffer::CMD_TEXTURE_DESTROY: Cmd_Texture_Destroy(static_cast<const CCommandBuffer::SCommand_Texture_Destroy *>(pBaseCommand)); break;
case CCommandBuffer::CMD_TEXTURE_UPDATE: Cmd_Texture_Update(static_cast<const CCommandBuffer::SCommand_Texture_Update *>(pBaseCommand)); break;
@ -487,11 +507,14 @@ int CGraphicsBackend_SDL_OpenGL::Init(const char *pName, int *Width, int *Height
m_pProcessor = new CCommandProcessor_SDL_OpenGL;
StartProcessor(m_pProcessor);
// issue a init command
// issue init commands for OpenGL and SDL
CCommandBuffer CmdBuffer(1024, 512);
CCommandProcessorFragment_SDL::SCommand_Init Cmd;
Cmd.m_Context = m_GLContext;
CmdBuffer.AddCommand(Cmd);
CCommandProcessorFragment_OpenGL::SCommand_Init CmdOpenGL;
CmdOpenGL.m_pTextureMemoryUsage = &m_TextureMemoryUsage;
CmdBuffer.AddCommand(CmdOpenGL);
CCommandProcessorFragment_SDL::SCommand_Init CmdSDL;
CmdSDL.m_Context = m_GLContext;
CmdBuffer.AddCommand(CmdSDL);
RunBuffer(&CmdBuffer);
WaitForIdle();
@ -517,6 +540,11 @@ int CGraphicsBackend_SDL_OpenGL::Shutdown()
return 0;
}
int CGraphicsBackend_SDL_OpenGL::MemoryUsage() const
{
return m_TextureMemoryUsage;
}
void CGraphicsBackend_SDL_OpenGL::Minimize()
{
SDL_WM_IconifyWindow();

View file

@ -167,11 +167,32 @@ public:
// takes care of opengl related rendering
class CCommandProcessorFragment_OpenGL
{
GLuint m_aTextures[CCommandBuffer::MAX_TEXTURES];
struct CTexture
{
GLuint m_Tex;
int m_MemSize;
};
CTexture m_aTextures[CCommandBuffer::MAX_TEXTURES];
volatile int *m_pTextureMemoryUsage;
public:
enum
{
CMD_INIT = CCommandBuffer::CMDGROUP_PLATFORM_OPENGL,
};
struct SCommand_Init : public CCommandBuffer::SCommand
{
SCommand_Init() : SCommand(CMD_INIT) {}
volatile int *m_pTextureMemoryUsage;
};
private:
static int TexFormatToOpenGLFormat(int TexFormat);
void SetState(const CCommandBuffer::SState &State);
void Cmd_Init(const SCommand_Init *pCommand);
void Cmd_Texture_Update(const CCommandBuffer::SCommand_Texture_Update *pCommand);
void Cmd_Texture_Destroy(const CCommandBuffer::SCommand_Texture_Destroy *pCommand);
void Cmd_Texture_Create(const CCommandBuffer::SCommand_Texture_Create *pCommand);
@ -193,7 +214,7 @@ class CCommandProcessorFragment_SDL
public:
enum
{
CMD_INIT = CCommandBuffer::CMDGROUP_PLATFORM,
CMD_INIT = CCommandBuffer::CMDGROUP_PLATFORM_SDL,
CMD_SHUTDOWN,
};
@ -235,10 +256,13 @@ class CGraphicsBackend_SDL_OpenGL : public CGraphicsBackend_Threaded
SDL_Surface *m_pScreenSurface;
ICommandProcessor *m_pProcessor;
SGLContext m_GLContext;
volatile int m_TextureMemoryUsage;
public:
virtual int Init(const char *pName, int *Width, int *Height, int FsaaSamples, int Flags);
virtual int Shutdown();
virtual int MemoryUsage() const;
virtual void Minimize();
virtual void Maximize();
virtual int WindowActive();

View file

@ -228,7 +228,7 @@ void CGraphics_Threaded::WrapClamp()
int CGraphics_Threaded::MemoryUsage() const
{
return m_TextureMemoryUsage;
return m_pBackend->MemoryUsage();
}
void CGraphics_Threaded::MapScreen(float TopLeftX, float TopLeftY, float BottomRightX, float BottomRightY)
@ -293,8 +293,7 @@ int CGraphics_Threaded::UnloadTexture(int Index)
Cmd.m_Slot = Index;
m_pCommandBuffer->AddCommand(Cmd);
m_aTextures[Index].m_Next = m_FirstFreeTexture;
m_TextureMemoryUsage -= m_aTextures[Index].m_MemSize;
m_aTextures[Index] = m_FirstFreeTexture;
m_FirstFreeTexture = Index;
return 0;
}
@ -307,6 +306,16 @@ static int ImageFormatToTexFormat(int Format)
return CCommandBuffer::TEXFORMAT_RGBA;
}
static int ImageFormatToPixelSize(int Format)
{
switch(Format)
{
case CImageInfo::FORMAT_RGB: return 3;
case CImageInfo::FORMAT_ALPHA: return 1;
default: return 4;
}
}
int CGraphics_Threaded::LoadTextureRawSub(int TextureID, int x, int y, int Width, int Height, int Format, const void *pData)
{
@ -319,13 +328,7 @@ int CGraphics_Threaded::LoadTextureRawSub(int TextureID, int x, int y, int Width
Cmd.m_Format = ImageFormatToTexFormat(Format);
// calculate memory usage
int PixelSize = 4;
if(Format == CImageInfo::FORMAT_RGB)
PixelSize = 3;
else if(Format == CImageInfo::FORMAT_ALPHA)
PixelSize = 1;
int MemSize = Width*Height*PixelSize;
int MemSize = Width*Height*ImageFormatToPixelSize(Format);
// copy texture data
void *pTmpData = mem_alloc(MemSize, sizeof(void*));
@ -345,13 +348,14 @@ int CGraphics_Threaded::LoadTextureRaw(int Width, int Height, int Format, const
// grab texture
int Tex = m_FirstFreeTexture;
m_FirstFreeTexture = m_aTextures[Tex].m_Next;
m_aTextures[Tex].m_Next = -1;
m_FirstFreeTexture = m_aTextureIndices[Tex];
m_aTextureIndices[Tex] = -1;
CCommandBuffer::SCommand_Texture_Create Cmd;
Cmd.m_Slot = Tex;
Cmd.m_Width = Width;
Cmd.m_Height = Height;
Cmd.m_PixelSize = ImageFormatToPixelSize(Format);
Cmd.m_Format = ImageFormatToTexFormat(Format);
Cmd.m_StoreFormat = ImageFormatToTexFormat(StoreFormat);
@ -362,16 +366,8 @@ int CGraphics_Threaded::LoadTextureRaw(int Width, int Height, int Format, const
if(g_Config.m_GfxTextureCompression)
Cmd.m_Flags |= CCommandBuffer::TEXFLAG_COMPRESSED;
// calculate memory usage
int PixelSize = 4;
if(Format == CImageInfo::FORMAT_RGB)
PixelSize = 3;
else if(Format == CImageInfo::FORMAT_ALPHA)
PixelSize = 1;
int MemSize = Width*Height*PixelSize;
// copy texture data
int MemSize = Width*Height*Cmd.m_PixelSize;
void *pTmpData = mem_alloc(MemSize, sizeof(void*));
mem_copy(pTmpData, pData, MemSize);
Cmd.m_pData = pTmpData;
@ -379,17 +375,6 @@ int CGraphics_Threaded::LoadTextureRaw(int Width, int Height, int Format, const
//
m_pCommandBuffer->AddCommand(Cmd);
// calculate memory usage
int MemUsage = MemSize;
while(Width > 2 && Height > 2)
{
Width>>=1;
Height>>=1;
MemUsage += Width*Height*PixelSize;
}
m_TextureMemoryUsage += MemUsage;
//mem_free(pTmpData);
return Tex;
}
@ -775,9 +760,9 @@ int CGraphics_Threaded::Init()
// init textures
m_FirstFreeTexture = 0;
for(int i = 0; i < MAX_TEXTURES; i++)
m_aTextures[i].m_Next = i+1;
m_aTextures[MAX_TEXTURES-1].m_Next = -1;
for(int i = 0; i < MAX_TEXTURES-1; i++)
m_aTextureIndices[i] = i+1;
m_aTextureIndices[MAX_TEXTURES-1] = -1;
m_pBackend = CreateGraphicsBackend();
if(InitWindow() != 0)

View file

@ -57,7 +57,8 @@ public:
{
// commadn groups
CMDGROUP_CORE = 0, // commands that everyone has to implement
CMDGROUP_PLATFORM = 10000, // commands specific to a platform
CMDGROUP_PLATFORM_OPENGL = 10000, // commands specific to a platform
CMDGROUP_PLATFORM_SDL = 20000,
//
CMD_NOP = CMDGROUP_CORE,
@ -211,6 +212,7 @@ public:
int m_Width;
int m_Height;
int m_PixelSize;
int m_Format;
int m_StoreFormat;
int m_Flags;
@ -302,6 +304,8 @@ public:
virtual int Init(const char *pName, int *Width, int *Height, int FsaaSamples, int Flags) = 0;
virtual int Shutdown() = 0;
virtual int MemoryUsage() const = 0;
virtual void Minimize() = 0;
virtual void Maximize() = 0;
virtual int WindowActive() = 0;
@ -351,15 +355,7 @@ class CGraphics_Threaded : public IEngineGraphics
int m_InvalidTexture;
struct CTexture
{
int m_State;
int m_MemSize;
int m_Flags;
int m_Next;
};
CTexture m_aTextures[MAX_TEXTURES];
int m_aTextureIndices[MAX_TEXTURES];
int m_FirstFreeTexture;
int m_TextureMemoryUsage;