miroir de https://git.suyu.dev/suyu/suyu.git
258 lignes
7.3 KiB
C++
258 lignes
7.3 KiB
C++
// SPDX-FileCopyrightText: Copyright 2024 suyu Emulator Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#pragma once
|
|
|
|
#include <span>
|
|
|
|
#include "mtl_staging_buffer_pool.h"
|
|
#include "video_core/texture_cache/texture_cache_base.h"
|
|
|
|
#include "shader_recompiler/shader_info.h"
|
|
#include "video_core/renderer_metal/mtl_staging_buffer_pool.h"
|
|
#include "video_core/renderer_metal/objc_bridge.h"
|
|
#include "video_core/texture_cache/image_view_base.h"
|
|
|
|
namespace Settings {
|
|
struct ResolutionScalingInfo;
|
|
}
|
|
|
|
namespace Metal {
|
|
|
|
using Common::SlotVector;
|
|
using VideoCommon::ImageId;
|
|
using VideoCommon::NUM_RT;
|
|
using VideoCommon::Region2D;
|
|
using VideoCommon::RenderTargets;
|
|
using VideoCore::Surface::PixelFormat;
|
|
|
|
class CommandRecorder;
|
|
class Device;
|
|
class Image;
|
|
class ImageView;
|
|
class Framebuffer;
|
|
|
|
class TextureCacheRuntime {
|
|
public:
|
|
explicit TextureCacheRuntime(const Device& device_, CommandRecorder& command_recorder_,
|
|
StagingBufferPool& staging_buffer_pool_);
|
|
|
|
// TODO: implement
|
|
void Finish() {}
|
|
|
|
void TickFrame();
|
|
|
|
StagingBufferRef UploadStagingBuffer(size_t size);
|
|
|
|
StagingBufferRef DownloadStagingBuffer(size_t size, bool deferred = false);
|
|
|
|
void FreeDeferredStagingBuffer(StagingBufferRef& ref);
|
|
|
|
bool CanUploadMSAA() const noexcept {
|
|
return true;
|
|
}
|
|
|
|
u64 GetDeviceLocalMemory() const {
|
|
return 0;
|
|
}
|
|
|
|
u64 GetDeviceMemoryUsage() const {
|
|
return 0;
|
|
}
|
|
|
|
bool CanReportMemoryUsage() const {
|
|
return false;
|
|
}
|
|
|
|
// TODO: implement
|
|
void BlitImage(Framebuffer* dst_framebuffer, ImageView& dst, ImageView& src,
|
|
const Region2D& dst_region, const Region2D& src_region,
|
|
Tegra::Engines::Fermi2D::Filter filter,
|
|
Tegra::Engines::Fermi2D::Operation operation) {}
|
|
|
|
// TODO: implement
|
|
void CopyImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies) {}
|
|
|
|
// TODO: implement
|
|
void CopyImageMSAA(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies) {}
|
|
|
|
bool ShouldReinterpret(Image& dst, Image& src) {
|
|
// HACK
|
|
return false;
|
|
}
|
|
|
|
// TODO: implement
|
|
void ReinterpretImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies) {}
|
|
|
|
// TODO: implement
|
|
void ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view) {}
|
|
|
|
// TODO: implement
|
|
void InsertUploadMemoryBarrier() {}
|
|
|
|
void TransitionImageLayout(Image& image) {}
|
|
|
|
// TODO: implement
|
|
void AccelerateImageUpload(Image&, const StagingBufferRef&,
|
|
std::span<const VideoCommon::SwizzleParameters>) {}
|
|
|
|
bool HasNativeBgr() const noexcept {
|
|
return true;
|
|
}
|
|
|
|
bool HasBrokenTextureViewFormats() const noexcept {
|
|
return false;
|
|
}
|
|
|
|
// TODO: implement
|
|
void BarrierFeedbackLoop() {}
|
|
|
|
const Device& device;
|
|
CommandRecorder& command_recorder;
|
|
StagingBufferPool& staging_buffer_pool;
|
|
const Settings::ResolutionScalingInfo& resolution;
|
|
};
|
|
|
|
class Image : public VideoCommon::ImageBase {
|
|
public:
|
|
explicit Image(TextureCacheRuntime& runtime, const VideoCommon::ImageInfo& info,
|
|
GPUVAddr gpu_addr, VAddr cpu_addr);
|
|
explicit Image(const VideoCommon::NullImageParams&);
|
|
|
|
~Image();
|
|
|
|
Image(const Image&) = delete;
|
|
Image& operator=(const Image&) = delete;
|
|
|
|
Image(Image&&) = default;
|
|
Image& operator=(Image&&) = default;
|
|
|
|
void UploadMemory(MTLBuffer_t buffer, size_t offset,
|
|
std::span<const VideoCommon::BufferImageCopy> copies);
|
|
|
|
void UploadMemory(const StagingBufferRef& map,
|
|
std::span<const VideoCommon::BufferImageCopy> copies);
|
|
|
|
void DownloadMemory(MTLBuffer_t buffer, size_t offset,
|
|
std::span<const VideoCommon::BufferImageCopy> copies);
|
|
|
|
// For some reason, this function cannot be defined in the .mm file since it would report
|
|
// undefined symbols
|
|
void DownloadMemory(std::span<MTLBuffer_t> buffers, std::span<size_t> offsets,
|
|
std::span<const VideoCommon::BufferImageCopy> copies) {
|
|
// TODO: implement
|
|
}
|
|
|
|
void DownloadMemory(const StagingBufferRef& map,
|
|
std::span<const VideoCommon::BufferImageCopy> copies);
|
|
|
|
bool IsRescaled() const {
|
|
return rescaled;
|
|
}
|
|
|
|
bool ScaleUp(bool ignore = false) {
|
|
// HACK
|
|
return true;
|
|
}
|
|
|
|
bool ScaleDown(bool ignore = false) {
|
|
// HACK
|
|
return true;
|
|
}
|
|
|
|
MTLTexture_t GetHandle() const noexcept {
|
|
return texture;
|
|
}
|
|
|
|
private:
|
|
MTLTexture_t texture = nil;
|
|
bool initialized = false;
|
|
|
|
bool rescaled = false;
|
|
};
|
|
|
|
class ImageView : public VideoCommon::ImageViewBase {
|
|
public:
|
|
explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageViewInfo&, ImageId, Image&);
|
|
explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageViewInfo&, ImageId, Image&,
|
|
const SlotVector<Image>&);
|
|
explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageInfo&,
|
|
const VideoCommon::ImageViewInfo&, GPUVAddr);
|
|
explicit ImageView(TextureCacheRuntime&, const VideoCommon::NullImageViewParams&);
|
|
|
|
~ImageView();
|
|
|
|
ImageView(const ImageView&) = delete;
|
|
ImageView& operator=(const ImageView&) = delete;
|
|
|
|
ImageView(ImageView&&) = default;
|
|
ImageView& operator=(ImageView&&) = default;
|
|
|
|
MTLTexture_t GetHandle() const noexcept {
|
|
return texture;
|
|
}
|
|
|
|
private:
|
|
MTLTexture_t texture;
|
|
};
|
|
|
|
class ImageAlloc : public VideoCommon::ImageAllocBase {};
|
|
|
|
class Sampler {
|
|
public:
|
|
explicit Sampler(TextureCacheRuntime&, const Tegra::Texture::TSCEntry&);
|
|
|
|
MTLSamplerState_t GetHandle() const noexcept {
|
|
return sampler_state;
|
|
}
|
|
|
|
private:
|
|
MTLSamplerState_t sampler_state;
|
|
};
|
|
|
|
class Framebuffer {
|
|
public:
|
|
explicit Framebuffer(TextureCacheRuntime& runtime, std::span<ImageView*, NUM_RT> color_buffers,
|
|
ImageView* depth_buffer, const VideoCommon::RenderTargets& key);
|
|
~Framebuffer();
|
|
|
|
Framebuffer(const Framebuffer&) = delete;
|
|
Framebuffer& operator=(const Framebuffer&) = delete;
|
|
|
|
Framebuffer(Framebuffer&&) = default;
|
|
Framebuffer& operator=(Framebuffer&&) = default;
|
|
|
|
void CreateRenderPassDescriptor(TextureCacheRuntime& runtime,
|
|
std::span<ImageView*, NUM_RT> color_buffers,
|
|
ImageView* depth_buffer, bool is_rescaled, size_t width,
|
|
size_t height);
|
|
|
|
MTLRenderPassDescriptor* GetHandle() const noexcept {
|
|
return render_pass;
|
|
}
|
|
|
|
private:
|
|
MTLRenderPassDescriptor* render_pass{};
|
|
};
|
|
|
|
struct TextureCacheParams {
|
|
static constexpr bool ENABLE_VALIDATION = true;
|
|
static constexpr bool FRAMEBUFFER_BLITS = false;
|
|
static constexpr bool HAS_EMULATED_COPIES = false;
|
|
static constexpr bool HAS_DEVICE_MEMORY_INFO = true;
|
|
static constexpr bool IMPLEMENTS_ASYNC_DOWNLOADS = true;
|
|
|
|
using Runtime = Metal::TextureCacheRuntime;
|
|
using Image = Metal::Image;
|
|
using ImageAlloc = Metal::ImageAlloc;
|
|
using ImageView = Metal::ImageView;
|
|
using Sampler = Metal::Sampler;
|
|
using Framebuffer = Metal::Framebuffer;
|
|
using AsyncBuffer = Metal::StagingBufferRef;
|
|
using BufferType = MTLBuffer_t;
|
|
};
|
|
|
|
using TextureCache = VideoCommon::TextureCache<TextureCacheParams>;
|
|
|
|
} // namespace Metal
|