invalidation_accumulator.h 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <utility>
  5. #include <vector>
  6. #include "common/common_types.h"
  7. namespace VideoCommon {
  8. class InvalidationAccumulator {
  9. public:
  10. InvalidationAccumulator() = default;
  11. ~InvalidationAccumulator() = default;
  12. void Add(GPUVAddr address, size_t size) {
  13. const auto reset_values = [&]() {
  14. if (has_collected) {
  15. buffer.emplace_back(start_address, accumulated_size);
  16. }
  17. start_address = address;
  18. accumulated_size = size;
  19. last_collection = start_address + size;
  20. };
  21. if (address >= start_address && address + size <= last_collection) [[likely]] {
  22. return;
  23. }
  24. size = ((address + size + atomicity_size_mask) & atomicity_mask) - address;
  25. address = address & atomicity_mask;
  26. if (!has_collected) [[unlikely]] {
  27. reset_values();
  28. has_collected = true;
  29. return;
  30. }
  31. if (address != last_collection) [[unlikely]] {
  32. reset_values();
  33. return;
  34. }
  35. accumulated_size += size;
  36. last_collection += size;
  37. }
  38. void Clear() {
  39. buffer.clear();
  40. start_address = 0;
  41. last_collection = 0;
  42. has_collected = false;
  43. }
  44. bool AnyAccumulated() const {
  45. return has_collected;
  46. }
  47. template <typename Func>
  48. void Callback(Func&& func) {
  49. if (!has_collected) {
  50. return;
  51. }
  52. buffer.emplace_back(start_address, accumulated_size);
  53. for (auto& [address, size] : buffer) {
  54. func(address, size);
  55. }
  56. }
  57. private:
  58. static constexpr size_t atomicity_bits = 5;
  59. static constexpr size_t atomicity_size = 1ULL << atomicity_bits;
  60. static constexpr size_t atomicity_size_mask = atomicity_size - 1;
  61. static constexpr size_t atomicity_mask = ~atomicity_size_mask;
  62. GPUVAddr start_address{};
  63. GPUVAddr last_collection{};
  64. size_t accumulated_size{};
  65. bool has_collected{};
  66. std::vector<std::pair<VAddr, size_t>> buffer;
  67. };
  68. } // namespace VideoCommon