mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 06:09:50 -06:00
Move most backend functionality to VideoCommon
This commit is contained in:
171
Source/Core/VideoCommon/FramebufferManager.h
Normal file
171
Source/Core/VideoCommon/FramebufferManager.h
Normal file
@ -0,0 +1,171 @@
|
||||
// Copyright 2010 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "VideoCommon/AbstractTexture.h"
|
||||
#include "VideoCommon/RenderState.h"
|
||||
#include "VideoCommon/TextureConfig.h"
|
||||
|
||||
class AbstractFramebuffer;
|
||||
class AbstractPipeline;
|
||||
class AbstractStagingTexture;
|
||||
class NativeVertexFormat;
|
||||
|
||||
enum class EFBReinterpretType
|
||||
{
|
||||
RGB8ToRGB565 = 0,
|
||||
RGB8ToRGBA6 = 1,
|
||||
RGBA6ToRGB8 = 2,
|
||||
RGBA6ToRGB565 = 3,
|
||||
RGB565ToRGB8 = 4,
|
||||
RGB565ToRGBA6 = 5
|
||||
};
|
||||
constexpr u32 NUM_EFB_REINTERPRET_TYPES = 6;
|
||||
|
||||
inline bool AddressRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper)
|
||||
{
|
||||
return !((aLower >= bUpper) || (bLower >= aUpper));
|
||||
}
|
||||
|
||||
class FramebufferManager final
|
||||
{
|
||||
public:
|
||||
FramebufferManager();
|
||||
virtual ~FramebufferManager();
|
||||
|
||||
// Does not require the framebuffer to be created. Slower than direct queries.
|
||||
static AbstractTextureFormat GetEFBColorFormat();
|
||||
static AbstractTextureFormat GetEFBDepthFormat();
|
||||
static TextureConfig GetEFBColorTextureConfig();
|
||||
static TextureConfig GetEFBDepthTextureConfig();
|
||||
|
||||
// Accessors.
|
||||
AbstractTexture* GetEFBColorTexture() const { return m_efb_color_texture.get(); }
|
||||
AbstractTexture* GetEFBDepthTexture() const { return m_efb_depth_texture.get(); }
|
||||
AbstractFramebuffer* GetEFBFramebuffer() const { return m_efb_framebuffer.get(); }
|
||||
u32 GetEFBWidth() const { return m_efb_color_texture->GetWidth(); }
|
||||
u32 GetEFBHeight() const { return m_efb_color_texture->GetHeight(); }
|
||||
u32 GetEFBLayers() const { return m_efb_color_texture->GetLayers(); }
|
||||
u32 GetEFBSamples() const { return m_efb_color_texture->GetSamples(); }
|
||||
bool IsEFBMultisampled() const { return m_efb_color_texture->IsMultisampled(); }
|
||||
bool IsEFBStereo() const { return m_efb_color_texture->GetLayers() > 1; }
|
||||
FramebufferState GetEFBFramebufferState() const;
|
||||
|
||||
// First-time setup.
|
||||
bool Initialize();
|
||||
|
||||
// Recreate EFB framebuffers, call when the EFB size (IR) changes.
|
||||
void RecreateEFBFramebuffer();
|
||||
|
||||
// Recompile shaders, use when MSAA mode changes.
|
||||
void RecompileShaders();
|
||||
|
||||
// This is virtual, because D3D has both normalized and integer framebuffers.
|
||||
void BindEFBFramebuffer();
|
||||
|
||||
// Resolve color/depth textures to a non-msaa texture, and return it.
|
||||
AbstractTexture* ResolveEFBColorTexture(const MathUtil::Rectangle<int>& region);
|
||||
AbstractTexture* ResolveEFBDepthTexture(const MathUtil::Rectangle<int>& region);
|
||||
|
||||
// Reinterpret pixel format of EFB color texture.
|
||||
// Assumes no render pass is currently in progress.
|
||||
// Swaps EFB framebuffers, so re-bind afterwards.
|
||||
bool ReinterpretPixelData(EFBReinterpretType convtype);
|
||||
|
||||
// Clears the EFB using shaders.
|
||||
void ClearEFB(const MathUtil::Rectangle<int>& rc, bool clear_color, bool clear_alpha,
|
||||
bool clear_z, u32 color, u32 z);
|
||||
|
||||
// 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 InvalidatePeekCache();
|
||||
|
||||
// Writes a value to the framebuffer. This will never block, and writes will be batched.
|
||||
void PokeEFBColor(u32 x, u32 y, u32 color);
|
||||
void PokeEFBDepth(u32 x, u32 y, float depth);
|
||||
void FlushEFBPokes();
|
||||
|
||||
protected:
|
||||
struct EFBPokeVertex
|
||||
{
|
||||
float position[4];
|
||||
u32 color;
|
||||
};
|
||||
static_assert(std::is_standard_layout<EFBPokeVertex>::value, "EFBPokeVertex is standard-layout");
|
||||
|
||||
bool CreateEFBFramebuffer();
|
||||
void DestroyEFBFramebuffer();
|
||||
|
||||
bool CompileConversionPipelines();
|
||||
void DestroyConversionPipelines();
|
||||
|
||||
bool CompileReadbackPipelines();
|
||||
void DestroyReadbackPipelines();
|
||||
|
||||
bool CreateReadbackFramebuffer();
|
||||
void DestroyReadbackFramebuffer();
|
||||
|
||||
bool CompileClearPipelines();
|
||||
void DestroyClearPipelines();
|
||||
|
||||
bool CompilePokePipelines();
|
||||
void DestroyPokePipelines();
|
||||
|
||||
bool PopulateColorReadbackTexture();
|
||||
bool PopulateDepthReadbackTexture();
|
||||
|
||||
void CreatePokeVertices(std::vector<EFBPokeVertex>* destination_list, u32 x, u32 y, float z,
|
||||
u32 color);
|
||||
|
||||
void DrawPokeVertices(const EFBPokeVertex* vertices, u32 vertex_count,
|
||||
const AbstractPipeline* pipeline);
|
||||
|
||||
std::unique_ptr<AbstractTexture> m_efb_color_texture;
|
||||
std::unique_ptr<AbstractTexture> m_efb_convert_color_texture;
|
||||
std::unique_ptr<AbstractTexture> m_efb_depth_texture;
|
||||
std::unique_ptr<AbstractTexture> m_efb_resolve_color_texture;
|
||||
std::unique_ptr<AbstractTexture> m_efb_depth_resolve_texture;
|
||||
|
||||
std::unique_ptr<AbstractFramebuffer> m_efb_framebuffer;
|
||||
std::unique_ptr<AbstractFramebuffer> m_efb_convert_framebuffer;
|
||||
std::unique_ptr<AbstractFramebuffer> m_efb_depth_resolve_framebuffer;
|
||||
std::unique_ptr<AbstractPipeline> m_efb_depth_resolve_pipeline;
|
||||
|
||||
// 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 clear pipelines
|
||||
// Indexed by [color_write_enabled][alpha_write_enabled][depth_write_enabled]
|
||||
std::array<std::array<std::array<std::unique_ptr<AbstractPipeline>, 2>, 2>, 2>
|
||||
m_efb_clear_pipelines;
|
||||
|
||||
// EFB poke drawing setup
|
||||
std::unique_ptr<NativeVertexFormat> m_poke_vertex_format;
|
||||
std::unique_ptr<AbstractPipeline> m_color_poke_pipeline;
|
||||
std::unique_ptr<AbstractPipeline> m_depth_poke_pipeline;
|
||||
std::vector<EFBPokeVertex> m_color_poke_vertices;
|
||||
std::vector<EFBPokeVertex> m_depth_poke_vertices;
|
||||
};
|
||||
|
||||
extern std::unique_ptr<FramebufferManager> g_framebuffer_manager;
|
Reference in New Issue
Block a user