From fb94871791f78703737125cd2e5a13db8b7d1059 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 14 Apr 2019 01:44:16 -0300 Subject: gl_texture_cache: Add fast copy path --- .../renderer_opengl/gl_texture_cache.cpp | 51 ++++++++++++++++++++-- 1 file changed, 48 insertions(+), 3 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_texture_cache.cpp') 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& 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 TextureCacheOpenGL::CreateSurface(const SurfaceParams& params) { return std::make_unique(params); } -- cgit v1.2.3