From f039149198657c1891e1c6462ed30c31ed4b8486 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Fri, 15 Feb 2019 11:59:50 +1000 Subject: Move most backend functionality to VideoCommon --- Source/Core/VideoCommon/FramebufferManager.h | 171 +++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 Source/Core/VideoCommon/FramebufferManager.h (limited to 'Source/Core/VideoCommon/FramebufferManager.h') diff --git a/Source/Core/VideoCommon/FramebufferManager.h b/Source/Core/VideoCommon/FramebufferManager.h new file mode 100644 index 0000000000..d0de7b62b1 --- /dev/null +++ b/Source/Core/VideoCommon/FramebufferManager.h @@ -0,0 +1,171 @@ +// Copyright 2010 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +#include +#include + +#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& region); + AbstractTexture* ResolveEFBDepthTexture(const MathUtil::Rectangle& 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& 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::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* destination_list, u32 x, u32 y, float z, + u32 color); + + void DrawPokeVertices(const EFBPokeVertex* vertices, u32 vertex_count, + const AbstractPipeline* pipeline); + + std::unique_ptr m_efb_color_texture; + std::unique_ptr m_efb_convert_color_texture; + std::unique_ptr m_efb_depth_texture; + std::unique_ptr m_efb_resolve_color_texture; + std::unique_ptr m_efb_depth_resolve_texture; + + std::unique_ptr m_efb_framebuffer; + std::unique_ptr m_efb_convert_framebuffer; + std::unique_ptr m_efb_depth_resolve_framebuffer; + std::unique_ptr m_efb_depth_resolve_pipeline; + + // Format conversion shaders + std::array, 6> m_format_conversion_pipelines; + + // EFB readback texture + std::unique_ptr m_color_copy_texture; + std::unique_ptr m_depth_copy_texture; + std::unique_ptr m_color_copy_framebuffer; + std::unique_ptr m_depth_copy_framebuffer; + std::unique_ptr m_color_copy_pipeline; + std::unique_ptr m_depth_copy_pipeline; + + // CPU-side EFB readback texture + std::unique_ptr m_color_readback_texture; + std::unique_ptr 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, 2>, 2>, 2> + m_efb_clear_pipelines; + + // EFB poke drawing setup + std::unique_ptr m_poke_vertex_format; + std::unique_ptr m_color_poke_pipeline; + std::unique_ptr m_depth_poke_pipeline; + std::vector m_color_poke_vertices; + std::vector m_depth_poke_vertices; +}; + +extern std::unique_ptr g_framebuffer_manager; -- cgit v1.2.3