mirror of
https://github.com/charles-lunarg/vk-bootstrap.git
synced 2024-11-12 19:51:47 +00:00
Move Result & Error out of the detail namespace
Since its a part of the public interface, it means applications using vk-bootstrap will inevitably need to use the types in error handling paths.
This commit is contained in:
parent
789a24edb7
commit
ab52ad97a8
@ -469,14 +469,14 @@ const char* to_string(SwapchainError err) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
detail::Result<SystemInfo> SystemInfo::get_system_info() {
|
Result<SystemInfo> SystemInfo::get_system_info() {
|
||||||
if (!detail::vulkan_functions().init_vulkan_funcs(nullptr)) {
|
if (!detail::vulkan_functions().init_vulkan_funcs(nullptr)) {
|
||||||
return make_error_code(InstanceError::vulkan_unavailable);
|
return make_error_code(InstanceError::vulkan_unavailable);
|
||||||
}
|
}
|
||||||
return SystemInfo();
|
return SystemInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
detail::Result<SystemInfo> SystemInfo::get_system_info(PFN_vkGetInstanceProcAddr fp_vkGetInstanceProcAddr) {
|
Result<SystemInfo> SystemInfo::get_system_info(PFN_vkGetInstanceProcAddr fp_vkGetInstanceProcAddr) {
|
||||||
// Using externally provided function pointers, assume the loader is available
|
// Using externally provided function pointers, assume the loader is available
|
||||||
if (!detail::vulkan_functions().init_vulkan_funcs(fp_vkGetInstanceProcAddr)) {
|
if (!detail::vulkan_functions().init_vulkan_funcs(fp_vkGetInstanceProcAddr)) {
|
||||||
return make_error_code(InstanceError::vulkan_unavailable);
|
return make_error_code(InstanceError::vulkan_unavailable);
|
||||||
@ -554,7 +554,7 @@ InstanceBuilder::InstanceBuilder(PFN_vkGetInstanceProcAddr fp_vkGetInstanceProcA
|
|||||||
}
|
}
|
||||||
InstanceBuilder::InstanceBuilder() {}
|
InstanceBuilder::InstanceBuilder() {}
|
||||||
|
|
||||||
detail::Result<Instance> InstanceBuilder::build() const {
|
Result<Instance> InstanceBuilder::build() const {
|
||||||
|
|
||||||
auto sys_info_ret = SystemInfo::get_system_info(info.fp_vkGetInstanceProcAddr);
|
auto sys_info_ret = SystemInfo::get_system_info(info.fp_vkGetInstanceProcAddr);
|
||||||
if (!sys_info_ret) return sys_info_ret.error();
|
if (!sys_info_ret) return sys_info_ret.error();
|
||||||
@ -719,7 +719,7 @@ detail::Result<Instance> InstanceBuilder::build() const {
|
|||||||
Instance instance;
|
Instance instance;
|
||||||
VkResult res =
|
VkResult res =
|
||||||
detail::vulkan_functions().fp_vkCreateInstance(&instance_create_info, info.allocation_callbacks, &instance.instance);
|
detail::vulkan_functions().fp_vkCreateInstance(&instance_create_info, info.allocation_callbacks, &instance.instance);
|
||||||
if (res != VK_SUCCESS) return detail::Result<Instance>(InstanceError::failed_create_instance, res);
|
if (res != VK_SUCCESS) return Result<Instance>(InstanceError::failed_create_instance, res);
|
||||||
|
|
||||||
detail::vulkan_functions().init_instance_funcs(instance.instance);
|
detail::vulkan_functions().init_instance_funcs(instance.instance);
|
||||||
|
|
||||||
@ -732,7 +732,7 @@ detail::Result<Instance> InstanceBuilder::build() const {
|
|||||||
&instance.debug_messenger,
|
&instance.debug_messenger,
|
||||||
info.allocation_callbacks);
|
info.allocation_callbacks);
|
||||||
if (res != VK_SUCCESS) {
|
if (res != VK_SUCCESS) {
|
||||||
return detail::Result<Instance>(InstanceError::failed_create_debug_messenger, res);
|
return Result<Instance>(InstanceError::failed_create_debug_messenger, res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1162,7 +1162,7 @@ PhysicalDeviceSelector::PhysicalDeviceSelector(Instance const& instance, VkSurfa
|
|||||||
criteria.desired_version = instance.api_version;
|
criteria.desired_version = instance.api_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
detail::Result<std::vector<PhysicalDevice>> PhysicalDeviceSelector::select_impl(DeviceSelectionMode selection) const {
|
Result<std::vector<PhysicalDevice>> PhysicalDeviceSelector::select_impl(DeviceSelectionMode selection) const {
|
||||||
#if !defined(NDEBUG)
|
#if !defined(NDEBUG)
|
||||||
// Validation
|
// Validation
|
||||||
for (const auto& node : criteria.extended_features_chain) {
|
for (const auto& node : criteria.extended_features_chain) {
|
||||||
@ -1177,7 +1177,7 @@ detail::Result<std::vector<PhysicalDevice>> PhysicalDeviceSelector::select_impl(
|
|||||||
|
|
||||||
if (criteria.require_present && !criteria.defer_surface_initialization) {
|
if (criteria.require_present && !criteria.defer_surface_initialization) {
|
||||||
if (instance_info.surface == VK_NULL_HANDLE)
|
if (instance_info.surface == VK_NULL_HANDLE)
|
||||||
return detail::Result<std::vector<PhysicalDevice>>{ PhysicalDeviceError::no_surface_provided };
|
return Result<std::vector<PhysicalDevice>>{ PhysicalDeviceError::no_surface_provided };
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the VkPhysicalDevice handles on the system
|
// Get the VkPhysicalDevice handles on the system
|
||||||
@ -1186,11 +1186,10 @@ detail::Result<std::vector<PhysicalDevice>> PhysicalDeviceSelector::select_impl(
|
|||||||
auto vk_physical_devices_ret = detail::get_vector<VkPhysicalDevice>(
|
auto vk_physical_devices_ret = detail::get_vector<VkPhysicalDevice>(
|
||||||
vk_physical_devices, detail::vulkan_functions().fp_vkEnumeratePhysicalDevices, instance_info.instance);
|
vk_physical_devices, detail::vulkan_functions().fp_vkEnumeratePhysicalDevices, instance_info.instance);
|
||||||
if (vk_physical_devices_ret != VK_SUCCESS) {
|
if (vk_physical_devices_ret != VK_SUCCESS) {
|
||||||
return detail::Result<std::vector<PhysicalDevice>>{ PhysicalDeviceError::failed_enumerate_physical_devices,
|
return Result<std::vector<PhysicalDevice>>{ PhysicalDeviceError::failed_enumerate_physical_devices, vk_physical_devices_ret };
|
||||||
vk_physical_devices_ret };
|
|
||||||
}
|
}
|
||||||
if (vk_physical_devices.size() == 0) {
|
if (vk_physical_devices.size() == 0) {
|
||||||
return detail::Result<std::vector<PhysicalDevice>>{ PhysicalDeviceError::no_physical_devices_found };
|
return Result<std::vector<PhysicalDevice>>{ PhysicalDeviceError::no_physical_devices_found };
|
||||||
}
|
}
|
||||||
|
|
||||||
auto fill_out_phys_dev_with_criteria = [&](PhysicalDevice& phys_dev) {
|
auto fill_out_phys_dev_with_criteria = [&](PhysicalDevice& phys_dev) {
|
||||||
@ -1248,32 +1247,32 @@ detail::Result<std::vector<PhysicalDevice>> PhysicalDeviceSelector::select_impl(
|
|||||||
return physical_devices;
|
return physical_devices;
|
||||||
}
|
}
|
||||||
|
|
||||||
detail::Result<PhysicalDevice> PhysicalDeviceSelector::select(DeviceSelectionMode selection) const {
|
Result<PhysicalDevice> PhysicalDeviceSelector::select(DeviceSelectionMode selection) const {
|
||||||
auto const selected_devices = select_impl(selection);
|
auto const selected_devices = select_impl(selection);
|
||||||
|
|
||||||
if (!selected_devices) return detail::Result<PhysicalDevice>{ selected_devices.error() };
|
if (!selected_devices) return Result<PhysicalDevice>{ selected_devices.error() };
|
||||||
if (selected_devices.value().size() == 0) {
|
if (selected_devices.value().size() == 0) {
|
||||||
return detail::Result<PhysicalDevice>{ PhysicalDeviceError::no_suitable_device };
|
return Result<PhysicalDevice>{ PhysicalDeviceError::no_suitable_device };
|
||||||
}
|
}
|
||||||
|
|
||||||
return selected_devices.value().at(0);
|
return selected_devices.value().at(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return all devices which are considered suitable - intended for applications which want to let the user pick the physical device
|
// Return all devices which are considered suitable - intended for applications which want to let the user pick the physical device
|
||||||
detail::Result<std::vector<PhysicalDevice>> PhysicalDeviceSelector::select_devices(DeviceSelectionMode selection) const {
|
Result<std::vector<PhysicalDevice>> PhysicalDeviceSelector::select_devices(DeviceSelectionMode selection) const {
|
||||||
auto const selected_devices = select_impl(selection);
|
auto const selected_devices = select_impl(selection);
|
||||||
if (!selected_devices) return detail::Result<std::vector<PhysicalDevice>>{ selected_devices.error() };
|
if (!selected_devices) return Result<std::vector<PhysicalDevice>>{ selected_devices.error() };
|
||||||
if (selected_devices.value().size() == 0) {
|
if (selected_devices.value().size() == 0) {
|
||||||
return detail::Result<std::vector<PhysicalDevice>>{ PhysicalDeviceError::no_suitable_device };
|
return Result<std::vector<PhysicalDevice>>{ PhysicalDeviceError::no_suitable_device };
|
||||||
}
|
}
|
||||||
return selected_devices.value();
|
return selected_devices.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
detail::Result<std::vector<std::string>> PhysicalDeviceSelector::select_device_names(DeviceSelectionMode selection) const {
|
Result<std::vector<std::string>> PhysicalDeviceSelector::select_device_names(DeviceSelectionMode selection) const {
|
||||||
auto const selected_devices = select_impl(selection);
|
auto const selected_devices = select_impl(selection);
|
||||||
if (!selected_devices) return detail::Result<std::vector<std::string>>{ selected_devices.error() };
|
if (!selected_devices) return Result<std::vector<std::string>>{ selected_devices.error() };
|
||||||
if (selected_devices.value().size() == 0) {
|
if (selected_devices.value().size() == 0) {
|
||||||
return detail::Result<std::vector<std::string>>{ PhysicalDeviceError::no_suitable_device };
|
return Result<std::vector<std::string>>{ PhysicalDeviceError::no_suitable_device };
|
||||||
}
|
}
|
||||||
std::vector<std::string> names;
|
std::vector<std::string> names;
|
||||||
for (const auto& pd : selected_devices.value()) {
|
for (const auto& pd : selected_devices.value()) {
|
||||||
@ -1410,61 +1409,55 @@ PhysicalDevice::operator VkPhysicalDevice() const { return this->physical_device
|
|||||||
|
|
||||||
// ---- Queues ---- //
|
// ---- Queues ---- //
|
||||||
|
|
||||||
detail::Result<uint32_t> Device::get_queue_index(QueueType type) const {
|
Result<uint32_t> Device::get_queue_index(QueueType type) const {
|
||||||
uint32_t index = detail::QUEUE_INDEX_MAX_VALUE;
|
uint32_t index = detail::QUEUE_INDEX_MAX_VALUE;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case QueueType::present:
|
case QueueType::present:
|
||||||
index = detail::get_present_queue_index(physical_device.physical_device, surface, queue_families);
|
index = detail::get_present_queue_index(physical_device.physical_device, surface, queue_families);
|
||||||
if (index == detail::QUEUE_INDEX_MAX_VALUE)
|
if (index == detail::QUEUE_INDEX_MAX_VALUE) return Result<uint32_t>{ QueueError::present_unavailable };
|
||||||
return detail::Result<uint32_t>{ QueueError::present_unavailable };
|
|
||||||
break;
|
break;
|
||||||
case QueueType::graphics:
|
case QueueType::graphics:
|
||||||
index = detail::get_first_queue_index(queue_families, VK_QUEUE_GRAPHICS_BIT);
|
index = detail::get_first_queue_index(queue_families, VK_QUEUE_GRAPHICS_BIT);
|
||||||
if (index == detail::QUEUE_INDEX_MAX_VALUE)
|
if (index == detail::QUEUE_INDEX_MAX_VALUE) return Result<uint32_t>{ QueueError::graphics_unavailable };
|
||||||
return detail::Result<uint32_t>{ QueueError::graphics_unavailable };
|
|
||||||
break;
|
break;
|
||||||
case QueueType::compute:
|
case QueueType::compute:
|
||||||
index = detail::get_separate_queue_index(queue_families, VK_QUEUE_COMPUTE_BIT, VK_QUEUE_TRANSFER_BIT);
|
index = detail::get_separate_queue_index(queue_families, VK_QUEUE_COMPUTE_BIT, VK_QUEUE_TRANSFER_BIT);
|
||||||
if (index == detail::QUEUE_INDEX_MAX_VALUE)
|
if (index == detail::QUEUE_INDEX_MAX_VALUE) return Result<uint32_t>{ QueueError::compute_unavailable };
|
||||||
return detail::Result<uint32_t>{ QueueError::compute_unavailable };
|
|
||||||
break;
|
break;
|
||||||
case QueueType::transfer:
|
case QueueType::transfer:
|
||||||
index = detail::get_separate_queue_index(queue_families, VK_QUEUE_TRANSFER_BIT, VK_QUEUE_COMPUTE_BIT);
|
index = detail::get_separate_queue_index(queue_families, VK_QUEUE_TRANSFER_BIT, VK_QUEUE_COMPUTE_BIT);
|
||||||
if (index == detail::QUEUE_INDEX_MAX_VALUE)
|
if (index == detail::QUEUE_INDEX_MAX_VALUE) return Result<uint32_t>{ QueueError::transfer_unavailable };
|
||||||
return detail::Result<uint32_t>{ QueueError::transfer_unavailable };
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return detail::Result<uint32_t>{ QueueError::invalid_queue_family_index };
|
return Result<uint32_t>{ QueueError::invalid_queue_family_index };
|
||||||
}
|
}
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
detail::Result<uint32_t> Device::get_dedicated_queue_index(QueueType type) const {
|
Result<uint32_t> Device::get_dedicated_queue_index(QueueType type) const {
|
||||||
uint32_t index = detail::QUEUE_INDEX_MAX_VALUE;
|
uint32_t index = detail::QUEUE_INDEX_MAX_VALUE;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case QueueType::compute:
|
case QueueType::compute:
|
||||||
index = detail::get_dedicated_queue_index(queue_families, VK_QUEUE_COMPUTE_BIT, VK_QUEUE_TRANSFER_BIT);
|
index = detail::get_dedicated_queue_index(queue_families, VK_QUEUE_COMPUTE_BIT, VK_QUEUE_TRANSFER_BIT);
|
||||||
if (index == detail::QUEUE_INDEX_MAX_VALUE)
|
if (index == detail::QUEUE_INDEX_MAX_VALUE) return Result<uint32_t>{ QueueError::compute_unavailable };
|
||||||
return detail::Result<uint32_t>{ QueueError::compute_unavailable };
|
|
||||||
break;
|
break;
|
||||||
case QueueType::transfer:
|
case QueueType::transfer:
|
||||||
index = detail::get_dedicated_queue_index(queue_families, VK_QUEUE_TRANSFER_BIT, VK_QUEUE_COMPUTE_BIT);
|
index = detail::get_dedicated_queue_index(queue_families, VK_QUEUE_TRANSFER_BIT, VK_QUEUE_COMPUTE_BIT);
|
||||||
if (index == detail::QUEUE_INDEX_MAX_VALUE)
|
if (index == detail::QUEUE_INDEX_MAX_VALUE) return Result<uint32_t>{ QueueError::transfer_unavailable };
|
||||||
return detail::Result<uint32_t>{ QueueError::transfer_unavailable };
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return detail::Result<uint32_t>{ QueueError::invalid_queue_family_index };
|
return Result<uint32_t>{ QueueError::invalid_queue_family_index };
|
||||||
}
|
}
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
detail::Result<VkQueue> Device::get_queue(QueueType type) const {
|
Result<VkQueue> Device::get_queue(QueueType type) const {
|
||||||
auto index = get_queue_index(type);
|
auto index = get_queue_index(type);
|
||||||
if (!index.has_value()) return { index.error() };
|
if (!index.has_value()) return { index.error() };
|
||||||
VkQueue out_queue;
|
VkQueue out_queue;
|
||||||
internal_table.fp_vkGetDeviceQueue(device, index.value(), 0, &out_queue);
|
internal_table.fp_vkGetDeviceQueue(device, index.value(), 0, &out_queue);
|
||||||
return out_queue;
|
return out_queue;
|
||||||
}
|
}
|
||||||
detail::Result<VkQueue> Device::get_dedicated_queue(QueueType type) const {
|
Result<VkQueue> Device::get_dedicated_queue(QueueType type) const {
|
||||||
auto index = get_dedicated_queue_index(type);
|
auto index = get_dedicated_queue_index(type);
|
||||||
if (!index.has_value()) return { index.error() };
|
if (!index.has_value()) return { index.error() };
|
||||||
VkQueue out_queue;
|
VkQueue out_queue;
|
||||||
@ -1491,7 +1484,7 @@ void destroy_device(Device device) {
|
|||||||
|
|
||||||
DeviceBuilder::DeviceBuilder(PhysicalDevice phys_device) { physical_device = phys_device; }
|
DeviceBuilder::DeviceBuilder(PhysicalDevice phys_device) { physical_device = phys_device; }
|
||||||
|
|
||||||
detail::Result<Device> DeviceBuilder::build() const {
|
Result<Device> DeviceBuilder::build() const {
|
||||||
|
|
||||||
std::vector<CustomQueueDescription> queue_descriptions;
|
std::vector<CustomQueueDescription> queue_descriptions;
|
||||||
queue_descriptions.insert(queue_descriptions.end(), info.queue_descriptions.begin(), info.queue_descriptions.end());
|
queue_descriptions.insert(queue_descriptions.end(), info.queue_descriptions.begin(), info.queue_descriptions.end());
|
||||||
@ -1760,9 +1753,9 @@ SwapchainBuilder::SwapchainBuilder(VkPhysicalDevice const physical_device,
|
|||||||
info.present_queue_index = detail::get_present_queue_index(physical_device, surface, queue_families);
|
info.present_queue_index = detail::get_present_queue_index(physical_device, surface, queue_families);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
detail::Result<Swapchain> SwapchainBuilder::build() const {
|
Result<Swapchain> SwapchainBuilder::build() const {
|
||||||
if (info.surface == VK_NULL_HANDLE) {
|
if (info.surface == VK_NULL_HANDLE) {
|
||||||
return detail::Error{ SwapchainError::surface_handle_not_provided };
|
return Error{ SwapchainError::surface_handle_not_provided };
|
||||||
}
|
}
|
||||||
|
|
||||||
auto desired_formats = info.desired_formats;
|
auto desired_formats = info.desired_formats;
|
||||||
@ -1772,7 +1765,7 @@ detail::Result<Swapchain> SwapchainBuilder::build() const {
|
|||||||
|
|
||||||
auto surface_support_ret = detail::query_surface_support_details(info.physical_device, info.surface);
|
auto surface_support_ret = detail::query_surface_support_details(info.physical_device, info.surface);
|
||||||
if (!surface_support_ret.has_value())
|
if (!surface_support_ret.has_value())
|
||||||
return detail::Error{ SwapchainError::failed_query_surface_support_details, surface_support_ret.vk_result() };
|
return Error{ SwapchainError::failed_query_surface_support_details, surface_support_ret.vk_result() };
|
||||||
auto surface_support = surface_support_ret.value();
|
auto surface_support = surface_support_ret.value();
|
||||||
|
|
||||||
uint32_t image_count = info.min_image_count;
|
uint32_t image_count = info.min_image_count;
|
||||||
@ -1848,7 +1841,7 @@ detail::Result<Swapchain> SwapchainBuilder::build() const {
|
|||||||
auto res = swapchain_create_proc(info.device, &swapchain_create_info, info.allocation_callbacks, &swapchain.swapchain);
|
auto res = swapchain_create_proc(info.device, &swapchain_create_info, info.allocation_callbacks, &swapchain.swapchain);
|
||||||
|
|
||||||
if (res != VK_SUCCESS) {
|
if (res != VK_SUCCESS) {
|
||||||
return detail::Error{ SwapchainError::failed_create_swapchain, res };
|
return Error{ SwapchainError::failed_create_swapchain, res };
|
||||||
}
|
}
|
||||||
swapchain.device = info.device;
|
swapchain.device = info.device;
|
||||||
swapchain.image_format = surface_format.format;
|
swapchain.image_format = surface_format.format;
|
||||||
@ -1862,7 +1855,7 @@ detail::Result<Swapchain> SwapchainBuilder::build() const {
|
|||||||
info.device, swapchain.internal_table.fp_vkDestroySwapchainKHR, "vkDestroySwapchainKHR");
|
info.device, swapchain.internal_table.fp_vkDestroySwapchainKHR, "vkDestroySwapchainKHR");
|
||||||
auto images = swapchain.get_images();
|
auto images = swapchain.get_images();
|
||||||
if (!images) {
|
if (!images) {
|
||||||
return detail::Error{ SwapchainError::failed_get_swapchain_images };
|
return Error{ SwapchainError::failed_get_swapchain_images };
|
||||||
}
|
}
|
||||||
swapchain.requested_min_image_count = image_count;
|
swapchain.requested_min_image_count = image_count;
|
||||||
swapchain.present_mode = present_mode;
|
swapchain.present_mode = present_mode;
|
||||||
@ -1870,18 +1863,18 @@ detail::Result<Swapchain> SwapchainBuilder::build() const {
|
|||||||
swapchain.allocation_callbacks = info.allocation_callbacks;
|
swapchain.allocation_callbacks = info.allocation_callbacks;
|
||||||
return swapchain;
|
return swapchain;
|
||||||
}
|
}
|
||||||
detail::Result<std::vector<VkImage>> Swapchain::get_images() {
|
Result<std::vector<VkImage>> Swapchain::get_images() {
|
||||||
std::vector<VkImage> swapchain_images;
|
std::vector<VkImage> swapchain_images;
|
||||||
|
|
||||||
auto swapchain_images_ret =
|
auto swapchain_images_ret =
|
||||||
detail::get_vector<VkImage>(swapchain_images, internal_table.fp_vkGetSwapchainImagesKHR, device, swapchain);
|
detail::get_vector<VkImage>(swapchain_images, internal_table.fp_vkGetSwapchainImagesKHR, device, swapchain);
|
||||||
if (swapchain_images_ret != VK_SUCCESS) {
|
if (swapchain_images_ret != VK_SUCCESS) {
|
||||||
return detail::Error{ SwapchainError::failed_get_swapchain_images, swapchain_images_ret };
|
return Error{ SwapchainError::failed_get_swapchain_images, swapchain_images_ret };
|
||||||
}
|
}
|
||||||
return swapchain_images;
|
return swapchain_images;
|
||||||
}
|
}
|
||||||
detail::Result<std::vector<VkImageView>> Swapchain::get_image_views() { return get_image_views(nullptr); }
|
Result<std::vector<VkImageView>> Swapchain::get_image_views() { return get_image_views(nullptr); }
|
||||||
detail::Result<std::vector<VkImageView>> Swapchain::get_image_views(const void* pNext) {
|
Result<std::vector<VkImageView>> Swapchain::get_image_views(const void* pNext) {
|
||||||
const auto swapchain_images_ret = get_images();
|
const auto swapchain_images_ret = get_images();
|
||||||
if (!swapchain_images_ret) return swapchain_images_ret.error();
|
if (!swapchain_images_ret) return swapchain_images_ret.error();
|
||||||
const auto swapchain_images = swapchain_images_ret.value();
|
const auto swapchain_images = swapchain_images_ret.value();
|
||||||
@ -1904,9 +1897,8 @@ detail::Result<std::vector<VkImageView>> Swapchain::get_image_views(const void*
|
|||||||
createInfo.subresourceRange.levelCount = 1;
|
createInfo.subresourceRange.levelCount = 1;
|
||||||
createInfo.subresourceRange.baseArrayLayer = 0;
|
createInfo.subresourceRange.baseArrayLayer = 0;
|
||||||
createInfo.subresourceRange.layerCount = 1;
|
createInfo.subresourceRange.layerCount = 1;
|
||||||
|
|
||||||
VkResult res = internal_table.fp_vkCreateImageView(device, &createInfo, allocation_callbacks, &views[i]);
|
VkResult res = internal_table.fp_vkCreateImageView(device, &createInfo, allocation_callbacks, &views[i]);
|
||||||
if (res != VK_SUCCESS) return detail::Error{ SwapchainError::failed_create_swapchain_image_views, res };
|
if (res != VK_SUCCESS) return Error{ SwapchainError::failed_create_swapchain_image_views, res };
|
||||||
}
|
}
|
||||||
return views;
|
return views;
|
||||||
}
|
}
|
||||||
|
@ -52,8 +52,6 @@
|
|||||||
|
|
||||||
namespace vkb {
|
namespace vkb {
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
struct Error {
|
struct Error {
|
||||||
std::error_code type;
|
std::error_code type;
|
||||||
VkResult vk_result = VK_SUCCESS; // optional error value if a vulkan call failed
|
VkResult vk_result = VK_SUCCESS; // optional error value if a vulkan call failed
|
||||||
@ -61,75 +59,76 @@ struct Error {
|
|||||||
|
|
||||||
template <typename T> class Result {
|
template <typename T> class Result {
|
||||||
public:
|
public:
|
||||||
Result(const T& value) : m_value{ value }, m_init{ true } {}
|
Result(const T& value) noexcept : m_value{ value }, m_init{ true } {}
|
||||||
Result(T&& value) : m_value{ std::move(value) }, m_init{ true } {}
|
Result(T&& value) noexcept : m_value{ std::move(value) }, m_init{ true } {}
|
||||||
|
|
||||||
Result(Error error) : m_error{ error }, m_init{ false } {}
|
Result(Error error) noexcept : m_error{ error }, m_init{ false } {}
|
||||||
|
|
||||||
Result(std::error_code error_code, VkResult result = VK_SUCCESS) : m_error{ error_code, result }, m_init{ false } {}
|
Result(std::error_code error_code, VkResult result = VK_SUCCESS) noexcept
|
||||||
|
: m_error{ error_code, result }, m_init{ false } {}
|
||||||
|
|
||||||
~Result() { destroy(); }
|
~Result() noexcept { destroy(); }
|
||||||
Result(Result const& expected) : m_init(expected.m_init) {
|
Result(Result const& expected) noexcept : m_init(expected.m_init) {
|
||||||
if (m_init)
|
if (m_init)
|
||||||
new (&m_value) T{ expected.m_value };
|
new (&m_value) T{ expected.m_value };
|
||||||
else
|
else
|
||||||
m_error = expected.m_error;
|
m_error = expected.m_error;
|
||||||
}
|
}
|
||||||
Result& operator=(Result const& result) {
|
Result& operator=(Result const& result) noexcept {
|
||||||
m_init = result.m_init;
|
m_init = result.m_init;
|
||||||
if (m_init)
|
if (m_init)
|
||||||
new (&m_value) T{ result.m_value };
|
new (&m_value) T{ result.m_value };
|
||||||
else
|
else
|
||||||
m_error = result.m_error;
|
m_error = result.m_error;
|
||||||
}
|
}
|
||||||
Result(Result&& expected) : m_init(expected.m_init) {
|
Result(Result&& expected) noexcept : m_init(expected.m_init) {
|
||||||
if (m_init)
|
if (m_init)
|
||||||
new (&m_value) T{ std::move(expected.m_value) };
|
new (&m_value) T{ std::move(expected.m_value) };
|
||||||
else
|
else
|
||||||
m_error = std::move(expected.m_error);
|
m_error = std::move(expected.m_error);
|
||||||
expected.destroy();
|
expected.destroy();
|
||||||
}
|
}
|
||||||
Result& operator=(Result&& result) {
|
Result& operator=(Result&& result) noexcept {
|
||||||
m_init = result.m_init;
|
m_init = result.m_init;
|
||||||
if (m_init)
|
if (m_init)
|
||||||
new (&m_value) T{ std::move(result.m_value) };
|
new (&m_value) T{ std::move(result.m_value) };
|
||||||
else
|
else
|
||||||
m_error = std::move(result.m_error);
|
m_error = std::move(result.m_error);
|
||||||
}
|
}
|
||||||
Result& operator=(const T& expect) {
|
Result& operator=(const T& expect) noexcept {
|
||||||
destroy();
|
destroy();
|
||||||
m_init = true;
|
m_init = true;
|
||||||
new (&m_value) T{ expect };
|
new (&m_value) T{ expect };
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
Result& operator=(T&& expect) {
|
Result& operator=(T&& expect) noexcept {
|
||||||
destroy();
|
destroy();
|
||||||
m_init = true;
|
m_init = true;
|
||||||
new (&m_value) T{ std::move(expect) };
|
new (&m_value) T{ std::move(expect) };
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
Result& operator=(const Error& error) {
|
Result& operator=(const Error& error) noexcept {
|
||||||
destroy();
|
destroy();
|
||||||
m_init = false;
|
m_init = false;
|
||||||
m_error = error;
|
m_error = error;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
Result& operator=(Error&& error) {
|
Result& operator=(Error&& error) noexcept {
|
||||||
destroy();
|
destroy();
|
||||||
m_init = false;
|
m_init = false;
|
||||||
m_error = error;
|
m_error = error;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
// clang-format off
|
// clang-format off
|
||||||
const T* operator-> () const { assert (m_init); return &m_value; }
|
const T* operator-> () const noexcept { assert (m_init); return &m_value; }
|
||||||
T* operator-> () { assert (m_init); return &m_value; }
|
T* operator-> () noexcept { assert (m_init); return &m_value; }
|
||||||
const T& operator* () const& { assert (m_init); return m_value; }
|
const T& operator* () const& noexcept { assert (m_init); return m_value; }
|
||||||
T& operator* () & { assert (m_init); return m_value; }
|
T& operator* () & noexcept { assert (m_init); return m_value; }
|
||||||
T&& operator* () && { assert (m_init); return std::move (m_value); }
|
T&& operator* () && noexcept { assert (m_init); return std::move (m_value); }
|
||||||
const T& value () const& { assert (m_init); return m_value; }
|
const T& value () const& noexcept { assert (m_init); return m_value; }
|
||||||
T& value () & { assert (m_init); return m_value; }
|
T& value () & noexcept { assert (m_init); return m_value; }
|
||||||
const T&& value () const&& { assert (m_init); return std::move (m_value); }
|
const T&& value () const&& noexcept { assert (m_init); return std::move (m_value); }
|
||||||
T&& value () && { assert (m_init); return std::move (m_value); }
|
T&& value () && noexcept { assert (m_init); return std::move (m_value); }
|
||||||
|
|
||||||
// std::error_code associated with the error
|
// std::error_code associated with the error
|
||||||
std::error_code error() const { assert (!m_init); return m_error.type; }
|
std::error_code error() const { assert (!m_init); return m_error.type; }
|
||||||
@ -139,6 +138,11 @@ template <typename T> class Result {
|
|||||||
Error full_error() const { assert (!m_init); return m_error; }
|
Error full_error() const { assert (!m_init); return m_error; }
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
// check if the result has an error that matches a specific error case
|
||||||
|
template <typename E> bool matches_error(E error_enum_value) const {
|
||||||
|
return !m_init && static_cast<E>(m_error.type.value()) == error_enum_value;
|
||||||
|
}
|
||||||
|
|
||||||
bool has_value() const { return m_init; }
|
bool has_value() const { return m_init; }
|
||||||
explicit operator bool() const { return m_init; }
|
explicit operator bool() const { return m_init; }
|
||||||
|
|
||||||
@ -153,6 +157,7 @@ template <typename T> class Result {
|
|||||||
bool m_init;
|
bool m_init;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
struct GenericFeaturesPNextNode {
|
struct GenericFeaturesPNextNode {
|
||||||
|
|
||||||
static const uint32_t field_capacity = 256;
|
static const uint32_t field_capacity = 256;
|
||||||
@ -234,8 +239,8 @@ struct SystemInfo {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// Use get_system_info to create a SystemInfo struct. This is because loading vulkan could fail.
|
// Use get_system_info to create a SystemInfo struct. This is because loading vulkan could fail.
|
||||||
static detail::Result<SystemInfo> get_system_info();
|
static Result<SystemInfo> get_system_info();
|
||||||
static detail::Result<SystemInfo> get_system_info(PFN_vkGetInstanceProcAddr fp_vkGetInstanceProcAddr);
|
static Result<SystemInfo> get_system_info(PFN_vkGetInstanceProcAddr fp_vkGetInstanceProcAddr);
|
||||||
|
|
||||||
// Returns true if a layer is available
|
// Returns true if a layer is available
|
||||||
bool is_layer_available(const char* layer_name) const;
|
bool is_layer_available(const char* layer_name) const;
|
||||||
@ -321,7 +326,7 @@ class InstanceBuilder {
|
|||||||
explicit InstanceBuilder(PFN_vkGetInstanceProcAddr fp_vkGetInstanceProcAddr);
|
explicit InstanceBuilder(PFN_vkGetInstanceProcAddr fp_vkGetInstanceProcAddr);
|
||||||
|
|
||||||
// Create a VkInstance. Return an error if it failed.
|
// Create a VkInstance. Return an error if it failed.
|
||||||
detail::Result<Instance> build() const;
|
Result<Instance> build() const;
|
||||||
|
|
||||||
// Sets the name of the application. Defaults to "" if none is provided.
|
// Sets the name of the application. Defaults to "" if none is provided.
|
||||||
InstanceBuilder& set_app_name(const char* app_name);
|
InstanceBuilder& set_app_name(const char* app_name);
|
||||||
@ -526,14 +531,14 @@ class PhysicalDeviceSelector {
|
|||||||
|
|
||||||
// Return the first device which is suitable
|
// Return the first device which is suitable
|
||||||
// use the `selection` parameter to configure if partially
|
// use the `selection` parameter to configure if partially
|
||||||
detail::Result<PhysicalDevice> select(DeviceSelectionMode selection = DeviceSelectionMode::partially_and_fully_suitable) const;
|
Result<PhysicalDevice> select(DeviceSelectionMode selection = DeviceSelectionMode::partially_and_fully_suitable) const;
|
||||||
|
|
||||||
// Return all devices which are considered suitable - intended for applications which want to let the user pick the physical device
|
// Return all devices which are considered suitable - intended for applications which want to let the user pick the physical device
|
||||||
detail::Result<std::vector<PhysicalDevice>> select_devices(
|
Result<std::vector<PhysicalDevice>> select_devices(
|
||||||
DeviceSelectionMode selection = DeviceSelectionMode::partially_and_fully_suitable) const;
|
DeviceSelectionMode selection = DeviceSelectionMode::partially_and_fully_suitable) const;
|
||||||
|
|
||||||
// Return the names of all devices which are considered suitable - intended for applications which want to let the user pick the physical device
|
// Return the names of all devices which are considered suitable - intended for applications which want to let the user pick the physical device
|
||||||
detail::Result<std::vector<std::string>> select_device_names(
|
Result<std::vector<std::string>> select_device_names(
|
||||||
DeviceSelectionMode selection = DeviceSelectionMode::partially_and_fully_suitable) const;
|
DeviceSelectionMode selection = DeviceSelectionMode::partially_and_fully_suitable) const;
|
||||||
|
|
||||||
// Set the surface in which the physical device should render to.
|
// Set the surface in which the physical device should render to.
|
||||||
@ -661,7 +666,7 @@ class PhysicalDeviceSelector {
|
|||||||
|
|
||||||
PhysicalDevice::Suitable is_device_suitable(PhysicalDevice const& phys_device) const;
|
PhysicalDevice::Suitable is_device_suitable(PhysicalDevice const& phys_device) const;
|
||||||
|
|
||||||
detail::Result<std::vector<PhysicalDevice>> select_impl(DeviceSelectionMode selection) const;
|
Result<std::vector<PhysicalDevice>> select_impl(DeviceSelectionMode selection) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---- Queue ---- //
|
// ---- Queue ---- //
|
||||||
@ -682,13 +687,13 @@ struct Device {
|
|||||||
VkAllocationCallbacks* allocation_callbacks = VK_NULL_HANDLE;
|
VkAllocationCallbacks* allocation_callbacks = VK_NULL_HANDLE;
|
||||||
PFN_vkGetDeviceProcAddr fp_vkGetDeviceProcAddr = nullptr;
|
PFN_vkGetDeviceProcAddr fp_vkGetDeviceProcAddr = nullptr;
|
||||||
|
|
||||||
detail::Result<uint32_t> get_queue_index(QueueType type) const;
|
Result<uint32_t> get_queue_index(QueueType type) const;
|
||||||
// Only a compute or transfer queue type is valid. All other queue types do not support a 'dedicated' queue index
|
// Only a compute or transfer queue type is valid. All other queue types do not support a 'dedicated' queue index
|
||||||
detail::Result<uint32_t> get_dedicated_queue_index(QueueType type) const;
|
Result<uint32_t> get_dedicated_queue_index(QueueType type) const;
|
||||||
|
|
||||||
detail::Result<VkQueue> get_queue(QueueType type) const;
|
Result<VkQueue> get_queue(QueueType type) const;
|
||||||
// Only a compute or transfer queue type is valid. All other queue types do not support a 'dedicated' queue
|
// Only a compute or transfer queue type is valid. All other queue types do not support a 'dedicated' queue
|
||||||
detail::Result<VkQueue> get_dedicated_queue(QueueType type) const;
|
Result<VkQueue> get_dedicated_queue(QueueType type) const;
|
||||||
|
|
||||||
// Return a loaded dispatch table
|
// Return a loaded dispatch table
|
||||||
DispatchTable make_table() const;
|
DispatchTable make_table() const;
|
||||||
@ -721,7 +726,7 @@ class DeviceBuilder {
|
|||||||
// Any features and extensions that are requested/required in PhysicalDeviceSelector are automatically enabled.
|
// Any features and extensions that are requested/required in PhysicalDeviceSelector are automatically enabled.
|
||||||
explicit DeviceBuilder(PhysicalDevice physical_device);
|
explicit DeviceBuilder(PhysicalDevice physical_device);
|
||||||
|
|
||||||
detail::Result<Device> build() const;
|
Result<Device> build() const;
|
||||||
|
|
||||||
// For Advanced Users: specify the exact list of VkDeviceQueueCreateInfo's needed for the application.
|
// For Advanced Users: specify the exact list of VkDeviceQueueCreateInfo's needed for the application.
|
||||||
// If a custom queue setup is provided, getting the queues and queue indexes is up to the application.
|
// If a custom queue setup is provided, getting the queues and queue indexes is up to the application.
|
||||||
@ -760,13 +765,13 @@ struct Swapchain {
|
|||||||
VkAllocationCallbacks* allocation_callbacks = VK_NULL_HANDLE;
|
VkAllocationCallbacks* allocation_callbacks = VK_NULL_HANDLE;
|
||||||
|
|
||||||
// Returns a vector of VkImage handles to the swapchain.
|
// Returns a vector of VkImage handles to the swapchain.
|
||||||
detail::Result<std::vector<VkImage>> get_images();
|
Result<std::vector<VkImage>> get_images();
|
||||||
|
|
||||||
// Returns a vector of VkImageView's to the VkImage's of the swapchain.
|
// Returns a vector of VkImageView's to the VkImage's of the swapchain.
|
||||||
// VkImageViews must be destroyed. The pNext chain must be a nullptr or a valid
|
// VkImageViews must be destroyed. The pNext chain must be a nullptr or a valid
|
||||||
// structure.
|
// structure.
|
||||||
detail::Result<std::vector<VkImageView>> get_image_views();
|
Result<std::vector<VkImageView>> get_image_views();
|
||||||
detail::Result<std::vector<VkImageView>> get_image_views(const void* pNext);
|
Result<std::vector<VkImageView>> get_image_views(const void* pNext);
|
||||||
void destroy_image_views(std::vector<VkImageView> const& image_views);
|
void destroy_image_views(std::vector<VkImageView> const& image_views);
|
||||||
|
|
||||||
// A conversion function which allows this Swapchain to be used
|
// A conversion function which allows this Swapchain to be used
|
||||||
@ -801,7 +806,7 @@ class SwapchainBuilder {
|
|||||||
uint32_t graphics_queue_index = detail::QUEUE_INDEX_MAX_VALUE,
|
uint32_t graphics_queue_index = detail::QUEUE_INDEX_MAX_VALUE,
|
||||||
uint32_t present_queue_index = detail::QUEUE_INDEX_MAX_VALUE);
|
uint32_t present_queue_index = detail::QUEUE_INDEX_MAX_VALUE);
|
||||||
|
|
||||||
detail::Result<Swapchain> build() const;
|
Result<Swapchain> build() const;
|
||||||
|
|
||||||
// Set the oldSwapchain member of VkSwapchainCreateInfoKHR.
|
// Set the oldSwapchain member of VkSwapchainCreateInfoKHR.
|
||||||
// For use in rebuilding a swapchain.
|
// For use in rebuilding a swapchain.
|
||||||
|
Loading…
Reference in New Issue
Block a user