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  /// Push a parent node onto the stack
130  {
131  _parentNodes.push_back(node);
132  }
133 
134  /// Pop the current parent node from the stack.
136  {
137  _parentNodes.pop_back();
138  }
139 
140  /// Return the current stack of parent nodes.
141  const vector<ConstNodePtr>& getParentNodes()
142  {
143  return _parentNodes;
144  }
145 
146  /// Add user data to the context to make it
147  /// available during shader generator.
148  void pushUserData(const string& name, GenUserDataPtr data)
149  {
150  auto it = _userData.find(name);
151  if (it != _userData.end())
152  {
153  it->second.push_back(data);
154  }
155  else
156  {
157  _userData[name] = { data };
158  }
159  }
160 
161  /// Remove user data from the context.
162  void popUserData(const string& name)
163  {
164  auto it = _userData.find(name);
165  if (it != _userData.end())
166  {
167  it->second.pop_back();
168  }
169  }
170 
171  /// Clear all user data from the context.
172  void clearUserData();
173 
174  /// Return user data with given name,
175  /// or nullptr if no data is found.
176  template <class T>
177  std::shared_ptr<T> getUserData(const string& name)
178  {
179  auto it = _userData.find(name);
180  return it != _userData.end() && !it->second.empty() ? it->second.back()->asA<T>() : nullptr;
181  }
182 
183  /// Add an input suffix to be used for the input in this context.
184  /// @param input Node input
185  /// @param suffix Suffix string
186  void addInputSuffix(const ShaderInput* input, const string& suffix);
187 
188  /// Remove an input suffix to be used for the input in this context.
189  /// @param input Node input
190  void removeInputSuffix(const ShaderInput* input);
191 
192  /// Get an input suffix to be used for the input in this context.
193  /// @param input Node input
194  /// @param suffix Suffix string returned. Is empty if not found.
195  void getInputSuffix(const ShaderInput* input, string& suffix) const;
196 
197  /// Add an output suffix to be used for the output in this context.
198  /// @param output Node output
199  /// @param suffix Suffix string
200  void addOutputSuffix(const ShaderOutput* output, const string& suffix);
201 
202  /// Remove an output suffix to be used for the output in this context.
203  /// @param output Node output
204  void removeOutputSuffix(const ShaderOutput* output);
205 
206  /// Get an output suffix to be used for the output in this context.
207  /// @param output Node output
208  /// @param suffix Suffix string returned. Is empty if not found.
209  void getOutputSuffix(const ShaderOutput* output, string& suffix) const;
210 
211  /// Set handler for application variables
213  {
214  _applicationVariableHandler = handler;
215  }
216 
217  /// Get handler for application variables
219  {
220  return _applicationVariableHandler;
221  }
222 
223  protected:
224  GenContext() = delete;
225 
230 
231  std::unordered_map<string, ShaderNodeImplPtr> _nodeImpls;
232  std::unordered_map<string, vector<GenUserDataPtr>> _userData;
233  std::unordered_map<const ShaderInput*, string> _inputSuffix;
234  std::unordered_map<const ShaderOutput*, string> _outputSuffix;
235 
236  vector<ClosureContext*> _closureContexts;
237  vector<ConstNodePtr> _parentNodes;
238 
240 };
241 
242 /// @class ClosureContext
243 /// Class representing a context for closure evaluation.
244 /// On hardware BSDF closures are evaluated differently in reflection, transmission
245 /// or environment/indirect contexts. This class represents the context we are in
246 /// and if extra arguments and function decorators are needed for that context.
248 {
249  public:
250  /// An extra argument for closure functions.
251  /// An argument is a pair of strings holding the
252  /// 'type' and 'name' of the argument.
253  using Argument = std::pair<const TypeDesc*, string>;
254  /// An array of arguments
255  using Arguments = vector<Argument>;
256 
257  /// Extra parameters for closure evaluation.
258  using ClosureParams = std::unordered_map<string, const ShaderInput*>;
259 
260  /// Constructor
261  ClosureContext(int type = 0) :
262  _type(type) { }
263 
264  /// Return the identifier for this context.
265  int getType() const { return _type; }
266 
267  /// For the given node type add an extra argument to be used for the function in this context.
268  void addArgument(const TypeDesc* nodeType, const Argument& arg)
269  {
270  _arguments[nodeType].push_back(arg);
271  }
272 
273  /// Return a list of extra argument to be used for the given node in this context.
274  const Arguments& getArguments(const TypeDesc* nodeType) const
275  {
276  auto it = _arguments.find(nodeType);
277  return it != _arguments.end() ? it->second : EMPTY_ARGUMENTS;
278  }
279 
280  /// For the given node type set a function name suffix to be used for the function in this context.
281  void setSuffix(const TypeDesc* nodeType, const string& suffix)
282  {
283  _suffix[nodeType] = suffix;
284  }
285 
286  /// Return the function name suffix to be used for the given node in this context.
287  const string& getSuffix(const TypeDesc* nodeType) const
288  {
289  auto it = _suffix.find(nodeType);
290  return it != _suffix.end() ? it->second : EMPTY_STRING;
291  }
292 
293  /// Set extra parameters to use for evaluating a closure.
294  void setClosureParams(const ShaderNode* closure, const ClosureParams* params)
295  {
296  if (params)
297  {
298  _params[closure] = params;
299  }
300  else
301  {
302  _params.erase(closure);
303  }
304  }
305 
306  /// Return extra parameters to use for evaluating a closure. Or return
307  /// nullptr if no parameters have been set for the given closure.
308  const ClosureParams* getClosureParams(const ShaderNode* closure) const
309  {
310  auto it = _params.find(closure);
311  return it != _params.end() ? it->second : nullptr;
312  }
313 
314  protected:
315  const int _type;
316  std::unordered_map<const TypeDesc*, Arguments> _arguments;
317  std::unordered_map<const TypeDesc*, string> _suffix;
318  std::unordered_map<const ShaderNode*, const ClosureParams*> _params;
319 
321 };
322 
323 /// A RAII class for setting extra parameters for closure evaluation,
324 /// stored in the closure context.
326 {
327  public:
328  /// Constructor for setting explicit parameters for a closure node.
330 
331  /// Constructor for setting parameters from one closure node to another.
332  ScopedSetClosureParams(const ShaderNode* fromNode, const ShaderNode* toNode, ClosureContext* cct);
333 
334  /// Destructor restoring the closure parameter state.
336 
337  private:
338  ClosureContext* _cct;
339  const ShaderNode* _node;
340  const ClosureContext::ClosureParams* _oldParams;
341 };
342 
343 /// A RAII class for overriding port variable names.
345 {
346  public:
347  /// Constructor for setting a new variable name for a port.
348  ScopedSetVariableName(const string& name, ShaderPort* port);
349 
350  /// Destructor restoring the original variable name.
352 
353  private:
354  ShaderPort* _port;
355  string _oldName;
356 };
357 
359 
360 #endif // MATERIALX_GENCONTEXT_H
FileSearchPath _sourceCodeSearchPath
Definition: GenContext.h:228
vector< ConstNodePtr > _parentNodes
Definition: GenContext.h:237
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
const vector< ConstNodePtr > & getParentNodes()
Return the current stack of parent nodes.
Definition: GenContext.h:141
static const Arguments EMPTY_ARGUMENTS
Definition: GenContext.h:320
#define MATERIALX_NAMESPACE_BEGIN
Definition: Generated.h:25
StringSet _reservedWords
Definition: GenContext.h:229
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:274
A RAII class for overriding port variable names.
Definition: GenContext.h:344
const StringSet & getReservedWords() const
Definition: GenContext.h:89
ClosureContext(int type=0)
Constructor.
Definition: GenContext.h:261
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
shared_ptr< const Node > ConstNodePtr
A shared pointer to a const Node.
Definition: Node.h:26
std::unordered_map< const ShaderInput *, string > _inputSuffix
Definition: GenContext.h:233
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:162
vector< ClosureContext * > _closureContexts
Definition: GenContext.h:236
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:226
int getType() const
Return the identifier for this context.
Definition: GenContext.h:265
std::unordered_map< string, ShaderNodeImplPtr > _nodeImpls
Definition: GenContext.h:231
ApplicationVariableHandler getApplicationVariableHandler() const
Get handler for application variables.
Definition: GenContext.h:218
std::shared_ptr< GenUserData > GenUserDataPtr
Shared pointer to a GenUserData.
Definition: GenUserData.h:19
std::pair< const TypeDesc *, string > Argument
Definition: GenContext.h:253
ApplicationVariableHandler _applicationVariableHandler
Definition: GenContext.h:239
GLuint const GLchar * name
Definition: glcorearb.h:786
std::unordered_map< string, vector< GenUserDataPtr > > _userData
Definition: GenContext.h:232
std::shared_ptr< T > getUserData(const string &name)
Definition: GenContext.h:177
const ClosureParams * getClosureParams(const ShaderNode *closure) const
Definition: GenContext.h:308
std::unordered_map< string, const ShaderInput * > ClosureParams
Extra parameters for closure evaluation.
Definition: GenContext.h:258
void registerSourceCodeSearchPath(const FileSearchPath &path)
Definition: GenContext.h:63
void popClosureContext()
Pop the current closure context.
Definition: GenContext.h:114
void popParentNode()
Pop the current parent node from the stack.
Definition: GenContext.h:135
void pushUserData(const string &name, GenUserDataPtr data)
Definition: GenContext.h:148
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:287
ClosureContext * getClosureContext()
Return the current closure context.
Definition: GenContext.h:123
void setApplicationVariableHandler(ApplicationVariableHandler handler)
Set handler for application variables.
Definition: GenContext.h:212
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:315
FilePath resolveSourceFile(const FilePath &filename, const FilePath &localPath) const
Definition: GenContext.h:70
vector< Argument > Arguments
An array of arguments.
Definition: GenContext.h:255
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:268
std::unordered_map< const TypeDesc *, string > _suffix
Definition: GenContext.h:317
std::unordered_map< const ShaderOutput *, string > _outputSuffix
Definition: GenContext.h:234
FilePath find(const FilePath &filename) const
Definition: File.h:313
std::unordered_map< const ShaderNode *, const ClosureParams * > _params
Definition: GenContext.h:318
std::set< string > StringSet
A set of strings.
Definition: Library.h:61
void pushParentNode(ConstNodePtr node)
Push a parent node onto the stack.
Definition: GenContext.h:129
#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:227
void setClosureParams(const ShaderNode *closure, const ClosureParams *params)
Set extra parameters to use for evaluating a closure.
Definition: GenContext.h:294
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:281
Definition: format.h:895
std::unordered_map< const TypeDesc *, Arguments > _arguments
Definition: GenContext.h:316
void registerSourceCodeSearchPath(const FilePath &path)
Definition: GenContext.h:56