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_DEVICE
19 : #define INCLUDED_RENDERER_BACKEND_VULKAN_DEVICE
20 :
21 : #include "renderer/backend/IDevice.h"
22 : #include "renderer/backend/vulkan/DeviceForward.h"
23 : #include "renderer/backend/vulkan/DeviceSelection.h"
24 : #include "renderer/backend/vulkan/Texture.h"
25 : #include "renderer/backend/vulkan/VMA.h"
26 : #include "scriptinterface/ScriptForward.h"
27 :
28 : #include <glad/vulkan.h>
29 : #include <memory>
30 : #include <limits>
31 : #include <queue>
32 : #include <string>
33 : #include <tuple>
34 : #include <unordered_map>
35 : #include <vector>
36 :
37 : typedef struct SDL_Window SDL_Window;
38 :
39 : namespace Renderer
40 : {
41 :
42 : namespace Backend
43 : {
44 :
45 : namespace Vulkan
46 : {
47 :
48 : static constexpr size_t NUMBER_OF_FRAMES_IN_FLIGHT = 3;
49 :
50 : class CBuffer;
51 : class CDescriptorManager;
52 : class CFramebuffer;
53 : class CRenderPassManager;
54 : class CRingCommandContext;
55 : class CSamplerManager;
56 : class CSubmitScheduler;
57 : class CSwapChain;
58 :
59 0 : class CDevice final : public IDevice
60 : {
61 : public:
62 : /**
63 : * Creates the Vulkan device.
64 : */
65 : static std::unique_ptr<CDevice> Create(SDL_Window* window);
66 :
67 : ~CDevice() override;
68 :
69 0 : Backend GetBackend() const override { return Backend::VULKAN; }
70 :
71 0 : const std::string& GetName() const override { return m_Name; }
72 0 : const std::string& GetVersion() const override { return m_Version; }
73 0 : const std::string& GetDriverInformation() const override { return m_DriverInformation; }
74 0 : const std::vector<std::string>& GetExtensions() const override { return m_Extensions; }
75 :
76 : void Report(const ScriptRequest& rq, JS::HandleValue settings) override;
77 :
78 : std::unique_ptr<IDeviceCommandContext> CreateCommandContext() override;
79 :
80 : std::unique_ptr<IGraphicsPipelineState> CreateGraphicsPipelineState(
81 : const SGraphicsPipelineStateDesc& pipelineStateDesc) override;
82 :
83 : std::unique_ptr<IVertexInputLayout> CreateVertexInputLayout(
84 : const PS::span<const SVertexAttributeFormat> attributes) override;
85 :
86 : std::unique_ptr<ITexture> CreateTexture(
87 : const char* name, const ITexture::Type type, const uint32_t usage,
88 : const Format format, const uint32_t width, const uint32_t height,
89 : const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount, const uint32_t sampleCount) override;
90 :
91 : std::unique_ptr<ITexture> CreateTexture2D(
92 : const char* name, const uint32_t usage,
93 : const Format format, const uint32_t width, const uint32_t height,
94 : const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount = 1, const uint32_t sampleCount = 1) override;
95 :
96 : std::unique_ptr<IFramebuffer> CreateFramebuffer(
97 : const char* name, SColorAttachment* colorAttachment,
98 : SDepthStencilAttachment* depthStencilAttachment) override;
99 :
100 : std::unique_ptr<IBuffer> CreateBuffer(
101 : const char* name, const IBuffer::Type type, const uint32_t size, const bool dynamic) override;
102 :
103 : std::unique_ptr<CBuffer> CreateCBuffer(
104 : const char* name, const IBuffer::Type type, const uint32_t size, const bool dynamic);
105 :
106 : std::unique_ptr<IShaderProgram> CreateShaderProgram(
107 : const CStr& name, const CShaderDefines& defines) override;
108 :
109 : bool AcquireNextBackbuffer() override;
110 :
111 : IFramebuffer* GetCurrentBackbuffer(
112 : const AttachmentLoadOp colorAttachmentLoadOp,
113 : const AttachmentStoreOp colorAttachmentStoreOp,
114 : const AttachmentLoadOp depthStencilAttachmentLoadOp,
115 : const AttachmentStoreOp depthStencilAttachmentStoreOp) override;
116 :
117 : void Present() override;
118 :
119 : void OnWindowResize(const uint32_t width, const uint32_t height) override;
120 :
121 : bool IsTextureFormatSupported(const Format format) const override;
122 :
123 : bool IsFramebufferFormatSupported(const Format format) const override;
124 :
125 : Format GetPreferredDepthStencilFormat(
126 : const uint32_t usage, const bool depth, const bool stencil) const override;
127 :
128 0 : const Capabilities& GetCapabilities() const override { return m_Capabilities; }
129 :
130 0 : VkDevice GetVkDevice() { return m_Device; }
131 :
132 0 : VmaAllocator GetVMAAllocator() { return m_VMAAllocator; }
133 :
134 0 : void ScheduleObjectToDestroy(
135 : VkObjectType type, const void* handle, const VmaAllocation allocation)
136 : {
137 0 : ScheduleObjectToDestroy(type, reinterpret_cast<uint64_t>(handle), allocation);
138 0 : }
139 :
140 : void ScheduleObjectToDestroy(
141 : VkObjectType type, const uint64_t handle, const VmaAllocation allocation);
142 :
143 : void ScheduleTextureToDestroy(const CTexture::UID uid);
144 :
145 0 : void SetObjectName(VkObjectType type, const void* handle, const char* name)
146 : {
147 0 : SetObjectName(type, reinterpret_cast<uint64_t>(handle), name);
148 0 : }
149 :
150 : void SetObjectName(VkObjectType type, const uint64_t handle, const char* name);
151 :
152 : std::unique_ptr<CRingCommandContext> CreateRingCommandContext(const size_t size);
153 :
154 0 : const SAvailablePhysicalDevice& GetChoosenPhysicalDevice() const { return m_ChoosenDevice; }
155 :
156 0 : CRenderPassManager& GetRenderPassManager() { return *m_RenderPassManager; }
157 :
158 0 : CSamplerManager& GetSamplerManager() { return *m_SamplerManager; }
159 :
160 0 : CDescriptorManager& GetDescriptorManager() { return *m_DescriptorManager; }
161 :
162 : private:
163 : CDevice();
164 :
165 : void RecreateSwapChain();
166 : bool IsSwapChainValid();
167 : void ProcessObjectToDestroyQueue(const bool ignoreFrameID = false);
168 : void ProcessTextureToDestroyQueue(const bool ignoreFrameID = false);
169 :
170 : bool IsFormatSupportedForUsage(const Format format, const uint32_t usage) const;
171 :
172 : std::string m_Name;
173 : std::string m_Version;
174 : std::string m_VendorID;
175 : std::string m_DriverInformation;
176 : std::vector<std::string> m_Extensions;
177 : std::vector<std::string> m_InstanceExtensions;
178 : std::vector<std::string> m_ValidationLayers;
179 :
180 : SAvailablePhysicalDevice m_ChoosenDevice{};
181 : std::vector<SAvailablePhysicalDevice> m_AvailablePhysicalDevices;
182 :
183 : Capabilities m_Capabilities{};
184 :
185 : VkInstance m_Instance = VK_NULL_HANDLE;
186 :
187 : VkDebugUtilsMessengerEXT m_DebugMessenger = VK_NULL_HANDLE;
188 :
189 : SDL_Window* m_Window = nullptr;
190 : VkSurfaceKHR m_Surface = VK_NULL_HANDLE;
191 : VkDevice m_Device = VK_NULL_HANDLE;
192 : VmaAllocator m_VMAAllocator = VK_NULL_HANDLE;
193 : VkQueue m_GraphicsQueue = VK_NULL_HANDLE;
194 0 : uint32_t m_GraphicsQueueFamilyIndex = std::numeric_limits<uint32_t>::max();
195 :
196 : std::unique_ptr<CSwapChain> m_SwapChain;
197 :
198 : uint32_t m_FrameID = 0;
199 :
200 : struct ObjectToDestroy
201 : {
202 : uint32_t frameID;
203 : VkObjectType type;
204 : uint64_t handle;
205 : VmaAllocation allocation;
206 : };
207 : std::queue<ObjectToDestroy> m_ObjectToDestroyQueue;
208 : std::queue<std::pair<uint32_t, CTexture::UID>> m_TextureToDestroyQueue;
209 :
210 : std::unique_ptr<CRenderPassManager> m_RenderPassManager;
211 : std::unique_ptr<CSamplerManager> m_SamplerManager;
212 : std::unique_ptr<CDescriptorManager> m_DescriptorManager;
213 : std::unique_ptr<CSubmitScheduler> m_SubmitScheduler;
214 : };
215 :
216 : } // namespace Vulkan
217 :
218 : } // namespace Backend
219 :
220 : } // namespace Renderer
221 :
222 : #endif // INCLUDED_RENDERER_BACKEND_VULKAN_DEVICE
|