FramebufferManager: Implement EFB tile cache

The new tile cache is dynamic in size and can be turned on/off.
This commit is contained in:
Stenzek
2019-03-02 15:11:47 +10:00
parent 65216c9e87
commit 6bc4bfd26a
8 changed files with 240 additions and 159 deletions

View File

@ -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 @@ public:
// 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 @@ protected:
};
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 @@ protected:
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 @@ protected:
// 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]