gsdx ogl: monitor global GPU memory texture usage

So far there is a hardcoded limit at ~3.7GB

In the future, the limit will be reduced for low-end GPU.
This commit is contained in:
Gregory Hainaut 2016-07-07 21:33:59 +02:00
parent f450056626
commit 7e2b3da928
4 changed files with 23 additions and 15 deletions

View File

@ -57,6 +57,8 @@ namespace GLState {
GLuint program; GLuint program;
GLuint pipeline; GLuint pipeline;
uint64 available_vram;
void Clear() { void Clear() {
fbo = 0; fbo = 0;
viewport = GSVector2i(0, 0); viewport = GSVector2i(0, 0);
@ -93,5 +95,9 @@ namespace GLState {
vs = 0; vs = 0;
program = 0; program = 0;
pipeline = 0; pipeline = 0;
// Set a max vram limit for texture allocation
// (256MB are reserved for PBO/IBO/VBO/UBO buffers)
available_vram = (4096u - 256u) * 1024u * 1024u;
} }
} }

View File

@ -59,5 +59,7 @@ namespace GLState {
extern GLuint program; extern GLuint program;
extern GLuint pipeline; extern GLuint pipeline;
extern uint64 available_vram;
extern void Clear(); extern void Clear();
} }

View File

@ -221,14 +221,14 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, int format, GLuint fbo_read)
case GL_DEPTH32F_STENCIL8: case GL_DEPTH32F_STENCIL8:
m_int_format = GL_DEPTH_STENCIL; m_int_format = GL_DEPTH_STENCIL;
m_int_type = GL_FLOAT_32_UNSIGNED_INT_24_8_REV; m_int_type = GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
m_int_shift = 0; m_int_shift = 3; // 4 bytes for depth + 4 bytes for stencil by texels
break; break;
// Backbuffer // Backbuffer
case 0: case 0:
m_int_format = 0; m_int_format = 0;
m_int_type = 0; m_int_type = 0;
m_int_shift = 0; m_int_shift = 2; // 4 bytes by texels
break; break;
default: default:
@ -238,6 +238,13 @@ GSTextureOGL::GSTextureOGL(int type, int w, int h, int format, GLuint fbo_read)
ASSERT(0); ASSERT(0);
} }
m_mem_usage = (m_size.x * m_size.y) << m_int_shift;
if (m_mem_usage > GLState::available_vram) {
throw GSDXErrorOOM(); // Still time to do a prayer !
} else {
GLState::available_vram -= m_mem_usage;
}
// Generate & Allocate the buffer // Generate & Allocate the buffer
switch (m_type) { switch (m_type) {
case GSTexture::Offscreen: case GSTexture::Offscreen:
@ -275,6 +282,8 @@ GSTextureOGL::~GSTextureOGL()
glDeleteTextures(1, &m_texture_id); glDeleteTextures(1, &m_texture_id);
GLState::available_vram += m_mem_usage;
if (m_local_buffer) if (m_local_buffer)
_aligned_free(m_local_buffer); _aligned_free(m_local_buffer);
} }
@ -485,16 +494,5 @@ bool GSTextureOGL::Save(const string& fn, bool user_image, bool dds)
uint32 GSTextureOGL::GetMemUsage() uint32 GSTextureOGL::GetMemUsage()
{ {
switch (m_type) { return m_mem_usage;
case GSTexture::Offscreen:
return m_size.x * m_size.y * (4 + 4); // Texture + buffer
case GSTexture::Texture:
case GSTexture::RenderTarget:
return m_size.x * m_size.y * 4;
case GSTexture::DepthStencil:
return m_size.x * m_size.y * 8;
case GSTexture::Backbuffer:
default:
return 0;
}
} }

View File

@ -53,12 +53,14 @@ class GSTextureOGL final : public GSTexture
int m_r_w; int m_r_w;
int m_r_h; int m_r_h;
// internal opengl format/type/alignment // internal opengl format/type/alignment
GLenum m_int_format; GLenum m_int_format;
GLenum m_int_type; GLenum m_int_type;
uint32 m_int_shift; uint32 m_int_shift;
// Allow to track size of allocated memory
uint32 m_mem_usage;
public: public:
explicit GSTextureOGL(int type, int w, int h, int format, GLuint fbo_read); explicit GSTextureOGL(int type, int w, int h, int format, GLuint fbo_read);
virtual ~GSTextureOGL(); virtual ~GSTextureOGL();