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  /// On the given micronode, add an extra input to our code micro
250  /// node so it gets reset everytime we are dirtied.
252  {
253  if (target) target->addExplicitInput(myCodeUpdatedMicroNode);
254  }
255 
256  /// Return the time stamp from when VEX code was last generated or -1
257  /// if no cached code exists
258  int getCachedCodeTimeStamp(
259  VOP_ContextType context_type) const;
260  /// Return true if this code generator has any cached code.
261  bool hasCachedCode() const;
262 
263  void generateRslObject(UT_String &ofile,
264  const char *cache_directory,
265  const char *renderer,
266  int major_version,
267  int minor_version,
268  const char *shaderpath,
269  const char *shadername,
270  VOP_ContextType context_type,
271  bool ignore_dirty_flag,
272  UT_String *error_return);
273 
274  void generateOslObject(UT_String &ofile,
275  const char *cache_directory,
276  const char *shaderpath,
277  const char *shadername,
278  VOP_ContextType context_type,
279  bool ignore_dirty_flag,
280  UT_String *error_return);
281 
282  // Get a list of infos about the class member methods.
283  void getClassMethodInfos(
285 
286  // Returns parm nodes that define shader class parameters.
287  void getClassShaderParameterNodes(VOP_NodeList &parms);
288 
289  // Returns owner's output nodes and the shader type they're contributing.
290  void getOutputNodes(VOP_NodeList &outputs,
291  VOP_ShaderTypeList *types = nullptr) const;
292 
293  /// Return the collection VOP (or NULL if there is no collection)
294  VOP_Collect *getCollectNode() const;
295 
296  /// Return the code generating encapsulated shader for the given context
297  /// (or NULL).
298  VOP_Node *getEncapsulatedShader(VOP_ContextType context) const;
299 
300  // Expand the compiler & options using local variables.
301  const char *getCompiler(UT_String &compiler, fpreal now,
302  const char *defcompiler);
303  const char *getCompiler(UT_WorkBuffer &wbuf, fpreal now,
304  const char *defcompiler);
305 
306  /// @{ Get a string containing the errors or warnings from our last vex
307  /// code generation (including source code generation and compilation).
308  /// Returns true if there were any errors.
309  bool getGeneratorErrors(UT_String &errors) const;
310  bool getGeneratorErrors(UT_String &errors,
311  VOP_ContextType context_type) const;
312  bool getGeneratorErrorsAndWarnings(UT_String &msgs) const;
313  bool getGeneratorErrorsAndWarnings(UT_String &msgs,
314  VOP_ContextType context_type) const;
315 
316  bool getDiagnosticsForNode(VOP_Node *node,
317  VCC_DiagnosticList &list) const;
318  /// @}
319 
320  /// Get the VOP language generated by this code generator.
321  const VOP_Language *getLanguage() const
322  { return myLanguage; }
323 
324  /// Get the object representing the list of shader contexts (surface,
325  /// displacement, etc) supported by this generator. The returned object
326  /// also describes the language type supported by this generator.
328  { return myContextTypeList; }
329 
330  /// Returs a language for which this generator produces code.
331  VOP_LanguageType getLanguageType() const;
332 
333 
334  /// @{ An automatic code generator is created by default for a VOP,
335  /// when a VOP is created in a Shader Network container.
336  /// The automatic generator provides a code for a temporary shader
337  /// consisting of that VOP and any of its input chains.
338  void setIsAutoGenerator(bool is_auto)
339  { myIsAutoGenerator = is_auto; }
340  bool isAutoGenerator() const
341  { return myIsAutoGenerator; }
342  /// @}
343 
344  /// Returns true if the generator should generate temporary, automatic,
345  /// adhoc shader for the owner node, when that node is assigned as a shader.
346  /// Such code is needed for VOPs directly inside a Shader Network container,
347  /// when they are not true shaders themselves, or when a connected input
348  /// implies a composite shder generation.
349  /// In other cases (eg an unconnected VOP that represents an external
350  /// shader, or a RIS shader), there is no need for temp shader code gen.
351  bool needsToGenerateAutoShader() const;
352 
353  /// Returns true if it is a single-context vopnet that this generator
354  /// produces code for. Otherwise (ie, multi-context) returns false.
355  bool isSingleContextType() const;
356 
357  /// Returns true if this generator produces a class-based shader.
358  bool isClassBasedShader() const;
359 
360  /// Returns true if the given shader type is class-based.
361  bool isClassBasedShader(
362  const VOP_CodeGenContext &codegen_ctx) const;
363 
364  /// Returns a list of vopnet type masks for a given context list.
365  void getVopnetTypes(const VOP_ContextTypeList &ctxts,
366  UT_StringArray &vopnet_types);
367 
368  /// Returns true if the owner of the code generator displays parameters.
369  /// This is currently true for VOPNET_Nodes.
371  { return myOwnerHasParameters; }
372 
373  /// Determine the VOP context type for single-context type vopnet generator.
374  /// For generator of a multi-context vopnet returns
375  /// VOP_CONTEXT_TYPE_INVALID, because the specific VOP context cannot be
376  /// reliably and unambiguously determined.
377  VOP_ContextType getVopContextType() const;
378 
379  /// Determine the VEX context type for single-context type vopnet generator.
380  /// For generator of a multi-context vopnet (or for RSL vopnet) returns
381  /// VEX_INVALID_CONTEXT, because the specific VEX context cannot be
382  /// reliably and unambiguously determined.
383  VEX_ContextType getVexContextType() const;
384  RSL_ContextType getRslContextType() const;
385  OSL_ContextType getOslContextType() const;
386 
387  /// Returns the compiler arguments.
389  { return myCompilerArgs; }
390 
391  /// Set the locked compiled code. When set, the locked code causes the
392  /// code generator to ignore the VOP nodes in the owner network and always
393  /// return the locked value.
394  void setLockedCompiledCode(
395  const char *code, VOP_ContextType context_type,
396  bool is_source_code);
397 
398  /// Utility function to get a code generator corresponding to the node.
399  /// Returns own code generator if it exists, or creator's code generator.
400  static VOP_CodeGenerator *findCodeGenerator( const OP_Node *node );
401 
402  // The local variables that must be defined by any code generator node.
403  // These are the variables understood by the getVariableString function
404  static CH_LocalVariable theLocalVariables[];
405 
406  // Install commands specific to VOP code generators.
407  static void installCommands();
408 
409  // This function converts a local VOP code generator to a global VOP code
410  // generator that defines an operator type.
411  static bool convertVopOpToVopOpType(OP_Node *node,
412  UT_String &err);
413 
414  /// Returns the default VOP mask for VEX.
415  static const char *getDefaultVEXMask();
416 
417  // These variables define the parameter descriptions for the VOP
418  // compiler parm used to specify how to compile VOP generated code.
425 
426  static bool forceCompile(OP_Node *node);
427  static int forceCompile(void *data, int, fpreal,
428  const PRM_Template *);
429 
430  /// Determines the vex context. In single-context vop, returns a vex type
431  /// intrinsic to that vop. In multi-context vop, returns the vex type based
432  /// on context_type passed as an argument.
433  VEX_ContextType pickVexContextType(VOP_ContextType context_type) const;
434  RSL_ContextType pickRslContextType(VOP_ContextType context_type) const;
435  OSL_ContextType pickOslContextType(VOP_ContextType context_type) const;
436 
437  /// Determines the vop context (ie encode vex or rsl context type).
438  /// In single-context vop, returns a vex/rsl context type (encoded as vop
439  /// type) intrinsic to that vop. In multi-context vop, returns the vop
440  /// type based passed as an argument.
441  VOP_ContextType pickContextType(VOP_ContextType context_type) const;
442 
443  // Locates a procedural shader by searching the VOP network an output node
444  // of type "interpret_type" and tracing back to the first non-simple node.
445  VOP_Node *getProcedural(VOP_Type interpret_type) const;
446 
447  /// Obtains the export variables that don't have explicit output connectors.
448  void getVopFunctionArgInfosFromExports(
449  UT_Array<VOP_FunctionArgInfo> &arg_infos,
450  VOP_Type shader_type );
451 
452  /// Gathers all the rendering properties nodes.
453  void getPropertiesNodes(VOP_NodeList &properties);
454 
456  { return myOwner; }
457 
458  /// Return the micro-node representing the error state. The micro-node will
459  /// signal if we transition from clean -> error, error -> error, and
460  /// error -> clean.
462  { return myErrorMicroNode; }
463 
464  static void formatDiagnostic(const VCC_DiagnosticInfo &info,
465  UT_WorkBuffer &str);
466 
467  /// Get a list of all vop nodes participating in the shader. The list
468  /// is sorted according to order in which the vfl code should be generated.
469  /// If 'check_errors' is true, node error checking is performed and if
470  /// any error is encountered, the method will return false (and the node
471  /// list may be incomplete). If this argument is false, the method
472  /// does not check errors and always returns true and the list
473  /// of nodes is complete.
474  /// NB: when nodes a no longer needed, use cleanupNodesForShaderOutput()
475  /// to clean up the list of temporary nodes this method may create.
476  bool getNodesForContextOrNodeFunctionVflCode(
477  VOP_NodeList &nodes,
478  VOP_Node *&output_node,
479  const VOP_CodeGenContext &codegen_ctx,
480  VOP_CodeVarMapperContext &varmap_context,
481  const char *output_node_name,
482  bool check_errors,
483  VCC_Diagnostics *diagnostics);
484 
485  /// Get a list of all vop nodes participating in the function code
486  /// defined by a vop subnet. The list is sorted according to order in
487  /// which the vfl code should be generated.
488  /// NB: when nodes a no longer needed, use cleanupNodesForShaderOutput()
489  /// to clean up the list of temporary nodes this method may create.
490  bool getNodesForSubnetFunctionVflCode(VOP_NodeList &nodes,
491  const VOP_CodeGenContext &codegen_ctx,
492  VOP_CodeVarMapperContext &varmap_context,
493  VOP_Node *vop_subnet,
494  bool require_context_check);
495 
496  /// Clean up the list obtained with getNodesForShaderVflCode() or
497  /// getNodesForSubnetFunctionVflCode()
498  void cleanupNodesForVflCode(VOP_NodeList &nodes);
499 
501  { return myNeedAutoConvertCleanup; }
502 
503  /// Controls whether the source code is laced with #ifdef __vex.
504  void setUseIfdefVex(bool flag)
505  { myUseIfdefVex = flag; }
506 
507  /// Controls whether the source code contains pragmas.
508  void setOmitPragmas(bool flag)
509  { myOmitPragmas = flag; }
510 
511  /// Obtains the name of the shading context as is used in the language.
512  UT_StringHolder getShaderContextName(VOP_ContextType ctx_type)const;
513  static UT_StringHolder getShaderContextName(VOP_ContextType ctx_type,
514  VOP_LanguageType lang_type);
515 
516  /// Obtains the name of the shading context, which includes node path
517  /// prefix if it's an auto shader.
518  UT_StringHolder getShaderContextFullName(VOP_ContextType ctx_t) const;
519 
520  /// @{ Methods for marking code path related to adding and deleting
521  /// temporary nodes in auto-shader wrappers.
523  { myIsChangingAutoShader = flag; }
525  { return myIsChangingAutoShader; }
526  /// @}
527 
528 private:
529  /// Helper for compiling code.
530  void generateObjectCode(VOP_ObjectCodeArgs *args);
531 
532  /// Returns true if there is a precompiled VEX set on this generator.
533  bool isCompiled(VOP_ContextType context_type)
534  { return myLockedCompiledCode[context_type].length() > 0; }
535 
536 
537  void outputVflHeaderComment(std::ostream &os);
538  void outputShaderDefines(std::ostream &os,
539  VOP_ContextType context_type);
540  bool outputShaderVflCodeBlock(std::ostream &os,
541  const char *shadername,
543  const VOP_CodeGenContext &codegen_ctx,
544  const char *output_node_name,
545  VCC_Diagnostics *diagnostics);
546  bool outputStandardShaderVflCodeBlock(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 outputFunctionVflCodeBlock(std::ostream &os,
553  const char *function_name,
555  const VOP_CodeGenContext &codegen_ctx,
556  VOP_Node *subnet,
557  bool generate_outer_code);
558  bool outputMethodVflCodeBlock(
559  const vop_CodeGenOutputContext &output_ctx,
560  bool for_struct,
562  VOP_Node *method_node,
563  VCC_Diagnostics *diagnostics);
564  bool outputClassVflCodeBlock(std::ostream &os,
565  const char *shadername,
567  const VOP_CodeGenContext &codegen_ctx,
568  VCC_Diagnostics *diagnostics);
569  void outputVflPragmas(std::ostream &os,
570  const VOP_NodeList & nodes,
571  const VOP_CodeGenContext &codegen_ctx);
572  void outputVflFunctionBlock(
573  const vop_CodeGenOutputContext &output_ctx,
574  const VOP_NodeList & nodes,
575  VOP_Node *output_node,
576  VOP_CodeVarMapperContext & root_varmap_context,
577  const char *return_type,
578  const char *function_name,
580  const VOP_CodeGenContext &codegen_ctx,
581  VOP_Node *function_subnet,
582  bool generate_outer_code);
583  void outputIsConnectedDeclarations(std::ostream &os,
584  const char *indent,
585  const UT_StringArray &is_connected_list,
586  bool needs_default);
587  void outputShaderVflDeclaration(
588  const vop_CodeGenOutputContext &output_ctx,
589  const VOP_NodeList & nodes,
590  const char *return_type,
591  const char *function_name,
592  const VOP_CodeGenContext &codegen_ctx);
593  void outputClassVflDeclaration(
594  const vop_CodeGenOutputContext &output_ctx,
595  const char *shadername,
596  const VOP_CodeGenContext &codegen_ctx);
597  void outputStructVflDeclaration(
598  const vop_CodeGenOutputContext &output_ctx,
599  const char *shadername);
600  void outputFunctionVflDeclaration(
601  const vop_CodeGenOutputContext &output_ctx,
602  VOP_Node *func_node,
603  const VOP_NodeList & nodes,
604  const char *return_type,
605  const char *function_name,
606  const VOP_CodeGenContext &codegen_ctx,
607  const UT_StringArray &is_connected_list);
608  void outputVflEmptyShaderFunction(std::ostream &os,
609  const char *shadername,
610  const VOP_CodeGenContext &codegen_ctx);
611  void outputShaderParameterDeclarations(std::ostream &os,
612  const VOP_NodeList & nodes,
613  const char *indent,
614  const VOP_CodeGenContext &codegen_ctx);
615  void outputMemberVariableDeclarations(
616  const vop_CodeGenOutputContext &output_ctx);
617  void outputFunctionParameterDeclarations(std::ostream &os,
618  VOP_Node *function_subnet,
619  const VOP_NodeList & nodes,
620  const char *indent,
621  const VOP_CodeGenContext &codegen_ctx);
622 
623  /// Obtains the final shader or function name.
624  void getFunctionNameOrOverride(UT_String &function_name,
625  const char *override);
626 
627  void clearFileCache();
628 
629  /// Adds prologue and epilogue nodes to the list to complete shader code.
630  void wrapInAutoShaderIfNeeded( VOP_NodeList &nodes,
631  VOP_Node *output_node,
632  const VOP_CodeGenContext &codegen_ctx );
633 
634  /// Checks if there are any siblings subscribing to the owner.
635  bool hasSubscribingSiblings( VOP_Type shader_type ) const;
636 
637  /// Expand subnets and Fetch VOPs in the given list.
638  /// Nodes contained in the subnets and nodes pulled in from the
639  /// Fetch VOPs are inserted in the list.
640  /// @parm only_essential When expanding subnets, this method needs to
641  /// determine the 'culminating' nodes that calculate final
642  /// value of output variables. These are subnet output vop,
643  /// and exporting parameter vops and they are called essential
644  /// nodes. In the past, other nodes such as inline, print, etc
645  /// would also be considered as "culminating", but with the
646  /// advent of multi-contetxt it was nolonger clear which context
647  /// they would generate final code in. The remaining
648  /// (non-culminating) vops feed into the culminating ones, thus
649  /// providing variables necessary to calculate final variables.
650  /// This parameter serves as a switch between new
651  /// (multi-context) vops, when 'true', and backwards
652  /// compatibility (old) vops, when 'false'.
653  void expandSubnetsAndFetchVOPs(VOP_NodeList &nodes,
654  const VOP_CodeGenContext &codegen_ctx,
655  VOP_CodeVarMapperContext &root_context,
656  bool only_essential) const;
657 
658  /// Checks if the temporary files have been already created for this
659  /// context, and returns them if so. If not, it creates the files, and
660  /// then returns them. The temporary files will store the vfl code that is
661  /// passed to vcc compiler and any errors that occured during compilation.
662  /// They are means of passing the source code to the compiler.
663  void ensureTempFilesCreated(VOP_ContextType context_type,
664  UT_StringHolder &vfl_file,
665  UT_StringHolder &err_file);
666  void ensureDstDirCreated(UT_String &output_file_no_ext,
667  const char *path, const char *shaderpath,
668  const char *shadername, const char *context_suffix);
669 
670  void compileOutofProcess(VOP_ContextType context_type,
671  const char *shadername,
672  UT_WorkBuffer &code_to_cache);
673 
674  bool usesStandardVCCOptions();
675 
676  // Gets a suffix that disambiguates the files for the same function name
677  // but different context for a multi-context VOP.
678  void getContextFileSuffix( UT_String & suffix,
679  VOP_ContextType context_type );
680 
681  // Utility functions for code cache manipulation.
682  vop_CodeCacheData * findCachedCode( VOP_ContextType context_type ) const;
683  vop_CodeCacheData * addCachedCode( VOP_ContextType context_type,
684  const char * code,
685  const VCC_DiagnosticList &diagnostics);
686  void deleteCachedCode( VOP_ContextType context_type );
687  vop_CodeCacheData * removeCachedCode( VOP_ContextType context_type );
688  void addCachedCode( VOP_ContextType context_type,
689  vop_CodeCacheData * cache_data );
690  void copyCachedErrorToDiagnostic(
691  const vop_CodeCacheData * cache_data );
692  void clearCachedCode();
693 
694  /// Obtains any cached messages.
695  bool getCachedMessages(
696  UT_String &msg, bool errors_only,
697  VOP_ContextType context_type =
699 
700  /// Helper to test if a node parameter of a given index affects the
701  /// generated shader VFL code, by switching between different
702  /// Output VOP nodes.
703  bool isMetaSwitchParm(int parm_index) const;
704 
705  /// Returns true if the given VOP context is a mantra shading context.
706  bool isMantraShadingContext(
707  const VOP_CodeGenContext &codegen_ctx) const;
708 
709  void checkForErrorsOnChildren(OP_Context &cxt,
710  OP_Node *node,
711  bool force_cook);
712 
713  /// Generate VOP errors and propagate them to the owner node.
714  ///
715  /// This method is intended to generate/collect errors outside of cooking
716  /// (i.e. compilation errors) so it recreates the dirty-update-notify
717  /// process that is typically done for cooking.
718  void generateErrorsAndPropagateToOwner();
719 
720  /// Keeps code and other data relevant to the code generation and reuse.
721  OP_Network *myOwner;
722  VOP_LanguageContextTypeList *myContextTypeList;
723  VOP_Language *myLanguage;
724  UT_SharedPtr<VCC_Diagnostics> myDiagnostics;
725  UT_UniquePtr<VCC_Compiler> myVflCompiler;
726  TContextTypeStringMap myLockedCompiledCode;
727  TContextTypeStringMap myLockedSourceCode;
728  VOP_GlobalVarMap myGlobalVariables;
729  VOP_ParmGeneratorMap myLocalVariables;
730  VOP_LocalChannelMap myLocalChannels;
731  VOP_CodeOperatorFilter myOperatorFilter;
732  VOP_CodeCompilerArgs *myCompilerArgs;
733  UT_ErrorManager myErrorManager;
734 
735  mutable UT_Lock myCachedCodeLock;
736  UT_ValArray<vop_CodeCacheData*> myCachedCode;
737  UT_SymbolMap<UT_StringHolder> myTempVflFiles;
738  UT_SymbolMap<UT_StringHolder> myTempErrFiles;
739  UT_String myHipName;
740  UT_String myCachedEnglishName;
741  int myMinimumNumberOfInputs;
742  int myMaximumNumberOfInputs;
743 
744  mutable int myCollectNodeId;
745  int myUpdateLevel;
746  bool myNeedsCodeUpdate;
747 
748  bool myOwnerHasParameters;
749  bool myIsReCookingOwner;
750  bool myNeedAutoConvertCleanup;
751 
752  bool myUseIfdefVex;
753  bool myOmitPragmas;
754  bool myIsAutoGenerator;
755  bool myIsChangingAutoShader;
756 
757  /// Micro node representing VOP errors.
758  VOP_ErrorMicroNode myErrorMicroNode;
759 
760  /// Tracks if our snippet has changed.
761  VOP_SnippetMicroNode mySnippetMicroNode;
762 
763  /// Micro node which we invoke propagateDirty() on every
764  /// time we are invalidated.
765  DEP_MicroNode myCodeUpdatedMicroNode;
766 
767  /// If the owner network defines a VOP type (eg, a vop struct),
768  /// this member will channel such a definition to the VOP type manager.
769  VOP_VopTypeDefiner * myVopTypeDefiner;
770 
771  /// Manager of the exported parameters.
772  VOP_ExportedParmsManager *myExportedParmsMgr;
773 };
774 
775 /// ===========================================================================
776 /// This class VOP errors in the code generator and stores them
777 /// in the owner node.
778 /// The class should only be instantiated when the owner node is cooked
779 /// since its destructor can be expensive (i.e. generateVopErrors() is called).
781 {
782 public:
784  : myNode(node)
785  {
786  }
787 
789  {
790  // Get the code generator.
791  VOP_CodeGenerator *code_gen = myNode.getVopCodeGenerator();
792  if (!code_gen)
793  return;
794 
795  // Generate VOP errors in the code generator.
796  code_gen->generateVopErrors();
797 
798  // Now steal the errors from the code generator
799  // and transfer them to the owner node.
800  myNode.stealErrors(code_gen->getErrorManager(), true);
801  }
802 
803 private:
804  OP_Node &myNode;
805 };
806 
807 /// ===========================================================================
808 /// Class containing info about a scope level at which to generate/compile
809 /// the nested shaders. Usually they use global level, implying that they use
810 /// full node path as shader function name. But when compiling HDAs, the
811 /// shaders nested inside them are anchored to the HDA and should use
812 /// relative path as shader function name.
813 /// Also, this class can store all the nested shaders that need own compilation.
815 {
816 public:
817  VOP_ShaderSpaceInfo( VOP_Node *shader_node,
818  const char *shader_name );
819 
821  { return myNestedSubnetShaders; }
822  void addSubShader(VOP_Node *sub_shader, const char *name) const
823  { myNestedSubnetShaders[sub_shader] = name; }
824 
825  /// Returns true if the node generates code that should be isolated
826  /// to the space.
827  bool shouldAddSubShader(VOP_Node *shader_node) const;
828 
829  /// Replaces the scene-specific prefix with an hda-specific one.
830  void replaceSubShaderNamePrefix( UT_String &sub_shader_name,
831  VOP_Node *sub_shader ) const;
832 
833  /// Removes the hda-specific prefix.
834  void removeShaderNamePrefix( UT_String &sub_shader_name ) const;
835 
836 private:
837  // Main parent shader HDA that contains the space for sub-shaders.
838  VOP_Node * myShaderNode;
839  UT_StringHolder myShaderName;
840 
841  // A list of nested shader nodes that are subnets and that generate code
842  // from children. They need to be explicitly saved into own sections when
843  // the main (outer parent) shader HDA has "save cached code" turned on.
844  // The map is from node to the shader function name it used
845  // when generating a shader call in the main shader
846  mutable UT_Map<VOP_Node*, UT_StringHolder> myNestedSubnetShaders;
847 };
848 
849 /// ===========================================================================
850 /// A container for requesting generation of code that computes optional
851 /// variables. Some nodes downstream may express an interest in a variable
852 /// value that is not computed by default, and this is a mechanism to pass
853 /// requests for such values to the nodes upstream (which generate code first).
854 /// Eg, shader nodes may not include hidden exports in the shader function call,
855 /// unless explictly requested.
857 {
858 public:
859  /// Registers a request for a given vop to generate code for the
860  /// otherwise optional variable var.
861  void requestVarFrom(VOP_Node &vop, const VOP_FunctionArgInfo &var);
862 
863  /// Obtains a list of variables requested from given vop.
864  const UT_Array<VOP_FunctionArgInfo> *getRequestedVars(VOP_Node &vop) const;
865 
866 private:
868 };
869 
870 /// ===========================================================================
871 /// Utility class for automatically adding auto-code-generator to a node.
872 /// Adding generator is a two-step process, requiring calling generator's
873 /// two methods, one before node is added and one after it is added to parent.
875 {
876 public:
879 
880 private:
881  VOP_Node * myVop;
882 };
883 
884 
885 #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
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.
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)
GLbitfield flags
Definition: glcorearb.h:1595
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
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)
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()
GLenum target
Definition: glcorearb.h:1666
GLboolean * data
Definition: glcorearb.h:130
GLuint const GLchar * name
Definition: glcorearb.h:785
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.
void addCodeDependency(DEP_MicroNode *target)
GLsizei const GLfloat * value
Definition: glcorearb.h:823
double fpreal
Definition: SYS_Types.h:270
const VOP_LanguageContextTypeList * getLanguageContextTypeList() const
VEX_CodeGenFlags
VEX code generation flags when calling VEX_VexResolver::getVflCode.
Definition: VEX_VexTypes.h:137
GLuint index
Definition: glcorearb.h:785
VOP_CodeCompilerArgs * getCompilerArgs()
Returns the compiler arguments.
virtual bool allowOperatorAsChild(OP_Operator *)
Definition: OP_Network.h:111
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:35
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:2581
VEX_ContextType
Definition: VEX_VexTypes.h:60
png_infop png_uint_32 flag
Definition: png.h:2242
bool getIsChangingAutoShader() const
static PRM_Default theVopCompilerVexDefault
void setIsChangingAutoShader(bool flag)
virtual const char * className() const
VOP_LanguageType
Definition: VOP_Types.h:158
GLenum src
Definition: glcorearb.h:1792