forked from blender/blender
me-main #1
@ -886,7 +886,7 @@ int RenderScheduler::get_num_samples_during_navigation(int resolution_divider) c
|
|||||||
{
|
{
|
||||||
/* Special trick for fast navigation: schedule multiple samples during fast navigation
|
/* Special trick for fast navigation: schedule multiple samples during fast navigation
|
||||||
* (which will prefer to use lower resolution to keep up with refresh rate). This gives more
|
* (which will prefer to use lower resolution to keep up with refresh rate). This gives more
|
||||||
* usable visual feedback for artists. There are a couple of tricks though. */
|
* usable visual feedback for artists. */
|
||||||
|
|
||||||
if (is_denoise_active_during_update()) {
|
if (is_denoise_active_during_update()) {
|
||||||
/* When denoising is used during navigation prefer using a higher resolution with less samples
|
/* When denoising is used during navigation prefer using a higher resolution with less samples
|
||||||
@ -896,25 +896,12 @@ int RenderScheduler::get_num_samples_during_navigation(int resolution_divider) c
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resolution_divider <= pixel_size_) {
|
/* Schedule samples equal to the resolution divider up to a maximum of 4.
|
||||||
/* When resolution divider is at or below pixel size, schedule one sample. This doesn't effect
|
* The idea is to have enough information on the screen by increasing the sample count as the
|
||||||
* the sample count at this resolution division, but instead assists in the calculation of
|
* resolution is decreased. */
|
||||||
* the resolution divider. */
|
/* NOTE: Changeing this formula will change the formula in
|
||||||
return 1;
|
* "RenderScheduler::calculate_resolution_divider_for_time()"*/
|
||||||
}
|
return min(max(1, resolution_divider / pixel_size_), 4);
|
||||||
|
|
||||||
if (resolution_divider == pixel_size_ * 2) {
|
|
||||||
/* When resolution divider is the previous step to the final resolution, schedule two samples.
|
|
||||||
* This is so that rendering on lower resolution does not exceed time that it takes to render
|
|
||||||
* first sample at the full resolution. */
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Always render 4 samples, even if scene is configured for less.
|
|
||||||
* The idea here is to have enough information on the screen. Resolution divider of 2 allows us
|
|
||||||
* to have 4 time extra samples, so overall worst case timing is the same as the final resolution
|
|
||||||
* at one sample. */
|
|
||||||
return 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RenderScheduler::work_need_adaptive_filter() const
|
bool RenderScheduler::work_need_adaptive_filter() const
|
||||||
@ -1100,9 +1087,10 @@ void RenderScheduler::update_start_resolution_divider()
|
|||||||
/* TODO(sergey): Need to add hysteresis to avoid resolution divider bouncing around when actual
|
/* TODO(sergey): Need to add hysteresis to avoid resolution divider bouncing around when actual
|
||||||
* render time is somewhere on a boundary between two resolutions. */
|
* render time is somewhere on a boundary between two resolutions. */
|
||||||
|
|
||||||
/* Never increase resolution to higher than the pixel size (which is possible if the scene is
|
/* Don't let resolution drop below the desired one. It's better to be slow than provide an
|
||||||
* simple and compute device is fast). */
|
* unreadable viewport render. */
|
||||||
start_resolution_divider_ = max(resolution_divider_for_update, pixel_size_);
|
start_resolution_divider_ = min(resolution_divider_for_update,
|
||||||
|
default_start_resolution_divider_);
|
||||||
|
|
||||||
VLOG_WORK << "Calculated resolution divider is " << start_resolution_divider_;
|
VLOG_WORK << "Calculated resolution divider is " << start_resolution_divider_;
|
||||||
}
|
}
|
||||||
@ -1187,24 +1175,24 @@ void RenderScheduler::check_time_limit_reached()
|
|||||||
|
|
||||||
int RenderScheduler::calculate_resolution_divider_for_time(double desired_time, double actual_time)
|
int RenderScheduler::calculate_resolution_divider_for_time(double desired_time, double actual_time)
|
||||||
{
|
{
|
||||||
/* TODO(sergey): There should a non-iterative analytical formula here. */
|
const double ratio_between_times = actual_time / desired_time;
|
||||||
|
|
||||||
int resolution_divider = 1;
|
/* We can pass "ratio_between_times" to "get_num_samples_during_navigation()" to get our
|
||||||
|
* navigation samples because the equation for calculating the resolution divider is as follows:
|
||||||
|
* "actual_time / desired_time = sqr(resolution_divider) / sample_count".
|
||||||
|
* While "resolution_divider" is less than or equal to 4, "resolution_divider = sample_count"
|
||||||
|
* (This relationship is determined in "get_num_samples_during_navigation()"). With some
|
||||||
|
* substitution we end up with "actual_time / desired_time = resolution_divider" while the
|
||||||
|
* resolution divider is less than or equal to 4. Once the resolution divider increases above 4,
|
||||||
|
* the relationsip of "actual_time / desired_time = resolution_divider" is no longer true,
|
||||||
|
* however the sample count retrieved from "get_num_samples_during_navigation()" is still
|
||||||
|
* accurate if we continue using this assumption. It should be noted that the interaction between
|
||||||
|
* pixel_size, sample count, and resolution divider are automatically accounted for and that's
|
||||||
|
* why pixel_size isn't included in any of the equations. */
|
||||||
|
const int navigation_samples = get_num_samples_during_navigation(
|
||||||
|
ceil_to_int(ratio_between_times));
|
||||||
|
|
||||||
/* This algorithm iterates through resolution dividers until a divider is found that achieves
|
return ceil_to_int(sqrt(navigation_samples * ratio_between_times));
|
||||||
* the desired render time. A limit of default_start_resolution_divider_ is put in place as the
|
|
||||||
* maximum resolution divider to avoid an unreadable viewport due to a low resolution.
|
|
||||||
* pre_resolution_division_samples and post_resolution_division_samples are used in this
|
|
||||||
* calculation to better predict the performance impact of changing resolution divisions as
|
|
||||||
* the sample count can also change between resolution divisions. */
|
|
||||||
while (actual_time > desired_time && resolution_divider < default_start_resolution_divider_) {
|
|
||||||
int pre_resolution_division_samples = get_num_samples_during_navigation(resolution_divider);
|
|
||||||
resolution_divider = resolution_divider * 2;
|
|
||||||
int post_resolution_division_samples = get_num_samples_during_navigation(resolution_divider);
|
|
||||||
actual_time /= 4.0 * pre_resolution_division_samples / post_resolution_division_samples;
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolution_divider;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int calculate_resolution_divider_for_resolution(int width, int height, int resolution)
|
int calculate_resolution_divider_for_resolution(int width, int height, int resolution)
|
||||||
|
Loading…
Reference in New Issue
Block a user