aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.OpenGL/ComputePipeline.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.OpenGL/ComputePipeline.cs')
-rw-r--r--Ryujinx.Graphics.OpenGL/ComputePipeline.cs95
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();
+ }
+ }
+}