1 // Copyright Contributors to the Open Shading Language project. 2 // SPDX-License-Identifier: BSD-3-Clause 3 // https://github.com/AcademySoftwareFoundation/OpenShadingLanguage 4 5 #pragma once 6 7 #include <memory> 8 9 #include <OSL/oslconfig.h> 10 #include <OSL/shaderglobals.h> 11 #include <OSL/rendererservices.h> 12 13 #include <OpenImageIO/refcnt.h> 14 #include <OpenImageIO/ustring.h> 15 16 17 OSL_NAMESPACE_ENTER 18 19 class RendererServices; 20 class ShaderGroup; 21 typedef std::shared_ptr<ShaderGroup> ShaderGroupRef; 22 struct ClosureParam; 23 struct PerThreadInfo; 24 class ShadingContext; 25 class ShaderSymbol; 26 27 28 29 /// Opaque pointer to whatever the renderer uses to represent a 30 /// (potentially motion-blurred) coordinate transformation. 31 typedef const void* TransformationPtr; 32 33 34 // Callbacks for closure creation 35 typedef void (*PrepareClosureFunc)(RendererServices*, int id, void* data); 36 typedef void (*SetupClosureFunc)(RendererServices*, int id, void* data); 37 38 39 namespace pvt { 40 class ShadingSystemImpl; 41 } 42 43 namespace Strings { 44 #ifdef __CUDA_ARCH__ 45 #define STRDECL(str,var_name) extern __device__ ustring var_name; 46 #else 47 // Any strings referenced inside of a libsoslexec/wide/*.cpp 48 // or liboslnoise/wide/*.cpp will need OSLEXECPUBLIC 49 #define STRDECL(str,var_name) OSLEXECPUBLIC extern const ustring var_name; 50 #endif 51 #include <OSL/strdecls.h> 52 #undef STRDECL 53 }; // namespace Strings 54 55 56 57 class OSLEXECPUBLIC ShadingSystem 58 { 59 public: 60 ShadingSystem (RendererServices *renderer=NULL, 61 TextureSystem *texturesystem=NULL, 62 ErrorHandler *err=NULL); 63 ~ShadingSystem (); 64 65 /// Set an attribute controlling the shading system. Return true 66 /// if the name and type were recognized and the attrib was set. 67 /// Documented attributes are as follows: 68 /// 1. Attributes that should be exposed to users: 69 /// int statistics:level Automatically print OSL statistics (0). 70 /// string searchpath:shader Colon-separated path to search for .oso 71 /// files ("", meaning test "." only) 72 /// string colorspace Name of RGB color space ("Rec709") 73 /// int range_checking Generate extra code for component & array 74 /// range checking (1) 75 /// int debug_nan Add extra (expensive) code to pinpoint 76 /// when NaN/Inf happens (0). 77 /// int debug_uninit Add extra (expensive) code to pinpoint 78 /// use of uninitialized variables (0). 79 /// int compile_report Issue info messages to the renderer for 80 /// every shader compiled (0). 81 /// int max_warnings_per_thread Number of warning calls that should be 82 /// processed per thread (100). 83 /// int buffer_printf Buffer printf output from shaders and 84 /// output atomically, to prevent threads 85 /// from interleaving lines. (1) 86 /// int profile Perform some rudimentary profiling (0) 87 /// int no_noise Replace noise with constant value. (0) 88 /// int no_pointcloud Skip pointcloud lookups. (0) 89 /// int exec_repeat How many times to run each group (1). 90 /// int opt_warnings Warn on certain failure to runtime-optimize 91 /// certain shader constructs. (0) 92 /// int gpu_opt_error Consider a hard error if certain shader 93 /// constructs cannot be optimized away. (0) 94 /// 2. Attributes that should be set by applications/renderers that 95 /// incorporate OSL: 96 /// string commonspace Name of "common" coord system ("world") 97 /// string[] raytypes Array of ray type names 98 /// string[] renderer_outputs 99 /// Array of names of renderer outputs (AOVs) 100 /// that should not be optimized away. 101 /// int unknown_coordsys_error Should errors be issued when unknown 102 /// coord system names are used? (1) 103 /// int connection_error Should errors be issued when ConnectShaders 104 /// fails to find the layer or parameter? (1) 105 /// int strict_messages Issue error if a message is set after 106 /// being queried (1). 107 /// int error_repeats If zero, suppress repeats of errors and 108 /// warnings that are exact duplicates of 109 /// earlier ones. (1) 110 /// int lazylayers Evaluate shader layers only when their 111 /// outputs are first needed (1) 112 /// int lazyglobals Run layers lazily even if they write to 113 /// globals (1) 114 /// int lazyunconnected Run layers lazily even if they have no 115 /// output connections (1). For debugging. 116 /// int lazyerror Run layers lazily even if they have error 117 /// ops after optimization (1). 118 /// int lazy_userdata Retrieve userdata lazily (0). 119 /// int userdata_isconnected Should lockgeom=0 params (that may 120 /// receive userdata) return true from 121 /// isconnected()? (0) 122 /// int greedyjit Optimize and compile all shaders up front, 123 /// versus only as needed (0). 124 /// int llvm_target_host Target the specific host architecture for 125 /// LLVM IR generation. (1) 126 /// int llvm_jit_fma Allow fused mul/add (0). This can increase 127 /// speed but can change rounding accuracy 128 /// (generally by being better), and might 129 /// differ by hardware platform. 130 /// string llvm_jit_target JIT to a specific ISA: "" or "none" means 131 /// no special ops, "x64", "SSE4.2", "AVX", 132 /// "AVX2", "AVX2_noFMA", "AVX512", 133 /// "AVX512_noFMA", or "host" means to 134 /// figure out what the host can do. ("") 135 /// int llvm_jit_aggressive Use LLVM "aggressive" JIT mode. (0) 136 /// int vector_width Vector width to allow for SIMD ops (4). 137 /// int llvm_debugging_symbols When JITing, generate debug symbols 138 /// that associate machine code with shader 139 /// source and lines. (0) 140 /// int llvm_profiling_events When JITing, generate events to enable 141 /// full profiling of shaders. (0) 142 /// int lockgeom Default 'lockgeom' value for shader params 143 /// that don't specify it (1). Lockgeom 144 /// means a param CANNOT be overridden by 145 /// interpolated geometric parameters. 146 /// int countlayerexecs Add extra code to count total layers run. 147 /// int allow_shader_replacement Allow shader to be specified more than 148 /// once, replacing former definition. 149 /// string archive_groupname Name of a group to pickle and archive. 150 /// string archive_filename Name of file to save the group archive. 151 /// 3. Attributes that that are intended for developers debugging 152 /// liboslexec itself: 153 /// These attributes may be helpful for liboslexec developers or 154 /// for debugging, but probably not for using OSL in production: 155 /// int debug Set debug output level (0) 156 /// int clearmemory Zero out working memory before each shade (0) 157 /// int optimize Runtime optimization level (2) 158 /// And there are several int options that, if set to 0, will turn 159 /// off individual classes of runtime optimizations: 160 /// opt_simplify_param, opt_constant_fold, opt_stale_assign, 161 /// opt_elide_useless_ops, opt_elide_unconnected_outputs, 162 /// opt_peephole, opt_coalesce_temps, opt_assign, opt_mix 163 /// opt_merge_instances, opt_merge_instance_with_userdata, 164 /// opt_fold_getattribute, opt_middleman, opt_texture_handle 165 /// opt_seed_bblock_aliases 166 /// int opt_passes Number of optimization passes per layer (10) 167 /// int llvm_optimize Which of several LLVM optimize strategies (0) 168 /// int llvm_debug Set LLVM extra debug level (0) 169 /// int llvm_debug_layers Extra printfs upon entering and leaving 170 /// layer functions. 171 /// int llvm_debug_ops Extra printfs for each OSL op (helpful 172 /// for devs to find crashes) 173 /// int llvm_output_bitcode Output the full bitcode for each group, 174 /// for debugging. (0) 175 /// int llvm_dumpasm Print the CPU assembly code from the JIT (0) 176 /// string llvm_prune_ir_strategy Strategy for pruning unnecessary 177 /// IR (choices: "prune" [default], 178 /// "internalize", or "none"). 179 /// int max_local_mem_KB Error if shader group needs more than this 180 /// much local storage to execute (1024K) 181 /// string debug_groupname Name of shader group -- debug only this one 182 /// string debug_layername Name of shader layer -- debug only this one 183 /// int optimize_nondebug If 1, fully optimize shaders that are not 184 /// designated as the debug shaders. 185 /// string opt_layername If set, only optimize the named layer 186 /// string only_groupname Compile only this one group (skip all others) 187 /// int force_derivs Force all float-based variables to compute 188 /// and store derivatives. (0) 189 /// 190 /// Note: the attributes referred to as "string" are actually on the app 191 /// side as ustring or const char* (they have the same data layout), NOT 192 /// std::string! 193 bool attribute (string_view name, TypeDesc type, const void *val); 194 195 // Shortcuts for common types attribute(string_view name,int val)196 bool attribute (string_view name, int val) { 197 return attribute (name, TypeDesc::INT, &val); 198 } attribute(string_view name,float val)199 bool attribute (string_view name, float val) { 200 return attribute (name, TypeDesc::FLOAT, &val); 201 } attribute(string_view name,double val)202 bool attribute (string_view name, double val) { 203 float f = (float) val; 204 return attribute (name, TypeDesc::FLOAT, &f); 205 } attribute(string_view name,string_view val)206 bool attribute (string_view name, string_view val) { 207 const char *s = val.c_str(); 208 return attribute (name, TypeDesc::STRING, &s); 209 } 210 211 212 /// Set an attribute for a specific shader group. Return true if the 213 /// name and type were recognized and the attrib was set. Documented 214 /// attributes are as follows: 215 /// string[] renderer_outputs Array of names of renderer outputs 216 /// (AOVs) specific to this shader group 217 /// that should not be optimized away. 218 /// string[] entry_layers Array of names of layers that may be 219 /// callable entry points. They won't 220 /// be elided, but nor will they be 221 /// called unconditionally. 222 /// int exec_repeat How many times to run the group (1). 223 /// 224 bool attribute (ShaderGroup *group, string_view name, 225 TypeDesc type, const void *val); attribute(ShaderGroup * group,string_view name,int val)226 bool attribute (ShaderGroup *group, string_view name, int val) { 227 return attribute (group, name, TypeDesc::INT, &val); 228 } attribute(ShaderGroup * group,string_view name,float val)229 bool attribute (ShaderGroup *group, string_view name, float val) { 230 return attribute (group, name, TypeDesc::FLOAT, &val); 231 } attribute(ShaderGroup * group,string_view name,double val)232 bool attribute (ShaderGroup *group, string_view name, double val) { 233 float f = (float) val; 234 return attribute (group, name, TypeDesc::FLOAT, &f); 235 } attribute(ShaderGroup * group,string_view name,string_view val)236 bool attribute (ShaderGroup *group, string_view name, string_view val) { 237 const char *s = val.c_str(); 238 return attribute (group, name, TypeDesc::STRING, &s); 239 } 240 241 /// Get the named attribute, store it in value. 242 /// 243 bool getattribute (string_view name, TypeDesc type, void *val); 244 245 // Shortcuts for common types getattribute(string_view name,int & val)246 bool getattribute (string_view name, int &val) { 247 return getattribute (name, TypeDesc::INT, &val); 248 } getattribute(string_view name,float & val)249 bool getattribute (string_view name, float &val) { 250 return getattribute (name, TypeDesc::FLOAT, &val); 251 } getattribute(string_view name,double & val)252 bool getattribute (string_view name, double &val) { 253 float f; 254 bool ok = getattribute (name, TypeDesc::FLOAT, &f); 255 if (ok) 256 val = f; 257 return ok; 258 } getattribute(string_view name,char ** val)259 bool getattribute (string_view name, char **val) { 260 return getattribute (name, TypeDesc::STRING, val); 261 } getattribute(string_view name,ustring & val)262 bool getattribute (string_view name, ustring &val) { 263 return getattribute (name, TypeDesc::STRING, (char **)&val); 264 } getattribute(string_view name,std::string & val)265 bool getattribute (string_view name, std::string &val) { 266 const char *s = NULL; 267 bool ok = getattribute (name, TypeDesc::STRING, &s); 268 if (ok) 269 val = s; 270 return ok; 271 } 272 273 /// Get the named attribute about a particular shader group, store it 274 /// in value. Attributes that are currently documented include: 275 /// string groupname The name of the shader group. 276 /// int num_layers The number of layers in the group. 277 /// string[] layer_names The names of the layers in the group. 278 /// int num_textures_needed The number of texture names that are 279 /// known to be potentially needed by the 280 /// group (after optimization). 281 /// ptr textures_needed Retrieves a pointer to the ustring array 282 /// containing all textures known to be 283 /// needed. 284 /// int unknown_textures_needed Nonzero if additional textures may be 285 /// needed, whose names can't be known 286 /// without actually running the shader. 287 /// int num_closures_needed The number of named closures needed. 288 /// ptr closures_needed Retrieves a pointer to the ustring array 289 /// containing all closures known to be 290 /// needed. 291 /// int unknown_closures_needed Nonzero if additional closures may be 292 /// needed, whose names can't be known 293 /// without actually running the shader. 294 /// int globals_read Bitfield ("or'ed" SGBits values) of 295 /// which ShaderGlobals may be read by 296 /// by the shader group. 297 /// int globals_write Bitfield ("or'ed" SGBits values) of 298 /// which ShaderGlobals may be written by 299 /// by the shader group. 300 /// int num_globals_needed The number of named globals needed. 301 /// ptr globals_needed Retrieves a pointer to the ustring array 302 /// containing all globals needed. 303 /// int num_userdata The number of "user data" variables 304 /// retrieved by the shader. 305 /// ptr userdata_names Retrieves a pointer to the array of 306 /// ustring holding the userdata names. 307 /// ptr userdata_types Retrieves a pointer to the array of 308 /// TypeDesc describing the userdata. 309 /// ptr userdata_offsets Retrieves a pointer to the array of 310 /// int describing the userdata offsets 311 /// within the heap. 312 /// int num_attributes_needed The number of attribute/scope pairs that 313 /// are known to be queried by the group (the 314 /// length of the attributes_needed and 315 /// attribute_scopes arrays). 316 /// ptr attributes_needed Retrieves a pointer to the ustring array 317 /// containing the names of the needed attributes. 318 /// Note that if the same attribute 319 /// is requested in multiple scopes, it will 320 /// appear in the array multiple times - once for 321 /// each scope in which is is queried. 322 /// ptr attribute_scopes Retrieves a pointer to a ustring array containing 323 /// the scopes associated with each attribute query 324 /// in the attributes_needed array. 325 /// int unknown_attributes_needed Nonzero if additional attributes may be 326 /// needed, whose names will not be known 327 /// until the shader actually runs. 328 /// int num_renderer_outputs Number of named renderer outputs. 329 /// string renderer_outputs[] List of renderer outputs. 330 /// int raytype_queries Bit field of all possible rayquery 331 /// int num_entry_layers Number of named entry point layers. 332 /// string entry_layers[] List of entry point layers. 333 /// string pickle Retrieves a serialized representation 334 /// of the shader group declaration. 335 /// Note: the attributes referred to as "string" are actually on the app 336 /// side as ustring or const char* (they have the same data layout), NOT 337 /// std::string! 338 bool getattribute (ShaderGroup *group, string_view name, 339 TypeDesc type, void *val); 340 // Shortcuts for common types getattribute(ShaderGroup * group,string_view name,int & val)341 bool getattribute (ShaderGroup *group, string_view name, int &val) { 342 return getattribute (group, name, TypeDesc::INT, &val); 343 } getattribute(ShaderGroup * group,string_view name,float & val)344 bool getattribute (ShaderGroup *group, string_view name, float &val) { 345 return getattribute (group, name, TypeDesc::FLOAT, &val); 346 } getattribute(ShaderGroup * group,string_view name,double & val)347 bool getattribute (ShaderGroup *group, string_view name, double &val) { 348 float f; 349 bool ok = getattribute (group, name, TypeDesc::FLOAT, &f); 350 if (ok) 351 val = f; 352 return ok; 353 } getattribute(ShaderGroup * group,string_view name,char ** val)354 bool getattribute (ShaderGroup *group, string_view name, char **val) { 355 return getattribute (group, name, TypeDesc::STRING, val); 356 } getattribute(ShaderGroup * group,string_view name,ustring & val)357 bool getattribute (ShaderGroup *group, string_view name, ustring &val) { 358 return getattribute (group, name, TypeDesc::STRING, (char **)&val); 359 } getattribute(ShaderGroup * group,string_view name,std::string & val)360 bool getattribute (ShaderGroup *group, string_view name, std::string &val) { 361 const char *s = NULL; 362 bool ok = getattribute (group, name, TypeDesc::STRING, &s); 363 if (ok) 364 val = s; 365 return ok; 366 } 367 368 369 /// Load compiled shader (oso) from a memory buffer, overriding 370 /// shader lookups in the shader search path 371 bool LoadMemoryCompiledShader (string_view shadername, 372 string_view buffer); 373 374 // The basic sequence for declaring a shader group looks like this: 375 // ShadingSystem *ss = ...; 376 // ShaderGroupRef group = ss->ShaderGroupBegin (groupname); 377 // /* First layer - texture lookup shader: */ 378 // /* Specify instance parameter values */ 379 // const char *mapname = "colormap.exr"; 380 // ss->Parameter (*group, "texturename", mapname); 381 // float blur = 0.001; 382 // ss->Parameter (*group, "blur", blur); 383 // Vec3 colorfilter (0.5f, 0.5f, 1.0f); 384 // ss->Parameter (*group, "colorfilter", TypeDesc::TypeColor, 385 // &colorfilter); 386 // ss->Shader ("surface", "texmap", "texturelayer"); 387 // /* Second layer - generate the BSDF closure: */ 388 // float roughness = 0.05; 389 // ss->Parameter (*group, "roughness", roughness); 390 // ss->Shader (*group, "surface", "plastic", "illumlayer"); 391 // /* Make a connection between the layers */ 392 // ss->ConnectShaders (*group, "texturelayer", "Cout", 393 // "illumlayer", "Cs"); 394 // ss->ShaderGroupEnd (*group); 395 396 /// Signal the start of a new shader group. The return value is a 397 /// reference-counted opaque handle to the ShaderGroup. 398 ShaderGroupRef ShaderGroupBegin (string_view groupname = string_view()); 399 400 /// Alternate way to specify a shader group. The group specification 401 /// syntax looks like this: (as a string, all whitespace is equivalent): 402 /// param <typename> <paramname> <value>... [[hints]] ; 403 /// shader <shadername> <layername> ; 404 /// connect <layername>.<paramname> <layername>.<paramname> ; 405 /// For the sake of easy assembling on command lines, a comma ',' may 406 /// substitute for the semicolon as a separator, and the last separator 407 /// before the end of the string is optional. 408 ShaderGroupRef ShaderGroupBegin (string_view groupname, 409 string_view shaderusage, 410 string_view groupspec = string_view()); 411 412 /// Signal the end of a new shader group. 413 /// 414 bool ShaderGroupEnd (ShaderGroup& group); 415 416 /// Set a parameter of the next shader that will be added to the group, 417 /// optionally setting the 'lockgeom' metadata for that parameter 418 /// (despite how it may have been set in the shader). If lockgeom is 419 /// false, it means that this parameter should NOT be considered locked 420 /// against changes by the geometry, and therefore the shader should not 421 /// optimize assuming that the instance value (the 'val' specified by 422 /// this call) is a constant. 423 bool Parameter (ShaderGroup& group, string_view name, TypeDesc t, 424 const void *val, bool lockgeom=true); 425 // Shortcuts for param passing a single int, float, or string. 426 bool Parameter (ShaderGroup& group, string_view name, 427 int val, bool lockgeom=true) { 428 return Parameter (group, name, TypeDesc::INT, &val, lockgeom); 429 } 430 bool Parameter (ShaderGroup& group, string_view name, 431 float val, bool lockgeom=true) { 432 return Parameter (group, name, TypeDesc::FLOAT, &val, lockgeom); 433 } 434 bool Parameter (ShaderGroup& group, string_view name, 435 const std::string& val, bool lockgeom=true) { 436 const char *s = val.c_str(); 437 return Parameter (group, name, TypeDesc::STRING, &s, lockgeom); 438 } 439 bool Parameter (ShaderGroup& group, string_view name, 440 ustring val, bool lockgeom=true) { 441 return Parameter (group, name, TypeDesc::STRING, (const char**)&val, lockgeom); 442 } 443 444 /// Append a new shader instance onto the specified group. The shader 445 /// instance will get any pending parameters that were set by 446 /// Parameter() calls since the last Shader() call for the group. 447 bool Shader (ShaderGroup& group, string_view shaderusage, 448 string_view shadername, string_view layername); 449 450 /// Connect two shaders within the specified group. The source layer 451 /// must be *upstream* of down destination layer (i.e. source must be 452 /// declared earlier within the shader group). The named parameters must 453 /// be of compatible type -- float to float, color to color, array to 454 /// array of the same length and element type, etc. In general, it is 455 /// permissible to connect type A to type B if and only if it is allowed 456 /// within OSL to assign an A to a B (i.e., if `A = B` is legal). So any 457 /// "triple" may be connected to any other triple, and a float output 458 /// may be connected to a triple input (but not the other way around). 459 /// It is permitted to connect a single component of an aggregate to a 460 /// float and vice versa, for example, 461 /// `ConnectShaders (group, "lay1", "mycolorout[2]", 462 /// "lay2", "myfloatinput")` 463 /// 464 bool ConnectShaders (ShaderGroup &group, 465 string_view srclayer, string_view srcparam, 466 string_view dstlayer, string_view dstparam); 467 468 /// Replace a parameter value in a previously-declared shader group. 469 /// This is meant to called after the ShaderGroupBegin/End, but will 470 /// fail if the shader has already been irrevocably optimized/compiled, 471 /// unless the particular parameter is marked as lockgeom=0 (which 472 /// indicates that it's a parameter that may be overridden by the 473 /// geometric primitive). This call gives you a way of changing the 474 /// instance value, even if it's not a geometric override. 475 bool ReParameter (ShaderGroup &group, 476 string_view layername, string_view paramname, 477 TypeDesc type, const void *val); 478 // Shortcuts for param passing a single int, float, or string. ReParameter(ShaderGroup & group,string_view layername,string_view paramname,int val)479 bool ReParameter (ShaderGroup &group, string_view layername, 480 string_view paramname, int val) { 481 return ReParameter (group, layername, paramname, TypeDesc::INT, &val); 482 } ReParameter(ShaderGroup & group,string_view layername,string_view paramname,float val)483 bool ReParameter (ShaderGroup &group, string_view layername, 484 string_view paramname, float val) { 485 return ReParameter (group, layername, paramname, TypeDesc::FLOAT, &val); 486 } ReParameter(ShaderGroup & group,string_view layername,string_view paramname,const std::string & val)487 bool ReParameter (ShaderGroup &group, string_view layername, 488 string_view paramname, const std::string& val) { 489 const char *s = val.c_str(); 490 return ReParameter (group, layername, paramname, TypeDesc::STRING, &s); 491 } ReParameter(ShaderGroup & group,string_view layername,string_view paramname,ustring val)492 bool ReParameter (ShaderGroup &group, string_view layername, 493 string_view paramname, ustring val) { 494 return ReParameter (group, layername, paramname, TypeDesc::STRING, 495 (const char**)&val); 496 } 497 498 // Non-threadsafe versions of Parameter, Shader, ConnectShaders, and 499 // ShaderGroupEnd. These depend on some persistent state about which 500 // shader group is the "current" one being amended. It's fine to use 501 // that as long as all shader specification is done from one thread only 502 // (or at least that you are sure no two groups are being specified 503 // concurrently). If there is any doubt about that, use the versions 504 // above that take an explicit `ShaderGroup&`, which are thread-safe 505 // and re-entrant. 506 bool Parameter (string_view name, TypeDesc t, const void *val, 507 bool lockgeom=true); 508 bool Shader (string_view shaderusage, string_view shadername, 509 string_view layername); 510 bool ConnectShaders (string_view srclayer, string_view srcparam, 511 string_view dstlayer, string_view dstparam); 512 bool ShaderGroupEnd (void); 513 514 /// Create a per-thread data needed for shader execution. It's very 515 /// important for the app to never use a PerThreadInfo from more than 516 /// one thread (and probably a good idea allocate only one PerThreadInfo 517 /// for each renderer thread), and destroy it with destroy_thread_info 518 /// when the thread terminates (and before the ShadingSystem is 519 /// destroyed). 520 PerThreadInfo * create_thread_info(); 521 522 /// Destroy a PerThreadInfo that was allocated by 523 /// create_thread_info(). 524 void destroy_thread_info (PerThreadInfo *threadinfo); 525 526 /// Get a ShadingContext that we can use. The context is specific to a 527 /// renderer thread, and should never be passed between or shared by 528 /// more than one thread. The 'threadinfo' parameter should be a 529 /// thread-specific pointer created by create_thread_info. The context 530 /// can be used to shade many points; a typical usage is to allocate 531 /// just one context per thread and use it for the whole run. 532 ShadingContext *get_context (PerThreadInfo *threadinfo, 533 TextureSystem::Perthread *texture_threadinfo=NULL); 534 535 /// Return a ShadingContext to the pool. 536 /// 537 void release_context (ShadingContext *ctx); 538 539 /// Execute the shader group in this context. If ctx is NULL, then 540 /// execute will request one (based on the running thread) on its own 541 /// and then return it when it's done. This is just a wrapper around 542 /// execute_init, execute_layer of the last (presumably group entry) 543 /// layer, and execute_cleanup. If run==false, just do the binding and 544 /// setup, don't actually run the shader. 545 bool execute (ShadingContext &ctx, ShaderGroup &group, 546 ShaderGlobals &globals, bool run=true); 547 548 // DEPRECATED(2.0): ctx pointer 549 bool execute (ShadingContext *ctx, ShaderGroup &group, 550 ShaderGlobals &globals, bool run=true); 551 552 /// Bind a shader group and globals to the context, in preparation to 553 /// execute, including optimization and JIT of the group (if it has not 554 /// already been done). If 'run' is true, also run any initialization 555 /// necessary. If 'run' is false, we are not planning to actually 556 /// execute any part of the shader, so do all the usual binding 557 /// preparation, but don't actually run the shader. Return true if the 558 /// shader executed, false if it did not (including if the shader itself 559 /// was empty). 560 bool execute_init (ShadingContext &ctx, ShaderGroup &group, 561 ShaderGlobals &globals, bool run=true); 562 563 /// Execute the layer whose index is specified, in this context. It is 564 /// presumed that execute_init() has already been called, with 565 /// run==true, and that the call to execute_init() returned true. (One 566 /// reason why it might have returned false is if the shader group 567 /// turned out, after optimization, to do nothing.) 568 bool execute_layer (ShadingContext &ctx, ShaderGlobals &globals, 569 int layernumber); 570 /// Execute the layer by name. 571 bool execute_layer (ShadingContext &ctx, ShaderGlobals &globals, 572 ustring layername); 573 /// Execute the layer that has the given ShaderSymbol as an output. 574 /// (The symbol is one returned by find_symbol()). 575 bool execute_layer (ShadingContext &ctx, ShaderGlobals &globals, 576 const ShaderSymbol *symbol); 577 578 /// Signify that the context is done with the current execution of the 579 /// group that was kicked off by execute_init and one or more calls to 580 /// execute_layer. 581 bool execute_cleanup (ShadingContext &ctx); 582 583 /// Find the named layer within a group and return its index, or -1 584 /// if no such named layer exists. 585 int find_layer (const ShaderGroup &group, ustring layername) const; 586 587 /// Get a raw pointer to a named symbol (such as you'd need to pull 588 /// out the value of an output parameter). ctx is the shading 589 /// context (presumably already run), name is the name of the 590 /// symbol. If found, get_symbol will return the pointer to the 591 /// symbol's data, and type will get the symbol's type. If the 592 /// symbol is not found, get_symbol will return NULL. 593 /// If you give just a symbol name, it will search for the symbol in all 594 /// layers, last-to-first. If a specific layer is named, it will search 595 /// only that layer. You can specify a layer either by naming it 596 /// separately, or by concatenating "layername.symbolname", but note 597 /// that the latter will involve string manipulation inside get_symbol 598 /// and is much more expensive than specifying them separately. 599 /// 600 /// These are considered somewhat deprecated, in favor of using 601 /// find_symbol(), symbol_typedesc(), and symbol_address(). 602 const void* get_symbol (const ShadingContext &ctx, ustring layername, 603 ustring symbolname, TypeDesc &type) const; 604 const void* get_symbol (const ShadingContext &ctx, ustring symbolname, 605 TypeDesc &type) const; 606 607 /// Search for an output symbol by name (and optionally, layer) within 608 /// the optimized shader group. If the symbol is found, return an opaque 609 /// identifying pointer to it, otherwise return NULL. This is somewhat 610 /// expensive because of the name-based search, but once done, you can 611 /// reuse the pointer to the symbol for the lifetime of the group. 612 /// 613 /// If you give just a symbol name, it will search for the symbol in all 614 /// layers, last-to-first. If a specific layer is named, it will search 615 /// only that layer. You can specify a layer either by naming it 616 /// separately, or by concatenating "layername.symbolname", but note 617 /// that the latter will involve string manipulation inside find_symbol 618 /// and is much more expensive than specifying them separately. 619 const ShaderSymbol* find_symbol (const ShaderGroup &group, 620 ustring layername, ustring symbolname) const; 621 const ShaderSymbol* find_symbol (const ShaderGroup &group, 622 ustring symbolname) const; 623 624 /// Given an opaque ShaderSymbol*, return the TypeDesc describing it. 625 /// Note that a closure will end up with a TypeDesc::UNKNOWN value. 626 TypeDesc symbol_typedesc (const ShaderSymbol *sym) const; 627 628 /// Given a context (that has executed a shader) and an opaque 629 /// ShaderSymbol*, return the actual memory address where the value of 630 /// the symbol resides within the heap memory of the context. This 631 /// is only valid for the shader execution that had happened immediately 632 /// prior for this context, but it is a very inexpensive operation. 633 const void* symbol_address (const ShadingContext &ctx, 634 const ShaderSymbol *sym) const; 635 636 /// Return the statistics output as a huge string. 637 /// 638 std::string getstats (int level=1) const; 639 640 void register_closure (string_view name, int id, const ClosureParam *params, 641 PrepareClosureFunc prepare, SetupClosureFunc setup); 642 643 /// Query either by name or id an existing closure. If name is non 644 /// NULL it will use it for the search, otherwise id would be used 645 /// and the name will be placed in name if successful. Also return 646 /// pointer to the params array in the last argument. All args are 647 /// optional but at least one of name or id must non NULL. 648 bool query_closure (const char **name, int *id, 649 const ClosureParam **params); 650 651 /// For the proposed shader "global" name, return the corresponding 652 /// SGBits enum. 653 static SGBits globals_bit (ustring name); 654 655 /// For the SGBits value, return the shader "globals" name. 656 static ustring globals_name (SGBits bit); 657 658 /// For the proposed raytype name, return the bit pattern that 659 /// describes it, or 0 for an unrecognized name. (This retrieves 660 /// data passed in via attribute("raytypes")). 661 int raytype_bit (ustring name); 662 663 /// Configure the default raytypes to assume to be on (or off) at optimization 664 /// time for the given group. The raytypes_on gives a bitfield describing which 665 /// ray flags are known to be 1, and raytypes_off describes which ray flags are 666 /// known to be 0. Bits that are not set in either set of flags are not known 667 /// to the optimizer, and will be determined strictly at execution time. 668 void set_raytypes(ShaderGroup *group, int raytypes_on, int raytypes_off); 669 670 /// Ensure that the group has been optimized and optionally JITed. The ctx pointer 671 /// supplies a ShadingContext to use. 672 void optimize_group (ShaderGroup *group, ShadingContext *ctx, bool do_jit = true); 673 674 /// Ensure that the group has been optimized and optionally JITed. This is a 675 /// convenience function that simply calls set_raytypes followed by 676 /// optimize_group. The ctx supplies a ShadingContext to use. 677 void optimize_group (ShaderGroup *group, int raytypes_on, 678 int raytypes_off, ShadingContext *ctx, bool do_jit = true); 679 680 /// If option "greedyjit" was set, this call will trigger all 681 /// shader groups that have not yet been compiled to do so with the 682 /// specified number of threads (0 means use all available HW cores). 683 void optimize_all_groups (int nthreads=0, bool do_jit = true); 684 685 /// Return a pointer to the TextureSystem being used. 686 TextureSystem * texturesys () const; 687 688 /// Return a pointer to the RendererServices being used. 689 RendererServices * renderer () const; 690 691 /// Archive the entire shader group so that it can be reconstituted 692 /// later. 693 bool archive_shadergroup (ShaderGroup &group, string_view filename); 694 695 // DEPRECATED(2.0) 696 bool archive_shadergroup (ShaderGroup *group, string_view filename); 697 698 /// Helper function -- copy or convert a source value (described by 699 /// srctype) to destination (described by dsttype). The function 700 /// returns true upon success, or false if the types differ in a way 701 /// that cannot be converted. As a special case, if dst==NULL or 702 /// src==NULL, no copying is performed, and convert_value merely 703 /// returns a bool indicating if the proposed type conversion is 704 /// allowed. 705 /// 706 /// The following type conversions are supported: 707 /// 1. Identical types copy without modification. 708 /// 2. Conversions following the same rules as type casting and 709 /// assignment in OSL itself: 710 /// int -> float convert to float 711 /// int -> triple convert to float and replicate x3 712 /// int -> float[4] convert to float and replicate x4 713 /// float -> triple replicate x3 714 /// float -> float[4] replicate x4 715 /// float -> int truncate like a (int) type cast 716 /// triple -> triple copy, regardless of differing vector types 717 /// 3. Additional rules not allowed in OSL source code: 718 /// float -> float[2] replicate x2 719 /// int -> float[2] convert to float and replicate x2 720 /// float[2] -> triple (f[0], f[1], 0) 721 /// float[4] -> vec4 allow conversion to OIIO type (no vec4 in OSL) 722 /// 723 /// Observation: none of the supported conversions require more 724 /// storage for src than for dst. 725 static bool convert_value(void* dst, TypeDesc dsttype, const void* src, 726 TypeDesc srctype); 727 728 private: 729 pvt::ShadingSystemImpl* m_impl; 730 }; 731 732 733 734 #ifdef OPENIMAGEIO_IMAGEBUFALGO_H 735 // To keep from polluting all OSL clients with ImageBuf & ROI, only expose 736 // the following declarations if they have included OpenImageIO/imagebufalgo.h. 737 738 // enum describing where shades are located for shade_image(). 739 enum ShadeImageLocations { 740 ShadePixelCenters, // locate shades at pixel centers: (i+0.5)/res 741 ShadePixelGrid // locate shades at grid nodes: i/(res-1) 742 }; 743 744 745 /// Utility to execute a shader group on each pixel in a rectangular region 746 /// of an ImageBuf (which must already be allocated and which must have 747 /// FLOAT pixels). The output parameters to save are specified by an array 748 /// of ustring values in 'outputs'. If there are multiple outputs, they will 749 /// simply be concatenated channel by channel in the image. 750 /// 751 /// The roi specifies the region of the ImageBuf to shade (defaulting to the 752 /// whole thing), any pixels outside the roi will not be altered. 753 /// 754 /// The 'defaultsg', if non-NULL, provides a template for the default 755 /// ShaderGlobals to use for each point. If not provided, reasonable 756 /// defaults will be chosen. 757 /// 758 /// When shading, P will have the pixel lattice coordinates (i,j,k), and u 759 /// and v will vary from 0->1 across the full (aka "display") window. 760 /// Depending on the value of 'shadelocations', the shading locations 761 /// themselves will either be at "pixel centers" (position (i+0.5)/res), or 762 /// as if it were a grid that is shaded at exact endpoints (position 763 /// i/(res+1)). In either case, derivatives will be set appropriately. 764 OSLEXECPUBLIC 765 bool 766 shade_image(ShadingSystem& shadingsys, ShaderGroup& group, 767 const ShaderGlobals* defaultsg, OIIO::ImageBuf& buf, 768 cspan<ustring> outputs, 769 ShadeImageLocations shadelocations = ShadePixelCenters, 770 OIIO::ROI roi = OIIO::ROI(), 771 OIIO::parallel_options popt = 0); 772 773 #endif 774 775 776 OSL_NAMESPACE_EXIT 777