From 43c13057da7726c324f2b5d674e5e1308eb1f6a7 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Tue, 28 Jul 2020 18:30:08 -0300 Subject: [PATCH] Implement alpha test using legacy functions (#1426) --- Ryujinx.Graphics.GAL/IPipeline.cs | 4 ++-- Ryujinx.Graphics.Gpu/Engine/Methods.cs | 25 +++++++++++++++++++--- Ryujinx.Graphics.Gpu/State/MethodOffset.cs | 3 +++ Ryujinx.Graphics.OpenGL/Pipeline.cs | 20 ++++++++++------- 4 files changed, 39 insertions(+), 13 deletions(-) diff --git a/Ryujinx.Graphics.GAL/IPipeline.cs b/Ryujinx.Graphics.GAL/IPipeline.cs index 83ccfc3de..8e8cd965c 100644 --- a/Ryujinx.Graphics.GAL/IPipeline.cs +++ b/Ryujinx.Graphics.GAL/IPipeline.cs @@ -31,6 +31,8 @@ namespace Ryujinx.Graphics.GAL void EndTransformFeedback(); + void SetAlphaTest(bool enable, float reference, CompareOp op); + void SetBlendState(int index, BlendDescriptor blend); void SetDepthBias(PolygonModeMask enables, float factor, float units, float clamp); @@ -61,9 +63,7 @@ namespace Ryujinx.Graphics.GAL void SetRasterizerDiscard(bool discard); void SetRenderTargetScale(float scale); - void SetRenderTargetColorMasks(ReadOnlySpan componentMask); - void SetRenderTargets(ITexture[] colors, ITexture depthStencil); void SetSampler(int index, ShaderStage stage, ISampler sampler); diff --git a/Ryujinx.Graphics.Gpu/Engine/Methods.cs b/Ryujinx.Graphics.Gpu/Engine/Methods.cs index fbde0f0a3..f8b6e43f0 100644 --- a/Ryujinx.Graphics.Gpu/Engine/Methods.cs +++ b/Ryujinx.Graphics.Gpu/Engine/Methods.cs @@ -164,6 +164,13 @@ namespace Ryujinx.Graphics.Gpu.Engine UpdateDepthClampState(state); } + if (state.QueryModified(MethodOffset.AlphaTestEnable, + MethodOffset.AlphaTestRef, + MethodOffset.AlphaTestFunc)) + { + UpdateAlphaTestState(state); + } + if (state.QueryModified(MethodOffset.DepthTestEnable, MethodOffset.DepthWriteEnable, MethodOffset.DepthTestFunc)) @@ -372,7 +379,7 @@ namespace Ryujinx.Graphics.Gpu.Engine if (dsEnable) { var dsState = state.Get(MethodOffset.RtDepthStencilState); - var dsSize = state.Get (MethodOffset.RtDepthStencilSize); + var dsSize = state.Get(MethodOffset.RtDepthStencilSize); depthStencil = TextureManager.FindOrCreateTexture(dsState, dsSize, samplesInX, samplesInY); } @@ -450,6 +457,18 @@ namespace Ryujinx.Graphics.Gpu.Engine _context.Renderer.Pipeline.SetDepthClamp((clip & ViewVolumeClipControl.DepthClampDisabled) == 0); } + /// + /// Updates host alpha test state based on current GPU state. + /// + /// Current GPU state + private void UpdateAlphaTestState(GpuState state) + { + _context.Renderer.Pipeline.SetAlphaTest( + state.Get(MethodOffset.AlphaTestEnable), + state.Get(MethodOffset.AlphaTestRef), + state.Get(MethodOffset.AlphaTestFunc)); + } + /// /// Updates host depth test state based on current GPU state. /// @@ -577,8 +596,8 @@ namespace Ryujinx.Graphics.Gpu.Engine /// Current GPU state private void UpdateStencilTestState(GpuState state) { - var backMasks = state.Get (MethodOffset.StencilBackMasks); - var test = state.Get (MethodOffset.StencilTestState); + var backMasks = state.Get(MethodOffset.StencilBackMasks); + var test = state.Get(MethodOffset.StencilTestState); var backTest = state.Get(MethodOffset.StencilBackTestState); CompareOp backFunc; diff --git a/Ryujinx.Graphics.Gpu/State/MethodOffset.cs b/Ryujinx.Graphics.Gpu/State/MethodOffset.cs index 505e3d89e..13b699f3b 100644 --- a/Ryujinx.Graphics.Gpu/State/MethodOffset.cs +++ b/Ryujinx.Graphics.Gpu/State/MethodOffset.cs @@ -52,8 +52,11 @@ namespace Ryujinx.Graphics.Gpu.State DepthTestEnable = 0x4b3, BlendIndependent = 0x4b9, DepthWriteEnable = 0x4ba, + AlphaTestEnable = 0x4bb, VbElementU8 = 0x4c1, DepthTestFunc = 0x4c3, + AlphaTestRef = 0x4c4, + AlphaTestFunc = 0x4c5, BlendConstant = 0x4c7, BlendStateCommon = 0x4cf, BlendEnableCommon = 0x4d7, diff --git a/Ryujinx.Graphics.OpenGL/Pipeline.cs b/Ryujinx.Graphics.OpenGL/Pipeline.cs index 4f3c2a29b..69bd78448 100644 --- a/Ryujinx.Graphics.OpenGL/Pipeline.cs +++ b/Ryujinx.Graphics.OpenGL/Pipeline.cs @@ -157,7 +157,6 @@ namespace Ryujinx.Graphics.OpenGL if (!_program.IsLinked) { Logger.PrintDebug(LogClass.Gpu, "Dispatch error, shader not linked."); - return; } @@ -171,7 +170,6 @@ namespace Ryujinx.Graphics.OpenGL if (!_program.IsLinked) { Logger.PrintDebug(LogClass.Gpu, "Draw error, shader not linked."); - return; } @@ -290,7 +288,6 @@ namespace Ryujinx.Graphics.OpenGL if (!_program.IsLinked) { Logger.PrintDebug(LogClass.Gpu, "Draw error, shader not linked."); - return; } @@ -527,12 +524,23 @@ namespace Ryujinx.Graphics.OpenGL _tfEnabled = false; } + public void SetAlphaTest(bool enable, float reference, CompareOp op) + { + if (!enable) + { + GL.Disable(EnableCap.AlphaTest); + return; + } + + GL.AlphaFunc((AlphaFunction)op.Convert(), reference); + GL.Enable(EnableCap.AlphaTest); + } + public void SetBlendState(int index, BlendDescriptor blend) { if (!blend.Enable) { GL.Disable(IndexedEnableCap.Blend, index); - return; } @@ -658,7 +666,6 @@ namespace Ryujinx.Graphics.OpenGL if (!enable) { GL.Disable(EnableCap.CullFace); - return; } @@ -742,7 +749,6 @@ namespace Ryujinx.Graphics.OpenGL if (!enable) { GL.Disable(EnableCap.PrimitiveRestart); - return; } @@ -874,7 +880,6 @@ namespace Ryujinx.Graphics.OpenGL if (!stencilTest.TestEnable) { GL.Disable(EnableCap.StencilTest); - return; } @@ -1077,7 +1082,6 @@ namespace Ryujinx.Graphics.OpenGL if (buffer.Handle == null) { GL.BindBufferRange(target, bindingPoint, 0, IntPtr.Zero, 0); - return; }