forked from eden-emu/eden
		
	gl_rasterizer: Add rasterizer cache code to handle accerated fermi copies.
This commit is contained in:
		
							parent
							
								
									93822473f7
								
							
						
					
					
						commit
						6a6aa35a70
					
				
					 5 changed files with 60 additions and 16 deletions
				
			
		|  | @ -5,6 +5,7 @@ | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
|  | #include "video_core/engines/fermi_2d.h" | ||||||
| #include "video_core/gpu.h" | #include "video_core/gpu.h" | ||||||
| #include "video_core/memory_manager.h" | #include "video_core/memory_manager.h" | ||||||
| 
 | 
 | ||||||
|  | @ -33,13 +34,9 @@ public: | ||||||
|     /// and invalidated
 |     /// and invalidated
 | ||||||
|     virtual void FlushAndInvalidateRegion(VAddr addr, u64 size) = 0; |     virtual void FlushAndInvalidateRegion(VAddr addr, u64 size) = 0; | ||||||
| 
 | 
 | ||||||
|     /// Attempt to use a faster method to perform a display transfer with is_texture_copy = 0
 |     /// Attempt to use a faster method to perform a surface copy
 | ||||||
|     virtual bool AccelerateDisplayTransfer(const void* config) { |     virtual bool AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Regs::Surface& src, | ||||||
|         return false; |                                        const Tegra::Engines::Fermi2D::Regs::Surface& dst) { | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /// Attempt to use a faster method to perform a display transfer with is_texture_copy = 1
 |  | ||||||
|     virtual bool AccelerateTextureCopy(const void* config) { |  | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -616,14 +616,10 @@ void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) { | ||||||
|     InvalidateRegion(addr, size); |     InvalidateRegion(addr, size); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool RasterizerOpenGL::AccelerateDisplayTransfer(const void* config) { | bool RasterizerOpenGL::AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Regs::Surface& src, | ||||||
|  |                                              const Tegra::Engines::Fermi2D::Regs::Surface& dst) { | ||||||
|     MICROPROFILE_SCOPE(OpenGL_Blits); |     MICROPROFILE_SCOPE(OpenGL_Blits); | ||||||
|     UNREACHABLE(); |     res_cache.FermiCopySurface(src, dst); | ||||||
|     return true; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool RasterizerOpenGL::AccelerateTextureCopy(const void* config) { |  | ||||||
|     UNREACHABLE(); |  | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -52,8 +52,8 @@ public: | ||||||
|     void FlushRegion(VAddr addr, u64 size) override; |     void FlushRegion(VAddr addr, u64 size) override; | ||||||
|     void InvalidateRegion(VAddr addr, u64 size) override; |     void InvalidateRegion(VAddr addr, u64 size) override; | ||||||
|     void FlushAndInvalidateRegion(VAddr addr, u64 size) override; |     void FlushAndInvalidateRegion(VAddr addr, u64 size) override; | ||||||
|     bool AccelerateDisplayTransfer(const void* config) override; |     bool AccelerateSurfaceCopy(const Tegra::Engines::Fermi2D::Regs::Surface& src, | ||||||
|     bool AccelerateTextureCopy(const void* config) override; |                                const Tegra::Engines::Fermi2D::Regs::Surface& dst) override; | ||||||
|     bool AccelerateFill(const void* config) override; |     bool AccelerateFill(const void* config) override; | ||||||
|     bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, |     bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr, | ||||||
|                            u32 pixel_stride) override; |                            u32 pixel_stride) override; | ||||||
|  |  | ||||||
|  | @ -143,6 +143,28 @@ static VAddr TryGetCpuAddr(Tegra::GPUVAddr gpu_addr) { | ||||||
|     return params; |     return params; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /*static*/ SurfaceParams SurfaceParams::CreateForFermiCopySurface( | ||||||
|  |     const Tegra::Engines::Fermi2D::Regs::Surface& config) { | ||||||
|  |     SurfaceParams params{}; | ||||||
|  |     params.addr = TryGetCpuAddr(config.Address()); | ||||||
|  |     params.is_tiled = !config.linear; | ||||||
|  |     params.block_height = params.is_tiled ? config.BlockHeight() : 0, | ||||||
|  |     params.pixel_format = PixelFormatFromRenderTargetFormat(config.format); | ||||||
|  |     params.component_type = ComponentTypeFromRenderTarget(config.format); | ||||||
|  |     params.type = GetFormatType(params.pixel_format); | ||||||
|  |     params.width = config.width; | ||||||
|  |     params.height = config.height; | ||||||
|  |     params.unaligned_height = config.height; | ||||||
|  |     params.target = SurfaceTarget::Texture2D; | ||||||
|  |     params.depth = 1; | ||||||
|  |     params.size_in_bytes_total = params.SizeInBytesTotal(); | ||||||
|  |     params.size_in_bytes_2d = params.SizeInBytes2D(); | ||||||
|  |     params.max_mip_level = 0; | ||||||
|  |     params.rt = {}; | ||||||
|  | 
 | ||||||
|  |     return params; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{ | static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{ | ||||||
|     {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // ABGR8U
 |     {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // ABGR8U
 | ||||||
|     {GL_RGBA8, GL_RGBA, GL_BYTE, ComponentType::SNorm, false},                     // ABGR8S
 |     {GL_RGBA8, GL_RGBA, GL_BYTE, ComponentType::SNorm, false},                     // ABGR8S
 | ||||||
|  | @ -1045,6 +1067,26 @@ Surface RasterizerCacheOpenGL::GetUncachedSurface(const SurfaceParams& params) { | ||||||
|     return surface; |     return surface; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void RasterizerCacheOpenGL::FermiCopySurface( | ||||||
|  |     const Tegra::Engines::Fermi2D::Regs::Surface& src_config, | ||||||
|  |     const Tegra::Engines::Fermi2D::Regs::Surface& dst_config) { | ||||||
|  | 
 | ||||||
|  |     const auto& src_params = SurfaceParams::CreateForFermiCopySurface(src_config); | ||||||
|  |     const auto& dst_params = SurfaceParams::CreateForFermiCopySurface(dst_config); | ||||||
|  | 
 | ||||||
|  |     ASSERT(src_params.width == dst_params.width); | ||||||
|  |     ASSERT(src_params.height == dst_params.height); | ||||||
|  |     ASSERT(src_params.pixel_format == dst_params.pixel_format); | ||||||
|  |     ASSERT(src_params.block_height == dst_params.block_height); | ||||||
|  |     ASSERT(src_params.is_tiled == dst_params.is_tiled); | ||||||
|  |     ASSERT(src_params.depth == dst_params.depth); | ||||||
|  |     ASSERT(src_params.depth == 1); // Currently, FastCopySurface only works with 2D surfaces
 | ||||||
|  |     ASSERT(src_params.target == dst_params.target); | ||||||
|  |     ASSERT(src_params.rt.index == dst_params.rt.index); | ||||||
|  | 
 | ||||||
|  |     FastCopySurface(GetSurface(src_params, true), GetSurface(dst_params, false)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface, | Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface, | ||||||
|                                                const SurfaceParams& new_params) { |                                                const SurfaceParams& new_params) { | ||||||
|     // Verify surface is compatible for blitting
 |     // Verify surface is compatible for blitting
 | ||||||
|  |  | ||||||
|  | @ -13,6 +13,7 @@ | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
| #include "common/hash.h" | #include "common/hash.h" | ||||||
| #include "common/math_util.h" | #include "common/math_util.h" | ||||||
|  | #include "video_core/engines/fermi_2d.h" | ||||||
| #include "video_core/engines/maxwell_3d.h" | #include "video_core/engines/maxwell_3d.h" | ||||||
| #include "video_core/rasterizer_cache.h" | #include "video_core/rasterizer_cache.h" | ||||||
| #include "video_core/renderer_opengl/gl_resource_manager.h" | #include "video_core/renderer_opengl/gl_resource_manager.h" | ||||||
|  | @ -719,6 +720,10 @@ struct SurfaceParams { | ||||||
|                                               Tegra::GPUVAddr zeta_address, |                                               Tegra::GPUVAddr zeta_address, | ||||||
|                                               Tegra::DepthFormat format); |                                               Tegra::DepthFormat format); | ||||||
| 
 | 
 | ||||||
|  |     /// Creates SurfaceParams for a Fermi2D surface copy
 | ||||||
|  |     static SurfaceParams CreateForFermiCopySurface( | ||||||
|  |         const Tegra::Engines::Fermi2D::Regs::Surface& config); | ||||||
|  | 
 | ||||||
|     /// Checks if surfaces are compatible for caching
 |     /// Checks if surfaces are compatible for caching
 | ||||||
|     bool IsCompatibleSurface(const SurfaceParams& other) const { |     bool IsCompatibleSurface(const SurfaceParams& other) const { | ||||||
|         return std::tie(pixel_format, type, width, height, target, depth) == |         return std::tie(pixel_format, type, width, height, target, depth) == | ||||||
|  | @ -837,6 +842,10 @@ public: | ||||||
|     /// Tries to find a framebuffer using on the provided CPU address
 |     /// Tries to find a framebuffer using on the provided CPU address
 | ||||||
|     Surface TryFindFramebufferSurface(VAddr addr) const; |     Surface TryFindFramebufferSurface(VAddr addr) const; | ||||||
| 
 | 
 | ||||||
|  |     /// Copies the contents of one surface to another
 | ||||||
|  |     void FermiCopySurface(const Tegra::Engines::Fermi2D::Regs::Surface& src_config, | ||||||
|  |                           const Tegra::Engines::Fermi2D::Regs::Surface& dst_config); | ||||||
|  | 
 | ||||||
| private: | private: | ||||||
|     void LoadSurface(const Surface& surface); |     void LoadSurface(const Surface& surface); | ||||||
|     Surface GetSurface(const SurfaceParams& params, bool preserve_contents = true); |     Surface GetSurface(const SurfaceParams& params, bool preserve_contents = true); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bunnei
						bunnei