Corrections and redesign.
This commit is contained in:
		 Fernando Sahmkow
					Fernando Sahmkow
				
			
				
					committed by
					
						 FernandoS27
						FernandoS27
					
				
			
			
				
	
			
			
			 FernandoS27
						FernandoS27
					
				
			
						parent
						
							d6b9b51606
						
					
				
				
					commit
					5a9204dbd7
				
			| @@ -3,6 +3,7 @@ | |||||||
| // Refer to the license.txt file included. | // Refer to the license.txt file included. | ||||||
|  |  | ||||||
| #include <algorithm> | #include <algorithm> | ||||||
|  | #include <optional> | ||||||
| #include <glad/glad.h> | #include <glad/glad.h> | ||||||
|  |  | ||||||
| #include "common/alignment.h" | #include "common/alignment.h" | ||||||
| @@ -1000,7 +1001,7 @@ Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params, bool pres | |||||||
|     Surface surface{TryGet(params.addr)}; |     Surface surface{TryGet(params.addr)}; | ||||||
|     if (surface) { |     if (surface) { | ||||||
|         if (surface->GetSurfaceParams().IsCompatibleSurface(params)) { |         if (surface->GetSurfaceParams().IsCompatibleSurface(params)) { | ||||||
|             // Use the cached surface as-is |             // Use the cached surface as-is unless it's not synced with memory | ||||||
|             if (surface->MustReload()) |             if (surface->MustReload()) | ||||||
|                 LoadSurface(surface); |                 LoadSurface(surface); | ||||||
|             return surface; |             return surface; | ||||||
| @@ -1298,44 +1299,47 @@ Surface RasterizerCacheOpenGL::TryGetReservedSurface(const SurfaceParams& params | |||||||
|     return {}; |     return {}; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool FindBestMipMap(std::size_t memory, const SurfaceParams params, u32 height, u32& mipmap) { | static std::optional<u32> TryFindBestMipMap(std::size_t memory, const SurfaceParams params, | ||||||
|     for (u32 i = 0; i < params.max_mip_level; i++) |                                             u32 height) { | ||||||
|  |     for (u32 i = 0; i < params.max_mip_level; i++) { | ||||||
|         if (memory == params.GetMipmapSingleSize(i) && params.MipHeight(i) == height) { |         if (memory == params.GetMipmapSingleSize(i) && params.MipHeight(i) == height) { | ||||||
|             mipmap = i; |             return {i}; | ||||||
|             return true; |  | ||||||
|         } |         } | ||||||
|     return false; |     } | ||||||
|  |     return {}; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool FindBestLayer(VAddr addr, const SurfaceParams params, u32 mipmap, u32& layer) { | static std::optional<u32> TryFindBestLayer(VAddr addr, const SurfaceParams params, u32 mipmap) { | ||||||
|     std::size_t size = params.LayerMemorySize(); |     const std::size_t size = params.LayerMemorySize(); | ||||||
|     VAddr start = params.addr + params.GetMipmapLevelOffset(mipmap); |     VAddr start = params.addr + params.GetMipmapLevelOffset(mipmap); | ||||||
|     for (u32 i = 0; i < params.depth; i++) { |     for (u32 i = 0; i < params.depth; i++) { | ||||||
|         if (start == addr) { |         if (start == addr) { | ||||||
|             layer = i; |             return {i}; | ||||||
|             return true; |  | ||||||
|         } |         } | ||||||
|         start += size; |         start += size; | ||||||
|     } |     } | ||||||
|     return false; |     return {}; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool LayerFitReinterpretSurface(RasterizerCacheOpenGL& cache, const Surface render_surface, | static bool LayerFitReinterpretSurface(RasterizerCacheOpenGL& cache, const Surface render_surface, | ||||||
|                                        const Surface blitted_surface) { |                                        const Surface blitted_surface) { | ||||||
|     const auto dst_params = blitted_surface->GetSurfaceParams(); |     const auto& dst_params = blitted_surface->GetSurfaceParams(); | ||||||
|     const auto src_params = render_surface->GetSurfaceParams(); |     const auto& src_params = render_surface->GetSurfaceParams(); | ||||||
|     u32 level = 0; |     const std::size_t src_memory_size = src_params.size_in_bytes; | ||||||
|     std::size_t src_memory_size = src_params.size_in_bytes; |     const std::optional<u32> level = | ||||||
|     if (FindBestMipMap(src_memory_size, dst_params, src_params.height, level)) { |         TryFindBestMipMap(src_memory_size, dst_params, src_params.height); | ||||||
|         if (src_params.width == dst_params.MipWidthGobAligned(level) && |     if (level.has_value()) { | ||||||
|             src_params.height == dst_params.MipHeight(level) && |         if (src_params.width == dst_params.MipWidthGobAligned(*level) && | ||||||
|             src_params.block_height >= dst_params.MipBlockHeight(level)) { |             src_params.height == dst_params.MipHeight(*level) && | ||||||
|             u32 slot = 0; |             src_params.block_height >= dst_params.MipBlockHeight(*level)) { | ||||||
|             if (FindBestLayer(render_surface->GetAddr(), dst_params, level, slot)) { |             const std::optional<u32> slot = | ||||||
|                 glCopyImageSubData( |                 TryFindBestLayer(render_surface->GetAddr(), dst_params, *level); | ||||||
|                     render_surface->Texture().handle, SurfaceTargetToGL(src_params.target), 0, 0, 0, |             if (slot.has_value()) { | ||||||
|                     0, blitted_surface->Texture().handle, SurfaceTargetToGL(dst_params.target), |                 glCopyImageSubData(render_surface->Texture().handle, | ||||||
|                     level, 0, 0, slot, dst_params.MipWidth(level), dst_params.MipHeight(level), 1); |                                    SurfaceTargetToGL(src_params.target), 0, 0, 0, 0, | ||||||
|  |                                    blitted_surface->Texture().handle, | ||||||
|  |                                    SurfaceTargetToGL(dst_params.target), *level, 0, 0, *slot, | ||||||
|  |                                    dst_params.MipWidth(*level), dst_params.MipHeight(*level), 1); | ||||||
|                 blitted_surface->MarkAsModified(true, cache); |                 blitted_surface->MarkAsModified(true, cache); | ||||||
|                 return true; |                 return true; | ||||||
|             } |             } | ||||||
| @@ -1344,24 +1348,21 @@ bool LayerFitReinterpretSurface(RasterizerCacheOpenGL& cache, const Surface rend | |||||||
|     return false; |     return false; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool IsReinterpretInvalid(const Surface render_surface, const Surface blitted_surface) { | static bool IsReinterpretInvalid(const Surface render_surface, const Surface blitted_surface) { | ||||||
|     VAddr bound1 = blitted_surface->GetAddr() + blitted_surface->GetMemorySize(); |     const VAddr bound1 = blitted_surface->GetAddr() + blitted_surface->GetMemorySize(); | ||||||
|     VAddr bound2 = render_surface->GetAddr() + render_surface->GetMemorySize(); |     const VAddr bound2 = render_surface->GetAddr() + render_surface->GetMemorySize(); | ||||||
|     if (bound2 > bound1) |     if (bound2 > bound1) | ||||||
|         return true; |         return true; | ||||||
|     const auto dst_params = blitted_surface->GetSurfaceParams(); |     const auto& dst_params = blitted_surface->GetSurfaceParams(); | ||||||
|     const auto src_params = render_surface->GetSurfaceParams(); |     const auto& src_params = render_surface->GetSurfaceParams(); | ||||||
|     if (dst_params.component_type != src_params.component_type) |     return (dst_params.component_type != src_params.component_type); | ||||||
|         return true; |  | ||||||
|     return false; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| bool IsReinterpretInvalidSecond(const Surface render_surface, const Surface blitted_surface) { | static bool IsReinterpretInvalidSecond(const Surface render_surface, | ||||||
|     const auto dst_params = blitted_surface->GetSurfaceParams(); |                                        const Surface blitted_surface) { | ||||||
|     const auto src_params = render_surface->GetSurfaceParams(); |     const auto& dst_params = blitted_surface->GetSurfaceParams(); | ||||||
|     if (dst_params.height > src_params.height && dst_params.width > src_params.width) |     const auto& src_params = render_surface->GetSurfaceParams(); | ||||||
|         return false; |     return (dst_params.height > src_params.height && dst_params.width > src_params.width); | ||||||
|     return true; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| bool RasterizerCacheOpenGL::PartialReinterpretSurface(Surface triggering_surface, | bool RasterizerCacheOpenGL::PartialReinterpretSurface(Surface triggering_surface, | ||||||
| @@ -1383,7 +1384,7 @@ bool RasterizerCacheOpenGL::PartialReinterpretSurface(Surface triggering_surface | |||||||
| } | } | ||||||
|  |  | ||||||
| void RasterizerCacheOpenGL::SignalPreDrawCall() { | void RasterizerCacheOpenGL::SignalPreDrawCall() { | ||||||
|     if (texception) { |     if (texception && GLAD_GL_ARB_texture_barrier) { | ||||||
|         glTextureBarrier(); |         glTextureBarrier(); | ||||||
|     } |     } | ||||||
|     texception = false; |     texception = false; | ||||||
|   | |||||||
| @@ -412,7 +412,7 @@ public: | |||||||
|         reinterpreted = true; |         reinterpreted = true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     bool IsReinterpreted() { |     bool IsReinterpreted() const { | ||||||
|         return reinterpreted; |         return reinterpreted; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -420,11 +420,11 @@ public: | |||||||
|         must_reload = reload; |         must_reload = reload; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     bool MustReload() { |     bool MustReload() const { | ||||||
|         return must_reload; |         return must_reload; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     bool IsUploaded() { |     bool IsUploaded() const { | ||||||
|         return params.identity == SurfaceParams::SurfaceClass::Uploaded; |         return params.identity == SurfaceParams::SurfaceClass::Uploaded; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -489,6 +489,7 @@ private: | |||||||
|     Surface TryGetReservedSurface(const SurfaceParams& params); |     Surface TryGetReservedSurface(const SurfaceParams& params); | ||||||
|  |  | ||||||
|     // Partialy reinterpret a surface based on a triggering_surface that collides with it. |     // Partialy reinterpret a surface based on a triggering_surface that collides with it. | ||||||
|  |     // returns true if the reinterpret was successful, false in case it was not. | ||||||
|     bool PartialReinterpretSurface(Surface triggering_surface, Surface intersect); |     bool PartialReinterpretSurface(Surface triggering_surface, Surface intersect); | ||||||
|  |  | ||||||
|     /// Performs a slow but accurate surface copy, flushing to RAM and reinterpreting the data |     /// Performs a slow but accurate surface copy, flushing to RAM and reinterpreting the data | ||||||
| @@ -528,10 +529,10 @@ private: | |||||||
|     // Reinterpreted surfaces are very fragil as the game may keep rendering into them. |     // Reinterpreted surfaces are very fragil as the game may keep rendering into them. | ||||||
|     SurfaceIntervalCache reinterpreted_surfaces; |     SurfaceIntervalCache reinterpreted_surfaces; | ||||||
|  |  | ||||||
|     void RegisterReinterpretSurface(Surface r_surface) { |     void RegisterReinterpretSurface(Surface reinterpret_surface) { | ||||||
|         auto interval = GetReinterpretInterval(r_surface); |         auto interval = GetReinterpretInterval(reinterpret_surface); | ||||||
|         reinterpreted_surfaces.insert({interval, r_surface}); |         reinterpreted_surfaces.insert({interval, reinterpret_surface}); | ||||||
|         r_surface->MarkReinterpreted(); |         reinterpret_surface->MarkReinterpreted(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     Surface CollideOnReinterpretedSurface(VAddr addr) const { |     Surface CollideOnReinterpretedSurface(VAddr addr) const { | ||||||
| @@ -543,14 +544,12 @@ private: | |||||||
|         return nullptr; |         return nullptr; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| protected: |  | ||||||
|     void Register(const Surface& object) { |     void Register(const Surface& object) { | ||||||
|         RasterizerCache<Surface>::Register(object); |         RasterizerCache<Surface>::Register(object); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// Unregisters an object from the cache |     /// Unregisters an object from the cache | ||||||
|     void Unregister(const Surface& object) { |     void Unregister(const Surface& object) { | ||||||
|         const auto& params = object->GetSurfaceParams(); |  | ||||||
|         if (object->IsReinterpreted()) { |         if (object->IsReinterpreted()) { | ||||||
|             auto interval = GetReinterpretInterval(object); |             auto interval = GetReinterpretInterval(object); | ||||||
|             reinterpreted_surfaces.erase(interval); |             reinterpreted_surfaces.erase(interval); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user