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 #ifndef __OSL_H__
18 #define __OSL_H__
19 
20 #include "util/util_array.h"
21 #include "util/util_set.h"
22 #include "util/util_string.h"
23 #include "util/util_thread.h"
24 
25 #include "render/graph.h"
26 #include "render/nodes.h"
27 #include "render/shader.h"
28 
29 #ifdef WITH_OSL
30 #  include <OSL/llvm_util.h>
31 #  include <OSL/oslcomp.h>
32 #  include <OSL/oslexec.h>
33 #  include <OSL/oslquery.h>
34 #endif
35 
36 CCL_NAMESPACE_BEGIN
37 
38 class Device;
39 class DeviceScene;
40 class ImageManager;
41 class OSLRenderServices;
42 struct OSLGlobals;
43 class Scene;
44 class ShaderGraph;
45 class ShaderNode;
46 class ShaderInput;
47 class ShaderOutput;
48 
49 #ifdef WITH_OSL
50 
51 /* OSL Shader Info
52  * to auto detect closures in the shader for MIS and transparent shadows */
53 
54 struct OSLShaderInfo {
OSLShaderInfoOSLShaderInfo55   OSLShaderInfo()
56       : has_surface_emission(false), has_surface_transparent(false), has_surface_bssrdf(false)
57   {
58   }
59 
60   OSL::OSLQuery query;
61   bool has_surface_emission;
62   bool has_surface_transparent;
63   bool has_surface_bssrdf;
64 };
65 
66 /* Shader Manage */
67 
68 class OSLShaderManager : public ShaderManager {
69  public:
70   OSLShaderManager();
71   ~OSLShaderManager();
72 
73   static void free_memory();
74 
75   void reset(Scene *scene);
76 
use_osl()77   bool use_osl()
78   {
79     return true;
80   }
81 
82   void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress);
83   void device_free(Device *device, DeviceScene *dscene, Scene *scene);
84 
85   /* osl compile and query */
86   static bool osl_compile(const string &inputfile, const string &outputfile);
87   static bool osl_query(OSL::OSLQuery &query, const string &filepath);
88 
89   /* shader file loading, all functions return pointer to hash string if found */
90   const char *shader_test_loaded(const string &hash);
91   const char *shader_load_bytecode(const string &hash, const string &bytecode);
92   const char *shader_load_filepath(string filepath);
93   OSLShaderInfo *shader_loaded_info(const string &hash);
94 
95   /* create OSL node using OSLQuery */
96   static OSLNode *osl_node(ShaderGraph *graph,
97                            ShaderManager *manager,
98                            const std::string &filepath,
99                            const std::string &bytecode_hash = "",
100                            const std::string &bytecode = "");
101 
102  protected:
103   void texture_system_init();
104   void texture_system_free();
105 
106   void shading_system_init();
107   void shading_system_free();
108 
109   OSL::ShadingSystem *ss;
110   OSL::TextureSystem *ts;
111   OSLRenderServices *services;
112   OSL::ErrorHandler errhandler;
113   map<string, OSLShaderInfo> loaded_shaders;
114 
115   static OSL::TextureSystem *ts_shared;
116   static thread_mutex ts_shared_mutex;
117   static int ts_shared_users;
118 
119   static OSL::ShadingSystem *ss_shared;
120   static OSLRenderServices *services_shared;
121   static thread_mutex ss_shared_mutex;
122   static thread_mutex ss_mutex;
123   static int ss_shared_users;
124 };
125 
126 #endif
127 
128 /* Graph Compiler */
129 
130 class OSLCompiler {
131  public:
132 #ifdef WITH_OSL
133   OSLCompiler(OSLShaderManager *manager,
134               OSLRenderServices *services,
135               OSL::ShadingSystem *shadingsys,
136               Scene *scene);
137 #endif
138   void compile(OSLGlobals *og, Shader *shader);
139 
140   void add(ShaderNode *node, const char *name, bool isfilepath = false);
141 
142   void parameter(ShaderNode *node, const char *name);
143 
144   void parameter(const char *name, float f);
145   void parameter_color(const char *name, float3 f);
146   void parameter_vector(const char *name, float3 f);
147   void parameter_normal(const char *name, float3 f);
148   void parameter_point(const char *name, float3 f);
149   void parameter(const char *name, int f);
150   void parameter(const char *name, const char *s);
151   void parameter(const char *name, ustring str);
152   void parameter(const char *name, const Transform &tfm);
153 
154   void parameter_array(const char *name, const float f[], int arraylen);
155   void parameter_color_array(const char *name, const array<float3> &f);
156 
157   void parameter_attribute(const char *name, ustring s);
158 
159   void parameter_texture(const char *name, ustring filename, ustring colorspace);
160   void parameter_texture(const char *name, int svm_slot);
161   void parameter_texture_ies(const char *name, int svm_slot);
162 
output_type()163   ShaderType output_type()
164   {
165     return current_type;
166   }
167 
168   bool background;
169   Scene *scene;
170 
171  private:
172 #ifdef WITH_OSL
173   string id(ShaderNode *node);
174   OSL::ShaderGroupRef compile_type(Shader *shader, ShaderGraph *graph, ShaderType type);
175   bool node_skip_input(ShaderNode *node, ShaderInput *input);
176   string compatible_name(ShaderNode *node, ShaderInput *input);
177   string compatible_name(ShaderNode *node, ShaderOutput *output);
178 
179   void find_dependencies(ShaderNodeSet &dependencies, ShaderInput *input);
180   void generate_nodes(const ShaderNodeSet &nodes);
181 
182   OSLShaderManager *manager;
183   OSLRenderServices *services;
184   OSL::ShadingSystem *ss;
185 #endif
186 
187   ShaderType current_type;
188   Shader *current_shader;
189 
190   static int texture_shared_unique_id;
191 };
192 
193 CCL_NAMESPACE_END
194 
195 #endif /* __OSL_H__  */
196