Skip to content
Permalink
Browse files

Merge pull request #7838 from stenzek/efb-tile-cache

FramebufferManager: Implement EFB tile cache
  • Loading branch information...
JMC47 committed Mar 12, 2019
2 parents 909e932 + 0e2397a commit 22e7419747cf629c185546052006872f6d4838d6
@@ -15,3 +15,7 @@ SyncGPU = True
[ActionReplay]
# Add action replay cheats here.

[Video_Hacks]
# In the Sand Ocean track, EFB peeks occur across the whole screen.
# This leads to slow performance with the tile cache enabled, so disable it.
EFBAccessTileSize = 0
@@ -136,6 +136,10 @@ const ConfigInfo<int> GFX_STEREO_DEPTH_PERCENTAGE{
// Graphics.Hacks

const ConfigInfo<bool> GFX_HACK_EFB_ACCESS_ENABLE{{System::GFX, "Hacks", "EFBAccessEnable"}, true};
const ConfigInfo<bool> GFX_HACK_EFB_DEFER_INVALIDATION{
{System::GFX, "Hacks", "EFBAccessDeferInvalidation"}, false};
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,8 @@ extern const ConfigInfo<int> GFX_STEREO_DEPTH_PERCENTAGE;
// Graphics.Hacks

extern const ConfigInfo<bool> GFX_HACK_EFB_ACCESS_ENABLE;
extern const ConfigInfo<bool> GFX_HACK_EFB_DEFER_INVALIDATION;
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,8 @@ bool IsSettingSaveable(const Config::ConfigLocation& config_location)
// Graphics.Hacks

Config::GFX_HACK_EFB_ACCESS_ENABLE.location,
Config::GFX_HACK_EFB_DEFER_INVALIDATION.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,
@@ -105,9 +105,20 @@ void AdvancedWidget::CreateWidgets()
misc_layout->addWidget(m_borderless_fullscreen, 1, 1);
#endif

// Experimental.
auto* experimental_box = new QGroupBox(tr("Experimental"));
auto* experimental_layout = new QGridLayout();
experimental_box->setLayout(experimental_layout);

m_defer_efb_access_invalidation =
new GraphicsBool(tr("Defer EFB Cache Invalidation"), Config::GFX_HACK_EFB_DEFER_INVALIDATION);

experimental_layout->addWidget(m_defer_efb_access_invalidation, 0, 0);

main_layout->addWidget(debugging_box);
main_layout->addWidget(utility_box);
main_layout->addWidget(misc_box);
main_layout->addWidget(experimental_box);
main_layout->addStretch();

setLayout(main_layout);
@@ -194,6 +205,12 @@ void AdvancedWidget::AddDescriptions()
"this option may result in a performance improvement on systems with more than "
"two CPU cores. Currently, this is limited to the Vulkan backend.\n\nIf unsure, "
"leave this checked.");
static const char TR_DEFER_EFB_ACCESS_INVALIDATION_DESCRIPTION[] =
QT_TR_NOOP("Defers invalidation of the EFB access cache until a GPU synchronization command "
"is executed. If disabled, the cache will be invalidated with every draw call. "
"May improve performance in some games which rely on CPU EFB Access at the cost "
"of stability.\n\nIf unsure, leave this unchecked.");

#ifdef _WIN32
static const char TR_BORDERLESS_FULLSCREEN_DESCRIPTION[] = QT_TR_NOOP(
"Implements fullscreen mode with a borderless window spanning the whole screen instead of "
@@ -223,4 +240,5 @@ void AdvancedWidget::AddDescriptions()
#ifdef _WIN32
AddDescription(m_borderless_fullscreen, TR_BORDERLESS_FULLSCREEN_DESCRIPTION);
#endif
AddDescription(m_defer_efb_access_invalidation, TR_DEFER_EFB_ACCESS_INVALIDATION_DESCRIPTION);
}
@@ -46,4 +46,7 @@ class AdvancedWidget final : public GraphicsWidget
QCheckBox* m_enable_prog_scan;
QCheckBox* m_backend_multithreading;
QCheckBox* m_borderless_fullscreen;

// Experimental
QCheckBox* m_defer_efb_access_invalidation;
};
@@ -67,6 +67,7 @@ void VideoBackend::InitBackendInfo()
g_Config.backend_info.bSupportsST3CTextures = false;
g_Config.backend_info.bSupportsCopyToVram = true;
g_Config.backend_info.bSupportsLargePoints = false;
g_Config.backend_info.bSupportsPartialDepthCopies = false;
g_Config.backend_info.bSupportsBitfield = false;
g_Config.backend_info.bSupportsDynamicSamplerIndexing = false;
g_Config.backend_info.bSupportsBPTCTextures = false;
@@ -50,6 +50,8 @@ void VideoBackend::InitBackendInfo()
g_Config.backend_info.bSupportsFramebufferFetch = false;
g_Config.backend_info.bSupportsBackgroundCompiling = false;
g_Config.backend_info.bSupportsLogicOp = false;
g_Config.backend_info.bSupportsLargePoints = false;
g_Config.backend_info.bSupportsPartialDepthCopies = false;

// aamodes: We only support 1 sample, so no MSAA
g_Config.backend_info.Adapters.clear();
@@ -939,7 +939,7 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaE
u32 color, u32 z)
{
g_framebuffer_manager->FlushEFBPokes();
g_framebuffer_manager->InvalidatePeekCache();
g_framebuffer_manager->FlagPeekCacheAsOutOfDate();

u32 clear_mask = 0;
if (colorEnable || alphaEnable)
@@ -89,6 +89,7 @@ void VideoBackend::InitBackendInfo()
g_Config.backend_info.bSupportsMultithreading = false;
g_Config.backend_info.bSupportsCopyToVram = true;
g_Config.backend_info.bSupportsLargePoints = true;
g_Config.backend_info.bSupportsPartialDepthCopies = true;

// TODO: There is a bug here, if texel buffers are not supported the graphics options
// will show the option when it is not supported. The only way around this would be
@@ -70,6 +70,7 @@ void VideoSoftware::InitBackendInfo()
g_Config.backend_info.bSupportsBPTCTextures = false;
g_Config.backend_info.bSupportsCopyToVram = false;
g_Config.backend_info.bSupportsLargePoints = false;
g_Config.backend_info.bSupportsPartialDepthCopies = false;
g_Config.backend_info.bSupportsFramebufferFetch = false;
g_Config.backend_info.bSupportsBackgroundCompiling = false;
g_Config.backend_info.bSupportsLogicOp = true;
@@ -186,7 +186,7 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool color_enable, bool alpha
bool z_enable, u32 color, u32 z)
{
g_framebuffer_manager->FlushEFBPokes();
g_framebuffer_manager->InvalidatePeekCache();
g_framebuffer_manager->FlagPeekCacheAsOutOfDate();

// Native -> EFB coordinates
TargetRectangle target_rc = Renderer::ConvertEFBRectangle(rc);
@@ -252,6 +252,7 @@ void VulkanContext::PopulateBackendInfo(VideoConfig* config)
config->backend_info.bSupportsComputeShaders = true; // Assumed support.
config->backend_info.bSupportsGPUTextureDecoding = true; // Assumed support.
config->backend_info.bSupportsBitfield = true; // Assumed support.
config->backend_info.bSupportsPartialDepthCopies = true; // Assumed support.
config->backend_info.bSupportsDynamicSamplerIndexing = true; // Assumed support.
config->backend_info.bSupportsPostProcessing = true; // Assumed support.
config->backend_info.bSupportsBackgroundCompiling = true; // Assumed support.
@@ -22,6 +22,7 @@
#include "VideoCommon/BPMemory.h"
#include "VideoCommon/BoundingBox.h"
#include "VideoCommon/Fifo.h"
#include "VideoCommon/FramebufferManager.h"
#include "VideoCommon/GeometryShaderManager.h"
#include "VideoCommon/PerfQueryBase.h"
#include "VideoCommon/PixelEngine.h"
@@ -178,6 +179,7 @@ static void BPWritten(const BPCmd& bp)
{
case 0x02:
g_texture_cache->FlushEFBCopies();
g_framebuffer_manager->InvalidatePeekCache(false);
if (!Fifo::UseDeterministicGPUThread())
PixelEngine::SetFinish(); // may generate interrupt
DEBUG_LOG(VIDEO, "GXSetDrawDone SetPEFinish (value: 0x%02X)", (bp.newvalue & 0xFFFF));
@@ -190,12 +192,14 @@ static void BPWritten(const BPCmd& bp)
return;
case BPMEM_PE_TOKEN_ID: // Pixel Engine Token ID
g_texture_cache->FlushEFBCopies();
g_framebuffer_manager->InvalidatePeekCache(false);
if (!Fifo::UseDeterministicGPUThread())
PixelEngine::SetToken(static_cast<u16>(bp.newvalue & 0xFFFF), false);
DEBUG_LOG(VIDEO, "SetPEToken 0x%04x", (bp.newvalue & 0xFFFF));
return;
case BPMEM_PE_TOKEN_INT_ID: // Pixel Engine Interrupt Token ID
g_texture_cache->FlushEFBCopies();
g_framebuffer_manager->InvalidatePeekCache(false);
if (!Fifo::UseDeterministicGPUThread())
PixelEngine::SetToken(static_cast<u16>(bp.newvalue & 0xFFFF), true);
DEBUG_LOG(VIDEO, "SetPEToken + INT 0x%04x", (bp.newvalue & 0xFFFF));

0 comments on commit 22e7419

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