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

Fix depth buffer clear for aux buffers.

This commit is contained in:
Sergey Lipskiy 2016-09-11 18:08:03 +07:00
parent 21ef068f2a
commit 32172d30af
6 changed files with 31 additions and 18 deletions

View File

@ -17,7 +17,7 @@ const GLuint ZlutImageUnit = 0;
const GLuint TlutImageUnit = 1;
const GLuint depthImageUnit = 2;
DepthBuffer::DepthBuffer() : m_address(0), m_width(0), m_uly(0), m_lry(0),
DepthBuffer::DepthBuffer() : m_address(0), m_width(0), m_ulx(0), m_uly(0), m_lrx(0), m_lry(0),
m_depthImageFBO(0), m_pDepthImageTexture(nullptr), m_pDepthBufferTexture(nullptr),
m_depthRenderbuffer(0), m_depthRenderbufferWidth(0),
m_cleared(false), m_pResolveDepthBufferTexture(nullptr), m_resolved(false),
@ -29,7 +29,8 @@ DepthBuffer::DepthBuffer() : m_address(0), m_width(0), m_uly(0), m_lry(0),
}
DepthBuffer::DepthBuffer(DepthBuffer && _other) :
m_address(_other.m_address), m_width(_other.m_width), m_uly(_other.m_uly), m_lry(_other.m_lry),
m_address(_other.m_address), m_width(_other.m_width),
m_ulx(_other.m_ulx), m_uly(_other.m_uly), m_lrx(_other.m_lrx), m_lry(_other.m_lry),
m_depthImageFBO(_other.m_depthImageFBO), m_pDepthImageTexture(_other.m_pDepthImageTexture), m_pDepthBufferTexture(_other.m_pDepthBufferTexture),
m_depthRenderbuffer(_other.m_depthRenderbuffer), m_depthRenderbufferWidth(_other.m_depthRenderbufferWidth),
m_cleared(_other.m_cleared), m_pResolveDepthBufferTexture(_other.m_pResolveDepthBufferTexture), m_resolved(_other.m_resolved),
@ -102,7 +103,7 @@ void DepthBuffer::initDepthImageTexture(FrameBuffer * _pBuffer)
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _pBuffer->m_FBO);
depthBufferList().clearBuffer(0, VI.height);
depthBufferList().clearBuffer(0, 0, VI.width, VI.height);
#endif // GL_IMAGE_TEXTURES_SUPPORT
}
@ -409,12 +410,14 @@ void DepthBufferList::saveBuffer(u32 _address)
}
void DepthBufferList::clearBuffer(u32 _uly, u32 _lry)
void DepthBufferList::clearBuffer(u32 _ulx, u32 _uly, u32 _lrx, u32 _lry)
{
if (m_pCurrent == nullptr)
return;
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;
#ifdef GL_IMAGE_TEXTURES_SUPPORT
if (m_pCurrent->m_depthImageFBO == 0 || !video().getRender().isImageTexturesSupported() || config.frameBufferEmulation.N64DepthCompare == 0)
@ -424,7 +427,7 @@ void DepthBufferList::clearBuffer(u32 _uly, u32 _lry)
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_pCurrent->m_depthImageFBO);
const u32 cycleType = gDP.otherMode.cycleType;
gDP.otherMode.cycleType = G_CYC_FILL;
video().getRender().drawRect(0,0,VI.width, VI.height, color);
video().getRender().drawRect(_ulx, _uly, _lrx, _lry, color);
gDP.otherMode.cycleType = cycleType;
glBindImageTexture(depthImageUnit, m_pCurrent->m_pDepthImageTexture->glName, 0, GL_FALSE, 0, GL_READ_WRITE, fboFormats.depthImageInternalFormat);
frameBufferList().setCurrentDrawBuffer();

View File

@ -21,7 +21,7 @@ struct DepthBuffer
void bindDepthImageTexture();
u32 m_address, m_width;
u32 m_uly, m_lry; // Top and bottom bounds of fillrect command.
u32 m_ulx, m_uly, m_lrx, m_lry; // Parameters of fillrect command.
GLuint m_depthImageFBO;
CachedTexture *m_pDepthImageTexture;
CachedTexture *m_pDepthBufferTexture;
@ -49,7 +49,7 @@ public:
void destroy();
void saveBuffer(u32 _address);
void removeBuffer(u32 _address);
void clearBuffer(u32 _uly, u32 _lry);
void clearBuffer(u32 _ulx, u32 _uly, u32 _lrx, u32 _lry);
void setNotCleared();
DepthBuffer *findBuffer(u32 _address);
DepthBuffer * getCurrent() const {return m_pCurrent;}

View File

@ -553,7 +553,11 @@ void FrameBufferList::saveBuffer(u32 _address, u16 _format, u16 _size, u16 _widt
}
OGLVideo & ogl = video();
bool bPrevIsDepth = false;
if (m_pCurrent != nullptr) {
bPrevIsDepth = m_pCurrent->m_isDepthBuffer;
// Correct buffer's end address
if (!m_pCurrent->isAuxiliary()) {
if (gDP.colorImage.height > 200)
@ -639,8 +643,12 @@ void FrameBufferList::saveBuffer(u32 _address, u16 _format, u16 _size, u16 _widt
);
#endif
if (m_pCurrent->isAuxiliary())
ogl.getRender().clearDepthBuffer(0, 0);
if (m_pCurrent->isAuxiliary() && m_pCurrent->m_pDepthBuffer != nullptr && bPrevIsDepth) {
// 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;
ogl.getRender().clearDepthBuffer(pDepth->m_ulx, pDepth->m_uly, pDepth->m_lrx, pDepth->m_lry);
}
m_pCurrent->m_isDepthBuffer = _address == gDP.depthImageAddress;
m_pCurrent->m_isPauseScreen = m_pCurrent->m_isOBScreen = false;

View File

@ -1853,12 +1853,12 @@ void OGLRender::drawText(const char *_pText, float x, float y)
TextDrawer::get().renderText(_pText, x, y);
}
void OGLRender::clearDepthBuffer(u32 _uly, u32 _lry)
void OGLRender::clearDepthBuffer(u32 _ulx, u32 _uly, u32 _lrx, u32 _lry)
{
if (!_canDraw())
return;
depthBufferList().clearBuffer(_uly, _lry);
depthBufferList().clearBuffer(_ulx, _uly, _lrx, _lry);
glDisable( GL_SCISSOR_TEST );

View File

@ -135,7 +135,7 @@ public:
GLint _dstX0, GLint _dstY0, GLint _dstX1, GLint _dstY1,
GLuint _dstWidth, GLuint _dstHeight, GLenum _filter);
void drawText(const char *_pText, float x, float y);
void clearDepthBuffer(u32 _uly, u32 _lry);
void clearDepthBuffer(u32 _ulx, u32 _uly, u32 _lrx, u32 _lry);
void clearColorBuffer( float * _pColor );
int getTrianglesCount() const {return triangles.num;}

View File

@ -770,21 +770,23 @@ void gDPFillRectangle( s32 ulx, s32 uly, s32 lrx, s32 lry )
// Game may use depth texture as auxilary color texture. Example: Mario Tennis
// If color is not depth clear color, that is most likely the case
if (gDP.fillColor.color == DepthClearColor) {
gDPFillRDRAM(gDP.colorImage.address, ulx, uly, lrx, lry, gDP.colorImage.width, gDP.colorImage.size, gDP.fillColor.color);
if (config.generalEmulation.enableFragmentDepthWrite == 0 ||
(ulx == 0 && uly == 0 && lrx == gDP.scissor.lrx && lry == gDP.scissor.lry)) {
gDPFillRDRAM(gDP.colorImage.address, ulx, uly, lrx, lry, gDP.colorImage.width, gDP.colorImage.size, gDP.fillColor.color);
render.clearDepthBuffer(uly, lry);
render.clearDepthBuffer(ulx, uly, lrx, lry);
bBufferCleared = true;
}
} else
depthBufferList().clearBuffer(ulx, uly, lrx, lry);
}
} else if (gDP.fillColor.color == DepthClearColor && gDP.otherMode.cycleType == G_CYC_FILL) {
depthBufferList().saveBuffer(gDP.colorImage.address);
gDPFillRDRAM(gDP.colorImage.address, ulx, uly, lrx, lry, gDP.colorImage.width, gDP.colorImage.size, gDP.fillColor.color);
if (config.generalEmulation.enableFragmentDepthWrite == 0 ||
(ulx == 0 && uly == 0 && lrx == gDP.scissor.lrx && lry == gDP.scissor.lry)) {
gDPFillRDRAM(gDP.colorImage.address, ulx, uly, lrx, lry, gDP.colorImage.width, gDP.colorImage.size, gDP.fillColor.color);
render.clearDepthBuffer(uly, lry);
render.clearDepthBuffer(ulx, uly, lrx, lry);
bBufferCleared = true;
}
} else
depthBufferList().clearBuffer(ulx, uly, lrx, lry);
}
if (!bBufferCleared) {