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