2014-09-09 15:12:42 +00: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-12 23:20:47 +00: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 15:12:42 +00:00
# pragma once
# include <vector>
2018-06-03 15:08:45 +00:00
# include <unordered_map>
2015-07-26 20:38:40 +00:00
2014-09-09 15:12:42 +00:00
# include "Common/CommonTypes.h"
2020-10-04 07:29:36 +00:00
# include "Common/Log.h"
2022-08-03 09:42:37 +00:00
# include "Common/GPU/thin3d.h"
2015-07-26 20:38:40 +00:00
# include "GPU/GPU.h"
2014-09-09 15:12:42 +00:00
# include "GPU/ge_constants.h"
2017-10-18 10:49:15 +00:00
# include "GPU/GPUInterface.h"
2022-08-03 09:42:37 +00:00
# include "GPU/Common/Draw2D.h"
2014-09-09 15:12:42 +00:00
enum {
FB_USAGE_DISPLAYED_FRAMEBUFFER = 1 ,
2022-08-17 17:55:19 +00:00
FB_USAGE_RENDER_COLOR = 2 ,
2014-09-09 15:12:42 +00:00
FB_USAGE_TEXTURE = 4 ,
2015-04-28 07:08:00 +00:00
FB_USAGE_CLUT = 8 ,
2017-04-09 22:10:07 +00:00
FB_USAGE_DOWNLOAD = 16 ,
FB_USAGE_DOWNLOAD_CLEAR = 32 ,
2022-04-30 16:13:24 +00:00
FB_USAGE_BLUE_TO_ALPHA = 64 ,
2022-08-16 20:39:09 +00:00
FB_USAGE_FIRST_FRAME_SAVED = 128 ,
2022-08-17 17:55:19 +00:00
FB_USAGE_RENDER_DEPTH = 256 ,
2014-09-09 15:12:42 +00:00
} ;
enum {
FB_NON_BUFFERED_MODE = 0 ,
FB_BUFFERED_MODE = 1 ,
} ;
2017-02-04 17:46:12 +00:00
namespace Draw {
class Framebuffer ;
2015-11-14 12:24:51 +00:00
}
2014-09-09 15:12:42 +00:00
2016-03-17 10:56:43 +00:00
class VulkanFBO ;
2022-08-16 17:21:50 +00:00
class ShaderWriter ;
2016-01-03 22:09:37 +00:00
2022-07-17 16:14:55 +00: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.
2022-08-29 08:14:29 +00:00
// Two VirtualFramebuffer can occupy the same address range as long as they have different fb_format.
// In that case, the one with the highest colorBindSeq number is the valid one.
2014-09-09 15:12:42 +00:00
struct VirtualFramebuffer {
u32 fb_address ;
2019-09-17 12:45:40 +00:00
u32 z_address ; // If 0, it's a "RAM" framebuffer.
2022-08-16 20:39:09 +00:00
u16 fb_stride ;
u16 z_stride ;
2014-09-09 15:12:42 +00:00
2022-08-22 19:28:43 +00: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).
2022-08-29 08:14:29 +00:00
// NOTE: CANNOT be changed after creation anymore!
2022-08-22 19:28:43 +00:00
GEBufferFormat fb_format ;
2022-08-22 21:30:28 +00:00
Draw : : Framebuffer * fbo ;
2020-08-04 12:45:14 +00:00
// width/height: The detected size of the current framebuffer, in original PSP pixels.
2014-09-09 15:12:42 +00:00
u16 width ;
u16 height ;
2020-08-04 12:45:14 +00:00
2020-11-05 10:21:00 +00:00
// bufferWidth/bufferHeight: The pre-scaling size of the buffer itself. May only be bigger than or equal to width/height.
2022-08-16 20:39:09 +00:00
// In original PSP pixels - actual framebuffer is this size times the render resolution multiplier.
2020-11-05 10:21:00 +00: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-18 00:40:37 +00:00
// renderWidth/renderHeight: The scaled size we render at. May be scaled to render at higher resolutions.
2022-08-16 20:39:09 +00:00
// These are simply bufferWidth/Height * renderScaleFactor and are thus redundant.
2014-09-09 15:12:42 +00:00
u16 renderWidth ;
u16 renderHeight ;
2020-08-04 12:45:14 +00:00
2022-08-17 08:15:02 +00: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 20:39:09 +00: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 ;
2014-09-09 15:12:42 +00:00
u16 usageFlags ;
2022-08-16 20:39:09 +00:00
// These are used to track state to try to avoid buffer size shifting back and forth.
2022-08-17 08:15:02 +00: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 15:12:42 +00:00
u16 newWidth ;
u16 newHeight ;
2020-11-05 10:21:00 +00:00
2022-08-16 20:39:09 +00:00
// The frame number at which this was last resized.
2014-09-09 15:12:42 +00:00
int lastFrameNewSize ;
2022-08-16 20:39:09 +00:00
// Tracking for downloads-to-CLUT.
u16 clutUpdatedBytes ;
bool memoryUpdated ;
2014-09-09 15:12:42 +00:00
2022-08-16 20:39:09 +00:00
// TODO: Fold into usageFlags?
2014-09-09 15:12:42 +00:00
bool dirtyAfterDisplay ;
bool reallyDirtyAfterDisplay ; // takes frame skipping into account
2020-09-12 10:32:24 +00:00
2022-08-16 20:39:09 +00: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 10:32:24 +00: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 ;
2022-08-25 21:08:38 +00:00
// Convenience methods
inline int WidthInBytes ( ) const { return width * BufferFormatBytesPerPixel ( fb_format ) ; }
2022-09-11 12:46:00 +00:00
inline int BufferWidthInBytes ( ) const { return bufferWidth * BufferFormatBytesPerPixel ( fb_format ) ; }
2022-08-25 21:08:38 +00:00
inline int FbStrideInBytes ( ) const { return fb_stride * BufferFormatBytesPerPixel ( fb_format ) ; }
inline int ZStrideInBytes ( ) const { return z_stride * 2 ; }
2014-09-09 15:12:42 +00:00
} ;
2015-08-05 09:51:24 +00:00
struct FramebufferHeuristicParams {
u32 fb_address ;
u32 z_address ;
2022-08-16 20:39:09 +00:00
u16 fb_stride ;
u16 z_stride ;
2022-08-22 19:22:00 +00:00
GEBufferFormat fb_format ;
2015-08-05 09:51:24 +00:00
bool isClearingDepth ;
bool isWritingDepth ;
bool isDrawing ;
bool isModeThrough ;
2022-08-15 05:13:39 +00:00
bool isBlending ;
2015-08-05 09:51:24 +00:00
int viewportWidth ;
int viewportHeight ;
2022-08-31 09:40:10 +00:00
int16_t regionWidth ;
int16_t regionHeight ;
int16_t scissorLeft ;
int16_t scissorTop ;
int16_t scissorRight ;
int16_t scissorBottom ;
2015-08-05 09:51:24 +00:00
} ;
struct GPUgstate ;
extern GPUgstate gstate ;
void GetFramebufferHeuristicInputs ( FramebufferHeuristicParams * params , const GPUgstate & gstate ) ;
2015-09-13 18:14:51 +00:00
enum BindFramebufferColorFlags {
BINDFBCOLOR_SKIP_COPY = 0 ,
BINDFBCOLOR_MAY_COPY = 1 ,
2020-12-12 23:20:47 +00:00
BINDFBCOLOR_MAY_COPY_WITH_UV = 3 , // includes BINDFBCOLOR_MAY_COPY
2015-09-13 02:43:02 +00:00
BINDFBCOLOR_APPLY_TEX_OFFSET = 4 ,
2018-11-24 18:19:10 +00:00
// Used when rendering to a temporary surface (e.g. not the current render target.)
BINDFBCOLOR_FORCE_SELF = 8 ,
2015-09-13 18:14:51 +00:00
} ;
2017-06-01 06:24:56 +00:00
enum DrawTextureFlags {
DRAWTEX_NEAREST = 0 ,
DRAWTEX_LINEAR = 1 ,
2019-06-21 12:00:02 +00:00
DRAWTEX_TO_BACKBUFFER = 8 ,
2022-09-12 13:34:32 +00:00
DRAWTEX_DEPTH = 16 ,
2017-06-01 06:24:56 +00:00
} ;
2019-06-22 20:15:09 +00:00
inline DrawTextureFlags operator | ( const DrawTextureFlags & lhs , const DrawTextureFlags & rhs ) {
return DrawTextureFlags ( ( u32 ) lhs | ( u32 ) rhs ) ;
}
2018-05-06 15:57:44 +00:00
enum class TempFBO {
DEPAL ,
BLIT ,
// For copies of framebuffers (e.g. shader blending.)
COPY ,
2020-11-06 10:54:57 +00:00
// For another type of framebuffers that can happen together with COPY (see Outrun)
REINTERPRET ,
2019-03-10 15:35:31 +00:00
// Used to copy stencil data, means we need a stencil backing.
STENCIL ,
2018-05-06 15:57:44 +00:00
} ;
2022-08-29 21:59:43 +00:00
inline Draw : : DataFormat GEFormatToThin3D ( GEBufferFormat geFormat ) {
2017-10-18 09:20:58 +00:00
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 ;
2022-08-29 21:59:43 +00:00
case GE_FORMAT_DEPTH16 :
return Draw : : DataFormat : : D16 ;
2017-10-18 09:20:58 +00:00
default :
2022-08-29 21:59:43 +00:00
// TODO: Assert?
2017-10-18 09:20:58 +00:00
return Draw : : DataFormat : : UNDEFINED ;
}
}
2022-08-25 21:08:38 +00:00
// Dimensions are in bytes, later steps get to convert back into real coordinates as appropriate.
// Makes it easy to see if blits match etc.
struct BlockTransferRect {
VirtualFramebuffer * vfb ;
// RasterChannel channel; // We currently only deal with color for block copies.
int x_bytes ;
int y ;
int w_bytes ;
int h ;
std : : string ToString ( ) const ;
int w_pixels ( ) const {
return w_bytes / BufferFormatBytesPerPixel ( vfb - > fb_format ) ;
}
int x_pixels ( ) const {
return x_bytes / BufferFormatBytesPerPixel ( vfb - > fb_format ) ;
}
} ;
2017-02-05 18:51:50 +00:00
namespace Draw {
class DrawContext ;
}
2017-02-14 11:42:35 +00:00
struct GPUDebugBuffer ;
2017-10-18 10:26:02 +00:00
class DrawEngineCommon ;
2020-05-10 05:06:22 +00:00
class PresentationCommon ;
class ShaderManagerCommon ;
class TextureCacheCommon ;
2017-02-06 11:02:30 +00:00
2014-09-09 15:12:42 +00:00
class FramebufferManagerCommon {
public :
2020-11-03 14:44:57 +00:00
FramebufferManagerCommon ( Draw : : DrawContext * draw ) ;
2014-09-09 15:12:42 +00:00
virtual ~ FramebufferManagerCommon ( ) ;
2022-08-05 12:49:45 +00:00
void SetTextureCache ( TextureCacheCommon * tc ) {
textureCache_ = tc ;
}
void SetShaderManager ( ShaderManagerCommon * sm ) {
shaderManager_ = sm ;
}
void SetDrawEngine ( DrawEngineCommon * td ) {
drawEngine_ = td ;
}
2014-09-13 23:47:23 +00:00
virtual void Init ( ) ;
2017-10-25 18:28:12 +00:00
virtual void BeginFrame ( ) ;
2014-09-13 21:44:18 +00:00
void SetDisplayFramebuffer ( u32 framebuf , u32 stride , GEBufferFormat format ) ;
2017-02-06 11:02:30 +00:00
void DestroyFramebuf ( VirtualFramebuffer * v ) ;
2014-09-10 05:56:54 +00:00
2022-08-30 17:36:08 +00:00
VirtualFramebuffer * DoSetRenderFrameBuffer ( FramebufferHeuristicParams & params , u32 skipDrawReason ) ;
2015-08-05 00:43:40 +00:00
VirtualFramebuffer * SetRenderFrameBuffer ( bool framebufChanged , int skipDrawReason ) {
2014-09-09 15:12:42 +00:00
// Inlining this part since it's so frequent.
2015-07-26 20:38:40 +00:00
if ( ! framebufChanged & & currentRenderVfb_ ) {
2014-09-09 15:12:42 +00:00
currentRenderVfb_ - > last_frame_render = gpuStats . numFlips ;
currentRenderVfb_ - > dirtyAfterDisplay = true ;
2015-07-26 20:38:40 +00:00
if ( ! skipDrawReason )
2014-09-09 15:12:42 +00:00
currentRenderVfb_ - > reallyDirtyAfterDisplay = true ;
2015-08-05 00:43:40 +00:00
return currentRenderVfb_ ;
2015-08-05 09:51:24 +00: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-21 23:12:41 +00:00
VirtualFramebuffer * vfb = DoSetRenderFrameBuffer ( inputs , skipDrawReason ) ;
2020-07-19 15:47:02 +00:00
_dbg_assert_msg_ ( vfb , " DoSetRenderFramebuffer must return a valid framebuffer. " ) ;
_dbg_assert_msg_ ( currentRenderVfb_ , " DoSetRenderFramebuffer must set a valid framebuffer. " ) ;
2016-03-21 23:12:41 +00:00
return vfb ;
2014-09-09 15:12:42 +00:00
}
}
2022-08-20 07:46:15 +00:00
void SetDepthFrameBuffer ( bool isClearingDepth ) ;
2022-08-01 21:55:58 +00:00
2020-06-02 07:51:38 +00:00
void RebindFramebuffer ( const char * tag ) ;
2022-08-16 08:55:44 +00:00
std : : vector < FramebufferInfo > GetFramebufferList ( ) const ;
2014-09-09 15:12:42 +00:00
2020-03-01 21:55:28 +00:00
void CopyDisplayToOutput ( bool reallyDirty ) ;
2017-02-15 22:24:25 +00:00
2022-10-04 03:17:25 +00:00
bool NotifyFramebufferCopy ( u32 src , u32 dest , int size , GPUCopyFlag flags , u32 skipDrawReason ) ;
2022-10-09 20:49:41 +00:00
void PerformWriteFormattedFromMemory ( u32 addr , int size , int width , GEBufferFormat fmt ) ;
2022-08-30 04:41:37 +00:00
void UpdateFromMemory ( u32 addr , int size ) ;
2017-04-09 22:10:07 +00:00
void ApplyClearToMemory ( int x1 , int y1 , int x2 , int y2 , u32 clearColor ) ;
2022-10-09 20:49:41 +00:00
bool PerformWriteStencilFromMemory ( u32 addr , int size , WriteStencil flags ) ;
2022-08-24 22:25:53 +00:00
2014-09-13 22:40:55 +00: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).
2022-08-24 22:25:53 +00:00
// If this returns false, a memory copy will happen and NotifyBlockTransferAfter will be called.
2015-08-05 10:13:14 +00: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 ) ;
2022-08-24 22:25:53 +00:00
// This gets called after the memory copy, in case NotifyBlockTransferBefore returned false.
// Otherwise it doesn't get called.
2015-08-05 10:13:14 +00:00
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 15:12:42 +00:00
2020-11-07 10:10:54 +00:00
bool BindFramebufferAsColorTexture ( int stage , VirtualFramebuffer * framebuffer , int flags ) ;
2022-08-29 21:59:43 +00:00
void ReadFramebufferToMemory ( VirtualFramebuffer * vfb , int x , int y , int w , int h , RasterChannel channel ) ;
2017-10-18 10:34:01 +00:00
2017-12-21 14:38:55 +00:00
void DownloadFramebufferForClut ( u32 fb_address , u32 loadBytes ) ;
2022-08-29 08:14:29 +00:00
void DrawFramebufferToOutput ( const u8 * srcPixels , int srcStride , GEBufferFormat srcPixelFormat ) ;
2014-09-13 21:44:18 +00:00
2022-09-12 09:16:30 +00:00
void DrawPixels ( VirtualFramebuffer * vfb , int dstX , int dstY , const u8 * srcPixels , GEBufferFormat srcPixelFormat , int srcStride , int width , int height , RasterChannel channel , const char * tag ) ;
2017-02-15 17:32:44 +00:00
2014-09-13 21:44:18 +00:00
size_t NumVFBs ( ) const { return vfbs_ . size ( ) ; }
2014-09-09 15:12:42 +00:00
2022-08-16 08:55:44 +00:00
u32 PrevDisplayFramebufAddr ( ) const {
2018-11-11 09:54:28 +00:00
return prevDisplayFramebuf_ ? prevDisplayFramebuf_ - > fb_address : 0 ;
2014-09-09 15:12:42 +00:00
}
2022-09-20 21:01:36 +00:00
u32 CurrentDisplayFramebufAddr ( ) const {
2018-11-11 09:54:28 +00:00
return displayFramebuf_ ? displayFramebuf_ - > fb_address : 0 ;
2014-09-09 15:12:42 +00:00
}
2022-09-20 21:01:36 +00:00
u32 DisplayFramebufAddr ( ) const {
return displayFramebufPtr_ ;
}
2022-08-16 08:55:44 +00:00
u32 DisplayFramebufStride ( ) const {
2022-09-20 21:01:36 +00:00
return displayStride_ ;
2016-09-25 23:31:38 +00:00
}
2022-08-16 08:55:44 +00:00
GEBufferFormat DisplayFramebufFormat ( ) const {
2022-09-20 21:01:36 +00:00
return displayFormat_ ;
2016-09-25 23:31:38 +00:00
}
2022-08-16 08:55:44 +00:00
bool UseBufferedRendering ( ) const {
2020-04-04 17:51:47 +00:00
return useBufferedRendering_ ;
}
2022-08-16 08:55:44 +00:00
bool MayIntersectFramebuffer ( u32 start ) const {
2014-09-09 15:12:42 +00:00
// Clear the cache/kernel bits.
2022-10-03 04:28:53 +00:00
start & = 0x3FFFFFFF ;
if ( Memory : : IsVRAMAddress ( start ) )
start & = 0x041FFFFF ;
2014-09-09 15:12:42 +00:00
// Most games only have two framebuffers at the start.
if ( start > = framebufRangeEnd_ | | start < PSP_GetVidMemBase ( ) ) {
return false ;
}
return true ;
}
2017-02-17 13:30:42 +00:00
VirtualFramebuffer * GetCurrentRenderVFB ( ) const {
return currentRenderVfb_ ;
}
2022-08-16 21:00:16 +00:00
2022-08-29 08:14:29 +00:00
// This only checks for the color channel, and if there are multiple overlapping ones
// with different color depth, this might get things wrong.
// DEPRECATED FOR NEW USES - avoid whenever possible.
2022-08-16 08:55:44 +00:00
VirtualFramebuffer * GetVFBAt ( u32 addr ) const ;
2022-08-16 21:00:16 +00:00
2022-08-29 08:14:29 +00:00
// This will only return exact matches of addr+stride+format.
VirtualFramebuffer * GetExactVFB ( u32 addr , int stride , GEBufferFormat format ) const ;
// If this doesn't find the exact VFB, but one with a different color format with matching stride,
// it'll resolve the newest one at address to the format requested, and return that.
VirtualFramebuffer * ResolveVFB ( u32 addr , int stride , GEBufferFormat format ) ;
// Utility to get the display VFB.
VirtualFramebuffer * GetDisplayVFB ( ) ;
2014-09-10 05:09:41 +00:00
2014-09-09 15:12:42 +00: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 19:28:43 +00:00
GEBufferFormat GetTargetFormat ( ) const { return currentRenderVfb_ ? currentRenderVfb_ - > fb_format : displayFormat_ ; }
2014-09-09 15:12:42 +00:00
2015-07-26 20:38:40 +00:00
void SetColorUpdated ( int skipDrawReason ) {
2014-09-13 21:44:18 +00:00
if ( currentRenderVfb_ ) {
2015-07-26 20:38:40 +00:00
SetColorUpdated ( currentRenderVfb_ , skipDrawReason ) ;
2014-09-13 21:44:18 +00:00
}
}
2016-05-20 03:55:34 +00:00
void SetSafeSize ( u16 w , u16 h ) ;
2014-09-13 21:44:18 +00:00
2017-04-24 18:58:16 +00:00
virtual void Resized ( ) ;
2020-05-13 07:06:13 +00:00
virtual void DestroyAllFBOs ( ) ;
2016-12-21 17:13:58 +00:00
2020-11-06 23:56:48 +00:00
virtual void DeviceLost ( ) ;
virtual void DeviceRestore ( Draw : : DrawContext * draw ) ;
2020-11-05 13:51:46 +00:00
Draw : : Framebuffer * GetTempFBO ( TempFBO reason , u16 w , u16 h ) ;
2017-02-06 23:24:38 +00:00
2017-02-14 11:42:35 +00:00
// Debug features
2017-10-11 11:37:00 +00:00
virtual bool GetFramebuffer ( u32 fb_address , int fb_stride , GEBufferFormat format , GPUDebugBuffer & buffer , int maxRes ) ;
2017-10-11 13:21:53 +00: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 14:27:16 +00:00
virtual bool GetOutputFramebuffer ( GPUDebugBuffer & buffer ) ;
2017-02-14 11:42:35 +00:00
2022-08-16 08:55:44 +00:00
const std : : vector < VirtualFramebuffer * > & Framebuffers ( ) const {
2020-09-12 10:37:05 +00:00
return vfbs_ ;
}
2022-08-23 09:11:04 +00:00
Draw2D * GetDraw2D ( ) {
return & draw2D_ ;
}
2022-08-22 21:30:28 +00:00
// If a vfb with the target format exists, resolve it (run CopyToColorFromOverlappingFramebuffers).
// If it doesn't exist, create it and do the same.
// Returns the resolved framebuffer.
VirtualFramebuffer * ResolveFramebufferColorToFormat ( VirtualFramebuffer * vfb , GEBufferFormat newFormat ) ;
2022-09-13 09:28:37 +00:00
Draw2DPipeline * Get2DPipeline ( Draw2DShader shader ) ;
2022-09-15 14:57:03 +00:00
// If from==to, returns a copy pipeline.
2022-09-13 09:28:37 +00:00
Draw2DPipeline * GetReinterpretPipeline ( GEBufferFormat from , GEBufferFormat to , float * scaleFactorX ) ;
2022-09-13 21:55:57 +00:00
// Public to be used from the texture cache's depal shenanigans.
void BlitUsingRaster (
Draw : : Framebuffer * src , float srcX1 , float srcY1 , float srcX2 , float srcY2 ,
Draw : : Framebuffer * dest , float destX1 , float destY1 , float destX2 , float destY2 ,
bool linearFilter ,
int scaleFactor , // usually unused, except for swizzle...
Draw2DPipeline * pipeline , const char * tag ) ;
2014-09-09 15:12:42 +00:00
protected :
2022-10-09 20:49:41 +00:00
virtual void ReadbackFramebufferSync ( VirtualFramebuffer * vfb , int x , int y , int w , int h , RasterChannel channel ) ;
2022-10-09 08:08:04 +00:00
// Used for when a shader is required, such as GLES.
2022-10-09 20:49:41 +00:00
virtual void ReadbackDepthbufferSync ( VirtualFramebuffer * vfb , int x , int y , int w , int h ) ;
2020-05-10 05:06:22 +00:00
void SetViewport2D ( int x , int y , int w , int h ) ;
2022-07-20 08:27:08 +00:00
Draw : : Texture * MakePixelTexture ( const u8 * srcPixels , GEBufferFormat srcPixelFormat , int srcStride , int width , int height ) ;
2022-08-03 10:39:53 +00: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 11:09:51 +00:00
2022-08-18 08:51:50 +00:00
void CopyToColorFromOverlappingFramebuffers ( VirtualFramebuffer * dest ) ;
2022-08-17 10:11:00 +00:00
void CopyToDepthFromOverlappingFramebuffers ( VirtualFramebuffer * dest ) ;
2017-04-14 06:35:07 +00:00
bool UpdateSize ( ) ;
2015-09-27 17:59:47 +00:00
2017-10-18 10:26:02 +00:00
void FlushBeforeCopy ( ) ;
2017-02-06 23:42:39 +00:00
virtual void DecimateFBOs ( ) ; // keeping it virtual to let D3D do a little extra
2014-09-13 21:23:18 +00:00
2014-09-13 22:12:06 +00:00
// Used by ReadFramebufferToMemory and later framebuffer block copies
2022-08-29 21:59:43 +00:00
void BlitFramebuffer ( VirtualFramebuffer * dst , int dstX , int dstY , VirtualFramebuffer * src , int srcX , int srcY , int w , int h , int bpp , RasterChannel channel , const char * tag ) ;
2022-08-03 13:41:17 +00:00
2017-04-07 01:49:48 +00:00
void CopyFramebufferForColorTexture ( VirtualFramebuffer * dst , VirtualFramebuffer * src , int flags ) ;
2014-09-13 22:12:06 +00:00
2022-08-24 12:57:55 +00:00
void EstimateDrawingSize ( u32 fb_address , int fb_stride , GEBufferFormat fb_format , int viewport_width , int viewport_height , int region_width , int region_height , int scissor_width , int scissor_height , int & drawing_width , int & drawing_height ) ;
2019-09-17 12:45:40 +00:00
u32 ColorBufferByteSize ( const VirtualFramebuffer * vfb ) const ;
2014-09-09 15:12:42 +00:00
2017-02-06 11:10:08 +00:00
void NotifyRenderFramebufferCreated ( VirtualFramebuffer * vfb ) ;
2022-08-25 16:58:35 +00:00
void NotifyRenderFramebufferUpdated ( VirtualFramebuffer * vfb ) ;
2017-02-06 23:29:02 +00:00
void NotifyRenderFramebufferSwitched ( VirtualFramebuffer * prevVfb , VirtualFramebuffer * vfb , bool isClearingDepth ) ;
2017-02-06 11:10:08 +00:00
2020-09-17 18:31:40 +00:00
void BlitFramebufferDepth ( VirtualFramebuffer * src , VirtualFramebuffer * dst ) ;
2014-09-10 05:56:54 +00:00
2017-11-04 10:41:44 +00:00
void ResizeFramebufFBO ( VirtualFramebuffer * vfb , int w , int h , bool force = false , bool skipCopy = false ) ;
2015-09-23 10:25:38 +00:00
void ShowScreenResolution ( ) ;
2014-09-10 05:56:54 +00:00
bool ShouldDownloadFramebuffer ( const VirtualFramebuffer * vfb ) const ;
2016-06-05 02:36:30 +00:00
void DownloadFramebufferOnSwitch ( VirtualFramebuffer * vfb ) ;
2022-08-24 22:12:31 +00:00
2022-08-25 21:08:38 +00:00
bool FindTransferFramebuffer ( u32 basePtr , int stride , int x , int y , int w , int h , int bpp , bool destination , BlockTransferRect * rect ) ;
2022-08-24 22:12:31 +00:00
2022-08-29 21:59:43 +00:00
VirtualFramebuffer * FindDownloadTempBuffer ( VirtualFramebuffer * vfb , RasterChannel channel ) ;
2020-12-12 23:20:47 +00:00
virtual void UpdateDownloadTempBuffer ( VirtualFramebuffer * nvfb ) { }
2018-11-11 21:50:15 +00:00
VirtualFramebuffer * CreateRAMFramebuffer ( uint32_t fbAddress , int width , int height , int stride , GEBufferFormat format ) ;
2014-09-10 05:56:54 +00:00
2015-03-14 21:58:32 +00:00
void UpdateFramebufUsage ( VirtualFramebuffer * vfb ) ;
2020-09-12 10:32:24 +00:00
static void SetColorUpdated ( VirtualFramebuffer * dstBuffer , int skipDrawReason ) {
2014-09-09 15:12:42 +00:00
dstBuffer - > memoryUpdated = false ;
2016-01-05 06:21:33 +00:00
dstBuffer - > clutUpdatedBytes = 0 ;
2014-09-09 15:12:42 +00:00
dstBuffer - > dirtyAfterDisplay = true ;
dstBuffer - > drawnWidth = dstBuffer - > width ;
dstBuffer - > drawnHeight = dstBuffer - > height ;
2015-07-26 20:38:40 +00:00
if ( ( skipDrawReason & SKIPDRAW_SKIPFRAME ) = = 0 )
2014-09-09 15:12:42 +00:00
dstBuffer - > reallyDirtyAfterDisplay = true ;
}
2022-08-16 20:39:09 +00:00
inline int GetBindSeqCount ( ) {
return fbBindSeqCount_ + + ;
}
2020-05-10 05:06:22 +00:00
PresentationCommon * presentation_ = nullptr ;
2017-06-02 15:03:29 +00:00
Draw : : DrawContext * draw_ = nullptr ;
2022-08-05 12:49:45 +00:00
2017-06-02 15:03:29 +00:00
TextureCacheCommon * textureCache_ = nullptr ;
ShaderManagerCommon * shaderManager_ = nullptr ;
2017-10-18 10:26:02 +00:00
DrawEngineCommon * drawEngine_ = nullptr ;
2022-08-05 12:49:45 +00:00
2017-06-02 15:03:29 +00:00
bool needBackBufferYSwap_ = false ;
2017-02-05 18:51:50 +00:00
2017-06-02 15:03:29 +00:00
u32 displayFramebufPtr_ = 0 ;
u32 displayStride_ = 0 ;
2022-08-16 17:21:50 +00:00
GEBufferFormat displayFormat_ = GE_FORMAT_565 ;
2020-03-01 21:55:28 +00:00
u32 prevDisplayFramebufPtr_ = 0 ;
2014-09-09 15:12:42 +00:00
2022-08-16 20:39:09 +00:00
int fbBindSeqCount_ = 0 ;
2017-06-02 15:03:29 +00:00
VirtualFramebuffer * displayFramebuf_ = nullptr ;
VirtualFramebuffer * prevDisplayFramebuf_ = nullptr ;
VirtualFramebuffer * prevPrevDisplayFramebuf_ = nullptr ;
int frameLastFramebufUsed_ = 0 ;
2014-09-09 15:12:42 +00:00
2017-06-02 15:03:29 +00:00
VirtualFramebuffer * currentRenderVfb_ = nullptr ;
2014-09-09 15:12:42 +00:00
// The range of PSP memory that may contain FBOs. So we can skip iterating.
2017-06-02 15:03:29 +00:00
u32 framebufRangeEnd_ = 0 ;
2014-09-09 15:12:42 +00:00
2017-06-02 15:03:29 +00:00
bool useBufferedRendering_ = false ;
bool postShaderIsUpscalingFilter_ = false ;
2020-05-16 07:31:14 +00:00
bool postShaderIsSupersampling_ = false ;
2014-09-10 05:56:54 +00:00
2014-09-09 15:12:42 +00:00
std : : vector < VirtualFramebuffer * > vfbs_ ;
2016-01-05 04:40:07 +00:00
std : : vector < VirtualFramebuffer * > bvfbs_ ; // blitting framebuffers (for download)
2014-09-10 05:56:54 +00:00
2017-06-02 15:03:29 +00:00
bool gameUsesSequentialCopies_ = false ;
2014-09-10 06:11:25 +00:00
2020-11-05 10:21:00 +00:00
// Sampled in BeginFrame/UpdateSize for safety.
2018-03-22 21:25:04 +00:00
float renderWidth_ = 0.0f ;
float renderHeight_ = 0.0f ;
2022-08-16 20:39:09 +00:00
int renderScaleFactor_ = 1 ;
2022-08-16 17:21:50 +00:00
int pixelWidth_ = 0 ;
int pixelHeight_ = 0 ;
2017-04-14 06:35:07 +00:00
int bloomHack_ = 0 ;
2015-09-19 14:19:03 +00:00
2020-05-11 20:36:23 +00:00
Draw : : DataFormat preferredPixelsFormat_ = Draw : : DataFormat : : R8G8B8A8_UNORM ;
2017-02-06 23:24:38 +00:00
2018-05-06 15:57:44 +00:00
struct TempFBOInfo {
2017-02-06 23:24:38 +00:00
Draw : : Framebuffer * fbo ;
int last_frame_used ;
} ;
2018-06-03 15:08:45 +00:00
std : : unordered_map < u64 , TempFBOInfo > tempFBOs_ ;
2017-02-06 23:24:38 +00:00
2017-10-25 18:28:12 +00:00
std : : vector < Draw : : Framebuffer * > fbosToDelete_ ;
2014-09-10 06:11:25 +00:00
// Aggressively delete unused FBOs to save gpu memory.
enum {
FBO_OLD_AGE = 5 ,
2015-03-14 21:58:32 +00:00
FBO_OLD_USAGE_FLAG = 15 ,
2014-09-10 06:11:25 +00:00
} ;
2020-11-03 14:44:57 +00:00
2022-08-26 10:16:56 +00:00
// Thin3D stuff for reinterpreting image data between the various 16-bit color formats.
2020-11-03 14:44:57 +00:00
// 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-26 10:16:56 +00:00
Draw2DPipeline * reinterpretFromTo_ [ 4 ] [ 4 ] { } ;
2022-07-20 09:09:32 +00:00
2022-08-16 20:39:09 +00:00
// Common implementation of stencil buffer upload. Also not 100% optimal, but not performance
2022-07-20 09:09:32 +00:00
// critical either.
Draw : : Pipeline * stencilUploadPipeline_ = nullptr ;
Draw : : SamplerState * stencilUploadSampler_ = nullptr ;
2022-08-03 09:42:37 +00:00
// Draw2D pipelines
2022-08-23 08:05:44 +00:00
Draw2DPipeline * draw2DPipelineColor_ = nullptr ;
2022-09-21 16:33:15 +00:00
Draw2DPipeline * draw2DPipelineColorRect2Lin_ = nullptr ;
2022-08-23 08:05:44 +00:00
Draw2DPipeline * draw2DPipelineDepth_ = nullptr ;
Draw2DPipeline * draw2DPipeline565ToDepth_ = nullptr ;
Draw2DPipeline * draw2DPipeline565ToDepthDeswizzle_ = nullptr ;
2022-08-23 08:35:58 +00:00
Draw2D draw2D_ ;
2022-08-16 10:46:13 +00:00
// The fragment shaders are "owned" by the pipelines since they're 1:1.
2014-09-09 15:12:42 +00:00
} ;