Skip to content

Commit

Permalink
Add buffer orphan / stream options
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
lawnjelly committed Apr 14, 2021
1 parent c406f56 commit 2ffdfdf
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 15 deletions.
16 changes: 16 additions & 0 deletions doc/classes/ProjectSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
17 changes: 12 additions & 5 deletions drivers/gles2/rasterizer_canvas_base_gles2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down
13 changes: 13 additions & 0 deletions drivers/gles2/rasterizer_storage_gles2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
16 changes: 11 additions & 5 deletions drivers/gles3/rasterizer_canvas_base_gles3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

{
Expand Down
25 changes: 20 additions & 5 deletions drivers/gles3/rasterizer_storage_gles3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down Expand Up @@ -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() {
Expand Down
27 changes: 27 additions & 0 deletions drivers/gles_common/rasterizer_canvas_batcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
9 changes: 9 additions & 0 deletions servers/visual_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 2ffdfdf

Please sign in to comment.