66ce2dfb6f14815a6824523f20087646e26bc3bc
[blender.git] / intern / cycles / kernel / split / kernel_queue_enqueue.h
1 /*
2  * Copyright 2011-2016 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 /* This kernel enqueues rays of different ray state into their
20  * appropriate queues:
21  *
22  * 1. Rays that have been determined to hit the background from the
23  *    "kernel_scene_intersect" kernel are enqueued in
24  *    QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS;
25  * 2. Rays that have been determined to be actively participating in pat
26  *    -iteration will be enqueued into QUEUE_ACTIVE_AND_REGENERATED_RAYS.
27  *
28  * State of queue during other times this kernel is called:
29  * At entry,
30  *   - QUEUE_ACTIVE_AND_REGENERATED_RAYS will be empty.
31  *   - QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS will contain RAY_TO_REGENERATE
32  *     and RAY_UPDATE_BUFFER rays.
33  * At exit,
34  *   - QUEUE_ACTIVE_AND_REGENERATED_RAYS will be filled with RAY_ACTIVE rays.
35  *   - QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS will be filled with
36  *     RAY_TO_REGENERATE, RAY_UPDATE_BUFFER, RAY_HIT_BACKGROUND rays.
37  */
38 ccl_device void kernel_queue_enqueue(KernelGlobals *kg,
39                                      ccl_local_param QueueEnqueueLocals *locals)
40 {
41         /* We have only 2 cases (Hit/Not-Hit) */
42         int lidx = ccl_local_id(1) * ccl_local_size(0) + ccl_local_id(0);
43         int ray_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
44
45         if(lidx == 0) {
46                 locals->queue_atomics[0] = 0;
47                 locals->queue_atomics[1] = 0;
48         }
49         ccl_barrier(CCL_LOCAL_MEM_FENCE);
50
51         int queue_number = -1;
52
53         if(IS_STATE(kernel_split_state.ray_state, ray_index, RAY_HIT_BACKGROUND) ||
54            IS_STATE(kernel_split_state.ray_state, ray_index, RAY_UPDATE_BUFFER) ||
55            IS_STATE(kernel_split_state.ray_state, ray_index, RAY_TO_REGENERATE)) {
56                 queue_number = QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS;
57         }
58         else if(IS_STATE(kernel_split_state.ray_state, ray_index, RAY_ACTIVE) ||
59                 IS_STATE(kernel_split_state.ray_state, ray_index, RAY_REGENERATED)) {
60                 queue_number = QUEUE_ACTIVE_AND_REGENERATED_RAYS;
61         }
62
63         unsigned int my_lqidx;
64         if(queue_number != -1) {
65                 my_lqidx = get_local_queue_index(queue_number, locals->queue_atomics);
66         }
67         ccl_barrier(CCL_LOCAL_MEM_FENCE);
68
69         if(lidx == 0) {
70                 locals->queue_atomics[QUEUE_ACTIVE_AND_REGENERATED_RAYS] =
71                         get_global_per_queue_offset(QUEUE_ACTIVE_AND_REGENERATED_RAYS,
72                                                     locals->queue_atomics,
73                                                     kernel_split_params.queue_index);
74                 locals->queue_atomics[QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS] =
75                         get_global_per_queue_offset(QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS,
76                                                     locals->queue_atomics,
77                                                     kernel_split_params.queue_index);
78         }
79         ccl_barrier(CCL_LOCAL_MEM_FENCE);
80
81         unsigned int my_gqidx;
82         if(queue_number != -1) {
83                 my_gqidx = get_global_queue_index(queue_number,
84                                                   kernel_split_params.queue_size,
85                                                   my_lqidx,
86                                                   locals->queue_atomics);
87                 kernel_split_state.queue_data[my_gqidx] = ray_index;
88         }
89 }
90
91 CCL_NAMESPACE_END