diff options
author | gdkchan <gab.dark.100@gmail.com> | 2022-06-14 13:30:39 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-14 13:30:39 -0300 |
commit | 851f56b08a0c3b420f91143b6c6c007b429174a8 (patch) | |
tree | d4f331d1de9f4715a22abdc9b1b90b5ce5a3b4ae /Ryujinx.Graphics.OpenGL/Framebuffer.cs | |
parent | b1bd6a50b5341f444ceb31bbb0fb64f685828d75 (diff) |
Support Array/3D depth-stencil render target, and single layer clears (#3400)1.1.147
* Support Array/3D depth-stencil render target, and single layer clears
* Alignment
Diffstat (limited to 'Ryujinx.Graphics.OpenGL/Framebuffer.cs')
-rw-r--r-- | Ryujinx.Graphics.OpenGL/Framebuffer.cs | 116 |
1 files changed, 102 insertions, 14 deletions
diff --git a/Ryujinx.Graphics.OpenGL/Framebuffer.cs b/Ryujinx.Graphics.OpenGL/Framebuffer.cs index da928b4c..dafa7672 100644 --- a/Ryujinx.Graphics.OpenGL/Framebuffer.cs +++ b/Ryujinx.Graphics.OpenGL/Framebuffer.cs @@ -9,10 +9,13 @@ namespace Ryujinx.Graphics.OpenGL class Framebuffer : IDisposable { public int Handle { get; private set; } + private int _clearFbHandle; + private bool _clearFbInitialized; private FramebufferAttachment _lastDsAttachment; private readonly TextureView[] _colors; + private TextureView _depthStencil; private int _colorsCount; private bool _dualSourceBlend; @@ -20,6 +23,7 @@ namespace Ryujinx.Graphics.OpenGL public Framebuffer() { Handle = GL.GenFramebuffer(); + _clearFbHandle = GL.GenFramebuffer(); _colors = new TextureView[8]; } @@ -55,20 +59,7 @@ namespace Ryujinx.Graphics.OpenGL if (depthStencil != null) { - FramebufferAttachment attachment; - - if (IsPackedDepthStencilFormat(depthStencil.Format)) - { - attachment = FramebufferAttachment.DepthStencilAttachment; - } - else if (IsDepthOnlyFormat(depthStencil.Format)) - { - attachment = FramebufferAttachment.DepthAttachment; - } - else - { - attachment = FramebufferAttachment.StencilAttachment; - } + FramebufferAttachment attachment = GetAttachment(depthStencil.Format); GL.FramebufferTexture( FramebufferTarget.Framebuffer, @@ -82,6 +73,8 @@ namespace Ryujinx.Graphics.OpenGL { _lastDsAttachment = 0; } + + _depthStencil = depthStencil; } public void SetDualSourceBlend(bool enable) @@ -124,6 +117,22 @@ namespace Ryujinx.Graphics.OpenGL GL.DrawBuffers(colorsCount, drawBuffers); } + private static FramebufferAttachment GetAttachment(Format format) + { + if (IsPackedDepthStencilFormat(format)) + { + return FramebufferAttachment.DepthStencilAttachment; + } + else if (IsDepthOnlyFormat(format)) + { + return FramebufferAttachment.DepthAttachment; + } + else + { + return FramebufferAttachment.StencilAttachment; + } + } + private static bool IsPackedDepthStencilFormat(Format format) { return format == Format.D24UnormS8Uint || @@ -136,6 +145,78 @@ namespace Ryujinx.Graphics.OpenGL return format == Format.D16Unorm || format == Format.D32Float; } + public void AttachColorLayerForClear(int index, int layer) + { + TextureView color = _colors[index]; + + if (!IsLayered(color)) + { + return; + } + + BindClearFb(); + GL.FramebufferTextureLayer(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0 + index, color.Handle, 0, layer); + } + + public void DetachColorLayerForClear(int index) + { + TextureView color = _colors[index]; + + if (!IsLayered(color)) + { + return; + } + + GL.FramebufferTexture(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0 + index, 0, 0); + Bind(); + } + + public void AttachDepthStencilLayerForClear(int layer) + { + TextureView depthStencil = _depthStencil; + + if (!IsLayered(depthStencil)) + { + return; + } + + BindClearFb(); + GL.FramebufferTextureLayer(FramebufferTarget.Framebuffer, GetAttachment(depthStencil.Format), depthStencil.Handle, 0, layer); + } + + public void DetachDepthStencilLayerForClear() + { + TextureView depthStencil = _depthStencil; + + if (!IsLayered(depthStencil)) + { + return; + } + + GL.FramebufferTexture(FramebufferTarget.Framebuffer, GetAttachment(depthStencil.Format), 0, 0); + Bind(); + } + + private void BindClearFb() + { + GL.BindFramebuffer(FramebufferTarget.Framebuffer, _clearFbHandle); + + if (!_clearFbInitialized) + { + SetDrawBuffersImpl(Constants.MaxRenderTargets); + _clearFbInitialized = true; + } + } + + private static bool IsLayered(TextureView view) + { + return view != null && + view.Target != Target.Texture1D && + view.Target != Target.Texture2D && + view.Target != Target.Texture2DMultisample && + view.Target != Target.TextureBuffer; + } + public void Dispose() { if (Handle != 0) @@ -144,6 +225,13 @@ namespace Ryujinx.Graphics.OpenGL Handle = 0; } + + if (_clearFbHandle != 0) + { + GL.DeleteFramebuffer(_clearFbHandle); + + _clearFbHandle = 0; + } } } } |