diff --git a/src/Ryujinx.Graphics.Metal/EncoderState.cs b/src/Ryujinx.Graphics.Metal/EncoderState.cs index 35b726e25..248acd364 100644 --- a/src/Ryujinx.Graphics.Metal/EncoderState.cs +++ b/src/Ryujinx.Graphics.Metal/EncoderState.cs @@ -47,6 +47,8 @@ namespace Ryujinx.Graphics.Metal public MTLTexture DepthStencil = default; public MTLTexture[] RenderTargets = new MTLTexture[MaxColorAttachments]; public MTLVertexDescriptor VertexDescriptor = new(); + public Dictionary BlendDescriptors = new(); + public ColorF BlendColor = new(); public EncoderState() { } } diff --git a/src/Ryujinx.Graphics.Metal/EncoderStateManager.cs b/src/Ryujinx.Graphics.Metal/EncoderStateManager.cs index e2ad3bb13..88e6330ed 100644 --- a/src/Ryujinx.Graphics.Metal/EncoderStateManager.cs +++ b/src/Ryujinx.Graphics.Metal/EncoderStateManager.cs @@ -56,12 +56,22 @@ namespace Ryujinx.Graphics.Metal passAttachment.LoadAction = MTLLoadAction.Load; var pipelineAttachment = renderPipelineDescriptor.ColorAttachments.Object((ulong)i); - pipelineAttachment.SetBlendingEnabled(true); pipelineAttachment.PixelFormat = _currentState.RenderTargets[i].PixelFormat; pipelineAttachment.SourceAlphaBlendFactor = MTLBlendFactor.SourceAlpha; pipelineAttachment.DestinationAlphaBlendFactor = MTLBlendFactor.OneMinusSourceAlpha; pipelineAttachment.SourceRGBBlendFactor = MTLBlendFactor.SourceAlpha; pipelineAttachment.DestinationRGBBlendFactor = MTLBlendFactor.OneMinusSourceAlpha; + + if (_currentState.BlendDescriptors.TryGetValue(i, out BlendDescriptor blendDescriptor)) + { + pipelineAttachment.SetBlendingEnabled(blendDescriptor.Enable); + pipelineAttachment.AlphaBlendOperation = blendDescriptor.AlphaOp.Convert(); + pipelineAttachment.RgbBlendOperation = blendDescriptor.ColorOp.Convert(); + pipelineAttachment.SourceAlphaBlendFactor = blendDescriptor.AlphaSrcFactor.Convert(); + pipelineAttachment.DestinationAlphaBlendFactor = blendDescriptor.AlphaDstFactor.Convert(); + pipelineAttachment.SourceRGBBlendFactor = blendDescriptor.ColorSrcFactor.Convert(); + pipelineAttachment.DestinationRGBBlendFactor = blendDescriptor.ColorDstFactor.Convert(); + } } } @@ -136,6 +146,12 @@ namespace Ryujinx.Graphics.Metal renderCommandEncoder.SetRenderPipelineState(pipelineState); + renderCommandEncoder.SetBlendColor( + _currentState.BlendColor.Red, + _currentState.BlendColor.Green, + _currentState.BlendColor.Blue, + _currentState.BlendColor.Alpha); + SetDepthStencilState(renderCommandEncoder, _currentState.DepthStencilState); SetScissors(renderCommandEncoder, _currentState.Scissors); SetViewports(renderCommandEncoder, _currentState.Viewports); @@ -236,6 +252,18 @@ namespace Ryujinx.Graphics.Metal } } + public void UpdateBlendDescriptors(int index, BlendDescriptor blend) + { + _currentState.BlendDescriptors.Add(index, blend); + _currentState.BlendColor = blend.BlendConstant; + + // Requires recreating pipeline + if (_pipeline.CurrentEncoderType == EncoderType.Render) + { + _pipeline.EndCurrentPass(); + } + } + // Inlineable public void UpdateStencilState(StencilTestDescriptor stencilTest) { diff --git a/src/Ryujinx.Graphics.Metal/Pipeline.cs b/src/Ryujinx.Graphics.Metal/Pipeline.cs index 5819e941a..c7b926611 100644 --- a/src/Ryujinx.Graphics.Metal/Pipeline.cs +++ b/src/Ryujinx.Graphics.Metal/Pipeline.cs @@ -311,7 +311,7 @@ namespace Ryujinx.Graphics.Metal public void SetBlendState(int index, BlendDescriptor blend) { - Logger.Warning?.Print(LogClass.Gpu, "Not Implemented!"); + _encoderStateManager.UpdateBlendDescriptors(index, blend); } public void SetDepthBias(PolygonModeMask enables, float factor, float units, float clamp)