diff options
| author | 2018-03-22 22:56:41 -0400 | |
|---|---|---|
| committer | 2018-03-22 22:56:41 -0400 | |
| commit | 63d3924b5bb5dd17f1de9dfe3a357df293fc113d (patch) | |
| tree | 7f636f8c396ea50329ac20e45b58c387d9722eba /src | |
| parent | gl_rasterizer_cache: LoadGLBuffer should do a morton copy. (diff) | |
| download | yuzu-63d3924b5bb5dd17f1de9dfe3a357df293fc113d.tar.gz yuzu-63d3924b5bb5dd17f1de9dfe3a357df293fc113d.tar.xz yuzu-63d3924b5bb5dd17f1de9dfe3a357df293fc113d.zip | |
memory: Port RasterizerFlushVirtualRegion from Citra.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/memory.cpp | 39 | ||||
| -rw-r--r-- | src/core/memory.h | 20 |
2 files changed, 58 insertions, 1 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 4e34d8334..8a83de904 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp | |||
| @@ -42,6 +42,9 @@ static void MapPages(PageTable& page_table, VAddr base, u64 size, u8* memory, Pa | |||
| 42 | LOG_DEBUG(HW_Memory, "Mapping %p onto %016" PRIX64 "-%016" PRIX64, memory, base * PAGE_SIZE, | 42 | LOG_DEBUG(HW_Memory, "Mapping %p onto %016" PRIX64 "-%016" PRIX64, memory, base * PAGE_SIZE, |
| 43 | (base + size) * PAGE_SIZE); | 43 | (base + size) * PAGE_SIZE); |
| 44 | 44 | ||
| 45 | RasterizerFlushVirtualRegion(base << PAGE_BITS, size * PAGE_SIZE, | ||
| 46 | FlushMode::FlushAndInvalidate); | ||
| 47 | |||
| 45 | VAddr end = base + size; | 48 | VAddr end = base + size; |
| 46 | while (base != end) { | 49 | while (base != end) { |
| 47 | ASSERT_MSG(base < PAGE_TABLE_NUM_ENTRIES, "out of range mapping at %016" PRIX64, base); | 50 | ASSERT_MSG(base < PAGE_TABLE_NUM_ENTRIES, "out of range mapping at %016" PRIX64, base); |
| @@ -293,6 +296,42 @@ u8* GetPhysicalPointer(PAddr address) { | |||
| 293 | return target_pointer; | 296 | return target_pointer; |
| 294 | } | 297 | } |
| 295 | 298 | ||
| 299 | void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode) { | ||
| 300 | // Since pages are unmapped on shutdown after video core is shutdown, the renderer may be | ||
| 301 | // null here | ||
| 302 | if (VideoCore::g_renderer == nullptr) { | ||
| 303 | return; | ||
| 304 | } | ||
| 305 | |||
| 306 | VAddr end = start + size; | ||
| 307 | |||
| 308 | auto CheckRegion = [&](VAddr region_start, VAddr region_end) { | ||
| 309 | if (start >= region_end || end <= region_start) { | ||
| 310 | // No overlap with region | ||
| 311 | return; | ||
| 312 | } | ||
| 313 | |||
| 314 | VAddr overlap_start = std::max(start, region_start); | ||
| 315 | VAddr overlap_end = std::min(end, region_end); | ||
| 316 | u32 overlap_size = overlap_end - overlap_start; | ||
| 317 | |||
| 318 | auto* rasterizer = VideoCore::g_renderer->Rasterizer(); | ||
| 319 | switch (mode) { | ||
| 320 | case FlushMode::Flush: | ||
| 321 | rasterizer->FlushRegion(region_start, overlap_size); | ||
| 322 | break; | ||
| 323 | case FlushMode::Invalidate: | ||
| 324 | rasterizer->InvalidateRegion(region_start, overlap_size); | ||
| 325 | break; | ||
| 326 | case FlushMode::FlushAndInvalidate: | ||
| 327 | rasterizer->FlushAndInvalidateRegion(region_start, overlap_size); | ||
| 328 | break; | ||
| 329 | } | ||
| 330 | }; | ||
| 331 | |||
| 332 | CheckRegion(HEAP_VADDR, HEAP_VADDR_END); | ||
| 333 | } | ||
| 334 | |||
| 296 | u8 Read8(const VAddr addr) { | 335 | u8 Read8(const VAddr addr) { |
| 297 | return Read<u8>(addr); | 336 | return Read<u8>(addr); |
| 298 | } | 337 | } |
diff --git a/src/core/memory.h b/src/core/memory.h index f406cc848..1c7232115 100644 --- a/src/core/memory.h +++ b/src/core/memory.h | |||
| @@ -36,7 +36,10 @@ enum class PageType : u8 { | |||
| 36 | Unmapped, | 36 | Unmapped, |
| 37 | /// Page is mapped to regular memory. This is the only type you can get pointers to. | 37 | /// Page is mapped to regular memory. This is the only type you can get pointers to. |
| 38 | Memory, | 38 | Memory, |
| 39 | /// Page is mapped to a memory hook, which intercepts read and write requests. | 39 | /// Page is mapped to regular memory, but also needs to check for rasterizer cache flushing and |
| 40 | /// invalidation | ||
| 41 | RasterizerCachedMemory, | ||
| 42 | /// Page is mapped to a I/O region. Writing and reading to this page is handled by functions. | ||
| 40 | Special, | 43 | Special, |
| 41 | }; | 44 | }; |
| 42 | 45 | ||
| @@ -253,4 +256,19 @@ boost::optional<VAddr> PhysicalToVirtualAddress(PAddr addr); | |||
| 253 | */ | 256 | */ |
| 254 | u8* GetPhysicalPointer(PAddr address); | 257 | u8* GetPhysicalPointer(PAddr address); |
| 255 | 258 | ||
| 259 | enum class FlushMode { | ||
| 260 | /// Write back modified surfaces to RAM | ||
| 261 | Flush, | ||
| 262 | /// Remove region from the cache | ||
| 263 | Invalidate, | ||
| 264 | /// Write back modified surfaces to RAM, and also remove them from the cache | ||
| 265 | FlushAndInvalidate, | ||
| 266 | }; | ||
| 267 | |||
| 268 | /** | ||
| 269 | * Flushes and invalidates any externally cached rasterizer resources touching the given virtual | ||
| 270 | * address region. | ||
| 271 | */ | ||
| 272 | void RasterizerFlushVirtualRegion(VAddr start, u32 size, FlushMode mode); | ||
| 273 | |||
| 256 | } // namespace Memory | 274 | } // namespace Memory |