HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GenContext.h
Go to the documentation of this file.
1 //
2 // Copyright Contributors to the MaterialX Project
3 // SPDX-License-Identifier: Apache-2.0
4 //
5 
6 #ifndef MATERIALX_GENCONTEXT_H
7 #define MATERIALX_GENCONTEXT_H
8 
9 /// @file
10 /// Context classes for shader generation
11 
13 
17 
18 #include <MaterialXFormat/File.h>
19 
21 
22 class ClosureContext;
23 
24 /// A standard function to allow for handling of application variables for a given node
25 using ApplicationVariableHandler = std::function<void(ShaderNode*, GenContext&)>;
26 
27 /// @class GenContext
28 /// A context class for shader generation.
29 /// Used for thread local storage of data needed during shader generation.
31 {
32  public:
33  /// Constructor.
35 
36  /// Return shader generatior.
38  {
39  return *_sg;
40  }
41 
42  /// Return shader generation options.
44  {
45  return _options;
46  }
47 
48  /// Return shader generation options.
49  const GenOptions& getOptions() const
50  {
51  return _options;
52  }
53 
54  /// Register a user search path for finding source code during
55  /// code generation.
57  {
58  _sourceCodeSearchPath.append(path);
59  }
60 
61  /// Register a user search path for finding source code during
62  /// code generation.
64  {
65  _sourceCodeSearchPath.append(path);
66  }
67 
68  /// Resolve a source code filename, first checking the given local path
69  /// then checking any file paths registered by the user.
70  FilePath resolveSourceFile(const FilePath& filename, const FilePath& localPath) const
71  {
72  FileSearchPath searchPath = _sourceCodeSearchPath;
73  if (!localPath.isEmpty())
74  {
75  searchPath.prepend(localPath);
76  }
77  return searchPath.find(filename).getNormalized();
78  }
79 
80  /// Add reserved words that should not be used as
81  /// identifiers during code generation.
82  void addReservedWords(const StringSet& names)
83  {
84  _reservedWords.insert(names.begin(), names.end());
85  }
86 
87  /// Return the set of reserved words that should not be used
88  /// as identifiers during code generation.
89  const StringSet& getReservedWords() const
90  {
91  return _reservedWords;
92  }
93 
94  /// Cache a shader node implementation.
95  void addNodeImplementation(const string& name, ShaderNodeImplPtr impl);
96 
97  /// Find and return a cached shader node implementation,
98  /// or return nullptr if no implementation is found.
99  ShaderNodeImplPtr findNodeImplementation(const string& name) const;
100 
101  /// Get the names of all cached node implementations.
102  void getNodeImplementationNames(StringSet& names);
103 
104  /// Clear all cached shader node implementation.
105  void clearNodeImplementations();
106 
107  /// Push a new closure context to use for closure evaluation.
109  {
110  _closureContexts.push_back(cct);
111  }
112 
113  /// Pop the current closure context.
115  {
116  if (_closureContexts.size())
117  {
118  _closureContexts.pop_back();
119  }
120  }
121 
122  /// Return the current closure context.
124  {
125  return _closureContexts.size() ? _closureContexts.back() : nullptr;
126  }
127 
128  /// Add user data to the context to make it
129  /// available during shader generator.
130  void pushUserData(const string& name, GenUserDataPtr data)
131  {
132  auto it = _userData.find(name);
133  if (it != _userData.end())
134  {
135  it->second.push_back(data);
136  }
137  else
138  {
139  _userData[name] = { data };
140  }
141  }
142 
143  /// Remove user data from the context.
144  void popUserData(const string& name)
145  {
146  auto it = _userData.find(name);
147  if (it != _userData.end())
148  {
149  it->second.pop_back();
150  }
151  }
152 
153  /// Clear all user data from the context.
154  void clearUserData();
155 
156  /// Return user data with given name,
157  /// or nullptr if no data is found.
158  template <class T>
159  std::shared_ptr<T> getUserData(const string& name)
160  {
161  auto it = _userData.find(name);
162  return it != _userData.end() && !it->second.empty() ? it->second.back()->asA<T>() : nullptr;
163  }
164 
165  /// Add an input suffix to be used for the input in this context.
166  /// @param input Node input
167  /// @param suffix Suffix string
168  void addInputSuffix(const ShaderInput* input, const string& suffix);
169 
170  /// Remove an input suffix to be used for the input in this context.
171  /// @param input Node input
172  void removeInputSuffix(const ShaderInput* input);
173 
174  /// Get an input suffix to be used for the input in this context.
175  /// @param input Node input
176  /// @param suffix Suffix string returned. Is empty if not found.
177  void getInputSuffix(const ShaderInput* input, string& suffix) const;
178 
179  /// Add an output suffix to be used for the output in this context.
180  /// @param output Node output
181  /// @param suffix Suffix string
182  void addOutputSuffix(const ShaderOutput* output, const string& suffix);
183 
184  /// Remove an output suffix to be used for the output in this context.
185  /// @param output Node output
186  void removeOutputSuffix(const ShaderOutput* output);
187 
188  /// Get an output suffix to be used for the output in this context.
189  /// @param output Node output
190  /// @param suffix Suffix string returned. Is empty if not found.
191  void getOutputSuffix(const ShaderOutput* output, string& suffix) const;
192 
193  /// Set handler for application variables
195  {
196  _applicationVariableHandler = handler;
197  }
198 
199  /// Get handler for application variables
201  {
202  return _applicationVariableHandler;
203  }
204 
205  protected:
206  GenContext() = delete;
207 
212 
213  std::unordered_map<string, ShaderNodeImplPtr> _nodeImpls;
214  std::unordered_map<string, vector<GenUserDataPtr>> _userData;
215  std::unordered_map<const ShaderInput*, string> _inputSuffix;
216  std::unordered_map<const ShaderOutput*, string> _outputSuffix;
217 
218  vector<ClosureContext*> _closureContexts;
219 
221 };
222 
223 /// @class ClosureContext
224 /// Class representing a context for closure evaluation.
225 /// On hardware BSDF closures are evaluated differently in reflection, transmission
226 /// or environment/indirect contexts. This class represents the context we are in
227 /// and if extra arguments and function decorators are needed for that context.
229 {
230  public:
231  /// An extra argument for closure functions.
232  /// An argument is a pair of strings holding the
233  /// 'type' and 'name' of the argument.
234  using Argument = std::pair<const TypeDesc*, string>;
235  /// An array of arguments
236  using Arguments = vector<Argument>;
237 
238  /// Extra parameters for closure evaluation.
239  using ClosureParams = std::unordered_map<string, const ShaderInput*>;
240 
241  /// Constructor
242  ClosureContext(int type = 0) :
243  _type(type) { }
244 
245  /// Return the identifier for this context.
246  int getType() const { return _type; }
247 
248  /// For the given node type add an extra argument to be used for the function in this context.
249  void addArgument(const TypeDesc* nodeType, const Argument& arg)
250  {
251  _arguments[nodeType].push_back(arg);
252  }
253 
254  /// Return a list of extra argument to be used for the given node in this context.
255  const Arguments& getArguments(const TypeDesc* nodeType) const
256  {
257  auto it = _arguments.find(nodeType);
258  return it != _arguments.end() ? it->second : EMPTY_ARGUMENTS;
259  }
260 
261  /// For the given node type set a function name suffix to be used for the function in this context.
262  void setSuffix(const TypeDesc* nodeType, const string& suffix)
263  {
264  _suffix[nodeType] = suffix;
265  }
266 
267  /// Return the function name suffix to be used for the given node in this context.
268  const string& getSuffix(const TypeDesc* nodeType) const
269  {
270  auto it = _suffix.find(nodeType);
271  return it != _suffix.end() ? it->second : EMPTY_STRING;
272  }
273 
274  /// Set extra parameters to use for evaluating a closure.
275  void setClosureParams(const ShaderNode* closure, const ClosureParams* params)
276  {
277  if (params)
278  {
279  _params[closure] = params;
280  }
281  else
282  {
283  _params.erase(closure);
284  }
285  }
286 
287  /// Return extra parameters to use for evaluating a closure. Or return
288  /// nullptr if no parameters have been set for the given closure.
289  const ClosureParams* getClosureParams(const ShaderNode* closure) const
290  {
291  auto it = _params.find(closure);
292  return it != _params.end() ? it->second : nullptr;
293  }
294 
295  protected:
296  const int _type;
297  std::unordered_map<const TypeDesc*, Arguments> _arguments;
298  std::unordered_map<const TypeDesc*, string> _suffix;
299  std::unordered_map<const ShaderNode*, const ClosureParams*> _params;
300 
302 };
303 
304 /// A RAII class for setting extra parameters for closure evaluation,
305 /// stored in the closure context.
307 {
308  public:
309  /// Constructor for setting explicit parameters for a closure node.
311 
312  /// Constructor for setting parameters from one closure node to another.
313  ScopedSetClosureParams(const ShaderNode* fromNode, const ShaderNode* toNode, ClosureContext* cct);
314 
315  /// Destructor restoring the closure parameter state.
317 
318  private:
319  ClosureContext* _cct;
320  const ShaderNode* _node;
321  const ClosureContext::ClosureParams* _oldParams;
322 };
323 
324 /// A RAII class for overriding port variable names.
326 {
327  public:
328  /// Constructor for setting a new variable name for a port.
329  ScopedSetVariableName(const string& name, ShaderPort* port);
330 
331  /// Destructor restoring the original variable name.
333 
334  private:
335  ShaderPort* _port;
336  string _oldName;
337 };
338 
340 
341 #endif // MATERIALX_GENCONTEXT_H
FileSearchPath _sourceCodeSearchPath
Definition: GenContext.h:210
GT_API const UT_StringHolder filename
FilePath getNormalized() const
shared_ptr< ShaderNodeImpl > ShaderNodeImplPtr
Shared pointer to a ShaderNodeImpl.
Definition: Library.h:40
Definition: File.h:26
static const Arguments EMPTY_ARGUMENTS
Definition: GenContext.h:301
#define MATERIALX_NAMESPACE_BEGIN
Definition: Generated.h:25
StringSet _reservedWords
Definition: GenContext.h:211
const Arguments & getArguments(const TypeDesc *nodeType) const
Return a list of extra argument to be used for the given node in this context.
Definition: GenContext.h:255
A RAII class for overriding port variable names.
Definition: GenContext.h:325
const StringSet & getReservedWords() const
Definition: GenContext.h:89
ClosureContext(int type=0)
Constructor.
Definition: GenContext.h:242
GLsizei const GLchar *const * path
Definition: glcorearb.h:3341
void addReservedWords(const StringSet &names)
Definition: GenContext.h:82
MATERIALX_NAMESPACE_BEGIN MX_CORE_API const string EMPTY_STRING
std::unordered_map< const ShaderInput *, string > _inputSuffix
Definition: GenContext.h:215
std::function< void(ShaderNode *, GenContext &)> ApplicationVariableHandler
A standard function to allow for handling of application variables for a given node.
Definition: GenContext.h:25
#define MX_GENSHADER_API
Definition: Export.h:18
void popUserData(const string &name)
Remove user data from the context.
Definition: GenContext.h:144
vector< ClosureContext * > _closureContexts
Definition: GenContext.h:218
auto arg(const Char *name, const T &arg) -> detail::named_arg< Char, T >
Definition: core.h:1736
GLenum const GLfloat * params
Definition: glcorearb.h:105
const GenOptions & getOptions() const
Return shader generation options.
Definition: GenContext.h:49
bool isEmpty() const
Return true if the given path is empty.
Definition: File.h:92
ShaderGenerator & getShaderGenerator()
Return shader generatior.
Definition: GenContext.h:37
ShaderGeneratorPtr _sg
Definition: GenContext.h:208
int getType() const
Return the identifier for this context.
Definition: GenContext.h:246
std::unordered_map< string, ShaderNodeImplPtr > _nodeImpls
Definition: GenContext.h:213
ApplicationVariableHandler getApplicationVariableHandler() const
Get handler for application variables.
Definition: GenContext.h:200
std::shared_ptr< GenUserData > GenUserDataPtr
Shared pointer to a GenUserData.
Definition: GenUserData.h:19
std::pair< const TypeDesc *, string > Argument
Definition: GenContext.h:234
ApplicationVariableHandler _applicationVariableHandler
Definition: GenContext.h:220
GLuint const GLchar * name
Definition: glcorearb.h:786
std::unordered_map< string, vector< GenUserDataPtr > > _userData
Definition: GenContext.h:214
std::shared_ptr< T > getUserData(const string &name)
Definition: GenContext.h:159
const ClosureParams * getClosureParams(const ShaderNode *closure) const
Definition: GenContext.h:289
std::unordered_map< string, const ShaderInput * > ClosureParams
Extra parameters for closure evaluation.
Definition: GenContext.h:239
void registerSourceCodeSearchPath(const FileSearchPath &path)
Definition: GenContext.h:63
void popClosureContext()
Pop the current closure context.
Definition: GenContext.h:114
void pushUserData(const string &name, GenUserDataPtr data)
Definition: GenContext.h:130
const string & getSuffix(const TypeDesc *nodeType) const
Return the function name suffix to be used for the given node in this context.
Definition: GenContext.h:268
ClosureContext * getClosureContext()
Return the current closure context.
Definition: GenContext.h:123
void setApplicationVariableHandler(ApplicationVariableHandler handler)
Set handler for application variables.
Definition: GenContext.h:194
void prepend(const FilePath &path)
Prepend the given path to the sequence.
Definition: File.h:274
GenOptions & getOptions()
Return shader generation options.
Definition: GenContext.h:43
const int _type
Definition: GenContext.h:296
FilePath resolveSourceFile(const FilePath &filename, const FilePath &localPath) const
Definition: GenContext.h:70
vector< Argument > Arguments
An array of arguments.
Definition: GenContext.h:236
void addArgument(const TypeDesc *nodeType, const Argument &arg)
For the given node type add an extra argument to be used for the function in this context...
Definition: GenContext.h:249
std::unordered_map< const TypeDesc *, string > _suffix
Definition: GenContext.h:298
std::unordered_map< const ShaderOutput *, string > _outputSuffix
Definition: GenContext.h:216
FilePath find(const FilePath &filename) const
Definition: File.h:313
std::unordered_map< const ShaderNode *, const ClosureParams * > _params
Definition: GenContext.h:299
std::set< string > StringSet
A set of strings.
Definition: Library.h:61
#define MATERIALX_NAMESPACE_END
Definition: Generated.h:26
void pushClosureContext(ClosureContext *cct)
Push a new closure context to use for closure evaluation.
Definition: GenContext.h:108
type
Definition: core.h:1059
shared_ptr< ShaderGenerator > ShaderGeneratorPtr
Shared pointer to a ShaderGenerator.
Definition: Library.h:38
GenOptions _options
Definition: GenContext.h:209
void setClosureParams(const ShaderNode *closure, const ClosureParams *params)
Set extra parameters to use for evaluating a closure.
Definition: GenContext.h:275
void setSuffix(const TypeDesc *nodeType, const string &suffix)
For the given node type set a function name suffix to be used for the function in this context...
Definition: GenContext.h:262
Definition: format.h:895
std::unordered_map< const TypeDesc *, Arguments > _arguments
Definition: GenContext.h:297
void registerSourceCodeSearchPath(const FilePath &path)
Definition: GenContext.h:56