From 2d83553ea7ab2629e7e1a83cc3345c0115d69453 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Thu, 13 Jun 2019 09:46:36 -0400 Subject: [PATCH] texture_cache: Implement siblings texture formats. --- src/video_core/texture_cache/surface_base.h | 4 ++ src/video_core/texture_cache/texture_cache.h | 39 ++++++++++++++------ 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/video_core/texture_cache/surface_base.h b/src/video_core/texture_cache/surface_base.h index 9d19ecd5fe..58265e9d39 100644 --- a/src/video_core/texture_cache/surface_base.h +++ b/src/video_core/texture_cache/surface_base.h @@ -132,6 +132,10 @@ public: return params.pixel_format == pixel_format; } + VideoCore::Surface::PixelFormat GetFormat() const { + return params.pixel_format; + } + bool MatchTarget(VideoCore::Surface::SurfaceTarget target) const { return params.target == target; } diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index c95b1b9764..0224167060 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -43,6 +43,8 @@ class RasterizerInterface; namespace VideoCommon { +using VideoCore::Surface::PixelFormat; + using VideoCore::Surface::SurfaceTarget; using RenderTargetConfig = Tegra::Engines::Maxwell3D::Regs::RenderTargetConfig; @@ -96,7 +98,7 @@ public: return {}; } const auto params{SurfaceParams::CreateForTexture(system, config, entry)}; - return GetSurface(gpu_addr, params, true).second; + return GetSurface(gpu_addr, params, true, false).second; } TView GetDepthBufferSurface(bool preserve_contents) { @@ -118,7 +120,7 @@ public: system, regs.zeta_width, regs.zeta_height, regs.zeta.format, regs.zeta.memory_layout.block_width, regs.zeta.memory_layout.block_height, regs.zeta.memory_layout.block_depth, regs.zeta.memory_layout.type)}; - auto surface_view = GetSurface(gpu_addr, depth_params, preserve_contents); + auto surface_view = GetSurface(gpu_addr, depth_params, preserve_contents, true); if (depth_buffer.target) depth_buffer.target->MarkAsRenderTarget(false); depth_buffer.target = surface_view.first; @@ -152,7 +154,7 @@ public: } auto surface_view = GetSurface(gpu_addr, SurfaceParams::CreateForFramebuffer(system, index), - preserve_contents); + preserve_contents, true); if (render_targets[index].target) render_targets[index].target->MarkAsRenderTarget(false); render_targets[index].target = surface_view.first; @@ -226,6 +228,11 @@ protected: } SetEmptyDepthBuffer(); staging_cache.SetSize(2); + siblings_table[PixelFormat::Z16] = PixelFormat::R16F; + siblings_table[PixelFormat::Z32F] = PixelFormat::R32F; + siblings_table[PixelFormat::Z32FS8] = PixelFormat::RG32F; + siblings_table[PixelFormat::R16F] = PixelFormat::Z16; + siblings_table[PixelFormat::R32F] = PixelFormat::Z32F; } ~TextureCache() = default; @@ -289,7 +296,7 @@ protected: const Tegra::Engines::Fermi2D::Regs::Surface& config) { SurfaceParams params = SurfaceParams::CreateForFermiCopySurface(config); const GPUVAddr gpu_addr = config.Address(); - return GetSurface(gpu_addr, params, true); + return GetSurface(gpu_addr, params, true, false); } Core::System& system; @@ -406,16 +413,22 @@ private: * @param params, the new surface params which we want to check. **/ std::pair ManageStructuralMatch(TSurface current_surface, - const SurfaceParams& params) { + 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 { + 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); } - const bool matches_target = current_surface->MatchTarget(params.target); - if (matches_target) { - return {current_surface, current_surface->GetMainView()}; - } - return {current_surface, current_surface->EmplaceOverview(params)}; + return match_check(); } /** @@ -490,7 +503,7 @@ private: * @param preserve_contents, tells if the new surface should be loaded from meory or left blank. **/ std::pair GetSurface(const GPUVAddr gpu_addr, const SurfaceParams& params, - bool preserve_contents) { + bool preserve_contents, bool is_render) { const auto host_ptr{memory_manager->GetPointer(gpu_addr)}; const auto cache_addr{ToCacheAddr(host_ptr)}; @@ -524,7 +537,7 @@ private: (params.target != SurfaceTarget::Texture3D || current_surface->MatchTarget(params.target))) { if (s_result == MatchStructureResult::FullMatch) { - return ManageStructuralMatch(current_surface, params); + return ManageStructuralMatch(current_surface, params, is_render); } else { return RebuildSurface(current_surface, params); } @@ -724,6 +737,8 @@ private: // Guards the cache for protection conflicts. bool guard_cache{}; + std::unordered_map siblings_table; + // The internal Cache is different for the Texture Cache. It's based on buckets // of 1MB. This fits better for the purpose of this cache as textures are normaly // large in size.