texture_cache: Implement siblings texture formats.

This commit is contained in:
Fernando Sahmkow 2019-06-13 09:46:36 -04:00 committed by ReinUsesLisp
parent cb728797b0
commit 2d83553ea7
2 changed files with 31 additions and 12 deletions

View File

@ -132,6 +132,10 @@ public:
return params.pixel_format == pixel_format; return params.pixel_format == pixel_format;
} }
VideoCore::Surface::PixelFormat GetFormat() const {
return params.pixel_format;
}
bool MatchTarget(VideoCore::Surface::SurfaceTarget target) const { bool MatchTarget(VideoCore::Surface::SurfaceTarget target) const {
return params.target == target; return params.target == target;
} }

View File

@ -43,6 +43,8 @@ class RasterizerInterface;
namespace VideoCommon { namespace VideoCommon {
using VideoCore::Surface::PixelFormat;
using VideoCore::Surface::SurfaceTarget; using VideoCore::Surface::SurfaceTarget;
using RenderTargetConfig = Tegra::Engines::Maxwell3D::Regs::RenderTargetConfig; using RenderTargetConfig = Tegra::Engines::Maxwell3D::Regs::RenderTargetConfig;
@ -96,7 +98,7 @@ public:
return {}; return {};
} }
const auto params{SurfaceParams::CreateForTexture(system, config, entry)}; 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) { TView GetDepthBufferSurface(bool preserve_contents) {
@ -118,7 +120,7 @@ public:
system, regs.zeta_width, regs.zeta_height, regs.zeta.format, 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_width, regs.zeta.memory_layout.block_height,
regs.zeta.memory_layout.block_depth, regs.zeta.memory_layout.type)}; 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) if (depth_buffer.target)
depth_buffer.target->MarkAsRenderTarget(false); depth_buffer.target->MarkAsRenderTarget(false);
depth_buffer.target = surface_view.first; depth_buffer.target = surface_view.first;
@ -152,7 +154,7 @@ public:
} }
auto surface_view = GetSurface(gpu_addr, SurfaceParams::CreateForFramebuffer(system, index), auto surface_view = GetSurface(gpu_addr, SurfaceParams::CreateForFramebuffer(system, index),
preserve_contents); preserve_contents, true);
if (render_targets[index].target) if (render_targets[index].target)
render_targets[index].target->MarkAsRenderTarget(false); render_targets[index].target->MarkAsRenderTarget(false);
render_targets[index].target = surface_view.first; render_targets[index].target = surface_view.first;
@ -226,6 +228,11 @@ protected:
} }
SetEmptyDepthBuffer(); SetEmptyDepthBuffer();
staging_cache.SetSize(2); 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; ~TextureCache() = default;
@ -289,7 +296,7 @@ protected:
const Tegra::Engines::Fermi2D::Regs::Surface& config) { const Tegra::Engines::Fermi2D::Regs::Surface& config) {
SurfaceParams params = SurfaceParams::CreateForFermiCopySurface(config); SurfaceParams params = SurfaceParams::CreateForFermiCopySurface(config);
const GPUVAddr gpu_addr = config.Address(); const GPUVAddr gpu_addr = config.Address();
return GetSurface(gpu_addr, params, true); return GetSurface(gpu_addr, params, true, false);
} }
Core::System& system; Core::System& system;
@ -406,16 +413,22 @@ private:
* @param params, the new surface params which we want to check. * @param params, the new surface params which we want to check.
**/ **/
std::pair<TSurface, TView> ManageStructuralMatch(TSurface current_surface, 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 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_mirage) {
if (!is_render && siblings_table[current_surface->GetFormat()] == params.pixel_format) {
return match_check();
}
return RebuildSurface(current_surface, params); return RebuildSurface(current_surface, params);
} }
const bool matches_target = current_surface->MatchTarget(params.target); return match_check();
if (matches_target) {
return {current_surface, current_surface->GetMainView()};
}
return {current_surface, current_surface->EmplaceOverview(params)};
} }
/** /**
@ -490,7 +503,7 @@ private:
* @param preserve_contents, tells if the new surface should be loaded from meory or left blank. * @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, 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 host_ptr{memory_manager->GetPointer(gpu_addr)};
const auto cache_addr{ToCacheAddr(host_ptr)}; const auto cache_addr{ToCacheAddr(host_ptr)};
@ -524,7 +537,7 @@ private:
(params.target != SurfaceTarget::Texture3D || (params.target != SurfaceTarget::Texture3D ||
current_surface->MatchTarget(params.target))) { current_surface->MatchTarget(params.target))) {
if (s_result == MatchStructureResult::FullMatch) { if (s_result == MatchStructureResult::FullMatch) {
return ManageStructuralMatch(current_surface, params); return ManageStructuralMatch(current_surface, params, is_render);
} else { } else {
return RebuildSurface(current_surface, params); return RebuildSurface(current_surface, params);
} }
@ -724,6 +737,8 @@ private:
// Guards the cache for protection conflicts. // Guards the cache for protection conflicts.
bool guard_cache{}; bool guard_cache{};
std::unordered_map<PixelFormat, PixelFormat> siblings_table;
// The internal Cache is different for the Texture Cache. It's based on buckets // 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 // of 1MB. This fits better for the purpose of this cache as textures are normaly
// large in size. // large in size.