Pyrogenesis HEAD
Pyrogenesis, a RTS Engine
Device.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_DEVICE
19#define INCLUDED_RENDERER_BACKEND_VULKAN_DEVICE
20
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
37typedef struct SDL_Window SDL_Window;
38
39namespace Renderer
40{
41
42namespace Backend
43{
44
45namespace Vulkan
46{
47
48static constexpr size_t NUMBER_OF_FRAMES_IN_FLIGHT = 3;
49
50class CBuffer;
52class CFramebuffer;
55class CSamplerManager;
57class CSwapChain;
58
59class CDevice final : public IDevice
60{
61public:
62 /**
63 * Creates the Vulkan device.
64 */
65 static std::unique_ptr<CDevice> Create(SDL_Window* window);
66
67 ~CDevice() override;
68
69 Backend GetBackend() const override { return Backend::VULKAN; }
70
71 const std::string& GetName() const override { return m_Name; }
72 const std::string& GetVersion() const override { return m_Version; }
73 const std::string& GetDriverInformation() const override { return m_DriverInformation; }
74 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<IComputePipelineState> CreateComputePipelineState(
84 const SComputePipelineStateDesc& pipelineStateDesc) override;
85
86 std::unique_ptr<IVertexInputLayout> CreateVertexInputLayout(
87 const PS::span<const SVertexAttributeFormat> attributes) override;
88
89 std::unique_ptr<ITexture> CreateTexture(
90 const char* name, const ITexture::Type type, const uint32_t usage,
91 const Format format, const uint32_t width, const uint32_t height,
92 const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount, const uint32_t sampleCount) override;
93
94 std::unique_ptr<ITexture> CreateTexture2D(
95 const char* name, const uint32_t usage,
96 const Format format, const uint32_t width, const uint32_t height,
97 const Sampler::Desc& defaultSamplerDesc, const uint32_t MIPLevelCount = 1, const uint32_t sampleCount = 1) override;
98
99 std::unique_ptr<IFramebuffer> CreateFramebuffer(
100 const char* name, SColorAttachment* colorAttachment,
101 SDepthStencilAttachment* depthStencilAttachment) override;
102
103 std::unique_ptr<IBuffer> CreateBuffer(
104 const char* name, const IBuffer::Type type, const uint32_t size, const uint32_t usage) override;
105
106 std::unique_ptr<CBuffer> CreateCBuffer(
107 const char* name, const IBuffer::Type type, const uint32_t size, const uint32_t usage);
108
109 std::unique_ptr<IShaderProgram> CreateShaderProgram(
110 const CStr& name, const CShaderDefines& defines) override;
111
112 bool AcquireNextBackbuffer() override;
113
115 const AttachmentLoadOp colorAttachmentLoadOp,
116 const AttachmentStoreOp colorAttachmentStoreOp,
117 const AttachmentLoadOp depthStencilAttachmentLoadOp,
118 const AttachmentStoreOp depthStencilAttachmentStoreOp) override;
119
120 void Present() override;
121
122 void OnWindowResize(const uint32_t width, const uint32_t height) override;
123
124 bool IsTextureFormatSupported(const Format format) const override;
125
126 bool IsFramebufferFormatSupported(const Format format) const override;
127
129 const uint32_t usage, const bool depth, const bool stencil) const override;
130
131 const Capabilities& GetCapabilities() const override { return m_Capabilities; }
132
133 VkDevice GetVkDevice() { return m_Device; }
134
135 VmaAllocator GetVMAAllocator() { return m_VMAAllocator; }
136
138 VkObjectType type, const void* handle, const VmaAllocation allocation)
139 {
140 ScheduleObjectToDestroy(type, reinterpret_cast<uint64_t>(handle), allocation);
141 }
142
144 VkObjectType type, const uint64_t handle, const VmaAllocation allocation);
145
147
148 void SetObjectName(VkObjectType type, const void* handle, const char* name)
149 {
150 SetObjectName(type, reinterpret_cast<uint64_t>(handle), name);
151 }
152
153 void SetObjectName(VkObjectType type, const uint64_t handle, const char* name);
154
155 std::unique_ptr<CRingCommandContext> CreateRingCommandContext(const size_t size);
156
158
160
162
164
166
168
170
171private:
173
174 void RecreateSwapChain();
175 bool IsSwapChainValid();
176 void ProcessObjectToDestroyQueue(const bool ignoreFrameID = false);
177 void ProcessTextureToDestroyQueue(const bool ignoreFrameID = false);
178
179 bool IsFormatSupportedForUsage(const Format format, const uint32_t usage) const;
180
181 std::string m_Name;
182 std::string m_Version;
183 std::string m_VendorID;
185 std::vector<std::string> m_Extensions;
186 std::vector<std::string> m_InstanceExtensions;
187 std::vector<std::string> m_ValidationLayers;
188
190 std::vector<SAvailablePhysicalDevice> m_AvailablePhysicalDevices;
191
193
194 VkInstance m_Instance = VK_NULL_HANDLE;
195
196 VkDebugUtilsMessengerEXT m_DebugMessenger = VK_NULL_HANDLE;
197
199 VkSurfaceKHR m_Surface = VK_NULL_HANDLE;
200 VkDevice m_Device = VK_NULL_HANDLE;
201 VmaAllocator m_VMAAllocator = VK_NULL_HANDLE;
202 VkQueue m_GraphicsQueue = VK_NULL_HANDLE;
203 uint32_t m_GraphicsQueueFamilyIndex = std::numeric_limits<uint32_t>::max();
204
205 std::unique_ptr<CSwapChain> m_SwapChain;
206 std::unique_ptr<CTexture> m_BackbufferReadbackTexture;
207
209
211 {
213 VkObjectType type;
215 VmaAllocation allocation;
216 };
217 std::queue<ObjectToDestroy> m_ObjectToDestroyQueue;
218 std::queue<std::pair<uint32_t, DeviceObjectUID>> m_TextureToDestroyQueue;
219
220 std::unique_ptr<CRenderPassManager> m_RenderPassManager;
221 std::unique_ptr<CSamplerManager> m_SamplerManager;
222 std::unique_ptr<CDescriptorManager> m_DescriptorManager;
223 std::unique_ptr<CSubmitScheduler> m_SubmitScheduler;
224
226};
227
228} // namespace Vulkan
229
230} // namespace Backend
231
232} // namespace Renderer
233
234#endif // INCLUDED_RENDERER_BACKEND_VULKAN_DEVICE
struct SDL_Window SDL_Window
Definition: VideoMode.h:26
Represents a mapping of name strings to value strings, for use with #if and #ifdef and similar condit...
Definition: ShaderDefines.h:147
Simplifed version of std::span (C++20) as we don't support the original one yet.
Definition: Span.h:37
Type
Definition: IBuffer.h:35
Definition: IDevice.h:48
IFramebuffer stores attachments which should be used by backend as rendering destinations.
Definition: IFramebuffer.h:85
Type
Definition: ITexture.h:37
Definition: Buffer.h:39
Definition: DescriptorManager.h:45
Definition: Device.h:60
void SetObjectName(VkObjectType type, const void *handle, const char *name)
Definition: Device.h:148
VkDevice GetVkDevice()
Definition: Device.h:133
VmaAllocator m_VMAAllocator
Definition: Device.h:201
bool IsFramebufferFormatSupported(const Format format) const override
Definition: Device.cpp:851
std::unique_ptr< IShaderProgram > CreateShaderProgram(const CStr &name, const CShaderDefines &defines) override
Definition: Device.cpp:763
void Present() override
Presents the backbuffer to the swapchain queue to be flipped on a screen.
Definition: Device.cpp:800
bool IsFormatSupportedForUsage(const Format format, const uint32_t usage) const
Definition: Device.cpp:895
const std::string & GetVersion() const override
Definition: Device.h:72
std::string m_DriverInformation
Definition: Device.h:184
Backend GetBackend() const override
Definition: Device.h:69
std::vector< std::string > m_InstanceExtensions
Definition: Device.h:186
CRenderPassManager & GetRenderPassManager()
Definition: Device.h:159
std::string m_Version
Definition: Device.h:182
VkQueue m_GraphicsQueue
Definition: Device.h:202
std::queue< std::pair< uint32_t, DeviceObjectUID > > m_TextureToDestroyQueue
Definition: Device.h:218
SDL_Window * m_Window
Definition: Device.h:198
const std::string & GetDriverInformation() const override
Definition: Device.h:73
void Report(const ScriptRequest &rq, JS::HandleValue settings) override
Definition: Device.cpp:679
CSamplerManager & GetSamplerManager()
Definition: Device.h:161
uint32_t m_GraphicsQueueFamilyIndex
Definition: Device.h:203
VkInstance m_Instance
Definition: Device.h:194
void RecreateSwapChain()
Definition: Device.cpp:943
bool IsSwapChainValid()
Definition: Device.cpp:952
std::unique_ptr< IBuffer > CreateBuffer(const char *name, const IBuffer::Type type, const uint32_t size, const uint32_t usage) override
Definition: Device.cpp:751
std::unique_ptr< CSubmitScheduler > m_SubmitScheduler
Definition: Device.h:223
std::unique_ptr< ITexture > CreateTexture(const char *name, const ITexture::Type type, const uint32_t usage, const Format format, const uint32_t width, const uint32_t height, const Sampler::Desc &defaultSamplerDesc, const uint32_t MIPLevelCount, const uint32_t sampleCount) override
Definition: Device.cpp:723
std::string m_VendorID
Definition: Device.h:183
CTexture * GetOrCreateBackbufferReadbackTexture()
Definition: Device.cpp:1022
std::unique_ptr< CRenderPassManager > m_RenderPassManager
Definition: Device.h:220
std::string m_Name
Definition: Device.h:181
CTexture * GetCurrentBackbufferTexture()
Definition: Device.cpp:1017
SAvailablePhysicalDevice m_ChoosenDevice
Definition: Device.h:189
VkSurfaceKHR m_Surface
Definition: Device.h:199
const std::vector< std::string > & GetExtensions() const override
Definition: Device.h:74
void ScheduleTextureToDestroy(const DeviceObjectUID uid)
Definition: Device.cpp:920
std::unique_ptr< IFramebuffer > CreateFramebuffer(const char *name, SColorAttachment *colorAttachment, SDepthStencilAttachment *depthStencilAttachment) override
Definition: Device.cpp:743
~CDevice() override
Definition: Device.cpp:642
void ProcessTextureToDestroyQueue(const bool ignoreFrameID=false)
Definition: Device.cpp:1007
VmaAllocator GetVMAAllocator()
Definition: Device.h:135
static std::unique_ptr< CDevice > Create(SDL_Window *window)
Creates the Vulkan device.
Definition: Device.cpp:189
std::unique_ptr< IVertexInputLayout > CreateVertexInputLayout(const PS::span< const SVertexAttributeFormat > attributes) override
Creates a vertex input layout.
Definition: Device.cpp:717
const SAvailablePhysicalDevice & GetChoosenPhysicalDevice() const
Definition: Device.h:157
std::vector< std::string > m_ValidationLayers
Definition: Device.h:187
std::vector< std::string > m_Extensions
Definition: Device.h:185
std::unique_ptr< IGraphicsPipelineState > CreateGraphicsPipelineState(const SGraphicsPipelineStateDesc &pipelineStateDesc) override
Creates a graphics pipeline state.
Definition: Device.cpp:705
DeviceObjectUID GenerateNextDeviceObjectUID()
Definition: Device.cpp:1038
const std::string & GetName() const override
Definition: Device.h:71
VkDebugUtilsMessengerEXT m_DebugMessenger
Definition: Device.h:196
std::unique_ptr< CTexture > m_BackbufferReadbackTexture
Definition: Device.h:206
DeviceObjectUID m_LastAvailableUID
Definition: Device.h:225
CDescriptorManager & GetDescriptorManager()
Definition: Device.h:163
std::unique_ptr< CSwapChain > m_SwapChain
Definition: Device.h:205
IFramebuffer * GetCurrentBackbuffer(const AttachmentLoadOp colorAttachmentLoadOp, const AttachmentStoreOp colorAttachmentStoreOp, const AttachmentLoadOp depthStencilAttachmentLoadOp, const AttachmentStoreOp depthStencilAttachmentStoreOp) override
Returns a framebuffer for the current backbuffer with the required attachment operations.
Definition: Device.cpp:789
Format GetPreferredDepthStencilFormat(const uint32_t usage, const bool depth, const bool stencil) const override
Returns the most suitable format for the usage.
Definition: Device.cpp:861
std::unique_ptr< CDescriptorManager > m_DescriptorManager
Definition: Device.h:222
uint32_t m_FrameID
Definition: Device.h:208
void OnWindowResize(const uint32_t width, const uint32_t height) override
Should be called on window surface resize.
Definition: Device.cpp:815
void ProcessObjectToDestroyQueue(const bool ignoreFrameID=false)
Definition: Device.cpp:957
std::unique_ptr< CSamplerManager > m_SamplerManager
Definition: Device.h:221
void ScheduleObjectToDestroy(VkObjectType type, const void *handle, const VmaAllocation allocation)
Definition: Device.h:137
Capabilities m_Capabilities
Definition: Device.h:192
std::queue< ObjectToDestroy > m_ObjectToDestroyQueue
Definition: Device.h:217
std::unique_ptr< IDeviceCommandContext > CreateCommandContext() override
Definition: Device.cpp:769
std::unique_ptr< CRingCommandContext > CreateRingCommandContext(const size_t size)
Definition: Device.cpp:937
const Capabilities & GetCapabilities() const override
Definition: Device.h:131
VkDevice m_Device
Definition: Device.h:200
std::unique_ptr< CBuffer > CreateCBuffer(const char *name, const IBuffer::Type type, const uint32_t size, const uint32_t usage)
Definition: Device.cpp:757
bool IsTextureFormatSupported(const Format format) const override
Definition: Device.cpp:825
std::unique_ptr< ITexture > CreateTexture2D(const char *name, const uint32_t usage, const Format format, const uint32_t width, const uint32_t height, const Sampler::Desc &defaultSamplerDesc, const uint32_t MIPLevelCount=1, const uint32_t sampleCount=1) override
Definition: Device.cpp:733
bool AcquireNextBackbuffer() override
Acquires a backbuffer for rendering a frame.
Definition: Device.cpp:774
std::vector< SAvailablePhysicalDevice > m_AvailablePhysicalDevices
Definition: Device.h:190
std::unique_ptr< IComputePipelineState > CreateComputePipelineState(const SComputePipelineStateDesc &pipelineStateDesc) override
Creates a compute pipeline state.
Definition: Device.cpp:711
Definition: Framebuffer.h:41
A helper class to store unique render passes.
Definition: RenderPassManager.h:43
A simple helper class to decouple command buffers rotation from frames presenting.
Definition: RingCommandContext.h:48
A helper class to store unique samplers.
Definition: SamplerManager.h:44
A helper class to batch VkQueueSubmit calls and track VkCommandBuffer usages properly.
Definition: SubmitScheduler.h:47
Definition: SwapChain.h:44
Definition: Texture.h:41
Spidermonkey maintains some 'local' state via the JSContext* object.
Definition: ScriptRequest.h:60
uint32_t DeviceObjectUID
Unique identifier for a device object.
Definition: DeviceObjectUID.h:40
static constexpr size_t NUMBER_OF_FRAMES_IN_FLIGHT
Definition: Device.h:48
Format
Definition: Format.h:28
AttachmentStoreOp
Store operation is set for each attachment, what should be done with its content on EndFramebufferPas...
Definition: IFramebuffer.h:52
Backend
Definition: Backend.h:28
AttachmentLoadOp
Load operation is set for each attachment, what should be done with its content on BeginFramebufferPa...
Definition: IFramebuffer.h:37
Definition: VideoMode.h:29
Definition: IFramebuffer.h:60
Definition: PipelineState.h:175
Definition: IFramebuffer.h:68
Definition: PipelineState.h:165
Definition: Sampler.h:57
uint32_t frameID
Definition: Device.h:212
VkObjectType type
Definition: Device.h:213
VmaAllocation allocation
Definition: Device.h:215
Structure to store all information that might be useful on device selection.
Definition: DeviceSelection.h:40
unsigned int uint32_t
Definition: wposix_types.h:53
unsigned long long uint64_t
Definition: wposix_types.h:57