2013-04-05 06:13:26 +00:00
|
|
|
#ifndef FRAMEBUFFER_H
|
|
|
|
#define FRAMEBUFFER_H
|
|
|
|
|
2014-09-08 11:01:22 +00:00
|
|
|
#include <list>
|
2015-04-29 13:58:06 +00:00
|
|
|
#include <vector>
|
2021-04-18 00:45:47 +00:00
|
|
|
#include <memory>
|
2014-09-08 11:01:22 +00:00
|
|
|
|
2020-11-14 09:54:28 +00:00
|
|
|
#include "gDP.h"
|
2013-04-05 06:13:26 +00:00
|
|
|
#include "Textures.h"
|
2017-01-20 11:47:19 +00:00
|
|
|
#include "Graphics/ObjectHandle.h"
|
|
|
|
|
2013-06-29 11:52:57 +00:00
|
|
|
struct gDPTile;
|
2013-11-11 08:57:57 +00:00
|
|
|
struct DepthBuffer;
|
2013-04-05 06:13:26 +00:00
|
|
|
|
2020-11-14 09:54:28 +00:00
|
|
|
const u32 fingerprint[4] = { 2, 6, 4, 3 };
|
2015-07-21 15:26:35 +00:00
|
|
|
|
2021-04-18 00:45:47 +00:00
|
|
|
namespace graphics {
|
|
|
|
class ColorBufferReader;
|
|
|
|
}
|
|
|
|
|
2013-04-05 06:13:26 +00:00
|
|
|
struct FrameBuffer
|
|
|
|
{
|
2014-09-08 11:01:22 +00:00
|
|
|
FrameBuffer();
|
|
|
|
~FrameBuffer();
|
2017-03-02 15:09:08 +00:00
|
|
|
void init(u32 _address, u16 _format, u16 _size, u16 _width, bool _cfb);
|
|
|
|
void updateEndAddress();
|
2016-03-19 14:18:39 +00:00
|
|
|
void resolveMultisampledTexture(bool _bForce = false);
|
2019-06-27 09:21:51 +00:00
|
|
|
void copyDepthTexture();
|
2016-05-08 09:58:19 +00:00
|
|
|
CachedTexture * getTexture(u32 _t);
|
2020-11-14 09:54:28 +00:00
|
|
|
CachedTexture * getTextureBG();
|
2016-09-27 14:43:28 +00:00
|
|
|
void setBufferClearParams(u32 _fillcolor, s32 _ulx, s32 _uly, s32 _lrx, s32 _lry);
|
2015-04-29 13:58:06 +00:00
|
|
|
void copyRdram();
|
2017-09-26 08:23:07 +00:00
|
|
|
void setDirty();
|
2016-10-05 08:39:41 +00:00
|
|
|
bool isValid(bool _forceCheck) const;
|
2016-02-14 11:25:07 +00:00
|
|
|
bool isAuxiliary() const;
|
2021-04-18 00:45:47 +00:00
|
|
|
CachedTexture * getColorFbTexture();
|
|
|
|
graphics::ObjectHandle getColorFbFbo();
|
|
|
|
const u8 * readPixels(s32 _x0, s32 _y0, u32 _width, u32 _height, u32 _size, bool _sync);
|
|
|
|
void cleanUp();
|
2013-04-05 06:13:26 +00:00
|
|
|
|
2020-11-14 09:54:28 +00:00
|
|
|
u32 m_startAddress = 0;
|
|
|
|
u32 m_endAddress = 0;
|
|
|
|
u32 m_size = 0;
|
|
|
|
u32 m_width = 0;
|
|
|
|
u32 m_height = 0;
|
|
|
|
u32 m_originX = 0;
|
|
|
|
u32 m_originY = 0;
|
|
|
|
u32 m_swapCount = 0;
|
|
|
|
float m_scale = 0.0f;
|
|
|
|
bool m_copiedToRdram = false;
|
|
|
|
bool m_fingerprint = false;
|
|
|
|
bool m_cleared = false;
|
|
|
|
bool m_changed = false;
|
|
|
|
bool m_cfb = false;
|
|
|
|
bool m_isDepthBuffer = false;
|
|
|
|
bool m_isPauseScreen = false;
|
|
|
|
bool m_isOBScreen = false;
|
|
|
|
bool m_isMainBuffer = false;
|
|
|
|
bool m_readable = false;
|
|
|
|
bool m_copied = false;
|
2013-04-05 06:13:26 +00:00
|
|
|
|
2016-05-10 04:52:12 +00:00
|
|
|
struct {
|
2020-11-14 09:54:28 +00:00
|
|
|
u32 uls = 0;
|
|
|
|
u32 ult = 0;;
|
2016-05-10 04:52:12 +00:00
|
|
|
} m_loadTileOrigin;
|
2020-11-14 09:54:28 +00:00
|
|
|
u32 m_loadType = LOADTYPE_BLOCK;
|
2016-05-10 04:52:12 +00:00
|
|
|
|
2017-01-20 11:47:19 +00:00
|
|
|
graphics::ObjectHandle m_FBO;
|
2020-11-14 09:54:28 +00:00
|
|
|
CachedTexture *m_pTexture = nullptr;
|
2019-06-27 09:21:51 +00:00
|
|
|
|
|
|
|
graphics::ObjectHandle m_depthFBO;
|
2020-11-14 09:54:28 +00:00
|
|
|
CachedTexture *m_pDepthTexture = nullptr;
|
2019-06-27 09:21:51 +00:00
|
|
|
|
2021-04-18 00:45:47 +00:00
|
|
|
std::unique_ptr<graphics::ColorBufferReader> m_bufferReader;
|
|
|
|
graphics::ObjectHandle m_ColorBufferFBO;
|
|
|
|
CachedTexture *m_pColorBufferTexture = nullptr;
|
|
|
|
|
2020-11-14 09:54:28 +00:00
|
|
|
DepthBuffer *m_pDepthBuffer = nullptr;
|
2016-05-08 09:58:19 +00:00
|
|
|
|
2015-02-09 12:27:39 +00:00
|
|
|
// multisampling
|
2017-01-20 11:47:19 +00:00
|
|
|
graphics::ObjectHandle m_resolveFBO;
|
2020-11-14 09:54:28 +00:00
|
|
|
CachedTexture *m_pResolveTexture = nullptr;
|
|
|
|
bool m_resolved = false;
|
2015-02-09 12:27:39 +00:00
|
|
|
|
2016-05-08 09:58:19 +00:00
|
|
|
// subtexture
|
2017-01-20 11:47:19 +00:00
|
|
|
graphics::ObjectHandle m_SubFBO;
|
2020-11-14 09:54:28 +00:00
|
|
|
CachedTexture *m_pSubTexture = nullptr;
|
2016-05-08 09:58:19 +00:00
|
|
|
|
2018-04-16 19:13:18 +00:00
|
|
|
// copy FBO
|
|
|
|
graphics::ObjectHandle m_copyFBO;
|
2020-11-14 09:54:28 +00:00
|
|
|
CachedTexture * m_pFrameBufferCopyTexture = nullptr;
|
2018-04-16 19:13:18 +00:00
|
|
|
|
2015-04-29 13:58:06 +00:00
|
|
|
std::vector<u8> m_RdramCopy;
|
|
|
|
|
2015-02-09 12:27:39 +00:00
|
|
|
private:
|
2016-09-27 14:43:28 +00:00
|
|
|
struct {
|
2017-11-18 15:07:27 +00:00
|
|
|
u32 fillcolor = 0;
|
|
|
|
s32 ulx = 0;
|
|
|
|
s32 uly = 0;
|
|
|
|
s32 lrx = 0;
|
|
|
|
s32 lry = 0;
|
2016-09-27 14:43:28 +00:00
|
|
|
} m_clearParams;
|
|
|
|
|
2016-05-08 09:58:19 +00:00
|
|
|
void _initTexture(u16 _width, u16 _height, u16 _format, u16 _size, CachedTexture *_pTexture);
|
2017-01-20 11:47:19 +00:00
|
|
|
void _setAndAttachTexture(graphics::ObjectHandle _fbo, CachedTexture *_pTexture, u32 _t, bool _multisampling);
|
2016-05-08 09:58:19 +00:00
|
|
|
bool _initSubTexture(u32 _t);
|
2018-04-16 19:13:18 +00:00
|
|
|
void _initCopyTexture();
|
|
|
|
CachedTexture * _copyFrameBufferTexture();
|
2016-05-08 09:58:19 +00:00
|
|
|
CachedTexture * _getSubTexture(u32 _t);
|
2021-04-18 00:45:47 +00:00
|
|
|
void _initColorFBTexture(int _width);
|
|
|
|
void _destroyColorFBTexure();
|
2018-09-25 09:37:57 +00:00
|
|
|
|
2020-11-14 09:54:28 +00:00
|
|
|
mutable u32 m_validityChecked = false;
|
2013-04-05 06:13:26 +00:00
|
|
|
};
|
|
|
|
|
2014-09-08 11:01:22 +00:00
|
|
|
class FrameBufferList
|
2013-04-05 06:13:26 +00:00
|
|
|
{
|
2014-09-08 11:01:22 +00:00
|
|
|
public:
|
|
|
|
void init();
|
|
|
|
void destroy();
|
2017-03-02 15:09:08 +00:00
|
|
|
void saveBuffer(u32 _address, u16 _format, u16 _size, u16 _width, bool _cfb);
|
2015-10-31 02:36:16 +00:00
|
|
|
void removeAux();
|
|
|
|
void copyAux();
|
2014-09-28 06:09:03 +00:00
|
|
|
void removeBuffer(u32 _address);
|
2015-03-11 14:46:00 +00:00
|
|
|
void removeBuffers(u32 _width);
|
2014-09-08 11:01:22 +00:00
|
|
|
void attachDepthBuffer();
|
2016-03-06 15:12:23 +00:00
|
|
|
void clearDepthBuffer(DepthBuffer * _pDepthBuffer);
|
2014-10-22 07:49:55 +00:00
|
|
|
FrameBuffer * findBuffer(u32 _startAddress);
|
2017-09-29 15:24:30 +00:00
|
|
|
FrameBuffer * getBuffer(u32 _startAddress);
|
2014-09-08 11:01:22 +00:00
|
|
|
FrameBuffer * findTmpBuffer(u32 _address);
|
|
|
|
FrameBuffer * getCurrent() const {return m_pCurrent;}
|
2017-11-12 14:35:40 +00:00
|
|
|
void setCurrent(FrameBuffer * _pCurrent) { m_pCurrent = _pCurrent; }
|
2018-10-25 10:29:50 +00:00
|
|
|
void updateCurrentBufferEndAddress();
|
2017-03-01 16:12:39 +00:00
|
|
|
void renderBuffer();
|
2017-02-26 15:07:47 +00:00
|
|
|
void setBufferChanged(f32 _maxY);
|
2015-03-01 11:52:59 +00:00
|
|
|
void clearBuffersChanged();
|
2016-05-08 07:35:17 +00:00
|
|
|
void setCurrentDrawBuffer() const;
|
2016-09-27 14:43:28 +00:00
|
|
|
void fillRDRAM(s32 ulx, s32 uly, s32 lrx, s32 lry);
|
2014-09-04 12:46:46 +00:00
|
|
|
|
2015-09-27 04:10:05 +00:00
|
|
|
FrameBuffer * getCopyBuffer() const { return m_pCopy; }
|
|
|
|
void setCopyBuffer(FrameBuffer * _pBuffer) { m_pCopy = _pBuffer; }
|
2017-03-29 10:01:59 +00:00
|
|
|
void depthBufferCopyRdram();
|
2015-09-27 04:10:05 +00:00
|
|
|
|
2016-02-27 05:58:56 +00:00
|
|
|
void fillBufferInfo(void * _pinfo, u32 _size);
|
2015-11-23 12:36:03 +00:00
|
|
|
|
2015-03-31 12:44:41 +00:00
|
|
|
static FrameBufferList & get();
|
2014-09-04 12:46:46 +00:00
|
|
|
|
|
|
|
private:
|
2017-11-18 15:07:27 +00:00
|
|
|
FrameBufferList() : m_pCurrent(nullptr), m_pCopy(nullptr), m_prevColorImageHeight(0) {}
|
|
|
|
FrameBufferList(const FrameBufferList &) = delete;
|
2014-09-08 11:01:22 +00:00
|
|
|
|
2017-03-05 14:35:20 +00:00
|
|
|
void removeIntersections();
|
2014-10-22 07:49:55 +00:00
|
|
|
|
2017-02-25 06:38:33 +00:00
|
|
|
void _createScreenSizeBuffer();
|
|
|
|
void _renderScreenSizeBuffer();
|
|
|
|
|
2018-05-05 07:45:18 +00:00
|
|
|
class OverscanBuffer
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
void init();
|
|
|
|
void destroy();
|
|
|
|
|
|
|
|
void setInputBuffer(const FrameBuffer * _pBuffer);
|
|
|
|
void activate();
|
|
|
|
void draw(u32 _fullHeight, bool _PAL);
|
|
|
|
|
|
|
|
s32 getHOffset() const;
|
|
|
|
s32 getVOffset() const;
|
|
|
|
f32 getScaleX() const;
|
|
|
|
f32 getScaleY(u32 _fullHeight) const;
|
|
|
|
u32 getDrawingWidth() const { return m_drawingWidth; }
|
|
|
|
u32 getBufferWidth() const { return m_bufferWidth; }
|
|
|
|
u32 getBufferHeight() const { return m_bufferHeight; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
s32 m_hOffset = 0;
|
|
|
|
s32 m_vOffset = 0;
|
|
|
|
f32 m_scale = 1.0f;
|
|
|
|
u32 m_drawingWidth = 0U;
|
|
|
|
u32 m_bufferWidth = 0U;
|
|
|
|
u32 m_bufferHeight = 0U;
|
|
|
|
bool m_enabled = false;
|
|
|
|
|
|
|
|
graphics::ObjectHandle m_FBO;
|
|
|
|
CachedTexture *m_pTexture = nullptr;
|
2019-06-27 09:21:51 +00:00
|
|
|
CachedTexture *m_pDepthTexture = nullptr;
|
2018-05-05 07:45:18 +00:00
|
|
|
};
|
|
|
|
|
2014-09-08 11:01:22 +00:00
|
|
|
typedef std::list<FrameBuffer> FrameBuffers;
|
|
|
|
FrameBuffers m_list;
|
|
|
|
FrameBuffer * m_pCurrent;
|
2015-09-27 04:10:05 +00:00
|
|
|
FrameBuffer * m_pCopy;
|
2016-02-14 11:25:07 +00:00
|
|
|
u32 m_prevColorImageHeight;
|
2018-05-05 07:45:18 +00:00
|
|
|
OverscanBuffer m_overscan;
|
2019-01-09 14:54:31 +00:00
|
|
|
|
|
|
|
struct RdpUpdateResult {
|
|
|
|
u32 vi_vres;
|
|
|
|
u32 vi_hres;
|
|
|
|
u32 vi_v_start;
|
|
|
|
u32 vi_h_start;
|
|
|
|
u32 vi_x_start;
|
|
|
|
u32 vi_y_start;
|
|
|
|
u32 vi_x_add;
|
|
|
|
u32 vi_y_add;
|
|
|
|
u32 vi_width;
|
|
|
|
u32 vi_origin;
|
|
|
|
u32 vi_minhpass;
|
|
|
|
u32 vi_maxhpass;
|
|
|
|
bool vi_lowerfield;
|
|
|
|
bool vi_fsaa;
|
|
|
|
bool vi_divot;
|
|
|
|
bool vi_ispal;
|
|
|
|
};
|
|
|
|
|
|
|
|
class RdpUpdate
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
void init();
|
|
|
|
bool update(RdpUpdateResult & _result);
|
|
|
|
|
|
|
|
private:
|
2019-02-25 08:38:20 +00:00
|
|
|
s32 oldvstart = 0;
|
2019-01-09 14:54:31 +00:00
|
|
|
u32 prevvicurrent = 0U;
|
|
|
|
bool prevwasblank = false;
|
|
|
|
bool prevserrate = false;
|
|
|
|
bool oldlowerfield = false;
|
|
|
|
s32 emucontrolsvicurrent = -1;
|
|
|
|
} m_rdpUpdate;
|
2013-04-05 06:13:26 +00:00
|
|
|
};
|
|
|
|
|
2014-09-04 12:46:46 +00:00
|
|
|
inline
|
|
|
|
FrameBufferList & frameBufferList()
|
|
|
|
{
|
|
|
|
return FrameBufferList::get();
|
|
|
|
}
|
2013-04-05 06:13:26 +00:00
|
|
|
|
2016-05-28 15:37:20 +00:00
|
|
|
u32 cutHeight(u32 _address, u32 _height, u32 _stride);
|
2017-03-05 07:12:49 +00:00
|
|
|
void calcCoordsScales(const FrameBuffer * _pBuffer, f32 & _scaleX, f32 & _scaleY);
|
2016-05-28 15:37:20 +00:00
|
|
|
|
2013-04-05 06:13:26 +00:00
|
|
|
void FrameBuffer_Init();
|
|
|
|
void FrameBuffer_Destroy();
|
2015-10-31 03:11:33 +00:00
|
|
|
void FrameBuffer_CopyToRDRAM( u32 _address , bool _sync );
|
2015-11-23 13:03:33 +00:00
|
|
|
void FrameBuffer_CopyChunkToRDRAM(u32 _address);
|
2022-01-16 17:27:17 +00:00
|
|
|
void FrameBuffer_CopyFromRDRAM(word address, bool bUseAlpha);
|
|
|
|
void FrameBuffer_AddAddress(word address, u32 _size);
|
|
|
|
bool FrameBuffer_CopyDepthBuffer(word address);
|
|
|
|
bool FrameBuffer_CopyDepthBufferChunk(word address);
|
2017-09-29 15:24:30 +00:00
|
|
|
void FrameBuffer_ActivateBufferTexture(u32 t, u32 _frameBufferAddress);
|
|
|
|
void FrameBuffer_ActivateBufferTextureBG(u32 t, u32 _frameBufferAddress);
|
2013-04-05 06:13:26 +00:00
|
|
|
|
|
|
|
#endif
|