Pyrogenesis  trunk
Device.h
Go to the documentation of this file.
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 
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;
55 class CSamplerManager;
56 class CSubmitScheduler;
57 class CSwapChain;
58 
59 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  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<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 
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 
126  const uint32_t usage, const bool depth, const bool stencil) const override;
127 
128  const Capabilities& GetCapabilities() const override { return m_Capabilities; }
129 
130  VkDevice GetVkDevice() { return m_Device; }
131 
133 
135  VkObjectType type, const void* handle, const VmaAllocation allocation)
136  {
137  ScheduleObjectToDestroy(type, reinterpret_cast<uint64_t>(handle), allocation);
138  }
139 
141  VkObjectType type, const uint64_t handle, const VmaAllocation allocation);
142 
143  void ScheduleTextureToDestroy(const CTexture::UID uid);
144 
145  void SetObjectName(VkObjectType type, const void* handle, const char* name)
146  {
147  SetObjectName(type, reinterpret_cast<uint64_t>(handle), name);
148  }
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 
155 
157 
159 
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 
181  std::vector<SAvailablePhysicalDevice> m_AvailablePhysicalDevices;
182 
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  uint32_t m_GraphicsQueueFamilyIndex = std::numeric_limits<uint32_t>::max();
195 
196  std::unique_ptr<CSwapChain> m_SwapChain;
197 
199 
201  {
203  VkObjectType type;
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
const std::vector< std::string > & GetExtensions() const override
Definition: Device.h:74
AttachmentLoadOp
Load operation is set for each attachment, what should be done with its content on BeginFramebufferPa...
Definition: IFramebuffer.h:36
std::unique_ptr< IFramebuffer > CreateFramebuffer(const char *name, SColorAttachment *colorAttachment, SDepthStencilAttachment *depthStencilAttachment) override
Definition: Device.cpp:706
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:752
void SetObjectName(VkObjectType type, const void *handle, const char *name)
Definition: Device.h:145
std::unique_ptr< CRingCommandContext > CreateRingCommandContext(const size_t size)
Definition: Device.cpp:897
CSamplerManager & GetSamplerManager()
Definition: Device.h:158
Type
Definition: ITexture.h:36
AttachmentStoreOp
Store operation is set for each attachment, what should be done with its content on EndFramebufferPas...
Definition: IFramebuffer.h:51
Type
Definition: IBuffer.h:34
std::vector< SAvailablePhysicalDevice > m_AvailablePhysicalDevices
Definition: Device.h:181
bool IsFramebufferFormatSupported(const Format format) const override
Definition: Device.cpp:811
const std::string & GetVersion() const override
Definition: Device.h:72
VkDevice m_Device
Definition: Device.h:191
Definition: Buffer.h:38
std::unique_ptr< IBuffer > CreateBuffer(const char *name, const IBuffer::Type type, const uint32_t size, const bool dynamic) override
Definition: Device.cpp:714
A helper class to batch VkQueueSubmit calls and track VkCommandBuffer usages properly.
Definition: SubmitScheduler.h:46
std::vector< std::string > m_ValidationLayers
Definition: Device.h:178
void Present() override
Presents the backbuffer to the swapchain queue to be flipped on a screen.
Definition: Device.cpp:763
uint32_t frameID
Definition: Device.h:202
std::unique_ptr< CDescriptorManager > m_DescriptorManager
Definition: Device.h:212
void Report(const ScriptRequest &rq, JS::HandleValue settings) override
Definition: Device.cpp:648
static std::unique_ptr< CDevice > Create(SDL_Window *window)
Creates the Vulkan device.
Definition: Device.cpp:188
A helper class to store unique samplers.
Definition: SamplerManager.h:43
Definition: SwapChain.h:43
VmaAllocation allocation
Definition: Device.h:205
A helper class to store unique render passes.
Definition: RenderPassManager.h:42
void RecreateSwapChain()
Definition: Device.cpp:903
Definition: Device.h:59
void ProcessObjectToDestroyQueue(const bool ignoreFrameID=false)
Definition: Device.cpp:916
std::vector< std::string > m_Extensions
Definition: Device.h:176
static constexpr size_t NUMBER_OF_FRAMES_IN_FLIGHT
Definition: Device.h:48
const std::string & GetDriverInformation() const override
Definition: Device.h:73
std::unique_ptr< IDeviceCommandContext > CreateCommandContext() override
Definition: Device.cpp:732
void OnWindowResize(const uint32_t width, const uint32_t height) override
Should be called on window surface resize.
Definition: Device.cpp:778
Format
Definition: Format.h:27
unsigned long long uint64_t
Definition: wposix_types.h:57
CRenderPassManager & GetRenderPassManager()
Definition: Device.h:156
uint32_t UID
Definition: Texture.h:74
void ScheduleTextureToDestroy(const CTexture::UID uid)
Definition: Device.cpp:880
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:821
VkObjectType type
Definition: Device.h:203
std::string m_Version
Definition: Device.h:173
Definition: Framebuffer.h:39
VkDevice GetVkDevice()
Definition: Device.h:130
std::string m_Name
Definition: Device.h:172
Definition: IDevice.h:47
Definition: PipelineState.h:164
std::queue< ObjectToDestroy > m_ObjectToDestroyQueue
Definition: Device.h:207
Represents single memory allocation.
Definition: IFramebuffer.h:67
std::unique_ptr< CSubmitScheduler > m_SubmitScheduler
Definition: Device.h:213
Backend
Definition: Backend.h:27
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:686
VkInstance m_Instance
Definition: Device.h:185
std::unique_ptr< CSamplerManager > m_SamplerManager
Definition: Device.h:211
std::unique_ptr< IShaderProgram > CreateShaderProgram(const CStr &name, const CShaderDefines &defines) override
Definition: Device.cpp:726
std::unique_ptr< CSwapChain > m_SwapChain
Definition: Device.h:196
struct SDL_Window SDL_Window
Definition: VideoMode.h:26
A simple helper class to decouple command buffers rotation from frames presenting.
Definition: RingCommandContext.h:47
Represents a mapping of name strings to value strings, for use with #if and #ifdef and similar condit...
Definition: ShaderDefines.h:146
VkQueue m_GraphicsQueue
Definition: Device.h:193
const Capabilities & GetCapabilities() const override
Definition: Device.h:128
std::unique_ptr< IVertexInputLayout > CreateVertexInputLayout(const PS::span< const SVertexAttributeFormat > attributes) override
Creates a vertex input layout.
Definition: Device.cpp:680
std::unique_ptr< IGraphicsPipelineState > CreateGraphicsPipelineState(const SGraphicsPipelineStateDesc &pipelineStateDesc) override
Creates a graphics pipeline state.
Definition: Device.cpp:674
bool AcquireNextBackbuffer() override
Acquires a backbuffer for rendering a frame.
Definition: Device.cpp:737
SDL_Window * m_Window
Definition: Device.h:189
~CDevice() override
Definition: Device.cpp:613
VmaAllocator GetVMAAllocator()
Definition: Device.h:132
uint32_t m_FrameID
Definition: Device.h:198
Capabilities m_Capabilities
Definition: Device.h:183
void ScheduleObjectToDestroy(VkObjectType type, const void *handle, const VmaAllocation allocation)
Definition: Device.h:134
std::unique_ptr< CRenderPassManager > m_RenderPassManager
Definition: Device.h:210
unsigned int uint32_t
Definition: wposix_types.h:53
Definition: VideoMode.h:28
uint32_t m_GraphicsQueueFamilyIndex
Definition: Device.h:194
bool IsTextureFormatSupported(const Format format) const override
Definition: Device.cpp:788
std::queue< std::pair< uint32_t, CTexture::UID > > m_TextureToDestroyQueue
Definition: Device.h:208
const SAvailablePhysicalDevice & GetChoosenPhysicalDevice() const
Definition: Device.h:154
VkSurfaceKHR m_Surface
Definition: Device.h:190
std::unique_ptr< CBuffer > CreateCBuffer(const char *name, const IBuffer::Type type, const uint32_t size, const bool dynamic)
Definition: Device.cpp:720
void ProcessTextureToDestroyQueue(const bool ignoreFrameID=false)
Definition: Device.cpp:966
Represents main object of this library initialized.
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:696
std::vector< std::string > m_InstanceExtensions
Definition: Device.h:177
CDescriptorManager & GetDescriptorManager()
Definition: Device.h:160
bool IsSwapChainValid()
Definition: Device.cpp:911
Definition: IFramebuffer.h:59
Definition: Sampler.h:56
VkDebugUtilsMessengerEXT m_DebugMessenger
Definition: Device.h:187
bool IsFormatSupportedForUsage(const Format format, const uint32_t usage) const
Definition: Device.cpp:855
Spidermonkey maintains some &#39;local&#39; state via the JSContext* object.
Definition: ScriptRequest.h:59
IFramebuffer stores attachments which should be used by backend as rendering destinations.
Definition: IFramebuffer.h:84
const std::string & GetName() const override
Definition: Device.h:71
VmaAllocator m_VMAAllocator
Definition: Device.h:192
std::string m_VendorID
Definition: Device.h:174
Structure to store all information that might be useful on device selection.
Definition: DeviceSelection.h:39
Definition: DescriptorManager.h:42
Simplifed version of std::span (C++20) as we don&#39;t support the original one yet.
Definition: Span.h:36
std::string m_DriverInformation
Definition: Device.h:175
Backend GetBackend() const override
Definition: Device.h:69
SAvailablePhysicalDevice m_ChoosenDevice
Definition: Device.h:180