mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-07-24 14:49:48 -06:00

This is not a continuation of the Metal backend; this is simply bringing the branch up to date and merging it as-is behind an experiment. --------- Co-authored-by: Isaac Marovitz <isaacryu@icloud.com> Co-authored-by: Samuliak <samuliak77@gmail.com> Co-authored-by: SamoZ256 <96914946+SamoZ256@users.noreply.github.com> Co-authored-by: Isaac Marovitz <42140194+IsaacMarovitz@users.noreply.github.com> Co-authored-by: riperiperi <rhy3756547@hotmail.com> Co-authored-by: Gabriel A <gab.dark.100@gmail.com>
100 lines
3.0 KiB
C#
100 lines
3.0 KiB
C#
using Ryujinx.Graphics.GAL;
|
|
using System;
|
|
using System.Runtime.Versioning;
|
|
|
|
namespace Ryujinx.Graphics.Metal
|
|
{
|
|
[SupportedOSPlatform("macos")]
|
|
internal class PersistentFlushBuffer : IDisposable
|
|
{
|
|
private readonly MetalRenderer _renderer;
|
|
|
|
private BufferHolder _flushStorage;
|
|
|
|
public PersistentFlushBuffer(MetalRenderer renderer)
|
|
{
|
|
_renderer = renderer;
|
|
}
|
|
|
|
private BufferHolder ResizeIfNeeded(int size)
|
|
{
|
|
var flushStorage = _flushStorage;
|
|
|
|
if (flushStorage == null || size > _flushStorage.Size)
|
|
{
|
|
flushStorage?.Dispose();
|
|
|
|
flushStorage = _renderer.BufferManager.Create(size);
|
|
_flushStorage = flushStorage;
|
|
}
|
|
|
|
return flushStorage;
|
|
}
|
|
|
|
public Span<byte> GetBufferData(CommandBufferPool cbp, BufferHolder buffer, int offset, int size)
|
|
{
|
|
var flushStorage = ResizeIfNeeded(size);
|
|
Auto<DisposableBuffer> srcBuffer;
|
|
|
|
using (var cbs = cbp.Rent())
|
|
{
|
|
srcBuffer = buffer.GetBuffer();
|
|
var dstBuffer = flushStorage.GetBuffer();
|
|
|
|
if (srcBuffer.TryIncrementReferenceCount())
|
|
{
|
|
BufferHolder.Copy(cbs, srcBuffer, dstBuffer, offset, 0, size, registerSrcUsage: false);
|
|
}
|
|
else
|
|
{
|
|
// Source buffer is no longer alive, don't copy anything to flush storage.
|
|
srcBuffer = null;
|
|
}
|
|
}
|
|
|
|
flushStorage.WaitForFences();
|
|
srcBuffer?.DecrementReferenceCount();
|
|
return flushStorage.GetDataStorage(0, size);
|
|
}
|
|
|
|
public Span<byte> GetTextureData(CommandBufferPool cbp, Texture view, int size)
|
|
{
|
|
TextureCreateInfo info = view.Info;
|
|
|
|
var flushStorage = ResizeIfNeeded(size);
|
|
|
|
using (var cbs = cbp.Rent())
|
|
{
|
|
var buffer = flushStorage.GetBuffer().Get(cbs).Value;
|
|
var image = view.GetHandle();
|
|
|
|
view.CopyFromOrToBuffer(cbs, buffer, image, size, true, 0, 0, info.GetLayers(), info.Levels, singleSlice: false);
|
|
}
|
|
|
|
flushStorage.WaitForFences();
|
|
return flushStorage.GetDataStorage(0, size);
|
|
}
|
|
|
|
public Span<byte> GetTextureData(CommandBufferPool cbp, Texture view, int size, int layer, int level)
|
|
{
|
|
var flushStorage = ResizeIfNeeded(size);
|
|
|
|
using (var cbs = cbp.Rent())
|
|
{
|
|
var buffer = flushStorage.GetBuffer().Get(cbs).Value;
|
|
var image = view.GetHandle();
|
|
|
|
view.CopyFromOrToBuffer(cbs, buffer, image, size, true, layer, level, 1, 1, singleSlice: true);
|
|
}
|
|
|
|
flushStorage.WaitForFences();
|
|
return flushStorage.GetDataStorage(0, size);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_flushStorage.Dispose();
|
|
}
|
|
}
|
|
}
|