renderer_vulkan: Better error handling
This commit is contained in:
@ -19,6 +19,17 @@
|
|||||||
|
|
||||||
namespace Settings {
|
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 = {};
|
Values values = {};
|
||||||
static bool configuring_global = true;
|
static bool configuring_global = true;
|
||||||
|
|
||||||
@ -94,7 +105,7 @@ void LogSettings() {
|
|||||||
LOG_INFO(Config, "Citra Configuration:");
|
LOG_INFO(Config, "Citra Configuration:");
|
||||||
log_setting("Core_UseCpuJit", values.use_cpu_jit.GetValue());
|
log_setting("Core_UseCpuJit", values.use_cpu_jit.GetValue());
|
||||||
log_setting("Core_CPUClockPercentage", values.cpu_clock_percentage.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_UseHwRenderer", values.use_hw_renderer.GetValue());
|
||||||
log_setting("Renderer_UseHwShader", values.use_hw_shader.GetValue());
|
log_setting("Renderer_UseHwShader", values.use_hw_shader.GetValue());
|
||||||
log_setting("Renderer_SeparableShader", values.separable_shader.GetValue());
|
log_setting("Renderer_SeparableShader", values.separable_shader.GetValue());
|
||||||
|
@ -99,13 +99,19 @@ Instance::Instance(Frontend::EmuWindow& window, u32 physical_device_index, bool
|
|||||||
static_cast<u32>(extensions.size()),
|
static_cast<u32>(extensions.size()),
|
||||||
.ppEnabledExtensionNames = extensions.data()};
|
.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);
|
surface = CreateSurface(instance, window);
|
||||||
|
|
||||||
// Pick physical device
|
// Pick physical device
|
||||||
physical_devices = instance.enumeratePhysicalDevices();
|
physical_devices = instance.enumeratePhysicalDevices();
|
||||||
if (const u16 physical_device_count = static_cast<u16>(physical_devices.size());
|
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,
|
LOG_CRITICAL(Render_Vulkan,
|
||||||
"Invalid physical device index {} provided when only {} devices exist",
|
"Invalid physical device index {} provided when only {} devices exist",
|
||||||
physical_device_index, physical_device_count);
|
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];
|
physical_device = physical_devices[physical_device_index];
|
||||||
device_properties = physical_device.getProperties();
|
device_properties = physical_device.getProperties();
|
||||||
|
|
||||||
|
LOG_INFO(Render_Vulkan, "Creating logical device for physical device: {}",
|
||||||
|
device_properties.deviceName);
|
||||||
|
|
||||||
CreateDevice();
|
CreateDevice();
|
||||||
CreateFormatTable();
|
CreateFormatTable();
|
||||||
}
|
}
|
||||||
@ -262,7 +271,7 @@ bool Instance::CreateDevice() {
|
|||||||
// Search queue families for graphics and present queues
|
// Search queue families for graphics and present queues
|
||||||
auto family_properties = physical_device.getQueueFamilyProperties();
|
auto family_properties = physical_device.getQueueFamilyProperties();
|
||||||
if (family_properties.empty()) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -330,7 +339,14 @@ bool Instance::CreateDevice() {
|
|||||||
feature_chain.get<vk::PhysicalDeviceTimelineSemaphoreFeaturesKHR>()};
|
feature_chain.get<vk::PhysicalDeviceTimelineSemaphoreFeaturesKHR>()};
|
||||||
|
|
||||||
// Create logical device
|
// 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);
|
VULKAN_HPP_DEFAULT_DISPATCHER.init(device);
|
||||||
|
|
||||||
// Grab the graphics and present queues.
|
// Grab the graphics and present queues.
|
||||||
|
@ -187,9 +187,7 @@ RasterizerVulkan::~RasterizerVulkan() {
|
|||||||
vmaDestroyImage(allocator, default_texture.image, default_texture.allocation);
|
vmaDestroyImage(allocator, default_texture.image, default_texture.allocation);
|
||||||
vmaDestroyImage(allocator, default_storage_texture.image, default_storage_texture.allocation);
|
vmaDestroyImage(allocator, default_storage_texture.image, default_storage_texture.allocation);
|
||||||
device.destroyImageView(default_texture.image_view);
|
device.destroyImageView(default_texture.image_view);
|
||||||
device.destroyImageView(default_texture.base_view);
|
|
||||||
device.destroyImageView(default_storage_texture.image_view);
|
device.destroyImageView(default_storage_texture.image_view);
|
||||||
device.destroyImageView(default_storage_texture.base_view);
|
|
||||||
device.destroySampler(default_sampler);
|
device.destroySampler(default_sampler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
VkResult result = vmaCreateImage(instance.GetAllocator(), &unsafe_image_info, &alloc_info,
|
||||||
&unsafe_image, &allocation, nullptr);
|
&unsafe_image, &allocation, nullptr);
|
||||||
if (result != VK_SUCCESS) {
|
if (result != VK_SUCCESS) [[unlikely]] {
|
||||||
LOG_CRITICAL(Render_Vulkan, "Failed allocating texture with error {}", result);
|
LOG_CRITICAL(Render_Vulkan, "Failed allocating texture with error {}", result);
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
@ -168,19 +168,23 @@ ImageAlloc TextureRuntime::Allocate(u32 width, u32 height, u32 layers, u32 level
|
|||||||
.baseArrayLayer = 0,
|
.baseArrayLayer = 0,
|
||||||
.layerCount = layers}};
|
.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::Device device = instance.GetDevice();
|
||||||
vk::ImageView image_view = device.createImageView(view_info);
|
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
|
// Create seperate depth/stencil views in case this gets reinterpreted with a compute shader
|
||||||
vk::ImageView depth_view;
|
vk::ImageView depth_view;
|
||||||
@ -587,6 +591,7 @@ void Surface::Upload(const VideoCore::BufferTextureCopy& upload, const StagingDa
|
|||||||
|
|
||||||
const bool is_scaled = res_scale != 1;
|
const bool is_scaled = res_scale != 1;
|
||||||
if (is_scaled) {
|
if (is_scaled) {
|
||||||
|
LOG_ERROR(Render_Vulkan, "Unimplemented scaled upload!");
|
||||||
ScaledUpload(upload);
|
ScaledUpload(upload);
|
||||||
} else {
|
} else {
|
||||||
u32 region_count = 0;
|
u32 region_count = 0;
|
||||||
@ -641,6 +646,7 @@ void Surface::Download(const VideoCore::BufferTextureCopy& download, const Stagi
|
|||||||
|
|
||||||
const bool is_scaled = res_scale != 1;
|
const bool is_scaled = res_scale != 1;
|
||||||
if (is_scaled) {
|
if (is_scaled) {
|
||||||
|
LOG_ERROR(Render_Vulkan, "Unimplemented scaled download!");
|
||||||
ScaledDownload(download);
|
ScaledDownload(download);
|
||||||
} else {
|
} else {
|
||||||
u32 region_count = 0;
|
u32 region_count = 0;
|
||||||
|
Reference in New Issue
Block a user