Skip to content

Commit

Permalink
Merge pull request godotengine#98825 from DarioSamo/mobile-scs
Browse files Browse the repository at this point in the history
Add multiple specialization constants to Forward+ and Mobile.
  • Loading branch information
Repiteo committed Nov 5, 2024
2 parents 74d9a44 + 53099c5 commit c68ec6c
Show file tree
Hide file tree
Showing 10 changed files with 260 additions and 275 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,10 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p
RID xforms_uniform_set = surf->owner->transforms_uniform_set;

SceneShaderForwardClustered::ShaderSpecialization pipeline_specialization = p_params->base_specialization;
pipeline_specialization.multimesh = bool(surf->owner->base_flags & INSTANCE_DATA_FLAG_MULTIMESH);
pipeline_specialization.multimesh_format_2d = bool(surf->owner->base_flags & INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D);
pipeline_specialization.multimesh_has_color = bool(surf->owner->base_flags & INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR);
pipeline_specialization.multimesh_has_custom_data = bool(surf->owner->base_flags & INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA);

if constexpr (p_pass_mode == PASS_MODE_COLOR) {
pipeline_specialization.use_light_soft_shadows = element_info.uses_softshadow;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,10 @@ void SceneShaderForwardClustered::ShaderData::_create_pipeline(PipelineKey p_pip
sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_INT;
specialization_constants.push_back(sc);

sc.constant_id = 1;
sc.int_value = p_pipeline_key.shader_specialization.packed_1;
specialization_constants.push_back(sc);

RID shader_rid = get_shader_variant(p_pipeline_key.version, p_pipeline_key.color_pass_flags, p_pipeline_key.ubershader);
ERR_FAIL_COND(shader_rid.is_null());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,17 @@ class SceneShaderForwardClustered {
uint32_t packed_0;
};

uint32_t packed_1;
union {
struct {
uint32_t multimesh : 1;
uint32_t multimesh_format_2d : 1;
uint32_t multimesh_has_color : 1;
uint32_t multimesh_has_custom_data : 1;
};

uint32_t packed_1;
};

uint32_t packed_2;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -911,14 +911,19 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
Color clear_color = p_default_bg_color;
bool load_color = false;
bool copy_canvas = false;
bool use_ambient_cubemap = false;
bool use_reflection_cubemap = false;

if (get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_OVERDRAW) {
clear_color = Color(0, 0, 0, 1); //in overdraw mode, BG should always be black
} else if (is_environment(p_render_data->environment)) {
RS::EnvironmentAmbientSource ambient_source = environment_get_ambient_source(p_render_data->environment);
RS::EnvironmentBG bg_mode = environment_get_background(p_render_data->environment);
float bg_energy_multiplier = environment_get_bg_energy_multiplier(p_render_data->environment);
bg_energy_multiplier *= environment_get_bg_intensity(p_render_data->environment);
RS::EnvironmentReflectionSource reflection_source = environment_get_reflection_source(p_render_data->environment);
use_ambient_cubemap = (ambient_source == RS::ENV_AMBIENT_SOURCE_BG && bg_mode == RS::ENV_BG_SKY) || ambient_source == RS::ENV_AMBIENT_SOURCE_SKY;
use_reflection_cubemap = (reflection_source == RS::ENV_REFLECTION_SOURCE_BG && bg_mode == RS::ENV_BG_SKY) || reflection_source == RS::ENV_REFLECTION_SOURCE_SKY;

if (p_render_data->camera_attributes.is_valid()) {
bg_energy_multiplier *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);
Expand Down Expand Up @@ -963,7 +968,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
}

// setup sky if used for ambient, reflections, or background
if (draw_sky || draw_sky_fog_only || (reflection_source == RS::ENV_REFLECTION_SOURCE_BG && bg_mode == RS::ENV_BG_SKY) || reflection_source == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_render_data->environment) == RS::ENV_AMBIENT_SOURCE_SKY) {
if (draw_sky || draw_sky_fog_only || (reflection_source == RS::ENV_REFLECTION_SOURCE_BG && bg_mode == RS::ENV_BG_SKY) || reflection_source == RS::ENV_REFLECTION_SOURCE_SKY || ambient_source == RS::ENV_AMBIENT_SOURCE_SKY) {
RENDER_TIMESTAMP("Setup Sky");
RD::get_singleton()->draw_command_begin_label("Setup Sky");

Expand Down Expand Up @@ -1008,13 +1013,8 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
SceneShaderForwardMobile::ShaderSpecialization base_specialization = scene_shader.default_specialization;

{
//figure out spec constants

if (p_render_data->directional_light_count > 0) {
base_specialization.use_directional_soft_shadows = p_render_data->directional_light_soft_shadows;
} else {
base_specialization.disable_directional_lights = true;
}
base_specialization.use_directional_soft_shadows = p_render_data->directional_light_count > 0 ? p_render_data->directional_light_soft_shadows : false;
base_specialization.directional_lights = p_render_data->directional_light_count;

if (!is_environment(p_render_data->environment) || !environment_get_fog_enabled(p_render_data->environment)) {
base_specialization.disable_fog = true;
Expand All @@ -1023,6 +1023,10 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
if (p_render_data->environment.is_valid() && environment_get_fog_mode(p_render_data->environment) == RS::EnvironmentFogMode::ENV_FOG_MODE_DEPTH) {
base_specialization.use_depth_fog = true;
}

base_specialization.scene_use_ambient_cubemap = use_ambient_cubemap;
base_specialization.scene_use_reflection_cubemap = use_reflection_cubemap;
base_specialization.scene_roughness_limiter_enabled = p_render_data->render_buffers.is_valid() && screen_space_roughness_limiter_is_active();
}

{
Expand Down Expand Up @@ -2144,7 +2148,10 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
}

SceneShaderForwardMobile::ShaderSpecialization pipeline_specialization = p_params->base_specialization;
pipeline_specialization.is_multimesh = bool(inst->flags_cache & INSTANCE_DATA_FLAG_MULTIMESH);
pipeline_specialization.multimesh = bool(inst->flags_cache & INSTANCE_DATA_FLAG_MULTIMESH);
pipeline_specialization.multimesh_format_2d = bool(inst->flags_cache & INSTANCE_DATA_FLAG_MULTIMESH_FORMAT_2D);
pipeline_specialization.multimesh_has_color = bool(inst->flags_cache & INSTANCE_DATA_FLAG_MULTIMESH_HAS_COLOR);
pipeline_specialization.multimesh_has_custom_data = bool(inst->flags_cache & INSTANCE_DATA_FLAG_MULTIMESH_HAS_CUSTOM_DATA);

SceneState::PushConstant push_constant;
push_constant.base_index = i + p_params->element_offset;
Expand All @@ -2165,10 +2172,10 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
} else {
pipeline_specialization.use_light_projector = inst->use_projector;
pipeline_specialization.use_light_soft_shadows = inst->use_soft_shadow;
pipeline_specialization.disable_omni_lights = inst->omni_light_count == 0;
pipeline_specialization.disable_spot_lights = inst->spot_light_count == 0;
pipeline_specialization.disable_reflection_probes = inst->reflection_probe_count == 0;
pipeline_specialization.disable_decals = inst->decals_count == 0;
pipeline_specialization.omni_lights = inst->omni_light_count;
pipeline_specialization.spot_lights = inst->spot_light_count;
pipeline_specialization.reflection_probes = inst->reflection_probe_count;
pipeline_specialization.decals = inst->decals_count;

#ifdef DEBUG_ENABLED
if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_LIGHTING)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ void SceneShaderForwardMobile::ShaderData::_create_pipeline(PipelineKey p_pipeli
"VERSION:", p_pipeline_key.version,
"SPEC PACKED #0:", p_pipeline_key.shader_specialization.packed_0,
"SPEC PACKED #1:", p_pipeline_key.shader_specialization.packed_1,
"SPEC PACKED #2:", p_pipeline_key.shader_specialization.packed_2,
"RENDER PASS:", p_pipeline_key.render_pass,
"WIREFRAME:", p_pipeline_key.wireframe);
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,25 +65,35 @@ class SceneShaderForwardMobile {
uint32_t use_directional_soft_shadows : 1;
uint32_t decal_use_mipmaps : 1;
uint32_t projector_use_mipmaps : 1;
uint32_t disable_omni_lights : 1;
uint32_t disable_spot_lights : 1;
uint32_t disable_reflection_probes : 1;
uint32_t disable_directional_lights : 1;
uint32_t disable_decals : 1;
uint32_t disable_fog : 1;
uint32_t use_depth_fog : 1;
uint32_t is_multimesh : 1;
uint32_t use_lightmap_bicubic_filter : 1;
uint32_t multimesh : 1;
uint32_t multimesh_format_2d : 1;
uint32_t multimesh_has_color : 1;
uint32_t multimesh_has_custom_data : 1;
uint32_t scene_use_ambient_cubemap : 1;
uint32_t scene_use_reflection_cubemap : 1;
uint32_t scene_roughness_limiter_enabled : 1;
uint32_t padding : 5;
uint32_t soft_shadow_samples : 6;
uint32_t penumbra_shadow_samples : 6;
uint32_t directional_soft_shadow_samples : 6;
};

uint32_t packed_0;
};

union {
uint32_t directional_penumbra_shadow_samples : 6;
struct {
uint32_t directional_soft_shadow_samples : 6;
uint32_t directional_penumbra_shadow_samples : 6;
uint32_t omni_lights : 4;
uint32_t spot_lights : 4;
uint32_t reflection_probes : 4;
uint32_t directional_lights : 4;
uint32_t decals : 4;
};

uint32_t packed_1;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,13 @@ vec3 double_add_vec3(vec3 base_a, vec3 prec_a, vec3 base_b, vec3 prec_b, out vec
}
#endif

uint multimesh_stride() {
uint stride = sc_multimesh_format_2d() ? 2 : 3;
stride += sc_multimesh_has_color() ? 1 : 0;
stride += sc_multimesh_has_custom_data() ? 1 : 0;
return stride;
}

void vertex_shader(vec3 vertex_input,
#ifdef NORMAL_USED
in vec3 normal_input,
Expand All @@ -219,7 +226,7 @@ void vertex_shader(vec3 vertex_input,
in vec3 tangent_input,
in vec3 binormal_input,
#endif
in uint instance_index, in bool is_multimesh, in uint multimesh_offset, in SceneData scene_data, in mat4 model_matrix, out vec4 screen_pos) {
in uint instance_index, in uint multimesh_offset, in SceneData scene_data, in mat4 model_matrix, out vec4 screen_pos) {
vec4 instance_custom = vec4(0.0);
#if defined(COLOR_USED)
color_interp = color_attrib;
Expand Down Expand Up @@ -248,7 +255,7 @@ void vertex_shader(vec3 vertex_input,
mat4 matrix;
mat4 read_model_matrix = model_matrix;

if (is_multimesh) {
if (sc_multimesh()) {
//multimesh, instances are for it

#ifdef USE_PARTICLE_TRAILS
Expand Down Expand Up @@ -296,40 +303,25 @@ void vertex_shader(vec3 vertex_input,
#endif

#else
uint stride = 0;
{
//TODO implement a small lookup table for the stride
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_FORMAT_2D)) {
stride += 2;
} else {
stride += 3;
}
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_COLOR)) {
stride += 1;
}
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA)) {
stride += 1;
}
}

uint stride = multimesh_stride();
uint offset = stride * (gl_InstanceIndex + multimesh_offset);

if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_FORMAT_2D)) {
if (sc_multimesh_format_2d()) {
matrix = mat4(transforms.data[offset + 0], transforms.data[offset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));
offset += 2;
} else {
matrix = mat4(transforms.data[offset + 0], transforms.data[offset + 1], transforms.data[offset + 2], vec4(0.0, 0.0, 0.0, 1.0));
offset += 3;
}

if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_COLOR)) {
if (sc_multimesh_has_color()) {
#ifdef COLOR_USED
color_interp *= transforms.data[offset];
#endif
offset += 1;
}

if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA)) {
if (sc_multimesh_has_custom_data()) {
instance_custom = transforms.data[offset];
}

Expand Down Expand Up @@ -427,7 +419,7 @@ void vertex_shader(vec3 vertex_input,
// Then we combine the translations from the model matrix and the view matrix using emulated doubles.
// We add the result to the vertex and ignore the final lost precision.
vec3 model_origin = model_matrix[3].xyz;
if (is_multimesh) {
if (sc_multimesh()) {
vertex = mat3(matrix) * vertex;
model_origin = double_add_vec3(model_origin, model_precision, matrix[3].xyz, vec3(0.0), model_precision);
}
Expand Down Expand Up @@ -708,9 +700,7 @@ void _unpack_vertex_attributes(vec4 p_vertex_in, vec3 p_compressed_aabb_position

void main() {
uint instance_index = draw_call.instance_index;

bool is_multimesh = bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH);
if (!is_multimesh) {
if (!sc_multimesh()) {
instance_index += gl_InstanceIndex;
}

Expand Down Expand Up @@ -753,7 +743,7 @@ void main() {
prev_tangent,
prev_binormal,
#endif
instance_index, is_multimesh, draw_call.multimesh_motion_vectors_previous_offset, scene_data_block.prev_data, instances.data[instance_index].prev_transform, prev_screen_position);
instance_index, draw_call.multimesh_motion_vectors_previous_offset, scene_data_block.prev_data, instances.data[instance_index].prev_transform, prev_screen_position);
#else
// Unused output.
vec4 screen_position;
Expand Down Expand Up @@ -792,7 +782,7 @@ void main() {
tangent,
binormal,
#endif
instance_index, is_multimesh, draw_call.multimesh_motion_vectors_current_offset, scene_data_block.data, model_matrix, screen_position);
instance_index, draw_call.multimesh_motion_vectors_current_offset, scene_data_block.data, model_matrix, screen_position);
}

#[fragment]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ uint sc_packed_0() {
return draw_call.sc_packed_0;
}

uint sc_packed_1() {
return draw_call.sc_packed_1;
}

uint uc_cull_mode() {
return (draw_call.uc_packed_0 >> 0) & 3U;
}
Expand All @@ -67,11 +71,16 @@ uint uc_cull_mode() {

// Pull the constants from the pipeline's specialization constants.
layout(constant_id = 0) const uint pso_sc_packed_0 = 0;
layout(constant_id = 1) const uint pso_sc_packed_1 = 0;

uint sc_packed_0() {
return pso_sc_packed_0;
}

uint sc_packed_1() {
return pso_sc_packed_1;
}

#endif

bool sc_use_forward_gi() {
Expand Down Expand Up @@ -122,6 +131,22 @@ uint sc_directional_penumbra_shadow_samples() {
return (sc_packed_0() >> 26) & 63U;
}

bool sc_multimesh() {
return ((sc_packed_1() >> 0) & 1U) != 0;
}

bool sc_multimesh_format_2d() {
return ((sc_packed_1() >> 1) & 1U) != 0;
}

bool sc_multimesh_has_color() {
return ((sc_packed_1() >> 2) & 1U) != 0;
}

bool sc_multimesh_has_custom_data() {
return ((sc_packed_1() >> 3) & 1U) != 0;
}

float sc_luminance_multiplier() {
// Not used in clustered renderer but we share some code with the mobile renderer that requires this.
return 1.0;
Expand All @@ -144,10 +169,6 @@ layout(set = 0, binding = 2) uniform sampler shadow_sampler;
#define INSTANCE_FLAGS_USE_SH_LIGHTMAP (1 << 9)
#define INSTANCE_FLAGS_USE_VOXEL_GI (1 << 10)
#define INSTANCE_FLAGS_PARTICLES (1 << 11)
#define INSTANCE_FLAGS_MULTIMESH (1 << 12)
#define INSTANCE_FLAGS_MULTIMESH_FORMAT_2D (1 << 13)
#define INSTANCE_FLAGS_MULTIMESH_HAS_COLOR (1 << 14)
#define INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA (1 << 15)
#define INSTANCE_FLAGS_PARTICLE_TRAIL_SHIFT 16
#define INSTANCE_FLAGS_FADE_SHIFT 24
//3 bits of stride
Expand Down
Loading

0 comments on commit c68ec6c

Please sign in to comment.