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.
This commit is contained in:
@@ -71,6 +71,10 @@ void VertexFormat_copy(VertexFormat* dest, const VertexFormat* src);
|
||||
|
||||
unsigned VertexFormat_add_attrib(VertexFormat*, const char* name, VertexCompType, unsigned comp_ct, VertexFetchMode);
|
||||
|
||||
// Memory Management
|
||||
|
||||
unsigned VertexBuffer_get_memory_usage(void);
|
||||
|
||||
// format conversion
|
||||
|
||||
#if USE_10_10_10
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
#define KEEP_SINGLE_COPY 1
|
||||
|
||||
static unsigned vbo_memory_usage;
|
||||
|
||||
VertexBuffer* VertexBuffer_create(void)
|
||||
{
|
||||
VertexBuffer* verts = malloc(sizeof(VertexBuffer));
|
||||
@@ -51,14 +53,17 @@ void VertexBuffer_init_with_format(VertexBuffer* verts, const VertexFormat* form
|
||||
|
||||
void VertexBuffer_discard(VertexBuffer* verts)
|
||||
{
|
||||
if (verts->vbo_id)
|
||||
if (verts->vbo_id) {
|
||||
buffer_id_free(verts->vbo_id);
|
||||
vbo_memory_usage -= VertexBuffer_size(verts);
|
||||
}
|
||||
#if KEEP_SINGLE_COPY
|
||||
else
|
||||
#endif
|
||||
if (verts->data)
|
||||
free(verts->data);
|
||||
|
||||
|
||||
free(verts);
|
||||
}
|
||||
|
||||
@@ -155,6 +160,8 @@ static void VertexBuffer_prime(VertexBuffer* verts)
|
||||
// fill with delicious data & send to GPU the first time only
|
||||
glBufferData(GL_ARRAY_BUFFER, vertex_buffer_size(format, verts->vertex_ct), verts->data, GL_STATIC_DRAW);
|
||||
|
||||
vbo_memory_usage += VertexBuffer_size(verts);
|
||||
|
||||
#if KEEP_SINGLE_COPY
|
||||
// now that GL has a copy, discard original
|
||||
free(verts->data);
|
||||
@@ -169,3 +176,8 @@ void VertexBuffer_use(VertexBuffer* verts)
|
||||
else
|
||||
VertexBuffer_prime(verts);
|
||||
}
|
||||
|
||||
unsigned VertexBuffer_get_memory_usage(void)
|
||||
{
|
||||
return vbo_memory_usage;
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user