Pyrogenesis HEAD
Pyrogenesis, a RTS Engine
DescriptorManager.h
Go to the documentation of this file.
1/* Copyright (C) 2024 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_RENDERER_BACKEND_VULKAN_DESCRIPTORMANAGER
19#define INCLUDED_RENDERER_BACKEND_VULKAN_DESCRIPTORMANAGER
20
21#include "ps/CStrIntern.h"
25
26#include <glad/vulkan.h>
27#include <limits>
28#include <memory>
29#include <unordered_map>
30#include <utility>
31#include <vector>
32
33namespace Renderer
34{
35
36namespace Backend
37{
38
39namespace Vulkan
40{
41
42class CDevice;
43
45{
46public:
47 CDescriptorManager(CDevice* device, const bool useDescriptorIndexing);
49
51
52 /**
53 * @return a single type descriptor set layout with the number of bindings
54 * equals to the size. The returned layout is owned by the manager.
55 */
56 VkDescriptorSetLayout GetSingleTypeDescritorSetLayout(
57 VkDescriptorType type, const uint32_t size);
58
59 VkDescriptorSet GetSingleTypeDescritorSet(
60 VkDescriptorType type, VkDescriptorSetLayout layout,
61 const std::vector<DeviceObjectUID>& texturesUID,
62 const std::vector<CTexture*>& textures);
63
64 uint32_t GetUniformSet() const;
65
67
68 void OnTextureDestroy(const DeviceObjectUID uid);
69
70 const VkDescriptorSetLayout& GetDescriptorIndexingSetLayout() const { return m_DescriptorIndexingSetLayout; }
71 const VkDescriptorSetLayout& GetUniformDescriptorSetLayout() const { return m_UniformDescriptorSetLayout; }
72 const VkDescriptorSet& GetDescriptorIndexingSet() { return m_DescriptorIndexingSet; }
73
74 const std::vector<VkDescriptorSetLayout>& GetDescriptorSetLayouts() const { return m_DescriptorSetLayouts; }
75
76private:
78 {
79 VkDescriptorSetLayout layout;
80 VkDescriptorPool pool;
82 static constexpr int16_t INVALID_INDEX = -1;
83 struct Element
84 {
85 VkDescriptorSet set = VK_NULL_HANDLE;
88 };
89 std::vector<Element> elements;
90 };
91 SingleTypePool& GetSingleTypePool(const VkDescriptorType type, const uint32_t size);
92
93 std::pair<VkDescriptorSet, bool> GetSingleTypeDescritorSetImpl(
94 VkDescriptorType type, VkDescriptorSetLayout layout,
95 const std::vector<DeviceObjectUID>& uids);
96
97 CDevice* m_Device = nullptr;
98
100
101 VkDescriptorPool m_DescriptorIndexingPool = VK_NULL_HANDLE;
102 VkDescriptorSet m_DescriptorIndexingSet = VK_NULL_HANDLE;
103 VkDescriptorSetLayout m_DescriptorIndexingSetLayout = VK_NULL_HANDLE;
104 VkDescriptorSetLayout m_UniformDescriptorSetLayout = VK_NULL_HANDLE;
105 std::vector<VkDescriptorSetLayout> m_DescriptorSetLayouts;
106
109
111 {
112 static_assert(std::numeric_limits<int16_t>::max() >= DESCRIPTOR_INDEXING_BINDING_SIZE);
114 std::vector<int16_t> elements;
115 std::unordered_map<DeviceObjectUID, int16_t> map;
116 };
117 std::array<DescriptorIndexingBindingMap, NUMBER_OF_BINDINGS_PER_DESCRIPTOR_INDEXING_SET>
119 std::unordered_map<DeviceObjectUID, uint32_t> m_TextureToBindingMap;
120
121 std::unordered_map<VkDescriptorType, std::vector<SingleTypePool>> m_SingleTypePools;
123 {
124 VkDescriptorType type = VK_DESCRIPTOR_TYPE_MAX_ENUM;
128 };
129 std::unordered_map<DeviceObjectUID, std::vector<SingleTypePoolReference>> m_UIDToSingleTypePoolMap;
130
131 using SingleTypeCacheKey = std::pair<VkDescriptorSetLayout, std::vector<DeviceObjectUID>>;
133 {
134 size_t operator()(const SingleTypeCacheKey& key) const;
135 };
136 std::unordered_map<SingleTypeCacheKey, VkDescriptorSet, SingleTypeCacheKeyHash> m_SingleTypeSets;
137
138 std::unique_ptr<ITexture> m_ErrorTexture;
139};
140
141// TODO: ideally we might want to separate a set and its mapping.
142template<typename DeviceObject>
144{
145public:
146 CSingleTypeDescriptorSetBinding(CDevice* device, const VkDescriptorType type,
147 const uint32_t size, std::unordered_map<CStrIntern, uint32_t> mapping)
148 : m_Device{device}, m_Type{type}, m_Mapping{std::move(mapping)}
149 {
150 m_BoundDeviceObjects.resize(size);
151 m_BoundUIDs.resize(size);
154 }
155
156 int32_t GetBindingSlot(const CStrIntern name) const
157 {
158 const auto it = m_Mapping.find(name);
159 return it != m_Mapping.end() ? it->second : -1;
160 }
161
162 void SetObject(const int32_t bindingSlot, DeviceObject* object)
163 {
164 if (m_BoundUIDs[bindingSlot] == object->GetUID())
165 return;
166 m_BoundUIDs[bindingSlot] = object->GetUID();
167 m_BoundDeviceObjects[bindingSlot] = object;
168 m_Outdated = true;
169 }
170
171 bool IsOutdated() const { return m_Outdated; }
172
174 {
176 m_Outdated = false;
177
178 VkDescriptorSet descriptorSet =
181 ENSURE(descriptorSet != VK_NULL_HANDLE);
182
183 return descriptorSet;
184 }
185
186 void Unbind()
187 {
188 std::fill(m_BoundDeviceObjects.begin(), m_BoundDeviceObjects.end(), nullptr);
189 std::fill(m_BoundUIDs.begin(), m_BoundUIDs.end(), INVALID_DEVICE_OBJECT_UID);
190 m_Outdated = true;
191 }
192
193 VkDescriptorSetLayout GetDescriptorSetLayout() { return m_DescriptorSetLayout; }
194
195 const std::vector<DeviceObject*>& GetBoundDeviceObjects() const { return m_BoundDeviceObjects; }
196
197private:
199 const VkDescriptorType m_Type;
200 const std::unordered_map<CStrIntern, uint32_t> m_Mapping;
201
202 bool m_Outdated{true};
203
204 VkDescriptorSetLayout m_DescriptorSetLayout{VK_NULL_HANDLE};
205
206 std::vector<DeviceObject*> m_BoundDeviceObjects;
207 std::vector<DeviceObjectUID> m_BoundUIDs;
208};
209
210} // namespace Vulkan
211
212} // namespace Backend
213
214} // namespace Renderer
215
216#endif // INCLUDED_RENDERER_BACKEND_VULKAN_DESCRIPTORMANAGER
Interned 8-bit strings.
Definition: CStrIntern.h:38
Definition: DescriptorManager.h:45
std::pair< VkDescriptorSetLayout, std::vector< DeviceObjectUID > > SingleTypeCacheKey
Definition: DescriptorManager.h:131
static constexpr uint32_t NUMBER_OF_BINDINGS_PER_DESCRIPTOR_INDEXING_SET
Definition: DescriptorManager.h:108
CDevice * m_Device
Definition: DescriptorManager.h:97
bool UseDescriptorIndexing() const
Definition: DescriptorManager.h:50
const VkDescriptorSet & GetDescriptorIndexingSet()
Definition: DescriptorManager.h:72
uint32_t GetUniformSet() const
Definition: DescriptorManager.cpp:309
VkDescriptorSetLayout GetSingleTypeDescritorSetLayout(VkDescriptorType type, const uint32_t size)
Definition: DescriptorManager.cpp:205
std::unique_ptr< ITexture > m_ErrorTexture
Definition: DescriptorManager.h:138
const VkDescriptorSetLayout & GetUniformDescriptorSetLayout() const
Definition: DescriptorManager.h:71
std::unordered_map< SingleTypeCacheKey, VkDescriptorSet, SingleTypeCacheKeyHash > m_SingleTypeSets
Definition: DescriptorManager.h:136
const VkDescriptorSetLayout & GetDescriptorIndexingSetLayout() const
Definition: DescriptorManager.h:70
static constexpr uint32_t DESCRIPTOR_INDEXING_BINDING_SIZE
Definition: DescriptorManager.h:107
bool m_UseDescriptorIndexing
Definition: DescriptorManager.h:99
std::vector< VkDescriptorSetLayout > m_DescriptorSetLayouts
Definition: DescriptorManager.h:105
std::pair< VkDescriptorSet, bool > GetSingleTypeDescritorSetImpl(VkDescriptorType type, VkDescriptorSetLayout layout, const std::vector< DeviceObjectUID > &uids)
Definition: DescriptorManager.cpp:220
std::unordered_map< DeviceObjectUID, uint32_t > m_TextureToBindingMap
Definition: DescriptorManager.h:119
uint32_t GetTextureDescriptor(CTexture *texture)
Definition: DescriptorManager.cpp:314
VkDescriptorSetLayout m_UniformDescriptorSetLayout
Definition: DescriptorManager.h:104
VkDescriptorPool m_DescriptorIndexingPool
Definition: DescriptorManager.h:101
std::array< DescriptorIndexingBindingMap, NUMBER_OF_BINDINGS_PER_DESCRIPTOR_INDEXING_SET > m_DescriptorIndexingBindings
Definition: DescriptorManager.h:118
VkDescriptorSetLayout m_DescriptorIndexingSetLayout
Definition: DescriptorManager.h:103
VkDescriptorSet m_DescriptorIndexingSet
Definition: DescriptorManager.h:102
std::unordered_map< VkDescriptorType, std::vector< SingleTypePool > > m_SingleTypePools
Definition: DescriptorManager.h:121
void OnTextureDestroy(const DeviceObjectUID uid)
Definition: DescriptorManager.cpp:361
VkDescriptorSet GetSingleTypeDescritorSet(VkDescriptorType type, VkDescriptorSetLayout layout, const std::vector< DeviceObjectUID > &texturesUID, const std::vector< CTexture * > &textures)
Definition: DescriptorManager.cpp:262
CDescriptorManager(CDevice *device, const bool useDescriptorIndexing)
Definition: DescriptorManager.cpp:41
std::unordered_map< DeviceObjectUID, std::vector< SingleTypePoolReference > > m_UIDToSingleTypePoolMap
Definition: DescriptorManager.h:129
SingleTypePool & GetSingleTypePool(const VkDescriptorType type, const uint32_t size)
Definition: DescriptorManager.cpp:158
~CDescriptorManager()
Definition: DescriptorManager.cpp:134
const std::vector< VkDescriptorSetLayout > & GetDescriptorSetLayouts() const
Definition: DescriptorManager.h:74
Definition: Device.h:60
CDescriptorManager & GetDescriptorManager()
Definition: Device.h:163
VkDescriptorSetLayout GetDescriptorSetLayout()
Definition: DescriptorManager.h:193
std::vector< DeviceObject * > m_BoundDeviceObjects
Definition: DescriptorManager.h:206
CSingleTypeDescriptorSetBinding(CDevice *device, const VkDescriptorType type, const uint32_t size, std::unordered_map< CStrIntern, uint32_t > mapping)
Definition: DescriptorManager.h:146
bool m_Outdated
Definition: DescriptorManager.h:202
void Unbind()
Definition: DescriptorManager.h:186
VkDescriptorSetLayout m_DescriptorSetLayout
Definition: DescriptorManager.h:204
int32_t GetBindingSlot(const CStrIntern name) const
Definition: DescriptorManager.h:156
void SetObject(const int32_t bindingSlot, DeviceObject *object)
Definition: DescriptorManager.h:162
const std::vector< DeviceObject * > & GetBoundDeviceObjects() const
Definition: DescriptorManager.h:195
const VkDescriptorType m_Type
Definition: DescriptorManager.h:199
VkDescriptorSet UpdateAndReturnDescriptorSet()
Definition: DescriptorManager.h:173
CDevice *const m_Device
Definition: DescriptorManager.h:198
const std::unordered_map< CStrIntern, uint32_t > m_Mapping
Definition: DescriptorManager.h:200
std::vector< DeviceObjectUID > m_BoundUIDs
Definition: DescriptorManager.h:207
bool IsOutdated() const
Definition: DescriptorManager.h:171
Definition: Texture.h:41
#define ENSURE(expr)
ensure the expression <expr> evaluates to non-zero.
Definition: debug.h:277
static constexpr DeviceObjectUID INVALID_DEVICE_OBJECT_UID
Definition: DeviceObjectUID.h:41
uint32_t DeviceObjectUID
Unique identifier for a device object.
Definition: DeviceObjectUID.h:40
Backend
Definition: Backend.h:28
Definition: VideoMode.h:29
Definition: ShaderDefines.cpp:31
std::vector< int16_t > elements
Definition: DescriptorManager.h:114
std::unordered_map< DeviceObjectUID, int16_t > map
Definition: DescriptorManager.h:115
size_t operator()(const SingleTypeCacheKey &key) const
Definition: DescriptorManager.cpp:211
VkDescriptorType type
Definition: DescriptorManager.h:124
VkDescriptorSet set
Definition: DescriptorManager.h:85
static constexpr int16_t INVALID_INDEX
Definition: DescriptorManager.h:82
int16_t firstFreeIndex
Definition: DescriptorManager.h:81
VkDescriptorPool pool
Definition: DescriptorManager.h:80
std::vector< Element > elements
Definition: DescriptorManager.h:89
VkDescriptorSetLayout layout
Definition: DescriptorManager.h:79
unsigned int uint32_t
Definition: wposix_types.h:53
short int16_t
Definition: wposix_types.h:38
unsigned char uint8_t
Definition: wposix_types.h:51
pthread_key_t key
Definition: wpthread.cpp:140