diff --git a/src/Ryujinx.Graphics.Metal/Constants.cs b/src/Ryujinx.Graphics.Metal/Constants.cs index 1ee24e308..76f4e0f87 100644 --- a/src/Ryujinx.Graphics.Metal/Constants.cs +++ b/src/Ryujinx.Graphics.Metal/Constants.cs @@ -12,6 +12,7 @@ namespace Ryujinx.Graphics.Metal public const int MaxStorageBufferBindings = MaxStorageBuffersPerStage * MaxShaderStages; public const int MaxTextureBindings = MaxTexturesPerStage * MaxShaderStages; public const int MaxColorAttachments = 8; + public const int MaxViewports = 16; // TODO: Check this value public const int MaxVertexAttributes = 31; // TODO: Check this value diff --git a/src/Ryujinx.Graphics.Metal/EncoderState.cs b/src/Ryujinx.Graphics.Metal/EncoderState.cs index 6e7e6c66b..375d9d17a 100644 --- a/src/Ryujinx.Graphics.Metal/EncoderState.cs +++ b/src/Ryujinx.Graphics.Metal/EncoderState.cs @@ -109,8 +109,8 @@ namespace Ryujinx.Graphics.Metal public MTLWinding Winding = MTLWinding.CounterClockwise; public bool CullBoth = false; - public MTLViewport[] Viewports = []; - public MTLScissorRect[] Scissors = []; + public MTLViewport[] Viewports = new MTLViewport[Constants.MaxViewports]; + public MTLScissorRect[] Scissors = new MTLScissorRect[Constants.MaxViewports]; // Changes to attachments take recreation! public Texture DepthStencil = default; @@ -122,9 +122,8 @@ namespace Ryujinx.Graphics.Metal public Array8 StoredBlend; public ColorF BlendColor = new(); - public VertexBufferDescriptor[] VertexBuffers = []; - public VertexAttribDescriptor[] VertexAttribs = []; - + public readonly VertexBufferDescriptor[] VertexBuffers = new VertexBufferDescriptor[Constants.MaxVertexBuffers]; + public readonly VertexAttribDescriptor[] VertexAttribs = new VertexAttribDescriptor[Constants.MaxVertexAttributes]; // Dirty flags public DirtyFlags Dirty = DirtyFlags.None; diff --git a/src/Ryujinx.Graphics.Metal/EncoderStateManager.cs b/src/Ryujinx.Graphics.Metal/EncoderStateManager.cs index 16d1b7c0b..e24b091e7 100644 --- a/src/Ryujinx.Graphics.Metal/EncoderStateManager.cs +++ b/src/Ryujinx.Graphics.Metal/EncoderStateManager.cs @@ -510,7 +510,7 @@ namespace Ryujinx.Graphics.Metal public void UpdateVertexAttribs(ReadOnlySpan vertexAttribs) { - _currentState.VertexAttribs = vertexAttribs.ToArray(); + vertexAttribs.CopyTo(_currentState.VertexAttribs); // Update the buffers on the pipeline UpdatePipelineVertexState(_currentState.VertexBuffers, _currentState.VertexAttribs); @@ -625,11 +625,7 @@ namespace Ryujinx.Graphics.Metal // Inlineable public void UpdateScissors(ReadOnlySpan> regions) { - int maxScissors = Math.Min(regions.Length, _currentState.Viewports.Length); - - _currentState.Scissors = new MTLScissorRect[maxScissors]; - - for (int i = 0; i < maxScissors; i++) + for (int i = 0; i < regions.Length; i++) { var region = regions[i]; @@ -661,8 +657,6 @@ namespace Ryujinx.Graphics.Metal return Math.Clamp(value, 0f, 1f); } - _currentState.Viewports = new MTLViewport[viewports.Length]; - for (int i = 0; i < viewports.Length; i++) { var viewport = viewports[i]; @@ -691,7 +685,7 @@ namespace Ryujinx.Graphics.Metal public void UpdateVertexBuffers(ReadOnlySpan vertexBuffers) { - _currentState.VertexBuffers = vertexBuffers.ToArray(); + vertexBuffers.CopyTo(_currentState.VertexBuffers); // Update the buffers on the pipeline UpdatePipelineVertexState(_currentState.VertexBuffers, _currentState.VertexAttribs); @@ -1122,7 +1116,7 @@ namespace Ryujinx.Graphics.Metal MTLRenderStages renderStages = 0; - if (segment.Stages.HasFlag(ResourceStages.Vertex)) + if ((segment.Stages & ResourceStages.Vertex) != 0) { vertResourceIds[vertResourceIdIndex] = mtlTexture.GpuResourceID._impl; vertResourceIdIndex++; @@ -1136,7 +1130,7 @@ namespace Ryujinx.Graphics.Metal renderStages |= MTLRenderStages.RenderStageVertex; } - if (segment.Stages.HasFlag(ResourceStages.Fragment)) + if ((segment.Stages & ResourceStages.Fragment) != 0) { fragResourceIds[fragResourceIdIndex] = mtlTexture.GpuResourceID._impl; fragResourceIdIndex++; diff --git a/src/Ryujinx.Graphics.Metal/HelperShader.cs b/src/Ryujinx.Graphics.Metal/HelperShader.cs index d65aafc3e..f2d1aabad 100644 --- a/src/Ryujinx.Graphics.Metal/HelperShader.cs +++ b/src/Ryujinx.Graphics.Metal/HelperShader.cs @@ -129,7 +129,7 @@ namespace Ryujinx.Graphics.Metal MathF.Abs(dstRegion.X2 - dstRegion.X1), MathF.Abs(dstRegion.Y2 - dstRegion.Y1)); - Span viewports = stackalloc Viewport[1]; + Span viewports = stackalloc Viewport[16]; viewports[0] = new Viewport( rect, @@ -145,8 +145,12 @@ namespace Ryujinx.Graphics.Metal int dstWidth = dst.Width; int dstHeight = dst.Height; + Span> scissors = stackalloc Rectangle[16]; + + scissors[0] = new Rectangle(0, 0, dstWidth, dstHeight); + _pipeline.SetRenderTargets([dst], null); - _pipeline.SetScissors(stackalloc Rectangle[] { new Rectangle(0, 0, dstWidth, dstHeight) }); + _pipeline.SetScissors(scissors); _pipeline.SetClearLoadAction(clear); @@ -202,7 +206,7 @@ namespace Ryujinx.Graphics.Metal _renderer.BufferManager.SetData(bufferHandle, 0, region); _pipeline.SetUniformBuffers([new BufferAssignment(0, new BufferRange(bufferHandle, 0, RegionBufferSize))]); - Span viewports = stackalloc Viewport[1]; + Span viewports = stackalloc Viewport[16]; var rect = new Rectangle( MathF.Min(dstRegion.X1, dstRegion.X2), @@ -302,7 +306,7 @@ namespace Ryujinx.Graphics.Metal buffer.Holder.SetDataUnchecked(buffer.Offset, clearColor); _pipeline.SetUniformBuffers([new BufferAssignment(0, buffer.Range)]); - Span viewports = stackalloc Viewport[1]; + Span viewports = stackalloc Viewport[16]; // TODO: Set exact viewport! viewports[0] = new Viewport(