mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-12-16 01:36:57 +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
|
|
@ -167,7 +167,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||
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)
|
||||
{
|
||||
|
|
@ -183,11 +183,12 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||
_producerPtr = (_producerPtr + 1) % QueueCount;
|
||||
|
||||
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)
|
||||
|
|
@ -251,12 +252,12 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||
return Thread.CurrentThread == _gpuThread;
|
||||
}
|
||||
|
||||
public void BackgroundContextAction(Action action, bool alwaysBackground = false)
|
||||
public unsafe void BackgroundContextAction(Action action, bool alwaysBackground = false)
|
||||
{
|
||||
if (IsGpuThread() && !alwaysBackground)
|
||||
{
|
||||
// The action must be performed on the render thread.
|
||||
New<ActionCommand>().Set(Ref(action));
|
||||
New<ActionCommand>()->Set(Ref(action));
|
||||
InvokeCommand();
|
||||
}
|
||||
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();
|
||||
New<CreateBufferAccessCommand>().Set(handle, size, access);
|
||||
New<CreateBufferAccessCommand>()->Set(handle, size, access);
|
||||
QueueCommand();
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
public BufferHandle CreateBuffer(nint pointer, int size)
|
||||
public unsafe BufferHandle CreateBuffer(nint pointer, int size)
|
||||
{
|
||||
BufferHandle handle = Buffers.CreateBufferHandle();
|
||||
New<CreateHostBufferCommand>().Set(handle, pointer, size);
|
||||
New<CreateHostBufferCommand>()->Set(handle, pointer, size);
|
||||
QueueCommand();
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
public BufferHandle CreateBufferSparse(ReadOnlySpan<BufferRange> storageBuffers)
|
||||
public unsafe BufferHandle CreateBufferSparse(ReadOnlySpan<BufferRange> storageBuffers)
|
||||
{
|
||||
BufferHandle handle = Buffers.CreateBufferHandle();
|
||||
New<CreateBufferSparseCommand>().Set(handle, CopySpan(storageBuffers));
|
||||
New<CreateBufferSparseCommand>()->Set(handle, CopySpan(storageBuffers));
|
||||
QueueCommand();
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
public IImageArray CreateImageArray(int size, bool isBuffer)
|
||||
public unsafe IImageArray CreateImageArray(int size, bool isBuffer)
|
||||
{
|
||||
ThreadedImageArray imageArray = new(this);
|
||||
New<CreateImageArrayCommand>().Set(Ref(imageArray), size, isBuffer);
|
||||
New<CreateImageArrayCommand>()->Set(Ref(imageArray), size, isBuffer);
|
||||
QueueCommand();
|
||||
|
||||
return imageArray;
|
||||
}
|
||||
|
||||
public IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info)
|
||||
public unsafe IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info)
|
||||
{
|
||||
ThreadedProgram program = new(this);
|
||||
|
||||
|
|
@ -311,34 +312,34 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||
|
||||
ProgramCount++;
|
||||
|
||||
New<CreateProgramCommand>().Set(Ref((IProgramRequest)request));
|
||||
New<CreateProgramCommand>()->Set(Ref((IProgramRequest)request));
|
||||
QueueCommand();
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
public ISampler CreateSampler(SamplerCreateInfo info)
|
||||
public unsafe ISampler CreateSampler(SamplerCreateInfo info)
|
||||
{
|
||||
ThreadedSampler sampler = new(this);
|
||||
New<CreateSamplerCommand>().Set(Ref(sampler), info);
|
||||
New<CreateSamplerCommand>()->Set(Ref(sampler), info);
|
||||
QueueCommand();
|
||||
|
||||
return sampler;
|
||||
}
|
||||
|
||||
public void CreateSync(ulong id, bool strict)
|
||||
public unsafe void CreateSync(ulong id, bool strict)
|
||||
{
|
||||
Sync.CreateSyncHandle(id);
|
||||
New<CreateSyncCommand>().Set(id, strict);
|
||||
New<CreateSyncCommand>()->Set(id, strict);
|
||||
QueueCommand();
|
||||
}
|
||||
|
||||
public ITexture CreateTexture(TextureCreateInfo info)
|
||||
public unsafe ITexture CreateTexture(TextureCreateInfo info)
|
||||
{
|
||||
if (IsGpuThread())
|
||||
{
|
||||
ThreadedTexture texture = new(this, info);
|
||||
New<CreateTextureCommand>().Set(Ref(texture), info);
|
||||
New<CreateTextureCommand>()->Set(Ref(texture), info);
|
||||
QueueCommand();
|
||||
|
||||
return texture;
|
||||
|
|
@ -353,27 +354,27 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||
return texture;
|
||||
}
|
||||
}
|
||||
public ITextureArray CreateTextureArray(int size, bool isBuffer)
|
||||
public unsafe ITextureArray CreateTextureArray(int size, bool isBuffer)
|
||||
{
|
||||
ThreadedTextureArray textureArray = new(this);
|
||||
New<CreateTextureArrayCommand>().Set(Ref(textureArray), size, isBuffer);
|
||||
New<CreateTextureArrayCommand>()->Set(Ref(textureArray), size, isBuffer);
|
||||
QueueCommand();
|
||||
|
||||
return textureArray;
|
||||
}
|
||||
|
||||
public void DeleteBuffer(BufferHandle buffer)
|
||||
public unsafe void DeleteBuffer(BufferHandle buffer)
|
||||
{
|
||||
New<BufferDisposeCommand>().Set(buffer);
|
||||
New<BufferDisposeCommand>()->Set(buffer);
|
||||
QueueCommand();
|
||||
}
|
||||
|
||||
public PinnedSpan<byte> GetBufferData(BufferHandle buffer, int offset, int size)
|
||||
public unsafe PinnedSpan<byte> GetBufferData(BufferHandle buffer, int offset, int size)
|
||||
{
|
||||
if (IsGpuThread())
|
||||
{
|
||||
ResultBox<PinnedSpan<byte>> box = new();
|
||||
New<BufferGetDataCommand>().Set(buffer, offset, size, Ref(box));
|
||||
New<BufferGetDataCommand>()->Set(buffer, offset, size, Ref(box));
|
||||
InvokeCommand();
|
||||
|
||||
return box.Result;
|
||||
|
|
@ -384,10 +385,10 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||
}
|
||||
}
|
||||
|
||||
public Capabilities GetCapabilities()
|
||||
public unsafe Capabilities GetCapabilities()
|
||||
{
|
||||
ResultBox<Capabilities> box = new();
|
||||
New<GetCapabilitiesCommand>().Set(Ref(box));
|
||||
New<GetCapabilitiesCommand>()->Set(Ref(box));
|
||||
InvokeCommand();
|
||||
|
||||
return box.Result;
|
||||
|
|
@ -412,29 +413,29 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||
_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);
|
||||
|
||||
BinaryProgramRequest request = new(program, programBinary, hasFragmentShader, info);
|
||||
Programs.Add(request);
|
||||
|
||||
New<CreateProgramCommand>().Set(Ref((IProgramRequest)request));
|
||||
New<CreateProgramCommand>()->Set(Ref((IProgramRequest)request));
|
||||
QueueCommand();
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
public void PreFrame()
|
||||
public unsafe void PreFrame()
|
||||
{
|
||||
New<PreFrameCommand>();
|
||||
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);
|
||||
New<ReportCounterCommand>().Set(Ref(evt), type, Ref(resultHandler), divisor, hostReserved);
|
||||
New<ReportCounterCommand>()->Set(Ref(evt), type, Ref(resultHandler), divisor, hostReserved);
|
||||
QueueCommand();
|
||||
|
||||
if (type == CounterType.SamplesPassed)
|
||||
|
|
@ -445,9 +446,9 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||
return evt;
|
||||
}
|
||||
|
||||
public void ResetCounter(CounterType type)
|
||||
public unsafe void ResetCounter(CounterType type)
|
||||
{
|
||||
New<ResetCounterCommand>().Set(type);
|
||||
New<ResetCounterCommand>()->Set(type);
|
||||
QueueCommand();
|
||||
_lastSampleCounterClear = true;
|
||||
}
|
||||
|
|
@ -457,13 +458,13 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||
_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();
|
||||
}
|
||||
|
||||
public void UpdateCounters()
|
||||
public unsafe void UpdateCounters()
|
||||
{
|
||||
New<UpdateCountersCommand>();
|
||||
QueueCommand();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue