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:
parent
e3468d35b6
commit
ea30e543e6
2 changed files with 21 additions and 9 deletions
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue