gl_texture_cache: Add fast copy path
This commit is contained in:
parent
bab21e8cb3
commit
fb94871791
|
@ -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;
|
OGLTexture texture;
|
||||||
texture.Create(GetTextureTarget(params));
|
texture.Create(target);
|
||||||
|
|
||||||
switch (params.GetTarget()) {
|
switch (params.GetTarget()) {
|
||||||
case SurfaceTarget::Texture1D:
|
case SurfaceTarget::Texture1D:
|
||||||
|
@ -241,7 +241,8 @@ CachedSurface::CachedSurface(const SurfaceParams& params)
|
||||||
format = tuple.format;
|
format = tuple.format;
|
||||||
type = tuple.type;
|
type = tuple.type;
|
||||||
is_compressed = tuple.compressed;
|
is_compressed = tuple.compressed;
|
||||||
texture = CreateTexture(params, internal_format);
|
target = GetTextureTarget(params);
|
||||||
|
texture = CreateTexture(params, target, internal_format);
|
||||||
staging_buffer.resize(params.GetHostSizeInBytes());
|
staging_buffer.resize(params.GetHostSizeInBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -504,9 +505,53 @@ TextureCacheOpenGL::~TextureCacheOpenGL() = default;
|
||||||
CachedSurfaceView* TextureCacheOpenGL::TryFastGetSurfaceView(
|
CachedSurfaceView* TextureCacheOpenGL::TryFastGetSurfaceView(
|
||||||
VAddr cpu_addr, u8* host_ptr, const SurfaceParams& params, bool preserve_contents,
|
VAddr cpu_addr, u8* host_ptr, const SurfaceParams& params, bool preserve_contents,
|
||||||
const std::vector<CachedSurface*>& overlaps) {
|
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;
|
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) {
|
std::unique_ptr<CachedSurface> TextureCacheOpenGL::CreateSurface(const SurfaceParams& params) {
|
||||||
return std::make_unique<CachedSurface>(params);
|
return std::make_unique<CachedSurface>(params);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,10 @@ public:
|
||||||
|
|
||||||
void LoadBuffer();
|
void LoadBuffer();
|
||||||
|
|
||||||
|
GLenum GetTarget() const {
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
GLuint GetTexture() const {
|
GLuint GetTexture() const {
|
||||||
return texture.handle;
|
return texture.handle;
|
||||||
}
|
}
|
||||||
|
@ -56,6 +60,7 @@ private:
|
||||||
GLenum format{};
|
GLenum format{};
|
||||||
GLenum type{};
|
GLenum type{};
|
||||||
bool is_compressed{};
|
bool is_compressed{};
|
||||||
|
GLenum target{};
|
||||||
|
|
||||||
OGLTexture texture;
|
OGLTexture texture;
|
||||||
|
|
||||||
|
@ -126,6 +131,10 @@ protected:
|
||||||
const std::vector<CachedSurface*>& overlaps);
|
const std::vector<CachedSurface*>& overlaps);
|
||||||
|
|
||||||
std::unique_ptr<CachedSurface> CreateSurface(const SurfaceParams& params);
|
std::unique_ptr<CachedSurface> CreateSurface(const SurfaceParams& params);
|
||||||
|
|
||||||
|
private:
|
||||||
|
CachedSurfaceView* SurfaceCopy(VAddr cpu_addr, u8* host_ptr, const SurfaceParams& new_params,
|
||||||
|
CachedSurface* old_surface, const SurfaceParams& old_params);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace OpenGL
|
} // namespace OpenGL
|
||||||
|
|
|
@ -160,7 +160,7 @@ u32 SurfaceParams::GetMipBlockHeight(u32 level) const {
|
||||||
// Auto block resizing algorithm from:
|
// Auto block resizing algorithm from:
|
||||||
// https://cgit.freedesktop.org/mesa/mesa/tree/src/gallium/drivers/nouveau/nv50/nv50_miptree.c
|
// https://cgit.freedesktop.org/mesa/mesa/tree/src/gallium/drivers/nouveau/nv50/nv50_miptree.c
|
||||||
if (level == 0) {
|
if (level == 0) {
|
||||||
return block_height;
|
return this->block_height;
|
||||||
}
|
}
|
||||||
const u32 height{GetMipHeight(level)};
|
const u32 height{GetMipHeight(level)};
|
||||||
const u32 default_block_height{GetDefaultBlockHeight()};
|
const u32 default_block_height{GetDefaultBlockHeight()};
|
||||||
|
@ -316,7 +316,7 @@ std::size_t SurfaceParams::GetInnerMemorySize(bool as_host_size, bool layer_only
|
||||||
size += GetInnerMipmapMemorySize(level, as_host_size, layer_only, uncompressed);
|
size += GetInnerMipmapMemorySize(level, as_host_size, layer_only, uncompressed);
|
||||||
}
|
}
|
||||||
if (is_tiled && !as_host_size) {
|
if (is_tiled && !as_host_size) {
|
||||||
size = Common::AlignUp(size, Tegra::Texture::GetGOBSize() * block_height * block_depth);
|
//size = Common::AlignUp(size, Tegra::Texture::GetGOBSize() * block_height * block_depth);
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
|
@ -359,8 +359,7 @@ std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height
|
||||||
const u32 aligned_width = Common::AlignUp(width * bytes_per_pixel, gob_size_x);
|
const u32 aligned_width = Common::AlignUp(width * bytes_per_pixel, gob_size_x);
|
||||||
const u32 aligned_height = Common::AlignUp(height, gob_size_y * block_height);
|
const u32 aligned_height = Common::AlignUp(height, gob_size_y * block_height);
|
||||||
const u32 aligned_depth = Common::AlignUp(depth, gob_size_z * block_depth);
|
const u32 aligned_depth = Common::AlignUp(depth, gob_size_z * block_depth);
|
||||||
const u32 size = aligned_width * aligned_height * aligned_depth;
|
return aligned_width * aligned_height * aligned_depth;
|
||||||
return size;
|
|
||||||
} else {
|
} else {
|
||||||
return width * height * depth * bytes_per_pixel;
|
return width * height * depth * bytes_per_pixel;
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue