Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vulkan: Enable VULKAN_HPP_NO_EXCEPTIONS broadly. #995

Merged
merged 2 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/imgui/renderer/imgui_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,11 @@ void OnResize() {
}

void Shutdown(const vk::Device& device) {
device.waitIdle();
auto result = device.waitIdle();
if (result != vk::Result::eSuccess) {
LOG_WARNING(ImGui, "Failed to wait for Vulkan device idle on shutdown: {}",
vk::to_string(result));
}

TextureManager::StopWorker();

Expand Down
1 change: 0 additions & 1 deletion src/imgui/renderer/imgui_impl_vulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

#pragma once

#define VULKAN_HPP_NO_EXCEPTIONS
#include "common/types.h"
#include "video_core/renderer_vulkan/vk_common.h"

Expand Down
4 changes: 3 additions & 1 deletion src/video_core/buffer_cache/buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@ vk::BufferView Buffer::View(u32 offset, u32 size, bool is_written, AmdGpu::DataF
.offset = offset,
.range = size,
};
const auto view = instance->GetDevice().createBufferView(view_ci);
const auto [view_result, view] = instance->GetDevice().createBufferView(view_ci);
ASSERT_MSG(view_result == vk::Result::eSuccess, "Failed to create buffer view: {}",
vk::to_string(view_result));
scheduler->DeferOperation(
[view, device = instance->GetDevice()] { device.destroyBufferView(view); });
return view;
Expand Down
11 changes: 9 additions & 2 deletions src/video_core/renderer_vulkan/renderer_vulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,11 @@ RendererVulkan::RendererVulkan(Frontend::WindowSDL& window_, AmdGpu::Liverpool*
present_frames.resize(num_images);
for (u32 i = 0; i < num_images; i++) {
Frame& frame = present_frames[i];
frame.present_done = device.createFence({.flags = vk::FenceCreateFlagBits::eSignaled});
auto [fence_result, fence] =
device.createFence({.flags = vk::FenceCreateFlagBits::eSignaled});
ASSERT_MSG(fence_result == vk::Result::eSuccess, "Failed to create present done fence: {}",
vk::to_string(fence_result));
frame.present_done = fence;
free_queue.push(&frame);
}

Expand Down Expand Up @@ -157,7 +161,10 @@ void RendererVulkan::RecreateFrame(Frame* frame, u32 width, u32 height) {
.layerCount = 1,
},
};
frame->image_view = device.createImageView(view_info);
auto [view_result, view] = device.createImageView(view_info);
ASSERT_MSG(view_result == vk::Result::eSuccess, "Failed to create frame image view: {}",
vk::to_string(view_result));
frame->image_view = view;
frame->width = width;
frame->height = height;
}
Expand Down
3 changes: 3 additions & 0 deletions src/video_core/renderer_vulkan/vk_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
#define VULKAN_HPP_NO_CONSTRUCTORS
#define VULKAN_HPP_NO_STRUCT_SETTERS
#define VULKAN_HPP_HAS_SPACESHIP_OPERATOR
#define VULKAN_HPP_NO_EXCEPTIONS
// Define assert-on-result to nothing to instead return the result for our handling.
#define VULKAN_HPP_ASSERT_ON_RESULT
#include <vulkan/vulkan.hpp>

#define VMA_STATIC_VULKAN_FUNCTIONS 0
Expand Down
22 changes: 14 additions & 8 deletions src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,12 @@ ComputePipeline::ComputePipeline(const Instance& instance_, Scheduler& scheduler
.bindingCount = static_cast<u32>(bindings.size()),
.pBindings = bindings.data(),
};
desc_layout = instance.GetDevice().createDescriptorSetLayoutUnique(desc_layout_ci);
auto [descriptor_set_result, descriptor_set] =
instance.GetDevice().createDescriptorSetLayoutUnique(desc_layout_ci);
ASSERT_MSG(descriptor_set_result == vk::Result::eSuccess,
"Failed to create compute descriptor set layout: {}",
vk::to_string(descriptor_set_result));
desc_layout = std::move(descriptor_set);

const vk::DescriptorSetLayout set_layout = *desc_layout;
const vk::PipelineLayoutCreateInfo layout_info = {
Expand All @@ -87,19 +92,20 @@ ComputePipeline::ComputePipeline(const Instance& instance_, Scheduler& scheduler
.pushConstantRangeCount = 1U,
.pPushConstantRanges = &push_constants,
};
pipeline_layout = instance.GetDevice().createPipelineLayoutUnique(layout_info);
auto [layout_result, layout] = instance.GetDevice().createPipelineLayoutUnique(layout_info);
ASSERT_MSG(layout_result == vk::Result::eSuccess,
"Failed to create compute pipeline layout: {}", vk::to_string(layout_result));
pipeline_layout = std::move(layout);

const vk::ComputePipelineCreateInfo compute_pipeline_ci = {
.stage = shader_ci,
.layout = *pipeline_layout,
};
auto result =
auto [pipeline_result, pipe] =
instance.GetDevice().createComputePipelineUnique(pipeline_cache, compute_pipeline_ci);
if (result.result == vk::Result::eSuccess) {
pipeline = std::move(result.value);
} else {
UNREACHABLE_MSG("Graphics pipeline creation failed!");
}
ASSERT_MSG(pipeline_result == vk::Result::eSuccess, "Failed to create compute pipeline: {}",
vk::to_string(pipeline_result));
pipeline = std::move(pipe);
}

ComputePipeline::~ComputePipeline() = default;
Expand Down
22 changes: 14 additions & 8 deletions src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& schedul
.pushConstantRangeCount = 1,
.pPushConstantRanges = &push_constants,
};
pipeline_layout = instance.GetDevice().createPipelineLayoutUnique(layout_info);
auto [layout_result, layout] = instance.GetDevice().createPipelineLayoutUnique(layout_info);
ASSERT_MSG(layout_result == vk::Result::eSuccess,
"Failed to create graphics pipeline layout: {}", vk::to_string(layout_result));
pipeline_layout = std::move(layout);

boost::container::static_vector<vk::VertexInputBindingDescription, 32> vertex_bindings;
boost::container::static_vector<vk::VertexInputAttributeDescription, 32> vertex_attributes;
Expand Down Expand Up @@ -281,12 +284,11 @@ GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& schedul
.layout = *pipeline_layout,
};

auto result = device.createGraphicsPipelineUnique(pipeline_cache, pipeline_info);
if (result.result == vk::Result::eSuccess) {
pipeline = std::move(result.value);
} else {
UNREACHABLE_MSG("Graphics pipeline creation failed!");
}
auto [pipeline_result, pipe] =
device.createGraphicsPipelineUnique(pipeline_cache, pipeline_info);
ASSERT_MSG(pipeline_result == vk::Result::eSuccess, "Failed to create graphics pipeline: {}",
vk::to_string(pipeline_result));
pipeline = std::move(pipe);
}

GraphicsPipeline::~GraphicsPipeline() = default;
Expand Down Expand Up @@ -345,7 +347,11 @@ void GraphicsPipeline::BuildDescSetLayout() {
.bindingCount = static_cast<u32>(bindings.size()),
.pBindings = bindings.data(),
};
desc_layout = instance.GetDevice().createDescriptorSetLayoutUnique(desc_layout_ci);
auto [layout_result, layout] =
instance.GetDevice().createDescriptorSetLayoutUnique(desc_layout_ci);
ASSERT_MSG(layout_result == vk::Result::eSuccess,
"Failed to create graphics descriptor set layout: {}", vk::to_string(layout_result));
desc_layout = std::move(layout);
}

void GraphicsPipeline::BindResources(const Liverpool::Regs& regs,
Expand Down
76 changes: 48 additions & 28 deletions src/video_core/renderer_vulkan/vk_instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,20 @@ namespace Vulkan {

namespace {

std::vector<vk::PhysicalDevice> EnumeratePhysicalDevices(vk::UniqueInstance& instance) {
auto [devices_result, devices] = instance->enumeratePhysicalDevices();
ASSERT_MSG(devices_result == vk::Result::eSuccess, "Failed to enumerate physical devices: {}",
vk::to_string(devices_result));
return std::move(devices);
}

std::vector<std::string> GetSupportedExtensions(vk::PhysicalDevice physical) {
const std::vector extensions = physical.enumerateDeviceExtensionProperties();
const auto [extensions_result, extensions] = physical.enumerateDeviceExtensionProperties();
if (extensions_result != vk::Result::eSuccess) {
LOG_ERROR(Render_Vulkan, "Could not query supported extensions: {}",
vk::to_string(extensions_result));
return {};
}
std::vector<std::string> supported_extensions;
supported_extensions.reserve(extensions.size());
for (const auto& extension : extensions) {
Expand Down Expand Up @@ -82,13 +94,13 @@ std::string GetReadableVersion(u32 version) {
Instance::Instance(bool enable_validation, bool enable_crash_diagnostic)
: instance{CreateInstance(Frontend::WindowSystemType::Headless, enable_validation,
enable_crash_diagnostic)},
physical_devices{instance->enumeratePhysicalDevices()} {}
physical_devices{EnumeratePhysicalDevices(instance)} {}

Instance::Instance(Frontend::WindowSDL& window, s32 physical_device_index,
bool enable_validation /*= false*/, bool enable_crash_diagnostic /*= false*/)
: instance{CreateInstance(window.getWindowInfo().type, enable_validation,
enable_crash_diagnostic)},
physical_devices{instance->enumeratePhysicalDevices()} {
physical_devices{EnumeratePhysicalDevices(instance)} {
if (enable_validation) {
debug_callback = CreateDebugCallback(*instance);
}
Expand Down Expand Up @@ -421,43 +433,46 @@ bool Instance::CreateDevice() {
device_chain.unlink<vk::PhysicalDeviceVertexInputDynamicStateFeaturesEXT>();
}

try {
device = physical_device.createDeviceUnique(device_chain.get());
} catch (vk::ExtensionNotPresentError& err) {
LOG_CRITICAL(Render_Vulkan, "Some required extensions are not available {}", err.what());
return false;
} catch (vk::FeatureNotPresentError& err) {
LOG_CRITICAL(Render_Vulkan, "Some required features are not available {}", err.what());
auto [device_result, dev] = physical_device.createDeviceUnique(device_chain.get());
if (device_result != vk::Result::eSuccess) {
LOG_CRITICAL(Render_Vulkan, "Failed to create device: {}", vk::to_string(device_result));
return false;
}
device = std::move(dev);

VULKAN_HPP_DEFAULT_DISPATCHER.init(*device);

graphics_queue = device->getQueue(queue_family_index, 0);
present_queue = device->getQueue(queue_family_index, 0);

if (calibrated_timestamps) {
const auto& time_domains = physical_device.getCalibrateableTimeDomainsEXT();
const auto [time_domains_result, time_domains] =
physical_device.getCalibrateableTimeDomainsEXT();
if (time_domains_result == vk::Result::eSuccess) {
#if _WIN64
const bool has_host_time_domain =
std::find(time_domains.cbegin(), time_domains.cend(),
vk::TimeDomainEXT::eQueryPerformanceCounter) != time_domains.cend();
const bool has_host_time_domain =
std::find(time_domains.cbegin(), time_domains.cend(),
vk::TimeDomainEXT::eQueryPerformanceCounter) != time_domains.cend();
#elif __linux__
const bool has_host_time_domain =
std::find(time_domains.cbegin(), time_domains.cend(),
vk::TimeDomainEXT::eClockMonotonicRaw) != time_domains.cend();
const bool has_host_time_domain =
std::find(time_domains.cbegin(), time_domains.cend(),
vk::TimeDomainEXT::eClockMonotonicRaw) != time_domains.cend();
#else
// Tracy limitation means only Windows and Linux can use host time domain.
// https://github.com/shadps4-emu/tracy/blob/c6d779d78508514102fbe1b8eb28bda10d95bb2a/public/tracy/TracyVulkan.hpp#L384-L389
const bool has_host_time_domain = false;
// Tracy limitation means only Windows and Linux can use host time domain.
// https://github.com/shadps4-emu/tracy/blob/c6d779d78508514102fbe1b8eb28bda10d95bb2a/public/tracy/TracyVulkan.hpp#L384-L389
const bool has_host_time_domain = false;
#endif
if (has_host_time_domain) {
static constexpr std::string_view context_name{"vk_rasterizer"};
profiler_context =
TracyVkContextHostCalibrated(*instance, physical_device, *device,
VULKAN_HPP_DEFAULT_DISPATCHER.vkGetInstanceProcAddr,
VULKAN_HPP_DEFAULT_DISPATCHER.vkGetDeviceProcAddr);
TracyVkContextName(profiler_context, context_name.data(), context_name.size());
if (has_host_time_domain) {
static constexpr std::string_view context_name{"vk_rasterizer"};
profiler_context = TracyVkContextHostCalibrated(
*instance, physical_device, *device,
VULKAN_HPP_DEFAULT_DISPATCHER.vkGetInstanceProcAddr,
VULKAN_HPP_DEFAULT_DISPATCHER.vkGetDeviceProcAddr);
TracyVkContextName(profiler_context, context_name.data(), context_name.size());
}
} else {
LOG_WARNING(Render_Vulkan, "Could not query calibrated time domains for profiling: {}",
vk::to_string(time_domains_result));
}
}

Expand Down Expand Up @@ -513,7 +528,12 @@ void Instance::CollectToolingInfo() {
if (!tooling_info) {
return;
}
const auto tools = physical_device.getToolPropertiesEXT();
const auto [tools_result, tools] = physical_device.getToolPropertiesEXT();
if (tools_result != vk::Result::eSuccess) {
LOG_ERROR(Render_Vulkan, "Could not get Vulkan tool properties: {}",
vk::to_string(tools_result));
return;
}
for (const vk::PhysicalDeviceToolProperties& tool : tools) {
const std::string_view name = tool.name;
LOG_INFO(Render_Vulkan, "Attached debugging tool: {}", name);
Expand Down
13 changes: 11 additions & 2 deletions src/video_core/renderer_vulkan/vk_master_semaphore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include "video_core/renderer_vulkan/vk_instance.h"
#include "video_core/renderer_vulkan/vk_master_semaphore.h"

#include "common/assert.h"

namespace Vulkan {

constexpr u64 WAIT_TIMEOUT = std::numeric_limits<u64>::max();
Expand All @@ -17,7 +19,11 @@ MasterSemaphore::MasterSemaphore(const Instance& instance_) : instance{instance_
.initialValue = 0,
},
};
semaphore = instance.GetDevice().createSemaphoreUnique(semaphore_chain.get());
auto [semaphore_result, sem] =
instance.GetDevice().createSemaphoreUnique(semaphore_chain.get());
ASSERT_MSG(semaphore_result == vk::Result::eSuccess, "Failed to create master semaphore: {}",
vk::to_string(semaphore_result));
semaphore = std::move(sem);
}

MasterSemaphore::~MasterSemaphore() = default;
Expand All @@ -27,7 +33,10 @@ void MasterSemaphore::Refresh() {
u64 counter{};
do {
this_tick = gpu_tick.load(std::memory_order_acquire);
counter = instance.GetDevice().getSemaphoreCounterValue(*semaphore);
auto [counter_result, cntr] = instance.GetDevice().getSemaphoreCounterValue(*semaphore);
ASSERT_MSG(counter_result == vk::Result::eSuccess,
"Failed to get master semaphore value: {}", vk::to_string(counter_result));
counter = cntr;
if (counter < this_tick) {
return;
}
Expand Down
5 changes: 4 additions & 1 deletion src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,10 @@ PipelineCache::PipelineCache(const Instance& instance_, Scheduler& scheduler_,
.subgroup_size = instance.SubgroupSize(),
.support_explicit_workgroup_layout = true,
};
pipeline_cache = instance.GetDevice().createPipelineCacheUnique({});
auto [cache_result, cache] = instance.GetDevice().createPipelineCacheUnique({});
ASSERT_MSG(cache_result == vk::Result::eSuccess, "Failed to create pipeline cache: {}",
vk::to_string(cache_result));
pipeline_cache = std::move(cache);
}

PipelineCache::~PipelineCache() = default;
Expand Down
28 changes: 18 additions & 10 deletions src/video_core/renderer_vulkan/vk_platform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,10 @@ vk::SurfaceKHR CreateSurface(vk::Instance instance, const Frontend::WindowSDL& e

std::vector<const char*> GetInstanceExtensions(Frontend::WindowSystemType window_type,
bool enable_debug_utils) {
const auto properties = vk::enumerateInstanceExtensionProperties();
if (properties.empty()) {
LOG_ERROR(Render_Vulkan, "Failed to query extension properties");
const auto [properties_result, properties] = vk::enumerateInstanceExtensionProperties();
if (properties_result != vk::Result::eSuccess || properties.empty()) {
LOG_ERROR(Render_Vulkan, "Failed to query extension properties: {}",
vk::to_string(properties_result));
return {};
}

Expand Down Expand Up @@ -207,10 +208,12 @@ vk::UniqueInstance CreateInstance(Frontend::WindowSystemType window_type, bool e
#endif
VULKAN_HPP_DEFAULT_DISPATCHER.init(vkGetInstanceProcAddr);

const u32 available_version = VULKAN_HPP_DEFAULT_DISPATCHER.vkEnumerateInstanceVersion
? vk::enumerateInstanceVersion()
: VK_API_VERSION_1_0;

const auto [available_version_result, available_version] =
VULKAN_HPP_DEFAULT_DISPATCHER.vkEnumerateInstanceVersion
? vk::enumerateInstanceVersion()
: vk::ResultValue(vk::Result::eSuccess, VK_API_VERSION_1_0);
ASSERT_MSG(available_version_result == vk::Result::eSuccess,
"Failed to query Vulkan API version: {}", vk::to_string(available_version_result));
ASSERT_MSG(available_version >= TargetVulkanApiVersion,
"Vulkan {}.{} is required, but only {}.{} is supported by instance!",
VK_VERSION_MAJOR(TargetVulkanApiVersion), VK_VERSION_MINOR(TargetVulkanApiVersion),
Expand Down Expand Up @@ -341,11 +344,13 @@ vk::UniqueInstance CreateInstance(Frontend::WindowSystemType window_type, bool e
},
};

auto instance = vk::createInstanceUnique(instance_ci_chain.get());
auto [instance_result, instance] = vk::createInstanceUnique(instance_ci_chain.get());
ASSERT_MSG(instance_result == vk::Result::eSuccess, "Failed to create instance: {}",
vk::to_string(instance_result));

VULKAN_HPP_DEFAULT_DISPATCHER.init(*instance);

return instance;
return std::move(instance);
}

vk::UniqueDebugUtilsMessengerEXT CreateDebugCallback(vk::Instance instance) {
Expand All @@ -359,7 +364,10 @@ vk::UniqueDebugUtilsMessengerEXT CreateDebugCallback(vk::Instance instance) {
vk::DebugUtilsMessageTypeFlagBitsEXT::ePerformance,
.pfnUserCallback = DebugUtilsCallback,
};
return instance.createDebugUtilsMessengerEXTUnique(msg_ci);
auto [messenger_result, messenger] = instance.createDebugUtilsMessengerEXTUnique(msg_ci);
ASSERT_MSG(messenger_result == vk::Result::eSuccess, "Failed to create debug callback: {}",
vk::to_string(messenger_result));
return std::move(messenger);
}

} // namespace Vulkan
6 changes: 5 additions & 1 deletion src/video_core/renderer_vulkan/vk_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <variant>
#include <fmt/format.h>

#include "common/logging/log.h"
#include "common/types.h"
#include "video_core/renderer_vulkan/vk_common.h"

Expand Down Expand Up @@ -36,7 +37,10 @@ void SetObjectName(vk::Device device, const HandleType& handle, std::string_view
.objectHandle = reinterpret_cast<u64>(static_cast<typename HandleType::NativeType>(handle)),
.pObjectName = debug_name.data(),
};
device.setDebugUtilsObjectNameEXT(name_info);
auto result = device.setDebugUtilsObjectNameEXT(name_info);
if (result != vk::Result::eSuccess) {
LOG_DEBUG(Render_Vulkan, "Could not set object debug name: {}", vk::to_string(result));
}
}

template <VulkanHandleType HandleType, typename... Args>
Expand Down
Loading
Loading