[Bf-blender-cvs] [5bfa3cf6e9a] blender2.8: DRW: Revamp the performance debugging tool.

Clément Foucault noreply at git.blender.org
Thu Jul 27 14:59:11 CEST 2017


Commit: 5bfa3cf6e9a09c2cabbdb79d3d02024fcbc3a296
Author: Clément Foucault
Date:   Wed Jul 26 19:57:46 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB5bfa3cf6e9a09c2cabbdb79d3d02024fcbc3a296

DRW: Revamp the performance debugging tool.

Old performance debug was doing queries for every frame even if not debugging perf.
Also, it did not record when a pass was draw multiple time, leading to incorect measurement.

New module also allows to group the timers to limit infos displayed.

Also fix the background CPU draw timer.

===================================================================

M	source/blender/draw/CMakeLists.txt
M	source/blender/draw/intern/DRW_render.h
M	source/blender/draw/intern/draw_manager.c
A	source/blender/draw/intern/draw_manager_profiling.c
A	source/blender/draw/intern/draw_manager_profiling.h

===================================================================

diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 4098cfe696e..e3a3ac499a1 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -63,6 +63,7 @@ set(SRC
 	intern/draw_common.c
 	intern/draw_manager.c
 	intern/draw_manager_text.c
+	intern/draw_manager_profiling.c
 	intern/draw_view.c
 	modes/edit_armature_mode.c
 	modes/edit_curve_mode.c
@@ -94,6 +95,7 @@ set(SRC
 	intern/draw_cache_impl.h
 	intern/draw_common.h
 	intern/draw_manager_text.h
+	intern/draw_manager_profiling.h
 	intern/draw_view.h
 	modes/draw_mode_engines.h
 	engines/basic/basic_engine.h
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index ca6a89f174a..853f2d123eb 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -49,6 +49,8 @@
 #include "draw_cache.h"
 #include "draw_view.h"
 
+#include "draw_manager_profiling.h"
+
 #include "MEM_guardedalloc.h"
 
 #include "RE_engine.h"
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 70e9d985e6c..00a28f0371a 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -80,6 +80,7 @@
 #include "WM_types.h"
 
 #include "draw_manager_text.h"
+#include "draw_manager_profiling.h"
 
 /* only for callbacks */
 #include "draw_cache_impl.h"
@@ -191,12 +192,6 @@ struct DRWPass {
 	ListBase shgroups; /* DRWShadingGroup */
 	DRWState state;
 	char name[MAX_PASS_NAME];
-	/* use two query to not stall the cpu waiting for queries to complete */
-	unsigned int timer_queries[2];
-	/* alternate between front and back query */
-	unsigned int front_idx;
-	unsigned int back_idx;
-	bool wasdrawn; /* if it was drawn during this frame */
 };
 
 typedef struct DRWCallHeader {
@@ -1260,7 +1255,6 @@ void DRW_pass_free(DRWPass *pass)
 		DRW_shgroup_free(shgroup);
 	}
 
-	glDeleteQueries(2, pass->timer_queries);
 	BLI_freelistN(&pass->shgroups);
 }
 
@@ -1900,28 +1894,7 @@ static void DRW_draw_pass_ex(DRWPass *pass, DRWShadingGroup *start_group, DRWSha
 	DRW_state_set(pass->state);
 	BLI_listbase_clear(&DST.bound_texs);
 
-	/* Init Timer queries */
-	if (pass->timer_queries[0] == 0) {
-		pass->front_idx = 0;
-		pass->back_idx = 1;
-
-		glGenQueries(2, pass->timer_queries);
-
-		/* dummy query, avoid gl error */
-		glBeginQuery(GL_TIME_ELAPSED, pass->timer_queries[pass->front_idx]);
-		glEndQuery(GL_TIME_ELAPSED);
-	}
-	else {
-		/* swap indices */
-		unsigned int tmp = pass->back_idx;
-		pass->back_idx = pass->front_idx;
-		pass->front_idx = tmp;
-	}
-
-	if (!pass->wasdrawn) {
-		/* issue query for the next frame */
-		glBeginQuery(GL_TIME_ELAPSED, pass->timer_queries[pass->back_idx]);
-	}
+	DRW_stats_query_start(pass->name);
 
 	for (DRWShadingGroup *shgroup = start_group; shgroup; shgroup = shgroup->next) {
 		draw_shgroup(shgroup, pass->state);
@@ -1943,11 +1916,7 @@ static void DRW_draw_pass_ex(DRWPass *pass, DRWShadingGroup *start_group, DRWSha
 		DST.shader = NULL;
 	}
 
-	if (!pass->wasdrawn) {
-		glEndQuery(GL_TIME_ELAPSED);
-	}
-
-	pass->wasdrawn = true;
+	DRW_stats_query_end();
 }
 
 void DRW_draw_pass(DRWPass *pass)
@@ -2620,15 +2589,18 @@ static void DRW_engines_draw_background(void)
 	for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
 		DrawEngineType *engine = link->data;
 		ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
-		double stime = PIL_check_seconds_timer();
 
 		if (engine->draw_background) {
+			double stime = PIL_check_seconds_timer();
+
+			DRW_stats_group_start(engine->idname);
 			engine->draw_background(data);
+			DRW_stats_group_end();
+
+			double ftime = (PIL_check_seconds_timer() - stime) * 1e3;
+			data->background_time = data->background_time * (1.0f - TIMER_FALLOFF) + ftime * TIMER_FALLOFF; /* exp average */
 			return;
 		}
-
-		double ftime = (PIL_check_seconds_timer() - stime) * 1e3;
-		data->background_time = data->background_time * (1.0f - TIMER_FALLOFF) + ftime * TIMER_FALLOFF; /* exp average */
 	}
 
 	/* No draw_background found, doing default background */
@@ -2643,7 +2615,9 @@ static void DRW_engines_draw_scene(void)
 		double stime = PIL_check_seconds_timer();
 
 		if (engine->draw_scene) {
+			DRW_stats_group_start(engine->idname);
 			engine->draw_scene(data);
+			DRW_stats_group_end();
 		}
 
 		double ftime = (PIL_check_seconds_timer() - stime) * 1e3;
@@ -2877,7 +2851,7 @@ static unsigned int DRW_engines_get_hash(void)
 static void draw_stat(rcti *rect, int u, int v, const char *txt, const int size)
 {
 	BLF_draw_default_ascii(rect->xmin + (1 + u * 5) * U.widget_unit,
-	                       rect->ymax - (3 + v++) * U.widget_unit, 0.0f,
+	                       rect->ymax - (3 + v) * U.widget_unit, 0.0f,
 	                       txt, size);
 }
 
@@ -2968,66 +2942,32 @@ 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 + 16];
 	int v = BLI_listbase_count(&DST.enabled_engines) + 3;
-	GLuint64 tot_time = 0;
-
-	if (G.debug_value > 666) {
-		for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
-			GLuint64 engine_time = 0;
-			DrawEngineType *engine = link->data;
-			ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
-			int vsta = v;
 
-			draw_stat(&rect, 0, v, engine->idname, sizeof(engine->idname));
-			v++;
-
-			for (int i = 0; i < engine->vedata_size->psl_len; ++i) {
-				DRWPass *pass = data->psl->passes[i];
-				if (pass != NULL && pass->wasdrawn) {
-					GLuint64 time;
-					glGetQueryObjectui64v(pass->timer_queries[pass->front_idx], GL_QUERY_RESULT, &time);
-
-					sprintf(pass_name, "   |--> %s", pass->name);
-					draw_stat(&rect, 0, v, pass_name, sizeof(pass_name));
-
-					sprintf(time_to_txt, "%.2fms", time / 1000000.0);
-					engine_time += time;
-					tot_time += time;
-
-					draw_stat(&rect, 2, v++, time_to_txt, sizeof(time_to_txt));
-
-					pass->wasdrawn = false;
-				}
-			}
-			/* engine total time */
-			sprintf(time_to_txt, "%.2fms", engine_time / 1000000.0);
-			draw_stat(&rect, 2, vsta, time_to_txt, sizeof(time_to_txt));
-			v++;
-		}
-
-		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++;
-	}
+	char stat_string[32];
 
 	/* Memory Stats */
 	unsigned int tex_mem = GPU_texture_memory_usage_get();
 	unsigned int vbo_mem = GWN_vertbuf_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));
+	sprintf(stat_string, "GPU Memory");
+	draw_stat(&rect, 0, v, stat_string, sizeof(stat_string));
+	sprintf(stat_string, "%.2fMB", (float)(tex_mem + vbo_mem) / 1000000.0);
+	draw_stat(&rect, 1, v++, stat_string, sizeof(stat_string));
+	sprintf(stat_string, "   |--> Textures");
+	draw_stat(&rect, 0, v, stat_string, sizeof(stat_string));
+	sprintf(stat_string, "%.2fMB", (float)tex_mem / 1000000.0);
+	draw_stat(&rect, 1, v++, stat_string, sizeof(stat_string));
+	sprintf(stat_string, "   |--> Meshes");
+	draw_stat(&rect, 0, v, stat_string, sizeof(stat_string));
+	sprintf(stat_string, "%.2fMB", (float)vbo_mem / 1000000.0);
+	draw_stat(&rect, 1, v++, stat_string, sizeof(stat_string));
+
+	/* Pre offset for stats_draw */
+	rect.ymax -= (3 + ++v) * U.widget_unit;
+
+	/* Rendering Stats */
+	DRW_stats_draw(&rect);
 }
 
 
@@ -3106,6 +3046,8 @@ void DRW_draw_render_loop_ex(
 		DRW_engines_cache_finish();
 	}
 
+	DRW_stats_begin();
+
 	/* Start Drawing */
 	DRW_state_reset();
 	DRW_engines_draw_background();
@@ -3136,6 +3078,8 @@ void DRW_draw_render_loop_ex(
 		DRW_draw_region_info();
 	}
 
+	DRW_stats_reset();
+
 	if (G.debug_value > 20) {
 		DRW_debug_cpu_stats();
 		DRW_debug_gpu_stats();
@@ -3555,6 +3499,7 @@ extern struct GPUTexture *globals_ramp; /* draw_common.c */
 void DRW_engines_free(void)
 {
 	DRW_shape_cache_free();
+	DRW_stats_free();
 
 	DrawEngineType *next;
 	for (DrawEngineType *type = DRW_engines.first; type; type = next) {
diff --git a/source/blender/draw/intern/draw_manager_profiling.c b/source/blender/draw/intern/draw_manager_profiling.c
new file mode 100644
index 00000000000..bca9e50da99
--- /dev/null
+++ b/source/blender/draw/intern/draw_manager_profiling.c
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file draw_manager_profiling.c
+ *  \ingroup draw
+ */
+
+#include "BLI_rect.h"
+#include "BLI_string.h"
+
+#include "BKE_global.h"
+
+#include "BLF_api.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "GPU_glew.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "draw_manager_profiling.h"
+
+#define MAX_TIMER_NAME 32
+#define MAX_NESTED_TIMER 8
+#define CHUNK_SIZE 8
+#define GPU_TIMER_FALLOFF 0.1
+
+typedef struct DRWTimer {
+	GLuint q

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list