@@ -17,17 +17,12 @@ 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
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) {
2825 queue_create_infos.reserve (num_queues_to_create);
29-
30- std::vector<std::pair<uint32_t , uint32_t >> queues_to_get;
3126 queues_to_get.reserve (num_queues_to_create);
3227
3328 uint32_t remaining_queues = num_queues_to_create;
@@ -60,12 +55,44 @@ VkDevice create_logical_device(
6055 break ;
6156 }
6257 }
58+ }
6359
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) {
6466 queues.reserve (queues_to_get.size ());
6567 queue_usage.reserve (queues_to_get.size ());
6668
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
6889
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
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 (
174+ physical_device, handle, queues_to_get, queues, queue_usage);
147175
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 );
156206 }
157207
158- return handle ;
208+ return res == VK_SUCCESS ;
159209}
160210
161211} // namespace
@@ -186,37 +236,44 @@ 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_{
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;
218276 }
219- return ;
220277}
221278
222279Adapter::Queue Adapter::request_queue () {
0 commit comments