diff options
| author | Benjamin Saunders <ben.e.saunders@gmail.com> | 2020-01-21 20:43:03 -0800 |
|---|---|---|
| committer | Charles Giessen <46324611+charles-lunarg@users.noreply.github.com> | 2020-01-23 13:57:05 -0700 |
| commit | 93ab50fc27de5a2075535be35dd76b14138d46f2 (patch) | |
| tree | be477c6bad0a74ccc7442676123cc5a150d1c9e6 | |
| parent | d9854c32eee5d43d66f0c0273f9f5521e43f302e (diff) | |
| download | usermoji-93ab50fc27de5a2075535be35dd76b14138d46f2.tar.xz | |
vulkaninfo: Use a helper for the two-call idiom
Drastically reduces repetition and ensures consistent error handling.
| -rw-r--r-- | vulkaninfo/vulkaninfo.h | 167 |
1 files changed, 41 insertions, 126 deletions
diff --git a/vulkaninfo/vulkaninfo.h b/vulkaninfo/vulkaninfo.h index 7add1ca5..fee4a9d4 100644 --- a/vulkaninfo/vulkaninfo.h +++ b/vulkaninfo/vulkaninfo.h @@ -207,6 +207,27 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL DbgCallback(VkDebugReportFlagsEXT msgFlags return VK_FALSE; } +// Helper for robustly executing the two-call pattern +template <typename T, typename F, typename... Ts> +auto GetVectorInit(F &&f, T init, Ts &&... ts) -> std::vector<T> { + uint32_t count = 0; + std::vector<T> results; + VkResult err; + do { + err = f(ts..., &count, nullptr); + if (err) ERR_EXIT(err); + results.resize(count, init); + err = f(ts..., &count, results.data()); + } while (err == VK_INCOMPLETE); + if (err) ERR_EXIT(err); + return results; +} + +template <typename T, typename F, typename... Ts> +auto GetVector(F &&f, Ts &&... ts) -> std::vector<T> { + return GetVectorInit(f, T(), ts...); +} + // ----------- Instance Setup ------- // struct VkStructureHeader { @@ -390,22 +411,8 @@ struct AppInstance { /* Gets a list of layer and instance extensions */ void AppGetInstanceExtensions() { /* Scan layers */ - std::vector<VkLayerProperties> global_layer_properties; - - VkResult err; - uint32_t count = 0; - do { - err = vkEnumerateInstanceLayerProperties(&count, nullptr); - if (err) ERR_EXIT(err); - - global_layer_properties.resize(count); - - err = vkEnumerateInstanceLayerProperties(&count, global_layer_properties.data()); - } while (err == VK_INCOMPLETE); - if (err) ERR_EXIT(err); - - global_layers.resize(count); - assert(global_layer_properties.size() == global_layers.size()); + auto global_layer_properties = GetVector<VkLayerProperties>(vkEnumerateInstanceLayerProperties); + global_layers.resize(global_layer_properties.size()); for (size_t i = 0; i < global_layer_properties.size(); i++) { global_layers[i].layer_properties = global_layer_properties[i]; @@ -446,40 +453,11 @@ struct AppInstance { void AddSurfaceExtension(SurfaceExtension ext) { surface_extensions.push_back(ext); } static std::vector<VkExtensionProperties> AppGetGlobalLayerExtensions(char *layer_name) { - std::vector<VkExtensionProperties> ext_props; - VkResult err; - uint32_t ext_count = 0; - do { - // gets the extension count if the last parameter is nullptr - err = vkEnumerateInstanceExtensionProperties(layer_name, &ext_count, nullptr); - if (err) ERR_EXIT(err); - - ext_props.resize(ext_count); - // gets the extension properties if the last parameter is not nullptr - err = vkEnumerateInstanceExtensionProperties(layer_name, &ext_count, ext_props.data()); - } while (err == VK_INCOMPLETE); - if (err) ERR_EXIT(err); - return ext_props; + return GetVector<VkExtensionProperties>(vkEnumerateInstanceExtensionProperties, layer_name); } std::vector<VkPhysicalDevice> FindPhysicalDevices() { - std::vector<VkPhysicalDevice> phys_devices; - - VkResult err; - uint32_t gpu_count = 0; - - /* repeat get until VK_INCOMPLETE goes away */ - do { - err = vkEnumeratePhysicalDevices(instance, &gpu_count, nullptr); - if (err) ERR_EXIT(err); - - phys_devices.resize(gpu_count); - err = vkEnumeratePhysicalDevices(instance, &gpu_count, phys_devices.data()); - if (err) ERR_EXIT(err); - phys_devices.resize(gpu_count); - } while (err == VK_INCOMPLETE); - - return phys_devices; + return GetVector<VkPhysicalDevice>(vkEnumeratePhysicalDevices, instance); } }; @@ -902,7 +880,7 @@ void SetupWindowExtensions(AppInstance &inst) { class AppSurface { public: AppInstance &inst; - VkPhysicalDevice phys_device; + VkPhysicalDevice phys_device; SurfaceExtension surface_extension; std::vector<VkPresentModeKHR> surf_present_modes; @@ -916,39 +894,23 @@ class AppSurface { AppSurface(AppInstance &inst, VkPhysicalDevice phys_device, SurfaceExtension surface_extension, std::vector<pNextChainBuildingBlockInfo> &sur_extension_pNextChain) - : inst(inst), phys_device(phys_device), surface_extension(surface_extension) { - uint32_t present_mode_count = 0; - VkResult error = - inst.vkGetPhysicalDeviceSurfacePresentModesKHR(phys_device, surface_extension.surface, &present_mode_count, nullptr); - if (error) ERR_EXIT(error); - - surf_present_modes.resize(present_mode_count); - error = inst.vkGetPhysicalDeviceSurfacePresentModesKHR(phys_device, surface_extension.surface, &present_mode_count, - surf_present_modes.data()); - if (error) ERR_EXIT(error); - + : inst(inst), + phys_device(phys_device), + surface_extension(surface_extension), + surf_present_modes( + GetVector<VkPresentModeKHR>(inst.vkGetPhysicalDeviceSurfacePresentModesKHR, phys_device, surface_extension.surface)) { const VkPhysicalDeviceSurfaceInfo2KHR surface_info2 = {VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR, nullptr, surface_extension.surface}; - uint32_t format_count = 0; if (inst.CheckExtensionEnabled(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME)) { - VkResult err = inst.vkGetPhysicalDeviceSurfaceFormats2KHR(phys_device, &surface_info2, &format_count, nullptr); - if (err) ERR_EXIT(err); - surf_formats2.resize(format_count); - for (uint32_t i = 0; i < format_count; ++i) { - surf_formats2[i].sType = VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR; - surf_formats2[i].pNext = nullptr; - } - err = inst.vkGetPhysicalDeviceSurfaceFormats2KHR(phys_device, &surface_info2, &format_count, surf_formats2.data()); - if (err) ERR_EXIT(err); + VkSurfaceFormat2KHR init; + init.sType = VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR; + init.pNext = nullptr; + surf_formats2 = + GetVectorInit<VkSurfaceFormat2KHR>(inst.vkGetPhysicalDeviceSurfaceFormats2KHR, init, phys_device, &surface_info2); } else { - VkResult err = - inst.vkGetPhysicalDeviceSurfaceFormatsKHR(phys_device, surface_extension.surface, &format_count, nullptr); - if (err) ERR_EXIT(err); - surf_formats.resize(format_count); - err = inst.vkGetPhysicalDeviceSurfaceFormatsKHR(phys_device, surface_extension.surface, &format_count, - surf_formats.data()); - if (err) ERR_EXIT(err); + surf_formats = + GetVector<VkSurfaceFormatKHR>(inst.vkGetPhysicalDeviceSurfaceFormatsKHR, phys_device, surface_extension.surface); } if (inst.CheckExtensionEnabled(VK_KHR_SURFACE_EXTENSION_NAME)) { @@ -996,23 +958,7 @@ std::vector<VkPhysicalDeviceGroupProperties> GetGroups(AppInstance &inst) { PFN_vkEnumeratePhysicalDeviceGroupsKHR vkEnumeratePhysicalDeviceGroupsKHR = reinterpret_cast<PFN_vkEnumeratePhysicalDeviceGroupsKHR>( vkGetInstanceProcAddr(inst.instance, "vkEnumeratePhysicalDeviceGroupsKHR")); - - std::vector<VkPhysicalDeviceGroupProperties> groups; - uint32_t group_count; - VkResult err; - do { - err = vkEnumeratePhysicalDeviceGroupsKHR(inst.instance, &group_count, NULL); - if (err != VK_SUCCESS && err != VK_INCOMPLETE) { - return {}; - } - groups.resize(group_count); - - err = vkEnumeratePhysicalDeviceGroupsKHR(inst.instance, &group_count, groups.data()); - if (err != VK_SUCCESS && err != VK_INCOMPLETE) { - return {}; - } - } while (err == VK_INCOMPLETE); - return groups; + return GetVector<VkPhysicalDeviceGroupProperties>(vkEnumeratePhysicalDeviceGroupsKHR, inst.instance); } return {}; } @@ -1367,23 +1313,7 @@ struct AppGpu { } std::vector<VkExtensionProperties> AppGetPhysicalDeviceLayerExtensions(char *layer_name) { - std::vector<VkExtensionProperties> extension_properties; - - VkResult err; - uint32_t ext_count = 0; - - /* repeat get until VK_INCOMPLETE goes away */ - do { - err = vkEnumerateDeviceExtensionProperties(phys_device, layer_name, &ext_count, nullptr); - if (err) ERR_EXIT(err); - - extension_properties.resize(ext_count); - err = vkEnumerateDeviceExtensionProperties(phys_device, layer_name, &ext_count, extension_properties.data()); - if (err) ERR_EXIT(err); - extension_properties.resize(ext_count); - } while (err == VK_INCOMPLETE); - - return extension_properties; + return GetVector<VkExtensionProperties>(vkEnumerateDeviceExtensionProperties, phys_device, layer_name); } // Helper function to determine whether a format range is currently supported. @@ -1440,23 +1370,8 @@ struct AppQueueFamilyProperties { }; std::vector<VkPhysicalDeviceToolPropertiesEXT> GetToolingInfo(AppGpu &gpu) { - uint32_t count = 0; - VkResult err; - std::vector<VkPhysicalDeviceToolPropertiesEXT> tool_properties; - if (gpu.inst.vkGetPhysicalDeviceToolPropertiesEXT == nullptr) return {}; - do { - err = gpu.inst.vkGetPhysicalDeviceToolPropertiesEXT(gpu.phys_device, &count, nullptr); - if (err != VK_SUCCESS && err != VK_INCOMPLETE) { - return {}; - } - tool_properties.resize(count); - err = gpu.inst.vkGetPhysicalDeviceToolPropertiesEXT(gpu.phys_device, &count, tool_properties.data()); - if (err != VK_SUCCESS && err != VK_INCOMPLETE) { - return {}; - } - } while (err == VK_INCOMPLETE); - return tool_properties; + return GetVector<VkPhysicalDeviceToolPropertiesEXT>(gpu.inst.vkGetPhysicalDeviceToolPropertiesEXT, gpu.phys_device); } // --------- Format Properties ----------// |
