Browse Source

Merge pull request #47864 from lawnjelly/orphan_options

Add buffer orphan / stream options
Rémi Verschelde 4 years ago
parent
commit
4a942afb9b

+ 16 - 0
doc/classes/ProjectSettings.xml

@@ -1034,6 +1034,22 @@
 			Fix to improve physics jitter, specially on monitors where refresh rate is different than the physics FPS.
 			[b]Note:[/b] This property is only read when the project starts. To change the physics FPS at runtime, set [member Engine.physics_jitter_fix] instead.
 		</member>
+		<member name="rendering/2d/opengl/batching_send_null" type="int" setter="" getter="" default="0">
+			[b]Experimental[/b] Calls [code]glBufferData[/code] with NULL data prior to uploading batching data. This may not be necessary but can be used for safety.
+			[b]Note:[/b] Use with care. You are advised to leave this as default for exports. A non-default setting that works better on your machine may adversely affect performance for end users.
+		</member>
+		<member name="rendering/2d/opengl/batching_stream" type="int" setter="" getter="" default="0">
+			[b]Experimental[/b] If set to on, uses the [code]GL_STREAM_DRAW[/code] flag for batching buffer uploads. If off, uses the [code]GL_DYNAMIC_DRAW[/code] flag.
+			[b]Note:[/b] Use with care. You are advised to leave this as default for exports. A non-default setting that works better on your machine may adversely affect performance for end users.
+		</member>
+		<member name="rendering/2d/opengl/legacy_orphan_buffers" type="int" setter="" getter="" default="0">
+			[b]Experimental[/b] If set to on, this applies buffer orphaning - [code]glBufferData[/code] is called with NULL data and the full buffer size prior to uploading new data. This can be important to avoid stalling on some hardware.
+			[b]Note:[/b] Use with care. You are advised to leave this as default for exports. A non-default setting that works better on your machine may adversely affect performance for end users.
+		</member>
+		<member name="rendering/2d/opengl/legacy_stream" type="int" setter="" getter="" default="0">
+			[b]Experimental[/b] If set to on, uses the [code]GL_STREAM_DRAW[/code] flag for legacy buffer uploads. If off, uses the [code]GL_DYNAMIC_DRAW[/code] flag.
+			[b]Note:[/b] Use with care. You are advised to leave this as default for exports. A non-default setting that works better on your machine may adversely affect performance for end users.
+		</member>
 		<member name="rendering/2d/options/ninepatch_mode" type="int" setter="" getter="" default="1">
 			Choose between fixed mode where corner scalings are preserved matching the artwork, and scaling mode.
 			Not available in GLES3 when [member rendering/batching/options/use_batching] is off.

+ 12 - 5
drivers/gles2/rasterizer_canvas_base_gles2.cpp

@@ -947,11 +947,18 @@ void RasterizerCanvasBaseGLES2::draw_lens_distortion_rect(const Rect2 &p_rect, f
 
 void RasterizerCanvasBaseGLES2::initialize() {
 
-	bool flag_stream = false;
-	if (flag_stream)
-		_buffer_upload_usage_flag = GL_STREAM_DRAW;
-	else
-		_buffer_upload_usage_flag = GL_DYNAMIC_DRAW;
+	int flag_stream_mode = GLOBAL_GET("rendering/2d/opengl/legacy_stream");
+	switch (flag_stream_mode) {
+		default: {
+			_buffer_upload_usage_flag = GL_STREAM_DRAW;
+		} break;
+		case 1: {
+			_buffer_upload_usage_flag = GL_DYNAMIC_DRAW;
+		} break;
+		case 2: {
+			_buffer_upload_usage_flag = GL_STREAM_DRAW;
+		} break;
+	}
 
 	// quad buffer
 	{

+ 13 - 0
drivers/gles2/rasterizer_storage_gles2.cpp

@@ -6420,6 +6420,19 @@ void RasterizerStorageGLES2::initialize() {
 	GLOBAL_DEF_RST("rendering/quality/lightmapping/use_bicubic_sampling", true);
 	GLOBAL_DEF_RST("rendering/quality/lightmapping/use_bicubic_sampling.mobile", false);
 	config.use_lightmap_filter_bicubic = GLOBAL_GET("rendering/quality/lightmapping/use_bicubic_sampling");
+
+	int orphan_mode = GLOBAL_GET("rendering/2d/opengl/legacy_orphan_buffers");
+	switch (orphan_mode) {
+		default: {
+			config.should_orphan = true;
+		} break;
+		case 1: {
+			config.should_orphan = false;
+		} break;
+		case 2: {
+			config.should_orphan = true;
+		} break;
+	}
 }
 
 void RasterizerStorageGLES2::finalize() {

+ 11 - 5
drivers/gles3/rasterizer_canvas_base_gles3.cpp

@@ -1137,11 +1137,17 @@ void RasterizerCanvasBaseGLES3::draw_window_margins(int *black_margin, RID *blac
 
 void RasterizerCanvasBaseGLES3::initialize() {
 
-	bool flag_stream = false;
-	if (flag_stream) {
-		_buffer_upload_usage_flag = GL_STREAM_DRAW;
-	} else {
-		_buffer_upload_usage_flag = GL_DYNAMIC_DRAW;
+	int flag_stream_mode = GLOBAL_GET("rendering/2d/opengl/legacy_stream");
+	switch (flag_stream_mode) {
+		default: {
+			_buffer_upload_usage_flag = GL_STREAM_DRAW;
+		} break;
+		case 1: {
+			_buffer_upload_usage_flag = GL_DYNAMIC_DRAW;
+		} break;
+		case 2: {
+			_buffer_upload_usage_flag = GL_STREAM_DRAW;
+		} break;
 	}
 
 	{

+ 20 - 5
drivers/gles3/rasterizer_storage_gles3.cpp

@@ -5105,11 +5105,13 @@ void RasterizerStorageGLES3::update_dirty_multimeshes() {
 
 			glBindBuffer(GL_ARRAY_BUFFER, multimesh->buffer);
 			uint32_t buffer_size = multimesh->data.size() * sizeof(float);
-			if (config.should_orphan) {
-				glBufferData(GL_ARRAY_BUFFER, buffer_size, multimesh->data.ptr(), GL_DYNAMIC_DRAW);
-			} else {
-				glBufferSubData(GL_ARRAY_BUFFER, 0, buffer_size, multimesh->data.ptr());
-			}
+
+			// this could potentially have a project setting for API options as with 2d
+			// if (config.should_orphan) {
+			glBufferData(GL_ARRAY_BUFFER, buffer_size, multimesh->data.ptr(), GL_DYNAMIC_DRAW);
+			//	} else {
+			//	glBufferSubData(GL_ARRAY_BUFFER, 0, buffer_size, multimesh->data.ptr());
+			//	}
 			glBindBuffer(GL_ARRAY_BUFFER, 0);
 		}
 
@@ -8652,6 +8654,19 @@ void RasterizerStorageGLES3::initialize() {
 			}
 		}
 	}
+
+	int orphan_mode = GLOBAL_GET("rendering/2d/opengl/legacy_orphan_buffers");
+	switch (orphan_mode) {
+		default: {
+			config.should_orphan = true;
+		} break;
+		case 1: {
+			config.should_orphan = false;
+		} break;
+		case 2: {
+			config.should_orphan = true;
+		} break;
+	}
 }
 
 void RasterizerStorageGLES3::finalize() {

+ 27 - 0
drivers/gles_common/rasterizer_canvas_batcher.h

@@ -1007,6 +1007,33 @@ PREAMBLE(void)::batch_initialize() {
 	bdata.settings_use_software_skinning = GLOBAL_GET("rendering/2d/options/use_software_skinning");
 	bdata.settings_ninepatch_mode = GLOBAL_GET("rendering/2d/options/ninepatch_mode");
 
+	// allow user to override the api usage techniques using project settings
+	int send_null_mode = GLOBAL_GET("rendering/2d/opengl/batching_send_null");
+	switch (send_null_mode) {
+		default: {
+			bdata.buffer_mode_batch_upload_send_null = true;
+		} break;
+		case 1: {
+			bdata.buffer_mode_batch_upload_send_null = false;
+		} break;
+		case 2: {
+			bdata.buffer_mode_batch_upload_send_null = true;
+		} break;
+	}
+
+	int stream_mode = GLOBAL_GET("rendering/2d/opengl/batching_stream");
+	switch (stream_mode) {
+		default: {
+			bdata.buffer_mode_batch_upload_flag_stream = false;
+		} break;
+		case 1: {
+			bdata.buffer_mode_batch_upload_flag_stream = false;
+		} break;
+		case 2: {
+			bdata.buffer_mode_batch_upload_flag_stream = true;
+		} break;
+	}
+
 	// alternatively only enable uv contract if pixel snap in use,
 	// but with this enable bool, it should not be necessary
 	bdata.settings_uv_contract = GLOBAL_GET("rendering/batching/precision/uv_contract");

+ 9 - 0
servers/visual_server.cpp

@@ -2454,6 +2454,15 @@ VisualServer::VisualServer() {
 	GLOBAL_DEF_RST("rendering/2d/options/ninepatch_mode", 1);
 	ProjectSettings::get_singleton()->set_custom_property_info("rendering/2d/options/ninepatch_mode", PropertyInfo(Variant::INT, "rendering/2d/options/ninepatch_mode", PROPERTY_HINT_ENUM, "Fixed,Scaling"));
 
+	GLOBAL_DEF_RST("rendering/2d/opengl/batching_send_null", 0);
+	ProjectSettings::get_singleton()->set_custom_property_info("rendering/2d/opengl/batching_send_null", PropertyInfo(Variant::INT, "rendering/2d/opengl/batching_send_null", PROPERTY_HINT_ENUM, "Default (On),Off,On"));
+	GLOBAL_DEF_RST("rendering/2d/opengl/batching_stream", 0);
+	ProjectSettings::get_singleton()->set_custom_property_info("rendering/2d/opengl/batching_stream", PropertyInfo(Variant::INT, "rendering/2d/opengl/batching_stream", PROPERTY_HINT_ENUM, "Default (Off),Off,On"));
+	GLOBAL_DEF_RST("rendering/2d/opengl/legacy_orphan_buffers", 0);
+	ProjectSettings::get_singleton()->set_custom_property_info("rendering/2d/opengl/legacy_orphan_buffers", PropertyInfo(Variant::INT, "rendering/2d/opengl/legacy_orphan_buffers", PROPERTY_HINT_ENUM, "Default (On),Off,On"));
+	GLOBAL_DEF_RST("rendering/2d/opengl/legacy_stream", 0);
+	ProjectSettings::get_singleton()->set_custom_property_info("rendering/2d/opengl/legacy_stream", PropertyInfo(Variant::INT, "rendering/2d/opengl/legacy_stream", PROPERTY_HINT_ENUM, "Default (On),Off,On"));
+
 	GLOBAL_DEF("rendering/batching/options/use_batching", true);
 	GLOBAL_DEF_RST("rendering/batching/options/use_batching_in_editor", true);
 	GLOBAL_DEF("rendering/batching/options/single_rect_fallback", false);