Skip to content
Permalink
Browse files

FramebufferManager: Implement EFB tile cache

The new tile cache is dynamic in size and can be turned on/off.
  • Loading branch information...
stenzek committed Mar 2, 2019
1 parent 65216c9 commit 6bc4bfd26af96de8642e75bbf644722c44baeb7b
@@ -136,6 +136,8 @@ const ConfigInfo<int> GFX_STEREO_DEPTH_PERCENTAGE{
// Graphics.Hacks

const ConfigInfo<bool> GFX_HACK_EFB_ACCESS_ENABLE{{System::GFX, "Hacks", "EFBAccessEnable"}, true};
const ConfigInfo<int> GFX_HACK_EFB_ACCESS_TILE_SIZE{{System::GFX, "Hacks", "EFBAccessTileSize"},
64};
const ConfigInfo<bool> GFX_HACK_BBOX_ENABLE{{System::GFX, "Hacks", "BBoxEnable"}, false};
const ConfigInfo<bool> GFX_HACK_FORCE_PROGRESSIVE{{System::GFX, "Hacks", "ForceProgressive"}, true};
const ConfigInfo<bool> GFX_HACK_SKIP_EFB_COPY_TO_RAM{{System::GFX, "Hacks", "EFBToTextureEnable"},
@@ -101,6 +101,7 @@ extern const ConfigInfo<int> GFX_STEREO_DEPTH_PERCENTAGE;
// Graphics.Hacks

extern const ConfigInfo<bool> GFX_HACK_EFB_ACCESS_ENABLE;
extern const ConfigInfo<int> GFX_HACK_EFB_ACCESS_TILE_SIZE;
extern const ConfigInfo<bool> GFX_HACK_BBOX_ENABLE;
extern const ConfigInfo<bool> GFX_HACK_FORCE_PROGRESSIVE;
extern const ConfigInfo<bool> GFX_HACK_SKIP_EFB_COPY_TO_RAM;
@@ -113,6 +113,7 @@ bool IsSettingSaveable(const Config::ConfigLocation& config_location)
// Graphics.Hacks

Config::GFX_HACK_EFB_ACCESS_ENABLE.location,
Config::GFX_HACK_EFB_ACCESS_TILE_SIZE.location,
Config::GFX_HACK_BBOX_ENABLE.location,
Config::GFX_HACK_FORCE_PROGRESSIVE.location,
Config::GFX_HACK_SKIP_EFB_COPY_TO_RAM.location,

Large diffs are not rendered by default.

@@ -6,15 +6,16 @@

#include <array>
#include <memory>
#include <optional>

#include "Common/CommonTypes.h"
#include "VideoCommon/AbstractTexture.h"
#include "VideoCommon/AbstractFramebuffer.h"
#include "VideoCommon/AbstractStagingTexture.h"
#include "VideoCommon/AbstractPipeline.h"
#include "VideoCommon/RenderState.h"
#include "VideoCommon/TextureConfig.h"

class AbstractFramebuffer;
class AbstractPipeline;
class AbstractStagingTexture;
class NativeVertexFormat;

enum class EFBReinterpretType
@@ -85,6 +86,7 @@ class FramebufferManager final
// Reads a framebuffer value back from the GPU. This may block if the cache is not current.
u32 PeekEFBColor(u32 x, u32 y);
float PeekEFBDepth(u32 x, u32 y);
void SetEFBCacheTileSize(u32 size);
void InvalidatePeekCache();

// Writes a value to the framebuffer. This will never block, and writes will be batched.
@@ -100,6 +102,18 @@ class FramebufferManager final
};
static_assert(std::is_standard_layout<EFBPokeVertex>::value, "EFBPokeVertex is standard-layout");

// EFB cache - for CPU EFB access
// Tiles are ordered left-to-right, then top-to-bottom
struct EFBCacheData
{
std::unique_ptr<AbstractTexture> texture;
std::unique_ptr<AbstractFramebuffer> framebuffer;
std::unique_ptr<AbstractStagingTexture> readback_texture;
std::unique_ptr<AbstractPipeline> copy_pipeline;
std::vector<bool> tiles;
bool valid;
};

bool CreateEFBFramebuffer();
void DestroyEFBFramebuffer();

@@ -118,8 +132,10 @@ class FramebufferManager final
bool CompilePokePipelines();
void DestroyPokePipelines();

bool PopulateColorReadbackTexture();
bool PopulateDepthReadbackTexture();
bool IsUsingTiledEFBCache() const;
bool IsEFBCacheTilePresent(bool depth, u32 x, u32 y, u32* tile_index) const;
MathUtil::Rectangle<int> GetEFBCacheTileRect(u32 tile_index) const;
void PopulateEFBCache(bool depth, u32 tile_index);

void CreatePokeVertices(std::vector<EFBPokeVertex>* destination_list, u32 x, u32 y, float z,
u32 color);
@@ -141,19 +157,11 @@ class FramebufferManager final
// Format conversion shaders
std::array<std::unique_ptr<AbstractPipeline>, 6> m_format_conversion_pipelines;

// EFB readback texture
std::unique_ptr<AbstractTexture> m_color_copy_texture;
std::unique_ptr<AbstractTexture> m_depth_copy_texture;
std::unique_ptr<AbstractFramebuffer> m_color_copy_framebuffer;
std::unique_ptr<AbstractFramebuffer> m_depth_copy_framebuffer;
std::unique_ptr<AbstractPipeline> m_color_copy_pipeline;
std::unique_ptr<AbstractPipeline> m_depth_copy_pipeline;

// CPU-side EFB readback texture
std::unique_ptr<AbstractStagingTexture> m_color_readback_texture;
std::unique_ptr<AbstractStagingTexture> m_depth_readback_texture;
bool m_color_readback_texture_valid = false;
bool m_depth_readback_texture_valid = false;
// EFB cache - for CPU EFB access
u32 m_efb_cache_tile_size = 0;
u32 m_efb_cache_tiles_wide = 0;
EFBCacheData m_efb_color_cache = {};
EFBCacheData m_efb_depth_cache = {};

// EFB clear pipelines
// Indexed by [color_write_enabled][alpha_write_enabled][depth_write_enabled]
@@ -386,6 +386,7 @@ void Renderer::CheckForConfigChanges()
const StereoMode old_stereo = g_ActiveConfig.stereo_mode;
const u32 old_multisamples = g_ActiveConfig.iMultisamples;
const int old_anisotropy = g_ActiveConfig.iMaxAnisotropy;
const int old_efb_access_tile_size = g_ActiveConfig.iEFBAccessTileSize;
const bool old_force_filtering = g_ActiveConfig.bForceFiltering;
const bool old_vsync = g_ActiveConfig.bVSyncActive;
const bool old_bbox = g_ActiveConfig.bBBoxEnable;
@@ -395,6 +396,10 @@ void Renderer::CheckForConfigChanges()
// Update texture cache settings with any changed options.
g_texture_cache->OnConfigChanged(g_ActiveConfig);

// EFB tile cache doesn't need to notify the backend.
if (old_efb_access_tile_size != g_ActiveConfig.iEFBAccessTileSize)
g_framebuffer_manager->SetEFBCacheTileSize(std::max(g_ActiveConfig.iEFBAccessTileSize, 0));

// Check for post-processing shader changes. Done up here as it doesn't affect anything outside
// the post-processor. Note that options are applied every frame, so no need to check those.
if (m_post_processor->GetConfig()->GetShader() != g_ActiveConfig.sPostProcessingShader)
@@ -154,6 +154,7 @@ void VideoConfig::Refresh()
bCopyEFBScaled = Config::Get(Config::GFX_HACK_COPY_EFB_SCALED);
bEFBEmulateFormatChanges = Config::Get(Config::GFX_HACK_EFB_EMULATE_FORMAT_CHANGES);
bVertexRounding = Config::Get(Config::GFX_HACK_VERTEX_ROUDING);
iEFBAccessTileSize = Config::Get(Config::GFX_HACK_EFB_ACCESS_TILE_SIZE);

bPerfQueriesEnable = Config::Get(Config::GFX_PERF_QUERIES_ENABLE);

@@ -128,6 +128,7 @@ struct VideoConfig final
bool bEnablePixelLighting;
bool bFastDepthCalc;
bool bVertexRounding;
int iEFBAccessTileSize;
int iLog; // CONF_ bits
int iSaveTargetId; // TODO: Should be dropped

0 comments on commit 6bc4bfd

Please sign in to comment.
You can’t perform that action at this time.