diff options
Diffstat (limited to 'Ryujinx.Graphics.OpenGL/ComputePipeline.cs')
-rw-r--r-- | Ryujinx.Graphics.OpenGL/ComputePipeline.cs | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/Ryujinx.Graphics.OpenGL/ComputePipeline.cs b/Ryujinx.Graphics.OpenGL/ComputePipeline.cs new file mode 100644 index 00000000..bee96832 --- /dev/null +++ b/Ryujinx.Graphics.OpenGL/ComputePipeline.cs @@ -0,0 +1,95 @@ +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(); + } + } +} |