forked from suyu/suyu
texture_cache: Implement siblings texture formats.
This commit is contained in:
parent
cb728797b0
commit
2d83553ea7
2 changed files with 31 additions and 12 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue