aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.OpenGL
diff options
context:
space:
mode:
authorgdk <gab.dark.100@gmail.com>2019-10-17 23:41:18 -0300
committerThog <thog@protonmail.com>2020-01-09 02:13:00 +0100
commit1b7d95519569639135a68e7ebda5148f3263217c (patch)
tree52a5e471418bf28ce970a268e1b86b64abc9048f /Ryujinx.Graphics.OpenGL
parent717ace6f6ed65118148dc78976c6e818a095fa4d (diff)
Initial support for image stores, support texture sample on compute
Diffstat (limited to 'Ryujinx.Graphics.OpenGL')
-rw-r--r--Ryujinx.Graphics.OpenGL/ComputePipeline.cs95
-rw-r--r--Ryujinx.Graphics.OpenGL/Pipeline.cs (renamed from Ryujinx.Graphics.OpenGL/GraphicsPipeline.cs)104
-rw-r--r--Ryujinx.Graphics.OpenGL/Program.cs59
-rw-r--r--Ryujinx.Graphics.OpenGL/Renderer.cs6
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();