From 6c7eb81f7d871f5c08a4844471633a67725aae73 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Wed, 4 Jan 2023 22:05:20 -0500 Subject: video_core: Cache GPU internal writes. --- src/video_core/invalidation_accumulator.h | 78 +++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 src/video_core/invalidation_accumulator.h (limited to 'src/video_core/invalidation_accumulator.h') diff --git a/src/video_core/invalidation_accumulator.h b/src/video_core/invalidation_accumulator.h new file mode 100644 index 000000000..42420e31c --- /dev/null +++ b/src/video_core/invalidation_accumulator.h @@ -0,0 +1,78 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +#include "common/common_types.h" + +namespace VideoCommon { + +class InvalidationAccumulator { +public: + InvalidationAccumulator() = default; + ~InvalidationAccumulator() = default; + + void Add(GPUVAddr address, size_t size) { + const auto reset_values = [&]() { + if (has_collected) { + buffer.emplace_back(start_address, accumulated_size); + } + start_address = address; + accumulated_size = size; + last_collection = start_address + size; + }; + if (address >= start_address && address + size <= last_collection) [[likely]] { + return; + } + size = (address + size + atomicy_side_mask) & atomicy_mask - address; + address = address & atomicy_mask; + if (!has_collected) [[unlikely]] { + reset_values(); + has_collected = true; + return; + } + if (address != last_collection) [[unlikely]] { + reset_values(); + return; + } + accumulated_size += size; + last_collection += size; + } + + void Clear() { + buffer.clear(); + start_address = 0; + last_collection = 0; + has_collected = false; + } + + bool AnyAccumulated() const { + return has_collected; + } + + template + void Callback(Func&& func) { + if (!has_collected) { + return; + } + buffer.emplace_back(start_address, accumulated_size); + for (auto& [address, size] : buffer) { + func(address, size); + } + } + +private: + static constexpr size_t atomicy_bits = 5; + static constexpr size_t atomicy_size = 1ULL << atomicy_bits; + static constexpr size_t atomicy_side_mask = atomicy_size - 1; + static constexpr size_t atomicy_mask = ~atomicy_side_mask; + GPUVAddr start_address{}; + GPUVAddr last_collection{}; + size_t accumulated_size{}; + bool has_collected{}; + std::vector> buffer; +}; + +} // namespace VideoCommon -- cgit v1.2.3 From b56ad93bbc9ac38820c1e1cb4b03256dd50aa17a Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Thu, 5 Jan 2023 06:43:54 -0500 Subject: BufferBase: Don't ignore GPU pages. --- src/video_core/invalidation_accumulator.h | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/video_core/invalidation_accumulator.h') diff --git a/src/video_core/invalidation_accumulator.h b/src/video_core/invalidation_accumulator.h index 42420e31c..2c2aaf7bb 100644 --- a/src/video_core/invalidation_accumulator.h +++ b/src/video_core/invalidation_accumulator.h @@ -3,6 +3,7 @@ #pragma once +#include #include #include "common/common_types.h" @@ -26,8 +27,8 @@ public: if (address >= start_address && address + size <= last_collection) [[likely]] { return; } - size = (address + size + atomicy_side_mask) & atomicy_mask - address; - address = address & atomicy_mask; + size = ((address + size + atomicity_size_mask) & atomicity_mask) - address; + address = address & atomicity_mask; if (!has_collected) [[unlikely]] { reset_values(); has_collected = true; @@ -64,10 +65,10 @@ public: } private: - static constexpr size_t atomicy_bits = 5; - static constexpr size_t atomicy_size = 1ULL << atomicy_bits; - static constexpr size_t atomicy_side_mask = atomicy_size - 1; - static constexpr size_t atomicy_mask = ~atomicy_side_mask; + static constexpr size_t atomicity_bits = 5; + static constexpr size_t atomicity_size = 1ULL << atomicity_bits; + static constexpr size_t atomicity_size_mask = atomicity_size - 1; + static constexpr size_t atomicity_mask = ~atomicity_size_mask; GPUVAddr start_address{}; GPUVAddr last_collection{}; size_t accumulated_size{}; -- cgit v1.2.3