texture_cache: Implement siblings texture formats.
This commit is contained in:
parent
cb728797b0
commit
2d83553ea7
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
if (is_mirage) {
|
|
||||||
return RebuildSurface(current_surface, params);
|
|
||||||
}
|
|
||||||
const bool matches_target = current_surface->MatchTarget(params.target);
|
const bool matches_target = current_surface->MatchTarget(params.target);
|
||||||
|
auto match_check = ([&]() -> std::pair<TSurface, TView> {
|
||||||
if (matches_target) {
|
if (matches_target) {
|
||||||
return {current_surface, current_surface->GetMainView()};
|
return {current_surface, current_surface->GetMainView()};
|
||||||
}
|
}
|
||||||
return {current_surface, current_surface->EmplaceOverview(params)};
|
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);
|
||||||
|
}
|
||||||
|
return match_check();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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.
|
||||||
|
|
Loading…
Reference in New Issue