summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bgfx/src/renderer_gl.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bgfx/src/renderer_gl.cpp')
-rw-r--r--3rdparty/bgfx/src/renderer_gl.cpp333
1 files changed, 259 insertions, 74 deletions
diff --git a/3rdparty/bgfx/src/renderer_gl.cpp b/3rdparty/bgfx/src/renderer_gl.cpp
index ca09b64eba1..10f5a1c3fd9 100644
--- a/3rdparty/bgfx/src/renderer_gl.cpp
+++ b/3rdparty/bgfx/src/renderer_gl.cpp
@@ -1304,7 +1304,6 @@ namespace bgfx { namespace gl
, m_hash( (BX_PLATFORM_WINDOWS<<1) | BX_ARCH_64BIT)
, m_backBufferFbo(0)
, m_msaaBackBufferFbo(0)
- , m_ovrFbo(0)
{
memset(m_msaaBackBufferRbos, 0, sizeof(m_msaaBackBufferRbos) );
}
@@ -1818,6 +1817,17 @@ namespace bgfx { namespace gl
);
}
+// if (s_extension[Extension::ARB_clip_control].m_supported)
+// {
+// GL_CHECK(glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE) );
+// g_caps.originBottomLeft = true;
+// }
+// else
+ {
+ g_caps.homogeneousDepth = true;
+ g_caps.originBottomLeft = true;
+ }
+
m_vaoSupport = !!(BGFX_CONFIG_RENDERER_OPENGLES >= 30)
|| s_extension[Extension::ARB_vertex_array_object].m_supported
|| s_extension[Extension::OES_vertex_array_object].m_supported
@@ -2096,10 +2106,18 @@ namespace bgfx { namespace gl
m_glctx.swap(m_frameBuffers[m_windows[ii].idx].m_swapChain);
}
- if (!m_ovr.swap(_hmd) )
+ switch (m_ovr.swap(_hmd, true) )
{
- m_glctx.swap();
+ case OVR::DeviceLost:
+ ovrPreReset();
+ break;
+
+ default:
+ break;
}
+
+ // need to swap GL render context even if OVR is enabled to get the mirror texture in the output
+ m_glctx.swap();
}
}
@@ -2386,10 +2404,6 @@ namespace bgfx { namespace gl
uint32_t width = m_resolution.m_width;
uint32_t height = m_resolution.m_height;
- if (m_ovr.isEnabled() )
- {
- m_ovr.getSize(width, height);
- }
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_backBufferFbo) );
GL_CHECK(glViewport(0, 0, width, height) );
@@ -2848,61 +2862,23 @@ namespace bgfx { namespace gl
#if BGFX_CONFIG_USE_OVR
if (m_resolution.m_flags & (BGFX_RESET_HMD|BGFX_RESET_HMD_DEBUG) )
{
- ovrGLConfig config;
- config.OGL.Header.API = ovrRenderAPI_OpenGL;
-# if OVR_VERSION > OVR_VERSION_043
- config.OGL.Header.BackBufferSize.w = m_resolution.m_width;
- config.OGL.Header.BackBufferSize.h = m_resolution.m_height;
-# else
- config.OGL.Header.RTSize.w = m_resolution.m_width;
- config.OGL.Header.RTSize.h = m_resolution.m_height;
-# endif // OVR_VERSION > OVR_VERSION_043
- config.OGL.Header.Multisample = 0;
- config.OGL.Window = (HWND)g_platformData.nwh;
- config.OGL.DC = GetDC(config.OGL.Window);
- if (m_ovr.postReset(g_platformData.nwh, &config.Config, !!(m_resolution.m_flags & BGFX_RESET_HMD_DEBUG) ) )
+ if (m_ovr.postReset() )
{
- uint32_t size = sizeof(uint32_t) + sizeof(TextureCreate);
- const Memory* mem = alloc(size);
-
- bx::StaticMemoryBlockWriter writer(mem->data, mem->size);
- uint32_t magic = BGFX_CHUNK_MAGIC_TEX;
- bx::write(&writer, magic);
-
- TextureCreate tc;
- tc.m_flags = BGFX_TEXTURE_RT|( ((m_resolution.m_flags & BGFX_RESET_MSAA_MASK) >> BGFX_RESET_MSAA_SHIFT) << BGFX_TEXTURE_RT_MSAA_SHIFT);;
- tc.m_width = m_ovr.m_rtSize.w;
- tc.m_height = m_ovr.m_rtSize.h;
- tc.m_sides = 0;
- tc.m_depth = 0;
- tc.m_numMips = 1;
- tc.m_format = uint8_t(bgfx::TextureFormat::BGRA8);
- tc.m_cubeMap = false;
- tc.m_mem = NULL;
- bx::write(&writer, tc);
-
- m_ovrRT.create(mem, tc.m_flags, 0);
- release(mem);
-
- m_ovrFbo = m_msaaBackBufferFbo;
-
- GL_CHECK(glGenFramebuffers(1, &m_msaaBackBufferFbo) );
- GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_msaaBackBufferFbo) );
-
- GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER
- , GL_COLOR_ATTACHMENT0
- , GL_TEXTURE_2D
- , m_ovrRT.m_id
- , 0
- ) );
+ const uint32_t msaaSamples = 1 << ((m_resolution.m_flags&BGFX_RESET_MSAA_MASK) >> BGFX_RESET_MSAA_SHIFT);
- GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_ovrFbo) );
+ for (uint32_t ii = 0; ii < 2; ++ii)
+ {
+ // eye buffers need to be initialized only once during application lifetime
+ if (NULL == m_ovr.m_eyeBuffers[ii])
+ {
+ m_ovr.m_eyeBuffers[ii] = &m_ovrBuffers[ii];
+ m_ovr.m_eyeBuffers[ii]->create(m_ovr.m_hmd, ii, msaaSamples);
+ }
+ }
- ovrGLTexture texture;
- texture.OGL.Header.API = ovrRenderAPI_OpenGL;
- texture.OGL.Header.TextureSize = m_ovr.m_rtSize;
- texture.OGL.TexId = m_ovrRT.m_id;
- m_ovr.postReset(texture.Texture);
+ // recreate mirror texture
+ m_ovr.m_mirror = &m_ovrMirror;
+ m_ovr.m_mirror->create(m_ovr.m_hmd, m_resolution.m_width, m_resolution.m_height);
}
}
#endif // BGFX_CONFIG_USE_OVR
@@ -2912,14 +2888,6 @@ namespace bgfx { namespace gl
{
#if BGFX_CONFIG_USE_OVR
m_ovr.preReset();
- if (m_ovr.isEnabled() )
- {
- GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) );
- GL_CHECK(glDeleteFramebuffers(1, &m_msaaBackBufferFbo) );
- m_msaaBackBufferFbo = m_ovrFbo;
- m_ovrFbo = 0;
- m_ovrRT.destroy();
- }
#endif // BGFX_CONFIG_USE_OVR
}
@@ -3343,8 +3311,10 @@ namespace bgfx { namespace gl
const char* m_glslVersion;
OVR m_ovr;
- TextureGL m_ovrRT;
- GLint m_ovrFbo;
+#if BGFX_CONFIG_USE_OVR
+ OVRMirrorGL m_ovrMirror;
+ OVRBufferGL m_ovrBuffers[2];
+#endif // BGFX_CONFIG_USE_OVR
};
RendererContextGL* s_renderGL;
@@ -3363,6 +3333,219 @@ namespace bgfx { namespace gl
s_renderGL = NULL;
}
+#if BGFX_CONFIG_USE_OVR
+ void OVRBufferGL::create(const ovrSession& _session, int _eyeIdx, int _msaaSamples)
+ {
+ m_eyeFbo = 0;
+ m_eyeTexId = 0;
+ m_depthBuffer = 0;
+ m_msaaEyeFbo = 0;
+ m_msaaEyeTexId = 0;
+ m_msaaDepthBuffer = 0;
+
+ ovrHmdDesc hmdDesc = ovr_GetHmdDesc(_session);
+ m_eyeTextureSize = ovr_GetFovTextureSize(_session, ovrEyeType(_eyeIdx), hmdDesc.DefaultEyeFov[_eyeIdx], 1.0f);
+
+ ovrTextureSwapChainDesc desc = {};
+ desc.Type = ovrTexture_2D;
+ desc.ArraySize = 1;
+ desc.Width = m_eyeTextureSize.w;
+ desc.Height = m_eyeTextureSize.h;
+ desc.MipLevels = 1;
+ desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
+ desc.SampleCount = 1;
+ desc.StaticImage = ovrFalse;
+
+ ovr_CreateTextureSwapChainGL(_session, &desc, &m_textureSwapChain);
+
+ int textureCount = 0;
+ ovr_GetTextureSwapChainLength(_session, m_textureSwapChain, &textureCount);
+
+ for (int j = 0; j < textureCount; ++j)
+ {
+ GLuint chainTexId;
+ ovr_GetTextureSwapChainBufferGL(_session, m_textureSwapChain, j, &chainTexId);
+ GL_CHECK(glBindTexture(GL_TEXTURE_2D, chainTexId) );
+
+ GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) );
+ GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) );
+ GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) );
+ GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) );
+ }
+
+ GL_CHECK(glGenFramebuffers(1, &m_eyeFbo) );
+
+ // create depth buffer
+ GL_CHECK(glGenTextures(1, &m_depthBuffer) );
+ GL_CHECK(glBindTexture(GL_TEXTURE_2D, m_depthBuffer) );
+ GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) );
+ GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) );
+ GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) );
+ GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) );
+
+ GL_CHECK(glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, m_eyeTextureSize.w, m_eyeTextureSize.h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL) );
+
+ // create MSAA buffers
+ if (_msaaSamples > 1)
+ {
+ GL_CHECK(glGenFramebuffers(1, &m_msaaEyeFbo) );
+
+ // create color MSAA texture
+ GL_CHECK(glGenTextures(1, &m_msaaEyeTexId) );
+ GL_CHECK(glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_msaaEyeTexId) );
+
+ GL_CHECK(glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, _msaaSamples, GL_RGBA, m_eyeTextureSize.w, m_eyeTextureSize.h, false) );
+ GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER) );
+ GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER) );
+ GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR) );
+ GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) );
+ GL_CHECK(glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MAX_LEVEL, 0) );
+
+ // create MSAA depth buffer
+ GL_CHECK(glGenTextures(1, &m_msaaDepthBuffer) );
+ GL_CHECK(glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_msaaDepthBuffer) );
+
+ GL_CHECK(glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, _msaaSamples, GL_DEPTH_COMPONENT, m_eyeTextureSize.w, m_eyeTextureSize.h, false) );
+ GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT) );
+ GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT) );
+ GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR) );
+ GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) );
+
+ GL_CHECK(glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MAX_LEVEL, 0) );
+ }
+ }
+
+ void OVRBufferGL::render(const ovrSession& _session)
+ {
+ // set the current eye texture in swap chain
+ int curIndex;
+ ovr_GetTextureSwapChainCurrentIndex(_session, m_textureSwapChain, &curIndex);
+ ovr_GetTextureSwapChainBufferGL(_session, m_textureSwapChain, curIndex, &m_eyeTexId);
+
+ if (0 != m_msaaEyeFbo)
+ {
+ GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_msaaEyeFbo) );
+ GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, m_msaaEyeTexId, 0) );
+ GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE, m_msaaDepthBuffer, 0) );
+ }
+ else // MSAA disabled? render directly to eye buffer
+ {
+ GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_eyeFbo) );
+ GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_eyeTexId, 0) );
+ GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthBuffer, 0) );
+ }
+ GL_CHECK(glViewport(0, 0, m_eyeTextureSize.w, m_eyeTextureSize.h) );
+ GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) );
+ }
+
+ void OVRBufferGL::postRender(const ovrSession& /*_sesion*/)
+ {
+ if (0 != m_msaaEyeFbo && 0 != m_eyeTexId)
+ {
+ // blit the contents of MSAA FBO to the regular eye buffer "connected" to the HMD
+ GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, m_msaaEyeFbo));
+ GL_CHECK(glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, m_msaaEyeTexId, 0) );
+ GL_CHECK(glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0) );
+
+ BX_CHECK(GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_READ_FRAMEBUFFER)
+ , "glCheckFramebufferStatus failed 0x%08x"
+ , glCheckFramebufferStatus(GL_READ_FRAMEBUFFER) );
+
+ GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_eyeFbo));
+ GL_CHECK(glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_eyeTexId, 0) );
+ GL_CHECK(glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0) );
+
+ BX_CHECK(GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)
+ , "glCheckFramebufferStatus failed 0x%08x"
+ , glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) );
+
+ GL_CHECK(glBlitFramebuffer(0, 0, m_eyeTextureSize.w, m_eyeTextureSize.h,
+ 0, 0, m_eyeTextureSize.w, m_eyeTextureSize.h, GL_COLOR_BUFFER_BIT, GL_NEAREST) );
+
+ GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) );
+ }
+ }
+
+ void OVRBufferGL::destroy(const ovrSession& _session)
+ {
+ GL_CHECK(glDeleteFramebuffers(1, &m_eyeFbo) );
+ GL_CHECK(glDeleteTextures(1, &m_depthBuffer) );
+
+ ovr_DestroyTextureSwapChain(_session, m_textureSwapChain);
+
+ if (0 != m_msaaEyeFbo)
+ {
+ GL_CHECK(glDeleteFramebuffers(1, &m_msaaEyeFbo) );
+ m_msaaEyeFbo = 0;
+ }
+
+ if (0 != m_msaaEyeTexId)
+ {
+ GL_CHECK(glDeleteTextures(1, &m_msaaEyeTexId));
+ m_msaaEyeTexId = 0;
+ }
+
+ if (0 != m_msaaDepthBuffer)
+ {
+ GL_CHECK(glDeleteTextures(1, &m_msaaDepthBuffer));
+ m_msaaDepthBuffer = 0;
+ }
+ }
+
+ void OVRMirrorGL::create(const ovrSession& _session, int _width, int _height)
+ {
+ memset(&m_mirrorTextureDesc, 0, sizeof(m_mirrorTextureDesc) );
+ m_mirrorTextureDesc.Width = _width;
+ m_mirrorTextureDesc.Height = _height;
+ m_mirrorTextureDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
+
+ ovr_CreateMirrorTextureGL(_session, &m_mirrorTextureDesc, &m_mirrorTexture);
+
+ // Fallback to doing nothing if mirror was not created. This is to prevent errors with fast window resizes
+ if (!m_mirrorTexture)
+ return;
+
+ // Configure the mirror read buffer
+ GLuint texId;
+ ovr_GetMirrorTextureBufferGL(_session, m_mirrorTexture, &texId);
+ GL_CHECK(glGenFramebuffers(1, &m_mirrorFBO) );
+ GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, m_mirrorFBO) );
+ GL_CHECK(glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texId, 0) );
+ GL_CHECK(glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0) );
+ GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, 0) );
+
+ if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
+ {
+ GL_CHECK(glDeleteFramebuffers(1, &m_mirrorFBO) );
+ BX_CHECK(false, "Could not initialize VR buffers!");
+ }
+ }
+
+ void OVRMirrorGL::destroy(const ovrSession& _session)
+ {
+ if (NULL != m_mirrorTexture)
+ {
+ GL_CHECK(glDeleteFramebuffers(1, &m_mirrorFBO) );
+ ovr_DestroyMirrorTexture(_session, m_mirrorTexture);
+ m_mirrorTexture = NULL;
+ }
+ }
+
+ void OVRMirrorGL::blit(const ovrSession& /*_session*/)
+ {
+ if (NULL != m_mirrorTexture)
+ {
+ // Blit mirror texture to back buffer
+ GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, m_mirrorFBO) );
+ GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0) );
+ GLint width = m_mirrorTextureDesc.Width;
+ GLint height = m_mirrorTextureDesc.Height;
+ GL_CHECK(glBlitFramebuffer(0, height, width, 0, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST) );
+ GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, 0) );
+ }
+ }
+#endif // BGFX_CONFIG_USE_OVR
+
const char* glslTypeName(GLuint _type)
{
#define GLSL_TYPE(_ty) case _ty: return #_ty
@@ -3636,7 +3819,7 @@ namespace bgfx { namespace gl
}
m_numPredefined = 0;
- m_numSamplers = 0;
+ m_numSamplers = 0;
BX_TRACE("Uniforms (%d):", activeUniforms);
for (int32_t ii = 0; ii < activeUniforms; ++ii)
@@ -5428,7 +5611,7 @@ namespace bgfx { namespace gl
_render->m_hmdInitialized = m_ovr.isInitialized();
- const bool hmdEnabled = m_ovr.isEnabled() || m_ovr.isDebug();
+ const bool hmdEnabled = m_ovr.isEnabled();
ViewState viewState(_render, hmdEnabled);
uint16_t programIdx = invalidHandle;
@@ -5478,12 +5661,13 @@ namespace bgfx { namespace gl
m_occlusionQuery.resolve(_render);
}
+ uint8_t eye = 0;
+
if (0 == (_render->m_debug&BGFX_DEBUG_IFH) )
{
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_msaaBackBufferFbo) );
bool viewRestart = false;
- uint8_t eye = 0;
uint8_t restartState = 0;
viewState.m_rect = _render->m_rect[0];
@@ -5565,6 +5749,7 @@ namespace bgfx { namespace gl
if (m_ovr.isEnabled() )
{
m_ovr.getViewport(eye, &viewState.m_rect);
+ m_ovr.renderEyeStart(eye);
}
else
{
@@ -5584,7 +5769,7 @@ namespace bgfx { namespace gl
}
const Rect& scissorRect = _render->m_scissor[view];
- viewHasScissor = !scissorRect.isZero();
+ viewHasScissor = !scissorRect.isZero();
viewScissorRect = viewHasScissor ? scissorRect : viewState.m_rect;
GL_CHECK(glViewport(viewState.m_rect.m_x
@@ -5666,7 +5851,7 @@ namespace bgfx { namespace gl
const RenderCompute& compute = renderItem.compute;
ProgramGL& program = m_program[key.m_program];
- GL_CHECK(glUseProgram(program.m_id) );
+ GL_CHECK(glUseProgram(program.m_id) );
GLbitfield barrier = 0;
for (uint32_t ii = 0; ii < BGFX_MAX_COMPUTE_BINDINGS; ++ii)