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