Skip to content

Commit 3d25533

Browse files
committed
Merge pull request #102257 from clayjohn/lightmapgi-crash
Spread direct lighting calculation for LightmapGI over several submissions
2 parents 480843c + 49a004f commit 3d25533

File tree

1 file changed

+49
-19
lines changed

1 file changed

+49
-19
lines changed

modules/lightmapper_rd/lightmapper_rd.cpp

+49-19
Original file line numberDiff line numberDiff line change
@@ -1649,6 +1649,10 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
16491649
}
16501650
}
16511651

1652+
const int max_region_size = nearest_power_of_2_templated(int(GLOBAL_GET("rendering/lightmapping/bake_performance/region_size")));
1653+
const int x_regions = Math::division_round_up(atlas_size.width, max_region_size);
1654+
const int y_regions = Math::division_round_up(atlas_size.height, max_region_size);
1655+
16521656
// Set ray count to the quality used for direct light and bounces.
16531657
switch (p_quality) {
16541658
case BAKE_QUALITY_LOW: {
@@ -1718,18 +1722,52 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
17181722

17191723
RID light_uniform_set = rd->uniform_set_create(uniforms, compute_shader_primary, 1);
17201724

1721-
RD::ComputeListID compute_list = rd->compute_list_begin();
1722-
rd->compute_list_bind_compute_pipeline(compute_list, compute_shader_primary_pipeline);
1723-
rd->compute_list_bind_uniform_set(compute_list, compute_base_uniform_set, 0);
1724-
rd->compute_list_bind_uniform_set(compute_list, light_uniform_set, 1);
1725+
int count = 0;
1726+
for (int s = 0; s < atlas_slices; s++) {
1727+
push_constant.atlas_slice = s;
17251728

1726-
for (int i = 0; i < atlas_slices; i++) {
1727-
push_constant.atlas_slice = i;
1728-
rd->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant));
1729-
rd->compute_list_dispatch(compute_list, group_size.x, group_size.y, group_size.z);
1730-
//no barrier, let them run all together
1729+
for (int i = 0; i < x_regions; i++) {
1730+
for (int j = 0; j < y_regions; j++) {
1731+
int x = i * max_region_size;
1732+
int y = j * max_region_size;
1733+
int w = MIN((i + 1) * max_region_size, atlas_size.width) - x;
1734+
int h = MIN((j + 1) * max_region_size, atlas_size.height) - y;
1735+
1736+
push_constant.region_ofs[0] = x;
1737+
push_constant.region_ofs[1] = y;
1738+
1739+
group_size = Vector3i(Math::division_round_up(w, 8), Math::division_round_up(h, 8), 1);
1740+
RD::ComputeListID compute_list = rd->compute_list_begin();
1741+
rd->compute_list_bind_compute_pipeline(compute_list, compute_shader_primary_pipeline);
1742+
rd->compute_list_bind_uniform_set(compute_list, compute_base_uniform_set, 0);
1743+
rd->compute_list_bind_uniform_set(compute_list, light_uniform_set, 1);
1744+
rd->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant));
1745+
rd->compute_list_dispatch(compute_list, group_size.x, group_size.y, group_size.z);
1746+
rd->compute_list_end();
1747+
1748+
rd->submit();
1749+
rd->sync();
1750+
1751+
count++;
1752+
if (p_step_function) {
1753+
int total = (atlas_slices * x_regions * y_regions);
1754+
int percent = count * 100 / total;
1755+
float p = float(count) / total * 0.1;
1756+
if (p_step_function(0.5 + p, vformat(RTR("Plot direct lighting %d%%"), percent), p_bake_userdata, false)) {
1757+
FREE_TEXTURES
1758+
FREE_BUFFERS
1759+
FREE_RASTER_RESOURCES
1760+
FREE_COMPUTE_RESOURCES
1761+
memdelete(rd);
1762+
if (rcd != nullptr) {
1763+
memdelete(rcd);
1764+
}
1765+
return BAKE_ERROR_USER_ABORTED;
1766+
}
1767+
}
1768+
}
1769+
}
17311770
}
1732-
rd->compute_list_end(); //done
17331771
}
17341772

17351773
#ifdef DEBUG_TEXTURES
@@ -1802,17 +1840,9 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
18021840
RID secondary_uniform_set;
18031841
secondary_uniform_set = rd->uniform_set_create(uniforms, compute_shader_secondary, 1);
18041842

1805-
int max_region_size = nearest_power_of_2_templated(int(GLOBAL_GET("rendering/lightmapping/bake_performance/region_size")));
1806-
int max_rays = GLOBAL_GET("rendering/lightmapping/bake_performance/max_rays_per_pass");
1807-
1808-
int x_regions = Math::division_round_up(atlas_size.width, max_region_size);
1809-
int y_regions = Math::division_round_up(atlas_size.height, max_region_size);
1810-
1843+
const int max_rays = GLOBAL_GET("rendering/lightmapping/bake_performance/max_rays_per_pass");
18111844
int ray_iterations = Math::division_round_up((int32_t)push_constant.ray_count, max_rays);
18121845

1813-
rd->submit();
1814-
rd->sync();
1815-
18161846
if (p_step_function) {
18171847
if (p_step_function(0.6, RTR("Integrate indirect lighting"), p_bake_userdata, true)) {
18181848
FREE_TEXTURES

0 commit comments

Comments
 (0)