Procházet zdrojové kódy

Add INFO_SHADER_COMPILES_IN_FRAME to GL ES 3 render info

Pedro J. Estébanez před 3 roky
rodič
revize
f46d7583ff

+ 14 - 8
doc/classes/VisualServer.xml

@@ -3719,28 +3719,34 @@
 		<constant name="INFO_SHADER_CHANGES_IN_FRAME" value="3" enum="RenderInfo">
 			The amount of shader rebinds in the frame.
 		</constant>
-		<constant name="INFO_SURFACE_CHANGES_IN_FRAME" value="4" enum="RenderInfo">
+		<constant name="INFO_SHADER_COMPILES_IN_FRAME" value="4" enum="RenderInfo">
+			The peak amount of shaders that have been under compilation in the frame.
+			This is useful to know when asynchronous shader compilation has finished for the current shaders on screen.
+			[b]Note:[/b] For complete certainty, only assume there are no outstanding compilations when this value is zero for at least two frames in a row.
+			Unimplemented in the GLES2 rendering backend, always returns 0.
+		</constant>
+		<constant name="INFO_SURFACE_CHANGES_IN_FRAME" value="5" enum="RenderInfo">
 			The amount of surface changes in the frame.
 		</constant>
-		<constant name="INFO_DRAW_CALLS_IN_FRAME" value="5" enum="RenderInfo">
+		<constant name="INFO_DRAW_CALLS_IN_FRAME" value="6" enum="RenderInfo">
 			The amount of draw calls in frame.
 		</constant>
-		<constant name="INFO_2D_ITEMS_IN_FRAME" value="6" enum="RenderInfo">
+		<constant name="INFO_2D_ITEMS_IN_FRAME" value="7" enum="RenderInfo">
 			The amount of 2d items in the frame.
 		</constant>
-		<constant name="INFO_2D_DRAW_CALLS_IN_FRAME" value="7" enum="RenderInfo">
+		<constant name="INFO_2D_DRAW_CALLS_IN_FRAME" value="8" enum="RenderInfo">
 			The amount of 2d draw calls in frame.
 		</constant>
-		<constant name="INFO_USAGE_VIDEO_MEM_TOTAL" value="8" enum="RenderInfo">
+		<constant name="INFO_USAGE_VIDEO_MEM_TOTAL" value="9" enum="RenderInfo">
 			Unimplemented in the GLES2 and GLES3 rendering backends, always returns 0.
 		</constant>
-		<constant name="INFO_VIDEO_MEM_USED" value="9" enum="RenderInfo">
+		<constant name="INFO_VIDEO_MEM_USED" value="10" enum="RenderInfo">
 			The amount of video memory used, i.e. texture and vertex memory combined.
 		</constant>
-		<constant name="INFO_TEXTURE_MEM_USED" value="10" enum="RenderInfo">
+		<constant name="INFO_TEXTURE_MEM_USED" value="11" enum="RenderInfo">
 			The amount of texture memory used.
 		</constant>
-		<constant name="INFO_VERTEX_MEM_USED" value="11" enum="RenderInfo">
+		<constant name="INFO_VERTEX_MEM_USED" value="12" enum="RenderInfo">
 			The amount of vertex memory used.
 		</constant>
 		<constant name="FEATURE_SHADERS" value="0" enum="Features">

+ 3 - 2
drivers/gles3/rasterizer_gles3.cpp

@@ -207,13 +207,13 @@ void RasterizerGLES3::begin_frame(double frame_step) {
 	storage->frame.time[2] = Math::fmod(time_total, 900);
 	storage->frame.time[3] = Math::fmod(time_total, 60);
 	storage->frame.count++;
-	storage->frame.shader_compiles_started = 0;
 	storage->frame.delta = frame_step;
 
 	storage->update_dirty_resources();
 
 	storage->info.render_final = storage->info.render;
 	storage->info.render.reset();
+	storage->info.render.shader_compiles_in_progress_count = ShaderGLES3::active_compiles_count;
 
 	ShaderGLES3::current_frame = storage->frame.count;
 
@@ -493,7 +493,8 @@ RasterizerGLES3::RasterizerGLES3() {
 	time_total = 0;
 	time_scale = 1;
 
-	ShaderGLES3::compiles_started_this_frame = &storage->frame.shader_compiles_started;
+	ShaderGLES3::compiles_started_this_frame = &storage->info.render.shader_compiles_started_count;
+	ShaderGLES3::max_frame_compiles_in_progress = &storage->info.render.shader_compiles_in_progress_count;
 }
 
 RasterizerGLES3::~RasterizerGLES3() {

+ 7 - 0
drivers/gles3/rasterizer_storage_gles3.cpp

@@ -7950,6 +7950,8 @@ void RasterizerStorageGLES3::render_info_end_capture() {
 	info.snap.material_switch_count = info.render.material_switch_count - info.snap.material_switch_count;
 	info.snap.surface_switch_count = info.render.surface_switch_count - info.snap.surface_switch_count;
 	info.snap.shader_rebind_count = info.render.shader_rebind_count - info.snap.shader_rebind_count;
+	info.snap.shader_compiles_started_count = info.render.shader_compiles_started_count - info.snap.shader_compiles_started_count;
+	info.snap.shader_compiles_in_progress_count = info.render.shader_compiles_in_progress_count - info.snap.shader_compiles_in_progress_count;
 	info.snap.vertices_count = info.render.vertices_count - info.snap.vertices_count;
 	info.snap._2d_item_count = info.render._2d_item_count - info.snap._2d_item_count;
 	info.snap._2d_draw_call_count = info.render._2d_draw_call_count - info.snap._2d_draw_call_count;
@@ -7969,6 +7971,9 @@ int RasterizerStorageGLES3::get_captured_render_info(VS::RenderInfo p_info) {
 		case VS::INFO_SHADER_CHANGES_IN_FRAME: {
 			return info.snap.shader_rebind_count;
 		} break;
+		case VS::INFO_SHADER_COMPILES_IN_FRAME: {
+			return info.snap.shader_compiles_in_progress_count;
+		} break;
 		case VS::INFO_SURFACE_CHANGES_IN_FRAME: {
 			return info.snap.surface_switch_count;
 		} break;
@@ -7997,6 +8002,8 @@ uint64_t RasterizerStorageGLES3::get_render_info(VS::RenderInfo p_info) {
 			return info.render_final.material_switch_count;
 		case VS::INFO_SHADER_CHANGES_IN_FRAME:
 			return info.render_final.shader_rebind_count;
+		case VS::INFO_SHADER_COMPILES_IN_FRAME:
+			return info.render.shader_compiles_in_progress_count;
 		case VS::INFO_SURFACE_CHANGES_IN_FRAME:
 			return info.render_final.surface_switch_count;
 		case VS::INFO_DRAW_CALLS_IN_FRAME:

+ 4 - 1
drivers/gles3/rasterizer_storage_gles3.h

@@ -164,6 +164,8 @@ public:
 			uint32_t material_switch_count;
 			uint32_t surface_switch_count;
 			uint32_t shader_rebind_count;
+			uint32_t shader_compiles_started_count;
+			uint32_t shader_compiles_in_progress_count;
 			uint32_t vertices_count;
 			uint32_t _2d_item_count;
 			uint32_t _2d_draw_call_count;
@@ -174,6 +176,8 @@ public:
 				material_switch_count = 0;
 				surface_switch_count = 0;
 				shader_rebind_count = 0;
+				shader_compiles_started_count = 0;
+				shader_compiles_in_progress_count = 0;
 				vertices_count = 0;
 				_2d_item_count = 0;
 				_2d_draw_call_count = 0;
@@ -1487,7 +1491,6 @@ public:
 		float time[4];
 		float delta;
 		uint64_t count;
-		int shader_compiles_started;
 
 	} frame;
 

+ 29 - 7
drivers/gles3/shader_gles3.cpp

@@ -64,13 +64,14 @@ ThreadedCallableQueue<GLuint> *ShaderGLES3::compile_queue;
 bool ShaderGLES3::parallel_compile_supported;
 
 bool ShaderGLES3::async_hidden_forbidden;
-int *ShaderGLES3::compiles_started_this_frame;
-int ShaderGLES3::max_simultaneous_compiles;
+uint32_t *ShaderGLES3::compiles_started_this_frame;
+uint32_t *ShaderGLES3::max_frame_compiles_in_progress;
+uint32_t ShaderGLES3::max_simultaneous_compiles;
+uint32_t ShaderGLES3::active_compiles_count;
 #ifdef DEBUG_ENABLED
 bool ShaderGLES3::log_active_async_compiles_count;
 #endif
 
-int ShaderGLES3::active_compiles_count;
 uint64_t ShaderGLES3::current_frame;
 
 //#define DEBUG_SHADER
@@ -210,7 +211,6 @@ void ShaderGLES3::advance_async_shaders_compilation() {
 void ShaderGLES3::_log_active_compiles() {
 #ifdef DEBUG_ENABLED
 	if (log_active_async_compiles_count) {
-		ERR_FAIL_COND(active_compiles_count < 0);
 		if (parallel_compile_supported) {
 			print_line("Async. shader compiles: " + itos(active_compiles_count));
 		} else if (compile_queue) {
@@ -240,9 +240,9 @@ bool ShaderGLES3::_process_program_state(Version *p_version, bool p_async_forbid
 				// These lead to nowhere unless other piece of code starts the compile process
 			} break;
 			case Version::COMPILE_STATUS_SOURCE_PROVIDED: {
-				int start_compiles_count = p_async_forbidden ? 2 : 0;
+				uint32_t start_compiles_count = p_async_forbidden ? 2 : 0;
 				if (!start_compiles_count) {
-					int free_async_slots = MAX(0, MIN(max_simultaneous_compiles - active_compiles_count, max_simultaneous_compiles - *compiles_started_this_frame));
+					uint32_t free_async_slots = MAX(0, MIN(max_simultaneous_compiles - active_compiles_count, max_simultaneous_compiles - *compiles_started_this_frame));
 					start_compiles_count = MIN(2, free_async_slots);
 				}
 				if (start_compiles_count >= 1) {
@@ -257,6 +257,7 @@ bool ShaderGLES3::_process_program_state(Version *p_version, bool p_async_forbid
 						versions_compiling.add_last(&p_version->compiling_list);
 						// Vertex and fragment shaders take independent compile slots
 						active_compiles_count += start_compiles_count;
+						*max_frame_compiles_in_progress = MAX(*max_frame_compiles_in_progress, active_compiles_count);
 						_log_active_compiles();
 					}
 					(*compiles_started_this_frame) += start_compiles_count;
@@ -274,6 +275,7 @@ bool ShaderGLES3::_process_program_state(Version *p_version, bool p_async_forbid
 					glCompileShader(p_version->ids.frag);
 					if (p_version->compiling_list.in_list()) {
 						active_compiles_count++;
+						*max_frame_compiles_in_progress = MAX(*max_frame_compiles_in_progress, active_compiles_count);
 						_log_active_compiles();
 					}
 					p_version->compile_status = Version::COMPILE_STATUS_COMPILING_VERTEX_AND_FRAGMENT;
@@ -299,6 +301,10 @@ bool ShaderGLES3::_process_program_state(Version *p_version, bool p_async_forbid
 						glGetShaderiv(p_version->ids.vert, _EXT_COMPLETION_STATUS, &vertex_completed);
 						if (p_version->compiling_list.in_list()) {
 							active_compiles_count--;
+#ifdef DEV_ENABLED
+							CRASH_COND(active_compiles_count == UINT32_MAX);
+#endif
+							*max_frame_compiles_in_progress = MAX(*max_frame_compiles_in_progress, active_compiles_count);
 							_log_active_compiles();
 						}
 						p_version->compile_status = Version::COMPILE_STATUS_COMPILING_FRAGMENT;
@@ -322,6 +328,9 @@ bool ShaderGLES3::_process_program_state(Version *p_version, bool p_async_forbid
 						if (p_version->compiling_list.in_list()) {
 							p_version->compiling_list.remove_from_list();
 							active_compiles_count--;
+#ifdef DEV_ENABLED
+							CRASH_COND(active_compiles_count == UINT32_MAX);
+#endif
 							_log_active_compiles();
 						}
 					}
@@ -334,6 +343,9 @@ bool ShaderGLES3::_process_program_state(Version *p_version, bool p_async_forbid
 						p_version->compile_status = Version::COMPILE_STATUS_ERROR;
 						p_version->compiling_list.remove_from_list();
 						active_compiles_count--;
+#ifdef DEV_ENABLED
+						CRASH_COND(active_compiles_count == UINT32_MAX);
+#endif
 						_log_active_compiles();
 					} break;
 					case 0: { // In progress
@@ -361,6 +373,7 @@ bool ShaderGLES3::_process_program_state(Version *p_version, bool p_async_forbid
 					if (!p_async_forbidden) {
 						versions_compiling.add_last(&p_version->compiling_list);
 						active_compiles_count++;
+						*max_frame_compiles_in_progress = MAX(*max_frame_compiles_in_progress, active_compiles_count);
 						_log_active_compiles();
 						(*compiles_started_this_frame)++;
 					}
@@ -425,6 +438,9 @@ bool ShaderGLES3::_process_program_state(Version *p_version, bool p_async_forbid
 					if (p_version->compiling_list.in_list()) {
 						p_version->compiling_list.remove_from_list();
 						active_compiles_count--;
+#ifdef DEV_ENABLED
+						CRASH_COND(active_compiles_count == UINT32_MAX);
+#endif
 						_log_active_compiles();
 					}
 				}
@@ -818,6 +834,7 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version(bool &r_async_forbidden)
 			v.compile_status = Version::COMPILE_STATUS_PROCESSING_AT_QUEUE;
 			versions_compiling.add_last(&v.compiling_list);
 			active_compiles_count++;
+			*max_frame_compiles_in_progress = MAX(*max_frame_compiles_in_progress, active_compiles_count);
 			_log_active_compiles();
 			(*compiles_started_this_frame)++;
 
@@ -1065,13 +1082,18 @@ void ShaderGLES3::_dispose_program(Version *p_version) {
 	if (p_version->compiling_list.in_list()) {
 		p_version->compiling_list.remove_from_list();
 		active_compiles_count--;
+#ifdef DEV_ENABLED
+		CRASH_COND(active_compiles_count == UINT32_MAX);
+#endif
 		if (p_version->compile_status == Version::COMPILE_STATUS_COMPILING_VERTEX_AND_FRAGMENT) {
 			active_compiles_count--;
+#ifdef DEV_ENABLED
+			CRASH_COND(active_compiles_count == UINT32_MAX);
+#endif
 		}
 		_log_active_compiles();
 	}
 	p_version->compile_status = Version::COMPILE_STATUS_ERROR;
-	ERR_FAIL_COND(active_compiles_count < 0);
 }
 
 GLint ShaderGLES3::get_uniform_location(const String &p_name) const {

+ 4 - 4
drivers/gles3/shader_gles3.h

@@ -132,8 +132,10 @@ public:
 	static bool parallel_compile_supported; // True if using natively supported asyncrhonous compilation
 
 	static bool async_hidden_forbidden;
-	static int *compiles_started_this_frame;
-	static int max_simultaneous_compiles;
+	static uint32_t *compiles_started_this_frame;
+	static uint32_t *max_frame_compiles_in_progress;
+	static uint32_t max_simultaneous_compiles;
+	static uint32_t active_compiles_count;
 #ifdef DEBUG_ENABLED
 	static bool log_active_async_compiles_count;
 #endif
@@ -142,8 +144,6 @@ public:
 	static void advance_async_shaders_compilation();
 
 private:
-	static int active_compiles_count;
-
 	union VersionKey {
 		static const uint32_t UBERSHADER_FLAG = ((uint32_t)1) << 31;
 		struct {

+ 1 - 0
servers/visual_server.cpp

@@ -2465,6 +2465,7 @@ void VisualServer::_bind_methods() {
 	BIND_ENUM_CONSTANT(INFO_VERTICES_IN_FRAME);
 	BIND_ENUM_CONSTANT(INFO_MATERIAL_CHANGES_IN_FRAME);
 	BIND_ENUM_CONSTANT(INFO_SHADER_CHANGES_IN_FRAME);
+	BIND_ENUM_CONSTANT(INFO_SHADER_COMPILES_IN_FRAME);
 	BIND_ENUM_CONSTANT(INFO_SURFACE_CHANGES_IN_FRAME);
 	BIND_ENUM_CONSTANT(INFO_DRAW_CALLS_IN_FRAME);
 	BIND_ENUM_CONSTANT(INFO_2D_ITEMS_IN_FRAME);

+ 1 - 0
servers/visual_server.h

@@ -1147,6 +1147,7 @@ public:
 		INFO_VERTICES_IN_FRAME,
 		INFO_MATERIAL_CHANGES_IN_FRAME,
 		INFO_SHADER_CHANGES_IN_FRAME,
+		INFO_SHADER_COMPILES_IN_FRAME,
 		INFO_SURFACE_CHANGES_IN_FRAME,
 		INFO_DRAW_CALLS_IN_FRAME,
 		INFO_2D_ITEMS_IN_FRAME,