Foundation
Loading...
Searching...
No Matches
Device.hpp
Go to the documentation of this file.
1#pragma once
2#include <RHICore/Device.hpp>
3#include <SDL3/SDL.h>
4#include <vk_mem_alloc.h>
5#include <mutex>
6
7#include "Application.hpp"
8#include "Common.hpp"
9namespace Foundation::RHI
10{
11 class VulkanApplication;
12 class VulkanDeviceQueue;
13 constexpr uint32_t kInvalidQueueIndex = static_cast<uint32_t>(-1);
15 {
18 VulkanDeviceQueues(Allocator* allocator) : storage(allocator) {};
19 VulkanDeviceQueue* Get(Handle handle) const;
21 {
22 switch (type)
23 {
25 return Get(compute);
27 return Get(transfer);
30 return Get(graphics);
31 default:
32 return nullptr;
33 }
34 }
35 bool IsValid() const
36 {
38 }
39 };
40 class VulkanDevice;
42 {
44 vk::raii::Semaphore mSemaphore{nullptr};
45
46 public:
47 VulkanDeviceSemaphore(const VulkanDevice& device, bool is_timeline);
48 [[nodiscard]] auto const& GetVkSemaphore() const { return mSemaphore; }
49
50 void DebugSetObjectName(const char* name) override;
51 };
53 {
55 vk::raii::Fence mFence{nullptr};
56
57 public:
58 VulkanDeviceFence(const VulkanDevice& device, bool signaled);
59 [[nodiscard]] auto const& GetVkFence() const { return mFence; }
60
61 void DebugSetObjectName(const char* name) override;
62 };
64 {
66 vk::raii::DescriptorSetLayout mLayout{nullptr};
67
68 public:
70 [[nodiscard]] auto const& GetVkLayout() const { return mLayout; }
71
72 void DebugSetObjectName(const char* name) override;
73 };
75 {
77 vk::raii::Sampler mSampler{nullptr};
78
79 public:
80 VulkanDeviceSampler(const VulkanDevice& device, SamplerDesc const& desc);
81 [[nodiscard]] auto const& GetVkSampler() const { return mSampler; }
82
83 void DebugSetObjectName(const char* name) override;
84 };
86 {
89 vk::raii::QueryPool mQueryPool{nullptr};
90
92
93 public:
94 VulkanDeviceQueryPool(const VulkanDevice& device, QueryPoolDesc const& desc);
95 [[nodiscard]] auto const& GetVkQueryPool() const { return mQueryPool; }
96
97 const float GetTimestampResolution() override { return mTimestampResolution; }
98
99 void Reset() override;
100
101 Span<const uint64_t> GetResults(bool wait) override;
102 void DebugSetObjectName(const char* name) override;
103 };
105 {
107 VmaVirtualBlock mBlock{nullptr};
109 uint64_t mCapacity{0};
110 uint64_t mPeakUsage{0};
111 public:
112 VulkanVirtualAllocator(const VulkanDevice& device, uint64_t size);
113 ~VulkanVirtualAllocator() override;
114 [[nodiscard]] uint64_t Allocate(uint64_t size, uint64_t alignment) override;
115 void Free(uint64_t offset) override;
116 void Clear() override;
117 [[nodiscard]] uint64_t GetUsedBytes() const override;
118 [[nodiscard]] uint64_t GetCapacity() const override { return mCapacity; }
119 [[nodiscard]] uint64_t GetPeakUsage() const override { return mPeakUsage; }
120 };
121 class VulkanDevice : public RHIDevice
122 {
124
125 vk::raii::PhysicalDevice mPhysicalDevice{nullptr};
126 vk::raii::Device mDevice{nullptr};
127
128 VmaAllocator mVkAllocator{nullptr};
129 // Device Object storage
130 // Lifetimes and handle dereferencing are managed by the device.
132 // Queues
134 // Serializes queue submit/present/wait-idle: VkQueue access must be externally
135 // synchronized, and background uploads may submit while the renderer does.
137
138 vk::PhysicalDeviceProperties mPhysicalDeviceProperties{};
142 public:
143 [[nodiscard]] uint32_t GetGraphicsQueueFamilyIndex() const { return mGraphicsQueueFamilyIndex; }
144 [[nodiscard]] const VulkanApplication& GetApp() const { return mApp; }
145 [[nodiscard]] Mutex& GetQueueSubmitMutex() const { return mQueueSubmitMutex; }
146 VulkanDevice(VulkanApplication const& app, vk::raii::PhysicalDevice physicalDevice);
147 ~VulkanDevice() override;
148
151
153
155 CreateSurface(RHISurface::SurfaceDesc const& desc) override;
156 [[nodiscard]] RHISurface* GetSurface(Handle handle) const override;
157 void DestroySurface(Handle handle) override;
158
160 RHISwapchain* GetSwapchain(Handle handle) const override;
161 void DestroySwapchain(Handle handle) override;
162
165 RHIPipelineStateCache* GetPipelineCache(Handle handle) const override;
166 void DestroyPipelineCache(Handle handle) override;
167
170 RHIPipelineState* GetPipelineState(Handle handle) const override;
171 void DestroyPipelineState(Handle handle) override;
172
175 RHIShaderModule* GetShaderModule(Handle handle) const override;
176 void DestroyShaderModule(Handle handle) override;
177
179 RHICommandPool* GetCommandPool(Handle handle) const override;
180 void DestroyCommandPool(Handle handle) override;
181
183 RHIDeviceSemaphore* GetSemaphore(Handle handle) const override;
184 void DestroySemaphore(Handle handle) override;
185
187 RHIDeviceFence* GetFence(Handle handle) const override;
188 void DestroyFence(Handle handle) override;
189
191 RHIBuffer* GetBuffer(Handle handle) const override;
192 void DestroyBuffer(Handle handle) override;
193
195 RHITexture* GetTexture(Handle handle) const override;
196 void DestroyTexture(Handle handle) override;
197
200 [[nodiscard]] RHIAccelerationStructure* GetAccelerationStructure(Handle handle) const override;
201 void DestroyAccelerationStructure(Handle handle) override;
202
206 void DestroyDescriptorSetLayout(Handle handle) override;
207
210 RHIDeviceDescriptorPool* GetDescriptorPool(Handle handle) const override;
211 void DestroyDescriptorPool(Handle handle) override;
212
214 RHIDeviceSampler* GetSampler(Handle handle) const override;
215 void DestroySampler(Handle handle) override;
216
219 RHIDeviceQueryPool* GetQueryPool(Handle handle) const override;
220 void DestroyQueryPool(Handle handle) override;
221
223 RHIVirtualAllocator* GetVirtualAllocator(Handle handle) const override;
224 void DestroyVirtualAllocator(Handle handle) override;
225
228 Allocator* scratchAllocator = nullptr
229 ) const override;
230 [[nodiscard]] size_t
232 void* dest) const override;
233
234 void ResetFences(Span<RHIDeviceFence* const> fences) override;
235 bool WaitForFences(Span<RHIDeviceFence* const> fences, bool wait_all, size_t timeout) override;
236
237 void SignalTimelineSemaphores(Span<const Pair<RHIDeviceSemaphore*, size_t>> semaphores) override;
239 size_t timeout) override;
240
241 void WaitIdle() const override;
242
243 void QueryBudget(RHIDeviceHeapType heapType, size_t& used, size_t& budget) const override;
244 void QueryAllocationStats(size_t& blockBytes, size_t& allocationBytes) const override;
245 void QueryMemoryStats(RHIDeviceMemoryStats& outStats) const override;
246 String QueryDeviceString() const override;
247
248 Allocator* GetAllocator() const;
249
250 auto const& GetVkQueues() const { return mQueues; }
251 [[nodiscard]] auto const& GetVkDevice() const { return mDevice; }
252 [[nodiscard]] auto const& GetVkPhysicalDevice() const { return mPhysicalDevice; }
254 auto const& GetVkAllocator() const { return mVkAllocator; }
255 [[nodiscard]] vk::AllocationCallbacks const* GetVkAllocationCallbacks() const;
256 [[nodiscard]] VkAllocationCallbacks const* GetVkAllocationCallbacksNative() const;
257
258 void DebugSetObjectName(const char* name) override;
259 };
261 {
263 const uint32_t mQueueIndex;
264 const uint32_t mFamilyIndex;
265 vk::raii::Queue mQueue{nullptr};
266
267 public:
268 VulkanDeviceQueue(const VulkanDevice& device, uint32_t family_index, uint32_t queue_index) :
269 RHIDeviceQueue(device), mDevice(device), mQueueIndex(queue_index), mFamilyIndex(family_index),
270 mQueue(device.GetVkDevice().getQueue(family_index, queue_index))
271 {
272 }
273
274 [[nodiscard]] const VulkanDevice& GetVulkanDevice() const { return mDevice; }
275 [[nodiscard]] vk::raii::Queue GetVkQueue() const { return mQueue; }
276 [[nodiscard]] uint32_t GetVkQueueIndex() const { return mQueueIndex; }
277 [[nodiscard]] uint32_t GetVkQueueFamily() const override { return mFamilyIndex; }
278
279 void WaitIdle() const override;
280 void Submit(Span<const SubmitDesc>, RHIDeviceFence* completionFence) const override;
281 RHISwapchainResult Present(PresentDesc const& desc) const override;
282
283
284 void DebugSetObjectName(const char* name) override;
285 };
286} // namespace Foundation::RHI
Allocator interface (noexcept)
Definition Allocator.hpp:29
Definition Resource.hpp:57
Definition Command.hpp:18
Definition Descriptor.hpp:49
Definition Device.hpp:67
Definition Device.hpp:165
Definition Device.hpp:17
Definition Device.hpp:105
Definition Device.hpp:56
Definition Device.hpp:246
Thread-safe type-erased handle dereference facility for RHI Objects.
Definition Details.hpp:147
Definition PipelineState.hpp:43
Definition PipelineState.hpp:60
Scoped move-only RAII handle wrapper for RHI Objects.
Definition Details.hpp:85
Definition Shader.hpp:5
Definition Surface.hpp:6
Definition Swapchain.hpp:32
Definition Resource.hpp:216
Sub-allocates byte ranges within an abstract fixed-size space.
Definition Resource.hpp:124
Definition Application.hpp:8
const VulkanDevice & mDevice
Definition Device.hpp:65
void DebugSetObjectName(const char *name) override
Definition Device.cpp:901
vk::raii::DescriptorSetLayout mLayout
Definition Device.hpp:66
auto const & GetVkLayout() const
Definition Device.hpp:70
Definition Device.hpp:53
void DebugSetObjectName(const char *name) override
Definition Device.cpp:603
vk::raii::Fence mFence
Definition Device.hpp:55
const VulkanDevice & mDevice
Definition Device.hpp:54
auto const & GetVkFence() const
Definition Device.hpp:59
const VulkanDevice & mDevice
Definition Device.hpp:87
auto const & GetVkQueryPool() const
Definition Device.hpp:95
vk::raii::QueryPool mQueryPool
Definition Device.hpp:89
Vector< uint64_t > mResults
Definition Device.hpp:91
const float GetTimestampResolution() override
Definition Device.hpp:97
void Reset() override
Definition Device.cpp:1000
void DebugSetObjectName(const char *name) override
Definition Device.cpp:1041
Span< const uint64_t > GetResults(bool wait) override
Definition Device.cpp:1002
const float mTimestampResolution
Definition Device.hpp:88
Definition Device.hpp:261
vk::raii::Queue mQueue
Definition Device.hpp:265
void WaitIdle() const override
Definition Device.cpp:710
vk::raii::Queue GetVkQueue() const
Definition Device.hpp:275
const uint32_t mQueueIndex
Definition Device.hpp:263
uint32_t GetVkQueueIndex() const
Definition Device.hpp:276
uint32_t GetVkQueueFamily() const override
Definition Device.hpp:277
void DebugSetObjectName(const char *name) override
Definition Device.cpp:825
const VulkanDevice & mDevice
Definition Device.hpp:262
void Submit(Span< const SubmitDesc >, RHIDeviceFence *completionFence) const override
Definition Device.cpp:716
VulkanDeviceQueue(const VulkanDevice &device, uint32_t family_index, uint32_t queue_index)
Definition Device.hpp:268
const VulkanDevice & GetVulkanDevice() const
Definition Device.hpp:274
const uint32_t mFamilyIndex
Definition Device.hpp:264
Definition Device.hpp:75
const VulkanDevice & mDevice
Definition Device.hpp:76
void DebugSetObjectName(const char *name) override
Definition Device.cpp:972
auto const & GetVkSampler() const
Definition Device.hpp:81
vk::raii::Sampler mSampler
Definition Device.hpp:77
auto const & GetVkSemaphore() const
Definition Device.hpp:48
const VulkanDevice & mDevice
Definition Device.hpp:43
void DebugSetObjectName(const char *name) override
Definition Device.cpp:587
vk::raii::Semaphore mSemaphore
Definition Device.hpp:44
Definition Device.hpp:122
RHIDeviceFence * GetFence(Handle handle) const override
Definition Device.cpp:628
bool WaitForFences(Span< RHIDeviceFence *const > fences, bool wait_all, size_t timeout) override
Wait for fences to arrive.
Definition Device.cpp:642
RHIObjectPool mStorage
Definition Device.hpp:131
RHIDeviceDescriptorSetLayout * GetDescriptorSetLayout(Handle handle) const override
Definition Device.cpp:949
RHIDeviceDescriptorPool * GetDescriptorPool(Handle handle) const override
Definition Device.cpp:964
void DestroySemaphore(Handle handle) override
Definition Device.cpp:621
RHIDeviceScopedHandle< RHIDeviceDescriptorPool > CreateDescriptorPool(RHIDeviceDescriptorPool::PoolDesc const &desc) override
Definition Device.cpp:959
vk::AllocationCallbacks const * GetVkAllocationCallbacks() const
Definition Device.cpp:694
RHIDeviceScopedHandle< RHIVirtualAllocator > CreateVirtualAllocator(uint64_t size) override
Definition Device.cpp:1197
RHIDeviceCapabilities mDeviceCaps
Definition Device.hpp:140
void DestroyAccelerationStructure(Handle handle) override
Definition Device.cpp:899
void QueryBudget(RHIDeviceHeapType heapType, size_t &used, size_t &budget) const override
Definition Device.cpp:366
void DestroyQueryPool(Handle handle) override
Definition Device.cpp:1145
VkAllocationCallbacks const * GetVkAllocationCallbacksNative() const
Definition Device.cpp:698
const VulkanApplication & mApp
Definition Device.hpp:123
void ResetFences(Span< RHIDeviceFence *const > fences) override
Definition Device.cpp:631
RHIDeviceScopedHandle< RHIDeviceFence > CreateFence(bool signaled) override
Definition Device.cpp:623
size_t WriteAccelerationStructureInstanceData(RHIAccelerationStructureGeometryInstance const &data, void *dest) const override
Definition Device.cpp:864
void DestroyFence(Handle handle) override
Definition Device.cpp:629
RHIDeviceScopedHandle< RHIPipelineState > CreatePipelineState(RHIPipelineState::PipelineStateDesc const &desc) override
Definition Device.cpp:537
void DestroyPipelineState(Handle handle) override
Definition Device.cpp:547
RHIDeviceScopedHandle< RHIPipelineStateCache > CreatePipelineCache(RHIPipelineStateCache::PipelineStateCacheDesc const &desc) override
Definition Device.cpp:522
void DestroySurface(Handle handle) override
Definition Device.cpp:511
RHIDeviceScopedHandle< RHIDeviceSampler > CreateSampler(RHIDeviceSampler::SamplerDesc const &desc) override
Definition Device.cpp:1123
RHITexture * GetTexture(Handle handle) const override
Definition Device.cpp:846
RHIBuffer * GetBuffer(Handle handle) const override
Definition Device.cpp:838
RHIDeviceScopedHandle< RHIDeviceSemaphore > CreateSemaphore(bool is_timeline) override
Definition Device.cpp:611
void DestroyShaderModule(Handle handle) override
Definition Device.cpp:561
const VulkanApplication & GetApp() const
Definition Device.hpp:144
RHIDeviceScopedHandle< RHIBuffer > CreateBuffer(RHIBufferDesc const &desc) override
Definition Device.cpp:833
void DestroyVirtualAllocator(Handle handle) override
Definition Device.cpp:1207
vk::raii::PhysicalDevice mPhysicalDevice
Definition Device.hpp:125
bool WaitForTimelineSemaphores(Span< const Pair< RHIDeviceSemaphore *, size_t > > semaphores, size_t timeout) override
Wait for timeline semaphores to reach specified values.
Definition Device.cpp:669
RHIAccelerationStructure * GetAccelerationStructure(Handle handle) const override
Definition Device.cpp:894
void DestroyBuffer(Handle handle) override
Definition Device.cpp:839
RHIDeviceScopedHandle< RHIDeviceQueryPool > CreateQueryPool(RHIDeviceQueryPool::QueryPoolDesc const &desc) override
Definition Device.cpp:1135
void DestroySampler(Handle handle) override
Definition Device.cpp:1133
VmaAllocator mVkAllocator
Definition Device.hpp:128
void QueryAllocationStats(size_t &blockBytes, size_t &allocationBytes) const override
Definition Device.cpp:398
RHIDeviceQueue * GetDeviceQueue(RHIDeviceQueueType type) const override
Definition Device.cpp:488
RHIDeviceScopedHandle< RHISwapchain > CreateSwapchain(RHISwapchain::SwapchainDesc const &desc) override
Definition Device.cpp:513
auto const & GetVkPhysicalDeviceProperties() const
Definition Device.hpp:253
void DestroyDescriptorPool(Handle handle) override
Definition Device.cpp:969
void DestroySwapchain(Handle handle) override
Definition Device.cpp:519
RHIPipelineState * GetPipelineState(Handle handle) const override
Definition Device.cpp:542
uint32_t mGraphicsQueueFamilyIndex
Definition Device.hpp:141
RHIDeviceCapabilities GetCapabilities() const override
Definition Device.hpp:149
~VulkanDevice() override
Definition Device.cpp:351
RHIVirtualAllocator * GetVirtualAllocator(Handle handle) const override
Definition Device.cpp:1202
auto const & GetVkQueues() const
Definition Device.hpp:250
uint32_t GetGraphicsQueueFamilyIndex() const
Definition Device.hpp:143
void QueryMemoryStats(RHIDeviceMemoryStats &outStats) const override
Definition Device.cpp:410
auto const & GetVkAllocator() const
Definition Device.hpp:254
RHIDeviceScopedHandle< RHIAccelerationStructure > CreateAccelerationStructure(RHIAccelerationStructureDesc const &desc) override
Definition Device.cpp:889
Mutex mQueueSubmitMutex
Definition Device.hpp:136
RHICommandPool * GetCommandPool(Handle handle) const override
Definition Device.cpp:570
auto const & GetVkPhysicalDevice() const
Definition Device.hpp:252
vk::raii::Device mDevice
Definition Device.hpp:126
String QueryDeviceString() const override
Definition Device.cpp:477
Allocator * GetAllocator() const
Definition Device.cpp:53
RHIShaderModule * GetShaderModule(Handle handle) const override
Definition Device.cpp:556
RHIDeviceSemaphore * GetSemaphore(Handle handle) const override
Definition Device.cpp:616
RHISurface * GetSurface(Handle handle) const override
Definition Device.cpp:510
void DebugSetObjectName(const char *name) override
Definition Device.cpp:702
vk::PhysicalDeviceProperties mPhysicalDeviceProperties
Definition Device.hpp:138
RHIPipelineStateCacheKey mPipelineCacheKey
Definition Device.hpp:139
void DestroyDescriptorSetLayout(Handle handle) override
Definition Device.cpp:954
UniquePtr< VulkanDeviceQueues > mQueues
Definition Device.hpp:133
RHIAccelerationStructureSizeInfo GetAccelerationStructureSizeInfo(RHIAccelerationStructureBuildDesc const &desc, Allocator *scratchAllocator=nullptr) const override
Definition Device.cpp:850
void SignalTimelineSemaphores(Span< const Pair< RHIDeviceSemaphore *, size_t > > semaphores) override
Definition Device.cpp:658
void WaitIdle() const override
Definition Device.cpp:364
RHIPipelineStateCacheKey GetPipelineCacheKey() const override
Definition Device.hpp:150
RHIDeviceScopedHandle< RHISurface > CreateSurface(RHISurface::SurfaceDesc const &desc) override
Definition Device.cpp:505
RHIPipelineStateCache * GetPipelineCache(Handle handle) const override
Definition Device.cpp:527
RHIDeviceScopedHandle< RHITexture > CreateTexture(RHITextureDesc const &desc) override
Definition Device.cpp:841
RHISwapchain * GetSwapchain(Handle handle) const override
Definition Device.cpp:518
Mutex & GetQueueSubmitMutex() const
Definition Device.hpp:145
void DestroyPipelineCache(Handle handle) override
Definition Device.cpp:532
void DestroyTexture(Handle handle) override
Definition Device.cpp:847
RHIDeviceScopedHandle< RHIShaderModule > CreateShaderModule(RHIShaderModule::ShaderModuleDesc const &desc) override
Definition Device.cpp:551
void DestroyCommandPool(Handle handle) override
Definition Device.cpp:575
auto const & GetVkDevice() const
Definition Device.hpp:251
RHIDeviceQueryPool * GetQueryPool(Handle handle) const override
Definition Device.cpp:1140
RHIDeviceScopedHandle< RHICommandPool > CreateCommandPool(RHICommandPool::PoolDesc desc) override
Definition Device.cpp:565
RHIDeviceScopedHandle< RHIDeviceDescriptorSetLayout > CreateDescriptorSetLayout(RHIDeviceDescriptorSetLayoutDesc const &desc) override
Definition Device.cpp:944
RHIDeviceSampler * GetSampler(Handle handle) const override
Definition Device.cpp:1128
void Clear() override
Definition Device.cpp:1183
uint64_t Allocate(uint64_t size, uint64_t alignment) override
Sub-allocates size bytes with the given alignment.
Definition Device.cpp:1161
Map< uint64_t, VmaVirtualAllocation > mAllocations
Definition Device.hpp:108
const VulkanDevice & mDevice
Definition Device.hpp:106
VmaVirtualBlock mBlock
Definition Device.hpp:107
uint64_t GetPeakUsage() const override
Definition Device.hpp:119
~VulkanVirtualAllocator() override
Definition Device.cpp:1155
uint64_t mPeakUsage
Definition Device.hpp:110
uint64_t GetUsedBytes() const override
Definition Device.cpp:1190
void Free(uint64_t offset) override
Definition Device.cpp:1175
uint64_t mCapacity
Definition Device.hpp:109
uint64_t GetCapacity() const override
Definition Device.hpp:118
std::vector< T, StlAllocator< T > > Vector
std::vector with explicit Foundation::Core::StlAllocator constructor
Definition Container.hpp:149
std::mutex Mutex
Definition Thread.hpp:10
std::pair< First, Second > Pair
Alias for std::pair
Definition Container.hpp:33
std::map< K, V, Predicate, StlAllocator< Pair< const K, V > > > Map
std::map with explicit Foundation::Core::StlAllocator constructor
Definition Container.hpp:178
std::basic_string< char, std::char_traits< char >, StlDefaultAllocator< char > > String
Alias for std::basic_string<char>, without an explicit allocator constructor.
Definition Container.hpp:120
std::unique_ptr< T, Deleter > UniquePtr
std::unique_ptr with custom deleter that uses a Foundation::Core::Allocator to deallocate memory.
Definition Allocator.hpp:180
std::span< T > Span
Alias for std::span
Definition Container.hpp:62
Low-level Rendering Hardware Interface (RHI) abstractions.
Definition Application.hpp:3
Present
Definition Common.hpp:198
RHIDeviceHeapType
Definition Common.hpp:212
uintptr_t Handle
Definition Details.hpp:9
RHIDeviceQueueType
Definition Common.hpp:179
static constexpr Handle kInvalidHandle
Definition Details.hpp:10
constexpr uint32_t kInvalidQueueIndex
Definition Device.hpp:13
RHISwapchainResult
Definition Swapchain.hpp:9
Definition Resource.hpp:28
Definition Device.hpp:238
Definition PipelineState.hpp:18
Definition Resource.hpp:142
Definition Device.hpp:15
VulkanDeviceQueue * Get(Handle handle) const
Definition Device.cpp:486
VulkanDeviceQueues(Allocator *allocator)
Definition Device.hpp:18
Handle compute
Definition Device.hpp:17
Handle graphics
Definition Device.hpp:17
bool IsValid() const
Definition Device.hpp:35
RHIObjectPool< VulkanDeviceQueue > storage
Definition Device.hpp:16
VulkanDeviceQueue * Get(RHIDeviceQueueType type) const
Definition Device.hpp:20
Handle transfer
Definition Device.hpp:17