2014-10-13 12:38:51 +00:00
|
|
|
#ifdef OS_MAC_OS_X
|
|
|
|
#include <malloc/malloc.h>
|
|
|
|
#else
|
2013-04-05 06:13:26 +00:00
|
|
|
#include <malloc.h>
|
2014-10-13 12:38:51 +00:00
|
|
|
#endif
|
2013-06-04 16:00:03 +00:00
|
|
|
#include <assert.h>
|
2013-12-14 14:30:20 +00:00
|
|
|
#include "Combiner.h"
|
2013-06-01 13:10:30 +00:00
|
|
|
#include "FrameBuffer.h"
|
2013-04-05 06:13:26 +00:00
|
|
|
#include "DepthBuffer.h"
|
2013-06-04 16:00:03 +00:00
|
|
|
#include "VI.h"
|
2014-04-05 02:57:00 +00:00
|
|
|
#include "Config.h"
|
2013-06-01 13:10:30 +00:00
|
|
|
#include "Debug.h"
|
2017-01-01 13:56:13 +00:00
|
|
|
#include <Graphics/Context.h>
|
|
|
|
#include <Graphics/Parameters.h>
|
2017-01-15 07:57:25 +00:00
|
|
|
#include "DisplayWindow.h"
|
2013-04-05 06:13:26 +00:00
|
|
|
|
2017-01-15 07:57:25 +00:00
|
|
|
using namespace graphics;
|
|
|
|
|
2016-09-11 11:08:03 +00:00
|
|
|
DepthBuffer::DepthBuffer() : m_address(0), m_width(0), m_ulx(0), m_uly(0), m_lrx(0), m_lry(0),
|
2017-01-21 11:55:14 +00:00
|
|
|
m_pDepthImageTexture(nullptr), m_pDepthBufferTexture(nullptr), m_depthRenderbufferWidth(0),
|
2016-06-10 06:06:06 +00:00
|
|
|
m_cleared(false), m_pResolveDepthBufferTexture(nullptr), m_resolved(false),
|
|
|
|
m_pDepthBufferCopyTexture(nullptr), m_copied(false)
|
2013-04-05 06:13:26 +00:00
|
|
|
{
|
2017-01-21 11:55:14 +00:00
|
|
|
m_copyFBO = gfxContext.createFramebuffer();
|
2017-02-08 20:21:02 +00:00
|
|
|
if (config.frameBufferEmulation.N64DepthCompare != 0)
|
2017-01-21 11:55:14 +00:00
|
|
|
m_depthImageFBO = gfxContext.createFramebuffer();
|
2013-04-05 06:13:26 +00:00
|
|
|
}
|
|
|
|
|
2014-09-08 11:00:13 +00:00
|
|
|
DepthBuffer::DepthBuffer(DepthBuffer && _other) :
|
2016-09-11 11:08:03 +00:00
|
|
|
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),
|
2016-05-08 11:25:22 +00:00
|
|
|
m_depthImageFBO(_other.m_depthImageFBO), m_pDepthImageTexture(_other.m_pDepthImageTexture), m_pDepthBufferTexture(_other.m_pDepthBufferTexture),
|
2016-06-21 18:57:18 +00:00
|
|
|
m_depthRenderbuffer(_other.m_depthRenderbuffer), m_depthRenderbufferWidth(_other.m_depthRenderbufferWidth),
|
2016-05-08 11:25:22 +00:00
|
|
|
m_cleared(_other.m_cleared), m_pResolveDepthBufferTexture(_other.m_pResolveDepthBufferTexture), m_resolved(_other.m_resolved),
|
2016-11-03 05:53:26 +00:00
|
|
|
m_pDepthBufferCopyTexture(_other.m_pDepthBufferCopyTexture), m_copied(_other.m_copied)
|
2013-04-05 06:13:26 +00:00
|
|
|
{
|
2017-01-21 11:55:14 +00:00
|
|
|
_other.m_depthImageFBO = ObjectHandle();
|
2016-06-10 06:06:06 +00:00
|
|
|
_other.m_pDepthImageTexture = nullptr;
|
|
|
|
_other.m_pDepthBufferTexture = nullptr;
|
2017-01-21 11:55:14 +00:00
|
|
|
_other.m_depthRenderbuffer = ObjectHandle();
|
2016-06-10 06:06:06 +00:00
|
|
|
_other.m_pResolveDepthBufferTexture = nullptr;
|
2015-02-13 12:06:59 +00:00
|
|
|
_other.m_resolved = false;
|
2016-06-10 06:06:06 +00:00
|
|
|
_other.m_pDepthBufferCopyTexture = nullptr;
|
2016-05-08 11:25:22 +00:00
|
|
|
_other.m_copied = false;
|
2013-04-05 06:13:26 +00:00
|
|
|
}
|
|
|
|
|
2014-09-08 11:00:13 +00:00
|
|
|
DepthBuffer::~DepthBuffer()
|
2013-04-05 06:13:26 +00:00
|
|
|
{
|
2017-01-21 11:55:14 +00:00
|
|
|
gfxContext.deleteFramebuffer(m_depthImageFBO);
|
|
|
|
gfxContext.deleteFramebuffer(m_depthRenderbuffer);
|
|
|
|
gfxContext.deleteFramebuffer(m_copyFBO);
|
2017-01-02 14:00:49 +00:00
|
|
|
|
|
|
|
textureCache().removeFrameBufferTexture(m_pDepthImageTexture);
|
|
|
|
textureCache().removeFrameBufferTexture(m_pDepthBufferTexture);
|
|
|
|
textureCache().removeFrameBufferTexture(m_pResolveDepthBufferTexture);
|
|
|
|
textureCache().removeFrameBufferTexture(m_pDepthBufferCopyTexture);
|
2013-04-05 06:13:26 +00:00
|
|
|
}
|
|
|
|
|
2015-01-27 16:00:06 +00:00
|
|
|
void DepthBuffer::initDepthImageTexture(FrameBuffer * _pBuffer)
|
2013-04-05 06:13:26 +00:00
|
|
|
{
|
2017-02-08 20:21:02 +00:00
|
|
|
if (config.frameBufferEmulation.N64DepthCompare == 0 || m_pDepthImageTexture != nullptr)
|
2015-01-27 16:00:06 +00:00
|
|
|
return;
|
|
|
|
|
2017-01-21 11:55:14 +00:00
|
|
|
const FramebufferTextureFormats & fbTexFormat = gfxContext.getFramebufferTextureFormats();
|
2017-01-01 14:59:54 +00:00
|
|
|
m_pDepthImageTexture = textureCache().addFrameBufferTexture(false);
|
2015-01-27 16:00:06 +00:00
|
|
|
|
|
|
|
m_pDepthImageTexture->width = (u32)(_pBuffer->m_pTexture->width);
|
|
|
|
m_pDepthImageTexture->height = (u32)(_pBuffer->m_pTexture->height);
|
|
|
|
m_pDepthImageTexture->format = 0;
|
|
|
|
m_pDepthImageTexture->size = 2;
|
|
|
|
m_pDepthImageTexture->clampS = 1;
|
|
|
|
m_pDepthImageTexture->clampT = 1;
|
|
|
|
m_pDepthImageTexture->address = _pBuffer->m_startAddress;
|
|
|
|
m_pDepthImageTexture->clampWidth = _pBuffer->m_width;
|
|
|
|
m_pDepthImageTexture->clampHeight = _pBuffer->m_height;
|
2015-05-06 13:47:12 +00:00
|
|
|
m_pDepthImageTexture->frameBufferTexture = CachedTexture::fbOneSample;
|
2015-01-27 16:00:06 +00:00
|
|
|
m_pDepthImageTexture->maskS = 0;
|
|
|
|
m_pDepthImageTexture->maskT = 0;
|
|
|
|
m_pDepthImageTexture->mirrorS = 0;
|
|
|
|
m_pDepthImageTexture->mirrorT = 0;
|
|
|
|
m_pDepthImageTexture->realWidth = m_pDepthImageTexture->width;
|
|
|
|
m_pDepthImageTexture->realHeight = m_pDepthImageTexture->height;
|
2017-01-14 12:26:02 +00:00
|
|
|
m_pDepthImageTexture->textureBytes = m_pDepthImageTexture->realWidth * m_pDepthImageTexture->realHeight * fbTexFormat.depthImageFormatBytes;
|
2015-01-27 16:00:06 +00:00
|
|
|
textureCache().addFrameBufferTextureSize(m_pDepthImageTexture->textureBytes);
|
|
|
|
|
2017-01-01 13:56:13 +00:00
|
|
|
{
|
2017-01-21 11:55:14 +00:00
|
|
|
Context::InitTextureParams params;
|
2017-01-21 12:48:02 +00:00
|
|
|
params.handle = m_pDepthImageTexture->name;
|
2017-01-01 13:56:13 +00:00
|
|
|
params.width = m_pDepthImageTexture->realWidth;
|
|
|
|
params.height = m_pDepthImageTexture->realHeight;
|
2017-01-14 12:26:02 +00:00
|
|
|
params.internalFormat = fbTexFormat.depthImageInternalFormat;
|
|
|
|
params.format = fbTexFormat.depthImageFormat;
|
|
|
|
params.dataType = fbTexFormat.depthImageType;
|
2017-01-01 13:56:13 +00:00
|
|
|
gfxContext.init2DTexture(params);
|
|
|
|
}
|
|
|
|
{
|
2017-01-21 11:55:14 +00:00
|
|
|
Context::TexParameters params;
|
2017-01-21 12:48:02 +00:00
|
|
|
params.handle =m_pDepthImageTexture->name;
|
2017-01-28 09:52:09 +00:00
|
|
|
params.target = textureTarget::TEXTURE_2D;
|
2017-01-21 11:55:14 +00:00
|
|
|
params.textureUnitIndex = textureIndices::Tex[0];
|
|
|
|
params.minFilter = textureParameters::FILTER_NEAREST;
|
|
|
|
params.magFilter = textureParameters::FILTER_NEAREST;
|
2017-01-01 13:56:13 +00:00
|
|
|
gfxContext.setTextureParameters(params);
|
|
|
|
}
|
2017-01-02 15:40:41 +00:00
|
|
|
{
|
2017-01-21 11:55:14 +00:00
|
|
|
Context::FrameBufferRenderTarget bufTarget;
|
|
|
|
bufTarget.bufferHandle = m_depthImageFBO;
|
|
|
|
bufTarget.bufferTarget = bufferTarget::DRAW_FRAMEBUFFER;
|
|
|
|
bufTarget.attachment = bufferAttachment::COLOR_ATTACHMENT0;
|
2017-01-28 09:52:09 +00:00
|
|
|
bufTarget.textureTarget = textureTarget::TEXTURE_2D;
|
2017-01-21 12:48:02 +00:00
|
|
|
bufTarget.textureHandle = m_pDepthImageTexture->name;
|
2017-01-02 15:40:41 +00:00
|
|
|
gfxContext.addFrameBufferRenderTarget(bufTarget);
|
|
|
|
}
|
2015-01-27 16:00:06 +00:00
|
|
|
|
2017-01-21 11:55:14 +00:00
|
|
|
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, _pBuffer->m_FBO);
|
2017-01-02 15:40:41 +00:00
|
|
|
|
2016-09-11 11:08:03 +00:00
|
|
|
depthBufferList().clearBuffer(0, 0, VI.width, VI.height);
|
2013-04-05 06:13:26 +00:00
|
|
|
}
|
|
|
|
|
2015-02-13 12:06:59 +00:00
|
|
|
void DepthBuffer::_initDepthBufferTexture(FrameBuffer * _pBuffer, CachedTexture * _pTexture, bool _multisample)
|
2015-01-27 16:00:06 +00:00
|
|
|
{
|
2017-01-21 11:55:14 +00:00
|
|
|
const FramebufferTextureFormats & fbTexFormat = gfxContext.getFramebufferTextureFormats();
|
2017-01-14 12:26:02 +00:00
|
|
|
|
2016-06-10 06:06:06 +00:00
|
|
|
if (_pBuffer != nullptr) {
|
2015-02-13 12:06:59 +00:00
|
|
|
_pTexture->width = (u32)(_pBuffer->m_pTexture->width);
|
|
|
|
_pTexture->height = (u32)(_pBuffer->m_pTexture->height);
|
|
|
|
_pTexture->address = _pBuffer->m_startAddress;
|
|
|
|
_pTexture->clampWidth = _pBuffer->m_width;
|
|
|
|
_pTexture->clampHeight = _pBuffer->m_height;
|
2017-01-14 12:26:02 +00:00
|
|
|
} else {
|
2016-02-09 17:33:31 +00:00
|
|
|
if (config.frameBufferEmulation.nativeResFactor == 0) {
|
2017-01-15 07:57:25 +00:00
|
|
|
_pTexture->width = dwnd().getWidth();
|
|
|
|
_pTexture->height = dwnd().getHeight();
|
2016-02-09 17:33:31 +00:00
|
|
|
} else {
|
|
|
|
_pTexture->width = VI.width * config.frameBufferEmulation.nativeResFactor;
|
|
|
|
_pTexture->height = VI.height * config.frameBufferEmulation.nativeResFactor;
|
|
|
|
}
|
2015-04-08 17:06:17 +00:00
|
|
|
_pTexture->address = gDP.depthImageAddress;
|
2015-02-13 12:06:59 +00:00
|
|
|
_pTexture->clampWidth = VI.width;
|
|
|
|
_pTexture->clampHeight = VI.height;
|
2015-01-27 16:00:06 +00:00
|
|
|
}
|
2015-02-13 12:06:59 +00:00
|
|
|
_pTexture->format = 0;
|
|
|
|
_pTexture->size = 2;
|
|
|
|
_pTexture->clampS = 1;
|
|
|
|
_pTexture->clampT = 1;
|
2015-05-06 13:47:12 +00:00
|
|
|
_pTexture->frameBufferTexture = CachedTexture::fbOneSample;
|
2015-02-13 12:06:59 +00:00
|
|
|
_pTexture->maskS = 0;
|
|
|
|
_pTexture->maskT = 0;
|
|
|
|
_pTexture->mirrorS = 0;
|
|
|
|
_pTexture->mirrorT = 0;
|
|
|
|
_pTexture->realWidth = _pTexture->width;
|
|
|
|
_pTexture->realHeight = _pTexture->height;
|
2017-01-14 12:26:02 +00:00
|
|
|
_pTexture->textureBytes = _pTexture->realWidth * _pTexture->realHeight * fbTexFormat.depthFormatBytes;
|
2015-02-13 12:06:59 +00:00
|
|
|
textureCache().addFrameBufferTextureSize(_pTexture->textureBytes);
|
2015-01-27 16:00:06 +00:00
|
|
|
|
2017-02-12 09:10:58 +00:00
|
|
|
Context::InitTextureParams initParams;
|
|
|
|
initParams.handle = _pTexture->name;
|
|
|
|
initParams.msaaLevel = _multisample ? config.video.multisampling : 0U;
|
|
|
|
initParams.width = _pTexture->realWidth;
|
|
|
|
initParams.height = _pTexture->realHeight;
|
|
|
|
initParams.internalFormat = fbTexFormat.depthInternalFormat;
|
|
|
|
initParams.format = fbTexFormat.depthFormat;
|
|
|
|
initParams.dataType = fbTexFormat.depthType;
|
|
|
|
gfxContext.init2DTexture(initParams);
|
|
|
|
|
2017-02-12 09:05:02 +00:00
|
|
|
if (!_multisample) {
|
2017-02-12 09:10:58 +00:00
|
|
|
_pTexture->frameBufferTexture = CachedTexture::fbOneSample;
|
|
|
|
Context::TexParameters texParams;
|
|
|
|
texParams.handle = _pTexture->name;
|
|
|
|
texParams.target = textureTarget::TEXTURE_2D;
|
|
|
|
texParams.textureUnitIndex = textureIndices::Tex[0];
|
|
|
|
texParams.minFilter = textureParameters::FILTER_NEAREST;
|
|
|
|
texParams.magFilter = textureParameters::FILTER_NEAREST;
|
|
|
|
gfxContext.setTextureParameters(texParams);
|
|
|
|
} else {
|
|
|
|
_pTexture->frameBufferTexture = CachedTexture::fbMultiSample;
|
2017-01-01 13:56:13 +00:00
|
|
|
}
|
2015-01-27 16:00:06 +00:00
|
|
|
}
|
|
|
|
|
2016-06-21 18:57:18 +00:00
|
|
|
void DepthBuffer::_initDepthBufferRenderbuffer(FrameBuffer * _pBuffer)
|
|
|
|
{
|
2017-01-21 11:55:14 +00:00
|
|
|
if (m_depthRenderbuffer.isNotNull())
|
2016-06-21 18:57:18 +00:00
|
|
|
return;
|
|
|
|
u32 height;
|
|
|
|
if (_pBuffer != NULL) {
|
|
|
|
m_depthRenderbufferWidth = (u32)(_pBuffer->m_pTexture->width);
|
|
|
|
height = (u32)(_pBuffer->m_pTexture->height);
|
|
|
|
} else {
|
|
|
|
if (config.frameBufferEmulation.nativeResFactor == 0) {
|
2017-01-15 07:57:25 +00:00
|
|
|
m_depthRenderbufferWidth = dwnd().getWidth();
|
|
|
|
height = dwnd().getHeight();
|
2016-06-21 18:57:18 +00:00
|
|
|
} else {
|
|
|
|
m_depthRenderbufferWidth = VI.width * config.frameBufferEmulation.nativeResFactor;
|
|
|
|
height = VI.height * config.frameBufferEmulation.nativeResFactor;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-21 11:55:14 +00:00
|
|
|
m_depthRenderbuffer = gfxContext.createRenderbuffer();
|
|
|
|
Context::InitRenderbufferParams params;
|
|
|
|
params.handle = m_depthRenderbuffer;
|
2017-01-28 09:52:09 +00:00
|
|
|
params.target = textureTarget::RENDERBUFFER;
|
2017-01-14 12:26:02 +00:00
|
|
|
params.format = gfxContext.getFramebufferTextureFormats().depthInternalFormat;
|
2017-01-02 15:40:41 +00:00
|
|
|
params.width = m_depthRenderbufferWidth;
|
|
|
|
params.height = height;
|
|
|
|
gfxContext.initRenderbuffer(params);
|
2016-06-21 18:57:18 +00:00
|
|
|
}
|
|
|
|
|
2017-01-28 09:52:09 +00:00
|
|
|
void DepthBuffer::setDepthAttachment(ObjectHandle _fbo, BufferTargetParam _target)
|
2015-02-13 12:06:59 +00:00
|
|
|
{
|
2017-01-21 11:55:14 +00:00
|
|
|
Context::FrameBufferRenderTarget params;
|
|
|
|
params.attachment = bufferAttachment::DEPTH_ATTACHMENT;
|
|
|
|
params.bufferHandle = _fbo;
|
2017-01-02 15:40:41 +00:00
|
|
|
params.bufferTarget = _target;
|
2017-01-21 11:55:14 +00:00
|
|
|
if (gfxContext.isSupported(SpecialFeatures::DepthFramebufferTextures)) {
|
2017-01-21 12:48:02 +00:00
|
|
|
params.textureHandle = m_pDepthBufferTexture->name;
|
2017-01-28 09:52:09 +00:00
|
|
|
params.textureTarget = config.video.multisampling != 0 ? textureTarget::TEXTURE_2D_MULTISAMPLE : textureTarget::TEXTURE_2D;
|
2017-01-21 11:55:14 +00:00
|
|
|
} else {
|
|
|
|
params.textureHandle = m_depthRenderbuffer;
|
2017-01-28 09:52:09 +00:00
|
|
|
params.textureTarget = textureTarget::RENDERBUFFER;
|
2017-01-21 11:55:14 +00:00
|
|
|
}
|
2017-01-02 15:40:41 +00:00
|
|
|
gfxContext.addFrameBufferRenderTarget(params);
|
|
|
|
|
2016-05-08 11:25:22 +00:00
|
|
|
m_copied = false;
|
2015-02-13 12:06:59 +00:00
|
|
|
m_resolved = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DepthBuffer::initDepthBufferTexture(FrameBuffer * _pBuffer)
|
|
|
|
{
|
2017-01-21 11:55:14 +00:00
|
|
|
if (gfxContext.isSupported(SpecialFeatures::DepthFramebufferTextures)) {
|
|
|
|
if (m_pDepthBufferTexture == nullptr) {
|
|
|
|
m_pDepthBufferTexture = textureCache().addFrameBufferTexture(config.video.multisampling != 0);
|
|
|
|
_initDepthBufferTexture(_pBuffer, m_pDepthBufferTexture, config.video.multisampling != 0);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
_initDepthBufferRenderbuffer(_pBuffer);
|
2015-02-13 12:06:59 +00:00
|
|
|
}
|
|
|
|
|
2016-06-10 06:06:06 +00:00
|
|
|
if (config.video.multisampling != 0 && m_pResolveDepthBufferTexture == nullptr) {
|
2017-01-01 14:59:54 +00:00
|
|
|
m_pResolveDepthBufferTexture = textureCache().addFrameBufferTexture(false);
|
2015-02-13 12:06:59 +00:00
|
|
|
_initDepthBufferTexture(_pBuffer, m_pResolveDepthBufferTexture, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CachedTexture * DepthBuffer::resolveDepthBufferTexture(FrameBuffer * _pBuffer)
|
|
|
|
{
|
|
|
|
if (config.video.multisampling == 0)
|
|
|
|
return m_pDepthBufferTexture;
|
2017-01-21 11:55:14 +00:00
|
|
|
|
2015-02-13 12:06:59 +00:00
|
|
|
if (m_resolved)
|
|
|
|
return m_pResolveDepthBufferTexture;
|
2017-01-21 11:55:14 +00:00
|
|
|
|
|
|
|
Context::FrameBufferRenderTarget targetParams;
|
|
|
|
targetParams.attachment = bufferAttachment::DEPTH_ATTACHMENT;
|
|
|
|
targetParams.bufferHandle = _pBuffer->m_resolveFBO;
|
|
|
|
targetParams.bufferTarget = bufferTarget::DRAW_FRAMEBUFFER;
|
2017-01-21 12:48:02 +00:00
|
|
|
targetParams.textureHandle = m_pResolveDepthBufferTexture->name;
|
2017-01-28 09:52:09 +00:00
|
|
|
targetParams.textureTarget = textureTarget::TEXTURE_2D;
|
2017-01-21 11:55:14 +00:00
|
|
|
gfxContext.addFrameBufferRenderTarget(targetParams);
|
|
|
|
|
|
|
|
Context::BlitFramebuffersParams blitParams;
|
|
|
|
blitParams.readBuffer = _pBuffer->m_FBO;
|
|
|
|
blitParams.drawBuffer = _pBuffer->m_resolveFBO;
|
|
|
|
blitParams.srcX0 = 0;
|
|
|
|
blitParams.srcY0 = 0;
|
|
|
|
blitParams.srcX1 = m_pDepthBufferTexture->realWidth;
|
|
|
|
blitParams.srcY1 = m_pDepthBufferTexture->realHeight;
|
|
|
|
blitParams.dstX0 = 0;
|
|
|
|
blitParams.dstY0 = 0;
|
|
|
|
blitParams.dstX1 = m_pResolveDepthBufferTexture->realWidth;
|
|
|
|
blitParams.dstY1 = m_pResolveDepthBufferTexture->realHeight;
|
|
|
|
blitParams.mask = blitMask::DEPTH_BUFFER;
|
|
|
|
blitParams.filter = textureParameters::FILTER_NEAREST;
|
|
|
|
|
|
|
|
gfxContext.blitFramebuffers(blitParams);
|
|
|
|
|
|
|
|
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, ObjectHandle());
|
|
|
|
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, _pBuffer->m_FBO);
|
|
|
|
|
2015-02-13 12:06:59 +00:00
|
|
|
m_resolved = true;
|
|
|
|
return m_pResolveDepthBufferTexture;
|
2015-01-27 16:00:06 +00:00
|
|
|
}
|
|
|
|
|
2016-05-08 11:25:22 +00:00
|
|
|
CachedTexture * DepthBuffer::copyDepthBufferTexture(FrameBuffer * _pBuffer)
|
|
|
|
{
|
|
|
|
if (m_copied)
|
|
|
|
return m_pDepthBufferCopyTexture;
|
|
|
|
|
2016-06-10 06:06:06 +00:00
|
|
|
if (m_pDepthBufferCopyTexture == nullptr) {
|
2017-01-01 14:59:54 +00:00
|
|
|
m_pDepthBufferCopyTexture = textureCache().addFrameBufferTexture(false);
|
2016-05-08 11:25:22 +00:00
|
|
|
_initDepthBufferTexture(_pBuffer, m_pDepthBufferCopyTexture, false);
|
|
|
|
}
|
|
|
|
|
2017-01-21 11:55:14 +00:00
|
|
|
|
|
|
|
Context::FrameBufferRenderTarget targetParams;
|
|
|
|
targetParams.bufferHandle = m_copyFBO;
|
|
|
|
targetParams.bufferTarget = bufferTarget::DRAW_FRAMEBUFFER;
|
|
|
|
targetParams.attachment = bufferAttachment::COLOR_ATTACHMENT0;
|
|
|
|
targetParams.textureHandle = _pBuffer->m_pTexture->frameBufferTexture == CachedTexture::fbMultiSample ?
|
2017-01-21 12:48:02 +00:00
|
|
|
_pBuffer->m_pResolveTexture->name :
|
|
|
|
_pBuffer->m_pTexture->name;
|
2017-01-28 09:52:09 +00:00
|
|
|
targetParams.textureTarget = textureTarget::TEXTURE_2D;
|
2017-01-21 11:55:14 +00:00
|
|
|
|
|
|
|
gfxContext.addFrameBufferRenderTarget(targetParams);
|
|
|
|
|
|
|
|
targetParams.attachment = bufferAttachment::DEPTH_ATTACHMENT;
|
2017-01-21 12:48:02 +00:00
|
|
|
targetParams.textureHandle = m_pDepthBufferCopyTexture->name;
|
2017-01-21 11:55:14 +00:00
|
|
|
|
|
|
|
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->realWidth;
|
|
|
|
blitParams.srcY1 = m_pDepthBufferTexture->realHeight;
|
|
|
|
blitParams.dstX0 = 0;
|
|
|
|
blitParams.dstY0 = 0;
|
|
|
|
blitParams.dstX1 = m_pDepthBufferTexture->realWidth;
|
|
|
|
blitParams.dstY1 = m_pDepthBufferTexture->realHeight;
|
|
|
|
blitParams.mask = blitMask::DEPTH_BUFFER;
|
|
|
|
blitParams.filter = textureParameters::FILTER_NEAREST;
|
|
|
|
|
|
|
|
gfxContext.blitFramebuffers(blitParams);
|
|
|
|
|
|
|
|
gfxContext.bindFramebuffer(bufferTarget::READ_FRAMEBUFFER, ObjectHandle());
|
|
|
|
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, _pBuffer->m_FBO);
|
|
|
|
|
2016-05-08 11:25:22 +00:00
|
|
|
m_copied = true;
|
|
|
|
return m_pDepthBufferCopyTexture;
|
|
|
|
}
|
|
|
|
|
2015-02-13 12:06:59 +00:00
|
|
|
void DepthBuffer::activateDepthBufferTexture(FrameBuffer * _pBuffer)
|
|
|
|
{
|
|
|
|
textureCache().activateTexture(0, resolveDepthBufferTexture(_pBuffer));
|
2015-01-27 16:00:06 +00:00
|
|
|
}
|
|
|
|
|
2015-02-13 12:06:59 +00:00
|
|
|
void DepthBuffer::bindDepthImageTexture()
|
|
|
|
{
|
2017-01-21 11:55:14 +00:00
|
|
|
if (!Context::imageTextures)
|
|
|
|
return;
|
|
|
|
|
|
|
|
Context::BindImageTextureParameters bindParams;
|
|
|
|
bindParams.imageUnit = textureImageUnits::Depth;
|
2017-01-21 12:48:02 +00:00
|
|
|
bindParams.texture = m_pDepthImageTexture->name;
|
2017-01-21 11:55:14 +00:00
|
|
|
bindParams.accessMode = textureImageAccessMode::READ_WRITE;
|
|
|
|
bindParams.textureFormat = gfxContext.getFramebufferTextureFormats().depthImageInternalFormat;
|
|
|
|
|
|
|
|
gfxContext.bindImageTexture(bindParams);
|
2015-01-27 16:00:06 +00:00
|
|
|
}
|
|
|
|
|
2016-06-10 06:06:06 +00:00
|
|
|
DepthBufferList::DepthBufferList() : m_pCurrent(nullptr), m_pzLUT(nullptr)
|
2013-04-05 06:13:26 +00:00
|
|
|
{
|
2015-01-27 11:56:22 +00:00
|
|
|
m_pzLUT = new u16[0x40000];
|
|
|
|
for (int i = 0; i<0x40000; i++) {
|
|
|
|
u32 exponent = 0;
|
|
|
|
u32 testbit = 1 << 17;
|
|
|
|
while ((i & testbit) && (exponent < 7)) {
|
|
|
|
exponent++;
|
|
|
|
testbit = 1 << (17 - exponent);
|
|
|
|
}
|
|
|
|
|
|
|
|
const u32 mantissa = (i >> (6 - (6 < exponent ? 6 : exponent))) & 0x7ff;
|
|
|
|
m_pzLUT[i] = (u16)(((exponent << 11) | mantissa) << 2);
|
|
|
|
}
|
2013-04-05 06:13:26 +00:00
|
|
|
}
|
|
|
|
|
2015-03-26 15:24:51 +00:00
|
|
|
DepthBufferList::~DepthBufferList()
|
2013-04-05 06:13:26 +00:00
|
|
|
{
|
2015-01-27 11:56:22 +00:00
|
|
|
delete[] m_pzLUT;
|
2016-06-10 06:06:06 +00:00
|
|
|
m_pzLUT = nullptr;
|
2015-03-26 15:24:51 +00:00
|
|
|
m_list.clear();
|
|
|
|
}
|
|
|
|
|
2015-03-31 12:44:41 +00:00
|
|
|
DepthBufferList & DepthBufferList::get()
|
|
|
|
{
|
|
|
|
static DepthBufferList depthBufferList;
|
|
|
|
return depthBufferList;
|
|
|
|
}
|
|
|
|
|
2015-03-26 15:24:51 +00:00
|
|
|
void DepthBufferList::init()
|
|
|
|
{
|
2016-06-10 06:06:06 +00:00
|
|
|
m_pCurrent = nullptr;
|
2015-03-26 15:24:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void DepthBufferList::destroy()
|
|
|
|
{
|
2016-06-10 06:06:06 +00:00
|
|
|
m_pCurrent = nullptr;
|
2014-09-08 11:00:13 +00:00
|
|
|
m_list.clear();
|
2013-04-05 06:13:26 +00:00
|
|
|
}
|
|
|
|
|
2015-02-17 16:10:44 +00:00
|
|
|
void DepthBufferList::setNotCleared()
|
|
|
|
{
|
|
|
|
for (DepthBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter)
|
|
|
|
iter->m_cleared = false;
|
|
|
|
}
|
|
|
|
|
2014-09-08 11:00:13 +00:00
|
|
|
DepthBuffer * DepthBufferList::findBuffer(u32 _address)
|
2013-04-05 06:13:26 +00:00
|
|
|
{
|
2014-09-08 11:00:13 +00:00
|
|
|
for (DepthBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter)
|
|
|
|
if (iter->m_address == _address)
|
|
|
|
return &(*iter);
|
2016-06-10 06:06:06 +00:00
|
|
|
return nullptr;
|
2014-09-08 11:00:13 +00:00
|
|
|
}
|
2013-04-05 06:13:26 +00:00
|
|
|
|
2014-09-08 11:00:13 +00:00
|
|
|
void DepthBufferList::removeBuffer(u32 _address )
|
|
|
|
{
|
|
|
|
for (DepthBuffers::iterator iter = m_list.begin(); iter != m_list.end(); ++iter)
|
|
|
|
if (iter->m_address == _address) {
|
2016-03-06 15:12:23 +00:00
|
|
|
frameBufferList().clearDepthBuffer(&(*iter));
|
2014-09-08 11:00:13 +00:00
|
|
|
m_list.erase(iter);
|
|
|
|
return;
|
|
|
|
}
|
2013-04-05 06:13:26 +00:00
|
|
|
}
|
|
|
|
|
2014-09-08 11:00:13 +00:00
|
|
|
void DepthBufferList::saveBuffer(u32 _address)
|
2013-04-05 06:13:26 +00:00
|
|
|
{
|
2014-09-08 11:00:13 +00:00
|
|
|
if (!config.frameBufferEmulation.enable)
|
|
|
|
return;
|
|
|
|
|
|
|
|
FrameBuffer * pFrameBuffer = frameBufferList().findBuffer(_address);
|
2016-06-10 06:06:06 +00:00
|
|
|
if (pFrameBuffer != nullptr)
|
2015-02-19 12:50:02 +00:00
|
|
|
pFrameBuffer->m_isDepthBuffer = true;
|
2013-06-02 15:20:44 +00:00
|
|
|
|
2016-09-19 04:50:05 +00:00
|
|
|
DepthBuffer * pDepthBuffer = findBuffer(_address);
|
2014-09-08 11:00:13 +00:00
|
|
|
|
2016-09-19 04:50:05 +00:00
|
|
|
if (pDepthBuffer != nullptr && pFrameBuffer != nullptr && pDepthBuffer->m_width != pFrameBuffer->m_width) {
|
2014-09-08 11:00:13 +00:00
|
|
|
removeBuffer(_address);
|
2016-09-19 04:50:05 +00:00
|
|
|
pDepthBuffer = nullptr;
|
2013-04-05 06:13:26 +00:00
|
|
|
}
|
|
|
|
|
2016-11-02 04:13:50 +00:00
|
|
|
if (pDepthBuffer == nullptr && VI.height != 0) {
|
2014-09-08 11:00:13 +00:00
|
|
|
m_list.emplace_front();
|
|
|
|
DepthBuffer & buffer = m_list.front();
|
2013-06-04 16:00:03 +00:00
|
|
|
|
2014-09-08 11:00:13 +00:00
|
|
|
buffer.m_address = _address;
|
2016-06-10 06:06:06 +00:00
|
|
|
buffer.m_width = pFrameBuffer != nullptr ? pFrameBuffer->m_width : VI.width;
|
2015-01-27 16:00:06 +00:00
|
|
|
|
|
|
|
buffer.initDepthBufferTexture(pFrameBuffer);
|
2014-09-08 11:00:13 +00:00
|
|
|
|
2016-09-19 04:50:05 +00:00
|
|
|
pDepthBuffer = &buffer;
|
2013-06-04 16:00:03 +00:00
|
|
|
}
|
2016-07-23 05:18:27 +00:00
|
|
|
|
2016-11-02 04:13:50 +00:00
|
|
|
//Check for null since the depth buffer will not be initialized if VI.height == 0
|
|
|
|
if(pDepthBuffer != nullptr) {
|
|
|
|
DepthBuffer * pCurrent = m_pCurrent;
|
|
|
|
m_pCurrent = pDepthBuffer;
|
|
|
|
frameBufferList().attachDepthBuffer();
|
|
|
|
if (pDepthBuffer->m_address != gDP.depthImageAddress)
|
|
|
|
m_pCurrent = pCurrent;
|
|
|
|
}
|
2013-06-01 13:10:30 +00:00
|
|
|
|
|
|
|
#ifdef DEBUG
|
2016-11-02 04:13:50 +00:00
|
|
|
DebugMsg( DEBUG_HIGH | DEBUG_HANDLED, "DepthBuffer_SetBuffer( 0x%08X ); color buffer is 0x%08X\n",
|
|
|
|
address, ( pFrameBuffer != nullptr && pFrameBuffer->m_FBO > 0) ? pFrameBuffer->m_startAddress : 0
|
|
|
|
);
|
2013-06-01 13:10:30 +00:00
|
|
|
#endif
|
2013-04-05 06:13:26 +00:00
|
|
|
}
|
2014-01-08 16:22:42 +00:00
|
|
|
|
2016-09-11 11:08:03 +00:00
|
|
|
void DepthBufferList::clearBuffer(u32 _ulx, u32 _uly, u32 _lrx, u32 _lry)
|
2013-04-05 06:13:26 +00:00
|
|
|
{
|
2016-06-10 06:06:06 +00:00
|
|
|
if (m_pCurrent == nullptr)
|
2013-12-15 17:20:12 +00:00
|
|
|
return;
|
2017-01-14 12:26:02 +00:00
|
|
|
|
2017-01-21 11:55:14 +00:00
|
|
|
const FramebufferTextureFormats & fbTexFormats = gfxContext.getFramebufferTextureFormats();
|
2017-01-14 12:26:02 +00:00
|
|
|
|
2015-04-29 13:31:04 +00:00
|
|
|
m_pCurrent->m_cleared = true;
|
2016-09-11 11:08:03 +00:00
|
|
|
m_pCurrent->m_ulx = _ulx;
|
2015-04-29 16:14:57 +00:00
|
|
|
m_pCurrent->m_uly = _uly;
|
2016-09-11 11:08:03 +00:00
|
|
|
m_pCurrent->m_lrx = _lrx;
|
2015-04-29 16:14:57 +00:00
|
|
|
m_pCurrent->m_lry = _lry;
|
2017-01-15 07:57:25 +00:00
|
|
|
|
2017-02-08 20:21:02 +00:00
|
|
|
if (!m_pCurrent->m_depthImageFBO.isNotNull() || config.frameBufferEmulation.N64DepthCompare == 0)
|
2013-12-14 14:30:20 +00:00
|
|
|
return;
|
2017-01-15 07:57:25 +00:00
|
|
|
|
2017-01-21 11:55:14 +00:00
|
|
|
|
|
|
|
Context::BindImageTextureParameters bindParams;
|
|
|
|
bindParams.imageUnit = textureImageUnits::Depth;
|
|
|
|
bindParams.texture = ObjectHandle();
|
|
|
|
bindParams.accessMode = textureImageAccessMode::READ_WRITE;
|
|
|
|
bindParams.textureFormat = gfxContext.getFramebufferTextureFormats().depthImageInternalFormat;
|
|
|
|
gfxContext.bindImageTexture(bindParams);
|
|
|
|
|
|
|
|
gfxContext.bindFramebuffer(bufferTarget::DRAW_FRAMEBUFFER, m_pCurrent->m_depthImageFBO);
|
|
|
|
|
2014-11-04 11:02:48 +00:00
|
|
|
const u32 cycleType = gDP.otherMode.cycleType;
|
2014-11-08 18:02:50 +00:00
|
|
|
gDP.otherMode.cycleType = G_CYC_FILL;
|
2017-01-21 11:55:14 +00:00
|
|
|
float color[4] = { 1.0f, 1.0f, 0.0f, 1.0f };
|
2017-01-15 07:57:25 +00:00
|
|
|
dwnd().getDrawer().drawRect(_ulx, _uly, _lrx, _lry, color);
|
2014-11-04 11:02:48 +00:00
|
|
|
gDP.otherMode.cycleType = cycleType;
|
2017-01-21 11:55:14 +00:00
|
|
|
|
2017-01-21 12:48:02 +00:00
|
|
|
bindParams.texture = m_pCurrent->m_pDepthImageTexture->name;
|
2017-01-21 11:55:14 +00:00
|
|
|
gfxContext.bindImageTexture(bindParams);
|
|
|
|
|
2016-05-08 07:35:17 +00:00
|
|
|
frameBufferList().setCurrentDrawBuffer();
|
2013-12-14 14:30:20 +00:00
|
|
|
}
|
2014-09-08 11:00:13 +00:00
|
|
|
|
|
|
|
void DepthBuffer_Init()
|
|
|
|
{
|
|
|
|
depthBufferList().init();
|
|
|
|
}
|
|
|
|
|
|
|
|
void DepthBuffer_Destroy()
|
|
|
|
{
|
|
|
|
depthBufferList().destroy();
|
|
|
|
}
|