diff options
Diffstat (limited to '')
| -rw-r--r-- | src/video_core/rasterizer_accelerated.cpp | 56 |
1 files changed, 41 insertions, 15 deletions
diff --git a/src/video_core/rasterizer_accelerated.cpp b/src/video_core/rasterizer_accelerated.cpp index 6decd2546..4c9524702 100644 --- a/src/video_core/rasterizer_accelerated.cpp +++ b/src/video_core/rasterizer_accelerated.cpp | |||
| @@ -2,6 +2,8 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <atomic> | ||
| 6 | |||
| 5 | #include "common/assert.h" | 7 | #include "common/assert.h" |
| 6 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 7 | #include "common/div_ceil.h" | 9 | #include "common/div_ceil.h" |
| @@ -10,35 +12,59 @@ | |||
| 10 | 12 | ||
| 11 | namespace VideoCore { | 13 | namespace VideoCore { |
| 12 | 14 | ||
| 13 | RasterizerAccelerated::RasterizerAccelerated(Core::Memory::Memory& cpu_memory_) | 15 | using namespace Core::Memory; |
| 14 | : cpu_memory{cpu_memory_} {} | 16 | |
| 17 | RasterizerAccelerated::RasterizerAccelerated(Memory& cpu_memory_) : cpu_memory{cpu_memory_} {} | ||
| 15 | 18 | ||
| 16 | RasterizerAccelerated::~RasterizerAccelerated() = default; | 19 | RasterizerAccelerated::~RasterizerAccelerated() = default; |
| 17 | 20 | ||
| 18 | void RasterizerAccelerated::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) { | 21 | void RasterizerAccelerated::UpdatePagesCachedCount(VAddr addr, u64 size, int delta) { |
| 19 | const auto page_end = Common::DivCeil(addr + size, Core::Memory::PAGE_SIZE); | 22 | u64 uncache_begin = 0; |
| 20 | for (auto page = addr >> Core::Memory::PAGE_BITS; page != page_end; ++page) { | 23 | u64 cache_begin = 0; |
| 21 | auto& count = cached_pages.at(page >> 2).Count(page); | 24 | u64 uncache_bytes = 0; |
| 25 | u64 cache_bytes = 0; | ||
| 26 | |||
| 27 | std::atomic_thread_fence(std::memory_order_acquire); | ||
| 28 | const u64 page_end = Common::DivCeil(addr + size, PAGE_SIZE); | ||
| 29 | for (u64 page = addr >> PAGE_BITS; page != page_end; ++page) { | ||
| 30 | std::atomic_uint16_t& count = cached_pages.at(page >> 2).Count(page); | ||
| 22 | 31 | ||
| 23 | if (delta > 0) { | 32 | if (delta > 0) { |
| 24 | ASSERT_MSG(count < UINT16_MAX, "Count may overflow!"); | 33 | ASSERT_MSG(count.load(std::memory_order::relaxed) < UINT16_MAX, "Count may overflow!"); |
| 25 | } else if (delta < 0) { | 34 | } else if (delta < 0) { |
| 26 | ASSERT_MSG(count > 0, "Count may underflow!"); | 35 | ASSERT_MSG(count.load(std::memory_order::relaxed) > 0, "Count may underflow!"); |
| 27 | } else { | 36 | } else { |
| 28 | ASSERT_MSG(true, "Delta must be non-zero!"); | 37 | ASSERT_MSG(false, "Delta must be non-zero!"); |
| 29 | } | 38 | } |
| 30 | 39 | ||
| 31 | // Adds or subtracts 1, as count is a unsigned 8-bit value | 40 | // Adds or subtracts 1, as count is a unsigned 8-bit value |
| 32 | count += static_cast<u16>(delta); | 41 | count.fetch_add(static_cast<u16>(delta), std::memory_order_release); |
| 33 | 42 | ||
| 34 | // Assume delta is either -1 or 1 | 43 | // Assume delta is either -1 or 1 |
| 35 | if (count == 0) { | 44 | if (count.load(std::memory_order::relaxed) == 0) { |
| 36 | cpu_memory.RasterizerMarkRegionCached(page << Core::Memory::PAGE_BITS, | 45 | if (uncache_bytes == 0) { |
| 37 | Core::Memory::PAGE_SIZE, false); | 46 | uncache_begin = page; |
| 38 | } else if (count == 1 && delta > 0) { | 47 | } |
| 39 | cpu_memory.RasterizerMarkRegionCached(page << Core::Memory::PAGE_BITS, | 48 | uncache_bytes += PAGE_SIZE; |
| 40 | Core::Memory::PAGE_SIZE, true); | 49 | } else if (uncache_bytes > 0) { |
| 50 | cpu_memory.RasterizerMarkRegionCached(uncache_begin << PAGE_BITS, uncache_bytes, false); | ||
| 51 | uncache_bytes = 0; | ||
| 41 | } | 52 | } |
| 53 | if (count.load(std::memory_order::relaxed) == 1 && delta > 0) { | ||
| 54 | if (cache_bytes == 0) { | ||
| 55 | cache_begin = page; | ||
| 56 | } | ||
| 57 | cache_bytes += PAGE_SIZE; | ||
| 58 | } else if (cache_bytes > 0) { | ||
| 59 | cpu_memory.RasterizerMarkRegionCached(cache_begin << PAGE_BITS, cache_bytes, true); | ||
| 60 | cache_bytes = 0; | ||
| 61 | } | ||
| 62 | } | ||
| 63 | if (uncache_bytes > 0) { | ||
| 64 | cpu_memory.RasterizerMarkRegionCached(uncache_begin << PAGE_BITS, uncache_bytes, false); | ||
| 65 | } | ||
| 66 | if (cache_bytes > 0) { | ||
| 67 | cpu_memory.RasterizerMarkRegionCached(cache_begin << PAGE_BITS, cache_bytes, true); | ||
| 42 | } | 68 | } |
| 43 | } | 69 | } |
| 44 | 70 | ||