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;
}
VideoCore::Surface::PixelFormat GetFormat() const {
return params.pixel_format;
}
bool MatchTarget(VideoCore::Surface::SurfaceTarget target) const {
return params.target == target;
}

View File

@ -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.