diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2017-05-04 22:22:41 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2017-05-04 22:26:54 +0300 |
commit | 6f5307e74d2f4b66bd9a9e2c6259dcb0aa3dc95f (patch) | |
tree | 6fbf91b87fcbf937c91c2a65c8cb4bfbbd51c6ce /source/blender | |
parent | 4bd2429f3519a58ccd1f93200dae42e52c45956e (diff) |
Draw Manager: Add a memory stats to debug view.
Adds 2 static unsigned int to Gawain and GPUTexture to roughly keep track of the memory stats on the GPU.
Stats can be view at the bottom of the GPU stats with debug value > 20.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 20 | ||||
-rw-r--r-- | source/blender/gpu/GPU_texture.h | 2 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_texture.c | 86 |
3 files changed, 104 insertions, 4 deletions
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 2a9e7770b2f..dd2ebea59ae 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -2330,7 +2330,7 @@ static void DRW_debug_gpu_stats(void) UI_FontThemeColor(BLF_default(), TH_TEXT_HI); char time_to_txt[16]; - char pass_name[MAX_PASS_NAME + 8]; + char pass_name[MAX_PASS_NAME + 16]; int v = BLI_listbase_count(&DST.enabled_engines) + 3; GLuint64 tot_time = 0; @@ -2372,7 +2372,25 @@ static void DRW_debug_gpu_stats(void) } sprintf(pass_name, "Total GPU time %.2fms (%.1f fps)", tot_time / 1000000.0, 1000000000.0 / tot_time); + draw_stat(&rect, 0, v++, pass_name, sizeof(pass_name)); + v++; + + /* Memory Stats */ + unsigned int tex_mem = GPU_texture_memory_usage_get(); + unsigned int vbo_mem = VertexBuffer_get_memory_usage(); + + sprintf(pass_name, "GPU Memory"); + draw_stat(&rect, 0, v, pass_name, sizeof(pass_name)); + sprintf(pass_name, "%.2fMB", (float)(tex_mem + vbo_mem) / 1000000.0); + draw_stat(&rect, 1, v++, pass_name, sizeof(pass_name)); + sprintf(pass_name, " |--> Textures"); + draw_stat(&rect, 0, v, pass_name, sizeof(pass_name)); + sprintf(pass_name, "%.2fMB", (float)tex_mem / 1000000.0); + draw_stat(&rect, 1, v++, pass_name, sizeof(pass_name)); + sprintf(pass_name, " |--> Meshes"); draw_stat(&rect, 0, v, pass_name, sizeof(pass_name)); + sprintf(pass_name, "%.2fMB", (float)vbo_mem / 1000000.0); + draw_stat(&rect, 1, v++, pass_name, sizeof(pass_name)); } diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h index 834194c99bc..3cd64eb5255 100644 --- a/source/blender/gpu/GPU_texture.h +++ b/source/blender/gpu/GPU_texture.h @@ -143,6 +143,8 @@ typedef enum GPUTextureFormat { GPU_DEPTH_COMPONENT16, } GPUTextureFormat; +unsigned int GPU_texture_memory_usage_get(void); + GPUTexture *GPU_texture_create_1D(int w, const float *pixels, char err_out[256]); GPUTexture *GPU_texture_create_1D_custom( int w, int channels, GPUTextureFormat data_type, const float *pixels, char err_out[256]); diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c index c330726daea..6e7fec1942b 100644 --- a/source/blender/gpu/intern/gpu_texture.c +++ b/source/blender/gpu/intern/gpu_texture.c @@ -63,11 +63,55 @@ struct GPUTexture { int fb_attachment; /* slot the texture is attached to */ bool depth; /* is a depth texture? */ bool stencil; /* is a stencil texture? */ + + unsigned int bytesize; /* number of byte for one pixel */ }; +/* ------ Memory Management ------- */ +/* Records every texture allocation / free + * to estimate the Texture Pool Memory consumption */ +static unsigned int memory_usage; + +static unsigned int gpu_texture_memory_footprint_compute(GPUTexture *tex) +{ + switch (tex->target) { + case GL_TEXTURE_1D: + return tex->bytesize * tex->w; + case GL_TEXTURE_1D_ARRAY: + case GL_TEXTURE_2D: + return tex->bytesize * tex->w * tex->h; + case GL_TEXTURE_2D_ARRAY: + case GL_TEXTURE_3D: + return tex->bytesize * tex->w * tex->h * tex->d; + case GL_TEXTURE_CUBE_MAP: + return tex->bytesize * 6 * tex->w * tex->h; + case GL_TEXTURE_CUBE_MAP_ARRAY: + return tex->bytesize * 6 * tex->w * tex->h * tex->d; + default: + return 0; + } +} + +static void gpu_texture_memory_footprint_add(GPUTexture *tex) +{ + memory_usage += gpu_texture_memory_footprint_compute(tex); +} + +static void gpu_texture_memory_footprint_remove(GPUTexture *tex) +{ + memory_usage -= gpu_texture_memory_footprint_compute(tex); +} + +unsigned int GPU_texture_memory_usage_get(void) +{ + return memory_usage; +} + +/* -------------------------------- */ + static GLenum gpu_texture_get_format( int components, GPUTextureFormat data_type, - GLenum *format, GLenum *data_format, bool *is_depth, bool *is_stencil) + GLenum *format, GLenum *data_format, bool *is_depth, bool *is_stencil, unsigned int *bytesize) { if (data_type == GPU_DEPTH_COMPONENT24 || data_type == GPU_DEPTH_COMPONENT16 || @@ -98,6 +142,35 @@ static GLenum gpu_texture_get_format( } } + switch (data_type) { + case GPU_RG32F: + case GPU_RGBA16F: + *bytesize = 16; + break; + case GPU_RGB16F: + *bytesize = 12; + break; + case GPU_RG16F: + case GPU_DEPTH24_STENCIL8: + case GPU_DEPTH_COMPONENT32F: + case GPU_RGBA8: + *bytesize = 4; + break; + case GPU_DEPTH_COMPONENT24: + *bytesize = 3; + break; + case GPU_DEPTH_COMPONENT16: + case GPU_R16F: + *bytesize = 2; + break; + case GPU_R8: + *bytesize = 1; + break; + default: + *bytesize = 0; + break; + } + /* You can add any of the available type to this list * For available types see GPU_texture.h */ switch (data_type) { @@ -267,7 +340,9 @@ static GPUTexture *GPU_texture_create_nD( tex->target = GL_TEXTURE_2D_MULTISAMPLE; GLenum format, internalformat, data_format; - internalformat = gpu_texture_get_format(components, data_type, &format, &data_format, &tex->depth, &tex->stencil); + internalformat = gpu_texture_get_format(components, data_type, &format, &data_format, &tex->depth, &tex->stencil, &tex->bytesize); + + gpu_texture_memory_footprint_add(tex); /* Generate Texture object */ glGenTextures(1, &tex->bindcode); @@ -392,7 +467,9 @@ static GPUTexture *GPU_texture_cube_create( // tex->target_base = tex->target = GL_TEXTURE_CUBE_MAP_ARRAY; } - internalformat = gpu_texture_get_format(components, data_type, &format, &data_format, &tex->depth, &tex->stencil); + internalformat = gpu_texture_get_format(components, data_type, &format, &data_format, &tex->depth, &tex->stencil, &tex->bytesize); + + gpu_texture_memory_footprint_add(tex); /* Generate Texture object */ glGenTextures(1, &tex->bindcode); @@ -622,6 +699,7 @@ GPUTexture *GPU_texture_create_depth_multisample(int w, int h, int samples, char void GPU_invalid_tex_init(void) { + memory_usage = 0; const float color[4] = {1.0f, 0.0f, 1.0f, 1.0f}; GG.invalid_tex_1D = GPU_texture_create_1D(1, color, NULL); GG.invalid_tex_2D = GPU_texture_create_2D(1, 1, color, NULL); @@ -828,6 +906,8 @@ void GPU_texture_free(GPUTexture *tex) if (tex->bindcode && !tex->fromblender) glDeleteTextures(1, &tex->bindcode); + gpu_texture_memory_footprint_remove(tex); + MEM_freeN(tex); } } |