mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2025-07-20 19:55:46 +00:00
[vk, opengl] defer checks to topmost call (avoid unnecessary call) (#40)
Co-authored-by: crueter <crueter@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/40 Co-authored-by: lizzie <lizzie@eden-emu.dev> Co-committed-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
parent
03351a4f8b
commit
5091759a47
4 changed files with 66 additions and 61 deletions
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: 2015 Citra Emulator Project
|
// SPDX-FileCopyrightText: 2015 Citra Emulator Project
|
||||||
// SPDX-FileCopyrightText: 2018 yuzu Emulator Project
|
// SPDX-FileCopyrightText: 2018 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
@ -868,17 +871,15 @@ struct Memory::Impl {
|
||||||
[[nodiscard]] u8* GetPointerImpl(u64 vaddr, auto on_unmapped, auto on_rasterizer) const {
|
[[nodiscard]] u8* GetPointerImpl(u64 vaddr, auto on_unmapped, auto on_rasterizer) const {
|
||||||
// AARCH64 masks the upper 16 bit of all memory accesses
|
// AARCH64 masks the upper 16 bit of all memory accesses
|
||||||
vaddr = vaddr & 0xffffffffffffULL;
|
vaddr = vaddr & 0xffffffffffffULL;
|
||||||
|
|
||||||
if (!AddressSpaceContains(*current_page_table, vaddr, 1)) [[unlikely]] {
|
if (!AddressSpaceContains(*current_page_table, vaddr, 1)) [[unlikely]] {
|
||||||
on_unmapped();
|
on_unmapped();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
} else {
|
||||||
|
|
||||||
// Avoid adding any extra logic to this fast-path block
|
// Avoid adding any extra logic to this fast-path block
|
||||||
const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Raw();
|
const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Raw();
|
||||||
if (const uintptr_t pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) {
|
if (const uintptr_t pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) {
|
||||||
return reinterpret_cast<u8*>(pointer + vaddr);
|
return reinterpret_cast<u8*>(pointer + vaddr);
|
||||||
}
|
} else {
|
||||||
switch (Common::PageTable::PageInfo::ExtractType(raw_pointer)) {
|
switch (Common::PageTable::PageInfo::ExtractType(raw_pointer)) {
|
||||||
case Common::PageType::Unmapped:
|
case Common::PageType::Unmapped:
|
||||||
on_unmapped();
|
on_unmapped();
|
||||||
|
@ -898,6 +899,8 @@ struct Memory::Impl {
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] u8* GetPointer(const Common::ProcessAddress vaddr) const {
|
[[nodiscard]] u8* GetPointer(const Common::ProcessAddress vaddr) const {
|
||||||
return GetPointerImpl(
|
return GetPointerImpl(
|
||||||
|
@ -1149,13 +1152,19 @@ struct Memory::Impl {
|
||||||
gpu_device_memory->ApplyOpOnPointer(p, scratch_buffers[core], [&](DAddr address) {
|
gpu_device_memory->ApplyOpOnPointer(p, scratch_buffers[core], [&](DAddr address) {
|
||||||
auto& current_area = rasterizer_write_areas[core];
|
auto& current_area = rasterizer_write_areas[core];
|
||||||
PAddr subaddress = address >> YUZU_PAGEBITS;
|
PAddr subaddress = address >> YUZU_PAGEBITS;
|
||||||
bool do_collection = current_area.last_address == subaddress;
|
// Performance note:
|
||||||
if (!do_collection) [[unlikely]] {
|
// It may not be a good idea to assume accesses are within the same subaddress (i.e same page)
|
||||||
do_collection = system.GPU().OnCPUWrite(address, size);
|
// It is often the case the games like to access wildly different addresses. Hence why I propose
|
||||||
if (!do_collection) {
|
// we should let the compiler just do it's thing...
|
||||||
|
if (current_area.last_address != subaddress) {
|
||||||
|
// Short circuit the need to check for address/size
|
||||||
|
auto const do_collection = (address != 0 && size != 0)
|
||||||
|
&& system.GPU().OnCPUWrite(address, size);
|
||||||
|
if (do_collection) {
|
||||||
|
current_area.last_address = subaddress;
|
||||||
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
current_area.last_address = subaddress;
|
|
||||||
}
|
}
|
||||||
gpu_dirty_managers[core].Collect(address, size);
|
gpu_dirty_managers[core].Collect(address, size);
|
||||||
});
|
});
|
||||||
|
|
|
@ -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-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
@ -244,7 +247,7 @@ public:
|
||||||
void InvalidateRegion(DAddr addr, u64 size);
|
void InvalidateRegion(DAddr addr, u64 size);
|
||||||
|
|
||||||
/// Notify rasterizer that CPU is trying to write this area. It returns true if the area is
|
/// Notify rasterizer that CPU is trying to write this area. It returns true if the area is
|
||||||
/// sensible, false otherwise
|
/// sensible, false otherwise, addr and size must be a valid combination
|
||||||
bool OnCPUWrite(DAddr addr, u64 size);
|
bool OnCPUWrite(DAddr addr, u64 size);
|
||||||
|
|
||||||
/// Notify rasterizer that any caches of the specified region should be flushed and invalidated
|
/// Notify rasterizer that any caches of the specified region should be flushed and invalidated
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: 2015 Citra Emulator Project
|
// SPDX-FileCopyrightText: 2015 Citra Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
@ -565,22 +568,17 @@ void RasterizerOpenGL::InvalidateRegion(DAddr addr, u64 size, VideoCommon::Cache
|
||||||
|
|
||||||
bool RasterizerOpenGL::OnCPUWrite(DAddr addr, u64 size) {
|
bool RasterizerOpenGL::OnCPUWrite(DAddr addr, u64 size) {
|
||||||
MICROPROFILE_SCOPE(OpenGL_CacheManagement);
|
MICROPROFILE_SCOPE(OpenGL_CacheManagement);
|
||||||
if (addr == 0 || size == 0) {
|
DEBUG_ASSERT(addr != 0 || size != 0);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
std::scoped_lock lock{buffer_cache.mutex};
|
std::scoped_lock lock{buffer_cache.mutex};
|
||||||
if (buffer_cache.OnCPUWrite(addr, size)) {
|
if (buffer_cache.OnCPUWrite(addr, size)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
std::scoped_lock lock{texture_cache.mutex};
|
std::scoped_lock lock{texture_cache.mutex};
|
||||||
texture_cache.WriteMemory(addr, size);
|
texture_cache.WriteMemory(addr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
shader_cache.InvalidateRegion(addr, size);
|
shader_cache.InvalidateRegion(addr, size);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -636,22 +636,17 @@ void RasterizerVulkan::InnerInvalidation(std::span<const std::pair<DAddr, std::s
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RasterizerVulkan::OnCPUWrite(DAddr addr, u64 size) {
|
bool RasterizerVulkan::OnCPUWrite(DAddr addr, u64 size) {
|
||||||
if (addr == 0 || size == 0) {
|
DEBUG_ASSERT(addr != 0 || size != 0);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
std::scoped_lock lock{buffer_cache.mutex};
|
std::scoped_lock lock{buffer_cache.mutex};
|
||||||
if (buffer_cache.OnCPUWrite(addr, size)) {
|
if (buffer_cache.OnCPUWrite(addr, size)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
std::scoped_lock lock{texture_cache.mutex};
|
std::scoped_lock lock{texture_cache.mutex};
|
||||||
texture_cache.WriteMemory(addr, size);
|
texture_cache.WriteMemory(addr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline_cache.InvalidateRegion(addr, size);
|
pipeline_cache.InvalidateRegion(addr, size);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue