GL: Update frame buffer after reset.

This commit is contained in:
Branimir Karadžić 2015-04-13 22:13:16 -07:00
parent c01a93e29d
commit bff3ae937c
3 changed files with 130 additions and 106 deletions

View File

@ -1936,7 +1936,10 @@ namespace bgfx
if (BackbufferRatio::None != textureRef.m_bbRatio)
{
TextureHandle handle = { textureIdx };
resizeTexture(handle, uint16_t(m_resolution.m_width), uint16_t(m_resolution.m_height) );
resizeTexture(handle
, uint16_t(m_resolution.m_width)
, uint16_t(m_resolution.m_height)
);
}
}
}

View File

@ -1946,6 +1946,12 @@ namespace bgfx { namespace gl
);
updateCapture();
for (uint32_t ii = 0; ii < BX_COUNTOF(m_frameBuffers); ++ii)
{
FrameBufferGL& frameBuffer = m_frameBuffers[ii];
frameBuffer.postReset();
}
ovrPreReset();
ovrPostReset();
}
@ -4267,128 +4273,140 @@ namespace bgfx { namespace gl
void FrameBufferGL::create(uint8_t _num, const TextureHandle* _handles)
{
GL_CHECK(glGenFramebuffers(1, &m_fbo[0]) );
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_fbo[0]) );
// m_denseIdx = UINT16_MAX;
bool needResolve = false;
GLenum buffers[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
uint32_t colorIdx = 0;
for (uint32_t ii = 0; ii < _num; ++ii)
{
TextureHandle handle = _handles[ii];
if (isValid(handle) )
{
const TextureGL& texture = s_renderGL->m_textures[handle.idx];
if (0 == colorIdx)
{
m_width = texture.m_width;
m_height = texture.m_height;
}
GLenum attachment = GL_COLOR_ATTACHMENT0 + colorIdx;
TextureFormat::Enum format = (TextureFormat::Enum)texture.m_textureFormat;
if (isDepth(format) )
{
const ImageBlockInfo& info = getBlockInfo(format);
if (0 < info.stencilBits)
{
attachment = GL_DEPTH_STENCIL_ATTACHMENT;
}
else if (0 == info.depthBits)
{
attachment = GL_STENCIL_ATTACHMENT;
}
else
{
attachment = GL_DEPTH_ATTACHMENT;
}
}
else
{
buffers[colorIdx] = attachment;
++colorIdx;
}
if (0 != texture.m_rbo)
{
GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER
, attachment
, GL_RENDERBUFFER
, texture.m_rbo
) );
}
else
{
GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER
, attachment
, texture.m_target
, texture.m_id
, 0
) );
}
needResolve |= (0 != texture.m_rbo) && (0 != texture.m_id);
}
m_th[ii] = _handles[ii];
}
m_numTh = _num;
postReset();
}
m_num = uint8_t(colorIdx);
if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL) )
void FrameBufferGL::postReset()
{
if (0 != m_fbo[0])
{
if (0 == colorIdx)
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_fbo[0]) );
bool needResolve = false;
GLenum buffers[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
uint32_t colorIdx = 0;
for (uint32_t ii = 0; ii < m_numTh; ++ii)
{
// When only depth is attached disable draw buffer to avoid
// GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER.
GL_CHECK(glDrawBuffer(GL_NONE) );
}
else
{
GL_CHECK(glDrawBuffers(colorIdx, buffers) );
}
// Disable read buffer to avoid GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER.
GL_CHECK(glReadBuffer(GL_NONE) );
}
frameBufferValidate();
if (needResolve)
{
GL_CHECK(glGenFramebuffers(1, &m_fbo[1]) );
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_fbo[1]) );
colorIdx = 0;
for (uint32_t ii = 0; ii < _num; ++ii)
{
TextureHandle handle = _handles[ii];
TextureHandle handle = m_th[ii];
if (isValid(handle) )
{
const TextureGL& texture = s_renderGL->m_textures[handle.idx];
if (0 != texture.m_id)
if (0 == colorIdx)
{
GLenum attachment = GL_COLOR_ATTACHMENT0 + colorIdx;
if (!isDepth( (TextureFormat::Enum)texture.m_textureFormat) )
m_width = texture.m_width;
m_height = texture.m_height;
}
GLenum attachment = GL_COLOR_ATTACHMENT0 + colorIdx;
TextureFormat::Enum format = (TextureFormat::Enum)texture.m_textureFormat;
if (isDepth(format) )
{
const ImageBlockInfo& info = getBlockInfo(format);
if (0 < info.stencilBits)
{
++colorIdx;
GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER
, attachment
, texture.m_target
, texture.m_id
, 0
) );
attachment = GL_DEPTH_STENCIL_ATTACHMENT;
}
else if (0 == info.depthBits)
{
attachment = GL_STENCIL_ATTACHMENT;
}
else
{
attachment = GL_DEPTH_ATTACHMENT;
}
}
else
{
buffers[colorIdx] = attachment;
++colorIdx;
}
if (0 != texture.m_rbo)
{
GL_CHECK(glFramebufferRenderbuffer(GL_FRAMEBUFFER
, attachment
, GL_RENDERBUFFER
, texture.m_rbo
) );
}
else
{
GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER
, attachment
, texture.m_target
, texture.m_id
, 0
) );
}
needResolve |= (0 != texture.m_rbo) && (0 != texture.m_id);
}
}
frameBufferValidate();
}
m_num = uint8_t(colorIdx);
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, s_renderGL->m_msaaBackBufferFbo) );
if (BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL) )
{
if (0 == colorIdx)
{
// When only depth is attached disable draw buffer to avoid
// GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER.
GL_CHECK(glDrawBuffer(GL_NONE) );
}
else
{
GL_CHECK(glDrawBuffers(colorIdx, buffers) );
}
// Disable read buffer to avoid GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER.
GL_CHECK(glReadBuffer(GL_NONE) );
}
frameBufferValidate();
if (needResolve)
{
GL_CHECK(glGenFramebuffers(1, &m_fbo[1]) );
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_fbo[1]) );
colorIdx = 0;
for (uint32_t ii = 0; ii < m_numTh; ++ii)
{
TextureHandle handle = m_th[ii];
if (isValid(handle) )
{
const TextureGL& texture = s_renderGL->m_textures[handle.idx];
if (0 != texture.m_id)
{
GLenum attachment = GL_COLOR_ATTACHMENT0 + colorIdx;
if (!isDepth( (TextureFormat::Enum)texture.m_textureFormat) )
{
++colorIdx;
GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER
, attachment
, texture.m_target
, texture.m_id
, 0
) );
}
}
}
}
frameBufferValidate();
}
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, s_renderGL->m_msaaBackBufferFbo) );
}
}
void FrameBufferGL::create(uint16_t _denseIdx, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _depthFormat)

View File

@ -930,6 +930,7 @@ namespace bgfx { namespace gl
void create(uint8_t _num, const TextureHandle* _handles);
void create(uint16_t _denseIdx, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _depthFormat);
void postReset();
uint16_t destroy();
void resolve();
void discard(uint16_t _flags);
@ -939,7 +940,9 @@ namespace bgfx { namespace gl
uint32_t m_width;
uint32_t m_height;
uint16_t m_denseIdx;
uint8_t m_num;
uint8_t m_num;
uint8_t m_numTh;
TextureHandle m_th[BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS];
};
struct ProgramGL