mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-06-28 15:26:24 +02:00
EXPERIMENTAL: Metal backend (#441)
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>
This commit is contained in:
parent
3094df54dd
commit
852823104f
131 changed files with 14992 additions and 140 deletions
206
src/Ryujinx.Graphics.Metal/EncoderState.cs
Normal file
206
src/Ryujinx.Graphics.Metal/EncoderState.cs
Normal file
|
@ -0,0 +1,206 @@
|
|||
using Ryujinx.Common.Memory;
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Graphics.Metal.State;
|
||||
using Ryujinx.Graphics.Shader;
|
||||
using SharpMetal.Metal;
|
||||
using System;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace Ryujinx.Graphics.Metal
|
||||
{
|
||||
[Flags]
|
||||
enum DirtyFlags
|
||||
{
|
||||
None = 0,
|
||||
RenderPipeline = 1 << 0,
|
||||
ComputePipeline = 1 << 1,
|
||||
DepthStencil = 1 << 2,
|
||||
DepthClamp = 1 << 3,
|
||||
DepthBias = 1 << 4,
|
||||
CullMode = 1 << 5,
|
||||
FrontFace = 1 << 6,
|
||||
StencilRef = 1 << 7,
|
||||
Viewports = 1 << 8,
|
||||
Scissors = 1 << 9,
|
||||
Uniforms = 1 << 10,
|
||||
Storages = 1 << 11,
|
||||
Textures = 1 << 12,
|
||||
Images = 1 << 13,
|
||||
|
||||
ArgBuffers = Uniforms | Storages | Textures | Images,
|
||||
|
||||
RenderAll = RenderPipeline | DepthStencil | DepthClamp | DepthBias | CullMode | FrontFace | StencilRef | Viewports | Scissors | ArgBuffers,
|
||||
ComputeAll = ComputePipeline | ArgBuffers,
|
||||
All = RenderAll | ComputeAll,
|
||||
}
|
||||
|
||||
record struct BufferRef
|
||||
{
|
||||
public Auto<DisposableBuffer> Buffer;
|
||||
public BufferRange? Range;
|
||||
|
||||
public BufferRef(Auto<DisposableBuffer> buffer)
|
||||
{
|
||||
Buffer = buffer;
|
||||
}
|
||||
|
||||
public BufferRef(Auto<DisposableBuffer> buffer, ref BufferRange range)
|
||||
{
|
||||
Buffer = buffer;
|
||||
Range = range;
|
||||
}
|
||||
}
|
||||
|
||||
record struct TextureRef
|
||||
{
|
||||
public ShaderStage Stage;
|
||||
public TextureBase Storage;
|
||||
public Auto<DisposableSampler> Sampler;
|
||||
public Format ImageFormat;
|
||||
|
||||
public TextureRef(ShaderStage stage, TextureBase storage, Auto<DisposableSampler> sampler)
|
||||
{
|
||||
Stage = stage;
|
||||
Storage = storage;
|
||||
Sampler = sampler;
|
||||
}
|
||||
}
|
||||
|
||||
record struct ImageRef
|
||||
{
|
||||
public ShaderStage Stage;
|
||||
public Texture Storage;
|
||||
|
||||
public ImageRef(ShaderStage stage, Texture storage)
|
||||
{
|
||||
Stage = stage;
|
||||
Storage = storage;
|
||||
}
|
||||
}
|
||||
|
||||
struct PredrawState
|
||||
{
|
||||
public MTLCullMode CullMode;
|
||||
public DepthStencilUid DepthStencilUid;
|
||||
public PrimitiveTopology Topology;
|
||||
public MTLViewport[] Viewports;
|
||||
}
|
||||
|
||||
struct RenderTargetCopy
|
||||
{
|
||||
public MTLScissorRect[] Scissors;
|
||||
public Texture DepthStencil;
|
||||
public Texture[] RenderTargets;
|
||||
}
|
||||
|
||||
[SupportedOSPlatform("macos")]
|
||||
class EncoderState
|
||||
{
|
||||
public Program RenderProgram = null;
|
||||
public Program ComputeProgram = null;
|
||||
|
||||
public PipelineState Pipeline;
|
||||
public DepthStencilUid DepthStencilUid;
|
||||
|
||||
public readonly record struct ArrayRef<T>(ShaderStage Stage, T Array);
|
||||
|
||||
public readonly BufferRef[] UniformBufferRefs = new BufferRef[Constants.MaxUniformBufferBindings];
|
||||
public readonly BufferRef[] StorageBufferRefs = new BufferRef[Constants.MaxStorageBufferBindings];
|
||||
public readonly TextureRef[] TextureRefs = new TextureRef[Constants.MaxTextureBindings * 2];
|
||||
public readonly ImageRef[] ImageRefs = new ImageRef[Constants.MaxImageBindings * 2];
|
||||
|
||||
public ArrayRef<TextureArray>[] TextureArrayRefs = [];
|
||||
public ArrayRef<ImageArray>[] ImageArrayRefs = [];
|
||||
|
||||
public ArrayRef<TextureArray>[] TextureArrayExtraRefs = [];
|
||||
public ArrayRef<ImageArray>[] ImageArrayExtraRefs = [];
|
||||
|
||||
public IndexBufferState IndexBuffer = default;
|
||||
|
||||
public MTLDepthClipMode DepthClipMode = MTLDepthClipMode.Clip;
|
||||
|
||||
public float DepthBias;
|
||||
public float SlopeScale;
|
||||
public float Clamp;
|
||||
|
||||
public int BackRefValue = 0;
|
||||
public int FrontRefValue = 0;
|
||||
|
||||
public PrimitiveTopology Topology = PrimitiveTopology.Triangles;
|
||||
public MTLCullMode CullMode = MTLCullMode.None;
|
||||
public MTLWinding Winding = MTLWinding.CounterClockwise;
|
||||
public bool CullBoth = false;
|
||||
|
||||
public MTLViewport[] Viewports = new MTLViewport[Constants.MaxViewports];
|
||||
public MTLScissorRect[] Scissors = new MTLScissorRect[Constants.MaxViewports];
|
||||
|
||||
// Changes to attachments take recreation!
|
||||
public Texture DepthStencil;
|
||||
public Texture[] RenderTargets = new Texture[Constants.MaxColorAttachments];
|
||||
public ITexture PreMaskDepthStencil = default;
|
||||
public ITexture[] PreMaskRenderTargets;
|
||||
public bool FramebufferUsingColorWriteMask;
|
||||
|
||||
public Array8<ColorBlendStateUid> StoredBlend;
|
||||
public ColorF BlendColor = new();
|
||||
|
||||
public readonly VertexBufferState[] VertexBuffers = new VertexBufferState[Constants.MaxVertexBuffers];
|
||||
public readonly VertexAttribDescriptor[] VertexAttribs = new VertexAttribDescriptor[Constants.MaxVertexAttributes];
|
||||
// Dirty flags
|
||||
public DirtyFlags Dirty = DirtyFlags.None;
|
||||
|
||||
// Only to be used for present
|
||||
public bool ClearLoadAction = false;
|
||||
|
||||
public RenderEncoderBindings RenderEncoderBindings = new();
|
||||
public ComputeEncoderBindings ComputeEncoderBindings = new();
|
||||
|
||||
public EncoderState()
|
||||
{
|
||||
Pipeline.Initialize();
|
||||
DepthStencilUid.DepthCompareFunction = MTLCompareFunction.Always;
|
||||
}
|
||||
|
||||
public RenderTargetCopy InheritForClear(EncoderState other, bool depth, int singleIndex = -1)
|
||||
{
|
||||
// Inherit render target related information without causing a render encoder split.
|
||||
|
||||
var oldState = new RenderTargetCopy
|
||||
{
|
||||
Scissors = other.Scissors,
|
||||
RenderTargets = other.RenderTargets,
|
||||
DepthStencil = other.DepthStencil
|
||||
};
|
||||
|
||||
Scissors = other.Scissors;
|
||||
RenderTargets = other.RenderTargets;
|
||||
DepthStencil = other.DepthStencil;
|
||||
|
||||
Pipeline.ColorBlendAttachmentStateCount = other.Pipeline.ColorBlendAttachmentStateCount;
|
||||
Pipeline.Internal.ColorBlendState = other.Pipeline.Internal.ColorBlendState;
|
||||
Pipeline.DepthStencilFormat = other.Pipeline.DepthStencilFormat;
|
||||
|
||||
ref var blendStates = ref Pipeline.Internal.ColorBlendState;
|
||||
|
||||
// Mask out irrelevant attachments.
|
||||
for (int i = 0; i < blendStates.Length; i++)
|
||||
{
|
||||
if (depth || (singleIndex != -1 && singleIndex != i))
|
||||
{
|
||||
blendStates[i].WriteMask = MTLColorWriteMask.None;
|
||||
}
|
||||
}
|
||||
|
||||
return oldState;
|
||||
}
|
||||
|
||||
public void Restore(RenderTargetCopy copy)
|
||||
{
|
||||
Scissors = copy.Scissors;
|
||||
RenderTargets = copy.RenderTargets;
|
||||
DepthStencil = copy.DepthStencil;
|
||||
|
||||
Pipeline.Internal.ResetColorState();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue