@@ -17,17 +17,12 @@ namespace vkapi {
17
17
18
18
namespace {
19
19
20
- VkDevice create_logical_device (
20
+ void find_compute_queues (
21
21
const PhysicalDevice& physical_device,
22
22
const uint32_t num_queues_to_create,
23
- std::vector<Adapter::Queue>& queues,
24
- std::vector<uint32_t >& queue_usage) {
25
- // Find compute queues up to the requested number of queues
26
-
27
- std::vector<VkDeviceQueueCreateInfo> queue_create_infos;
23
+ std::vector<VkDeviceQueueCreateInfo>& queue_create_infos,
24
+ std::vector<std::pair<uint32_t , uint32_t >>& queues_to_get) {
28
25
queue_create_infos.reserve (num_queues_to_create);
29
-
30
- std::vector<std::pair<uint32_t , uint32_t >> queues_to_get;
31
26
queues_to_get.reserve (num_queues_to_create);
32
27
33
28
uint32_t remaining_queues = num_queues_to_create;
@@ -60,12 +55,44 @@ VkDevice create_logical_device(
60
55
break ;
61
56
}
62
57
}
58
+ }
63
59
60
+ void populate_queue_info (
61
+ const PhysicalDevice& physical_device,
62
+ VkDevice logical_device,
63
+ const std::vector<std::pair<uint32_t , uint32_t >>& queues_to_get,
64
+ std::vector<Adapter::Queue>& queues,
65
+ std::vector<uint32_t >& queue_usage) {
64
66
queues.reserve (queues_to_get.size ());
65
67
queue_usage.reserve (queues_to_get.size ());
66
68
67
- // Create the VkDevice
69
+ // Obtain handles for the created queues and initialize queue usage heuristic
70
+
71
+ for (const std::pair<uint32_t , uint32_t >& queue_idx : queues_to_get) {
72
+ VkQueue queue_handle = VK_NULL_HANDLE;
73
+ VkQueueFlags flags =
74
+ physical_device.queue_families .at (queue_idx.first ).queueFlags ;
75
+ vkGetDeviceQueue (
76
+ logical_device, queue_idx.first , queue_idx.second , &queue_handle);
77
+ queues.push_back ({queue_idx.first , queue_idx.second , flags, queue_handle});
78
+ // Initial usage value
79
+ queue_usage.push_back (0 );
80
+ }
81
+ }
82
+
83
+ VkDevice create_logical_device (
84
+ const PhysicalDevice& physical_device,
85
+ const uint32_t num_queues_to_create,
86
+ std::vector<Adapter::Queue>& queues,
87
+ std::vector<uint32_t >& queue_usage) {
88
+ // Find compute queues up to the requested number of queues
68
89
90
+ std::vector<VkDeviceQueueCreateInfo> queue_create_infos;
91
+ std::vector<std::pair<uint32_t , uint32_t >> queues_to_get;
92
+ find_compute_queues (
93
+ physical_device, num_queues_to_create, queue_create_infos, queues_to_get);
94
+
95
+ // Create the VkDevice
69
96
std::vector<const char *> requested_device_extensions{
70
97
#ifdef VK_KHR_portability_subset
71
98
VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME,
@@ -143,19 +170,42 @@ VkDevice create_logical_device(
143
170
volkLoadDevice (handle);
144
171
#endif /* USE_VULKAN_VOLK */
145
172
146
- // Obtain handles for the created queues and initialize queue usage heuristic
173
+ populate_queue_info (
174
+ physical_device, handle, queues_to_get, queues, queue_usage);
147
175
148
- for (const std::pair<uint32_t , uint32_t >& queue_idx : queues_to_get) {
149
- VkQueue queue_handle = VK_NULL_HANDLE;
150
- VkQueueFlags flags =
151
- physical_device.queue_families .at (queue_idx.first ).queueFlags ;
152
- vkGetDeviceQueue (handle, queue_idx.first , queue_idx.second , &queue_handle);
153
- queues.push_back ({queue_idx.first , queue_idx.second , flags, queue_handle});
154
- // Initial usage value
155
- queue_usage.push_back (0 );
176
+ return handle;
177
+ }
178
+
179
+ bool test_linear_tiling_3d_image_support (VkDevice device) {
180
+ // Test creating a 3D image with linear tiling to see if it is supported.
181
+ // According to the Vulkan spec, linear tiling may not be supported for 3D
182
+ // images.
183
+ VkExtent3D image_extents{1u , 1u , 1u };
184
+ const VkImageCreateInfo image_create_info{
185
+ VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // sType
186
+ nullptr , // pNext
187
+ 0u , // flags
188
+ VK_IMAGE_TYPE_3D, // imageType
189
+ VK_FORMAT_R32G32B32A32_SFLOAT, // format
190
+ image_extents, // extents
191
+ 1u , // mipLevels
192
+ 1u , // arrayLayers
193
+ VK_SAMPLE_COUNT_1_BIT, // samples
194
+ VK_IMAGE_TILING_LINEAR, // tiling
195
+ VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, // usage
196
+ VK_SHARING_MODE_EXCLUSIVE, // sharingMode
197
+ 0u , // queueFamilyIndexCount
198
+ nullptr , // pQueueFamilyIndices
199
+ VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
200
+ };
201
+ VkImage image = VK_NULL_HANDLE;
202
+ VkResult res = vkCreateImage (device, &image_create_info, nullptr , &image);
203
+
204
+ if (res == VK_SUCCESS) {
205
+ vkDestroyImage (device, image, nullptr );
156
206
}
157
207
158
- return handle ;
208
+ return res == VK_SUCCESS ;
159
209
}
160
210
161
211
} // namespace
@@ -186,37 +236,44 @@ Adapter::Adapter(
186
236
compute_pipeline_cache_ (device_.handle, cache_data_path),
187
237
sampler_cache_ (device_.handle),
188
238
vma_ (instance_, physical_device_.handle, device_.handle),
189
- linear_tiling_3d_enabled_{true } {
190
- // Test creating a 3D image with linear tiling to see if it is supported.
191
- // According to the Vulkan spec, linear tiling may not be supported for 3D
192
- // images.
193
- VkExtent3D image_extents{1u , 1u , 1u };
194
- const VkImageCreateInfo image_create_info{
195
- VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // sType
196
- nullptr , // pNext
197
- 0u , // flags
198
- VK_IMAGE_TYPE_3D, // imageType
199
- VK_FORMAT_R32G32B32A32_SFLOAT, // format
200
- image_extents, // extents
201
- 1u , // mipLevels
202
- 1u , // arrayLayers
203
- VK_SAMPLE_COUNT_1_BIT, // samples
204
- VK_IMAGE_TILING_LINEAR, // tiling
205
- VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, // usage
206
- VK_SHARING_MODE_EXCLUSIVE, // sharingMode
207
- 0u , // queueFamilyIndexCount
208
- nullptr , // pQueueFamilyIndices
209
- VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
210
- };
211
- VkImage image = VK_NULL_HANDLE;
212
- VkResult res =
213
- vkCreateImage (device_.handle , &image_create_info, nullptr , &image);
214
- if (res != VK_SUCCESS) {
215
- linear_tiling_3d_enabled_ = false ;
216
- } else {
217
- vkDestroyImage (device_.handle , image, nullptr );
239
+ linear_tiling_3d_enabled_{
240
+ test_linear_tiling_3d_image_support (device_.handle )},
241
+ owns_device_{true } {}
242
+
243
+ Adapter::Adapter (
244
+ VkInstance instance,
245
+ VkPhysicalDevice physical_device,
246
+ VkDevice logical_device,
247
+ const uint32_t num_queues,
248
+ const std::string& cache_data_path)
249
+ : queue_usage_mutex_{},
250
+ physical_device_ (physical_device),
251
+ queues_{},
252
+ queue_usage_{},
253
+ queue_mutexes_{},
254
+ instance_ (instance),
255
+ device_ (logical_device),
256
+ shader_layout_cache_ (device_.handle),
257
+ shader_cache_ (device_.handle),
258
+ pipeline_layout_cache_ (device_.handle),
259
+ compute_pipeline_cache_ (device_.handle, cache_data_path),
260
+ sampler_cache_ (device_.handle),
261
+ vma_ (instance_, physical_device_.handle, device_.handle),
262
+ linear_tiling_3d_enabled_{
263
+ test_linear_tiling_3d_image_support (device_.handle )},
264
+ owns_device_{false } {
265
+ std::vector<VkDeviceQueueCreateInfo> queue_create_infos;
266
+ std::vector<std::pair<uint32_t , uint32_t >> queues_to_get;
267
+ find_compute_queues (
268
+ physical_device_, num_queues, queue_create_infos, queues_to_get);
269
+ populate_queue_info (
270
+ physical_device_, device_.handle , queues_to_get, queues_, queue_usage_);
271
+ }
272
+
273
+ Adapter::~Adapter () {
274
+ if (!owns_device_) {
275
+ device_.handle = VK_NULL_HANDLE;
218
276
}
219
- return ;
220
277
}
221
278
222
279
Adapter::Queue Adapter::request_queue () {
0 commit comments