diff options
Diffstat (limited to '')
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 31 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 33 |
2 files changed, 61 insertions, 3 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index a13c1d97d..10b2d8f3c 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | |||
| @@ -787,10 +787,20 @@ Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params, bool pres | |||
| 787 | } | 787 | } |
| 788 | } | 788 | } |
| 789 | 789 | ||
| 790 | // Try to get a previously reserved surface | ||
| 791 | surface = TryGetReservedSurface(params); | ||
| 792 | |||
| 790 | // No surface found - create a new one | 793 | // No surface found - create a new one |
| 791 | surface = std::make_shared<CachedSurface>(params); | 794 | if (!surface) { |
| 792 | RegisterSurface(surface); | 795 | surface = std::make_shared<CachedSurface>(params); |
| 793 | LoadSurface(surface); | 796 | ReserveSurface(surface); |
| 797 | RegisterSurface(surface); | ||
| 798 | } | ||
| 799 | |||
| 800 | // Only load surface from memory if we care about the contents | ||
| 801 | if (preserve_contents) { | ||
| 802 | LoadSurface(surface); | ||
| 803 | } | ||
| 794 | 804 | ||
| 795 | return surface; | 805 | return surface; |
| 796 | } | 806 | } |
| @@ -940,6 +950,21 @@ void RasterizerCacheOpenGL::UnregisterSurface(const Surface& surface) { | |||
| 940 | surface_cache.erase(search); | 950 | surface_cache.erase(search); |
| 941 | } | 951 | } |
| 942 | 952 | ||
| 953 | void RasterizerCacheOpenGL::ReserveSurface(const Surface& surface) { | ||
| 954 | const auto& surface_reserve_key{SurfaceReserveKey::Create(surface->GetSurfaceParams())}; | ||
| 955 | surface_reserve[surface_reserve_key] = surface; | ||
| 956 | } | ||
| 957 | |||
| 958 | Surface RasterizerCacheOpenGL::TryGetReservedSurface(const SurfaceParams& params) { | ||
| 959 | const auto& surface_reserve_key{SurfaceReserveKey::Create(params)}; | ||
| 960 | auto search{surface_reserve.find(surface_reserve_key)}; | ||
| 961 | if (search != surface_reserve.end()) { | ||
| 962 | RegisterSurface(search->second); | ||
| 963 | return search->second; | ||
| 964 | } | ||
| 965 | return {}; | ||
| 966 | } | ||
| 967 | |||
| 943 | template <typename Map, typename Interval> | 968 | template <typename Map, typename Interval> |
| 944 | constexpr auto RangeFromInterval(Map& map, const Interval& interval) { | 969 | constexpr auto RangeFromInterval(Map& map, const Interval& interval) { |
| 945 | return boost::make_iterator_range(map.equal_range(interval)); | 970 | return boost::make_iterator_range(map.equal_range(interval)); |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index f273152a2..c8c615df2 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include <boost/icl/interval_map.hpp> | 11 | #include <boost/icl/interval_map.hpp> |
| 12 | 12 | ||
| 13 | #include "common/common_types.h" | 13 | #include "common/common_types.h" |
| 14 | #include "common/hash.h" | ||
| 14 | #include "common/math_util.h" | 15 | #include "common/math_util.h" |
| 15 | #include "video_core/engines/maxwell_3d.h" | 16 | #include "video_core/engines/maxwell_3d.h" |
| 16 | #include "video_core/renderer_opengl/gl_resource_manager.h" | 17 | #include "video_core/renderer_opengl/gl_resource_manager.h" |
| @@ -682,6 +683,27 @@ struct SurfaceParams { | |||
| 682 | u32 cache_height; | 683 | u32 cache_height; |
| 683 | }; | 684 | }; |
| 684 | 685 | ||
| 686 | }; // namespace OpenGL | ||
| 687 | |||
| 688 | /// Hashable variation of SurfaceParams, used for a key in the surface cache | ||
| 689 | struct SurfaceReserveKey : Common::HashableStruct<OpenGL::SurfaceParams> { | ||
| 690 | static SurfaceReserveKey Create(const OpenGL::SurfaceParams& params) { | ||
| 691 | SurfaceReserveKey res; | ||
| 692 | res.state = params; | ||
| 693 | return res; | ||
| 694 | } | ||
| 695 | }; | ||
| 696 | namespace std { | ||
| 697 | template <> | ||
| 698 | struct hash<SurfaceReserveKey> { | ||
| 699 | size_t operator()(const SurfaceReserveKey& k) const { | ||
| 700 | return k.Hash(); | ||
| 701 | } | ||
| 702 | }; | ||
| 703 | } // namespace std | ||
| 704 | |||
| 705 | namespace OpenGL { | ||
| 706 | |||
| 685 | class CachedSurface final { | 707 | class CachedSurface final { |
| 686 | public: | 708 | public: |
| 687 | CachedSurface(const SurfaceParams& params); | 709 | CachedSurface(const SurfaceParams& params); |
| @@ -752,12 +774,23 @@ private: | |||
| 752 | /// Remove surface from the cache | 774 | /// Remove surface from the cache |
| 753 | void UnregisterSurface(const Surface& surface); | 775 | void UnregisterSurface(const Surface& surface); |
| 754 | 776 | ||
| 777 | /// Reserves a unique surface that can be reused later | ||
| 778 | void ReserveSurface(const Surface& surface); | ||
| 779 | |||
| 780 | /// Tries to get a reserved surface for the specified parameters | ||
| 781 | Surface TryGetReservedSurface(const SurfaceParams& params); | ||
| 782 | |||
| 755 | /// Increase/decrease the number of surface in pages touching the specified region | 783 | /// Increase/decrease the number of surface in pages touching the specified region |
| 756 | void UpdatePagesCachedCount(Tegra::GPUVAddr addr, u64 size, int delta); | 784 | void UpdatePagesCachedCount(Tegra::GPUVAddr addr, u64 size, int delta); |
| 757 | 785 | ||
| 758 | std::unordered_map<Tegra::GPUVAddr, Surface> surface_cache; | 786 | std::unordered_map<Tegra::GPUVAddr, Surface> surface_cache; |
| 759 | PageMap cached_pages; | 787 | PageMap cached_pages; |
| 760 | 788 | ||
| 789 | /// The surface reserve is a "backup" cache, this is where we put unique surfaces that have | ||
| 790 | /// previously been used. This is to prevent surfaces from being constantly created and | ||
| 791 | /// destroyed when used with different surface parameters. | ||
| 792 | std::unordered_map<SurfaceReserveKey, Surface> surface_reserve; | ||
| 793 | |||
| 761 | OGLFramebuffer read_framebuffer; | 794 | OGLFramebuffer read_framebuffer; |
| 762 | OGLFramebuffer draw_framebuffer; | 795 | OGLFramebuffer draw_framebuffer; |
| 763 | }; | 796 | }; |