diff options
| author | gdk <gab.dark.100@gmail.com> | 2019-10-17 23:41:18 -0300 |
|---|---|---|
| committer | Thog <thog@protonmail.com> | 2020-01-09 02:13:00 +0100 |
| commit | 1b7d95519569639135a68e7ebda5148f3263217c (patch) | |
| tree | 52a5e471418bf28ce970a268e1b86b64abc9048f /Ryujinx.Graphics.OpenGL | |
| parent | 717ace6f6ed65118148dc78976c6e818a095fa4d (diff) | |
Initial support for image stores, support texture sample on compute
Diffstat (limited to 'Ryujinx.Graphics.OpenGL')
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/ComputePipeline.cs | 95 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Pipeline.cs (renamed from Ryujinx.Graphics.OpenGL/GraphicsPipeline.cs) | 104 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Program.cs | 59 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Renderer.cs | 6 |
4 files changed, 121 insertions, 143 deletions
diff --git a/Ryujinx.Graphics.OpenGL/ComputePipeline.cs b/Ryujinx.Graphics.OpenGL/ComputePipeline.cs deleted file mode 100644 index bee96832..00000000 --- a/Ryujinx.Graphics.OpenGL/ComputePipeline.cs +++ /dev/null @@ -1,95 +0,0 @@ -using OpenTK.Graphics.OpenGL; -using Ryujinx.Graphics.GAL; -using Ryujinx.Graphics.Shader; -using System; - -namespace Ryujinx.Graphics.OpenGL -{ - class ComputePipeline : IComputePipeline - { - private Renderer _renderer; - - private Program _program; - - public ComputePipeline(Renderer renderer) - { - _renderer = renderer; - } - - public void Dispatch(int groupsX, int groupsY, int groupsZ) - { - BindProgram(); - - GL.DispatchCompute(groupsX, groupsY, groupsZ); - - UnbindProgram(); - } - - public void SetProgram(IProgram program) - { - _program = (Program)program; - } - - public void SetStorageBuffer(int index, BufferRange buffer) - { - BindProgram(); - - BindBuffer(index, buffer, isStorage: true); - - UnbindProgram(); - } - - public void SetUniformBuffer(int index, BufferRange buffer) - { - BindProgram(); - - BindBuffer(index, buffer, isStorage: false); - - UnbindProgram(); - } - - private void BindBuffer(int index, BufferRange buffer, bool isStorage) - { - int bindingPoint = isStorage - ? _program.GetStorageBufferBindingPoint(ShaderStage.Compute, index) - : _program.GetUniformBufferBindingPoint(ShaderStage.Compute, index); - - if (bindingPoint == -1) - { - return; - } - - BufferRangeTarget target = isStorage - ? BufferRangeTarget.ShaderStorageBuffer - : BufferRangeTarget.UniformBuffer; - - if (buffer.Buffer == null) - { - GL.BindBufferRange(target, bindingPoint, 0, IntPtr.Zero, 0); - - return; - } - - int bufferHandle = ((Buffer)buffer.Buffer).Handle; - - IntPtr bufferOffset = (IntPtr)buffer.Offset; - - GL.BindBufferRange( - target, - bindingPoint, - bufferHandle, - bufferOffset, - buffer.Size); - } - - private void BindProgram() - { - _program.Bind(); - } - - private void UnbindProgram() - { - ((GraphicsPipeline)_renderer.GraphicsPipeline).RebindProgram(); - } - } -} diff --git a/Ryujinx.Graphics.OpenGL/GraphicsPipeline.cs b/Ryujinx.Graphics.OpenGL/Pipeline.cs index e904efed..e804eff5 100644 --- a/Ryujinx.Graphics.OpenGL/GraphicsPipeline.cs +++ b/Ryujinx.Graphics.OpenGL/Pipeline.cs @@ -4,12 +4,13 @@ using Ryujinx.Graphics.GAL.Blend; using Ryujinx.Graphics.GAL.Color; using Ryujinx.Graphics.GAL.DepthStencil; using Ryujinx.Graphics.GAL.InputAssembler; +using Ryujinx.Graphics.OpenGL.Formats; using Ryujinx.Graphics.Shader; using System; namespace Ryujinx.Graphics.OpenGL { - class GraphicsPipeline : IGraphicsPipeline + class Pipeline : IPipeline { private Program _program; @@ -33,7 +34,7 @@ namespace Ryujinx.Graphics.OpenGL private uint[] _componentMasks; - internal GraphicsPipeline() + internal Pipeline() { _clipOrigin = ClipOrigin.LowerLeft; } @@ -62,6 +63,29 @@ namespace Ryujinx.Graphics.OpenGL GL.Enable(IndexedEnableCap.Blend, index); } + public void BindImage(int index, ShaderStage stage, ITexture texture) + { + int unit = _program.GetImageUnit(stage, index); + + if (unit != -1 && texture != null) + { + TextureView view = (TextureView)texture; + + FormatInfo formatInfo = FormatTable.GetFormatInfo(view.Format); + + SizedInternalFormat format = (SizedInternalFormat)formatInfo.PixelInternalFormat; + + GL.BindImageTexture( + unit, + view.Handle, + 0, + true, + 0, + TextureAccess.ReadWrite, + format); + } + } + public void BindIndexBuffer(BufferRange buffer, IndexType type) { _elementsType = type.Convert(); @@ -107,53 +131,48 @@ namespace Ryujinx.Graphics.OpenGL } } - public void BindStorageBuffers(int index, ShaderStage stage, BufferRange[] buffers) + public void BindStorageBuffer(int index, ShaderStage stage, BufferRange buffer) { - BindBuffers(index, stage, buffers, isStorage: true); + BindBuffer(index, stage, buffer, isStorage: true); } - public void BindUniformBuffers(int index, ShaderStage stage, BufferRange[] buffers) + public void BindUniformBuffer(int index, ShaderStage stage, BufferRange buffer) { - BindBuffers(index, stage, buffers, isStorage: false); + BindBuffer(index, stage, buffer, isStorage: false); } - private void BindBuffers(int index, ShaderStage stage, BufferRange[] buffers, bool isStorage) + private void BindBuffer(int index, ShaderStage stage, BufferRange buffer, bool isStorage) { - for (int bufferIndex = 0; bufferIndex < buffers.Length; bufferIndex++, index++) - { - int bindingPoint = isStorage - ? _program.GetStorageBufferBindingPoint(stage, index) - : _program.GetUniformBufferBindingPoint(stage, index); - - if (bindingPoint == -1) - { - continue; - } + int bindingPoint = isStorage + ? _program.GetStorageBufferBindingPoint(stage, index) + : _program.GetUniformBufferBindingPoint(stage, index); - BufferRange buffer = buffers[bufferIndex]; + if (bindingPoint == -1) + { + return; + } - BufferRangeTarget target = isStorage - ? BufferRangeTarget.ShaderStorageBuffer - : BufferRangeTarget.UniformBuffer; + BufferRangeTarget target = isStorage + ? BufferRangeTarget.ShaderStorageBuffer + : BufferRangeTarget.UniformBuffer; - if (buffer.Buffer == null) - { - GL.BindBufferRange(target, bindingPoint, 0, IntPtr.Zero, 0); + if (buffer.Buffer == null) + { + GL.BindBufferRange(target, bindingPoint, 0, IntPtr.Zero, 0); - continue; - } + return; + } - int bufferHandle = ((Buffer)buffer.Buffer).Handle; + int bufferHandle = ((Buffer)buffer.Buffer).Handle; - IntPtr bufferOffset = (IntPtr)buffer.Offset; + IntPtr bufferOffset = (IntPtr)buffer.Offset; - GL.BindBufferRange( - target, - bindingPoint, - bufferHandle, - bufferOffset, - buffer.Size); - } + GL.BindBufferRange( + target, + bindingPoint, + bufferHandle, + bufferOffset, + buffer.Size); } public void BindVertexAttribs(VertexAttribDescriptor[] vertexAttribs) @@ -264,6 +283,11 @@ namespace Ryujinx.Graphics.OpenGL } } + public void Dispatch(int groupsX, int groupsY, int groupsZ) + { + GL.DispatchCompute(groupsX, groupsY, groupsZ); + } + public void Draw(int vertexCount, int instanceCount, int firstVertex, int firstInstance) { if (!_program.IsLinked) @@ -803,6 +827,16 @@ namespace Ryujinx.Graphics.OpenGL SetOrigin(flipY ? ClipOrigin.UpperLeft : ClipOrigin.LowerLeft); } + public void TextureBarrier() + { + GL.MemoryBarrier(MemoryBarrierFlags.TextureFetchBarrierBit); + } + + public void TextureBarrierTiled() + { + GL.MemoryBarrier(MemoryBarrierFlags.TextureFetchBarrierBit); + } + private void SetOrigin(ClipOrigin origin) { if (_clipOrigin != origin) diff --git a/Ryujinx.Graphics.OpenGL/Program.cs b/Ryujinx.Graphics.OpenGL/Program.cs index 1f95b449..61b1645a 100644 --- a/Ryujinx.Graphics.OpenGL/Program.cs +++ b/Ryujinx.Graphics.OpenGL/Program.cs @@ -6,8 +6,17 @@ namespace Ryujinx.Graphics.OpenGL { class Program : IProgram { - private const int StageShift = 5; - private const int SbStageShift = 4; + private const int ShaderStages = 6; + + private const int UbStageShift = 5; + private const int SbStageShift = 4; + private const int TexStageShift = 5; + private const int ImgStageShift = 3; + + private const int UbsPerStage = 1 << UbStageShift; + private const int SbsPerStage = 1 << SbStageShift; + private const int TexsPerStage = 1 << TexStageShift; + private const int ImgsPerStage = 1 << ImgStageShift; public int Handle { get; private set; } @@ -16,12 +25,14 @@ namespace Ryujinx.Graphics.OpenGL private int[] _ubBindingPoints; private int[] _sbBindingPoints; private int[] _textureUnits; + private int[] _imageUnits; public Program(IShader[] shaders) { - _ubBindingPoints = new int[32 * 6]; - _sbBindingPoints = new int[16 * 6]; - _textureUnits = new int[32 * 6]; + _ubBindingPoints = new int[UbsPerStage * ShaderStages]; + _sbBindingPoints = new int[SbsPerStage * ShaderStages]; + _textureUnits = new int[TexsPerStage * ShaderStages]; + _imageUnits = new int[ImgsPerStage * ShaderStages]; for (int index = 0; index < _ubBindingPoints.Length; index++) { @@ -38,6 +49,11 @@ namespace Ryujinx.Graphics.OpenGL _textureUnits[index] = -1; } + for (int index = 0; index < _imageUnits.Length; index++) + { + _imageUnits[index] = -1; + } + Handle = GL.CreateProgram(); for (int index = 0; index < shaders.Length; index++) @@ -79,7 +95,7 @@ namespace Ryujinx.Graphics.OpenGL GL.UniformBlockBinding(Handle, location, ubBindingPoint); - int bpIndex = (int)shader.Stage << StageShift | descriptor.Slot; + int bpIndex = (int)shader.Stage << UbStageShift | descriptor.Slot; _ubBindingPoints[bpIndex] = ubBindingPoint; @@ -117,7 +133,27 @@ namespace Ryujinx.Graphics.OpenGL GL.Uniform1(location, textureUnit); - int uIndex = (int)shader.Stage << StageShift | samplerIndex++; + int uIndex = (int)shader.Stage << TexStageShift | samplerIndex++; + + _textureUnits[uIndex] = textureUnit; + + textureUnit++; + } + + int imageIndex = 0; + + foreach (TextureDescriptor descriptor in shader.Info.Images) + { + int location = GL.GetUniformLocation(Handle, descriptor.Name); + + if (location < 0) + { + continue; + } + + GL.Uniform1(location, textureUnit); + + int uIndex = (int)shader.Stage << ImgStageShift | imageIndex++; _textureUnits[uIndex] = textureUnit; @@ -133,7 +169,7 @@ namespace Ryujinx.Graphics.OpenGL public int GetUniformBufferBindingPoint(ShaderStage stage, int index) { - return _ubBindingPoints[(int)stage << StageShift | index]; + return _ubBindingPoints[(int)stage << UbStageShift | index]; } public int GetStorageBufferBindingPoint(ShaderStage stage, int index) @@ -143,7 +179,12 @@ namespace Ryujinx.Graphics.OpenGL public int GetTextureUnit(ShaderStage stage, int index) { - return _textureUnits[(int)stage << StageShift | index]; + return _textureUnits[(int)stage << TexStageShift | index]; + } + + public int GetImageUnit(ShaderStage stage, int index) + { + return _textureUnits[(int)stage << ImgStageShift | index]; } private void CheckProgramLink() diff --git a/Ryujinx.Graphics.OpenGL/Renderer.cs b/Ryujinx.Graphics.OpenGL/Renderer.cs index 56ba7624..1baee04b 100644 --- a/Ryujinx.Graphics.OpenGL/Renderer.cs +++ b/Ryujinx.Graphics.OpenGL/Renderer.cs @@ -8,8 +8,7 @@ namespace Ryujinx.Graphics.OpenGL { public class Renderer : IRenderer { - public IComputePipeline ComputePipeline { get; } - public IGraphicsPipeline GraphicsPipeline { get; } + public IPipeline Pipeline { get; } private Counters _counters; @@ -21,8 +20,7 @@ namespace Ryujinx.Graphics.OpenGL public Renderer() { - ComputePipeline = new ComputePipeline(this); - GraphicsPipeline = new GraphicsPipeline(); + Pipeline = new Pipeline(); _counters = new Counters(); |
