mirror of
https://github.com/blawar/GLideN64.git
synced 2024-07-02 09:03:37 +00:00
Always render to FBO, even when frame buffer emulation is disabled.
This commit is contained in:
parent
4b040304bb
commit
873a830d88
|
@ -417,10 +417,32 @@ void DepthBufferList::removeBuffer(u32 _address )
|
|||
}
|
||||
}
|
||||
|
||||
void DepthBufferList::_createScreenSizeBuffer(u32 _address)
|
||||
{
|
||||
FrameBuffer * pFrameBuffer = frameBufferList().findBuffer(VI.width*2);
|
||||
if (pFrameBuffer == nullptr)
|
||||
return;
|
||||
|
||||
m_list.emplace_front();
|
||||
DepthBuffer & buffer = m_list.front();
|
||||
|
||||
buffer.m_address = _address;
|
||||
buffer.m_width = pFrameBuffer->m_width;
|
||||
|
||||
buffer.initDepthBufferTexture(pFrameBuffer);
|
||||
|
||||
m_pCurrent = &buffer;
|
||||
frameBufferList().attachDepthBuffer();
|
||||
m_pCurrent = nullptr;
|
||||
}
|
||||
|
||||
void DepthBufferList::saveBuffer(u32 _address)
|
||||
{
|
||||
if (!config.frameBufferEmulation.enable)
|
||||
if (config.frameBufferEmulation.enable == 0) {
|
||||
if (m_list.empty())
|
||||
_createScreenSizeBuffer(_address);
|
||||
return;
|
||||
}
|
||||
|
||||
FrameBuffer * pFrameBuffer = frameBufferList().findBuffer(_address);
|
||||
if (pFrameBuffer != nullptr)
|
||||
|
|
|
@ -67,6 +67,8 @@ private:
|
|||
DepthBufferList(const DepthBufferList &);
|
||||
~DepthBufferList();
|
||||
|
||||
void _createScreenSizeBuffer(u32 _address);
|
||||
|
||||
typedef std::list<DepthBuffer> DepthBuffers;
|
||||
DepthBuffers m_list;
|
||||
DepthBuffer *m_pCurrent;
|
||||
|
|
|
@ -151,7 +151,7 @@ void FrameBuffer::init(u32 _address, u32 _endAddress, u16 _format, u16 _size, u1
|
|||
if (isAuxiliary() && config.frameBufferEmulation.copyAuxToRDRAM != 0) {
|
||||
m_scaleX = 1.0f;
|
||||
m_scaleY = 1.0f;
|
||||
} else if (config.frameBufferEmulation.nativeResFactor != 0) {
|
||||
} 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();
|
||||
|
@ -564,8 +564,24 @@ FrameBuffer * FrameBufferList::findTmpBuffer(u32 _address)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
void FrameBufferList::_createScreenSizeBuffer()
|
||||
{
|
||||
if (VI.height == 0)
|
||||
return;
|
||||
m_list.emplace_front();
|
||||
FrameBuffer & buffer = m_list.front();
|
||||
buffer.init(VI.width * 2, VI.width * VI.height * 2, G_IM_FMT_RGBA, G_IM_SIZ_16b, VI.width, VI.height, false);
|
||||
}
|
||||
|
||||
void FrameBufferList::saveBuffer(u32 _address, u16 _format, u16 _size, u16 _width, u16 _height, bool _cfb)
|
||||
{
|
||||
if (config.frameBufferEmulation.enable == 0) {
|
||||
if (m_list.empty())
|
||||
_createScreenSizeBuffer();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_pCurrent != nullptr &&
|
||||
config.frameBufferEmulation.copyAuxToRDRAM != 0 &&
|
||||
(config.generalEmulation.hacks & hack_Snap) == 0) {
|
||||
|
@ -754,35 +770,36 @@ void FrameBufferList::fillBufferInfo(void * _pinfo, u32 _size)
|
|||
|
||||
void FrameBufferList::attachDepthBuffer()
|
||||
{
|
||||
if (m_pCurrent == nullptr)
|
||||
FrameBuffer * pCurrent = config.frameBufferEmulation.enable == 0 ? &m_list.back() : m_pCurrent;
|
||||
if (pCurrent == nullptr)
|
||||
return;
|
||||
|
||||
DepthBuffer * pDepthBuffer = depthBufferList().getCurrent();
|
||||
if (m_pCurrent->m_pDepthBuffer == pDepthBuffer)
|
||||
if (pCurrent->m_pDepthBuffer == pDepthBuffer)
|
||||
return;
|
||||
|
||||
if (m_pCurrent->m_FBO.isNotNull() && pDepthBuffer != nullptr) {
|
||||
pDepthBuffer->initDepthImageTexture(m_pCurrent);
|
||||
pDepthBuffer->initDepthBufferTexture(m_pCurrent);
|
||||
if (pCurrent->m_FBO.isNotNull() && pDepthBuffer != nullptr) {
|
||||
pDepthBuffer->initDepthImageTexture(pCurrent);
|
||||
pDepthBuffer->initDepthBufferTexture(pCurrent);
|
||||
|
||||
bool goodDepthBufferTexture = false;
|
||||
if (gfxContext.isSupported(SpecialFeatures::DepthFramebufferTextures)) {
|
||||
goodDepthBufferTexture = gfxContext.isSupported(SpecialFeatures::WeakBlitFramebuffer) ?
|
||||
pDepthBuffer->m_pDepthBufferTexture->realWidth == m_pCurrent->m_pTexture->realWidth :
|
||||
pDepthBuffer->m_pDepthBufferTexture->realWidth >= m_pCurrent->m_pTexture->realWidth;
|
||||
pDepthBuffer->m_pDepthBufferTexture->realWidth == pCurrent->m_pTexture->realWidth :
|
||||
pDepthBuffer->m_pDepthBufferTexture->realWidth >= pCurrent->m_pTexture->realWidth;
|
||||
} else {
|
||||
goodDepthBufferTexture = pDepthBuffer->m_depthRenderbufferWidth == m_pCurrent->m_pTexture->realWidth;
|
||||
goodDepthBufferTexture = pDepthBuffer->m_depthRenderbufferWidth == pCurrent->m_pTexture->realWidth;
|
||||
}
|
||||
|
||||
if (goodDepthBufferTexture) {
|
||||
m_pCurrent->m_pDepthBuffer = pDepthBuffer;
|
||||
pDepthBuffer->setDepthAttachment(m_pCurrent->m_FBO, bufferTarget::DRAW_FRAMEBUFFER);
|
||||
pCurrent->m_pDepthBuffer = pDepthBuffer;
|
||||
pDepthBuffer->setDepthAttachment(pCurrent->m_FBO, bufferTarget::DRAW_FRAMEBUFFER);
|
||||
if (config.frameBufferEmulation.N64DepthCompare != 0)
|
||||
pDepthBuffer->bindDepthImageTexture();
|
||||
} else
|
||||
m_pCurrent->m_pDepthBuffer = nullptr;
|
||||
pCurrent->m_pDepthBuffer = nullptr;
|
||||
} else
|
||||
m_pCurrent->m_pDepthBuffer = nullptr;
|
||||
pCurrent->m_pDepthBuffer = nullptr;
|
||||
|
||||
assert(!gfxContext.isFramebufferError());
|
||||
}
|
||||
|
@ -814,6 +831,60 @@ void FrameBuffer_Destroy()
|
|||
frameBufferList().destroy();
|
||||
}
|
||||
|
||||
void FrameBufferList::_renderScreenSizeBuffer()
|
||||
{
|
||||
if (m_list.empty())
|
||||
return;
|
||||
|
||||
DisplayWindow & wnd = dwnd();
|
||||
GraphicsDrawer & drawer = wnd.getDrawer();
|
||||
FrameBuffer *pBuffer = &m_list.back();
|
||||
PostProcessor & postProcessor = PostProcessor::get();
|
||||
FrameBuffer * pFilteredBuffer = postProcessor.doBlur(postProcessor.doGammaCorrection(
|
||||
postProcessor.doOrientationCorrection(pBuffer)));
|
||||
CachedTexture * pBufferTexture = pFilteredBuffer->m_pTexture;
|
||||
|
||||
|
||||
s32 srcCoord[4] = { 0, 0, pBufferTexture->realWidth, pBufferTexture->realHeight };
|
||||
const s32 hOffset = (wnd.getScreenWidth() - wnd.getWidth()) / 2;
|
||||
const s32 vOffset = (wnd.getScreenHeight() - wnd.getHeight()) / 2 + wnd.getHeightOffset();
|
||||
s32 dstCoord[4] = { hOffset, vOffset, hOffset + pBufferTexture->realWidth, vOffset + pBufferTexture->realHeight };
|
||||
|
||||
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::null);
|
||||
|
||||
float clearColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
drawer.clearColorBuffer(clearColor);
|
||||
|
||||
TextureParam filter = textureParameters::FILTER_LINEAR;
|
||||
|
||||
GraphicsDrawer::BlitOrCopyRectParams blitParams;
|
||||
blitParams.srcX0 = srcCoord[0];
|
||||
blitParams.srcY0 = srcCoord[1];
|
||||
blitParams.srcX1 = srcCoord[2];
|
||||
blitParams.srcY1 = srcCoord[3];
|
||||
blitParams.srcWidth = pBufferTexture->realWidth;
|
||||
blitParams.srcHeight = pBufferTexture->realHeight;
|
||||
blitParams.dstX0 = dstCoord[0];
|
||||
blitParams.dstY0 = dstCoord[1];
|
||||
blitParams.dstX1 = dstCoord[2];
|
||||
blitParams.dstY1 = dstCoord[3];
|
||||
blitParams.dstWidth = wnd.getScreenWidth();
|
||||
blitParams.dstHeight = wnd.getScreenHeight() + wnd.getHeightOffset();
|
||||
blitParams.filter = filter;
|
||||
blitParams.mask = blitMask::COLOR_BUFFER;
|
||||
blitParams.tex[0] = pBufferTexture;
|
||||
blitParams.combiner = CombinerInfo::get().getTexrectCopyProgram();
|
||||
blitParams.readBuffer = pFilteredBuffer->m_FBO;
|
||||
|
||||
drawer.blitOrCopyTexturedRect(blitParams);
|
||||
|
||||
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, ObjectHandle::null);
|
||||
|
||||
wnd.swapBuffers();
|
||||
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, pBuffer->m_FBO);
|
||||
gDP.changed |= CHANGED_SCISSOR;
|
||||
}
|
||||
|
||||
void FrameBufferList::renderBuffer(u32 _address)
|
||||
{
|
||||
static s32 vStartPrev = 0;
|
||||
|
@ -821,6 +892,11 @@ void FrameBufferList::renderBuffer(u32 _address)
|
|||
if (VI.width == 0 || *REG.VI_WIDTH == 0 || *REG.VI_H_START == 0) // H width is zero. Don't draw
|
||||
return;
|
||||
|
||||
if (config.frameBufferEmulation.enable == 0) {
|
||||
_renderScreenSizeBuffer();
|
||||
return;
|
||||
}
|
||||
|
||||
FrameBuffer *pBuffer = findBuffer(_address);
|
||||
if (pBuffer == nullptr)
|
||||
return;
|
||||
|
|
|
@ -110,6 +110,9 @@ private:
|
|||
|
||||
FrameBuffer * _findBuffer(u32 _startAddress, u32 _endAddress, u32 _width);
|
||||
|
||||
void _createScreenSizeBuffer();
|
||||
void _renderScreenSizeBuffer();
|
||||
|
||||
typedef std::list<FrameBuffer> FrameBuffers;
|
||||
FrameBuffers m_list;
|
||||
FrameBuffer * m_pCurrent;
|
||||
|
|
|
@ -173,16 +173,14 @@ void GraphicsDrawer::updateScissor(FrameBuffer * _pBuffer) const
|
|||
{
|
||||
DisplayWindow & wnd = DisplayWindow::get();
|
||||
f32 scaleX, scaleY;
|
||||
u32 heightOffset, screenHeight;
|
||||
u32 screenHeight;
|
||||
if (_pBuffer == nullptr) {
|
||||
scaleX = wnd.getScaleX();
|
||||
scaleY = wnd.getScaleY();
|
||||
heightOffset = wnd.getHeightOffset();
|
||||
screenHeight = VI.height;
|
||||
} else {
|
||||
scaleX = _pBuffer->m_scaleX;
|
||||
scaleY = _pBuffer->m_scaleY;
|
||||
heightOffset = 0;
|
||||
screenHeight = (_pBuffer->m_height == 0) ? VI.height : _pBuffer->m_height;
|
||||
}
|
||||
|
||||
|
@ -191,7 +189,7 @@ void GraphicsDrawer::updateScissor(FrameBuffer * _pBuffer) const
|
|||
if (_needAdjustCoordinate(wnd))
|
||||
_adjustScissorX(SX0, SX1, wnd.getAdjustScale());
|
||||
|
||||
gfxContext.setScissor((s32)(SX0 * scaleX), (s32)((screenHeight - gDP.scissor.lry) * scaleY + heightOffset),
|
||||
gfxContext.setScissor((s32)(SX0 * scaleX), (s32)((screenHeight - gDP.scissor.lry) * scaleY),
|
||||
std::max((s32)((SX1 - SX0) * scaleX), 0), std::max((s32)((gDP.scissor.lry - gDP.scissor.uly) * scaleY), 0));
|
||||
gDP.changed &= ~CHANGED_SCISSOR;
|
||||
}
|
||||
|
@ -216,7 +214,7 @@ void GraphicsDrawer::_updateViewport() const
|
|||
Xf = _adjustViewportX(Xf);
|
||||
const s32 X = (s32)(Xf * scaleX);
|
||||
const s32 Y = gSP.viewport.vscale[1] < 0 ? (s32)((gSP.viewport.y + gSP.viewport.vscale[1] * 2.0f) * scaleY) : (s32)((VI.height - (gSP.viewport.y + gSP.viewport.height)) * scaleY);
|
||||
gfxContext.setViewport(X, Y + wnd.getHeightOffset(),
|
||||
gfxContext.setViewport(X, Y,
|
||||
std::max((s32)(gSP.viewport.width * scaleX), 0), std::max((s32)(gSP.viewport.height * scaleY), 0));
|
||||
} else {
|
||||
const f32 scaleX = pCurrentBuffer->m_scaleX;
|
||||
|
@ -237,7 +235,7 @@ void GraphicsDrawer::_updateScreenCoordsViewport() const
|
|||
DisplayWindow & wnd = DisplayWindow::get();
|
||||
FrameBuffer * pCurrentBuffer = frameBufferList().getCurrent();
|
||||
if (pCurrentBuffer == nullptr)
|
||||
gfxContext.setViewport(0, wnd.getHeightOffset(), wnd.getScreenWidth(), wnd.getScreenHeight());
|
||||
gfxContext.setViewport(0, 0, wnd.getScreenWidth(), wnd.getScreenHeight());
|
||||
else
|
||||
gfxContext.setViewport(0, 0, s32(pCurrentBuffer->m_width*pCurrentBuffer->m_scaleX), s32(pCurrentBuffer->m_height*pCurrentBuffer->m_scaleY));
|
||||
gSP.changed |= CHANGED_VIEWPORT;
|
||||
|
@ -846,7 +844,7 @@ void GraphicsDrawer::drawRect(int _ulx, int _uly, int _lrx, int _lry, float *_pC
|
|||
FrameBuffer * pCurrentBuffer = frameBufferList().getCurrent();
|
||||
DisplayWindow & wnd = dwnd();
|
||||
if (pCurrentBuffer == nullptr)
|
||||
gfxContext.setViewport(0, wnd.getHeightOffset(), wnd.getScreenWidth(), wnd.getScreenHeight());
|
||||
gfxContext.setViewport(0, 0, wnd.getScreenWidth(), wnd.getScreenHeight());
|
||||
else
|
||||
gfxContext.setViewport(0, 0, pCurrentBuffer->m_width*pCurrentBuffer->m_scaleX, pCurrentBuffer->m_height*pCurrentBuffer->m_scaleY);
|
||||
|
||||
|
@ -1249,7 +1247,7 @@ void GraphicsDrawer::drawTexturedRect(const TexturedRectParams & _params)
|
|||
m_texrectDrawer.add();
|
||||
else {
|
||||
if (pCurrentBuffer == nullptr)
|
||||
gfxContext.setViewport(0, wnd.getHeightOffset(), wnd.getScreenWidth(), wnd.getScreenHeight());
|
||||
gfxContext.setViewport(0, 0, wnd.getScreenWidth(), wnd.getScreenHeight());
|
||||
else
|
||||
gfxContext.setViewport(0, 0, pCurrentBuffer->m_width*pCurrentBuffer->m_scaleX, pCurrentBuffer->m_height*pCurrentBuffer->m_scaleY);
|
||||
|
||||
|
|
|
@ -163,10 +163,9 @@ void VI_UpdateScreen()
|
|||
frameBufferList().clearBuffersChanged();
|
||||
VI.lastOrigin = *REG.VI_ORIGIN;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (gDP.changed & CHANGED_COLORBUFFER) {
|
||||
wnd.swapBuffers();
|
||||
frameBufferList().renderBuffer(*REG.VI_ORIGIN);
|
||||
gDP.changed &= ~CHANGED_COLORBUFFER;
|
||||
VI.lastOrigin = *REG.VI_ORIGIN;
|
||||
}
|
||||
|
|
|
@ -148,10 +148,10 @@ void gDPSetColorImage( u32 format, u32 size, u32 width, u32 address )
|
|||
else
|
||||
height = VI.height > 0 ? VI.height : gDP.scissor.lry;
|
||||
|
||||
if (config.frameBufferEmulation.enable) {
|
||||
frameBufferList().saveBuffer(address, (u16)format, (u16)size, (u16)width, height, false);
|
||||
gDP.colorImage.height = 0;
|
||||
} else
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user