forked from dolphin-emu/dolphin
		
	
		
			
				
	
	
		
			190 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			190 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// Copyright 2016 Dolphin Emulator Project
 | 
						|
// Licensed under GPLv2+
 | 
						|
// Refer to the license.txt file included.
 | 
						|
 | 
						|
#pragma once
 | 
						|
 | 
						|
#include <memory>
 | 
						|
 | 
						|
#include "Common/CommonTypes.h"
 | 
						|
#include "VideoBackends/Vulkan/Constants.h"
 | 
						|
#include "VideoBackends/Vulkan/TextureCache.h"
 | 
						|
#include "VideoCommon/FramebufferManagerBase.h"
 | 
						|
 | 
						|
namespace Vulkan
 | 
						|
{
 | 
						|
class StagingTexture2D;
 | 
						|
class StateTracker;
 | 
						|
class StreamBuffer;
 | 
						|
class Texture2D;
 | 
						|
class VertexFormat;
 | 
						|
class XFBSource;
 | 
						|
 | 
						|
class FramebufferManager : public FramebufferManagerBase
 | 
						|
{
 | 
						|
public:
 | 
						|
  FramebufferManager();
 | 
						|
  ~FramebufferManager();
 | 
						|
 | 
						|
  static FramebufferManager* GetInstance();
 | 
						|
 | 
						|
  bool Initialize();
 | 
						|
 | 
						|
  VkRenderPass GetEFBLoadRenderPass() const { return m_efb_load_render_pass; }
 | 
						|
  VkRenderPass GetEFBClearRenderPass() const { return m_efb_clear_render_pass; }
 | 
						|
  u32 GetEFBWidth() const { return m_efb_width; }
 | 
						|
  u32 GetEFBHeight() const { return m_efb_height; }
 | 
						|
  u32 GetEFBLayers() const { return m_efb_layers; }
 | 
						|
  VkSampleCountFlagBits GetEFBSamples() const { return m_efb_samples; }
 | 
						|
  Texture2D* GetEFBColorTexture() const { return m_efb_color_texture.get(); }
 | 
						|
  Texture2D* GetEFBDepthTexture() const { return m_efb_depth_texture.get(); }
 | 
						|
  VkFramebuffer GetEFBFramebuffer() const { return m_efb_framebuffer; }
 | 
						|
  void GetTargetSize(unsigned int* width, unsigned int* height) override;
 | 
						|
 | 
						|
  std::unique_ptr<XFBSourceBase> CreateXFBSource(unsigned int target_width,
 | 
						|
                                                 unsigned int target_height,
 | 
						|
                                                 unsigned int layers) override;
 | 
						|
 | 
						|
  // GPU EFB textures -> Guest
 | 
						|
  void CopyToRealXFB(u32 xfb_addr, u32 fb_stride, u32 fb_height, const EFBRectangle& source_rc,
 | 
						|
                     float gamma = 1.0f) override;
 | 
						|
 | 
						|
  void ResizeEFBTextures();
 | 
						|
 | 
						|
  // Recompile shaders, use when MSAA mode changes.
 | 
						|
  void RecreateRenderPass();
 | 
						|
  void RecompileShaders();
 | 
						|
 | 
						|
  // Reinterpret pixel format of EFB color texture.
 | 
						|
  // Assumes no render pass is currently in progress.
 | 
						|
  // Swaps EFB framebuffers, so re-bind afterwards.
 | 
						|
  void ReinterpretPixelData(int convtype);
 | 
						|
 | 
						|
  // This render pass can be used for other readback operations.
 | 
						|
  VkRenderPass GetColorCopyForReadbackRenderPass() const { return m_copy_color_render_pass; }
 | 
						|
  // Resolve color/depth textures to a non-msaa texture, and return it.
 | 
						|
  Texture2D* ResolveEFBColorTexture(const VkRect2D& region);
 | 
						|
  Texture2D* ResolveEFBDepthTexture(const VkRect2D& region);
 | 
						|
 | 
						|
  // 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();
 | 
						|
 | 
						|
private:
 | 
						|
  struct EFBPokeVertex
 | 
						|
  {
 | 
						|
    float position[4];
 | 
						|
    u32 color;
 | 
						|
  };
 | 
						|
 | 
						|
  bool CreateEFBRenderPass();
 | 
						|
  void DestroyEFBRenderPass();
 | 
						|
  bool CreateEFBFramebuffer();
 | 
						|
  void DestroyEFBFramebuffer();
 | 
						|
 | 
						|
  bool CompileConversionShaders();
 | 
						|
  void DestroyConversionShaders();
 | 
						|
 | 
						|
  bool CreateReadbackRenderPasses();
 | 
						|
  void DestroyReadbackRenderPasses();
 | 
						|
  bool CompileReadbackShaders();
 | 
						|
  void DestroyReadbackShaders();
 | 
						|
  bool CreateReadbackTextures();
 | 
						|
  void DestroyReadbackTextures();
 | 
						|
  bool CreateReadbackFramebuffer();
 | 
						|
  void DestroyReadbackFramebuffer();
 | 
						|
 | 
						|
  void CreatePokeVertexFormat();
 | 
						|
  bool CreatePokeVertexBuffer();
 | 
						|
  void DestroyPokeVertexBuffer();
 | 
						|
  bool CompilePokeShaders();
 | 
						|
  void DestroyPokeShaders();
 | 
						|
 | 
						|
  bool PopulateColorReadbackTexture();
 | 
						|
  bool PopulateDepthReadbackTexture();
 | 
						|
 | 
						|
  void CreatePokeVertices(std::vector<EFBPokeVertex>* destination_list, u32 x, u32 y, float z,
 | 
						|
                          u32 color);
 | 
						|
 | 
						|
  void DrawPokeVertices(const EFBPokeVertex* vertices, size_t vertex_count, bool write_color,
 | 
						|
                        bool write_depth);
 | 
						|
 | 
						|
  VkRenderPass m_efb_load_render_pass = VK_NULL_HANDLE;
 | 
						|
  VkRenderPass m_efb_clear_render_pass = VK_NULL_HANDLE;
 | 
						|
  VkRenderPass m_depth_resolve_render_pass = VK_NULL_HANDLE;
 | 
						|
 | 
						|
  u32 m_efb_width = 0;
 | 
						|
  u32 m_efb_height = 0;
 | 
						|
  u32 m_efb_layers = 1;
 | 
						|
  VkSampleCountFlagBits m_efb_samples = VK_SAMPLE_COUNT_1_BIT;
 | 
						|
 | 
						|
  std::unique_ptr<Texture2D> m_efb_color_texture;
 | 
						|
  std::unique_ptr<Texture2D> m_efb_convert_color_texture;
 | 
						|
  std::unique_ptr<Texture2D> m_efb_depth_texture;
 | 
						|
  std::unique_ptr<Texture2D> m_efb_resolve_color_texture;
 | 
						|
  std::unique_ptr<Texture2D> m_efb_resolve_depth_texture;
 | 
						|
  VkFramebuffer m_efb_framebuffer = VK_NULL_HANDLE;
 | 
						|
  VkFramebuffer m_efb_convert_framebuffer = VK_NULL_HANDLE;
 | 
						|
  VkFramebuffer m_depth_resolve_framebuffer = VK_NULL_HANDLE;
 | 
						|
 | 
						|
  // Format conversion shaders
 | 
						|
  VkShaderModule m_ps_rgb8_to_rgba6 = VK_NULL_HANDLE;
 | 
						|
  VkShaderModule m_ps_rgba6_to_rgb8 = VK_NULL_HANDLE;
 | 
						|
  VkShaderModule m_ps_depth_resolve = VK_NULL_HANDLE;
 | 
						|
 | 
						|
  // EFB readback texture
 | 
						|
  std::unique_ptr<Texture2D> m_color_copy_texture;
 | 
						|
  std::unique_ptr<Texture2D> m_depth_copy_texture;
 | 
						|
  VkFramebuffer m_color_copy_framebuffer = VK_NULL_HANDLE;
 | 
						|
  VkFramebuffer m_depth_copy_framebuffer = VK_NULL_HANDLE;
 | 
						|
 | 
						|
  // CPU-side EFB readback texture
 | 
						|
  std::unique_ptr<StagingTexture2D> m_color_readback_texture;
 | 
						|
  std::unique_ptr<StagingTexture2D> m_depth_readback_texture;
 | 
						|
  bool m_color_readback_texture_valid = false;
 | 
						|
  bool m_depth_readback_texture_valid = false;
 | 
						|
 | 
						|
  // EFB poke drawing setup
 | 
						|
  std::unique_ptr<VertexFormat> m_poke_vertex_format;
 | 
						|
  std::unique_ptr<StreamBuffer> m_poke_vertex_stream_buffer;
 | 
						|
  std::vector<EFBPokeVertex> m_color_poke_vertices;
 | 
						|
  std::vector<EFBPokeVertex> m_depth_poke_vertices;
 | 
						|
  VkPrimitiveTopology m_poke_primitive_topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
 | 
						|
 | 
						|
  VkRenderPass m_copy_color_render_pass = VK_NULL_HANDLE;
 | 
						|
  VkRenderPass m_copy_depth_render_pass = VK_NULL_HANDLE;
 | 
						|
  VkShaderModule m_copy_color_shader = VK_NULL_HANDLE;
 | 
						|
  VkShaderModule m_copy_depth_shader = VK_NULL_HANDLE;
 | 
						|
 | 
						|
  VkShaderModule m_poke_vertex_shader = VK_NULL_HANDLE;
 | 
						|
  VkShaderModule m_poke_geometry_shader = VK_NULL_HANDLE;
 | 
						|
  VkShaderModule m_poke_fragment_shader = VK_NULL_HANDLE;
 | 
						|
};
 | 
						|
 | 
						|
// The XFB source class simply wraps a texture cache entry.
 | 
						|
// All the required functionality is provided by TextureCache.
 | 
						|
class XFBSource final : public XFBSourceBase
 | 
						|
{
 | 
						|
public:
 | 
						|
  explicit XFBSource(std::unique_ptr<TextureCache::TCacheEntry> texture);
 | 
						|
  ~XFBSource();
 | 
						|
 | 
						|
  TextureCache::TCacheEntry* GetTexture() const { return m_texture.get(); }
 | 
						|
  // Guest -> GPU EFB Textures
 | 
						|
  void DecodeToTexture(u32 xfb_addr, u32 fb_width, u32 fb_height) override;
 | 
						|
 | 
						|
  // Used for virtual XFB
 | 
						|
  void CopyEFB(float gamma) override;
 | 
						|
 | 
						|
private:
 | 
						|
  std::unique_ptr<TextureCache::TCacheEntry> m_texture;
 | 
						|
};
 | 
						|
 | 
						|
}  // namespace Vulkan
 |