You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-12-04 17:04:49 +00:00
Optimize Mobile renderer by using FP16 explicitly.
This commit is contained in:
@@ -380,6 +380,14 @@ uint32_t RenderForwardMobile::get_pipeline_compilations(RS::PipelineSource p_sou
|
||||
}
|
||||
|
||||
void RenderForwardMobile::enable_features(BitField<FeatureBits> p_feature_bits) {
|
||||
if (p_feature_bits.has_flag(FEATURE_FP32_BIT)) {
|
||||
scene_shader.enable_fp32_shader_group();
|
||||
}
|
||||
|
||||
if (p_feature_bits.has_flag(FEATURE_FP16_BIT)) {
|
||||
scene_shader.enable_fp16_shader_group();
|
||||
}
|
||||
|
||||
if (p_feature_bits.has_flag(FEATURE_MULTIVIEW_BIT)) {
|
||||
scene_shader.enable_multiview_shader_group();
|
||||
}
|
||||
|
||||
@@ -381,7 +381,7 @@ RID SceneShaderForwardMobile::ShaderData::get_shader_variant(ShaderVersion p_sha
|
||||
if (version.is_valid()) {
|
||||
MutexLock lock(SceneShaderForwardMobile::singleton_mutex);
|
||||
ERR_FAIL_NULL_V(SceneShaderForwardMobile::singleton, RID());
|
||||
return SceneShaderForwardMobile::singleton->shader.version_get_shader(version, p_shader_version + (p_ubershader ? SHADER_VERSION_MAX : 0));
|
||||
return SceneShaderForwardMobile::singleton->shader.version_get_shader(version, p_shader_version + (SceneShaderForwardMobile::singleton->use_fp16 ? SHADER_VERSION_MAX * 2 : 0) + (p_ubershader ? SHADER_VERSION_MAX : 0));
|
||||
} else {
|
||||
return RID();
|
||||
}
|
||||
@@ -389,6 +389,7 @@ RID SceneShaderForwardMobile::ShaderData::get_shader_variant(ShaderVersion p_sha
|
||||
|
||||
uint64_t SceneShaderForwardMobile::ShaderData::get_vertex_input_mask(ShaderVersion p_shader_version, bool p_ubershader) {
|
||||
// Vertex input masks require knowledge of the shader. Since querying the shader can be expensive due to high contention and the necessary mutex, we cache the result instead.
|
||||
// It is intentional for the range of the input masks to be different than the versions available in the shaders as it'll only ever use the regular variants or the FP16 ones.
|
||||
uint32_t input_mask_index = p_shader_version + (p_ubershader ? SHADER_VERSION_MAX : 0);
|
||||
uint64_t input_mask = vertex_input_masks[input_mask_index].load(std::memory_order_relaxed);
|
||||
if (input_mask == 0) {
|
||||
@@ -446,7 +447,8 @@ void SceneShaderForwardMobile::MaterialData::set_next_pass(RID p_pass) {
|
||||
bool SceneShaderForwardMobile::MaterialData::update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
|
||||
if (shader_data->version.is_valid()) {
|
||||
MutexLock lock(SceneShaderForwardMobile::singleton_mutex);
|
||||
return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, SceneShaderForwardMobile::singleton->shader.version_get_shader(shader_data->version, 0), RenderForwardMobile::MATERIAL_UNIFORM_SET, true, true);
|
||||
RID base_shader = SceneShaderForwardMobile::singleton->shader.version_get_shader(shader_data->version, (SceneShaderForwardMobile::singleton->use_fp16 ? SHADER_VERSION_MAX * 2 : 0));
|
||||
return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, base_shader, RenderForwardMobile::MATERIAL_UNIFORM_SET, true, true);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -476,6 +478,9 @@ SceneShaderForwardMobile::SceneShaderForwardMobile() {
|
||||
void SceneShaderForwardMobile::init(const String p_defines) {
|
||||
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
|
||||
|
||||
// Store whether the shader will prefer using the FP16 variant.
|
||||
use_fp16 = RD::get_singleton()->has_feature(RD::SUPPORTS_HALF_FLOAT);
|
||||
|
||||
// Immutable samplers : create the shadow sampler to be passed when creating the pipeline.
|
||||
{
|
||||
RD::SamplerState sampler;
|
||||
@@ -490,19 +495,26 @@ void SceneShaderForwardMobile::init(const String p_defines) {
|
||||
|
||||
{
|
||||
Vector<ShaderRD::VariantDefine> shader_versions;
|
||||
for (uint32_t ubershader = 0; ubershader < 2; ubershader++) {
|
||||
const String base_define = ubershader ? "\n#define UBERSHADER\n" : "";
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(SHADER_GROUP_BASE, base_define + "", true)); // SHADER_VERSION_COLOR_PASS
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(SHADER_GROUP_BASE, base_define + "\n#define USE_LIGHTMAP\n", true)); // SHADER_VERSION_LIGHTMAP_COLOR_PASS
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(SHADER_GROUP_BASE, base_define + "\n#define MODE_RENDER_DEPTH\n#define SHADOW_PASS\n", true)); // SHADER_VERSION_SHADOW_PASS, should probably change this to MODE_RENDER_SHADOW because we don't have a depth pass here...
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(SHADER_GROUP_BASE, base_define + "\n#define MODE_RENDER_DEPTH\n#define MODE_DUAL_PARABOLOID\n#define SHADOW_PASS\n", true)); // SHADER_VERSION_SHADOW_PASS_DP
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(SHADER_GROUP_BASE, base_define + "\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_MATERIAL\n", true)); // SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL
|
||||
for (uint32_t fp16 = 0; fp16 < 2; fp16++) {
|
||||
for (uint32_t ubershader = 0; ubershader < 2; ubershader++) {
|
||||
String base_define = fp16 ? "\n#define EXPLICIT_FP16\n" : "";
|
||||
int shader_group = fp16 ? SHADER_GROUP_FP16 : SHADER_GROUP_FP32;
|
||||
int shader_group_multiview = fp16 ? SHADER_GROUP_FP16_MULTIVIEW : SHADER_GROUP_FP32_MULTIVIEW;
|
||||
base_define += ubershader ? "\n#define UBERSHADER\n" : "";
|
||||
|
||||
// Multiview versions of our shaders.
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(SHADER_GROUP_MULTIVIEW, base_define + "\n#define USE_MULTIVIEW\n", false)); // SHADER_VERSION_COLOR_PASS_MULTIVIEW
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(SHADER_GROUP_MULTIVIEW, base_define + "\n#define USE_MULTIVIEW\n#define USE_LIGHTMAP\n", false)); // SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(SHADER_GROUP_MULTIVIEW, base_define + "\n#define USE_MULTIVIEW\n#define MODE_RENDER_DEPTH\n#define SHADOW_PASS\n", false)); // SHADER_VERSION_SHADOW_PASS_MULTIVIEW
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(SHADER_GROUP_MULTIVIEW, base_define + "\n#define USE_MULTIVIEW\n#define MODE_RENDER_MOTION_VECTORS\n", false)); // SHADER_VERSION_MOTION_VECTORS_MULTIVIEW
|
||||
bool default_enabled = (uint32_t(use_fp16) == fp16);
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(shader_group, base_define + "", default_enabled)); // SHADER_VERSION_COLOR_PASS
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(shader_group, base_define + "\n#define USE_LIGHTMAP\n", default_enabled)); // SHADER_VERSION_LIGHTMAP_COLOR_PASS
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(shader_group, base_define + "\n#define MODE_RENDER_DEPTH\n#define SHADOW_PASS\n", default_enabled)); // SHADER_VERSION_SHADOW_PASS, should probably change this to MODE_RENDER_SHADOW because we don't have a depth pass here...
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(shader_group, base_define + "\n#define MODE_RENDER_DEPTH\n#define MODE_DUAL_PARABOLOID\n#define SHADOW_PASS\n", default_enabled)); // SHADER_VERSION_SHADOW_PASS_DP
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(shader_group, base_define + "\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_MATERIAL\n", default_enabled)); // SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL
|
||||
|
||||
// Multiview versions of our shaders.
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(shader_group_multiview, base_define + "\n#define USE_MULTIVIEW\n", false)); // SHADER_VERSION_COLOR_PASS_MULTIVIEW
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(shader_group_multiview, base_define + "\n#define USE_MULTIVIEW\n#define USE_LIGHTMAP\n", false)); // SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(shader_group_multiview, base_define + "\n#define USE_MULTIVIEW\n#define MODE_RENDER_DEPTH\n#define SHADOW_PASS\n", false)); // SHADER_VERSION_SHADOW_PASS_MULTIVIEW
|
||||
shader_versions.push_back(ShaderRD::VariantDefine(shader_group_multiview, base_define + "\n#define USE_MULTIVIEW\n#define MODE_RENDER_MOTION_VECTORS\n", false)); // SHADER_VERSION_MOTION_VECTORS_MULTIVIEW
|
||||
}
|
||||
}
|
||||
|
||||
Vector<RD::PipelineImmutableSampler> immutable_samplers;
|
||||
@@ -514,7 +526,7 @@ void SceneShaderForwardMobile::init(const String p_defines) {
|
||||
shader.initialize(shader_versions, p_defines, immutable_samplers);
|
||||
|
||||
if (RendererCompositorRD::get_singleton()->is_xr_enabled()) {
|
||||
shader.enable_group(SHADER_GROUP_MULTIVIEW);
|
||||
enable_multiview_shader_group();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -536,21 +548,21 @@ void SceneShaderForwardMobile::init(const String p_defines) {
|
||||
actions.renames["MAIN_CAM_INV_VIEW_MATRIX"] = "scene_data.main_cam_inv_view_matrix";
|
||||
|
||||
actions.renames["VERTEX"] = "vertex";
|
||||
actions.renames["NORMAL"] = "normal";
|
||||
actions.renames["TANGENT"] = "tangent";
|
||||
actions.renames["BINORMAL"] = "binormal";
|
||||
actions.renames["NORMAL"] = "normal_highp";
|
||||
actions.renames["TANGENT"] = "tangent_highp";
|
||||
actions.renames["BINORMAL"] = "binormal_highp";
|
||||
actions.renames["POSITION"] = "position";
|
||||
actions.renames["UV"] = "uv_interp";
|
||||
actions.renames["UV2"] = "uv2_interp";
|
||||
actions.renames["COLOR"] = "color_interp";
|
||||
actions.renames["COLOR"] = "color_highp";
|
||||
actions.renames["POINT_SIZE"] = "gl_PointSize";
|
||||
actions.renames["INSTANCE_ID"] = "gl_InstanceIndex";
|
||||
actions.renames["VERTEX_ID"] = "gl_VertexIndex";
|
||||
actions.renames["Z_CLIP_SCALE"] = "z_clip_scale";
|
||||
|
||||
actions.renames["ALPHA_SCISSOR_THRESHOLD"] = "alpha_scissor_threshold";
|
||||
actions.renames["ALPHA_HASH_SCALE"] = "alpha_hash_scale";
|
||||
actions.renames["ALPHA_ANTIALIASING_EDGE"] = "alpha_antialiasing_edge";
|
||||
actions.renames["ALPHA_SCISSOR_THRESHOLD"] = "alpha_scissor_threshold_highp";
|
||||
actions.renames["ALPHA_HASH_SCALE"] = "alpha_hash_scale_highp";
|
||||
actions.renames["ALPHA_ANTIALIASING_EDGE"] = "alpha_antialiasing_edge_highp";
|
||||
actions.renames["ALPHA_TEXTURE_COORDINATE"] = "alpha_texture_coordinate";
|
||||
|
||||
//builtins
|
||||
@@ -567,36 +579,36 @@ void SceneShaderForwardMobile::init(const String p_defines) {
|
||||
|
||||
actions.renames["FRAGCOORD"] = "gl_FragCoord";
|
||||
actions.renames["FRONT_FACING"] = "gl_FrontFacing";
|
||||
actions.renames["NORMAL_MAP"] = "normal_map";
|
||||
actions.renames["NORMAL_MAP_DEPTH"] = "normal_map_depth";
|
||||
actions.renames["BENT_NORMAL_MAP"] = "bent_normal_map";
|
||||
actions.renames["ALBEDO"] = "albedo";
|
||||
actions.renames["ALPHA"] = "alpha";
|
||||
actions.renames["PREMUL_ALPHA_FACTOR"] = "premul_alpha";
|
||||
actions.renames["METALLIC"] = "metallic";
|
||||
actions.renames["SPECULAR"] = "specular";
|
||||
actions.renames["ROUGHNESS"] = "roughness";
|
||||
actions.renames["RIM"] = "rim";
|
||||
actions.renames["RIM_TINT"] = "rim_tint";
|
||||
actions.renames["CLEARCOAT"] = "clearcoat";
|
||||
actions.renames["CLEARCOAT_ROUGHNESS"] = "clearcoat_roughness";
|
||||
actions.renames["ANISOTROPY"] = "anisotropy";
|
||||
actions.renames["ANISOTROPY_FLOW"] = "anisotropy_flow";
|
||||
actions.renames["SSS_STRENGTH"] = "sss_strength";
|
||||
actions.renames["SSS_TRANSMITTANCE_COLOR"] = "transmittance_color";
|
||||
actions.renames["SSS_TRANSMITTANCE_DEPTH"] = "transmittance_depth";
|
||||
actions.renames["SSS_TRANSMITTANCE_BOOST"] = "transmittance_boost";
|
||||
actions.renames["BACKLIGHT"] = "backlight";
|
||||
actions.renames["AO"] = "ao";
|
||||
actions.renames["AO_LIGHT_AFFECT"] = "ao_light_affect";
|
||||
actions.renames["EMISSION"] = "emission";
|
||||
actions.renames["NORMAL_MAP"] = "normal_map_highp";
|
||||
actions.renames["NORMAL_MAP_DEPTH"] = "normal_map_depth_highp";
|
||||
actions.renames["BENT_NORMAL_MAP"] = "bent_normal_map_highp";
|
||||
actions.renames["ALBEDO"] = "albedo_highp";
|
||||
actions.renames["ALPHA"] = "alpha_highp";
|
||||
actions.renames["PREMUL_ALPHA_FACTOR"] = "premul_alpha_highp";
|
||||
actions.renames["METALLIC"] = "metallic_highp";
|
||||
actions.renames["SPECULAR"] = "specular_highp";
|
||||
actions.renames["ROUGHNESS"] = "roughness_highp";
|
||||
actions.renames["RIM"] = "rim_highp";
|
||||
actions.renames["RIM_TINT"] = "rim_tint_highp";
|
||||
actions.renames["CLEARCOAT"] = "clearcoat_highp";
|
||||
actions.renames["CLEARCOAT_ROUGHNESS"] = "clearcoat_roughness_highp";
|
||||
actions.renames["ANISOTROPY"] = "anisotropy_highp";
|
||||
actions.renames["ANISOTROPY_FLOW"] = "anisotropy_flow_highp";
|
||||
actions.renames["SSS_STRENGTH"] = "sss_strength_highp";
|
||||
actions.renames["SSS_TRANSMITTANCE_COLOR"] = "transmittance_color_highp";
|
||||
actions.renames["SSS_TRANSMITTANCE_DEPTH"] = "transmittance_depth_highp";
|
||||
actions.renames["SSS_TRANSMITTANCE_BOOST"] = "transmittance_boost_highp";
|
||||
actions.renames["BACKLIGHT"] = "backlight_highp";
|
||||
actions.renames["AO"] = "ao_highp";
|
||||
actions.renames["AO_LIGHT_AFFECT"] = "ao_light_affect_highp";
|
||||
actions.renames["EMISSION"] = "emission_highp";
|
||||
actions.renames["POINT_COORD"] = "gl_PointCoord";
|
||||
actions.renames["INSTANCE_CUSTOM"] = "instance_custom";
|
||||
actions.renames["SCREEN_UV"] = "screen_uv";
|
||||
actions.renames["DEPTH"] = "gl_FragDepth";
|
||||
actions.renames["FOG"] = "fog";
|
||||
actions.renames["RADIANCE"] = "custom_radiance";
|
||||
actions.renames["IRRADIANCE"] = "custom_irradiance";
|
||||
actions.renames["FOG"] = "fog_highp";
|
||||
actions.renames["RADIANCE"] = "custom_radiance_highp";
|
||||
actions.renames["IRRADIANCE"] = "custom_irradiance_highp";
|
||||
actions.renames["BONE_INDICES"] = "bone_attrib";
|
||||
actions.renames["BONE_WEIGHTS"] = "weight_attrib";
|
||||
actions.renames["CUSTOM0"] = "custom0_attrib";
|
||||
@@ -617,14 +629,14 @@ void SceneShaderForwardMobile::init(const String p_defines) {
|
||||
actions.renames["EYE_OFFSET"] = "eye_offset";
|
||||
|
||||
//for light
|
||||
actions.renames["VIEW"] = "view";
|
||||
actions.renames["SPECULAR_AMOUNT"] = "specular_amount";
|
||||
actions.renames["LIGHT_COLOR"] = "light_color";
|
||||
actions.renames["VIEW"] = "view_highp";
|
||||
actions.renames["SPECULAR_AMOUNT"] = "specular_amount_highp";
|
||||
actions.renames["LIGHT_COLOR"] = "light_color_highp";
|
||||
actions.renames["LIGHT_IS_DIRECTIONAL"] = "is_directional";
|
||||
actions.renames["LIGHT"] = "light";
|
||||
actions.renames["ATTENUATION"] = "attenuation";
|
||||
actions.renames["DIFFUSE_LIGHT"] = "diffuse_light";
|
||||
actions.renames["SPECULAR_LIGHT"] = "specular_light";
|
||||
actions.renames["LIGHT"] = "light_highp";
|
||||
actions.renames["ATTENUATION"] = "attenuation_highp";
|
||||
actions.renames["DIFFUSE_LIGHT"] = "diffuse_light_highp";
|
||||
actions.renames["SPECULAR_LIGHT"] = "specular_light_highp";
|
||||
|
||||
actions.usage_defines["NORMAL"] = "#define NORMAL_USED\n";
|
||||
actions.usage_defines["TANGENT"] = "#define TANGENT_USED\n";
|
||||
@@ -749,7 +761,7 @@ void fragment() {
|
||||
material_storage->material_set_shader(default_material, default_shader);
|
||||
|
||||
MaterialData *md = static_cast<MaterialData *>(material_storage->material_get_data(default_material, RendererRD::MaterialStorage::SHADER_TYPE_3D));
|
||||
default_shader_rd = shader.version_get_shader(md->shader_data->version, SHADER_VERSION_COLOR_PASS);
|
||||
default_shader_rd = shader.version_get_shader(md->shader_data->version, (use_fp16 ? SHADER_VERSION_MAX * 2 : 0) + SHADER_VERSION_COLOR_PASS);
|
||||
|
||||
default_material_shader_ptr = md->shader_data;
|
||||
default_material_uniform_set = md->uniform_set;
|
||||
@@ -830,12 +842,34 @@ uint32_t SceneShaderForwardMobile::get_pipeline_compilations(RS::PipelineSource
|
||||
return pipeline_compilations[p_source];
|
||||
}
|
||||
|
||||
void SceneShaderForwardMobile::enable_fp32_shader_group() {
|
||||
shader.enable_group(SHADER_GROUP_FP32);
|
||||
|
||||
if (is_multiview_shader_group_enabled()) {
|
||||
enable_multiview_shader_group();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneShaderForwardMobile::enable_fp16_shader_group() {
|
||||
shader.enable_group(SHADER_GROUP_FP16);
|
||||
|
||||
if (is_multiview_shader_group_enabled()) {
|
||||
enable_multiview_shader_group();
|
||||
}
|
||||
}
|
||||
|
||||
void SceneShaderForwardMobile::enable_multiview_shader_group() {
|
||||
shader.enable_group(SHADER_GROUP_MULTIVIEW);
|
||||
if (shader.is_group_enabled(SHADER_GROUP_FP32)) {
|
||||
shader.enable_group(SHADER_GROUP_FP32_MULTIVIEW);
|
||||
}
|
||||
|
||||
if (shader.is_group_enabled(SHADER_GROUP_FP16)) {
|
||||
shader.enable_group(SHADER_GROUP_FP16_MULTIVIEW);
|
||||
}
|
||||
}
|
||||
|
||||
bool SceneShaderForwardMobile::is_multiview_shader_group_enabled() const {
|
||||
return shader.is_group_enabled(SHADER_GROUP_MULTIVIEW);
|
||||
return shader.is_group_enabled(SHADER_GROUP_FP32_MULTIVIEW) || shader.is_group_enabled(SHADER_GROUP_FP16_MULTIVIEW);
|
||||
}
|
||||
|
||||
SceneShaderForwardMobile::~SceneShaderForwardMobile() {
|
||||
|
||||
@@ -74,8 +74,10 @@ public:
|
||||
}
|
||||
|
||||
enum ShaderGroup {
|
||||
SHADER_GROUP_BASE, // Always compiled at the beginning.
|
||||
SHADER_GROUP_MULTIVIEW,
|
||||
SHADER_GROUP_FP32,
|
||||
SHADER_GROUP_FP32_MULTIVIEW,
|
||||
SHADER_GROUP_FP16,
|
||||
SHADER_GROUP_FP16_MULTIVIEW,
|
||||
};
|
||||
|
||||
struct ShaderSpecialization {
|
||||
@@ -311,6 +313,7 @@ public:
|
||||
|
||||
SceneForwardMobileShaderRD shader;
|
||||
ShaderCompiler compiler;
|
||||
bool use_fp16 = false;
|
||||
|
||||
RID default_shader;
|
||||
RID default_material;
|
||||
@@ -344,6 +347,8 @@ public:
|
||||
void init(const String p_defines);
|
||||
void set_default_specialization(const ShaderSpecialization &p_specialization);
|
||||
uint32_t get_pipeline_compilations(RS::PipelineSource p_source);
|
||||
void enable_fp32_shader_group();
|
||||
void enable_fp16_shader_group();
|
||||
void enable_multiview_shader_group();
|
||||
bool is_multiview_shader_group_enabled() const;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user