// Copyright 2019 yuzu Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. #pragma once #include #include #include #include #include #include "common/common_types.h" #include "video_core/engines/shader_bytecode.h" #include "video_core/renderer_opengl/gl_resource_manager.h" #include "video_core/texture_cache/texture_cache.h" namespace OpenGL { using VideoCommon::SurfaceParams; using VideoCommon::ViewKey; class CachedSurfaceView; class CachedSurface; class TextureCacheOpenGL; using Surface = std::shared_ptr; using TextureCacheBase = VideoCommon::TextureCache; class CachedSurface final : public VideoCommon::SurfaceBase { friend CachedSurfaceView; public: explicit CachedSurface(TextureCacheOpenGL& texture_cache, const SurfaceParams& params); ~CachedSurface(); void UploadTexture(); void DownloadTexture(); GLenum GetTarget() const { return target; } GLuint GetTexture() const { return texture.handle; } protected: void DecorateSurfaceName(); std::unique_ptr CreateView(const ViewKey& view_key); private: void UploadTextureMipmap(u32 level); GLenum internal_format{}; GLenum format{}; GLenum type{}; bool is_compressed{}; GLenum target{}; OGLTexture texture; }; class CachedSurfaceView final { public: explicit CachedSurfaceView(CachedSurface& surface, ViewKey key); ~CachedSurfaceView(); /// Attaches this texture view to the current bound GL_DRAW_FRAMEBUFFER void Attach(GLenum attachment) const; 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; } 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; } private: struct TextureView { OGLTexture texture; std::array 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, 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(GPUVAddr gpu_addr, VAddr cpu_addr, u8* host_ptr, const SurfaceParams& new_params, bool preserve_contents, const std::vector& overlaps); Surface CreateSurface(const SurfaceParams& params); private: CachedSurfaceView* SurfaceCopy(GPUVAddr gpu_addr, VAddr cpu_addr, u8* host_ptr, const SurfaceParams& new_params, const Surface& old_surface, const SurfaceParams& old_params); CachedSurfaceView* TryCopyAsViews(GPUVAddr gpu_addr, VAddr cpu_addr, u8* host_ptr, const SurfaceParams& new_params, const std::vector& overlaps); }; } // namespace OpenGL