Improve ubershader compatibility
- Prevent debug enforced use of ubershader on shaders not supporting it - Use unsigned integer for ubershader flags - Add project setting for disabling async shader compilation on mobile - Stop sampling some textures through different kinds of samplers at the same time
This commit is contained in:
parent
22166639ed
commit
0d1ec9a7cf
|
@ -1294,6 +1294,10 @@
|
||||||
To reduce loading times after the project has been launched at least once, you can use [code]Asynchronous + Cache[/code]. This also causes the ubershaders to be cached into storage so they can be ready faster next time they are used (provided the platform provides support for it).
|
To reduce loading times after the project has been launched at least once, you can use [code]Asynchronous + Cache[/code]. This also causes the ubershaders to be cached into storage so they can be ready faster next time they are used (provided the platform provides support for it).
|
||||||
[b]Note:[/b] Asynchronous compilation is currently only supported for spatial (3D) and particle materials/shaders. CanvasItem (2D) shaders will not use asynchronous compilation even if this setting is set to [code]Asynchronous[/code] or [code]Asynchronous + Cache[/code].
|
[b]Note:[/b] Asynchronous compilation is currently only supported for spatial (3D) and particle materials/shaders. CanvasItem (2D) shaders will not use asynchronous compilation even if this setting is set to [code]Asynchronous[/code] or [code]Asynchronous + Cache[/code].
|
||||||
</member>
|
</member>
|
||||||
|
<member name="rendering/gles3/shaders/shader_compilation_mode.mobile" type="int" setter="" getter="" default="0">
|
||||||
|
An override for [code]rendering/gles3/shaders/shader_compilation_mode[/code], so asynchronous compilation can be disabled for mobile.
|
||||||
|
You may want to do that since mobile GPUs generally won't support ubershaders due to their complexity.
|
||||||
|
</member>
|
||||||
<member name="rendering/limits/buffers/blend_shape_max_buffer_size_kb" type="int" setter="" getter="" default="4096">
|
<member name="rendering/limits/buffers/blend_shape_max_buffer_size_kb" type="int" setter="" getter="" default="4096">
|
||||||
Max buffer size for blend shapes. Any blend shape bigger than this will not work.
|
Max buffer size for blend shapes. Any blend shape bigger than this will not work.
|
||||||
</member>
|
</member>
|
||||||
|
|
|
@ -1819,7 +1819,14 @@ void RasterizerSceneGLES3::_setup_light(RenderList::Element *e, const Transform
|
||||||
GIProbeInstance *gipi = gi_probe_instance_owner.getptr(ridp[0]);
|
GIProbeInstance *gipi = gi_probe_instance_owner.getptr(ridp[0]);
|
||||||
|
|
||||||
float bias_scale = e->instance->baked_light ? 1 : 0;
|
float bias_scale = e->instance->baked_light ? 1 : 0;
|
||||||
|
// Normally, lightmapping uses the same texturing units than the GI probes; however, in the case of the ubershader
|
||||||
|
// that's not a good idea because some hardware/drivers (Android/Intel) may fail to render if a single texturing unit
|
||||||
|
// is used through multiple kinds of samplers in the same shader.
|
||||||
|
if (state.scene_shader.is_version_ubershader()) {
|
||||||
|
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 12);
|
||||||
|
} else {
|
||||||
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 10);
|
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 10);
|
||||||
|
}
|
||||||
glBindTexture(GL_TEXTURE_3D, gipi->tex_cache);
|
glBindTexture(GL_TEXTURE_3D, gipi->tex_cache);
|
||||||
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_XFORM1, gipi->transform_to_data * p_view_transform);
|
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_XFORM1, gipi->transform_to_data * p_view_transform);
|
||||||
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BOUNDS1, gipi->bounds);
|
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BOUNDS1, gipi->bounds);
|
||||||
|
@ -1831,7 +1838,11 @@ void RasterizerSceneGLES3::_setup_light(RenderList::Element *e, const Transform
|
||||||
if (gi_probe_count > 1) {
|
if (gi_probe_count > 1) {
|
||||||
GIProbeInstance *gipi2 = gi_probe_instance_owner.getptr(ridp[1]);
|
GIProbeInstance *gipi2 = gi_probe_instance_owner.getptr(ridp[1]);
|
||||||
|
|
||||||
|
if (state.scene_shader.is_version_ubershader()) {
|
||||||
|
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 13);
|
||||||
|
} else {
|
||||||
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 11);
|
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 11);
|
||||||
|
}
|
||||||
glBindTexture(GL_TEXTURE_3D, gipi2->tex_cache);
|
glBindTexture(GL_TEXTURE_3D, gipi2->tex_cache);
|
||||||
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_XFORM2, gipi2->transform_to_data * p_view_transform);
|
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_XFORM2, gipi2->transform_to_data * p_view_transform);
|
||||||
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BOUNDS2, gipi2->bounds);
|
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BOUNDS2, gipi2->bounds);
|
||||||
|
|
|
@ -123,7 +123,7 @@ bool ShaderGLES3::_bind(bool p_binding_fallback) {
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
if (ready) {
|
if (ready) {
|
||||||
if (VS::get_singleton()->is_force_shader_fallbacks_enabled() && !must_be_ready_now) {
|
if (VS::get_singleton()->is_force_shader_fallbacks_enabled() && !must_be_ready_now && get_ubershader_flags_uniform() != -1) {
|
||||||
ready = false;
|
ready = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,7 +160,7 @@ bool ShaderGLES3::_bind_ubershader() {
|
||||||
ERR_FAIL_COND_V(conditionals_uniform == -1, false);
|
ERR_FAIL_COND_V(conditionals_uniform == -1, false);
|
||||||
#endif
|
#endif
|
||||||
new_conditional_version.version &= ~VersionKey::UBERSHADER_FLAG;
|
new_conditional_version.version &= ~VersionKey::UBERSHADER_FLAG;
|
||||||
glUniform1i(conditionals_uniform, new_conditional_version.version);
|
glUniform1ui(conditionals_uniform, new_conditional_version.version);
|
||||||
return bound;
|
return bound;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,11 +454,11 @@ static CharString _prepare_ubershader_chunk(const CharString &p_chunk) {
|
||||||
} else if (l.begins_with("#ifdef")) {
|
} else if (l.begins_with("#ifdef")) {
|
||||||
Vector<String> pieces = l.split_spaces();
|
Vector<String> pieces = l.split_spaces();
|
||||||
CRASH_COND(pieces.size() != 2);
|
CRASH_COND(pieces.size() != 2);
|
||||||
s += "if ((ubershader_flags & FLAG_" + pieces[1] + ") != 0) {\n";
|
s += "if ((ubershader_flags & FLAG_" + pieces[1] + ") != 0u) {\n";
|
||||||
} else if (l.begins_with("#ifndef")) {
|
} else if (l.begins_with("#ifndef")) {
|
||||||
Vector<String> pieces = l.split_spaces();
|
Vector<String> pieces = l.split_spaces();
|
||||||
CRASH_COND(pieces.size() != 2);
|
CRASH_COND(pieces.size() != 2);
|
||||||
s += "if ((ubershader_flags & FLAG_" + pieces[1] + ") == 0) {\n";
|
s += "if ((ubershader_flags & FLAG_" + pieces[1] + ") == 0u) {\n";
|
||||||
} else {
|
} else {
|
||||||
CRASH_NOW_MSG("The shader template is using too complex syntax in a line marked with ubershader-runtime.");
|
CRASH_NOW_MSG("The shader template is using too complex syntax in a line marked with ubershader-runtime.");
|
||||||
}
|
}
|
||||||
|
@ -532,7 +532,7 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version(bool &r_async_forbidden)
|
||||||
if (build_ubershader) {
|
if (build_ubershader) {
|
||||||
strings_common.push_back("#define IS_UBERSHADER\n");
|
strings_common.push_back("#define IS_UBERSHADER\n");
|
||||||
for (int i = 0; i < conditional_count; i++) {
|
for (int i = 0; i < conditional_count; i++) {
|
||||||
String s = vformat("#define FLAG_%s (1 << %d)\n", String(conditional_defines[i]).strip_edges().trim_prefix("#define "), i);
|
String s = vformat("#define FLAG_%s (1u << %du)\n", String(conditional_defines[i]).strip_edges().trim_prefix("#define "), i);
|
||||||
CharString cs = s.ascii();
|
CharString cs = s.ascii();
|
||||||
flag_macros.push_back(cs);
|
flag_macros.push_back(cs);
|
||||||
strings_common.push_back(cs.ptr());
|
strings_common.push_back(cs.ptr());
|
||||||
|
|
|
@ -399,6 +399,7 @@ public:
|
||||||
void free_custom_shader(uint32_t p_code_id);
|
void free_custom_shader(uint32_t p_code_id);
|
||||||
|
|
||||||
uint32_t get_version() const { return new_conditional_version.version; }
|
uint32_t get_version() const { return new_conditional_version.version; }
|
||||||
|
bool is_version_ubershader() const { return (new_conditional_version.version & VersionKey::UBERSHADER_FLAG); }
|
||||||
_FORCE_INLINE_ bool is_version_valid() const { return version && version->compile_status == Version::COMPILE_STATUS_OK; }
|
_FORCE_INLINE_ bool is_version_valid() const { return version && version->compile_status == Version::COMPILE_STATUS_OK; }
|
||||||
|
|
||||||
virtual void init() = 0;
|
virtual void init() = 0;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
[vertex]
|
[vertex]
|
||||||
|
|
||||||
#if defined(IS_UBERSHADER)
|
#if defined(IS_UBERSHADER)
|
||||||
uniform highp int ubershader_flags;
|
uniform highp uint ubershader_flags;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
layout(location = 0) in highp vec4 color;
|
layout(location = 0) in highp vec4 color;
|
||||||
|
@ -222,7 +222,7 @@ VERTEX_SHADER_CODE
|
||||||
[fragment]
|
[fragment]
|
||||||
|
|
||||||
#if defined(IS_UBERSHADER)
|
#if defined(IS_UBERSHADER)
|
||||||
uniform highp int ubershader_flags;
|
uniform highp uint ubershader_flags;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// any code here is never executed, stuff is filled just so it works
|
// any code here is never executed, stuff is filled just so it works
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
[vertex]
|
[vertex]
|
||||||
|
|
||||||
#if defined(IS_UBERSHADER)
|
#if defined(IS_UBERSHADER)
|
||||||
uniform highp int ubershader_flags;
|
uniform highp uint ubershader_flags;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define M_PI 3.14159265359
|
#define M_PI 3.14159265359
|
||||||
|
@ -645,7 +645,7 @@ VERTEX_SHADER_CODE
|
||||||
[fragment]
|
[fragment]
|
||||||
|
|
||||||
#if defined(IS_UBERSHADER)
|
#if defined(IS_UBERSHADER)
|
||||||
uniform highp int ubershader_flags;
|
uniform highp uint ubershader_flags;
|
||||||
// These are more performant and make the ubershaderification simpler
|
// These are more performant and make the ubershaderification simpler
|
||||||
#define VCT_QUALITY_HIGH
|
#define VCT_QUALITY_HIGH
|
||||||
#define USE_LIGHTMAP_FILTER_BICUBIC
|
#define USE_LIGHTMAP_FILTER_BICUBIC
|
||||||
|
@ -1649,7 +1649,12 @@ uniform mediump vec4[12] lightmap_captures;
|
||||||
|
|
||||||
#ifdef USE_GI_PROBES //ubershader-skip
|
#ifdef USE_GI_PROBES //ubershader-skip
|
||||||
|
|
||||||
|
#if !defined(IS_UBERSHADER)
|
||||||
uniform mediump sampler3D gi_probe1; //texunit:-10
|
uniform mediump sampler3D gi_probe1; //texunit:-10
|
||||||
|
#else
|
||||||
|
uniform mediump sampler3D gi_probe1_uber; //texunit:-12
|
||||||
|
#define gi_probe1 gi_probe1_uber
|
||||||
|
#endif
|
||||||
uniform highp mat4 gi_probe_xform1;
|
uniform highp mat4 gi_probe_xform1;
|
||||||
uniform highp vec3 gi_probe_bounds1;
|
uniform highp vec3 gi_probe_bounds1;
|
||||||
uniform highp vec3 gi_probe_cell_size1;
|
uniform highp vec3 gi_probe_cell_size1;
|
||||||
|
@ -1658,7 +1663,12 @@ uniform highp float gi_probe_bias1;
|
||||||
uniform highp float gi_probe_normal_bias1;
|
uniform highp float gi_probe_normal_bias1;
|
||||||
uniform bool gi_probe_blend_ambient1;
|
uniform bool gi_probe_blend_ambient1;
|
||||||
|
|
||||||
|
#if !defined(IS_UBERSHADER)
|
||||||
uniform mediump sampler3D gi_probe2; //texunit:-11
|
uniform mediump sampler3D gi_probe2; //texunit:-11
|
||||||
|
#else
|
||||||
|
uniform mediump sampler3D gi_probe2_uber; //texunit:-13
|
||||||
|
#define gi_probe2 gi_probe2_uber
|
||||||
|
#endif
|
||||||
uniform highp mat4 gi_probe_xform2;
|
uniform highp mat4 gi_probe_xform2;
|
||||||
uniform highp vec3 gi_probe_bounds2;
|
uniform highp vec3 gi_probe_bounds2;
|
||||||
uniform highp vec3 gi_probe_cell_size2;
|
uniform highp vec3 gi_probe_cell_size2;
|
||||||
|
|
|
@ -2727,6 +2727,7 @@ VisualServer::VisualServer() {
|
||||||
#endif
|
#endif
|
||||||
GLOBAL_DEF("rendering/gles3/shaders/shader_compilation_mode", 0);
|
GLOBAL_DEF("rendering/gles3/shaders/shader_compilation_mode", 0);
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/gles3/shaders/shader_compilation_mode", PropertyInfo(Variant::INT, "rendering/gles3/shaders/shader_compilation_mode", PROPERTY_HINT_ENUM, "Synchronous,Asynchronous,Asynchronous + Cache"));
|
ProjectSettings::get_singleton()->set_custom_property_info("rendering/gles3/shaders/shader_compilation_mode", PropertyInfo(Variant::INT, "rendering/gles3/shaders/shader_compilation_mode", PROPERTY_HINT_ENUM, "Synchronous,Asynchronous,Asynchronous + Cache"));
|
||||||
|
GLOBAL_DEF("rendering/gles3/shaders/shader_compilation_mode.mobile", 0);
|
||||||
GLOBAL_DEF("rendering/gles3/shaders/max_simultaneous_compiles", 2);
|
GLOBAL_DEF("rendering/gles3/shaders/max_simultaneous_compiles", 2);
|
||||||
ProjectSettings::get_singleton()->set_custom_property_info("rendering/gles3/shaders/max_simultaneous_compiles", PropertyInfo(Variant::INT, "rendering/gles3/shaders/max_simultaneous_compiles", PROPERTY_HINT_RANGE, "1,8,1"));
|
ProjectSettings::get_singleton()->set_custom_property_info("rendering/gles3/shaders/max_simultaneous_compiles", PropertyInfo(Variant::INT, "rendering/gles3/shaders/max_simultaneous_compiles", PROPERTY_HINT_RANGE, "1,8,1"));
|
||||||
GLOBAL_DEF("rendering/gles3/shaders/max_simultaneous_compiles.mobile", 1);
|
GLOBAL_DEF("rendering/gles3/shaders/max_simultaneous_compiles.mobile", 1);
|
||||||
|
|
Loading…
Reference in New Issue