2014-09-09 08:12:42 -07:00
// Copyright (c) 2012- PPSSPP Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0 or later versions.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
2020-12-13 00:20:47 +01:00
// TODO: We now have the tools in thin3d to nearly eliminate the backend-specific framebuffer managers.
// Here's a list of functionality to unify into FramebufferManagerCommon:
// * DrawActiveTexture
// * BlitFramebuffer
//
// Also, in TextureCache we should be able to unify texture-based depal.
2014-09-09 08:12:42 -07:00
# pragma once
# include <vector>
2018-06-03 08:08:45 -07:00
# include <unordered_map>
2015-07-26 22:38:40 +02:00
2014-09-09 08:12:42 -07:00
# include "Common/CommonTypes.h"
2020-10-04 09:29:36 +02:00
# include "Common/Log.h"
2022-08-03 11:42:37 +02:00
# include "Common/GPU/thin3d.h"
2015-07-26 22:38:40 +02:00
# include "GPU/GPU.h"
2014-09-09 08:12:42 -07:00
# include "GPU/ge_constants.h"
2017-10-18 12:49:15 +02:00
# include "GPU/GPUInterface.h"
2022-08-03 11:42:37 +02:00
# include "GPU/Common/Draw2D.h"
2014-09-09 08:12:42 -07:00
enum {
FB_USAGE_DISPLAYED_FRAMEBUFFER = 1 ,
2022-08-17 19:55:19 +02:00
FB_USAGE_RENDER_COLOR = 2 ,
2014-09-09 08:12:42 -07:00
FB_USAGE_TEXTURE = 4 ,
2015-04-28 00:08:00 -07:00
FB_USAGE_CLUT = 8 ,
2017-04-09 15:10:07 -07:00
FB_USAGE_DOWNLOAD = 16 ,
FB_USAGE_DOWNLOAD_CLEAR = 32 ,
2022-04-30 18:13:24 +02:00
FB_USAGE_BLUE_TO_ALPHA = 64 ,
2022-08-16 22:39:09 +02:00
FB_USAGE_FIRST_FRAME_SAVED = 128 ,
2022-08-17 19:55:19 +02:00
FB_USAGE_RENDER_DEPTH = 256 ,
2014-09-09 08:12:42 -07:00
} ;
enum {
FB_NON_BUFFERED_MODE = 0 ,
FB_BUFFERED_MODE = 1 ,
} ;
2017-02-04 18:46:12 +01:00
namespace Draw {
class Framebuffer ;
2015-11-14 13:24:51 +01:00
}
2014-09-09 08:12:42 -07:00
2016-03-17 11:56:43 +01:00
class VulkanFBO ;
2022-08-16 19:21:50 +02:00
class ShaderWriter ;
2016-01-03 23:09:37 +01:00
2022-07-17 18:14:55 +02:00
// We have to track VFBs and depth buffers together, since bits are shared between the color alpha channel
// and the stencil buffer on the PSP.
// Sometimes, virtual framebuffers need to share a Z buffer. We emulate this by copying from on to the next
// when such a situation is detected. In order to reliably detect this, we separately track depth buffers,
// and they know which color buffer they were used with last.
2014-09-09 08:12:42 -07:00
struct VirtualFramebuffer {
2022-08-16 22:39:09 +02:00
Draw : : Framebuffer * fbo ;
2014-09-09 08:12:42 -07:00
u32 fb_address ;
2019-09-17 14:45:40 +02:00
u32 z_address ; // If 0, it's a "RAM" framebuffer.
2022-08-16 22:39:09 +02:00
u16 fb_stride ;
u16 z_stride ;
2014-09-09 08:12:42 -07:00
2022-08-22 21:28:43 +02:00
// The original PSP format of the framebuffer.
// In reality they are all RGBA8888 for better quality but this is what the PSP thinks it is. This is necessary
// when we need to interpret the bits directly (depal or buffer aliasing).
GEBufferFormat fb_format ;
2020-08-04 14:45:14 +02:00
// width/height: The detected size of the current framebuffer, in original PSP pixels.
2014-09-09 08:12:42 -07:00
u16 width ;
u16 height ;
2020-08-04 14:45:14 +02:00
2020-11-05 11:21:00 +01:00
// bufferWidth/bufferHeight: The pre-scaling size of the buffer itself. May only be bigger than or equal to width/height.
2022-08-16 22:39:09 +02:00
// In original PSP pixels - actual framebuffer is this size times the render resolution multiplier.
2020-11-05 11:21:00 +01:00
// The buffer may be used to render a width or height from 0 to these values without being recreated.
u16 bufferWidth ;
u16 bufferHeight ;
2018-06-17 17:40:37 -07:00
// renderWidth/renderHeight: The scaled size we render at. May be scaled to render at higher resolutions.
2022-08-16 22:39:09 +02:00
// These are simply bufferWidth/Height * renderScaleFactor and are thus redundant.
2014-09-09 08:12:42 -07:00
u16 renderWidth ;
u16 renderHeight ;
2020-08-04 14:45:14 +02:00
2022-08-17 10:15:02 +02:00
// Attempt to keep track of a bounding rectangle of what's been actually drawn. Coarse, but might be smaller
// than width/height if framebuffer has been enlarged. In PSP pixels.
2022-08-16 22:39:09 +02:00
u16 drawnWidth ;
u16 drawnHeight ;
// The dimensions at which we are confident that we can read back this buffer without stomping on irrelevant memory.
u16 safeWidth ;
u16 safeHeight ;
// The scale factor at which we are rendering (to achieve higher resolution).
u8 renderScaleFactor ;
// The configured buffer format at the time of the latest/current draw. This will change first, then
// if different we'll "reinterpret" the framebuffer to match 'format' as needed.
GEBufferFormat drawnFormat ;
2014-09-09 08:12:42 -07:00
u16 usageFlags ;
2022-08-16 22:39:09 +02:00
// These are used to track state to try to avoid buffer size shifting back and forth.
2022-08-17 10:15:02 +02:00
// You might think that doesn't happen since we mostly grow framebuffers, but we do resize down,
// if the size has shrunk for a while and the framebuffer is also larger than the stride.
// At this point, the "safe" size is probably a lie, and we have had various issues with readbacks, so this resizes down to avoid them.
// An example would be a game that always uses the address 0x00154000 for temp buffers, and uses it for a full-screen effect for 3 frames, then goes back to using it for character shadows or something much smaller.
2014-09-09 08:12:42 -07:00
u16 newWidth ;
u16 newHeight ;
2020-11-05 11:21:00 +01:00
2022-08-16 22:39:09 +02:00
// The frame number at which this was last resized.
2014-09-09 08:12:42 -07:00
int lastFrameNewSize ;
2022-08-16 22:39:09 +02:00
// Tracking for downloads-to-CLUT.
u16 clutUpdatedBytes ;
bool memoryUpdated ;
2014-09-09 08:12:42 -07:00
2022-08-16 22:39:09 +02:00
// TODO: Fold into usageFlags?
2014-09-09 08:12:42 -07:00
bool dirtyAfterDisplay ;
bool reallyDirtyAfterDisplay ; // takes frame skipping into account
2020-09-12 12:32:24 +02:00
2022-08-16 22:39:09 +02:00
// Global sequence numbers for the last time these were bound.
// Not based on frames at all. Can be used to determine new-ness of one framebuffer over another,
// can even be within a frame.
int colorBindSeq ;
int depthBindSeq ;
// These are mainly used for garbage collection purposes and similar.
// Cannot be used to determine new-ness against a similar other buffer, since they are
// only at frame granularity.
2020-09-12 12:32:24 +02:00
int last_frame_used ;
int last_frame_attached ;
int last_frame_render ;
int last_frame_displayed ;
int last_frame_clut ;
int last_frame_failed ;
int last_frame_depth_updated ;
int last_frame_depth_render ;
2014-09-09 08:12:42 -07:00
} ;
2015-08-05 11:51:24 +02:00
struct FramebufferHeuristicParams {
u32 fb_address ;
u32 z_address ;
2022-08-16 22:39:09 +02:00
u16 fb_stride ;
u16 z_stride ;
2022-08-22 21:22:00 +02:00
GEBufferFormat fb_format ;
2015-08-05 11:51:24 +02:00
bool isClearingDepth ;
bool isWritingDepth ;
bool isDrawing ;
bool isModeThrough ;
2022-08-14 22:13:39 -07:00
bool isBlending ;
2015-08-05 11:51:24 +02:00
int viewportWidth ;
int viewportHeight ;
int regionWidth ;
int regionHeight ;
int scissorWidth ;
int scissorHeight ;
} ;
struct GPUgstate ;
extern GPUgstate gstate ;
void GetFramebufferHeuristicInputs ( FramebufferHeuristicParams * params , const GPUgstate & gstate ) ;
2015-09-13 11:14:51 -07:00
enum BindFramebufferColorFlags {
BINDFBCOLOR_SKIP_COPY = 0 ,
BINDFBCOLOR_MAY_COPY = 1 ,
2020-12-13 00:20:47 +01:00
BINDFBCOLOR_MAY_COPY_WITH_UV = 3 , // includes BINDFBCOLOR_MAY_COPY
2015-09-12 19:43:02 -07:00
BINDFBCOLOR_APPLY_TEX_OFFSET = 4 ,
2018-11-24 10:19:10 -08:00
// Used when rendering to a temporary surface (e.g. not the current render target.)
BINDFBCOLOR_FORCE_SELF = 8 ,
2015-09-13 11:14:51 -07:00
} ;
2017-05-31 23:24:56 -07:00
enum DrawTextureFlags {
DRAWTEX_NEAREST = 0 ,
DRAWTEX_LINEAR = 1 ,
2019-06-21 14:00:02 +02:00
DRAWTEX_TO_BACKBUFFER = 8 ,
2017-05-31 23:24:56 -07:00
} ;
2019-06-22 22:15:09 +02:00
inline DrawTextureFlags operator | ( const DrawTextureFlags & lhs , const DrawTextureFlags & rhs ) {
return DrawTextureFlags ( ( u32 ) lhs | ( u32 ) rhs ) ;
}
2018-05-06 08:57:44 -07:00
enum class TempFBO {
DEPAL ,
BLIT ,
// For copies of framebuffers (e.g. shader blending.)
COPY ,
2020-11-06 11:54:57 +01:00
// For another type of framebuffers that can happen together with COPY (see Outrun)
REINTERPRET ,
2019-03-10 08:35:31 -07:00
// Used to copy stencil data, means we need a stencil backing.
STENCIL ,
2018-05-06 08:57:44 -07:00
} ;
2017-10-18 11:20:58 +02:00
inline Draw : : DataFormat GEFormatToThin3D ( int geFormat ) {
switch ( geFormat ) {
case GE_FORMAT_4444 :
return Draw : : DataFormat : : A4R4G4B4_UNORM_PACK16 ;
case GE_FORMAT_5551 :
return Draw : : DataFormat : : A1R5G5B5_UNORM_PACK16 ;
case GE_FORMAT_565 :
return Draw : : DataFormat : : R5G6B5_UNORM_PACK16 ;
case GE_FORMAT_8888 :
return Draw : : DataFormat : : R8G8B8A8_UNORM ;
default :
return Draw : : DataFormat : : UNDEFINED ;
}
}
2017-02-05 19:51:50 +01:00
namespace Draw {
class DrawContext ;
}
2017-02-14 12:42:35 +01:00
struct GPUDebugBuffer ;
2017-10-18 12:26:02 +02:00
class DrawEngineCommon ;
2020-05-09 22:06:22 -07:00
class PresentationCommon ;
class ShaderManagerCommon ;
class TextureCacheCommon ;
2017-02-06 12:02:30 +01:00
2014-09-09 08:12:42 -07:00
class FramebufferManagerCommon {
public :
2020-11-03 15:44:57 +01:00
FramebufferManagerCommon ( Draw : : DrawContext * draw ) ;
2014-09-09 08:12:42 -07:00
virtual ~ FramebufferManagerCommon ( ) ;
2022-08-05 14:49:45 +02:00
void SetTextureCache ( TextureCacheCommon * tc ) {
textureCache_ = tc ;
}
void SetShaderManager ( ShaderManagerCommon * sm ) {
shaderManager_ = sm ;
}
void SetDrawEngine ( DrawEngineCommon * td ) {
drawEngine_ = td ;
}
2014-09-13 16:47:23 -07:00
virtual void Init ( ) ;
2017-10-25 20:28:12 +02:00
virtual void BeginFrame ( ) ;
2014-09-13 14:44:18 -07:00
void SetDisplayFramebuffer ( u32 framebuf , u32 stride , GEBufferFormat format ) ;
2017-02-06 12:02:30 +01:00
void DestroyFramebuf ( VirtualFramebuffer * v ) ;
2014-09-09 22:56:54 -07:00
2022-07-31 13:01:50 +02:00
VirtualFramebuffer * DoSetRenderFrameBuffer ( const FramebufferHeuristicParams & params , u32 skipDrawReason ) ;
2015-08-05 02:43:40 +02:00
VirtualFramebuffer * SetRenderFrameBuffer ( bool framebufChanged , int skipDrawReason ) {
2014-09-09 08:12:42 -07:00
// Inlining this part since it's so frequent.
2015-07-26 22:38:40 +02:00
if ( ! framebufChanged & & currentRenderVfb_ ) {
2014-09-09 08:12:42 -07:00
currentRenderVfb_ - > last_frame_render = gpuStats . numFlips ;
currentRenderVfb_ - > dirtyAfterDisplay = true ;
2015-07-26 22:38:40 +02:00
if ( ! skipDrawReason )
2014-09-09 08:12:42 -07:00
currentRenderVfb_ - > reallyDirtyAfterDisplay = true ;
2015-08-05 02:43:40 +02:00
return currentRenderVfb_ ;
2015-08-05 11:51:24 +02:00
} else {
// This is so that we will be able to drive DoSetRenderFramebuffer with inputs
// that come from elsewhere than gstate.
FramebufferHeuristicParams inputs ;
GetFramebufferHeuristicInputs ( & inputs , gstate ) ;
2016-03-22 00:12:41 +01:00
VirtualFramebuffer * vfb = DoSetRenderFrameBuffer ( inputs , skipDrawReason ) ;
2020-07-19 17:47:02 +02:00
_dbg_assert_msg_ ( vfb , " DoSetRenderFramebuffer must return a valid framebuffer. " ) ;
_dbg_assert_msg_ ( currentRenderVfb_ , " DoSetRenderFramebuffer must set a valid framebuffer. " ) ;
2016-03-22 00:12:41 +01:00
return vfb ;
2014-09-09 08:12:42 -07:00
}
}
2022-08-20 09:46:15 +02:00
void SetDepthFrameBuffer ( bool isClearingDepth ) ;
2022-08-01 23:55:58 +02:00
2020-06-02 09:51:38 +02:00
void RebindFramebuffer ( const char * tag ) ;
2022-08-16 10:55:44 +02:00
std : : vector < FramebufferInfo > GetFramebufferList ( ) const ;
2014-09-09 08:12:42 -07:00
2020-03-01 13:55:28 -08:00
void CopyDisplayToOutput ( bool reallyDirty ) ;
2017-02-15 23:24:25 +01:00
2015-08-05 12:13:14 +02:00
bool NotifyFramebufferCopy ( u32 src , u32 dest , int size , bool isMemset , u32 skipDrawReason ) ;
2016-01-17 12:52:40 -08:00
void NotifyVideoUpload ( u32 addr , int size , int width , GEBufferFormat fmt ) ;
2014-09-13 14:44:18 -07:00
void UpdateFromMemory ( u32 addr , int size , bool safe ) ;
2017-04-09 15:10:07 -07:00
void ApplyClearToMemory ( int x1 , int y1 , int x2 , int y2 , u32 clearColor ) ;
2022-08-06 21:12:42 -07:00
bool PerformStencilUpload ( u32 addr , int size , StencilUpload flags ) ;
2014-09-13 15:40:55 -07:00
// Returns true if it's sure this is a direct FBO->FBO transfer and it has already handle it.
// In that case we hardly need to actually copy the bytes in VRAM, they will be wrong anyway (unless
// read framebuffers is on, in which case this should always return false).
2015-08-05 12:13:14 +02:00
bool NotifyBlockTransferBefore ( u32 dstBasePtr , int dstStride , int dstX , int dstY , u32 srcBasePtr , int srcStride , int srcX , int srcY , int w , int h , int bpp , u32 skipDrawReason ) ;
void NotifyBlockTransferAfter ( u32 dstBasePtr , int dstStride , int dstX , int dstY , u32 srcBasePtr , int srcStride , int srcX , int srcY , int w , int h , int bpp , u32 skipDrawReason ) ;
2014-09-09 08:12:42 -07:00
2020-11-07 11:10:54 +01:00
bool BindFramebufferAsColorTexture ( int stage , VirtualFramebuffer * framebuffer , int flags ) ;
2020-08-03 23:35:40 +02:00
void ReadFramebufferToMemory ( VirtualFramebuffer * vfb , int x , int y , int w , int h ) ;
2017-10-18 12:34:01 +02:00
2017-12-21 15:38:55 +01:00
void DownloadFramebufferForClut ( u32 fb_address , u32 loadBytes ) ;
2020-05-11 19:11:43 -07:00
void DrawFramebufferToOutput ( const u8 * srcPixels , GEBufferFormat srcPixelFormat , int srcStride ) ;
2014-09-13 14:44:18 -07:00
2017-02-15 18:32:44 +01:00
void DrawPixels ( VirtualFramebuffer * vfb , int dstX , int dstY , const u8 * srcPixels , GEBufferFormat srcPixelFormat , int srcStride , int width , int height ) ;
2014-09-13 14:44:18 -07:00
size_t NumVFBs ( ) const { return vfbs_ . size ( ) ; }
2014-09-09 08:12:42 -07:00
2022-08-16 10:55:44 +02:00
u32 PrevDisplayFramebufAddr ( ) const {
2018-11-11 10:54:28 +01:00
return prevDisplayFramebuf_ ? prevDisplayFramebuf_ - > fb_address : 0 ;
2014-09-09 08:12:42 -07:00
}
2022-08-16 10:55:44 +02:00
u32 DisplayFramebufAddr ( ) const {
2018-11-11 10:54:28 +01:00
return displayFramebuf_ ? displayFramebuf_ - > fb_address : 0 ;
2014-09-09 08:12:42 -07:00
}
2022-08-16 10:55:44 +02:00
u32 DisplayFramebufStride ( ) const {
2016-09-25 16:31:38 -07:00
return displayFramebuf_ ? displayStride_ : 0 ;
}
2022-08-16 10:55:44 +02:00
GEBufferFormat DisplayFramebufFormat ( ) const {
2016-09-25 16:31:38 -07:00
return displayFramebuf_ ? displayFormat_ : GE_FORMAT_INVALID ;
}
2022-08-16 10:55:44 +02:00
bool UseBufferedRendering ( ) const {
2020-04-04 10:51:47 -07:00
return useBufferedRendering_ ;
}
2022-08-16 10:55:44 +02:00
bool MayIntersectFramebuffer ( u32 start ) const {
2014-09-09 08:12:42 -07:00
// Clear the cache/kernel bits.
start = start & 0x3FFFFFFF ;
// Most games only have two framebuffers at the start.
if ( start > = framebufRangeEnd_ | | start < PSP_GetVidMemBase ( ) ) {
return false ;
}
return true ;
}
2017-02-17 14:30:42 +01:00
VirtualFramebuffer * GetCurrentRenderVFB ( ) const {
return currentRenderVfb_ ;
}
2022-08-16 23:00:16 +02:00
// This only checks for the color channel.
2022-08-16 10:55:44 +02:00
VirtualFramebuffer * GetVFBAt ( u32 addr ) const ;
2022-08-16 23:00:16 +02:00
2022-08-16 10:55:44 +02:00
VirtualFramebuffer * GetDisplayVFB ( ) const {
2014-09-09 22:09:41 -07:00
return GetVFBAt ( displayFramebufPtr_ ) ;
}
2014-09-09 08:12:42 -07:00
int GetRenderWidth ( ) const { return currentRenderVfb_ ? currentRenderVfb_ - > renderWidth : 480 ; }
int GetRenderHeight ( ) const { return currentRenderVfb_ ? currentRenderVfb_ - > renderHeight : 272 ; }
int GetTargetWidth ( ) const { return currentRenderVfb_ ? currentRenderVfb_ - > width : 480 ; }
int GetTargetHeight ( ) const { return currentRenderVfb_ ? currentRenderVfb_ - > height : 272 ; }
int GetTargetBufferWidth ( ) const { return currentRenderVfb_ ? currentRenderVfb_ - > bufferWidth : 480 ; }
int GetTargetBufferHeight ( ) const { return currentRenderVfb_ ? currentRenderVfb_ - > bufferHeight : 272 ; }
int GetTargetStride ( ) const { return currentRenderVfb_ ? currentRenderVfb_ - > fb_stride : 512 ; }
2022-08-22 21:28:43 +02:00
GEBufferFormat GetTargetFormat ( ) const { return currentRenderVfb_ ? currentRenderVfb_ - > fb_format : displayFormat_ ; }
2014-09-09 08:12:42 -07:00
2015-07-26 22:38:40 +02:00
void SetColorUpdated ( int skipDrawReason ) {
2014-09-13 14:44:18 -07:00
if ( currentRenderVfb_ ) {
2015-07-26 22:38:40 +02:00
SetColorUpdated ( currentRenderVfb_ , skipDrawReason ) ;
2014-09-13 14:44:18 -07:00
}
}
2016-05-19 20:55:34 -07:00
void SetSafeSize ( u16 w , u16 h ) ;
2014-09-13 14:44:18 -07:00
2017-04-24 11:58:16 -07:00
virtual void Resized ( ) ;
2020-05-13 00:06:13 -07:00
virtual void DestroyAllFBOs ( ) ;
2016-12-21 18:13:58 +01:00
2020-11-07 00:56:48 +01:00
virtual void DeviceLost ( ) ;
virtual void DeviceRestore ( Draw : : DrawContext * draw ) ;
2020-11-05 14:51:46 +01:00
Draw : : Framebuffer * GetTempFBO ( TempFBO reason , u16 w , u16 h ) ;
2017-02-07 00:24:38 +01:00
2017-02-14 12:42:35 +01:00
// Debug features
2017-10-11 13:37:00 +02:00
virtual bool GetFramebuffer ( u32 fb_address , int fb_stride , GEBufferFormat format , GPUDebugBuffer & buffer , int maxRes ) ;
2017-10-11 15:21:53 +02:00
virtual bool GetDepthbuffer ( u32 fb_address , int fb_stride , u32 z_address , int z_stride , GPUDebugBuffer & buffer ) ;
virtual bool GetStencilbuffer ( u32 fb_address , int fb_stride , GPUDebugBuffer & buffer ) ;
2017-10-16 16:27:16 +02:00
virtual bool GetOutputFramebuffer ( GPUDebugBuffer & buffer ) ;
2017-02-14 12:42:35 +01:00
2022-08-16 10:55:44 +02:00
const std : : vector < VirtualFramebuffer * > & Framebuffers ( ) const {
2020-09-12 12:37:05 +02:00
return vfbs_ ;
}
2020-12-13 00:20:47 +01:00
void ReinterpretFramebuffer ( VirtualFramebuffer * vfb , GEBufferFormat oldFormat , GEBufferFormat newFormat ) ;
2020-09-12 12:37:05 +02:00
2014-09-09 08:12:42 -07:00
protected :
2017-10-18 11:20:58 +02:00
virtual void PackFramebufferSync_ ( VirtualFramebuffer * vfb , int x , int y , int w , int h ) ;
2020-05-09 22:06:22 -07:00
void SetViewport2D ( int x , int y , int w , int h ) ;
2022-07-20 10:27:08 +02:00
Draw : : Texture * MakePixelTexture ( const u8 * srcPixels , GEBufferFormat srcPixelFormat , int srcStride , int width , int height ) ;
2022-08-03 12:39:53 +02:00
void DrawActiveTexture ( float x , float y , float w , float h , float destW , float destH , float u0 , float v0 , float u1 , float v1 , int uvRotation , int flags ) ;
2017-02-15 12:09:51 +01:00
2022-08-23 10:35:58 +02:00
Draw2DPipeline * Get2DPipeline ( Draw2DShader shader ) ;
2022-08-03 11:42:37 +02:00
2022-08-18 10:51:50 +02:00
void CopyToColorFromOverlappingFramebuffers ( VirtualFramebuffer * dest ) ;
2022-08-17 12:11:00 +02:00
void CopyToDepthFromOverlappingFramebuffers ( VirtualFramebuffer * dest ) ;
2017-04-13 23:35:07 -07:00
bool UpdateSize ( ) ;
2015-09-27 19:59:47 +02:00
2017-10-18 12:26:02 +02:00
void FlushBeforeCopy ( ) ;
2017-02-07 00:42:39 +01:00
virtual void DecimateFBOs ( ) ; // keeping it virtual to let D3D do a little extra
2014-09-13 14:23:18 -07:00
2014-09-13 15:12:06 -07:00
// Used by ReadFramebufferToMemory and later framebuffer block copies
2022-08-07 13:19:27 +02:00
void BlitFramebuffer ( VirtualFramebuffer * dst , int dstX , int dstY , VirtualFramebuffer * src , int srcX , int srcY , int w , int h , int bpp , const char * tag ) ;
2022-08-03 15:41:17 +02:00
void BlitUsingRaster (
Draw : : Framebuffer * src , float srcX1 , float srcY1 , float srcX2 , float srcY2 ,
2022-08-23 10:05:44 +02:00
Draw : : Framebuffer * dest , float destX1 , float destY1 , float destX2 , float destY2 , bool linearFilter , Draw2DPipeline * pipeline , const char * tag ) ;
2022-08-03 15:41:17 +02:00
2017-04-06 18:49:48 -07:00
void CopyFramebufferForColorTexture ( VirtualFramebuffer * dst , VirtualFramebuffer * src , int flags ) ;
2014-09-13 15:12:06 -07:00
2015-08-05 02:43:40 +02:00
void EstimateDrawingSize ( u32 fb_address , GEBufferFormat fb_format , int viewport_width , int viewport_height , int region_width , int region_height , int scissor_width , int scissor_height , int fb_stride , int & drawing_width , int & drawing_height ) ;
2019-09-17 14:45:40 +02:00
u32 ColorBufferByteSize ( const VirtualFramebuffer * vfb ) const ;
2014-09-09 08:12:42 -07:00
2017-02-06 12:10:08 +01:00
void NotifyRenderFramebufferCreated ( VirtualFramebuffer * vfb ) ;
void NotifyRenderFramebufferUpdated ( VirtualFramebuffer * vfb , bool vfbFormatChanged ) ;
2017-02-07 00:29:02 +01:00
void NotifyRenderFramebufferSwitched ( VirtualFramebuffer * prevVfb , VirtualFramebuffer * vfb , bool isClearingDepth ) ;
2017-02-06 12:10:08 +01:00
2020-09-17 20:31:40 +02:00
void BlitFramebufferDepth ( VirtualFramebuffer * src , VirtualFramebuffer * dst ) ;
2014-09-09 22:56:54 -07:00
2017-11-04 11:41:44 +01:00
void ResizeFramebufFBO ( VirtualFramebuffer * vfb , int w , int h , bool force = false , bool skipCopy = false ) ;
2015-09-23 12:25:38 +02:00
void ShowScreenResolution ( ) ;
2014-09-09 22:56:54 -07:00
bool ShouldDownloadFramebuffer ( const VirtualFramebuffer * vfb ) const ;
2016-06-04 19:36:30 -07:00
void DownloadFramebufferOnSwitch ( VirtualFramebuffer * vfb ) ;
2018-11-05 00:28:01 +01:00
void FindTransferFramebuffers ( VirtualFramebuffer * & dstBuffer , VirtualFramebuffer * & srcBuffer , u32 dstBasePtr , int dstStride , int & dstX , int & dstY , u32 srcBasePtr , int srcStride , int & srcX , int & srcY , int & srcWidth , int & srcHeight , int & dstWidth , int & dstHeight , int bpp ) ;
2016-01-04 20:40:07 -08:00
VirtualFramebuffer * FindDownloadTempBuffer ( VirtualFramebuffer * vfb ) ;
2020-12-13 00:20:47 +01:00
virtual void UpdateDownloadTempBuffer ( VirtualFramebuffer * nvfb ) { }
2018-11-11 22:50:15 +01:00
VirtualFramebuffer * CreateRAMFramebuffer ( uint32_t fbAddress , int width , int height , int stride , GEBufferFormat format ) ;
2014-09-09 22:56:54 -07:00
2015-03-14 14:58:32 -07:00
void UpdateFramebufUsage ( VirtualFramebuffer * vfb ) ;
2020-09-12 12:32:24 +02:00
static void SetColorUpdated ( VirtualFramebuffer * dstBuffer , int skipDrawReason ) {
2014-09-09 08:12:42 -07:00
dstBuffer - > memoryUpdated = false ;
2016-01-04 22:21:33 -08:00
dstBuffer - > clutUpdatedBytes = 0 ;
2014-09-09 08:12:42 -07:00
dstBuffer - > dirtyAfterDisplay = true ;
dstBuffer - > drawnWidth = dstBuffer - > width ;
dstBuffer - > drawnHeight = dstBuffer - > height ;
2022-08-22 21:28:43 +02:00
dstBuffer - > drawnFormat = dstBuffer - > fb_format ;
2015-07-26 22:38:40 +02:00
if ( ( skipDrawReason & SKIPDRAW_SKIPFRAME ) = = 0 )
2014-09-09 08:12:42 -07:00
dstBuffer - > reallyDirtyAfterDisplay = true ;
}
2022-08-16 22:39:09 +02:00
inline int GetBindSeqCount ( ) {
return fbBindSeqCount_ + + ;
}
2020-05-09 22:06:22 -07:00
PresentationCommon * presentation_ = nullptr ;
2017-06-02 17:03:29 +02:00
Draw : : DrawContext * draw_ = nullptr ;
2022-08-05 14:49:45 +02:00
2017-06-02 17:03:29 +02:00
TextureCacheCommon * textureCache_ = nullptr ;
ShaderManagerCommon * shaderManager_ = nullptr ;
2017-10-18 12:26:02 +02:00
DrawEngineCommon * drawEngine_ = nullptr ;
2022-08-05 14:49:45 +02:00
2017-06-02 17:03:29 +02:00
bool needBackBufferYSwap_ = false ;
2017-02-05 19:51:50 +01:00
2017-06-02 17:03:29 +02:00
u32 displayFramebufPtr_ = 0 ;
u32 displayStride_ = 0 ;
2022-08-16 19:21:50 +02:00
GEBufferFormat displayFormat_ = GE_FORMAT_565 ;
2020-03-01 13:55:28 -08:00
u32 prevDisplayFramebufPtr_ = 0 ;
2014-09-09 08:12:42 -07:00
2022-08-16 22:39:09 +02:00
int fbBindSeqCount_ = 0 ;
2017-06-02 17:03:29 +02:00
VirtualFramebuffer * displayFramebuf_ = nullptr ;
VirtualFramebuffer * prevDisplayFramebuf_ = nullptr ;
VirtualFramebuffer * prevPrevDisplayFramebuf_ = nullptr ;
int frameLastFramebufUsed_ = 0 ;
2014-09-09 08:12:42 -07:00
2017-06-02 17:03:29 +02:00
VirtualFramebuffer * currentRenderVfb_ = nullptr ;
2014-09-09 08:12:42 -07:00
// The range of PSP memory that may contain FBOs. So we can skip iterating.
2017-06-02 17:03:29 +02:00
u32 framebufRangeEnd_ = 0 ;
2014-09-09 08:12:42 -07:00
2017-06-02 17:03:29 +02:00
bool useBufferedRendering_ = false ;
bool postShaderIsUpscalingFilter_ = false ;
2020-05-16 00:31:14 -07:00
bool postShaderIsSupersampling_ = false ;
2014-09-09 22:56:54 -07:00
2014-09-09 08:12:42 -07:00
std : : vector < VirtualFramebuffer * > vfbs_ ;
2016-01-04 20:40:07 -08:00
std : : vector < VirtualFramebuffer * > bvfbs_ ; // blitting framebuffers (for download)
2014-09-09 22:56:54 -07:00
2017-06-02 17:03:29 +02:00
bool gameUsesSequentialCopies_ = false ;
2014-09-09 23:11:25 -07:00
2020-11-05 11:21:00 +01:00
// Sampled in BeginFrame/UpdateSize for safety.
2018-03-22 22:25:04 +01:00
float renderWidth_ = 0.0f ;
float renderHeight_ = 0.0f ;
2022-08-16 22:39:09 +02:00
int renderScaleFactor_ = 1 ;
2022-08-16 19:21:50 +02:00
int pixelWidth_ = 0 ;
int pixelHeight_ = 0 ;
2017-04-13 23:35:07 -07:00
int bloomHack_ = 0 ;
2015-09-19 16:19:03 +02:00
2020-05-11 13:36:23 -07:00
Draw : : DataFormat preferredPixelsFormat_ = Draw : : DataFormat : : R8G8B8A8_UNORM ;
2017-02-07 00:24:38 +01:00
2018-05-06 08:57:44 -07:00
struct TempFBOInfo {
2017-02-07 00:24:38 +01:00
Draw : : Framebuffer * fbo ;
int last_frame_used ;
} ;
2018-06-03 08:08:45 -07:00
std : : unordered_map < u64 , TempFBOInfo > tempFBOs_ ;
2017-02-07 00:24:38 +01:00
2017-10-25 20:28:12 +02:00
std : : vector < Draw : : Framebuffer * > fbosToDelete_ ;
2014-09-09 23:11:25 -07:00
// Aggressively delete unused FBOs to save gpu memory.
enum {
FBO_OLD_AGE = 5 ,
2015-03-14 14:58:32 -07:00
FBO_OLD_USAGE_FLAG = 15 ,
2014-09-09 23:11:25 -07:00
} ;
2020-11-03 15:44:57 +01:00
// Thin3D stuff for reinterpreting image data between the various 16-bit formats.
// Safe, not optimal - there might be input attachment tricks, etc, but we can't use them
// since we don't want N different implementations.
2022-08-23 10:15:53 +02:00
Draw2DPipeline * reinterpretFromTo_ [ 3 ] [ 3 ] { } ;
2022-07-20 11:09:32 +02:00
2022-08-16 22:39:09 +02:00
// Common implementation of stencil buffer upload. Also not 100% optimal, but not performance
2022-07-20 11:09:32 +02:00
// critical either.
Draw : : Pipeline * stencilUploadPipeline_ = nullptr ;
Draw : : SamplerState * stencilUploadSampler_ = nullptr ;
2022-08-03 11:42:37 +02:00
// Draw2D pipelines
2022-08-23 10:05:44 +02:00
Draw2DPipeline * draw2DPipelineColor_ = nullptr ;
Draw2DPipeline * draw2DPipelineDepth_ = nullptr ;
Draw2DPipeline * draw2DPipeline565ToDepth_ = nullptr ;
Draw2DPipeline * draw2DPipeline565ToDepthDeswizzle_ = nullptr ;
2022-08-23 10:35:58 +02:00
Draw2D draw2D_ ;
2022-08-16 12:46:13 +02:00
// The fragment shaders are "owned" by the pipelines since they're 1:1.
2014-09-09 08:12:42 -07:00
} ;