1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-06-25 05:49:34 +00:00

Implement copy depth to main depth buffer. It is necessary for correct work of some Reshade shaders.

This commit is contained in:
Sergey Lipskiy 2019-06-27 16:21:51 +07:00
parent a1faafcc1b
commit 86a227308e
17 changed files with 176 additions and 31 deletions

View File

@ -112,12 +112,14 @@ void CombinerInfo::init()
m_shadowmapProgram.reset(gfxContext.createDepthFogShader());
m_texrectCopyProgram.reset(gfxContext.createTexrectCopyShader());
m_texrectColorAndDepthCopyProgram.reset(gfxContext.createTexrectColorAndDepthCopyShader());
}
void CombinerInfo::destroy()
{
m_shadowmapProgram.reset();
m_texrectCopyProgram.reset();
m_texrectColorAndDepthCopyProgram.reset();
m_pCurrent = nullptr;
if (config.generalEmulation.enableShadersStorage != 0)
@ -318,6 +320,11 @@ ShaderProgram * CombinerInfo::getTexrectCopyProgram()
return m_texrectCopyProgram.get();
}
ShaderProgram * CombinerInfo::getTexrectColorAndDepthCopyProgram()
{
return m_texrectColorAndDepthCopyProgram.get();
}
bool CombinerInfo::isShaderCacheSupported() const
{
return config.generalEmulation.enableShadersStorage != 0 && Context::ShaderProgramBinary;

View File

@ -127,6 +127,7 @@ public:
void setDepthFogCombiner();
graphics::ShaderProgram * getTexrectCopyProgram();
graphics::ShaderProgram * getTexrectColorAndDepthCopyProgram();
graphics::CombinerProgram * getCurrent() const { return m_pCurrent; }
bool isChanged() const {return m_bChanged;}
@ -159,6 +160,7 @@ private:
std::unique_ptr<graphics::ShaderProgram> m_shadowmapProgram;
std::unique_ptr<graphics::ShaderProgram> m_texrectCopyProgram;
std::unique_ptr<graphics::ShaderProgram> m_texrectColorAndDepthCopyProgram;
};
inline

View File

@ -65,6 +65,7 @@ void Config::resetToDefaults()
frameBufferEmulation.nativeResFactor = 0;
frameBufferEmulation.fbInfoReadColorChunk = 0;
frameBufferEmulation.fbInfoReadDepthChunk = 1;
frameBufferEmulation.copyDepthToMainDepthBuffer = 0;
#ifndef MUPENPLUSAPI
frameBufferEmulation.fbInfoDisabled = 0;
#else

View File

@ -120,6 +120,9 @@ struct Config
u32 fbInfoReadColorChunk;
u32 fbInfoReadDepthChunk;
// Depth buffer copy. For Reshade.
u32 copyDepthToMainDepthBuffer;
// Overscan
u32 enableOverscan;
struct {

View File

@ -112,7 +112,7 @@ void DepthBuffer::initDepthImageTexture(FrameBuffer * _pBuffer)
depthBufferList().clearBuffer();
}
void DepthBuffer::_initDepthBufferTexture(FrameBuffer * _pBuffer, CachedTexture * _pTexture, bool _multisample)
void DepthBuffer::_initDepthBufferTexture(const FrameBuffer * _pBuffer, CachedTexture * _pTexture, bool _multisample)
{
const FramebufferTextureFormats & fbTexFormat = gfxContext.getFramebufferTextureFormats();
@ -273,19 +273,15 @@ CachedTexture * DepthBuffer::resolveDepthBufferTexture(FrameBuffer * _pBuffer)
return m_pResolveDepthBufferTexture;
}
CachedTexture * DepthBuffer::copyDepthBufferTexture(FrameBuffer * _pBuffer)
void DepthBuffer::copyDepthBufferTexture(FrameBuffer * _pBuffer, CachedTexture *& _pTexture, graphics::ObjectHandle _copyFBO)
{
if (m_copied)
return m_pDepthBufferCopyTexture;
if (m_pDepthBufferCopyTexture == nullptr) {
m_pDepthBufferCopyTexture = textureCache().addFrameBufferTexture(false);
_initDepthBufferTexture(_pBuffer, m_pDepthBufferCopyTexture, false);
if (_pTexture == nullptr) {
_pTexture = textureCache().addFrameBufferTexture(false);
_initDepthBufferTexture(_pBuffer, _pTexture, false);
}
Context::FrameBufferRenderTarget targetParams;
targetParams.bufferHandle = m_copyFBO;
targetParams.bufferHandle = _copyFBO;
targetParams.bufferTarget = bufferTarget::DRAW_FRAMEBUFFER;
targetParams.attachment = bufferAttachment::COLOR_ATTACHMENT0;
targetParams.textureHandle = _pBuffer->m_pTexture->frameBufferTexture == CachedTexture::fbMultiSample ?
@ -296,22 +292,17 @@ CachedTexture * DepthBuffer::copyDepthBufferTexture(FrameBuffer * _pBuffer)
gfxContext.addFrameBufferRenderTarget(targetParams);
targetParams.attachment = bufferAttachment::DEPTH_ATTACHMENT;
targetParams.textureHandle = m_pDepthBufferCopyTexture->name;
targetParams.textureHandle = _pTexture->name;
gfxContext.addFrameBufferRenderTarget(targetParams);
Context::BlitFramebuffersParams blitParams;
blitParams.readBuffer = _pBuffer->m_FBO;
blitParams.drawBuffer = m_copyFBO;
blitParams.srcX0 = 0;
blitParams.srcY0 = 0;
blitParams.srcX1 = m_pDepthBufferTexture->width;
blitParams.srcY1 = m_pDepthBufferTexture->height;
blitParams.dstX0 = 0;
blitParams.dstY0 = 0;
blitParams.dstX1 = m_pDepthBufferTexture->width;
blitParams.dstY1 = m_pDepthBufferTexture->height;
blitParams.drawBuffer = _copyFBO;
blitParams.srcX0 = blitParams.dstX0 = 0;
blitParams.srcY0 = blitParams.dstY0 = 0;
blitParams.srcX1 = blitParams.dstX1 = _pTexture->width;
blitParams.srcY1 = blitParams.dstY1 = _pTexture->height;
blitParams.mask = blitMask::DEPTH_BUFFER;
blitParams.filter = textureParameters::FILTER_NEAREST;
@ -319,7 +310,14 @@ CachedTexture * DepthBuffer::copyDepthBufferTexture(FrameBuffer * _pBuffer)
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, _pBuffer->m_FBO);
}
CachedTexture * DepthBuffer::copyDepthBufferTexture(FrameBuffer * _pBuffer)
{
if (m_copied)
return m_pDepthBufferCopyTexture;
DepthBuffer::copyDepthBufferTexture(_pBuffer, m_pDepthBufferCopyTexture, m_copyFBO);
m_copied = true;
return m_pDepthBufferCopyTexture;
}

View File

@ -44,9 +44,12 @@ struct DepthBuffer
CachedTexture *m_pDepthBufferCopyTexture;
bool m_copied;
static void copyDepthBufferTexture(FrameBuffer * _pBuffer, CachedTexture *& _pTexture, graphics::ObjectHandle _copyFBO);
static void _initDepthBufferTexture(const FrameBuffer * _pBuffer, CachedTexture *_pTexture, bool _multisample);
private:
void _initDepthImageTexture(FrameBuffer * _pBuffer, CachedTexture& _cachedTexture, graphics::ObjectHandle & _clearFBO);
void _initDepthBufferTexture(FrameBuffer * _pBuffer, CachedTexture *_pTexture, bool _multisample);
static void _initDepthImageTexture(FrameBuffer * _pBuffer, CachedTexture& _cachedTexture, graphics::ObjectHandle & _clearFBO);
void _initDepthBufferRenderbuffer(FrameBuffer * _pBuffer);
};

View File

@ -64,16 +64,22 @@ FrameBuffer::FrameBuffer()
m_loadTileOrigin.uls = m_loadTileOrigin.ult = 0;
m_pTexture = textureCache().addFrameBufferTexture(config.video.multisampling != 0);
m_FBO = gfxContext.createFramebuffer();
m_pDepthTexture = nullptr;
if (config.frameBufferEmulation.copyDepthToMainDepthBuffer != 0)
m_depthFBO = gfxContext.createFramebuffer();
}
FrameBuffer::~FrameBuffer()
{
gfxContext.deleteFramebuffer(m_FBO);
gfxContext.deleteFramebuffer(m_depthFBO);
gfxContext.deleteFramebuffer(m_resolveFBO);
gfxContext.deleteFramebuffer(m_SubFBO);
gfxContext.deleteFramebuffer(m_copyFBO);
textureCache().removeFrameBufferTexture(m_pTexture);
textureCache().removeFrameBufferTexture(m_pDepthTexture);
textureCache().removeFrameBufferTexture(m_pResolveTexture);
textureCache().removeFrameBufferTexture(m_pSubTexture);
textureCache().removeFrameBufferTexture(m_pFrameBufferCopyTexture);
@ -346,6 +352,12 @@ void FrameBuffer::resolveMultisampledTexture(bool _bForce)
m_resolved = true;
}
void FrameBuffer::copyDepthTexture()
{
if (config.frameBufferEmulation.copyDepthToMainDepthBuffer != 0)
DepthBuffer::copyDepthBufferTexture(this, m_pDepthTexture, m_depthFBO);
}
bool FrameBuffer::_initSubTexture(u32 _t)
{
if (!m_SubFBO.isNotNull())
@ -1240,6 +1252,12 @@ void FrameBufferList::OverscanBuffer::destroy()
m_FBO = graphics::ObjectHandle::null;
textureCache().removeFrameBufferTexture(m_pTexture);
m_pTexture = nullptr;
textureCache().removeFrameBufferTexture(m_pDepthTexture);
m_pDepthTexture = nullptr;
#if defined(OS_WINDOWS)
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
gfxContext.clearDepthBuffer();
#endif
}
void FrameBufferList::OverscanBuffer::setInputBuffer(const FrameBuffer * _pBuffer)
@ -1269,6 +1287,21 @@ void FrameBufferList::OverscanBuffer::setInputBuffer(const FrameBuffer * _pBuff
m_scale = _pBuffer->m_scale;
m_drawingWidth = m_bufferWidth = m_pTexture->width;
m_bufferHeight = m_pTexture->height;
if (config.frameBufferEmulation.copyDepthToMainDepthBuffer == 0)
return;
// Init depth texture
textureCache().removeFrameBufferTexture(m_pDepthTexture);
m_pDepthTexture = textureCache().addFrameBufferTexture(false);
DepthBuffer::_initDepthBufferTexture(_pBuffer, m_pDepthTexture, false);
Context::FrameBufferRenderTarget params;
params.attachment = bufferAttachment::DEPTH_ATTACHMENT;
params.bufferHandle = m_FBO;
params.bufferTarget = bufferTarget::DRAW_FRAMEBUFFER;
params.textureHandle = m_pDepthTexture->name;
params.textureTarget = textureTarget::TEXTURE_2D;
gfxContext.addFrameBufferRenderTarget(params);
}
void FrameBufferList::OverscanBuffer::activate()
@ -1290,6 +1323,9 @@ void FrameBufferList::OverscanBuffer::draw(u32 _fullHeight, bool _PAL)
GraphicsDrawer & drawer = wnd.getDrawer();
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, ObjectHandle::defaultFramebuffer);
#if defined(OS_WINDOWS)
gfxContext.clearDepthBuffer();
#endif
GraphicsDrawer::BlitOrCopyRectParams blitParams;
const auto & overscan = _PAL ? config.frameBufferEmulation.overscanPAL : config.frameBufferEmulation.overscanNTSC;
const s32 left = static_cast<s32>(overscan.left * m_scale);
@ -1311,7 +1347,12 @@ void FrameBufferList::OverscanBuffer::draw(u32 _fullHeight, bool _PAL)
blitParams.filter = textureParameters::FILTER_LINEAR;
blitParams.mask = blitMask::COLOR_BUFFER;
blitParams.tex[0] = m_pTexture;
blitParams.combiner = CombinerInfo::get().getTexrectCopyProgram();
if (config.frameBufferEmulation.copyDepthToMainDepthBuffer != 0) {
blitParams.tex[1] = m_pDepthTexture;
blitParams.combiner = CombinerInfo::get().getTexrectColorAndDepthCopyProgram();
} else {
blitParams.combiner = CombinerInfo::get().getTexrectCopyProgram();
}
blitParams.readBuffer = m_FBO;
blitParams.invertY = false;
@ -1454,6 +1495,9 @@ void FrameBufferList::renderBuffer()
m_overscan.activate();
gfxContext.clearColorBuffer(0.0f, 0.0f, 0.0f, 0.0f);
#if defined(OS_WINDOWS)
gfxContext.clearDepthBuffer();
#endif
GraphicsDrawer::BlitOrCopyRectParams blitParams;
blitParams.srcX0 = srcCoord[0];
@ -1471,7 +1515,12 @@ void FrameBufferList::renderBuffer()
blitParams.filter = filter;
blitParams.mask = blitMask::COLOR_BUFFER;
blitParams.tex[0] = pBufferTexture;
blitParams.combiner = CombinerInfo::get().getTexrectCopyProgram();
if (config.frameBufferEmulation.copyDepthToMainDepthBuffer != 0) {
blitParams.tex[1] = pBuffer->m_pDepthTexture;
blitParams.combiner = CombinerInfo::get().getTexrectColorAndDepthCopyProgram();
} else {
blitParams.combiner = CombinerInfo::get().getTexrectCopyProgram();
}
blitParams.readBuffer = readBuffer;
blitParams.invertY = config.frameBufferEmulation.enableOverscan == 0;
@ -1489,8 +1538,7 @@ void FrameBufferList::renderBuffer()
pFilteredBuffer->resolveMultisampledTexture();
readBuffer = pFilteredBuffer->m_resolveFBO;
pBufferTexture = pFilteredBuffer->m_pResolveTexture;
}
else {
} else {
readBuffer = pFilteredBuffer->m_FBO;
pBufferTexture = pFilteredBuffer->m_pTexture;
}
@ -1504,6 +1552,9 @@ void FrameBufferList::renderBuffer()
blitParams.dstWidth = m_overscan.getBufferWidth();
blitParams.dstHeight = m_overscan.getBufferHeight();
blitParams.tex[0] = pBufferTexture;
blitParams.tex[1] = pNextBuffer->m_pDepthTexture;
blitParams.filter = filter;
blitParams.mask = blitMask::COLOR_BUFFER;
blitParams.readBuffer = readBuffer;
drawer.copyTexturedRect(blitParams);

View File

@ -20,6 +20,7 @@ struct FrameBuffer
void init(u32 _address, u16 _format, u16 _size, u16 _width, bool _cfb);
void updateEndAddress();
void resolveMultisampledTexture(bool _bForce = false);
void copyDepthTexture();
CachedTexture * getTexture(u32 _t);
CachedTexture * getTextureBG(u32 _t);
void setBufferClearParams(u32 _fillcolor, s32 _ulx, s32 _uly, s32 _lrx, s32 _lry);
@ -56,6 +57,10 @@ struct FrameBuffer
graphics::ObjectHandle m_FBO;
CachedTexture *m_pTexture;
graphics::ObjectHandle m_depthFBO;
CachedTexture *m_pDepthTexture;
DepthBuffer *m_pDepthBuffer;
// multisampling
@ -162,6 +167,7 @@ private:
graphics::ObjectHandle m_FBO;
CachedTexture *m_pTexture = nullptr;
CachedTexture *m_pDepthTexture = nullptr;
};
typedef std::list<FrameBuffer> FrameBuffers;

View File

@ -281,6 +281,11 @@ ShaderProgram * Context::createTexrectCopyShader()
return m_impl->createTexrectCopyShader();
}
ShaderProgram * Context::createTexrectColorAndDepthCopyShader()
{
return m_impl->createTexrectColorAndDepthCopyShader();
}
ShaderProgram * Context::createGammaCorrectionShader()
{
return m_impl->createGammaCorrectionShader();

View File

@ -232,6 +232,8 @@ namespace graphics {
ShaderProgram * createTexrectCopyShader();
ShaderProgram * createTexrectColorAndDepthCopyShader();
ShaderProgram * createGammaCorrectionShader();
ShaderProgram * createOrientationCorrectionShader();

View File

@ -58,6 +58,7 @@ namespace graphics {
virtual TexrectDrawerShaderProgram * createTexrectDrawerDrawShader() = 0;
virtual ShaderProgram * createTexrectDrawerClearShader() = 0;
virtual ShaderProgram * createTexrectCopyShader() = 0;
virtual ShaderProgram * createTexrectColorAndDepthCopyShader() = 0;
virtual ShaderProgram * createGammaCorrectionShader() = 0;
virtual ShaderProgram * createOrientationCorrectionShader() = 0;
virtual ShaderProgram * createFXAAShader() = 0;

View File

@ -371,6 +371,27 @@ namespace glsl {
}
};
/*---------------TexrectDepthCopyShaderPart-------------*/
class TexrectColorAndDepthCopy : public ShaderPart
{
public:
TexrectColorAndDepthCopy(const opengl::GLInfo & _glinfo)
{
m_part =
"IN mediump vec2 vTexCoord0; \n"
"uniform sampler2D uTex0; \n"
"uniform sampler2D uTex1; \n"
"OUT lowp vec4 fragColor; \n"
" \n"
"void main() \n"
"{ \n"
" fragColor = texture2D(uTex0, vTexCoord0); \n"
" gl_FragDepth = texture2D(uTex1, vTexCoord0).r; \n"
;
}
};
/*---------------PostProcessorShaderPart-------------*/
class GammaCorrection : public ShaderPart
@ -664,6 +685,29 @@ namespace glsl {
}
};
/*---------------TexrectColorAndDepthCopyShader-------------*/
typedef SpecialShader<VertexShaderTexturedRect, TexrectColorAndDepthCopy> TexrectColorAndDepthCopyShaderBase;
class TexrectColorAndDepthCopyShader : public TexrectColorAndDepthCopyShaderBase
{
public:
TexrectColorAndDepthCopyShader(const opengl::GLInfo & _glinfo,
opengl::CachedUseProgram * _useProgram,
const ShaderPart * _vertexHeader,
const ShaderPart * _fragmentHeader,
const ShaderPart * _fragmentEnd)
: TexrectColorAndDepthCopyShaderBase(_glinfo, _useProgram, _vertexHeader, _fragmentHeader, _fragmentEnd)
{
m_useProgram->useProgram(m_program);
const int texLoc0 = glGetUniformLocation(GLuint(m_program), "uTex0");
glUniform1i(texLoc0, 0);
const int texLoc1 = glGetUniformLocation(GLuint(m_program), "uTex1");
glUniform1i(texLoc1, 1);
m_useProgram->useProgram(graphics::ObjectHandle::null);
}
};
/*---------------PostProcessorShader-------------*/
typedef SpecialShader<VertexShaderTexturedRect, GammaCorrection> GammaCorrectionShaderBase;
@ -778,6 +822,11 @@ namespace glsl {
return new TexrectCopyShader(m_glinfo, m_useProgram, m_vertexHeader, m_fragmentHeader, m_fragmentEnd);
}
graphics::ShaderProgram * SpecialShadersFactory::createTexrectColorAndDepthCopyShader() const
{
return new TexrectColorAndDepthCopyShader(m_glinfo, m_useProgram, m_vertexHeader, m_fragmentHeader, m_fragmentEnd);
}
graphics::ShaderProgram * SpecialShadersFactory::createGammaCorrectionShader() const
{
return new GammaCorrectionShader(m_glinfo, m_useProgram, m_vertexHeader, m_fragmentHeader, m_fragmentEnd);

View File

@ -30,6 +30,8 @@ namespace glsl {
graphics::ShaderProgram * createTexrectCopyShader() const;
graphics::ShaderProgram * createTexrectColorAndDepthCopyShader() const;
graphics::ShaderProgram * createGammaCorrectionShader() const;
graphics::ShaderProgram * createOrientationCorrectionShader() const;

View File

@ -423,6 +423,11 @@ graphics::ShaderProgram * ContextImpl::createTexrectCopyShader()
return m_specialShadersFactory->createTexrectCopyShader();
}
graphics::ShaderProgram * ContextImpl::createTexrectColorAndDepthCopyShader()
{
return m_specialShadersFactory->createTexrectColorAndDepthCopyShader();
}
graphics::ShaderProgram * ContextImpl::createGammaCorrectionShader()
{
return m_specialShadersFactory->createGammaCorrectionShader();

View File

@ -124,6 +124,8 @@ namespace opengl {
graphics::ShaderProgram * createTexrectCopyShader() override;
graphics::ShaderProgram * createTexrectColorAndDepthCopyShader() override;
graphics::ShaderProgram * createGammaCorrectionShader() override;
graphics::ShaderProgram * createOrientationCorrectionShader() override;

View File

@ -1665,8 +1665,15 @@ void GraphicsDrawer::copyTexturedRect(const CopyRectParams & _params)
gfxContext.setViewport(0, 0, _params.dstWidth, _params.dstHeight);
gfxContext.enable(enable::CULL_FACE, false);
gfxContext.enable(enable::BLEND, false);
gfxContext.enable(enable::DEPTH_TEST, false);
gfxContext.enableDepthWrite(false);
if (config.frameBufferEmulation.copyDepthToMainDepthBuffer == 0 || _params.tex[1] == nullptr) {
gfxContext.enable(enable::DEPTH_TEST, false);
gfxContext.enableDepthWrite(false);
} else {
gfxContext.setDepthCompare(compare::ALWAYS);
gfxContext.enableDepthWrite(true);
gfxContext.enable(enable::DEPTH_TEST, true);
}
Context::DrawRectParameters rectParams;
rectParams.mode = drawmode::TRIANGLE_STRIP;
@ -1698,10 +1705,10 @@ void GraphicsDrawer::blitOrCopyTexturedRect(const BlitOrCopyRectParams & _params
blitParams.mask = _params.mask;
blitParams.filter = _params.filter;
if (_params.invertX) {
std::swap(blitParams.srcX0, blitParams.srcX1);
std::swap(blitParams.dstX0, blitParams.dstX1);
}
if (_params.invertY) {
std::swap(blitParams.srcY0, blitParams.srcY1);
std::swap(blitParams.dstY0, blitParams.dstY1);
}
if (gfxContext.blitFramebuffers(blitParams))

View File

@ -900,6 +900,7 @@ void gDPFullSync()
frameBufferList().updateCurrentBufferEndAddress();
FrameBuffer * pCurrentBuffer = frameBufferList().getCurrent();
pCurrentBuffer->copyDepthTexture();
if ((config.frameBufferEmulation.copyToRDRAM != Config::ctDisable || (config.generalEmulation.hacks & hack_subscreen) != 0) &&
!FBInfo::fbInfo.isSupported() &&
pCurrentBuffer != nullptr &&