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).
|
||||
[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 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">
|
||||
Max buffer size for blend shapes. Any blend shape bigger than this will not work.
|
||||
</member>
|
||||
|
|
|
@ -1819,7 +1819,14 @@ void RasterizerSceneGLES3::_setup_light(RenderList::Element *e, const Transform
|
|||
GIProbeInstance *gipi = gi_probe_instance_owner.getptr(ridp[0]);
|
||||
|
||||
float bias_scale = e->instance->baked_light ? 1 : 0;
|
||||
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 10);
|
||||
// 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);
|
||||
}
|
||||
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_BOUNDS1, gipi->bounds);
|
||||
|
@ -1831,7 +1838,11 @@ void RasterizerSceneGLES3::_setup_light(RenderList::Element *e, const Transform
|
|||
if (gi_probe_count > 1) {
|
||||
GIProbeInstance *gipi2 = gi_probe_instance_owner.getptr(ridp[1]);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 11);
|
||||
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);
|
||||
}
|
||||
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_BOUNDS2, gipi2->bounds);
|
||||
|
|
|
@ -123,7 +123,7 @@ bool ShaderGLES3::_bind(bool p_binding_fallback) {
|
|||
|
||||
#ifdef DEBUG_ENABLED
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -160,7 +160,7 @@ bool ShaderGLES3::_bind_ubershader() {
|
|||
ERR_FAIL_COND_V(conditionals_uniform == -1, false);
|
||||
#endif
|
||||
new_conditional_version.version &= ~VersionKey::UBERSHADER_FLAG;
|
||||
glUniform1i(conditionals_uniform, new_conditional_version.version);
|
||||
glUniform1ui(conditionals_uniform, new_conditional_version.version);
|
||||
return bound;
|
||||
}
|
||||
|
||||
|
@ -454,11 +454,11 @@ static CharString _prepare_ubershader_chunk(const CharString &p_chunk) {
|
|||
} else if (l.begins_with("#ifdef")) {
|
||||
Vector<String> pieces = l.split_spaces();
|
||||
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")) {
|
||||
Vector<String> pieces = l.split_spaces();
|
||||
CRASH_COND(pieces.size() != 2);
|
||||
s += "if ((ubershader_flags & FLAG_" + pieces[1] + ") == 0) {\n";
|
||||
s += "if ((ubershader_flags & FLAG_" + pieces[1] + ") == 0u) {\n";
|
||||
} else {
|
||||
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) {
|
||||
strings_common.push_back("#define IS_UBERSHADER\n");
|
||||
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();
|
||||
flag_macros.push_back(cs);
|
||||
strings_common.push_back(cs.ptr());
|
||||
|
|
|
@ -399,6 +399,7 @@ public:
|
|||
void free_custom_shader(uint32_t p_code_id);
|
||||
|
||||
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; }
|
||||
|
||||
virtual void init() = 0;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
[vertex]
|
||||
|
||||
#if defined(IS_UBERSHADER)
|
||||
uniform highp int ubershader_flags;
|
||||
uniform highp uint ubershader_flags;
|
||||
#endif
|
||||
|
||||
layout(location = 0) in highp vec4 color;
|
||||
|
@ -222,7 +222,7 @@ VERTEX_SHADER_CODE
|
|||
[fragment]
|
||||
|
||||
#if defined(IS_UBERSHADER)
|
||||
uniform highp int ubershader_flags;
|
||||
uniform highp uint ubershader_flags;
|
||||
#endif
|
||||
|
||||
// any code here is never executed, stuff is filled just so it works
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
[vertex]
|
||||
|
||||
#if defined(IS_UBERSHADER)
|
||||
uniform highp int ubershader_flags;
|
||||
uniform highp uint ubershader_flags;
|
||||
#endif
|
||||
|
||||
#define M_PI 3.14159265359
|
||||
|
@ -645,7 +645,7 @@ VERTEX_SHADER_CODE
|
|||
[fragment]
|
||||
|
||||
#if defined(IS_UBERSHADER)
|
||||
uniform highp int ubershader_flags;
|
||||
uniform highp uint ubershader_flags;
|
||||
// These are more performant and make the ubershaderification simpler
|
||||
#define VCT_QUALITY_HIGH
|
||||
#define USE_LIGHTMAP_FILTER_BICUBIC
|
||||
|
@ -1649,7 +1649,12 @@ uniform mediump vec4[12] lightmap_captures;
|
|||
|
||||
#ifdef USE_GI_PROBES //ubershader-skip
|
||||
|
||||
#if !defined(IS_UBERSHADER)
|
||||
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 vec3 gi_probe_bounds1;
|
||||
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 bool gi_probe_blend_ambient1;
|
||||
|
||||
#if !defined(IS_UBERSHADER)
|
||||
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 vec3 gi_probe_bounds2;
|
||||
uniform highp vec3 gi_probe_cell_size2;
|
||||
|
|
|
@ -2727,6 +2727,7 @@ VisualServer::VisualServer() {
|
|||
#endif
|
||||
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"));
|
||||
GLOBAL_DEF("rendering/gles3/shaders/shader_compilation_mode.mobile", 0);
|
||||
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"));
|
||||
GLOBAL_DEF("rendering/gles3/shaders/max_simultaneous_compiles.mobile", 1);
|
||||
|
|
Loading…
Reference in New Issue