Cycles: svn merge -r41225:41232 ^/trunk/blender
[blender.git] / intern / cycles / kernel / svm / svm.h
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18
19 #ifndef __SVM_H__
20 #define __SVM_H__
21
22 /* Shader Virtual Machine
23  *
24  * A shader is a list of nodes to be executed. These are simply read one after
25  * the other and executed, using an node counter. Each node and it's associated
26  * data is encoded as one or more uint4's in a 1D texture. If the data is larger
27  * than an uint4, the node can increase the node counter to compensate for this.
28  * Floats are encoded as int and then converted to float again.
29  *
30  * Nodes write their output into a stack. All stack data in the stack is
31  * floats, since it's all factors, colors and vectors. The stack will be stored
32  * in local memory on the GPU, as it would take too many register and indexes in
33  * ways not known at compile time. This seems the only solution even though it
34  * may be slow, with two positive factors. If the same shader is being executed,
35  * memory access will be coalesced, and on fermi cards, memory will actually be
36  * cached.
37  *
38  * The result of shader execution will be a single closure. This means the
39  * closure type, associated label, data and weight. Sampling from multiple
40  * closures is supported through the mix closure node, the logic for that is
41  * mostly taken care of in the SVM compiler.
42  */
43
44 #include "svm_types.h"
45
46 CCL_NAMESPACE_BEGIN
47
48 /* Stack */
49
50 __device_inline float3 stack_load_float3(float *stack, uint a)
51 {
52         kernel_assert(a+2 < SVM_STACK_SIZE);
53
54         return make_float3(stack[a+0], stack[a+1], stack[a+2]);
55 }
56
57 __device_inline void stack_store_float3(float *stack, uint a, float3 f)
58 {
59         kernel_assert(a+2 < SVM_STACK_SIZE);
60
61         stack[a+0] = f.x;
62         stack[a+1] = f.y;
63         stack[a+2] = f.z;
64 }
65
66 __device_inline float stack_load_float(float *stack, uint a)
67 {
68         kernel_assert(a < SVM_STACK_SIZE);
69
70         return stack[a];
71 }
72
73 __device_inline float stack_load_float_default(float *stack, uint a, uint value)
74 {
75         return (a == (uint)SVM_STACK_INVALID)? __int_as_float(value): stack_load_float(stack, a);
76 }
77
78 __device_inline void stack_store_float(float *stack, uint a, float f)
79 {
80         kernel_assert(a < SVM_STACK_SIZE);
81
82         stack[a] = f;
83 }
84
85 __device_inline bool stack_valid(uint a)
86 {
87         return a != (uint)SVM_STACK_INVALID;
88 }
89
90 /* Reading Nodes */
91
92 __device_inline uint4 read_node(KernelGlobals *kg, int *offset)
93 {
94         uint4 node = kernel_tex_fetch(__svm_nodes, *offset);
95         (*offset)++;
96         return node;
97 }
98
99 __device_inline float4 read_node_float(KernelGlobals *kg, int *offset)
100 {
101         uint4 node = kernel_tex_fetch(__svm_nodes, *offset);
102         float4 f = make_float4(__int_as_float(node.x), __int_as_float(node.y), __int_as_float(node.z), __int_as_float(node.w));
103         (*offset)++;
104         return f;
105 }
106
107 __device_inline void decode_node_uchar4(uint i, uint *x, uint *y, uint *z, uint *w)
108 {
109         if(x) *x = (i & 0xFF);
110         if(y) *y = ((i >> 8) & 0xFF);
111         if(z) *z = ((i >> 16) & 0xFF);
112         if(w) *w = ((i >> 24) & 0xFF);
113 }
114
115 CCL_NAMESPACE_END
116
117 /* Nodes */
118
119 #include "svm_noise.h"
120 #include "svm_texture.h"
121
122 #include "svm_attribute.h"
123 #include "svm_blend.h"
124 #include "svm_closure.h"
125 #include "svm_clouds.h"
126 #include "svm_convert.h"
127 #include "svm_displace.h"
128 #include "svm_distorted_noise.h"
129 #include "svm_fresnel.h"
130 #include "svm_geometry.h"
131 #include "svm_image.h"
132 #include "svm_light_path.h"
133 #include "svm_magic.h"
134 #include "svm_mapping.h"
135 #include "svm_marble.h"
136 #include "svm_math.h"
137 #include "svm_mix.h"
138 #include "svm_musgrave.h"
139 #include "svm_noisetex.h"
140 #include "svm_sky.h"
141 #include "svm_stucci.h"
142 #include "svm_tex_coord.h"
143 #include "svm_value.h"
144 #include "svm_voronoi.h"
145 #include "svm_wood.h"
146
147 CCL_NAMESPACE_BEGIN
148
149 /* Main Interpreter Loop */
150
151 __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderType type, float randb, int path_flag)
152 {
153         float stack[SVM_STACK_SIZE];
154         float closure_weight = 1.0f;
155         int offset = sd->shader & SHADER_MASK;
156
157 #ifdef __MULTI_CLOSURE__
158         sd->num_closure = 0;
159         sd->randb_closure = randb;
160 #else
161         sd->closure.type = NBUILTIN_CLOSURES;
162 #endif
163
164         while(1) {
165                 uint4 node = read_node(kg, &offset);
166
167                 switch(node.x) {
168                         case NODE_SHADER_JUMP: {
169                                 if(type == SHADER_TYPE_SURFACE) offset = node.y;
170                                 else if(type == SHADER_TYPE_VOLUME) offset = node.z;
171                                 else if(type == SHADER_TYPE_DISPLACEMENT) offset = node.w;
172                                 else return;
173                                 break;
174                         }
175                         case NODE_CLOSURE_BSDF:
176                                 svm_node_closure_bsdf(kg, sd, stack, node, randb, path_flag);
177                                 break;
178                         case NODE_CLOSURE_EMISSION:
179                                 svm_node_closure_emission(sd, stack, node);
180                                 break;
181                         case NODE_CLOSURE_BACKGROUND:
182                                 svm_node_closure_background(sd, stack, node);
183                                 break;
184                         case NODE_CLOSURE_HOLDOUT:
185                                 svm_node_closure_holdout(sd, stack, node);
186                                 break;
187                         case NODE_CLOSURE_VOLUME:
188                                 svm_node_closure_volume(kg, sd, stack, node, path_flag);
189                                 break;
190                         case NODE_CLOSURE_SET_WEIGHT:
191                                 svm_node_closure_set_weight(sd, node.y, node.z, node.w);
192                                 break;
193                         case NODE_CLOSURE_WEIGHT:
194                                 svm_node_closure_weight(sd, stack, node.y);
195                                 break;
196                         case NODE_EMISSION_WEIGHT:
197                                 svm_node_emission_weight(kg, sd, stack, node);
198                                 break;
199                         case NODE_MIX_CLOSURE:
200                                 svm_node_mix_closure(sd, stack, node, &offset, &randb);
201                                 break;
202                         case NODE_ADD_CLOSURE:
203                                 svm_node_add_closure(sd, stack, node.y, node.z, &offset, &randb, &closure_weight);
204                                 break;
205                         case NODE_JUMP:
206                                 offset = node.y;
207                                 break;
208 #ifdef __TEXTURES__
209                         case NODE_TEX_NOISE_F:
210                                 svm_node_tex_noise_f(sd, stack, node.y, node.z);
211                                 break;
212                         case NODE_TEX_NOISE_V:
213                                 svm_node_tex_noise_v(sd, stack, node.y, node.z);
214                                 break;
215                         case NODE_TEX_IMAGE:
216                                 svm_node_tex_image(kg, sd, stack, node);
217                                 break;
218                         case NODE_TEX_ENVIRONMENT:
219                                 svm_node_tex_environment(kg, sd, stack, node);
220                                 break;
221                         case NODE_TEX_SKY:
222                                 svm_node_tex_sky(kg, sd, stack, node.y, node.z);
223                                 break;
224                         case NODE_TEX_BLEND:
225                                 svm_node_tex_blend(sd, stack, node);
226                                 break;
227                         case NODE_TEX_CLOUDS:
228                                 svm_node_tex_clouds(sd, stack, node);
229                                 break;
230                         case NODE_TEX_VORONOI:
231                                 svm_node_tex_voronoi(kg, sd, stack, node, &offset);
232                                 break;
233                         case NODE_TEX_MUSGRAVE:
234                                 svm_node_tex_musgrave(kg, sd, stack, node, &offset);
235                                 break;
236                         case NODE_TEX_MARBLE:
237                                 svm_node_tex_marble(kg, sd, stack, node, &offset);
238                                 break;
239                         case NODE_TEX_MAGIC:
240                                 svm_node_tex_magic(sd, stack, node);
241                                 break;
242                         case NODE_TEX_STUCCI:
243                                 svm_node_tex_stucci(kg, sd, stack, node, &offset);
244                                 break;
245                         case NODE_TEX_DISTORTED_NOISE:
246                                 svm_node_tex_distorted_noise(kg, sd, stack, node, &offset);
247                                 break;
248                         case NODE_TEX_WOOD:
249                                 svm_node_tex_wood(kg, sd, stack, node, &offset);
250                                 break;
251 #endif
252                         case NODE_GEOMETRY:
253                                 svm_node_geometry(sd, stack, node.y, node.z);
254                                 break;
255                         case NODE_GEOMETRY_BUMP_DX:
256                                 svm_node_geometry_bump_dx(sd, stack, node.y, node.z);
257                                 break;
258                         case NODE_GEOMETRY_BUMP_DY:
259                                 svm_node_geometry_bump_dy(sd, stack, node.y, node.z);
260                                 break;
261                         case NODE_LIGHT_PATH:
262                                 svm_node_light_path(sd, stack, node.y, node.z, path_flag);
263                                 break;
264                         case NODE_CONVERT:
265                                 svm_node_convert(sd, stack, node.y, node.z, node.w);
266                                 break;
267                         case NODE_VALUE_F:
268                                 svm_node_value_f(kg, sd, stack, node.y, node.z);
269                                 break;
270                         case NODE_VALUE_V:
271                                 svm_node_value_v(kg, sd, stack, node.y, &offset);
272                                 break;
273                         case NODE_MIX:
274                                 svm_node_mix(kg, sd, stack, node.y, node.z, node.w, &offset);
275                                 break;
276                         case NODE_ATTR:
277                                 svm_node_attr(kg, sd, stack, node);
278                                 break;
279                         case NODE_ATTR_BUMP_DX:
280                                 svm_node_attr_bump_dx(kg, sd, stack, node);
281                                 break;
282                         case NODE_ATTR_BUMP_DY:
283                                 svm_node_attr_bump_dy(kg, sd, stack, node);
284                                 break;
285                         case NODE_FRESNEL:
286                                 svm_node_fresnel(sd, stack, node.y, node.z, node.w);
287                                 break;
288                         case NODE_BLEND_WEIGHT:
289                                 svm_node_blend_weight(sd, stack, node);
290                                 break;
291                         case NODE_SET_DISPLACEMENT:
292                                 svm_node_set_displacement(sd, stack, node.y);
293                                 break;
294                         case NODE_SET_BUMP:
295                                 svm_node_set_bump(sd, stack, node.y, node.z, node.w);
296                                 break;
297                         case NODE_MATH:
298                                 svm_node_math(kg, sd, stack, node.y, node.z, node.w, &offset);
299                                 break;
300                         case NODE_VECTOR_MATH:
301                                 svm_node_vector_math(kg, sd, stack, node.y, node.z, node.w, &offset);
302                                 break;
303                         case NODE_MAPPING:
304                                 svm_node_mapping(kg, sd, stack, node.y, node.z, &offset);
305                                 break;
306                         case NODE_TEX_COORD:
307                                 svm_node_tex_coord(kg, sd, stack, node.y, node.z);
308                                 break;
309                         case NODE_TEX_COORD_BUMP_DX:
310                                 svm_node_tex_coord_bump_dx(kg, sd, stack, node.y, node.z);
311                                 break;
312                         case NODE_TEX_COORD_BUMP_DY:
313                                 svm_node_tex_coord_bump_dy(kg, sd, stack, node.y, node.z);
314                                 break;
315                         case NODE_EMISSION_SET_WEIGHT_TOTAL:
316                                 svm_node_emission_set_weight_total(kg, sd, node.y, node.z, node.w);
317                                 break;
318                         case NODE_END:
319                         default:
320 #ifndef __MULTI_CLOSURE__
321                                 sd->closure.weight *= closure_weight;
322 #endif
323                                 return;
324                 }
325         }
326 }
327
328 CCL_NAMESPACE_END
329
330 #endif /* __SVM_H__ */
331