77 const bool use_sample_subset,
78 const int sample_subset_offset,
79 const int sample_subset_length)
84 if (use_sample_subset) {
87 min(sample_subset_offset + sample_subset_length,
num_samples_) - sample_subset_offset, 0);
120 return state_.num_rendered_samples;
132 state_.resolution_divider = 1;
135 state_.user_is_navigating =
true;
139 state_.num_rendered_samples = 0;
140 state_.last_display_update_time = 0.0;
141 state_.last_display_update_sample = -1;
143 state_.last_rebalance_time = 0.0;
144 state_.num_rebalance_requested = 0;
145 state_.num_rebalance_changes = 0;
146 state_.last_rebalance_changed =
false;
147 state_.need_rebalance_at_next_work =
false;
151 state_.adaptive_sampling_threshold = 0.4f;
153 state_.last_work_tile_was_denoised =
false;
154 state_.tile_result_was_written =
false;
155 state_.postprocess_work_scheduled =
false;
156 state_.full_frame_work_scheduled =
false;
157 state_.full_frame_was_written =
false;
159 state_.path_trace_finished =
false;
161 state_.start_render_time = 0.0;
162 state_.end_render_time = 0.0;
163 state_.time_limit_reached =
false;
165 state_.occupancy_num_samples = 0;
197 state_.path_trace_finished =
true;
199 bool denoiser_delayed;
200 bool denoiser_ready_to_display;
223 state_.adaptive_sampling_threshold =
max(
state_.adaptive_sampling_threshold / 2,
238 LOG_DEBUG <<
"Schedule work for cancel.";
249 const bool tile_write = render_work.
tile.
write;
250 const bool full_write = render_work.
full.
write;
259 if (!
state_.tile_result_was_written && has_rendered_samples) {
263 if (!
state_.full_frame_was_written) {
276 if (has_rendered_samples && !
state_.full_frame_was_written) {
287 if (
state_.path_trace_finished ||
state_.time_limit_reached) {
298 const double time_now =
time_dt();
309 state_.end_render_time = time_now;
320 if (
state_.user_is_navigating) {
322 state_.user_is_navigating =
false;
335 state_.num_rendered_samples = 0;
336 state_.last_display_update_sample = -1;
358 bool denoiser_delayed;
359 bool denoiser_ready_to_display;
378 const double time_now =
time_dt();
381 state_.last_rebalance_time = time_now;
382 ++
state_.num_rebalance_requested;
388 state_.last_display_update_time = time_now;
389 state_.last_display_update_sample =
state_.num_rendered_samples;
399 if (
state_.postprocess_work_scheduled) {
402 state_.postprocess_work_scheduled =
true;
404 bool any_scheduled =
false;
408 any_scheduled =
true;
413 any_scheduled =
true;
416 if (!
state_.tile_result_was_written) {
418 any_scheduled =
true;
425 return any_scheduled;
430 if (
state_.full_frame_work_scheduled) {
444 if (
state_.full_frame_was_written) {
448 state_.full_frame_work_scheduled =
true;
463 return time * resolution_divider_sq;
569 LOG_DEBUG <<
"Average volume guiding denoising time: "
600 bool balance_changed)
610 if (balance_changed) {
611 ++
state_.num_rebalance_changes;
614 state_.last_rebalance_changed = balance_changed;
621 const double render_wall_time =
state_.end_render_time -
state_.start_render_time;
624 string result =
"\nRender Scheduler Summary\n\n";
635 mode =
"Interactive";
637 result +=
"Mode: " + mode +
"\n";
643 result +=
"\nAdaptive sampling:\n";
651 result +=
"\nDenoiser:\n";
657 string passes =
"Color";
659 passes +=
", Albedo";
662 passes +=
", Normal";
665 result +=
" Passes: " + passes +
"\n";
668 if (
state_.num_rebalance_requested) {
669 result +=
"\nRebalancer:\n";
676 result +=
"\nTime (in seconds):\n";
700 if (
state_.num_rebalance_requested) {
736 const double remaining_render_time =
max(0.0,
739 update_interval =
min(update_interval, remaining_render_time);
742 return update_interval;
755 if (
state_.need_rebalance_at_next_work) {
758 if (
state_.last_rebalance_changed) {
780 if (render_time < 1) {
783 if (render_time < 2) {
786 if (render_time < 4) {
799 if (time_per_sample_average == 0.0) {
807 return max(
int(num_samples_in_second * update_interval_in_seconds), 1);
821 if (num_samples == 1) {
830 const uint num_samples_down = num_samples_up - (num_samples_up >> 1);
832 const uint delta_up = num_samples_up - num_samples;
833 const uint delta_down = num_samples - num_samples_down;
835 if (delta_up <= delta_down) {
836 return num_samples_up;
839 return num_samples_down;
851 if (
state_.num_rendered_samples == 0) {
868 int num_samples_to_render =
min(num_samples_pot, max_num_samples_to_render);
875 int num_samples_to_occupy =
state_.occupancy_num_samples;
876 float ratio_to_increase_occupancy = 1.0f;
878 ratio_to_increase_occupancy = 0.7f /
state_.occupancy;
879 num_samples_to_occupy = lround(
state_.occupancy_num_samples * ratio_to_increase_occupancy);
888 double path_tracing_time_limit = 0;
899 path_tracing_time_limit = 2.0;
902 path_tracing_time_limit = 15.0;
912 const double remaining_render_time =
max(
914 if (path_tracing_time_limit == 0) {
915 path_tracing_time_limit = remaining_render_time;
918 path_tracing_time_limit =
min(path_tracing_time_limit, remaining_render_time);
921 if (path_tracing_time_limit != 0) {
925 const double predicted_render_time = num_samples_to_occupy *
927 ratio_to_increase_occupancy;
928 if (predicted_render_time > path_tracing_time_limit) {
929 num_samples_to_occupy = lround(num_samples_to_occupy *
930 (path_tracing_time_limit / predicted_render_time));
934 num_samples_to_render =
max(num_samples_to_render,
935 min(num_samples_to_occupy, max_num_samples_to_render));
945 return num_samples_to_render;
953 num_samples_to_render);
1011 ready_to_display =
true;
1041 state_.num_rendered_samples :
1053 ready_to_display =
false;
1060 delayed = (
path_trace_time_.get_wall() > 4 && num_samples_finished >= 20 &&
1074 if (denoiser_delayed) {
1087 if (
done() ||
state_.last_display_update_sample == -1) {
1105 state_.last_display_update_sample);
1106 return (
time_dt() -
state_.last_display_update_time) > update_interval;
1113 static const double kRebalanceIntervalInSeconds = 1;
1126 if (
state_.num_rendered_samples == 0) {
1127 state_.need_rebalance_at_next_work =
true;
1131 if (
state_.need_rebalance_at_next_work) {
1132 state_.need_rebalance_at_next_work =
false;
1136 if (
state_.last_rebalance_changed) {
1140 return (
time_dt() -
state_.last_rebalance_time) > kRebalanceIntervalInSeconds;
1152 const int max_res_divider_for_desired_size = long_viewport_axis / 128;
1158 max_res_divider_for_desired_size);
1168 const double desired_update_interval_in_seconds =
1179 desired_update_interval_in_seconds * 1.4, actual_time_per_update);
1249 if (
state_.start_render_time == 0.0) {
1254 const double current_time =
time_dt();
1261 state_.time_limit_reached =
true;
1262 state_.end_render_time = current_time;
1270 const double actual_time)
1272 const double ratio_between_times = actual_time / desired_time;
1294 if (resolution == INT_MAX) {
1298 int resolution_divider = 1;
1299 while (width * height > resolution * resolution) {
1300 width =
max(1, width / 2);
1301 height =
max(1, height / 2);
1303 resolution_divider <<= 1;
1306 return resolution_divider;
1311 const int resolution_divider)
1313 const int pixel_area = width * height;
1314 const int resolution = lround(
sqrt(pixel_area));
1316 return resolution / resolution_divider;
void reset()
clear internal cached data and reset random seed
static const int MAX_SAMPLES
int limit_samples_per_update_
AdaptiveSampling adaptive_sampling_
DenoiseParams denoiser_params_
void set_time_limit(const double time_limit)
void update_state_for_render_work(const RenderWork &render_work)
void report_path_trace_occupancy(const RenderWork &render_work, const float occupancy)
double guess_display_update_interval_in_seconds_for_num_samples(const int num_rendered_samples) const
float work_adaptive_threshold() const
int calculate_num_samples_per_update() const
int get_rendered_sample() const
void report_adaptive_filter_time(const RenderWork &render_work, const double time, bool is_cancelled)
struct RenderScheduler::@160041044210107046321320116341171004134167053234 state_
bool work_need_update_display(const bool denoiser_delayed)
BufferParams buffer_params_
bool work_need_rebalance()
void set_need_schedule_rebalance(bool need_schedule_rebalance)
double guess_display_update_interval_in_seconds() const
void reset_for_next_tile()
bool work_need_denoise(bool &delayed, bool &ready_to_display)
bool work_need_adaptive_filter() const
int get_num_rendered_samples() const
string full_report() const
bool need_schedule_rebalance_works_
bool is_denoise_active_during_update() const
void report_denoise_time(const RenderWork &render_work, const double time)
bool set_postprocess_render_work(RenderWork *render_work)
struct RenderScheduler::@363331175056261256267056367351034116315347004137 first_render_time_
double get_time_limit() const
double guess_display_update_interval_in_seconds_for_num_samples_no_limit(int num_rendered_samples) const
bool work_is_usable_for_first_render_estimation(const RenderWork &render_work)
int calculate_resolution_divider_for_time(const double desired_time, const double actual_time)
TimeWithAverage volume_guiding_denoise_time_
bool is_adaptive_sampling_used() const
void set_denoiser_params(const DenoiseParams ¶ms)
bool use_progressive_noise_floor_
bool render_work_reschedule_on_idle(RenderWork &render_work)
int get_num_samples() const
TimeWithAverage adaptive_filter_time_
void report_display_update_time(const RenderWork &render_work, const double time)
TimeWithAverage rebalance_time_
void set_sample_params(const int num_samples, const bool use_sample_subset, const int sample_subset_offset, const int sample_subset_length)
int get_sample_offset() const
int default_start_resolution_divider_
bool is_denoiser_gpu_used() const
TimeWithAverage display_update_time_
void reset(const BufferParams &buffer_params)
void set_full_frame_render_work(RenderWork *render_work)
double guess_viewport_navigation_update_interval_in_seconds() const
void update_start_resolution_divider()
void report_path_trace_time(const RenderWork &render_work, const double time, bool is_cancelled)
void set_adaptive_sampling(const AdaptiveSampling &adaptive_sampling)
int start_resolution_divider_
int get_num_samples_during_navigation(const int resolution_divider) const
bool render_work_reschedule_on_converge(RenderWork &render_work)
TileManager & tile_manager_
bool work_report_reset_average(const RenderWork &render_work)
bool volume_guiding_need_denoise() const
TimeWithAverage path_trace_time_
bool need_schedule_cryptomatte_
void check_time_limit_reached()
int get_start_sample_to_path_trace() const
int get_num_samples_to_path_trace() const
void render_work_reschedule_on_cancel(RenderWork &render_work)
void report_work_begin(const RenderWork &render_work)
TimeWithAverage denoise_time_
void set_need_schedule_cryptomatte(bool need_schedule_cryptomatte)
void report_rebalance_time(const RenderWork &render_work, const double time, bool balance_changed)
void set_limit_samples_per_update(const int limit_samples)
RenderWork get_render_work()
RenderScheduler(TileManager &tile_manager, const SessionParams ¶ms)
bool is_background() const
void report_volume_guiding_denoise_time(const RenderWork &render_work, const double time)
struct RenderWork::@274302037211333357242061375066056076354104241257 cryptomatte
struct RenderWork::@143272241044374345203044061122063322004171016113 tile
struct RenderWork::@332011177057136214007215372066145235154020032310 path_trace
struct RenderWork::@165363207370354371245137325023006326210217053004 adaptive_sampling
struct RenderWork::@226364033061301324161311275016362103243040016376 display
struct RenderWork::@200361311027272113377377324353154145102345065344 full
CCL_NAMESPACE_BEGIN const char * denoiserTypeToHumanReadable(DenoiserType type)
#define CCL_NAMESPACE_END
static const char * to_string(const Interpolation &interp)
ccl_device_inline int ceil_to_int(const float f)
ccl_device_inline uint next_power_of_two(const uint x)
int calculate_resolution_divider_for_resolution(int width, int height, const int resolution)
int calculate_resolution_for_divider(const int width, const int height, const int resolution_divider)
static double approximate_final_time(const RenderWork &render_work, const double time)
static uint round_num_samples_to_power_of_2(const uint num_samples)
string string_from_bool(bool var)
CCL_NAMESPACE_BEGIN string string_printf(const char *format,...)
CCL_NAMESPACE_BEGIN double time_dt()
ccl_device_inline bool is_power_of_two(const size_t x)