Rasterizer Cache: Use a temporal storage for Surfaces loading/flushing.
This PR should heavily reduce memory usage since temporal buffers are no longer stored per Surface but instead managed by the Rasterizer Cache.
This commit is contained in:
		 Fernando Sahmkow
					Fernando Sahmkow
				
			
				
					committed by
					
						 FernandoS27
						FernandoS27
					
				
			
			
				
	
			
			
			 FernandoS27
						FernandoS27
					
				
			
						parent
						
							a3eb91ed8c
						
					
				
				
					commit
					4c36b78567
				
			| @@ -66,7 +66,6 @@ public: | ||||
|                                  Tegra::Engines::Maxwell3D::Regs::ShaderStage stage); | ||||
|  | ||||
| protected: | ||||
|  | ||||
|     void FlushObjectInner(const GlobalRegion& object) override { | ||||
|         object->Flush(); | ||||
|     } | ||||
|   | ||||
| @@ -628,9 +628,11 @@ CachedSurface::CachedSurface(const SurfaceParams& params) | ||||
| } | ||||
|  | ||||
| MICROPROFILE_DEFINE(OpenGL_SurfaceLoad, "OpenGL", "Surface Load", MP_RGB(128, 192, 64)); | ||||
| void CachedSurface::LoadGLBuffer() { | ||||
| void CachedSurface::LoadGLBuffer(RasterizerTemporaryMemory& res_cache_tmp_mem) { | ||||
|     MICROPROFILE_SCOPE(OpenGL_SurfaceLoad); | ||||
|     gl_buffer.resize(params.max_mip_level); | ||||
|     auto& gl_buffer = res_cache_tmp_mem.gl_buffer; | ||||
|     if (gl_buffer.size() < params.max_mip_level) | ||||
|         gl_buffer.resize(params.max_mip_level); | ||||
|     for (u32 i = 0; i < params.max_mip_level; i++) | ||||
|         gl_buffer[i].resize(params.GetMipmapSizeGL(i)); | ||||
|     if (params.is_tiled) { | ||||
| @@ -668,13 +670,13 @@ void CachedSurface::LoadGLBuffer() { | ||||
| } | ||||
|  | ||||
| MICROPROFILE_DEFINE(OpenGL_SurfaceFlush, "OpenGL", "Surface Flush", MP_RGB(128, 192, 64)); | ||||
| void CachedSurface::FlushGLBuffer() { | ||||
| void CachedSurface::FlushGLBuffer(RasterizerTemporaryMemory& res_cache_tmp_mem) { | ||||
|     MICROPROFILE_SCOPE(OpenGL_SurfaceFlush); | ||||
|  | ||||
|     ASSERT_MSG(!IsPixelFormatASTC(params.pixel_format), "Unimplemented"); | ||||
|  | ||||
|     auto& gl_buffer = res_cache_tmp_mem.gl_buffer; | ||||
|     // OpenGL temporary buffer needs to be big enough to store raw texture size | ||||
|     gl_buffer.resize(1); | ||||
|     gl_buffer[0].resize(GetSizeInBytes()); | ||||
|  | ||||
|     const FormatTuple& tuple = GetFormatTuple(params.pixel_format, params.component_type); | ||||
| @@ -710,10 +712,12 @@ void CachedSurface::FlushGLBuffer() { | ||||
|     } | ||||
| } | ||||
|  | ||||
| void CachedSurface::UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle, | ||||
|                                           GLuint draw_fb_handle) { | ||||
| void CachedSurface::UploadGLMipmapTexture(RasterizerTemporaryMemory& res_cache_tmp_mem, u32 mip_map, | ||||
|                                           GLuint read_fb_handle, GLuint draw_fb_handle) { | ||||
|     const auto& rect{params.GetRect(mip_map)}; | ||||
|  | ||||
|     auto& gl_buffer = res_cache_tmp_mem.gl_buffer; | ||||
|  | ||||
|     // Load data from memory to the surface | ||||
|     const auto x0 = static_cast<GLint>(rect.left); | ||||
|     const auto y0 = static_cast<GLint>(rect.bottom); | ||||
| @@ -842,11 +846,12 @@ void CachedSurface::EnsureTextureDiscrepantView() { | ||||
| } | ||||
|  | ||||
| MICROPROFILE_DEFINE(OpenGL_TextureUL, "OpenGL", "Texture Upload", MP_RGB(128, 192, 64)); | ||||
| void CachedSurface::UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle) { | ||||
| void CachedSurface::UploadGLTexture(RasterizerTemporaryMemory& res_cache_tmp_mem, | ||||
|                                     GLuint read_fb_handle, GLuint draw_fb_handle) { | ||||
|     MICROPROFILE_SCOPE(OpenGL_TextureUL); | ||||
|  | ||||
|     for (u32 i = 0; i < params.max_mip_level; i++) | ||||
|         UploadGLMipmapTexture(i, read_fb_handle, draw_fb_handle); | ||||
|         UploadGLMipmapTexture(res_cache_tmp_mem, i, read_fb_handle, draw_fb_handle); | ||||
| } | ||||
|  | ||||
| void CachedSurface::UpdateSwizzle(Tegra::Texture::SwizzleSource swizzle_x, | ||||
| @@ -926,8 +931,8 @@ Surface RasterizerCacheOpenGL::GetColorBufferSurface(std::size_t index, bool pre | ||||
| } | ||||
|  | ||||
| void RasterizerCacheOpenGL::LoadSurface(const Surface& surface) { | ||||
|     surface->LoadGLBuffer(); | ||||
|     surface->UploadGLTexture(read_framebuffer.handle, draw_framebuffer.handle); | ||||
|     surface->LoadGLBuffer(temporal_memory); | ||||
|     surface->UploadGLTexture(temporal_memory, read_framebuffer.handle, draw_framebuffer.handle); | ||||
|     surface->MarkAsModified(false, *this); | ||||
|     surface->MarkForReload(false); | ||||
| } | ||||
|   | ||||
| @@ -355,6 +355,12 @@ namespace OpenGL { | ||||
|  | ||||
| class RasterizerOpenGL; | ||||
|  | ||||
| // This is used to store temporary big buffers, | ||||
| // instead of creating/destroying all the time | ||||
| struct RasterizerTemporaryMemory { | ||||
|     std::vector<std::vector<u8>> gl_buffer; | ||||
| }; | ||||
|  | ||||
| class CachedSurface final : public RasterizerCacheObject { | ||||
| public: | ||||
|     explicit CachedSurface(const SurfaceParams& params); | ||||
| @@ -393,11 +399,12 @@ public: | ||||
|     } | ||||
|  | ||||
|     // Read/Write data in Switch memory to/from gl_buffer | ||||
|     void LoadGLBuffer(); | ||||
|     void FlushGLBuffer(); | ||||
|     void LoadGLBuffer(RasterizerTemporaryMemory& res_cache_tmp_mem); | ||||
|     void FlushGLBuffer(RasterizerTemporaryMemory& res_cache_tmp_mem); | ||||
|  | ||||
|     // Upload data in gl_buffer to this surface's texture | ||||
|     void UploadGLTexture(GLuint read_fb_handle, GLuint draw_fb_handle); | ||||
|     void UploadGLTexture(RasterizerTemporaryMemory& res_cache_tmp_mem, GLuint read_fb_handle, | ||||
|                          GLuint draw_fb_handle); | ||||
|  | ||||
|     void UpdateSwizzle(Tegra::Texture::SwizzleSource swizzle_x, | ||||
|                        Tegra::Texture::SwizzleSource swizzle_y, | ||||
| @@ -425,13 +432,13 @@ public: | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     void UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle, GLuint draw_fb_handle); | ||||
|     void UploadGLMipmapTexture(RasterizerTemporaryMemory& res_cache_tmp_mem, u32 mip_map, | ||||
|                                GLuint read_fb_handle, GLuint draw_fb_handle); | ||||
|  | ||||
|     void EnsureTextureDiscrepantView(); | ||||
|  | ||||
|     OGLTexture texture; | ||||
|     OGLTexture discrepant_view; | ||||
|     std::vector<std::vector<u8>> gl_buffer; | ||||
|     SurfaceParams params{}; | ||||
|     GLenum gl_target{}; | ||||
|     GLenum gl_internal_format{}; | ||||
| @@ -471,7 +478,7 @@ public: | ||||
|  | ||||
| protected: | ||||
|     void FlushObjectInner(const Surface& object) override { | ||||
|         object->FlushGLBuffer(); | ||||
|         object->FlushGLBuffer(temporal_memory); | ||||
|     } | ||||
|  | ||||
| private: | ||||
| @@ -520,6 +527,8 @@ private: | ||||
|     std::array<Surface, Maxwell::NumRenderTargets> current_color_buffers; | ||||
|     Surface last_depth_buffer; | ||||
|  | ||||
|     RasterizerTemporaryMemory temporal_memory; | ||||
|  | ||||
|     using SurfaceIntervalCache = boost::icl::interval_map<CacheAddr, Surface>; | ||||
|     using SurfaceInterval = typename SurfaceIntervalCache::interval_type; | ||||
|  | ||||
|   | ||||
| @@ -49,7 +49,6 @@ public: | ||||
|         return alignment; | ||||
|     } | ||||
|  | ||||
|  | ||||
| private: | ||||
|     VAddr cpu_addr{}; | ||||
|     std::size_t size{}; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user