2019-04-11 22:14:55 +02:00
|
|
|
// Copyright 2019 yuzu Emulator Project
|
|
|
|
// Licensed under GPLv2 or any later version
|
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2019-06-24 07:01:44 +02:00
|
|
|
#include <memory>
|
2020-12-30 06:25:23 +01:00
|
|
|
#include <span>
|
2019-04-11 22:14:55 +02:00
|
|
|
|
|
|
|
#include <glad/glad.h>
|
|
|
|
|
2019-04-24 23:47:59 +02:00
|
|
|
#include "video_core/renderer_opengl/gl_resource_manager.h"
|
2020-12-30 06:25:23 +01:00
|
|
|
#include "video_core/renderer_opengl/util_shaders.h"
|
2019-04-25 18:41:57 +02:00
|
|
|
#include "video_core/texture_cache/texture_cache.h"
|
2019-04-11 22:14:55 +02:00
|
|
|
|
|
|
|
namespace OpenGL {
|
|
|
|
|
2020-12-30 06:25:23 +01:00
|
|
|
class Device;
|
|
|
|
class ProgramManager;
|
2019-12-29 01:45:56 +01:00
|
|
|
class StateTracker;
|
2019-04-11 22:14:55 +02:00
|
|
|
|
2020-12-30 06:25:23 +01:00
|
|
|
class Framebuffer;
|
|
|
|
class Image;
|
|
|
|
class ImageView;
|
|
|
|
class Sampler;
|
2019-04-11 22:14:55 +02:00
|
|
|
|
2020-12-30 06:25:23 +01:00
|
|
|
using VideoCommon::ImageId;
|
|
|
|
using VideoCommon::ImageViewId;
|
|
|
|
using VideoCommon::ImageViewType;
|
|
|
|
using VideoCommon::NUM_RT;
|
|
|
|
using VideoCommon::Offset2D;
|
|
|
|
using VideoCommon::RenderTargets;
|
2019-04-11 22:14:55 +02:00
|
|
|
|
2021-01-17 00:48:58 +01:00
|
|
|
struct ImageBufferMap {
|
2020-12-30 06:25:23 +01:00
|
|
|
~ImageBufferMap();
|
2019-04-25 18:41:57 +02:00
|
|
|
|
2021-01-17 00:48:58 +01:00
|
|
|
std::span<u8> mapped_span;
|
2021-01-16 20:20:18 +01:00
|
|
|
size_t offset = 0;
|
2020-12-30 06:25:23 +01:00
|
|
|
OGLSync* sync;
|
2021-01-17 00:48:58 +01:00
|
|
|
GLuint buffer;
|
2020-12-30 06:25:23 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
struct FormatProperties {
|
|
|
|
GLenum compatibility_class;
|
|
|
|
bool compatibility_by_size;
|
|
|
|
bool is_compressed;
|
|
|
|
};
|
|
|
|
|
|
|
|
class TextureCacheRuntime {
|
|
|
|
friend Framebuffer;
|
|
|
|
friend Image;
|
|
|
|
friend ImageView;
|
|
|
|
friend Sampler;
|
|
|
|
|
|
|
|
public:
|
|
|
|
explicit TextureCacheRuntime(const Device& device, ProgramManager& program_manager,
|
|
|
|
StateTracker& state_tracker);
|
|
|
|
~TextureCacheRuntime();
|
|
|
|
|
|
|
|
void Finish();
|
|
|
|
|
2021-01-17 00:48:58 +01:00
|
|
|
ImageBufferMap UploadStagingBuffer(size_t size);
|
2020-12-30 06:25:23 +01:00
|
|
|
|
2021-01-17 00:48:58 +01:00
|
|
|
ImageBufferMap DownloadStagingBuffer(size_t size);
|
2020-12-30 06:25:23 +01:00
|
|
|
|
|
|
|
void CopyImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies);
|
|
|
|
|
|
|
|
void ConvertImage(Framebuffer* dst, ImageView& dst_view, ImageView& src_view) {
|
|
|
|
UNIMPLEMENTED();
|
2020-03-15 00:24:54 +01:00
|
|
|
}
|
|
|
|
|
2020-12-30 06:25:23 +01:00
|
|
|
bool CanImageBeCopied(const Image& dst, const Image& src);
|
|
|
|
|
|
|
|
void EmulateCopyImage(Image& dst, Image& src, std::span<const VideoCommon::ImageCopy> copies);
|
|
|
|
|
|
|
|
void BlitFramebuffer(Framebuffer* dst, Framebuffer* src,
|
|
|
|
const std::array<Offset2D, 2>& dst_region,
|
|
|
|
const std::array<Offset2D, 2>& src_region,
|
|
|
|
Tegra::Engines::Fermi2D::Filter filter,
|
|
|
|
Tegra::Engines::Fermi2D::Operation operation);
|
2019-04-17 01:01:07 +02:00
|
|
|
|
2021-01-16 20:20:18 +01:00
|
|
|
void AccelerateImageUpload(Image& image, const ImageBufferMap& map,
|
2020-12-30 06:25:23 +01:00
|
|
|
std::span<const VideoCommon::SwizzleParameters> swizzles);
|
|
|
|
|
|
|
|
void InsertUploadMemoryBarrier();
|
|
|
|
|
|
|
|
FormatProperties FormatInfo(VideoCommon::ImageType type, GLenum internal_format) const;
|
2019-04-11 22:14:55 +02:00
|
|
|
|
2021-03-04 20:12:25 +01:00
|
|
|
bool HasNativeBgr() const noexcept {
|
|
|
|
// OpenGL does not have native support for the BGR internal format
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-01-04 05:54:54 +01:00
|
|
|
bool HasBrokenTextureViewFormats() const noexcept {
|
|
|
|
return has_broken_texture_view_formats;
|
|
|
|
}
|
|
|
|
|
2021-02-13 21:50:12 +01:00
|
|
|
bool HasNativeASTC() const noexcept;
|
|
|
|
|
2019-04-11 22:14:55 +02:00
|
|
|
private:
|
2020-12-30 06:25:23 +01:00
|
|
|
struct StagingBuffers {
|
|
|
|
explicit StagingBuffers(GLenum storage_flags_, GLenum map_flags_);
|
|
|
|
~StagingBuffers();
|
2019-04-11 22:14:55 +02:00
|
|
|
|
2020-12-30 06:25:23 +01:00
|
|
|
ImageBufferMap RequestMap(size_t requested_size, bool insert_fence);
|
2019-04-11 22:14:55 +02:00
|
|
|
|
2020-12-30 06:25:23 +01:00
|
|
|
size_t RequestBuffer(size_t requested_size);
|
|
|
|
|
|
|
|
std::optional<size_t> FindBuffer(size_t requested_size);
|
|
|
|
|
|
|
|
std::vector<OGLSync> syncs;
|
|
|
|
std::vector<OGLBuffer> buffers;
|
|
|
|
std::vector<u8*> maps;
|
|
|
|
std::vector<size_t> sizes;
|
|
|
|
GLenum storage_flags;
|
|
|
|
GLenum map_flags;
|
|
|
|
};
|
|
|
|
|
|
|
|
const Device& device;
|
|
|
|
StateTracker& state_tracker;
|
|
|
|
UtilShaders util_shaders;
|
|
|
|
|
|
|
|
std::array<std::unordered_map<GLenum, FormatProperties>, 3> format_properties;
|
2021-01-04 05:54:54 +01:00
|
|
|
bool has_broken_texture_view_formats = false;
|
2020-12-30 06:25:23 +01:00
|
|
|
|
|
|
|
StagingBuffers upload_buffers{GL_MAP_WRITE_BIT, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT};
|
|
|
|
StagingBuffers download_buffers{GL_MAP_READ_BIT, GL_MAP_READ_BIT};
|
|
|
|
|
|
|
|
OGLTexture null_image_1d_array;
|
|
|
|
OGLTexture null_image_cube_array;
|
|
|
|
OGLTexture null_image_3d;
|
|
|
|
OGLTexture null_image_rect;
|
|
|
|
OGLTextureView null_image_view_1d;
|
|
|
|
OGLTextureView null_image_view_2d;
|
|
|
|
OGLTextureView null_image_view_2d_array;
|
|
|
|
OGLTextureView null_image_view_cube;
|
|
|
|
|
|
|
|
std::array<GLuint, VideoCommon::NUM_IMAGE_VIEW_TYPES> null_image_views;
|
2019-04-11 22:14:55 +02:00
|
|
|
};
|
|
|
|
|
2020-12-30 06:25:23 +01:00
|
|
|
class Image : public VideoCommon::ImageBase {
|
|
|
|
friend ImageView;
|
|
|
|
|
2019-04-11 22:14:55 +02:00
|
|
|
public:
|
2020-12-30 06:25:23 +01:00
|
|
|
explicit Image(TextureCacheRuntime&, const VideoCommon::ImageInfo& info, GPUVAddr gpu_addr,
|
|
|
|
VAddr cpu_addr);
|
2019-04-11 22:14:55 +02:00
|
|
|
|
2021-01-16 20:20:18 +01:00
|
|
|
void UploadMemory(const ImageBufferMap& map,
|
2020-12-30 06:25:23 +01:00
|
|
|
std::span<const VideoCommon::BufferImageCopy> copies);
|
2019-04-11 22:14:55 +02:00
|
|
|
|
2021-01-16 20:20:18 +01:00
|
|
|
void UploadMemory(const ImageBufferMap& map, std::span<const VideoCommon::BufferCopy> copies);
|
2019-09-06 04:26:05 +02:00
|
|
|
|
2021-01-16 20:20:18 +01:00
|
|
|
void DownloadMemory(ImageBufferMap& map, std::span<const VideoCommon::BufferImageCopy> copies);
|
2019-09-06 04:26:05 +02:00
|
|
|
|
2021-02-13 19:27:50 +01:00
|
|
|
GLuint StorageHandle() noexcept;
|
|
|
|
|
2020-12-30 06:25:23 +01:00
|
|
|
GLuint Handle() const noexcept {
|
|
|
|
return texture.handle;
|
2019-09-06 04:26:05 +02:00
|
|
|
}
|
|
|
|
|
2020-12-30 06:25:23 +01:00
|
|
|
private:
|
|
|
|
void CopyBufferToImage(const VideoCommon::BufferImageCopy& copy, size_t buffer_offset);
|
|
|
|
|
|
|
|
void CopyImageToBuffer(const VideoCommon::BufferImageCopy& copy, size_t buffer_offset);
|
|
|
|
|
|
|
|
OGLTexture texture;
|
|
|
|
OGLBuffer buffer;
|
2021-02-13 19:27:50 +01:00
|
|
|
OGLTextureView store_view;
|
2020-12-30 06:25:23 +01:00
|
|
|
GLenum gl_internal_format = GL_NONE;
|
|
|
|
GLenum gl_format = GL_NONE;
|
|
|
|
GLenum gl_type = GL_NONE;
|
|
|
|
};
|
|
|
|
|
|
|
|
class ImageView : public VideoCommon::ImageViewBase {
|
|
|
|
friend Image;
|
|
|
|
|
|
|
|
public:
|
|
|
|
explicit ImageView(TextureCacheRuntime&, const VideoCommon::ImageViewInfo&, ImageId, Image&);
|
|
|
|
explicit ImageView(TextureCacheRuntime&, const VideoCommon::NullImageParams&);
|
|
|
|
|
|
|
|
[[nodiscard]] GLuint Handle(ImageViewType query_type) const noexcept {
|
|
|
|
return views[static_cast<size_t>(query_type)];
|
2019-04-11 22:14:55 +02:00
|
|
|
}
|
|
|
|
|
2020-12-30 06:25:23 +01:00
|
|
|
[[nodiscard]] GLuint DefaultHandle() const noexcept {
|
|
|
|
return default_handle;
|
2019-12-26 08:17:02 +01:00
|
|
|
}
|
|
|
|
|
2020-12-30 06:25:23 +01:00
|
|
|
[[nodiscard]] GLenum Format() const noexcept {
|
|
|
|
return internal_format;
|
2019-04-11 22:14:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2020-12-30 06:25:23 +01:00
|
|
|
void SetupView(const Device& device, Image& image, ImageViewType view_type, GLuint handle,
|
|
|
|
const VideoCommon::ImageViewInfo& info,
|
|
|
|
VideoCommon::SubresourceRange view_range);
|
|
|
|
|
|
|
|
std::array<GLuint, VideoCommon::NUM_IMAGE_VIEW_TYPES> views{};
|
|
|
|
std::vector<OGLTextureView> stored_views;
|
|
|
|
GLuint default_handle = 0;
|
|
|
|
GLenum internal_format = GL_NONE;
|
|
|
|
};
|
|
|
|
|
|
|
|
class ImageAlloc : public VideoCommon::ImageAllocBase {};
|
2019-04-11 22:14:55 +02:00
|
|
|
|
2020-12-30 06:25:23 +01:00
|
|
|
class Sampler {
|
|
|
|
public:
|
|
|
|
explicit Sampler(TextureCacheRuntime&, const Tegra::Texture::TSCEntry&);
|
2020-05-26 07:17:17 +02:00
|
|
|
|
2020-12-30 06:25:23 +01:00
|
|
|
GLuint Handle() const noexcept {
|
|
|
|
return sampler.handle;
|
|
|
|
}
|
2019-05-07 16:57:16 +02:00
|
|
|
|
2020-12-30 06:25:23 +01:00
|
|
|
private:
|
|
|
|
OGLSampler sampler;
|
2019-04-11 22:14:55 +02:00
|
|
|
};
|
|
|
|
|
2020-12-30 06:25:23 +01:00
|
|
|
class Framebuffer {
|
2019-04-11 22:14:55 +02:00
|
|
|
public:
|
2020-12-30 06:25:23 +01:00
|
|
|
explicit Framebuffer(TextureCacheRuntime&, std::span<ImageView*, NUM_RT> color_buffers,
|
|
|
|
ImageView* depth_buffer, const VideoCommon::RenderTargets& key);
|
2019-05-08 05:13:05 +02:00
|
|
|
|
2020-12-30 06:25:23 +01:00
|
|
|
[[nodiscard]] GLuint Handle() const noexcept {
|
|
|
|
return framebuffer.handle;
|
|
|
|
}
|
2019-05-08 05:13:05 +02:00
|
|
|
|
2020-12-30 06:25:23 +01:00
|
|
|
[[nodiscard]] GLbitfield BufferBits() const noexcept {
|
|
|
|
return buffer_bits;
|
|
|
|
}
|
2019-06-02 01:12:00 +02:00
|
|
|
|
2019-05-08 05:13:05 +02:00
|
|
|
private:
|
2020-12-30 06:25:23 +01:00
|
|
|
OGLFramebuffer framebuffer;
|
|
|
|
GLbitfield buffer_bits = GL_NONE;
|
|
|
|
};
|
2019-12-29 01:45:56 +01:00
|
|
|
|
2020-12-30 06:25:23 +01:00
|
|
|
struct TextureCacheParams {
|
|
|
|
static constexpr bool ENABLE_VALIDATION = true;
|
|
|
|
static constexpr bool FRAMEBUFFER_BLITS = true;
|
|
|
|
static constexpr bool HAS_EMULATED_COPIES = true;
|
|
|
|
|
|
|
|
using Runtime = OpenGL::TextureCacheRuntime;
|
|
|
|
using Image = OpenGL::Image;
|
|
|
|
using ImageAlloc = OpenGL::ImageAlloc;
|
|
|
|
using ImageView = OpenGL::ImageView;
|
|
|
|
using Sampler = OpenGL::Sampler;
|
|
|
|
using Framebuffer = OpenGL::Framebuffer;
|
2019-04-11 22:14:55 +02:00
|
|
|
};
|
|
|
|
|
2020-12-30 06:25:23 +01:00
|
|
|
using TextureCache = VideoCommon::TextureCache<TextureCacheParams>;
|
|
|
|
|
2019-04-11 22:14:55 +02:00
|
|
|
} // namespace OpenGL
|