Skip to content

Commit a12e9d5

Browse files
committed
Merge pull request godotengine#106493 from DarioSamo/mobile-scs-permutations
Reduce amount of permutations in mobile shader.
2 parents 5d2074a + ff3abab commit a12e9d5

File tree

5 files changed

+116
-76
lines changed

5 files changed

+116
-76
lines changed

servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,7 +1050,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
10501050

10511051
{
10521052
base_specialization.use_directional_soft_shadows = p_render_data->directional_light_count > 0 ? p_render_data->directional_light_soft_shadows : false;
1053-
base_specialization.directional_lights = p_render_data->directional_light_count;
1053+
base_specialization.directional_lights = SceneShaderForwardMobile::shader_count_for(p_render_data->directional_light_count);
10541054
base_specialization.directional_light_blend_splits = light_storage->get_directional_light_blend_splits(p_render_data->directional_light_count);
10551055

10561056
if (!is_environment(p_render_data->environment) || !environment_get_fog_enabled(p_render_data->environment)) {
@@ -2214,10 +2214,10 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
22142214
} else {
22152215
pipeline_specialization.use_light_projector = inst->use_projector;
22162216
pipeline_specialization.use_light_soft_shadows = inst->use_soft_shadow;
2217-
pipeline_specialization.omni_lights = inst->omni_light_count;
2218-
pipeline_specialization.spot_lights = inst->spot_light_count;
2219-
pipeline_specialization.reflection_probes = inst->reflection_probe_count;
2220-
pipeline_specialization.decals = inst->decals_count;
2217+
pipeline_specialization.omni_lights = SceneShaderForwardMobile::shader_count_for(inst->omni_light_count);
2218+
pipeline_specialization.spot_lights = SceneShaderForwardMobile::shader_count_for(inst->spot_light_count);
2219+
pipeline_specialization.reflection_probes = SceneShaderForwardMobile::shader_count_for(inst->reflection_probe_count);
2220+
pipeline_specialization.decals = inst->decals_count > 0;
22212221

22222222
#ifdef DEBUG_ENABLED
22232223
if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_LIGHTING)) {

servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,6 @@ void SceneShaderForwardMobile::ShaderData::_create_pipeline(PipelineKey p_pipeli
249249
"SPEC PACKED #0:", p_pipeline_key.shader_specialization.packed_0,
250250
"SPEC PACKED #1:", p_pipeline_key.shader_specialization.packed_1,
251251
"SPEC PACKED #2:", p_pipeline_key.shader_specialization.packed_2,
252-
"SPEC PACKED #3:", p_pipeline_key.shader_specialization.packed_3,
253252
"RENDER PASS:", p_pipeline_key.render_pass,
254253
"WIREFRAME:", p_pipeline_key.wireframe);
255254
#endif
@@ -340,12 +339,7 @@ void SceneShaderForwardMobile::ShaderData::_create_pipeline(PipelineKey p_pipeli
340339
specialization_constants.push_back(sc);
341340

342341
sc.constant_id = 2;
343-
sc.int_value = p_pipeline_key.shader_specialization.packed_2;
344-
sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_INT;
345-
specialization_constants.push_back(sc);
346-
347-
sc.constant_id = 3;
348-
sc.float_value = p_pipeline_key.shader_specialization.packed_3;
342+
sc.float_value = p_pipeline_key.shader_specialization.packed_2;
349343
sc.type = RD::PIPELINE_SPECIALIZATION_CONSTANT_TYPE_FLOAT;
350344
specialization_constants.push_back(sc);
351345

servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,22 @@ class SceneShaderForwardMobile {
5656
SHADER_VERSION_MAX
5757
};
5858

59+
enum ShaderCount {
60+
SHADER_COUNT_NONE,
61+
SHADER_COUNT_SINGLE,
62+
SHADER_COUNT_MULTIPLE
63+
};
64+
65+
_FORCE_INLINE_ static ShaderCount shader_count_for(uint32_t p_count) {
66+
if (p_count == 0) {
67+
return SHADER_COUNT_NONE;
68+
} else if (p_count == 1) {
69+
return SHADER_COUNT_SINGLE;
70+
} else {
71+
return SHADER_COUNT_MULTIPLE;
72+
}
73+
}
74+
5975
struct ShaderSpecialization {
6076
union {
6177
uint32_t packed_0;
@@ -91,25 +107,18 @@ class SceneShaderForwardMobile {
91107
struct {
92108
uint32_t directional_soft_shadow_samples : 6;
93109
uint32_t directional_penumbra_shadow_samples : 6;
94-
uint32_t omni_lights : 4;
95-
uint32_t spot_lights : 4;
96-
uint32_t reflection_probes : 4;
97-
uint32_t directional_lights : 4;
98-
uint32_t decals : 4;
99-
};
100-
};
101-
102-
union {
103-
uint32_t packed_2;
104-
105-
struct {
110+
uint32_t omni_lights : 2;
111+
uint32_t spot_lights : 2;
112+
uint32_t reflection_probes : 2;
113+
uint32_t directional_lights : 2;
114+
uint32_t decals : 1;
106115
uint32_t directional_light_blend_splits : 8;
107-
uint32_t padding_1 : 24;
116+
uint32_t padding_1 : 3;
108117
};
109118
};
110119

111120
union {
112-
float packed_3;
121+
float packed_2;
113122
float luminance_multiplier;
114123
};
115124
};
@@ -122,10 +131,6 @@ class SceneShaderForwardMobile {
122131
uint32_t cull_mode : 2;
123132
};
124133
};
125-
126-
uint32_t padding_1;
127-
uint32_t padding_2;
128-
uint32_t padding_3;
129134
};
130135

131136
struct ShaderData : public RendererRD::MaterialStorage::ShaderData {
@@ -172,8 +177,7 @@ class SceneShaderForwardMobile {
172177
h = hash_murmur3_one_32(primitive_type, h);
173178
h = hash_murmur3_one_32(shader_specialization.packed_0, h);
174179
h = hash_murmur3_one_32(shader_specialization.packed_1, h);
175-
h = hash_murmur3_one_32(shader_specialization.packed_2, h);
176-
h = hash_murmur3_one_float(shader_specialization.packed_3, h);
180+
h = hash_murmur3_one_float(shader_specialization.packed_2, h);
177181
h = hash_murmur3_one_32(version, h);
178182
h = hash_murmur3_one_32(render_pass, h);
179183
h = hash_murmur3_one_32(wireframe, h);

servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -456,24 +456,35 @@ void main() {
456456
diffuse_light_interp = vec4(0.0);
457457
specular_light_interp = vec4(0.0);
458458

459+
uint omni_light_count = sc_omni_lights(8);
459460
uvec2 omni_light_indices = instances.data[draw_call.instance_index].omni_lights;
460-
for (uint i = 0; i < sc_omni_lights(); i++) {
461+
for (uint i = 0; i < omni_light_count; i++) {
461462
uint light_index = (i > 3) ? ((omni_light_indices.y >> ((i - 4) * 8)) & 0xFF) : ((omni_light_indices.x >> (i * 8)) & 0xFF);
463+
if (i > 0 && light_index == 0xFF) {
464+
break;
465+
}
466+
462467
light_process_omni_vertex(light_index, vertex, view, normal_interp, roughness, diffuse_light_interp.rgb, specular_light_interp.rgb);
463468
}
464469

470+
uint spot_light_count = sc_spot_lights(8);
465471
uvec2 spot_light_indices = instances.data[draw_call.instance_index].spot_lights;
466-
for (uint i = 0; i < sc_spot_lights(); i++) {
472+
for (uint i = 0; i < spot_light_count; i++) {
467473
uint light_index = (i > 3) ? ((spot_light_indices.y >> ((i - 4) * 8)) & 0xFF) : ((spot_light_indices.x >> (i * 8)) & 0xFF);
474+
if (i > 0 && light_index == 0xFF) {
475+
break;
476+
}
477+
468478
light_process_spot_vertex(light_index, vertex, view, normal_interp, roughness, diffuse_light_interp.rgb, specular_light_interp.rgb);
469479
}
470480

471-
if (sc_directional_lights() > 0) {
481+
uint directional_lights_count = sc_directional_lights(scene_data.directional_light_count);
482+
if (directional_lights_count > 0) {
472483
// We process the first directional light separately as it may have shadows.
473484
vec3 directional_diffuse = vec3(0.0);
474485
vec3 directional_specular = vec3(0.0);
475486

476-
for (uint i = 0; i < sc_directional_lights(); i++) {
487+
for (uint i = 0; i < directional_lights_count; i++) {
477488
if (!bool(directional_lights.data[i].mask & instances.data[draw_call.instance_index].layer_mask)) {
478489
continue; // Not masked, skip.
479490
}
@@ -729,6 +740,8 @@ layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms
729740

730741
#GLOBALS
731742

743+
#define scene_data scene_data_block.data
744+
732745
/* clang-format on */
733746

734747
#ifdef MODE_RENDER_DEPTH
@@ -799,7 +812,8 @@ vec4 fog_process(vec3 vertex) {
799812
float sun_total = 0.0;
800813
vec3 view = normalize(vertex);
801814

802-
for (uint i = 0; i < sc_directional_lights(); i++) {
815+
uint directional_lights_count = sc_directional_lights(scene_data.directional_light_count);
816+
for (uint i = 0; i < directional_lights_count; i++) {
803817
vec3 light_color = directional_lights.data[i].color * directional_lights.data[i].energy;
804818
float light_amount = pow(max(dot(view, directional_lights.data[i].direction), 0.0), 8.0);
805819
fog_color += light_color * light_amount * scene_data_block.data.fog_sun_scatter;
@@ -831,8 +845,6 @@ vec4 fog_process(vec3 vertex) {
831845

832846
#endif //!MODE_RENDER DEPTH
833847

834-
#define scene_data scene_data_block.data
835-
836848
void main() {
837849
#ifdef UBERSHADER
838850
bool front_facing = gl_FrontFacing;
@@ -1129,9 +1141,13 @@ void main() {
11291141
vec3 vertex_ddx = dFdx(vertex);
11301142
vec3 vertex_ddy = dFdy(vertex);
11311143

1144+
uint decal_count = sc_decals(8);
11321145
uvec2 decal_indices = instances.data[draw_call.instance_index].decals;
1133-
for (uint i = 0; i < sc_decals(); i++) {
1146+
for (uint i = 0; i < decal_count; i++) {
11341147
uint decal_index = (i > 3) ? ((decal_indices.y >> ((i - 4) * 8)) & 0xFF) : ((decal_indices.x >> (i * 8)) & 0xFF);
1148+
if (decal_index == 0xFF) {
1149+
break;
1150+
}
11351151

11361152
vec3 uv_local = (decals.data[decal_index].xform * vec4(vertex, 1.0)).xyz;
11371153
if (any(lessThan(uv_local, vec3(0.0, -1.0, 0.0))) || any(greaterThan(uv_local, vec3(1.0)))) {
@@ -1405,7 +1421,8 @@ void main() {
14051421

14061422
// skipping ssao, do we remove ssao totally?
14071423

1408-
if (sc_reflection_probes() > 0) {
1424+
uint reflection_probe_count = sc_reflection_probes(8);
1425+
if (reflection_probe_count > 0) {
14091426
vec4 reflection_accum = vec4(0.0, 0.0, 0.0, 0.0);
14101427
vec4 ambient_accum = vec4(0.0, 0.0, 0.0, 0.0);
14111428

@@ -1423,8 +1440,11 @@ void main() {
14231440
ref_vec = mix(ref_vec, bent_normal, roughness * roughness * roughness * roughness);
14241441

14251442
uvec2 reflection_indices = instances.data[draw_call.instance_index].reflection_probes;
1426-
for (uint i = 0; i < sc_reflection_probes(); i++) {
1443+
for (uint i = 0; i < reflection_probe_count; i++) {
14271444
uint reflection_index = (i > 3) ? ((reflection_indices.y >> ((i - 4) * 8)) & 0xFF) : ((reflection_indices.x >> (i * 8)) & 0xFF);
1445+
if (reflection_index == 0xFF) {
1446+
break;
1447+
}
14281448

14291449
if (reflection_accum.a >= 1.0 && ambient_accum.a >= 1.0) {
14301450
break;
@@ -1519,7 +1539,8 @@ void main() {
15191539
direct_specular_light += specular_light_interp.rgb * f0;
15201540
#endif
15211541

1522-
if (sc_directional_lights() > 0) {
1542+
uint directional_lights_count = sc_directional_lights(scene_data.directional_light_count);
1543+
if (directional_lights_count > 0) {
15231544
#ifndef SHADOWS_DISABLED
15241545
// Do shadow and lighting in two passes to reduce register pressure
15251546
uint shadow0 = 0;
@@ -1554,7 +1575,7 @@ void main() {
15541575
// Only process the first light's shadow for vertex lighting.
15551576
for (uint i = 0; i < 1; i++) {
15561577
#else
1557-
for (uint i = 0; i < sc_directional_lights(); i++) {
1578+
for (uint i = 0; i < directional_lights_count; i++) {
15581579
#endif
15591580
if (!bool(directional_lights.data[i].mask & instances.data[draw_call.instance_index].layer_mask)) {
15601581
continue; //not masked
@@ -1696,7 +1717,8 @@ void main() {
16961717
#endif // SHADOWS_DISABLED
16971718

16981719
#ifndef USE_VERTEX_LIGHTING
1699-
for (uint i = 0; i < sc_directional_lights(); i++) {
1720+
uint directional_lights_count = sc_directional_lights(scene_data.directional_light_count);
1721+
for (uint i = 0; i < directional_lights_count; i++) {
17001722
if (!bool(directional_lights.data[i].mask & instances.data[draw_call.instance_index].layer_mask)) {
17011723
continue; //not masked
17021724
}
@@ -1767,9 +1789,14 @@ void main() {
17671789
} //directional light
17681790

17691791
#ifndef USE_VERTEX_LIGHTING
1792+
uint omni_light_count = sc_omni_lights(8);
17701793
uvec2 omni_indices = instances.data[draw_call.instance_index].omni_lights;
1771-
for (uint i = 0; i < sc_omni_lights(); i++) {
1794+
for (uint i = 0; i < omni_light_count; i++) {
17721795
uint light_index = (i > 3) ? ((omni_indices.y >> ((i - 4) * 8)) & 0xFF) : ((omni_indices.x >> (i * 8)) & 0xFF);
1796+
if (i > 0 && light_index == 0xFF) {
1797+
break;
1798+
}
1799+
17731800
light_process_omni(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, scene_data.taa_frame_count, albedo, alpha, screen_uv, vec3(1.0),
17741801
#ifdef LIGHT_BACKLIGHT_USED
17751802
backlight,
@@ -1795,9 +1822,14 @@ void main() {
17951822
diffuse_light, direct_specular_light);
17961823
}
17971824

1825+
uint spot_light_count = sc_spot_lights(8);
17981826
uvec2 spot_indices = instances.data[draw_call.instance_index].spot_lights;
1799-
for (uint i = 0; i < sc_spot_lights(); i++) {
1827+
for (uint i = 0; i < spot_light_count; i++) {
18001828
uint light_index = (i > 3) ? ((spot_indices.y >> ((i - 4) * 8)) & 0xFF) : ((spot_indices.x >> (i * 8)) & 0xFF);
1829+
if (i > 0 && light_index == 0xFF) {
1830+
break;
1831+
}
1832+
18011833
light_process_spot(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, scene_data.taa_frame_count, albedo, alpha, screen_uv, vec3(1.0),
18021834
#ifdef LIGHT_BACKLIGHT_USED
18031835
backlight,

0 commit comments

Comments
 (0)