summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/texture_cache/surface_params.cpp2
-rw-r--r--src/video_core/texture_cache/texture_cache.h49
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 }