mirror of
https://git.naxdy.org/Mirror/Ryujinx.git
synced 2024-12-26 18:43:04 +00:00
Metal: Argument Buffer Pre-Pass (#38)
* Init * Fix missing flags * Cleanup
This commit is contained in:
parent
fff3a4f8f8
commit
6e3aaa6360
5 changed files with 187 additions and 61 deletions
|
@ -18,11 +18,11 @@ class CommandBufferEncoder
|
||||||
{
|
{
|
||||||
public EncoderType CurrentEncoderType { get; private set; } = EncoderType.None;
|
public EncoderType CurrentEncoderType { get; private set; } = EncoderType.None;
|
||||||
|
|
||||||
public MTLBlitCommandEncoder BlitEncoder => new MTLBlitCommandEncoder(CurrentEncoder.Value);
|
public MTLBlitCommandEncoder BlitEncoder => new(CurrentEncoder.Value);
|
||||||
|
|
||||||
public MTLComputeCommandEncoder ComputeEncoder => new MTLComputeCommandEncoder(CurrentEncoder.Value);
|
public MTLComputeCommandEncoder ComputeEncoder => new(CurrentEncoder.Value);
|
||||||
|
|
||||||
public MTLRenderCommandEncoder RenderEncoder => new MTLRenderCommandEncoder(CurrentEncoder.Value);
|
public MTLRenderCommandEncoder RenderEncoder => new(CurrentEncoder.Value);
|
||||||
|
|
||||||
internal MTLCommandEncoder? CurrentEncoder { get; private set; }
|
internal MTLCommandEncoder? CurrentEncoder { get; private set; }
|
||||||
|
|
||||||
|
|
63
src/Ryujinx.Graphics.Metal/EncoderResources.cs
Normal file
63
src/Ryujinx.Graphics.Metal/EncoderResources.cs
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
using SharpMetal.Metal;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Ryujinx.Graphics.Metal
|
||||||
|
{
|
||||||
|
public struct RenderEncoderResources
|
||||||
|
{
|
||||||
|
public List<Resource> Resources = new();
|
||||||
|
public List<BufferResource> VertexBuffers = new();
|
||||||
|
public List<BufferResource> FragmentBuffers = new();
|
||||||
|
|
||||||
|
public RenderEncoderResources() { }
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
Resources.Clear();
|
||||||
|
VertexBuffers.Clear();
|
||||||
|
FragmentBuffers.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct ComputeEncoderResources
|
||||||
|
{
|
||||||
|
public List<Resource> Resources = new();
|
||||||
|
public List<BufferResource> Buffers = new();
|
||||||
|
|
||||||
|
public ComputeEncoderResources() { }
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
Resources.Clear();
|
||||||
|
Buffers.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct BufferResource
|
||||||
|
{
|
||||||
|
public MTLBuffer Buffer;
|
||||||
|
public ulong Offset;
|
||||||
|
public ulong Binding;
|
||||||
|
|
||||||
|
public BufferResource(MTLBuffer buffer, ulong offset, ulong binding)
|
||||||
|
{
|
||||||
|
Buffer = buffer;
|
||||||
|
Offset = offset;
|
||||||
|
Binding = binding;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct Resource
|
||||||
|
{
|
||||||
|
public MTLResource MtlResource;
|
||||||
|
public MTLResourceUsage ResourceUsage;
|
||||||
|
public MTLRenderStages Stages;
|
||||||
|
|
||||||
|
public Resource(MTLResource resource, MTLResourceUsage resourceUsage, MTLRenderStages stages)
|
||||||
|
{
|
||||||
|
MtlResource = resource;
|
||||||
|
ResourceUsage = resourceUsage;
|
||||||
|
Stages = stages;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -152,6 +152,9 @@ namespace Ryujinx.Graphics.Metal
|
||||||
// Only to be used for present
|
// Only to be used for present
|
||||||
public bool ClearLoadAction = false;
|
public bool ClearLoadAction = false;
|
||||||
|
|
||||||
|
public RenderEncoderResources RenderEncoderResources = new();
|
||||||
|
public ComputeEncoderResources ComputeEncoderResources = new();
|
||||||
|
|
||||||
public EncoderState()
|
public EncoderState()
|
||||||
{
|
{
|
||||||
Pipeline.Initialize();
|
Pipeline.Initialize();
|
||||||
|
|
|
@ -62,6 +62,16 @@ namespace Ryujinx.Graphics.Metal
|
||||||
_currentState.Dirty |= flags;
|
_currentState.Dirty |= flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SignalRenderDirty()
|
||||||
|
{
|
||||||
|
SignalDirty(DirtyFlags.RenderAll);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SignalComputeDirty()
|
||||||
|
{
|
||||||
|
SignalDirty(DirtyFlags.ComputeAll);
|
||||||
|
}
|
||||||
|
|
||||||
public EncoderState SwapState(EncoderState state, DirtyFlags flags = DirtyFlags.All)
|
public EncoderState SwapState(EncoderState state, DirtyFlags flags = DirtyFlags.All)
|
||||||
{
|
{
|
||||||
_currentState = state ?? _mainState;
|
_currentState = state ?? _mainState;
|
||||||
|
@ -110,7 +120,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
public readonly MTLRenderCommandEncoder CreateRenderCommandEncoder()
|
public readonly MTLRenderCommandEncoder CreateRenderCommandEncoder()
|
||||||
{
|
{
|
||||||
// Initialise Pass & State
|
// Initialise Pass & State
|
||||||
var renderPassDescriptor = new MTLRenderPassDescriptor();
|
using var renderPassDescriptor = new MTLRenderPassDescriptor();
|
||||||
|
|
||||||
for (int i = 0; i < Constants.MaxColorAttachments; i++)
|
for (int i = 0; i < Constants.MaxColorAttachments; i++)
|
||||||
{
|
{
|
||||||
|
@ -165,12 +175,6 @@ namespace Ryujinx.Graphics.Metal
|
||||||
// Initialise Encoder
|
// Initialise Encoder
|
||||||
var renderCommandEncoder = _pipeline.CommandBuffer.RenderCommandEncoder(renderPassDescriptor);
|
var renderCommandEncoder = _pipeline.CommandBuffer.RenderCommandEncoder(renderPassDescriptor);
|
||||||
|
|
||||||
// Mark all state as dirty to ensure it is set on the encoder
|
|
||||||
SignalDirty(DirtyFlags.RenderAll);
|
|
||||||
|
|
||||||
// Cleanup
|
|
||||||
renderPassDescriptor.Dispose();
|
|
||||||
|
|
||||||
return renderCommandEncoder;
|
return renderCommandEncoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,18 +183,69 @@ namespace Ryujinx.Graphics.Metal
|
||||||
using var descriptor = new MTLComputePassDescriptor();
|
using var descriptor = new MTLComputePassDescriptor();
|
||||||
var computeCommandEncoder = _pipeline.CommandBuffer.ComputeCommandEncoder(descriptor);
|
var computeCommandEncoder = _pipeline.CommandBuffer.ComputeCommandEncoder(descriptor);
|
||||||
|
|
||||||
// Mark all state as dirty to ensure it is set on the encoder
|
|
||||||
SignalDirty(DirtyFlags.ComputeAll);
|
|
||||||
|
|
||||||
return computeCommandEncoder;
|
return computeCommandEncoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RenderResourcesPrepass()
|
||||||
|
{
|
||||||
|
_currentState.RenderEncoderResources.Clear();
|
||||||
|
|
||||||
|
if ((_currentState.Dirty & DirtyFlags.RenderPipeline) != 0)
|
||||||
|
{
|
||||||
|
SetVertexBuffers(_currentState.VertexBuffers, ref _currentState.RenderEncoderResources);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((_currentState.Dirty & DirtyFlags.Uniforms) != 0)
|
||||||
|
{
|
||||||
|
UpdateAndBind(_currentState.RenderProgram, Constants.ConstantBuffersSetIndex, ref _currentState.RenderEncoderResources);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((_currentState.Dirty & DirtyFlags.Storages) != 0)
|
||||||
|
{
|
||||||
|
UpdateAndBind(_currentState.RenderProgram, Constants.StorageBuffersSetIndex, ref _currentState.RenderEncoderResources);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((_currentState.Dirty & DirtyFlags.Textures) != 0)
|
||||||
|
{
|
||||||
|
UpdateAndBind(_currentState.RenderProgram, Constants.TexturesSetIndex, ref _currentState.RenderEncoderResources);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((_currentState.Dirty & DirtyFlags.Images) != 0)
|
||||||
|
{
|
||||||
|
UpdateAndBind(_currentState.RenderProgram, Constants.ImagesSetIndex, ref _currentState.RenderEncoderResources);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ComputeResourcesPrepass()
|
||||||
|
{
|
||||||
|
_currentState.ComputeEncoderResources.Clear();
|
||||||
|
|
||||||
|
if ((_currentState.Dirty & DirtyFlags.Uniforms) != 0)
|
||||||
|
{
|
||||||
|
UpdateAndBind(_currentState.ComputeProgram, Constants.ConstantBuffersSetIndex, ref _currentState.ComputeEncoderResources);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((_currentState.Dirty & DirtyFlags.Storages) != 0)
|
||||||
|
{
|
||||||
|
UpdateAndBind(_currentState.ComputeProgram, Constants.StorageBuffersSetIndex, ref _currentState.ComputeEncoderResources);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((_currentState.Dirty & DirtyFlags.Textures) != 0)
|
||||||
|
{
|
||||||
|
UpdateAndBind(_currentState.ComputeProgram, Constants.TexturesSetIndex, ref _currentState.ComputeEncoderResources);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((_currentState.Dirty & DirtyFlags.Images) != 0)
|
||||||
|
{
|
||||||
|
UpdateAndBind(_currentState.ComputeProgram, Constants.ImagesSetIndex, ref _currentState.ComputeEncoderResources);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void RebindRenderState(MTLRenderCommandEncoder renderCommandEncoder)
|
public void RebindRenderState(MTLRenderCommandEncoder renderCommandEncoder)
|
||||||
{
|
{
|
||||||
if ((_currentState.Dirty & DirtyFlags.RenderPipeline) != 0)
|
if ((_currentState.Dirty & DirtyFlags.RenderPipeline) != 0)
|
||||||
{
|
{
|
||||||
SetRenderPipelineState(renderCommandEncoder);
|
SetRenderPipelineState(renderCommandEncoder);
|
||||||
SetVertexBuffers(renderCommandEncoder, _currentState.VertexBuffers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((_currentState.Dirty & DirtyFlags.DepthStencil) != 0)
|
if ((_currentState.Dirty & DirtyFlags.DepthStencil) != 0)
|
||||||
|
@ -233,24 +288,19 @@ namespace Ryujinx.Graphics.Metal
|
||||||
SetScissors(renderCommandEncoder);
|
SetScissors(renderCommandEncoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((_currentState.Dirty & DirtyFlags.Uniforms) != 0)
|
foreach (var resource in _currentState.RenderEncoderResources.Resources)
|
||||||
{
|
{
|
||||||
UpdateAndBind(renderCommandEncoder, _currentState.RenderProgram, Constants.ConstantBuffersSetIndex);
|
renderCommandEncoder.UseResource(resource.MtlResource, resource.ResourceUsage, resource.Stages);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((_currentState.Dirty & DirtyFlags.Storages) != 0)
|
foreach (var buffer in _currentState.RenderEncoderResources.VertexBuffers)
|
||||||
{
|
{
|
||||||
UpdateAndBind(renderCommandEncoder, _currentState.RenderProgram, Constants.StorageBuffersSetIndex);
|
renderCommandEncoder.SetVertexBuffer(buffer.Buffer, buffer.Offset, buffer.Binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((_currentState.Dirty & DirtyFlags.Textures) != 0)
|
foreach (var buffer in _currentState.RenderEncoderResources.FragmentBuffers)
|
||||||
{
|
{
|
||||||
UpdateAndBind(renderCommandEncoder, _currentState.RenderProgram, Constants.TexturesSetIndex);
|
renderCommandEncoder.SetFragmentBuffer(buffer.Buffer, buffer.Offset, buffer.Binding);
|
||||||
}
|
|
||||||
|
|
||||||
if ((_currentState.Dirty & DirtyFlags.Images) != 0)
|
|
||||||
{
|
|
||||||
UpdateAndBind(renderCommandEncoder, _currentState.RenderProgram, Constants.ImagesSetIndex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_currentState.Dirty &= ~DirtyFlags.RenderAll;
|
_currentState.Dirty &= ~DirtyFlags.RenderAll;
|
||||||
|
@ -263,24 +313,14 @@ namespace Ryujinx.Graphics.Metal
|
||||||
SetComputePipelineState(computeCommandEncoder);
|
SetComputePipelineState(computeCommandEncoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((_currentState.Dirty & DirtyFlags.Uniforms) != 0)
|
foreach (var resource in _currentState.ComputeEncoderResources.Resources)
|
||||||
{
|
{
|
||||||
UpdateAndBind(computeCommandEncoder, _currentState.ComputeProgram, Constants.ConstantBuffersSetIndex);
|
computeCommandEncoder.UseResource(resource.MtlResource, resource.ResourceUsage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((_currentState.Dirty & DirtyFlags.Storages) != 0)
|
foreach (var buffer in _currentState.ComputeEncoderResources.Buffers)
|
||||||
{
|
{
|
||||||
UpdateAndBind(computeCommandEncoder, _currentState.ComputeProgram, Constants.StorageBuffersSetIndex);
|
computeCommandEncoder.SetBuffer(buffer.Buffer, buffer.Offset, buffer.Binding);
|
||||||
}
|
|
||||||
|
|
||||||
if ((_currentState.Dirty & DirtyFlags.Textures) != 0)
|
|
||||||
{
|
|
||||||
UpdateAndBind(computeCommandEncoder, _currentState.ComputeProgram, Constants.TexturesSetIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((_currentState.Dirty & DirtyFlags.Images) != 0)
|
|
||||||
{
|
|
||||||
UpdateAndBind(computeCommandEncoder, _currentState.ComputeProgram, Constants.ImagesSetIndex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_currentState.Dirty &= ~DirtyFlags.ComputeAll;
|
_currentState.Dirty &= ~DirtyFlags.ComputeAll;
|
||||||
|
@ -1013,7 +1053,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
pipeline.VertexBindingDescriptionsCount = Constants.ZeroBufferIndex + 1; // TODO: move this out?
|
pipeline.VertexBindingDescriptionsCount = Constants.ZeroBufferIndex + 1; // TODO: move this out?
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly void SetVertexBuffers(MTLRenderCommandEncoder renderCommandEncoder, VertexBufferState[] bufferStates)
|
private readonly void SetVertexBuffers(VertexBufferState[] bufferStates, ref readonly RenderEncoderResources resources)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < bufferStates.Length; i++)
|
for (int i = 0; i < bufferStates.Length; i++)
|
||||||
{
|
{
|
||||||
|
@ -1021,7 +1061,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
if (mtlBuffer.NativePtr != IntPtr.Zero)
|
if (mtlBuffer.NativePtr != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
renderCommandEncoder.SetVertexBuffer(mtlBuffer, (ulong)offset, (ulong)i);
|
resources.VertexBuffers.Add(new BufferResource(mtlBuffer, (ulong)offset, (ulong)i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1035,10 +1075,10 @@ namespace Ryujinx.Graphics.Metal
|
||||||
}
|
}
|
||||||
|
|
||||||
var zeroMtlBuffer = autoZeroBuffer.Get(_pipeline.Cbs).Value;
|
var zeroMtlBuffer = autoZeroBuffer.Get(_pipeline.Cbs).Value;
|
||||||
renderCommandEncoder.SetVertexBuffer(zeroMtlBuffer, 0, Constants.ZeroBufferIndex);
|
resources.VertexBuffers.Add(new BufferResource(zeroMtlBuffer, 0, Constants.ZeroBufferIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly void UpdateAndBind(MTLRenderCommandEncoder renderCommandEncoder, Program program, uint setIndex)
|
private readonly void UpdateAndBind(Program program, uint setIndex, ref readonly RenderEncoderResources resources)
|
||||||
{
|
{
|
||||||
var bindingSegments = program.BindingSegments[setIndex];
|
var bindingSegments = program.BindingSegments[setIndex];
|
||||||
|
|
||||||
|
@ -1120,7 +1160,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
renderStages |= MTLRenderStages.RenderStageFragment;
|
renderStages |= MTLRenderStages.RenderStageFragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderCommandEncoder.UseResource(new MTLResource(mtlBuffer.NativePtr), MTLResourceUsage.Read, renderStages);
|
resources.Resources.Add(new Resource(new MTLResource(mtlBuffer.NativePtr), MTLResourceUsage.Read, renderStages));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Constants.StorageBuffersSetIndex:
|
case Constants.StorageBuffersSetIndex:
|
||||||
|
@ -1170,7 +1210,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
renderStages |= MTLRenderStages.RenderStageFragment;
|
renderStages |= MTLRenderStages.RenderStageFragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderCommandEncoder.UseResource(new MTLResource(mtlBuffer.NativePtr), MTLResourceUsage.Read, renderStages);
|
resources.Resources.Add(new Resource(new MTLResource(mtlBuffer.NativePtr), MTLResourceUsage.Read, renderStages));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Constants.TexturesSetIndex:
|
case Constants.TexturesSetIndex:
|
||||||
|
@ -1226,7 +1266,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
renderStages |= MTLRenderStages.RenderStageFragment;
|
renderStages |= MTLRenderStages.RenderStageFragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderCommandEncoder.UseResource(new MTLResource(mtlTexture.NativePtr), MTLResourceUsage.Read, renderStages);
|
resources.Resources.Add(new Resource(new MTLResource(mtlTexture.NativePtr), MTLResourceUsage.Read, renderStages));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1268,8 +1308,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
renderStages |= MTLRenderStages.RenderStageFragment;
|
renderStages |= MTLRenderStages.RenderStageFragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderCommandEncoder.UseResource(new MTLResource(mtlTexture.NativePtr),
|
resources.Resources.Add(new Resource(new MTLResource(mtlTexture.NativePtr), MTLResourceUsage.Read, renderStages));
|
||||||
MTLResourceUsage.Read, renderStages);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var sampler in samplers)
|
foreach (var sampler in samplers)
|
||||||
|
@ -1325,7 +1364,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
renderStages |= MTLRenderStages.RenderStageFragment;
|
renderStages |= MTLRenderStages.RenderStageFragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderCommandEncoder.UseResource(new MTLResource(mtlTexture.NativePtr), MTLResourceUsage.Read, renderStages);
|
resources.Resources.Add(new Resource(new MTLResource(mtlTexture.NativePtr), MTLResourceUsage.Read, renderStages));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1364,7 +1403,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
renderStages |= MTLRenderStages.RenderStageFragment;
|
renderStages |= MTLRenderStages.RenderStageFragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderCommandEncoder.UseResource(new MTLResource(mtlTexture.NativePtr), MTLResourceUsage.Read | MTLResourceUsage.Write, renderStages);
|
resources.Resources.Add(new Resource(new MTLResource(mtlTexture.NativePtr), MTLResourceUsage.Read | MTLResourceUsage.Write, renderStages));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1375,18 +1414,18 @@ namespace Ryujinx.Graphics.Metal
|
||||||
{
|
{
|
||||||
vertArgBuffer.Holder.SetDataUnchecked(vertArgBuffer.Offset, MemoryMarshal.AsBytes(vertResourceIds));
|
vertArgBuffer.Holder.SetDataUnchecked(vertArgBuffer.Offset, MemoryMarshal.AsBytes(vertResourceIds));
|
||||||
var mtlVertArgBuffer = _bufferManager.GetBuffer(vertArgBuffer.Handle, false).Get(_pipeline.Cbs).Value;
|
var mtlVertArgBuffer = _bufferManager.GetBuffer(vertArgBuffer.Handle, false).Get(_pipeline.Cbs).Value;
|
||||||
renderCommandEncoder.SetVertexBuffer(mtlVertArgBuffer, (uint)vertArgBuffer.Range.Offset, SetIndexToBindingIndex(setIndex));
|
resources.VertexBuffers.Add(new BufferResource(mtlVertArgBuffer, (uint)vertArgBuffer.Range.Offset, SetIndexToBindingIndex(setIndex)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (program.FragArgumentBufferSizes[setIndex] > 0)
|
if (program.FragArgumentBufferSizes[setIndex] > 0)
|
||||||
{
|
{
|
||||||
fragArgBuffer.Holder.SetDataUnchecked(fragArgBuffer.Offset, MemoryMarshal.AsBytes(fragResourceIds));
|
fragArgBuffer.Holder.SetDataUnchecked(fragArgBuffer.Offset, MemoryMarshal.AsBytes(fragResourceIds));
|
||||||
var mtlFragArgBuffer = _bufferManager.GetBuffer(fragArgBuffer.Handle, false).Get(_pipeline.Cbs).Value;
|
var mtlFragArgBuffer = _bufferManager.GetBuffer(fragArgBuffer.Handle, false).Get(_pipeline.Cbs).Value;
|
||||||
renderCommandEncoder.SetFragmentBuffer(mtlFragArgBuffer, (uint)fragArgBuffer.Range.Offset, SetIndexToBindingIndex(setIndex));
|
resources.FragmentBuffers.Add(new BufferResource(mtlFragArgBuffer, (uint)fragArgBuffer.Range.Offset, SetIndexToBindingIndex(setIndex)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly void UpdateAndBind(MTLComputeCommandEncoder computeCommandEncoder, Program program, uint setIndex)
|
private readonly void UpdateAndBind(Program program, uint setIndex, ref readonly ComputeEncoderResources resources)
|
||||||
{
|
{
|
||||||
var bindingSegments = program.BindingSegments[setIndex];
|
var bindingSegments = program.BindingSegments[setIndex];
|
||||||
|
|
||||||
|
@ -1443,7 +1482,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
if ((segment.Stages & ResourceStages.Compute) != 0)
|
if ((segment.Stages & ResourceStages.Compute) != 0)
|
||||||
{
|
{
|
||||||
computeCommandEncoder.UseResource(new MTLResource(mtlBuffer.NativePtr), MTLResourceUsage.Read);
|
resources.Resources.Add(new Resource(new MTLResource(mtlBuffer.NativePtr), MTLResourceUsage.Read, 0));
|
||||||
resourceIds[resourceIdIndex] = mtlBuffer.GpuAddress + (ulong)offset;
|
resourceIds[resourceIdIndex] = mtlBuffer.GpuAddress + (ulong)offset;
|
||||||
resourceIdIndex++;
|
resourceIdIndex++;
|
||||||
}
|
}
|
||||||
|
@ -1480,7 +1519,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
if ((segment.Stages & ResourceStages.Compute) != 0)
|
if ((segment.Stages & ResourceStages.Compute) != 0)
|
||||||
{
|
{
|
||||||
computeCommandEncoder.UseResource(new MTLResource(mtlBuffer.NativePtr), MTLResourceUsage.Read | MTLResourceUsage.Write);
|
resources.Resources.Add(new Resource(new MTLResource(mtlBuffer.NativePtr), MTLResourceUsage.Read | MTLResourceUsage.Write, 0));
|
||||||
resourceIds[resourceIdIndex] = mtlBuffer.GpuAddress + (ulong)offset;
|
resourceIds[resourceIdIndex] = mtlBuffer.GpuAddress + (ulong)offset;
|
||||||
resourceIdIndex++;
|
resourceIdIndex++;
|
||||||
}
|
}
|
||||||
|
@ -1511,7 +1550,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
if ((segment.Stages & ResourceStages.Compute) != 0)
|
if ((segment.Stages & ResourceStages.Compute) != 0)
|
||||||
{
|
{
|
||||||
computeCommandEncoder.UseResource(new MTLResource(mtlTexture.NativePtr), MTLResourceUsage.Read);
|
resources.Resources.Add(new Resource(new MTLResource(mtlTexture.NativePtr), MTLResourceUsage.Read, 0));
|
||||||
resourceIds[resourceIdIndex] = mtlTexture.GpuResourceID._impl;
|
resourceIds[resourceIdIndex] = mtlTexture.GpuResourceID._impl;
|
||||||
resourceIdIndex++;
|
resourceIdIndex++;
|
||||||
|
|
||||||
|
@ -1545,8 +1584,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
if ((segment.Stages & ResourceStages.Compute) != 0)
|
if ((segment.Stages & ResourceStages.Compute) != 0)
|
||||||
{
|
{
|
||||||
computeCommandEncoder.UseResource(new MTLResource(mtlTexture.NativePtr),
|
resources.Resources.Add(new Resource(new MTLResource(mtlTexture.NativePtr), MTLResourceUsage.Read, 0));
|
||||||
MTLResourceUsage.Read);
|
|
||||||
resourceIds[resourceIdIndex] = mtlTexture.GpuResourceID._impl;
|
resourceIds[resourceIdIndex] = mtlTexture.GpuResourceID._impl;
|
||||||
resourceIdIndex++;
|
resourceIdIndex++;
|
||||||
|
|
||||||
|
@ -1580,7 +1618,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
if ((segment.Stages & ResourceStages.Compute) != 0)
|
if ((segment.Stages & ResourceStages.Compute) != 0)
|
||||||
{
|
{
|
||||||
computeCommandEncoder.UseResource(new MTLResource(mtlTexture.NativePtr), MTLResourceUsage.Read);
|
resources.Resources.Add(new Resource(new MTLResource(mtlTexture.NativePtr), MTLResourceUsage.Read, 0));
|
||||||
resourceIds[resourceIdIndex] = mtlTexture.GpuResourceID._impl;
|
resourceIds[resourceIdIndex] = mtlTexture.GpuResourceID._impl;
|
||||||
resourceIdIndex++;
|
resourceIdIndex++;
|
||||||
}
|
}
|
||||||
|
@ -1610,7 +1648,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
if ((segment.Stages & ResourceStages.Compute) != 0)
|
if ((segment.Stages & ResourceStages.Compute) != 0)
|
||||||
{
|
{
|
||||||
computeCommandEncoder.UseResource(new MTLResource(mtlTexture.NativePtr), MTLResourceUsage.Read | MTLResourceUsage.Write);
|
resources.Resources.Add(new Resource(new MTLResource(mtlTexture.NativePtr), MTLResourceUsage.Read | MTLResourceUsage.Write, 0));
|
||||||
resourceIds[resourceIdIndex] = mtlTexture.GpuResourceID._impl;
|
resourceIds[resourceIdIndex] = mtlTexture.GpuResourceID._impl;
|
||||||
resourceIdIndex++;
|
resourceIdIndex++;
|
||||||
}
|
}
|
||||||
|
@ -1625,7 +1663,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
{
|
{
|
||||||
argBuffer.Holder.SetDataUnchecked(argBuffer.Offset, MemoryMarshal.AsBytes(resourceIds));
|
argBuffer.Holder.SetDataUnchecked(argBuffer.Offset, MemoryMarshal.AsBytes(resourceIds));
|
||||||
var mtlArgBuffer = _bufferManager.GetBuffer(argBuffer.Handle, false).Get(_pipeline.Cbs).Value;
|
var mtlArgBuffer = _bufferManager.GetBuffer(argBuffer.Handle, false).Get(_pipeline.Cbs).Value;
|
||||||
computeCommandEncoder.SetBuffer(mtlArgBuffer, (uint)argBuffer.Range.Offset, SetIndexToBindingIndex(setIndex));
|
resources.Buffers.Add(new BufferResource(mtlArgBuffer, (uint)argBuffer.Range.Offset, SetIndexToBindingIndex(setIndex)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,17 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
public MTLRenderCommandEncoder GetOrCreateRenderEncoder(bool forDraw = false)
|
public MTLRenderCommandEncoder GetOrCreateRenderEncoder(bool forDraw = false)
|
||||||
{
|
{
|
||||||
|
// Mark all state as dirty to ensure it is set on the new encoder
|
||||||
|
if (Cbs.Encoders.CurrentEncoderType != EncoderType.Render)
|
||||||
|
{
|
||||||
|
_encoderStateManager.SignalRenderDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (forDraw)
|
||||||
|
{
|
||||||
|
_encoderStateManager.RenderResourcesPrepass();
|
||||||
|
}
|
||||||
|
|
||||||
MTLRenderCommandEncoder renderCommandEncoder = Cbs.Encoders.EnsureRenderEncoder();
|
MTLRenderCommandEncoder renderCommandEncoder = Cbs.Encoders.EnsureRenderEncoder();
|
||||||
|
|
||||||
if (forDraw)
|
if (forDraw)
|
||||||
|
@ -99,6 +110,17 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
public MTLComputeCommandEncoder GetOrCreateComputeEncoder(bool forDispatch = false)
|
public MTLComputeCommandEncoder GetOrCreateComputeEncoder(bool forDispatch = false)
|
||||||
{
|
{
|
||||||
|
// Mark all state as dirty to ensure it is set on the new encoder
|
||||||
|
if (Cbs.Encoders.CurrentEncoderType != EncoderType.Compute)
|
||||||
|
{
|
||||||
|
_encoderStateManager.SignalComputeDirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (forDispatch)
|
||||||
|
{
|
||||||
|
_encoderStateManager.ComputeResourcesPrepass();
|
||||||
|
}
|
||||||
|
|
||||||
MTLComputeCommandEncoder computeCommandEncoder = Cbs.Encoders.EnsureComputeEncoder();
|
MTLComputeCommandEncoder computeCommandEncoder = Cbs.Encoders.EnsureComputeEncoder();
|
||||||
|
|
||||||
if (forDispatch)
|
if (forDispatch)
|
||||||
|
|
Loading…
Reference in a new issue