EEVEE-Next: Skip bake if there's not enough VRAM #113509

Merged
Miguel Pozo merged 4 commits from pragma37/blender:pull-eevee-bake-out-of-mem into main 2023-10-18 18:49:30 +02:00
4 changed files with 53 additions and 3 deletions

View File

@ -610,12 +610,21 @@ void Instance::light_bake_irradiance(
capture_view.render_world();
irradiance_cache.bake.surfels_create(probe);
if (irradiance_cache.bake.should_break()) {
return;
}
irradiance_cache.bake.surfels_lights_eval();
irradiance_cache.bake.clusters_build();
irradiance_cache.bake.irradiance_offset();
});
if (irradiance_cache.bake.should_break()) {
return;
}
sampling.init(probe);
while (!sampling.finished()) {
context_wrapper([&]() {

View File

@ -860,13 +860,22 @@ void IrradianceBake::surfels_create(const Object &probe_object)
irradiance_L1_b_tx_.ensure_3d(GPU_RGBA32F, grid_resolution, texture_usage);
irradiance_L1_c_tx_.ensure_3d(GPU_RGBA32F, grid_resolution, texture_usage);
validity_tx_.ensure_3d(GPU_R32F, grid_resolution, texture_usage);
virtual_offset_tx_.ensure_3d(GPU_RGBA16F, grid_resolution, texture_usage);
if (!irradiance_L0_tx_.is_valid() || !irradiance_L1_a_tx_.is_valid() ||
!irradiance_L1_b_tx_.is_valid() || !irradiance_L1_c_tx_.is_valid() ||
!validity_tx_.is_valid() || !virtual_offset_tx_.is_valid())
{
inst_.info = "Error: Not enough memory to bake " + std::string(probe_object.id.name) + ".";
do_break_ = true;
return;
}
irradiance_L0_tx_.clear(float4(0.0f));
irradiance_L1_a_tx_.clear(float4(0.0f));
irradiance_L1_b_tx_.clear(float4(0.0f));
irradiance_L1_c_tx_.clear(float4(0.0f));
validity_tx_.clear(float4(0.0f));
virtual_offset_tx_.ensure_3d(GPU_RGBA16F, grid_resolution, texture_usage);
virtual_offset_tx_.clear(float4(0.0f));
DRW_stats_group_start("IrradianceBake.SceneBounds");
@ -947,10 +956,28 @@ void IrradianceBake::surfels_create(const Object &probe_object)
capture_info_buf_.read();
if (capture_info_buf_.surfel_len == 0) {
/* No surfel to allocated. */
do_break_ = true;
return;
}
/* TODO(fclem): Check for GL limit and abort if the surfel cache doesn't fit the GPU memory. */
if (capture_info_buf_.surfel_len > surfels_buf_.size()) {
size_t max_size = GPU_max_storage_buffer_size();
if (GPU_mem_stats_supported()) {
int total_mem_kb, free_mem_kb;
GPU_mem_stats_get(&total_mem_kb, &free_mem_kb);
max_size = min(max_size, size_t(free_mem_kb) * 1024);
}
size_t required_mem = sizeof(Surfel) * (capture_info_buf_.surfel_len - surfels_buf_.size());
if (required_mem > max_size) {
capture_info_buf_.surfel_len = 0u;
capture_info_buf_.push_update();
inst_.info = "Error: Not enough memory to bake " + std::string(probe_object.id.name) + ".";
do_break_ = true;
return;
}
}
surfels_buf_.resize(capture_info_buf_.surfel_len);
surfels_buf_.clear_to_zero();

View File

@ -130,12 +130,21 @@ class IrradianceBake {
/** True if emission is recorded during the light propagation. */
bool capture_emission_ = false;
/** True if the bake job should stop. */
bool do_break_ = false;
public:
IrradianceBake(Instance &inst) : inst_(inst){};
void init(const Object &probe_object);
void sync();
/** True if the bake job should stop. */
bool should_break()
{
return do_break_;
}
/** Create the views used to rasterize the scene into surfel representation. */
void surfel_raster_views_sync(float3 scene_min, float3 scene_max, float4x4 probe_to_world);
/** Create a surfel representation of the scene from the probe using the capture pipeline. */

View File

@ -179,6 +179,11 @@ class LightBake {
}
});
if (instance_->info != "") {
/** TODO: Print to the Status Bar UI. */
printf("%s\n", instance_->info.c_str());
}
if ((G.is_break == true) || (stop != nullptr && *stop == true)) {
break;
}