1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-02 09:03:37 +00:00

Copy FBO texture if glTextureBarrier is unsupported

This commit is contained in:
Logan McNaughton 2018-04-16 13:13:18 -06:00 committed by Sergey Lipskiy
parent 75ea06cec7
commit 9bda0568a8
6 changed files with 85 additions and 13 deletions

View File

@ -53,6 +53,9 @@ FrameBuffer::FrameBuffer()
, m_pResolveTexture(nullptr)
, m_resolved(false)
, m_pSubTexture(nullptr)
, m_copied(false)
, m_pFrameBufferCopyTexture(nullptr)
, m_copyFBO(ObjectHandle::null)
{
m_loadTileOrigin.uls = m_loadTileOrigin.ult = 0;
m_pTexture = textureCache().addFrameBufferTexture(config.video.multisampling != 0);
@ -64,10 +67,12 @@ FrameBuffer::~FrameBuffer()
gfxContext.deleteFramebuffer(m_FBO);
gfxContext.deleteFramebuffer(m_resolveFBO);
gfxContext.deleteFramebuffer(m_SubFBO);
gfxContext.deleteFramebuffer(m_copyFBO);
textureCache().removeFrameBufferTexture(m_pTexture);
textureCache().removeFrameBufferTexture(m_pResolveTexture);
textureCache().removeFrameBufferTexture(m_pSubTexture);
textureCache().removeFrameBufferTexture(m_pFrameBufferCopyTexture);
}
void FrameBuffer::_initTexture(u16 _width, u16 _height, u16 _format, u16 _size, CachedTexture *_pTexture)
@ -418,6 +423,47 @@ CachedTexture * FrameBuffer::_getSubTexture(u32 _t)
return m_pSubTexture;
}
void FrameBuffer::_initCopyTexture()
{
m_copyFBO = gfxContext.createFramebuffer();
m_pFrameBufferCopyTexture = textureCache().addFrameBufferTexture(config.video.multisampling != 0);
_initTexture(m_width, VI_GetMaxBufferHeight(m_width), m_pTexture->format, m_pTexture->size, m_pFrameBufferCopyTexture);
_setAndAttachTexture(m_copyFBO, m_pFrameBufferCopyTexture, 0, config.video.multisampling != 0);
if (config.video.multisampling != 0)
m_pFrameBufferCopyTexture->frameBufferTexture = CachedTexture::fbMultiSample;
}
CachedTexture * FrameBuffer::_copyFrameBufferTexture()
{
if (m_copied)
return m_pFrameBufferCopyTexture;
if (m_pFrameBufferCopyTexture == nullptr)
_initCopyTexture();
Context::BlitFramebuffersParams blitParams;
blitParams.readBuffer = m_FBO;
blitParams.drawBuffer = m_copyFBO;
blitParams.srcX0 = 0;
blitParams.srcY0 = 0;
blitParams.srcX1 = m_pTexture->realWidth;
blitParams.srcY1 = m_pTexture->realHeight;
blitParams.dstX0 = 0;
blitParams.dstY0 = 0;
blitParams.dstX1 = m_pTexture->realWidth;
blitParams.dstY1 = m_pTexture->realHeight;
blitParams.mask = blitMask::COLOR_BUFFER;
blitParams.filter = textureParameters::FILTER_NEAREST;
gfxContext.blitFramebuffers(blitParams);
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, ObjectHandle::null);
frameBufferList().setCurrentDrawBuffer();
m_copied = true;
return m_pFrameBufferCopyTexture;
}
CachedTexture * FrameBuffer::getTexture(u32 _t)
{
const bool getDepthTexture = m_isDepthBuffer &&
@ -426,6 +472,13 @@ CachedTexture * FrameBuffer::getTexture(u32 _t)
(config.generalEmulation.hacks & hack_ZeldaMM) == 0;
CachedTexture *pTexture = getDepthTexture ? m_pDepthBuffer->m_pDepthBufferTexture : m_pTexture;
if (this == frameBufferList().getCurrent()) {
if (Context::TextureBarrier)
gfxContext.textureBarrier();
else if (Context::BlitFramebuffer)
pTexture = getDepthTexture ? m_pDepthBuffer->copyDepthBufferTexture(this) : _copyFrameBufferTexture();
}
const u32 shift = (gSP.textureTile[_t]->imageAddress - m_startAddress) >> (m_size - 1);
const u32 factor = m_width;
if (m_loadType == LOADTYPE_TILE) {
@ -461,15 +514,24 @@ CachedTexture * FrameBuffer::getTexture(u32 _t)
CachedTexture * FrameBuffer::getTextureBG(u32 _t)
{
m_pTexture->scaleS = m_scale / (float)m_pTexture->realWidth;
m_pTexture->scaleT = m_scale / (float)m_pTexture->realHeight;
CachedTexture *pTexture = m_pTexture;
m_pTexture->shiftScaleS = 1.0f;
m_pTexture->shiftScaleT = 1.0f;
if (this == frameBufferList().getCurrent()) {
if (Context::TextureBarrier)
gfxContext.textureBarrier();
else if (Context::BlitFramebuffer)
pTexture = _copyFrameBufferTexture();
}
m_pTexture->offsetS = gSP.bgImage.imageX;
m_pTexture->offsetT = gSP.bgImage.imageY;
return m_pTexture;
pTexture->scaleS = m_scale / (float)pTexture->realWidth;
pTexture->scaleT = m_scale / (float)pTexture->realHeight;
pTexture->shiftScaleS = 1.0f;
pTexture->shiftScaleT = 1.0f;
pTexture->offsetS = gSP.bgImage.imageX;
pTexture->offsetT = gSP.bgImage.imageY;
return pTexture;
}
FrameBufferList & FrameBufferList::get()
@ -704,6 +766,7 @@ void FrameBufferList::saveBuffer(u32 _address, u16 _format, u16 _size, u16 _widt
m_pCurrent->m_isDepthBuffer = _address == gDP.depthImageAddress;
m_pCurrent->m_isPauseScreen = m_pCurrent->m_isOBScreen = false;
m_pCurrent->m_copied = false;
}
void FrameBufferList::copyAux()
@ -1278,8 +1341,6 @@ void FrameBuffer_ActivateBufferTexture(u32 t, u32 _frameBufferAddress)
// frameBufferList().renderBuffer(pBuffer->m_startAddress);
textureCache().activateTexture(t, pTexture);
if (pBuffer == frameBufferList().getCurrent())
gfxContext.textureBarrier();
gDP.changed |= CHANGED_FB_TEXTURE;
}
@ -1295,8 +1356,6 @@ void FrameBuffer_ActivateBufferTextureBG(u32 t, u32 _frameBufferAddress)
// frameBufferList().renderBuffer(pBuffer->m_startAddress);
textureCache().activateTexture(t, pTexture);
if (pBuffer == frameBufferList().getCurrent())
gfxContext.textureBarrier();
gDP.changed |= CHANGED_FB_TEXTURE;
}

View File

@ -42,6 +42,7 @@ struct FrameBuffer
bool m_isOBScreen;
bool m_isMainBuffer;
bool m_readable;
bool m_copied;
struct {
u32 uls, ult;
@ -61,6 +62,10 @@ struct FrameBuffer
graphics::ObjectHandle m_SubFBO;
CachedTexture *m_pSubTexture;
// copy FBO
graphics::ObjectHandle m_copyFBO;
CachedTexture * m_pFrameBufferCopyTexture;
std::vector<u8> m_RdramCopy;
private:
@ -75,6 +80,8 @@ private:
void _initTexture(u16 _width, u16 _height, u16 _format, u16 _size, CachedTexture *_pTexture);
void _setAndAttachTexture(graphics::ObjectHandle _fbo, CachedTexture *_pTexture, u32 _t, bool _multisampling);
bool _initSubTexture(u32 _t);
void _initCopyTexture();
CachedTexture * _copyFrameBufferTexture();
CachedTexture * _getSubTexture(u32 _t);
mutable u32 m_validityChecked;
};

View File

@ -14,6 +14,7 @@ bool Context::ImageTextures = false;
bool Context::IntegerTextures = false;
bool Context::ClipControl = false;
bool Context::FramebufferFetch = false;
bool Context::TextureBarrier = false;
Context::Context() {}
@ -36,6 +37,7 @@ void Context::init()
IntegerTextures = m_impl->isSupported(SpecialFeatures::IntegerTextures);
ClipControl = m_impl->isSupported(SpecialFeatures::ClipControl);
FramebufferFetch = m_impl->isSupported(SpecialFeatures::FramebufferFetch);
TextureBarrier = m_impl->isSupported(SpecialFeatures::TextureBarrier);
}
void Context::destroy()

View File

@ -24,7 +24,8 @@ namespace graphics {
ImageTextures,
IntegerTextures,
ClipControl,
FramebufferFetch
FramebufferFetch,
TextureBarrier
};
enum class ClampMode {
@ -285,6 +286,7 @@ namespace graphics {
static bool IntegerTextures;
static bool ClipControl;
static bool FramebufferFetch;
static bool TextureBarrier;
private:
std::unique_ptr<ContextImpl> m_impl;

View File

@ -491,6 +491,8 @@ bool ContextImpl::isSupported(graphics::SpecialFeatures _feature) const
return !m_glInfo.isGLESX;
case graphics::SpecialFeatures::FramebufferFetch:
return m_glInfo.ext_fetch;
case graphics::SpecialFeatures::TextureBarrier:
return m_glInfo.texture_barrier || m_glInfo.texture_barrierNV;
}
return false;
}

View File

@ -121,7 +121,7 @@ void GLInfo::init() {
noPerspective = Utils::isExtensionSupported(*this, "GL_NV_shader_noperspective_interpolation");
fetch_depth = Utils::isExtensionSupported(*this, "GL_ARM_shader_framebuffer_fetch_depth_stencil");
texture_barrier = (!isGLESX && numericVersion >= 45) || Utils::isExtensionSupported(*this, "GL_ARB_texture_barrier");
texture_barrier = !isGLESX && (numericVersion >= 45 || Utils::isExtensionSupported(*this, "GL_ARB_texture_barrier"));
texture_barrierNV = Utils::isExtensionSupported(*this, "GL_NV_texture_barrier");
ext_fetch = Utils::isExtensionSupported(*this, "GL_EXT_shader_framebuffer_fetch") && !isGLES2 && (!isGLESX || ext_draw_buffers_indexed) && !imageTextures;