Class Program
Synopsis
#include <Source/Falcor/Core/Program/Program.h>
class dlldecl Program : public std::enable_shared_from_this<Program>
Description
High-level abstraction of a program class. This class manages different versions of the same program. Different versions means same shader files, different macro definitions. This allows simple usage in case different macros are required - for example static vs. animated models.
Inheritance
Ancestors: std::enable_shared_from_this< Program >
Decsendents: GraphicsProgram, ComputeProgram, RtProgram
Classes
Desc | Description of a program to be created. |
Methods
Program | ||
~Program | ||
addDefine | Adds a macro definition to the program | |
addDefines | Add a list of macro definitions to the program | |
addGlobalDefines | Add a list of defines applied to all programs. | |
checkIfFilesChanged | ||
createEntryPointGroupKernels | ||
createProgramKernels | ||
createSlangCompileRequest | ||
doSlangReflection | ||
getActiveVersion | Get the API handle of the active program. | |
getDefineList | Get the macro definition list of the active program version. | |
getEntryPointGroupCount | ||
getGroupEntryPointCount | ||
getGroupEntryPointIndex | ||
getProgramDescString | ||
getReflector | Get the program reflection for the active program. | |
init | ||
link | ||
markDirty | ||
preprocessAndCreateProgramKernels | ||
preprocessAndCreateProgramVersion | ||
reloadAllPrograms | Reload and relink all programs. | |
removeDefine | Remove a macro definition from the program | |
removeDefines overload | Removes a list of macro definitions from the program | |
removeDefines overload | Removes all macro definitions that matches string comparison from the program. | |
removeGlobalDefines | Remove a list of defines applied to all programs. | |
reset | ||
setDefines | Set the macro definition list of the active program version. | |
setUpSlangCompilationTarget |
Source
Lines 39-298 in Source/Falcor/Core/Program/Program.h.
class dlldecl Program : public std::enable_shared_from_this<Program>
{
public:
using SharedPtr = std::shared_ptr<Program>;
using SharedConstPtr = std::shared_ptr<const Program>;
using DefineList = Shader::DefineList;
/** Description of a program to be created.
*/
class dlldecl Desc
{
public:
/** Begin building a description, that initially has no source files or entry points.
*/
Desc();
/** Begin building a description, based on a single path for source code.
This is equivalent to: `Desc().sourceFile(path)`
*/
explicit Desc(std::string const& filename);
/** Add a file of source code to use.
This also sets the given file as the "active" source for subsequent entry points.
*/
Desc& addShaderLibrary(const std::string& path);
/** Add a string of source code to use.
This also sets the given string as the "active" source for subsequent entry points.
*/
Desc& addShaderString(const std::string& shader);
/** Adds an entry point based on the "active" source.
*/
Desc& entryPoint(ShaderType shaderType, const std::string& name);
Desc& vsEntry(const std::string& name) { return entryPoint(ShaderType::Vertex, name); }
Desc& hsEntry(const std::string& name) { return entryPoint(ShaderType::Hull, name); }
Desc& dsEntry(const std::string& name) { return entryPoint(ShaderType::Domain, name); }
Desc& gsEntry(const std::string& name) { return entryPoint(ShaderType::Geometry, name); }
Desc& psEntry(const std::string& name) { return entryPoint(ShaderType::Pixel, name); }
Desc& csEntry(const std::string& name) { return entryPoint(ShaderType::Compute, name); }
/** Enable/disable treat-warnings-as-error compilation flag
*/
Desc& warningsAsErrors(bool enable) { enable ? mShaderFlags |= Shader::CompilerFlags::TreatWarningsAsErrors : mShaderFlags &= ~(Shader::CompilerFlags::TreatWarningsAsErrors); return *this; }
/** Enable/disable pre-processed shader dump
*/
Desc& dumpIntermediates(bool enable) { enable ? mShaderFlags |= Shader::CompilerFlags::DumpIntermediates : mShaderFlags &= ~(Shader::CompilerFlags::DumpIntermediates); return *this; }
/** Set the shader model string. This depends on the API you are using.
For DirectX it should be `4_0`, `4_1`, `5_0`, `5_1`, `6_0`, `6_1`, `6_2`, `6_3`, `6_4`, or `6_5`. The default is `6_2`. Shader model `6.x` will use dxcompiler, previous shader models use fxc.
For Vulkan, it should be `400`, `410`, `420`, `430`, `440` or `450`. The default is `450`
*/
Desc& setShaderModel(const std::string& sm);
/** Get the compiler flags
*/
Shader::CompilerFlags getCompilerFlags() const { return mShaderFlags; }
/** Set the compiler flags. Replaces any previously set flags.
*/
Desc& setCompilerFlags(Shader::CompilerFlags flags) { mShaderFlags = flags; return *this; }
bool hasEntryPoint(ShaderType stage) const;
protected:
friend class Program;
friend class GraphicsProgram;
friend class RtProgram;
Desc& beginEntryPointGroup();
Desc& addDefaultVertexShaderIfNeeded();
uint32_t declareEntryPoint(ShaderType type, const std::string& name);
struct Source
{
enum class Type
{
String,
File
};
Source(ShaderLibrary::SharedPtr pLib) : pLibrary(pLib), type(Type::File) {};
Source(std::string s) : str(s), type(Type::String) {};
Type type;
ShaderLibrary::SharedPtr pLibrary;
std::string str;
std::vector<uint32_t> entryPoints;
};
struct EntryPointGroup
{
std::vector<uint32_t> entryPoints;
};
struct EntryPoint
{
std::string name;
ShaderType stage;
int32_t sourceIndex;
};
std::vector<Source> mSources;
std::vector<EntryPointGroup> mGroups;
std::vector<EntryPoint> mEntryPoints;
int32_t mActiveSource = -1;
int32_t mActiveGroup = -1;
Shader::CompilerFlags mShaderFlags = Shader::CompilerFlags::None;
ef FALCOR_VK
std::string mShaderModel = "450";
f defined FALCOR_D3D12
std::string mShaderModel = "6_2";
if
};
virtual ~Program() = 0;
/** Get the API handle of the active program.
\return The active program version, or an exception is thrown on failure.
*/
const ProgramVersion::SharedConstPtr& getActiveVersion() const;
/** Adds a macro definition to the program. If the macro already exists, it will be replaced.
\param[in] name The name of define.
\param[in] value Optional. The value of the define string.
\return True if any macro definitions were modified.
*/
bool addDefine(const std::string& name, const std::string& value = "");
/** Add a list of macro definitions to the program. If a macro already exists, it will be replaced.
\param[in] dl List of macro definitions to add.
\return True if any macro definitions were modified.
*/
bool addDefines(const DefineList& dl);
/** Remove a macro definition from the program. If the definition doesn't exist, the function call will be silently ignored.
\param[in] name The name of define.
\return True if any macro definitions were modified.
*/
bool removeDefine(const std::string& name);
/** Removes a list of macro definitions from the program. If a macro doesn't exist, it is silently ignored.
\param[in] dl List of macro definitions to remove.
\return True if any macro definitions were modified.
*/
bool removeDefines(const DefineList& dl);
/** Removes all macro definitions that matches string comparison from the program.
\param[in] pos Position of the first character in macro name. If this is greater than the string length, the macro will be silently kept.
\param[in] len Length of compared macro name (if the string is shorter, as many characters as possible). A value of string::npos indicates all characters.
\param[in] str The comparing string that is matched against macro names.
\return True if any macro definitions were modified.
*/
bool removeDefines(size_t pos, size_t len, const std::string& str);
/** Set the macro definition list of the active program version.
\param[in] dl List of macro definitions.
\return True if any macro definition was changed, false otherwise.
*/
bool setDefines(const DefineList& dl);
/** Get the macro definition list of the active program version.
*/
const DefineList& getDefineList() const { return mDefineList; }
/** Reload and relink all programs.
\param[in] forceReload Force reloading all programs.
\return True if any program was reloaded, false otherwise.
*/
static bool reloadAllPrograms(bool forceReload = false);
/** Add a list of defines applied to all programs.
\param[in] defineList List of macro definitions.
*/
static void addGlobalDefines(const DefineList& defineList);
/** Remove a list of defines applied to all programs.
\param[in] defineList List of macro definitions.
*/
static void removeGlobalDefines(const DefineList& defineList);
/** Get the program reflection for the active program.
\return Program reflection object, or an exception is thrown on failure.
*/
const ProgramReflection::SharedPtr& getReflector() const { return getActiveVersion()->getReflector(); }
uint32_t getEntryPointGroupCount() const { return uint32_t(mDesc.mGroups.size()); }
uint32_t getGroupEntryPointCount(uint32_t groupIndex) const { return (uint32_t)mDesc.mGroups[groupIndex].entryPoints.size(); }
uint32_t getGroupEntryPointIndex(uint32_t groupIndex, uint32_t entryPointIndexInGroup) const
{
return mDesc.mGroups[groupIndex].entryPoints[entryPointIndexInGroup];
}
protected:
friend class ::Falcor::ProgramVersion;
Program() = default;
void init(Desc const& desc, DefineList const& programDefines);
bool link() const;
SlangCompileRequest* createSlangCompileRequest(
DefineList const& defineList) const;
virtual void setUpSlangCompilationTarget(
slang::TargetDesc& ioTargetDesc,
char const*& ioTargetMacroName) const;
bool doSlangReflection(
ProgramVersion const* pVersion,
slang::IComponentType* pSlangGlobalScope,
std::vector<ComPtr<slang::IComponentType>> pSlangEntryPointGroups,
ProgramReflection::SharedPtr& pReflector,
std::string& log) const;
ProgramVersion::SharedPtr preprocessAndCreateProgramVersion(std::string& log) const;
ProgramKernels::SharedPtr preprocessAndCreateProgramKernels(
ProgramVersion const* pVersion,
ProgramVars const* pVars,
std::string & log) const;
virtual EntryPointGroupKernels::SharedPtr createEntryPointGroupKernels(
const std::vector<Shader::SharedPtr>& shaders,
EntryPointGroupReflection::SharedPtr const& pReflector) const;
virtual ProgramKernels::SharedPtr createProgramKernels(
const ProgramVersion* pVersion,
const ProgramReflection::SharedPtr& pReflector,
const ProgramKernels::UniqueEntryPointGroups& uniqueEntryPointGroups,
std::string& log,
const std::string& name = "") const;
// The description used to create this program
Desc mDesc;
DefineList mDefineList;
// We are doing lazy compilation, so these are mutable
mutable bool mLinkRequired = true;
mutable std::map<DefineList, ProgramVersion::SharedConstPtr> mProgramVersions;
mutable ProgramVersion::SharedConstPtr mpActiveVersion;
void markDirty() { mLinkRequired = true; }
std::string getProgramDescString() const;
static std::vector<std::weak_ptr<Program>> sPrograms;
using string_time_map = std::unordered_map<std::string, time_t>;
mutable string_time_map mFileTimeMap;
bool checkIfFilesChanged();
void reset();
};