diff --git a/Ryujinx.Graphics.OpenGL/Pipeline.cs b/Ryujinx.Graphics.OpenGL/Pipeline.cs index c20ce8a3..35278629 100644 --- a/Ryujinx.Graphics.OpenGL/Pipeline.cs +++ b/Ryujinx.Graphics.OpenGL/Pipeline.cs @@ -1478,6 +1478,11 @@ namespace Ryujinx.Graphics.OpenGL _currentComponentMasks |= componentMaskAtIndex; } + public void RestoreClipControl() + { + GL.ClipControl(_clipOrigin, _clipDepthMode); + } + public void RestoreScissor0Enable() { if ((_scissorEnables & 1u) != 0) @@ -1494,6 +1499,11 @@ namespace Ryujinx.Graphics.OpenGL } } + public void RestoreViewport0() + { + GL.ViewportArray(0, 1, _viewportArray); + } + public bool TryHostConditionalRendering(ICounterEvent value, ulong compare, bool isEqual) { if (value is CounterQueueEvent) diff --git a/Ryujinx.Graphics.OpenGL/Window.cs b/Ryujinx.Graphics.OpenGL/Window.cs index da214553..f7f75f4e 100644 --- a/Ryujinx.Graphics.OpenGL/Window.cs +++ b/Ryujinx.Graphics.OpenGL/Window.cs @@ -27,11 +27,12 @@ namespace Ryujinx.Graphics.OpenGL { GL.Disable(EnableCap.FramebufferSrgb); - CopyTextureToFrameBufferRGB(0, GetCopyFramebufferHandleLazy(), (TextureView)texture, crop); + CopyTextureToFrameBufferRGB(0, GetCopyFramebufferHandleLazy(), (TextureView)texture, crop, swapBuffersCallback); GL.Enable(EnableCap.FramebufferSrgb); - swapBuffersCallback(); + // Restore unpack alignment to 4, as performance overlays such as RTSS may change this to load their resources. + GL.PixelStore(PixelStoreParameter.UnpackAlignment, 4); } public void SetSize(int width, int height) @@ -40,7 +41,7 @@ namespace Ryujinx.Graphics.OpenGL _height = height; } - private void CopyTextureToFrameBufferRGB(int drawFramebuffer, int readFramebuffer, TextureView view, ImageCrop crop) + private void CopyTextureToFrameBufferRGB(int drawFramebuffer, int readFramebuffer, TextureView view, ImageCrop crop, Action swapBuffersCallback) { (int oldDrawFramebufferHandle, int oldReadFramebufferHandle) = ((Pipeline)_renderer.Pipeline).GetBoundFramebuffers(); @@ -139,11 +140,20 @@ namespace Ryujinx.Graphics.OpenGL ((Pipeline)_renderer.Pipeline).RestoreComponentMask(i); } + // Set clip control, viewport and the framebuffer to the output to placate overlays and OBS capture. + GL.ClipControl(ClipOrigin.LowerLeft, ClipDepthMode.NegativeOneToOne); + GL.Viewport(0, 0, _width, _height); + GL.BindFramebuffer(FramebufferTarget.Framebuffer, drawFramebuffer); + + swapBuffersCallback(); + GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, oldReadFramebufferHandle); GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, oldDrawFramebufferHandle); + ((Pipeline)_renderer.Pipeline).RestoreClipControl(); ((Pipeline)_renderer.Pipeline).RestoreScissor0Enable(); ((Pipeline)_renderer.Pipeline).RestoreRasterizerDiscard(); + ((Pipeline)_renderer.Pipeline).RestoreViewport0(); if (viewConverted != view) {