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