mirror of
https://github.com/blawar/GLideN64.git
synced 2024-07-04 10:03:36 +00:00
Fix depth buffer clear for aux buffers.
This commit is contained in:
parent
21ef068f2a
commit
32172d30af
|
@ -17,7 +17,7 @@ const GLuint ZlutImageUnit = 0;
|
||||||
const GLuint TlutImageUnit = 1;
|
const GLuint TlutImageUnit = 1;
|
||||||
const GLuint depthImageUnit = 2;
|
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_depthImageFBO(0), m_pDepthImageTexture(nullptr), m_pDepthBufferTexture(nullptr),
|
||||||
m_depthRenderbuffer(0), m_depthRenderbufferWidth(0),
|
m_depthRenderbuffer(0), m_depthRenderbufferWidth(0),
|
||||||
m_cleared(false), m_pResolveDepthBufferTexture(nullptr), m_resolved(false),
|
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) :
|
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_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_depthRenderbuffer(_other.m_depthRenderbuffer), m_depthRenderbufferWidth(_other.m_depthRenderbufferWidth),
|
||||||
m_cleared(_other.m_cleared), m_pResolveDepthBufferTexture(_other.m_pResolveDepthBufferTexture), m_resolved(_other.m_resolved),
|
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, 0);
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _pBuffer->m_FBO);
|
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
|
#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)
|
if (m_pCurrent == nullptr)
|
||||||
return;
|
return;
|
||||||
m_pCurrent->m_cleared = true;
|
m_pCurrent->m_cleared = true;
|
||||||
|
m_pCurrent->m_ulx = _ulx;
|
||||||
m_pCurrent->m_uly = _uly;
|
m_pCurrent->m_uly = _uly;
|
||||||
|
m_pCurrent->m_lrx = _lrx;
|
||||||
m_pCurrent->m_lry = _lry;
|
m_pCurrent->m_lry = _lry;
|
||||||
#ifdef GL_IMAGE_TEXTURES_SUPPORT
|
#ifdef GL_IMAGE_TEXTURES_SUPPORT
|
||||||
if (m_pCurrent->m_depthImageFBO == 0 || !video().getRender().isImageTexturesSupported() || config.frameBufferEmulation.N64DepthCompare == 0)
|
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);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_pCurrent->m_depthImageFBO);
|
||||||
const u32 cycleType = gDP.otherMode.cycleType;
|
const u32 cycleType = gDP.otherMode.cycleType;
|
||||||
gDP.otherMode.cycleType = G_CYC_FILL;
|
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;
|
gDP.otherMode.cycleType = cycleType;
|
||||||
glBindImageTexture(depthImageUnit, m_pCurrent->m_pDepthImageTexture->glName, 0, GL_FALSE, 0, GL_READ_WRITE, fboFormats.depthImageInternalFormat);
|
glBindImageTexture(depthImageUnit, m_pCurrent->m_pDepthImageTexture->glName, 0, GL_FALSE, 0, GL_READ_WRITE, fboFormats.depthImageInternalFormat);
|
||||||
frameBufferList().setCurrentDrawBuffer();
|
frameBufferList().setCurrentDrawBuffer();
|
||||||
|
|
|
@ -21,7 +21,7 @@ struct DepthBuffer
|
||||||
void bindDepthImageTexture();
|
void bindDepthImageTexture();
|
||||||
|
|
||||||
u32 m_address, m_width;
|
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;
|
GLuint m_depthImageFBO;
|
||||||
CachedTexture *m_pDepthImageTexture;
|
CachedTexture *m_pDepthImageTexture;
|
||||||
CachedTexture *m_pDepthBufferTexture;
|
CachedTexture *m_pDepthBufferTexture;
|
||||||
|
@ -49,7 +49,7 @@ public:
|
||||||
void destroy();
|
void destroy();
|
||||||
void saveBuffer(u32 _address);
|
void saveBuffer(u32 _address);
|
||||||
void removeBuffer(u32 _address);
|
void removeBuffer(u32 _address);
|
||||||
void clearBuffer(u32 _uly, u32 _lry);
|
void clearBuffer(u32 _ulx, u32 _uly, u32 _lrx, u32 _lry);
|
||||||
void setNotCleared();
|
void setNotCleared();
|
||||||
DepthBuffer *findBuffer(u32 _address);
|
DepthBuffer *findBuffer(u32 _address);
|
||||||
DepthBuffer * getCurrent() const {return m_pCurrent;}
|
DepthBuffer * getCurrent() const {return m_pCurrent;}
|
||||||
|
|
|
@ -553,7 +553,11 @@ void FrameBufferList::saveBuffer(u32 _address, u16 _format, u16 _size, u16 _widt
|
||||||
}
|
}
|
||||||
|
|
||||||
OGLVideo & ogl = video();
|
OGLVideo & ogl = video();
|
||||||
|
bool bPrevIsDepth = false;
|
||||||
|
|
||||||
if (m_pCurrent != nullptr) {
|
if (m_pCurrent != nullptr) {
|
||||||
|
bPrevIsDepth = m_pCurrent->m_isDepthBuffer;
|
||||||
|
|
||||||
// Correct buffer's end address
|
// Correct buffer's end address
|
||||||
if (!m_pCurrent->isAuxiliary()) {
|
if (!m_pCurrent->isAuxiliary()) {
|
||||||
if (gDP.colorImage.height > 200)
|
if (gDP.colorImage.height > 200)
|
||||||
|
@ -639,8 +643,12 @@ void FrameBufferList::saveBuffer(u32 _address, u16 _format, u16 _size, u16 _widt
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (m_pCurrent->isAuxiliary())
|
if (m_pCurrent->isAuxiliary() && m_pCurrent->m_pDepthBuffer != nullptr && bPrevIsDepth) {
|
||||||
ogl.getRender().clearDepthBuffer(0, 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;
|
||||||
|
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_isDepthBuffer = _address == gDP.depthImageAddress;
|
||||||
m_pCurrent->m_isPauseScreen = m_pCurrent->m_isOBScreen = false;
|
m_pCurrent->m_isPauseScreen = m_pCurrent->m_isOBScreen = false;
|
||||||
|
|
|
@ -1853,12 +1853,12 @@ void OGLRender::drawText(const char *_pText, float x, float y)
|
||||||
TextDrawer::get().renderText(_pText, x, 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())
|
if (!_canDraw())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
depthBufferList().clearBuffer(_uly, _lry);
|
depthBufferList().clearBuffer(_ulx, _uly, _lrx, _lry);
|
||||||
|
|
||||||
glDisable( GL_SCISSOR_TEST );
|
glDisable( GL_SCISSOR_TEST );
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ public:
|
||||||
GLint _dstX0, GLint _dstY0, GLint _dstX1, GLint _dstY1,
|
GLint _dstX0, GLint _dstY0, GLint _dstX1, GLint _dstY1,
|
||||||
GLuint _dstWidth, GLuint _dstHeight, GLenum _filter);
|
GLuint _dstWidth, GLuint _dstHeight, GLenum _filter);
|
||||||
void drawText(const char *_pText, float x, float y);
|
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 );
|
void clearColorBuffer( float * _pColor );
|
||||||
|
|
||||||
int getTrianglesCount() const {return triangles.num;}
|
int getTrianglesCount() const {return triangles.num;}
|
||||||
|
|
14
src/gDP.cpp
14
src/gDP.cpp
|
@ -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
|
// 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 color is not depth clear color, that is most likely the case
|
||||||
if (gDP.fillColor.color == DepthClearColor) {
|
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 ||
|
if (config.generalEmulation.enableFragmentDepthWrite == 0 ||
|
||||||
(ulx == 0 && uly == 0 && lrx == gDP.scissor.lrx && lry == gDP.scissor.lry)) {
|
(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(ulx, uly, lrx, lry);
|
||||||
render.clearDepthBuffer(uly, lry);
|
|
||||||
bBufferCleared = true;
|
bBufferCleared = true;
|
||||||
}
|
} else
|
||||||
|
depthBufferList().clearBuffer(ulx, uly, lrx, lry);
|
||||||
}
|
}
|
||||||
} else if (gDP.fillColor.color == DepthClearColor && gDP.otherMode.cycleType == G_CYC_FILL) {
|
} else if (gDP.fillColor.color == DepthClearColor && gDP.otherMode.cycleType == G_CYC_FILL) {
|
||||||
depthBufferList().saveBuffer(gDP.colorImage.address);
|
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 ||
|
if (config.generalEmulation.enableFragmentDepthWrite == 0 ||
|
||||||
(ulx == 0 && uly == 0 && lrx == gDP.scissor.lrx && lry == gDP.scissor.lry)) {
|
(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(ulx, uly, lrx, lry);
|
||||||
render.clearDepthBuffer(uly, lry);
|
|
||||||
bBufferCleared = true;
|
bBufferCleared = true;
|
||||||
}
|
} else
|
||||||
|
depthBufferList().clearBuffer(ulx, uly, lrx, lry);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bBufferCleared) {
|
if (!bBufferCleared) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user