virtual_buffer.h 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. // Copyright 2020 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <type_traits>
  6. #include <utility>
  7. namespace Common {
  8. void* AllocateMemoryPages(std::size_t size) noexcept;
  9. void FreeMemoryPages(void* base, std::size_t size) noexcept;
  10. template <typename T>
  11. class VirtualBuffer final {
  12. public:
  13. static_assert(
  14. std::is_trivially_constructible_v<T>,
  15. "T must be trivially constructible, as non-trivial constructors will not be executed "
  16. "with the current allocator");
  17. constexpr VirtualBuffer() = default;
  18. explicit VirtualBuffer(std::size_t count) : alloc_size{count * sizeof(T)} {
  19. base_ptr = reinterpret_cast<T*>(AllocateMemoryPages(alloc_size));
  20. }
  21. ~VirtualBuffer() noexcept {
  22. FreeMemoryPages(base_ptr, alloc_size);
  23. }
  24. VirtualBuffer(const VirtualBuffer&) = delete;
  25. VirtualBuffer& operator=(const VirtualBuffer&) = delete;
  26. VirtualBuffer(VirtualBuffer&& other) noexcept
  27. : alloc_size{std::exchange(other.alloc_size, 0)}, base_ptr{std::exchange(other.base_ptr),
  28. nullptr} {}
  29. VirtualBuffer& operator=(VirtualBuffer&& other) noexcept {
  30. alloc_size = std::exchange(other.alloc_size, 0);
  31. base_ptr = std::exchange(other.base_ptr, nullptr);
  32. return *this;
  33. }
  34. void resize(std::size_t count) {
  35. FreeMemoryPages(base_ptr, alloc_size);
  36. alloc_size = count * sizeof(T);
  37. base_ptr = reinterpret_cast<T*>(AllocateMemoryPages(alloc_size));
  38. }
  39. [[nodiscard]] constexpr const T& operator[](std::size_t index) const {
  40. return base_ptr[index];
  41. }
  42. [[nodiscard]] constexpr T& operator[](std::size_t index) {
  43. return base_ptr[index];
  44. }
  45. [[nodiscard]] constexpr T* data() {
  46. return base_ptr;
  47. }
  48. [[nodiscard]] constexpr const T* data() const {
  49. return base_ptr;
  50. }
  51. [[nodiscard]] constexpr std::size_t size() const {
  52. return alloc_size / sizeof(T);
  53. }
  54. private:
  55. std::size_t alloc_size{};
  56. T* base_ptr{};
  57. };
  58. } // namespace Common