HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
VOP_CodeGenerator.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  */
7 
8 #ifndef __VOP_CodeGenerator_h__
9 #define __VOP_CodeGenerator_h__
10 
11 #include "VOP_API.h"
12 #include "VOP_Error.h"
13 #include "VOP_ErrorMicroNode.h"
14 #include "VOP_Node.h"
15 #include "VOP_Types.h"
16 
17 #include <OP/OP_Network.h>
18 #include <OP/OP_Node.h>
19 #include <VEX/VEX_VexTypes.h>
20 #include <UT/UT_NonCopyable.h>
21 #include <UT/UT_UniquePtr.h>
22 #include <UT/UT_SharedPtr.h>
23 
24 #include <map>
25 #include <string>
26 #include <time.h>
27 
28 // The names of the parameters for setting the min and max inputs for the
29 // operator type defined by a VOP Network.
30 #define VOP_MININPUTS_NAME "mininputs"
31 #define VOP_MAXINPUTS_NAME "maxinputs"
32 
33 // A node may be a shader node that defines a shader function code on its own
34 // (eg, a vopnet) but also represent an ad-hoc temporary shader code
35 // constructed from node and its inputs (siblings). The temporary auto shader
36 // will contain a call to the node's own shader. To disambiguate which of
37 // these shaders we refer to, we prefix the node path for auto shaders.
38 #define VOP_AUTO_SHADER_PREFIX "_auto_"
39 #define VOP_AUTO_SHADER_PREFIX_LEN 6
40 #define VOP_AUTO_SHADER_FN_PREFIX "auto_"
41 #define VOP_AUTO_SHADER_FN_PREFIX_LEN 5
42 
43 class UT_StringArray;
44 class CH_LocalVariable;
45 class OP_OTLDefinition;
46 class OP_Network;
47 class VOP_Collect;
48 class VOP_Language;
49 class VOP_CodeGenerator;
54 class VOP_VopTypeDefiner;
56 class VOP_ObjectCodeArgs;
58 class VCC_Compiler;
59 class VCC_Diagnostics;
60 class VCC_DiagnosticInfo;
61 class VCC_Options;
62 
64 
65 
66 class vop_CodeCacheData;
67 class vop_CodeGenOutputContext;
68 
69 typedef std::map < VOP_ContextType, std::string > TContextTypeStringMap;
70 
72 {
73 public:
75  const char *className() const override
76  { return "VOP_SnippetMicroNode"; }
78  const DEP_PropagateData &data) override;
79 protected:
81 };
82 
84 {
85 public:
86  VOP_CodeOperatorFilter(const char *optypename, VOP_CodeGenerator *owner);
87  ~VOP_CodeOperatorFilter() override;
88 
89  bool allowOperatorAsChild(OP_Operator *op) override;
90 
91  /// Returns true if operator's vopnet maks is accepted by one of the given
92  /// shader contexts.
93  static bool isOpVopnetMaskAllowed(OP_Operator *op,
94  const UT_StringArray &accepted_contexts,
95  bool is_vex );
96 
97 private:
98  UT_StringArray myVopnetTypes;
99  VOP_CodeGenerator *myOwner;
100 };
101 
102 
104 {
105 public:
106  /// Constructor
107  /// @param owner The network based on which the code is generated (whose
108  /// outupt node is used during code generation, etc)
109  /// @param context_type A list of context type for a specific language,
110  /// which the generator will generate code for. For
111  /// single-context shaders, the list will have a single
112  /// entry, while multi-context shaders will have several.
113  /// The code generator will take ownership of that
114  /// context type list object and will delete it in the
115  /// destructor.
116  /// @param mininputs Minimum number of inputs to the owner
117  /// @param maxinputs Maximum number of input to the owner
119  VOP_LanguageContextTypeList * context_type,
120  int mininputs,
121  int maxinputs);
122  virtual ~VOP_CodeGenerator();
123 
124  OP_OperatorFilter *getOperatorFilter();
125  UT_ErrorManager &getErrorManager();
126 
127  /// Return the exported parameters manager.
129  { return myExportedParmsMgr; }
130  virtual bool hasShaderParameter(const char *parm_name);
131 
132  void beforeAddNode(OP_Node *node);
133  void afterAddNode(OP_Node *node);
134 
135  /// Sometimes a VOP needs to change its variable tables (i.e. an
136  /// encapsulated shader)
137  void resetTables(VOP_Node *node);
138 
139  /// Functions for controlling when a code generator is updated.
140  /// The code pattern is something like this:
141  /// int update_id = codegenerator->beginUpdate();
142  /// ...
143  /// if (code_needs_to_update)
144  /// codegenerator->setNeedsCodeUpdate();
145  /// ...
146  /// codegenerator->endUpdate(update_id);
147  /// @{
148  int beginUpdate();
149  void endUpdate(int update_level);
150 
152  {
153  myNeedsCodeUpdate = false;
154  }
155  void setNeedsCodeUpdate();
156  /// @}
157 
158  void ownerChanged(OP_EventType reason, void *data);
159  void ownerFinishedLoadingNetwork();
160  void generateVopErrors();
161 
162  bool getVariableString(int index, UT_String &value);
163 
164  const char *getEnglishName();
165 
166  /// @{
167  /// The function name is mangled for some renderers (i.e. RSL) since basing
168  /// the function name on the node name is not safe. However, some places
169  /// require the node name -- unmangled (i.e. dialog scripts).
170  const char *getFunctionName(UT_String &name) const;
171  const char *getInternalFunctionName(UT_String &name) const;
172  /// @}
173 
174  /// The function path is the leading path to the shader
175  const char *getFunctionPath(UT_String &name) const;
176 
177  int getMinimumInputs() const;
178  int getMaximumInputs() const;
179  void getInternalOperatorInfo(OP_OTLDefinition &info);
180 
181  /// Returns ture if the generator can generate code for the given type.
182  bool canGenerateCode( VOP_Type shader_type ) const;
183 
184  /// Returns a list of shader types that can be auto-generated for the owner.
185  void getAutoShaderTypes( VOP_ShaderTypeList &types ) const;
186 
187  void setVexCodeDirty();
188 
189  /// Outputs vex code.
190  /// @param[out] os Stream to write the vex code to.
191  /// @param[in] shadername Specifies the name that should be used for the
192  /// generated vex code.
193  /// @param[in] context_type Specifies the shading context for which
194  /// to generate vex code; relevant only for multi-context
195  /// vopnets.
196  /// @param[out] is_pure_compiled Set to true if the vex code comes from
197  /// a locked code source (i.e., a CPIO packet for the
198  /// node saved in the hip file), which indicates the node
199  /// has been compiled out.
200  bool outputVexCode(std::ostream &os, const char *shadername,
203  bool *is_pure_compiled = nullptr,
204  VOP_ShaderSpaceInfo *shader_space = nullptr );
205 
206  /// Determines if the giving context has already been cached.
207  bool isVexCodeCached(VOP_ContextType context_type) const
208  {
209  return findCachedCode(context_type) ? true : false;
210  }
211 
212  /// Generates a VFL code and writes it to the os.
213  /// @param shadername The name of the shader function.
214  /// @param flags The code generation flags.
215  /// @param context_type For multi-context materials, this is the shader
216  /// context for which to generate code.
217  /// @param skipheader If true the file comment will be skpped;
218  /// the file comment contains info about original
219  /// node, file name, and generation time stamp.
220  /// @param output_node_name Optional, this is a hint that specifies
221  /// the name of the output node for which to generate the code.
222  /// If the node by this name is found and it supports the
223  /// context type (if given), then it is used for gathering
224  /// nodes that participate in VFL code generation.
225  /// If the node by this name cannot be used, then a Collect VOP
226  /// node will be used. And if there is no collect node
227  /// a (arbitrary) output node supporting the context type
228  /// will be used.
229  virtual bool outputVflCode(
230  std::ostream &os, const char *shadername,
233  bool skipheader = false,
234  const char * output_node_name = nullptr,
235  VCC_Diagnostics *diag = nullptr,
236  VOP_ShaderSpaceInfo *shader_space = nullptr );
237 
238  /// Generates a VFL code for a vex function defined by a vop subnet node.
239  // TODO: unify it with outputVflCode(); use temp code gen if needed
240  bool outputEncapsulatedVflCode(
241  std::ostream &os,
242  VOP_Node *subnet,
243  const char *function_name,
245  VOP_ContextType context_type,
246  bool generate_outer_code);
247 
248  /// Compiles VFL code into VEX output, and uses the global disk
249  /// cache.
250  static bool compileAndCacheVflCode(UT_WorkBuffer &vex_output,
251  const UT_WorkBuffer &vfl_input,
252  const char *filename,
253  VCC_Compiler *compiler,
254  const VCC_Options &opts);
255 
256  /// Returns a list of dependencies, if the shader handled by this code
257  /// generator is an encapsulated shader (cached code).
258  void getDependencies(VOP_ContextType context_type,
259  UT_StringArray &shader_deps);
260 
261  // Returns parm nodes that define shader parameters.
262  void getShaderParameterNodes(VOP_NodeList &parm_vops,
263  VOP_Type shader_type);
264 
265  /// On the given micronode, add an extra input to our code micro
266  /// node so it gets reset everytime we are dirtied.
268  {
269  if (target) target->addExplicitInput(myCodeUpdatedMicroNode);
270  }
271 
272  /// Return the time stamp from when VEX code was last generated or -1
273  /// if no cached code exists
274  time_t getCachedCodeTimeStamp(
275  VOP_ContextType context_type) const;
276  /// Return true if this code generator has any cached code.
277  bool hasCachedCode() const;
278 
279  void generateRslObject(UT_String &ofile,
280  const char *cache_directory,
281  const char *renderer,
282  int major_version,
283  int minor_version,
284  const char *shaderpath,
285  const char *shadername,
286  VOP_ContextType context_type,
287  bool ignore_dirty_flag,
288  UT_String *error_return);
289 
290  void generateOslObject(UT_String &ofile,
291  const char *cache_directory,
292  const char *shaderpath,
293  const char *shadername,
294  VOP_ContextType context_type,
295  bool ignore_dirty_flag,
296  UT_String *error_return);
297 
298  // Get a list of infos about the class member methods.
299  void getClassMethodInfos(
301 
302  // Returns owner's output nodes and the shader type they're contributing.
303  void getOutputNodes(VOP_NodeList &outputs,
304  VOP_ShaderTypeList *types = nullptr) const;
305 
306  /// Return the collection VOP (or NULL if there is no collection)
307  VOP_Collect *getCollectNode() const;
308 
309  /// Return the code generating encapsulated shader for the given context
310  /// (or NULL).
311  VOP_Node *getEncapsulatedShader(VOP_ContextType context) const;
312 
313  // Expand the compiler & options using local variables.
314  const char *getCompiler(UT_String &compiler, fpreal now,
315  const char *defcompiler);
316  const char *getCompiler(UT_WorkBuffer &wbuf, fpreal now,
317  const char *defcompiler);
318 
319  /// @{ Get a string containing the errors or warnings from our last vex
320  /// code generation (including source code generation and compilation).
321  /// Returns true if there were any errors.
322  bool getGeneratorErrors(UT_String &errors) const;
323  bool getGeneratorErrors(UT_String &errors,
324  VOP_ContextType context_type) const;
325  bool getGeneratorErrorsAndWarnings(UT_String &msgs) const;
326  bool getGeneratorErrorsAndWarnings(UT_String &msgs,
327  VOP_ContextType context_type) const;
328 
329  bool getDiagnosticsForNode(VOP_Node *node,
330  VCC_DiagnosticList &list) const;
331  /// @}
332 
333  /// Get the VOP language generated by this code generator.
334  const VOP_Language *getLanguage() const
335  { return myLanguage; }
336 
337  /// Get the object representing the list of shader contexts (surface,
338  /// displacement, etc) supported by this generator. The returned object
339  /// also describes the language type supported by this generator.
341  { return myContextTypeList.get(); }
342 
343  /// Returs a language for which this generator produces code.
344  VOP_LanguageType getLanguageType() const;
345 
346 
347  /// @{ An automatic code generator is created by default for a VOP,
348  /// when a VOP is created in a Shader Network container.
349  /// The automatic generator provides a code for a temporary shader
350  /// consisting of that VOP and any of its input chains.
351  void setIsAutoGenerator(bool is_auto)
352  { myIsAutoGenerator = is_auto; }
353  bool isAutoGenerator() const
354  { return myIsAutoGenerator; }
355  /// @}
356 
357  /// Returns true if the generator should generate temporary, automatic,
358  /// adhoc shader for the owner node, when that node is assigned as a shader.
359  /// Such code is needed for VOPs directly inside a Shader Network container,
360  /// when they are not true shaders themselves, or when a connected input
361  /// implies a composite shder generation.
362  /// In other cases (eg an unconnected VOP that represents an external
363  /// shader, or a RIS shader), there is no need for temp shader code gen.
364  ///
365  /// @param allow_value_inputs - if true, don't need to generate auto-shader
366  /// when all inputs are simple value (Parm or Const VOPs).
367  bool needsToGenerateAutoShader(
368  bool allow_value_inputs = false) const;
369 
370  /// Returns true if it is a single-context vopnet that this generator
371  /// produces code for. Otherwise (ie, multi-context) returns false.
372  bool isSingleContextType() const;
373 
374  /// Returns true if this generator produces a class-based shader.
375  bool isClassBasedShader() const;
376 
377  /// Returns true if the given shader type is class-based.
378  bool isClassBasedShader(
379  const VOP_CodeGenContext &codegen_ctx) const;
380 
381  /// Returns a list of vopnet type masks for a given context list.
382  void getVopnetTypes(const VOP_ContextTypeList &ctxts,
383  UT_StringArray &vopnet_types);
384 
385  /// Returns true if the owner of the code generator displays parameters.
386  /// This is currently true for VOPNET_Nodes.
388  { return myOwnerHasParameters; }
389 
390  /// Determine the VOP context type for single-context type vopnet generator.
391  /// For generator of a multi-context vopnet returns
392  /// VOP_CONTEXT_TYPE_INVALID, because the specific VOP context cannot be
393  /// reliably and unambiguously determined.
394  VOP_ContextType getVopContextType() const;
395 
396  /// Determine the VEX context type for single-context type vopnet generator.
397  /// For generator of a multi-context vopnet (or for RSL vopnet) returns
398  /// VEX_INVALID_CONTEXT, because the specific VEX context cannot be
399  /// reliably and unambiguously determined.
400  VEX_ContextType getVexContextType() const;
401  RSL_ContextType getRslContextType() const;
402  OSL_ContextType getOslContextType() const;
403 
404  /// Returns the compiler arguments.
406  { return myCompilerArgs; }
407 
408  /// Set the locked compiled code. When set, the locked code causes the
409  /// code generator to ignore the VOP nodes in the owner network and always
410  /// return the locked value.
411  void setLockedCompiledCode(
412  const char *code, VOP_ContextType context_type,
413  bool is_source_code);
414 
415  /// Utility function to get a code generator corresponding to the node.
416  /// Returns own code generator if it exists, or creator's code generator.
417  static VOP_CodeGenerator *findCodeGenerator( const OP_Node *node );
418 
419  // The local variables that must be defined by any code generator node.
420  // These are the variables understood by the getVariableString function
421  static CH_LocalVariable theLocalVariables[];
422 
423  // Install commands specific to VOP code generators.
424  static void installCommands();
425 
426  // This function converts a local VOP code generator to a global VOP code
427  // generator that defines an operator type.
428  static bool convertVopOpToVopOpType(OP_Node *node,
429  UT_String &err);
430 
431  /// Returns the default VOP mask for VEX.
432  static const char *getDefaultVEXMask();
433 
434  // These variables define the parameter descriptions for the VOP
435  // compiler parm used to specify how to compile VOP generated code.
442 
443  static bool forceCompile(OP_Node *node);
444  static int forceCompile(void *data, int, fpreal,
445  const PRM_Template *);
446 
447  /// Determines the vex context. In single-context vop, returns a vex type
448  /// intrinsic to that vop. In multi-context vop, returns the vex type based
449  /// on context_type passed as an argument.
450  VEX_ContextType pickVexContextType(VOP_ContextType context_type) const;
451  RSL_ContextType pickRslContextType(VOP_ContextType context_type) const;
452  OSL_ContextType pickOslContextType(VOP_ContextType context_type) const;
453 
454  /// Determines the vop context (ie encode vex or rsl context type).
455  /// In single-context vop, returns a vex/rsl context type (encoded as vop
456  /// type) intrinsic to that vop. In multi-context vop, returns the vop
457  /// type based passed as an argument.
458  VOP_ContextType pickContextType(VOP_ContextType context_type) const;
459 
460  // Locates a procedural shader by searching the VOP network an output node
461  // of type "interpret_type" and tracing back to the first non-simple node.
462  VOP_Node *getProcedural(VOP_Type interpret_type) const;
463 
464  /// Obtains the export variables that don't have explicit output connectors.
465  void getVopFunctionArgInfosFromExports(
466  UT_Array<VOP_FunctionArgInfo> &arg_infos,
467  VOP_Type shader_type );
468 
469  /// Gathers all the rendering properties nodes.
470  void getPropertiesNodes(VOP_NodeList &properties);
471 
473  { return myOwner; }
474 
475  /// Return the micro-node representing the error state. The micro-node will
476  /// signal if we transition from clean -> error, error -> error, and
477  /// error -> clean.
479  { return myErrorMicroNode; }
480 
481  static void formatDiagnostic(const VCC_DiagnosticInfo &info,
482  UT_WorkBuffer &str);
483 
484  /// Get a list of all vop nodes participating in the shader. The list
485  /// is sorted according to order in which the vfl code should be generated.
486  /// If 'check_errors' is true, node error checking is performed and if
487  /// any error is encountered, the method will return false (and the node
488  /// list may be incomplete). If this argument is false, the method
489  /// does not check errors and always returns true and the list
490  /// of nodes is complete.
491  /// NB: when nodes a no longer needed, use cleanupNodesForShaderOutput()
492  /// to clean up the list of temporary nodes this method may create.
493  bool getNodesForContextOrNodeFunctionVflCode(
494  VOP_NodeList &nodes,
495  VOP_Node *&output_node,
496  const VOP_CodeGenContext &codegen_ctx,
497  VOP_CodeVarMapperContext &varmap_context,
498  const char *output_node_name,
499  bool check_errors,
500  VCC_Diagnostics *diagnostics);
501 
502  /// Get a list of all vop nodes participating in the function code
503  /// defined by a vop subnet. The list is sorted according to order in
504  /// which the vfl code should be generated.
505  /// NB: when nodes a no longer needed, use cleanupNodesForShaderOutput()
506  /// to clean up the list of temporary nodes this method may create.
507  bool getNodesForSubnetFunctionVflCode(VOP_NodeList &nodes,
508  const VOP_CodeGenContext &codegen_ctx,
509  VOP_CodeVarMapperContext &varmap_context,
510  VOP_Node *vop_subnet,
511  bool require_context_check);
512 
513  /// Clean up the list obtained with getNodesForShaderVflCode() or
514  /// getNodesForSubnetFunctionVflCode()
515  void cleanupNodesForVflCode(VOP_NodeList &nodes);
516 
518  { return myNeedsAutoVopNodeCleanup; }
519 
520  /// Controls whether the source code is laced with #ifdef __vex.
521  void setUseIfdefVex(bool flag)
522  { myUseIfdefVex = flag; }
523 
524  /// Controls whether the source code contains pragmas.
525  void setOmitPragmas(bool flag)
526  { myOmitPragmas = flag; }
527 
528  /// Obtains the name of the shading context as is used in the language.
529  UT_StringHolder getShaderContextName(VOP_ContextType ctx_type)const;
530  static UT_StringHolder getShaderContextName(VOP_ContextType ctx_type,
531  VOP_LanguageType lang_type);
532 
533  /// Obtains the name of the shading context, which includes node path
534  /// prefix if it's an auto shader.
535  UT_StringHolder getShaderContextFullName(VOP_ContextType ctx_t) const;
536 
537  /// @{ Methods for marking code path related to adding and deleting
538  /// temporary nodes in auto-shader wrappers.
539  void setIsChangingAutoShader(bool flag)
540  { myIsChangingAutoShader = flag; }
542  { return myIsChangingAutoShader; }
543  /// @}
544 
545 private:
546  /// Helper for compiling code.
547  void generateObjectCode(VOP_ObjectCodeArgs *args);
548 
549  /// Returns true if there is a precompiled VEX set on this generator.
550  bool isCompiled(VOP_ContextType context_type)
551  { return myLockedCompiledCode[context_type].length() > 0; }
552 
553 
554  void outputVflHeaderComment(std::ostream &os);
555  void outputShaderDefines(std::ostream &os,
556  VOP_ContextType context_type);
557  bool outputShaderVflCodeBlock(std::ostream &os,
558  const char *shadername,
560  const VOP_CodeGenContext &codegen_ctx,
561  const char *output_node_name,
562  VCC_Diagnostics *diagnostics);
563  bool outputStandardShaderVflCodeBlock(std::ostream &os,
564  const char *shadername,
566  const VOP_CodeGenContext &codegen_ctx,
567  const char *output_node_name,
568  VCC_Diagnostics *diagnostics);
569  bool outputFunctionVflCodeBlock(std::ostream &os,
570  const char *function_name,
572  const VOP_CodeGenContext &codegen_ctx,
573  VOP_Node *subnet,
574  bool generate_outer_code);
575  bool outputMethodVflCodeBlock(
576  const vop_CodeGenOutputContext &output_ctx,
577  bool for_struct,
579  VOP_Node *method_node,
580  VCC_Diagnostics *diagnostics);
581  bool outputClassVflCodeBlock(std::ostream &os,
582  const char *shadername,
584  const VOP_CodeGenContext &codegen_ctx,
585  VCC_Diagnostics *diagnostics);
586  void outputVflPragmas(std::ostream &os,
587  const VOP_NodeList & nodes,
588  const VOP_CodeGenContext &codegen_ctx);
589  void outputVflFunctionBlock(
590  const vop_CodeGenOutputContext &output_ctx,
591  const VOP_NodeList & nodes,
592  VOP_Node *output_node,
593  VOP_CodeVarMapperContext & root_varmap_context,
594  const char *return_type,
595  const char *function_name,
597  const VOP_CodeGenContext &codegen_ctx,
598  VOP_Node *function_subnet,
599  bool generate_outer_code);
600  void outputIsConnectedDeclarations(std::ostream &os,
601  const char *indent,
602  const UT_StringArray &is_connected_list,
603  bool needs_default);
604  void outputShaderVflDeclaration(
605  const vop_CodeGenOutputContext &output_ctx,
606  const VOP_NodeList & nodes,
607  const char *return_type,
608  const char *function_name,
609  const VOP_CodeGenContext &codegen_ctx);
610  void outputClassVflDeclaration(
611  const vop_CodeGenOutputContext &output_ctx,
612  const char *shadername,
613  const VOP_CodeGenContext &codegen_ctx);
614  void outputStructVflDeclaration(
615  const vop_CodeGenOutputContext &output_ctx,
616  const char *shadername);
617  void outputFunctionVflDeclaration(
618  const vop_CodeGenOutputContext &output_ctx,
619  VOP_Node *func_node,
620  const VOP_NodeList & nodes,
621  const char *return_type,
622  const char *function_name,
623  const VOP_CodeGenContext &codegen_ctx,
624  const UT_StringArray &is_connected_list);
625  void outputVflEmptyShaderFunction(std::ostream &os,
626  const char *shadername,
627  const VOP_CodeGenContext &codegen_ctx);
628  void outputShaderParameterDeclarations(std::ostream &os,
629  const VOP_NodeList & nodes,
630  const char *indent,
631  const VOP_CodeGenContext &codegen_ctx);
632  void outputMemberVariableDeclarations(
633  const vop_CodeGenOutputContext &output_ctx);
634  void outputFunctionParameterDeclarations(std::ostream &os,
635  VOP_Node *function_subnet,
636  const VOP_NodeList & nodes,
637  const char *indent,
638  const VOP_CodeGenContext &codegen_ctx);
639 
640  /// Obtains the final shader or function name.
641  void getFunctionNameOrOverride(UT_String &function_name,
642  const char *override);
643 
644  void clearFileCache();
645 
646  /// Adds prologue and epilogue nodes to the list to complete shader code.
647  void wrapInAutoShaderIfNeeded( VOP_NodeList &nodes,
648  VOP_Node *output_node,
649  const VOP_CodeGenContext &codegen_ctx );
650 
651  /// Checks if there are any siblings subscribing to the owner.
652  bool hasSubscribingSiblings( VOP_Type shader_type ) const;
653 
654  /// Expand subnets and Fetch VOPs in the given list.
655  /// Nodes contained in the subnets and nodes pulled in from the
656  /// Fetch VOPs are inserted in the list.
657  /// @parm only_essential When expanding subnets, this method needs to
658  /// determine the 'culminating' nodes that calculate final
659  /// value of output variables. These are subnet output vop,
660  /// and exporting parameter vops and they are called essential
661  /// nodes. In the past, other nodes such as inline, print, etc
662  /// would also be considered as "culminating", but with the
663  /// advent of multi-contetxt it was nolonger clear which context
664  /// they would generate final code in. The remaining
665  /// (non-culminating) vops feed into the culminating ones, thus
666  /// providing variables necessary to calculate final variables.
667  /// This parameter serves as a switch between new
668  /// (multi-context) vops, when 'true', and backwards
669  /// compatibility (old) vops, when 'false'.
670  void expandSubnetsAndFetchVOPs(VOP_NodeList &nodes,
671  const VOP_CodeGenContext &codegen_ctx,
672  VOP_CodeVarMapperContext &root_context,
673  bool only_essential) const;
674 
675  /// Checks if the temporary files have been already created for this
676  /// context, and returns them if so. If not, it creates the files, and
677  /// then returns them. The temporary files will store the vfl code that is
678  /// passed to vcc compiler and any errors that occured during compilation.
679  /// They are means of passing the source code to the compiler.
680  void ensureTempFilesCreated(VOP_ContextType context_type,
681  UT_StringHolder &vfl_file,
682  UT_StringHolder &err_file);
683  void ensureDstDirCreated(UT_String &output_file_no_ext,
684  const char *path, const char *shaderpath,
685  const char *shadername, const char *context_suffix);
686 
687  void compileOutofProcess(VOP_ContextType context_type,
688  const char *shadername,
689  UT_WorkBuffer &code_to_cache);
690 
691  bool usesStandardVCCOptions();
692 
693  // Gets a suffix that disambiguates the files for the same function name
694  // but different context for a multi-context VOP.
695  void getContextFileSuffix( UT_String & suffix,
696  VOP_ContextType context_type );
697 
698  // Utility functions for code cache manipulation.
699  vop_CodeCacheData * findCachedCode( VOP_ContextType context_type ) const;
700  vop_CodeCacheData * addCachedCode( VOP_ContextType context_type,
701  const char * code,
702  const VCC_DiagnosticList &diagnostics);
703  void deleteCachedCode( VOP_ContextType context_type );
704  vop_CodeCacheData * removeCachedCode( VOP_ContextType context_type );
705  void addCachedCode( VOP_ContextType context_type,
706  vop_CodeCacheData * cache_data );
707  void copyCachedErrorToDiagnostic(
708  const vop_CodeCacheData * cache_data );
709  void clearCachedCode();
710 
711  /// Obtains any cached messages.
712  bool getCachedMessages(
713  UT_String &msg, bool errors_only,
714  VOP_ContextType context_type =
716 
717  /// Helper to test if a node parameter of a given index affects the
718  /// generated shader VFL code, by switching between different
719  /// Output VOP nodes.
720  bool isMetaSwitchParm(int parm_index) const;
721 
722  /// Returns true if the given VOP context is a mantra shading context.
723  bool isMantraShadingContext(
724  const VOP_CodeGenContext &codegen_ctx) const;
725 
726  void checkForErrorsOnChildren(OP_Context &cxt,
727  OP_Node *node,
728  bool force_cook);
729 
730  /// Generate VOP errors and propagate them to the owner node.
731  ///
732  /// This method is intended to generate/collect errors outside of cooking
733  /// (i.e. compilation errors) so it recreates the dirty-update-notify
734  /// process that is typically done for cooking.
735  void generateErrorsAndPropagateToOwner();
736 
737  /// Keeps code and other data relevant to the code generation and reuse.
738  OP_Network *myOwner;
740  myContextTypeList;
741  const VOP_Language *myLanguage;
742  UT_SharedPtr<VCC_Diagnostics> myDiagnostics;
743  UT_UniquePtr<VCC_Compiler> myVflCompiler;
744  TContextTypeStringMap myLockedCompiledCode;
745  TContextTypeStringMap myLockedSourceCode;
746  VOP_GlobalVarMap myGlobalVariables;
747  VOP_ParmGeneratorMap myLocalVariables;
748  VOP_LocalChannelMap myLocalChannels;
749  VOP_CodeOperatorFilter myOperatorFilter;
750  VOP_CodeCompilerArgs *myCompilerArgs;
751  UT_ErrorManager myErrorManager;
752 
753  mutable UT_Lock myCachedCodeLock;
754  UT_ValArray<vop_CodeCacheData*> myCachedCode;
755  UT_SymbolMap<UT_StringHolder> myTempVflFiles;
756  UT_SymbolMap<UT_StringHolder> myTempErrFiles;
757  UT_String myHipName;
758  UT_String myCachedEnglishName;
759  int myMinimumNumberOfInputs;
760  int myMaximumNumberOfInputs;
761 
762  mutable int myCollectNodeId;
763  int myUpdateLevel;
764  bool myNeedsCodeUpdate;
765 
766  bool myOwnerHasParameters;
767  bool myIsReCookingOwner;
768  bool myNeedsAutoVopNodeCleanup;
769 
770  bool myUseIfdefVex;
771  bool myOmitPragmas;
772  bool myIsAutoGenerator;
773  bool myIsChangingAutoShader;
774 
775  /// Micro node representing VOP errors.
776  VOP_ErrorMicroNode myErrorMicroNode;
777 
778  /// Tracks if our snippet has changed.
779  VOP_SnippetMicroNode mySnippetMicroNode;
780 
781  /// Micro node which we invoke propagateDirty() on every
782  /// time we are invalidated.
783  DEP_MicroNode myCodeUpdatedMicroNode;
784 
785  /// If the owner network defines a VOP type (eg, a vop struct),
786  /// this member will channel such a definition to the VOP type manager.
788  myVopTypeDefiner;
789 
790  /// Manager of the exported parameters.
791  VOP_ExportedParmsManager *myExportedParmsMgr;
792 };
793 
794 /// ===========================================================================
795 /// This class VOP errors in the code generator and stores them
796 /// in the owner node.
797 /// The class should only be instantiated when the owner node is cooked
798 /// since its destructor can be expensive (i.e. generateVopErrors() is called).
800 {
801 public:
803  : myNode(node)
804  {
805  }
806 
808  {
809  // Get the code generator.
810  VOP_CodeGenerator *code_gen = myNode.getVopCodeGenerator();
811  if (!code_gen)
812  return;
813 
814  // Generate VOP errors in the code generator.
815  code_gen->generateVopErrors();
816 
817  // Now steal the errors from the code generator
818  // and transfer them to the owner node.
819  myNode.stealErrors(code_gen->getErrorManager(), true);
820  }
821 
822 private:
823  OP_Node &myNode;
824 };
825 
826 /// ===========================================================================
827 /// Class containing info about a scope level at which to generate/compile
828 /// the nested shaders. Usually they use global level, implying that they use
829 /// full node path as shader function name. But when compiling HDAs, the
830 /// shaders nested inside them are anchored to the HDA and should use
831 /// relative path as shader function name.
832 /// Also, this class can store all the nested shaders that need own compilation.
834 {
835 public:
836  VOP_ShaderSpaceInfo( VOP_Node *shader_node,
837  const char *shader_name );
838 
840  { return myNestedSubnetShaders; }
841  void addSubShader(VOP_Node *sub_shader, const char *name) const
842  { myNestedSubnetShaders[sub_shader] = name; }
843 
844  /// Returns true if the node generates code that should be isolated
845  /// to the space.
846  bool shouldAddSubShader(VOP_Node *shader_node) const;
847 
848  /// Replaces the scene-specific prefix with an hda-specific one.
849  void replaceSubShaderNamePrefix( UT_String &sub_shader_name,
850  VOP_Node *sub_shader ) const;
851 
852  /// Removes the hda-specific prefix.
853  void removeShaderNamePrefix( UT_String &sub_shader_name ) const;
854 
855 private:
856  // Main parent shader HDA that contains the space for sub-shaders.
857  VOP_Node * myShaderNode;
858  UT_StringHolder myShaderName;
859 
860  // A list of nested shader nodes that are subnets and that generate code
861  // from children. They need to be explicitly saved into own sections when
862  // the main (outer parent) shader HDA has "save cached code" turned on.
863  // The map is from node to the shader function name it used
864  // when generating a shader call in the main shader
865  mutable UT_Map<VOP_Node*, UT_StringHolder> myNestedSubnetShaders;
866 };
867 
868 /// ===========================================================================
869 /// A container for requesting generation of code that computes optional
870 /// variables. Some nodes downstream may express an interest in a variable
871 /// value that is not computed by default, and this is a mechanism to pass
872 /// requests for such values to the nodes upstream (which generate code first).
873 /// Eg, shader nodes may not include hidden exports in the shader function call,
874 /// unless explictly requested.
876 {
877 public:
878  /// Registers a request for a given vop to generate code for the
879  /// otherwise optional variable var.
880  void requestVarFrom(VOP_Node &vop, const VOP_FunctionArgInfo &var);
881 
882  /// Obtains a list of variables requested from given vop.
883  const UT_Array<VOP_FunctionArgInfo> *getRequestedVars(VOP_Node &vop) const;
884 
885 private:
887 };
888 
889 /// ===========================================================================
890 /// Utility class for automatically adding auto-code-generator to a node.
891 /// Adding generator is a two-step process, requiring calling generator's
892 /// two methods, one before node is added and one after it is added to parent.
894 {
895 public:
898 
899 private:
900  VOP_Node * myVop;
901 };
902 
903 
904 #endif
Reprsents a language for which VOPs can generate source code.
Definition: VOP_Language.h:29
static PRM_Name theVopCompilerName
UT_ErrorManager & getErrorManager()
GLbitfield flags
Definition: glcorearb.h:1596
OP_Network * ownerNetwork() const
GT_API const UT_StringHolder filename
void addSubShader(VOP_Node *sub_shader, const char *name) const
virtual void becameDirty(DEP_MicroNode &src, const DEP_PropagateData &propdata)
static PRM_Default theVopCompilerOslDefault
bool isVexCodeCached(VOP_ContextType context_type) const
Determines if the giving context has already been cached.
void setOmitPragmas(bool flag)
Controls whether the source code contains pragmas.
void addExplicitInput(DEP_MicroNode &inp, bool check_dup)
Methods for manipulating explicit edges.
bool needsAutoVopNodeCleanup() const
const UT_Map< VOP_Node *, UT_StringHolder > & getNestedSubnetShaders() const
bool isAutoGenerator() const
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
bool getOwnerHasParameters() const
void setIsAutoGenerator(bool is_auto)
const char * className() const override
static PRM_Name theVopForceCompileName
std::map< VOP_ContextType, std::string > TContextTypeStringMap
void setUseIfdefVex(bool flag)
Controls whether the source code is laced with #ifdef __vex.
int VOP_ContextType
Definition: VOP_Types.h:177
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
static PRM_ChoiceList theVopCompilerChoices
static PRM_Default theVopCompilerRslDefault
#define VOP_API
Definition: VOP_API.h:10
VOP_CodeGenerator & myCodeGenerator
VOP_ExportedParmsManager * exportedParmsManager() const
Return the exported parameters manager.
std::shared_ptr< T > UT_SharedPtr
Wrapper around std::shared_ptr.
Definition: UT_SharedPtr.h:36
void stealErrors(UT_ErrorManager &src, bool borrow_only=false)
#define VOP_CONTEXT_TYPE_INVALID
Definition: VOP_Types.h:178
const VOP_Language * getLanguage() const
Get the VOP language generated by this code generator.
VOP_ErrorMicroNode & errorMicroNode()
GLenum target
Definition: glcorearb.h:1667
GLuint const GLchar * name
Definition: glcorearb.h:786
UT_Array< VCC_DiagnosticInfo > VCC_DiagnosticList
OSL_ContextType
RenderMan shader context types.
Definition: VEX_OslTypes.h:25
Class that contains information about a struct/class method.
virtual bool allowOperatorAsChild(OP_Operator *op)
Definition: OP_Network.h:114
void addCodeDependency(DEP_MicroNode *target)
const VOP_LanguageContextTypeList * getLanguageContextTypeList() const
VEX_CodeGenFlags
VEX code generation flags when calling VEX_VexResolver::getVflCode.
Definition: VEX_VexTypes.h:138
fpreal64 fpreal
Definition: SYS_Types.h:277
GLuint index
Definition: glcorearb.h:786
VOP_CodeCompilerArgs * getCompilerArgs()
Returns the compiler arguments.
OP_EventType
Definition: OP_Value.h:22
A global error manager scope.
VOP_Type
Enumeration of the built-in (basic) VOP data types.
Definition: VOP_Types.h:25
Propagation info for a dep micro node.
Definition: DEP_MicroNode.h:36
**If you just want to fire and args
Definition: thread.h:609
VOP_CodeGeneratorErrorThief(OP_Node &node)
Definition: core.h:1131
RSL_ContextType
RenderMan shader context types.
Definition: VEX_RslTypes.h:25
void generateVopErrors()
GLsizei GLenum GLenum * types
Definition: glcorearb.h:2542
virtual VOP_CodeGenerator * getVopCodeGenerator()
Definition: OP_Node.h:2697
VEX_ContextType
Definition: VEX_VexTypes.h:60
bool getIsChangingAutoShader() const
static PRM_Default theVopCompilerVexDefault
void setIsChangingAutoShader(bool flag)
VOP_LanguageType
Definition: VOP_Types.h:186
Definition: format.h:895
GLenum src
Definition: glcorearb.h:1793