Browse Source

[TEST] Caching for texture + pages on NCE

tiled-gpu
CamilleLaVey 2 weeks ago
parent
commit
9c313fb787
  1. 5
      src/core/device_memory_manager.h
  2. 23
      src/core/device_memory_manager.inc
  3. 5
      src/video_core/renderer_vulkan/vk_rasterizer.cpp
  4. 5
      src/video_core/texture_cache/texture_cache.h

5
src/core/device_memory_manager.h

@ -126,6 +126,10 @@ public:
// New batch API to update multiple ranges with a single lock acquisition.
void UpdatePagesCachedBatch(std::span<const std::pair<DAddr, size_t>> ranges, s32 delta);
void UpdateTexturePagesCount(DAddr addr, size_t size, s32 delta);
[[nodiscard]] bool IsRegionTextureCached(DAddr addr, size_t size) const noexcept;
private:
struct TranslationEntry {
DAddr guest_page{};
@ -234,6 +238,7 @@ private:
(1ULL << (device_virtual_bits - page_bits)) / subentries;
using CachedPages = std::array<CounterEntry, num_counter_entries>;
std::unique_ptr<CachedPages> cached_pages;
std::unique_ptr<CachedPages> texture_cached_pages;
Common::RangeMutex counter_guard;
std::mutex mapping_guard;

23
src/core/device_memory_manager.inc

@ -177,6 +177,7 @@ DeviceMemoryManager<Traits>::DeviceMemoryManager(const DeviceMemory& device_memo
{
impl = std::make_unique<DeviceMemoryManagerAllocator<Traits>>();
cached_pages = std::make_unique<CachedPages>();
texture_cached_pages = std::make_unique<CachedPages>();
const size_t total_virtual = device_as_size >> Memory::YUZU_PAGEBITS;
for (size_t i = 0; i < total_virtual; i++) {
@ -625,6 +626,28 @@ void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size
UpdatePagesCachedCountNoLock(addr, size, delta);
}
template <typename Traits>
void DeviceMemoryManager<Traits>::UpdateTexturePagesCount(DAddr addr, size_t size, s32 delta) {
Common::ScopedRangeLock lk(counter_guard, addr, size);
const size_t page_end = Common::DivCeil(addr + size, Memory::YUZU_PAGESIZE);
for (size_t page = addr >> Memory::YUZU_PAGEBITS; page != page_end; ++page) {
CounterAtomicType& count = texture_cached_pages->at(page >> subentries_shift).Count(page);
count.fetch_add(static_cast<CounterType>(delta), std::memory_order_release);
}
}
template <typename Traits>
bool DeviceMemoryManager<Traits>::IsRegionTextureCached(DAddr addr, size_t size) const noexcept {
const size_t page_end = Common::DivCeil(addr + size, Memory::YUZU_PAGESIZE);
for (size_t page = addr >> Memory::YUZU_PAGEBITS; page != page_end; ++page) {
if (texture_cached_pages->at(page >> subentries_shift).Count(page).load(
std::memory_order_acquire) != 0) {
return true;
}
}
return false;
}
template <typename Traits>
void DeviceMemoryManager<Traits>::UpdatePagesCachedBatch(std::span<const std::pair<DAddr, size_t>> ranges, s32 delta) {
if (ranges.empty()) {

5
src/video_core/renderer_vulkan/vk_rasterizer.cpp

@ -772,12 +772,15 @@ bool RasterizerVulkan::OnCPUWrite(DAddr addr, u64 size) {
return false;
}
static constexpr bool ENABLE_TEXTURE_CACHE_INVALIDATION_SKIP = true;
void RasterizerVulkan::OnCacheInvalidation(DAddr addr, u64 size) {
if (addr == 0 || size == 0) {
return;
}
{
if (!ENABLE_TEXTURE_CACHE_INVALIDATION_SKIP ||
device_memory.IsRegionTextureCached(addr, size)) {
std::scoped_lock lock{texture_cache.mutex};
texture_cache.WriteMemory(addr, size);
}

5
src/video_core/texture_cache/texture_cache.h

@ -2308,6 +2308,7 @@ void TextureCache<P>::TrackImage(ImageBase& image, ImageId image_id) {
if (False(image.flags & ImageFlagBits::Sparse)) {
if (image.cpu_addr < ~(1ULL << 40)) {
device_memory.UpdatePagesCachedCount(image.cpu_addr, image.guest_size_bytes, 1);
device_memory.UpdateTexturePagesCount(image.cpu_addr, image.guest_size_bytes, 1);
}
return;
}
@ -2320,12 +2321,14 @@ void TextureCache<P>::TrackImage(ImageBase& image, ImageId image_id) {
const DAddr cpu_addr = map.cpu_addr;
const std::size_t size = map.size;
device_memory.UpdatePagesCachedCount(cpu_addr, size, 1);
device_memory.UpdateTexturePagesCount(cpu_addr, size, 1);
}
return;
}
ForEachSparseSegment(image,
[this]([[maybe_unused]] GPUVAddr gpu_addr, DAddr cpu_addr, size_t size) {
device_memory.UpdatePagesCachedCount(cpu_addr, size, 1);
device_memory.UpdateTexturePagesCount(cpu_addr, size, 1);
});
}
@ -2336,6 +2339,7 @@ void TextureCache<P>::UntrackImage(ImageBase& image, ImageId image_id) {
if (False(image.flags & ImageFlagBits::Sparse)) {
if (image.cpu_addr < ~(1ULL << 40)) {
device_memory.UpdatePagesCachedCount(image.cpu_addr, image.guest_size_bytes, -1);
device_memory.UpdateTexturePagesCount(image.cpu_addr, image.guest_size_bytes, -1);
}
return;
}
@ -2348,6 +2352,7 @@ void TextureCache<P>::UntrackImage(ImageBase& image, ImageId image_id) {
const DAddr cpu_addr = map.cpu_addr;
const std::size_t size = map.size;
device_memory.UpdatePagesCachedCount(cpu_addr, size, -1);
device_memory.UpdateTexturePagesCount(cpu_addr, size, -1);
}
}

Loading…
Cancel
Save