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