diff options
Diffstat (limited to '')
| -rw-r--r-- | src/video_core/texture_cache/surface_params.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/texture_cache/texture_cache.h | 49 |
2 files changed, 35 insertions, 16 deletions
diff --git a/src/video_core/texture_cache/surface_params.cpp b/src/video_core/texture_cache/surface_params.cpp index 6fe7c85ac..0b2b2b8c4 100644 --- a/src/video_core/texture_cache/surface_params.cpp +++ b/src/video_core/texture_cache/surface_params.cpp | |||
| @@ -247,7 +247,7 @@ SurfaceParams SurfaceParams::CreateForFermiCopySurface( | |||
| 247 | params.height = config.height; | 247 | params.height = config.height; |
| 248 | params.pitch = config.pitch; | 248 | params.pitch = config.pitch; |
| 249 | // TODO(Rodrigo): Try to guess texture arrays from parameters | 249 | // TODO(Rodrigo): Try to guess texture arrays from parameters |
| 250 | params.target = params.block_depth > 0 ? SurfaceTarget::Texture3D : SurfaceTarget::Texture2D; | 250 | params.target = SurfaceTarget::Texture2D; |
| 251 | params.depth = 1; | 251 | params.depth = 1; |
| 252 | params.num_levels = 1; | 252 | params.num_levels = 1; |
| 253 | params.emulated_levels = 1; | 253 | params.emulated_levels = 1; |
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index b19eeed66..b543fc8c0 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -724,10 +724,35 @@ private: | |||
| 724 | * @param params The parameters on the new surface. | 724 | * @param params The parameters on the new surface. |
| 725 | * @param gpu_addr The starting address of the new surface. | 725 | * @param gpu_addr The starting address of the new surface. |
| 726 | * @param cpu_addr The starting address of the new surface on physical memory. | 726 | * @param cpu_addr The starting address of the new surface on physical memory. |
| 727 | * @param preserve_contents Indicates that the new surface should be loaded from memory or | ||
| 728 | * left blank. | ||
| 727 | */ | 729 | */ |
| 728 | std::optional<std::pair<TSurface, TView>> Manage3DSurfaces(VectorSurface& overlaps, | 730 | std::optional<std::pair<TSurface, TView>> Manage3DSurfaces(VectorSurface& overlaps, |
| 729 | const SurfaceParams& params, | 731 | const SurfaceParams& params, |
| 730 | GPUVAddr gpu_addr, VAddr cpu_addr) { | 732 | GPUVAddr gpu_addr, VAddr cpu_addr, |
| 733 | bool preserve_contents) { | ||
| 734 | if (params.target != SurfaceTarget::Texture3D) { | ||
| 735 | for (const auto& surface : overlaps) { | ||
| 736 | if (!surface->MatchTarget(params.target)) { | ||
| 737 | if (overlaps.size() == 1 && surface->GetCpuAddr() == cpu_addr) { | ||
| 738 | if (Settings::IsGPULevelExtreme()) { | ||
| 739 | return std::nullopt; | ||
| 740 | } | ||
| 741 | Unregister(surface); | ||
| 742 | return InitializeSurface(gpu_addr, params, preserve_contents); | ||
| 743 | } | ||
| 744 | return std::nullopt; | ||
| 745 | } | ||
| 746 | if (surface->GetCpuAddr() != cpu_addr) { | ||
| 747 | continue; | ||
| 748 | } | ||
| 749 | if (surface->MatchesStructure(params) == MatchStructureResult::FullMatch) { | ||
| 750 | return std::make_pair(surface, surface->GetMainView()); | ||
| 751 | } | ||
| 752 | } | ||
| 753 | return InitializeSurface(gpu_addr, params, preserve_contents); | ||
| 754 | } | ||
| 755 | |||
| 731 | if (params.num_levels > 1) { | 756 | if (params.num_levels > 1) { |
| 732 | // We can't handle mipmaps in 3D textures yet, better fallback to LLE approach | 757 | // We can't handle mipmaps in 3D textures yet, better fallback to LLE approach |
| 733 | return std::nullopt; | 758 | return std::nullopt; |
| @@ -748,25 +773,18 @@ private: | |||
| 748 | } | 773 | } |
| 749 | } | 774 | } |
| 750 | 775 | ||
| 751 | if (params.depth == 1) { | ||
| 752 | return std::nullopt; | ||
| 753 | } | ||
| 754 | |||
| 755 | TSurface new_surface = GetUncachedSurface(gpu_addr, params); | 776 | TSurface new_surface = GetUncachedSurface(gpu_addr, params); |
| 756 | LoadSurface(new_surface); | ||
| 757 | |||
| 758 | bool modified = false; | 777 | bool modified = false; |
| 778 | |||
| 759 | for (auto& surface : overlaps) { | 779 | for (auto& surface : overlaps) { |
| 760 | const SurfaceParams& src_params = surface->GetSurfaceParams(); | 780 | const SurfaceParams& src_params = surface->GetSurfaceParams(); |
| 761 | if (src_params.height != params.height || | 781 | if (src_params.target != SurfaceTarget::Texture2D || |
| 782 | src_params.height != params.height || | ||
| 762 | src_params.block_depth != params.block_depth || | 783 | src_params.block_depth != params.block_depth || |
| 763 | src_params.block_height != params.block_height) { | 784 | src_params.block_height != params.block_height) { |
| 764 | return std::nullopt; | 785 | return std::nullopt; |
| 765 | } | 786 | } |
| 766 | if (!surface->IsModified()) { | 787 | modified |= surface->IsModified(); |
| 767 | continue; | ||
| 768 | } | ||
| 769 | modified = true; | ||
| 770 | 788 | ||
| 771 | const u32 offset = static_cast<u32>(surface->GetCpuAddr() - cpu_addr); | 789 | const u32 offset = static_cast<u32>(surface->GetCpuAddr() - cpu_addr); |
| 772 | const u32 slice = std::get<2>(params.GetBlockOffsetXYZ(offset)); | 790 | const u32 slice = std::get<2>(params.GetBlockOffsetXYZ(offset)); |
| @@ -781,7 +799,7 @@ private: | |||
| 781 | new_surface->MarkAsModified(modified, Tick()); | 799 | new_surface->MarkAsModified(modified, Tick()); |
| 782 | Register(new_surface); | 800 | Register(new_surface); |
| 783 | 801 | ||
| 784 | auto view = new_surface->GetMainView(); | 802 | TView view = new_surface->GetMainView(); |
| 785 | return std::make_pair(std::move(new_surface), std::move(view)); | 803 | return std::make_pair(std::move(new_surface), std::move(view)); |
| 786 | } | 804 | } |
| 787 | 805 | ||
| @@ -861,8 +879,9 @@ private: | |||
| 861 | } | 879 | } |
| 862 | 880 | ||
| 863 | // Manage 3D textures | 881 | // Manage 3D textures |
| 864 | if (params.target == SurfaceTarget::Texture3D) { | 882 | if (params.block_depth > 0) { |
| 865 | auto surface = Manage3DSurfaces(overlaps, params, gpu_addr, cpu_addr); | 883 | auto surface = |
| 884 | Manage3DSurfaces(overlaps, params, gpu_addr, cpu_addr, preserve_contents); | ||
| 866 | if (surface) { | 885 | if (surface) { |
| 867 | return *surface; | 886 | return *surface; |
| 868 | } | 887 | } |