Cycles: Replace __MAX_CLOSURE__ build option with runtime integrator variable
[blender.git] / intern / cycles / kernel / split / kernel_branched.h
1 /*
2  * Copyright 2011-2017 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 CCL_NAMESPACE_BEGIN
18
19 #ifdef __BRANCHED_PATH__
20
21 /* sets up the various state needed to do an indirect loop */
22 ccl_device_inline void kernel_split_branched_path_indirect_loop_init(KernelGlobals *kg, int ray_index)
23 {
24         SplitBranchedState *branched_state = &kernel_split_state.branched_state[ray_index];
25
26         /* save a copy of the state to restore later */
27 #define BRANCHED_STORE(name) \
28                 branched_state->name = kernel_split_state.name[ray_index];
29
30         BRANCHED_STORE(path_state);
31         BRANCHED_STORE(throughput);
32         BRANCHED_STORE(ray);
33         BRANCHED_STORE(isect);
34         BRANCHED_STORE(ray_state);
35
36         branched_state->sd = *kernel_split_sd(sd, ray_index);
37         for(int i = 0; i < branched_state->sd.num_closure; i++) {
38                 branched_state->sd.closure[i] = kernel_split_sd(sd, ray_index)->closure[i];
39         }
40
41 #undef BRANCHED_STORE
42
43         /* set loop counters to intial position */
44         branched_state->next_closure = 0;
45         branched_state->next_sample = 0;
46 }
47
48 /* ends an indirect loop and restores the previous state */
49 ccl_device_inline void kernel_split_branched_path_indirect_loop_end(KernelGlobals *kg, int ray_index)
50 {
51         SplitBranchedState *branched_state = &kernel_split_state.branched_state[ray_index];
52
53         /* restore state */
54 #define BRANCHED_RESTORE(name) \
55                 kernel_split_state.name[ray_index] = branched_state->name;
56
57         BRANCHED_RESTORE(path_state);
58         BRANCHED_RESTORE(throughput);
59         BRANCHED_RESTORE(ray);
60         BRANCHED_RESTORE(isect);
61         BRANCHED_RESTORE(ray_state);
62
63         *kernel_split_sd(sd, ray_index) = branched_state->sd;
64         for(int i = 0; i < branched_state->sd.num_closure; i++) {
65                 kernel_split_sd(sd, ray_index)->closure[i] = branched_state->sd.closure[i];
66         }
67
68 #undef BRANCHED_RESTORE
69
70         /* leave indirect loop */
71         REMOVE_RAY_FLAG(kernel_split_state.ray_state, ray_index, RAY_BRANCHED_INDIRECT);
72 }
73
74 ccl_device_inline bool kernel_split_branched_indirect_start_shared(KernelGlobals *kg, int ray_index)
75 {
76         ccl_global char *ray_state = kernel_split_state.ray_state;
77
78         int inactive_ray = dequeue_ray_index(QUEUE_INACTIVE_RAYS,
79                 kernel_split_state.queue_data, kernel_split_params.queue_size, kernel_split_params.queue_index);
80
81         if(!IS_STATE(ray_state, inactive_ray, RAY_INACTIVE)) {
82                 return false;
83         }
84
85 #define SPLIT_DATA_ENTRY(type, name, num) \
86                 kernel_split_state.name[inactive_ray] = kernel_split_state.name[ray_index];
87         SPLIT_DATA_ENTRIES_BRANCHED_SHARED
88 #undef SPLIT_DATA_ENTRY
89
90         kernel_split_state.branched_state[inactive_ray].shared_sample_count = 0;
91         kernel_split_state.branched_state[inactive_ray].original_ray = ray_index;
92         kernel_split_state.branched_state[inactive_ray].waiting_on_shared_samples = false;
93
94         PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
95         PathRadiance *inactive_L = &kernel_split_state.path_radiance[inactive_ray];
96
97         path_radiance_init(inactive_L, kernel_data.film.use_light_pass);
98         path_radiance_copy_indirect(inactive_L, L);
99
100         ray_state[inactive_ray] = RAY_REGENERATED;
101         ADD_RAY_FLAG(ray_state, inactive_ray, RAY_BRANCHED_INDIRECT_SHARED);
102         ADD_RAY_FLAG(ray_state, inactive_ray, IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT));
103
104         atomic_fetch_and_inc_uint32((ccl_global uint*)&kernel_split_state.branched_state[ray_index].shared_sample_count);
105
106         return true;
107 }
108
109 /* bounce off surface and integrate indirect light */
110 ccl_device_noinline bool kernel_split_branched_path_surface_indirect_light_iter(KernelGlobals *kg,
111                                                                                 int ray_index,
112                                                                                 float num_samples_adjust,
113                                                                                 ShaderData *saved_sd,
114                                                                                 bool reset_path_state,
115                                                                                 bool wait_for_shared)
116 {
117         SplitBranchedState *branched_state = &kernel_split_state.branched_state[ray_index];
118
119         ShaderData *sd = saved_sd;
120         PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
121         float3 throughput = branched_state->throughput;
122         ccl_global PathState *ps = &kernel_split_state.path_state[ray_index];
123
124         float sum_sample_weight = 0.0f;
125 #ifdef __DENOISING_FEATURES__
126         if(ps->denoising_feature_weight > 0.0f) {
127                 for(int i = 0; i < sd->num_closure; i++) {
128                         const ShaderClosure *sc = &sd->closure[i];
129
130                         /* transparency is not handled here, but in outer loop */
131                         if(!CLOSURE_IS_BSDF(sc->type) || CLOSURE_IS_BSDF_TRANSPARENT(sc->type)) {
132                                 continue;
133                         }
134
135                         sum_sample_weight += sc->sample_weight;
136                 }
137         }
138         else {
139                 sum_sample_weight = 1.0f;
140         }
141 #endif  /* __DENOISING_FEATURES__ */
142
143         for(int i = branched_state->next_closure; i < sd->num_closure; i++) {
144                 const ShaderClosure *sc = &sd->closure[i];
145
146                 if(!CLOSURE_IS_BSDF(sc->type))
147                         continue;
148                 /* transparency is not handled here, but in outer loop */
149                 if(sc->type == CLOSURE_BSDF_TRANSPARENT_ID)
150                         continue;
151
152                 int num_samples;
153
154                 if(CLOSURE_IS_BSDF_DIFFUSE(sc->type))
155                         num_samples = kernel_data.integrator.diffuse_samples;
156                 else if(CLOSURE_IS_BSDF_BSSRDF(sc->type))
157                         num_samples = 1;
158                 else if(CLOSURE_IS_BSDF_GLOSSY(sc->type))
159                         num_samples = kernel_data.integrator.glossy_samples;
160                 else
161                         num_samples = kernel_data.integrator.transmission_samples;
162
163                 num_samples = ceil_to_int(num_samples_adjust*num_samples);
164
165                 float num_samples_inv = num_samples_adjust/num_samples;
166
167                 for(int j = branched_state->next_sample; j < num_samples; j++) {
168                         if(reset_path_state) {
169                                 *ps = branched_state->path_state;
170                         }
171
172                         ps->rng_hash = cmj_hash(branched_state->path_state.rng_hash, i);
173
174                         ccl_global float3 *tp = &kernel_split_state.throughput[ray_index];
175                         *tp = throughput;
176
177                         ccl_global Ray *bsdf_ray = &kernel_split_state.ray[ray_index];
178
179                         if(!kernel_branched_path_surface_bounce(kg,
180                                                                 sd,
181                                                                 sc,
182                                                                 j,
183                                                                 num_samples,
184                                                                 tp,
185                                                                 ps,
186                                                                 &L->state,
187                                                                 bsdf_ray,
188                                                                 sum_sample_weight))
189                         {
190                                 continue;
191                         }
192
193                         ps->rng_hash = branched_state->path_state.rng_hash;
194
195                         /* update state for next iteration */
196                         branched_state->next_closure = i;
197                         branched_state->next_sample = j+1;
198
199                         /* start the indirect path */
200                         *tp *= num_samples_inv;
201
202                         if(kernel_split_branched_indirect_start_shared(kg, ray_index)) {
203                                 continue;
204                         }
205
206                         return true;
207                 }
208
209                 branched_state->next_sample = 0;
210         }
211
212         branched_state->next_closure = sd->num_closure;
213
214         if(wait_for_shared) {
215                 branched_state->waiting_on_shared_samples = (branched_state->shared_sample_count > 0);
216                 if(branched_state->waiting_on_shared_samples) {
217                         return true;
218                 }
219         }
220
221         return false;
222 }
223
224 #endif  /* __BRANCHED_PATH__ */
225
226 CCL_NAMESPACE_END
227