From 756c593e96eac4eea409a2904c824d61470ccba2 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Thu, 23 May 2019 14:09:05 +0200 Subject: [PATCH] - create a new error class for vulkan errors as they are only recoverable during initialization (unlike CRecoverableError which is recoverable during normal processing) - improve vulkan errors by including the status code returned by vulkan if they fail --- src/posix/sdl/sdlglvideo.cpp | 2 +- src/rendering/vulkan/system/vk_builders.cpp | 6 +- src/rendering/vulkan/system/vk_builders.h | 36 ++++------ src/rendering/vulkan/system/vk_device.cpp | 73 +++++++++++++++----- src/rendering/vulkan/system/vk_device.h | 18 +++++ src/rendering/vulkan/system/vk_objects.h | 24 +++---- src/rendering/vulkan/system/vk_swapchain.cpp | 48 ++++++------- src/utility/doomerrors.h | 7 ++ src/win32/hardware.cpp | 2 +- 9 files changed, 126 insertions(+), 90 deletions(-) diff --git a/src/posix/sdl/sdlglvideo.cpp b/src/posix/sdl/sdlglvideo.cpp index 78f545216..e12da69cd 100644 --- a/src/posix/sdl/sdlglvideo.cpp +++ b/src/posix/sdl/sdlglvideo.cpp @@ -282,7 +282,7 @@ DFrameBuffer *SDLVideo::CreateFrameBuffer () device = new VulkanDevice(); fb = new VulkanFrameBuffer(nullptr, fullscreen, device); } - catch (CRecoverableError const&) + catch (CVulkanError const&) { if (Priv::window != nullptr) { diff --git a/src/rendering/vulkan/system/vk_builders.cpp b/src/rendering/vulkan/system/vk_builders.cpp index c0baed821..c8b4986bc 100644 --- a/src/rendering/vulkan/system/vk_builders.cpp +++ b/src/rendering/vulkan/system/vk_builders.cpp @@ -177,7 +177,11 @@ std::unique_ptr ShaderBuilder::create(const char *shadername, Vulk VkShaderModule shaderModule; VkResult result = vkCreateShaderModule(device->device, &createInfo, nullptr, &shaderModule); if (result != VK_SUCCESS) - I_FatalError("Could not create vulkan shader module for '%s'", shadername); + { + FString msg; + msg.Format("Could not create vulkan shader module for '%s': %s", shadername, VkResultToString(result).GetChars()); + VulkanError(msg.GetChars()); + } return std::make_unique(device, shaderModule); } diff --git a/src/rendering/vulkan/system/vk_builders.h b/src/rendering/vulkan/system/vk_builders.h index 9f6969d30..7eca4c6a1 100644 --- a/src/rendering/vulkan/system/vk_builders.h +++ b/src/rendering/vulkan/system/vk_builders.h @@ -430,8 +430,7 @@ inline std::unique_ptr ImageBuilder::create(VulkanDevice *device, V VmaAllocation allocation; VkResult result = vmaCreateImage(device->allocator, &imageInfo, &allocInfo, &image, &allocation, nullptr); - if (result != VK_SUCCESS) - I_FatalError("Could not create vulkan image"); + CheckVulkanError(result, "Could not create vulkan image"); if (allocatedBytes != nullptr) { @@ -480,8 +479,7 @@ inline std::unique_ptr ImageViewBuilder::create(VulkanDevice *d { VkImageView view; VkResult result = vkCreateImageView(device->device, &viewInfo, nullptr, &view); - if (result != VK_SUCCESS) - I_FatalError("Could not create texture image view"); + CheckVulkanError(result, "Could not create texture image view"); return std::make_unique(device, view); } @@ -552,8 +550,7 @@ inline std::unique_ptr SamplerBuilder::create(VulkanDevice *devic { VkSampler sampler; VkResult result = vkCreateSampler(device->device, &samplerInfo, nullptr, &sampler); - if (result != VK_SUCCESS) - I_FatalError("Could not create texture sampler"); + CheckVulkanError(result, "Could not create texture sampler"); return std::make_unique(device, sampler); } @@ -590,8 +587,7 @@ inline std::unique_ptr BufferBuilder::create(VulkanDevice *device) VmaAllocation allocation; VkResult result = vmaCreateBuffer(device->allocator, &bufferInfo, &allocInfo, &buffer, &allocation, nullptr); - if (result != VK_SUCCESS) - I_FatalError("could not allocate memory for vulkan buffer"); + CheckVulkanError(result, "Could not allocate memory for vulkan buffer"); return std::make_unique(device, buffer, allocation, bufferInfo.size); } @@ -650,8 +646,7 @@ inline std::unique_ptr DescriptorSetLayoutBuilder::cr { VkDescriptorSetLayout layout; VkResult result = vkCreateDescriptorSetLayout(device->device, &layoutInfo, nullptr, &layout); - if (result != VK_SUCCESS) - I_FatalError("Could not create descriptor set layout"); + CheckVulkanError(result, "Could not create descriptor set layout"); return std::make_unique(device, layout); } @@ -684,8 +679,7 @@ inline std::unique_ptr DescriptorPoolBuilder::create(Vulka { VkDescriptorPool descriptorPool; VkResult result = vkCreateDescriptorPool(device->device, &poolInfo, nullptr, &descriptorPool); - if (result != VK_SUCCESS) - I_FatalError("Could not create descriptor pool"); + CheckVulkanError(result, "Could not create descriptor pool"); return std::make_unique(device, descriptorPool); } @@ -707,8 +701,7 @@ inline std::unique_ptr QueryPoolBuilder::create(VulkanDevice *d { VkQueryPool queryPool; VkResult result = vkCreateQueryPool(device->device, &poolInfo, nullptr, &queryPool); - if (result != VK_SUCCESS) - I_FatalError("Could not create query pool"); + CheckVulkanError(result, "Could not create query pool"); return std::make_unique(device, queryPool); } @@ -751,8 +744,7 @@ inline std::unique_ptr FramebufferBuilder::create(VulkanDevic { VkFramebuffer framebuffer = 0; VkResult result = vkCreateFramebuffer(device->device, &framebufferInfo, nullptr, &framebuffer); - if (result != VK_SUCCESS) - I_FatalError("Failed to create framebuffer"); + CheckVulkanError(result, "Could not create framebuffer"); return std::make_unique(device, framebuffer); } @@ -1042,8 +1034,7 @@ inline std::unique_ptr GraphicsPipelineBuilder::create(VulkanDev { VkPipeline pipeline = 0; VkResult result = vkCreateGraphicsPipelines(device->device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &pipeline); - if (result != VK_SUCCESS) - I_FatalError("Could not create graphics pipeline"); + CheckVulkanError(result, "Could not create graphics pipeline"); return std::make_unique(device, pipeline); } @@ -1076,8 +1067,7 @@ inline std::unique_ptr PipelineLayoutBuilder::create(Vulka { VkPipelineLayout pipelineLayout; VkResult result = vkCreatePipelineLayout(device->device, &pipelineLayoutInfo, nullptr, &pipelineLayout); - if (result != VK_SUCCESS) - I_FatalError("Could not create pipeline layout"); + CheckVulkanError(result, "Could not create pipeline layout"); return std::make_unique(device, pipelineLayout); } @@ -1172,8 +1162,7 @@ inline std::unique_ptr RenderPassBuilder::create(VulkanDevice { VkRenderPass renderPass = 0; VkResult result = vkCreateRenderPass(device->device, &renderPassInfo, nullptr, &renderPass); - if (result != VK_SUCCESS) - I_FatalError("Could not create render pass"); + CheckVulkanError(result, "Could not create render pass"); return std::make_unique(device, renderPass); } @@ -1305,8 +1294,7 @@ inline void QueueSubmit::addSignal(VulkanSemaphore *semaphore) inline void QueueSubmit::execute(VulkanDevice *device, VkQueue queue, VulkanFence *fence) { VkResult result = vkQueueSubmit(device->graphicsQueue, 1, &submitInfo, fence ? fence->fence : VK_NULL_HANDLE); - if (result < VK_SUCCESS) - I_FatalError("Failed to submit command buffer"); + CheckVulkanError(result, "Could not submit command buffer"); } ///////////////////////////////////////////////////////////////////////////// diff --git a/src/rendering/vulkan/system/vk_device.cpp b/src/rendering/vulkan/system/vk_device.cpp index 08393a032..e0b70fa82 100644 --- a/src/rendering/vulkan/system/vk_device.cpp +++ b/src/rendering/vulkan/system/vk_device.cpp @@ -117,7 +117,7 @@ void VulkanDevice::SelectPhysicalDevice() { AvailableDevices = GetPhysicalDevices(instance); if (AvailableDevices.empty()) - I_Error("No Vulkan devices found. Either the graphics card has no vulkan support or the driver is too old."); + VulkanError("No Vulkan devices found. Either the graphics card has no vulkan support or the driver is too old."); for (size_t idx = 0; idx < AvailableDevices.size(); idx++) { @@ -169,7 +169,7 @@ void VulkanDevice::SelectPhysicalDevice() } if (SupportedDevices.empty()) - I_Error("No Vulkan device supports the minimum requirements of this application"); + VulkanError("No Vulkan device supports the minimum requirements of this application"); // The device order returned by Vulkan can be anything. Prefer discrete > integrated > virtual gpu > cpu > other std::stable_sort(SupportedDevices.begin(), SupportedDevices.end(), [&](const auto &a, const auto b) { @@ -221,7 +221,7 @@ void VulkanDevice::CreateAllocator() allocinfo.device = device; allocinfo.preferredLargeHeapBlockSize = 64 * 1024 * 1024; if (vmaCreateAllocator(&allocinfo, &allocator) != VK_SUCCESS) - I_Error("Unable to create allocator"); + VulkanError("Unable to create allocator"); } void VulkanDevice::CreateDevice() @@ -253,8 +253,7 @@ void VulkanDevice::CreateDevice() deviceCreateInfo.enabledLayerCount = 0; VkResult result = vkCreateDevice(PhysicalDevice.Device, &deviceCreateInfo, nullptr, &device); - if (result != VK_SUCCESS) - I_Error("Could not create vulkan device"); + CheckVulkanError(result, "Could not create vulkan device"); volkLoadDevice(device); @@ -266,7 +265,7 @@ void VulkanDevice::CreateSurface() { if (!I_CreateVulkanSurface(instance, &surface)) { - I_Error("Could not create vulkan surface"); + VulkanError("Could not create vulkan surface"); } } @@ -318,8 +317,7 @@ void VulkanDevice::CreateInstance() createInfo.ppEnabledExtensionNames = EnabledExtensions.data(); VkResult result = vkCreateInstance(&createInfo, nullptr, &instance); - if (result != VK_SUCCESS) - I_Error("Could not create vulkan instance"); + CheckVulkanError(result, "Could not create vulkan instance"); volkLoadInstance(instance); @@ -339,8 +337,7 @@ void VulkanDevice::CreateInstance() createInfo.pfnUserCallback = DebugCallback; createInfo.pUserData = this; result = vkCreateDebugUtilsMessengerEXT(instance, &createInfo, nullptr, &debugMessenger); - if (result != VK_SUCCESS) - I_Error("vkCreateDebugUtilsMessengerEXT failed"); + CheckVulkanError(result, "vkCreateDebugUtilsMessengerEXT failed"); DebugLayerActive = true; } @@ -441,15 +438,13 @@ std::vector VulkanDevice::GetPhysicalDevices(VkInstance in VkResult result = vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr); if (result == VK_ERROR_INITIALIZATION_FAILED) // Some drivers return this when a card does not support vulkan return {}; - if (result != VK_SUCCESS) - I_Error("vkEnumeratePhysicalDevices failed"); + CheckVulkanError(result, "vkEnumeratePhysicalDevices failed"); if (deviceCount == 0) return {}; std::vector devices(deviceCount); result = vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data()); - if (result != VK_SUCCESS) - I_Error("vkEnumeratePhysicalDevices failed (2)"); + CheckVulkanError(result, "vkEnumeratePhysicalDevices failed (2)"); std::vector devinfo(deviceCount); for (size_t i = 0; i < devices.size(); i++) @@ -478,11 +473,11 @@ std::vector VulkanDevice::GetPlatformExtensions() { uint32_t extensionCount = 0; if (!I_GetVulkanPlatformExtensions(&extensionCount, nullptr)) - I_Error("Cannot obtain number of Vulkan extensions"); + VulkanError("Cannot obtain number of Vulkan extensions"); std::vector extensions(extensionCount); if (!I_GetVulkanPlatformExtensions(&extensionCount, extensions.data())) - I_Error("Cannot obtain list of Vulkan extensions"); + VulkanError("Cannot obtain list of Vulkan extensions"); return extensions; } @@ -490,12 +485,12 @@ void VulkanDevice::InitVolk() { if (volkInitialize() != VK_SUCCESS) { - I_Error("Unable to find Vulkan"); + VulkanError("Unable to find Vulkan"); } auto iver = volkGetInstanceVersion(); if (iver == 0) { - I_Error("Vulkan not supported"); + VulkanError("Vulkan not supported"); } } @@ -531,6 +526,46 @@ uint32_t VulkanDevice::FindMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags return i; } - I_FatalError("failed to find suitable memory type!"); + VulkanError("failed to find suitable memory type!"); return 0; } + +FString VkResultToString(VkResult result) +{ + switch (result) + { + case VK_SUCCESS: return "success"; + case VK_NOT_READY: return "not ready"; + case VK_TIMEOUT: return "timeout"; + case VK_EVENT_SET: return "event set"; + case VK_EVENT_RESET: return "event reset"; + case VK_INCOMPLETE: return "incomplete"; + case VK_ERROR_OUT_OF_HOST_MEMORY: return "out of host memory"; + case VK_ERROR_OUT_OF_DEVICE_MEMORY: return "out of device memory"; + case VK_ERROR_INITIALIZATION_FAILED: return "initialization failed"; + case VK_ERROR_DEVICE_LOST: return "device lost"; + case VK_ERROR_MEMORY_MAP_FAILED: return "memory map failed"; + case VK_ERROR_LAYER_NOT_PRESENT: return "layer not present"; + case VK_ERROR_EXTENSION_NOT_PRESENT: return "extension not present"; + case VK_ERROR_FEATURE_NOT_PRESENT: return "feature not present"; + case VK_ERROR_INCOMPATIBLE_DRIVER: return "incompatible driver"; + case VK_ERROR_TOO_MANY_OBJECTS: return "too many objects"; + case VK_ERROR_FORMAT_NOT_SUPPORTED: return "format not supported"; + case VK_ERROR_FRAGMENTED_POOL: return "fragmented pool"; + case VK_ERROR_OUT_OF_POOL_MEMORY: return "out of pool memory"; + case VK_ERROR_INVALID_EXTERNAL_HANDLE: return "invalid external handle"; + case VK_ERROR_SURFACE_LOST_KHR: return "surface lost"; + case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: return "native window in use"; + case VK_SUBOPTIMAL_KHR: return "suboptimal"; + case VK_ERROR_OUT_OF_DATE_KHR: return "out of date"; + case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR: return "incompatible display"; + case VK_ERROR_VALIDATION_FAILED_EXT: return "validation failed"; + case VK_ERROR_INVALID_SHADER_NV: return "invalid shader"; + case VK_ERROR_FRAGMENTATION_EXT: return "fragmentation"; + case VK_ERROR_NOT_PERMITTED_EXT: return "not permitted"; + default: break; + } + FString res; + res.Format("vkResult %d", (int)result); + return result; +} diff --git a/src/rendering/vulkan/system/vk_device.h b/src/rendering/vulkan/system/vk_device.h index ac6767fe9..7609e7fdb 100644 --- a/src/rendering/vulkan/system/vk_device.h +++ b/src/rendering/vulkan/system/vk_device.h @@ -2,6 +2,7 @@ #include "volk/volk.h" #include "vk_mem_alloc/vk_mem_alloc.h" +#include "utility/doomerrors.h" #include #include #include @@ -99,3 +100,20 @@ private: static std::vector GetPlatformExtensions(); static std::vector GetPhysicalDevices(VkInstance instance); }; + +FString VkResultToString(VkResult result); + +inline void VulkanError(const char *text) +{ + throw CVulkanError(text); +} + +inline void CheckVulkanError(VkResult result, const char *text) +{ + if (result >= VK_SUCCESS) + return; + + FString msg; + msg.Format("%s: %s", text, VkResultToString(result).GetChars()); + throw CVulkanError(msg.GetChars()); +} diff --git a/src/rendering/vulkan/system/vk_objects.h b/src/rendering/vulkan/system/vk_objects.h index ac7bd89f2..9a71503c8 100644 --- a/src/rendering/vulkan/system/vk_objects.h +++ b/src/rendering/vulkan/system/vk_objects.h @@ -393,8 +393,7 @@ inline VulkanSemaphore::VulkanSemaphore(VulkanDevice *device) : device(device) VkSemaphoreCreateInfo semaphoreInfo = {}; semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; VkResult result = vkCreateSemaphore(device->device, &semaphoreInfo, nullptr, &semaphore); - if (result != VK_SUCCESS) - I_Error("Failed to create semaphore!"); + CheckVulkanError(result, "Could not create semaphore"); } inline VulkanSemaphore::~VulkanSemaphore() @@ -409,8 +408,7 @@ inline VulkanFence::VulkanFence(VulkanDevice *device) : device(device) VkFenceCreateInfo fenceInfo = {}; fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; VkResult result = vkCreateFence(device->device, &fenceInfo, nullptr, &fence); - if (result != VK_SUCCESS) - I_Error("Failed to create fence!"); + CheckVulkanError(result, "Could not create fence!"); } inline VulkanFence::~VulkanFence() @@ -451,8 +449,7 @@ inline VulkanCommandPool::VulkanCommandPool(VulkanDevice *device, int queueFamil poolInfo.flags = 0; VkResult result = vkCreateCommandPool(device->device, &poolInfo, nullptr, &pool); - if (result != VK_SUCCESS) - I_Error("Could not create command pool"); + CheckVulkanError(result, "Could not create command pool"); } inline VulkanCommandPool::~VulkanCommandPool() @@ -542,8 +539,7 @@ inline VulkanCommandBuffer::VulkanCommandBuffer(VulkanCommandPool *pool) : pool( allocInfo.commandBufferCount = 1; VkResult result = vkAllocateCommandBuffers(pool->device->device, &allocInfo, &buffer); - if (result != VK_SUCCESS) - I_Error("Could not create command buffer"); + CheckVulkanError(result, "Could not create command buffer"); } inline VulkanCommandBuffer::~VulkanCommandBuffer() @@ -559,15 +555,13 @@ inline void VulkanCommandBuffer::begin() beginInfo.pInheritanceInfo = nullptr; VkResult result = vkBeginCommandBuffer(buffer, &beginInfo); - if (result != VK_SUCCESS) - I_Error("Failed to begin recording command buffer!"); + CheckVulkanError(result, "Could not begin recording command buffer"); } inline void VulkanCommandBuffer::end() { VkResult result = vkEndCommandBuffer(buffer); - if (result != VK_SUCCESS) - I_Error("Failed to record command buffer!"); + CheckVulkanError(result, "Could not end command buffer recording"); } inline void VulkanCommandBuffer::debugFullPipelineBarrier() @@ -959,8 +953,7 @@ inline std::unique_ptr VulkanDescriptorPool::allocate(Vulka VkDescriptorSet descriptorSet; VkResult result = vkAllocateDescriptorSets(device->device, &allocInfo, &descriptorSet); - if (result != VK_SUCCESS) - I_FatalError("Could not allocate descriptor sets"); + CheckVulkanError(result, "Could not allocate descriptor sets"); return std::make_unique(device, this, descriptorSet); } @@ -979,8 +972,7 @@ inline VulkanQueryPool::~VulkanQueryPool() inline bool VulkanQueryPool::getResults(uint32_t firstQuery, uint32_t queryCount, size_t dataSize, void *data, VkDeviceSize stride, VkQueryResultFlags flags) { VkResult result = vkGetQueryPoolResults(device->device, pool, firstQuery, queryCount, dataSize, data, stride, flags); - if (result != VK_SUCCESS && result != VK_NOT_READY) - I_Error("vkGetQueryPoolResults failed"); + CheckVulkanError(result, "vkGetQueryPoolResults failed"); return result == VK_SUCCESS; } diff --git a/src/rendering/vulkan/system/vk_swapchain.cpp b/src/rendering/vulkan/system/vk_swapchain.cpp index 11d4d7143..4842d9e22 100644 --- a/src/rendering/vulkan/system/vk_swapchain.cpp +++ b/src/rendering/vulkan/system/vk_swapchain.cpp @@ -63,19 +63,19 @@ uint32_t VulkanSwapChain::AcquireImage(int width, int height, VulkanSemaphore *s } else if (result == VK_ERROR_OUT_OF_HOST_MEMORY || result == VK_ERROR_OUT_OF_DEVICE_MEMORY) { - I_FatalError("vkAcquireNextImageKHR failed: out of memory"); + VulkanError("vkAcquireNextImageKHR failed: out of memory"); } else if (result == VK_ERROR_DEVICE_LOST) { - I_FatalError("vkAcquireNextImageKHR failed: device lost"); + VulkanError("vkAcquireNextImageKHR failed: device lost"); } else if (result == VK_ERROR_SURFACE_LOST_KHR) { - I_FatalError("vkAcquireNextImageKHR failed: surface lost"); + VulkanError("vkAcquireNextImageKHR failed: surface lost"); } else { - I_FatalError("vkAcquireNextImageKHR failed"); + VulkanError("vkAcquireNextImageKHR failed"); } } return imageIndex; @@ -102,19 +102,19 @@ void VulkanSwapChain::QueuePresent(uint32_t imageIndex, VulkanSemaphore *semapho // The spec says we can recover from this. // However, if we are out of memory it is better to crash now than in some other weird place further away from the source of the problem. - I_FatalError("vkQueuePresentKHR failed: out of memory"); + VulkanError("vkQueuePresentKHR failed: out of memory"); } else if (result == VK_ERROR_DEVICE_LOST) { - I_FatalError("vkQueuePresentKHR failed: device lost"); + VulkanError("vkQueuePresentKHR failed: device lost"); } else if (result == VK_ERROR_SURFACE_LOST_KHR) { - I_FatalError("vkQueuePresentKHR failed: surface lost"); + VulkanError("vkQueuePresentKHR failed: surface lost"); } else if (result != VK_SUCCESS) { - I_FatalError("vkQueuePresentKHR failed"); + VulkanError("vkQueuePresentKHR failed"); } } @@ -225,8 +225,7 @@ void VulkanSwapChain::CreateViews() VkImageView view; VkResult result = vkCreateImageView(device->device, &createInfo, nullptr, &view); - if (result != VK_SUCCESS) - I_Error("Could not create image view for swapchain image"); + CheckVulkanError(result, "Could not create image view for swapchain image"); device->SetDebugObjectName("SwapChainImageView", (uint64_t)view, VK_OBJECT_TYPE_IMAGE_VIEW); @@ -238,7 +237,7 @@ void VulkanSwapChain::SelectFormat() { std::vector surfaceFormats = GetSurfaceFormats(); if (surfaceFormats.empty()) - I_Error("No surface formats supported"); + VulkanError("No surface formats supported"); if (surfaceFormats.size() == 1 && surfaceFormats.front().format == VK_FORMAT_UNDEFINED) { @@ -276,7 +275,7 @@ void VulkanSwapChain::SelectPresentMode() std::vector presentModes = GetPresentModes(); if (presentModes.empty()) - I_Error("No surface present modes supported"); + VulkanError("No surface present modes supported"); swapChainPresentMode = VK_PRESENT_MODE_FIFO_KHR; if (vid_vsync) @@ -327,13 +326,11 @@ void VulkanSwapChain::GetImages() { uint32_t imageCount; VkResult result = vkGetSwapchainImagesKHR(device->device, swapChain, &imageCount, nullptr); - if (result != VK_SUCCESS) - I_Error("vkGetSwapchainImagesKHR failed"); + CheckVulkanError(result, "vkGetSwapchainImagesKHR failed"); swapChainImages.resize(imageCount); result = vkGetSwapchainImagesKHR(device->device, swapChain, &imageCount, swapChainImages.data()); - if (result != VK_SUCCESS) - I_Error("vkGetSwapchainImagesKHR failed (2)"); + CheckVulkanError(result, "vkGetSwapchainImagesKHR failed (2)"); } void VulkanSwapChain::ReleaseViews() @@ -356,8 +353,7 @@ VkSurfaceCapabilitiesKHR VulkanSwapChain::GetSurfaceCapabilities() { VkSurfaceCapabilitiesKHR surfaceCapabilities; VkResult result = vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device->PhysicalDevice.Device, device->surface, &surfaceCapabilities); - if (result != VK_SUCCESS) - I_Error("vkGetPhysicalDeviceSurfaceCapabilitiesKHR failed"); + CheckVulkanError(result, "vkGetPhysicalDeviceSurfaceCapabilitiesKHR failed"); return surfaceCapabilities; } @@ -365,15 +361,13 @@ std::vector VulkanSwapChain::GetSurfaceFormats() { uint32_t surfaceFormatCount = 0; VkResult result = vkGetPhysicalDeviceSurfaceFormatsKHR(device->PhysicalDevice.Device, device->surface, &surfaceFormatCount, nullptr); - if (result != VK_SUCCESS) - I_Error("vkGetPhysicalDeviceSurfaceFormatsKHR failed"); - else if (surfaceFormatCount == 0) + CheckVulkanError(result, "vkGetPhysicalDeviceSurfaceFormatsKHR failed"); + if (surfaceFormatCount == 0) return {}; std::vector surfaceFormats(surfaceFormatCount); result = vkGetPhysicalDeviceSurfaceFormatsKHR(device->PhysicalDevice.Device, device->surface, &surfaceFormatCount, surfaceFormats.data()); - if (result != VK_SUCCESS) - I_Error("vkGetPhysicalDeviceSurfaceFormatsKHR failed"); + CheckVulkanError(result, "vkGetPhysicalDeviceSurfaceFormatsKHR failed"); return surfaceFormats; } @@ -381,14 +375,12 @@ std::vector VulkanSwapChain::GetPresentModes() { uint32_t presentModeCount = 0; VkResult result = vkGetPhysicalDeviceSurfacePresentModesKHR(device->PhysicalDevice.Device, device->surface, &presentModeCount, nullptr); - if (result != VK_SUCCESS) - I_Error("vkGetPhysicalDeviceSurfacePresentModesKHR failed"); - else if (presentModeCount == 0) + CheckVulkanError(result, "vkGetPhysicalDeviceSurfacePresentModesKHR failed"); + if (presentModeCount == 0) return {}; std::vector presentModes(presentModeCount); vkGetPhysicalDeviceSurfacePresentModesKHR(device->PhysicalDevice.Device, device->surface, &presentModeCount, presentModes.data()); - if (result != VK_SUCCESS) - I_Error("vkGetPhysicalDeviceSurfacePresentModesKHR failed"); + CheckVulkanError(result, "vkGetPhysicalDeviceSurfacePresentModesKHR failed"); return presentModes; } diff --git a/src/utility/doomerrors.h b/src/utility/doomerrors.h index 9847120e6..29e1a6fc9 100644 --- a/src/utility/doomerrors.h +++ b/src/utility/doomerrors.h @@ -104,6 +104,13 @@ public: CFatalError(const char *message) : CDoomError(message) {} }; +class CVulkanError : public CDoomError +{ +public: + CVulkanError() : CDoomError() {} + CVulkanError(const char *message) : CDoomError(message) {} +}; + void I_Error (const char *error, ...) GCCPRINTF(1,2); void I_FatalError (const char *error, ...) GCCPRINTF(1,2); diff --git a/src/win32/hardware.cpp b/src/win32/hardware.cpp index 7f101112c..0a5457eef 100644 --- a/src/win32/hardware.cpp +++ b/src/win32/hardware.cpp @@ -137,7 +137,7 @@ void I_InitGraphics () { Video = new Win32VulkanVideo(); } - catch (CRecoverableError &error) + catch (CVulkanError &error) { Printf(TEXTCOLOR_RED "Initialization of Vulkan failed: %s\n", error.what()); Video = new Win32GLVideo();