diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2020-11-08 08:10:00 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-11-08 12:10:00 +0100 |
| commit | 8d168574eb04ae1e7026ac2b058e3b184f068fae (patch) | |
| tree | 6e0f79447276619af980055419874f5e99595b58 /Ryujinx.Graphics.OpenGL | |
| parent | 5561a3b95e9c980e3354366570e7896a213b95ae (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.cs | 88 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Program.cs | 149 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Renderer.cs | 4 | ||||
| -rw-r--r-- | Ryujinx.Graphics.OpenGL/Shader.cs | 31 |
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); } |
