Fix preload cbs optimization (for real) (#34)

* Mostly fix preload cbs. There seems to be some random flickering...

* fix index buffer usage range

* fix missing preflush submit before present
This commit is contained in:
riperiperi 2024-07-05 09:35:17 +01:00 committed by Isaac Marovitz
parent e3468d35b6
commit ea30e543e6
2 changed files with 21 additions and 9 deletions

View file

@ -191,14 +191,14 @@ namespace Ryujinx.Graphics.Metal
} }
if (cbs != null && if (cbs != null &&
_pipeline.RenderPassActive && cbs.Value.Encoders.CurrentEncoderType == EncoderType.Render &&
!(_buffer.HasCommandBufferDependency(cbs.Value) && !(_buffer.HasCommandBufferDependency(cbs.Value) &&
_waitable.IsBufferRangeInUse(cbs.Value.CommandBufferIndex, offset, dataSize))) _waitable.IsBufferRangeInUse(cbs.Value.CommandBufferIndex, offset, dataSize)))
{ {
// If the buffer hasn't been used on the command buffer yet, try to preload the data. // If the buffer hasn't been used on the command buffer yet, try to preload the data.
// This avoids ending and beginning render passes on each buffer data upload. // This avoids ending and beginning render passes on each buffer data upload.
cbs = _pipeline.PreloadCbs; cbs = _pipeline.GetPreloadCommandBuffer();
} }
if (allowCbsWait) if (allowCbsWait)

View file

@ -36,7 +36,6 @@ namespace Ryujinx.Graphics.Metal
internal CommandBufferScoped Cbs { get; private set; } internal CommandBufferScoped Cbs { get; private set; }
internal CommandBufferEncoder Encoders => Cbs.Encoders; internal CommandBufferEncoder Encoders => Cbs.Encoders;
internal EncoderType CurrentEncoderType => Encoders.CurrentEncoderType; internal EncoderType CurrentEncoderType => Encoders.CurrentEncoderType;
internal bool RenderPassActive { get; private set; }
public Pipeline(MTLDevice device, MetalRenderer renderer) public Pipeline(MTLDevice device, MetalRenderer renderer)
{ {
@ -137,7 +136,7 @@ namespace Ryujinx.Graphics.Metal
Cbs.CommandBuffer.PresentDrawable(drawable); Cbs.CommandBuffer.PresentDrawable(drawable);
CommandBuffer = (Cbs = _renderer.CommandBufferPool.ReturnAndRent(Cbs)).CommandBuffer; FlushCommandsImpl();
// TODO: Auto flush counting // TODO: Auto flush counting
_renderer.SyncManager.GetAndResetWaitTicks(); _renderer.SyncManager.GetAndResetWaitTicks();
@ -146,6 +145,13 @@ namespace Ryujinx.Graphics.Metal
dst.Dispose(); dst.Dispose();
} }
public CommandBufferScoped GetPreloadCommandBuffer()
{
PreloadCbs ??= _renderer.CommandBufferPool.Rent();
return PreloadCbs.Value;
}
public void FlushCommandsIfWeightExceeding(IAuto disposedResource, ulong byteWeight) public void FlushCommandsIfWeightExceeding(IAuto disposedResource, ulong byteWeight)
{ {
bool usedByCurrentCb = disposedResource.HasCommandBufferDependency(Cbs); bool usedByCurrentCb = disposedResource.HasCommandBufferDependency(Cbs);
@ -383,12 +389,16 @@ namespace Ryujinx.Graphics.Metal
var indexBuffer = _encoderStateManager.IndexBuffer; var indexBuffer = _encoderStateManager.IndexBuffer;
ulong offset = _encoderStateManager.IndexBufferOffset;
MTLIndexType type = _encoderStateManager.IndexType;
int indexSize = type == MTLIndexType.UInt32 ? sizeof(int) : sizeof(short);
renderCommandEncoder.DrawIndexedPrimitives( renderCommandEncoder.DrawIndexedPrimitives(
primitiveType, primitiveType,
(ulong)indexCount, (ulong)indexCount,
_encoderStateManager.IndexType, type,
indexBuffer.Get(Cbs, 0, indexCount * sizeof(int)).Value, indexBuffer.Get(Cbs, (int)offset, indexCount * indexSize).Value,
_encoderStateManager.IndexBufferOffset, offset,
(ulong)instanceCount, (ulong)instanceCount,
firstVertex, firstVertex,
(ulong)firstInstance); (ulong)firstInstance);
@ -533,11 +543,13 @@ namespace Ryujinx.Graphics.Metal
public void SetPrimitiveRestart(bool enable, int index) public void SetPrimitiveRestart(bool enable, int index)
{ {
// TODO: Supported for LineStrip and TriangleStrip // Always active for LineStrip and TriangleStrip
// https://github.com/gpuweb/gpuweb/issues/1220#issuecomment-732483263 // https://github.com/gpuweb/gpuweb/issues/1220#issuecomment-732483263
// https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515520-drawindexedprimitives // https://developer.apple.com/documentation/metal/mtlrendercommandencoder/1515520-drawindexedprimitives
// https://stackoverflow.com/questions/70813665/how-to-render-multiple-trianglestrips-using-metal // https://stackoverflow.com/questions/70813665/how-to-render-multiple-trianglestrips-using-metal
Logger.Warning?.Print(LogClass.Gpu, "Not Implemented!");
// Emulating disabling this is very difficult. It's unlikely for an index buffer to use the largest possible index,
// so it's fine nearly all of the time.
} }
public void SetPrimitiveTopology(PrimitiveTopology topology) public void SetPrimitiveTopology(PrimitiveTopology topology)