1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-06-25 22:09:35 +00:00

Fix DepthBufferList::clearBuffer() for image textures.

This commit is contained in:
Sergey Lipskiy 2018-09-27 18:31:41 +07:00
parent 9a2a77982b
commit 57ad2e96c6
7 changed files with 96 additions and 45 deletions

View File

@ -16,20 +16,28 @@
using namespace graphics;
DepthBuffer::DepthBuffer() : m_address(0), m_width(0), m_ulx(0), m_uly(0), m_lrx(0), m_lry(0),
m_pDepthImageZTexture(nullptr), m_pDepthImageDeltaZTexture(nullptr), m_pDepthBufferTexture(nullptr),
m_depthRenderbufferWidth(0), m_cleared(false), m_pResolveDepthBufferTexture(nullptr), m_resolved(false),
m_pDepthBufferCopyTexture(nullptr), m_copied(false)
DepthBuffer::DepthBuffer()
: m_address(0)
, m_width(0)
, m_pDepthImageZTexture(nullptr)
, m_pDepthImageDeltaZTexture(nullptr)
, m_pDepthBufferTexture(nullptr)
, m_depthRenderbufferWidth(0)
, m_cleared(false)
, m_pResolveDepthBufferTexture(nullptr)
, m_resolved(false)
, m_pDepthBufferCopyTexture(nullptr)
, m_copied(false)
{
m_copyFBO = gfxContext.createFramebuffer();
if (config.frameBufferEmulation.N64DepthCompare != 0) {
}
}
DepthBuffer::~DepthBuffer()
{
gfxContext.deleteFramebuffer(m_depthRenderbuffer);
gfxContext.deleteFramebuffer(m_copyFBO);
gfxContext.deleteFramebuffer(m_ZTextureClearFBO);
gfxContext.deleteFramebuffer(m_DeltaZTextureClearFBO);
textureCache().removeFrameBufferTexture(m_pDepthImageZTexture);
textureCache().removeFrameBufferTexture(m_pDepthImageDeltaZTexture);
@ -38,7 +46,7 @@ DepthBuffer::~DepthBuffer()
textureCache().removeFrameBufferTexture(m_pDepthBufferCopyTexture);
}
void DepthBuffer::_initDepthImageTexture(FrameBuffer * _pBuffer, CachedTexture& _cachedTexture)
void DepthBuffer::_initDepthImageTexture(FrameBuffer * _pBuffer, CachedTexture& _cachedTexture, graphics::ObjectHandle & _clearFBO)
{
const FramebufferTextureFormats & fbTexFormat = gfxContext.getFramebufferTextureFormats();
@ -79,6 +87,15 @@ void DepthBuffer::_initDepthImageTexture(FrameBuffer * _pBuffer, CachedTexture&
params.magFilter = textureParameters::FILTER_NEAREST;
gfxContext.setTextureParameters(params);
}
{
Context::FrameBufferRenderTarget targetParams;
targetParams.bufferHandle = _clearFBO;
targetParams.bufferTarget = bufferTarget::DRAW_FRAMEBUFFER;
targetParams.attachment = bufferAttachment::COLOR_ATTACHMENT0;
targetParams.textureHandle = _cachedTexture.name;
targetParams.textureTarget = textureTarget::TEXTURE_2D;
gfxContext.addFrameBufferRenderTarget(targetParams);
}
}
void DepthBuffer::initDepthImageTexture(FrameBuffer * _pBuffer)
@ -87,14 +104,14 @@ void DepthBuffer::initDepthImageTexture(FrameBuffer * _pBuffer)
return;
m_pDepthImageZTexture = textureCache().addFrameBufferTexture(false);
m_ZTextureClearFBO = gfxContext.createFramebuffer();
m_pDepthImageDeltaZTexture = textureCache().addFrameBufferTexture(false);
m_DeltaZTextureClearFBO = gfxContext.createFramebuffer();
_initDepthImageTexture(_pBuffer, *m_pDepthImageZTexture);
_initDepthImageTexture(_pBuffer, *m_pDepthImageDeltaZTexture);
_initDepthImageTexture(_pBuffer, *m_pDepthImageZTexture, m_ZTextureClearFBO);
_initDepthImageTexture(_pBuffer, *m_pDepthImageDeltaZTexture, m_DeltaZTextureClearFBO);
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, _pBuffer->m_FBO);
depthBufferList().clearBuffer(0, 0, _pBuffer->m_width, _pBuffer->m_height);
depthBufferList().clearBuffer();
}
void DepthBuffer::_initDepthBufferTexture(FrameBuffer * _pBuffer, CachedTexture * _pTexture, bool _multisample)
@ -387,10 +404,10 @@ void DepthBufferList::destroy()
m_list.clear();
}
void DepthBufferList::setNotCleared()
void DepthBufferList::setCleared(bool _cleared)
{
for (DepthBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter)
iter->m_cleared = false;
iter->m_cleared = _cleared;
}
DepthBuffer * DepthBufferList::findBuffer(u32 _address)
@ -469,21 +486,53 @@ void DepthBufferList::saveBuffer(u32 _address)
m_pCurrent = pDepthBuffer;
frameBufferList().attachDepthBuffer();
if (pFrameBuffer == nullptr)
gfxContext.clearDepthBuffer();
clearBuffer();
if (pDepthBuffer->m_address != gDP.depthImageAddress)
m_pCurrent = pCurrent;
}
void DepthBufferList::clearBuffer(u32 _ulx, u32 _uly, u32 _lrx, u32 _lry)
void DepthBufferList::clearBuffer()
{
if (m_pCurrent == nullptr)
return;
if (m_pCurrent != nullptr)
m_pCurrent->m_cleared = true;
m_pCurrent->m_cleared = true;
m_pCurrent->m_ulx = _ulx;
m_pCurrent->m_uly = _uly;
m_pCurrent->m_lrx = _lrx;
m_pCurrent->m_lry = _lry;
if (config.frameBufferEmulation.enable == 0 || config.frameBufferEmulation.N64DepthCompare == 0) {
gfxContext.clearDepthBuffer();
return;
}
// Clear depth image texture
FrameBuffer * pColorBuffer = frameBufferList().getCurrent();
if (pColorBuffer == nullptr || pColorBuffer->m_pDepthBuffer == nullptr)
return;
DepthBuffer * pDepthBuffer = pColorBuffer->m_pDepthBuffer;
//if (pColorBuffer->m_pTexture->realWidth == pDepthBuffer->m_pDepthImageZTexture->realWidth)
{
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, pDepthBuffer->m_ZTextureClearFBO);
gfxContext.clearColorBuffer(1.0f, 0.0f, 0.0f, 0.0f);
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, pDepthBuffer->m_DeltaZTextureClearFBO);
gfxContext.clearColorBuffer(1.0f, 0.0f, 0.0f, 0.0f);
}
//else {
// gDP.rectColor.g = gDP.rectColor.b = gDP.rectColor.a = 0.0f;
// u32 cycleType = gDP.otherMode.cycleType;
// u32 fillcolor = gDP.fillColor.color;
// gDP.otherMode.cycleType = G_CYC_FILL;
// gDP.fillColor.color = 0;
// const int lrx = pColorBuffer->m_width;
// const int lry = VI_GetMaxBufferHeight(pColorBuffer->m_width);
// gDP.rectColor.r = 1.0f;
// gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, pDepthBuffer->m_ZTextureClearFBO);
// dwnd().getDrawer().drawRect(0, 0, lrx, lry);
// gDP.rectColor.r = 0.0f;
// gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, pDepthBuffer->m_DeltaZTextureClearFBO);
// dwnd().getDrawer().drawRect(0, 0, lrx, lry);
// gDP.otherMode.cycleType = cycleType;
// gDP.fillColor.color = fillcolor;
//}
frameBufferList().setCurrentDrawBuffer();
}
void DepthBuffer_Init()

View File

@ -23,26 +23,31 @@ struct DepthBuffer
void bindDepthImageTexture(graphics::ObjectHandle _fbo);
u32 m_address, m_width;
u32 m_ulx, m_uly, m_lrx, m_lry; // Parameters of fillrect command.
CachedTexture *m_pDepthImageZTexture;
CachedTexture *m_pDepthImageDeltaZTexture;
bool m_cleared;
CachedTexture *m_pDepthBufferTexture;
graphics::ObjectHandle m_depthRenderbuffer;
u32 m_depthRenderbufferWidth;
bool m_cleared;
CachedTexture *m_pDepthImageZTexture;
CachedTexture *m_pDepthImageDeltaZTexture;
graphics::ObjectHandle m_ZTextureClearFBO;
graphics::ObjectHandle m_DeltaZTextureClearFBO;
// multisampling
CachedTexture *m_pResolveDepthBufferTexture;
bool m_resolved;
// render to depth buffer
graphics::ObjectHandle m_copyFBO;
CachedTexture *m_pDepthBufferCopyTexture;
bool m_copied;
private:
void _initDepthImageTexture(FrameBuffer * _pBuffer, CachedTexture& _cachedTexture);
void _initDepthImageTexture(FrameBuffer * _pBuffer, CachedTexture& _cachedTexture, graphics::ObjectHandle & _clearFBO);
void _initDepthBufferTexture(FrameBuffer * _pBuffer, CachedTexture *_pTexture, bool _multisample);
void _initDepthBufferRenderbuffer(FrameBuffer * _pBuffer);
void _DepthBufferTexture(FrameBuffer * _pBuffer);
};
class DepthBufferList
@ -52,8 +57,8 @@ public:
void destroy();
void saveBuffer(u32 _address);
void removeBuffer(u32 _address);
void clearBuffer(u32 _ulx, u32 _uly, u32 _lrx, u32 _lry);
void setNotCleared();
void clearBuffer();
void setCleared(bool _cleared);
DepthBuffer *findBuffer(u32 _address);
DepthBuffer * getCurrent() const {return m_pCurrent;}

View File

@ -809,8 +809,7 @@ void FrameBufferList::saveBuffer(u32 _address, u16 _format, u16 _size, u16 _widt
(config.generalEmulation.hacks&hack_LoadDepthTextures) == 0) {
// N64 games may use partial depth buffer clear for aux buffers
// It will not work for GL, so we have to force clear depth buffer for aux buffer
const DepthBuffer * pDepth = m_pCurrent->m_pDepthBuffer;
wnd.getDrawer().clearDepthBuffer(pDepth->m_ulx, pDepth->m_uly, pDepth->m_lrx, pDepth->m_lry);
wnd.getDrawer().clearDepthBuffer();
}
m_pCurrent->m_isDepthBuffer = _address == gDP.depthImageAddress;
@ -1013,7 +1012,7 @@ void FrameBufferList::_renderScreenSizeBuffer()
wnd.swapBuffers();
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, pBuffer->m_FBO);
if (config.frameBufferEmulation.forceDepthBufferClear != 0) {
gfxContext.clearDepthBuffer();
drawer.clearDepthBuffer();
}
gDP.changed |= CHANGED_SCISSOR;
}
@ -1484,7 +1483,7 @@ void FrameBufferList::renderBuffer()
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, m_pCurrent->m_FBO);
}
if (config.frameBufferEmulation.forceDepthBufferClear != 0) {
gfxContext.clearDepthBuffer();
drawer.clearDepthBuffer();
}
const s32 X = hOffset;

View File

@ -1529,14 +1529,12 @@ void GraphicsDrawer::_removeOSDMessage(OSDMessages::iterator _iter, Milliseconds
m_osdMessages.erase(_iter);
}
void GraphicsDrawer::clearDepthBuffer(u32 _ulx, u32 _uly, u32 _lrx, u32 _lry)
void GraphicsDrawer::clearDepthBuffer()
{
if (!_canDraw())
return;
depthBufferList().clearBuffer(_ulx, _uly, _lrx, _lry);
gfxContext.clearDepthBuffer();
depthBufferList().clearBuffer();
_updateDepthUpdate();
}

View File

@ -121,7 +121,7 @@ public:
void showMessage(std::string _message, Milliseconds _interval);
void clearDepthBuffer(u32 _ulx, u32 _uly, u32 _lrx, u32 _lry);
void clearDepthBuffer();
void clearColorBuffer(float * _pColor);

View File

@ -154,7 +154,7 @@ void RSP_ProcessDList()
if ((uc_start != RSP.uc_start) || (uc_dstart != RSP.uc_dstart))
gSPLoadUcodeEx(uc_start, uc_dstart, uc_dsize);
depthBufferList().setNotCleared();
depthBufferList().setCleared(false);
if (GBI.getMicrocodeType() == ZSortBOSS) {
RSP.PC[1] = *(u32*)&DMEM[0xff8];

View File

@ -708,10 +708,10 @@ void gDPFillRectangle( s32 ulx, s32 uly, s32 lrx, s32 lry )
depthBuffer = dbFound;
if (config.generalEmulation.enableFragmentDepthWrite == 0) {
frameBufferList().fillRDRAM(ulx, uly, lrx, lry);
drawer.clearDepthBuffer(ulx, uly, lrx, lry);
drawer.clearDepthBuffer();
depthBuffer = dbCleared;
} else
depthBufferList().clearBuffer(ulx, uly, lrx, lry);
depthBufferList().setCleared(true);
}
} else if (gDP.fillColor.color == DepthClearColor && gDP.otherMode.cycleType == G_CYC_FILL) {
depthBuffer = dbFound;
@ -719,10 +719,10 @@ void gDPFillRectangle( s32 ulx, s32 uly, s32 lrx, s32 lry )
if (config.generalEmulation.enableFragmentDepthWrite == 0 ||
(config.generalEmulation.hacks & hack_Snap) != 0) {
frameBufferList().fillRDRAM(ulx, uly, lrx, lry);
drawer.clearDepthBuffer(ulx, uly, lrx, lry);
drawer.clearDepthBuffer();
depthBuffer = dbCleared;
} else
depthBufferList().clearBuffer(ulx, uly, lrx, lry);
depthBufferList().setCleared(true);
}
if (depthBuffer != dbCleared) {