image_base.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <array>
  5. #include <optional>
  6. #include <vector>
  7. #include "common/common_funcs.h"
  8. #include "common/common_types.h"
  9. #include "video_core/texture_cache/image_info.h"
  10. #include "video_core/texture_cache/image_view_info.h"
  11. #include "video_core/texture_cache/types.h"
  12. namespace VideoCommon {
  13. enum class ImageFlagBits : u32 {
  14. AcceleratedUpload = 1 << 0, ///< Upload can be accelerated in the GPU
  15. Converted = 1 << 1, ///< Guest format is not supported natively and it has to be converted
  16. CpuModified = 1 << 2, ///< Contents have been modified from the CPU
  17. GpuModified = 1 << 3, ///< Contents have been modified from the GPU
  18. Tracked = 1 << 4, ///< Writes and reads are being hooked from the CPU JIT
  19. Strong = 1 << 5, ///< Exists in the image table, the dimensions are can be trusted
  20. Registered = 1 << 6, ///< True when the image is registered
  21. Picked = 1 << 7, ///< Temporary flag to mark the image as picked
  22. Remapped = 1 << 8, ///< Image has been remapped.
  23. Sparse = 1 << 9, ///< Image has non continous submemory.
  24. // Garbage Collection Flags
  25. BadOverlap = 1 << 10, ///< This image overlaps other but doesn't fit, has higher
  26. ///< garbage collection priority
  27. Alias = 1 << 11, ///< This image has aliases and has priority on garbage
  28. ///< collection
  29. CostlyLoad = 1 << 12, ///< Protected from low-tier GC as it is costly to load back.
  30. // Rescaler
  31. Rescaled = 1 << 13,
  32. CheckingRescalable = 1 << 14,
  33. IsRescalable = 1 << 15,
  34. AsynchronousDecode = 1 << 16,
  35. IsDecoding = 1 << 17, ///< Is currently being decoded asynchornously.
  36. };
  37. DECLARE_ENUM_FLAG_OPERATORS(ImageFlagBits)
  38. struct ImageViewInfo;
  39. struct AliasedImage {
  40. std::vector<ImageCopy> copies;
  41. ImageId id;
  42. };
  43. struct NullImageParams {};
  44. struct ImageBase {
  45. explicit ImageBase(const ImageInfo& info, GPUVAddr gpu_addr, VAddr cpu_addr);
  46. explicit ImageBase(const NullImageParams&);
  47. [[nodiscard]] std::optional<SubresourceBase> TryFindBase(GPUVAddr other_addr) const noexcept;
  48. [[nodiscard]] ImageViewId FindView(const ImageViewInfo& view_info) const noexcept;
  49. void InsertView(const ImageViewInfo& view_info, ImageViewId image_view_id);
  50. [[nodiscard]] bool IsSafeDownload() const noexcept;
  51. [[nodiscard]] bool Overlaps(VAddr overlap_cpu_addr, size_t overlap_size) const noexcept {
  52. const VAddr overlap_end = overlap_cpu_addr + overlap_size;
  53. return cpu_addr < overlap_end && overlap_cpu_addr < cpu_addr_end;
  54. }
  55. [[nodiscard]] bool OverlapsGPU(GPUVAddr overlap_gpu_addr, size_t overlap_size) const noexcept {
  56. const VAddr overlap_end = overlap_gpu_addr + overlap_size;
  57. const GPUVAddr gpu_addr_end = gpu_addr + guest_size_bytes;
  58. return gpu_addr < overlap_end && overlap_gpu_addr < gpu_addr_end;
  59. }
  60. void CheckBadOverlapState();
  61. void CheckAliasState();
  62. bool HasScaled() const {
  63. return has_scaled;
  64. }
  65. ImageInfo info;
  66. u32 guest_size_bytes = 0;
  67. u32 unswizzled_size_bytes = 0;
  68. u32 converted_size_bytes = 0;
  69. u32 scale_rating = 0;
  70. u64 scale_tick = 0;
  71. bool has_scaled = false;
  72. size_t channel = 0;
  73. ImageFlagBits flags = ImageFlagBits::CpuModified;
  74. GPUVAddr gpu_addr = 0;
  75. VAddr cpu_addr = 0;
  76. VAddr cpu_addr_end = 0;
  77. u64 modification_tick = 0;
  78. size_t lru_index = SIZE_MAX;
  79. std::array<u32, MAX_MIP_LEVELS> mip_level_offsets{};
  80. std::vector<ImageViewInfo> image_view_infos;
  81. std::vector<ImageViewId> image_view_ids;
  82. std::vector<u32> slice_offsets;
  83. std::vector<SubresourceBase> slice_subresources;
  84. std::vector<AliasedImage> aliased_images;
  85. std::vector<ImageId> overlapping_images;
  86. ImageMapId map_view_id{};
  87. };
  88. struct ImageMapView {
  89. explicit ImageMapView(GPUVAddr gpu_addr, VAddr cpu_addr, size_t size, ImageId image_id);
  90. [[nodiscard]] bool Overlaps(VAddr overlap_cpu_addr, size_t overlap_size) const noexcept {
  91. const VAddr overlap_end = overlap_cpu_addr + overlap_size;
  92. const VAddr cpu_addr_end = cpu_addr + size;
  93. return cpu_addr < overlap_end && overlap_cpu_addr < cpu_addr_end;
  94. }
  95. [[nodiscard]] bool OverlapsGPU(GPUVAddr overlap_gpu_addr, size_t overlap_size) const noexcept {
  96. const GPUVAddr overlap_end = overlap_gpu_addr + overlap_size;
  97. const GPUVAddr gpu_addr_end = gpu_addr + size;
  98. return gpu_addr < overlap_end && overlap_gpu_addr < gpu_addr_end;
  99. }
  100. GPUVAddr gpu_addr;
  101. VAddr cpu_addr;
  102. size_t size;
  103. ImageId image_id;
  104. bool picked{};
  105. };
  106. struct ImageAllocBase {
  107. std::vector<ImageId> images;
  108. };
  109. void AddImageAlias(ImageBase& lhs, ImageBase& rhs, ImageId lhs_id, ImageId rhs_id);
  110. } // namespace VideoCommon