diff --git a/src/Ryujinx.Graphics.Metal/EncoderState.cs b/src/Ryujinx.Graphics.Metal/EncoderState.cs index 81cc7d3bf..043fb1660 100644 --- a/src/Ryujinx.Graphics.Metal/EncoderState.cs +++ b/src/Ryujinx.Graphics.Metal/EncoderState.cs @@ -1,6 +1,7 @@ using Ryujinx.Graphics.GAL; using SharpMetal.Metal; using System.Collections.Generic; +using System.Linq; using System.Runtime.Versioning; namespace Ryujinx.Graphics.Metal @@ -64,6 +65,8 @@ namespace Ryujinx.Graphics.Metal // Changes to attachments take recreation! public Texture DepthStencil = default; public Texture[] RenderTargets = new Texture[Constants.MaxColorAttachments]; + + public MTLColorWriteMask[] RenderTargetMasks = Enumerable.Repeat(MTLColorWriteMask.All, Constants.MaxColorAttachments).ToArray(); public BlendDescriptor?[] BlendDescriptors = new BlendDescriptor?[Constants.MaxColorAttachments]; public ColorF BlendColor = new(); diff --git a/src/Ryujinx.Graphics.Metal/EncoderStateManager.cs b/src/Ryujinx.Graphics.Metal/EncoderStateManager.cs index 84afb6eb9..c737c25ba 100644 --- a/src/Ryujinx.Graphics.Metal/EncoderStateManager.cs +++ b/src/Ryujinx.Graphics.Metal/EncoderStateManager.cs @@ -207,6 +207,7 @@ namespace Ryujinx.Graphics.Metal pipelineAttachment.DestinationAlphaBlendFactor = MTLBlendFactor.OneMinusSourceAlpha; pipelineAttachment.SourceRGBBlendFactor = MTLBlendFactor.SourceAlpha; pipelineAttachment.DestinationRGBBlendFactor = MTLBlendFactor.OneMinusSourceAlpha; + pipelineAttachment.WriteMask = _currentState.RenderTargetMasks[i]; if (_currentState.BlendDescriptors[i] != null) { @@ -349,6 +350,34 @@ namespace Ryujinx.Graphics.Metal } } + public void UpdateRenderTargetColorMasks(ReadOnlySpan componentMask) + { + _currentState.RenderTargetMasks = new MTLColorWriteMask[Constants.MaxColorAttachments]; + + for (int i = 0; i < componentMask.Length; i++) + { + bool red = (componentMask[i] & (0x1 << 0)) != 0; + bool green = (componentMask[i] & (0x1 << 1)) != 0; + bool blue = (componentMask[i] & (0x1 << 2)) != 0; + bool alpha = (componentMask[i] & (0x1 << 3)) != 0; + + var mask = MTLColorWriteMask.None; + + mask |= red ? MTLColorWriteMask.Red : 0; + mask |= green ? MTLColorWriteMask.Green : 0; + mask |= blue ? MTLColorWriteMask.Blue : 0; + mask |= alpha ? MTLColorWriteMask.Alpha : 0; + + _currentState.RenderTargetMasks[i] = mask; + } + + // Requires recreating pipeline + if (_pipeline.CurrentEncoderType == EncoderType.Render) + { + _pipeline.EndCurrentPass(); + } + } + public void UpdateVertexAttribs(ReadOnlySpan vertexAttribs) { _currentState.VertexAttribs = vertexAttribs.ToArray(); diff --git a/src/Ryujinx.Graphics.Metal/Pipeline.cs b/src/Ryujinx.Graphics.Metal/Pipeline.cs index 504a2d5cf..4ff307dce 100644 --- a/src/Ryujinx.Graphics.Metal/Pipeline.cs +++ b/src/Ryujinx.Graphics.Metal/Pipeline.cs @@ -461,7 +461,7 @@ namespace Ryujinx.Graphics.Metal public void SetRenderTargetColorMasks(ReadOnlySpan componentMask) { - Logger.Warning?.Print(LogClass.Gpu, "Not Implemented!"); + _encoderStateManager.UpdateRenderTargetColorMasks(componentMask); } public void SetRenderTargets(ITexture[] colors, ITexture depthStencil)