-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVulkanDevices.h
197 lines (152 loc) · 6.73 KB
/
VulkanDevices.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#ifndef VULKAN_DEVICES_H_
#define VULKAN_DEVICES_H_
#include <vulkan/vulkan.h>
#include "optional.h"
#include <vector>
#include <stdexcept>
#include <limits>
class QueueFamily
{
public:
QueueFamily(){}
QueueFamily(const VkQueueFamilyProperties& aFamily, uint32_t aIndex);
inline bool hasCoreQueueSupport() const {return(mGraphics && mCompute && mTransfer);}
inline bool hasAllQueueSupport() const {return(mGraphics && mCompute && mTransfer && mSparseBinding && mProtected);}
uint32_t mIndex = std::numeric_limits<uint32_t>::max();
uint32_t mCount = 0;
VkQueueFlags mFlags = 0x0;
VkExtent3D mMinImageTransferGranularity = VkExtent3D();
uint32_t mTimeStampValidBits = 0;
bool mGraphics = false;
bool mCompute = false;
bool mTransfer = false;
bool mSparseBinding = false;
bool mProtected = false;
};
struct VulkanDeviceHandlePair
{
VkDevice device = VK_NULL_HANDLE;
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
VulkanDeviceHandlePair() {}
VulkanDeviceHandlePair(VkDevice aDevice, VkPhysicalDevice aPhysDevice) : device(aDevice), physicalDevice(aPhysDevice) {}
bool isValid() const {return(device != VK_NULL_HANDLE && physicalDevice != VK_NULL_HANDLE);}
friend bool operator==(const VulkanDeviceHandlePair& lhs, const VulkanDeviceHandlePair& rhs){return(lhs.device == rhs.device && lhs.physicalDevice == rhs.physicalDevice);}
friend bool operator!=(const VulkanDeviceHandlePair& lhs, const VulkanDeviceHandlePair& rhs){return(!operator==(lhs, rhs));}
};
class VulkanLogicalDevice
{
public:
VulkanLogicalDevice(){}
inline VkDevice handle() const {return(mHandle);}
inline bool isValid() const {return(mHandle != VK_NULL_HANDLE);}
void invalidate() {mHandle = VK_NULL_HANDLE;}
VkQueue getGraphicsQueue() const {return(mGraphicsQueue);}
VkQueue getComputeQueue() const {return(mComputeQueue);}
VkQueue getTransferQueue() const {return(mTransferQueue);}
VkQueue getSparseBindingQueue() const {return(mSparseBindingQueue);}
VkQueue getProtectedQueue() const {return(mProtectedQueue);}
VkQueue getPresentationQueue() const {return(mPresentationQueue);}
operator VkDevice() const {return(mHandle);}
protected:
friend class VulkanPhysicalDevice;
VulkanLogicalDevice(VkDevice aDevice) : mHandle(aDevice) {}
VkDevice mHandle = VK_NULL_HANDLE;
VkQueue mGraphicsQueue = VK_NULL_HANDLE;
VkQueue mComputeQueue = VK_NULL_HANDLE;
VkQueue mTransferQueue = VK_NULL_HANDLE;
VkQueue mSparseBindingQueue = VK_NULL_HANDLE;
VkQueue mProtectedQueue = VK_NULL_HANDLE;
VkQueue mPresentationQueue = VK_NULL_HANDLE;
};
struct SwapChainSupportInfo;
class VulkanPhysicalDevice
{
public:
VulkanPhysicalDevice(){}
VulkanPhysicalDevice(VkPhysicalDevice aDevice);
inline VkPhysicalDevice handle() const {return(mHandle);}
inline bool isValid() const {return(mHandle != VK_NULL_HANDLE);}
void invalidate() {mHandle = VK_NULL_HANDLE;}
SwapChainSupportInfo getSwapChainSupportInfo(const VkSurfaceKHR aSurface) const;
opt::optional<uint32_t> getPresentableQueueIndex(const VkSurfaceKHR aSurface) const;
VulkanLogicalDevice createLogicalDevice(
VkQueueFlags aQueues,
const std::vector<const char*>& aExtensions = std::vector<const char*>(),
const VkPhysicalDeviceFeatures& aFeatures = {},
VkSurfaceKHR aSurface = VK_NULL_HANDLE,
void* aDeviceCreateInfoPnext = nullptr
) const;
VulkanLogicalDevice createLogicalDevice(
const VkDeviceCreateInfo& aDeviceCreateInfo,
const std::optional<uint32_t>& aPresentationIdx = std::nullopt
) const;
VulkanLogicalDevice createCoreDevice() const { return(createLogicalDevice(VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT)); }
VulkanLogicalDevice createPresentableCoreDevice(
VkSurfaceKHR aSurface,
const std::vector<const char*>& aExtensions = std::vector<const char*>(),
const VkPhysicalDeviceFeatures& aFeatures = {}
) const {
if(aSurface == VK_NULL_HANDLE) throw std::runtime_error("Attempted to create presentable core device with invalid surface handle!");
return(createLogicalDevice(VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT | VK_QUEUE_TRANSFER_BIT, aExtensions, aFeatures, aSurface));
}
VkPhysicalDeviceProperties mProperties;
VkPhysicalDeviceFeatures mFeatures;
std::vector<QueueFamily> mQueueFamilies;
std::vector<VkExtensionProperties> mAvailableExtensions;
opt::optional<uint32_t> mGraphicsIdx;
opt::optional<uint32_t> mComputeIdx;
opt::optional<uint32_t> mTransferIdx;
opt::optional<uint32_t> mProtectedIdx;
opt::optional<uint32_t> mSparseBindIdx;
// Index of queue supporting graphics, compute, transfer, and presentation
opt::optional<uint32_t> coreFeaturesIdx;
operator VkPhysicalDevice() const {return(mHandle);}
protected:
void _initExtensionProps();
void _initQueueFamilies();
VkPhysicalDevice mHandle = VK_NULL_HANDLE;
};
struct SwapChainSupportInfo
{
VkSurfaceCapabilitiesKHR capabilities;
std::vector<VkSurfaceFormatKHR> formats;
std::vector<VkPresentModeKHR> presentation_modes;
};
struct VulkanDeviceBundle
{
VulkanLogicalDevice logicalDevice;
VulkanPhysicalDevice physicalDevice;
bool isValid() const {return(logicalDevice.isValid() && physicalDevice.isValid());}
/*explicit*/ operator VulkanDeviceHandlePair() const{
return(VulkanDeviceHandlePair{logicalDevice.handle(), physicalDevice.handle()});
}
/*explicit*/ operator VkPhysicalDevice() const{
return(physicalDevice.handle());
}
/*explicit*/ operator VkDevice() const{
return(logicalDevice.handle());
}
friend bool operator==(const VulkanDeviceBundle& aDeviceBundle, const VulkanDeviceHandlePair& aDevicePair){
bool logicalMatch = aDeviceBundle.logicalDevice.handle() == aDevicePair.device;
bool physicalMatch = aDeviceBundle.physicalDevice.handle() == aDevicePair.physicalDevice;
return(logicalMatch && physicalMatch);
}
friend bool operator==(const VulkanDeviceHandlePair& aDevicePair, const VulkanDeviceBundle& aDeviceBundle){
return(operator==(aDeviceBundle, aDevicePair));
}
friend bool operator!=(const VulkanDeviceBundle& aDeviceBundle, const VulkanDeviceHandlePair& aDevicePair){
return(!(aDeviceBundle == aDevicePair));
}
friend bool operator!=(const VulkanDeviceHandlePair& aDevicePair, const VulkanDeviceBundle& aDeviceBundle){
return(!(aDeviceBundle == aDevicePair));
}
};
class VulkanPhysicalDeviceEnumeration : public std::vector<VulkanPhysicalDevice>
{
public:
using base_vector = std::vector<VulkanPhysicalDevice>;
VulkanPhysicalDeviceEnumeration(){}
VulkanPhysicalDeviceEnumeration(const std::vector<VkPhysicalDevice>& aDevices);
using base_vector::operator[];
};
#endif