Merge pull request #1439 from Armada651/ogl-stereo-3d

OGL: Stereoscopic 3D Support
This commit is contained in:
Ryan Houdek
2014-11-28 11:45:38 -06:00
48 changed files with 774 additions and 267 deletions

View File

@ -89,6 +89,8 @@ static RasterFont* s_pfont = nullptr;
static int s_MSAASamples = 1;
static int s_LastMultisampleMode = 0;
static bool s_LastStereo = false;
static u32 s_blendMode;
static bool s_vsync;
@ -204,6 +206,10 @@ static void GLAPIENTRY ClearDepthf(GLfloat depthval)
{
glClearDepth(depthval);
}
static void GLAPIENTRY FramebufferTexture(GLenum target, GLenum attachment, GLuint texture, GLint level)
{
glFramebufferTextureLayer(target, attachment, texture, level, 0);
}
static void InitDriverInfo()
{
@ -460,11 +466,17 @@ Renderer::Renderer()
glClearDepthf = ClearDepthf;
}
if (GLExtensions::Version() < 320 || GLInterface->GetMode() != GLInterfaceMode::MODE_OPENGL)
{
glFramebufferTexture = FramebufferTexture;
}
g_Config.backend_info.bSupportsDualSourceBlend = GLExtensions::Supports("GL_ARB_blend_func_extended");
g_Config.backend_info.bSupportsPrimitiveRestart = !DriverDetails::HasBug(DriverDetails::BUG_PRIMITIVERESTART) &&
((GLExtensions::Version() >= 310) || GLExtensions::Supports("GL_NV_primitive_restart"));
g_Config.backend_info.bSupportsEarlyZ = GLExtensions::Supports("GL_ARB_shader_image_load_store");
g_Config.backend_info.bSupportsBBox = GLExtensions::Supports("GL_ARB_shader_storage_buffer_object");
g_Config.backend_info.bSupportsGSInstancing = GLExtensions::Supports("GL_ARB_gpu_shader5");
// Desktop OpenGL supports the binding layout if it supports 420pack
// OpenGL ES 3.1 supports it implicitly without an extension
@ -493,6 +505,8 @@ Renderer::Renderer()
g_Config.backend_info.bSupportsBindingLayout = true;
g_Config.backend_info.bSupportsEarlyZ = true;
}
// TODO: OpenGL ES 3.1 provides the necessary features as extensions.
g_Config.backend_info.bSupportsStereoscopy = false;
}
else
{
@ -507,11 +521,13 @@ Renderer::Renderer()
{
g_ogl_config.eSupportedGLSLVersion = GLSL_130;
g_Config.backend_info.bSupportsEarlyZ = false; // layout keyword is only supported on glsl150+
g_Config.backend_info.bSupportsStereoscopy = false; // geometry shaders are only supported on glsl150+
}
else if (strstr(g_ogl_config.glsl_version, "1.40"))
{
g_ogl_config.eSupportedGLSLVersion = GLSL_140;
g_Config.backend_info.bSupportsEarlyZ = false; // layout keyword is only supported on glsl150+
g_Config.backend_info.bSupportsStereoscopy = false; // geometry shaders are only supported on glsl150+
}
else
{
@ -545,6 +561,9 @@ Renderer::Renderer()
bSuccess = false;
}
if (g_Config.iStereoMode > 0 && !g_Config.backend_info.bSupportsStereoscopy)
OSD::AddMessage("Stereoscopic 3D isn't supported by your GPU, support for OpenGL 3.2 is required.", 10000);
if (!bSuccess)
{
// Not all needed extensions are supported, so we have to stop here.
@ -556,6 +575,7 @@ Renderer::Renderer()
if (g_ogl_config.max_samples < 1 || !g_ogl_config.bSupportsMSAA)
g_ogl_config.max_samples = 1;
g_Config.VerifyValidity();
UpdateActiveConfig();
OSD::AddMessage(StringFromFormat("Video Info: %s, %s, %s",
@ -563,7 +583,7 @@ Renderer::Renderer()
g_ogl_config.gl_renderer,
g_ogl_config.gl_version), 5000);
WARN_LOG(VIDEO,"Missing OGL Extensions: %s%s%s%s%s%s%s%s%s%s",
WARN_LOG(VIDEO,"Missing OGL Extensions: %s%s%s%s%s%s%s%s%s%s%s",
g_ActiveConfig.backend_info.bSupportsDualSourceBlend ? "" : "DualSourceBlend ",
g_ActiveConfig.backend_info.bSupportsPrimitiveRestart ? "" : "PrimitiveRestart ",
g_ActiveConfig.backend_info.bSupportsEarlyZ ? "" : "EarlyZ ",
@ -573,12 +593,14 @@ Renderer::Renderer()
g_ogl_config.bSupportsGLBufferStorage ? "" : "BufferStorage ",
g_ogl_config.bSupportsGLSync ? "" : "Sync ",
g_ogl_config.bSupportsMSAA ? "" : "MSAA ",
g_ogl_config.bSupportSampleShading ? "" : "SSAA "
g_ogl_config.bSupportSampleShading ? "" : "SSAA ",
g_ActiveConfig.backend_info.bSupportsGSInstancing ? "" : "GSInstancing "
);
s_LastMultisampleMode = g_ActiveConfig.iMultisampleMode;
s_MSAASamples = GetNumMSAASamples(s_LastMultisampleMode);
ApplySSAASettings();
s_LastStereo = g_ActiveConfig.iStereoMode > 0;
// Decide framebuffer size
s_backbuffer_width = (int)GLInterface->GetBackBufferWidth();
@ -1493,7 +1515,8 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
sourceRc.right -= fbStride - fbWidth;
m_post_processor->BlitFromTexture(sourceRc, drawRc, xfbSource->texture, xfbSource->texWidth, xfbSource->texHeight);
// TODO: Virtual XFB stereoscopic 3D support.
m_post_processor->BlitFromTexture(sourceRc, drawRc, xfbSource->texture, xfbSource->texWidth, xfbSource->texHeight, 1);
}
}
else
@ -1503,7 +1526,18 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
// for msaa mode, we must resolve the efb content to non-msaa
GLuint tex = FramebufferManager::ResolveAndGetRenderTarget(rc);
m_post_processor->BlitFromTexture(targetRc, flipped_trc, tex, s_target_width, s_target_height);
if (g_ActiveConfig.iStereoMode == STEREO_SBS || g_ActiveConfig.iStereoMode == STEREO_TAB)
{
TargetRectangle leftRc, rightRc;
ConvertStereoRectangle(flipped_trc, leftRc, rightRc);
m_post_processor->BlitFromTexture(targetRc, leftRc, tex, s_target_width, s_target_height, 0);
m_post_processor->BlitFromTexture(targetRc, rightRc, tex, s_target_width, s_target_height, 1);
}
else
{
m_post_processor->BlitFromTexture(targetRc, flipped_trc, tex, s_target_width, s_target_height);
}
}
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
@ -1652,15 +1686,16 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, co
s_LastEFBScale = g_ActiveConfig.iEFBScale;
}
if (xfbchanged || WindowResized || (s_LastMultisampleMode != g_ActiveConfig.iMultisampleMode))
if (xfbchanged || WindowResized || (s_LastMultisampleMode != g_ActiveConfig.iMultisampleMode) || (s_LastStereo != (g_ActiveConfig.iStereoMode > 0)))
{
UpdateDrawRectangle(s_backbuffer_width, s_backbuffer_height);
if (CalculateTargetSize(s_backbuffer_width, s_backbuffer_height) || s_LastMultisampleMode != g_ActiveConfig.iMultisampleMode)
if (CalculateTargetSize(s_backbuffer_width, s_backbuffer_height) || s_LastMultisampleMode != g_ActiveConfig.iMultisampleMode || s_LastStereo != (g_ActiveConfig.iStereoMode > 0))
{
s_LastMultisampleMode = g_ActiveConfig.iMultisampleMode;
s_MSAASamples = GetNumMSAASamples(s_LastMultisampleMode);
ApplySSAASettings();
s_LastStereo = g_ActiveConfig.iStereoMode > 0;
delete g_framebuffer_manager;
g_framebuffer_manager = new FramebufferManager(s_target_width, s_target_height,