renderer_vulkan: Better error handling

This commit is contained in:
emufan4568
2022-10-14 15:06:32 +03:00
committed by GPUCode
parent 2601a1df6c
commit 28a2805450
4 changed files with 50 additions and 19 deletions

View File

@ -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());

View File

@ -99,13 +99,19 @@ Instance::Instance(Frontend::EmuWindow& window, u32 physical_device_index, bool
static_cast<u32>(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<u16>(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<vk::PhysicalDeviceTimelineSemaphoreFeaturesKHR>()};
// 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.

View File

@ -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);
}

View File

@ -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;