// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once #include #include #include #include #include "common/common_funcs.h" #include "common/common_types.h" #include "video_core/texture_cache/image_info.h" #include "video_core/texture_cache/image_view_info.h" #include "video_core/texture_cache/types.h" namespace VideoCommon { enum class ImageFlagBits : u32 { AcceleratedUpload = 1 << 0, ///< Upload can be accelerated in the GPU Converted = 1 << 1, ///< Guest format is not supported natively and it has to be converted CpuModified = 1 << 2, ///< Contents have been modified from the CPU GpuModified = 1 << 3, ///< Contents have been modified from the GPU Tracked = 1 << 4, ///< Writes and reads are being hooked from the CPU JIT Strong = 1 << 5, ///< Exists in the image table, the dimensions are can be trusted Registered = 1 << 6, ///< True when the image is registered Picked = 1 << 7, ///< Temporary flag to mark the image as picked Remapped = 1 << 8, ///< Image has been remapped. Sparse = 1 << 9, ///< Image has non continuous submemory. // Garbage Collection Flags BadOverlap = 1 << 10, ///< This image overlaps other but doesn't fit, has higher ///< garbage collection priority Alias = 1 << 11, ///< This image has aliases and has priority on garbage ///< collection CostlyLoad = 1 << 12, ///< Protected from low-tier GC as it is costly to load back. // Rescaler Rescaled = 1 << 13, CheckingRescalable = 1 << 14, IsRescalable = 1 << 15, AsynchronousDecode = 1 << 16, IsDecoding = 1 << 17, ///< Is currently being decoded asynchronously. }; DECLARE_ENUM_FLAG_OPERATORS(ImageFlagBits) struct ImageViewInfo; struct AliasedImage { std::vector copies; ImageId id; }; struct NullImageParams {}; struct ImageBase { explicit ImageBase(const ImageInfo& info, GPUVAddr gpu_addr, VAddr cpu_addr); explicit ImageBase(const NullImageParams&); [[nodiscard]] std::optional TryFindBase(GPUVAddr other_addr) const noexcept; [[nodiscard]] ImageViewId FindView(const ImageViewInfo& view_info) const noexcept; void InsertView(const ImageViewInfo& view_info, ImageViewId image_view_id); [[nodiscard]] bool IsSafeDownload() const noexcept; [[nodiscard]] bool Overlaps(VAddr overlap_cpu_addr, size_t overlap_size) const noexcept { const VAddr overlap_end = overlap_cpu_addr + overlap_size; return cpu_addr < overlap_end && overlap_cpu_addr < cpu_addr_end; } [[nodiscard]] bool OverlapsGPU(GPUVAddr overlap_gpu_addr, size_t overlap_size) const noexcept { const VAddr overlap_end = overlap_gpu_addr + overlap_size; const GPUVAddr gpu_addr_end = gpu_addr + guest_size_bytes; return gpu_addr < overlap_end && overlap_gpu_addr < gpu_addr_end; } void CheckBadOverlapState(); void CheckAliasState(); bool HasScaled() const { return has_scaled; } ImageInfo info; u32 guest_size_bytes = 0; u32 unswizzled_size_bytes = 0; u32 converted_size_bytes = 0; u32 scale_rating = 0; u64 scale_tick = 0; bool has_scaled = false; size_t channel = 0; ImageFlagBits flags = ImageFlagBits::CpuModified; GPUVAddr gpu_addr = 0; VAddr cpu_addr = 0; VAddr cpu_addr_end = 0; u64 modification_tick = 0; size_t lru_index = SIZE_MAX; std::array mip_level_offsets{}; std::vector image_view_infos; std::vector image_view_ids; boost::container::small_vector slice_offsets; boost::container::small_vector slice_subresources; std::vector aliased_images; std::vector overlapping_images; ImageMapId map_view_id{}; }; struct ImageMapView { explicit ImageMapView(GPUVAddr gpu_addr, VAddr cpu_addr, size_t size, ImageId image_id); [[nodiscard]] bool Overlaps(VAddr overlap_cpu_addr, size_t overlap_size) const noexcept { const VAddr overlap_end = overlap_cpu_addr + overlap_size; const VAddr cpu_addr_end = cpu_addr + size; return cpu_addr < overlap_end && overlap_cpu_addr < cpu_addr_end; } [[nodiscard]] bool OverlapsGPU(GPUVAddr overlap_gpu_addr, size_t overlap_size) const noexcept { const GPUVAddr overlap_end = overlap_gpu_addr + overlap_size; const GPUVAddr gpu_addr_end = gpu_addr + size; return gpu_addr < overlap_end && overlap_gpu_addr < gpu_addr_end; } GPUVAddr gpu_addr; VAddr cpu_addr; size_t size; ImageId image_id; bool picked{}; }; struct ImageAllocBase { std::vector images; }; bool AddImageAlias(ImageBase& lhs, ImageBase& rhs, ImageId lhs_id, ImageId rhs_id); } // namespace VideoCommon