|
|
|
@ -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<CachedSurface*>& 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<CachedSurface> TextureCacheOpenGL::CreateSurface(const SurfaceParams& params) { |
|
|
|
return std::make_unique<CachedSurface>(params); |
|
|
|
} |
|
|
|
|