Implemented Fast Layered Copy

This commit is contained in:
FernandoS27 2018-11-19 12:04:07 -04:00
parent f02b125ac8
commit eb36463e03
2 changed files with 30 additions and 2 deletions

View File

@ -1275,6 +1275,31 @@ Surface RasterizerCacheOpenGL::GetUncachedSurface(const SurfaceParams& params) {
return surface; 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( void RasterizerCacheOpenGL::FermiCopySurface(
const Tegra::Engines::Fermi2D::Regs::Surface& src_config, const Tegra::Engines::Fermi2D::Regs::Surface& src_config,
const Tegra::Engines::Fermi2D::Regs::Surface& dst_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); CopySurface(old_surface, new_surface, copy_pbo.handle);
} }
break; break;
case SurfaceTarget::TextureCubemap:
case SurfaceTarget::Texture3D: case SurfaceTarget::Texture3D:
AccurateCopySurface(old_surface, new_surface);
break;
case SurfaceTarget::TextureCubemap:
case SurfaceTarget::Texture2DArray: case SurfaceTarget::Texture2DArray:
case SurfaceTarget::TextureCubeArray: case SurfaceTarget::TextureCubeArray:
AccurateCopySurface(old_surface, new_surface); FastLayeredCopySurface(old_surface, new_surface);
break; break;
default: default:
LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}", LOG_CRITICAL(Render_OpenGL, "Unimplemented surface target={}",

View File

@ -350,6 +350,7 @@ private:
/// Performs a slow but accurate surface copy, flushing to RAM and reinterpreting the data /// 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 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 /// 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 /// previously been used. This is to prevent surfaces from being constantly created and