diff options
author | FernandoS27 <fsahmkow27@gmail.com> | 2018-11-19 17:04:07 +0100 |
---|---|---|
committer | FernandoS27 <fsahmkow27@gmail.com> | 2018-11-20 00:51:13 +0100 |
commit | eb36463e039be17bb336cba07fa8807a1795e6c2 (patch) | |
tree | 36aee8654de9c765e99708c5ad3104490005db5a /src/video_core/renderer_opengl | |
parent | Merge pull request #1717 from FreddyFunk/swizzle-gob (diff) | |
download | yuzu-eb36463e039be17bb336cba07fa8807a1795e6c2.tar yuzu-eb36463e039be17bb336cba07fa8807a1795e6c2.tar.gz yuzu-eb36463e039be17bb336cba07fa8807a1795e6c2.tar.bz2 yuzu-eb36463e039be17bb336cba07fa8807a1795e6c2.tar.lz yuzu-eb36463e039be17bb336cba07fa8807a1795e6c2.tar.xz yuzu-eb36463e039be17bb336cba07fa8807a1795e6c2.tar.zst yuzu-eb36463e039be17bb336cba07fa8807a1795e6c2.zip |
Diffstat (limited to 'src/video_core/renderer_opengl')
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 31 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 1 |
2 files changed, 30 insertions, 2 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 9ca82c06c..b994e89dd 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -1275,6 +1275,31 @@ Surface RasterizerCacheOpenGL::GetUncachedSurface(const SurfaceParams& params) { return surface; } +void RasterizerCacheOpenGL::FastLayeredCopySurface(const Surface& src_surface, + const Surface& dst_surface) { + const auto& init_params{src_surface->GetSurfaceParams()}; + const auto& dst_params{dst_surface->GetSurfaceParams()}; + VAddr address = init_params.addr; + const std::size_t layer_size = dst_params.LayerMemorySize(); + for (u32 layer = 0; layer < dst_params.depth; layer++) { + for (u32 mipmap = 0; mipmap < dst_params.max_mip_level; mipmap++) { + const VAddr sub_address = address + dst_params.GetMipmapLevelOffset(mipmap); + const Surface& copy = TryGet(sub_address); + if (!copy) + continue; + const auto& src_params{copy->GetSurfaceParams()}; + const u32 width{std::min(src_params.width, dst_params.MipWidth(mipmap))}; + const u32 height{std::min(src_params.height, dst_params.MipHeight(mipmap))}; + + glCopyImageSubData(copy->Texture().handle, SurfaceTargetToGL(src_params.target), 0, 0, + 0, 0, dst_surface->Texture().handle, + SurfaceTargetToGL(dst_params.target), mipmap, 0, 0, layer, width, + height, 1); + } + address += layer_size; + } +} + void RasterizerCacheOpenGL::FermiCopySurface( const Tegra::Engines::Fermi2D::Regs::Surface& src_config, const Tegra::Engines::Fermi2D::Regs::Surface& dst_config) { @@ -1340,11 +1365,13 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface, CopySurface(old_surface, new_surface, copy_pbo.handle); } break; - case SurfaceTarget::TextureCubemap: case SurfaceTarget::Texture3D: + AccurateCopySurface(old_surface, new_surface); + break; + case SurfaceTarget::TextureCubemap: case SurfaceTarget::Texture2DArray: case SurfaceTarget::TextureCubeArray: - AccurateCopySurface(old_surface, new_surface); + FastLayeredCopySurface(old_surface, new_surface); break; default: LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 494f6b903..9ac79c5a4 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -350,6 +350,7 @@ private: /// Performs a slow but accurate surface copy, flushing to RAM and reinterpreting the data void AccurateCopySurface(const Surface& src_surface, const Surface& dst_surface); + void FastLayeredCopySurface(const Surface& src_surface, const Surface& dst_surface); /// The surface reserve is a "backup" cache, this is where we put unique surfaces that have /// previously been used. This is to prevent surfaces from being constantly created and |