Add buffer orphan / stream options

Allows users to override default API usage, in order to get best performance on different platforms.

Also changes the default legacy flags to use STREAM rather than DYNAMIC.
This commit is contained in:
lawnjelly 2021-04-13 17:34:27 +01:00
parent c406f569aa
commit 2ffdfdfd1a
7 changed files with 108 additions and 15 deletions

View file

@ -1034,6 +1034,22 @@
Fix to improve physics jitter, specially on monitors where refresh rate is different than the physics FPS. 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. [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>
<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"> <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. 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. Not available in GLES3 when [member rendering/batching/options/use_batching] is off.

View file

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

View file

@ -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", true);
GLOBAL_DEF_RST("rendering/quality/lightmapping/use_bicubic_sampling.mobile", false); GLOBAL_DEF_RST("rendering/quality/lightmapping/use_bicubic_sampling.mobile", false);
config.use_lightmap_filter_bicubic = GLOBAL_GET("rendering/quality/lightmapping/use_bicubic_sampling"); 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() { void RasterizerStorageGLES2::finalize() {

View file

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

View file

@ -5105,11 +5105,13 @@ void RasterizerStorageGLES3::update_dirty_multimeshes() {
glBindBuffer(GL_ARRAY_BUFFER, multimesh->buffer); glBindBuffer(GL_ARRAY_BUFFER, multimesh->buffer);
uint32_t buffer_size = multimesh->data.size() * sizeof(float); uint32_t buffer_size = multimesh->data.size() * sizeof(float);
if (config.should_orphan) {
// 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); glBufferData(GL_ARRAY_BUFFER, buffer_size, multimesh->data.ptr(), GL_DYNAMIC_DRAW);
} else { // } else {
glBufferSubData(GL_ARRAY_BUFFER, 0, buffer_size, multimesh->data.ptr()); // glBufferSubData(GL_ARRAY_BUFFER, 0, buffer_size, multimesh->data.ptr());
} // }
glBindBuffer(GL_ARRAY_BUFFER, 0); 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() { void RasterizerStorageGLES3::finalize() {

View file

@ -1007,6 +1007,33 @@ PREAMBLE(void)::batch_initialize() {
bdata.settings_use_software_skinning = GLOBAL_GET("rendering/2d/options/use_software_skinning"); bdata.settings_use_software_skinning = GLOBAL_GET("rendering/2d/options/use_software_skinning");
bdata.settings_ninepatch_mode = GLOBAL_GET("rendering/2d/options/ninepatch_mode"); 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, // alternatively only enable uv contract if pixel snap in use,
// but with this enable bool, it should not be necessary // but with this enable bool, it should not be necessary
bdata.settings_uv_contract = GLOBAL_GET("rendering/batching/precision/uv_contract"); bdata.settings_uv_contract = GLOBAL_GET("rendering/batching/precision/uv_contract");

View file

@ -2454,6 +2454,15 @@ VisualServer::VisualServer() {
GLOBAL_DEF_RST("rendering/2d/options/ninepatch_mode", 1); 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")); 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("rendering/batching/options/use_batching", true);
GLOBAL_DEF_RST("rendering/batching/options/use_batching_in_editor", true); GLOBAL_DEF_RST("rendering/batching/options/use_batching_in_editor", true);
GLOBAL_DEF("rendering/batching/options/single_rect_fallback", false); GLOBAL_DEF("rendering/batching/options/single_rect_fallback", false);