From 94b0e2e5dae4e0bd0021ac2d8fe1ff904a93ee69 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sat, 11 Apr 2020 01:50:58 -0300 Subject: [PATCH] texture_cache: Remove preserve_contents preserve_contents was always true. We can't assume we don't have to preserve clears because scissored and color masked clears exist. This removes preserve_contents and assumes it as true at all times. --- .../renderer_opengl/gl_rasterizer.cpp | 8 +-- .../renderer_vulkan/vk_rasterizer.cpp | 4 +- src/video_core/texture_cache/texture_cache.h | 66 +++++++------------ 3 files changed, 31 insertions(+), 47 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 368f399df..c6ff4e27f 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -345,7 +345,7 @@ void RasterizerOpenGL::ConfigureFramebuffers() { texture_cache.GuardRenderTargets(true); - View depth_surface = texture_cache.GetDepthBufferSurface(true); + View depth_surface = texture_cache.GetDepthBufferSurface(); const auto& regs = gpu.regs; UNIMPLEMENTED_IF(regs.rt_separate_frag_data == 0); @@ -354,7 +354,7 @@ void RasterizerOpenGL::ConfigureFramebuffers() { FramebufferCacheKey key; const auto colors_count = static_cast(regs.rt_control.count); for (std::size_t index = 0; index < colors_count; ++index) { - View color_surface{texture_cache.GetColorBufferSurface(index, true)}; + View color_surface{texture_cache.GetColorBufferSurface(index)}; if (!color_surface) { continue; } @@ -387,12 +387,12 @@ void RasterizerOpenGL::ConfigureClearFramebuffer(bool using_color_fb, bool using View color_surface; if (using_color_fb) { const std::size_t index = regs.clear_buffers.RT; - color_surface = texture_cache.GetColorBufferSurface(index, true); + color_surface = texture_cache.GetColorBufferSurface(index); texture_cache.MarkColorBufferInUse(index); } View depth_surface; if (using_depth_fb || using_stencil_fb) { - depth_surface = texture_cache.GetDepthBufferSurface(true); + depth_surface = texture_cache.GetDepthBufferSurface(); texture_cache.MarkDepthBufferInUse(); } texture_cache.GuardRenderTargets(false); diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 0a2ea4fd4..6b99cbbbc 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -599,7 +599,7 @@ RasterizerVulkan::Texceptions RasterizerVulkan::UpdateAttachments() { Texceptions texceptions; for (std::size_t rt = 0; rt < Maxwell::NumRenderTargets; ++rt) { if (update_rendertargets) { - color_attachments[rt] = texture_cache.GetColorBufferSurface(rt, true); + color_attachments[rt] = texture_cache.GetColorBufferSurface(rt); } if (color_attachments[rt] && WalkAttachmentOverlaps(*color_attachments[rt])) { texceptions[rt] = true; @@ -607,7 +607,7 @@ RasterizerVulkan::Texceptions RasterizerVulkan::UpdateAttachments() { } if (update_rendertargets) { - zeta_attachment = texture_cache.GetDepthBufferSurface(true); + zeta_attachment = texture_cache.GetDepthBufferSurface(); } if (zeta_attachment && WalkAttachmentOverlaps(*zeta_attachment)) { texceptions[ZETA_TEXCEPTION_INDEX] = true; diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 88fe3e25f..cfc7fe6e9 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -108,7 +108,7 @@ public: } const auto params{SurfaceParams::CreateForTexture(format_lookup_table, tic, entry)}; - const auto [surface, view] = GetSurface(gpu_addr, *cpu_addr, params, true, false); + const auto [surface, view] = GetSurface(gpu_addr, *cpu_addr, params, false); if (guard_samplers) { sampled_textures.push_back(surface); } @@ -128,7 +128,7 @@ public: return GetNullSurface(SurfaceParams::ExpectedTarget(entry)); } const auto params{SurfaceParams::CreateForImage(format_lookup_table, tic, entry)}; - const auto [surface, view] = GetSurface(gpu_addr, *cpu_addr, params, true, false); + const auto [surface, view] = GetSurface(gpu_addr, *cpu_addr, params, false); if (guard_samplers) { sampled_textures.push_back(surface); } @@ -143,7 +143,7 @@ public: return any_rt; } - TView GetDepthBufferSurface(bool preserve_contents) { + TView GetDepthBufferSurface() { std::lock_guard lock{mutex}; auto& maxwell3d = system.GPU().Maxwell3D(); if (!maxwell3d.dirty.flags[VideoCommon::Dirty::ZetaBuffer]) { @@ -164,7 +164,7 @@ public: return {}; } const auto depth_params{SurfaceParams::CreateForDepthBuffer(system)}; - auto surface_view = GetSurface(gpu_addr, *cpu_addr, depth_params, preserve_contents, true); + auto surface_view = GetSurface(gpu_addr, *cpu_addr, depth_params, true); if (depth_buffer.target) depth_buffer.target->MarkAsRenderTarget(false, NO_RT); depth_buffer.target = surface_view.first; @@ -174,7 +174,7 @@ public: return surface_view.second; } - TView GetColorBufferSurface(std::size_t index, bool preserve_contents) { + TView GetColorBufferSurface(std::size_t index) { std::lock_guard lock{mutex}; ASSERT(index < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets); auto& maxwell3d = system.GPU().Maxwell3D(); @@ -204,9 +204,8 @@ public: return {}; } - auto surface_view = - GetSurface(gpu_addr, *cpu_addr, SurfaceParams::CreateForFramebuffer(system, index), - preserve_contents, true); + auto surface_view = GetSurface(gpu_addr, *cpu_addr, + SurfaceParams::CreateForFramebuffer(system, index), true); if (render_targets[index].target) render_targets[index].target->MarkAsRenderTarget(false, NO_RT); render_targets[index].target = surface_view.first; @@ -260,9 +259,9 @@ public: const std::optional src_cpu_addr = system.GPU().MemoryManager().GpuToCpuAddress(src_gpu_addr); std::pair dst_surface = - GetSurface(dst_gpu_addr, *dst_cpu_addr, dst_params, true, false); + GetSurface(dst_gpu_addr, *dst_cpu_addr, dst_params, false); std::pair src_surface = - GetSurface(src_gpu_addr, *src_cpu_addr, src_params, true, false); + GetSurface(src_gpu_addr, *src_cpu_addr, src_params, false); ImageBlit(src_surface.second, dst_surface.second, copy_config); dst_surface.first->MarkAsModified(true, Tick()); } @@ -451,22 +450,18 @@ private: * @param overlaps The overlapping surfaces registered in the cache. * @param params The parameters for the new surface. * @param gpu_addr The starting address of the new surface. - * @param preserve_contents Indicates that the new surface should be loaded from memory or left - * blank. * @param untopological Indicates to the recycler that the texture has no way to match the * overlaps due to topological reasons. **/ std::pair RecycleSurface(std::vector& overlaps, const SurfaceParams& params, const GPUVAddr gpu_addr, - const bool preserve_contents, const MatchTopologyResult untopological) { - 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)) { case RecycleStrategy::Ignore: { - return InitializeSurface(gpu_addr, params, do_load); + return InitializeSurface(gpu_addr, params, Settings::values.use_accurate_gpu_emulation); } case RecycleStrategy::Flush: { std::sort(overlaps.begin(), overlaps.end(), @@ -476,7 +471,7 @@ private: for (auto& surface : overlaps) { FlushSurface(surface); } - return InitializeSurface(gpu_addr, params, preserve_contents); + return InitializeSurface(gpu_addr, params); } case RecycleStrategy::BufferCopy: { auto new_surface = GetUncachedSurface(gpu_addr, params); @@ -485,7 +480,7 @@ private: } default: { UNIMPLEMENTED_MSG("Unimplemented Texture Cache Recycling Strategy!"); - return InitializeSurface(gpu_addr, params, do_load); + return InitializeSurface(gpu_addr, params); } } } @@ -621,14 +616,11 @@ private: * @param params The parameters on the new surface. * @param gpu_addr The starting address of the new surface. * @param cache_addr The starting address of the new surface on physical memory. - * @param preserve_contents Indicates that the new surface should be loaded from memory or - * left blank. */ std::optional> Manage3DSurfaces(std::vector& overlaps, const SurfaceParams& params, const GPUVAddr gpu_addr, - const VAddr cpu_addr, - bool preserve_contents) { + const VAddr cpu_addr) { if (params.target == SurfaceTarget::Texture3D) { bool failed = false; if (params.num_levels > 1) { @@ -677,7 +669,7 @@ private: return std::nullopt; } Unregister(surface); - return InitializeSurface(gpu_addr, params, preserve_contents); + return InitializeSurface(gpu_addr, params); } return std::nullopt; } @@ -688,7 +680,7 @@ private: return {{surface, surface->GetMainView()}}; } } - return InitializeSurface(gpu_addr, params, preserve_contents); + return InitializeSurface(gpu_addr, params); } } @@ -711,13 +703,10 @@ private: * * @param gpu_addr The starting address of the candidate surface. * @param params The parameters on the candidate surface. - * @param preserve_contents Indicates that the new surface should be loaded from memory or - * left blank. * @param is_render Whether or not the surface is a render target. **/ std::pair GetSurface(const GPUVAddr gpu_addr, const VAddr cpu_addr, - const SurfaceParams& params, bool preserve_contents, - bool is_render) { + const SurfaceParams& params, bool is_render) { // Step 1 // Check Level 1 Cache for a fast structural match. If candidate surface // matches at certain level we are pretty much done. @@ -726,8 +715,7 @@ private: const auto topological_result = current_surface->MatchesTopology(params); if (topological_result != MatchTopologyResult::FullMatch) { std::vector overlaps{current_surface}; - return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, - topological_result); + return RecycleSurface(overlaps, params, gpu_addr, topological_result); } const auto struct_result = current_surface->MatchesStructure(params); @@ -752,7 +740,7 @@ private: // If none are found, we are done. we just load the surface and create it. if (overlaps.empty()) { - return InitializeSurface(gpu_addr, params, preserve_contents); + return InitializeSurface(gpu_addr, params); } // Step 3 @@ -762,15 +750,13 @@ private: 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); + return RecycleSurface(overlaps, params, gpu_addr, topological_result); } } // Check if it's a 3D texture if (params.block_depth > 0) { - auto surface = - Manage3DSurfaces(overlaps, params, gpu_addr, cpu_addr, preserve_contents); + auto surface = Manage3DSurfaces(overlaps, params, gpu_addr, cpu_addr); if (surface) { return *surface; } @@ -790,8 +776,7 @@ private: return *view; } } - return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, - MatchTopologyResult::FullMatch); + return RecycleSurface(overlaps, params, gpu_addr, MatchTopologyResult::FullMatch); } // Now we check if the candidate is a mipmap/layer of the overlap std::optional view = @@ -815,7 +800,7 @@ private: pair.first->EmplaceView(params, gpu_addr, candidate_size); if (mirage_view) return {pair.first, *mirage_view}; - return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, + return RecycleSurface(overlaps, params, gpu_addr, MatchTopologyResult::FullMatch); } return {current_surface, *view}; @@ -831,8 +816,7 @@ private: } } // We failed all the tests, recycle the overlaps into a new texture. - return RecycleSurface(overlaps, params, gpu_addr, preserve_contents, - MatchTopologyResult::FullMatch); + return RecycleSurface(overlaps, params, gpu_addr, MatchTopologyResult::FullMatch); } /** @@ -990,10 +974,10 @@ private: } std::pair InitializeSurface(GPUVAddr gpu_addr, const SurfaceParams& params, - bool preserve_contents) { + bool do_load = true) { auto new_surface{GetUncachedSurface(gpu_addr, params)}; Register(new_surface); - if (preserve_contents) { + if (do_load) { LoadSurface(new_surface); } return {new_surface, new_surface->GetMainView()};