Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/integrator/path_trace_work_gpu.cpp')
-rw-r--r--intern/cycles/integrator/path_trace_work_gpu.cpp98
1 files changed, 69 insertions, 29 deletions
diff --git a/intern/cycles/integrator/path_trace_work_gpu.cpp b/intern/cycles/integrator/path_trace_work_gpu.cpp
index 2c71b1cf876..36f275e1075 100644
--- a/intern/cycles/integrator/path_trace_work_gpu.cpp
+++ b/intern/cycles/integrator/path_trace_work_gpu.cpp
@@ -361,26 +361,13 @@ bool PathTraceWorkGPU::enqueue_path_iteration()
return false;
}
- /* If the number of shadow kernels dropped to zero, set the next shadow path
- * index to zero as well.
- *
- * TODO: use shadow path compaction to lower it more often instead of letting
- * it fill up entirely? */
- const int num_queued_shadow =
- queue_counter->num_queued[DEVICE_KERNEL_INTEGRATOR_INTERSECT_SHADOW] +
- queue_counter->num_queued[DEVICE_KERNEL_INTEGRATOR_SHADE_SHADOW];
- if (num_queued_shadow == 0) {
- if (integrator_next_shadow_path_index_.data()[0] != 0) {
- integrator_next_shadow_path_index_.data()[0] = 0;
- queue_->copy_to_device(integrator_next_shadow_path_index_);
- }
- }
-
/* For kernels that add shadow paths, check if there is enough space available.
* If not, schedule shadow kernels first to clear out the shadow paths. */
int num_paths_limit = INT_MAX;
if (kernel_creates_shadow_paths(kernel)) {
+ compact_shadow_paths();
+
const int available_shadow_paths = max_num_paths_ -
integrator_next_shadow_path_index_.data()[0];
if (available_shadow_paths < queue_counter->num_queued[kernel]) {
@@ -535,18 +522,76 @@ void PathTraceWorkGPU::compute_queued_paths(DeviceKernel kernel, DeviceKernel qu
queue_->enqueue(kernel, work_size, args);
}
-void PathTraceWorkGPU::compact_states(const int num_active_paths)
+void PathTraceWorkGPU::compact_main_paths(const int num_active_paths)
{
+ /* Early out if there is nothing that needs to be compacted. */
if (num_active_paths == 0) {
max_active_main_path_index_ = 0;
+ return;
}
- /* Compact fragmented path states into the start of the array, moving any paths
- * with index higher than the number of active paths into the gaps. */
- if (max_active_main_path_index_ == num_active_paths) {
+ const int min_compact_paths = 32;
+ if (max_active_main_path_index_ == num_active_paths ||
+ max_active_main_path_index_ < min_compact_paths) {
+ return;
+ }
+
+ /* Compact. */
+ compact_paths(num_active_paths,
+ max_active_main_path_index_,
+ DEVICE_KERNEL_INTEGRATOR_TERMINATED_PATHS_ARRAY,
+ DEVICE_KERNEL_INTEGRATOR_COMPACT_PATHS_ARRAY,
+ DEVICE_KERNEL_INTEGRATOR_COMPACT_STATES);
+
+ /* Adjust max active path index now we know which part of the array is actually used. */
+ max_active_main_path_index_ = num_active_paths;
+}
+
+void PathTraceWorkGPU::compact_shadow_paths()
+{
+ IntegratorQueueCounter *queue_counter = integrator_queue_counter_.data();
+ const int num_active_paths =
+ queue_counter->num_queued[DEVICE_KERNEL_INTEGRATOR_INTERSECT_SHADOW] +
+ queue_counter->num_queued[DEVICE_KERNEL_INTEGRATOR_SHADE_SHADOW];
+
+ /* Early out if there is nothing that needs to be compacted. */
+ if (num_active_paths == 0) {
+ if (integrator_next_shadow_path_index_.data()[0] != 0) {
+ integrator_next_shadow_path_index_.data()[0] = 0;
+ queue_->copy_to_device(integrator_next_shadow_path_index_);
+ }
+ return;
+ }
+
+ /* Compact if we can reduce the space used by half. Not always since
+ * compaction has a cost. */
+ const float shadow_compact_ratio = 0.5f;
+ const int min_compact_paths = 32;
+ if (integrator_next_shadow_path_index_.data()[0] < num_active_paths * shadow_compact_ratio ||
+ integrator_next_shadow_path_index_.data()[0] < min_compact_paths) {
return;
}
+ /* Compact. */
+ compact_paths(num_active_paths,
+ integrator_next_shadow_path_index_.data()[0],
+ DEVICE_KERNEL_INTEGRATOR_TERMINATED_SHADOW_PATHS_ARRAY,
+ DEVICE_KERNEL_INTEGRATOR_COMPACT_SHADOW_PATHS_ARRAY,
+ DEVICE_KERNEL_INTEGRATOR_COMPACT_SHADOW_STATES);
+
+ /* Adjust max active path index now we know which part of the array is actually used. */
+ integrator_next_shadow_path_index_.data()[0] = num_active_paths;
+ queue_->copy_to_device(integrator_next_shadow_path_index_);
+}
+
+void PathTraceWorkGPU::compact_paths(const int num_active_paths,
+ const int max_active_path_index,
+ DeviceKernel terminated_paths_kernel,
+ DeviceKernel compact_paths_kernel,
+ DeviceKernel compact_kernel)
+{
+ /* Compact fragmented path states into the start of the array, moving any paths
+ * with index higher than the number of active paths into the gaps. */
void *d_compact_paths = (void *)queued_paths_.device_pointer;
void *d_num_queued_paths = (void *)num_queued_paths_.device_pointer;
@@ -557,17 +602,17 @@ void PathTraceWorkGPU::compact_states(const int num_active_paths)
int work_size = num_active_paths;
void *args[] = {&work_size, &d_compact_paths, &d_num_queued_paths, &offset};
queue_->zero_to_device(num_queued_paths_);
- queue_->enqueue(DEVICE_KERNEL_INTEGRATOR_TERMINATED_PATHS_ARRAY, work_size, args);
+ queue_->enqueue(terminated_paths_kernel, work_size, args);
}
/* Create array of paths that we need to compact, where the path index is bigger
* than the number of active paths. */
{
- int work_size = max_active_main_path_index_;
+ int work_size = max_active_path_index;
void *args[] = {
&work_size, &d_compact_paths, &d_num_queued_paths, const_cast<int *>(&num_active_paths)};
queue_->zero_to_device(num_queued_paths_);
- queue_->enqueue(DEVICE_KERNEL_INTEGRATOR_COMPACT_PATHS_ARRAY, work_size, args);
+ queue_->enqueue(compact_paths_kernel, work_size, args);
}
queue_->copy_from_device(num_queued_paths_);
@@ -582,13 +627,8 @@ void PathTraceWorkGPU::compact_states(const int num_active_paths)
int terminated_states_offset = num_active_paths;
void *args[] = {
&d_compact_paths, &active_states_offset, &terminated_states_offset, &work_size};
- queue_->enqueue(DEVICE_KERNEL_INTEGRATOR_COMPACT_STATES, work_size, args);
+ queue_->enqueue(compact_kernel, work_size, args);
}
-
- queue_->synchronize();
-
- /* Adjust max active path index now we know which part of the array is actually used. */
- max_active_main_path_index_ = num_active_paths;
}
bool PathTraceWorkGPU::enqueue_work_tiles(bool &finished)
@@ -669,7 +709,7 @@ bool PathTraceWorkGPU::enqueue_work_tiles(bool &finished)
/* Compact state array when number of paths becomes small relative to the
* known maximum path index, which makes computing active index arrays slow. */
- compact_states(num_active_paths);
+ compact_main_paths(num_active_paths);
if (has_shadow_catcher()) {
integrator_next_main_path_index_.data()[0] = num_paths;