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"
29 #include <unordered_map>
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
40 CShaderManager(Renderer::Backend::IDevice
* device
);
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
);
53 * Load a shader effect, with empty defines.
55 CShaderTechniquePtr
LoadEffect(CStrIntern name
);
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
);
66 * Returns the number of shader effects that are currently loaded.
68 size_t GetNumEffectsLoaded() const;
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
;
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.
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
117 using HotloadFilesMap
= std::unordered_map
<
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