mirror of
https://github.com/blawar/GLideN64.git
synced 2024-06-25 22:09:35 +00:00
Rewrite buffer height calculation.
This commit is contained in:
parent
e6811b4d4f
commit
dd11326115
|
@ -109,16 +109,17 @@ void DepthBuffer::_initDepthBufferTexture(FrameBuffer * _pBuffer, CachedTexture
|
|||
_pTexture->clampWidth = _pBuffer->m_width;
|
||||
_pTexture->clampHeight = _pBuffer->m_height;
|
||||
} else {
|
||||
const u16 maxHeight = VI_GetMaxBufferHeight(VI.width);
|
||||
if (config.frameBufferEmulation.nativeResFactor == 0) {
|
||||
_pTexture->width = dwnd().getWidth();
|
||||
_pTexture->height = dwnd().getHeight();
|
||||
_pTexture->height = (u16)(u32)(maxHeight * dwnd().getScaleX());
|
||||
} else {
|
||||
_pTexture->width = VI.width * config.frameBufferEmulation.nativeResFactor;
|
||||
_pTexture->height = VI.height * config.frameBufferEmulation.nativeResFactor;
|
||||
_pTexture->height = maxHeight * config.frameBufferEmulation.nativeResFactor;
|
||||
}
|
||||
_pTexture->address = gDP.depthImageAddress;
|
||||
_pTexture->clampWidth = VI.width;
|
||||
_pTexture->clampHeight = VI.height;
|
||||
_pTexture->clampHeight = maxHeight;
|
||||
}
|
||||
_pTexture->format = 0;
|
||||
_pTexture->size = 2;
|
||||
|
@ -169,10 +170,10 @@ void DepthBuffer::_initDepthBufferRenderbuffer(FrameBuffer * _pBuffer)
|
|||
} else {
|
||||
if (config.frameBufferEmulation.nativeResFactor == 0) {
|
||||
m_depthRenderbufferWidth = dwnd().getWidth();
|
||||
height = dwnd().getHeight();
|
||||
height = (u32)(VI_GetMaxBufferHeight(VI.width) * dwnd().getScaleX());
|
||||
} else {
|
||||
m_depthRenderbufferWidth = VI.width * config.frameBufferEmulation.nativeResFactor;
|
||||
height = VI.height * config.frameBufferEmulation.nativeResFactor;
|
||||
height = VI_GetMaxBufferHeight(VI.width) * config.frameBufferEmulation.nativeResFactor;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,8 +33,7 @@ FrameBuffer::FrameBuffer() :
|
|||
m_startAddress(0), m_endAddress(0), m_size(0), m_width(0), m_height(0), m_validityChecked(0),
|
||||
m_scaleX(0), m_scaleY(0),
|
||||
m_copiedToRdram(false), m_fingerprint(false), m_cleared(false), m_changed(false), m_cfb(false),
|
||||
m_isDepthBuffer(false), m_isPauseScreen(false), m_isOBScreen(false),
|
||||
m_needHeightCorrection(false), m_readable(false),
|
||||
m_isDepthBuffer(false), m_isPauseScreen(false), m_isOBScreen(false), m_readable(false),
|
||||
m_loadType(LOADTYPE_BLOCK), m_pDepthBuffer(nullptr),
|
||||
m_pResolveTexture(nullptr), m_resolved(false),
|
||||
m_pSubTexture(nullptr)
|
||||
|
@ -59,8 +58,8 @@ void FrameBuffer::_initTexture(u16 _width, u16 _height, u16 _format, u16 _size,
|
|||
{
|
||||
const FramebufferTextureFormats & fbTexFormats = gfxContext.getFramebufferTextureFormats();
|
||||
|
||||
_pTexture->width = (u32)(_width * m_scaleX);
|
||||
_pTexture->height = (u32)(_height * m_scaleY);
|
||||
_pTexture->width = (u16)(u32)(_width * m_scaleX);
|
||||
_pTexture->height = (u16)(u32)(_height * m_scaleY);
|
||||
_pTexture->format = _format;
|
||||
_pTexture->size = _size;
|
||||
_pTexture->clampS = 1;
|
||||
|
@ -140,13 +139,13 @@ bool FrameBuffer::isAuxiliary() const
|
|||
return m_width != VI.width;
|
||||
}
|
||||
|
||||
void FrameBuffer::init(u32 _address, u16 _format, u16 _size, u16 _width, u16 _height, bool _cfb)
|
||||
void FrameBuffer::init(u32 _address, u16 _format, u16 _size, u16 _width, bool _cfb)
|
||||
{
|
||||
DisplayWindow & wnd = dwnd();
|
||||
m_startAddress = _address;
|
||||
m_endAddress = _address + ((_width * _height) << _size >> 1) - 1;
|
||||
m_endAddress = _address + (_width << _size >> 1) - 1;
|
||||
m_width = _width;
|
||||
m_height = _height;
|
||||
m_height = 1;
|
||||
m_size = _size;
|
||||
if (isAuxiliary() && config.frameBufferEmulation.copyAuxToRDRAM != 0) {
|
||||
m_scaleX = 1.0f;
|
||||
|
@ -154,22 +153,21 @@ void FrameBuffer::init(u32 _address, u16 _format, u16 _size, u16 _width, u16 _he
|
|||
} else if (config.frameBufferEmulation.nativeResFactor != 0 && config.frameBufferEmulation.enable != 0) {
|
||||
m_scaleX = m_scaleY = static_cast<float>(config.frameBufferEmulation.nativeResFactor);
|
||||
} else {
|
||||
m_scaleX = wnd.getScaleX();
|
||||
m_scaleY = wnd.getScaleY();
|
||||
m_scaleY = m_scaleX = wnd.getScaleX();
|
||||
}
|
||||
m_cfb = _cfb;
|
||||
m_needHeightCorrection = _width != VI.width && _width != *REG.VI_WIDTH;
|
||||
m_cleared = false;
|
||||
m_fingerprint = false;
|
||||
|
||||
_initTexture(_width, _height, _format, _size, m_pTexture);
|
||||
const u16 maxHeight = VI_GetMaxBufferHeight(_width);
|
||||
_initTexture(_width, maxHeight, _format, _size, m_pTexture);
|
||||
|
||||
if (config.video.multisampling != 0) {
|
||||
_setAndAttachTexture(m_FBO, m_pTexture, 0, true);
|
||||
m_pTexture->frameBufferTexture = CachedTexture::fbMultiSample;
|
||||
|
||||
m_pResolveTexture = textureCache().addFrameBufferTexture(false);
|
||||
_initTexture(_width, _height, _format, _size, m_pResolveTexture);
|
||||
_initTexture(_width, maxHeight, _format, _size, m_pResolveTexture);
|
||||
m_resolveFBO = gfxContext.createFramebuffer();
|
||||
_setAndAttachTexture(m_resolveFBO, m_pResolveTexture, 0, false);
|
||||
assert(!gfxContext.isFramebufferError());
|
||||
|
@ -181,16 +179,9 @@ void FrameBuffer::init(u32 _address, u16 _format, u16 _size, u16 _width, u16 _he
|
|||
wnd.getDrawer().clearColorBuffer(nullptr);
|
||||
}
|
||||
|
||||
void FrameBuffer::reinit(u16 _height)
|
||||
void FrameBuffer::updateEndAddress()
|
||||
{
|
||||
const u16 format = m_pTexture->format;
|
||||
textureCache().removeFrameBufferTexture(m_pTexture);
|
||||
|
||||
gfxContext.deleteFramebuffer(ObjectHandle(m_resolveFBO));
|
||||
|
||||
textureCache().removeFrameBufferTexture(m_pResolveTexture);
|
||||
m_pTexture = textureCache().addFrameBufferTexture(config.video.multisampling != 0);
|
||||
init(m_startAddress, format, m_size, m_width, _height, m_cfb);
|
||||
m_endAddress = min(RDRAMSize, m_startAddress + (((m_width * m_height) << m_size >> 1) - 1));
|
||||
}
|
||||
|
||||
inline
|
||||
|
@ -498,26 +489,6 @@ void FrameBufferList::setBufferChanged(f32 _maxY)
|
|||
}
|
||||
}
|
||||
|
||||
void FrameBufferList::correctHeight()
|
||||
{
|
||||
if (m_pCurrent == nullptr)
|
||||
return;
|
||||
if (m_pCurrent->m_changed) {
|
||||
m_pCurrent->m_needHeightCorrection = false;
|
||||
return;
|
||||
}
|
||||
if (m_pCurrent->m_needHeightCorrection && m_pCurrent->m_width == gDP.scissor.lrx) {
|
||||
if (m_pCurrent->m_height != gDP.scissor.lry) {
|
||||
m_pCurrent->reinit((u32)gDP.scissor.lry);
|
||||
|
||||
if (m_pCurrent->_isMarioTennisScoreboard())
|
||||
RDRAMtoColorBuffer::get().copyFromRDRAM(m_pCurrent->m_startAddress + 4, true);
|
||||
gSP.changed |= CHANGED_VIEWPORT;
|
||||
}
|
||||
m_pCurrent->m_needHeightCorrection = false;
|
||||
}
|
||||
}
|
||||
|
||||
void FrameBufferList::clearBuffersChanged()
|
||||
{
|
||||
gDP.colorImage.changed = FALSE;
|
||||
|
@ -578,10 +549,10 @@ void FrameBufferList::_createScreenSizeBuffer()
|
|||
return;
|
||||
m_list.emplace_front();
|
||||
FrameBuffer & buffer = m_list.front();
|
||||
buffer.init(VI.width * 2, G_IM_FMT_RGBA, G_IM_SIZ_16b, VI.width, VI.height, false);
|
||||
buffer.init(VI.width * 2, G_IM_FMT_RGBA, G_IM_SIZ_16b, VI.width, false);
|
||||
}
|
||||
|
||||
void FrameBufferList::saveBuffer(u32 _address, u16 _format, u16 _size, u16 _width, u16 _height, bool _cfb)
|
||||
void FrameBufferList::saveBuffer(u32 _address, u16 _format, u16 _size, u16 _width, bool _cfb)
|
||||
{
|
||||
if (config.frameBufferEmulation.enable == 0) {
|
||||
if (m_list.empty())
|
||||
|
@ -598,37 +569,21 @@ void FrameBufferList::saveBuffer(u32 _address, u16 _format, u16 _size, u16 _widt
|
|||
}
|
||||
}
|
||||
|
||||
if (VI.width == 0 || _height == 0) {
|
||||
m_pCurrent = nullptr;
|
||||
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::null);
|
||||
return;
|
||||
}
|
||||
|
||||
DisplayWindow & wnd = dwnd();
|
||||
bool bPrevIsDepth = false;
|
||||
|
||||
if (m_pCurrent != nullptr) {
|
||||
bPrevIsDepth = m_pCurrent->m_isDepthBuffer;
|
||||
m_pCurrent->m_readable = true;
|
||||
m_pCurrent->updateEndAddress();
|
||||
|
||||
// Correct buffer's end address
|
||||
if (!m_pCurrent->isAuxiliary()) {
|
||||
if (gDP.colorImage.height > 200)
|
||||
m_prevColorImageHeight = gDP.colorImage.height;
|
||||
else if (gDP.colorImage.height == 0)
|
||||
gDP.colorImage.height = m_prevColorImageHeight;
|
||||
|
||||
gDP.colorImage.height = min(gDP.colorImage.height, VI.height);
|
||||
}
|
||||
|
||||
//Non-auxiliary buffers are always corrected, auxiliary buffers are correct only if they need correction.
|
||||
//Also, before making any adjustments, make sure gDP.colorImage.height has a valid value.
|
||||
if((!m_pCurrent->isAuxiliary() || m_pCurrent->m_needHeightCorrection) && gDP.colorImage.height != 0)
|
||||
{
|
||||
m_pCurrent->m_endAddress = min(RDRAMSize, m_pCurrent->m_startAddress + (((m_pCurrent->m_width * gDP.colorImage.height) << m_pCurrent->m_size >> 1) - 1));
|
||||
}
|
||||
|
||||
if (!m_pCurrent->_isMarioTennisScoreboard() && !m_pCurrent->m_isDepthBuffer && !m_pCurrent->m_copiedToRdram && !m_pCurrent->m_cfb && !m_pCurrent->m_cleared && m_pCurrent->m_RdramCopy.empty() && gDP.colorImage.height > 1) {
|
||||
if (!m_pCurrent->_isMarioTennisScoreboard() &&
|
||||
!m_pCurrent->m_isDepthBuffer &&
|
||||
!m_pCurrent->m_copiedToRdram &&
|
||||
!m_pCurrent->m_cfb &&
|
||||
!m_pCurrent->m_cleared
|
||||
&& m_pCurrent->m_RdramCopy.empty()
|
||||
&& m_pCurrent->m_height > 1) {
|
||||
m_pCurrent->copyRdram();
|
||||
}
|
||||
|
||||
|
@ -637,15 +592,14 @@ void FrameBufferList::saveBuffer(u32 _address, u16 _format, u16 _size, u16 _widt
|
|||
|
||||
if (m_pCurrent == nullptr || m_pCurrent->m_startAddress != _address || m_pCurrent->m_width != _width)
|
||||
m_pCurrent = findBuffer(_address);
|
||||
const float scaleX = config.frameBufferEmulation.nativeResFactor == 0 ? wnd.getScaleX() : static_cast<float>(config.frameBufferEmulation.nativeResFactor);
|
||||
const float scaleY = config.frameBufferEmulation.nativeResFactor == 0 ? wnd.getScaleY() : scaleX;
|
||||
const float scaleX = config.frameBufferEmulation.nativeResFactor == 0 ?
|
||||
wnd.getScaleX() :
|
||||
static_cast<float>(config.frameBufferEmulation.nativeResFactor);
|
||||
if (m_pCurrent != nullptr) {
|
||||
if ((m_pCurrent->m_startAddress != _address) ||
|
||||
(m_pCurrent->m_width != _width) ||
|
||||
//(current->height != height) ||
|
||||
(m_pCurrent->m_size < _size) ||
|
||||
(m_pCurrent->m_scaleX != scaleX) ||
|
||||
(m_pCurrent->m_scaleY != scaleY))
|
||||
(m_pCurrent->m_scaleX != scaleX))
|
||||
{
|
||||
removeBuffer(m_pCurrent->m_startAddress);
|
||||
m_pCurrent = nullptr;
|
||||
|
@ -673,7 +627,7 @@ void FrameBufferList::saveBuffer(u32 _address, u16 _format, u16 _size, u16 _widt
|
|||
// Wasn't found or removed, create a new one
|
||||
m_list.emplace_front();
|
||||
FrameBuffer & buffer = m_list.front();
|
||||
buffer.init(_address, _format, _size, _width, _height, _cfb);
|
||||
buffer.init(_address, _format, _size, _width, _cfb);
|
||||
m_pCurrent = &buffer;
|
||||
|
||||
if (m_pCurrent->_isMarioTennisScoreboard() || ((config.generalEmulation.hacks & hack_legoRacers) != 0 && _width == VI.width))
|
||||
|
|
|
@ -17,8 +17,8 @@ struct FrameBuffer
|
|||
{
|
||||
FrameBuffer();
|
||||
~FrameBuffer();
|
||||
void init(u32 _address, u16 _format, u16 _size, u16 _width, u16 _height, bool _cfb);
|
||||
void reinit(u16 _height);
|
||||
void init(u32 _address, u16 _format, u16 _size, u16 _width, bool _cfb);
|
||||
void updateEndAddress();
|
||||
void resolveMultisampledTexture(bool _bForce = false);
|
||||
CachedTexture * getTexture(u32 _t);
|
||||
CachedTexture * getTextureBG(u32 _t);
|
||||
|
@ -39,7 +39,6 @@ struct FrameBuffer
|
|||
bool m_isDepthBuffer;
|
||||
bool m_isPauseScreen;
|
||||
bool m_isOBScreen;
|
||||
bool m_needHeightCorrection;
|
||||
bool m_readable;
|
||||
|
||||
struct {
|
||||
|
@ -80,7 +79,7 @@ class FrameBufferList
|
|||
public:
|
||||
void init();
|
||||
void destroy();
|
||||
void saveBuffer(u32 _address, u16 _format, u16 _size, u16 _width, u16 _height, bool _cfb);
|
||||
void saveBuffer(u32 _address, u16 _format, u16 _size, u16 _width, bool _cfb);
|
||||
void removeAux();
|
||||
void copyAux();
|
||||
void removeBuffer(u32 _address);
|
||||
|
@ -92,7 +91,6 @@ public:
|
|||
FrameBuffer * getCurrent() const {return m_pCurrent;}
|
||||
void renderBuffer(u32 _address);
|
||||
void setBufferChanged(f32 _maxY);
|
||||
void correctHeight();
|
||||
void clearBuffersChanged();
|
||||
void setCurrentDrawBuffer() const;
|
||||
void fillRDRAM(s32 ulx, s32 uly, s32 lrx, s32 lry);
|
||||
|
|
20
src/VI.cpp
20
src/VI.cpp
|
@ -19,6 +19,14 @@ using namespace std;
|
|||
|
||||
VIInfo VI;
|
||||
|
||||
u16 VI_GetMaxBufferHeight(u16 _width)
|
||||
{
|
||||
if (_width > 320 || VI.interlaced)
|
||||
return VI.PAL ? 580 : 480;
|
||||
|
||||
return VI.PAL ? 290 : 240;
|
||||
}
|
||||
|
||||
void VI_UpdateSize()
|
||||
{
|
||||
const f32 xScale = _FIXED2FLOAT( _SHIFTR( *REG.VI_X_SCALE, 0, 12 ), 10 );
|
||||
|
@ -27,8 +35,8 @@ void VI_UpdateSize()
|
|||
const u32 vScale = _SHIFTR(*REG.VI_Y_SCALE, 0, 12);
|
||||
// f32 yOffset = _FIXED2FLOAT( _SHIFTR( *REG.VI_Y_SCALE, 16, 12 ), 10 );
|
||||
|
||||
const u32 hEnd = _SHIFTR( *REG.VI_H_START, 0, 10 );
|
||||
const u32 hStart = _SHIFTR( *REG.VI_H_START, 16, 10 );
|
||||
// const u32 hEnd = _SHIFTR( *REG.VI_H_START, 0, 10 );
|
||||
// const u32 hStart = _SHIFTR( *REG.VI_H_START, 16, 10 );
|
||||
|
||||
// These are in half-lines, so shift an extra bit
|
||||
const u32 vEnd = _SHIFTR( *REG.VI_V_START, 0, 10 );
|
||||
|
@ -77,8 +85,10 @@ void VI_UpdateSize()
|
|||
if (config.frameBufferEmulation.enable && ((config.generalEmulation.hacks & hack_ZeldaMM) == 0) &&
|
||||
((interlacedPrev != VI.interlaced) ||
|
||||
(VI.width > 0 && VI.width != VI.widthPrev) ||
|
||||
(!VI.interlaced && pDepthBuffer != nullptr && pDepthBuffer->m_width != VI.width) ||
|
||||
((config.generalEmulation.hacks & hack_ignoreVIHeightChange) == 0 && pBuffer != nullptr && pBuffer->m_height != VI.height))
|
||||
(!VI.interlaced && pDepthBuffer != nullptr && pDepthBuffer->m_width != VI.width)
|
||||
)// ||
|
||||
// ((config.generalEmulation.hacks & hack_ignoreVIHeightChange) == 0 && pBuffer != nullptr && pBuffer->m_height != VI.height))
|
||||
|
||||
) {
|
||||
fbList.removeBuffers(VI.widthPrev);
|
||||
fbList.removeBuffers(VI.width);
|
||||
|
@ -148,7 +158,7 @@ void VI_UpdateScreen()
|
|||
}
|
||||
const u32 size = *REG.VI_STATUS & 3;
|
||||
if (VI.height > 0 && size > G_IM_SIZ_8b && VI.width > 0)
|
||||
frameBufferList().saveBuffer(*REG.VI_ORIGIN, G_IM_FMT_RGBA, size, VI.width, VI.height, true);
|
||||
frameBufferList().saveBuffer(*REG.VI_ORIGIN, G_IM_FMT_RGBA, size, VI.width, true);
|
||||
}
|
||||
}
|
||||
// if ((((*REG.VI_STATUS) & 3) > 0) && (gDP.colorImage.changed || bCFB)) { // Does not work in release build!!!
|
||||
|
|
1
src/VI.h
1
src/VI.h
|
@ -20,6 +20,7 @@ extern VIInfo VI;
|
|||
|
||||
void VI_UpdateSize();
|
||||
void VI_UpdateScreen();
|
||||
u16 VI_GetMaxBufferHeight(u16 _width);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
25
src/gDP.cpp
25
src/gDP.cpp
|
@ -132,32 +132,13 @@ void gDPSetColorImage( u32 format, u32 size, u32 width, u32 address )
|
|||
address = RSP_SegmentToPhysical( address );
|
||||
|
||||
if (gDP.colorImage.address != address || gDP.colorImage.width != width || gDP.colorImage.size != size) {
|
||||
u32 height = 1;
|
||||
if (width == VI.width)
|
||||
height = VI.height > 0 ? VI.height : gDP.scissor.lry;
|
||||
else if (!RSP.bLLE && width == gDP.scissor.lrx && width == gSP.viewport.width) {
|
||||
height = max(gDP.scissor.lry, gSP.viewport.height);
|
||||
if (VI.height > 0)
|
||||
height = min(height, VI.height);
|
||||
} else if (width == gDP.scissor.lrx)
|
||||
height = gDP.scissor.lry;
|
||||
else if (width <= 64)
|
||||
height = width;
|
||||
else if (!RSP.bLLE && gSP.viewport.height > 0)
|
||||
height = gSP.viewport.height;
|
||||
else
|
||||
height = VI.height > 0 ? VI.height : gDP.scissor.lry;
|
||||
|
||||
frameBufferList().saveBuffer(address, (u16)format, (u16)size, (u16)width, height, false);
|
||||
if (config.frameBufferEmulation.enable != 0)
|
||||
gDP.colorImage.height = 0;
|
||||
else
|
||||
gDP.colorImage.height = height;
|
||||
frameBufferList().saveBuffer(address, (u16)format, (u16)size, (u16)width, false);
|
||||
}
|
||||
|
||||
gDP.colorImage.format = format;
|
||||
gDP.colorImage.size = size;
|
||||
gDP.colorImage.width = width;
|
||||
gDP.colorImage.height = 0;
|
||||
gDP.colorImage.address = address;
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -711,8 +692,6 @@ void gDPSetScissor( u32 mode, f32 ulx, f32 uly, f32 lrx, f32 lry )
|
|||
|
||||
gDP.changed |= CHANGED_SCISSOR;
|
||||
|
||||
frameBufferList().correctHeight();
|
||||
|
||||
if (config.video.cropMode == Config::cmAuto && gDP.depthImageAddress != gDP.colorImage.address) {
|
||||
const u32 maxCropH = VI.width / 16;
|
||||
const u32 maxCropV = VI.height / 10;
|
||||
|
|
Loading…
Reference in New Issue
Block a user