gl_rasterizer_cache: Reserve surfaces that have already been created for later use.
This commit is contained in:
		
							parent
							
								
									fde2017a3f
								
							
						
					
					
						commit
						fee8bdd90c
					
				@ -787,10 +787,20 @@ Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params, bool pres
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Try to get a previously reserved surface
 | 
			
		||||
    surface = TryGetReservedSurface(params);
 | 
			
		||||
 | 
			
		||||
    // No surface found - create a new one
 | 
			
		||||
    if (!surface) {
 | 
			
		||||
        surface = std::make_shared<CachedSurface>(params);
 | 
			
		||||
        ReserveSurface(surface);
 | 
			
		||||
        RegisterSurface(surface);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Only load surface from memory if we care about the contents
 | 
			
		||||
    if (preserve_contents) {
 | 
			
		||||
        LoadSurface(surface);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return surface;
 | 
			
		||||
}
 | 
			
		||||
@ -940,6 +950,21 @@ void RasterizerCacheOpenGL::UnregisterSurface(const Surface& surface) {
 | 
			
		||||
    surface_cache.erase(search);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void RasterizerCacheOpenGL::ReserveSurface(const Surface& surface) {
 | 
			
		||||
    const auto& surface_reserve_key{SurfaceReserveKey::Create(surface->GetSurfaceParams())};
 | 
			
		||||
    surface_reserve[surface_reserve_key] = surface;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Surface RasterizerCacheOpenGL::TryGetReservedSurface(const SurfaceParams& params) {
 | 
			
		||||
    const auto& surface_reserve_key{SurfaceReserveKey::Create(params)};
 | 
			
		||||
    auto search{surface_reserve.find(surface_reserve_key)};
 | 
			
		||||
    if (search != surface_reserve.end()) {
 | 
			
		||||
        RegisterSurface(search->second);
 | 
			
		||||
        return search->second;
 | 
			
		||||
    }
 | 
			
		||||
    return {};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Map, typename Interval>
 | 
			
		||||
constexpr auto RangeFromInterval(Map& map, const Interval& interval) {
 | 
			
		||||
    return boost::make_iterator_range(map.equal_range(interval));
 | 
			
		||||
 | 
			
		||||
@ -11,6 +11,7 @@
 | 
			
		||||
#include <boost/icl/interval_map.hpp>
 | 
			
		||||
 | 
			
		||||
#include "common/common_types.h"
 | 
			
		||||
#include "common/hash.h"
 | 
			
		||||
#include "common/math_util.h"
 | 
			
		||||
#include "video_core/engines/maxwell_3d.h"
 | 
			
		||||
#include "video_core/renderer_opengl/gl_resource_manager.h"
 | 
			
		||||
@ -682,6 +683,27 @@ struct SurfaceParams {
 | 
			
		||||
    u32 cache_height;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}; // namespace OpenGL
 | 
			
		||||
 | 
			
		||||
/// Hashable variation of SurfaceParams, used for a key in the surface cache
 | 
			
		||||
struct SurfaceReserveKey : Common::HashableStruct<OpenGL::SurfaceParams> {
 | 
			
		||||
    static SurfaceReserveKey Create(const OpenGL::SurfaceParams& params) {
 | 
			
		||||
        SurfaceReserveKey res;
 | 
			
		||||
        res.state = params;
 | 
			
		||||
        return res;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
namespace std {
 | 
			
		||||
template <>
 | 
			
		||||
struct hash<SurfaceReserveKey> {
 | 
			
		||||
    size_t operator()(const SurfaceReserveKey& k) const {
 | 
			
		||||
        return k.Hash();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
} // namespace std
 | 
			
		||||
 | 
			
		||||
namespace OpenGL {
 | 
			
		||||
 | 
			
		||||
class CachedSurface final {
 | 
			
		||||
public:
 | 
			
		||||
    CachedSurface(const SurfaceParams& params);
 | 
			
		||||
@ -752,12 +774,23 @@ private:
 | 
			
		||||
    /// Remove surface from the cache
 | 
			
		||||
    void UnregisterSurface(const Surface& surface);
 | 
			
		||||
 | 
			
		||||
    /// Reserves a unique surface that can be reused later
 | 
			
		||||
    void ReserveSurface(const Surface& surface);
 | 
			
		||||
 | 
			
		||||
    /// Tries to get a reserved surface for the specified parameters
 | 
			
		||||
    Surface TryGetReservedSurface(const SurfaceParams& params);
 | 
			
		||||
 | 
			
		||||
    /// Increase/decrease the number of surface in pages touching the specified region
 | 
			
		||||
    void UpdatePagesCachedCount(Tegra::GPUVAddr addr, u64 size, int delta);
 | 
			
		||||
 | 
			
		||||
    std::unordered_map<Tegra::GPUVAddr, Surface> surface_cache;
 | 
			
		||||
    PageMap cached_pages;
 | 
			
		||||
 | 
			
		||||
    /// The surface reserve is a "backup" cache, this is where we put unique surfaces that have
 | 
			
		||||
    /// previously been used. This is to prevent surfaces from being constantly created and
 | 
			
		||||
    /// destroyed when used with different surface parameters.
 | 
			
		||||
    std::unordered_map<SurfaceReserveKey, Surface> surface_reserve;
 | 
			
		||||
 | 
			
		||||
    OGLFramebuffer read_framebuffer;
 | 
			
		||||
    OGLFramebuffer draw_framebuffer;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user