summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-04-15 16:17:27 -0300
committerGravatar ReinUsesLisp2019-06-20 21:36:11 -0300
commit0cefb7bcb481dc32d6362bba1976cadf25f9c95a (patch)
treedad54e28e8995e3eb4b1788225f2e26f64882570 /src
parentgl_texture_cache: Attach surface textures instead of views (diff)
downloadyuzu-0cefb7bcb481dc32d6362bba1976cadf25f9c95a.tar.gz
yuzu-0cefb7bcb481dc32d6362bba1976cadf25f9c95a.tar.xz
yuzu-0cefb7bcb481dc32d6362bba1976cadf25f9c95a.zip
gl_texture_cache: Add copy from multiple overlaps into a single surface
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.cpp54
-rw-r--r--src/video_core/renderer_opengl/gl_texture_cache.h34
-rw-r--r--src/video_core/texture_cache.cpp2
3 files changed, 84 insertions, 6 deletions
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp
index ba6d3af4b..6a6fe7cc4 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp
@@ -518,16 +518,14 @@ TextureCacheOpenGL::TextureCacheOpenGL(Core::System& system,
518TextureCacheOpenGL::~TextureCacheOpenGL() = default; 518TextureCacheOpenGL::~TextureCacheOpenGL() = default;
519 519
520CachedSurfaceView* TextureCacheOpenGL::TryFastGetSurfaceView( 520CachedSurfaceView* TextureCacheOpenGL::TryFastGetSurfaceView(
521 VAddr cpu_addr, u8* host_ptr, const SurfaceParams& params, bool preserve_contents, 521 VAddr cpu_addr, u8* host_ptr, const SurfaceParams& new_params, bool preserve_contents,
522 const std::vector<CachedSurface*>& overlaps) { 522 const std::vector<CachedSurface*>& overlaps) {
523 if (overlaps.size() > 1) { 523 if (overlaps.size() > 1) {
524 return nullptr; 524 return TryCopyAsViews(cpu_addr, host_ptr, new_params, overlaps);
525 } 525 }
526 526
527 const auto& old_surface{overlaps[0]}; 527 const auto& old_surface{overlaps[0]};
528 const auto& old_params{old_surface->GetSurfaceParams()}; 528 const auto& old_params{old_surface->GetSurfaceParams()};
529 const auto& new_params{params};
530
531 if (old_params.GetTarget() == new_params.GetTarget() && 529 if (old_params.GetTarget() == new_params.GetTarget() &&
532 old_params.GetDepth() == new_params.GetDepth() && old_params.GetDepth() == 1 && 530 old_params.GetDepth() == new_params.GetDepth() && old_params.GetDepth() == 1 &&
533 old_params.GetNumLevels() == new_params.GetNumLevels() && 531 old_params.GetNumLevels() == new_params.GetNumLevels() &&
@@ -567,6 +565,54 @@ CachedSurfaceView* TextureCacheOpenGL::SurfaceCopy(VAddr cpu_addr, u8* host_ptr,
567 return new_surface->GetView(cpu_addr, new_params); 565 return new_surface->GetView(cpu_addr, new_params);
568} 566}
569 567
568CachedSurfaceView* TextureCacheOpenGL::TryCopyAsViews(VAddr cpu_addr, u8* host_ptr,
569 const SurfaceParams& new_params,
570 const std::vector<CachedSurface*>& overlaps) {
571 if (new_params.GetTarget() == SurfaceTarget::Texture1D ||
572 new_params.GetTarget() == SurfaceTarget::Texture1DArray ||
573 new_params.GetTarget() == SurfaceTarget::Texture3D) {
574 // Non-2D textures are not handled at the moment in this fast path.
575 return nullptr;
576 }
577
578 CachedSurface* const new_surface{GetUncachedSurface(new_params)};
579 // TODO(Rodrigo): Move this down
580 Register(new_surface, cpu_addr, host_ptr);
581
582 // TODO(Rodrigo): Find a way to avoid heap allocations here.
583 std::vector<CachedSurfaceView*> views;
584 views.reserve(overlaps.size());
585 for (const auto& overlap : overlaps) {
586 const auto view{
587 new_surface->TryGetView(overlap->GetCpuAddr(), overlap->GetSurfaceParams())};
588 if (!view) {
589 // TODO(Rodrigo): Remove this
590 Unregister(new_surface);
591 return nullptr;
592 }
593 views.push_back(view);
594 }
595
596 // TODO(Rodrigo): It's possible that these method leaves some unloaded textures if the data has
597 // been uploaded to guest memory but not used as a surface previously.
598 for (std::size_t i = 0; i < overlaps.size(); ++i) {
599 const auto& overlap{overlaps[i]};
600 const auto& view{views[i]};
601 for (u32 overlap_level = 0; overlap_level < view->GetNumLevels(); ++overlap_level) {
602 const u32 super_level{view->GetBaseLevel() + overlap_level};
603 glCopyImageSubData(overlap->GetTexture(), overlap->GetTarget(), overlap_level, 0, 0, 0,
604 new_surface->GetTexture(), new_surface->GetTarget(), super_level, 0,
605 0, view->GetBaseLayer(), view->GetWidth(), view->GetHeight(),
606 view->GetNumLayers());
607 }
608 }
609
610 new_surface->MarkAsModified(true);
611
612 // TODO(Rodrigo): Add an entry to directly get the superview
613 return new_surface->GetView(cpu_addr, new_params);
614}
615
570std::unique_ptr<CachedSurface> TextureCacheOpenGL::CreateSurface(const SurfaceParams& params) { 616std::unique_ptr<CachedSurface> TextureCacheOpenGL::CreateSurface(const SurfaceParams& params) {
571 return std::make_unique<CachedSurface>(params); 617 return std::make_unique<CachedSurface>(params);
572} 618}
diff --git a/src/video_core/renderer_opengl/gl_texture_cache.h b/src/video_core/renderer_opengl/gl_texture_cache.h
index 80733ac36..86ad91dab 100644
--- a/src/video_core/renderer_opengl/gl_texture_cache.h
+++ b/src/video_core/renderer_opengl/gl_texture_cache.h
@@ -90,6 +90,34 @@ public:
90 return params; 90 return params;
91 } 91 }
92 92
93 u32 GetWidth() const {
94 return params.GetMipWidth(GetBaseLevel());
95 }
96
97 u32 GetHeight() const {
98 return params.GetMipHeight(GetBaseLevel());
99 }
100
101 u32 GetDepth() const {
102 return params.GetMipDepth(GetBaseLevel());
103 }
104
105 u32 GetBaseLayer() const {
106 return key.base_layer;
107 }
108
109 u32 GetNumLayers() const {
110 return key.num_layers;
111 }
112
113 u32 GetBaseLevel() const {
114 return key.base_level;
115 }
116
117 u32 GetNumLevels() const {
118 return key.num_levels;
119 }
120
93private: 121private:
94 struct TextureView { 122 struct TextureView {
95 OGLTexture texture; 123 OGLTexture texture;
@@ -128,7 +156,8 @@ public:
128 156
129protected: 157protected:
130 CachedSurfaceView* TryFastGetSurfaceView(VAddr cpu_addr, u8* host_ptr, 158 CachedSurfaceView* TryFastGetSurfaceView(VAddr cpu_addr, u8* host_ptr,
131 const SurfaceParams& params, bool preserve_contents, 159 const SurfaceParams& new_params,
160 bool preserve_contents,
132 const std::vector<CachedSurface*>& overlaps); 161 const std::vector<CachedSurface*>& overlaps);
133 162
134 std::unique_ptr<CachedSurface> CreateSurface(const SurfaceParams& params); 163 std::unique_ptr<CachedSurface> CreateSurface(const SurfaceParams& params);
@@ -136,6 +165,9 @@ protected:
136private: 165private:
137 CachedSurfaceView* SurfaceCopy(VAddr cpu_addr, u8* host_ptr, const SurfaceParams& new_params, 166 CachedSurfaceView* SurfaceCopy(VAddr cpu_addr, u8* host_ptr, const SurfaceParams& new_params,
138 CachedSurface* old_surface, const SurfaceParams& old_params); 167 CachedSurface* old_surface, const SurfaceParams& old_params);
168
169 CachedSurfaceView* TryCopyAsViews(VAddr cpu_addr, u8* host_ptr, const SurfaceParams& new_params,
170 const std::vector<CachedSurface*>& overlaps);
139}; 171};
140 172
141} // namespace OpenGL 173} // namespace OpenGL
diff --git a/src/video_core/texture_cache.cpp b/src/video_core/texture_cache.cpp
index 1cfb9962f..2994312f4 100644
--- a/src/video_core/texture_cache.cpp
+++ b/src/video_core/texture_cache.cpp
@@ -316,7 +316,7 @@ std::size_t SurfaceParams::GetInnerMemorySize(bool as_host_size, bool layer_only
316 size += GetInnerMipmapMemorySize(level, as_host_size, layer_only, uncompressed); 316 size += GetInnerMipmapMemorySize(level, as_host_size, layer_only, uncompressed);
317 } 317 }
318 if (is_tiled && !as_host_size) { 318 if (is_tiled && !as_host_size) {
319 //size = Common::AlignUp(size, Tegra::Texture::GetGOBSize() * block_height * block_depth); 319 size = Common::AlignUp(size, Tegra::Texture::GetGOBSize() * block_height * block_depth);
320 } 320 }
321 return size; 321 return size;
322} 322}