Pyrogenesis  trunk
ShaderManager.h
Go to the documentation of this file.
1 /* Copyright (C) 2022 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef INCLUDED_SHADERMANAGER
19 #define INCLUDED_SHADERMANAGER
20 
21 #include "graphics/ShaderDefines.h"
22 #include "graphics/ShaderProgram.h"
25 
26 #include <functional>
27 #include <memory>
28 #include <set>
29 #include <unordered_map>
30 
31 /**
32  * Shader manager: loads and caches shader programs.
33  *
34  * For a high-level overview of shaders and materials, see
35  * http://trac.wildfiregames.com/wiki/MaterialSystem
36  */
38 {
39 public:
42 
43  /**
44  * Load a shader effect.
45  * Effects can be implemented via many techniques; this returns the best usable technique.
46  * @param name name of effect XML specification (file is loaded from shaders/effects/${name}.xml)
47  * @param defines key/value set of preprocessor definitions
48  * @return loaded technique, or empty technique on error
49  */
51 
52  /**
53  * Load a shader effect, with empty defines.
54  */
56 
57  /**
58  * Load a shader effect with the pipeline state description overwriting.
59  * TODO: we should set all needed states in XML.
60  */
63  CStrIntern name, const CShaderDefines& defines, const PipelineStateDescCallback& callback);
64 
65  /**
66  * Returns the number of shader effects that are currently loaded.
67  */
68  size_t GetNumEffectsLoaded() const;
69 
70 private:
71  struct CacheKey
72  {
73  std::string name;
75 
76  bool operator<(const CacheKey& k) const
77  {
78  if (name < k.name) return true;
79  if (k.name < name) return false;
80  return defines < k.defines;
81  }
82  };
83 
84  // A CShaderProgram contains expensive backend state, so we ought to cache it.
85  // The compiled state depends solely on the filename and list of defines,
86  // so we store that in CacheKey.
87  // TODO: is this cache useful when we already have an effect cache?
88  std::map<CacheKey, CShaderProgramPtr> m_ProgramCache;
89 
90  /**
91  * Key for effect cache lookups.
92  * This stores two separate CShaderDefines because the renderer typically
93  * has one set from the rendering context and one set from the material;
94  * by handling both separately here, we avoid the cost of having to merge
95  * the two sets into a single one before doing the cache lookup.
96  */
98  {
101 
102  bool operator==(const EffectCacheKey& b) const;
103  };
104 
106  {
107  size_t operator()(const EffectCacheKey& key) const;
108  };
109 
110  using EffectCacheMap = std::unordered_map<EffectCacheKey, CShaderTechniquePtr, EffectCacheKeyHash>;
112 
113  // Store the set of shaders that need to be reloaded when the given file is modified
114  template<typename T>
115  using HotloadFilesMap = std::unordered_map<
116  VfsPath,
117  std::set<std::weak_ptr<T>, std::owner_less<std::weak_ptr<T>>>>;
120 
121  /**
122  * Load a shader program.
123  * @param name name of shader XML specification (file is loaded from shaders/${name}.xml)
124  * @param defines key/value set of preprocessor definitions
125  * @return loaded program, or null pointer on error
126  */
127  CShaderProgramPtr LoadProgram(const CStr& name, const CShaderDefines& defines);
128 
130 
131  static Status ReloadChangedFileCB(void* param, const VfsPath& path);
132  Status ReloadChangedFile(const VfsPath& path);
133 
134  /**
135  * Associates the file with the technique to be reloaded if the file has changed.
136  */
137  void AddTechniqueFileDependency(const CShaderTechniquePtr& technique, const VfsPath& path);
138 
139  /**
140  * Associates the file with the program to be reloaded if the file has changed.
141  */
142  void AddProgramFileDependency(const CShaderProgramPtr& program, const VfsPath& path);
143 };
144 
145 #endif // INCLUDED_SHADERMANAGER
~CShaderManager()
Definition: ShaderManager.cpp:65
Definition: ShaderManager.h:105
CShaderProgramPtr LoadProgram(const CStr &name, const CShaderDefines &defines)
Load a shader program.
Definition: ShaderManager.cpp:70
HotloadFilesMap< CShaderTechnique > m_HotloadTechniques
Definition: ShaderManager.h:118
std::unordered_map< VfsPath, std::set< std::weak_ptr< T >, std::owner_less< std::weak_ptr< T > >> > HotloadFilesMap
Definition: ShaderManager.h:117
bool operator==(const FCDJointWeightPair &a, const FCDJointWeightPair &b)
Definition: GeomReindex.cpp:59
CShaderDefines defines
Definition: ShaderManager.h:74
std::string name
Definition: ShaderManager.h:73
Key for effect cache lookups.
Definition: ShaderManager.h:97
std::map< CacheKey, CShaderProgramPtr > m_ProgramCache
Definition: ShaderManager.h:88
Status ReloadChangedFile(const VfsPath &path)
Definition: ShaderManager.cpp:465
HotloadFilesMap< CShaderProgram > m_HotloadPrograms
Definition: ShaderManager.h:119
void AddProgramFileDependency(const CShaderProgramPtr &program, const VfsPath &path)
Associates the file with the program to be reloaded if the file has changed.
Definition: ShaderManager.cpp:499
Interned 8-bit strings.
Definition: CStrIntern.h:37
CShaderManager()
Definition: ShaderManager.cpp:50
bool LoadTechnique(CShaderTechniquePtr &tech)
Definition: ShaderManager.cpp:146
EffectCacheMap m_EffectCache
Definition: ShaderManager.h:111
bool operator<(const CacheKey &k) const
Definition: ShaderManager.h:76
pthread_key_t key
Definition: wpthread.cpp:140
Definition: ShaderManager.h:71
size_t GetNumEffectsLoaded() const
Returns the number of shader effects that are currently loaded.
Definition: ShaderManager.cpp:455
void AddTechniqueFileDependency(const CShaderTechniquePtr &technique, const VfsPath &path)
Associates the file with the technique to be reloaded if the file has changed.
Definition: ShaderManager.cpp:494
i64 Status
Error handling system.
Definition: status.h:169
std::unordered_map< EffectCacheKey, CShaderTechniquePtr, EffectCacheKeyHash > EffectCacheMap
Definition: ShaderManager.h:110
static Status ReloadChangedFileCB(void *param, const VfsPath &path)
Definition: ShaderManager.cpp:460
Represents a mapping of name strings to value strings, for use with #if and #ifdef and similar condit...
Definition: ShaderDefines.h:146
CShaderTechnique::PipelineStateDescCallback PipelineStateDescCallback
Load a shader effect with the pipeline state description overwriting.
Definition: ShaderManager.h:61
std::shared_ptr< CShaderTechnique > CShaderTechniquePtr
Definition: ShaderTechniquePtr.h:27
CShaderTechniquePtr LoadEffect(CStrIntern name, const CShaderDefines &defines)
Load a shader effect.
Definition: ShaderManager.cpp:110
std::function< void(Renderer::Backend::SGraphicsPipelineStateDesc &pipelineStateDesc)> PipelineStateDescCallback
Definition: ShaderTechnique.h:63
CStrIntern name
Definition: ShaderManager.h:99
std::shared_ptr< CShaderProgram > CShaderProgramPtr
Definition: ShaderProgramPtr.h:25
Shader manager: loads and caches shader programs.
Definition: ShaderManager.h:37
CShaderDefines defines
Definition: ShaderManager.h:100
Path VfsPath
Definition: HeightMipmap.h:30