mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-10-28 06:32:47 -05:00 
			
		
		
		
	gl_texture_cache: Add fast copy path
This commit is contained in:
		| @@ -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
	
	Block a user
	 ReinUsesLisp
					ReinUsesLisp