From de940a5fd6a07728c51d53ebdab7489aa03cdb55 Mon Sep 17 00:00:00 2001 From: Michael Maltese Date: Sun, 5 Mar 2017 15:17:54 -0800 Subject: VideoConfig: add bSupportsFragmentStoresAndAtomics --- Source/Core/VideoBackends/OGL/Render.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Source/Core/VideoBackends/OGL/Render.cpp') diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index f898d73722..341e6b3686 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -411,7 +411,7 @@ Renderer::Renderer() g_Config.backend_info.bSupportsPrimitiveRestart = !DriverDetails::HasBug(DriverDetails::BUG_PRIMITIVE_RESTART) && ((GLExtensions::Version() >= 310) || GLExtensions::Supports("GL_NV_primitive_restart")); - g_Config.backend_info.bSupportsBBox = + g_Config.backend_info.bSupportsBBox = g_Config.backend_info.bSupportsFragmentStoresAndAtomics = GLExtensions::Supports("GL_ARB_shader_storage_buffer_object"); g_Config.backend_info.bSupportsGSInstancing = GLExtensions::Supports("GL_ARB_gpu_shader5"); g_Config.backend_info.bSupportsSSAA = GLExtensions::Supports("GL_ARB_gpu_shader5") && @@ -498,6 +498,7 @@ Renderer::Renderer() g_Config.backend_info.bSupportsGeometryShaders && g_ogl_config.SupportedESPointSize > 0; g_Config.backend_info.bSupportsSSAA = g_ogl_config.bSupportsAEP; g_Config.backend_info.bSupportsBBox = true; + g_Config.backend_info.bSupportsFragmentStoresAndAtomics = true; g_ogl_config.bSupportsMSAA = true; g_ogl_config.bSupports2DTextureStorage = true; if (g_ActiveConfig.iStereoMode > 0 && g_ActiveConfig.iMultisamples > 1 && @@ -519,6 +520,7 @@ Renderer::Renderer() g_Config.backend_info.bSupportsPaletteConversion = true; g_Config.backend_info.bSupportsSSAA = true; g_Config.backend_info.bSupportsBBox = true; + g_Config.backend_info.bSupportsFragmentStoresAndAtomics = true; g_ogl_config.bSupportsCopySubImage = true; g_ogl_config.bSupportsGLBaseVertex = true; g_ogl_config.bSupportsDebug = true; -- cgit v1.2.3 From ba6e917b49fcb192bc658557742106e29159dff7 Mon Sep 17 00:00:00 2001 From: Michael Maltese Date: Sun, 5 Mar 2017 15:34:30 -0800 Subject: OGL: implement Bounding Box on systems w/o SSBO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit should have zero performance effect if SSBOs are supported. If they aren't (e.g. on all Macs), this commit alters FramebufferManager to attach a new stencil buffer and VertexManager to draw to it when bounding box is active. `BBoxRead` gets the pixel data from the buffer and dumbly loops through it to find the bounding box. This patch can run Paper Mario: The Thousand-Year Door at almost full speed (50–60 FPS) without Dual-Core enabled for all common bounding box-using actions I tested (going through pipes, Plane Mode, Paper Mode, Prof. Frankly's gate, combat, walking around the overworld, etc.) on my computer (macOS 10.12.3, 2.8 GHz Intel Core i7, 16 GB 1600 MHz DDR3, and Intel Iris 1536 MB). A few more demanding scenes (e.g. the self-building bridge on the way to Petalburg) slow to ~15% of their speed without this patch (though they don't run quite at full speed even on master). The slowdown is caused almost solely by `glReadPixels` in `OGL::BoundingBox::Get`. Other implementation ideas: - Use a stencil buffer that's separate from the depth buffer. This would require ARB_texture_stencil8 / OpenGL 4.4, which isn't available on macOS. - Use `glGetTexImage` instead of `glReadPixels`. This is ~5 FPS slower on my computer, presumably because it has to transfer the entire combined depth-stencil buffer instead of only the stencil data. Getting only stencil data from `glGetTexImage` requires ARB_texture_stencil8 / OpenGL 4.4, which (again) is not available on macOS. - Don't use a PBO, and use `glReadPixels` synchronously. This has no visible performance effect on my computer, and is theoretically slower. --- Source/Core/VideoBackends/OGL/Render.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'Source/Core/VideoBackends/OGL/Render.cpp') diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index 341e6b3686..d2124c6c5c 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -411,7 +411,8 @@ Renderer::Renderer() g_Config.backend_info.bSupportsPrimitiveRestart = !DriverDetails::HasBug(DriverDetails::BUG_PRIMITIVE_RESTART) && ((GLExtensions::Version() >= 310) || GLExtensions::Supports("GL_NV_primitive_restart")); - g_Config.backend_info.bSupportsBBox = g_Config.backend_info.bSupportsFragmentStoresAndAtomics = + g_Config.backend_info.bSupportsBBox = true; + g_Config.backend_info.bSupportsFragmentStoresAndAtomics = GLExtensions::Supports("GL_ARB_shader_storage_buffer_object"); g_Config.backend_info.bSupportsGSInstancing = GLExtensions::Supports("GL_ARB_gpu_shader5"); g_Config.backend_info.bSupportsSSAA = GLExtensions::Supports("GL_ARB_gpu_shader5") && @@ -497,7 +498,6 @@ Renderer::Renderer() g_Config.backend_info.bSupportsGSInstancing = g_Config.backend_info.bSupportsGeometryShaders && g_ogl_config.SupportedESPointSize > 0; g_Config.backend_info.bSupportsSSAA = g_ogl_config.bSupportsAEP; - g_Config.backend_info.bSupportsBBox = true; g_Config.backend_info.bSupportsFragmentStoresAndAtomics = true; g_ogl_config.bSupportsMSAA = true; g_ogl_config.bSupports2DTextureStorage = true; @@ -519,7 +519,6 @@ Renderer::Renderer() g_Config.backend_info.bSupportsGSInstancing = g_ogl_config.SupportedESPointSize > 0; g_Config.backend_info.bSupportsPaletteConversion = true; g_Config.backend_info.bSupportsSSAA = true; - g_Config.backend_info.bSupportsBBox = true; g_Config.backend_info.bSupportsFragmentStoresAndAtomics = true; g_ogl_config.bSupportsCopySubImage = true; g_ogl_config.bSupportsGLBaseVertex = true; @@ -657,10 +656,13 @@ Renderer::Renderer() // options while running g_Config.bRunning = true; - glStencilFunc(GL_ALWAYS, 0, 0); - glBlendFunc(GL_ONE, GL_ONE); + // The stencil is used for bounding box emulation when SSBOs are not available + glDisable(GL_STENCIL_TEST); + glStencilFunc(GL_ALWAYS, 1, 0xFF); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - glViewport(0, 0, GetTargetWidth(), GetTargetHeight()); // Reset The Current Viewport + // Reset The Current Viewport + glViewport(0, 0, GetTargetWidth(), GetTargetHeight()); if (g_ActiveConfig.backend_info.bSupportsClipControl) glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE); @@ -677,10 +679,9 @@ Renderer::Renderer() glPixelStorei(GL_UNPACK_ALIGNMENT, 4); // 4-byte pixel alignment - glDisable(GL_STENCIL_TEST); glEnable(GL_SCISSOR_TEST); - glScissor(0, 0, GetTargetWidth(), GetTargetHeight()); + glBlendFunc(GL_ONE, GL_ONE); glBlendColor(0, 0, 0, 0.5f); glClearDepthf(1.0f); @@ -1364,6 +1365,7 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, g_framebuffer_manager.reset(); g_framebuffer_manager = std::make_unique(m_target_width, m_target_height, s_MSAASamples); + BoundingBox::SetTargetSizeChanged(m_target_width, m_target_height); } } -- cgit v1.2.3 From 53224d41d05a9ec70d0a2715e1a7601a0e60bb14 Mon Sep 17 00:00:00 2001 From: Michael Maltese Date: Thu, 9 Mar 2017 15:33:10 -0800 Subject: OGL: only create stencil buffer when needed --- Source/Core/VideoBackends/OGL/Render.cpp | 53 +++++++++++++++++--------------- 1 file changed, 28 insertions(+), 25 deletions(-) (limited to 'Source/Core/VideoBackends/OGL/Render.cpp') diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index d2124c6c5c..69554269cb 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -734,8 +734,8 @@ void Renderer::Shutdown() void Renderer::Init() { // Initialize the FramebufferManager - g_framebuffer_manager = - std::make_unique(m_target_width, m_target_height, s_MSAASamples); + g_framebuffer_manager = std::make_unique( + m_target_width, m_target_height, s_MSAASamples, BoundingBox::NeedsStencilBuffer()); m_post_processor = std::make_unique(); s_raster_font = std::make_unique(); @@ -1338,35 +1338,38 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbStride, u32 fbHeight, } bool target_size_changed = CalculateTargetSize(); - if (target_size_changed || xfbchanged || window_resized || - (s_last_multisamples != g_ActiveConfig.iMultisamples) || - (s_last_stereo_mode != (g_ActiveConfig.iStereoMode > 0))) + bool stencil_buffer_enabled = + static_cast(g_framebuffer_manager.get())->HasStencilBuffer(); + + bool fb_needs_update = target_size_changed || + s_last_multisamples != g_ActiveConfig.iMultisamples || + stencil_buffer_enabled != BoundingBox::NeedsStencilBuffer() || + s_last_stereo_mode != (g_ActiveConfig.iStereoMode > 0); + + if (xfbchanged || window_resized || fb_needs_update) { s_last_xfb_mode = g_ActiveConfig.bUseRealXFB; - UpdateDrawRectangle(); + } + if (fb_needs_update) + { + s_last_stereo_mode = g_ActiveConfig.iStereoMode > 0; + s_last_multisamples = g_ActiveConfig.iMultisamples; + s_MSAASamples = s_last_multisamples; - if (target_size_changed || s_last_multisamples != g_ActiveConfig.iMultisamples || - s_last_stereo_mode != (g_ActiveConfig.iStereoMode > 0)) + if (s_MSAASamples > 1 && s_MSAASamples > g_ogl_config.max_samples) { - s_last_stereo_mode = g_ActiveConfig.iStereoMode > 0; - s_last_multisamples = g_ActiveConfig.iMultisamples; - s_MSAASamples = s_last_multisamples; - - if (s_MSAASamples > 1 && s_MSAASamples > g_ogl_config.max_samples) - { - s_MSAASamples = g_ogl_config.max_samples; - OSD::AddMessage(StringFromFormat( - "%d Anti Aliasing samples selected, but only %d supported by your GPU.", - s_last_multisamples, g_ogl_config.max_samples), - 10000); - } - - g_framebuffer_manager.reset(); - g_framebuffer_manager = - std::make_unique(m_target_width, m_target_height, s_MSAASamples); - BoundingBox::SetTargetSizeChanged(m_target_width, m_target_height); + s_MSAASamples = g_ogl_config.max_samples; + OSD::AddMessage( + StringFromFormat("%d Anti Aliasing samples selected, but only %d supported by your GPU.", + s_last_multisamples, g_ogl_config.max_samples), + 10000); } + + g_framebuffer_manager.reset(); + g_framebuffer_manager = std::make_unique( + m_target_width, m_target_height, s_MSAASamples, BoundingBox::NeedsStencilBuffer()); + BoundingBox::SetTargetSizeChanged(m_target_width, m_target_height); } // --------------------------------------------------------------------- -- cgit v1.2.3