Cycles: Make all #include statements relative to cycles source directory
[blender.git] / intern / cycles / kernel / split / kernel_data_init.h
1 /*
2  * Copyright 2011-2015 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 Initializes structures needed in path-iteration kernels.
20  *
21  * Note on Queues:
22  * All slots in queues are initialized to queue empty slot;
23  * The number of elements in the queues is initialized to 0;
24  */
25
26 /* Distributes an amount of work across all threads
27  * note: work done inside the loop may not show up to all threads till after
28  * the current kernel has completed
29  */
30 #define parallel_for(kg, iter_name, work_size) \
31         for(size_t _size = (work_size), \
32             _global_size = ccl_global_size(0) * ccl_global_size(1), \
33             _n = _size / _global_size, \
34                 _thread = ccl_global_id(0) + ccl_global_id(1) * ccl_global_size(0), \
35             iter_name = (_n > 0) ? (_thread * _n) : (_thread) \
36                 ; \
37                 (iter_name < (_thread+1) * _n) || (iter_name == _n * _global_size + _thread && _thread < _size % _global_size) \
38                 ; \
39                 iter_name = (iter_name != (_thread+1) * _n - 1) ? (iter_name + 1) : (_n * _global_size + _thread) \
40         )
41
42 #ifndef __KERNEL_CPU__
43 ccl_device void kernel_data_init(
44 #else
45 void KERNEL_FUNCTION_FULL_NAME(data_init)(
46 #endif
47         KernelGlobals *kg,
48         ccl_constant KernelData *data,
49         ccl_global void *split_data_buffer,
50         int num_elements,
51         ccl_global char *ray_state,
52         ccl_global uint *rng_state,
53
54 #ifdef __KERNEL_OPENCL__
55 #define KERNEL_TEX(type, ttype, name)                                   \
56         ccl_global type *name,
57 #include "kernel/kernel_textures.h"
58 #endif
59
60         int start_sample,
61         int end_sample,
62         int sx, int sy, int sw, int sh, int offset, int stride,
63         ccl_global int *Queue_index,                 /* Tracks the number of elements in queues */
64         int queuesize,                               /* size (capacity) of the queue */
65         ccl_global char *use_queues_flag,            /* flag to decide if scene-intersect kernel should use queues to fetch ray index */
66         ccl_global unsigned int *work_pools,      /* Work pool for each work group */
67         unsigned int num_samples,
68         ccl_global float *buffer)
69 {
70 #ifdef __KERNEL_OPENCL__
71         kg->data = data;
72 #endif
73
74         kernel_split_params.x = sx;
75         kernel_split_params.y = sy;
76         kernel_split_params.w = sw;
77         kernel_split_params.h = sh;
78
79         kernel_split_params.offset = offset;
80         kernel_split_params.stride = stride;
81
82         kernel_split_params.rng_state = rng_state;
83
84         kernel_split_params.start_sample = start_sample;
85         kernel_split_params.end_sample = end_sample;
86
87         kernel_split_params.work_pools = work_pools;
88         kernel_split_params.num_samples = num_samples;
89
90         kernel_split_params.queue_index = Queue_index;
91         kernel_split_params.queue_size = queuesize;
92         kernel_split_params.use_queues_flag = use_queues_flag;
93
94         kernel_split_params.buffer = buffer;
95
96         split_data_init(kg, &kernel_split_state, num_elements, split_data_buffer, ray_state);
97
98 #ifdef __KERNEL_OPENCL__
99 #define KERNEL_TEX(type, ttype, name) \
100         kg->name = name;
101 #include "kernel/kernel_textures.h"
102 #endif
103
104         int thread_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
105
106         /* Initialize queue data and queue index. */
107         if(thread_index < queuesize) {
108                 /* Initialize active ray queue. */
109                 kernel_split_state.queue_data[QUEUE_ACTIVE_AND_REGENERATED_RAYS * queuesize + thread_index] = QUEUE_EMPTY_SLOT;
110                 /* Initialize background and buffer update queue. */
111                 kernel_split_state.queue_data[QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS * queuesize + thread_index] = QUEUE_EMPTY_SLOT;
112                 /* Initialize shadow ray cast of AO queue. */
113                 kernel_split_state.queue_data[QUEUE_SHADOW_RAY_CAST_AO_RAYS * queuesize + thread_index] = QUEUE_EMPTY_SLOT;
114                 /* Initialize shadow ray cast of direct lighting queue. */
115                 kernel_split_state.queue_data[QUEUE_SHADOW_RAY_CAST_DL_RAYS * queuesize + thread_index] = QUEUE_EMPTY_SLOT;
116         }
117
118         if(thread_index == 0) {
119                 Queue_index[QUEUE_ACTIVE_AND_REGENERATED_RAYS] = 0;
120                 Queue_index[QUEUE_HITBG_BUFF_UPDATE_TOREGEN_RAYS] = 0;
121                 Queue_index[QUEUE_SHADOW_RAY_CAST_AO_RAYS] = 0;
122                 Queue_index[QUEUE_SHADOW_RAY_CAST_DL_RAYS] = 0;
123                 /* The scene-intersect kernel should not use the queues very first time.
124                  * since the queue would be empty.
125                  */
126                 *use_queues_flag = 0;
127         }
128
129         /* zero the tiles pixels and initialize rng_state if this is the first sample */
130         if(start_sample == 0) {
131                 parallel_for(kg, i, sw * sh * kernel_data.film.pass_stride) {
132                         int pixel = i / kernel_data.film.pass_stride;
133                         int pass = i % kernel_data.film.pass_stride;
134
135                         int x = sx + pixel % sw;
136                         int y = sy + pixel / sw;
137
138                         int index = (offset + x + y*stride) * kernel_data.film.pass_stride + pass;
139
140                         *(buffer + index) = 0.0f;
141                 }
142
143                 parallel_for(kg, i, sw * sh) {
144                         int x = sx + i % sw;
145                         int y = sy + i / sw;
146
147                         int index = (offset + x + y*stride);
148                         *(rng_state + index) = hash_int_2d(x, y);
149                 }
150         }
151 }
152
153 CCL_NAMESPACE_END