summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp31
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h33
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
953void RasterizerCacheOpenGL::ReserveSurface(const Surface& surface) {
954 const auto& surface_reserve_key{SurfaceReserveKey::Create(surface->GetSurfaceParams())};
955 surface_reserve[surface_reserve_key] = surface;
956}
957
958Surface 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
943template <typename Map, typename Interval> 968template <typename Map, typename Interval>
944constexpr auto RangeFromInterval(Map& map, const Interval& interval) { 969constexpr 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
689struct 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};
696namespace std {
697template <>
698struct hash<SurfaceReserveKey> {
699 size_t operator()(const SurfaceReserveKey& k) const {
700 return k.Hash();
701 }
702};
703} // namespace std
704
705namespace OpenGL {
706
685class CachedSurface final { 707class CachedSurface final {
686public: 708public:
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};