mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-07-07 13:56:26 +02:00
Move support buffer update out of the backends (#5411)
* Move support buffer update out of the backends * Fix render scale init and remove redundant state from SupportBufferUpdater * Stop passing texture scale to the backends * XML docs for SupportBufferUpdater
This commit is contained in:
parent
fa32ef9275
commit
9c6071a645
51 changed files with 364 additions and 496 deletions
|
@ -79,7 +79,6 @@ namespace Ryujinx.Graphics.GAL
|
|||
|
||||
void SetRasterizerDiscard(bool discard);
|
||||
|
||||
void SetRenderTargetScale(float scale);
|
||||
void SetRenderTargetColorMasks(ReadOnlySpan<uint> componentMask);
|
||||
void SetRenderTargets(ITexture[] colors, ITexture depthStencil);
|
||||
|
||||
|
@ -99,7 +98,7 @@ namespace Ryujinx.Graphics.GAL
|
|||
void SetVertexAttribs(ReadOnlySpan<VertexAttribDescriptor> vertexAttribs);
|
||||
void SetVertexBuffers(ReadOnlySpan<VertexBufferDescriptor> vertexBuffers);
|
||||
|
||||
void SetViewports(ReadOnlySpan<Viewport> viewports, bool disableTransform);
|
||||
void SetViewports(ReadOnlySpan<Viewport> viewports);
|
||||
|
||||
void TextureBarrier();
|
||||
void TextureBarrierTiled();
|
||||
|
@ -107,7 +106,5 @@ namespace Ryujinx.Graphics.GAL
|
|||
bool TryHostConditionalRendering(ICounterEvent value, ulong compare, bool isEqual);
|
||||
bool TryHostConditionalRendering(ICounterEvent value, ICounterEvent compare, bool isEqual);
|
||||
void EndHostConditionalRendering();
|
||||
|
||||
void UpdateRenderScale(ReadOnlySpan<float> scales, int totalCount, int fragmentCount);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ namespace Ryujinx.Graphics.GAL
|
|||
void BackgroundContextAction(Action action, bool alwaysBackground = false);
|
||||
|
||||
BufferHandle CreateBuffer(int size, BufferHandle storageHint);
|
||||
|
||||
BufferHandle CreateBuffer(int size)
|
||||
{
|
||||
return CreateBuffer(size, BufferHandle.Null);
|
||||
|
@ -28,7 +27,7 @@ namespace Ryujinx.Graphics.GAL
|
|||
IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info);
|
||||
|
||||
ISampler CreateSampler(SamplerCreateInfo info);
|
||||
ITexture CreateTexture(TextureCreateInfo info, float scale);
|
||||
ITexture CreateTexture(TextureCreateInfo info);
|
||||
bool PrepareHostMapping(nint address, ulong size);
|
||||
|
||||
void CreateSync(ulong id, bool strict);
|
||||
|
@ -49,7 +48,7 @@ namespace Ryujinx.Graphics.GAL
|
|||
|
||||
void PreFrame();
|
||||
|
||||
ICounterEvent ReportCounter(CounterType type, EventHandler<ulong> resultHandler, bool hostReserved);
|
||||
ICounterEvent ReportCounter(CounterType type, EventHandler<ulong> resultHandler, float divisor, bool hostReserved);
|
||||
|
||||
void ResetCounter(CounterType type);
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ namespace Ryujinx.Graphics.GAL
|
|||
{
|
||||
int Width { get; }
|
||||
int Height { get; }
|
||||
float ScaleFactor { get; }
|
||||
|
||||
void CopyTo(ITexture destination, int firstLayer, int firstLevel);
|
||||
void CopyTo(ITexture destination, int srcLayer, int dstLayer, int srcLevel, int dstLevel);
|
||||
|
|
|
@ -125,7 +125,6 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||
Register<SetProgramCommand>(CommandType.SetProgram);
|
||||
Register<SetRasterizerDiscardCommand>(CommandType.SetRasterizerDiscard);
|
||||
Register<SetRenderTargetColorMasksCommand>(CommandType.SetRenderTargetColorMasks);
|
||||
Register<SetRenderTargetScaleCommand>(CommandType.SetRenderTargetScale);
|
||||
Register<SetRenderTargetsCommand>(CommandType.SetRenderTargets);
|
||||
Register<SetScissorsCommand>(CommandType.SetScissor);
|
||||
Register<SetStencilTestCommand>(CommandType.SetStencilTest);
|
||||
|
@ -138,7 +137,6 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||
Register<TextureBarrierTiledCommand>(CommandType.TextureBarrierTiled);
|
||||
Register<TryHostConditionalRenderingCommand>(CommandType.TryHostConditionalRendering);
|
||||
Register<TryHostConditionalRenderingFlushCommand>(CommandType.TryHostConditionalRenderingFlush);
|
||||
Register<UpdateRenderScaleCommand>(CommandType.UpdateRenderScale);
|
||||
|
||||
return maxCommandSize;
|
||||
}
|
||||
|
|
|
@ -87,7 +87,6 @@
|
|||
SetProgram,
|
||||
SetRasterizerDiscard,
|
||||
SetRenderTargetColorMasks,
|
||||
SetRenderTargetScale,
|
||||
SetRenderTargets,
|
||||
SetScissor,
|
||||
SetStencilTest,
|
||||
|
@ -100,6 +99,5 @@
|
|||
TextureBarrierTiled,
|
||||
TryHostConditionalRendering,
|
||||
TryHostConditionalRenderingFlush,
|
||||
UpdateRenderScale,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,18 +8,16 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
|
|||
public readonly CommandType CommandType => CommandType.CreateTexture;
|
||||
private TableRef<ThreadedTexture> _texture;
|
||||
private TextureCreateInfo _info;
|
||||
private float _scale;
|
||||
|
||||
public void Set(TableRef<ThreadedTexture> texture, TextureCreateInfo info, float scale)
|
||||
public void Set(TableRef<ThreadedTexture> texture, TextureCreateInfo info)
|
||||
{
|
||||
_texture = texture;
|
||||
_info = info;
|
||||
_scale = scale;
|
||||
}
|
||||
|
||||
public static void Run(ref CreateTextureCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
command._texture.Get(threaded).Base = renderer.CreateTexture(command._info, command._scale);
|
||||
command._texture.Get(threaded).Base = renderer.CreateTexture(command._info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,13 +10,15 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
|
|||
private TableRef<ThreadedCounterEvent> _event;
|
||||
private CounterType _type;
|
||||
private TableRef<EventHandler<ulong>> _resultHandler;
|
||||
private float _divisor;
|
||||
private bool _hostReserved;
|
||||
|
||||
public void Set(TableRef<ThreadedCounterEvent> evt, CounterType type, TableRef<EventHandler<ulong>> resultHandler, bool hostReserved)
|
||||
public void Set(TableRef<ThreadedCounterEvent> evt, CounterType type, TableRef<EventHandler<ulong>> resultHandler, float divisor, bool hostReserved)
|
||||
{
|
||||
_event = evt;
|
||||
_type = type;
|
||||
_resultHandler = resultHandler;
|
||||
_divisor = divisor;
|
||||
_hostReserved = hostReserved;
|
||||
}
|
||||
|
||||
|
@ -24,7 +26,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands.Renderer
|
|||
{
|
||||
ThreadedCounterEvent evt = command._event.Get(threaded);
|
||||
|
||||
evt.Create(renderer, command._type, command._resultHandler.Get(threaded), command._hostReserved);
|
||||
evt.Create(renderer, command._type, command._resultHandler.Get(threaded), command._divisor, command._hostReserved);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct SetRenderTargetScaleCommand : IGALCommand, IGALCommand<SetRenderTargetScaleCommand>
|
||||
{
|
||||
public readonly CommandType CommandType => CommandType.SetRenderTargetScale;
|
||||
private float _scale;
|
||||
|
||||
public void Set(float scale)
|
||||
{
|
||||
_scale = scale;
|
||||
}
|
||||
|
||||
public static void Run(ref SetRenderTargetScaleCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.SetRenderTargetScale(command._scale);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,18 +7,16 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
|||
{
|
||||
public readonly CommandType CommandType => CommandType.SetViewports;
|
||||
private SpanRef<Viewport> _viewports;
|
||||
private bool _disableTransform;
|
||||
|
||||
public void Set(SpanRef<Viewport> viewports, bool disableTransform)
|
||||
public void Set(SpanRef<Viewport> viewports)
|
||||
{
|
||||
_viewports = viewports;
|
||||
_disableTransform = disableTransform;
|
||||
}
|
||||
|
||||
public static void Run(ref SetViewportsCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
ReadOnlySpan<Viewport> viewports = command._viewports.Get(threaded);
|
||||
renderer.Pipeline.SetViewports(viewports, command._disableTransform);
|
||||
renderer.Pipeline.SetViewports(viewports);
|
||||
command._viewports.Dispose(threaded);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||
{
|
||||
struct UpdateRenderScaleCommand : IGALCommand, IGALCommand<UpdateRenderScaleCommand>
|
||||
{
|
||||
public readonly CommandType CommandType => CommandType.UpdateRenderScale;
|
||||
private SpanRef<float> _scales;
|
||||
private int _totalCount;
|
||||
private int _fragmentCount;
|
||||
|
||||
public void Set(SpanRef<float> scales, int totalCount, int fragmentCount)
|
||||
{
|
||||
_scales = scales;
|
||||
_totalCount = totalCount;
|
||||
_fragmentCount = fragmentCount;
|
||||
}
|
||||
|
||||
public static void Run(ref UpdateRenderScaleCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||
{
|
||||
renderer.Pipeline.UpdateRenderScale(command._scales.Get(threaded), command._totalCount, command._fragmentCount);
|
||||
command._scales.Dispose(threaded);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -70,10 +70,10 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Resources
|
|||
}
|
||||
}
|
||||
|
||||
public void Create(IRenderer renderer, CounterType type, System.EventHandler<ulong> eventHandler, bool hostReserved)
|
||||
public void Create(IRenderer renderer, CounterType type, System.EventHandler<ulong> eventHandler, float divisor, bool hostReserved)
|
||||
{
|
||||
ThreadedHelpers.SpinUntilExchange(ref _createLock, 1, 0);
|
||||
Base = renderer.ReportCounter(type, eventHandler, hostReserved || _reserved);
|
||||
Base = renderer.ReportCounter(type, eventHandler, divisor, hostReserved || _reserved);
|
||||
Volatile.Write(ref _createLock, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,13 +17,10 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Resources
|
|||
|
||||
public int Height => _info.Height;
|
||||
|
||||
public float ScaleFactor { get; }
|
||||
|
||||
public ThreadedTexture(ThreadedRenderer renderer, TextureCreateInfo info, float scale)
|
||||
public ThreadedTexture(ThreadedRenderer renderer, TextureCreateInfo info)
|
||||
{
|
||||
_renderer = renderer;
|
||||
_info = info;
|
||||
ScaleFactor = scale;
|
||||
}
|
||||
|
||||
private TableRef<T> Ref<T>(T reference)
|
||||
|
@ -64,7 +61,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Resources
|
|||
|
||||
public ITexture CreateView(TextureCreateInfo info, int firstLayer, int firstLevel)
|
||||
{
|
||||
ThreadedTexture newTex = new(_renderer, info, ScaleFactor);
|
||||
ThreadedTexture newTex = new(_renderer, info);
|
||||
_renderer.New<TextureCreateViewCommand>().Set(Ref(this), Ref(newTex), info, firstLayer, firstLevel);
|
||||
_renderer.QueueCommand();
|
||||
|
||||
|
|
|
@ -261,12 +261,6 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||
_renderer.QueueCommand();
|
||||
}
|
||||
|
||||
public void SetRenderTargetScale(float scale)
|
||||
{
|
||||
_renderer.New<SetRenderTargetScaleCommand>().Set(scale);
|
||||
_renderer.QueueCommand();
|
||||
}
|
||||
|
||||
public void SetScissors(ReadOnlySpan<Rectangle<int>> scissors)
|
||||
{
|
||||
_renderer.New<SetScissorsCommand>().Set(_renderer.CopySpan(scissors));
|
||||
|
@ -321,9 +315,9 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||
_renderer.QueueCommand();
|
||||
}
|
||||
|
||||
public void SetViewports(ReadOnlySpan<Viewport> viewports, bool disableTransform)
|
||||
public void SetViewports(ReadOnlySpan<Viewport> viewports)
|
||||
{
|
||||
_renderer.New<SetViewportsCommand>().Set(_renderer.CopySpan(viewports), disableTransform);
|
||||
_renderer.New<SetViewportsCommand>().Set(_renderer.CopySpan(viewports));
|
||||
_renderer.QueueCommand();
|
||||
}
|
||||
|
||||
|
@ -368,11 +362,5 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||
_renderer.QueueCommand();
|
||||
return false;
|
||||
}
|
||||
|
||||
public void UpdateRenderScale(ReadOnlySpan<float> scales, int totalCount, int fragmentCount)
|
||||
{
|
||||
_renderer.New<UpdateRenderScaleCommand>().Set(_renderer.CopySpan(scales[..totalCount]), totalCount, fragmentCount);
|
||||
_renderer.QueueCommand();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -320,21 +320,21 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||
QueueCommand();
|
||||
}
|
||||
|
||||
public ITexture CreateTexture(TextureCreateInfo info, float scale)
|
||||
public ITexture CreateTexture(TextureCreateInfo info)
|
||||
{
|
||||
if (IsGpuThread())
|
||||
{
|
||||
var texture = new ThreadedTexture(this, info, scale);
|
||||
New<CreateTextureCommand>().Set(Ref(texture), info, scale);
|
||||
var texture = new ThreadedTexture(this, info);
|
||||
New<CreateTextureCommand>().Set(Ref(texture), info);
|
||||
QueueCommand();
|
||||
|
||||
return texture;
|
||||
}
|
||||
else
|
||||
{
|
||||
var texture = new ThreadedTexture(this, info, scale)
|
||||
var texture = new ThreadedTexture(this, info)
|
||||
{
|
||||
Base = _baseRenderer.CreateTexture(info, scale),
|
||||
Base = _baseRenderer.CreateTexture(info),
|
||||
};
|
||||
|
||||
return texture;
|
||||
|
@ -410,10 +410,10 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||
QueueCommand();
|
||||
}
|
||||
|
||||
public ICounterEvent ReportCounter(CounterType type, EventHandler<ulong> resultHandler, bool hostReserved)
|
||||
public ICounterEvent ReportCounter(CounterType type, EventHandler<ulong> resultHandler, float divisor, bool hostReserved)
|
||||
{
|
||||
ThreadedCounterEvent evt = new(this, type, _lastSampleCounterClear);
|
||||
New<ReportCounterCommand>().Set(Ref(evt), type, Ref(resultHandler), hostReserved);
|
||||
ThreadedCounterEvent evt = new ThreadedCounterEvent(this, type, _lastSampleCounterClear);
|
||||
New<ReportCounterCommand>().Set(Ref(evt), type, Ref(resultHandler), divisor, hostReserved);
|
||||
QueueCommand();
|
||||
|
||||
if (type == CounterType.SamplesPassed)
|
||||
|
|
|
@ -1,102 +0,0 @@
|
|||
using Ryujinx.Graphics.Shader;
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL
|
||||
{
|
||||
public class SupportBufferUpdater : IDisposable
|
||||
{
|
||||
public SupportBuffer Data;
|
||||
public BufferHandle Handle;
|
||||
|
||||
private readonly IRenderer _renderer;
|
||||
private int _startOffset = -1;
|
||||
private int _endOffset = -1;
|
||||
|
||||
public SupportBufferUpdater(IRenderer renderer)
|
||||
{
|
||||
_renderer = renderer;
|
||||
Handle = renderer.CreateBuffer(SupportBuffer.RequiredSize);
|
||||
renderer.Pipeline.ClearBuffer(Handle, 0, SupportBuffer.RequiredSize, 0);
|
||||
}
|
||||
|
||||
private void MarkDirty(int startOffset, int byteSize)
|
||||
{
|
||||
int endOffset = startOffset + byteSize;
|
||||
|
||||
if (_startOffset == -1)
|
||||
{
|
||||
_startOffset = startOffset;
|
||||
_endOffset = endOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (startOffset < _startOffset)
|
||||
{
|
||||
_startOffset = startOffset;
|
||||
}
|
||||
|
||||
if (endOffset > _endOffset)
|
||||
{
|
||||
_endOffset = endOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateFragmentRenderScaleCount(int count)
|
||||
{
|
||||
if (Data.FragmentRenderScaleCount.X != count)
|
||||
{
|
||||
Data.FragmentRenderScaleCount.X = count;
|
||||
|
||||
MarkDirty(SupportBuffer.FragmentRenderScaleCountOffset, sizeof(int));
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateGenericField<T>(int baseOffset, ReadOnlySpan<T> data, Span<T> target, int offset, int count) where T : unmanaged
|
||||
{
|
||||
data[..count].CopyTo(target[offset..]);
|
||||
|
||||
int elemSize = Unsafe.SizeOf<T>();
|
||||
|
||||
MarkDirty(baseOffset + offset * elemSize, count * elemSize);
|
||||
}
|
||||
|
||||
public void UpdateRenderScale(ReadOnlySpan<Vector4<float>> data, int offset, int count)
|
||||
{
|
||||
UpdateGenericField(SupportBuffer.GraphicsRenderScaleOffset, data, Data.RenderScale.AsSpan(), offset, count);
|
||||
}
|
||||
|
||||
public void UpdateFragmentIsBgra(ReadOnlySpan<Vector4<int>> data, int offset, int count)
|
||||
{
|
||||
UpdateGenericField(SupportBuffer.FragmentIsBgraOffset, data, Data.FragmentIsBgra.AsSpan(), offset, count);
|
||||
}
|
||||
|
||||
public void UpdateViewportInverse(Vector4<float> data)
|
||||
{
|
||||
Data.ViewportInverse = data;
|
||||
|
||||
MarkDirty(SupportBuffer.ViewportInverseOffset, SupportBuffer.FieldSize);
|
||||
}
|
||||
|
||||
public void Commit()
|
||||
{
|
||||
if (_startOffset != -1)
|
||||
{
|
||||
ReadOnlySpan<byte> data = MemoryMarshal.Cast<SupportBuffer, byte>(MemoryMarshal.CreateSpan(ref Data, 1));
|
||||
|
||||
_renderer.SetBufferData(Handle, _startOffset, data[_startOffset.._endOffset]);
|
||||
|
||||
_startOffset = -1;
|
||||
_endOffset = -1;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
_renderer.DeleteBuffer(Handle);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue