@@ -17,17 +17,13 @@ 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
23
+ std::vector<VkDeviceQueueCreateInfo>& queue_create_infos,
24
+ std::vector<std::pair<uint32_t , uint32_t >>& queues_to_get) {
26
25
27
- std::vector<VkDeviceQueueCreateInfo> queue_create_infos;
28
26
queue_create_infos.reserve (num_queues_to_create);
29
-
30
- std::vector<std::pair<uint32_t , uint32_t >> queues_to_get;
31
27
queues_to_get.reserve (num_queues_to_create);
32
28
33
29
uint32_t remaining_queues = num_queues_to_create;
@@ -60,12 +56,43 @@ VkDevice create_logical_device(
60
56
break ;
61
57
}
62
58
}
59
+ }
60
+
61
+ void populate_queue_info (
62
+ const PhysicalDevice& physical_device,
63
+ VkDevice logical_device,
64
+ const std::vector<std::pair<uint32_t , uint32_t >>& queues_to_get,
65
+ std::vector<Adapter::Queue>& queues,
66
+ std::vector<uint32_t >& queue_usage) {
63
67
64
68
queues.reserve (queues_to_get.size ());
65
69
queue_usage.reserve (queues_to_get.size ());
66
70
67
- // Create the VkDevice
71
+ // Obtain handles for the created queues and initialize queue usage heuristic
72
+
73
+ for (const std::pair<uint32_t , uint32_t >& queue_idx : queues_to_get) {
74
+ VkQueue queue_handle = VK_NULL_HANDLE;
75
+ VkQueueFlags flags =
76
+ physical_device.queue_families .at (queue_idx.first ).queueFlags ;
77
+ vkGetDeviceQueue (logical_device, queue_idx.first , queue_idx.second , &queue_handle);
78
+ queues.push_back ({queue_idx.first , queue_idx.second , flags, queue_handle});
79
+ // Initial usage value
80
+ queue_usage.push_back (0 );
81
+ }
82
+ }
83
+
84
+ VkDevice create_logical_device (
85
+ const PhysicalDevice& physical_device,
86
+ const uint32_t num_queues_to_create,
87
+ std::vector<Adapter::Queue>& queues,
88
+ std::vector<uint32_t >& queue_usage) {
89
+ // Find compute queues up to the requested number of queues
68
90
91
+ std::vector<VkDeviceQueueCreateInfo> queue_create_infos;
92
+ std::vector<std::pair<uint32_t , uint32_t >> queues_to_get;
93
+ find_compute_queues (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 (physical_device, handle, queues_to_get, queues, queue_usage);
147
174
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 );
175
+ return handle;
176
+ }
177
+
178
+ bool test_linear_tiling_3d_image_support (VkDevice device) {
179
+ // Test creating a 3D image with linear tiling to see if it is supported.
180
+ // According to the Vulkan spec, linear tiling may not be supported for 3D
181
+ // images.
182
+ VkExtent3D image_extents{1u , 1u , 1u };
183
+ const VkImageCreateInfo image_create_info{
184
+ VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // sType
185
+ nullptr , // pNext
186
+ 0u , // flags
187
+ VK_IMAGE_TYPE_3D, // imageType
188
+ VK_FORMAT_R32G32B32A32_SFLOAT, // format
189
+ image_extents, // extents
190
+ 1u , // mipLevels
191
+ 1u , // arrayLayers
192
+ VK_SAMPLE_COUNT_1_BIT, // samples
193
+ VK_IMAGE_TILING_LINEAR, // tiling
194
+ VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT, // usage
195
+ VK_SHARING_MODE_EXCLUSIVE, // sharingMode
196
+ 0u , // queueFamilyIndexCount
197
+ nullptr , // pQueueFamilyIndices
198
+ VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
199
+ };
200
+ VkImage image = VK_NULL_HANDLE;
201
+ VkResult res =
202
+ 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,46 @@ 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_{test_linear_tiling_3d_image_support (device_.handle )},
240
+ owns_device_{true } {
241
+ }
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_{test_linear_tiling_3d_image_support (device_.handle )},
263
+ owns_device_{false } {
264
+ std::vector<VkDeviceQueueCreateInfo> queue_create_infos;
265
+ std::vector<std::pair<uint32_t , uint32_t >> queues_to_get;
266
+ find_compute_queues (physical_device_, num_queues, queue_create_infos, queues_to_get);
267
+ populate_queue_info (
268
+ physical_device_,
269
+ device_.handle ,
270
+ queues_to_get,
271
+ queues_,
272
+ queue_usage_);
273
+ }
274
+
275
+ Adapter::~Adapter () {
276
+ if (!owns_device_) {
277
+ device_.handle = VK_NULL_HANDLE;
218
278
}
219
- return ;
220
279
}
221
280
222
281
Adapter::Queue Adapter::request_queue () {
0 commit comments