1
0
Fork 0
forked from suyu/suyu

Merge pull request #11995 from FernandoS27/you-dont-need-the-new-iphone

Revert PR #11806 and do a proper fix to the memory handling.
This commit is contained in:
liamwhite 2023-11-16 09:17:13 -05:00 committed by GitHub
commit d86e88a622
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 32 additions and 30 deletions

View file

@ -1,8 +1,10 @@
// SPDX-FileCopyrightText: 2015 Citra Emulator Project // SPDX-FileCopyrightText: 2015 Citra Emulator Project
// SPDX-FileCopyrightText: 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <algorithm> #include <algorithm>
#include <cstring> #include <cstring>
#include <mutex>
#include <span> #include <span>
#include "common/assert.h" #include "common/assert.h"
@ -10,6 +12,7 @@
#include "common/common_types.h" #include "common/common_types.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/page_table.h" #include "common/page_table.h"
#include "common/scope_exit.h"
#include "common/settings.h" #include "common/settings.h"
#include "common/swap.h" #include "common/swap.h"
#include "core/core.h" #include "core/core.h"
@ -318,7 +321,7 @@ struct Memory::Impl {
[&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount, [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
u8* const host_ptr) { u8* const host_ptr) {
if constexpr (!UNSAFE) { if constexpr (!UNSAFE) {
system.GPU().InvalidateRegion(GetInteger(current_vaddr), copy_amount); HandleRasterizerWrite(GetInteger(current_vaddr), copy_amount);
} }
std::memcpy(host_ptr, src_buffer, copy_amount); std::memcpy(host_ptr, src_buffer, copy_amount);
}, },
@ -351,7 +354,7 @@ struct Memory::Impl {
}, },
[&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount, [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
u8* const host_ptr) { u8* const host_ptr) {
system.GPU().InvalidateRegion(GetInteger(current_vaddr), copy_amount); HandleRasterizerWrite(GetInteger(current_vaddr), copy_amount);
std::memset(host_ptr, 0, copy_amount); std::memset(host_ptr, 0, copy_amount);
}, },
[](const std::size_t copy_amount) {}); [](const std::size_t copy_amount) {});
@ -420,7 +423,7 @@ struct Memory::Impl {
const std::size_t block_size) { const std::size_t block_size) {
// dc cvac: Store to point of coherency // dc cvac: Store to point of coherency
// CPU flush -> GPU invalidate // CPU flush -> GPU invalidate
system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size); HandleRasterizerWrite(GetInteger(current_vaddr), block_size);
}; };
return PerformCacheOperation(dest_addr, size, on_rasterizer); return PerformCacheOperation(dest_addr, size, on_rasterizer);
} }
@ -430,7 +433,7 @@ struct Memory::Impl {
const std::size_t block_size) { const std::size_t block_size) {
// dc civac: Store to point of coherency, and invalidate from cache // dc civac: Store to point of coherency, and invalidate from cache
// CPU flush -> GPU invalidate // CPU flush -> GPU invalidate
system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size); HandleRasterizerWrite(GetInteger(current_vaddr), block_size);
}; };
return PerformCacheOperation(dest_addr, size, on_rasterizer); return PerformCacheOperation(dest_addr, size, on_rasterizer);
} }
@ -767,7 +770,18 @@ struct Memory::Impl {
} }
void HandleRasterizerWrite(VAddr address, size_t size) { void HandleRasterizerWrite(VAddr address, size_t size) {
const size_t core = system.GetCurrentHostThreadID(); constexpr size_t sys_core = Core::Hardware::NUM_CPU_CORES - 1;
const size_t core = std::min(system.GetCurrentHostThreadID(),
sys_core); // any other calls threads go to syscore.
// Guard on sys_core;
if (core == sys_core) [[unlikely]] {
sys_core_guard.lock();
}
SCOPE_EXIT({
if (core == sys_core) [[unlikely]] {
sys_core_guard.unlock();
}
});
auto& current_area = rasterizer_write_areas[core]; auto& current_area = rasterizer_write_areas[core];
VAddr subaddress = address >> YUZU_PAGEBITS; VAddr subaddress = address >> YUZU_PAGEBITS;
bool do_collection = current_area.last_address == subaddress; bool do_collection = current_area.last_address == subaddress;
@ -799,6 +813,7 @@ struct Memory::Impl {
rasterizer_read_areas{}; rasterizer_read_areas{};
std::array<GPUDirtyState, Core::Hardware::NUM_CPU_CORES> rasterizer_write_areas{}; std::array<GPUDirtyState, Core::Hardware::NUM_CPU_CORES> rasterizer_write_areas{};
std::span<Core::GPUDirtyMemoryManager> gpu_dirty_managers; std::span<Core::GPUDirtyMemoryManager> gpu_dirty_managers;
std::mutex sys_core_guard;
}; };
Memory::Memory(Core::System& system_) : system{system_} { Memory::Memory(Core::System& system_) : system{system_} {

View file

@ -86,10 +86,7 @@ public:
uncommitted_operations.emplace_back(std::move(func)); uncommitted_operations.emplace_back(std::move(func));
} }
pending_operations.emplace_back(std::move(uncommitted_operations)); pending_operations.emplace_back(std::move(uncommitted_operations));
{
std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
QueueFence(new_fence); QueueFence(new_fence);
}
if (!delay_fence) { if (!delay_fence) {
func(); func();
} }

View file

@ -555,7 +555,7 @@ void RasterizerOpenGL::OnCacheInvalidation(VAddr addr, u64 size) {
} }
{ {
std::scoped_lock lock{buffer_cache.mutex}; std::scoped_lock lock{buffer_cache.mutex};
buffer_cache.CachedWriteMemory(addr, size); buffer_cache.WriteMemory(addr, size);
} }
shader_cache.InvalidateRegion(addr, size); shader_cache.InvalidateRegion(addr, size);
} }

View file

@ -132,16 +132,12 @@ void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
const bool use_accelerated = const bool use_accelerated =
rasterizer.AccelerateDisplay(*framebuffer, framebuffer_addr, framebuffer->stride); rasterizer.AccelerateDisplay(*framebuffer, framebuffer_addr, framebuffer->stride);
const bool is_srgb = use_accelerated && screen_info.is_srgb; const bool is_srgb = use_accelerated && screen_info.is_srgb;
{
std::scoped_lock lock{rasterizer.LockCaches()};
RenderScreenshot(*framebuffer, use_accelerated); RenderScreenshot(*framebuffer, use_accelerated);
Frame* frame = present_manager.GetRenderFrame(); Frame* frame = present_manager.GetRenderFrame();
blit_screen.DrawToSwapchain(frame, *framebuffer, use_accelerated, is_srgb); blit_screen.DrawToSwapchain(frame, *framebuffer, use_accelerated, is_srgb);
scheduler.Flush(*frame->render_ready); scheduler.Flush(*frame->render_ready);
present_manager.Present(frame); present_manager.Present(frame);
}
gpu.RendererFrameEndNotify(); gpu.RendererFrameEndNotify();
rasterizer.TickFrame(); rasterizer.TickFrame();

View file

@ -199,7 +199,7 @@ void RasterizerVulkan::PrepareDraw(bool is_indexed, Func&& draw_func) {
if (!pipeline) { if (!pipeline) {
return; return;
} }
std::scoped_lock lock{LockCaches()}; std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
// update engine as channel may be different. // update engine as channel may be different.
pipeline->SetEngine(maxwell3d, gpu_memory); pipeline->SetEngine(maxwell3d, gpu_memory);
pipeline->Configure(is_indexed); pipeline->Configure(is_indexed);
@ -621,7 +621,7 @@ void RasterizerVulkan::OnCacheInvalidation(VAddr addr, u64 size) {
} }
{ {
std::scoped_lock lock{buffer_cache.mutex}; std::scoped_lock lock{buffer_cache.mutex};
buffer_cache.CachedWriteMemory(addr, size); buffer_cache.WriteMemory(addr, size);
} }
pipeline_cache.InvalidateRegion(addr, size); pipeline_cache.InvalidateRegion(addr, size);
} }
@ -710,7 +710,6 @@ void RasterizerVulkan::TiledCacheBarrier() {
} }
void RasterizerVulkan::FlushCommands() { void RasterizerVulkan::FlushCommands() {
std::scoped_lock lock{LockCaches()};
if (draw_counter == 0) { if (draw_counter == 0) {
return; return;
} }
@ -808,7 +807,6 @@ void RasterizerVulkan::FlushWork() {
if ((++draw_counter & 7) != 7) { if ((++draw_counter & 7) != 7) {
return; return;
} }
std::scoped_lock lock{LockCaches()};
if (draw_counter < DRAWS_TO_DISPATCH) { if (draw_counter < DRAWS_TO_DISPATCH) {
// Send recorded tasks to the worker thread // Send recorded tasks to the worker thread
scheduler.DispatchWork(); scheduler.DispatchWork();
@ -1507,7 +1505,7 @@ void RasterizerVulkan::UpdateVertexInput(Tegra::Engines::Maxwell3D::Regs& regs)
void RasterizerVulkan::InitializeChannel(Tegra::Control::ChannelState& channel) { void RasterizerVulkan::InitializeChannel(Tegra::Control::ChannelState& channel) {
CreateChannel(channel); CreateChannel(channel);
{ {
std::scoped_lock lock{LockCaches()}; std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
texture_cache.CreateChannel(channel); texture_cache.CreateChannel(channel);
buffer_cache.CreateChannel(channel); buffer_cache.CreateChannel(channel);
} }
@ -1520,7 +1518,7 @@ void RasterizerVulkan::BindChannel(Tegra::Control::ChannelState& channel) {
const s32 channel_id = channel.bind_id; const s32 channel_id = channel.bind_id;
BindToChannel(channel_id); BindToChannel(channel_id);
{ {
std::scoped_lock lock{LockCaches()}; std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
texture_cache.BindToChannel(channel_id); texture_cache.BindToChannel(channel_id);
buffer_cache.BindToChannel(channel_id); buffer_cache.BindToChannel(channel_id);
} }
@ -1533,7 +1531,7 @@ void RasterizerVulkan::BindChannel(Tegra::Control::ChannelState& channel) {
void RasterizerVulkan::ReleaseChannel(s32 channel_id) { void RasterizerVulkan::ReleaseChannel(s32 channel_id) {
EraseChannel(channel_id); EraseChannel(channel_id);
{ {
std::scoped_lock lock{LockCaches()}; std::scoped_lock lock{buffer_cache.mutex, texture_cache.mutex};
texture_cache.EraseChannel(channel_id); texture_cache.EraseChannel(channel_id);
buffer_cache.EraseChannel(channel_id); buffer_cache.EraseChannel(channel_id);
} }

View file

@ -133,10 +133,6 @@ public:
void ReleaseChannel(s32 channel_id) override; void ReleaseChannel(s32 channel_id) override;
std::scoped_lock<std::recursive_mutex, std::recursive_mutex> LockCaches() {
return std::scoped_lock{buffer_cache.mutex, texture_cache.mutex};
}
private: private:
static constexpr size_t MAX_TEXTURES = 192; static constexpr size_t MAX_TEXTURES = 192;
static constexpr size_t MAX_IMAGES = 48; static constexpr size_t MAX_IMAGES = 48;