texture_cache: Corrections, documentation and asserts
This commit is contained in:
		| @@ -60,10 +60,10 @@ public: | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|     /*** | ||||
|      * `Guard` guarantees that rendertargets don't unregister themselves if the | ||||
|      * collide. Protection is currently only done on 3D slices. | ||||
|      **/ | ||||
|      ***/ | ||||
|     void GuardRenderTargets(bool new_guard) { | ||||
|         guard_render_targets = new_guard; | ||||
|     } | ||||
| @@ -191,19 +191,21 @@ public: | ||||
|     } | ||||
|  | ||||
|     void SetEmptyDepthBuffer() { | ||||
|         if (depth_buffer.target != nullptr) { | ||||
|             depth_buffer.target->MarkAsRenderTarget(false); | ||||
|             depth_buffer.target = nullptr; | ||||
|             depth_buffer.view = nullptr; | ||||
|         if (depth_buffer.target == nullptr) { | ||||
|             return; | ||||
|         } | ||||
|         depth_buffer.target->MarkAsRenderTarget(false); | ||||
|         depth_buffer.target = nullptr; | ||||
|         depth_buffer.view = nullptr; | ||||
|     } | ||||
|  | ||||
|     void SetEmptyColorBuffer(std::size_t index) { | ||||
|         if (render_targets[index].target != nullptr) { | ||||
|             render_targets[index].target->MarkAsRenderTarget(false); | ||||
|             render_targets[index].target = nullptr; | ||||
|             render_targets[index].view = nullptr; | ||||
|         if (render_targets[index].target == nullptr) { | ||||
|             return; | ||||
|         } | ||||
|         render_targets[index].target->MarkAsRenderTarget(false); | ||||
|         render_targets[index].target = nullptr; | ||||
|         render_targets[index].view = nullptr; | ||||
|     } | ||||
|  | ||||
|     void DoFermiCopy(const Tegra::Engines::Fermi2D::Regs::Surface& src_config, | ||||
| @@ -283,8 +285,8 @@ protected: | ||||
|                          gpu_addr); | ||||
|             return; | ||||
|         } | ||||
|         bool continuouty = system.GPU().MemoryManager().IsBlockContinuous(gpu_addr, size); | ||||
|         surface->MarkAsContinuous(continuouty); | ||||
|         const bool continuous = system.GPU().MemoryManager().IsBlockContinuous(gpu_addr, size); | ||||
|         surface->MarkAsContinuous(continuous); | ||||
|         surface->SetCacheAddr(cache_ptr); | ||||
|         surface->SetCpuAddr(*cpu_addr); | ||||
|         RegisterInnerCache(surface); | ||||
| @@ -381,8 +383,8 @@ private: | ||||
|                                               const SurfaceParams& params, const GPUVAddr gpu_addr, | ||||
|                                               const bool preserve_contents, | ||||
|                                               const MatchTopologyResult untopological) { | ||||
|         const bool do_load = Settings::values.use_accurate_gpu_emulation && preserve_contents; | ||||
|         for (auto surface : overlaps) { | ||||
|         const bool do_load = preserve_contents && Settings::values.use_accurate_gpu_emulation; | ||||
|         for (auto& surface : overlaps) { | ||||
|             Unregister(surface); | ||||
|         } | ||||
|         switch (PickStrategy(overlaps, params, gpu_addr, untopological)) { | ||||
| @@ -394,7 +396,7 @@ private: | ||||
|                       [](const TSurface& a, const TSurface& b) -> bool { | ||||
|                           return a->GetModificationTick() < b->GetModificationTick(); | ||||
|                       }); | ||||
|             for (auto surface : overlaps) { | ||||
|             for (auto& surface : overlaps) { | ||||
|                 FlushSurface(surface); | ||||
|             } | ||||
|             return InitializeSurface(gpu_addr, params, preserve_contents); | ||||
| @@ -460,19 +462,19 @@ private: | ||||
|                                                      const SurfaceParams& params, bool is_render) { | ||||
|         const bool is_mirage = !current_surface->MatchFormat(params.pixel_format); | ||||
|         const bool matches_target = current_surface->MatchTarget(params.target); | ||||
|         auto match_check = ([&]() -> std::pair<TSurface, TView> { | ||||
|         const auto match_check = ([&]() -> std::pair<TSurface, TView> { | ||||
|             if (matches_target) { | ||||
|                 return {current_surface, current_surface->GetMainView()}; | ||||
|             } | ||||
|             return {current_surface, current_surface->EmplaceOverview(params)}; | ||||
|         }); | ||||
|         if (is_mirage) { | ||||
|             if (!is_render && siblings_table[current_surface->GetFormat()] == params.pixel_format) { | ||||
|                 return match_check(); | ||||
|             } | ||||
|             return RebuildSurface(current_surface, params, is_render); | ||||
|         if (!is_mirage) { | ||||
|             return match_check(); | ||||
|         } | ||||
|         return match_check(); | ||||
|         if (!is_render && siblings_table[current_surface->GetFormat()] == params.pixel_format) { | ||||
|             return match_check(); | ||||
|         } | ||||
|         return RebuildSurface(current_surface, params, is_render); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -493,7 +495,7 @@ private: | ||||
|         bool modified = false; | ||||
|         TSurface new_surface = GetUncachedSurface(gpu_addr, params); | ||||
|         u32 passed_tests = 0; | ||||
|         for (auto surface : overlaps) { | ||||
|         for (auto& surface : overlaps) { | ||||
|             const SurfaceParams& src_params = surface->GetSurfaceParams(); | ||||
|             if (src_params.is_layered || src_params.num_levels > 1) { | ||||
|                 // We send this cases to recycle as they are more complex to handle | ||||
| @@ -504,8 +506,7 @@ private: | ||||
|             if (!mipmap_layer) { | ||||
|                 continue; | ||||
|             } | ||||
|             const u32 layer{mipmap_layer->first}; | ||||
|             const u32 mipmap{mipmap_layer->second}; | ||||
|             const auto [layer, mipmap] = *mipmap_layer; | ||||
|             if (new_surface->GetMipmapSize(mipmap) != candidate_size) { | ||||
|                 continue; | ||||
|             } | ||||
| @@ -519,7 +520,7 @@ private: | ||||
|         } | ||||
|         if (passed_tests == 0) { | ||||
|             return {}; | ||||
|             // In Accurate GPU all test should pass, else we recycle | ||||
|             // In Accurate GPU all tests should pass, else we recycle | ||||
|         } else if (Settings::values.use_accurate_gpu_emulation && passed_tests != overlaps.size()) { | ||||
|             return {}; | ||||
|         } | ||||
| @@ -548,7 +549,6 @@ private: | ||||
|      **/ | ||||
|     std::pair<TSurface, TView> GetSurface(const GPUVAddr gpu_addr, const SurfaceParams& params, | ||||
|                                           bool preserve_contents, bool is_render) { | ||||
|  | ||||
|         const auto host_ptr{system.GPU().MemoryManager().GetPointer(gpu_addr)}; | ||||
|         const auto cache_addr{ToCacheAddr(host_ptr)}; | ||||
|  | ||||
| @@ -570,17 +570,17 @@ private: | ||||
|         auto iter = l1_cache.find(cache_addr); | ||||
|         if (iter != l1_cache.end()) { | ||||
|             TSurface& current_surface = iter->second; | ||||
|             auto topological_result = current_surface->MatchesTopology(params); | ||||
|             const auto topological_result = current_surface->MatchesTopology(params); | ||||
|             if (topological_result != MatchTopologyResult::FullMatch) { | ||||
|                 std::vector<TSurface> overlaps{current_surface}; | ||||
|                 return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, | ||||
|                                       topological_result); | ||||
|             } | ||||
|             MatchStructureResult s_result = current_surface->MatchesStructure(params); | ||||
|             if (s_result != MatchStructureResult::None && | ||||
|             const auto struct_result = current_surface->MatchesStructure(params); | ||||
|             if (struct_result != MatchStructureResult::None && | ||||
|                 (params.target != SurfaceTarget::Texture3D || | ||||
|                  current_surface->MatchTarget(params.target))) { | ||||
|                 if (s_result == MatchStructureResult::FullMatch) { | ||||
|                 if (struct_result == MatchStructureResult::FullMatch) { | ||||
|                     return ManageStructuralMatch(current_surface, params, is_render); | ||||
|                 } else { | ||||
|                     return RebuildSurface(current_surface, params, is_render); | ||||
| @@ -602,8 +602,8 @@ private: | ||||
|         // Now we need to figure the relationship between the texture and its overlaps | ||||
|         // we do a topological test to ensure we can find some relationship. If it fails | ||||
|         // inmediatly recycle the texture | ||||
|         for (auto surface : overlaps) { | ||||
|             auto topological_result = surface->MatchesTopology(params); | ||||
|         for (const auto& surface : overlaps) { | ||||
|             const auto topological_result = surface->MatchesTopology(params); | ||||
|             if (topological_result != MatchTopologyResult::FullMatch) { | ||||
|                 return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, | ||||
|                                       topological_result); | ||||
| @@ -620,7 +620,7 @@ private: | ||||
|                 if (current_surface->GetGpuAddr() == gpu_addr) { | ||||
|                     std::optional<std::pair<TSurface, TView>> view = | ||||
|                         TryReconstructSurface(overlaps, params, gpu_addr); | ||||
|                     if (view.has_value()) { | ||||
|                     if (view) { | ||||
|                         return *view; | ||||
|                     } | ||||
|                 } | ||||
| @@ -630,7 +630,7 @@ private: | ||||
|             // Now we check if the candidate is a mipmap/layer of the overlap | ||||
|             std::optional<TView> view = | ||||
|                 current_surface->EmplaceView(params, gpu_addr, candidate_size); | ||||
|             if (view.has_value()) { | ||||
|             if (view) { | ||||
|                 const bool is_mirage = !current_surface->MatchFormat(params.pixel_format); | ||||
|                 if (is_mirage) { | ||||
|                     // On a mirage view, we need to recreate the surface under this new view | ||||
| @@ -669,7 +669,7 @@ private: | ||||
|             // using the overlaps. If a single overlap fails, this will fail. | ||||
|             std::optional<std::pair<TSurface, TView>> view = | ||||
|                 TryReconstructSurface(overlaps, params, gpu_addr); | ||||
|             if (view.has_value()) { | ||||
|             if (view) { | ||||
|                 return *view; | ||||
|             } | ||||
|         } | ||||
| @@ -738,16 +738,16 @@ private: | ||||
|         std::vector<TSurface> surfaces; | ||||
|         while (start <= end) { | ||||
|             std::vector<TSurface>& list = registry[start]; | ||||
|             for (auto& s : list) { | ||||
|                 if (!s->IsPicked() && s->Overlaps(cache_addr, cache_addr_end)) { | ||||
|                     s->MarkAsPicked(true); | ||||
|                     surfaces.push_back(s); | ||||
|             for (auto& surface : list) { | ||||
|                 if (!surface->IsPicked() && surface->Overlaps(cache_addr, cache_addr_end)) { | ||||
|                     surface->MarkAsPicked(true); | ||||
|                     surfaces.push_back(surface); | ||||
|                 } | ||||
|             } | ||||
|             start++; | ||||
|         } | ||||
|         for (auto& s : surfaces) { | ||||
|             s->MarkAsPicked(false); | ||||
|         for (auto& surface : surfaces) { | ||||
|             surface->MarkAsPicked(false); | ||||
|         } | ||||
|         return surfaces; | ||||
|     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Fernando Sahmkow
					Fernando Sahmkow