diff options
author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2019-04-14 06:44:16 +0200 |
---|---|---|
committer | ReinUsesLisp <reinuseslisp@airmail.cc> | 2019-06-21 02:36:11 +0200 |
commit | fb94871791f78703737125cd2e5a13db8b7d1059 (patch) | |
tree | 774dc3eab1bea643568582fd96ea4d96c4bd824b /src/video_core/renderer_opengl | |
parent | gl_texture_cache: Initial implementation (diff) | |
download | yuzu-fb94871791f78703737125cd2e5a13db8b7d1059.tar yuzu-fb94871791f78703737125cd2e5a13db8b7d1059.tar.gz yuzu-fb94871791f78703737125cd2e5a13db8b7d1059.tar.bz2 yuzu-fb94871791f78703737125cd2e5a13db8b7d1059.tar.lz yuzu-fb94871791f78703737125cd2e5a13db8b7d1059.tar.xz yuzu-fb94871791f78703737125cd2e5a13db8b7d1059.tar.zst yuzu-fb94871791f78703737125cd2e5a13db8b7d1059.zip |
Diffstat (limited to 'src/video_core/renderer_opengl')
-rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.cpp | 51 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.h | 9 |
2 files changed, 57 insertions, 3 deletions
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index 3a456995e..00f9ab92f 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp @@ -177,9 +177,9 @@ void ApplyTextureDefaults(const SurfaceParams& params, GLuint texture) { } } -OGLTexture CreateTexture(const SurfaceParams& params, GLenum internal_format) { +OGLTexture CreateTexture(const SurfaceParams& params, GLenum target, GLenum internal_format) { OGLTexture texture; - texture.Create(GetTextureTarget(params)); + texture.Create(target); switch (params.GetTarget()) { case SurfaceTarget::Texture1D: @@ -241,7 +241,8 @@ CachedSurface::CachedSurface(const SurfaceParams& params) format = tuple.format; type = tuple.type; is_compressed = tuple.compressed; - texture = CreateTexture(params, internal_format); + target = GetTextureTarget(params); + texture = CreateTexture(params, target, internal_format); staging_buffer.resize(params.GetHostSizeInBytes()); } @@ -504,9 +505,53 @@ TextureCacheOpenGL::~TextureCacheOpenGL() = default; CachedSurfaceView* TextureCacheOpenGL::TryFastGetSurfaceView( VAddr cpu_addr, u8* host_ptr, const SurfaceParams& params, bool preserve_contents, const std::vector<CachedSurface*>& overlaps) { + if (overlaps.size() > 1) { + return nullptr; + } + + const auto& old_surface{overlaps[0]}; + const auto& old_params{old_surface->GetSurfaceParams()}; + const auto& new_params{params}; + + if (old_params.GetTarget() == new_params.GetTarget() && + old_params.GetDepth() == new_params.GetDepth() && old_params.GetDepth() == 1 && + old_params.GetNumLevels() == new_params.GetNumLevels() && + old_params.GetPixelFormat() == new_params.GetPixelFormat()) { + return SurfaceCopy(cpu_addr, host_ptr, new_params, old_surface, old_params); + } + return nullptr; } +CachedSurfaceView* TextureCacheOpenGL::SurfaceCopy(VAddr cpu_addr, u8* host_ptr, + const SurfaceParams& new_params, + CachedSurface* old_surface, + const SurfaceParams& old_params) { + CachedSurface* const new_surface{GetUncachedSurface(new_params)}; + Register(new_surface, cpu_addr, host_ptr); + + const u32 min_width{ + std::max(old_params.GetDefaultBlockWidth(), new_params.GetDefaultBlockWidth())}; + const u32 min_height{ + std::max(old_params.GetDefaultBlockHeight(), new_params.GetDefaultBlockHeight())}; + for (u32 level = 0; level < old_params.GetNumLevels(); ++level) { + const u32 width{std::min(old_params.GetMipWidth(level), new_params.GetMipWidth(level))}; + const u32 height{std::min(old_params.GetMipHeight(level), new_params.GetMipHeight(level))}; + if (width < min_width || height < min_height) { + // Avoid copies that are too small to be handled in OpenGL + break; + } + glCopyImageSubData(old_surface->GetTexture(), old_surface->GetTarget(), level, 0, 0, 0, + new_surface->GetTexture(), new_surface->GetTarget(), level, 0, 0, 0, + width, height, 1); + } + + new_surface->MarkAsModified(true); + + // TODO(Rodrigo): Add an entry to directly get the superview + return new_surface->GetView(cpu_addr, new_params); +} + std::unique_ptr<CachedSurface> TextureCacheOpenGL::CreateSurface(const SurfaceParams& params) { return std::make_unique<CachedSurface>(params); } diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h index f0a524882..b18b32d99 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.h +++ b/src/video_core/renderer_opengl/gl_texture_cache.h @@ -38,6 +38,10 @@ public: void LoadBuffer(); + GLenum GetTarget() const { + return target; + } + GLuint GetTexture() const { return texture.handle; } @@ -56,6 +60,7 @@ private: GLenum format{}; GLenum type{}; bool is_compressed{}; + GLenum target{}; OGLTexture texture; @@ -126,6 +131,10 @@ protected: const std::vector<CachedSurface*>& overlaps); std::unique_ptr<CachedSurface> CreateSurface(const SurfaceParams& params); + +private: + CachedSurfaceView* SurfaceCopy(VAddr cpu_addr, u8* host_ptr, const SurfaceParams& new_params, + CachedSurface* old_surface, const SurfaceParams& old_params); }; } // namespace OpenGL |