& mask,
const UniformBufferSizes* sizes) {
- if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) {
- if (channel_state->enabled_uniform_buffer_masks != mask) {
- if constexpr (IS_OPENGL) {
- channel_state->fast_bound_uniform_buffers.fill(0);
- }
+ const bool mask_changed = channel_state->enabled_uniform_buffer_masks != mask;
+ if (mask_changed) {
+ channel_state->fast_bound_uniform_buffers.fill(0);
+ if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) {
channel_state->dirty_uniform_buffers.fill(~u32{0});
channel_state->uniform_buffer_binding_sizes.fill({});
}
@@ -806,7 +805,7 @@ void BufferCache::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32
channel_state->uniform_buffer_binding_sizes[stage][binding_index] != size;
if (should_fast_bind) {
// We only have to bind when the currently bound buffer is not the fast version
- channel_state->fast_bound_uniform_buffers[stage] |= 1U << binding_index;
+ channel_state->fast_bound_uniform_buffers[stage] |= 1u << binding_index;
channel_state->uniform_buffer_binding_sizes[stage][binding_index] = size;
runtime.BindFastUniformBuffer(stage, binding_index, size);
}
@@ -815,13 +814,22 @@ void BufferCache
::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32
return;
}
}
- if constexpr (IS_OPENGL) {
- channel_state->fast_bound_uniform_buffers[stage] |= 1U << binding_index;
- channel_state->uniform_buffer_binding_sizes[stage][binding_index] = size;
- }
+ channel_state->fast_bound_uniform_buffers[stage] |= 1u << binding_index;
+ channel_state->uniform_buffer_binding_sizes[stage][binding_index] = size;
// Stream buffer path to avoid stalling on non-Nvidia drivers or Vulkan
const std::span span = runtime.BindMappedUniformBuffer(stage, binding_index, size);
+#ifdef YUZU_DEBUG
+ ASSERT(binding_index < NUM_GRAPHICS_UNIFORM_BUFFERS);
+ ASSERT(span.size() >= size && "UBO stream span too small");
+ if (!device_memory.ReadBlockFastChecked(device_addr, span.data(), size)) {
+ LOG_CRITICAL(Render, "DeviceMemory OOB/unmapped: addr=0x{:x} size={}", device_addr, size);
+ channel_state->fast_bound_uniform_buffers[stage] &= ~(1u << binding_index);
+ ASSERT(false);
+ return;
+ }
+#else
device_memory.ReadBlockUnsafe(device_addr, span.data(), size);
+#endif
return;
}
// Classic cached path
@@ -830,7 +838,8 @@ void BufferCache::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32
}
// Skip binding if it's not needed and if the bound buffer is not the fast version
// This exists to avoid instances where the fast buffer is bound and a GPU write happens
- needs_bind |= HasFastUniformBufferBound(stage, binding_index);
+ const bool was_fast_bound = HasFastUniformBufferBound(stage, binding_index);
+ needs_bind |= was_fast_bound;
if constexpr (HAS_PERSISTENT_UNIFORM_BUFFER_BINDINGS) {
needs_bind |= channel_state->uniform_buffer_binding_sizes[stage][binding_index] != size;
}
@@ -839,9 +848,6 @@ void BufferCache
::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32
}
const u32 offset = buffer.Offset(device_addr);
if constexpr (IS_OPENGL) {
- // Fast buffer will be unbound
- channel_state->fast_bound_uniform_buffers[stage] &= ~(1U << binding_index);
-
// Mark the index as dirty if offset doesn't match
const bool is_copy_bind = offset != 0 && !runtime.SupportsNonZeroUniformOffset();
channel_state->dirty_uniform_buffers[stage] |= (is_copy_bind ? 1U : 0U) << index;
@@ -855,6 +861,7 @@ void BufferCache
::BindHostGraphicsUniformBuffer(size_t stage, u32 index, u32
} else {
runtime.BindUniformBuffer(buffer, offset, size);
}
+ channel_state->fast_bound_uniform_buffers[stage] &= ~(1u << binding_index);
}
template
@@ -1789,12 +1796,7 @@ std::span BufferCache::ImmediateBuffer(size_t wanted_capacity) {
template
bool BufferCache::HasFastUniformBufferBound(size_t stage, u32 binding_index) const noexcept {
- if constexpr (IS_OPENGL) {
- return ((channel_state->fast_bound_uniform_buffers[stage] >> binding_index) & 1) != 0;
- } else {
- // Only OpenGL has fast uniform buffers
- return false;
- }
+ return ((channel_state->fast_bound_uniform_buffers[stage] >> binding_index) & 1u) != 0;
}
template
diff --git a/src/video_core/buffer_cache/buffer_cache_base.h b/src/video_core/buffer_cache/buffer_cache_base.h
index 486d19fb79..09631ffd83 100644
--- a/src/video_core/buffer_cache/buffer_cache_base.h
+++ b/src/video_core/buffer_cache/buffer_cache_base.h
@@ -53,6 +53,7 @@ constexpr u32 NUM_COMPUTE_UNIFORM_BUFFERS = 8;
constexpr u32 NUM_STORAGE_BUFFERS = 16;
constexpr u32 NUM_TEXTURE_BUFFERS = 32;
constexpr u32 NUM_STAGES = 5;
+static_assert(NUM_GRAPHICS_UNIFORM_BUFFERS <= 32, "fast bitmask must fit u32");
using UniformBufferSizes = std::array, NUM_STAGES>;
using ComputeUniformBufferSizes = std::array;
@@ -137,8 +138,8 @@ public:
u32 written_compute_texture_buffers = 0;
u32 image_compute_texture_buffers = 0;
- std::array uniform_cache_hits{};
- std::array uniform_cache_shots{};
+ std::array uniform_cache_hits{};
+ std::array uniform_cache_shots{};
u32 uniform_buffer_skip_cache_size = DEFAULT_SKIP_CACHE_SIZE;
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
index 6f3a0e4cd1..e6e72cdca7 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp
@@ -164,15 +164,6 @@ try
PresentFiltersForAppletCapture)
, rasterizer(render_window, gpu, device_memory, device, memory_allocator, state_tracker, scheduler) {
- // Initialize RAII wrappers after creating the main objects
- if (Settings::values.enable_raii.GetValue()) {
- managed_instance = MakeManagedInstance(instance, dld);
- if (Settings::values.renderer_debug) {
- managed_debug_messenger = MakeManagedDebugUtilsMessenger(debug_messenger, instance, dld);
- }
- managed_surface = MakeManagedSurface(surface, instance, dld);
- }
-
if (Settings::values.renderer_force_max_clock.GetValue() && device.ShouldBoostClocks()) {
turbo_mode.emplace(instance, dld);
scheduler.RegisterOnSubmit([this] { turbo_mode->QueueSubmitted(); });
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h
index c1e6d5db7f..4fb88b29de 100644
--- a/src/video_core/renderer_vulkan/renderer_vulkan.h
+++ b/src/video_core/renderer_vulkan/renderer_vulkan.h
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
@@ -20,7 +23,6 @@
#include "video_core/vulkan_common/vulkan_device.h"
#include "video_core/vulkan_common/vulkan_memory_allocator.h"
#include "video_core/vulkan_common/vulkan_wrapper.h"
-#include "video_core/vulkan_common/vulkan_raii.h"
namespace Core::Memory {
class Memory;
@@ -78,16 +80,10 @@ private:
// Keep original handles for compatibility with existing code
vk::Instance instance;
- // RAII wrapper for instance
- ManagedInstance managed_instance;
vk::DebugUtilsMessenger debug_messenger;
- // RAII wrapper for debug messenger
- ManagedDebugUtilsMessenger managed_debug_messenger;
vk::SurfaceKHR surface;
- // RAII wrapper for surface
- ManagedSurface managed_surface;
Device device;
MemoryAllocator memory_allocator;
diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp
index ecc4f77dc7..0fbe707b04 100644
--- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp
+++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp
@@ -25,12 +25,12 @@ namespace {
using namespace Common::Literals;
-// Maximum potential alignment of a Vulkan buffer
-constexpr VkDeviceSize MAX_ALIGNMENT = 256;
+// Minimum alignment we want to enforce for the streaming ring
+constexpr VkDeviceSize MIN_STREAM_ALIGNMENT = 256;
// Stream buffer size in bytes
constexpr VkDeviceSize MAX_STREAM_BUFFER_SIZE = 128_MiB;
-size_t GetStreamBufferSize(const Device& device) {
+size_t GetStreamBufferSize(const Device& device, VkDeviceSize alignment) {
VkDeviceSize size{0};
if (device.HasDebuggingToolAttached()) {
bool found_heap = false;
@@ -53,8 +53,9 @@ size_t GetStreamBufferSize(const Device& device) {
// Clamp to the configured maximum, align up for safety, and ensure a sane minimum so
// region_size (stream_buffer_size / NUM_SYNCS) never becomes zero.
- const VkDeviceSize aligned = (std::min)(Common::AlignUp(size, MAX_ALIGNMENT), MAX_STREAM_BUFFER_SIZE);
- const VkDeviceSize min_size = MAX_ALIGNMENT * StagingBufferPool::NUM_SYNCS;
+ const VkDeviceSize aligned =
+ (std::min)(Common::AlignUp(size, alignment), MAX_STREAM_BUFFER_SIZE);
+ const VkDeviceSize min_size = alignment * StagingBufferPool::NUM_SYNCS;
return static_cast((std::max)(aligned, min_size));
}
} // Anonymous namespace
@@ -62,8 +63,10 @@ size_t GetStreamBufferSize(const Device& device) {
StagingBufferPool::StagingBufferPool(const Device& device_, MemoryAllocator& memory_allocator_,
Scheduler& scheduler_)
: device{device_}, memory_allocator{memory_allocator_}, scheduler{scheduler_},
- stream_buffer_size{GetStreamBufferSize(device)}, region_size{stream_buffer_size /
- StagingBufferPool::NUM_SYNCS} {
+ stream_alignment{std::max(device_.GetUniformBufferAlignment(),
+ MIN_STREAM_ALIGNMENT)},
+ stream_buffer_size{GetStreamBufferSize(device_, stream_alignment)},
+ region_size{stream_buffer_size / StagingBufferPool::NUM_SYNCS} {
VkBufferCreateInfo stream_ci = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
@@ -116,10 +119,11 @@ void StagingBufferPool::TickFrame() {
}
StagingBufferRef StagingBufferPool::GetStreamBuffer(size_t size) {
- const size_t aligned_size = Common::AlignUp(size, MAX_ALIGNMENT);
+ const size_t alignment = static_cast(stream_alignment);
+ const size_t aligned_size = Common::AlignUp(size, alignment);
const bool wraps = iterator + size >= stream_buffer_size;
const size_t new_iterator =
- wraps ? aligned_size : Common::AlignUp(iterator + size, MAX_ALIGNMENT);
+ wraps ? aligned_size : Common::AlignUp(iterator + size, alignment);
const size_t begin_region = wraps ? 0 : Region(iterator);
const size_t last_byte = new_iterator == 0 ? 0 : new_iterator - 1;
const size_t end_region = (std::min)(Region(last_byte) + 1, NUM_SYNCS);
@@ -145,7 +149,7 @@ StagingBufferRef StagingBufferPool::GetStreamBuffer(size_t size) {
current_tick);
used_iterator = 0;
iterator = 0;
- free_iterator = size;
+ free_iterator = aligned_size;
const size_t head_last_byte = aligned_size == 0 ? 0 : aligned_size - 1;
const size_t head_end_region = (std::min)(Region(head_last_byte) + 1, NUM_SYNCS);
if (AreRegionsActive(0, head_end_region)) {
@@ -160,7 +164,7 @@ StagingBufferRef StagingBufferPool::GetStreamBuffer(size_t size) {
iterator = new_iterator;
if (!wraps) {
- free_iterator = (std::max)(free_iterator, offset + size);
+ free_iterator = (std::max)(free_iterator, offset + aligned_size);
}
return StagingBufferRef{
diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h
index f63a203272..5c40ca069f 100644
--- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h
+++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.h
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
@@ -102,6 +105,7 @@ private:
MemoryAllocator& memory_allocator;
Scheduler& scheduler;
+ VkDeviceSize stream_alignment;
vk::Buffer stream_buffer;
std::span stream_pointer;
VkDeviceSize stream_buffer_size;
diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp
index 3b35e28c05..fdd2de2379 100644
--- a/src/video_core/renderer_vulkan/vk_swapchain.cpp
+++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp
@@ -351,6 +351,7 @@ void Swapchain::CreateSemaphores() {
void Swapchain::Destroy() {
frame_index = 0;
present_semaphores.clear();
+ render_semaphores.clear();
swapchain.reset();
}
diff --git a/src/video_core/vulkan_common/vulkan_raii.h b/src/video_core/vulkan_common/vulkan_raii.h
deleted file mode 100644
index cf5e268b68..0000000000
--- a/src/video_core/vulkan_common/vulkan_raii.h
+++ /dev/null
@@ -1,231 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2025 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include
-#include
-#include
-#include
-
-#include "common/logging/log.h"
-
-#include "video_core/vulkan_common/vulkan_wrapper.h"
-
-namespace Vulkan {
-
-/**
- * RAII wrapper for Vulkan resources.
- * Automatically manages the lifetime of Vulkan objects using RAII principles.
- */
-template
-class VulkanRaii {
-public:
- using DeleterFunc = std::function;
-
- // Default constructor - creates a null handle
- VulkanRaii() : handle{}, deleter{}, dispatch{} {}
-
- // Constructor with handle and deleter
- VulkanRaii(T handle_, DeleterFunc deleter_, const Dispatch& dispatch_, const char* resource_name = "Vulkan resource")
- : handle{handle_}, deleter{std::move(deleter_)}, dispatch{dispatch_} {
- LOG_DEBUG(Render_Vulkan, "RAII wrapper created for {}", resource_name);
- }
-
- // Move constructor
- VulkanRaii(VulkanRaii&& other) noexcept
- : handle{std::exchange(other.handle, VK_NULL_HANDLE)},
- deleter{std::move(other.deleter)},
- dispatch{other.dispatch} {
- }
-
- // Move assignment
- VulkanRaii& operator=(VulkanRaii&& other) noexcept {
- if (this != &other) {
- cleanup();
- handle = std::exchange(other.handle, VK_NULL_HANDLE);
- deleter = std::move(other.deleter);
- dispatch = other.dispatch;
- }
- return *this;
- }
-
- // Destructor - automatically cleans up the resource
- ~VulkanRaii() {
- cleanup();
- }
-
- // Disallow copying
- VulkanRaii(const VulkanRaii&) = delete;
- VulkanRaii& operator=(const VulkanRaii&) = delete;
-
- // Get the underlying handle
- T get() const noexcept {
- return handle;
- }
-
- // Check if the handle is valid
- bool valid() const noexcept {
- return handle != VK_NULL_HANDLE;
- }
-
- // Release ownership of the handle without destroying it
- T release() noexcept {
- return std::exchange(handle, VK_NULL_HANDLE);
- }
-
- // Reset the handle (destroying the current one if it exists)
- void reset(T new_handle = VK_NULL_HANDLE, DeleterFunc new_deleter = {}) {
- cleanup();
- handle = new_handle;
- deleter = std::move(new_deleter);
- }
-
- // Implicit conversion to handle type
- operator T() const noexcept {
- return handle;
- }
-
- // Dereference operator for pointer-like access
- T operator->() const noexcept {
- return handle;
- }
-
-private:
- // Optimized cleanup function
- void cleanup() noexcept {
- if (handle != VK_NULL_HANDLE && deleter) {
- deleter(handle, dispatch);
- handle = VK_NULL_HANDLE;
- }
- }
-
- T handle;
- DeleterFunc deleter;
- Dispatch dispatch;
-};
-
-// Common type aliases for Vulkan RAII wrappers with clearer names
-using ManagedInstance = VulkanRaii;
-using ManagedDevice = VulkanRaii;
-using ManagedSurface = VulkanRaii;
-using ManagedSwapchain = VulkanRaii;
-using ManagedCommandPool = VulkanRaii;
-using ManagedBuffer = VulkanRaii;
-using ManagedImage = VulkanRaii;
-using ManagedImageView = VulkanRaii;
-using ManagedSampler = VulkanRaii;
-using ManagedShaderModule = VulkanRaii;
-using ManagedPipeline = VulkanRaii;
-using ManagedPipelineLayout = VulkanRaii;
-using ManagedDescriptorSetLayout = VulkanRaii;
-using ManagedDescriptorPool = VulkanRaii;
-using ManagedSemaphore = VulkanRaii;
-using ManagedFence = VulkanRaii;
-using ManagedDebugUtilsMessenger = VulkanRaii;
-
-// Helper functions to create RAII wrappers
-
-/**
- * Creates an RAII wrapper for a Vulkan instance
- */
-inline ManagedInstance MakeManagedInstance(const vk::Instance& instance, const vk::InstanceDispatch& dispatch) {
- auto deleter = [](VkInstance handle, const vk::InstanceDispatch& dld) {
- dld.vkDestroyInstance(handle, nullptr);
- };
- return ManagedInstance(*instance, deleter, dispatch, "VkInstance");
-}
-
-/**
- * Creates an RAII wrapper for a Vulkan device
- */
-inline ManagedDevice MakeManagedDevice(const vk::Device& device, const vk::DeviceDispatch& dispatch) {
- auto deleter = [](VkDevice handle, const vk::DeviceDispatch& dld) {
- dld.vkDestroyDevice(handle, nullptr);
- };
- return ManagedDevice(*device, deleter, dispatch, "VkDevice");
-}
-
-/**
- * Creates an RAII wrapper for a Vulkan surface
- */
-inline ManagedSurface MakeManagedSurface(const vk::SurfaceKHR& surface, const vk::Instance& instance, const vk::InstanceDispatch& dispatch) {
- auto deleter = [instance_ptr = *instance](VkSurfaceKHR handle, const vk::InstanceDispatch& dld) {
- dld.vkDestroySurfaceKHR(instance_ptr, handle, nullptr);
- };
- return ManagedSurface(*surface, deleter, dispatch, "VkSurfaceKHR");
-}
-
-/**
- * Creates an RAII wrapper for a Vulkan debug messenger
- */
-inline ManagedDebugUtilsMessenger MakeManagedDebugUtilsMessenger(const vk::DebugUtilsMessenger& messenger,
- const vk::Instance& instance,
- const vk::InstanceDispatch& dispatch) {
- auto deleter = [instance_ptr = *instance](VkDebugUtilsMessengerEXT handle, const vk::InstanceDispatch& dld) {
- dld.vkDestroyDebugUtilsMessengerEXT(instance_ptr, handle, nullptr);
- };
- return ManagedDebugUtilsMessenger(*messenger, deleter, dispatch, "VkDebugUtilsMessengerEXT");
-}
-
-/**
- * Creates an RAII wrapper for a Vulkan swapchain
- */
-inline ManagedSwapchain MakeManagedSwapchain(VkSwapchainKHR swapchain_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) {
- auto deleter = [device_handle](VkSwapchainKHR handle, const vk::DeviceDispatch& dld) {
- dld.vkDestroySwapchainKHR(device_handle, handle, nullptr);
- };
- return ManagedSwapchain(swapchain_handle, deleter, dispatch, "VkSwapchainKHR");
-}
-
-/**
- * Creates an RAII wrapper for a Vulkan buffer
- */
-inline ManagedBuffer MakeManagedBuffer(VkBuffer buffer_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) {
- auto deleter = [device_handle](VkBuffer handle, const vk::DeviceDispatch& dld) {
- dld.vkDestroyBuffer(device_handle, handle, nullptr);
- };
- return ManagedBuffer(buffer_handle, deleter, dispatch, "VkBuffer");
-}
-
-/**
- * Creates an RAII wrapper for a Vulkan image
- */
-inline ManagedImage MakeManagedImage(VkImage image_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) {
- auto deleter = [device_handle](VkImage handle, const vk::DeviceDispatch& dld) {
- dld.vkDestroyImage(device_handle, handle, nullptr);
- };
- return ManagedImage(image_handle, deleter, dispatch, "VkImage");
-}
-
-/**
- * Creates an RAII wrapper for a Vulkan image view
- */
-inline ManagedImageView MakeManagedImageView(VkImageView view_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) {
- auto deleter = [device_handle](VkImageView handle, const vk::DeviceDispatch& dld) {
- dld.vkDestroyImageView(device_handle, handle, nullptr);
- };
- return ManagedImageView(view_handle, deleter, dispatch, "VkImageView");
-}
-
-/**
- * Creates an RAII wrapper for a Vulkan semaphore
- */
-inline ManagedSemaphore MakeManagedSemaphore(VkSemaphore semaphore_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) {
- auto deleter = [device_handle](VkSemaphore handle, const vk::DeviceDispatch& dld) {
- dld.vkDestroySemaphore(device_handle, handle, nullptr);
- };
- return ManagedSemaphore(semaphore_handle, deleter, dispatch, "VkSemaphore");
-}
-
-/**
- * Creates an RAII wrapper for a Vulkan fence
- */
-inline ManagedFence MakeManagedFence(VkFence fence_handle, VkDevice device_handle, const vk::DeviceDispatch& dispatch) {
- auto deleter = [device_handle](VkFence handle, const vk::DeviceDispatch& dld) {
- dld.vkDestroyFence(device_handle, handle, nullptr);
- };
- return ManagedFence(fence_handle, deleter, dispatch, "VkFence");
-}
-
-} // namespace Vulkan
\ No newline at end of file
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp
index 949b91499d..b77d01711a 100644
--- a/src/video_core/vulkan_common/vulkan_wrapper.cpp
+++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp
@@ -12,7 +12,6 @@
#include "common/common_types.h"
#include "common/logging/log.h"
-#include "common/settings.h"
#include "video_core/vulkan_common/vk_enum_string_helper.h"
#include "video_core/vulkan_common/vma.h"
#include "video_core/vulkan_common/vulkan_wrapper.h"
@@ -311,10 +310,7 @@ const char* Exception::what() const noexcept {
}
void Destroy(VkInstance instance, const InstanceDispatch& dld) noexcept {
- // FIXME: A double free occurs here if RAII is enabled.
- if (!Settings::values.enable_raii.GetValue()) {
- dld.vkDestroyInstance(instance, nullptr);
- }
+ dld.vkDestroyInstance(instance, nullptr);
}
void Destroy(VkDevice device, const InstanceDispatch& dld) noexcept {
@@ -417,10 +413,7 @@ void Destroy(VkInstance instance, VkDebugReportCallbackEXT handle,
}
void Destroy(VkInstance instance, VkSurfaceKHR handle, const InstanceDispatch& dld) noexcept {
- // FIXME: A double free occurs here if RAII is enabled.
- if (!Settings::values.enable_raii.GetValue()) {
- dld.vkDestroySurfaceKHR(instance, handle, nullptr);
- }
+ dld.vkDestroySurfaceKHR(instance, handle, nullptr);
}
VkResult Free(VkDevice device, VkDescriptorPool handle, Span sets,
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.h b/src/video_core/vulkan_common/vulkan_wrapper.h
index 6501094f05..39396b3279 100644
--- a/src/video_core/vulkan_common/vulkan_wrapper.h
+++ b/src/video_core/vulkan_common/vulkan_wrapper.h
@@ -516,7 +516,7 @@ public:
}
/// Returns true when there's a held object.
- operator bool() const noexcept {
+ explicit operator bool() const noexcept {
return handle != nullptr;
}
@@ -627,7 +627,7 @@ class Instance : public Handle {
public:
/// Creates a Vulkan instance.
/// @throw Exception on initialization error.
- static Instance Create(u32 version, Span layers, Span extensions,
+ [[nodiscard]] static Instance Create(u32 version, Span layers, Span extensions,
InstanceDispatch& dispatch);
/// Enumerates physical devices.
@@ -637,12 +637,12 @@ public:
/// Creates a debug callback messenger.
/// @throw Exception on creation failure.
- DebugUtilsMessenger CreateDebugUtilsMessenger(
+ [[nodiscard]] DebugUtilsMessenger CreateDebugUtilsMessenger(
const VkDebugUtilsMessengerCreateInfoEXT& create_info) const;
/// Creates a debug report callback.
/// @throw Exception on creation failure.
- DebugReportCallback CreateDebugReportCallback(
+ [[nodiscard]] DebugReportCallback CreateDebugReportCallback(
const VkDebugReportCallbackCreateInfoEXT& create_info) const;
/// Returns dispatch table.
@@ -986,58 +986,60 @@ class Device : public Handle {
using Handle::Handle;
public:
- static Device Create(VkPhysicalDevice physical_device, Span queues_ci,
- Span enabled_extensions, const void* next,
- DeviceDispatch& dispatch);
+ [[nodiscard]] static Device Create(VkPhysicalDevice physical_device,
+ Span queues_ci,
+ Span enabled_extensions, const void* next,
+ DeviceDispatch& dispatch);
- Queue GetQueue(u32 family_index) const noexcept;
+ [[nodiscard]] Queue GetQueue(u32 family_index) const noexcept;
- BufferView CreateBufferView(const VkBufferViewCreateInfo& ci) const;
+ [[nodiscard]] BufferView CreateBufferView(const VkBufferViewCreateInfo& ci) const;
- ImageView CreateImageView(const VkImageViewCreateInfo& ci) const;
+ [[nodiscard]] ImageView CreateImageView(const VkImageViewCreateInfo& ci) const;
- Semaphore CreateSemaphore() const;
+ [[nodiscard]] Semaphore CreateSemaphore() const;
- Semaphore CreateSemaphore(const VkSemaphoreCreateInfo& ci) const;
+ [[nodiscard]] Semaphore CreateSemaphore(const VkSemaphoreCreateInfo& ci) const;
- Fence CreateFence(const VkFenceCreateInfo& ci) const;
+ [[nodiscard]] Fence CreateFence(const VkFenceCreateInfo& ci) const;
- DescriptorPool CreateDescriptorPool(const VkDescriptorPoolCreateInfo& ci) const;
+ [[nodiscard]] DescriptorPool CreateDescriptorPool(const VkDescriptorPoolCreateInfo& ci) const;
- RenderPass CreateRenderPass(const VkRenderPassCreateInfo& ci) const;
+ [[nodiscard]] RenderPass CreateRenderPass(const VkRenderPassCreateInfo& ci) const;
- DescriptorSetLayout CreateDescriptorSetLayout(const VkDescriptorSetLayoutCreateInfo& ci) const;
+ [[nodiscard]] DescriptorSetLayout CreateDescriptorSetLayout(
+ const VkDescriptorSetLayoutCreateInfo& ci) const;
- PipelineCache CreatePipelineCache(const VkPipelineCacheCreateInfo& ci) const;
+ [[nodiscard]] PipelineCache CreatePipelineCache(const VkPipelineCacheCreateInfo& ci) const;
- PipelineLayout CreatePipelineLayout(const VkPipelineLayoutCreateInfo& ci) const;
+ [[nodiscard]] PipelineLayout CreatePipelineLayout(const VkPipelineLayoutCreateInfo& ci) const;
- Pipeline CreateGraphicsPipeline(const VkGraphicsPipelineCreateInfo& ci,
- VkPipelineCache cache = nullptr) const;
+ [[nodiscard]] Pipeline CreateGraphicsPipeline(const VkGraphicsPipelineCreateInfo& ci,
+ VkPipelineCache cache = nullptr) const;
- Pipeline CreateComputePipeline(const VkComputePipelineCreateInfo& ci,
- VkPipelineCache cache = nullptr) const;
+ [[nodiscard]] Pipeline CreateComputePipeline(const VkComputePipelineCreateInfo& ci,
+ VkPipelineCache cache = nullptr) const;
- Sampler CreateSampler(const VkSamplerCreateInfo& ci) const;
+ [[nodiscard]] Sampler CreateSampler(const VkSamplerCreateInfo& ci) const;
- Framebuffer CreateFramebuffer(const VkFramebufferCreateInfo& ci) const;
+ [[nodiscard]] Framebuffer CreateFramebuffer(const VkFramebufferCreateInfo& ci) const;
- CommandPool CreateCommandPool(const VkCommandPoolCreateInfo& ci) const;
+ [[nodiscard]] CommandPool CreateCommandPool(const VkCommandPoolCreateInfo& ci) const;
- DescriptorUpdateTemplate CreateDescriptorUpdateTemplate(
+ [[nodiscard]] DescriptorUpdateTemplate CreateDescriptorUpdateTemplate(
const VkDescriptorUpdateTemplateCreateInfo& ci) const;
- QueryPool CreateQueryPool(const VkQueryPoolCreateInfo& ci) const;
+ [[nodiscard]] QueryPool CreateQueryPool(const VkQueryPoolCreateInfo& ci) const;
- ShaderModule CreateShaderModule(const VkShaderModuleCreateInfo& ci) const;
+ [[nodiscard]] ShaderModule CreateShaderModule(const VkShaderModuleCreateInfo& ci) const;
- Event CreateEvent() const;
+ [[nodiscard]] Event CreateEvent() const;
- SwapchainKHR CreateSwapchainKHR(const VkSwapchainCreateInfoKHR& ci) const;
+ [[nodiscard]] SwapchainKHR CreateSwapchainKHR(const VkSwapchainCreateInfoKHR& ci) const;
- DeviceMemory TryAllocateMemory(const VkMemoryAllocateInfo& ai) const noexcept;
+ [[nodiscard]] DeviceMemory TryAllocateMemory(const VkMemoryAllocateInfo& ai) const noexcept;
- DeviceMemory AllocateMemory(const VkMemoryAllocateInfo& ai) const;
+ [[nodiscard]] DeviceMemory AllocateMemory(const VkMemoryAllocateInfo& ai) const;
VkMemoryRequirements GetBufferMemoryRequirements(VkBuffer buffer,
void* pnext = nullptr) const noexcept;