Cycles: Added Cryptomatte output.
[blender.git] / intern / cycles / kernel / kernel_globals.h
1 /*
2  * Copyright 2011-2013 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 /* Constant Globals */
18
19 #ifndef __KERNEL_GLOBALS_H__
20 #define __KERNEL_GLOBALS_H__
21
22 #ifdef __KERNEL_CPU__
23 #  include "util/util_vector.h"
24 #  include "util/util_map.h"
25 #endif
26
27 #ifdef __KERNEL_OPENCL__
28 #  include "util/util_atomic.h"
29 #endif
30
31 CCL_NAMESPACE_BEGIN
32
33 /* On the CPU, we pass along the struct KernelGlobals to nearly everywhere in
34  * the kernel, to access constant data. These are all stored as "textures", but
35  * these are really just standard arrays. We can't use actually globals because
36  * multiple renders may be running inside the same process. */
37
38 #ifdef __KERNEL_CPU__
39
40 #  ifdef __OSL__
41 struct OSLGlobals;
42 struct OSLThreadData;
43 struct OSLShadingSystem;
44 #  endif
45
46 typedef unordered_map<float, float> CoverageMap;
47
48 struct Intersection;
49 struct VolumeStep;
50
51 typedef struct KernelGlobals {
52 #  define KERNEL_TEX(type, name) texture<type> name;
53 #  include "kernel/kernel_textures.h"
54
55         KernelData __data;
56
57 #  ifdef __OSL__
58         /* On the CPU, we also have the OSL globals here. Most data structures are shared
59          * with SVM, the difference is in the shaders and object/mesh attributes. */
60         OSLGlobals *osl;
61         OSLShadingSystem *osl_ss;
62         OSLThreadData *osl_tdata;
63 #  endif
64
65         /* **** Run-time data ****  */
66
67         /* Heap-allocated storage for transparent shadows intersections. */
68         Intersection *transparent_shadow_intersections;
69
70         /* Storage for decoupled volume steps. */
71         VolumeStep *decoupled_volume_steps[2];
72         int decoupled_volume_steps_index;
73
74         /* A buffer for storing per-pixel coverage for Cryptomatte. */
75         CoverageMap *coverage_object;
76         CoverageMap *coverage_material;
77         CoverageMap *coverage_asset;
78
79         /* split kernel */
80         SplitData split_data;
81         SplitParams split_param_data;
82
83         int2 global_size;
84         int2 global_id;
85 } KernelGlobals;
86
87 #endif  /* __KERNEL_CPU__ */
88
89 /* For CUDA, constant memory textures must be globals, so we can't put them
90  * into a struct. As a result we don't actually use this struct and use actual
91  * globals and simply pass along a NULL pointer everywhere, which we hope gets
92  * optimized out. */
93
94 #ifdef __KERNEL_CUDA__
95
96 __constant__ KernelData __data;
97 typedef struct KernelGlobals {
98         /* NOTE: Keep the size in sync with SHADOW_STACK_MAX_HITS. */
99         Intersection hits_stack[64];
100 } KernelGlobals;
101
102 #  define KERNEL_TEX(type, name) const __constant__ __device__ type *name;
103 #  include "kernel/kernel_textures.h"
104
105 #endif  /* __KERNEL_CUDA__ */
106
107 /* OpenCL */
108
109 #ifdef __KERNEL_OPENCL__
110
111 #  define KERNEL_TEX(type, name) \
112 typedef type name##_t;
113 #  include "kernel/kernel_textures.h"
114
115 typedef ccl_addr_space struct KernelGlobals {
116         ccl_constant KernelData *data;
117         ccl_global char *buffers[8];
118
119 #  define KERNEL_TEX(type, name) \
120         TextureInfo name;
121 #  include "kernel/kernel_textures.h"
122
123 #  ifdef __SPLIT_KERNEL__
124         SplitData split_data;
125         SplitParams split_param_data;
126 #  endif
127 } KernelGlobals;
128
129 #define KERNEL_BUFFER_PARAMS \
130         ccl_global char *buffer0, \
131         ccl_global char *buffer1, \
132         ccl_global char *buffer2, \
133         ccl_global char *buffer3, \
134         ccl_global char *buffer4, \
135         ccl_global char *buffer5, \
136         ccl_global char *buffer6, \
137         ccl_global char *buffer7
138
139 #define KERNEL_BUFFER_ARGS buffer0, buffer1, buffer2, buffer3, buffer4, buffer5, buffer6, buffer7
140
141 ccl_device_inline void kernel_set_buffer_pointers(KernelGlobals *kg, KERNEL_BUFFER_PARAMS)
142 {
143 #ifdef __SPLIT_KERNEL__
144         if(ccl_local_id(0) + ccl_local_id(1) == 0)
145 #endif
146         {
147                 kg->buffers[0] = buffer0;
148                 kg->buffers[1] = buffer1;
149                 kg->buffers[2] = buffer2;
150                 kg->buffers[3] = buffer3;
151                 kg->buffers[4] = buffer4;
152                 kg->buffers[5] = buffer5;
153                 kg->buffers[6] = buffer6;
154                 kg->buffers[7] = buffer7;
155         }
156
157 #  ifdef __SPLIT_KERNEL__
158         ccl_barrier(CCL_LOCAL_MEM_FENCE);
159 #  endif
160 }
161
162 ccl_device_inline void kernel_set_buffer_info(KernelGlobals *kg)
163 {
164 #  ifdef __SPLIT_KERNEL__
165         if(ccl_local_id(0) + ccl_local_id(1) == 0)
166 #  endif
167         {
168                 ccl_global TextureInfo *info = (ccl_global TextureInfo*)kg->buffers[0];
169
170 #  define KERNEL_TEX(type, name) \
171                 kg->name = *(info++);
172 #  include "kernel/kernel_textures.h"
173         }
174
175 #  ifdef __SPLIT_KERNEL__
176         ccl_barrier(CCL_LOCAL_MEM_FENCE);
177 #  endif
178 }
179
180 #endif  /* __KERNEL_OPENCL__ */
181
182 /* Interpolated lookup table access */
183
184 ccl_device float lookup_table_read(KernelGlobals *kg, float x, int offset, int size)
185 {
186         x = saturate(x)*(size-1);
187
188         int index = min(float_to_int(x), size-1);
189         int nindex = min(index+1, size-1);
190         float t = x - index;
191
192         float data0 = kernel_tex_fetch(__lookup_table, index + offset);
193         if(t == 0.0f)
194                 return data0;
195
196         float data1 = kernel_tex_fetch(__lookup_table, nindex + offset);
197         return (1.0f - t)*data0 + t*data1;
198 }
199
200 ccl_device float lookup_table_read_2D(KernelGlobals *kg, float x, float y, int offset, int xsize, int ysize)
201 {
202         y = saturate(y)*(ysize-1);
203
204         int index = min(float_to_int(y), ysize-1);
205         int nindex = min(index+1, ysize-1);
206         float t = y - index;
207
208         float data0 = lookup_table_read(kg, x, offset + xsize*index, xsize);
209         if(t == 0.0f)
210                 return data0;
211
212         float data1 = lookup_table_read(kg, x, offset + xsize*nindex, xsize);
213         return (1.0f - t)*data0 + t*data1;
214 }
215
216 CCL_NAMESPACE_END
217
218 #endif  /* __KERNEL_GLOBALS_H__ */