diff --git a/src/Ryujinx.Graphics.GAL/IPipeline.cs b/src/Ryujinx.Graphics.GAL/IPipeline.cs index 1ecbb402c..f10db1c2d 100644 --- a/src/Ryujinx.Graphics.GAL/IPipeline.cs +++ b/src/Ryujinx.Graphics.GAL/IPipeline.cs @@ -50,7 +50,7 @@ namespace Ryujinx.Graphics.GAL void SetDepthBias(PolygonModeMask enables, float factor, float units, float clamp); void SetDepthClamp(bool clamp); void SetDepthMode(DepthMode mode); - void SetDepthTest(DepthTestDescriptor depthTest); + void SetDepthTest(DepthTestDescriptor depthTest, bool signalChange = true); void SetFaceCulling(Face face); @@ -75,16 +75,16 @@ namespace Ryujinx.Graphics.GAL void SetPrimitiveRestart(bool enable, int index); - void SetPrimitiveTopology(PrimitiveTopology topology); + void SetPrimitiveTopology(PrimitiveTopology topology, bool signalChange = true); - void SetProgram(IProgram program); + void SetProgram(IProgram program, bool signalChange = true); void SetRasterizerDiscard(bool discard); - void SetRenderTargetColorMasks(ReadOnlySpan componentMask); + void SetRenderTargetColorMasks(ReadOnlySpan componentMask, bool signalChange = true); void SetRenderTargets(ITexture[] colors, ITexture depthStencil); - void SetScissors(ReadOnlySpan> regions); + void SetScissors(ReadOnlySpan> regions, bool signalChange = true); void SetStencilTest(StencilTestDescriptor stencilTest); @@ -102,7 +102,7 @@ namespace Ryujinx.Graphics.GAL void SetVertexAttribs(ReadOnlySpan vertexAttribs); void SetVertexBuffers(ReadOnlySpan vertexBuffers); - void SetViewports(ReadOnlySpan viewports); + void SetViewports(ReadOnlySpan viewports, bool signalChange = true); void TextureBarrier(); void TextureBarrierTiled(); diff --git a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs index cee3480fe..7d4bda1c4 100644 --- a/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs +++ b/src/Ryujinx.Graphics.GAL/Multithreading/ThreadedPipeline.cs @@ -159,7 +159,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading _renderer.QueueCommand(); } - public void SetDepthTest(DepthTestDescriptor depthTest) + public void SetDepthTest(DepthTestDescriptor depthTest, bool signalChange = true) { _renderer.New().Set(depthTest); _renderer.QueueCommand(); @@ -243,13 +243,13 @@ namespace Ryujinx.Graphics.GAL.Multithreading _renderer.QueueCommand(); } - public void SetPrimitiveTopology(PrimitiveTopology topology) + public void SetPrimitiveTopology(PrimitiveTopology topology, bool signalChange = true) { _renderer.New().Set(topology); _renderer.QueueCommand(); } - public void SetProgram(IProgram program) + public void SetProgram(IProgram program, bool signalChange = true) { _renderer.New().Set(Ref(program)); _renderer.QueueCommand(); @@ -261,7 +261,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading _renderer.QueueCommand(); } - public void SetRenderTargetColorMasks(ReadOnlySpan componentMask) + public void SetRenderTargetColorMasks(ReadOnlySpan componentMask, bool signalChange = true) { _renderer.New().Set(_renderer.CopySpan(componentMask)); _renderer.QueueCommand(); @@ -273,7 +273,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading _renderer.QueueCommand(); } - public void SetScissors(ReadOnlySpan> scissors) + public void SetScissors(ReadOnlySpan> scissors, bool signalChange = true) { _renderer.New().Set(_renderer.CopySpan(scissors)); _renderer.QueueCommand(); @@ -339,7 +339,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading _renderer.QueueCommand(); } - public void SetViewports(ReadOnlySpan viewports) + public void SetViewports(ReadOnlySpan viewports, bool signalChange = true) { _renderer.New().Set(_renderer.CopySpan(viewports)); _renderer.QueueCommand(); diff --git a/src/Ryujinx.Graphics.OpenGL/Pipeline.cs b/src/Ryujinx.Graphics.OpenGL/Pipeline.cs index ac6bc3f17..b75d4930e 100644 --- a/src/Ryujinx.Graphics.OpenGL/Pipeline.cs +++ b/src/Ryujinx.Graphics.OpenGL/Pipeline.cs @@ -898,7 +898,7 @@ namespace Ryujinx.Graphics.OpenGL } } - public void SetDepthTest(DepthTestDescriptor depthTest) + public void SetDepthTest(DepthTestDescriptor depthTest, bool signalChange = true) { if (depthTest.TestEnable) { @@ -1107,12 +1107,12 @@ namespace Ryujinx.Graphics.OpenGL GL.Enable(EnableCap.PrimitiveRestart); } - public void SetPrimitiveTopology(PrimitiveTopology topology) + public void SetPrimitiveTopology(PrimitiveTopology topology, bool signalChange = true) { _primitiveType = topology.Convert(); } - public void SetProgram(IProgram program) + public void SetProgram(IProgram program, bool signalChange = true) { Program prg = (Program)program; @@ -1154,7 +1154,7 @@ namespace Ryujinx.Graphics.OpenGL _rasterizerDiscard = discard; } - public void SetRenderTargetColorMasks(ReadOnlySpan componentMasks) + public void SetRenderTargetColorMasks(ReadOnlySpan componentMasks, bool signalChange = true) { _componentMasks = 0; @@ -1195,7 +1195,7 @@ namespace Ryujinx.Graphics.OpenGL _framebuffer.SetDrawBuffers(colors.Length); } - public void SetScissors(ReadOnlySpan> regions) + public void SetScissors(ReadOnlySpan> regions, bool signalChange = true) { int count = Math.Min(regions.Length, Constants.MaxViewports); @@ -1388,7 +1388,7 @@ namespace Ryujinx.Graphics.OpenGL _vertexArray.SetVertexBuffers(vertexBuffers); } - public void SetViewports(ReadOnlySpan viewports) + public void SetViewports(ReadOnlySpan viewports, bool signalChange = true) { Array.Resize(ref _viewportArray, viewports.Length * 4); Array.Resize(ref _depthRangeArray, viewports.Length * 2); diff --git a/src/Ryujinx.Graphics.Vulkan/Effects/SmaaPostProcessingEffect.cs b/src/Ryujinx.Graphics.Vulkan/Effects/SmaaPostProcessingEffect.cs index a8e68f429..555151992 100644 --- a/src/Ryujinx.Graphics.Vulkan/Effects/SmaaPostProcessingEffect.cs +++ b/src/Ryujinx.Graphics.Vulkan/Effects/SmaaPostProcessingEffect.cs @@ -257,8 +257,8 @@ namespace Ryujinx.Graphics.Vulkan.Effects scissors[0] = new Rectangle(0, 0, texture.Width, texture.Height); - _pipeline.SetRenderTarget(texture, (uint)texture.Width, (uint)texture.Height); - _pipeline.SetRenderTargetColorMasks(colorMasks); + _pipeline.SetRenderTarget(texture, (uint)texture.Width, (uint)texture.Height, false); + _pipeline.SetRenderTargetColorMasks(colorMasks, false); _pipeline.SetScissors(scissors); _pipeline.ClearRenderTargetColor(0, 0, 1, new ColorF(0f, 0f, 0f, 1f)); } diff --git a/src/Ryujinx.Graphics.Vulkan/HelperShader.cs b/src/Ryujinx.Graphics.Vulkan/HelperShader.cs index b7c42aff0..ce4f58057 100644 --- a/src/Ryujinx.Graphics.Vulkan/HelperShader.cs +++ b/src/Ryujinx.Graphics.Vulkan/HelperShader.cs @@ -429,35 +429,35 @@ namespace Ryujinx.Graphics.Vulkan if (dstIsDepthOrStencil) { - _pipeline.SetProgram(src.Info.Target.IsMultisample() ? _programDepthBlitMs : _programDepthBlit); - _pipeline.SetDepthTest(new DepthTestDescriptor(true, true, CompareOp.Always)); + _pipeline.SetProgram(src.Info.Target.IsMultisample() ? _programDepthBlitMs : _programDepthBlit, false); + _pipeline.SetDepthTest(new DepthTestDescriptor(true, true, CompareOp.Always), false); } else if (src.Info.Target.IsMultisample()) { - _pipeline.SetProgram(_programColorBlitMs); + _pipeline.SetProgram(_programColorBlitMs, false); } else if (clearAlpha) { - _pipeline.SetProgram(_programColorBlitClearAlpha); + _pipeline.SetProgram(_programColorBlitClearAlpha, false); } else { - _pipeline.SetProgram(_programColorBlit); + _pipeline.SetProgram(_programColorBlit, false); } int dstWidth = dst.Width; int dstHeight = dst.Height; - _pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight); - _pipeline.SetRenderTargetColorMasks(new uint[] { 0xf }); - _pipeline.SetScissors(stackalloc Rectangle[] { new Rectangle(0, 0, dstWidth, dstHeight) }); + _pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, false); + _pipeline.SetRenderTargetColorMasks(new uint[] { 0xf }, false); + _pipeline.SetScissors(stackalloc Rectangle[] { new Rectangle(0, 0, dstWidth, dstHeight) }, false); if (clearAlpha) { _pipeline.ClearRenderTargetColor(0, 0, 1, new ColorF(0f, 0f, 0f, 1f)); } - _pipeline.SetViewports(viewports); + _pipeline.SetViewports(viewports, false); _pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip); _pipeline.Draw(4, 1, 0, 0); @@ -524,10 +524,10 @@ namespace Ryujinx.Graphics.Vulkan int dstWidth = dst.Width; int dstHeight = dst.Height; - _pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight); - _pipeline.SetScissors(stackalloc Rectangle[] { new Rectangle(0, 0, dstWidth, dstHeight) }); - _pipeline.SetViewports(viewports); - _pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip); + _pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, false); + _pipeline.SetScissors(stackalloc Rectangle[] { new Rectangle(0, 0, dstWidth, dstHeight) }, false); + _pipeline.SetViewports(viewports, false); + _pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip, false); var aspectFlags = src.Info.Format.ConvertAspectFlags(); @@ -589,12 +589,12 @@ namespace Ryujinx.Graphics.Vulkan if (isDepth) { - _pipeline.SetProgram(src.Info.Target.IsMultisample() ? _programDepthBlitMs : _programDepthBlit); + _pipeline.SetProgram(src.Info.Target.IsMultisample() ? _programDepthBlitMs : _programDepthBlit, false); _pipeline.SetDepthTest(new DepthTestDescriptor(true, true, CompareOp.Always)); } else { - _pipeline.SetProgram(src.Info.Target.IsMultisample() ? _programStencilBlitMs : _programStencilBlit); + _pipeline.SetProgram(src.Info.Target.IsMultisample() ? _programStencilBlitMs : _programStencilBlit, false); _pipeline.SetStencilTest(CreateStencilTestDescriptor(true)); } @@ -684,11 +684,11 @@ namespace Ryujinx.Graphics.Vulkan program = _programColorClearF; } - _pipeline.SetProgram(program); - _pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight); - _pipeline.SetRenderTargetColorMasks(new[] { componentMask }); - _pipeline.SetViewports(viewports); - _pipeline.SetScissors(stackalloc Rectangle[] { scissor }); + _pipeline.SetProgram(program, false); + _pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, false); + _pipeline.SetRenderTargetColorMasks(new[] { componentMask }, false); + _pipeline.SetViewports(viewports, false); + _pipeline.SetScissors(stackalloc Rectangle[] { scissor }, false); _pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip); _pipeline.Draw(4, 1, 0, 0); _pipeline.Finish(); @@ -731,12 +731,12 @@ namespace Ryujinx.Graphics.Vulkan 0f, 1f); - _pipeline.SetProgram(_programDepthStencilClear); - _pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight); - _pipeline.SetViewports(viewports); - _pipeline.SetScissors(stackalloc Rectangle[] { scissor }); - _pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip); - _pipeline.SetDepthTest(new DepthTestDescriptor(true, depthMask, CompareOp.Always)); + _pipeline.SetProgram(_programDepthStencilClear, false); + _pipeline.SetRenderTarget(dst, (uint)dstWidth, (uint)dstHeight, false); + _pipeline.SetViewports(viewports, false); + _pipeline.SetScissors(stackalloc Rectangle[] { scissor }, false); + _pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip, false); + _pipeline.SetDepthTest(new DepthTestDescriptor(true, depthMask, CompareOp.Always), false); _pipeline.SetStencilTest(CreateStencilTestDescriptor(stencilMask != 0, stencilValue, 0xff, stencilMask)); _pipeline.Draw(4, 1, 0, 0); _pipeline.Finish(); @@ -794,8 +794,8 @@ namespace Ryujinx.Graphics.Vulkan 0f, 1f); - pipeline.SetProgram(_programColorBlit); - pipeline.SetViewports(viewports); + pipeline.SetProgram(_programColorBlit, false); + pipeline.SetViewports(viewports, false); pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip); pipeline.Draw(4, 1, 0, 0); @@ -1129,16 +1129,16 @@ namespace Ryujinx.Graphics.Vulkan 0f, 1f); - _pipeline.SetScissors(stackalloc Rectangle[] { new Rectangle(0, 0, dst.Width, dst.Height) }); - _pipeline.SetViewports(viewports); - _pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip); + _pipeline.SetScissors(stackalloc Rectangle[] { new Rectangle(0, 0, dst.Width, dst.Height) }, false); + _pipeline.SetViewports(viewports, false); + _pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip, false); for (int z = 0; z < depth; z++) { var srcView = Create2DLayerView(src, srcLayer + z, 0); var dstView = Create2DLayerView(dst, dstLayer + z, 0); - _pipeline.SetRenderTarget(dstView, (uint)dst.Width, (uint)dst.Height); + _pipeline.SetRenderTarget(dstView, (uint)dst.Width, (uint)dst.Height, false); CopyMSDraw(srcView, aspectFlags, fromMS: true); @@ -1251,9 +1251,9 @@ namespace Ryujinx.Graphics.Vulkan 1f); _pipeline.SetRenderTargetColorMasks(new uint[] { 0xf }); - _pipeline.SetScissors(stackalloc Rectangle[] { new Rectangle(0, 0, dst.Width, dst.Height) }); - _pipeline.SetViewports(viewports); - _pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip); + _pipeline.SetScissors(stackalloc Rectangle[] { new Rectangle(0, 0, dst.Width, dst.Height) }, false); + _pipeline.SetViewports(viewports, false); + _pipeline.SetPrimitiveTopology(PrimitiveTopology.TriangleStrip, false); _pipeline.SetUniformBuffers(stackalloc[] { new BufferAssignment(0, buffer.Range) }); @@ -1264,7 +1264,7 @@ namespace Ryujinx.Graphics.Vulkan var srcView = Create2DLayerView(src, srcLayer + z, 0); var dstView = Create2DLayerView(dst, dstLayer + z, 0); - _pipeline.SetRenderTarget(dstView, (uint)dst.Width, (uint)dst.Height); + _pipeline.SetRenderTarget(dstView, (uint)dst.Width, (uint)dst.Height, false); CopyMSDraw(srcView, aspectFlags, fromMS: false); @@ -1281,7 +1281,7 @@ namespace Ryujinx.Graphics.Vulkan } else { - _pipeline.SetProgram(_programColorDrawToMs); + _pipeline.SetProgram(_programColorDrawToMs, false); var format = GetFormat(src.Info.BytesPerPixel); var vkFormat = FormatTable.GetFormat(format); @@ -1358,12 +1358,12 @@ namespace Ryujinx.Graphics.Vulkan if (isDepth) { - _pipeline.SetProgram(fromMS ? _programDepthDrawToNonMs : _programDepthDrawToMs); + _pipeline.SetProgram(fromMS ? _programDepthDrawToNonMs : _programDepthDrawToMs, false); _pipeline.SetDepthTest(new DepthTestDescriptor(true, true, CompareOp.Always)); } else { - _pipeline.SetProgram(fromMS ? _programStencilDrawToNonMs : _programStencilDrawToMs); + _pipeline.SetProgram(fromMS ? _programStencilDrawToNonMs : _programStencilDrawToMs, false); _pipeline.SetStencilTest(CreateStencilTestDescriptor(true)); } diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs index 28c37af40..96d22e878 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineBase.cs @@ -693,8 +693,6 @@ namespace Ryujinx.Graphics.Vulkan _newState.StencilTestEnable = false; _newState.DepthTestEnable = false; _newState.DepthWriteEnable = false; - - SignalStateChange(); } Gd.HelperShader.DrawTexture( @@ -896,7 +894,7 @@ namespace Ryujinx.Graphics.Vulkan SignalStateChange(); } - public void SetDepthTest(DepthTestDescriptor depthTest) + public void SetDepthTest(DepthTestDescriptor depthTest, bool signalChange = true) { if (_supportExtDynamic) { @@ -912,7 +910,10 @@ namespace Ryujinx.Graphics.Vulkan _newState.DepthWriteEnable = depthTest.WriteEnable; _newState.DepthCompareOp = depthTest.Func.Convert(); - SignalStateChange(); + if (signalChange) + { + SignalStateChange(); + } } UpdatePassDepthStencil(); @@ -1062,7 +1063,7 @@ namespace Ryujinx.Graphics.Vulkan // TODO: What to do about the index? } - public void SetPrimitiveTopology(PrimitiveTopology topology) + public void SetPrimitiveTopology(PrimitiveTopology topology, bool signalChange = true) { _topology = topology; @@ -1075,10 +1076,13 @@ namespace Ryujinx.Graphics.Vulkan DynamicState.SetPrimitiveTopology(vkTopology); } - SignalStateChange(); + if (signalChange) + { + SignalStateChange(); + } } - public void SetProgram(IProgram program) + public void SetProgram(IProgram program, bool signalChange = true) { var internalProgram = (ShaderCollection)program; var stages = internalProgram.GetInfos(); @@ -1094,7 +1098,10 @@ namespace Ryujinx.Graphics.Vulkan stages.CopyTo(_newState.Stages.AsSpan()[..stages.Length]); - SignalStateChange(); + if (signalChange) + { + SignalStateChange(); + } if (internalProgram.IsCompute) { @@ -1139,7 +1146,7 @@ namespace Ryujinx.Graphics.Vulkan } } - public void SetRenderTargetColorMasks(ReadOnlySpan componentMask) + public void SetRenderTargetColorMasks(ReadOnlySpan componentMask, bool signalChange = true) { int count = Math.Min(Constants.MaxRenderTargets, componentMask.Length); int writtenAttachments = 0; @@ -1179,7 +1186,10 @@ namespace Ryujinx.Graphics.Vulkan } else { - SignalStateChange(); + if (signalChange) + { + SignalStateChange(); + } if (writtenAttachments != _writtenAttachmentCount) { @@ -1203,7 +1213,7 @@ namespace Ryujinx.Graphics.Vulkan SetRenderTargetsInternal(colors, depthStencil, Gd.IsTBDR); } - public void SetScissors(ReadOnlySpan> regions) + public void SetScissors(ReadOnlySpan> regions, bool signalChange = true) { int maxScissors = Gd.Capabilities.SupportsMultiView ? Constants.MaxViewports : 1; int count = Math.Min(maxScissors, regions.Length); @@ -1227,7 +1237,10 @@ namespace Ryujinx.Graphics.Vulkan { _newState.ScissorsCount = (uint)count; - SignalStateChange(); + if (signalChange) + { + SignalStateChange(); + } } } @@ -1514,7 +1527,7 @@ namespace Ryujinx.Graphics.Vulkan } } - public void SetViewports(ReadOnlySpan viewports) + public void SetViewports(ReadOnlySpan viewports, bool signalChange = true) { int maxViewports = Gd.Capabilities.SupportsMultiView ? Constants.MaxViewports : 1; int count = Math.Min(maxViewports, viewports.Length); @@ -1543,7 +1556,10 @@ namespace Ryujinx.Graphics.Vulkan { _newState.ViewportsCount = (uint)count; - SignalStateChange(); + if (signalChange) + { + SignalStateChange(); + } } } diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineHelperShader.cs b/src/Ryujinx.Graphics.Vulkan/PipelineHelperShader.cs index dfbf19013..9a29d3fc9 100644 --- a/src/Ryujinx.Graphics.Vulkan/PipelineHelperShader.cs +++ b/src/Ryujinx.Graphics.Vulkan/PipelineHelperShader.cs @@ -9,11 +9,15 @@ namespace Ryujinx.Graphics.Vulkan { } - public void SetRenderTarget(TextureView view, uint width, uint height) + public void SetRenderTarget(TextureView view, uint width, uint height, bool signalChange = true) { CreateFramebuffer(view, width, height); CreateRenderPass(); - SignalStateChange(); + + if (signalChange) + { + SignalStateChange(); + } } private void CreateFramebuffer(TextureView view, uint width, uint height)