From 28a280545083f9a62c8668edca56de96ec045ebd Mon Sep 17 00:00:00 2001 From: emufan4568 Date: Fri, 14 Oct 2022 15:06:32 +0300 Subject: [PATCH] renderer_vulkan: Better error handling --- src/common/settings.cpp | 13 +++++++- .../renderer_vulkan/vk_instance.cpp | 24 ++++++++++++--- .../renderer_vulkan/vk_rasterizer.cpp | 2 -- .../renderer_vulkan/vk_texture_runtime.cpp | 30 +++++++++++-------- 4 files changed, 50 insertions(+), 19 deletions(-) diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 17bb637cf..af4db7386 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -19,6 +19,17 @@ namespace Settings { +[[nodiscard]] std::string_view GetAPIName(GraphicsAPI api) { + switch (api) { + case GraphicsAPI::OpenGL: + return "OpenGL"; + case GraphicsAPI::OpenGLES: + return "OpenGLES"; + case GraphicsAPI::Vulkan: + return "Vulkan"; + } +} + Values values = {}; static bool configuring_global = true; @@ -94,7 +105,7 @@ void LogSettings() { LOG_INFO(Config, "Citra Configuration:"); log_setting("Core_UseCpuJit", values.use_cpu_jit.GetValue()); log_setting("Core_CPUClockPercentage", values.cpu_clock_percentage.GetValue()); - log_setting("Renderer_GraphicsAPI", values.graphics_api.GetValue()); + log_setting("Renderer_GraphicsAPI", GetAPIName(values.graphics_api.GetValue())); log_setting("Renderer_UseHwRenderer", values.use_hw_renderer.GetValue()); log_setting("Renderer_UseHwShader", values.use_hw_shader.GetValue()); log_setting("Renderer_SeparableShader", values.separable_shader.GetValue()); diff --git a/src/video_core/renderer_vulkan/vk_instance.cpp b/src/video_core/renderer_vulkan/vk_instance.cpp index 0c4130335..7f15da86f 100644 --- a/src/video_core/renderer_vulkan/vk_instance.cpp +++ b/src/video_core/renderer_vulkan/vk_instance.cpp @@ -99,13 +99,19 @@ Instance::Instance(Frontend::EmuWindow& window, u32 physical_device_index, bool static_cast(extensions.size()), .ppEnabledExtensionNames = extensions.data()}; - instance = vk::createInstance(instance_info); + try { + instance = vk::createInstance(instance_info); + } catch (vk::LayerNotPresentError& err) { + LOG_CRITICAL(Render_Vulkan, "Validation requested but layer is not available!"); + UNREACHABLE(); + } + surface = CreateSurface(instance, window); // Pick physical device physical_devices = instance.enumeratePhysicalDevices(); if (const u16 physical_device_count = static_cast(physical_devices.size()); - physical_device_index >= physical_devices.size()) { + physical_device_index >= physical_devices.size()) [[unlikely]] { LOG_CRITICAL(Render_Vulkan, "Invalid physical device index {} provided when only {} devices exist", physical_device_index, physical_device_count); @@ -115,6 +121,9 @@ Instance::Instance(Frontend::EmuWindow& window, u32 physical_device_index, bool physical_device = physical_devices[physical_device_index]; device_properties = physical_device.getProperties(); + LOG_INFO(Render_Vulkan, "Creating logical device for physical device: {}", + device_properties.deviceName); + CreateDevice(); CreateFormatTable(); } @@ -262,7 +271,7 @@ bool Instance::CreateDevice() { // Search queue families for graphics and present queues auto family_properties = physical_device.getQueueFamilyProperties(); if (family_properties.empty()) { - LOG_CRITICAL(Render_Vulkan, "Vulkan physical device reported no queues."); + LOG_CRITICAL(Render_Vulkan, "Physical device reported no queues."); return false; } @@ -330,7 +339,14 @@ bool Instance::CreateDevice() { feature_chain.get()}; // Create logical device - device = physical_device.createDevice(device_chain.get()); + try { + device = physical_device.createDevice(device_chain.get()); + } catch (vk::ExtensionNotPresentError& err) { + LOG_CRITICAL(Render_Vulkan, "Some required extensions are not available, " + "check extension log for details"); + UNREACHABLE(); + } + VULKAN_HPP_DEFAULT_DISPATCHER.init(device); // Grab the graphics and present queues. diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 17e5a055a..5bcebdf87 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -187,9 +187,7 @@ RasterizerVulkan::~RasterizerVulkan() { vmaDestroyImage(allocator, default_texture.image, default_texture.allocation); vmaDestroyImage(allocator, default_storage_texture.image, default_storage_texture.allocation); device.destroyImageView(default_texture.image_view); - device.destroyImageView(default_texture.base_view); device.destroyImageView(default_storage_texture.image_view); - device.destroyImageView(default_storage_texture.base_view); device.destroySampler(default_sampler); } diff --git a/src/video_core/renderer_vulkan/vk_texture_runtime.cpp b/src/video_core/renderer_vulkan/vk_texture_runtime.cpp index 3ea74241e..ad9fb5010 100644 --- a/src/video_core/renderer_vulkan/vk_texture_runtime.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_runtime.cpp @@ -149,7 +149,7 @@ ImageAlloc TextureRuntime::Allocate(u32 width, u32 height, u32 layers, u32 level VkResult result = vmaCreateImage(instance.GetAllocator(), &unsafe_image_info, &alloc_info, &unsafe_image, &allocation, nullptr); - if (result != VK_SUCCESS) { + if (result != VK_SUCCESS) [[unlikely]] { LOG_CRITICAL(Render_Vulkan, "Failed allocating texture with error {}", result); UNREACHABLE(); } @@ -168,19 +168,23 @@ ImageAlloc TextureRuntime::Allocate(u32 width, u32 height, u32 layers, u32 level .baseArrayLayer = 0, .layerCount = layers}}; - // Also create a base mip view in case this is used as an attachment - const vk::ImageViewCreateInfo base_view_info = {.image = image, - .viewType = view_type, - .format = format, - .subresourceRange = {.aspectMask = aspect, - .baseMipLevel = 0, - .levelCount = 1, - .baseArrayLayer = 0, - .layerCount = layers}}; - vk::Device device = instance.GetDevice(); vk::ImageView image_view = device.createImageView(view_info); - vk::ImageView base_view = device.createImageView(base_view_info); + + // Also create a base mip view in case this is used as an attachment + vk::ImageView base_view; + if (levels > 1) [[likely]] { + const vk::ImageViewCreateInfo base_view_info = {.image = image, + .viewType = view_type, + .format = format, + .subresourceRange = {.aspectMask = aspect, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = layers}}; + + base_view = device.createImageView(base_view_info); + } // Create seperate depth/stencil views in case this gets reinterpreted with a compute shader vk::ImageView depth_view; @@ -587,6 +591,7 @@ void Surface::Upload(const VideoCore::BufferTextureCopy& upload, const StagingDa const bool is_scaled = res_scale != 1; if (is_scaled) { + LOG_ERROR(Render_Vulkan, "Unimplemented scaled upload!"); ScaledUpload(upload); } else { u32 region_count = 0; @@ -641,6 +646,7 @@ void Surface::Download(const VideoCore::BufferTextureCopy& download, const Stagi const bool is_scaled = res_scale != 1; if (is_scaled) { + LOG_ERROR(Render_Vulkan, "Unimplemented scaled download!"); ScaledDownload(download); } else { u32 region_count = 0;