mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu-mainline.git
				synced 2025-03-21 01:53:15 +00:00 
			
		
		
		
	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,7 +505,51 @@ 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;
 | 
					        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) {
 | 
					std::unique_ptr<CachedSurface> TextureCacheOpenGL::CreateSurface(const SurfaceParams& 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;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user