diff options
| author | 2019-04-15 16:17:27 -0300 | |
|---|---|---|
| committer | 2019-06-20 21:36:11 -0300 | |
| commit | 0cefb7bcb481dc32d6362bba1976cadf25f9c95a (patch) | |
| tree | dad54e28e8995e3eb4b1788225f2e26f64882570 /src | |
| parent | gl_texture_cache: Attach surface textures instead of views (diff) | |
| download | yuzu-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.cpp | 54 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.h | 34 | ||||
| -rw-r--r-- | src/video_core/texture_cache.cpp | 2 |
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, | |||
| 518 | TextureCacheOpenGL::~TextureCacheOpenGL() = default; | 518 | TextureCacheOpenGL::~TextureCacheOpenGL() = default; |
| 519 | 519 | ||
| 520 | CachedSurfaceView* TextureCacheOpenGL::TryFastGetSurfaceView( | 520 | CachedSurfaceView* 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 | ||
| 568 | CachedSurfaceView* 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 | |||
| 570 | std::unique_ptr<CachedSurface> TextureCacheOpenGL::CreateSurface(const SurfaceParams& params) { | 616 | std::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 | |||
| 93 | private: | 121 | private: |
| 94 | struct TextureView { | 122 | struct TextureView { |
| 95 | OGLTexture texture; | 123 | OGLTexture texture; |
| @@ -128,7 +156,8 @@ public: | |||
| 128 | 156 | ||
| 129 | protected: | 157 | protected: |
| 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: | |||
| 136 | private: | 165 | private: |
| 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 | } |