forked from AcademySoftwareFoundation/MaterialX
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ShaderGenerator.h
243 lines (187 loc) · 9.93 KB
/
ShaderGenerator.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
//
// TM & (c) 2017 Lucasfilm Entertainment Company Ltd. and Lucasfilm Ltd.
// All rights reserved. See LICENSE.txt for license.
//
#ifndef MATERIALX_SHADERGENERATOR_H
#define MATERIALX_SHADERGENERATOR_H
/// @file
/// Base shader generator class
#include <MaterialXGenShader/Export.h>
#include <MaterialXGenShader/ColorManagementSystem.h>
#include <MaterialXGenShader/Factory.h>
#include <MaterialXGenShader/ShaderStage.h>
#include <MaterialXGenShader/Syntax.h>
#include <MaterialXFormat/File.h>
#include <MaterialXCore/Exception.h>
MATERIALX_NAMESPACE_BEGIN
/// @class ShaderGenerator
/// Base class for shader generators
/// All third-party shader generators should derive from this class.
/// Derived classes should use DECLARE_SHADER_GENERATOR / DEFINE_SHADER_GENERATOR
/// in their declaration / definition, and register with the Registry class.
class MX_GENSHADER_API ShaderGenerator
{
public:
/// Destructor
virtual ~ShaderGenerator() { }
/// Return the name of the target this generator is for.
virtual const string& getTarget() const
{
return EMPTY_STRING;
}
/// Generate a shader starting from the given element, translating
/// the element and all dependencies upstream into shader code.
virtual ShaderPtr generate(const string&, ElementPtr, GenContext&) const
{
return nullptr;
}
/// Start a new scope using the given bracket type.
virtual void emitScopeBegin(ShaderStage& stage, Syntax::Punctuation punc = Syntax::CURLY_BRACKETS) const;
/// End the current scope.
virtual void emitScopeEnd(ShaderStage& stage, bool semicolon = false, bool newline = true) const;
/// Start a new line.
virtual void emitLineBegin(ShaderStage& stage) const;
/// End the current line.
virtual void emitLineEnd(ShaderStage& stage, bool semicolon = true) const;
/// Add a line break.
virtual void emitLineBreak(ShaderStage& stage) const;
/// Add a string.
virtual void emitString(const string& str, ShaderStage& stage) const;
/// Add a single line of code, optionally appending a semicolon.
virtual void emitLine(const string& str, ShaderStage& stage, bool semicolon = true) const;
/// Add a single line code comment.
virtual void emitComment(const string& str, ShaderStage& stage) const;
/// Add a block of code.
virtual void emitBlock(const string& str, const FilePath& sourceFilename, GenContext& context, ShaderStage& stage) const;
/// Add the contents of a standard library include file if not already present.
/// The library file prefix of the given context, if any, will be prepended
/// to the given filename.
virtual void emitLibraryInclude(const FilePath& filename, GenContext& context, ShaderStage& stage) const;
/// Add a value.
template<typename T>
void emitValue(const T& value, ShaderStage& stage) const
{
stage.addValue<T>(value);
}
/// Add the function definition for a single node.
virtual void emitFunctionDefinition(const ShaderNode& node, GenContext& context, ShaderStage& stage) const;
/// Add all function definitions for a graph.
virtual void emitFunctionDefinitions(const ShaderGraph& graph, GenContext& context, ShaderStage& stage) const;
/// Add the function call for a single node.
virtual void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage, bool checkScope = true) const;
/// Add all function calls for a graph. If a classification mask is given only functions for
/// nodes matching this classification will be emitted.
virtual void emitFunctionCalls(const ShaderGraph& graph, GenContext& context, ShaderStage& stage, uint32_t classification = 0u) const;
/// Add function calls for nodes connected directly upstream from the given node.
/// If a classification mask is given only functions for nodes matching this classification
/// will be emitted.
virtual void emitDependentFunctionCalls(const ShaderNode& node, GenContext& context, ShaderStage& stage, uint32_t classification = 0u) const;
/// Emit code for starting a new function body.
virtual void emitFunctionBodyBegin(const ShaderNode& node, GenContext& context, ShaderStage& stage, Syntax::Punctuation punc = Syntax::CURLY_BRACKETS) const;
/// Emit code for ending a function body.
virtual void emitFunctionBodyEnd(const ShaderNode& node, GenContext& context, ShaderStage& stage) const;
/// Emit type definitions for all data types that needs it.
virtual void emitTypeDefinitions(GenContext& context, ShaderStage& stage) const;
/// Emit the connected variable name for an input,
/// or constant value if the port is not connected
virtual void emitInput(const ShaderInput* input, GenContext& context, ShaderStage& stage) const;
/// Emit the output variable name for an output, optionally including it's type
/// and default value assignment.
virtual void emitOutput(const ShaderOutput* output, bool includeType, bool assignValue, GenContext& context, ShaderStage& stage) const;
/// Emit definitions for all shader variables in a block.
/// @param block Block to emit.
/// @param qualifier Optional qualifier to add before the variable declaration.
/// @param separator Separator to use between the declarations.
/// @param context Context for generation.
/// @param stage The stage to emit code into.
/// @param assignValue If true the variables are initialized with their value.
virtual void emitVariableDeclarations(const VariableBlock& block, const string& qualifier, const string& separator, GenContext& context, ShaderStage& stage,
bool assignValue = true) const;
/// Emit definition of a single shader variable.
/// @param variable Shader port representing the variable.
/// @param qualifier Optional qualifier to add before the variable declaration.
/// @param context Context for generation.
/// @param stage The stage to emit code into.
/// @param assignValue If true the variable is initialized with its value.
virtual void emitVariableDeclaration(const ShaderPort* variable, const string& qualifier, GenContext& context, ShaderStage& stage,
bool assignValue = true) const;
/// Return the closure contexts defined for the given node.
virtual void getClosureContexts(const ShaderNode& node, vector<ClosureContext*>& cct) const;
/// Return the result of an upstream connection or value for an input.
virtual string getUpstreamResult(const ShaderInput* input, GenContext& context) const;
/// Return the syntax object for the language used by the code generator
const Syntax& getSyntax() const { return *_syntax; }
/// Register a shader node implementation for a given implementation element name
void registerImplementation(const string& name, CreatorFunction<ShaderNodeImpl> creator);
/// Determine if a shader node implementation has been registered for a given implementation element name
bool implementationRegistered(const string& name) const;
/// Return a registered shader node implementation for the given nodedef.
virtual ShaderNodeImplPtr getImplementation(const NodeDef& nodedef, GenContext& context) const;
/// Sets the color management system
void setColorManagementSystem(ColorManagementSystemPtr colorManagementSystem)
{
_colorManagementSystem = colorManagementSystem;
}
/// Returns the color management system
ColorManagementSystemPtr getColorManagementSystem() const
{
return _colorManagementSystem;
}
/// Sets the unit system
void setUnitSystem(UnitSystemPtr unitSystem)
{
_unitSystem = unitSystem;
}
/// Returns the unit system
UnitSystemPtr getUnitSystem() const
{
return _unitSystem;
}
/// Return the map of token substitutions used by the generator.
const StringMap& getTokenSubstitutions() const
{
return _tokenSubstitutions;
}
/// Register metadata that should be exported to the generated shaders.
/// Supported metadata includes standard UI attributes like "uiname", "uifolder",
/// "uimin", "uimax", etc.
/// But it is also extendable by defining custom attributes using AttributeDefs.
/// Any AttributeDef in the given document with exportable="true" will be
/// exported as shader metadata when found on nodes during shader generation.
/// Derived shader generators may override this method to change the registration.
/// Applications must explicitly call this method before shader generation to enable
/// export of metadata.
virtual void registerShaderMetadata(const DocumentPtr& doc, GenContext& context) const;
protected:
/// Protected constructor
ShaderGenerator(SyntaxPtr syntax);
/// Create a new stage in a shader.
virtual ShaderStagePtr createStage(const string& name, Shader& shader) const;
/// Set function name for a stage.
void setFunctionName(const string& functionName, ShaderStage& stage) const
{
stage.setFunctionName(functionName);
}
/// Replace tokens with identifiers according to the given substitutions map.
void replaceTokens(const StringMap& substitutions, ShaderStage& stage) const;
/// Create shader variables (e.g. uniforms, inputs and outputs) for
/// nodes that require input data from the application.
void createVariables(ShaderGraphPtr graph, GenContext& context, Shader& shader) const;
protected:
static const string T_FILE_TRANSFORM_UV;
SyntaxPtr _syntax;
Factory<ShaderNodeImpl> _implFactory;
ColorManagementSystemPtr _colorManagementSystem;
UnitSystemPtr _unitSystem;
mutable StringMap _tokenSubstitutions;
friend ShaderGraph;
};
/// @class ExceptionShaderGenError
/// An exception that is thrown when shader generation fails.
class MX_GENSHADER_API ExceptionShaderGenError : public Exception
{
public:
using Exception::Exception;
};
MATERIALX_NAMESPACE_END
#endif // MATERIALX_SHADERGENERATOR_H