summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/video_core/texture_cache/surface_base.h4
-rw-r--r--src/video_core/texture_cache/texture_cache.h39
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 9d19ecd5f..58265e9d3 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 c95b1b976..022416706 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<TSurface, TView> 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<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);
}
- 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<TSurface, TView> 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<PixelFormat, PixelFormat> 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.