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