aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.OpenGL
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2020-11-08 08:10:00 -0300
committerGitHub <noreply@github.com>2020-11-08 12:10:00 +0100
commit8d168574eb04ae1e7026ac2b058e3b184f068fae (patch)
tree6e0f79447276619af980055419874f5e99595b58 /Ryujinx.Graphics.OpenGL
parent5561a3b95e9c980e3354366570e7896a213b95ae (diff)
Use explicit buffer and texture bindings on shaders (#1666)
* Use explicit buffer and texture bindings on shaders * More XML docs and other nits
Diffstat (limited to 'Ryujinx.Graphics.OpenGL')
-rw-r--r--Ryujinx.Graphics.OpenGL/Pipeline.cs88
-rw-r--r--Ryujinx.Graphics.OpenGL/Program.cs149
-rw-r--r--Ryujinx.Graphics.OpenGL/Renderer.cs4
-rw-r--r--Ryujinx.Graphics.OpenGL/Shader.cs31
4 files changed, 53 insertions, 219 deletions
diff --git a/Ryujinx.Graphics.OpenGL/Pipeline.cs b/Ryujinx.Graphics.OpenGL/Pipeline.cs
index 06cf5ef4..56873291 100644
--- a/Ryujinx.Graphics.OpenGL/Pipeline.cs
+++ b/Ryujinx.Graphics.OpenGL/Pipeline.cs
@@ -697,20 +697,20 @@ namespace Ryujinx.Graphics.OpenGL
SetFrontFace(_frontFace = frontFace.Convert());
}
- public void SetImage(int index, ShaderStage stage, ITexture texture, Format imageFormat)
+ public void SetImage(int binding, ITexture texture, Format imageFormat)
{
- int unit = _program.GetImageUnit(stage, index);
-
- if (unit != -1 && texture != null)
+ if (texture == null)
{
- TextureBase texBase = (TextureBase)texture;
+ return;
+ }
- SizedInternalFormat format = FormatTable.GetImageFormat(imageFormat);
+ TextureBase texBase = (TextureBase)texture;
- if (format != 0)
- {
- GL.BindImageTexture(unit, texBase.Handle, 0, true, 0, TextureAccess.ReadWrite, format);
- }
+ SizedInternalFormat format = FormatTable.GetImageFormat(imageFormat);
+
+ if (format != 0)
+ {
+ GL.BindImageTexture(binding, texBase.Handle, 0, true, 0, TextureAccess.ReadWrite, format);
}
}
@@ -866,14 +866,14 @@ namespace Ryujinx.Graphics.OpenGL
UpdateDepthTest();
}
- public void SetSampler(int index, ShaderStage stage, ISampler sampler)
+ public void SetSampler(int binding, ISampler sampler)
{
- int unit = _program.GetTextureUnit(stage, index);
-
- if (unit != -1 && sampler != null)
+ if (sampler == null)
{
- ((Sampler)sampler).Bind(unit);
+ return;
}
+
+ ((Sampler)sampler).Bind(binding);
}
public void SetScissorEnable(int index, bool enable)
@@ -939,25 +939,25 @@ namespace Ryujinx.Graphics.OpenGL
_stencilFrontMask = stencilTest.FrontMask;
}
- public void SetStorageBuffer(int index, ShaderStage stage, BufferRange buffer)
+ public void SetStorageBuffers(ReadOnlySpan<BufferRange> buffers)
{
- SetBuffer(index, stage, buffer, isStorage: true);
+ SetBuffers(buffers, isStorage: true);
}
- public void SetTexture(int index, ShaderStage stage, ITexture texture)
+ public void SetTexture(int binding, ITexture texture)
{
- int unit = _program.GetTextureUnit(stage, index);
+ if (texture == null)
+ {
+ return;
+ }
- if (unit != -1 && texture != null)
+ if (binding == 0)
{
- if (unit == 0)
- {
- _unit0Texture = (TextureBase)texture;
- }
- else
- {
- ((TextureBase)texture).Bind(unit);
- }
+ _unit0Texture = (TextureBase)texture;
+ }
+ else
+ {
+ ((TextureBase)texture).Bind(binding);
}
}
@@ -997,9 +997,9 @@ namespace Ryujinx.Graphics.OpenGL
}
}
- public void SetUniformBuffer(int index, ShaderStage stage, BufferRange buffer)
+ public void SetUniformBuffers(ReadOnlySpan<BufferRange> buffers)
{
- SetBuffer(index, stage, buffer, isStorage: false);
+ SetBuffers(buffers, isStorage: false);
}
public void SetUserClipDistance(int index, bool enableClip)
@@ -1077,30 +1077,22 @@ namespace Ryujinx.Graphics.OpenGL
GL.MemoryBarrier(MemoryBarrierFlags.TextureFetchBarrierBit);
}
- private void SetBuffer(int index, ShaderStage stage, BufferRange buffer, bool isStorage)
+ private void SetBuffers(ReadOnlySpan<BufferRange> buffers, bool isStorage)
{
- int bindingPoint = isStorage
- ? _program.GetStorageBufferBindingPoint(stage, index)
- : _program.GetUniformBufferBindingPoint(stage, index);
+ BufferRangeTarget target = isStorage ? BufferRangeTarget.ShaderStorageBuffer : BufferRangeTarget.UniformBuffer;
- if (bindingPoint == -1)
+ for (int index = 0; index < buffers.Length; index++)
{
- return;
- }
+ BufferRange buffer = buffers[index];
- BufferRangeTarget target = isStorage
- ? BufferRangeTarget.ShaderStorageBuffer
- : BufferRangeTarget.UniformBuffer;
+ if (buffer.Handle == BufferHandle.Null)
+ {
+ GL.BindBufferRange(target, index, 0, IntPtr.Zero, 0);
+ continue;
+ }
- if (buffer.Handle == BufferHandle.Null)
- {
- GL.BindBufferRange(target, bindingPoint, 0, IntPtr.Zero, 0);
- return;
+ GL.BindBufferRange(target, index, buffer.Handle.ToInt32(), (IntPtr)buffer.Offset, buffer.Size);
}
-
- IntPtr bufferOffset = (IntPtr)buffer.Offset;
-
- GL.BindBufferRange(target, bindingPoint, buffer.Handle.ToInt32(), bufferOffset, buffer.Size);
}
private void SetOrigin(ClipOrigin origin)
diff --git a/Ryujinx.Graphics.OpenGL/Program.cs b/Ryujinx.Graphics.OpenGL/Program.cs
index babe17a0..17e14df6 100644
--- a/Ryujinx.Graphics.OpenGL/Program.cs
+++ b/Ryujinx.Graphics.OpenGL/Program.cs
@@ -1,7 +1,6 @@
using OpenTK.Graphics.OpenGL;
using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL;
-using Ryujinx.Graphics.Shader;
using Ryujinx.Graphics.Shader.CodeGen.Glsl;
using System;
using System.Collections.Generic;
@@ -11,18 +10,6 @@ namespace Ryujinx.Graphics.OpenGL
{
class Program : IProgram
{
- 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; }
public int FragmentIsBgraUniform { get; }
@@ -31,38 +18,8 @@ namespace Ryujinx.Graphics.OpenGL
public bool IsLinked { get; private set; }
- private int[] _ubBindingPoints;
- private int[] _sbBindingPoints;
- private int[] _textureUnits;
- private int[] _imageUnits;
-
public Program(IShader[] shaders, TransformFeedbackDescriptor[] transformFeedbackDescriptors)
{
- _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++)
- {
- _ubBindingPoints[index] = -1;
- }
-
- for (int index = 0; index < _sbBindingPoints.Length; index++)
- {
- _sbBindingPoints[index] = -1;
- }
-
- for (int index = 0; index < _textureUnits.Length; index++)
- {
- _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++)
@@ -131,92 +88,6 @@ namespace Ryujinx.Graphics.OpenGL
CheckProgramLink();
- int ubBindingPoint = 0;
- int sbBindingPoint = 0;
- int textureUnit = 0;
- int imageUnit = 0;
-
- for (int index = 0; index < shaders.Length; index++)
- {
- Shader shader = (Shader)shaders[index];
-
- foreach (BufferDescriptor descriptor in shader.Info.CBuffers)
- {
- int location = GL.GetUniformBlockIndex(Handle, descriptor.Name);
-
- if (location < 0)
- {
- continue;
- }
-
- GL.UniformBlockBinding(Handle, location, ubBindingPoint);
-
- int bpIndex = (int)shader.Stage << UbStageShift | descriptor.Slot;
-
- _ubBindingPoints[bpIndex] = ubBindingPoint;
-
- ubBindingPoint++;
- }
-
- foreach (BufferDescriptor descriptor in shader.Info.SBuffers)
- {
- int location = GL.GetProgramResourceIndex(Handle, ProgramInterface.ShaderStorageBlock, descriptor.Name);
-
- if (location < 0)
- {
- continue;
- }
-
- GL.ShaderStorageBlockBinding(Handle, location, sbBindingPoint);
-
- int bpIndex = (int)shader.Stage << SbStageShift | descriptor.Slot;
-
- _sbBindingPoints[bpIndex] = sbBindingPoint;
-
- sbBindingPoint++;
- }
-
- int samplerIndex = 0;
-
- foreach (TextureDescriptor descriptor in shader.Info.Textures)
- {
- int location = GL.GetUniformLocation(Handle, descriptor.Name);
-
- if (location < 0)
- {
- continue;
- }
-
- GL.ProgramUniform1(Handle, location, textureUnit);
-
- 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.ProgramUniform1(Handle, location, imageUnit);
-
- int uIndex = (int)shader.Stage << ImgStageShift | imageIndex++;
-
- _imageUnits[uIndex] = imageUnit;
-
- imageUnit++;
- }
- }
-
FragmentIsBgraUniform = GL.GetUniformLocation(Handle, "is_bgra");
FragmentRenderScaleUniform = GL.GetUniformLocation(Handle, "fp_renderScale");
ComputeRenderScaleUniform = GL.GetUniformLocation(Handle, "cp_renderScale");
@@ -227,26 +98,6 @@ namespace Ryujinx.Graphics.OpenGL
GL.UseProgram(Handle);
}
- public int GetUniformBufferBindingPoint(ShaderStage stage, int index)
- {
- return _ubBindingPoints[(int)stage << UbStageShift | index];
- }
-
- public int GetStorageBufferBindingPoint(ShaderStage stage, int index)
- {
- return _sbBindingPoints[(int)stage << SbStageShift | index];
- }
-
- public int GetTextureUnit(ShaderStage stage, int index)
- {
- return _textureUnits[(int)stage << TexStageShift | index];
- }
-
- public int GetImageUnit(ShaderStage stage, int index)
- {
- return _imageUnits[(int)stage << ImgStageShift | index];
- }
-
private void CheckProgramLink()
{
GL.GetProgram(Handle, GetProgramParameterName.LinkStatus, out int status);
diff --git a/Ryujinx.Graphics.OpenGL/Renderer.cs b/Ryujinx.Graphics.OpenGL/Renderer.cs
index aac3c69e..75bcda12 100644
--- a/Ryujinx.Graphics.OpenGL/Renderer.cs
+++ b/Ryujinx.Graphics.OpenGL/Renderer.cs
@@ -42,9 +42,9 @@ namespace Ryujinx.Graphics.OpenGL
ResourcePool = new ResourcePool();
}
- public IShader CompileShader(ShaderProgram shader)
+ public IShader CompileShader(ShaderStage stage, string code)
{
- return new Shader(shader);
+ return new Shader(stage, code);
}
public BufferHandle CreateBuffer(int size)
diff --git a/Ryujinx.Graphics.OpenGL/Shader.cs b/Ryujinx.Graphics.OpenGL/Shader.cs
index f25845cf..1df07ee4 100644
--- a/Ryujinx.Graphics.OpenGL/Shader.cs
+++ b/Ryujinx.Graphics.OpenGL/Shader.cs
@@ -8,31 +8,22 @@ namespace Ryujinx.Graphics.OpenGL
{
public int Handle { get; private set; }
- private ShaderProgram _program;
-
- public ShaderProgramInfo Info => _program.Info;
-
- public ShaderStage Stage => _program.Stage;
-
- public Shader(ShaderProgram program)
+ public Shader(ShaderStage stage, string code)
{
- _program = program;
-
- ShaderType type = ShaderType.VertexShader;
-
- switch (program.Stage)
+ ShaderType type = stage switch
{
- case ShaderStage.Compute: type = ShaderType.ComputeShader; break;
- case ShaderStage.Vertex: type = ShaderType.VertexShader; break;
- case ShaderStage.TessellationControl: type = ShaderType.TessControlShader; break;
- case ShaderStage.TessellationEvaluation: type = ShaderType.TessEvaluationShader; break;
- case ShaderStage.Geometry: type = ShaderType.GeometryShader; break;
- case ShaderStage.Fragment: type = ShaderType.FragmentShader; break;
- }
+ ShaderStage.Compute => ShaderType.ComputeShader,
+ ShaderStage.Vertex => ShaderType.VertexShader,
+ ShaderStage.TessellationControl => ShaderType.TessControlShader,
+ ShaderStage.TessellationEvaluation => ShaderType.TessEvaluationShader,
+ ShaderStage.Geometry => ShaderType.GeometryShader,
+ ShaderStage.Fragment => ShaderType.FragmentShader,
+ _ => ShaderType.VertexShader
+ };
Handle = GL.CreateShader(type);
- GL.ShaderSource(Handle, program.Code);
+ GL.ShaderSource(Handle, code);
GL.CompileShader(Handle);
}