Files
UnrealEngine/Engine/Source/ThirdParty/MaterialX/Deploy/MaterialX-1.39.3/include/MaterialXGenShader/GenContext.h
2025-05-18 13:04:45 +08:00

243 lines
7.0 KiB
C++

//
// Copyright Contributors to the MaterialX Project
// SPDX-License-Identifier: Apache-2.0
//
#ifndef MATERIALX_GENCONTEXT_H
#define MATERIALX_GENCONTEXT_H
/// @file
/// Context classes for shader generation
#include <MaterialXGenShader/Export.h>
#include <MaterialXGenShader/GenOptions.h>
#include <MaterialXGenShader/GenUserData.h>
#include <MaterialXGenShader/ShaderNode.h>
#include <MaterialXGenShader/ShaderGenerator.h>
#include <MaterialXFormat/File.h>
MATERIALX_NAMESPACE_BEGIN
/// A standard function to allow for handling of application variables for a given node
using ApplicationVariableHandler = std::function<void(ShaderNode*, GenContext&)>;
/// @class GenContext
/// A context class for shader generation.
/// Used for thread local storage of data needed during shader generation.
class MX_GENSHADER_API GenContext
{
public:
/// Constructor.
GenContext(ShaderGeneratorPtr sg);
/// Return shader generatior.
ShaderGenerator& getShaderGenerator()
{
return *_sg;
}
/// Return shader generation options.
GenOptions& getOptions()
{
return _options;
}
/// Return shader generation options.
const GenOptions& getOptions() const
{
return _options;
}
/// Return a TypeDesc for the given type name.
TypeDesc getTypeDesc(const string& name) const
{
return _sg->getTypeSystem()->getType(name);
}
/// Register a user search path for finding source code during
/// code generation.
void registerSourceCodeSearchPath(const FilePath& path)
{
_sourceCodeSearchPath.append(path);
}
/// Register a user search path for finding source code during
/// code generation.
void registerSourceCodeSearchPath(const FileSearchPath& path)
{
_sourceCodeSearchPath.append(path);
}
/// Resolve a source code filename, first checking the given local path
/// then checking any file paths registered by the user.
FilePath resolveSourceFile(const FilePath& filename, const FilePath& localPath) const
{
FileSearchPath searchPath = _sourceCodeSearchPath;
if (!localPath.isEmpty())
{
searchPath.prepend(localPath);
}
return searchPath.find(filename).getNormalized();
}
/// Add reserved words that should not be used as
/// identifiers during code generation.
void addReservedWords(const StringSet& names)
{
_reservedWords.insert(names.begin(), names.end());
}
/// Return the set of reserved words that should not be used
/// as identifiers during code generation.
const StringSet& getReservedWords() const
{
return _reservedWords;
}
/// Cache a shader node implementation.
void addNodeImplementation(const string& name, ShaderNodeImplPtr impl);
/// Find and return a cached shader node implementation,
/// or return nullptr if no implementation is found.
ShaderNodeImplPtr findNodeImplementation(const string& name) const;
/// Get the names of all cached node implementations.
void getNodeImplementationNames(StringSet& names);
/// Clear all cached shader node implementation.
void clearNodeImplementations();
/// Push a parent node onto the stack
void pushParentNode(ConstNodePtr node)
{
_parentNodes.push_back(node);
}
/// Pop the current parent node from the stack.
void popParentNode()
{
_parentNodes.pop_back();
}
/// Return the current stack of parent nodes.
const vector<ConstNodePtr>& getParentNodes()
{
return _parentNodes;
}
/// Add user data to the context to make it
/// available during shader generator.
void pushUserData(const string& name, GenUserDataPtr data)
{
auto it = _userData.find(name);
if (it != _userData.end())
{
it->second.push_back(data);
}
else
{
_userData[name] = { data };
}
}
/// Remove user data from the context.
void popUserData(const string& name)
{
auto it = _userData.find(name);
if (it != _userData.end())
{
it->second.pop_back();
}
}
/// Clear all user data from the context.
void clearUserData();
/// Return user data with given name,
/// or nullptr if no data is found.
template <class T>
std::shared_ptr<T> getUserData(const string& name)
{
auto it = _userData.find(name);
return it != _userData.end() && !it->second.empty() ? it->second.back()->asA<T>() : nullptr;
}
/// Add an input suffix to be used for the input in this context.
/// @param input Node input
/// @param suffix Suffix string
void addInputSuffix(const ShaderInput* input, const string& suffix);
/// Remove an input suffix to be used for the input in this context.
/// @param input Node input
void removeInputSuffix(const ShaderInput* input);
/// Get an input suffix to be used for the input in this context.
/// @param input Node input
/// @param suffix Suffix string returned. Is empty if not found.
void getInputSuffix(const ShaderInput* input, string& suffix) const;
/// Add an output suffix to be used for the output in this context.
/// @param output Node output
/// @param suffix Suffix string
void addOutputSuffix(const ShaderOutput* output, const string& suffix);
/// Remove an output suffix to be used for the output in this context.
/// @param output Node output
void removeOutputSuffix(const ShaderOutput* output);
/// Get an output suffix to be used for the output in this context.
/// @param output Node output
/// @param suffix Suffix string returned. Is empty if not found.
void getOutputSuffix(const ShaderOutput* output, string& suffix) const;
/// Set handler for application variables
void setApplicationVariableHandler(ApplicationVariableHandler handler)
{
_applicationVariableHandler = handler;
}
/// Get handler for application variables
ApplicationVariableHandler getApplicationVariableHandler() const
{
return _applicationVariableHandler;
}
protected:
GenContext() = delete;
ShaderGeneratorPtr _sg;
GenOptions _options;
FileSearchPath _sourceCodeSearchPath;
StringSet _reservedWords;
std::unordered_map<string, ShaderNodeImplPtr> _nodeImpls;
std::unordered_map<string, vector<GenUserDataPtr>> _userData;
std::unordered_map<const ShaderInput*, string> _inputSuffix;
std::unordered_map<const ShaderOutput*, string> _outputSuffix;
vector<ConstNodePtr> _parentNodes;
ApplicationVariableHandler _applicationVariableHandler;
};
/// A RAII class for overriding port variable names.
class MX_GENSHADER_API ScopedSetVariableName
{
public:
/// Constructor for setting a new variable name for a port.
ScopedSetVariableName(const string& name, ShaderPort* port);
/// Destructor restoring the original variable name.
~ScopedSetVariableName();
private:
ShaderPort* _port;
string _oldName;
};
MATERIALX_NAMESPACE_END
#endif // MATERIALX_GENCONTEXT_H