Implemented Fast Layered Copy
This commit is contained in:
parent
f02b125ac8
commit
eb36463e03
@ -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={}",
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user