Line data Source code
1 : /* Copyright (C) 2023 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 "renderer/backend/Sampler.h"
22 : #include "renderer/backend/vulkan/Texture.h"
23 :
24 : #include <glad/vulkan.h>
25 : #include <limits>
26 : #include <memory>
27 : #include <unordered_map>
28 : #include <utility>
29 : #include <vector>
30 :
31 : namespace Renderer
32 : {
33 :
34 : namespace Backend
35 : {
36 :
37 : namespace Vulkan
38 : {
39 :
40 : class CDevice;
41 :
42 : class CDescriptorManager
43 : {
44 : public:
45 : CDescriptorManager(CDevice* device, const bool useDescriptorIndexing);
46 : ~CDescriptorManager();
47 :
48 0 : bool UseDescriptorIndexing() const { return m_UseDescriptorIndexing; }
49 :
50 : /**
51 : * @return a single type descriptor set layout with the number of bindings
52 : * equals to the size. The returned layout is owned by the manager.
53 : */
54 : VkDescriptorSetLayout GetSingleTypeDescritorSetLayout(
55 : VkDescriptorType type, const uint32_t size);
56 :
57 : VkDescriptorSet GetSingleTypeDescritorSet(
58 : VkDescriptorType type, VkDescriptorSetLayout layout,
59 : const std::vector<CTexture::UID>& texturesUID,
60 : const std::vector<CTexture*>& textures);
61 :
62 : uint32_t GetUniformSet() const;
63 :
64 : uint32_t GetTextureDescriptor(CTexture* texture);
65 : void OnTextureDestroy(const CTexture::UID uid);
66 :
67 : const VkDescriptorSetLayout& GetDescriptorIndexingSetLayout() const { return m_DescriptorIndexingSetLayout; }
68 0 : const VkDescriptorSetLayout& GetUniformDescriptorSetLayout() const { return m_UniformDescriptorSetLayout; }
69 0 : const VkDescriptorSet& GetDescriptorIndexingSet() { return m_DescriptorIndexingSet; }
70 :
71 0 : const std::vector<VkDescriptorSetLayout>& GetDescriptorSetLayouts() const { return m_DescriptorSetLayouts; }
72 :
73 : private:
74 0 : struct SingleTypePool
75 : {
76 : VkDescriptorSetLayout layout;
77 : VkDescriptorPool pool;
78 : int16_t firstFreeIndex = 0;
79 : std::vector<std::pair<VkDescriptorSet, int16_t>> elements;
80 : };
81 : SingleTypePool& GetSingleTypePool(const VkDescriptorType type, const uint32_t size);
82 :
83 : CDevice* m_Device = nullptr;
84 :
85 : bool m_UseDescriptorIndexing = false;
86 :
87 : VkDescriptorPool m_DescriptorIndexingPool = VK_NULL_HANDLE;
88 : VkDescriptorSet m_DescriptorIndexingSet = VK_NULL_HANDLE;
89 : VkDescriptorSetLayout m_DescriptorIndexingSetLayout = VK_NULL_HANDLE;
90 : VkDescriptorSetLayout m_UniformDescriptorSetLayout = VK_NULL_HANDLE;
91 : std::vector<VkDescriptorSetLayout> m_DescriptorSetLayouts;
92 :
93 : static constexpr uint32_t DESCRIPTOR_INDEXING_BINDING_SIZE = 16384;
94 : static constexpr uint32_t NUMBER_OF_BINDINGS_PER_DESCRIPTOR_INDEXING_SET = 3;
95 :
96 0 : struct DescriptorIndexingBindingMap
97 : {
98 : static_assert(std::numeric_limits<int16_t>::max() >= DESCRIPTOR_INDEXING_BINDING_SIZE);
99 : int16_t firstFreeIndex = 0;
100 : std::vector<int16_t> elements;
101 : std::unordered_map<CTexture::UID, int16_t> map;
102 : };
103 : std::array<DescriptorIndexingBindingMap, NUMBER_OF_BINDINGS_PER_DESCRIPTOR_INDEXING_SET>
104 : m_DescriptorIndexingBindings;
105 : std::unordered_map<CTexture::UID, uint32_t> m_TextureToBindingMap;
106 :
107 : std::unordered_map<VkDescriptorType, std::vector<SingleTypePool>> m_SingleTypePools;
108 : std::unordered_map<CTexture::UID, std::vector<std::tuple<VkDescriptorType, uint8_t, int16_t>>> m_TextureSingleTypePoolMap;
109 :
110 : using SingleTypeCacheKey = std::pair<VkDescriptorSetLayout, std::vector<CTexture::UID>>;
111 : struct SingleTypeCacheKeyHash
112 : {
113 : size_t operator()(const SingleTypeCacheKey& key) const;
114 : };
115 : std::unordered_map<SingleTypeCacheKey, VkDescriptorSet, SingleTypeCacheKeyHash> m_SingleTypeSets;
116 : };
117 :
118 : } // namespace Vulkan
119 :
120 : } // namespace Backend
121 :
122 : } // namespace Renderer
123 :
124 : #endif // INCLUDED_RENDERER_BACKEND_VULKAN_DESCRIPTORMANAGER
|