aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Ryujinx.Graphics.GAL/BufferAssignment.cs14
-rw-r--r--Ryujinx.Graphics.GAL/IPipeline.cs4
-rw-r--r--Ryujinx.Graphics.GAL/Multithreading/BufferMap.cs24
-rw-r--r--Ryujinx.Graphics.GAL/Multithreading/Commands/SetStorageBuffersCommand.cs10
-rw-r--r--Ryujinx.Graphics.GAL/Multithreading/Commands/SetUniformBuffersCommand.cs10
-rw-r--r--Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs8
-rw-r--r--Ryujinx.Graphics.Gpu/Memory/BufferManager.cs46
-rw-r--r--Ryujinx.Graphics.OpenGL/Pipeline.cs17
-rw-r--r--Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs14
-rw-r--r--Ryujinx.Graphics.Vulkan/HelperShader.cs14
-rw-r--r--Ryujinx.Graphics.Vulkan/PipelineBase.cs8
11 files changed, 91 insertions, 78 deletions
diff --git a/Ryujinx.Graphics.GAL/BufferAssignment.cs b/Ryujinx.Graphics.GAL/BufferAssignment.cs
new file mode 100644
index 00000000..9f0f56c5
--- /dev/null
+++ b/Ryujinx.Graphics.GAL/BufferAssignment.cs
@@ -0,0 +1,14 @@
+namespace Ryujinx.Graphics.GAL
+{
+ public struct BufferAssignment
+ {
+ public readonly int Binding;
+ public readonly BufferRange Range;
+
+ public BufferAssignment(int binding, BufferRange range)
+ {
+ Binding = binding;
+ Range = range;
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.Graphics.GAL/IPipeline.cs b/Ryujinx.Graphics.GAL/IPipeline.cs
index 38bf54f7..26d019eb 100644
--- a/Ryujinx.Graphics.GAL/IPipeline.cs
+++ b/Ryujinx.Graphics.GAL/IPipeline.cs
@@ -86,12 +86,12 @@ namespace Ryujinx.Graphics.GAL
void SetStencilTest(StencilTestDescriptor stencilTest);
- void SetStorageBuffers(int first, ReadOnlySpan<BufferRange> buffers);
+ void SetStorageBuffers(ReadOnlySpan<BufferAssignment> buffers);
void SetTextureAndSampler(ShaderStage stage, int binding, ITexture texture, ISampler sampler);
void SetTransformFeedbackBuffers(ReadOnlySpan<BufferRange> buffers);
- void SetUniformBuffers(int first, ReadOnlySpan<BufferRange> buffers);
+ void SetUniformBuffers(ReadOnlySpan<BufferAssignment> buffers);
void SetUserClipDistance(int index, bool enableClip);
diff --git a/Ryujinx.Graphics.GAL/Multithreading/BufferMap.cs b/Ryujinx.Graphics.GAL/Multithreading/BufferMap.cs
index fcf09f9f..24b0af2d 100644
--- a/Ryujinx.Graphics.GAL/Multithreading/BufferMap.cs
+++ b/Ryujinx.Graphics.GAL/Multithreading/BufferMap.cs
@@ -142,6 +142,30 @@ namespace Ryujinx.Graphics.GAL.Multithreading
return ranges;
}
+ internal Span<BufferAssignment> MapBufferRanges(Span<BufferAssignment> ranges)
+ {
+ // Rewrite the buffer ranges to point to the mapped handles.
+
+ lock (_bufferMap)
+ {
+ for (int i = 0; i < ranges.Length; i++)
+ {
+ ref BufferAssignment assignment = ref ranges[i];
+ BufferRange range = assignment.Range;
+ BufferHandle result;
+
+ if (!_bufferMap.TryGetValue(range.Handle, out result))
+ {
+ result = BufferHandle.Null;
+ }
+
+ assignment = new BufferAssignment(ranges[i].Binding, new BufferRange(result, range.Offset, range.Size));
+ }
+ }
+
+ return ranges;
+ }
+
internal Span<VertexBufferDescriptor> MapBufferRanges(Span<VertexBufferDescriptor> ranges)
{
// Rewrite the buffer ranges to point to the mapped handles.
diff --git a/Ryujinx.Graphics.GAL/Multithreading/Commands/SetStorageBuffersCommand.cs b/Ryujinx.Graphics.GAL/Multithreading/Commands/SetStorageBuffersCommand.cs
index c2963373..610603ca 100644
--- a/Ryujinx.Graphics.GAL/Multithreading/Commands/SetStorageBuffersCommand.cs
+++ b/Ryujinx.Graphics.GAL/Multithreading/Commands/SetStorageBuffersCommand.cs
@@ -6,19 +6,17 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands
struct SetStorageBuffersCommand : IGALCommand
{
public CommandType CommandType => CommandType.SetStorageBuffers;
- private int _first;
- private SpanRef<BufferRange> _buffers;
+ private SpanRef<BufferAssignment> _buffers;
- public void Set(int first, SpanRef<BufferRange> buffers)
+ public void Set(SpanRef<BufferAssignment> buffers)
{
- _first = first;
_buffers = buffers;
}
public static void Run(ref SetStorageBuffersCommand command, ThreadedRenderer threaded, IRenderer renderer)
{
- Span<BufferRange> buffers = command._buffers.Get(threaded);
- renderer.Pipeline.SetStorageBuffers(command._first, threaded.Buffers.MapBufferRanges(buffers));
+ Span<BufferAssignment> buffers = command._buffers.Get(threaded);
+ renderer.Pipeline.SetStorageBuffers(threaded.Buffers.MapBufferRanges(buffers));
command._buffers.Dispose(threaded);
}
}
diff --git a/Ryujinx.Graphics.GAL/Multithreading/Commands/SetUniformBuffersCommand.cs b/Ryujinx.Graphics.GAL/Multithreading/Commands/SetUniformBuffersCommand.cs
index 750d8dac..e4abb403 100644
--- a/Ryujinx.Graphics.GAL/Multithreading/Commands/SetUniformBuffersCommand.cs
+++ b/Ryujinx.Graphics.GAL/Multithreading/Commands/SetUniformBuffersCommand.cs
@@ -6,19 +6,17 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands
struct SetUniformBuffersCommand : IGALCommand
{
public CommandType CommandType => CommandType.SetUniformBuffers;
- private int _first;
- private SpanRef<BufferRange> _buffers;
+ private SpanRef<BufferAssignment> _buffers;
- public void Set(int first, SpanRef<BufferRange> buffers)
+ public void Set(SpanRef<BufferAssignment> buffers)
{
- _first = first;
_buffers = buffers;
}
public static void Run(ref SetUniformBuffersCommand command, ThreadedRenderer threaded, IRenderer renderer)
{
- Span<BufferRange> buffers = command._buffers.Get(threaded);
- renderer.Pipeline.SetUniformBuffers(command._first, threaded.Buffers.MapBufferRanges(buffers));
+ Span<BufferAssignment> buffers = command._buffers.Get(threaded);
+ renderer.Pipeline.SetUniformBuffers(threaded.Buffers.MapBufferRanges(buffers));
command._buffers.Dispose(threaded);
}
}
diff --git a/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs b/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs
index 52d69933..ba120867 100644
--- a/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs
+++ b/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs
@@ -275,9 +275,9 @@ namespace Ryujinx.Graphics.GAL.Multithreading
_renderer.QueueCommand();
}
- public void SetStorageBuffers(int first, ReadOnlySpan<BufferRange> buffers)
+ public void SetStorageBuffers(ReadOnlySpan<BufferAssignment> buffers)
{
- _renderer.New<SetStorageBuffersCommand>().Set(first, _renderer.CopySpan(buffers));
+ _renderer.New<SetStorageBuffersCommand>().Set(_renderer.CopySpan(buffers));
_renderer.QueueCommand();
}
@@ -293,9 +293,9 @@ namespace Ryujinx.Graphics.GAL.Multithreading
_renderer.QueueCommand();
}
- public void SetUniformBuffers(int first, ReadOnlySpan<BufferRange> buffers)
+ public void SetUniformBuffers(ReadOnlySpan<BufferAssignment> buffers)
{
- _renderer.New<SetUniformBuffersCommand>().Set(first, _renderer.CopySpan(buffers));
+ _renderer.New<SetUniformBuffersCommand>().Set(_renderer.CopySpan(buffers));
_renderer.QueueCommand();
}
diff --git a/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs b/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs
index 1b67f650..f0831e15 100644
--- a/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs
+++ b/Ryujinx.Graphics.Gpu/Memory/BufferManager.cs
@@ -24,7 +24,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
private readonly VertexBuffer[] _vertexBuffers;
private readonly BufferBounds[] _transformFeedbackBuffers;
private readonly List<BufferTextureBinding> _bufferTextures;
- private readonly BufferRange[] _ranges;
+ private readonly BufferAssignment[] _ranges;
/// <summary>
/// Holds shader stage buffer state and binding information.
@@ -134,7 +134,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
_bufferTextures = new List<BufferTextureBinding>();
- _ranges = new BufferRange[Constants.TotalGpUniformBuffers * Constants.ShaderStages];
+ _ranges = new BufferAssignment[Constants.TotalGpUniformBuffers * Constants.ShaderStages];
}
@@ -618,10 +618,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void BindBuffers(BufferCache bufferCache, BuffersPerStage[] bindings, bool isStorage)
{
- int rangesFirst = 0;
int rangesCount = 0;
- Span<BufferRange> ranges = _ranges;
+ Span<BufferAssignment> ranges = _ranges;
for (ShaderStage stage = ShaderStage.Vertex; stage <= ShaderStage.Fragment; stage++)
{
@@ -640,25 +639,14 @@ namespace Ryujinx.Graphics.Gpu.Memory
? bufferCache.GetBufferRangeTillEnd(bounds.Address, bounds.Size, isWrite)
: bufferCache.GetBufferRange(bounds.Address, bounds.Size);
- if (rangesCount == 0)
- {
- rangesFirst = bindingInfo.Binding;
- }
- else if (bindingInfo.Binding != rangesFirst + rangesCount)
- {
- SetHostBuffers(ranges, rangesFirst, rangesCount, isStorage);
- rangesFirst = bindingInfo.Binding;
- rangesCount = 0;
- }
-
- ranges[rangesCount++] = range;
+ ranges[rangesCount++] = new BufferAssignment(bindingInfo.Binding, range);
}
}
}
if (rangesCount != 0)
{
- SetHostBuffers(ranges, rangesFirst, rangesCount, isStorage);
+ SetHostBuffers(ranges, rangesCount, isStorage);
}
}
@@ -671,10 +659,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void BindBuffers(BufferCache bufferCache, BuffersPerStage buffers, bool isStorage)
{
- int rangesFirst = 0;
int rangesCount = 0;
- Span<BufferRange> ranges = _ranges;
+ Span<BufferAssignment> ranges = _ranges;
for (int index = 0; index < buffers.Count; index++)
{
@@ -689,24 +676,13 @@ namespace Ryujinx.Graphics.Gpu.Memory
? bufferCache.GetBufferRangeTillEnd(bounds.Address, bounds.Size, isWrite)
: bufferCache.GetBufferRange(bounds.Address, bounds.Size);
- if (rangesCount == 0)
- {
- rangesFirst = bindingInfo.Binding;
- }
- else if (bindingInfo.Binding != rangesFirst + rangesCount)
- {
- SetHostBuffers(ranges, rangesFirst, rangesCount, isStorage);
- rangesFirst = bindingInfo.Binding;
- rangesCount = 0;
- }
-
- ranges[rangesCount++] = range;
+ ranges[rangesCount++] = new BufferAssignment(bindingInfo.Binding, range);
}
}
if (rangesCount != 0)
{
- SetHostBuffers(ranges, rangesFirst, rangesCount, isStorage);
+ SetHostBuffers(ranges, rangesCount, isStorage);
}
}
@@ -718,15 +694,15 @@ namespace Ryujinx.Graphics.Gpu.Memory
/// <param name="count">Number of bindings</param>
/// <param name="isStorage">Indicates if the buffers are storage or uniform buffers</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- private void SetHostBuffers(ReadOnlySpan<BufferRange> ranges, int first, int count, bool isStorage)
+ private void SetHostBuffers(ReadOnlySpan<BufferAssignment> ranges, int count, bool isStorage)
{
if (isStorage)
{
- _context.Renderer.Pipeline.SetStorageBuffers(first, ranges.Slice(0, count));
+ _context.Renderer.Pipeline.SetStorageBuffers(ranges.Slice(0, count));
}
else
{
- _context.Renderer.Pipeline.SetUniformBuffers(first, ranges.Slice(0, count));
+ _context.Renderer.Pipeline.SetUniformBuffers(ranges.Slice(0, count));
}
}
diff --git a/Ryujinx.Graphics.OpenGL/Pipeline.cs b/Ryujinx.Graphics.OpenGL/Pipeline.cs
index 3b234eb0..8bcaf4c7 100644
--- a/Ryujinx.Graphics.OpenGL/Pipeline.cs
+++ b/Ryujinx.Graphics.OpenGL/Pipeline.cs
@@ -1296,9 +1296,9 @@ namespace Ryujinx.Graphics.OpenGL
_stencilFrontMask = stencilTest.FrontMask;
}
- public void SetStorageBuffers(int first, ReadOnlySpan<BufferRange> buffers)
+ public void SetStorageBuffers(ReadOnlySpan<BufferAssignment> buffers)
{
- SetBuffers(first, buffers, isStorage: true);
+ SetBuffers(buffers, isStorage: true);
}
public void SetTextureAndSampler(ShaderStage stage, int binding, ITexture texture, ISampler sampler)
@@ -1366,9 +1366,9 @@ namespace Ryujinx.Graphics.OpenGL
}
}
- public void SetUniformBuffers(int first, ReadOnlySpan<BufferRange> buffers)
+ public void SetUniformBuffers(ReadOnlySpan<BufferAssignment> buffers)
{
- SetBuffers(first, buffers, isStorage: false);
+ SetBuffers(buffers, isStorage: false);
}
public void SetUserClipDistance(int index, bool enableClip)
@@ -1460,21 +1460,22 @@ namespace Ryujinx.Graphics.OpenGL
GL.MemoryBarrier(MemoryBarrierFlags.TextureFetchBarrierBit);
}
- private void SetBuffers(int first, ReadOnlySpan<BufferRange> buffers, bool isStorage)
+ private void SetBuffers(ReadOnlySpan<BufferAssignment> buffers, bool isStorage)
{
BufferRangeTarget target = isStorage ? BufferRangeTarget.ShaderStorageBuffer : BufferRangeTarget.UniformBuffer;
for (int index = 0; index < buffers.Length; index++)
{
- BufferRange buffer = buffers[index];
+ BufferAssignment assignment = buffers[index];
+ BufferRange buffer = assignment.Range;
if (buffer.Handle == BufferHandle.Null)
{
- GL.BindBufferRange(target, first + index, 0, IntPtr.Zero, 0);
+ GL.BindBufferRange(target, assignment.Binding, 0, IntPtr.Zero, 0);
continue;
}
- GL.BindBufferRange(target, first + index, buffer.Handle.ToInt32(), (IntPtr)buffer.Offset, buffer.Size);
+ GL.BindBufferRange(target, assignment.Binding, buffer.Handle.ToInt32(), (IntPtr)buffer.Offset, buffer.Size);
}
}
diff --git a/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs b/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs
index 8479bcf7..4cf9ce87 100644
--- a/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs
+++ b/Ryujinx.Graphics.Vulkan/DescriptorSetUpdater.cs
@@ -163,12 +163,13 @@ namespace Ryujinx.Graphics.Vulkan
SignalDirty(DirtyFlags.Image);
}
- public void SetStorageBuffers(CommandBuffer commandBuffer, int first, ReadOnlySpan<BufferRange> buffers)
+ public void SetStorageBuffers(CommandBuffer commandBuffer, ReadOnlySpan<BufferAssignment> buffers)
{
for (int i = 0; i < buffers.Length; i++)
{
- var buffer = buffers[i];
- int index = first + i;
+ var assignment = buffers[i];
+ var buffer = assignment.Range;
+ int index = assignment.Binding;
Auto<DisposableBuffer> vkBuffer = _gd.BufferManager.GetBuffer(commandBuffer, buffer.Handle, false);
ref Auto<DisposableBuffer> currentVkBuffer = ref _storageBufferRefs[index];
@@ -243,12 +244,13 @@ namespace Ryujinx.Graphics.Vulkan
SignalDirty(DirtyFlags.Texture);
}
- public void SetUniformBuffers(CommandBuffer commandBuffer, int first, ReadOnlySpan<BufferRange> buffers)
+ public void SetUniformBuffers(CommandBuffer commandBuffer, ReadOnlySpan<BufferAssignment> buffers)
{
for (int i = 0; i < buffers.Length; i++)
{
- var buffer = buffers[i];
- int index = first + i;
+ var assignment = buffers[i];
+ var buffer = assignment.Range;
+ int index = assignment.Binding;
Auto<DisposableBuffer> vkBuffer = _gd.BufferManager.GetBuffer(commandBuffer, buffer.Handle, false);
ref Auto<DisposableBuffer> currentVkBuffer = ref _uniformBufferRefs[index];
diff --git a/Ryujinx.Graphics.Vulkan/HelperShader.cs b/Ryujinx.Graphics.Vulkan/HelperShader.cs
index 1ef22dc2..076a3baa 100644
--- a/Ryujinx.Graphics.Vulkan/HelperShader.cs
+++ b/Ryujinx.Graphics.Vulkan/HelperShader.cs
@@ -177,7 +177,7 @@ namespace Ryujinx.Graphics.Vulkan
gd.BufferManager.SetData<float>(bufferHandle, 0, region);
- _pipeline.SetUniformBuffers(1, stackalloc[] { new BufferRange(bufferHandle, 0, RegionBufferSize) });
+ _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(1, new BufferRange(bufferHandle, 0, RegionBufferSize)) });
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
@@ -240,7 +240,7 @@ namespace Ryujinx.Graphics.Vulkan
gd.BufferManager.SetData<float>(bufferHandle, 0, clearColor);
- _pipeline.SetUniformBuffers(1, stackalloc[] { new BufferRange(bufferHandle, 0, ClearColorBufferSize) });
+ _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(1, new BufferRange(bufferHandle, 0, ClearColorBufferSize)) });
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
@@ -302,7 +302,7 @@ namespace Ryujinx.Graphics.Vulkan
gd.BufferManager.SetData<float>(bufferHandle, 0, region);
- pipeline.SetUniformBuffers(1, stackalloc[] { new BufferRange(bufferHandle, 0, RegionBufferSize) });
+ pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(1, new BufferRange(bufferHandle, 0, RegionBufferSize)) });
Span<GAL.Viewport> viewports = stackalloc GAL.Viewport[1];
@@ -380,7 +380,7 @@ namespace Ryujinx.Graphics.Vulkan
_pipeline.SetCommandBuffer(cbs);
- _pipeline.SetUniformBuffers(0, stackalloc[] { new BufferRange(bufferHandle, 0, ParamsBufferSize) });
+ _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, new BufferRange(bufferHandle, 0, ParamsBufferSize)) });
Span<Auto<DisposableBuffer>> sbRanges = new Auto<DisposableBuffer>[2];
@@ -571,7 +571,7 @@ namespace Ryujinx.Graphics.Vulkan
int conversionType = srcIsMs ? src.Info.BytesPerPixel : -src.Info.BytesPerPixel;
_pipeline.Specialize(conversionType);
- _pipeline.SetUniformBuffers(0, stackalloc[] { new BufferRange(bufferHandle, 0, ParamsBufferSize) });
+ _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, new BufferRange(bufferHandle, 0, ParamsBufferSize)) });
if (src.Info.Target == Target.Texture2DMultisampleArray ||
dst.Info.Target == Target.Texture2DMultisampleArray)
@@ -776,7 +776,7 @@ namespace Ryujinx.Graphics.Vulkan
srcIndirectBufferOffset,
indirectDataSize);
- _pipeline.SetUniformBuffers(0, stackalloc[] { drawCountBufferAligned });
+ _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, drawCountBufferAligned) });
_pipeline.SetStorageBuffers(1, new[] { srcIndirectBuffer.GetBuffer(), dstIndirectBuffer.GetBuffer(), patternBuffer.GetBuffer() });
_pipeline.SetProgram(_programConvertIndirectData);
@@ -804,7 +804,7 @@ namespace Ryujinx.Graphics.Vulkan
0,
convertedCount * outputIndexSize);
- _pipeline.SetUniformBuffers(0, stackalloc[] { new BufferRange(patternBufferHandle, 0, ParamsBufferSize) });
+ _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, new BufferRange(patternBufferHandle, 0, ParamsBufferSize)) });
_pipeline.SetStorageBuffers(1, new[] { srcIndexBuffer.GetBuffer(), dstIndexBuffer.GetBuffer() });
_pipeline.SetProgram(_programConvertIndexBuffer);
diff --git a/Ryujinx.Graphics.Vulkan/PipelineBase.cs b/Ryujinx.Graphics.Vulkan/PipelineBase.cs
index 5d2263aa..87155a0d 100644
--- a/Ryujinx.Graphics.Vulkan/PipelineBase.cs
+++ b/Ryujinx.Graphics.Vulkan/PipelineBase.cs
@@ -973,9 +973,9 @@ namespace Ryujinx.Graphics.Vulkan
SignalStateChange();
}
- public void SetStorageBuffers(int first, ReadOnlySpan<BufferRange> buffers)
+ public void SetStorageBuffers(ReadOnlySpan<BufferAssignment> buffers)
{
- _descriptorSetUpdater.SetStorageBuffers(CommandBuffer, first, buffers);
+ _descriptorSetUpdater.SetStorageBuffers(CommandBuffer, buffers);
}
public void SetStorageBuffers(int first, ReadOnlySpan<Auto<DisposableBuffer>> buffers)
@@ -1013,9 +1013,9 @@ namespace Ryujinx.Graphics.Vulkan
}
}
- public void SetUniformBuffers(int first, ReadOnlySpan<BufferRange> buffers)
+ public void SetUniformBuffers(ReadOnlySpan<BufferAssignment> buffers)
{
- _descriptorSetUpdater.SetUniformBuffers(CommandBuffer, first, buffers);
+ _descriptorSetUpdater.SetUniformBuffers(CommandBuffer, buffers);
}
public void SetUserClipDistance(int index, bool enableClip)