Query Cache: Use VAddr instead of physical memory for adressing.

This commit is contained in:
Fernando Sahmkow 2020-04-05 18:39:24 -04:00
parent 7fcd0fee6d
commit 3dd5c07454
3 changed files with 22 additions and 23 deletions

View File

@ -98,12 +98,12 @@ public:
static_cast<QueryCache&>(*this), static_cast<QueryCache&>(*this),
VideoCore::QueryType::SamplesPassed}}} {} VideoCore::QueryType::SamplesPassed}}} {}
void InvalidateRegion(CacheAddr addr, std::size_t size) { void InvalidateRegion(VAddr addr, std::size_t size) {
std::unique_lock lock{mutex}; std::unique_lock lock{mutex};
FlushAndRemoveRegion(addr, size); FlushAndRemoveRegion(addr, size);
} }
void FlushRegion(CacheAddr addr, std::size_t size) { void FlushRegion(VAddr addr, std::size_t size) {
std::unique_lock lock{mutex}; std::unique_lock lock{mutex};
FlushAndRemoveRegion(addr, size); FlushAndRemoveRegion(addr, size);
} }
@ -117,14 +117,18 @@ public:
void Query(GPUVAddr gpu_addr, VideoCore::QueryType type, std::optional<u64> timestamp) { void Query(GPUVAddr gpu_addr, VideoCore::QueryType type, std::optional<u64> timestamp) {
std::unique_lock lock{mutex}; std::unique_lock lock{mutex};
auto& memory_manager = system.GPU().MemoryManager(); auto& memory_manager = system.GPU().MemoryManager();
const auto host_ptr = memory_manager.GetPointer(gpu_addr); const std::optional<VAddr> cpu_addr_opt =
memory_manager.GpuToCpuAddress(gpu_addr);
ASSERT(cpu_addr_opt);
VAddr cpu_addr = *cpu_addr_opt;
CachedQuery* query = TryGet(ToCacheAddr(host_ptr));
CachedQuery* query = TryGet(cpu_addr);
if (!query) { if (!query) {
const auto cpu_addr = memory_manager.GpuToCpuAddress(gpu_addr); ASSERT_OR_EXECUTE(cpu_addr_opt, return;);
ASSERT_OR_EXECUTE(cpu_addr, return;); const auto host_ptr = memory_manager.GetPointer(gpu_addr);
query = Register(type, *cpu_addr, host_ptr, timestamp.has_value()); query = Register(type, cpu_addr, host_ptr, timestamp.has_value());
} }
query->BindCounter(Stream(type).Current(), timestamp); query->BindCounter(Stream(type).Current(), timestamp);
@ -173,11 +177,11 @@ protected:
private: private:
/// Flushes a memory range to guest memory and removes it from the cache. /// Flushes a memory range to guest memory and removes it from the cache.
void FlushAndRemoveRegion(CacheAddr addr, std::size_t size) { void FlushAndRemoveRegion(VAddr addr, std::size_t size) {
const u64 addr_begin = static_cast<u64>(addr); const u64 addr_begin = static_cast<u64>(addr);
const u64 addr_end = addr_begin + static_cast<u64>(size); const u64 addr_end = addr_begin + static_cast<u64>(size);
const auto in_range = [addr_begin, addr_end](CachedQuery& query) { const auto in_range = [addr_begin, addr_end](CachedQuery& query) {
const u64 cache_begin = query.GetCacheAddr(); const u64 cache_begin = query.GetCpuAddr();
const u64 cache_end = cache_begin + query.SizeInBytes(); const u64 cache_end = cache_begin + query.SizeInBytes();
return cache_begin < addr_end && addr_begin < cache_end; return cache_begin < addr_end && addr_begin < cache_end;
}; };
@ -193,7 +197,7 @@ private:
if (!in_range(query)) { if (!in_range(query)) {
continue; continue;
} }
rasterizer.UpdatePagesCachedCount(query.CpuAddr(), query.SizeInBytes(), -1); rasterizer.UpdatePagesCachedCount(query.GetCpuAddr(), query.SizeInBytes(), -1);
query.Flush(); query.Flush();
} }
contents.erase(std::remove_if(std::begin(contents), std::end(contents), in_range), contents.erase(std::remove_if(std::begin(contents), std::end(contents), in_range),
@ -204,13 +208,13 @@ private:
/// Registers the passed parameters as cached and returns a pointer to the stored cached query. /// Registers the passed parameters as cached and returns a pointer to the stored cached query.
CachedQuery* Register(VideoCore::QueryType type, VAddr cpu_addr, u8* host_ptr, bool timestamp) { CachedQuery* Register(VideoCore::QueryType type, VAddr cpu_addr, u8* host_ptr, bool timestamp) {
rasterizer.UpdatePagesCachedCount(cpu_addr, CachedQuery::SizeInBytes(timestamp), 1); rasterizer.UpdatePagesCachedCount(cpu_addr, CachedQuery::SizeInBytes(timestamp), 1);
const u64 page = static_cast<u64>(ToCacheAddr(host_ptr)) >> PAGE_SHIFT; const u64 page = static_cast<u64>(cpu_addr) >> PAGE_SHIFT;
return &cached_queries[page].emplace_back(static_cast<QueryCache&>(*this), type, cpu_addr, return &cached_queries[page].emplace_back(static_cast<QueryCache&>(*this), type, cpu_addr,
host_ptr); host_ptr);
} }
/// Tries to a get a cached query. Returns nullptr on failure. /// Tries to a get a cached query. Returns nullptr on failure.
CachedQuery* TryGet(CacheAddr addr) { CachedQuery* TryGet(VAddr addr) {
const u64 page = static_cast<u64>(addr) >> PAGE_SHIFT; const u64 page = static_cast<u64>(addr) >> PAGE_SHIFT;
const auto it = cached_queries.find(page); const auto it = cached_queries.find(page);
if (it == std::end(cached_queries)) { if (it == std::end(cached_queries)) {
@ -219,7 +223,7 @@ private:
auto& contents = it->second; auto& contents = it->second;
const auto found = const auto found =
std::find_if(std::begin(contents), std::end(contents), std::find_if(std::begin(contents), std::end(contents),
[addr](auto& query) { return query.GetCacheAddr() == addr; }); [addr](auto& query) { return query.GetCpuAddr() == addr; });
return found != std::end(contents) ? &*found : nullptr; return found != std::end(contents) ? &*found : nullptr;
} }
@ -323,14 +327,10 @@ public:
timestamp = timestamp_; timestamp = timestamp_;
} }
VAddr CpuAddr() const noexcept { VAddr GetCpuAddr() const noexcept {
return cpu_addr; return cpu_addr;
} }
CacheAddr GetCacheAddr() const noexcept {
return ToCacheAddr(host_ptr);
}
u64 SizeInBytes() const noexcept { u64 SizeInBytes() const noexcept {
return SizeInBytes(timestamp.has_value()); return SizeInBytes(timestamp.has_value());
} }

View File

@ -661,10 +661,9 @@ void RasterizerOpenGL::FlushRegion(VAddr addr, u64 size) {
if (!addr || !size) { if (!addr || !size) {
return; return;
} }
CacheAddr cache_addr = ToCacheAddr(system.Memory().GetPointer(addr));
texture_cache.FlushRegion(addr, size); texture_cache.FlushRegion(addr, size);
buffer_cache.FlushRegion(addr, size); buffer_cache.FlushRegion(addr, size);
query_cache.FlushRegion(cache_addr, size); query_cache.FlushRegion(addr, size);
} }
void RasterizerOpenGL::InvalidateRegion(VAddr addr, u64 size) { void RasterizerOpenGL::InvalidateRegion(VAddr addr, u64 size) {
@ -676,7 +675,7 @@ void RasterizerOpenGL::InvalidateRegion(VAddr addr, u64 size) {
texture_cache.InvalidateRegion(addr, size); texture_cache.InvalidateRegion(addr, size);
shader_cache.InvalidateRegion(cache_addr, size); shader_cache.InvalidateRegion(cache_addr, size);
buffer_cache.InvalidateRegion(addr, size); buffer_cache.InvalidateRegion(addr, size);
query_cache.InvalidateRegion(cache_addr, size); query_cache.InvalidateRegion(addr, size);
} }
void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) { void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) {

View File

@ -502,7 +502,7 @@ void RasterizerVulkan::FlushRegion(VAddr addr, u64 size) {
CacheAddr cache_addr = ToCacheAddr(system.Memory().GetPointer(addr)); CacheAddr cache_addr = ToCacheAddr(system.Memory().GetPointer(addr));
texture_cache.FlushRegion(addr, size); texture_cache.FlushRegion(addr, size);
buffer_cache.FlushRegion(addr, size); buffer_cache.FlushRegion(addr, size);
query_cache.FlushRegion(cache_addr, size); query_cache.FlushRegion(addr, size);
} }
void RasterizerVulkan::InvalidateRegion(VAddr addr, u64 size) { void RasterizerVulkan::InvalidateRegion(VAddr addr, u64 size) {
@ -513,7 +513,7 @@ void RasterizerVulkan::InvalidateRegion(VAddr addr, u64 size) {
texture_cache.InvalidateRegion(addr, size); texture_cache.InvalidateRegion(addr, size);
pipeline_cache.InvalidateRegion(cache_addr, size); pipeline_cache.InvalidateRegion(cache_addr, size);
buffer_cache.InvalidateRegion(addr, size); buffer_cache.InvalidateRegion(addr, size);
query_cache.InvalidateRegion(cache_addr, size); query_cache.InvalidateRegion(addr, size);
} }
void RasterizerVulkan::FlushAndInvalidateRegion(VAddr addr, u64 size) { void RasterizerVulkan::FlushAndInvalidateRegion(VAddr addr, u64 size) {