mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-12-12 07:36:59 +00:00
gpu allocation optimizations (ryubing/ryujinx!195)
See merge request ryubing/ryujinx!195
This commit is contained in:
parent
718652599d
commit
c94ffaa00a
20 changed files with 297 additions and 234 deletions
|
|
@ -99,7 +99,6 @@ namespace Ryujinx.Audio.Renderer.Server
|
||||||
break;
|
break;
|
||||||
case CommandType.BiquadFilterFloatCoeff:
|
case CommandType.BiquadFilterFloatCoeff:
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
break;
|
|
||||||
case CommandType.Mix:
|
case CommandType.Mix:
|
||||||
_mixCommandPool.Release((MixCommand)command);
|
_mixCommandPool.Release((MixCommand)command);
|
||||||
break;
|
break;
|
||||||
|
|
@ -159,7 +158,6 @@ namespace Ryujinx.Audio.Renderer.Server
|
||||||
break;
|
break;
|
||||||
case CommandType.MultiTapBiquadFilterFloatCoeff:
|
case CommandType.MultiTapBiquadFilterFloatCoeff:
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
break;
|
|
||||||
case CommandType.CaptureBuffer:
|
case CommandType.CaptureBuffer:
|
||||||
_captureBufferCommandPool.Release((CaptureBufferCommand)command);
|
_captureBufferCommandPool.Release((CaptureBufferCommand)command);
|
||||||
break;
|
break;
|
||||||
|
|
@ -171,25 +169,19 @@ namespace Ryujinx.Audio.Renderer.Server
|
||||||
break;
|
break;
|
||||||
case CommandType.BiquadFilterAndMixFloatCoeff:
|
case CommandType.BiquadFilterAndMixFloatCoeff:
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
break;
|
|
||||||
case CommandType.MultiTapBiquadFilterAndMix:
|
case CommandType.MultiTapBiquadFilterAndMix:
|
||||||
_multiTapBiquadFilterAndMixCommandPool.Release((MultiTapBiquadFilterAndMixCommand)command);
|
_multiTapBiquadFilterAndMixCommandPool.Release((MultiTapBiquadFilterAndMixCommand)command);
|
||||||
break;
|
break;
|
||||||
case CommandType.MultiTapBiquadFilterAndMixFloatCoef:
|
case CommandType.MultiTapBiquadFilterAndMixFloatCoef:
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
break;
|
|
||||||
case CommandType.AuxiliaryBufferGrouped:
|
case CommandType.AuxiliaryBufferGrouped:
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
break;
|
|
||||||
case CommandType.FillMixBuffer:
|
case CommandType.FillMixBuffer:
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
break;
|
|
||||||
case CommandType.BiquadFilterCrossFade:
|
case CommandType.BiquadFilterCrossFade:
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
break;
|
|
||||||
case CommandType.MultiTapBiquadFilterCrossFade:
|
case CommandType.MultiTapBiquadFilterCrossFade:
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
break;
|
|
||||||
case CommandType.FillBuffer:
|
case CommandType.FillBuffer:
|
||||||
_fillBufferCommandPool.Release((FillBufferCommand)command);
|
_fillBufferCommandPool.Release((FillBufferCommand)command);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,11 @@ namespace Ryujinx.Common
|
||||||
where T : class
|
where T : class
|
||||||
{
|
{
|
||||||
private int _size = size;
|
private int _size = size;
|
||||||
private readonly ConcurrentStack<T> _items = new();
|
private readonly ConcurrentBag<T> _items = new();
|
||||||
|
|
||||||
public T Allocate()
|
public T Allocate()
|
||||||
{
|
{
|
||||||
bool success = _items.TryPop(out T instance);
|
bool success = _items.TryTake(out T instance);
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
|
|
@ -25,7 +25,7 @@ namespace Ryujinx.Common
|
||||||
{
|
{
|
||||||
if (_size < 0 || _items.Count < _size)
|
if (_size < 0 || _items.Count < _size)
|
||||||
{
|
{
|
||||||
_items.Push(obj);
|
_items.Add(obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,11 @@ namespace Ryujinx.Cpu.AppleHv
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool TryReadUnsafe(ulong va, int length, out Span<byte> data)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
public override void Write(ulong va, ReadOnlySpan<byte> data)
|
public override void Write(ulong va, ReadOnlySpan<byte> data)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
||||||
|
|
@ -175,6 +175,11 @@ namespace Ryujinx.Cpu.Jit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool TryReadUnsafe(ulong va, int length, out Span<byte> data)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
public override void Write(ulong va, ReadOnlySpan<byte> data)
|
public override void Write(ulong va, ReadOnlySpan<byte> data)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,11 @@ namespace Ryujinx.Cpu.Jit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool TryReadUnsafe(ulong va, int length, out Span<byte> data)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
public override T ReadTracked<T>(ulong va)
|
public override T ReadTracked<T>(ulong va)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
||||||
|
|
@ -228,6 +228,11 @@ namespace Ryujinx.Cpu.Jit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool TryReadUnsafe(ulong va, int length, out Span<byte> data)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
public override bool WriteWithRedundancyCheck(ulong va, ReadOnlySpan<byte> data)
|
public override bool WriteWithRedundancyCheck(ulong va, ReadOnlySpan<byte> data)
|
||||||
{
|
{
|
||||||
if (data.Length == 0)
|
if (data.Length == 0)
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,9 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Resources
|
||||||
return new TableRef<T>(_renderer, reference);
|
return new TableRef<T>(_renderer, reference);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public unsafe void Dispose()
|
||||||
{
|
{
|
||||||
_renderer.New<CounterEventDisposeCommand>().Set(Ref(this));
|
_renderer.New<CounterEventDisposeCommand>()->Set(Ref(this));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,15 +21,15 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Resources
|
||||||
return new TableRef<T>(_renderer, reference);
|
return new TableRef<T>(_renderer, reference);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public unsafe void Dispose()
|
||||||
{
|
{
|
||||||
_renderer.New<ImageArrayDisposeCommand>().Set(Ref(this));
|
_renderer.New<ImageArrayDisposeCommand>()->Set(Ref(this));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetImages(int index, ITexture[] images)
|
public unsafe void SetImages(int index, ITexture[] images)
|
||||||
{
|
{
|
||||||
_renderer.New<ImageArraySetImagesCommand>().Set(Ref(this), index, Ref(images));
|
_renderer.New<ImageArraySetImagesCommand>()->Set(Ref(this), index, Ref(images));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,25 +21,25 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Resources
|
||||||
return new TableRef<T>(_renderer, reference);
|
return new TableRef<T>(_renderer, reference);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public unsafe void Dispose()
|
||||||
{
|
{
|
||||||
_renderer.New<ProgramDisposeCommand>().Set(Ref(this));
|
_renderer.New<ProgramDisposeCommand>()->Set(Ref(this));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] GetBinary()
|
public unsafe byte[] GetBinary()
|
||||||
{
|
{
|
||||||
ResultBox<byte[]> box = new();
|
ResultBox<byte[]> box = new();
|
||||||
_renderer.New<ProgramGetBinaryCommand>().Set(Ref(this), Ref(box));
|
_renderer.New<ProgramGetBinaryCommand>()->Set(Ref(this), Ref(box));
|
||||||
_renderer.InvokeCommand();
|
_renderer.InvokeCommand();
|
||||||
|
|
||||||
return box.Result;
|
return box.Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProgramLinkStatus CheckProgramLink(bool blocking)
|
public unsafe ProgramLinkStatus CheckProgramLink(bool blocking)
|
||||||
{
|
{
|
||||||
ResultBox<ProgramLinkStatus> box = new();
|
ResultBox<ProgramLinkStatus> box = new();
|
||||||
_renderer.New<ProgramCheckLinkCommand>().Set(Ref(this), blocking, Ref(box));
|
_renderer.New<ProgramCheckLinkCommand>()->Set(Ref(this), blocking, Ref(box));
|
||||||
_renderer.InvokeCommand();
|
_renderer.InvokeCommand();
|
||||||
|
|
||||||
return box.Result;
|
return box.Result;
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,9 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Resources
|
||||||
_renderer = renderer;
|
_renderer = renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public unsafe void Dispose()
|
||||||
{
|
{
|
||||||
_renderer.New<SamplerDisposeCommand>().Set(new TableRef<ThreadedSampler>(_renderer, this));
|
_renderer.New<SamplerDisposeCommand>()->Set(new TableRef<ThreadedSampler>(_renderer, this));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,25 +28,25 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Resources
|
||||||
return new TableRef<T>(_renderer, reference);
|
return new TableRef<T>(_renderer, reference);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CopyTo(ITexture destination, int firstLayer, int firstLevel)
|
public unsafe void CopyTo(ITexture destination, int firstLayer, int firstLevel)
|
||||||
{
|
{
|
||||||
_renderer.New<TextureCopyToCommand>().Set(Ref(this), Ref((ThreadedTexture)destination), firstLayer, firstLevel);
|
_renderer.New<TextureCopyToCommand>()->Set(Ref(this), Ref((ThreadedTexture)destination), firstLayer, firstLevel);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CopyTo(ITexture destination, int srcLayer, int dstLayer, int srcLevel, int dstLevel)
|
public unsafe void CopyTo(ITexture destination, int srcLayer, int dstLayer, int srcLevel, int dstLevel)
|
||||||
{
|
{
|
||||||
_renderer.New<TextureCopyToSliceCommand>().Set(Ref(this), Ref((ThreadedTexture)destination), srcLayer, dstLayer, srcLevel, dstLevel);
|
_renderer.New<TextureCopyToSliceCommand>()->Set(Ref(this), Ref((ThreadedTexture)destination), srcLayer, dstLayer, srcLevel, dstLevel);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CopyTo(ITexture destination, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter)
|
public unsafe void CopyTo(ITexture destination, Extents2D srcRegion, Extents2D dstRegion, bool linearFilter)
|
||||||
{
|
{
|
||||||
ThreadedTexture dest = (ThreadedTexture)destination;
|
ThreadedTexture dest = (ThreadedTexture)destination;
|
||||||
|
|
||||||
if (_renderer.IsGpuThread())
|
if (_renderer.IsGpuThread())
|
||||||
{
|
{
|
||||||
_renderer.New<TextureCopyToScaledCommand>().Set(Ref(this), Ref(dest), srcRegion, dstRegion, linearFilter);
|
_renderer.New<TextureCopyToScaledCommand>()->Set(Ref(this), Ref(dest), srcRegion, dstRegion, linearFilter);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -59,21 +59,21 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Resources
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ITexture CreateView(TextureCreateInfo info, int firstLayer, int firstLevel)
|
public unsafe ITexture CreateView(TextureCreateInfo info, int firstLayer, int firstLevel)
|
||||||
{
|
{
|
||||||
ThreadedTexture newTex = new(_renderer, info);
|
ThreadedTexture newTex = new(_renderer, info);
|
||||||
_renderer.New<TextureCreateViewCommand>().Set(Ref(this), Ref(newTex), info, firstLayer, firstLevel);
|
_renderer.New<TextureCreateViewCommand>()->Set(Ref(this), Ref(newTex), info, firstLayer, firstLevel);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
|
|
||||||
return newTex;
|
return newTex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PinnedSpan<byte> GetData()
|
public unsafe PinnedSpan<byte> GetData()
|
||||||
{
|
{
|
||||||
if (_renderer.IsGpuThread())
|
if (_renderer.IsGpuThread())
|
||||||
{
|
{
|
||||||
ResultBox<PinnedSpan<byte>> box = new();
|
ResultBox<PinnedSpan<byte>> box = new();
|
||||||
_renderer.New<TextureGetDataCommand>().Set(Ref(this), Ref(box));
|
_renderer.New<TextureGetDataCommand>()->Set(Ref(this), Ref(box));
|
||||||
_renderer.InvokeCommand();
|
_renderer.InvokeCommand();
|
||||||
|
|
||||||
return box.Result;
|
return box.Result;
|
||||||
|
|
@ -86,12 +86,12 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Resources
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public PinnedSpan<byte> GetData(int layer, int level)
|
public unsafe PinnedSpan<byte> GetData(int layer, int level)
|
||||||
{
|
{
|
||||||
if (_renderer.IsGpuThread())
|
if (_renderer.IsGpuThread())
|
||||||
{
|
{
|
||||||
ResultBox<PinnedSpan<byte>> box = new();
|
ResultBox<PinnedSpan<byte>> box = new();
|
||||||
_renderer.New<TextureGetDataSliceCommand>().Set(Ref(this), Ref(box), layer, level);
|
_renderer.New<TextureGetDataSliceCommand>()->Set(Ref(this), Ref(box), layer, level);
|
||||||
_renderer.InvokeCommand();
|
_renderer.InvokeCommand();
|
||||||
|
|
||||||
return box.Result;
|
return box.Result;
|
||||||
|
|
@ -104,42 +104,42 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Resources
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CopyTo(BufferRange range, int layer, int level, int stride)
|
public unsafe void CopyTo(BufferRange range, int layer, int level, int stride)
|
||||||
{
|
{
|
||||||
_renderer.New<TextureCopyToBufferCommand>().Set(Ref(this), range, layer, level, stride);
|
_renderer.New<TextureCopyToBufferCommand>()->Set(Ref(this), range, layer, level, stride);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void SetData(MemoryOwner<byte> data)
|
public unsafe void SetData(MemoryOwner<byte> data)
|
||||||
{
|
{
|
||||||
_renderer.New<TextureSetDataCommand>().Set(Ref(this), Ref(data));
|
_renderer.New<TextureSetDataCommand>()->Set(Ref(this), Ref(data));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void SetData(MemoryOwner<byte> data, int layer, int level)
|
public unsafe void SetData(MemoryOwner<byte> data, int layer, int level)
|
||||||
{
|
{
|
||||||
_renderer.New<TextureSetDataSliceCommand>().Set(Ref(this), Ref(data), layer, level);
|
_renderer.New<TextureSetDataSliceCommand>()->Set(Ref(this), Ref(data), layer, level);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void SetData(MemoryOwner<byte> data, int layer, int level, Rectangle<int> region)
|
public unsafe void SetData(MemoryOwner<byte> data, int layer, int level, Rectangle<int> region)
|
||||||
{
|
{
|
||||||
_renderer.New<TextureSetDataSliceRegionCommand>().Set(Ref(this), Ref(data), layer, level, region);
|
_renderer.New<TextureSetDataSliceRegionCommand>()->Set(Ref(this), Ref(data), layer, level, region);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetStorage(BufferRange buffer)
|
public unsafe void SetStorage(BufferRange buffer)
|
||||||
{
|
{
|
||||||
_renderer.New<TextureSetStorageCommand>().Set(Ref(this), buffer);
|
_renderer.New<TextureSetStorageCommand>()->Set(Ref(this), buffer);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Release()
|
public unsafe void Release()
|
||||||
{
|
{
|
||||||
_renderer.New<TextureReleaseCommand>().Set(Ref(this));
|
_renderer.New<TextureReleaseCommand>()->Set(Ref(this));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,21 +22,21 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Resources
|
||||||
return new TableRef<T>(_renderer, reference);
|
return new TableRef<T>(_renderer, reference);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public unsafe void Dispose()
|
||||||
{
|
{
|
||||||
_renderer.New<TextureArrayDisposeCommand>().Set(Ref(this));
|
_renderer.New<TextureArrayDisposeCommand>()->Set(Ref(this));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetSamplers(int index, ISampler[] samplers)
|
public unsafe void SetSamplers(int index, ISampler[] samplers)
|
||||||
{
|
{
|
||||||
_renderer.New<TextureArraySetSamplersCommand>().Set(Ref(this), index, Ref(samplers.ToArray()));
|
_renderer.New<TextureArraySetSamplersCommand>()->Set(Ref(this), index, Ref(samplers.ToArray()));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetTextures(int index, ITexture[] textures)
|
public unsafe void SetTextures(int index, ITexture[] textures)
|
||||||
{
|
{
|
||||||
_renderer.New<TextureArraySetTexturesCommand>().Set(Ref(this), index, Ref(textures.ToArray()));
|
_renderer.New<TextureArraySetTexturesCommand>()->Set(Ref(this), index, Ref(textures.ToArray()));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,343 +21,343 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
||||||
return new TableRef<T>(_renderer, reference);
|
return new TableRef<T>(_renderer, reference);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Barrier()
|
public unsafe void Barrier()
|
||||||
{
|
{
|
||||||
_renderer.New<BarrierCommand>();
|
_renderer.New<BarrierCommand>();
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BeginTransformFeedback(PrimitiveTopology topology)
|
public unsafe void BeginTransformFeedback(PrimitiveTopology topology)
|
||||||
{
|
{
|
||||||
_renderer.New<BeginTransformFeedbackCommand>().Set(topology);
|
_renderer.New<BeginTransformFeedbackCommand>()->Set(topology);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearBuffer(BufferHandle destination, int offset, int size, uint value)
|
public unsafe void ClearBuffer(BufferHandle destination, int offset, int size, uint value)
|
||||||
{
|
{
|
||||||
_renderer.New<ClearBufferCommand>().Set(destination, offset, size, value);
|
_renderer.New<ClearBufferCommand>()->Set(destination, offset, size, value);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearRenderTargetColor(int index, int layer, int layerCount, uint componentMask, ColorF color)
|
public unsafe void ClearRenderTargetColor(int index, int layer, int layerCount, uint componentMask, ColorF color)
|
||||||
{
|
{
|
||||||
_renderer.New<ClearRenderTargetColorCommand>().Set(index, layer, layerCount, componentMask, color);
|
_renderer.New<ClearRenderTargetColorCommand>()->Set(index, layer, layerCount, componentMask, color);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearRenderTargetDepthStencil(int layer, int layerCount, float depthValue, bool depthMask, int stencilValue, int stencilMask)
|
public unsafe void ClearRenderTargetDepthStencil(int layer, int layerCount, float depthValue, bool depthMask, int stencilValue, int stencilMask)
|
||||||
{
|
{
|
||||||
_renderer.New<ClearRenderTargetDepthStencilCommand>().Set(layer, layerCount, depthValue, depthMask, stencilValue, stencilMask);
|
_renderer.New<ClearRenderTargetDepthStencilCommand>()->Set(layer, layerCount, depthValue, depthMask, stencilValue, stencilMask);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CommandBufferBarrier()
|
public unsafe void CommandBufferBarrier()
|
||||||
{
|
{
|
||||||
_renderer.New<CommandBufferBarrierCommand>();
|
_renderer.New<CommandBufferBarrierCommand>();
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CopyBuffer(BufferHandle source, BufferHandle destination, int srcOffset, int dstOffset, int size)
|
public unsafe void CopyBuffer(BufferHandle source, BufferHandle destination, int srcOffset, int dstOffset, int size)
|
||||||
{
|
{
|
||||||
_renderer.New<CopyBufferCommand>().Set(source, destination, srcOffset, dstOffset, size);
|
_renderer.New<CopyBufferCommand>()->Set(source, destination, srcOffset, dstOffset, size);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DispatchCompute(int groupsX, int groupsY, int groupsZ)
|
public unsafe void DispatchCompute(int groupsX, int groupsY, int groupsZ)
|
||||||
{
|
{
|
||||||
_renderer.New<DispatchComputeCommand>().Set(groupsX, groupsY, groupsZ);
|
_renderer.New<DispatchComputeCommand>()->Set(groupsX, groupsY, groupsZ);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Draw(int vertexCount, int instanceCount, int firstVertex, int firstInstance)
|
public unsafe void Draw(int vertexCount, int instanceCount, int firstVertex, int firstInstance)
|
||||||
{
|
{
|
||||||
_renderer.New<DrawCommand>().Set(vertexCount, instanceCount, firstVertex, firstInstance);
|
_renderer.New<DrawCommand>()->Set(vertexCount, instanceCount, firstVertex, firstInstance);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawIndexed(int indexCount, int instanceCount, int firstIndex, int firstVertex, int firstInstance)
|
public unsafe void DrawIndexed(int indexCount, int instanceCount, int firstIndex, int firstVertex, int firstInstance)
|
||||||
{
|
{
|
||||||
_renderer.New<DrawIndexedCommand>().Set(indexCount, instanceCount, firstIndex, firstVertex, firstInstance);
|
_renderer.New<DrawIndexedCommand>()->Set(indexCount, instanceCount, firstIndex, firstVertex, firstInstance);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawIndexedIndirect(BufferRange indirectBuffer)
|
public unsafe void DrawIndexedIndirect(BufferRange indirectBuffer)
|
||||||
{
|
{
|
||||||
_renderer.New<DrawIndexedIndirectCommand>().Set(indirectBuffer);
|
_renderer.New<DrawIndexedIndirectCommand>()->Set(indirectBuffer);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawIndexedIndirectCount(BufferRange indirectBuffer, BufferRange parameterBuffer, int maxDrawCount, int stride)
|
public unsafe void DrawIndexedIndirectCount(BufferRange indirectBuffer, BufferRange parameterBuffer, int maxDrawCount, int stride)
|
||||||
{
|
{
|
||||||
_renderer.New<DrawIndexedIndirectCountCommand>().Set(indirectBuffer, parameterBuffer, maxDrawCount, stride);
|
_renderer.New<DrawIndexedIndirectCountCommand>()->Set(indirectBuffer, parameterBuffer, maxDrawCount, stride);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawIndirect(BufferRange indirectBuffer)
|
public unsafe void DrawIndirect(BufferRange indirectBuffer)
|
||||||
{
|
{
|
||||||
_renderer.New<DrawIndirectCommand>().Set(indirectBuffer);
|
_renderer.New<DrawIndirectCommand>()->Set(indirectBuffer);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawIndirectCount(BufferRange indirectBuffer, BufferRange parameterBuffer, int maxDrawCount, int stride)
|
public unsafe void DrawIndirectCount(BufferRange indirectBuffer, BufferRange parameterBuffer, int maxDrawCount, int stride)
|
||||||
{
|
{
|
||||||
_renderer.New<DrawIndirectCountCommand>().Set(indirectBuffer, parameterBuffer, maxDrawCount, stride);
|
_renderer.New<DrawIndirectCountCommand>()->Set(indirectBuffer, parameterBuffer, maxDrawCount, stride);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawTexture(ITexture texture, ISampler sampler, Extents2DF srcRegion, Extents2DF dstRegion)
|
public unsafe void DrawTexture(ITexture texture, ISampler sampler, Extents2DF srcRegion, Extents2DF dstRegion)
|
||||||
{
|
{
|
||||||
_renderer.New<DrawTextureCommand>().Set(Ref(texture), Ref(sampler), srcRegion, dstRegion);
|
_renderer.New<DrawTextureCommand>()->Set(Ref(texture), Ref(sampler), srcRegion, dstRegion);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EndHostConditionalRendering()
|
public unsafe void EndHostConditionalRendering()
|
||||||
{
|
{
|
||||||
_renderer.New<EndHostConditionalRenderingCommand>();
|
_renderer.New<EndHostConditionalRenderingCommand>();
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EndTransformFeedback()
|
public unsafe void EndTransformFeedback()
|
||||||
{
|
{
|
||||||
_renderer.New<EndTransformFeedbackCommand>();
|
_renderer.New<EndTransformFeedbackCommand>();
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetAlphaTest(bool enable, float reference, CompareOp op)
|
public unsafe void SetAlphaTest(bool enable, float reference, CompareOp op)
|
||||||
{
|
{
|
||||||
_renderer.New<SetAlphaTestCommand>().Set(enable, reference, op);
|
_renderer.New<SetAlphaTestCommand>()->Set(enable, reference, op);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetBlendState(AdvancedBlendDescriptor blend)
|
public unsafe void SetBlendState(AdvancedBlendDescriptor blend)
|
||||||
{
|
{
|
||||||
_renderer.New<SetBlendStateAdvancedCommand>().Set(blend);
|
_renderer.New<SetBlendStateAdvancedCommand>()->Set(blend);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetBlendState(int index, BlendDescriptor blend)
|
public unsafe void SetBlendState(int index, BlendDescriptor blend)
|
||||||
{
|
{
|
||||||
_renderer.New<SetBlendStateCommand>().Set(index, blend);
|
_renderer.New<SetBlendStateCommand>()->Set(index, blend);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetDepthBias(PolygonModeMask enables, float factor, float units, float clamp)
|
public unsafe void SetDepthBias(PolygonModeMask enables, float factor, float units, float clamp)
|
||||||
{
|
{
|
||||||
_renderer.New<SetDepthBiasCommand>().Set(enables, factor, units, clamp);
|
_renderer.New<SetDepthBiasCommand>()->Set(enables, factor, units, clamp);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetDepthClamp(bool clamp)
|
public unsafe void SetDepthClamp(bool clamp)
|
||||||
{
|
{
|
||||||
_renderer.New<SetDepthClampCommand>().Set(clamp);
|
_renderer.New<SetDepthClampCommand>()->Set(clamp);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetDepthMode(DepthMode mode)
|
public unsafe void SetDepthMode(DepthMode mode)
|
||||||
{
|
{
|
||||||
_renderer.New<SetDepthModeCommand>().Set(mode);
|
_renderer.New<SetDepthModeCommand>()->Set(mode);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetDepthTest(DepthTestDescriptor depthTest)
|
public unsafe void SetDepthTest(DepthTestDescriptor depthTest)
|
||||||
{
|
{
|
||||||
_renderer.New<SetDepthTestCommand>().Set(depthTest);
|
_renderer.New<SetDepthTestCommand>()->Set(depthTest);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetFaceCulling(bool enable, Face face)
|
public unsafe void SetFaceCulling(bool enable, Face face)
|
||||||
{
|
{
|
||||||
_renderer.New<SetFaceCullingCommand>().Set(enable, face);
|
_renderer.New<SetFaceCullingCommand>()->Set(enable, face);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetFrontFace(FrontFace frontFace)
|
public unsafe void SetFrontFace(FrontFace frontFace)
|
||||||
{
|
{
|
||||||
_renderer.New<SetFrontFaceCommand>().Set(frontFace);
|
_renderer.New<SetFrontFaceCommand>()->Set(frontFace);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetImage(ShaderStage stage, int binding, ITexture texture)
|
public unsafe void SetImage(ShaderStage stage, int binding, ITexture texture)
|
||||||
{
|
{
|
||||||
_renderer.New<SetImageCommand>().Set(stage, binding, Ref(texture));
|
_renderer.New<SetImageCommand>()->Set(stage, binding, Ref(texture));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetImageArray(ShaderStage stage, int binding, IImageArray array)
|
public unsafe void SetImageArray(ShaderStage stage, int binding, IImageArray array)
|
||||||
{
|
{
|
||||||
_renderer.New<SetImageArrayCommand>().Set(stage, binding, Ref(array));
|
_renderer.New<SetImageArrayCommand>()->Set(stage, binding, Ref(array));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetImageArraySeparate(ShaderStage stage, int setIndex, IImageArray array)
|
public unsafe void SetImageArraySeparate(ShaderStage stage, int setIndex, IImageArray array)
|
||||||
{
|
{
|
||||||
_renderer.New<SetImageArraySeparateCommand>().Set(stage, setIndex, Ref(array));
|
_renderer.New<SetImageArraySeparateCommand>()->Set(stage, setIndex, Ref(array));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetIndexBuffer(BufferRange buffer, IndexType type)
|
public unsafe void SetIndexBuffer(BufferRange buffer, IndexType type)
|
||||||
{
|
{
|
||||||
_renderer.New<SetIndexBufferCommand>().Set(buffer, type);
|
_renderer.New<SetIndexBufferCommand>()->Set(buffer, type);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetLineParameters(float width, bool smooth)
|
public unsafe void SetLineParameters(float width, bool smooth)
|
||||||
{
|
{
|
||||||
_renderer.New<SetLineParametersCommand>().Set(width, smooth);
|
_renderer.New<SetLineParametersCommand>()->Set(width, smooth);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetLogicOpState(bool enable, LogicalOp op)
|
public unsafe void SetLogicOpState(bool enable, LogicalOp op)
|
||||||
{
|
{
|
||||||
_renderer.New<SetLogicOpStateCommand>().Set(enable, op);
|
_renderer.New<SetLogicOpStateCommand>()->Set(enable, op);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetMultisampleState(MultisampleDescriptor multisample)
|
public unsafe void SetMultisampleState(MultisampleDescriptor multisample)
|
||||||
{
|
{
|
||||||
_renderer.New<SetMultisampleStateCommand>().Set(multisample);
|
_renderer.New<SetMultisampleStateCommand>()->Set(multisample);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPatchParameters(int vertices, ReadOnlySpan<float> defaultOuterLevel, ReadOnlySpan<float> defaultInnerLevel)
|
public unsafe void SetPatchParameters(int vertices, ReadOnlySpan<float> defaultOuterLevel, ReadOnlySpan<float> defaultInnerLevel)
|
||||||
{
|
{
|
||||||
_renderer.New<SetPatchParametersCommand>().Set(vertices, defaultOuterLevel, defaultInnerLevel);
|
_renderer.New<SetPatchParametersCommand>()->Set(vertices, defaultOuterLevel, defaultInnerLevel);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPointParameters(float size, bool isProgramPointSize, bool enablePointSprite, Origin origin)
|
public unsafe void SetPointParameters(float size, bool isProgramPointSize, bool enablePointSprite, Origin origin)
|
||||||
{
|
{
|
||||||
_renderer.New<SetPointParametersCommand>().Set(size, isProgramPointSize, enablePointSprite, origin);
|
_renderer.New<SetPointParametersCommand>()->Set(size, isProgramPointSize, enablePointSprite, origin);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPolygonMode(PolygonMode frontMode, PolygonMode backMode)
|
public unsafe void SetPolygonMode(PolygonMode frontMode, PolygonMode backMode)
|
||||||
{
|
{
|
||||||
_renderer.New<SetPolygonModeCommand>().Set(frontMode, backMode);
|
_renderer.New<SetPolygonModeCommand>()->Set(frontMode, backMode);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPrimitiveRestart(bool enable, int index)
|
public unsafe void SetPrimitiveRestart(bool enable, int index)
|
||||||
{
|
{
|
||||||
_renderer.New<SetPrimitiveRestartCommand>().Set(enable, index);
|
_renderer.New<SetPrimitiveRestartCommand>()->Set(enable, index);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPrimitiveTopology(PrimitiveTopology topology)
|
public unsafe void SetPrimitiveTopology(PrimitiveTopology topology)
|
||||||
{
|
{
|
||||||
_renderer.New<SetPrimitiveTopologyCommand>().Set(topology);
|
_renderer.New<SetPrimitiveTopologyCommand>()->Set(topology);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetProgram(IProgram program)
|
public unsafe void SetProgram(IProgram program)
|
||||||
{
|
{
|
||||||
_renderer.New<SetProgramCommand>().Set(Ref(program));
|
_renderer.New<SetProgramCommand>()->Set(Ref(program));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetRasterizerDiscard(bool discard)
|
public unsafe void SetRasterizerDiscard(bool discard)
|
||||||
{
|
{
|
||||||
_renderer.New<SetRasterizerDiscardCommand>().Set(discard);
|
_renderer.New<SetRasterizerDiscardCommand>()->Set(discard);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetRenderTargetColorMasks(ReadOnlySpan<uint> componentMask)
|
public unsafe void SetRenderTargetColorMasks(ReadOnlySpan<uint> componentMask)
|
||||||
{
|
{
|
||||||
_renderer.New<SetRenderTargetColorMasksCommand>().Set(_renderer.CopySpan(componentMask));
|
_renderer.New<SetRenderTargetColorMasksCommand>()->Set(_renderer.CopySpan(componentMask));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetRenderTargets(ITexture[] colors, ITexture depthStencil)
|
public unsafe void SetRenderTargets(ITexture[] colors, ITexture depthStencil)
|
||||||
{
|
{
|
||||||
_renderer.New<SetRenderTargetsCommand>().Set(Ref(colors.ToArray()), Ref(depthStencil));
|
_renderer.New<SetRenderTargetsCommand>()->Set(Ref(colors.ToArray()), Ref(depthStencil));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetScissors(ReadOnlySpan<Rectangle<int>> scissors)
|
public unsafe void SetScissors(ReadOnlySpan<Rectangle<int>> scissors)
|
||||||
{
|
{
|
||||||
_renderer.New<SetScissorsCommand>().Set(_renderer.CopySpan(scissors));
|
_renderer.New<SetScissorsCommand>()->Set(_renderer.CopySpan(scissors));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetStencilTest(StencilTestDescriptor stencilTest)
|
public unsafe void SetStencilTest(StencilTestDescriptor stencilTest)
|
||||||
{
|
{
|
||||||
_renderer.New<SetStencilTestCommand>().Set(stencilTest);
|
_renderer.New<SetStencilTestCommand>()->Set(stencilTest);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetStorageBuffers(ReadOnlySpan<BufferAssignment> buffers)
|
public unsafe void SetStorageBuffers(ReadOnlySpan<BufferAssignment> buffers)
|
||||||
{
|
{
|
||||||
_renderer.New<SetStorageBuffersCommand>().Set(_renderer.CopySpan(buffers));
|
_renderer.New<SetStorageBuffersCommand>()->Set(_renderer.CopySpan(buffers));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetTextureAndSampler(ShaderStage stage, int binding, ITexture texture, ISampler sampler)
|
public unsafe void SetTextureAndSampler(ShaderStage stage, int binding, ITexture texture, ISampler sampler)
|
||||||
{
|
{
|
||||||
_renderer.New<SetTextureAndSamplerCommand>().Set(stage, binding, Ref(texture), Ref(sampler));
|
_renderer.New<SetTextureAndSamplerCommand>()->Set(stage, binding, Ref(texture), Ref(sampler));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetTextureArray(ShaderStage stage, int binding, ITextureArray array)
|
public unsafe void SetTextureArray(ShaderStage stage, int binding, ITextureArray array)
|
||||||
{
|
{
|
||||||
_renderer.New<SetTextureArrayCommand>().Set(stage, binding, Ref(array));
|
_renderer.New<SetTextureArrayCommand>()->Set(stage, binding, Ref(array));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetTextureArraySeparate(ShaderStage stage, int setIndex, ITextureArray array)
|
public unsafe void SetTextureArraySeparate(ShaderStage stage, int setIndex, ITextureArray array)
|
||||||
{
|
{
|
||||||
_renderer.New<SetTextureArraySeparateCommand>().Set(stage, setIndex, Ref(array));
|
_renderer.New<SetTextureArraySeparateCommand>()->Set(stage, setIndex, Ref(array));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetTransformFeedbackBuffers(ReadOnlySpan<BufferRange> buffers)
|
public unsafe void SetTransformFeedbackBuffers(ReadOnlySpan<BufferRange> buffers)
|
||||||
{
|
{
|
||||||
_renderer.New<SetTransformFeedbackBuffersCommand>().Set(_renderer.CopySpan(buffers));
|
_renderer.New<SetTransformFeedbackBuffersCommand>()->Set(_renderer.CopySpan(buffers));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetUniformBuffers(ReadOnlySpan<BufferAssignment> buffers)
|
public unsafe void SetUniformBuffers(ReadOnlySpan<BufferAssignment> buffers)
|
||||||
{
|
{
|
||||||
_renderer.New<SetUniformBuffersCommand>().Set(_renderer.CopySpan(buffers));
|
_renderer.New<SetUniformBuffersCommand>()->Set(_renderer.CopySpan(buffers));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetUserClipDistance(int index, bool enableClip)
|
public unsafe void SetUserClipDistance(int index, bool enableClip)
|
||||||
{
|
{
|
||||||
_renderer.New<SetUserClipDistanceCommand>().Set(index, enableClip);
|
_renderer.New<SetUserClipDistanceCommand>()->Set(index, enableClip);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetVertexAttribs(ReadOnlySpan<VertexAttribDescriptor> vertexAttribs)
|
public unsafe void SetVertexAttribs(ReadOnlySpan<VertexAttribDescriptor> vertexAttribs)
|
||||||
{
|
{
|
||||||
_renderer.New<SetVertexAttribsCommand>().Set(_renderer.CopySpan(vertexAttribs));
|
_renderer.New<SetVertexAttribsCommand>()->Set(_renderer.CopySpan(vertexAttribs));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetVertexBuffers(ReadOnlySpan<VertexBufferDescriptor> vertexBuffers)
|
public unsafe void SetVertexBuffers(ReadOnlySpan<VertexBufferDescriptor> vertexBuffers)
|
||||||
{
|
{
|
||||||
_renderer.New<SetVertexBuffersCommand>().Set(_renderer.CopySpan(vertexBuffers));
|
_renderer.New<SetVertexBuffersCommand>()->Set(_renderer.CopySpan(vertexBuffers));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetViewports(ReadOnlySpan<Viewport> viewports)
|
public unsafe void SetViewports(ReadOnlySpan<Viewport> viewports)
|
||||||
{
|
{
|
||||||
_renderer.New<SetViewportsCommand>().Set(_renderer.CopySpan(viewports));
|
_renderer.New<SetViewportsCommand>()->Set(_renderer.CopySpan(viewports));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TextureBarrier()
|
public unsafe void TextureBarrier()
|
||||||
{
|
{
|
||||||
_renderer.New<TextureBarrierCommand>();
|
_renderer.New<TextureBarrierCommand>();
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TextureBarrierTiled()
|
public unsafe void TextureBarrierTiled()
|
||||||
{
|
{
|
||||||
_renderer.New<TextureBarrierTiledCommand>();
|
_renderer.New<TextureBarrierTiledCommand>();
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryHostConditionalRendering(ICounterEvent value, ulong compare, bool isEqual)
|
public unsafe bool TryHostConditionalRendering(ICounterEvent value, ulong compare, bool isEqual)
|
||||||
{
|
{
|
||||||
ThreadedCounterEvent evt = value as ThreadedCounterEvent;
|
ThreadedCounterEvent evt = value as ThreadedCounterEvent;
|
||||||
if (evt != null)
|
if (evt != null)
|
||||||
|
|
@ -369,20 +369,20 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_renderer.New<TryHostConditionalRenderingCommand>().Set(Ref(evt), compare, isEqual);
|
_renderer.New<TryHostConditionalRenderingCommand>()->Set(Ref(evt), compare, isEqual);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_renderer.New<TryHostConditionalRenderingFlushCommand>().Set(Ref(evt), Ref<ThreadedCounterEvent>(null), isEqual);
|
_renderer.New<TryHostConditionalRenderingFlushCommand>()->Set(Ref(evt), Ref<ThreadedCounterEvent>(null), isEqual);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryHostConditionalRendering(ICounterEvent value, ICounterEvent compare, bool isEqual)
|
public unsafe bool TryHostConditionalRendering(ICounterEvent value, ICounterEvent compare, bool isEqual)
|
||||||
{
|
{
|
||||||
_renderer.New<TryHostConditionalRenderingFlushCommand>().Set(Ref(value as ThreadedCounterEvent), Ref(compare as ThreadedCounterEvent), isEqual);
|
_renderer.New<TryHostConditionalRenderingFlushCommand>()->Set(Ref(value as ThreadedCounterEvent), Ref(compare as ThreadedCounterEvent), isEqual);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -167,7 +167,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
||||||
return new TableRef<T>(this, reference);
|
return new TableRef<T>(this, reference);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal ref T New<T>() where T : struct
|
internal unsafe T* New<T>() where T : unmanaged, IGALCommand
|
||||||
{
|
{
|
||||||
while (_producerPtr == (Volatile.Read(ref _consumerPtr) + QueueCount - 1) % QueueCount)
|
while (_producerPtr == (Volatile.Read(ref _consumerPtr) + QueueCount - 1) % QueueCount)
|
||||||
{
|
{
|
||||||
|
|
@ -183,11 +183,12 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
||||||
_producerPtr = (_producerPtr + 1) % QueueCount;
|
_producerPtr = (_producerPtr + 1) % QueueCount;
|
||||||
|
|
||||||
Span<byte> memory = new(_commandQueue, taken * _elementSize, _elementSize);
|
Span<byte> memory = new(_commandQueue, taken * _elementSize, _elementSize);
|
||||||
ref T result = ref Unsafe.As<byte, T>(ref MemoryMarshal.GetReference(memory));
|
T* result = (T*)Unsafe.AsPointer(ref memory.GetPinnableReference());
|
||||||
|
// ref T result = ref Unsafe.As<byte, T>(ref MemoryMarshal.GetReference(memory));
|
||||||
|
|
||||||
memory[^1] = (byte)((IGALCommand)result).CommandType;
|
memory[^1] = (byte)(result)->CommandType;
|
||||||
|
|
||||||
return ref result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal int AddTableRef(object obj)
|
internal int AddTableRef(object obj)
|
||||||
|
|
@ -251,12 +252,12 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
||||||
return Thread.CurrentThread == _gpuThread;
|
return Thread.CurrentThread == _gpuThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BackgroundContextAction(Action action, bool alwaysBackground = false)
|
public unsafe void BackgroundContextAction(Action action, bool alwaysBackground = false)
|
||||||
{
|
{
|
||||||
if (IsGpuThread() && !alwaysBackground)
|
if (IsGpuThread() && !alwaysBackground)
|
||||||
{
|
{
|
||||||
// The action must be performed on the render thread.
|
// The action must be performed on the render thread.
|
||||||
New<ActionCommand>().Set(Ref(action));
|
New<ActionCommand>()->Set(Ref(action));
|
||||||
InvokeCommand();
|
InvokeCommand();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -265,43 +266,43 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BufferHandle CreateBuffer(int size, BufferAccess access)
|
public unsafe BufferHandle CreateBuffer(int size, BufferAccess access)
|
||||||
{
|
{
|
||||||
BufferHandle handle = Buffers.CreateBufferHandle();
|
BufferHandle handle = Buffers.CreateBufferHandle();
|
||||||
New<CreateBufferAccessCommand>().Set(handle, size, access);
|
New<CreateBufferAccessCommand>()->Set(handle, size, access);
|
||||||
QueueCommand();
|
QueueCommand();
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BufferHandle CreateBuffer(nint pointer, int size)
|
public unsafe BufferHandle CreateBuffer(nint pointer, int size)
|
||||||
{
|
{
|
||||||
BufferHandle handle = Buffers.CreateBufferHandle();
|
BufferHandle handle = Buffers.CreateBufferHandle();
|
||||||
New<CreateHostBufferCommand>().Set(handle, pointer, size);
|
New<CreateHostBufferCommand>()->Set(handle, pointer, size);
|
||||||
QueueCommand();
|
QueueCommand();
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BufferHandle CreateBufferSparse(ReadOnlySpan<BufferRange> storageBuffers)
|
public unsafe BufferHandle CreateBufferSparse(ReadOnlySpan<BufferRange> storageBuffers)
|
||||||
{
|
{
|
||||||
BufferHandle handle = Buffers.CreateBufferHandle();
|
BufferHandle handle = Buffers.CreateBufferHandle();
|
||||||
New<CreateBufferSparseCommand>().Set(handle, CopySpan(storageBuffers));
|
New<CreateBufferSparseCommand>()->Set(handle, CopySpan(storageBuffers));
|
||||||
QueueCommand();
|
QueueCommand();
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IImageArray CreateImageArray(int size, bool isBuffer)
|
public unsafe IImageArray CreateImageArray(int size, bool isBuffer)
|
||||||
{
|
{
|
||||||
ThreadedImageArray imageArray = new(this);
|
ThreadedImageArray imageArray = new(this);
|
||||||
New<CreateImageArrayCommand>().Set(Ref(imageArray), size, isBuffer);
|
New<CreateImageArrayCommand>()->Set(Ref(imageArray), size, isBuffer);
|
||||||
QueueCommand();
|
QueueCommand();
|
||||||
|
|
||||||
return imageArray;
|
return imageArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info)
|
public unsafe IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info)
|
||||||
{
|
{
|
||||||
ThreadedProgram program = new(this);
|
ThreadedProgram program = new(this);
|
||||||
|
|
||||||
|
|
@ -311,34 +312,34 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
||||||
|
|
||||||
ProgramCount++;
|
ProgramCount++;
|
||||||
|
|
||||||
New<CreateProgramCommand>().Set(Ref((IProgramRequest)request));
|
New<CreateProgramCommand>()->Set(Ref((IProgramRequest)request));
|
||||||
QueueCommand();
|
QueueCommand();
|
||||||
|
|
||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ISampler CreateSampler(SamplerCreateInfo info)
|
public unsafe ISampler CreateSampler(SamplerCreateInfo info)
|
||||||
{
|
{
|
||||||
ThreadedSampler sampler = new(this);
|
ThreadedSampler sampler = new(this);
|
||||||
New<CreateSamplerCommand>().Set(Ref(sampler), info);
|
New<CreateSamplerCommand>()->Set(Ref(sampler), info);
|
||||||
QueueCommand();
|
QueueCommand();
|
||||||
|
|
||||||
return sampler;
|
return sampler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CreateSync(ulong id, bool strict)
|
public unsafe void CreateSync(ulong id, bool strict)
|
||||||
{
|
{
|
||||||
Sync.CreateSyncHandle(id);
|
Sync.CreateSyncHandle(id);
|
||||||
New<CreateSyncCommand>().Set(id, strict);
|
New<CreateSyncCommand>()->Set(id, strict);
|
||||||
QueueCommand();
|
QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ITexture CreateTexture(TextureCreateInfo info)
|
public unsafe ITexture CreateTexture(TextureCreateInfo info)
|
||||||
{
|
{
|
||||||
if (IsGpuThread())
|
if (IsGpuThread())
|
||||||
{
|
{
|
||||||
ThreadedTexture texture = new(this, info);
|
ThreadedTexture texture = new(this, info);
|
||||||
New<CreateTextureCommand>().Set(Ref(texture), info);
|
New<CreateTextureCommand>()->Set(Ref(texture), info);
|
||||||
QueueCommand();
|
QueueCommand();
|
||||||
|
|
||||||
return texture;
|
return texture;
|
||||||
|
|
@ -353,27 +354,27 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public ITextureArray CreateTextureArray(int size, bool isBuffer)
|
public unsafe ITextureArray CreateTextureArray(int size, bool isBuffer)
|
||||||
{
|
{
|
||||||
ThreadedTextureArray textureArray = new(this);
|
ThreadedTextureArray textureArray = new(this);
|
||||||
New<CreateTextureArrayCommand>().Set(Ref(textureArray), size, isBuffer);
|
New<CreateTextureArrayCommand>()->Set(Ref(textureArray), size, isBuffer);
|
||||||
QueueCommand();
|
QueueCommand();
|
||||||
|
|
||||||
return textureArray;
|
return textureArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeleteBuffer(BufferHandle buffer)
|
public unsafe void DeleteBuffer(BufferHandle buffer)
|
||||||
{
|
{
|
||||||
New<BufferDisposeCommand>().Set(buffer);
|
New<BufferDisposeCommand>()->Set(buffer);
|
||||||
QueueCommand();
|
QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PinnedSpan<byte> GetBufferData(BufferHandle buffer, int offset, int size)
|
public unsafe PinnedSpan<byte> GetBufferData(BufferHandle buffer, int offset, int size)
|
||||||
{
|
{
|
||||||
if (IsGpuThread())
|
if (IsGpuThread())
|
||||||
{
|
{
|
||||||
ResultBox<PinnedSpan<byte>> box = new();
|
ResultBox<PinnedSpan<byte>> box = new();
|
||||||
New<BufferGetDataCommand>().Set(buffer, offset, size, Ref(box));
|
New<BufferGetDataCommand>()->Set(buffer, offset, size, Ref(box));
|
||||||
InvokeCommand();
|
InvokeCommand();
|
||||||
|
|
||||||
return box.Result;
|
return box.Result;
|
||||||
|
|
@ -384,10 +385,10 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Capabilities GetCapabilities()
|
public unsafe Capabilities GetCapabilities()
|
||||||
{
|
{
|
||||||
ResultBox<Capabilities> box = new();
|
ResultBox<Capabilities> box = new();
|
||||||
New<GetCapabilitiesCommand>().Set(Ref(box));
|
New<GetCapabilitiesCommand>()->Set(Ref(box));
|
||||||
InvokeCommand();
|
InvokeCommand();
|
||||||
|
|
||||||
return box.Result;
|
return box.Result;
|
||||||
|
|
@ -412,29 +413,29 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
||||||
_baseRenderer.Initialize(logLevel);
|
_baseRenderer.Initialize(logLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IProgram LoadProgramBinary(byte[] programBinary, bool hasFragmentShader, ShaderInfo info)
|
public unsafe IProgram LoadProgramBinary(byte[] programBinary, bool hasFragmentShader, ShaderInfo info)
|
||||||
{
|
{
|
||||||
ThreadedProgram program = new(this);
|
ThreadedProgram program = new(this);
|
||||||
|
|
||||||
BinaryProgramRequest request = new(program, programBinary, hasFragmentShader, info);
|
BinaryProgramRequest request = new(program, programBinary, hasFragmentShader, info);
|
||||||
Programs.Add(request);
|
Programs.Add(request);
|
||||||
|
|
||||||
New<CreateProgramCommand>().Set(Ref((IProgramRequest)request));
|
New<CreateProgramCommand>()->Set(Ref((IProgramRequest)request));
|
||||||
QueueCommand();
|
QueueCommand();
|
||||||
|
|
||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PreFrame()
|
public unsafe void PreFrame()
|
||||||
{
|
{
|
||||||
New<PreFrameCommand>();
|
New<PreFrameCommand>();
|
||||||
QueueCommand();
|
QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ICounterEvent ReportCounter(CounterType type, EventHandler<ulong> resultHandler, float divisor, bool hostReserved)
|
public unsafe ICounterEvent ReportCounter(CounterType type, EventHandler<ulong> resultHandler, float divisor, bool hostReserved)
|
||||||
{
|
{
|
||||||
ThreadedCounterEvent evt = new(this, type, _lastSampleCounterClear);
|
ThreadedCounterEvent evt = new(this, type, _lastSampleCounterClear);
|
||||||
New<ReportCounterCommand>().Set(Ref(evt), type, Ref(resultHandler), divisor, hostReserved);
|
New<ReportCounterCommand>()->Set(Ref(evt), type, Ref(resultHandler), divisor, hostReserved);
|
||||||
QueueCommand();
|
QueueCommand();
|
||||||
|
|
||||||
if (type == CounterType.SamplesPassed)
|
if (type == CounterType.SamplesPassed)
|
||||||
|
|
@ -445,9 +446,9 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
||||||
return evt;
|
return evt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetCounter(CounterType type)
|
public unsafe void ResetCounter(CounterType type)
|
||||||
{
|
{
|
||||||
New<ResetCounterCommand>().Set(type);
|
New<ResetCounterCommand>()->Set(type);
|
||||||
QueueCommand();
|
QueueCommand();
|
||||||
_lastSampleCounterClear = true;
|
_lastSampleCounterClear = true;
|
||||||
}
|
}
|
||||||
|
|
@ -457,13 +458,13 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
||||||
_baseRenderer.Screenshot();
|
_baseRenderer.Screenshot();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetBufferData(BufferHandle buffer, int offset, ReadOnlySpan<byte> data)
|
public unsafe void SetBufferData(BufferHandle buffer, int offset, ReadOnlySpan<byte> data)
|
||||||
{
|
{
|
||||||
New<BufferSetDataCommand>().Set(buffer, offset, CopySpan(data));
|
New<BufferSetDataCommand>()->Set(buffer, offset, CopySpan(data));
|
||||||
QueueCommand();
|
QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateCounters()
|
public unsafe void UpdateCounters()
|
||||||
{
|
{
|
||||||
New<UpdateCountersCommand>();
|
New<UpdateCountersCommand>();
|
||||||
QueueCommand();
|
QueueCommand();
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,13 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
||||||
_impl = impl;
|
_impl = impl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback)
|
public unsafe void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback)
|
||||||
{
|
{
|
||||||
// If there's already a frame in the pipeline, wait for it to be presented first.
|
// If there's already a frame in the pipeline, wait for it to be presented first.
|
||||||
// This is a multithread rate limit - we can't be more than one frame behind the command queue.
|
// This is a multithread rate limit - we can't be more than one frame behind the command queue.
|
||||||
|
|
||||||
_renderer.WaitForFrame();
|
_renderer.WaitForFrame();
|
||||||
_renderer.New<WindowPresentCommand>().Set(new TableRef<ThreadedTexture>(_renderer, texture as ThreadedTexture), crop, new TableRef<Action>(_renderer, swapBuffersCallback));
|
_renderer.New<WindowPresentCommand>()->Set(new TableRef<ThreadedTexture>(_renderer, texture as ThreadedTexture), crop, new TableRef<Action>(_renderer, swapBuffersCallback));
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,12 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal CounterCache CounterCache { get; }
|
internal CounterCache CounterCache { get; }
|
||||||
|
|
||||||
|
private delegate void WriteCallback(ulong address, ReadOnlySpan<byte> data);
|
||||||
|
|
||||||
|
private WriteCallback _write;
|
||||||
|
private WriteCallback _writeTrackedResource;
|
||||||
|
private WriteCallback _writeUntracked;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new instance of the GPU memory manager.
|
/// Creates a new instance of the GPU memory manager.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -58,6 +64,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
internal MemoryManager(PhysicalMemory physicalMemory, ulong cpuMemorySize)
|
internal MemoryManager(PhysicalMemory physicalMemory, ulong cpuMemorySize)
|
||||||
{
|
{
|
||||||
Physical = physicalMemory;
|
Physical = physicalMemory;
|
||||||
|
_write = physicalMemory.Write;
|
||||||
|
_writeTrackedResource = physicalMemory.WriteTrackedResource;
|
||||||
|
_writeUntracked = physicalMemory.WriteUntracked;
|
||||||
VirtualRangeCache = new VirtualRangeCache(this);
|
VirtualRangeCache = new VirtualRangeCache(this);
|
||||||
CounterCache = new CounterCache();
|
CounterCache = new CounterCache();
|
||||||
_pageTable = new ulong[PtLvl0Size][];
|
_pageTable = new ulong[PtLvl0Size][];
|
||||||
|
|
@ -269,7 +278,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
/// <param name="data">The data to be written</param>
|
/// <param name="data">The data to be written</param>
|
||||||
public void Write(ulong va, ReadOnlySpan<byte> data)
|
public void Write(ulong va, ReadOnlySpan<byte> data)
|
||||||
{
|
{
|
||||||
WriteImpl(va, data, Physical.Write);
|
WriteImpl(va, data, _write);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -279,7 +288,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
/// <param name="data">The data to be written</param>
|
/// <param name="data">The data to be written</param>
|
||||||
public void WriteTrackedResource(ulong va, ReadOnlySpan<byte> data)
|
public void WriteTrackedResource(ulong va, ReadOnlySpan<byte> data)
|
||||||
{
|
{
|
||||||
WriteImpl(va, data, Physical.WriteTrackedResource);
|
WriteImpl(va, data, _writeTrackedResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -289,11 +298,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
/// <param name="data">The data to be written</param>
|
/// <param name="data">The data to be written</param>
|
||||||
public void WriteUntracked(ulong va, ReadOnlySpan<byte> data)
|
public void WriteUntracked(ulong va, ReadOnlySpan<byte> data)
|
||||||
{
|
{
|
||||||
WriteImpl(va, data, Physical.WriteUntracked);
|
WriteImpl(va, data, _writeUntracked);
|
||||||
}
|
}
|
||||||
|
|
||||||
private delegate void WriteCallback(ulong address, ReadOnlySpan<byte> data);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Writes data to possibly non-contiguous GPU mapped memory.
|
/// Writes data to possibly non-contiguous GPU mapped memory.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -123,15 +123,15 @@ namespace Ryujinx.HLE.HOS.Services.Nv
|
||||||
return NvResult.InvalidSize;
|
return NvResult.InvalidSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] outputData = new byte[outputDataSize];
|
if (!context.Memory.TryReadUnsafe(inputDataPosition, (int)inputDataSize, out arguments))
|
||||||
|
{
|
||||||
byte[] temp = new byte[inputDataSize];
|
arguments = new byte[inputDataSize];
|
||||||
|
context.Memory.Read(inputDataPosition, arguments);
|
||||||
context.Memory.Read(inputDataPosition, temp);
|
}
|
||||||
|
else
|
||||||
Buffer.BlockCopy(temp, 0, outputData, 0, temp.Length);
|
{
|
||||||
|
arguments = arguments.ToArray();
|
||||||
arguments = new Span<byte>(outputData);
|
}
|
||||||
}
|
}
|
||||||
else if (isWrite)
|
else if (isWrite)
|
||||||
{
|
{
|
||||||
|
|
@ -471,11 +471,11 @@ namespace Ryujinx.HLE.HOS.Services.Nv
|
||||||
|
|
||||||
errorCode = GetIoctlArgument(context, ioctlCommand, out Span<byte> arguments);
|
errorCode = GetIoctlArgument(context, ioctlCommand, out Span<byte> arguments);
|
||||||
|
|
||||||
byte[] temp = new byte[inlineInBufferSize];
|
if (!context.Memory.TryReadUnsafe(inlineInBufferPosition, (int)inlineInBufferSize, out Span<byte> inlineInBuffer))
|
||||||
|
{
|
||||||
context.Memory.Read(inlineInBufferPosition, temp);
|
inlineInBuffer = new byte[inlineInBufferSize];
|
||||||
|
context.Memory.Read(inlineInBufferPosition, inlineInBuffer);
|
||||||
Span<byte> inlineInBuffer = new(temp);
|
}
|
||||||
|
|
||||||
if (errorCode == NvResult.Success)
|
if (errorCode == NvResult.Success)
|
||||||
{
|
{
|
||||||
|
|
@ -520,11 +520,11 @@ namespace Ryujinx.HLE.HOS.Services.Nv
|
||||||
|
|
||||||
errorCode = GetIoctlArgument(context, ioctlCommand, out Span<byte> arguments);
|
errorCode = GetIoctlArgument(context, ioctlCommand, out Span<byte> arguments);
|
||||||
|
|
||||||
byte[] temp = new byte[inlineOutBufferSize];
|
if (!context.Memory.TryReadUnsafe(inlineOutBufferPosition, (int)inlineOutBufferSize, out Span<byte> inlineOutBuffer))
|
||||||
|
{
|
||||||
context.Memory.Read(inlineOutBufferPosition, temp);
|
inlineOutBuffer = new byte[inlineOutBufferSize];
|
||||||
|
context.Memory.Read(inlineOutBufferPosition, inlineOutBuffer);
|
||||||
Span<byte> inlineOutBuffer = new(temp);
|
}
|
||||||
|
|
||||||
if (errorCode == NvResult.Success)
|
if (errorCode == NvResult.Success)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,15 @@ namespace Ryujinx.Memory
|
||||||
/// <exception cref="InvalidMemoryRegionException">Throw for unhandled invalid or unmapped memory accesses</exception>
|
/// <exception cref="InvalidMemoryRegionException">Throw for unhandled invalid or unmapped memory accesses</exception>
|
||||||
void Read(ulong va, Span<byte> data);
|
void Read(ulong va, Span<byte> data);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a span of CPU mapped memory.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="va">Virtual address of the data in memory</param>
|
||||||
|
/// <param name="length">Length of the data in memory</param>
|
||||||
|
/// <param name="data">Span that references the data being read</param>
|
||||||
|
/// <exception cref="InvalidMemoryRegionException">Throw for unhandled invalid or unmapped memory accesses</exception>
|
||||||
|
bool TryReadUnsafe(ulong va, int length, out Span<byte> data);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Writes data to CPU mapped memory.
|
/// Writes data to CPU mapped memory.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -159,6 +159,13 @@ namespace Ryujinx.Memory
|
||||||
|
|
||||||
AssertValidAddressAndSize(va, data.Length);
|
AssertValidAddressAndSize(va, data.Length);
|
||||||
|
|
||||||
|
if (IsContiguousAndMapped(va, data.Length))
|
||||||
|
{
|
||||||
|
nuint pa = TranslateVirtualAddressChecked(va);
|
||||||
|
|
||||||
|
GetPhysicalAddressSpan(pa, data.Length).CopyTo(data);
|
||||||
|
}
|
||||||
|
|
||||||
int offset = 0, size;
|
int offset = 0, size;
|
||||||
|
|
||||||
if ((va & PageMask) != 0)
|
if ((va & PageMask) != 0)
|
||||||
|
|
@ -182,6 +189,28 @@ namespace Ryujinx.Memory
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual bool TryReadUnsafe(ulong va, int length, out Span<byte> data)
|
||||||
|
{
|
||||||
|
if (!IsContiguousAndMapped(va, length))
|
||||||
|
{
|
||||||
|
data = default;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length == 0)
|
||||||
|
{
|
||||||
|
data = Span<byte>.Empty;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
AssertValidAddressAndSize(va, length);
|
||||||
|
|
||||||
|
nuint pa = TranslateVirtualAddressChecked(va);
|
||||||
|
|
||||||
|
data = GetPhysicalAddressSpan(pa, length);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public virtual T ReadTracked<T>(ulong va) where T : unmanaged
|
public virtual T ReadTracked<T>(ulong va) where T : unmanaged
|
||||||
{
|
{
|
||||||
SignalMemoryTracking(va, (ulong)Unsafe.SizeOf<T>(), false);
|
SignalMemoryTracking(va, (ulong)Unsafe.SizeOf<T>(), false);
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,11 @@ namespace Ryujinx.Tests.Memory
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool TryReadUnsafe(ulong va, int lenfth, out Span<byte> data)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
public void Write<T>(ulong va, T value) where T : unmanaged
|
public void Write<T>(ulong va, T value) where T : unmanaged
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue