@@ -17,17 +17,13 @@ namespace vkapi {
1717
1818namespace {
1919
20- VkDevice create_logical_device (
20+ void find_compute_queues (
2121 const PhysicalDevice& physical_device,
2222 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) {
2625
27- std::vector<VkDeviceQueueCreateInfo> queue_create_infos;
2826 queue_create_infos.reserve (num_queues_to_create);
29-
30- std::vector<std::pair<uint32_t , uint32_t >> queues_to_get;
3127 queues_to_get.reserve (num_queues_to_create);
3228
3329 uint32_t remaining_queues = num_queues_to_create;
@@ -60,12 +56,43 @@ VkDevice create_logical_device(
6056 break ;
6157 }
6258 }
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) {
6367
6468 queues.reserve (queues_to_get.size ());
6569 queue_usage.reserve (queues_to_get.size ());
6670
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
6890
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
6996 std::vector<const char *> requested_device_extensions{
7097#ifdef VK_KHR_portability_subset
7198 VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME,
@@ -143,19 +170,42 @@ VkDevice create_logical_device(
143170 volkLoadDevice (handle);
144171#endif /* USE_VULKAN_VOLK */
145172
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);
147174
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 );
156206 }
157207
158- return handle ;
208+ return res == VK_SUCCESS ;
159209}
160210
161211} // namespace
@@ -186,37 +236,46 @@ Adapter::Adapter(
186236 compute_pipeline_cache_ (device_.handle, cache_data_path),
187237 sampler_cache_ (device_.handle),
188238 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;
218278 }
219- return ;
220279}
221280
222281Adapter::Queue Adapter::request_queue () {
0 commit comments