diff options
| -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) { | |||
| 1275 | return surface; | 1275 | return surface; |
| 1276 | } | 1276 | } |
| 1277 | 1277 | ||
| 1278 | void RasterizerCacheOpenGL::FastLayeredCopySurface(const Surface& src_surface, | ||
| 1279 | const Surface& dst_surface) { | ||
| 1280 | const auto& init_params{src_surface->GetSurfaceParams()}; | ||
| 1281 | const auto& dst_params{dst_surface->GetSurfaceParams()}; | ||
| 1282 | VAddr address = init_params.addr; | ||
| 1283 | const std::size_t layer_size = dst_params.LayerMemorySize(); | ||
| 1284 | for (u32 layer = 0; layer < dst_params.depth; layer++) { | ||
| 1285 | for (u32 mipmap = 0; mipmap < dst_params.max_mip_level; mipmap++) { | ||
| 1286 | const VAddr sub_address = address + dst_params.GetMipmapLevelOffset(mipmap); | ||
| 1287 | const Surface& copy = TryGet(sub_address); | ||
| 1288 | if (!copy) | ||
| 1289 | continue; | ||
| 1290 | const auto& src_params{copy->GetSurfaceParams()}; | ||
| 1291 | const u32 width{std::min(src_params.width, dst_params.MipWidth(mipmap))}; | ||
| 1292 | const u32 height{std::min(src_params.height, dst_params.MipHeight(mipmap))}; | ||
| 1293 | |||
| 1294 | glCopyImageSubData(copy->Texture().handle, SurfaceTargetToGL(src_params.target), 0, 0, | ||
| 1295 | 0, 0, dst_surface->Texture().handle, | ||
| 1296 | SurfaceTargetToGL(dst_params.target), mipmap, 0, 0, layer, width, | ||
| 1297 | height, 1); | ||
| 1298 | } | ||
| 1299 | address += layer_size; | ||
| 1300 | } | ||
| 1301 | } | ||
| 1302 | |||
| 1278 | void RasterizerCacheOpenGL::FermiCopySurface( | 1303 | void RasterizerCacheOpenGL::FermiCopySurface( |
| 1279 | const Tegra::Engines::Fermi2D::Regs::Surface& src_config, | 1304 | const Tegra::Engines::Fermi2D::Regs::Surface& src_config, |
| 1280 | const Tegra::Engines::Fermi2D::Regs::Surface& dst_config) { | 1305 | const Tegra::Engines::Fermi2D::Regs::Surface& dst_config) { |
| @@ -1340,11 +1365,13 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface, | |||
| 1340 | CopySurface(old_surface, new_surface, copy_pbo.handle); | 1365 | CopySurface(old_surface, new_surface, copy_pbo.handle); |
| 1341 | } | 1366 | } |
| 1342 | break; | 1367 | break; |
| 1343 | case SurfaceTarget::TextureCubemap: | ||
| 1344 | case SurfaceTarget::Texture3D: | 1368 | case SurfaceTarget::Texture3D: |
| 1369 | AccurateCopySurface(old_surface, new_surface); | ||
| 1370 | break; | ||
| 1371 | case SurfaceTarget::TextureCubemap: | ||
| 1345 | case SurfaceTarget::Texture2DArray: | 1372 | case SurfaceTarget::Texture2DArray: |
| 1346 | case SurfaceTarget::TextureCubeArray: | 1373 | case SurfaceTarget::TextureCubeArray: |
| 1347 | AccurateCopySurface(old_surface, new_surface); | 1374 | FastLayeredCopySurface(old_surface, new_surface); |
| 1348 | break; | 1375 | break; |
| 1349 | default: | 1376 | default: |
| 1350 | LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", | 1377 | 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: | |||
| 350 | 350 | ||
| 351 | /// Performs a slow but accurate surface copy, flushing to RAM and reinterpreting the data | 351 | /// Performs a slow but accurate surface copy, flushing to RAM and reinterpreting the data |
| 352 | void AccurateCopySurface(const Surface& src_surface, const Surface& dst_surface); | 352 | void AccurateCopySurface(const Surface& src_surface, const Surface& dst_surface); |
| 353 | void FastLayeredCopySurface(const Surface& src_surface, const Surface& dst_surface); | ||
| 353 | 354 | ||
| 354 | /// The surface reserve is a "backup" cache, this is where we put unique surfaces that have | 355 | /// The surface reserve is a "backup" cache, this is where we put unique surfaces that have |
| 355 | /// previously been used. This is to prevent surfaces from being constantly created and | 356 | /// previously been used. This is to prevent surfaces from being constantly created and |