WIP: uv-simple-select #1

Closed
Chris Blackbourn wants to merge 182 commits from uv-simple-select into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
Showing only changes of commit 6e52a74202 - Show all commits

View File

@ -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)