From 44c1cf3fe5a3886f34251f93fbcfc3b9c8f0e164 Mon Sep 17 00:00:00 2001 From: gdkchan Date: Thu, 1 Nov 2018 01:22:24 -0300 Subject: Implment common and independent blend properly (fixes #458) (#485) * Implment common and independent blend properly * Nits --- Ryujinx.Graphics/NvGpuEngine3d.cs | 65 ++++++++++++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 15 deletions(-) (limited to 'Ryujinx.Graphics/NvGpuEngine3d.cs') diff --git a/Ryujinx.Graphics/NvGpuEngine3d.cs b/Ryujinx.Graphics/NvGpuEngine3d.cs index 618d7d9f..f4a45347 100644 --- a/Ryujinx.Graphics/NvGpuEngine3d.cs +++ b/Ryujinx.Graphics/NvGpuEngine3d.cs @@ -407,22 +407,59 @@ namespace Ryujinx.Graphics private void SetBlending(GalPipelineState State) { - //TODO: Support independent blend properly. - State.BlendEnabled = ReadRegisterBool(NvGpuEngine3dReg.IBlendNEnable); + bool BlendIndependent = ReadRegisterBool(NvGpuEngine3dReg.BlendIndependent); - if (State.BlendEnabled) + State.BlendIndependent = BlendIndependent; + + for (int Index = 0; Index < GalPipelineState.RenderTargetsCount; Index++) { - State.BlendSeparateAlpha = ReadRegisterBool(NvGpuEngine3dReg.IBlendNSeparateAlpha); + if (BlendIndependent) + { + State.Blends[Index].Enabled = ReadRegisterBool(NvGpuEngine3dReg.IBlendNEnable + Index); + + if (State.Blends[Index].Enabled) + { + State.Blends[Index].SeparateAlpha = ReadRegisterBool(NvGpuEngine3dReg.IBlendNSeparateAlpha + Index * 8); + + State.Blends[Index].EquationRgb = ReadBlendEquation(NvGpuEngine3dReg.IBlendNEquationRgb + Index * 8); + State.Blends[Index].FuncSrcRgb = ReadBlendFactor (NvGpuEngine3dReg.IBlendNFuncSrcRgb + Index * 8); + State.Blends[Index].FuncDstRgb = ReadBlendFactor (NvGpuEngine3dReg.IBlendNFuncDstRgb + Index * 8); + State.Blends[Index].EquationAlpha = ReadBlendEquation(NvGpuEngine3dReg.IBlendNEquationAlpha + Index * 8); + State.Blends[Index].FuncSrcAlpha = ReadBlendFactor (NvGpuEngine3dReg.IBlendNFuncSrcAlpha + Index * 8); + State.Blends[Index].FuncDstAlpha = ReadBlendFactor (NvGpuEngine3dReg.IBlendNFuncDstAlpha + Index * 8); + } + } + else + { + //It seems that even when independent blend is disabled, the first IBlend enable + //register is still set to indicate whenever blend is enabled or not (?). + State.Blends[Index].Enabled = ReadRegisterBool(NvGpuEngine3dReg.IBlendNEnable); - State.BlendEquationRgb = (GalBlendEquation)ReadRegister(NvGpuEngine3dReg.IBlendNEquationRgb); - State.BlendFuncSrcRgb = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncSrcRgb); - State.BlendFuncDstRgb = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncDstRgb); - State.BlendEquationAlpha = (GalBlendEquation)ReadRegister(NvGpuEngine3dReg.IBlendNEquationAlpha); - State.BlendFuncSrcAlpha = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncSrcAlpha); - State.BlendFuncDstAlpha = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncDstAlpha); + if (State.Blends[Index].Enabled) + { + State.Blends[Index].SeparateAlpha = ReadRegisterBool(NvGpuEngine3dReg.BlendSeparateAlpha); + + State.Blends[Index].EquationRgb = ReadBlendEquation(NvGpuEngine3dReg.BlendEquationRgb); + State.Blends[Index].FuncSrcRgb = ReadBlendFactor (NvGpuEngine3dReg.BlendFuncSrcRgb); + State.Blends[Index].FuncDstRgb = ReadBlendFactor (NvGpuEngine3dReg.BlendFuncDstRgb); + State.Blends[Index].EquationAlpha = ReadBlendEquation(NvGpuEngine3dReg.BlendEquationAlpha); + State.Blends[Index].FuncSrcAlpha = ReadBlendFactor (NvGpuEngine3dReg.BlendFuncSrcAlpha); + State.Blends[Index].FuncDstAlpha = ReadBlendFactor (NvGpuEngine3dReg.BlendFuncDstAlpha); + } + } } } + private GalBlendEquation ReadBlendEquation(NvGpuEngine3dReg Register) + { + return (GalBlendEquation)ReadRegister(Register); + } + + private GalBlendFactor ReadBlendFactor(NvGpuEngine3dReg Register) + { + return (GalBlendFactor)ReadRegister(Register); + } + private void SetColorMask(GalPipelineState State) { bool ColorMaskCommon = ReadRegisterBool(NvGpuEngine3dReg.ColorMaskCommon); @@ -514,10 +551,8 @@ namespace Ryujinx.Graphics { if (TextureHandle == 0) { - //TODO: Is this correct? - //Some games like puyo puyo will have 0 handles. - //It may be just normal behaviour or a bug caused by sync issues. - //The game does initialize the value properly after through. + //FIXME: Some games like puyo puyo will use handles with the value 0. + //This is a bug, most likely caused by sync issues. return; } @@ -603,7 +638,7 @@ namespace Ryujinx.Graphics if (IndexEntrySize > 4) { - throw new InvalidOperationException(); + throw new InvalidOperationException("Invalid index entry size \"" + IndexEntrySize + "\"!"); } if (IndexCount != 0) -- cgit v1.2.3