[Gameplay] Reduce loom cost
[0ad.git] / source / graphics / ShaderManager.h
blob79cd908cb15e004b021fe0a456d324d08e030074
1 /* Copyright (C) 2023 Wildfire Games.
2 * This file is part of 0 A.D.
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.
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.
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/>.
18 #ifndef INCLUDED_SHADERMANAGER
19 #define INCLUDED_SHADERMANAGER
21 #include "graphics/ShaderDefines.h"
22 #include "graphics/ShaderProgram.h"
23 #include "graphics/ShaderTechnique.h"
24 #include "renderer/backend/PipelineState.h"
26 #include <functional>
27 #include <memory>
28 #include <set>
29 #include <unordered_map>
31 /**
32 * Shader manager: loads and caches shader programs.
34 * For a high-level overview of shaders and materials, see
35 * http://trac.wildfiregames.com/wiki/MaterialSystem
37 class CShaderManager
39 public:
40 CShaderManager(Renderer::Backend::IDevice* device);
41 ~CShaderManager();
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
50 CShaderTechniquePtr LoadEffect(CStrIntern name, const CShaderDefines& defines);
52 /**
53 * Load a shader effect, with empty defines.
55 CShaderTechniquePtr LoadEffect(CStrIntern name);
57 /**
58 * Load a shader effect with the pipeline state description overwriting.
59 * TODO: we should set all needed states in XML.
61 using PipelineStateDescCallback = CShaderTechnique::PipelineStateDescCallback;
62 CShaderTechniquePtr LoadEffect(
63 CStrIntern name, const CShaderDefines& defines, const PipelineStateDescCallback& callback);
65 /**
66 * Returns the number of shader effects that are currently loaded.
68 size_t GetNumEffectsLoaded() const;
70 private:
71 struct CacheKey
73 std::string name;
74 CShaderDefines defines;
76 bool operator<(const CacheKey& k) const
78 if (name < k.name) return true;
79 if (k.name < name) return false;
80 return defines < k.defines;
84 Renderer::Backend::IDevice* m_Device = nullptr;
86 // A CShaderProgram contains expensive backend state, so we ought to cache it.
87 // The compiled state depends solely on the filename and list of defines,
88 // so we store that in CacheKey.
89 // TODO: is this cache useful when we already have an effect cache?
90 std::map<CacheKey, CShaderProgramPtr> m_ProgramCache;
92 /**
93 * Key for effect cache lookups.
94 * This stores two separate CShaderDefines because the renderer typically
95 * has one set from the rendering context and one set from the material;
96 * by handling both separately here, we avoid the cost of having to merge
97 * the two sets into a single one before doing the cache lookup.
99 struct EffectCacheKey
101 CStrIntern name;
102 CShaderDefines defines;
104 bool operator==(const EffectCacheKey& b) const;
107 struct EffectCacheKeyHash
109 size_t operator()(const EffectCacheKey& key) const;
112 using EffectCacheMap = std::unordered_map<EffectCacheKey, CShaderTechniquePtr, EffectCacheKeyHash>;
113 EffectCacheMap m_EffectCache;
115 // Store the set of shaders that need to be reloaded when the given file is modified
116 template<typename T>
117 using HotloadFilesMap = std::unordered_map<
118 VfsPath,
119 std::set<std::weak_ptr<T>, std::owner_less<std::weak_ptr<T>>>>;
120 HotloadFilesMap<CShaderTechnique> m_HotloadTechniques;
121 HotloadFilesMap<CShaderProgram> m_HotloadPrograms;
124 * Load a shader program.
125 * @param name name of shader XML specification (file is loaded from shaders/${name}.xml)
126 * @param defines key/value set of preprocessor definitions
127 * @return loaded program, or null pointer on error
129 CShaderProgramPtr LoadProgram(const CStr& name, const CShaderDefines& defines);
131 bool LoadTechnique(CShaderTechniquePtr& tech);
133 static Status ReloadChangedFileCB(void* param, const VfsPath& path);
134 Status ReloadChangedFile(const VfsPath& path);
137 * Associates the file with the technique to be reloaded if the file has changed.
139 void AddTechniqueFileDependency(const CShaderTechniquePtr& technique, const VfsPath& path);
142 * Associates the file with the program to be reloaded if the file has changed.
144 void AddProgramFileDependency(const CShaderProgramPtr& program, const VfsPath& path);
147 #endif // INCLUDED_SHADERMANAGER