Merge branch 'master' into blender2.8
[blender.git] / intern / cycles / render / osl.cpp
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 #include "device/device.h"
18
19 #include "render/graph.h"
20 #include "render/light.h"
21 #include "render/osl.h"
22 #include "render/scene.h"
23 #include "render/shader.h"
24 #include "render/nodes.h"
25
26 #ifdef WITH_OSL
27
28 #include "kernel/osl/osl_globals.h"
29 #include "kernel/osl/osl_services.h"
30 #include "kernel/osl/osl_shader.h"
31
32 #include "util/util_foreach.h"
33 #include "util/util_logging.h"
34 #include "util/util_md5.h"
35 #include "util/util_path.h"
36 #include "util/util_progress.h"
37 #include "util/util_projection.h"
38
39 #endif
40
41 CCL_NAMESPACE_BEGIN
42
43 #ifdef WITH_OSL
44
45 /* Shared Texture and Shading System */
46
47 OSL::TextureSystem *OSLShaderManager::ts_shared = NULL;
48 int OSLShaderManager::ts_shared_users = 0;
49 thread_mutex OSLShaderManager::ts_shared_mutex;
50
51 OSL::ShadingSystem *OSLShaderManager::ss_shared = NULL;
52 OSLRenderServices *OSLShaderManager::services_shared = NULL;
53 int OSLShaderManager::ss_shared_users = 0;
54 thread_mutex OSLShaderManager::ss_shared_mutex;
55 thread_mutex OSLShaderManager::ss_mutex;
56
57 /* Shader Manager */
58
59 OSLShaderManager::OSLShaderManager()
60 {
61         texture_system_init();
62         shading_system_init();
63 }
64
65 OSLShaderManager::~OSLShaderManager()
66 {
67         shading_system_free();
68         texture_system_free();
69 #ifdef OSL_HAS_BLENDER_CLEANUP_FIX
70         /* There is a problem with llvm+osl: The order global destructors across
71          * different compilation units run cannot be guaranteed, on windows this means
72          * that the llvm destructors run before the osl destructors, causing a crash
73          * when the process exits. the OSL in svn has a special cleanup hack to
74          * sidestep this behavior */
75         OSL::pvt::LLVM_Util::Cleanup();
76 #endif
77 }
78
79 void OSLShaderManager::reset(Scene * /*scene*/)
80 {
81         shading_system_free();
82         shading_system_init();
83 }
84
85 void OSLShaderManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
86 {
87         if(!need_update)
88                 return;
89
90         VLOG(1) << "Total " << scene->shaders.size() << " shaders.";
91
92         device_free(device, dscene, scene);
93
94         /* determine which shaders are in use */
95         device_update_shaders_used(scene);
96
97         /* create shaders */
98         OSLGlobals *og = (OSLGlobals*)device->osl_memory();
99
100         foreach(Shader *shader, scene->shaders) {
101                 assert(shader->graph);
102
103                 if(progress.get_cancel()) return;
104
105                 /* we can only compile one shader at the time as the OSL ShadingSytem
106                  * has a single state, but we put the lock here so different renders can
107                  * compile shaders alternating */
108                 thread_scoped_lock lock(ss_mutex);
109
110                 OSLCompiler compiler((void*)this, (void*)ss,
111                                      scene->image_manager,
112                                      scene->light_manager);
113                 compiler.background = (shader == scene->default_background);
114                 compiler.compile(scene, og, shader);
115
116                 if(shader->use_mis && shader->has_surface_emission)
117                         scene->light_manager->need_update = true;
118         }
119
120         /* setup shader engine */
121         og->ss = ss;
122         og->ts = ts;
123         og->services = services;
124
125         int background_id = scene->shader_manager->get_shader_id(scene->default_background);
126         og->background_state = og->surface_state[background_id & SHADER_MASK];
127         og->use = true;
128
129         foreach(Shader *shader, scene->shaders)
130                 shader->need_update = false;
131
132         need_update = false;
133
134         /* set texture system */
135         scene->image_manager->set_osl_texture_system((void*)ts);
136
137         device_update_common(device, dscene, scene, progress);
138
139         {
140                 /* Perform greedyjit optimization.
141                  *
142                  * This might waste time on optimizing gorups which are never actually
143                  * used, but this prevents OSL from allocating data on TLS at render
144                  * time.
145                  *
146                  * This is much better for us because this way we aren't required to
147                  * stop task scheduler threads to make sure all TLS is clean and don't
148                  * have issues with TLS data free accessing freed memory if task scheduler
149                  * is being freed after the Session is freed.
150                  */
151                 thread_scoped_lock lock(ss_shared_mutex);
152                 ss->optimize_all_groups();
153         }
154 }
155
156 void OSLShaderManager::device_free(Device *device, DeviceScene *dscene, Scene *scene)
157 {
158         OSLGlobals *og = (OSLGlobals*)device->osl_memory();
159
160         device_free_common(device, dscene, scene);
161
162         /* clear shader engine */
163         og->use = false;
164         og->ss = NULL;
165         og->ts = NULL;
166
167         og->surface_state.clear();
168         og->volume_state.clear();
169         og->displacement_state.clear();
170         og->bump_state.clear();
171         og->background_state.reset();
172 }
173
174 void OSLShaderManager::texture_system_init()
175 {
176         /* create texture system, shared between different renders to reduce memory usage */
177         thread_scoped_lock lock(ts_shared_mutex);
178
179         if(ts_shared_users == 0) {
180                 ts_shared = TextureSystem::create(true);
181
182                 ts_shared->attribute("automip",  1);
183                 ts_shared->attribute("autotile", 64);
184                 ts_shared->attribute("gray_to_rgb", 1);
185
186                 /* effectively unlimited for now, until we support proper mipmap lookups */
187                 ts_shared->attribute("max_memory_MB", 16384);
188         }
189
190         ts = ts_shared;
191         ts_shared_users++;
192 }
193
194 void OSLShaderManager::texture_system_free()
195 {
196         /* shared texture system decrease users and destroy if no longer used */
197         thread_scoped_lock lock(ts_shared_mutex);
198         ts_shared_users--;
199
200         if(ts_shared_users == 0) {
201                 ts_shared->invalidate_all(true);
202                 OSL::TextureSystem::destroy(ts_shared);
203                 ts_shared = NULL;
204         }
205
206         ts = NULL;
207 }
208
209 void OSLShaderManager::shading_system_init()
210 {
211         /* create shading system, shared between different renders to reduce memory usage */
212         thread_scoped_lock lock(ss_shared_mutex);
213
214         if(ss_shared_users == 0) {
215                 services_shared = new OSLRenderServices();
216
217                 string shader_path = path_get("shader");
218 #ifdef _WIN32
219                 /* Annoying thing, Cycles stores paths in UTF-8 codepage, so it can
220                  * operate with file paths with any character. This requires to use wide
221                  * char functions, but OSL uses old fashioned ANSI functions which means:
222                  *
223                  * - We have to convert our paths to ANSI before passing to OSL
224                  * - OSL can't be used when there's a multi-byte character in the path
225                  *   to the shaders folder.
226                  */
227                 shader_path = string_to_ansi(shader_path);
228 #endif
229
230                 ss_shared = new OSL::ShadingSystem(services_shared, ts_shared, &errhandler);
231                 ss_shared->attribute("lockgeom", 1);
232                 ss_shared->attribute("commonspace", "world");
233                 ss_shared->attribute("searchpath:shader", shader_path);
234                 ss_shared->attribute("greedyjit", 1);
235
236                 VLOG(1) << "Using shader search path: " << shader_path;
237
238                 /* our own ray types */
239                 static const char *raytypes[] = {
240                         "camera",                       /* PATH_RAY_CAMERA */
241                         "reflection",           /* PATH_RAY_REFLECT */
242                         "refraction",           /* PATH_RAY_TRANSMIT */
243                         "diffuse",                      /* PATH_RAY_DIFFUSE */
244                         "glossy",                       /* PATH_RAY_GLOSSY */
245                         "singular",                     /* PATH_RAY_SINGULAR */
246                         "transparent",          /* PATH_RAY_TRANSPARENT */
247
248                         "shadow",                       /* PATH_RAY_SHADOW_OPAQUE_NON_CATCHER */
249                         "shadow",                       /* PATH_RAY_SHADOW_OPAQUE_CATCHER */
250                         "shadow",                       /* PATH_RAY_SHADOW_TRANSPARENT_NON_CATCHER */
251                         "shadow",                       /* PATH_RAY_SHADOW_TRANSPARENT_CATCHER */
252
253                         "__unused__",
254                         "volume_scatter",       /* PATH_RAY_VOLUME_SCATTER */
255                         "__unused__",
256
257                         "__unused__",
258                         "diffuse_ancestor",     /* PATH_RAY_DIFFUSE_ANCESTOR */
259                         "__unused__",
260                         "__unused__",
261                         "__unused__",
262                         "__unused__",
263                         "__unused__",
264                         "__unused__",
265                         "__unused__",
266                 };
267
268                 const int nraytypes = sizeof(raytypes)/sizeof(raytypes[0]);
269                 ss_shared->attribute("raytypes", TypeDesc(TypeDesc::STRING, nraytypes), raytypes);
270
271                 OSLShader::register_closures((OSLShadingSystem*)ss_shared);
272
273                 loaded_shaders.clear();
274         }
275
276         ss = ss_shared;
277         services = services_shared;
278         ss_shared_users++;
279 }
280
281 void OSLShaderManager::shading_system_free()
282 {
283         /* shared shading system decrease users and destroy if no longer used */
284         thread_scoped_lock lock(ss_shared_mutex);
285         ss_shared_users--;
286
287         if(ss_shared_users == 0) {
288                 delete ss_shared;
289                 ss_shared = NULL;
290
291                 delete services_shared;
292                 services_shared = NULL;
293         }
294
295         ss = NULL;
296         services = NULL;
297 }
298
299 bool OSLShaderManager::osl_compile(const string& inputfile, const string& outputfile)
300 {
301         vector<string> options;
302         string stdosl_path;
303         string shader_path = path_get("shader");
304
305         /* specify output file name */
306         options.push_back("-o");
307         options.push_back(outputfile);
308
309         /* specify standard include path */
310         string include_path_arg = string("-I") + shader_path;
311         options.push_back(include_path_arg);
312
313         stdosl_path = path_get("shader/stdosl.h");
314
315         /* compile */
316         OSL::OSLCompiler *compiler = new OSL::OSLCompiler(&OSL::ErrorHandler::default_handler());
317         bool ok = compiler->compile(string_view(inputfile), options, string_view(stdosl_path));
318         delete compiler;
319
320         return ok;
321 }
322
323 bool OSLShaderManager::osl_query(OSL::OSLQuery& query, const string& filepath)
324 {
325         string searchpath = path_user_get("shaders");
326         return query.open(filepath, searchpath);
327 }
328
329 static string shader_filepath_hash(const string& filepath, uint64_t modified_time)
330 {
331         /* compute a hash from filepath and modified time to detect changes */
332         MD5Hash md5;
333         md5.append((const uint8_t*)filepath.c_str(), filepath.size());
334         md5.append((const uint8_t*)&modified_time, sizeof(modified_time));
335
336         return md5.get_hex();
337 }
338
339 const char *OSLShaderManager::shader_test_loaded(const string& hash)
340 {
341         map<string, OSLShaderInfo>::iterator it = loaded_shaders.find(hash);
342         return (it == loaded_shaders.end())? NULL: it->first.c_str();
343 }
344
345 OSLShaderInfo *OSLShaderManager::shader_loaded_info(const string& hash)
346 {
347         map<string, OSLShaderInfo>::iterator it = loaded_shaders.find(hash);
348         return (it == loaded_shaders.end())? NULL: &it->second;
349 }
350
351 const char *OSLShaderManager::shader_load_filepath(string filepath)
352 {
353         size_t len = filepath.size();
354         string extension = filepath.substr(len - 4);
355         uint64_t modified_time = path_modified_time(filepath);
356
357         if(extension == ".osl") {
358                 /* .OSL File */
359                 string osopath = filepath.substr(0, len - 4) + ".oso";
360                 uint64_t oso_modified_time = path_modified_time(osopath);
361
362                 /* test if we have loaded the corresponding .OSO already */
363                 if(oso_modified_time != 0) {
364                         const char *hash = shader_test_loaded(shader_filepath_hash(osopath, oso_modified_time));
365
366                         if(hash)
367                                 return hash;
368                 }
369
370                 /* autocompile .OSL to .OSO if needed */
371                 if(oso_modified_time == 0 || (oso_modified_time < modified_time)) {
372                         OSLShaderManager::osl_compile(filepath, osopath);
373                         modified_time = path_modified_time(osopath);
374                 }
375                 else
376                         modified_time = oso_modified_time;
377
378                 filepath = osopath;
379         }
380         else {
381                 if(extension == ".oso") {
382                         /* .OSO File, nothing to do */
383                 }
384                 else if(path_dirname(filepath) == "") {
385                         /* .OSO File in search path */
386                         filepath = path_join(path_user_get("shaders"), filepath + ".oso");
387                 }
388                 else {
389                         /* unknown file */
390                         return NULL;
391                 }
392
393                 /* test if we have loaded this .OSO already */
394                 const char *hash = shader_test_loaded(shader_filepath_hash(filepath, modified_time));
395
396                 if(hash)
397                         return hash;
398         }
399
400         /* read oso bytecode from file */
401         string bytecode_hash = shader_filepath_hash(filepath, modified_time);
402         string bytecode;
403
404         if(!path_read_text(filepath, bytecode)) {
405                 fprintf(stderr, "Cycles shader graph: failed to read file %s\n", filepath.c_str());
406                 OSLShaderInfo info;
407                 loaded_shaders[bytecode_hash] = info; /* to avoid repeat tries */
408                 return NULL;
409         }
410
411         return shader_load_bytecode(bytecode_hash, bytecode);
412 }
413
414 const char *OSLShaderManager::shader_load_bytecode(const string& hash, const string& bytecode)
415 {
416         ss->LoadMemoryCompiledShader(hash.c_str(), bytecode.c_str());
417
418         OSLShaderInfo info;
419
420         if(!info.query.open_bytecode(bytecode)) {
421                 fprintf(stderr, "OSL query error: %s\n", info.query.geterror().c_str());
422         }
423
424         /* this is a bit weak, but works */
425         info.has_surface_emission = (bytecode.find("\"emission\"") != string::npos);
426         info.has_surface_transparent = (bytecode.find("\"transparent\"") != string::npos);
427         info.has_surface_bssrdf = (bytecode.find("\"bssrdf\"") != string::npos);
428
429         loaded_shaders[hash] = info;
430
431         return loaded_shaders.find(hash)->first.c_str();
432 }
433
434 OSLNode *OSLShaderManager::osl_node(const std::string& filepath,
435                                     const std::string& bytecode_hash,
436                                     const std::string& bytecode)
437 {
438         /* create query */
439         const char *hash;
440
441         if(!filepath.empty()) {
442                 hash = shader_load_filepath(filepath);
443         }
444         else {
445                 hash = shader_test_loaded(bytecode_hash);
446                 if(!hash)
447                         hash = shader_load_bytecode(bytecode_hash, bytecode);
448         }
449
450         if(!hash) {
451                 return NULL;
452         }
453
454         OSLShaderInfo *info = shader_loaded_info(hash);
455
456         /* count number of inputs */
457         size_t num_inputs = 0;
458
459         for(int i = 0; i < info->query.nparams(); i++) {
460                 const OSL::OSLQuery::Parameter *param = info->query.getparam(i);
461
462                 /* skip unsupported types */
463                 if(param->varlenarray || param->isstruct || param->type.arraylen > 1)
464                         continue;
465
466                 if(!param->isoutput)
467                         num_inputs++;
468         }
469
470         /* create node */
471         OSLNode *node = OSLNode::create(num_inputs);
472
473         /* add new sockets from parameters */
474         set<void*> used_sockets;
475
476         for(int i = 0; i < info->query.nparams(); i++) {
477                 const OSL::OSLQuery::Parameter *param = info->query.getparam(i);
478
479                 /* skip unsupported types */
480                 if(param->varlenarray || param->isstruct || param->type.arraylen > 1)
481                         continue;
482
483                 SocketType::Type socket_type;
484
485                 if(param->isclosure) {
486                         socket_type = SocketType::CLOSURE;
487                 }
488                 else if(param->type.vecsemantics != TypeDesc::NOSEMANTICS) {
489                         if(param->type.vecsemantics == TypeDesc::COLOR)
490                                 socket_type = SocketType::COLOR;
491                         else if(param->type.vecsemantics == TypeDesc::POINT)
492                                 socket_type = SocketType::POINT;
493                         else if(param->type.vecsemantics == TypeDesc::VECTOR)
494                                 socket_type = SocketType::VECTOR;
495                         else if(param->type.vecsemantics == TypeDesc::NORMAL)
496                                 socket_type = SocketType::NORMAL;
497                         else
498                                 continue;
499
500                         if(!param->isoutput && param->validdefault) {
501                                 float3 *default_value = (float3*)node->input_default_value();
502                                 default_value->x = param->fdefault[0];
503                                 default_value->y = param->fdefault[1];
504                                 default_value->z = param->fdefault[2];
505                         }
506                 }
507                 else if(param->type.aggregate == TypeDesc::SCALAR) {
508                         if(param->type.basetype == TypeDesc::INT) {
509                                 socket_type = SocketType::INT;
510
511                                 if(!param->isoutput && param->validdefault) {
512                                         *(int*)node->input_default_value() = param->idefault[0];
513                                 }
514                         }
515                         else if(param->type.basetype == TypeDesc::FLOAT) {
516                                 socket_type = SocketType::FLOAT;
517
518                                 if(!param->isoutput && param->validdefault) {
519                                         *(float*)node->input_default_value() = param->fdefault[0];
520                                 }
521                         }
522                         else if(param->type.basetype == TypeDesc::STRING) {
523                                 socket_type = SocketType::STRING;
524
525                                 if(!param->isoutput && param->validdefault) {
526                                         *(ustring*)node->input_default_value() = param->sdefault[0];
527                                 }
528                         }
529                         else
530                                 continue;
531                 }
532                 else
533                         continue;
534
535                 if(param->isoutput) {
536                         node->add_output(param->name, socket_type);
537                 }
538                 else {
539                         node->add_input(param->name, socket_type);
540                 }
541         }
542
543         /* set bytcode hash or filepath */
544         if(!bytecode_hash.empty()) {
545                 node->bytecode_hash = bytecode_hash;
546         }
547         else {
548                 node->filepath = filepath;
549         }
550
551         /* Generate inputs and outputs */
552         node->create_inputs_outputs(node->type);
553
554         return node;
555 }
556
557 /* Graph Compiler */
558
559 OSLCompiler::OSLCompiler(void *manager_, void *shadingsys_,
560                          ImageManager *image_manager_,
561                          LightManager *light_manager_)
562 {
563         manager = manager_;
564         shadingsys = shadingsys_;
565         image_manager = image_manager_;
566         light_manager = light_manager_;
567         current_type = SHADER_TYPE_SURFACE;
568         current_shader = NULL;
569         background = false;
570 }
571
572 string OSLCompiler::id(ShaderNode *node)
573 {
574         /* assign layer unique name based on pointer address + bump mode */
575         stringstream stream;
576         stream << "node_" << node->type->name << "_" << node;
577
578         return stream.str();
579 }
580
581 string OSLCompiler::compatible_name(ShaderNode *node, ShaderInput *input)
582 {
583         string sname(input->name().string());
584         size_t i;
585
586         /* strip whitespace */
587         while((i = sname.find(" ")) != string::npos)
588                 sname.replace(i, 1, "");
589
590         /* if output exists with the same name, add "In" suffix */
591         foreach(ShaderOutput *output, node->outputs) {
592                 if(input->name() == output->name()) {
593                         sname += "In";
594                         break;
595                 }
596         }
597
598         return sname;
599 }
600
601 string OSLCompiler::compatible_name(ShaderNode *node, ShaderOutput *output)
602 {
603         string sname(output->name().string());
604         size_t i;
605
606         /* strip whitespace */
607         while((i = sname.find(" ")) != string::npos)
608                 sname.replace(i, 1, "");
609
610         /* if input exists with the same name, add "Out" suffix */
611         foreach(ShaderInput *input, node->inputs) {
612                 if(input->name() == output->name()) {
613                         sname += "Out";
614                         break;
615                 }
616         }
617
618         return sname;
619 }
620
621 bool OSLCompiler::node_skip_input(ShaderNode *node, ShaderInput *input)
622 {
623         /* exception for output node, only one input is actually used
624          * depending on the current shader type */
625
626         if(input->flags() & SocketType::SVM_INTERNAL)
627                 return true;
628
629         if(node->special_type == SHADER_SPECIAL_TYPE_OUTPUT) {
630                 if(input->name() == "Surface" && current_type != SHADER_TYPE_SURFACE)
631                         return true;
632                 if(input->name() == "Volume" && current_type != SHADER_TYPE_VOLUME)
633                         return true;
634                 if(input->name() == "Displacement" && current_type != SHADER_TYPE_DISPLACEMENT)
635                         return true;
636                 if(input->name() == "Normal" && current_type != SHADER_TYPE_BUMP)
637                         return true;
638         }
639         else if(node->special_type == SHADER_SPECIAL_TYPE_BUMP) {
640                 if(input->name() == "Height")
641                         return true;
642         }
643         else if(current_type == SHADER_TYPE_DISPLACEMENT && input->link && input->link->parent->special_type == SHADER_SPECIAL_TYPE_BUMP)
644                 return true;
645
646         return false;
647 }
648
649 void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath)
650 {
651         OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
652
653         /* load filepath */
654         if(isfilepath) {
655                 name = ((OSLShaderManager*)manager)->shader_load_filepath(name);
656
657                 if(name == NULL)
658                         return;
659         }
660
661         /* pass in fixed parameter values */
662         foreach(ShaderInput *input, node->inputs) {
663                 if(!input->link) {
664                         /* checks to untangle graphs */
665                         if(node_skip_input(node, input))
666                                 continue;
667                         /* already has default value assigned */
668                         else if(input->flags() & SocketType::DEFAULT_LINK_MASK)
669                                 continue;
670
671                         string param_name = compatible_name(node, input);
672                         const SocketType& socket = input->socket_type;
673                         switch(input->type()) {
674                                 case SocketType::COLOR:
675                                         parameter_color(param_name.c_str(), node->get_float3(socket));
676                                         break;
677                                 case SocketType::POINT:
678                                         parameter_point(param_name.c_str(), node->get_float3(socket));
679                                         break;
680                                 case SocketType::VECTOR:
681                                         parameter_vector(param_name.c_str(), node->get_float3(socket));
682                                         break;
683                                 case SocketType::NORMAL:
684                                         parameter_normal(param_name.c_str(), node->get_float3(socket));
685                                         break;
686                                 case SocketType::FLOAT:
687                                         parameter(param_name.c_str(), node->get_float(socket));
688                                         break;
689                                 case SocketType::INT:
690                                         parameter(param_name.c_str(), node->get_int(socket));
691                                         break;
692                                 case SocketType::STRING:
693                                         parameter(param_name.c_str(), node->get_string(socket));
694                                         break;
695                                 case SocketType::CLOSURE:
696                                 case SocketType::UNDEFINED:
697                                 default:
698                                         break;
699                         }
700                 }
701         }
702
703         /* create shader of the appropriate type. OSL only distinguishes between "surface"
704          * and "displacement" atm */
705         if(current_type == SHADER_TYPE_SURFACE)
706                 ss->Shader("surface", name, id(node).c_str());
707         else if(current_type == SHADER_TYPE_VOLUME)
708                 ss->Shader("surface", name, id(node).c_str());
709         else if(current_type == SHADER_TYPE_DISPLACEMENT)
710                 ss->Shader("displacement", name, id(node).c_str());
711         else if(current_type == SHADER_TYPE_BUMP)
712                 ss->Shader("displacement", name, id(node).c_str());
713         else
714                 assert(0);
715
716         /* link inputs to other nodes */
717         foreach(ShaderInput *input, node->inputs) {
718                 if(input->link) {
719                         if(node_skip_input(node, input))
720                                 continue;
721
722                         /* connect shaders */
723                         string id_from = id(input->link->parent);
724                         string id_to = id(node);
725                         string param_from = compatible_name(input->link->parent, input->link);
726                         string param_to = compatible_name(node, input);
727
728                         ss->ConnectShaders(id_from.c_str(), param_from.c_str(), id_to.c_str(), param_to.c_str());
729                 }
730         }
731
732         /* test if we shader contains specific closures */
733         OSLShaderInfo *info = ((OSLShaderManager*)manager)->shader_loaded_info(name);
734
735         if(current_type == SHADER_TYPE_SURFACE) {
736                 if(info) {
737                         if(info->has_surface_emission)
738                                 current_shader->has_surface_emission = true;
739                         if(info->has_surface_transparent)
740                                 current_shader->has_surface_transparent = true;
741                         if(info->has_surface_bssrdf) {
742                                 current_shader->has_surface_bssrdf = true;
743                                 current_shader->has_bssrdf_bump = true; /* can't detect yet */
744                         }
745                         current_shader->has_bump = true; /* can't detect yet */
746                 }
747
748                 if(node->has_spatial_varying()) {
749                         current_shader->has_surface_spatial_varying = true;
750                 }
751         }
752         else if(current_type == SHADER_TYPE_VOLUME) {
753                 if(node->has_spatial_varying())
754                         current_shader->has_volume_spatial_varying = true;
755         }
756
757         if(node->has_object_dependency()) {
758                 current_shader->has_object_dependency = true;
759         }
760
761         if(node->has_attribute_dependency()) {
762                 current_shader->has_attribute_dependency = true;
763         }
764
765         if(node->has_integrator_dependency()) {
766                 current_shader->has_integrator_dependency = true;
767         }
768 }
769
770 static TypeDesc array_typedesc(TypeDesc typedesc, int arraylength)
771 {
772         return TypeDesc((TypeDesc::BASETYPE)typedesc.basetype,
773                         (TypeDesc::AGGREGATE)typedesc.aggregate,
774                         (TypeDesc::VECSEMANTICS)typedesc.vecsemantics,
775                         arraylength);
776 }
777
778 void OSLCompiler::parameter(ShaderNode* node, const char *name)
779 {
780         OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
781         ustring uname = ustring(name);
782         const SocketType& socket = *(node->type->find_input(uname));
783
784         switch(socket.type)
785         {
786                 case SocketType::BOOLEAN:
787                 {
788                         int value = node->get_bool(socket);
789                         ss->Parameter(name, TypeDesc::TypeInt, &value);
790                         break;
791                 }
792                 case SocketType::FLOAT:
793                 {
794                         float value = node->get_float(socket);
795                         ss->Parameter(uname, TypeDesc::TypeFloat, &value);
796                         break;
797                 }
798                 case SocketType::INT:
799                 {
800                         int value = node->get_int(socket);
801                         ss->Parameter(uname, TypeDesc::TypeInt, &value);
802                         break;
803                 }
804                 case SocketType::COLOR:
805                 {
806                         float3 value = node->get_float3(socket);
807                         ss->Parameter(uname, TypeDesc::TypeColor, &value);
808                         break;
809                 }
810                 case SocketType::VECTOR:
811                 {
812                         float3 value = node->get_float3(socket);
813                         ss->Parameter(uname, TypeDesc::TypeVector, &value);
814                         break;
815                 }
816                 case SocketType::POINT:
817                 {
818                         float3 value = node->get_float3(socket);
819                         ss->Parameter(uname, TypeDesc::TypePoint, &value);
820                         break;
821                 }
822                 case SocketType::NORMAL:
823                 {
824                         float3 value = node->get_float3(socket);
825                         ss->Parameter(uname, TypeDesc::TypeNormal, &value);
826                         break;
827                 }
828                 case SocketType::POINT2:
829                 {
830                         float2 value = node->get_float2(socket);
831                         ss->Parameter(uname, TypeDesc(TypeDesc::FLOAT, TypeDesc::VEC2, TypeDesc::POINT), &value);
832                         break;
833                 }
834                 case SocketType::STRING:
835                 {
836                         ustring value = node->get_string(socket);
837                         ss->Parameter(uname, TypeDesc::TypeString, &value);
838                         break;
839                 }
840                 case SocketType::ENUM:
841                 {
842                         ustring value = node->get_string(socket);
843                         ss->Parameter(uname, TypeDesc::TypeString, &value);
844                         break;
845                 }
846                 case SocketType::TRANSFORM:
847                 {
848                         Transform value = node->get_transform(socket);
849                         ProjectionTransform projection(value);
850                         projection = projection_transpose(projection);
851                         ss->Parameter(uname, TypeDesc::TypeMatrix, &projection);
852                         break;
853                 }
854                 case SocketType::BOOLEAN_ARRAY:
855                 {
856                         // OSL does not support booleans, so convert to int
857                         const array<bool>& value = node->get_bool_array(socket);
858                         array<int> intvalue(value.size());
859                         for(size_t i = 0; i < value.size(); i++)
860                                 intvalue[i] = value[i];
861                         ss->Parameter(uname, array_typedesc(TypeDesc::TypeInt, value.size()), intvalue.data());
862                         break;
863                 }
864                 case SocketType::FLOAT_ARRAY:
865                 {
866                         const array<float>& value = node->get_float_array(socket);
867                         ss->Parameter(uname, array_typedesc(TypeDesc::TypeFloat, value.size()), value.data());
868                         break;
869                 }
870                 case SocketType::INT_ARRAY:
871                 {
872                         const array<int>& value = node->get_int_array(socket);
873                         ss->Parameter(uname, array_typedesc(TypeDesc::TypeInt, value.size()), value.data());
874                         break;
875                 }
876                 case SocketType::COLOR_ARRAY:
877                 case SocketType::VECTOR_ARRAY:
878                 case SocketType::POINT_ARRAY:
879                 case SocketType::NORMAL_ARRAY:
880                 {
881                         TypeDesc typedesc;
882
883                         switch(socket.type)
884                         {
885                                 case SocketType::COLOR_ARRAY: typedesc = TypeDesc::TypeColor; break;
886                                 case SocketType::VECTOR_ARRAY: typedesc = TypeDesc::TypeVector; break;
887                                 case SocketType::POINT_ARRAY: typedesc = TypeDesc::TypePoint; break;
888                                 case SocketType::NORMAL_ARRAY: typedesc = TypeDesc::TypeNormal; break;
889                                 default: assert(0); break;
890                         }
891
892                         // convert to tightly packed array since float3 has padding
893                         const array<float3>& value = node->get_float3_array(socket);
894                         array<float> fvalue(value.size() * 3);
895                         for(size_t i = 0, j = 0; i < value.size(); i++) {
896                                 fvalue[j++] = value[i].x;
897                                 fvalue[j++] = value[i].y;
898                                 fvalue[j++] = value[i].z;
899                         }
900
901                         ss->Parameter(uname, array_typedesc(typedesc, value.size()), fvalue.data());
902                         break;
903                 }
904                 case SocketType::POINT2_ARRAY:
905                 {
906                         const array<float2>& value = node->get_float2_array(socket);
907                         ss->Parameter(uname, array_typedesc(TypeDesc(TypeDesc::FLOAT, TypeDesc::VEC2, TypeDesc::POINT), value.size()), value.data());
908                         break;
909                 }
910                 case SocketType::STRING_ARRAY:
911                 {
912                         const array<ustring>& value = node->get_string_array(socket);
913                         ss->Parameter(uname, array_typedesc(TypeDesc::TypeString, value.size()), value.data());
914                         break;
915                 }
916                 case SocketType::TRANSFORM_ARRAY:
917                 {
918                         const array<Transform>& value = node->get_transform_array(socket);
919                         array<ProjectionTransform> fvalue(value.size());
920                         for(size_t i = 0; i < value.size(); i++) {
921                                 fvalue[i] = projection_transpose(ProjectionTransform(value[i]));
922                         }
923                         ss->Parameter(uname, array_typedesc(TypeDesc::TypeMatrix, fvalue.size()), fvalue.data());
924                         break;
925                 }
926                 case SocketType::CLOSURE:
927                 case SocketType::NODE:
928                 case SocketType::NODE_ARRAY:
929                 case SocketType::UNDEFINED:
930                 case SocketType::UINT:
931                 {
932                         assert(0);
933                         break;
934                 }
935         }
936 }
937
938 void OSLCompiler::parameter(const char *name, float f)
939 {
940         OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
941         ss->Parameter(name, TypeDesc::TypeFloat, &f);
942 }
943
944 void OSLCompiler::parameter_color(const char *name, float3 f)
945 {
946         OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
947         ss->Parameter(name, TypeDesc::TypeColor, &f);
948 }
949
950 void OSLCompiler::parameter_point(const char *name, float3 f)
951 {
952         OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
953         ss->Parameter(name, TypeDesc::TypePoint, &f);
954 }
955
956 void OSLCompiler::parameter_normal(const char *name, float3 f)
957 {
958         OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
959         ss->Parameter(name, TypeDesc::TypeNormal, &f);
960 }
961
962 void OSLCompiler::parameter_vector(const char *name, float3 f)
963 {
964         OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
965         ss->Parameter(name, TypeDesc::TypeVector, &f);
966 }
967
968 void OSLCompiler::parameter(const char *name, int f)
969 {
970         OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
971         ss->Parameter(name, TypeDesc::TypeInt, &f);
972 }
973
974 void OSLCompiler::parameter(const char *name, const char *s)
975 {
976         OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
977         ss->Parameter(name, TypeDesc::TypeString, &s);
978 }
979
980 void OSLCompiler::parameter(const char *name, ustring s)
981 {
982         OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
983         const char *str = s.c_str();
984         ss->Parameter(name, TypeDesc::TypeString, &str);
985 }
986
987 void OSLCompiler::parameter(const char *name, const Transform& tfm)
988 {
989         OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
990         ProjectionTransform projection(tfm);
991         projection = projection_transpose(projection);
992         ss->Parameter(name, TypeDesc::TypeMatrix, (float*)&projection);
993 }
994
995 void OSLCompiler::parameter_array(const char *name, const float f[], int arraylen)
996 {
997         OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
998         TypeDesc type = TypeDesc::TypeFloat;
999         type.arraylen = arraylen;
1000         ss->Parameter(name, type, f);
1001 }
1002
1003 void OSLCompiler::parameter_color_array(const char *name, const array<float3>& f)
1004 {
1005         /* NB: cycles float3 type is actually 4 floats! need to use an explicit array */
1006         array<float[3]> table(f.size());
1007
1008         for(int i = 0; i < f.size(); ++i) {
1009                 table[i][0] = f[i].x;
1010                 table[i][1] = f[i].y;
1011                 table[i][2] = f[i].z;
1012         }
1013
1014         OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
1015         TypeDesc type = TypeDesc::TypeColor;
1016         type.arraylen = table.size();
1017         ss->Parameter(name, type, table.data());
1018 }
1019
1020 void OSLCompiler::parameter_attribute(const char *name, ustring s)
1021 {
1022         if(Attribute::name_standard(s.c_str()))
1023                 parameter(name, (string("geom:") + s.c_str()).c_str());
1024         else
1025                 parameter(name, s.c_str());
1026 }
1027
1028 void OSLCompiler::find_dependencies(ShaderNodeSet& dependencies, ShaderInput *input)
1029 {
1030         ShaderNode *node = (input->link)? input->link->parent: NULL;
1031
1032         if(node != NULL && dependencies.find(node) == dependencies.end()) {
1033                 foreach(ShaderInput *in, node->inputs)
1034                         if(!node_skip_input(node, in))
1035                                 find_dependencies(dependencies, in);
1036
1037                 dependencies.insert(node);
1038         }
1039 }
1040
1041 void OSLCompiler::generate_nodes(const ShaderNodeSet& nodes)
1042 {
1043         ShaderNodeSet done;
1044         bool nodes_done;
1045
1046         do {
1047                 nodes_done = true;
1048
1049                 foreach(ShaderNode *node, nodes) {
1050                         if(done.find(node) == done.end()) {
1051                                 bool inputs_done = true;
1052
1053                                 foreach(ShaderInput *input, node->inputs)
1054                                         if(!node_skip_input(node, input))
1055                                                 if(input->link && done.find(input->link->parent) == done.end())
1056                                                         inputs_done = false;
1057
1058                                 if(inputs_done) {
1059                                         node->compile(*this);
1060                                         done.insert(node);
1061
1062                                         if(current_type == SHADER_TYPE_SURFACE) {
1063                                                 if(node->has_surface_emission())
1064                                                         current_shader->has_surface_emission = true;
1065                                                 if(node->has_surface_transparent())
1066                                                         current_shader->has_surface_transparent = true;
1067                                                 if(node->has_spatial_varying())
1068                                                         current_shader->has_surface_spatial_varying = true;
1069                                                 if(node->has_surface_bssrdf()) {
1070                                                         current_shader->has_surface_bssrdf = true;
1071                                                         if(node->has_bssrdf_bump())
1072                                                                 current_shader->has_bssrdf_bump = true;
1073                                                 }
1074                                                 if(node->has_bump()) {
1075                                                         current_shader->has_bump = true;
1076                                                 }
1077                                         }
1078                                         else if(current_type == SHADER_TYPE_VOLUME) {
1079                                                 if(node->has_spatial_varying())
1080                                                         current_shader->has_volume_spatial_varying = true;
1081                                         }
1082                                 }
1083                                 else
1084                                         nodes_done = false;
1085                         }
1086                 }
1087         } while(!nodes_done);
1088 }
1089
1090 OSL::ShaderGroupRef OSLCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType type)
1091 {
1092         OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
1093
1094         current_type = type;
1095
1096         OSL::ShaderGroupRef group = ss->ShaderGroupBegin(shader->name.c_str());
1097
1098         ShaderNode *output = graph->output();
1099         ShaderNodeSet dependencies;
1100
1101         if(type == SHADER_TYPE_SURFACE) {
1102                 /* generate surface shader */
1103                 find_dependencies(dependencies, output->input("Surface"));
1104                 generate_nodes(dependencies);
1105                 output->compile(*this);
1106         }
1107         else if(type == SHADER_TYPE_BUMP) {
1108                 /* generate bump shader */
1109                 find_dependencies(dependencies, output->input("Normal"));
1110                 generate_nodes(dependencies);
1111                 output->compile(*this);
1112         }
1113         else if(type == SHADER_TYPE_VOLUME) {
1114                 /* generate volume shader */
1115                 find_dependencies(dependencies, output->input("Volume"));
1116                 generate_nodes(dependencies);
1117                 output->compile(*this);
1118         }
1119         else if(type == SHADER_TYPE_DISPLACEMENT) {
1120                 /* generate displacement shader */
1121                 find_dependencies(dependencies, output->input("Displacement"));
1122                 generate_nodes(dependencies);
1123                 output->compile(*this);
1124         }
1125         else
1126                 assert(0);
1127
1128         ss->ShaderGroupEnd();
1129
1130         return group;
1131 }
1132
1133 void OSLCompiler::compile(Scene *scene, OSLGlobals *og, Shader *shader)
1134 {
1135         if(shader->need_update) {
1136                 ShaderGraph *graph = shader->graph;
1137                 ShaderNode *output = (graph)? graph->output(): NULL;
1138
1139                 bool has_bump = (shader->displacement_method != DISPLACE_TRUE) &&
1140                                 output->input("Surface")->link && output->input("Displacement")->link;
1141
1142                 /* finalize */
1143                 shader->graph->finalize(scene,
1144                                         has_bump,
1145                                         shader->has_integrator_dependency,
1146                                         shader->displacement_method == DISPLACE_BOTH);
1147
1148                 current_shader = shader;
1149
1150                 shader->has_surface = false;
1151                 shader->has_surface_emission = false;
1152                 shader->has_surface_transparent = false;
1153                 shader->has_surface_bssrdf = false;
1154                 shader->has_bump = has_bump;
1155                 shader->has_bssrdf_bump = has_bump;
1156                 shader->has_volume = false;
1157                 shader->has_displacement = false;
1158                 shader->has_surface_spatial_varying = false;
1159                 shader->has_volume_spatial_varying = false;
1160                 shader->has_object_dependency = false;
1161                 shader->has_attribute_dependency = false;
1162                 shader->has_integrator_dependency = false;
1163
1164                 /* generate surface shader */
1165                 if(shader->used && graph && output->input("Surface")->link) {
1166                         shader->osl_surface_ref = compile_type(shader, shader->graph, SHADER_TYPE_SURFACE);
1167
1168                         if(has_bump)
1169                                 shader->osl_surface_bump_ref = compile_type(shader, shader->graph, SHADER_TYPE_BUMP);
1170                         else
1171                                 shader->osl_surface_bump_ref = OSL::ShaderGroupRef();
1172
1173                         shader->has_surface = true;
1174                 }
1175                 else {
1176                         shader->osl_surface_ref = OSL::ShaderGroupRef();
1177                         shader->osl_surface_bump_ref = OSL::ShaderGroupRef();
1178                 }
1179
1180                 /* generate volume shader */
1181                 if(shader->used && graph && output->input("Volume")->link) {
1182                         shader->osl_volume_ref = compile_type(shader, shader->graph, SHADER_TYPE_VOLUME);
1183                         shader->has_volume = true;
1184                 }
1185                 else
1186                         shader->osl_volume_ref = OSL::ShaderGroupRef();
1187
1188                 /* generate displacement shader */
1189                 if(shader->used && graph && output->input("Displacement")->link) {
1190                         shader->osl_displacement_ref = compile_type(shader, shader->graph, SHADER_TYPE_DISPLACEMENT);
1191                         shader->has_displacement = true;
1192                 }
1193                 else
1194                         shader->osl_displacement_ref = OSL::ShaderGroupRef();
1195         }
1196
1197         /* push state to array for lookup */
1198         og->surface_state.push_back(shader->osl_surface_ref);
1199         og->volume_state.push_back(shader->osl_volume_ref);
1200         og->displacement_state.push_back(shader->osl_displacement_ref);
1201         og->bump_state.push_back(shader->osl_surface_bump_ref);
1202 }
1203
1204 #else
1205
1206 void OSLCompiler::add(ShaderNode * /*node*/, const char * /*name*/, bool /*isfilepath*/)
1207 {
1208 }
1209
1210 void OSLCompiler::parameter(ShaderNode * /*node*/, const char * /*name*/)
1211 {
1212 }
1213
1214 void OSLCompiler::parameter(const char * /*name*/, float /*f*/)
1215 {
1216 }
1217
1218 void OSLCompiler::parameter_color(const char * /*name*/, float3 /*f*/)
1219 {
1220 }
1221
1222 void OSLCompiler::parameter_vector(const char * /*name*/, float3 /*f*/)
1223 {
1224 }
1225
1226 void OSLCompiler::parameter_point(const char * /*name*/, float3 /*f*/)
1227 {
1228 }
1229
1230 void OSLCompiler::parameter_normal(const char * /*name*/, float3 /*f*/)
1231 {
1232 }
1233
1234 void OSLCompiler::parameter(const char * /*name*/, int /*f*/)
1235 {
1236 }
1237
1238 void OSLCompiler::parameter(const char * /*name*/, const char * /*s*/)
1239 {
1240 }
1241
1242 void OSLCompiler::parameter(const char * /*name*/, ustring /*s*/)
1243 {
1244 }
1245
1246 void OSLCompiler::parameter(const char * /*name*/, const Transform& /*tfm*/)
1247 {
1248 }
1249
1250 void OSLCompiler::parameter_array(const char * /*name*/, const float /*f*/[], int /*arraylen*/)
1251 {
1252 }
1253
1254 void OSLCompiler::parameter_color_array(const char * /*name*/, const array<float3>& /*f*/)
1255 {
1256 }
1257
1258 #endif  /* WITH_OSL */
1259
1260 CCL_NAMESPACE_END