MaterialX 1.39.5
Loading...
Searching...
No Matches
ShaderStage.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_SHADERSTAGE_H
7#define MATERIALX_SHADERSTAGE_H
8
11
13
17
19
20#include <MaterialXCore/Node.h>
21
22#include <map>
23#include <sstream>
24
25// Restrict a scoped block of statements to a specific shader stage, as
26// is required for multi-stage shading languages. Statements within
27// the block will only be emitted when processing the given stage.
28#define DEFINE_SHADER_STAGE(stage, name) if (stage.getName() == name)
29
30// These macros are deprecated, and should be replaced with DEFINE_SHADER_STAGE.
31#define BEGIN_SHADER_STAGE(stage, name) \
32 if (stage.getName() == name) \
33 {
34#define END_SHADER_STAGE(stage, name) }
35
36MATERIALX_NAMESPACE_BEGIN
37
38namespace Stage
39{
40
47extern MX_GENSHADER_API const string PIXEL;
48// technically this might only be needed in MaterialXGenHW, but including it here
49// now for simplicity - refactoring code in MaterialXGenShader may be possible
50// in the future
51extern MX_GENSHADER_API const string VERTEX;
52
53} // namespace Stage
54
55class VariableBlock;
57using VariableBlockPtr = std::shared_ptr<VariableBlock>;
60using VariableBlockMap = std::map<string, VariableBlockPtr>;
62using ShaderPortPredicate = std::function<bool(ShaderPort*)>;
63
66class MX_GENSHADER_API VariableBlock
67{
68 public:
69 VariableBlock(const string& name, const string& instance) :
70 _name(name),
71 _instance(instance)
72 {
73 }
74
76 const string& getName() const { return _name; }
77
79 void setName(const string& name) { _name = name; }
80
82 const string& getInstance() const { return _instance; }
83
85 void setInstance(const string& instance) { _instance = instance; }
86
88 bool empty() const { return _variableOrder.empty(); }
89
91 size_t size() const { return _variableOrder.size(); }
92
94 ShaderPort* operator[](size_t index) { return _variableOrder[index]; }
95
97 const ShaderPort* operator[](size_t index) const { return _variableOrder[index]; }
98
100 const vector<ShaderPort*>& getVariableOrder() const { return _variableOrder; }
101
104 ShaderPort* operator[](const string& name);
105
108 const ShaderPort* operator[](const string& name) const;
109
112 ShaderPort* find(const string& name);
113
116 const ShaderPort* find(const string& name) const;
117
120
129 ShaderPort* add(TypeDesc type, const string& name, ValuePtr value = nullptr, bool shouldWiden = false);
130
132 void add(ShaderPortPtr port);
133
134 private:
135 string _name;
136 string _instance;
137 std::unordered_map<string, ShaderPortPtr> _variableMap;
138 vector<ShaderPort*> _variableOrder;
139};
140
144class MX_GENSHADER_API ShaderStage
145{
146 public:
147 using FunctionCallId = const ShaderNode*;
148 struct Scope
149 {
150 Syntax::Punctuation punctuation;
151 std::set<FunctionCallId> functions;
152 Scope(Syntax::Punctuation p) :
153 punctuation(p) { }
154 };
155
156 public:
158 ShaderStage(const string& name, ConstSyntaxPtr syntax);
159
161 const string& getName() const { return _name; }
162
164 const string& getFunctionName() const { return _functionName; }
165
167 void setSourceCode(const string& code) { _code = code; }
168
170 const string& getSourceCode() const { return _code; }
171
173 VariableBlockPtr createUniformBlock(const string& name, const string& instance = EMPTY_STRING);
174
176 VariableBlockPtr createInputBlock(const string& name, const string& instance = EMPTY_STRING);
177
179 VariableBlockPtr createOutputBlock(const string& name, const string& instance = EMPTY_STRING);
180
182 VariableBlock& getUniformBlock(const string& name);
183
185 const VariableBlock& getUniformBlock(const string& name) const;
186
188 VariableBlock& getInputBlock(const string& name);
189
191 const VariableBlock& getInputBlock(const string& name) const;
192
194 VariableBlock& getOutputBlock(const string& name);
195
197 const VariableBlock& getOutputBlock(const string& name) const;
198
201
204
207 {
208 return _uniforms;
209 }
210
213 {
214 return _inputs;
215 }
216
219 {
220 return _outputs;
221 }
222
224 const StringSet& getIncludes() const
225 {
226 return _includes;
227 }
228
231 {
232 return _sourceDependencies;
233 }
234
236 void beginScope(Syntax::Punctuation punc = Syntax::CURLY_BRACKETS);
237
239 void endScope(bool semicolon = false, bool newline = true);
240
242 void beginLine();
243
245 void endLine(bool semicolon = true);
246
248 void newLine();
249
251 void addString(const string& str);
252
254 void addLine(const string& str, bool semicolon = true);
255
257 void addComment(const string& str);
258
260 void addBlock(const string& str, const FilePath& sourceFilename, GenContext& context);
261
263 void addInclude(const FilePath& includeFilename, const FilePath& sourceFilename, GenContext& context);
264
266 bool hasSourceDependency(const FilePath& file);
267
269 void addSourceDependency(const FilePath& file);
270
272 template <typename T>
273 void addValue(const T& value)
274 {
275 StringStream str;
276 str << value;
277 _code += str.str();
278 }
279
281 void addFunctionDefinition(const ShaderNode& node, GenContext& context);
282
287 void addFunctionCall(const ShaderNode& node, GenContext& context, bool emitCode = true);
288
290 bool isEmitted(const ShaderNode& node, GenContext& context) const;
291
293 void setFunctionName(const string& functionName)
294 {
295 _functionName = functionName;
296 }
297
298 private:
300 const string _name;
301
303 string _functionName;
304
306 ConstSyntaxPtr _syntax;
307
309 int _indentations;
310
312 vector<Scope> _scopes;
313
315 StringSet _includes;
316
318 StringSet _sourceDependencies;
319
321 std::set<size_t> _definedFunctions;
322
324 VariableBlock _constants;
325
327 VariableBlockMap _uniforms;
328
330 VariableBlockMap _inputs;
331
333 VariableBlockMap _outputs;
334
336 string _code;
337
338 friend class ShaderGenerator;
339};
340
342using ShaderStagePtr = std::shared_ptr<ShaderStage>;
343
345inline ShaderPort* addStageUniform(const string& block,
346 TypeDesc type,
347 const string& name,
348 ShaderStage& stage)
349{
350 VariableBlock& uniforms = stage.getUniformBlock(block);
351 return uniforms.add(type, name);
352}
353[[deprecated]] inline ShaderPort* addStageUniform(const string& block,
354 const TypeDesc* type,
355 const string& name,
356 ShaderStage& stage)
357{
358 return addStageUniform(block, *type, name, stage);
359}
360
362inline ShaderPort* addStageInput(const string& block,
363 TypeDesc type,
364 const string& name,
365 ShaderStage& stage,
366 bool shouldWiden = false)
367{
368 VariableBlock& inputs = stage.getInputBlock(block);
369 return inputs.add(type, name, {}, shouldWiden);
370}
371[[deprecated]] inline ShaderPort* addStageInput(const string& block,
372 const TypeDesc* type,
373 const string& name,
374 ShaderStage& stage,
375 bool shouldWiden = false)
376{
377 return addStageInput(block, *type, name, stage, shouldWiden);
378}
379
381inline ShaderPort* addStageOutput(const string& block,
382 TypeDesc type,
383 const string& name,
384 ShaderStage& stage,
385 bool shouldWiden = false)
386{
387 VariableBlock& outputs = stage.getOutputBlock(block);
388 return outputs.add(type, name, {}, shouldWiden);
389}
390[[deprecated]] inline ShaderPort* addStageOutput(const string& block,
391 const TypeDesc* type,
392 const string& name,
393 ShaderStage& stage,
394 bool shouldWiden = false)
395{
396 return addStageOutput(block, *type, name, stage, shouldWiden);
397}
398
400inline void addStageConnectorBlock(const string& block,
401 const string& instance,
402 ShaderStage& from,
403 ShaderStage& to)
404{
405 from.createOutputBlock(block, instance);
406 to.createInputBlock(block, instance);
407}
408
410inline void addStageConnector(const string& block,
411 TypeDesc type,
412 const string& name,
413 ShaderStage& from,
414 ShaderStage& to,
415 bool shouldWiden = false)
416{
417 addStageOutput(block, type, name, from, shouldWiden);
418 addStageInput(block, type, name, to, shouldWiden);
419}
420[[deprecated]] inline void addStageConnector(const string& block,
421 const TypeDesc* type,
422 const string& name,
423 ShaderStage& from,
424 ShaderStage& to,
425 bool shouldWiden = false)
426{
427 addStageConnector(block, *type, name, from, to, shouldWiden);
428}
429
430MATERIALX_NAMESPACE_END
431
432#endif
Cross-platform support for file and search paths.
Shader generation options class.
std::set< string > StringSet
A set of strings.
Definition Library.h:65
Macros for declaring imported and exported symbols.
shared_ptr< ShaderStage > ShaderStagePtr
Shared pointer to a ShaderStage.
Definition Library.h:35
std::stringstream StringStream
A string stream.
Definition Library.h:30
Node element subclasses.
Shader graph class.
shared_ptr< class ShaderPort > ShaderPortPtr
Shared pointer to a ShaderPort.
Definition ShaderNode.h:29
std::shared_ptr< VariableBlock > VariableBlockPtr
Shared pointer to a VariableBlock.
Definition ShaderStage.h:57
void addStageConnectorBlock(const string &block, const string &instance, ShaderStage &from, ShaderStage &to)
Utility function for adding a connector block between stages.
Definition ShaderStage.h:400
ShaderPort * addStageOutput(const string &block, TypeDesc type, const string &name, ShaderStage &stage, bool shouldWiden=false)
Utility function for adding a new shader port to an output block.
Definition ShaderStage.h:381
ShaderPort * addStageInput(const string &block, TypeDesc type, const string &name, ShaderStage &stage, bool shouldWiden=false)
Utility function for adding a new shader port to an input block.
Definition ShaderStage.h:362
std::map< string, VariableBlockPtr > VariableBlockMap
Shared pointer to a map between string identifiers and VariableBlocks.
Definition ShaderStage.h:60
ShaderPort * addStageUniform(const string &block, TypeDesc type, const string &name, ShaderStage &stage)
Utility function for adding a new shader port to a uniform block.
Definition ShaderStage.h:345
void addStageConnector(const string &block, TypeDesc type, const string &name, ShaderStage &from, ShaderStage &to, bool shouldWiden=false)
Utility function for adding a variable to a stage connector block.
Definition ShaderStage.h:410
MX_GENSHADER_API const string PIXEL
Identifier for pixel stage.
std::function< bool(ShaderPort *)> ShaderPortPredicate
A standard function predicate taking an ShaderPort pointer and returning a boolean.
Definition ShaderStage.h:62
Base class for syntax handling for shader generators.
shared_ptr< const Syntax > ConstSyntaxPtr
Shared pointer to a constant Syntax.
Definition Syntax.h:30
shared_ptr< Value > ValuePtr
A shared pointer to a Value.
Definition Value.h:30
A generic file path, supporting both syntactic and file system operations.
Definition File.h:27
A context class for shader generation.
Definition GenContext.h:30
Base class for shader generators All third-party shader generators should derive from this class.
Definition ShaderGenerator.h:32
Class representing a node in the shader generation DAG.
Definition ShaderNode.h:328
An input or output port on a ShaderNode.
Definition ShaderNode.h:124
A shader stage, containing the state and resulting source code for the stage.
Definition ShaderStage.h:145
const VariableBlockMap & getUniformBlocks() const
Return a map of all uniform blocks.
Definition ShaderStage.h:206
void setFunctionName(const string &functionName)
Set stage function name.
Definition ShaderStage.h:293
void beginLine()
Start a new line.
void addValue(const T &value)
Add a value.
Definition ShaderStage.h:273
void addBlock(const string &str, const FilePath &sourceFilename, GenContext &context)
Add a block of code.
const VariableBlock & getConstantBlock() const
Return the constant variable block.
void newLine()
Add a newline character.
void addInclude(const FilePath &includeFilename, const FilePath &sourceFilename, GenContext &context)
Add the contents of an include file if not already present.
void addLine(const string &str, bool semicolon=true)
Add a single line of code, optionally appending a semicolon.
VariableBlock & getOutputBlock(const string &name)
Return the output variable block with given name.
const string & getName() const
Return the stage name.
Definition ShaderStage.h:161
void addString(const string &str)
Add a string.
bool isEmitted(const ShaderNode &node, GenContext &context) const
Return true if the function for the given node has been emitted in the current scope.
VariableBlockPtr createUniformBlock(const string &name, const string &instance=EMPTY_STRING)
Create a new uniform variable block.
ShaderStage(const string &name, ConstSyntaxPtr syntax)
Constructor.
bool hasSourceDependency(const FilePath &file)
Return true if this stage depends on the given source file.
void setSourceCode(const string &code)
Set the stage source code.
Definition ShaderStage.h:167
void addFunctionCall(const ShaderNode &node, GenContext &context, bool emitCode=true)
Add the function call for the given node.
void addSourceDependency(const FilePath &file)
Mark the given source file as a dependency of this stage.
const VariableBlockMap & getInputBlocks() const
Return a map of all input blocks.
Definition ShaderStage.h:212
VariableBlockPtr createOutputBlock(const string &name, const string &instance=EMPTY_STRING)
Create a new output variable block.
void endScope(bool semicolon=false, bool newline=true)
End the current scope.
void addFunctionDefinition(const ShaderNode &node, GenContext &context)
Add the function definition for a node's implementation.
void beginScope(Syntax::Punctuation punc=Syntax::CURLY_BRACKETS)
Start a new scope using the given bracket type.
const string & getFunctionName() const
Return the stage function name.
Definition ShaderStage.h:164
const StringSet & getSourceDependencies() const
Return a set of all source dependencies.
Definition ShaderStage.h:230
VariableBlockPtr createInputBlock(const string &name, const string &instance=EMPTY_STRING)
Create a new input variable block.
void addComment(const string &str)
Add a single line code comment.
VariableBlock & getUniformBlock(const string &name)
Return the uniform variable block with given name.
void endLine(bool semicolon=true)
End the current line.
const VariableBlock & getUniformBlock(const string &name) const
Return the uniform variable block with given name.
const string & getSourceCode() const
Return the stage source code.
Definition ShaderStage.h:170
const VariableBlock & getOutputBlock(const string &name) const
Return the output variable block with given name.
const VariableBlockMap & getOutputBlocks() const
Return a map of all output blocks.
Definition ShaderStage.h:218
const StringSet & getIncludes() const
Return a set of all include files.
Definition ShaderStage.h:224
const VariableBlock & getInputBlock(const string &name) const
Return the input variable block with given name.
VariableBlock & getInputBlock(const string &name)
Return the input variable block with given name.
VariableBlock & getConstantBlock()
Return the constant variable block.
Punctuation
Punctuation types.
Definition Syntax.h:48
A type descriptor for MaterialX data types.
Definition TypeDesc.h:40
A block of variables in a shader stage.
Definition ShaderStage.h:67
const ShaderPort * operator[](const string &name) const
Return a variable by name.
size_t size() const
Return the number of variables in this block.
Definition ShaderStage.h:91
const string & getName() const
Get the name of this block.
Definition ShaderStage.h:76
void setName(const string &name)
Set the name of this block.
Definition ShaderStage.h:79
ShaderPort * operator[](size_t index)
Return a variable by index.
Definition ShaderStage.h:94
bool empty() const
Return true if the block has no variables.
Definition ShaderStage.h:88
void add(ShaderPortPtr port)
Add an existing shader port to this block.
ShaderPort * add(TypeDesc type, const string &name, ValuePtr value=nullptr, bool shouldWiden=false)
Add a new shader port to this block.
ShaderPort * operator[](const string &name)
Return a variable by name.
const string & getInstance() const
Get the instance name of this block.
Definition ShaderStage.h:82
ShaderPort * find(const string &name)
Return a variable by name.
const ShaderPort * find(const string &name) const
Return a variable by name.
const ShaderPort * operator[](size_t index) const
Return a variable by index.
Definition ShaderStage.h:97
ShaderPort * find(const ShaderPortPredicate &predicate)
Find a port based on a predicate.
const vector< ShaderPort * > & getVariableOrder() const
Return a const reference to our variable order vector.
Definition ShaderStage.h:100
void setInstance(const string &instance)
Set the instance name of this block.
Definition ShaderStage.h:85