141 lines
4.6 KiB
C++
141 lines
4.6 KiB
C++
// Copyright 2020 yuzu Emulator Project
|
|
// Licensed under GPLv2 or any later version
|
|
// Refer to the license.txt file included.
|
|
|
|
#pragma once
|
|
|
|
#include <array>
|
|
#include <optional>
|
|
#include <vector>
|
|
|
|
#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 continous 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
|
|
|
|
// Rescaler
|
|
Rescaled = 1 << 12,
|
|
CheckingRescalable = 1 << 13,
|
|
IsRescalable = 1 << 14,
|
|
};
|
|
DECLARE_ENUM_FLAG_OPERATORS(ImageFlagBits)
|
|
|
|
struct ImageViewInfo;
|
|
|
|
struct AliasedImage {
|
|
std::vector<ImageCopy> 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<SubresourceBase> 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;
|
|
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<u32, MAX_MIP_LEVELS> mip_level_offsets{};
|
|
|
|
std::vector<ImageViewInfo> image_view_infos;
|
|
std::vector<ImageViewId> image_view_ids;
|
|
|
|
std::vector<u32> slice_offsets;
|
|
std::vector<SubresourceBase> slice_subresources;
|
|
|
|
std::vector<AliasedImage> aliased_images;
|
|
std::vector<ImageId> 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<ImageId> images;
|
|
};
|
|
|
|
void AddImageAlias(ImageBase& lhs, ImageBase& rhs, ImageId lhs_id, ImageId rhs_id);
|
|
|
|
} // namespace VideoCommon
|