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
|
|
|
|
|
|
|
|
#include <array>
|
|
|
|
#include <functional>
|
|
|
|
#include <utility>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
#include <glad/glad.h>
|
|
|
|
|
|
|
|
#include "common/common_types.h"
|
|
|
|
#include "video_core/engines/shader_bytecode.h"
|
|
|
|
#include "video_core/texture_cache.h"
|
|
|
|
|
|
|
|
namespace OpenGL {
|
|
|
|
|
|
|
|
using VideoCommon::SurfaceParams;
|
|
|
|
using VideoCommon::ViewKey;
|
|
|
|
using VideoCore::Surface::ComponentType;
|
|
|
|
using VideoCore::Surface::PixelFormat;
|
|
|
|
using VideoCore::Surface::SurfaceTarget;
|
|
|
|
using VideoCore::Surface::SurfaceType;
|
|
|
|
|
|
|
|
class CachedSurfaceView;
|
|
|
|
class CachedSurface;
|
|
|
|
|
|
|
|
using TextureCacheBase = VideoCommon::TextureCacheContextless<CachedSurface, CachedSurfaceView>;
|
|
|
|
|
|
|
|
class CachedSurface final : public VideoCommon::SurfaceBaseContextless<CachedSurfaceView> {
|
|
|
|
friend CachedSurfaceView;
|
|
|
|
|
|
|
|
public:
|
|
|
|
explicit CachedSurface(const SurfaceParams& params);
|
|
|
|
~CachedSurface();
|
|
|
|
|
|
|
|
void LoadBuffer();
|
|
|
|
|
2019-04-14 06:44:16 +02:00
|
|
|
GLenum GetTarget() const {
|
|
|
|
return target;
|
|
|
|
}
|
|
|
|
|
2019-04-11 22:14:55 +02:00
|
|
|
GLuint GetTexture() const {
|
|
|
|
return texture.handle;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
std::unique_ptr<CachedSurfaceView> CreateView(const ViewKey& view_key);
|
|
|
|
|
|
|
|
void FlushBufferImpl();
|
|
|
|
|
|
|
|
void UploadTextureImpl();
|
|
|
|
|
|
|
|
private:
|
|
|
|
void UploadTextureMipmap(u32 level);
|
|
|
|
|
|
|
|
GLenum internal_format{};
|
|
|
|
GLenum format{};
|
|
|
|
GLenum type{};
|
|
|
|
bool is_compressed{};
|
2019-04-14 06:44:16 +02:00
|
|
|
GLenum target{};
|
2019-04-11 22:14:55 +02:00
|
|
|
|
|
|
|
OGLTexture texture;
|
|
|
|
|
|
|
|
std::vector<u8> staging_buffer;
|
|
|
|
u8* host_ptr{};
|
|
|
|
};
|
|
|
|
|
|
|
|
class CachedSurfaceView final {
|
|
|
|
public:
|
|
|
|
explicit CachedSurfaceView(CachedSurface& surface, ViewKey key);
|
|
|
|
~CachedSurfaceView();
|
|
|
|
|
2019-04-14 23:16:27 +02:00
|
|
|
/// Attaches this texture view to the current bound GL_DRAW_FRAMEBUFFER
|
|
|
|
void Attach(GLenum attachment) const;
|
2019-04-11 22:14:55 +02:00
|
|
|
|
|
|
|
GLuint GetTexture(Tegra::Shader::TextureType texture_type, bool is_array,
|
|
|
|
Tegra::Texture::SwizzleSource x_source,
|
|
|
|
Tegra::Texture::SwizzleSource y_source,
|
|
|
|
Tegra::Texture::SwizzleSource z_source,
|
|
|
|
Tegra::Texture::SwizzleSource w_source);
|
|
|
|
|
|
|
|
void MarkAsModified(bool is_modified) {
|
|
|
|
surface.MarkAsModified(is_modified);
|
|
|
|
}
|
|
|
|
|
|
|
|
const SurfaceParams& GetSurfaceParams() const {
|
|
|
|
return params;
|
|
|
|
}
|
|
|
|
|
2019-04-15 21:17:27 +02:00
|
|
|
u32 GetWidth() const {
|
|
|
|
return params.GetMipWidth(GetBaseLevel());
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 GetHeight() const {
|
|
|
|
return params.GetMipHeight(GetBaseLevel());
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 GetDepth() const {
|
|
|
|
return params.GetMipDepth(GetBaseLevel());
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 GetBaseLayer() const {
|
|
|
|
return key.base_layer;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 GetNumLayers() const {
|
|
|
|
return key.num_layers;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 GetBaseLevel() const {
|
|
|
|
return key.base_level;
|
|
|
|
}
|
|
|
|
|
|
|
|
u32 GetNumLevels() const {
|
|
|
|
return key.num_levels;
|
|
|
|
}
|
|
|
|
|
2019-04-11 22:14:55 +02:00
|
|
|
private:
|
|
|
|
struct TextureView {
|
|
|
|
OGLTexture texture;
|
|
|
|
std::array<Tegra::Texture::SwizzleSource, 4> swizzle{
|
|
|
|
Tegra::Texture::SwizzleSource::R, Tegra::Texture::SwizzleSource::G,
|
|
|
|
Tegra::Texture::SwizzleSource::B, Tegra::Texture::SwizzleSource::A};
|
|
|
|
};
|
|
|
|
|
|
|
|
void ApplySwizzle(TextureView& texture_view, Tegra::Texture::SwizzleSource x_source,
|
|
|
|
Tegra::Texture::SwizzleSource y_source,
|
|
|
|
Tegra::Texture::SwizzleSource z_source,
|
|
|
|
Tegra::Texture::SwizzleSource w_source);
|
|
|
|
|
|
|
|
TextureView CreateTextureView(GLenum target) const;
|
|
|
|
|
|
|
|
std::pair<std::reference_wrapper<TextureView>, GLenum> GetTextureView(
|
|
|
|
Tegra::Shader::TextureType texture_type, bool is_array);
|
|
|
|
|
|
|
|
CachedSurface& surface;
|
|
|
|
const ViewKey key;
|
|
|
|
const SurfaceParams params;
|
|
|
|
|
|
|
|
TextureView texture_view_1d;
|
|
|
|
TextureView texture_view_1d_array;
|
|
|
|
TextureView texture_view_2d;
|
|
|
|
TextureView texture_view_2d_array;
|
|
|
|
TextureView texture_view_3d;
|
|
|
|
TextureView texture_view_cube;
|
|
|
|
TextureView texture_view_cube_array;
|
|
|
|
};
|
|
|
|
|
|
|
|
class TextureCacheOpenGL final : public TextureCacheBase {
|
|
|
|
public:
|
|
|
|
explicit TextureCacheOpenGL(Core::System& system, VideoCore::RasterizerInterface& rasterizer);
|
|
|
|
~TextureCacheOpenGL();
|
|
|
|
|
|
|
|
protected:
|
|
|
|
CachedSurfaceView* TryFastGetSurfaceView(VAddr cpu_addr, u8* host_ptr,
|
2019-04-15 21:17:27 +02:00
|
|
|
const SurfaceParams& new_params,
|
|
|
|
bool preserve_contents,
|
2019-04-11 22:14:55 +02:00
|
|
|
const std::vector<CachedSurface*>& overlaps);
|
|
|
|
|
|
|
|
std::unique_ptr<CachedSurface> CreateSurface(const SurfaceParams& params);
|
2019-04-14 06:44:16 +02:00
|
|
|
|
|
|
|
private:
|
|
|
|
CachedSurfaceView* SurfaceCopy(VAddr cpu_addr, u8* host_ptr, const SurfaceParams& new_params,
|
|
|
|
CachedSurface* old_surface, const SurfaceParams& old_params);
|
2019-04-15 21:17:27 +02:00
|
|
|
|
|
|
|
CachedSurfaceView* TryCopyAsViews(VAddr cpu_addr, u8* host_ptr, const SurfaceParams& new_params,
|
|
|
|
const std::vector<CachedSurface*>& overlaps);
|
2019-04-11 22:14:55 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace OpenGL
|