Integer socket support in Cycles. Int values are already supported natively in OSL...
[blender.git] / intern / cycles / render / svm.cpp
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 #include "device.h"
20 #include "graph.h"
21 #include "light.h"
22 #include "mesh.h"
23 #include "scene.h"
24 #include "shader.h"
25 #include "svm.h"
26
27 #include "util_debug.h"
28 #include "util_foreach.h"
29 #include "util_progress.h"
30
31 CCL_NAMESPACE_BEGIN
32
33 /* Shader Manager */
34
35 SVMShaderManager::SVMShaderManager()
36 {
37 }
38
39 SVMShaderManager::~SVMShaderManager()
40 {
41 }
42
43 void SVMShaderManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
44 {
45         if(!need_update)
46                 return;
47
48         /* test if we need to update */
49         device_free(device, dscene);
50
51         /* svm_nodes */
52         vector<int4> svm_nodes;
53         size_t i;
54
55         for(i = 0; i < scene->shaders.size(); i++) {
56                 svm_nodes.push_back(make_int4(NODE_SHADER_JUMP, 0, 0, 0));
57                 svm_nodes.push_back(make_int4(NODE_SHADER_JUMP, 0, 0, 0));
58         }
59         
60         bool sunsky_done = false;
61         bool use_multi_closure = device->info.advanced_shading;
62
63         for(i = 0; i < scene->shaders.size(); i++) {
64                 Shader *shader = scene->shaders[i];
65
66                 if(progress.get_cancel()) return;
67
68                 assert(shader->graph);
69
70                 if(shader->sample_as_light && shader->has_surface_emission)
71                         scene->light_manager->need_update = true;
72
73                 SVMCompiler compiler(scene->shader_manager, scene->image_manager,
74                         use_multi_closure);
75                 compiler.sunsky = (sunsky_done)? NULL: &dscene->data.sunsky;
76                 compiler.background = ((int)i == scene->default_background);
77                 compiler.compile(shader, svm_nodes, i);
78                 if(!compiler.sunsky)
79                         sunsky_done = true;
80         }
81
82         dscene->svm_nodes.copy((uint4*)&svm_nodes[0], svm_nodes.size());
83         device->tex_alloc("__svm_nodes", dscene->svm_nodes);
84
85         for(i = 0; i < scene->shaders.size(); i++) {
86                 Shader *shader = scene->shaders[i];
87                 shader->need_update = false;
88         }
89
90         device_update_common(device, dscene, scene, progress);
91
92         need_update = false;
93 }
94
95 void SVMShaderManager::device_free(Device *device, DeviceScene *dscene)
96 {
97         device_free_common(device, dscene);
98
99         device->tex_free(dscene->svm_nodes);
100         dscene->svm_nodes.clear();
101 }
102
103 /* Graph Compiler */
104
105 SVMCompiler::SVMCompiler(ShaderManager *shader_manager_, ImageManager *image_manager_, bool use_multi_closure_)
106 {
107         shader_manager = shader_manager_;
108         image_manager = image_manager_;
109         sunsky = NULL;
110         max_stack_use = 0;
111         current_type = SHADER_TYPE_SURFACE;
112         current_shader = NULL;
113         background = false;
114         mix_weight_offset = SVM_STACK_INVALID;
115         use_multi_closure = use_multi_closure_;
116 }
117
118 int SVMCompiler::stack_size(ShaderSocketType type)
119 {
120         if(type == SHADER_SOCKET_FLOAT)
121                 return 1;
122         else if(type == SHADER_SOCKET_INT)
123                 return 1;
124         else if(type == SHADER_SOCKET_COLOR)
125                 return 3;
126         else if(type == SHADER_SOCKET_VECTOR)
127                 return 3;
128         else if(type == SHADER_SOCKET_NORMAL)
129                 return 3;
130         else if(type == SHADER_SOCKET_POINT)
131                 return 3;
132         else if(type == SHADER_SOCKET_CLOSURE)
133                 return 0;
134
135         assert(0);
136         return 0;
137 }
138
139 int SVMCompiler::stack_find_offset(ShaderSocketType type)
140 {
141         int size = stack_size(type);
142         int offset = -1;
143         
144         /* find free space in stack & mark as used */
145         for(int i = 0, num_unused = 0; i < SVM_STACK_SIZE; i++) {
146                 if(active_stack.users[i]) num_unused = 0;
147                 else num_unused++;
148
149                 if(num_unused == size) {
150                         offset = i+1 - size;
151                         max_stack_use = max(i+1, max_stack_use);
152
153                         while(i >= offset)
154                                 active_stack.users[i--] = 1;
155
156                         return offset;
157                 }
158         }
159
160         fprintf(stderr, "Out of SVM stack space.\n");
161         assert(0);
162
163         return offset;
164 }
165
166 void SVMCompiler::stack_clear_offset(ShaderSocketType type, int offset)
167 {
168         int size = stack_size(type);
169
170         for(int i = 0; i < size; i++)
171                 active_stack.users[offset + i]--;
172 }
173
174 void SVMCompiler::stack_backup(StackBackup& backup, set<ShaderNode*>& done)
175 {
176         backup.done = done;
177         backup.stack = active_stack;
178
179         foreach(ShaderNode *node, current_graph->nodes) {
180                 foreach(ShaderInput *input, node->inputs)
181                         backup.offsets.push_back(input->stack_offset);
182                 foreach(ShaderOutput *output, node->outputs)
183                         backup.offsets.push_back(output->stack_offset);
184         }
185 }
186
187 void SVMCompiler::stack_restore(StackBackup& backup, set<ShaderNode*>& done)
188 {
189         int i = 0;
190
191         done = backup.done;
192         active_stack = backup.stack;
193
194         foreach(ShaderNode *node, current_graph->nodes) {
195                 foreach(ShaderInput *input, node->inputs)
196                         input->stack_offset = backup.offsets[i++];
197                 foreach(ShaderOutput *output, node->outputs)
198                         output->stack_offset = backup.offsets[i++];
199         }
200 }
201
202 void SVMCompiler::stack_assign(ShaderInput *input)
203 {
204         /* stack offset assign? */
205         if(input->stack_offset == SVM_STACK_INVALID) {
206                 if(input->link) {
207                         /* linked to output -> use output offset */
208                         input->stack_offset = input->link->stack_offset;
209                 }
210                 else {
211                         /* not linked to output -> add nodes to load default value */
212                         input->stack_offset = stack_find_offset(input->type);
213
214                         if(input->type == SHADER_SOCKET_FLOAT) {
215                                 add_node(NODE_VALUE_F, __float_as_int(input->value.x), input->stack_offset);
216                         }
217                         else if(input->type == SHADER_SOCKET_INT) {
218                                 add_node(NODE_VALUE_F, (int)input->value.x, input->stack_offset);
219                         }
220                         else if(input->type == SHADER_SOCKET_VECTOR ||
221                                 input->type == SHADER_SOCKET_NORMAL ||
222                                 input->type == SHADER_SOCKET_POINT ||
223                                 input->type == SHADER_SOCKET_COLOR) {
224
225                                 add_node(NODE_VALUE_V, input->stack_offset);
226                                 add_node(NODE_VALUE_V, input->value);
227                         }
228                         else /* should not get called for closure */
229                                 assert(0);
230                 }
231         }
232 }
233
234 void SVMCompiler::stack_assign(ShaderOutput *output)
235 {
236         /* if no stack offset assigned yet, find one */
237         if(output->stack_offset == SVM_STACK_INVALID)
238                 output->stack_offset = stack_find_offset(output->type);
239 }
240
241 void SVMCompiler::stack_link(ShaderInput *input, ShaderOutput *output)
242 {
243         if(output->stack_offset == SVM_STACK_INVALID) {
244                 assert(input->link);
245                 assert(stack_size(output->type) == stack_size(input->link->type));
246
247                 output->stack_offset = input->link->stack_offset;
248
249                 int size = stack_size(output->type);
250
251                 for(int i = 0; i < size; i++)
252                         active_stack.users[output->stack_offset + i]++;
253         }
254 }
255
256 void SVMCompiler::stack_clear_users(ShaderNode *node, set<ShaderNode*>& done)
257 {
258         /* optimization we should add:
259          * find and lower user counts for outputs for which all inputs are done.
260          * this is done before the node is compiled, under the assumption that the
261          * node will first load all inputs from the stack and then writes its
262          * outputs. this used to work, but was disabled because it gave trouble
263          * with inputs getting stack positions assigned */
264
265         foreach(ShaderInput *input, node->inputs) {
266                 ShaderOutput *output = input->link;
267
268                 if(output && output->stack_offset != SVM_STACK_INVALID) {
269                         bool all_done = true;
270
271                         /* optimization we should add: verify if in->parent is actually used */
272                         foreach(ShaderInput *in, output->links)
273                                 if(in->parent != node && done.find(in->parent) == done.end())
274                                         all_done = false;
275
276                         if(all_done) {
277                                 stack_clear_offset(output->type, output->stack_offset);
278                                 output->stack_offset = SVM_STACK_INVALID;
279
280                                 foreach(ShaderInput *in, output->links)
281                                         in->stack_offset = SVM_STACK_INVALID;
282                         }
283                 }
284         }
285 }
286
287 void SVMCompiler::stack_clear_temporary(ShaderNode *node)
288 {
289         foreach(ShaderInput *input, node->inputs) {
290                 if(!input->link && input->stack_offset != SVM_STACK_INVALID) {
291                         stack_clear_offset(input->type, input->stack_offset);
292                         input->stack_offset = SVM_STACK_INVALID;
293                 }
294         }
295 }
296
297 uint SVMCompiler::encode_uchar4(uint x, uint y, uint z, uint w)
298 {
299         assert(x <= 255);
300         assert(y <= 255);
301         assert(z <= 255);
302         assert(w <= 255);
303
304         return (x) | (y << 8) | (z << 16) | (w << 24);
305 }
306
307 void SVMCompiler::add_node(int a, int b, int c, int d)
308 {
309         svm_nodes.push_back(make_int4(a, b, c, d));
310 }
311
312 void SVMCompiler::add_node(NodeType type, int a, int b, int c)
313 {
314         svm_nodes.push_back(make_int4(type, a, b, c));
315 }
316
317 void SVMCompiler::add_node(NodeType type, const float3& f)
318 {
319         svm_nodes.push_back(make_int4(type,
320                 __float_as_int(f.x),
321                 __float_as_int(f.y),
322                 __float_as_int(f.z)));
323 }
324
325 void SVMCompiler::add_node(const float4& f)
326 {
327         svm_nodes.push_back(make_int4(
328                 __float_as_int(f.x),
329                 __float_as_int(f.y),
330                 __float_as_int(f.z),
331                 __float_as_int(f.w)));
332 }
333
334 void SVMCompiler::add_array(float4 *f, int num)
335 {
336         for(int i = 0; i < num; i++)
337                 add_node(f[i]);
338 }
339
340 uint SVMCompiler::attribute(ustring name)
341 {
342         return shader_manager->get_attribute_id(name);
343 }
344
345 uint SVMCompiler::attribute(AttributeStandard std)
346 {
347         return shader_manager->get_attribute_id(std);
348 }
349
350 bool SVMCompiler::node_skip_input(ShaderNode *node, ShaderInput *input)
351 {
352         /* nasty exception .. */
353         if(current_type == SHADER_TYPE_DISPLACEMENT && input->link && input->link->parent->name == ustring("bump"))
354                 return true;
355         
356         return false;
357 }
358
359 void SVMCompiler::find_dependencies(set<ShaderNode*>& dependencies, const set<ShaderNode*>& done, ShaderInput *input)
360 {
361         ShaderNode *node = (input->link)? input->link->parent: NULL;
362
363         if(node && done.find(node) == done.end()) {
364                 foreach(ShaderInput *in, node->inputs)
365                         if(!node_skip_input(node, in))
366                                 find_dependencies(dependencies, done, in);
367
368                 dependencies.insert(node);
369         }
370 }
371
372 void SVMCompiler::generate_svm_nodes(const set<ShaderNode*>& nodes, set<ShaderNode*>& done)
373 {
374         bool nodes_done;
375
376         do {
377                 nodes_done = true;
378
379                 foreach(ShaderNode *node, nodes) {
380                         if(done.find(node) == done.end()) {
381                                 bool inputs_done = true;
382
383                                 foreach(ShaderInput *input, node->inputs)
384                                         if(!node_skip_input(node, input))
385                                                 if(input->link && done.find(input->link->parent) == done.end())
386                                                         inputs_done = false;
387
388                                 if(inputs_done) {
389                                         node->compile(*this);
390                                         stack_clear_users(node, done);
391                                         stack_clear_temporary(node);
392                                         done.insert(node);
393                                 }
394                                 else
395                                         nodes_done = false;
396                         }
397                 }
398         } while(!nodes_done);
399 }
400
401 void SVMCompiler::generate_closure(ShaderNode *node, set<ShaderNode*>& done)
402 {
403         if(node->name == ustring("mix_closure") || node->name == ustring("add_closure")) {
404                 ShaderInput *fin = node->input("Fac");
405                 ShaderInput *cl1in = node->input("Closure1");
406                 ShaderInput *cl2in = node->input("Closure2");
407
408                 /* execute dependencies for mix weight */
409                 if(fin) {
410                         set<ShaderNode*> dependencies;
411                         find_dependencies(dependencies, done, fin);
412                         generate_svm_nodes(dependencies, done);
413
414                         /* add mix node */
415                         stack_assign(fin);
416                 }
417
418                 int mix_offset = svm_nodes.size();
419
420                 if(fin)
421                         add_node(NODE_MIX_CLOSURE, fin->stack_offset, 0, 0);
422                 else
423                         add_node(NODE_ADD_CLOSURE, 0, 0, 0);
424
425                 /* generate code for closure 1
426                  * note we backup all compiler state and restore it afterwards, so one
427                  * closure choice doesn't influence the other*/
428                 if(cl1in->link) {
429                         StackBackup backup;
430                         stack_backup(backup, done);
431
432                         generate_closure(cl1in->link->parent, done);
433                         add_node(NODE_END, 0, 0, 0);
434
435                         stack_restore(backup, done);
436                 }
437                 else
438                         add_node(NODE_END, 0, 0, 0);
439
440                 /* generate code for closure 2 */
441                 int cl2_offset = svm_nodes.size();
442
443                 if(cl2in->link) {
444                         StackBackup backup;
445                         stack_backup(backup, done);
446
447                         generate_closure(cl2in->link->parent, done);
448                         add_node(NODE_END, 0, 0, 0);
449
450                         stack_restore(backup, done);
451                 }
452                 else
453                         add_node(NODE_END, 0, 0, 0);
454
455                 /* set jump for mix node, -1 because offset is already
456                  * incremented when this jump is added to it */
457                 svm_nodes[mix_offset].z = cl2_offset - mix_offset - 1;
458
459                 done.insert(node);
460                 stack_clear_users(node, done);
461                 stack_clear_temporary(node);
462         }
463         else {
464                 /* execute dependencies for closure */
465                 foreach(ShaderInput *in, node->inputs) {
466                         if(!node_skip_input(node, in) && in->link) {
467                                 set<ShaderNode*> dependencies;
468                                 find_dependencies(dependencies, done, in);
469                                 generate_svm_nodes(dependencies, done);
470                         }
471                 }
472
473                 /* compile closure itself */
474                 node->compile(*this);
475                 stack_clear_users(node, done);
476                 stack_clear_temporary(node);
477
478                 if(node->name == ustring("emission"))
479                         current_shader->has_surface_emission = true;
480                 if(node->name == ustring("transparent"))
481                         current_shader->has_surface_transparent = true;
482
483                 /* end node is added outside of this */
484         }
485 }
486
487 void SVMCompiler::generate_multi_closure(ShaderNode *node, set<ShaderNode*>& done, uint in_offset)
488 {
489         /* todo: the weaks point here is that unlike the single closure sampling 
490          * we will evaluate all nodes even if they are used as input for closures
491          * that are unused. it's not clear what would be the best way to skip such
492          * nodes at runtime, especially if they are tangled up  */
493
494         if(node->name == ustring("mix_closure") || node->name == ustring("add_closure")) {
495                 ShaderInput *fin = node->input("Fac");
496                 ShaderInput *cl1in = node->input("Closure1");
497                 ShaderInput *cl2in = node->input("Closure2");
498
499                 uint out1_offset = SVM_STACK_INVALID;
500                 uint out2_offset = SVM_STACK_INVALID;
501
502                 if(fin) {
503                         /* mix closure */
504                         set<ShaderNode*> dependencies;
505                         find_dependencies(dependencies, done, fin);
506                         generate_svm_nodes(dependencies, done);
507
508                         stack_assign(fin);
509
510                         if(cl1in->link)
511                                 out1_offset = stack_find_offset(SHADER_SOCKET_FLOAT);
512                         if(cl2in->link)
513                                 out2_offset = stack_find_offset(SHADER_SOCKET_FLOAT);
514
515                         add_node(NODE_MIX_CLOSURE, 
516                                 encode_uchar4(fin->stack_offset, in_offset, out1_offset, out2_offset));
517                 }
518                 else {
519                         /* add closure */
520                         out1_offset = in_offset;
521                         out2_offset = in_offset;
522                 }
523
524                 if(cl1in->link) {
525                         generate_multi_closure(cl1in->link->parent, done, out1_offset);
526
527                         if(fin)
528                                 stack_clear_offset(SHADER_SOCKET_FLOAT, out1_offset);
529                 }
530
531                 if(cl2in->link) {
532                         generate_multi_closure(cl2in->link->parent, done, out2_offset);
533
534                         if(fin)
535                                 stack_clear_offset(SHADER_SOCKET_FLOAT, out2_offset);
536                 }
537         }
538         else {
539                 /* execute dependencies for closure */
540                 foreach(ShaderInput *in, node->inputs) {
541                         if(!node_skip_input(node, in) && in->link) {
542                                 set<ShaderNode*> dependencies;
543                                 find_dependencies(dependencies, done, in);
544                                 generate_svm_nodes(dependencies, done);
545                         }
546                 }
547
548                 mix_weight_offset = in_offset;
549
550                 /* compile closure itself */
551                 node->compile(*this);
552                 stack_clear_users(node, done);
553                 stack_clear_temporary(node);
554
555                 mix_weight_offset = SVM_STACK_INVALID;
556
557                 if(node->name == ustring("emission"))
558                         current_shader->has_surface_emission = true;
559                 if(node->name == ustring("transparent"))
560                         current_shader->has_surface_transparent = true;
561
562                 /* end node is added outside of this */
563         }
564 }
565
566
567 void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType type)
568 {
569         /* Converting a shader graph into svm_nodes that can be executed
570          * sequentially on the virtual machine is fairly simple. We can keep
571          * looping over nodes and each time all the inputs of a node are
572          * ready, we add svm_nodes for it that read the inputs from the
573          * stack and write outputs back to the stack.
574          *
575          * With the SVM, we always sample only a single closure. We can think
576          * of all closures nodes as a binary tree with mix closures as inner
577          * nodes and other closures as leafs. The SVM will traverse that tree,
578          * each time deciding to go left or right depending on the mix weights,
579          * until a closure is found.
580          *
581          * We only execute nodes that are needed for the mix weights and chosen
582          * closure.
583          */
584
585         current_type = type;
586         current_graph = graph;
587
588         /* get input in output node */
589         ShaderNode *node = graph->output();
590         ShaderInput *clin = NULL;
591         
592         if(type == SHADER_TYPE_SURFACE)
593                 clin = node->input("Surface");
594         else if(type == SHADER_TYPE_VOLUME)
595                 clin = node->input("Volume");
596         else if(type == SHADER_TYPE_DISPLACEMENT)
597                 clin = node->input("Displacement");
598         else
599                 assert(0);
600
601         /* clear all compiler state */
602         memset(&active_stack, 0, sizeof(active_stack));
603         svm_nodes.clear();
604
605         foreach(ShaderNode *node_iter, graph->nodes) {
606                 foreach(ShaderInput *input, node_iter->inputs)
607                         input->stack_offset = SVM_STACK_INVALID;
608                 foreach(ShaderOutput *output, node_iter->outputs)
609                         output->stack_offset = SVM_STACK_INVALID;
610         }
611
612         if(clin->link) {
613                 bool generate = false;
614                 if(type == SHADER_TYPE_SURFACE) {
615                         /* generate surface shader */
616                         generate = true;
617                         shader->has_surface = true;
618                 }
619                 else if(type == SHADER_TYPE_VOLUME) {
620                         /* generate volume shader */
621                         generate = true;
622                         shader->has_volume = true;
623                 }
624                 else if(type == SHADER_TYPE_DISPLACEMENT) {
625                         /* generate displacement shader */
626                         generate = true;
627                         shader->has_displacement = true;
628                 }
629
630                 if(generate) {
631                         set<ShaderNode*> done;
632
633                         if(use_multi_closure)
634                                 generate_multi_closure(clin->link->parent, done, SVM_STACK_INVALID);
635                         else
636                                 generate_closure(clin->link->parent, done);
637                 }
638         }
639
640         /* compile output node */
641         node->compile(*this);
642
643         add_node(NODE_END, 0, 0, 0);
644 }
645
646 void SVMCompiler::compile(Shader *shader, vector<int4>& global_svm_nodes, int index)
647 {
648         /* copy graph for shader with bump mapping */
649         ShaderNode *node = shader->graph->output();
650
651         if(node->input("Surface")->link && node->input("Displacement")->link)
652                 if(!shader->graph_bump)
653                         shader->graph_bump = shader->graph->copy();
654
655         /* finalize */
656         shader->graph->finalize(false, false);
657         if(shader->graph_bump)
658                 shader->graph_bump->finalize(true, false);
659
660         current_shader = shader;
661
662         shader->has_surface = false;
663         shader->has_surface_emission = false;
664         shader->has_surface_transparent = false;
665         shader->has_volume = false;
666         shader->has_displacement = false;
667
668         /* generate surface shader */
669         compile_type(shader, shader->graph, SHADER_TYPE_SURFACE);
670         global_svm_nodes[index*2 + 0].y = global_svm_nodes.size();
671         global_svm_nodes[index*2 + 1].y = global_svm_nodes.size();
672         global_svm_nodes.insert(global_svm_nodes.end(), svm_nodes.begin(), svm_nodes.end());
673
674         if(shader->graph_bump) {
675                 compile_type(shader, shader->graph_bump, SHADER_TYPE_SURFACE);
676                 global_svm_nodes[index*2 + 1].y = global_svm_nodes.size();
677                 global_svm_nodes.insert(global_svm_nodes.end(), svm_nodes.begin(), svm_nodes.end());
678         }
679
680         /* generate volume shader */
681         compile_type(shader, shader->graph, SHADER_TYPE_VOLUME);
682         global_svm_nodes[index*2 + 0].z = global_svm_nodes.size();
683         global_svm_nodes[index*2 + 1].z = global_svm_nodes.size();
684         global_svm_nodes.insert(global_svm_nodes.end(), svm_nodes.begin(), svm_nodes.end());
685
686         /* generate displacement shader */
687         compile_type(shader, shader->graph, SHADER_TYPE_DISPLACEMENT);
688         global_svm_nodes[index*2 + 0].w = global_svm_nodes.size();
689         global_svm_nodes[index*2 + 1].w = global_svm_nodes.size();
690         global_svm_nodes.insert(global_svm_nodes.end(), svm_nodes.begin(), svm_nodes.end());
691 }
692
693 CCL_NAMESPACE_END
694