Merge branch 'raiichanges' of https://git.eden-emu.dev/Ribbit/ribbitvulkanadditions into raiichanges
Some checks failed
eden-license / license-header (pull_request) Failing after 23s

This commit is contained in:
Ribbit 2025-10-05 20:23:33 -07:00
commit 52cbf4507b
12 changed files with 91 additions and 6 deletions

View file

@ -180,6 +180,7 @@
<item>@string/resolution_half</item> <item>@string/resolution_half</item>
<item>@string/resolution_three_quarter</item> <item>@string/resolution_three_quarter</item>
<item>@string/resolution_one</item> <item>@string/resolution_one</item>
<item>@string/resolution_five_quarter</item>
<item>@string/resolution_three_half</item> <item>@string/resolution_three_half</item>
<item>@string/resolution_two</item> <item>@string/resolution_two</item>
<item>@string/resolution_three</item> <item>@string/resolution_three</item>
@ -202,6 +203,7 @@
<item>5</item> <item>5</item>
<item>6</item> <item>6</item>
<item>7</item> <item>7</item>
<item>8</item>
</integer-array> </integer-array>
<integer-array name="rendererVSyncValues"> <integer-array name="rendererVSyncValues">

View file

@ -994,6 +994,7 @@
<string name="resolution_half">0.5X (360p/540p)</string> <string name="resolution_half">0.5X (360p/540p)</string>
<string name="resolution_three_quarter">0.75X (540p/810p)</string> <string name="resolution_three_quarter">0.75X (540p/810p)</string>
<string name="resolution_one">1X (720p/1080p)</string> <string name="resolution_one">1X (720p/1080p)</string>
<string name="resolution_five_quarter">1.25X (900p/1350p)</string>
<string name="resolution_three_half">1.5X (1080p/1620p)</string> <string name="resolution_three_half">1.5X (1080p/1620p)</string>
<string name="resolution_two">2X (1440p/2160p) (Slow)</string> <string name="resolution_two">2X (1440p/2160p) (Slow)</string>
<string name="resolution_three">3X (2160p/3240p) (Slow)</string> <string name="resolution_three">3X (2160p/3240p) (Slow)</string>

View file

@ -301,6 +301,10 @@ void TranslateResolutionInfo(ResolutionSetup setup, ResolutionScalingInfo& info)
info.up_scale = 3; info.up_scale = 3;
info.down_shift = 1; info.down_shift = 1;
break; break;
case ResolutionSetup::Res5_4X:
info.up_scale = 5;
info.down_shift = 2;
break;
case ResolutionSetup::Res2X: case ResolutionSetup::Res2X:
info.up_scale = 2; info.up_scale = 2;
info.down_shift = 0; info.down_shift = 0;

View file

@ -142,7 +142,7 @@ ENUM(MemoryLayout, Memory_4Gb, Memory_6Gb, Memory_8Gb, Memory_10Gb, Memory_12Gb)
ENUM(ConfirmStop, Ask_Always, Ask_Based_On_Game, Ask_Never); ENUM(ConfirmStop, Ask_Always, Ask_Based_On_Game, Ask_Never);
ENUM(FullscreenMode, Borderless, Exclusive); ENUM(FullscreenMode, Borderless, Exclusive);
ENUM(NvdecEmulation, Off, Cpu, Gpu); ENUM(NvdecEmulation, Off, Cpu, Gpu);
ENUM(ResolutionSetup, Res1_4X, Res1_2X, Res3_4X, Res1X, Res3_2X, Res2X, Res3X, Res4X, Res5X, Res6X, Res7X, Res8X); ENUM(ResolutionSetup, Res1_4X, Res1_2X, Res3_4X, Res1X, Res5_4X, Res3_2X, Res2X, Res3X, Res4X, Res5X, Res6X, Res7X, Res8X);
ENUM(ScalingFilter, NearestNeighbor, Bilinear, Bicubic, Spline1, Gaussian, Lanczos, ScaleForce, Fsr, Area, MaxEnum); ENUM(ScalingFilter, NearestNeighbor, Bilinear, Bicubic, Spline1, Gaussian, Lanczos, ScaleForce, Fsr, Area, MaxEnum);
ENUM(AntiAliasing, None, Fxaa, Smaa, MaxEnum); ENUM(AntiAliasing, None, Fxaa, Smaa, MaxEnum);
ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch); ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch);

View file

@ -534,6 +534,7 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QObject* parent)
PAIR(ResolutionSetup, Res1_2X, tr("0.5X (360p/540p) [EXPERIMENTAL]")), PAIR(ResolutionSetup, Res1_2X, tr("0.5X (360p/540p) [EXPERIMENTAL]")),
PAIR(ResolutionSetup, Res3_4X, tr("0.75X (540p/810p) [EXPERIMENTAL]")), PAIR(ResolutionSetup, Res3_4X, tr("0.75X (540p/810p) [EXPERIMENTAL]")),
PAIR(ResolutionSetup, Res1X, tr("1X (720p/1080p)")), PAIR(ResolutionSetup, Res1X, tr("1X (720p/1080p)")),
PAIR(ResolutionSetup, Res5_4X, tr("1.25X (900p/1350p) [EXPERIMENTAL]")),
PAIR(ResolutionSetup, Res3_2X, tr("1.5X (1080p/1620p) [EXPERIMENTAL]")), PAIR(ResolutionSetup, Res3_2X, tr("1.5X (1080p/1620p) [EXPERIMENTAL]")),
PAIR(ResolutionSetup, Res2X, tr("2X (1440p/2160p)")), PAIR(ResolutionSetup, Res2X, tr("2X (1440p/2160p)")),
PAIR(ResolutionSetup, Res3X, tr("3X (2160p/3240p)")), PAIR(ResolutionSetup, Res3X, tr("3X (2160p/3240p)")),

View file

@ -312,7 +312,7 @@ vk::DescriptorPool CreateWrappedDescriptorPool(const Device& device, size_t max_
return device.GetLogical().CreateDescriptorPool(VkDescriptorPoolCreateInfo{ return device.GetLogical().CreateDescriptorPool(VkDescriptorPoolCreateInfo{
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
.maxSets = static_cast<u32>(max_sets), .maxSets = static_cast<u32>(max_sets),
.poolSizeCount = static_cast<u32>(pool_sizes.size()), .poolSizeCount = static_cast<u32>(pool_sizes.size()),
.pPoolSizes = pool_sizes.data(), .pPoolSizes = pool_sizes.data(),

View file

@ -19,7 +19,9 @@ struct CommandPool::Pool {
CommandPool::CommandPool(MasterSemaphore& master_semaphore_, const Device& device_) CommandPool::CommandPool(MasterSemaphore& master_semaphore_, const Device& device_)
: ResourcePool(master_semaphore_, COMMAND_BUFFER_POOL_SIZE), device{device_} {} : ResourcePool(master_semaphore_, COMMAND_BUFFER_POOL_SIZE), device{device_} {}
CommandPool::~CommandPool() = default; CommandPool::~CommandPool() {
Drain();
}
void CommandPool::Allocate(size_t begin, size_t end) { void CommandPool::Allocate(size_t begin, size_t end) {
// Command buffers are going to be committed, recorded, executed every single usage cycle. // Command buffers are going to be committed, recorded, executed every single usage cycle.

View file

@ -80,7 +80,7 @@ static void AllocatePool(const Device& device, DescriptorBank& bank) {
bank.pools.push_back(device.GetLogical().CreateDescriptorPool({ bank.pools.push_back(device.GetLogical().CreateDescriptorPool({
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.flags = 0, .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
.maxSets = sets_per_pool, .maxSets = sets_per_pool,
.poolSizeCount = static_cast<u32>(pool_cursor), .poolSizeCount = static_cast<u32>(pool_cursor),
.pPoolSizes = std::data(pool_sizes), .pPoolSizes = std::data(pool_sizes),
@ -92,6 +92,10 @@ DescriptorAllocator::DescriptorAllocator(const Device& device_, MasterSemaphore&
: ResourcePool(master_semaphore_, SETS_GROW_RATE), device{&device_}, bank{&bank_}, : ResourcePool(master_semaphore_, SETS_GROW_RATE), device{&device_}, bank{&bank_},
layout{layout_} {} layout{layout_} {}
DescriptorAllocator::~DescriptorAllocator() {
Drain();
}
VkDescriptorSet DescriptorAllocator::Commit() { VkDescriptorSet DescriptorAllocator::Commit() {
const size_t index = CommitResource(); const size_t index = CommitResource();
return sets[index / SETS_GROW_RATE][index % SETS_GROW_RATE]; return sets[index / SETS_GROW_RATE][index % SETS_GROW_RATE];

View file

@ -35,7 +35,7 @@ class DescriptorAllocator final : public ResourcePool {
public: public:
explicit DescriptorAllocator() = default; explicit DescriptorAllocator() = default;
~DescriptorAllocator() override = default; ~DescriptorAllocator() override;
DescriptorAllocator& operator=(DescriptorAllocator&&) noexcept = default; DescriptorAllocator& operator=(DescriptorAllocator&&) noexcept = default;
DescriptorAllocator(DescriptorAllocator&&) noexcept = default; DescriptorAllocator(DescriptorAllocator&&) noexcept = default;

View file

@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <algorithm>
#include <optional> #include <optional>
#include "video_core/renderer_vulkan/vk_master_semaphore.h" #include "video_core/renderer_vulkan/vk_master_semaphore.h"
@ -42,6 +43,42 @@ size_t ResourcePool::CommitResource() {
return *found; return *found;
} }
void ResourcePool::Drain() {
if (!master_semaphore || ticks.empty()) {
return;
}
master_semaphore->Refresh();
const auto highest_iter = std::max_element(ticks.begin(), ticks.end());
if (highest_iter == ticks.end()) {
return;
}
const u64 highest_tick = *highest_iter;
if (highest_tick == 0) {
return;
}
const u64 current_tick = master_semaphore->CurrentTick();
const u64 last_submitted_tick = current_tick > 0 ? current_tick - 1 : 0;
u64 wait_tick = 0;
if (last_submitted_tick != 0) {
wait_tick = std::min(highest_tick, last_submitted_tick);
}
if (wait_tick != 0 && !master_semaphore->IsFree(wait_tick)) {
// Clamp to the last submitted tick so we never wait for a value that was
// never enqueued on the GPU timeline (CurrentTick() is always one ahead
// of the most recent submission).
master_semaphore->Wait(wait_tick);
}
master_semaphore->Refresh();
const u64 completed_tick = master_semaphore->KnownGpuTick();
std::fill(ticks.begin(), ticks.end(), completed_tick);
hint_iterator = 0;
}
size_t ResourcePool::ManageOverflow() { size_t ResourcePool::ManageOverflow() {
const size_t old_capacity = ticks.size(); const size_t old_capacity = ticks.size();
Grow(); Grow();

View file

@ -30,6 +30,7 @@ public:
protected: protected:
size_t CommitResource(); size_t CommitResource();
void Drain();
/// Called when a chunk of resources have to be allocated. /// Called when a chunk of resources have to be allocated.
virtual void Allocate(size_t begin, size_t end) = 0; virtual void Allocate(size_t begin, size_t end) = 0;

View file

@ -15,6 +15,7 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "common/assert.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "video_core/vulkan_common/vulkan.h" #include "video_core/vulkan_common/vulkan.h"
@ -552,6 +553,10 @@ public:
/// Construct an empty allocation. /// Construct an empty allocation.
PoolAllocations() = default; PoolAllocations() = default;
~PoolAllocations() noexcept {
Release();
}
/// Construct an allocation. Errors are reported through IsOutOfPoolMemory(). /// Construct an allocation. Errors are reported through IsOutOfPoolMemory().
explicit PoolAllocations(std::unique_ptr<AllocationType[]> allocations_, std::size_t num_, explicit PoolAllocations(std::unique_ptr<AllocationType[]> allocations_, std::size_t num_,
VkDevice device_, PoolType pool_, const DeviceDispatch& dld_) noexcept VkDevice device_, PoolType pool_, const DeviceDispatch& dld_) noexcept
@ -565,18 +570,38 @@ public:
/// Construct an allocation transferring ownership from another allocation. /// Construct an allocation transferring ownership from another allocation.
PoolAllocations(PoolAllocations&& rhs) noexcept PoolAllocations(PoolAllocations&& rhs) noexcept
: allocations{std::move(rhs.allocations)}, num{rhs.num}, device{rhs.device}, pool{rhs.pool}, : allocations{std::move(rhs.allocations)}, num{rhs.num}, device{rhs.device}, pool{rhs.pool},
dld{rhs.dld} {} dld{rhs.dld} {
rhs.Reset();
}
/// Assign an allocation transferring ownership from another allocation. /// Assign an allocation transferring ownership from another allocation.
PoolAllocations& operator=(PoolAllocations&& rhs) noexcept { PoolAllocations& operator=(PoolAllocations&& rhs) noexcept {
if (this == &rhs) [[unlikely]] {
return *this;
}
Release();
allocations = std::move(rhs.allocations); allocations = std::move(rhs.allocations);
num = rhs.num; num = rhs.num;
device = rhs.device; device = rhs.device;
pool = rhs.pool; pool = rhs.pool;
dld = rhs.dld; dld = rhs.dld;
rhs.Reset();
return *this; return *this;
} }
/// Releases the underlying allocations back to their pool if owned.
void Release() noexcept {
if (!allocations || num == 0 || !device || !pool || !dld) {
Reset();
return;
}
const Span<AllocationType> span{allocations.get(), num};
[[maybe_unused]] const VkResult result = Free(device, pool, span, *dld);
DEBUG_ASSERT(result == VK_SUCCESS);
Reset();
}
/// Returns the number of allocations. /// Returns the number of allocations.
std::size_t size() const noexcept { std::size_t size() const noexcept {
return num; return num;
@ -604,6 +629,14 @@ private:
VkDevice device = nullptr; VkDevice device = nullptr;
PoolType pool = nullptr; PoolType pool = nullptr;
const DeviceDispatch* dld = nullptr; const DeviceDispatch* dld = nullptr;
void Reset() noexcept {
allocations.reset();
num = 0;
device = nullptr;
pool = nullptr;
dld = nullptr;
}
}; };
using DebugUtilsMessenger = Handle<VkDebugUtilsMessengerEXT, VkInstance, InstanceDispatch>; using DebugUtilsMessenger = Handle<VkDebugUtilsMessengerEXT, VkInstance, InstanceDispatch>;