buffer_base.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-3.0-or-later
  3. #pragma once
  4. #include <algorithm>
  5. #include <bit>
  6. #include <limits>
  7. #include <utility>
  8. #include "common/alignment.h"
  9. #include "common/common_funcs.h"
  10. #include "common/common_types.h"
  11. #include "video_core/buffer_cache/word_manager.h"
  12. namespace VideoCommon {
  13. enum class BufferFlagBits {
  14. Picked = 1 << 0,
  15. CachedWrites = 1 << 1,
  16. PreemtiveDownload = 1 << 2,
  17. };
  18. DECLARE_ENUM_FLAG_OPERATORS(BufferFlagBits)
  19. /// Tag for creating null buffers with no storage or size
  20. struct NullBufferParams {};
  21. /**
  22. * Range tracking buffer container.
  23. *
  24. * It keeps track of the modified CPU and GPU ranges on a CPU page granularity, notifying the given
  25. * rasterizer about state changes in the tracking behavior of the buffer.
  26. *
  27. * The buffer size and address is forcefully aligned to CPU page boundaries.
  28. */
  29. class BufferBase {
  30. public:
  31. static constexpr u64 BASE_PAGE_BITS = 16;
  32. static constexpr u64 BASE_PAGE_SIZE = 1ULL << BASE_PAGE_BITS;
  33. explicit BufferBase(VAddr cpu_addr_, u64 size_bytes_)
  34. : cpu_addr{cpu_addr_}, size_bytes{size_bytes_} {}
  35. explicit BufferBase(NullBufferParams) {}
  36. BufferBase& operator=(const BufferBase&) = delete;
  37. BufferBase(const BufferBase&) = delete;
  38. BufferBase& operator=(BufferBase&&) = default;
  39. BufferBase(BufferBase&&) = default;
  40. /// Mark buffer as picked
  41. void Pick() noexcept {
  42. flags |= BufferFlagBits::Picked;
  43. }
  44. void MarkPreemtiveDownload() noexcept {
  45. flags |= BufferFlagBits::PreemtiveDownload;
  46. }
  47. /// Unmark buffer as picked
  48. void Unpick() noexcept {
  49. flags &= ~BufferFlagBits::Picked;
  50. }
  51. /// Increases the likeliness of this being a stream buffer
  52. void IncreaseStreamScore(int score) noexcept {
  53. stream_score += score;
  54. }
  55. /// Returns the likeliness of this being a stream buffer
  56. [[nodiscard]] int StreamScore() const noexcept {
  57. return stream_score;
  58. }
  59. /// Returns true when vaddr -> vaddr+size is fully contained in the buffer
  60. [[nodiscard]] bool IsInBounds(VAddr addr, u64 size) const noexcept {
  61. return addr >= cpu_addr && addr + size <= cpu_addr + SizeBytes();
  62. }
  63. /// Returns true if the buffer has been marked as picked
  64. [[nodiscard]] bool IsPicked() const noexcept {
  65. return True(flags & BufferFlagBits::Picked);
  66. }
  67. /// Returns true when the buffer has pending cached writes
  68. [[nodiscard]] bool HasCachedWrites() const noexcept {
  69. return True(flags & BufferFlagBits::CachedWrites);
  70. }
  71. bool IsPreemtiveDownload() const noexcept {
  72. return True(flags & BufferFlagBits::PreemtiveDownload);
  73. }
  74. /// Returns the base CPU address of the buffer
  75. [[nodiscard]] VAddr CpuAddr() const noexcept {
  76. return cpu_addr;
  77. }
  78. /// Returns the offset relative to the given CPU address
  79. /// @pre IsInBounds returns true
  80. [[nodiscard]] u32 Offset(VAddr other_cpu_addr) const noexcept {
  81. return static_cast<u32>(other_cpu_addr - cpu_addr);
  82. }
  83. size_t getLRUID() const noexcept {
  84. return lru_id;
  85. }
  86. void setLRUID(size_t lru_id_) {
  87. lru_id = lru_id_;
  88. }
  89. size_t SizeBytes() const {
  90. return size_bytes;
  91. }
  92. private:
  93. VAddr cpu_addr = 0;
  94. BufferFlagBits flags{};
  95. int stream_score = 0;
  96. size_t lru_id = SIZE_MAX;
  97. size_t size_bytes = 0;
  98. };
  99. } // namespace VideoCommon