diff options
| author | 2019-06-01 19:12:00 -0400 | |
|---|---|---|
| committer | 2019-06-20 21:38:33 -0300 | |
| commit | 60bf761afbb125abd324e4b798d18a1611b5777b (patch) | |
| tree | 5321727de0bf56eacd99a3917573f36f28197ba4 /src/video_core/texture_cache | |
| parent | texture_cache uncompress-compress is untopological. (diff) | |
| download | yuzu-60bf761afbb125abd324e4b798d18a1611b5777b.tar.gz yuzu-60bf761afbb125abd324e4b798d18a1611b5777b.tar.xz yuzu-60bf761afbb125abd324e4b798d18a1611b5777b.zip | |
texture_cache: Implement Buffer Copy and detect Turing GPUs Image Copies
Diffstat (limited to 'src/video_core/texture_cache')
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 69ef7a2bd..e0d0e1f70 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -214,6 +214,13 @@ public: | |||
| 214 | } | 214 | } |
| 215 | 215 | ||
| 216 | protected: | 216 | protected: |
| 217 | // This structure is used for communicating with the backend, on which behaviors | ||
| 218 | // it supports and what not, to avoid assuming certain things about hardware. | ||
| 219 | // The backend is RESPONSIBLE for filling this settings on creation. | ||
| 220 | struct Support { | ||
| 221 | bool depth_color_image_copies; | ||
| 222 | } support_info; | ||
| 223 | |||
| 217 | TextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer) | 224 | TextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer) |
| 218 | : system{system}, rasterizer{rasterizer} { | 225 | : system{system}, rasterizer{rasterizer} { |
| 219 | for (std::size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) { | 226 | for (std::size_t i = 0; i < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets; i++) { |
| @@ -233,6 +240,10 @@ protected: | |||
| 233 | virtual void ImageBlit(TView src_view, TView dst_view, | 240 | virtual void ImageBlit(TView src_view, TView dst_view, |
| 234 | const Tegra::Engines::Fermi2D::Config& copy_config) = 0; | 241 | const Tegra::Engines::Fermi2D::Config& copy_config) = 0; |
| 235 | 242 | ||
| 243 | // Depending on the backend, a buffer copy can be slow as it means deoptimizing the texture | ||
| 244 | // and reading it from a sepparate buffer. | ||
| 245 | virtual void BufferCopy(TSurface src_surface, TSurface dst_surface) = 0; | ||
| 246 | |||
| 236 | void Register(TSurface surface) { | 247 | void Register(TSurface surface) { |
| 237 | std::lock_guard lock{mutex}; | 248 | std::lock_guard lock{mutex}; |
| 238 | 249 | ||
| @@ -377,9 +388,14 @@ private: | |||
| 377 | const SurfaceParams& params) { | 388 | const SurfaceParams& params) { |
| 378 | const auto gpu_addr = current_surface->GetGpuAddr(); | 389 | const auto gpu_addr = current_surface->GetGpuAddr(); |
| 379 | TSurface new_surface = GetUncachedSurface(gpu_addr, params); | 390 | TSurface new_surface = GetUncachedSurface(gpu_addr, params); |
| 380 | std::vector<CopyParams> bricks = current_surface->BreakDown(params); | 391 | const auto& cr_params = current_surface->GetSurfaceParams(); |
| 381 | for (auto& brick : bricks) { | 392 | if (!support_info.depth_color_image_copies && cr_params.type != params.type) { |
| 382 | ImageCopy(current_surface, new_surface, brick); | 393 | BufferCopy(current_surface, new_surface); |
| 394 | } else { | ||
| 395 | std::vector<CopyParams> bricks = current_surface->BreakDown(params); | ||
| 396 | for (auto& brick : bricks) { | ||
| 397 | ImageCopy(current_surface, new_surface, brick); | ||
| 398 | } | ||
| 383 | } | 399 | } |
| 384 | Unregister(current_surface); | 400 | Unregister(current_surface); |
| 385 | Register(new_surface); | 401 | Register(new_surface); |
| @@ -505,7 +521,8 @@ private: | |||
| 505 | auto topological_result = current_surface->MatchesTopology(params); | 521 | auto topological_result = current_surface->MatchesTopology(params); |
| 506 | if (topological_result != MatchTopologyResult::FullMatch) { | 522 | if (topological_result != MatchTopologyResult::FullMatch) { |
| 507 | std::vector<TSurface> overlaps{current_surface}; | 523 | std::vector<TSurface> overlaps{current_surface}; |
| 508 | return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, topological_result); | 524 | return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, |
| 525 | topological_result); | ||
| 509 | } | 526 | } |
| 510 | MatchStructureResult s_result = current_surface->MatchesStructure(params); | 527 | MatchStructureResult s_result = current_surface->MatchesStructure(params); |
| 511 | if (s_result != MatchStructureResult::None && | 528 | if (s_result != MatchStructureResult::None && |
| @@ -537,7 +554,8 @@ private: | |||
| 537 | for (auto surface : overlaps) { | 554 | for (auto surface : overlaps) { |
| 538 | auto topological_result = surface->MatchesTopology(params); | 555 | auto topological_result = surface->MatchesTopology(params); |
| 539 | if (topological_result != MatchTopologyResult::FullMatch) { | 556 | if (topological_result != MatchTopologyResult::FullMatch) { |
| 540 | return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, topological_result); | 557 | return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, |
| 558 | topological_result); | ||
| 541 | } | 559 | } |
| 542 | } | 560 | } |
| 543 | 561 | ||
| @@ -555,7 +573,8 @@ private: | |||
| 555 | return *view; | 573 | return *view; |
| 556 | } | 574 | } |
| 557 | } | 575 | } |
| 558 | return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, MatchTopologyResult::FullMatch); | 576 | return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, |
| 577 | MatchTopologyResult::FullMatch); | ||
| 559 | } | 578 | } |
| 560 | // Now we check if the candidate is a mipmap/layer of the overlap | 579 | // Now we check if the candidate is a mipmap/layer of the overlap |
| 561 | std::optional<TView> view = | 580 | std::optional<TView> view = |
| @@ -578,13 +597,15 @@ private: | |||
| 578 | pair.first->EmplaceView(params, gpu_addr, candidate_size); | 597 | pair.first->EmplaceView(params, gpu_addr, candidate_size); |
| 579 | if (mirage_view) | 598 | if (mirage_view) |
| 580 | return {pair.first, *mirage_view}; | 599 | return {pair.first, *mirage_view}; |
| 581 | return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, MatchTopologyResult::FullMatch); | 600 | return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, |
| 601 | MatchTopologyResult::FullMatch); | ||
| 582 | } | 602 | } |
| 583 | return {current_surface, *view}; | 603 | return {current_surface, *view}; |
| 584 | } | 604 | } |
| 585 | // The next case is unsafe, so if we r in accurate GPU, just skip it | 605 | // The next case is unsafe, so if we r in accurate GPU, just skip it |
| 586 | if (Settings::values.use_accurate_gpu_emulation) { | 606 | if (Settings::values.use_accurate_gpu_emulation) { |
| 587 | return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, MatchTopologyResult::FullMatch); | 607 | return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, |
| 608 | MatchTopologyResult::FullMatch); | ||
| 588 | } | 609 | } |
| 589 | // This is the case the texture is a part of the parent. | 610 | // This is the case the texture is a part of the parent. |
| 590 | if (current_surface->MatchesSubTexture(params, gpu_addr)) { | 611 | if (current_surface->MatchesSubTexture(params, gpu_addr)) { |
| @@ -601,7 +622,8 @@ private: | |||
| 601 | } | 622 | } |
| 602 | } | 623 | } |
| 603 | // We failed all the tests, recycle the overlaps into a new texture. | 624 | // We failed all the tests, recycle the overlaps into a new texture. |
| 604 | return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, MatchTopologyResult::FullMatch); | 625 | return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, |
| 626 | MatchTopologyResult::FullMatch); | ||
| 605 | } | 627 | } |
| 606 | 628 | ||
| 607 | std::pair<TSurface, TView> InitializeSurface(GPUVAddr gpu_addr, const SurfaceParams& params, | 629 | std::pair<TSurface, TView> InitializeSurface(GPUVAddr gpu_addr, const SurfaceParams& params, |