diff options
author | gdkchan <gab.dark.100@gmail.com> | 2021-08-11 16:33:43 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-11 21:33:43 +0200 |
commit | 0f6ec446ea3be41b1c22aa5c3870bd7a6c595d1f (patch) | |
tree | e441560dbdd560e9a020bb4b7606d3cd0698da02 /Ryujinx.Graphics.OpenGL/Pipeline.cs | |
parent | b5b7e23fc41e7045f9e803d6926e98ec7d049f0c (diff) |
Replace BGRA and scale uniforms with a uniform block (#2496)
* Replace BGRA and scale uniforms with a uniform block
* Setting the data again on program change is no longer needed
* Optimize and resolve some warnings
* Avoid redundant support buffer updates
* Some optimizations to BindBuffers (now inlined)
* Unify render scale arrays
Diffstat (limited to 'Ryujinx.Graphics.OpenGL/Pipeline.cs')
-rw-r--r-- | Ryujinx.Graphics.OpenGL/Pipeline.cs | 122 |
1 files changed, 66 insertions, 56 deletions
diff --git a/Ryujinx.Graphics.OpenGL/Pipeline.cs b/Ryujinx.Graphics.OpenGL/Pipeline.cs index 948a8b89..9c39f719 100644 --- a/Ryujinx.Graphics.OpenGL/Pipeline.cs +++ b/Ryujinx.Graphics.OpenGL/Pipeline.cs @@ -5,6 +5,8 @@ using Ryujinx.Graphics.OpenGL.Image; using Ryujinx.Graphics.OpenGL.Queries; using Ryujinx.Graphics.Shader; using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; namespace Ryujinx.Graphics.OpenGL { @@ -31,9 +33,16 @@ namespace Ryujinx.Graphics.OpenGL private int _boundDrawFramebuffer; private int _boundReadFramebuffer; - private int[] _fpIsBgra = new int[8]; - private float[] _fpRenderScale = new float[65]; - private float[] _cpRenderScale = new float[64]; + private struct Vector4<T> + { + public T X; + public T Y; + public T Z; + public T W; + } + + private Vector4<int>[] _fpIsBgra = new Vector4<int>[SupportBuffer.FragmentIsBgraCount]; + private Vector4<float>[] _renderScale = new Vector4<float>[65]; private TextureBase _unit0Texture; @@ -48,6 +57,7 @@ namespace Ryujinx.Graphics.OpenGL private bool _tfEnabled; private TransformFeedbackPrimitiveType _tfTopology; + private BufferHandle _supportBuffer; private readonly BufferHandle[] _tfbs; private readonly BufferRange[] _tfbTargets; @@ -66,15 +76,8 @@ namespace Ryujinx.Graphics.OpenGL _componentMasks[index] = 0xf; } - for (int index = 0; index < _fpRenderScale.Length; index++) - { - _fpRenderScale[index] = 1f; - } - - for (int index = 0; index < _cpRenderScale.Length; index++) - { - _cpRenderScale[index] = 1f; - } + var v4Zero = new Vector4<float> { X = 0f, Y = 0f, Z = 0f, W = 0f }; + new Span<Vector4<float>>(_renderScale).Fill(v4Zero); _tfbs = new BufferHandle[Constants.MaxTransformFeedbackBuffers]; _tfbTargets = new BufferRange[Constants.MaxTransformFeedbackBuffers]; @@ -823,9 +826,6 @@ namespace Ryujinx.Graphics.OpenGL { _program.Bind(); } - - UpdateFpIsBgra(); - SetRenderTargetScale(_fpRenderScale[0]); } public void SetRasterizerDiscard(bool discard) @@ -844,12 +844,8 @@ namespace Ryujinx.Graphics.OpenGL public void SetRenderTargetScale(float scale) { - _fpRenderScale[0] = scale; - - if (_program != null && _program.FragmentRenderScaleUniform != -1) - { - GL.Uniform1(_program.FragmentRenderScaleUniform, 1, _fpRenderScale); // Just the first element. - } + _renderScale[0].X = scale; + SetSupportBufferData<Vector4<float>>(SupportBuffer.FragmentRenderScaleOffset, _renderScale, 1); // Just the first element. } public void SetRenderTargetColorMasks(ReadOnlySpan<uint> componentMasks) @@ -866,6 +862,8 @@ namespace Ryujinx.Graphics.OpenGL { EnsureFramebuffer(); + bool isBgraChanged = false; + for (int index = 0; index < colors.Length; index++) { TextureView color = (TextureView)colors[index]; @@ -874,15 +872,19 @@ namespace Ryujinx.Graphics.OpenGL int isBgra = color != null && color.Format.IsBgra8() ? 1 : 0; - if (_fpIsBgra[index] != isBgra) + if (_fpIsBgra[index].X != isBgra) { - _fpIsBgra[index] = isBgra; + _fpIsBgra[index].X = isBgra; + isBgraChanged = true; RestoreComponentMask(index); } } - UpdateFpIsBgra(); + if (isBgraChanged) + { + SetSupportBufferData<Vector4<int>>(SupportBuffer.FragmentIsBgraOffset, _fpIsBgra, SupportBuffer.FragmentIsBgraCount); + } TextureView depthStencilView = (TextureView)depthStencil; @@ -965,9 +967,9 @@ namespace Ryujinx.Graphics.OpenGL _stencilFrontMask = stencilTest.FrontMask; } - public void SetStorageBuffers(ReadOnlySpan<BufferRange> buffers) + public void SetStorageBuffers(int first, ReadOnlySpan<BufferRange> buffers) { - SetBuffers(buffers, isStorage: true); + SetBuffers(first, buffers, isStorage: true); } public void SetTexture(int binding, ITexture texture) @@ -1023,9 +1025,9 @@ namespace Ryujinx.Graphics.OpenGL } } - public void SetUniformBuffers(ReadOnlySpan<BufferRange> buffers) + public void SetUniformBuffers(int first, ReadOnlySpan<BufferRange> buffers) { - SetBuffers(buffers, isStorage: false); + SetBuffers(first, buffers, isStorage: false); } public void SetUserClipDistance(int index, bool enableClip) @@ -1103,7 +1105,7 @@ namespace Ryujinx.Graphics.OpenGL GL.MemoryBarrier(MemoryBarrierFlags.TextureFetchBarrierBit); } - private void SetBuffers(ReadOnlySpan<BufferRange> buffers, bool isStorage) + private void SetBuffers(int first, ReadOnlySpan<BufferRange> buffers, bool isStorage) { BufferRangeTarget target = isStorage ? BufferRangeTarget.ShaderStorageBuffer : BufferRangeTarget.UniformBuffer; @@ -1113,11 +1115,11 @@ namespace Ryujinx.Graphics.OpenGL if (buffer.Handle == BufferHandle.Null) { - GL.BindBufferRange(target, index, 0, IntPtr.Zero, 0); + GL.BindBufferRange(target, first + index, 0, IntPtr.Zero, 0); continue; } - GL.BindBufferRange(target, index, buffer.Handle.ToInt32(), (IntPtr)buffer.Offset, buffer.Size); + GL.BindBufferRange(target, first + index, buffer.Handle.ToInt32(), (IntPtr)buffer.Offset, buffer.Size); } } @@ -1179,37 +1181,39 @@ namespace Ryujinx.Graphics.OpenGL return (_boundDrawFramebuffer, _boundReadFramebuffer); } - private void UpdateFpIsBgra() + public void UpdateRenderScale(ShaderStage stage, float[] scales, int textureCount, int imageCount) { - if (_program != null) + if (stage != ShaderStage.Compute && stage != ShaderStage.Fragment) { - GL.Uniform1(_program.FragmentIsBgraUniform, 8, _fpIsBgra); + return; } - } - public void UpdateRenderScale(ShaderStage stage, float[] scales, int textureCount, int imageCount) - { - if (_program != null) + bool changed = false; + + for (int index = 0; index < textureCount + imageCount; index++) { - switch (stage) + if (_renderScale[1 + index].X != scales[index]) { - case ShaderStage.Fragment: - if (_program.FragmentRenderScaleUniform != -1) - { - Array.Copy(scales, 0, _fpRenderScale, 1, textureCount + imageCount); - GL.Uniform1(_program.FragmentRenderScaleUniform, 1 + textureCount + imageCount, _fpRenderScale); - } - break; - - case ShaderStage.Compute: - if (_program.ComputeRenderScaleUniform != -1) - { - Array.Copy(scales, 0, _cpRenderScale, 0, textureCount + imageCount); - GL.Uniform1(_program.ComputeRenderScaleUniform, textureCount + imageCount, _cpRenderScale); - } - break; + _renderScale[1 + index].X = scales[index]; + changed = true; } } + + if (changed) + { + SetSupportBufferData<Vector4<float>>(SupportBuffer.FragmentRenderScaleOffset, _renderScale, 1 + textureCount + imageCount); + } + } + + private void SetSupportBufferData<T>(int offset, ReadOnlySpan<T> data, int count) where T : unmanaged + { + if (_supportBuffer == BufferHandle.Null) + { + _supportBuffer = Buffer.Create(SupportBuffer.RequiredSize); + GL.BindBufferBase(BufferRangeTarget.UniformBuffer, 0, Unsafe.As<BufferHandle, int>(ref _supportBuffer)); + } + + Buffer.SetData(_supportBuffer, offset, MemoryMarshal.Cast<T, byte>(data.Slice(0, count))); } private void PrepareForDispatch() @@ -1249,8 +1253,8 @@ namespace Ryujinx.Graphics.OpenGL public void RestoreComponentMask(int index) { // If the bound render target is bgra, swap the red and blue masks. - uint redMask = _fpIsBgra[index] == 0 ? 1u : 4u; - uint blueMask = _fpIsBgra[index] == 0 ? 4u : 1u; + uint redMask = _fpIsBgra[index].X == 0 ? 1u : 4u; + uint blueMask = _fpIsBgra[index].X == 0 ? 4u : 1u; GL.ColorMask( index, @@ -1322,6 +1326,12 @@ namespace Ryujinx.Graphics.OpenGL public void Dispose() { + if (_supportBuffer != BufferHandle.Null) + { + Buffer.Delete(_supportBuffer); + _supportBuffer = BufferHandle.Null; + } + for (int i = 0; i < Constants.MaxTransformFeedbackBuffers; i++) { if (_tfbs[i] != BufferHandle.Null) |