1
0
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:
Sergey Lipskiy 2017-02-25 13:38:33 +07:00
parent 4b040304bb
commit 873a830d88
7 changed files with 129 additions and 29 deletions

View File

@ -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)

View File

@ -67,6 +67,8 @@ private:
DepthBufferList(const DepthBufferList &);
~DepthBufferList();
void _createScreenSizeBuffer(u32 _address);
typedef std::list<DepthBuffer> DepthBuffers;
DepthBuffers m_list;
DepthBuffer *m_pCurrent;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}