2
1
Fork 0
mirror of https://github.com/yuzu-emu/yuzu.git synced 2024-07-04 23:31:19 +01:00

memory: Simplify rasterizer cache operations.

This commit is contained in:
bunnei 2019-02-22 23:38:45 -05:00
parent 47b622825c
commit 10118c71e0
3 changed files with 22 additions and 68 deletions

View file

@ -18,6 +18,7 @@
#include "core/hle/lock.h" #include "core/hle/lock.h"
#include "core/memory.h" #include "core/memory.h"
#include "core/memory_setup.h" #include "core/memory_setup.h"
#include "video_core/gpu.h"
#include "video_core/renderer_base.h" #include "video_core/renderer_base.h"
namespace Memory { namespace Memory {
@ -69,8 +70,8 @@ static void MapPages(PageTable& page_table, VAddr base, u64 size, u8* memory, Pa
// During boot, current_page_table might not be set yet, in which case we need not flush // During boot, current_page_table might not be set yet, in which case we need not flush
if (current_page_table) { if (current_page_table) {
RasterizerFlushVirtualRegion(base << PAGE_BITS, size * PAGE_SIZE, Core::System::GetInstance().GPU().FlushAndInvalidateRegion(base << PAGE_BITS,
FlushMode::FlushAndInvalidate); size * PAGE_SIZE);
} }
VAddr end = base + size; VAddr end = base + size;
@ -183,10 +184,10 @@ T Read(const VAddr vaddr) {
ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", vaddr); ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", vaddr);
break; break;
case PageType::RasterizerCachedMemory: { case PageType::RasterizerCachedMemory: {
RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::Flush); auto host_ptr{GetPointerFromVMA(vaddr)};
Core::System::GetInstance().GPU().FlushRegion(ToCacheAddr(host_ptr), sizeof(T));
T value; T value;
std::memcpy(&value, GetPointerFromVMA(vaddr), sizeof(T)); std::memcpy(&value, host_ptr, sizeof(T));
return value; return value;
} }
default: default:
@ -214,8 +215,9 @@ void Write(const VAddr vaddr, const T data) {
ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", vaddr); ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", vaddr);
break; break;
case PageType::RasterizerCachedMemory: { case PageType::RasterizerCachedMemory: {
RasterizerFlushVirtualRegion(vaddr, sizeof(T), FlushMode::Invalidate); auto host_ptr{GetPointerFromVMA(vaddr)};
std::memcpy(GetPointerFromVMA(vaddr), &data, sizeof(T)); Core::System::GetInstance().GPU().InvalidateRegion(ToCacheAddr(host_ptr), sizeof(T));
std::memcpy(host_ptr, &data, sizeof(T));
break; break;
} }
default: default:
@ -338,47 +340,6 @@ void RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached) {
} }
} }
void RasterizerFlushVirtualRegion(VAddr start, u64 size, FlushMode mode) {
auto& system_instance = Core::System::GetInstance();
// Since pages are unmapped on shutdown after video core is shutdown, the renderer may be
// null here
if (!system_instance.IsPoweredOn()) {
return;
}
const VAddr end = start + size;
const auto CheckRegion = [&](VAddr region_start, VAddr region_end) {
if (start >= region_end || end <= region_start) {
// No overlap with region
return;
}
const VAddr overlap_start = std::max(start, region_start);
const VAddr overlap_end = std::min(end, region_end);
const VAddr overlap_size = overlap_end - overlap_start;
auto& gpu = system_instance.GPU();
switch (mode) {
case FlushMode::Flush:
gpu.FlushRegion(ToCacheAddr(GetPointer(overlap_start)), overlap_size);
break;
case FlushMode::Invalidate:
gpu.InvalidateRegion(ToCacheAddr(GetPointer(overlap_start)), overlap_size);
break;
case FlushMode::FlushAndInvalidate:
gpu.FlushAndInvalidateRegion(ToCacheAddr(GetPointer(overlap_start)), overlap_size);
break;
}
};
const auto& vm_manager = Core::CurrentProcess()->VMManager();
CheckRegion(vm_manager.GetCodeRegionBaseAddress(), vm_manager.GetCodeRegionEndAddress());
CheckRegion(vm_manager.GetHeapRegionBaseAddress(), vm_manager.GetHeapRegionEndAddress());
}
u8 Read8(const VAddr addr) { u8 Read8(const VAddr addr) {
return Read<u8>(addr); return Read<u8>(addr);
} }
@ -424,9 +385,9 @@ void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_
break; break;
} }
case PageType::RasterizerCachedMemory: { case PageType::RasterizerCachedMemory: {
RasterizerFlushVirtualRegion(current_vaddr, static_cast<u32>(copy_amount), const auto& host_ptr{GetPointerFromVMA(process, current_vaddr)};
FlushMode::Flush); Core::System::GetInstance().GPU().FlushRegion(ToCacheAddr(host_ptr), copy_amount);
std::memcpy(dest_buffer, GetPointerFromVMA(process, current_vaddr), copy_amount); std::memcpy(dest_buffer, host_ptr, copy_amount);
break; break;
} }
default: default:
@ -487,9 +448,9 @@ void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const voi
break; break;
} }
case PageType::RasterizerCachedMemory: { case PageType::RasterizerCachedMemory: {
RasterizerFlushVirtualRegion(current_vaddr, static_cast<u32>(copy_amount), const auto& host_ptr{GetPointerFromVMA(process, current_vaddr)};
FlushMode::Invalidate); Core::System::GetInstance().GPU().InvalidateRegion(ToCacheAddr(host_ptr), copy_amount);
std::memcpy(GetPointerFromVMA(process, current_vaddr), src_buffer, copy_amount); std::memcpy(host_ptr, src_buffer, copy_amount);
break; break;
} }
default: default:
@ -533,9 +494,9 @@ void ZeroBlock(const Kernel::Process& process, const VAddr dest_addr, const std:
break; break;
} }
case PageType::RasterizerCachedMemory: { case PageType::RasterizerCachedMemory: {
RasterizerFlushVirtualRegion(current_vaddr, static_cast<u32>(copy_amount), const auto& host_ptr{GetPointerFromVMA(process, current_vaddr)};
FlushMode::Invalidate); Core::System::GetInstance().GPU().InvalidateRegion(ToCacheAddr(host_ptr), copy_amount);
std::memset(GetPointerFromVMA(process, current_vaddr), 0, copy_amount); std::memset(host_ptr, 0, copy_amount);
break; break;
} }
default: default:
@ -575,9 +536,9 @@ void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr,
break; break;
} }
case PageType::RasterizerCachedMemory: { case PageType::RasterizerCachedMemory: {
RasterizerFlushVirtualRegion(current_vaddr, static_cast<u32>(copy_amount), const auto& host_ptr{GetPointerFromVMA(process, current_vaddr)};
FlushMode::Flush); Core::System::GetInstance().GPU().FlushRegion(ToCacheAddr(host_ptr), copy_amount);
WriteBlock(process, dest_addr, GetPointerFromVMA(process, current_vaddr), copy_amount); WriteBlock(process, dest_addr, host_ptr, copy_amount);
break; break;
} }
default: default:

View file

@ -161,10 +161,4 @@ enum class FlushMode {
*/ */
void RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached); void RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached);
/**
* Flushes and invalidates any externally cached rasterizer resources touching the given virtual
* address region.
*/
void RasterizerFlushVirtualRegion(VAddr start, u64 size, FlushMode mode);
} // namespace Memory } // namespace Memory

View file

@ -164,8 +164,7 @@ void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuf
// Reset the screen info's display texture to its own permanent texture // Reset the screen info's display texture to its own permanent texture
screen_info.display_texture = screen_info.texture.resource.handle; screen_info.display_texture = screen_info.texture.resource.handle;
Memory::RasterizerFlushVirtualRegion(framebuffer_addr, size_in_bytes, rasterizer->FlushRegion(ToCacheAddr(Memory::GetPointer(framebuffer_addr)), size_in_bytes);
Memory::FlushMode::Flush);
constexpr u32 linear_bpp = 4; constexpr u32 linear_bpp = 4;
VideoCore::MortonCopyPixels128(VideoCore::MortonSwizzleMode::MortonToLinear, VideoCore::MortonCopyPixels128(VideoCore::MortonSwizzleMode::MortonToLinear,