Skip to content

Commit

Permalink
Merge pull request #8 from frenzibyte/improve-mtl-drawable-retrieval-…
Browse files Browse the repository at this point in the history
…rebased

Improve Metal drawable retrieval for better performance (rebased)
  • Loading branch information
peppy committed Apr 13, 2023
2 parents 0ec05ac + 8e8268a commit b531597
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 72 deletions.
8 changes: 3 additions & 5 deletions src/Veldrid/MTL/MTLCommandList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ internal unsafe class MTLCommandList : CommandList
{
private readonly MTLGraphicsDevice _gd;
private MTLCommandBuffer _cb;
private MTLFramebufferBase _mtlFramebuffer;
private MTLFramebuffer _mtlFramebuffer;
private uint _viewportCount;
private bool _currentFramebufferEverActive;
private MTLRenderCommandEncoder _rce;
Expand Down Expand Up @@ -749,7 +749,7 @@ protected override void SetFramebufferCore(Framebuffer fb)
}

EnsureNoRenderPass();
_mtlFramebuffer = Util.AssertSubtype<Framebuffer, MTLFramebufferBase>(fb);
_mtlFramebuffer = Util.AssertSubtype<Framebuffer, MTLFramebuffer>(fb);
_viewportCount = Math.Max(1u, (uint)fb.ColorTargets.Count);
Util.EnsureArrayMinimumSize(ref _viewports, _viewportCount);
Util.ClearArray(_viewports);
Expand Down Expand Up @@ -996,10 +996,8 @@ private bool EnsureRenderPass()

private bool BeginCurrentRenderPass()
{
if (!_mtlFramebuffer.IsRenderable)
{
if (_mtlFramebuffer is MTLSwapchainFramebuffer swapchainFramebuffer && !swapchainFramebuffer.EnsureDrawableAvailable())
return false;
}

MTLRenderPassDescriptor rpDesc = _mtlFramebuffer.CreateRenderPassDescriptor();
for (uint i = 0; i < _clearColors.Length; i++)
Expand Down
13 changes: 9 additions & 4 deletions src/Veldrid/MTL/MTLFramebuffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,23 @@

namespace Veldrid.MTL
{
internal class MTLFramebuffer : MTLFramebufferBase
internal class MTLFramebuffer : Framebuffer
{
public override bool IsRenderable => true;
private bool _disposed;

public MTLFramebuffer(MTLGraphicsDevice gd, ref FramebufferDescription description)
: base(gd, ref description)
: base(description.DepthTarget, description.ColorTargets)
{
}

public override MTLRenderPassDescriptor CreateRenderPassDescriptor()
public MTLFramebuffer()
{
}

public MTLRenderPassDescriptor CreateRenderPassDescriptor()
{
MTLRenderPassDescriptor ret = MTLRenderPassDescriptor.New();

for (int i = 0; i < ColorTargets.Count; i++)
{
FramebufferAttachment colorTarget = ColorTargets[i];
Expand Down Expand Up @@ -50,6 +54,7 @@ public override MTLRenderPassDescriptor CreateRenderPassDescriptor()
return ret;
}

public override string Name { get; set; }
public override bool IsDisposed => _disposed;

public override void Dispose()
Expand Down
21 changes: 0 additions & 21 deletions src/Veldrid/MTL/MTLFramebufferBase.cs

This file was deleted.

4 changes: 2 additions & 2 deletions src/Veldrid/MTL/MTLGraphicsDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -308,9 +308,9 @@ private protected override void SwapBuffersCore(Swapchain swapchain)
submitCB.presentDrawable(currentDrawablePtr);
submitCB.commit();
}
}

mtlSC.GetNextDrawable();
mtlSC.InvalidateDrawable();
}
}

private protected override void UpdateBufferCore(DeviceBuffer buffer, uint bufferOffsetInBytes, IntPtr source, uint sizeInBytes)
Expand Down
24 changes: 19 additions & 5 deletions src/Veldrid/MTL/MTLSwapchain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,10 @@ public MTLSwapchain(MTLGraphicsDevice gd, ref SwapchainDescription description)
description.DepthFormat,
format);

GetNextDrawable();
getNextDrawable();
}

public void GetNextDrawable()
private bool getNextDrawable()
{
if (!_drawable.IsNull)
{
Expand All @@ -122,9 +122,15 @@ public void GetNextDrawable()
using (NSAutoreleasePool.Begin())
{
_drawable = _metalLayer.nextDrawable();
ObjectiveCRuntime.retain(_drawable.NativePtr);

_framebuffer.UpdateTextures(_drawable, _metalLayer.drawableSize);
if (!_drawable.IsNull)
{
ObjectiveCRuntime.retain(_drawable.NativePtr);
_framebuffer.UpdateTextures(_drawable, _metalLayer.drawableSize);
return true;
}

return false;
}
}

Expand All @@ -135,7 +141,15 @@ public override void Resize(uint width, uint height)

_metalLayer.drawableSize = new CGSize(width, height);

GetNextDrawable();
getNextDrawable();
}

public bool EnsureDrawableAvailable() => !_drawable.IsNull || getNextDrawable();

public void InvalidateDrawable()
{
ObjectiveCRuntime.release(_drawable.NativePtr);
_drawable = default;
}

private void SetSyncToVerticalBlank(bool value)
Expand Down
40 changes: 5 additions & 35 deletions src/Veldrid/MTL/MTLSwapchainFramebuffer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,32 @@

namespace Veldrid.MTL
{
internal class MTLSwapchainFramebuffer : MTLFramebufferBase
internal class MTLSwapchainFramebuffer : MTLFramebuffer
{
private readonly MTLGraphicsDevice _gd;
private MTLTexture _colorTexture;
private MTLTexture _depthTexture;
private readonly MTLSwapchain _parentSwapchain;
private readonly PixelFormat _colorFormat;
private bool _disposed;

public override uint Width => _colorTexture.Width;
public override uint Height => _colorTexture.Height;

public override OutputDescription OutputDescription { get; }

private FramebufferAttachment[] _colorTargets;
private FramebufferAttachment? _depthTarget;

private readonly FramebufferAttachment? _depthTarget;
private readonly PixelFormat? _depthFormat;

public override IReadOnlyList<FramebufferAttachment> ColorTargets => _colorTargets;
public override FramebufferAttachment? DepthTarget => _depthTarget;

public override bool IsDisposed => _disposed;

public MTLSwapchainFramebuffer(
MTLGraphicsDevice gd,
MTLSwapchain parent,
PixelFormat? depthFormat,
PixelFormat colorFormat)
: base()
{
_gd = gd;
_parentSwapchain = parent;
Expand Down Expand Up @@ -62,6 +58,7 @@ private void RecreateDepthTexture(uint width, uint height)
_depthTexture = Util.AssertSubtype<Texture, MTLTexture>(
_gd.ResourceFactory.CreateTexture(TextureDescription.Texture2D(
width, height, 1, 1, _depthFormat.Value, TextureUsage.DepthStencil)));
_depthTarget = new FramebufferAttachment(_depthTexture, 0);
}

public void UpdateTextures(CAMetalDrawable drawable, CGSize size)
Expand All @@ -73,39 +70,12 @@ public void UpdateTextures(CAMetalDrawable drawable, CGSize size)
RecreateDepthTexture((uint)size.width, (uint)size.height);
}

public override bool IsRenderable => !_parentSwapchain.CurrentDrawable.IsNull;

public override MTLRenderPassDescriptor CreateRenderPassDescriptor()
{
MTLRenderPassDescriptor ret = MTLRenderPassDescriptor.New();
var color0 = ret.colorAttachments[0];
color0.texture = _parentSwapchain.CurrentDrawable.texture;
color0.loadAction = MTLLoadAction.Load;

if (_depthTarget != null)
{
var depthAttachment = ret.depthAttachment;
depthAttachment.texture = _depthTexture.DeviceTexture;
depthAttachment.loadAction = MTLLoadAction.Load;
depthAttachment.storeAction = MTLStoreAction.Store;

if (FormatHelpers.IsStencilFormat(_depthTarget.Value.Target.Format))
{
MTLRenderPassStencilAttachmentDescriptor stencilDescriptor = ret.stencilAttachment;
stencilDescriptor.loadAction = MTLLoadAction.Load;
stencilDescriptor.storeAction = MTLStoreAction.Store;
stencilDescriptor.texture = _depthTexture.DeviceTexture;
stencilDescriptor.slice = (UIntPtr)_depthTarget.Value.ArrayLayer;
}
}

return ret;
}
public bool EnsureDrawableAvailable() => _parentSwapchain.EnsureDrawableAvailable();

public override void Dispose()
{
_depthTexture?.Dispose();
_disposed = true;
base.Dispose();
}
}
}

0 comments on commit b531597

Please sign in to comment.