1
1
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: 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <algorithm>
#include <cstring>
#include <mutex>
#include <span>
#include "common/assert.h"
@ -10,6 +12,7 @@
#include "common/common_types.h"
#include "common/logging/log.h"
#include "common/page_table.h"
#include "common/scope_exit.h"
#include "common/settings.h"
#include "common/swap.h"
#include "core/core.h"
@ -318,7 +321,7 @@ struct Memory::Impl {
[&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
u8* const host_ptr) {
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);
},
@ -351,7 +354,7 @@ struct Memory::Impl {
},
[&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
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);
},
[](const std::size_t copy_amount) {});
@ -420,7 +423,7 @@ struct Memory::Impl {
const std::size_t block_size) {
// dc cvac: Store to point of coherency
// 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);
}
@ -430,7 +433,7 @@ struct Memory::Impl {
const std::size_t block_size) {
// dc civac: Store to point of coherency, and invalidate from cache
// 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);
}
@ -767,7 +770,18 @@ struct Memory::Impl {
}
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];
VAddr subaddress = address >> YUZU_PAGEBITS;
bool do_collection = current_area.last_address == subaddress;
@ -799,6 +813,7 @@ struct Memory::Impl {
rasterizer_read_areas{};
std::array<GPUDirtyState, Core::Hardware::NUM_CPU_CORES> rasterizer_write_areas{};
std::span<Core::GPUDirtyMemoryManager> gpu_dirty_managers;
std::mutex sys_core_guard;
};
Memory::Memory(Core::System& system_) : system{system_} {

View file

@ -86,10 +86,7 @@ public:
uncommitted_operations.emplace_back(std::move(func));
}
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) {
func();
}

View file

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

View file

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

View file

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

View file

@ -133,10 +133,6 @@ public:
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:
static constexpr size_t MAX_TEXTURES = 192;
static constexpr size_t MAX_IMAGES = 48;