MaterialX 1.39.4
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
49} // namespace Stage
50
51class VariableBlock;
53using VariableBlockPtr = std::shared_ptr<VariableBlock>;
56using VariableBlockMap = std::map<string, VariableBlockPtr>;
58using ShaderPortPredicate = std::function<bool(ShaderPort*)>;
59
62class MX_GENSHADER_API VariableBlock
63{
64 public:
65 VariableBlock(const string& name, const string& instance) :
66 _name(name),
67 _instance(instance)
68 {
69 }
70
72 const string& getName() const { return _name; }
73
75 void setName(const string& name) { _name = name; }
76
78 const string& getInstance() const { return _instance; }
79
81 void setInstance(const string& instance) { _instance = instance; }
82
84 bool empty() const { return _variableOrder.empty(); }
85
87 size_t size() const { return _variableOrder.size(); }
88
90 ShaderPort* operator[](size_t index) { return _variableOrder[index]; }
91
93 const ShaderPort* operator[](size_t index) const { return _variableOrder[index]; }
94
96 const vector<ShaderPort*>& getVariableOrder() const { return _variableOrder; }
97
100 ShaderPort* operator[](const string& name);
101
104 const ShaderPort* operator[](const string& name) const;
105
108 ShaderPort* find(const string& name);
109
112 const ShaderPort* find(const string& name) const;
113
116
125 ShaderPort* add(TypeDesc type, const string& name, ValuePtr value = nullptr, bool shouldWiden = false);
126
128 void add(ShaderPortPtr port);
129
130 private:
131 string _name;
132 string _instance;
133 std::unordered_map<string, ShaderPortPtr> _variableMap;
134 vector<ShaderPort*> _variableOrder;
135};
136
140class MX_GENSHADER_API ShaderStage
141{
142 public:
143 using FunctionCallId = const ShaderNode*;
144 struct Scope
145 {
146 Syntax::Punctuation punctuation;
147 std::set<FunctionCallId> functions;
148 Scope(Syntax::Punctuation p) :
149 punctuation(p) { }
150 };
151
152 public:
154 ShaderStage(const string& name, ConstSyntaxPtr syntax);
155
157 const string& getName() const { return _name; }
158
160 const string& getFunctionName() const { return _functionName; }
161
163 void setSourceCode(const string& code) { _code = code; }
164
166 const string& getSourceCode() const { return _code; }
167
169 VariableBlockPtr createUniformBlock(const string& name, const string& instance = EMPTY_STRING);
170
172 VariableBlockPtr createInputBlock(const string& name, const string& instance = EMPTY_STRING);
173
175 VariableBlockPtr createOutputBlock(const string& name, const string& instance = EMPTY_STRING);
176
178 VariableBlock& getUniformBlock(const string& name);
179
181 const VariableBlock& getUniformBlock(const string& name) const;
182
184 VariableBlock& getInputBlock(const string& name);
185
187 const VariableBlock& getInputBlock(const string& name) const;
188
190 VariableBlock& getOutputBlock(const string& name);
191
193 const VariableBlock& getOutputBlock(const string& name) const;
194
197
200
203 {
204 return _uniforms;
205 }
206
209 {
210 return _inputs;
211 }
212
215 {
216 return _outputs;
217 }
218
220 const StringSet& getIncludes() const
221 {
222 return _includes;
223 }
224
227 {
228 return _sourceDependencies;
229 }
230
232 void beginScope(Syntax::Punctuation punc = Syntax::CURLY_BRACKETS);
233
235 void endScope(bool semicolon = false, bool newline = true);
236
238 void beginLine();
239
241 void endLine(bool semicolon = true);
242
244 void newLine();
245
247 void addString(const string& str);
248
250 void addLine(const string& str, bool semicolon = true);
251
253 void addComment(const string& str);
254
256 void addBlock(const string& str, const FilePath& sourceFilename, GenContext& context);
257
259 void addInclude(const FilePath& includeFilename, const FilePath& sourceFilename, GenContext& context);
260
262 bool hasSourceDependency(const FilePath& file);
263
265 void addSourceDependency(const FilePath& file);
266
268 template <typename T>
269 void addValue(const T& value)
270 {
271 StringStream str;
272 str << value;
273 _code += str.str();
274 }
275
277 void addFunctionDefinition(const ShaderNode& node, GenContext& context);
278
283 void addFunctionCall(const ShaderNode& node, GenContext& context, bool emitCode = true);
284
286 bool isEmitted(const ShaderNode& node, GenContext& context) const;
287
289 void setFunctionName(const string& functionName)
290 {
291 _functionName = functionName;
292 }
293
294 private:
296 const string _name;
297
299 string _functionName;
300
302 ConstSyntaxPtr _syntax;
303
305 int _indentations;
306
308 vector<Scope> _scopes;
309
311 StringSet _includes;
312
314 StringSet _sourceDependencies;
315
317 std::set<size_t> _definedFunctions;
318
320 VariableBlock _constants;
321
323 VariableBlockMap _uniforms;
324
326 VariableBlockMap _inputs;
327
329 VariableBlockMap _outputs;
330
332 string _code;
333
334 friend class ShaderGenerator;
335};
336
338using ShaderStagePtr = std::shared_ptr<ShaderStage>;
339
341inline ShaderPort* addStageUniform(const string& block,
342 TypeDesc type,
343 const string& name,
344 ShaderStage& stage)
345{
346 VariableBlock& uniforms = stage.getUniformBlock(block);
347 return uniforms.add(type, name);
348}
349[[deprecated]] inline ShaderPort* addStageUniform(const string& block,
350 const TypeDesc* type,
351 const string& name,
352 ShaderStage& stage)
353{
354 return addStageUniform(block, *type, name, stage);
355}
356
358inline ShaderPort* addStageInput(const string& block,
359 TypeDesc type,
360 const string& name,
361 ShaderStage& stage,
362 bool shouldWiden = false)
363{
364 VariableBlock& inputs = stage.getInputBlock(block);
365 return inputs.add(type, name, {}, shouldWiden);
366}
367[[deprecated]] inline ShaderPort* addStageInput(const string& block,
368 const TypeDesc* type,
369 const string& name,
370 ShaderStage& stage,
371 bool shouldWiden = false)
372{
373 return addStageInput(block, *type, name, stage, shouldWiden);
374}
375
377inline ShaderPort* addStageOutput(const string& block,
378 TypeDesc type,
379 const string& name,
380 ShaderStage& stage,
381 bool shouldWiden = false)
382{
383 VariableBlock& outputs = stage.getOutputBlock(block);
384 return outputs.add(type, name, {}, shouldWiden);
385}
386[[deprecated]] inline ShaderPort* addStageOutput(const string& block,
387 const TypeDesc* type,
388 const string& name,
389 ShaderStage& stage,
390 bool shouldWiden = false)
391{
392 return addStageOutput(block, *type, name, stage, shouldWiden);
393}
394
396inline void addStageConnectorBlock(const string& block,
397 const string& instance,
398 ShaderStage& from,
399 ShaderStage& to)
400{
401 from.createOutputBlock(block, instance);
402 to.createInputBlock(block, instance);
403}
404
406inline void addStageConnector(const string& block,
407 TypeDesc type,
408 const string& name,
409 ShaderStage& from,
410 ShaderStage& to,
411 bool shouldWiden = false)
412{
413 addStageOutput(block, type, name, from, shouldWiden);
414 addStageInput(block, type, name, to, shouldWiden);
415}
416[[deprecated]] inline void addStageConnector(const string& block,
417 const TypeDesc* type,
418 const string& name,
419 ShaderStage& from,
420 ShaderStage& to,
421 bool shouldWiden = false)
422{
423 addStageConnector(block, *type, name, from, to, shouldWiden);
424}
425
426MATERIALX_NAMESPACE_END
427
428#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:53
void addStageConnectorBlock(const string &block, const string &instance, ShaderStage &from, ShaderStage &to)
Utility function for adding a connector block between stages.
Definition ShaderStage.h:396
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:377
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:358
std::map< string, VariableBlockPtr > VariableBlockMap
Shared pointer to a map between string identifiers and VariableBlocks.
Definition ShaderStage.h:56
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:341
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:406
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:58
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:31
Class representing a node in the shader generation DAG.
Definition ShaderNode.h:320
An input or output port on a ShaderNode.
Definition ShaderNode.h:123
A shader stage, containing the state and resulting source code for the stage.
Definition ShaderStage.h:141
const VariableBlockMap & getUniformBlocks() const
Return a map of all uniform blocks.
Definition ShaderStage.h:202
void setFunctionName(const string &functionName)
Set stage function name.
Definition ShaderStage.h:289
void beginLine()
Start a new line.
void addValue(const T &value)
Add a value.
Definition ShaderStage.h:269
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:157
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:163
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:208
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:160
const StringSet & getSourceDependencies() const
Return a set of all source dependencies.
Definition ShaderStage.h:226
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:166
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:214
const StringSet & getIncludes() const
Return a set of all include files.
Definition ShaderStage.h:220
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:63
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:87
const string & getName() const
Get the name of this block.
Definition ShaderStage.h:72
void setName(const string &name)
Set the name of this block.
Definition ShaderStage.h:75
ShaderPort * operator[](size_t index)
Return a variable by index.
Definition ShaderStage.h:90
bool empty() const
Return true if the block has no variables.
Definition ShaderStage.h:84
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:78
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:93
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:96
void setInstance(const string &instance)
Set the instance name of this block.
Definition ShaderStage.h:81