Add GalPipelineState and IGalPipeline
This commit is contained in:
parent
eeb626947e
commit
06ac1a2b06
10 changed files with 345 additions and 358 deletions
45
Ryujinx.Graphics/Gal/GalPipelineState.cs
Normal file
45
Ryujinx.Graphics/Gal/GalPipelineState.cs
Normal file
|
@ -0,0 +1,45 @@
|
|||
namespace Ryujinx.Graphics.Gal
|
||||
{
|
||||
public struct GalPipelineState
|
||||
{
|
||||
public GalFrontFace FrontFace;
|
||||
|
||||
public bool CullFaceEnabled;
|
||||
public GalCullFace CullFace;
|
||||
|
||||
public bool DepthTestEnabled;
|
||||
public float DepthClear;
|
||||
public GalComparisonOp DepthFunc;
|
||||
|
||||
public bool StencilTestEnabled;
|
||||
public int StencilClear;
|
||||
|
||||
public GalComparisonOp StencilBackFuncFunc;
|
||||
public int StencilBackFuncRef;
|
||||
public uint StencilBackFuncMask;
|
||||
public GalStencilOp StencilBackOpFail;
|
||||
public GalStencilOp StencilBackOpZFail;
|
||||
public GalStencilOp StencilBackOpZPass;
|
||||
public uint StencilBackMask;
|
||||
|
||||
public GalComparisonOp StencilFrontFuncFunc;
|
||||
public int StencilFrontFuncRef;
|
||||
public uint StencilFrontFuncMask;
|
||||
public GalStencilOp StencilFrontOpFail;
|
||||
public GalStencilOp StencilFrontOpZFail;
|
||||
public GalStencilOp StencilFrontOpZPass;
|
||||
public uint StencilFrontMask;
|
||||
|
||||
public bool BlendEnabled;
|
||||
public bool BlendSeparateAlpha;
|
||||
public GalBlendEquation BlendEquationRgb;
|
||||
public GalBlendFactor BlendFuncSrcRgb;
|
||||
public GalBlendFactor BlendFuncDstRgb;
|
||||
public GalBlendEquation BlendEquationAlpha;
|
||||
public GalBlendFactor BlendFuncSrcAlpha;
|
||||
public GalBlendFactor BlendFuncDstAlpha;
|
||||
|
||||
public bool PrimitiveRestartEnabled;
|
||||
public uint PrimitiveRestartIndex;
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
namespace Ryujinx.Graphics.Gal
|
||||
{
|
||||
public interface IGalBlend
|
||||
{
|
||||
void Enable();
|
||||
|
||||
void Disable();
|
||||
|
||||
void Set(
|
||||
GalBlendEquation Equation,
|
||||
GalBlendFactor FuncSrc,
|
||||
GalBlendFactor FuncDst);
|
||||
|
||||
void SetSeparate(
|
||||
GalBlendEquation EquationRgb,
|
||||
GalBlendEquation EquationAlpha,
|
||||
GalBlendFactor FuncSrcRgb,
|
||||
GalBlendFactor FuncDstRgb,
|
||||
GalBlendFactor FuncSrcAlpha,
|
||||
GalBlendFactor FuncDstAlpha);
|
||||
}
|
||||
}
|
7
Ryujinx.Graphics/Gal/IGalPipeline.cs
Normal file
7
Ryujinx.Graphics/Gal/IGalPipeline.cs
Normal file
|
@ -0,0 +1,7 @@
|
|||
namespace Ryujinx.Graphics.Gal
|
||||
{
|
||||
public interface IGalPipeline
|
||||
{
|
||||
void Bind(ref GalPipelineState State);
|
||||
}
|
||||
}
|
|
@ -13,40 +13,6 @@ namespace Ryujinx.Graphics.Gal
|
|||
|
||||
bool IsIboCached(long Key, long DataSize);
|
||||
|
||||
void SetFrontFace(GalFrontFace FrontFace);
|
||||
|
||||
void EnableCullFace();
|
||||
|
||||
void DisableCullFace();
|
||||
|
||||
void SetCullFace(GalCullFace CullFace);
|
||||
|
||||
void EnableDepthTest();
|
||||
|
||||
void DisableDepthTest();
|
||||
|
||||
void SetDepthFunction(GalComparisonOp Func);
|
||||
|
||||
void SetClearDepth(float Depth);
|
||||
|
||||
void EnableStencilTest();
|
||||
|
||||
void DisableStencilTest();
|
||||
|
||||
void SetStencilFunction(bool IsFrontFace, GalComparisonOp Func, int Ref, int Mask);
|
||||
|
||||
void SetStencilOp(bool IsFrontFace, GalStencilOp Fail, GalStencilOp ZFail, GalStencilOp ZPass);
|
||||
|
||||
void SetStencilMask(bool IsFrontFace, int Mask);
|
||||
|
||||
void SetClearStencil(int Stencil);
|
||||
|
||||
void EnablePrimitiveRestart();
|
||||
|
||||
void DisablePrimitiveRestart();
|
||||
|
||||
void SetPrimitiveRestartIndex(uint Index);
|
||||
|
||||
void CreateVbo(long Key, int DataSize, IntPtr HostAddress);
|
||||
|
||||
void CreateIbo(long Key, int DataSize, IntPtr HostAddress);
|
||||
|
|
|
@ -8,14 +8,14 @@ namespace Ryujinx.Graphics.Gal
|
|||
|
||||
void RunActions();
|
||||
|
||||
IGalBlend Blend { get; }
|
||||
|
||||
IGalFrameBuffer FrameBuffer { get; }
|
||||
|
||||
IGalRasterizer Rasterizer { get; }
|
||||
|
||||
IGalShader Shader { get; }
|
||||
|
||||
IGalPipeline Pipeline { get; }
|
||||
|
||||
IGalTexture Texture { get; }
|
||||
}
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
|
||||
namespace Ryujinx.Graphics.Gal.OpenGL
|
||||
{
|
||||
public class OGLBlend : IGalBlend
|
||||
{
|
||||
public void Enable()
|
||||
{
|
||||
GL.Enable(EnableCap.Blend);
|
||||
}
|
||||
|
||||
public void Disable()
|
||||
{
|
||||
GL.Disable(EnableCap.Blend);
|
||||
}
|
||||
|
||||
public void Set(
|
||||
GalBlendEquation Equation,
|
||||
GalBlendFactor FuncSrc,
|
||||
GalBlendFactor FuncDst)
|
||||
{
|
||||
GL.BlendEquation(
|
||||
OGLEnumConverter.GetBlendEquation(Equation));
|
||||
|
||||
GL.BlendFunc(
|
||||
OGLEnumConverter.GetBlendFactor(FuncSrc),
|
||||
OGLEnumConverter.GetBlendFactor(FuncDst));
|
||||
}
|
||||
|
||||
public void SetSeparate(
|
||||
GalBlendEquation EquationRgb,
|
||||
GalBlendEquation EquationAlpha,
|
||||
GalBlendFactor FuncSrcRgb,
|
||||
GalBlendFactor FuncDstRgb,
|
||||
GalBlendFactor FuncSrcAlpha,
|
||||
GalBlendFactor FuncDstAlpha)
|
||||
{
|
||||
GL.BlendEquationSeparate(
|
||||
OGLEnumConverter.GetBlendEquation(EquationRgb),
|
||||
OGLEnumConverter.GetBlendEquation(EquationAlpha));
|
||||
|
||||
GL.BlendFuncSeparate(
|
||||
(BlendingFactorSrc)OGLEnumConverter.GetBlendFactor(FuncSrcRgb),
|
||||
(BlendingFactorDest)OGLEnumConverter.GetBlendFactor(FuncDstRgb),
|
||||
(BlendingFactorSrc)OGLEnumConverter.GetBlendFactor(FuncSrcAlpha),
|
||||
(BlendingFactorDest)OGLEnumConverter.GetBlendFactor(FuncDstAlpha));
|
||||
}
|
||||
}
|
||||
}
|
240
Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs
Normal file
240
Ryujinx.Graphics/Gal/OpenGL/OGLPipeline.cs
Normal file
|
@ -0,0 +1,240 @@
|
|||
using OpenTK.Graphics.OpenGL;
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Graphics.Gal.OpenGL
|
||||
{
|
||||
public class OGLPipeline : IGalPipeline
|
||||
{
|
||||
private GalPipelineState O;
|
||||
|
||||
public OGLPipeline()
|
||||
{
|
||||
//The following values match OpenGL's defaults
|
||||
O = new GalPipelineState();
|
||||
|
||||
O.FrontFace = GalFrontFace.CCW;
|
||||
|
||||
O.CullFaceEnabled = false;
|
||||
O.CullFace = GalCullFace.Back;
|
||||
|
||||
O.DepthTestEnabled = false;
|
||||
O.DepthClear = 1f;
|
||||
O.DepthFunc = GalComparisonOp.Less;
|
||||
|
||||
O.StencilTestEnabled = false;
|
||||
O.StencilClear = 0;
|
||||
|
||||
O.StencilBackFuncFunc = GalComparisonOp.Always;
|
||||
O.StencilBackFuncRef = 0;
|
||||
O.StencilBackFuncMask = UInt32.MaxValue;
|
||||
O.StencilBackOpFail = GalStencilOp.Keep;
|
||||
O.StencilBackOpZFail = GalStencilOp.Keep;
|
||||
O.StencilBackOpZPass = GalStencilOp.Keep;
|
||||
O.StencilBackMask = UInt32.MaxValue;
|
||||
|
||||
O.StencilFrontFuncFunc = GalComparisonOp.Always;
|
||||
O.StencilFrontFuncRef = 0;
|
||||
O.StencilFrontFuncMask = UInt32.MaxValue;
|
||||
O.StencilFrontOpFail = GalStencilOp.Keep;
|
||||
O.StencilFrontOpZFail = GalStencilOp.Keep;
|
||||
O.StencilFrontOpZPass = GalStencilOp.Keep;
|
||||
O.StencilFrontMask = UInt32.MaxValue;
|
||||
|
||||
O.BlendEnabled = false;
|
||||
O.BlendSeparateAlpha = false;
|
||||
|
||||
O.BlendEquationRgb = 0;
|
||||
O.BlendFuncSrcRgb = GalBlendFactor.One;
|
||||
O.BlendFuncDstRgb = GalBlendFactor.Zero;
|
||||
O.BlendEquationAlpha = 0;
|
||||
O.BlendFuncSrcAlpha = GalBlendFactor.One;
|
||||
O.BlendFuncDstAlpha = GalBlendFactor.Zero;
|
||||
|
||||
O.PrimitiveRestartEnabled = false;
|
||||
O.PrimitiveRestartIndex = 0;
|
||||
}
|
||||
|
||||
public void Bind(ref GalPipelineState S)
|
||||
{
|
||||
// O stands for Other, S from State (current state)
|
||||
|
||||
//Note: Uncomment SetFrontFace and SetCullFace when flipping issues are solved
|
||||
|
||||
//if (S.FrontFace != O.FrontFace)
|
||||
//{
|
||||
// GL.FrontFace(OGLEnumConverter.GetFrontFace(S.FrontFace));
|
||||
//}
|
||||
|
||||
//if (S.CullFaceEnabled != O.CullFaceEnabled)
|
||||
//{
|
||||
// Enable(EnableCap.CullFace, S.CullFaceEnabled);
|
||||
//}
|
||||
|
||||
//if (S.CullFaceEnabled)
|
||||
//{
|
||||
// if (S.CullFace != O.CullFace)
|
||||
// {
|
||||
// GL.CullFace(OGLEnumConverter.GetCullFace(S.CullFace));
|
||||
// }
|
||||
//}
|
||||
|
||||
if (S.DepthTestEnabled != O.DepthTestEnabled)
|
||||
{
|
||||
Enable(EnableCap.DepthTest, S.DepthTestEnabled);
|
||||
}
|
||||
|
||||
if (S.DepthClear != O.DepthClear)
|
||||
{
|
||||
GL.ClearDepth(S.DepthClear);
|
||||
}
|
||||
|
||||
if (S.DepthTestEnabled)
|
||||
{
|
||||
if (S.DepthFunc != O.DepthFunc)
|
||||
{
|
||||
GL.DepthFunc(OGLEnumConverter.GetDepthFunc(S.DepthFunc));
|
||||
}
|
||||
}
|
||||
|
||||
if (S.StencilTestEnabled != O.StencilTestEnabled)
|
||||
{
|
||||
Enable(EnableCap.StencilTest, S.StencilTestEnabled);
|
||||
}
|
||||
|
||||
if (S.StencilClear != O.StencilClear)
|
||||
{
|
||||
GL.ClearStencil(S.StencilClear);
|
||||
}
|
||||
|
||||
if (S.StencilTestEnabled)
|
||||
{
|
||||
if (S.StencilBackFuncFunc != O.StencilBackFuncFunc ||
|
||||
S.StencilBackFuncRef != O.StencilBackFuncRef ||
|
||||
S.StencilBackFuncMask != O.StencilBackFuncMask)
|
||||
{
|
||||
GL.StencilFuncSeparate(
|
||||
StencilFace.Back,
|
||||
OGLEnumConverter.GetStencilFunc(S.StencilBackFuncFunc),
|
||||
S.StencilBackFuncRef,
|
||||
S.StencilBackFuncMask);
|
||||
}
|
||||
|
||||
if (S.StencilBackOpFail != O.StencilBackOpFail ||
|
||||
S.StencilBackOpZFail != O.StencilBackOpZFail ||
|
||||
S.StencilBackOpZPass != O.StencilBackOpZPass)
|
||||
{
|
||||
GL.StencilOpSeparate(
|
||||
StencilFace.Back,
|
||||
OGLEnumConverter.GetStencilOp(S.StencilBackOpFail),
|
||||
OGLEnumConverter.GetStencilOp(S.StencilBackOpZFail),
|
||||
OGLEnumConverter.GetStencilOp(S.StencilBackOpZPass));
|
||||
}
|
||||
|
||||
if (S.StencilBackMask != O.StencilBackMask)
|
||||
{
|
||||
GL.StencilMaskSeparate(StencilFace.Back, S.StencilBackMask);
|
||||
}
|
||||
|
||||
if (S.StencilFrontFuncFunc != O.StencilFrontFuncFunc ||
|
||||
S.StencilFrontFuncRef != O.StencilFrontFuncRef ||
|
||||
S.StencilFrontFuncMask != O.StencilFrontFuncMask)
|
||||
{
|
||||
GL.StencilFuncSeparate(
|
||||
StencilFace.Front,
|
||||
OGLEnumConverter.GetStencilFunc(S.StencilFrontFuncFunc),
|
||||
S.StencilFrontFuncRef,
|
||||
S.StencilFrontFuncMask);
|
||||
}
|
||||
|
||||
if (S.StencilFrontOpFail != O.StencilFrontOpFail ||
|
||||
S.StencilFrontOpZFail != O.StencilFrontOpZFail ||
|
||||
S.StencilFrontOpZPass != O.StencilFrontOpZPass)
|
||||
{
|
||||
GL.StencilOpSeparate(
|
||||
StencilFace.Front,
|
||||
OGLEnumConverter.GetStencilOp(S.StencilFrontOpFail),
|
||||
OGLEnumConverter.GetStencilOp(S.StencilFrontOpZFail),
|
||||
OGLEnumConverter.GetStencilOp(S.StencilFrontOpZPass));
|
||||
}
|
||||
|
||||
if (S.StencilFrontMask != O.StencilFrontMask)
|
||||
{
|
||||
GL.StencilMaskSeparate(StencilFace.Front, S.StencilFrontMask);
|
||||
}
|
||||
}
|
||||
|
||||
if (S.BlendEnabled != O.BlendEnabled)
|
||||
{
|
||||
Enable(EnableCap.Blend, S.BlendEnabled);
|
||||
}
|
||||
|
||||
if (S.BlendEnabled)
|
||||
{
|
||||
if (S.BlendSeparateAlpha)
|
||||
{
|
||||
if (S.BlendEquationRgb != O.BlendEquationRgb ||
|
||||
S.BlendEquationAlpha != O.BlendEquationAlpha)
|
||||
{
|
||||
GL.BlendEquationSeparate(
|
||||
OGLEnumConverter.GetBlendEquation(S.BlendEquationRgb),
|
||||
OGLEnumConverter.GetBlendEquation(S.BlendEquationAlpha));
|
||||
}
|
||||
|
||||
if (S.BlendFuncSrcRgb != O.BlendFuncSrcRgb ||
|
||||
S.BlendFuncDstRgb != O.BlendFuncDstRgb ||
|
||||
S.BlendFuncSrcAlpha != O.BlendFuncSrcAlpha ||
|
||||
S.BlendFuncDstAlpha != O.BlendFuncDstAlpha)
|
||||
{
|
||||
GL.BlendFuncSeparate(
|
||||
(BlendingFactorSrc) OGLEnumConverter.GetBlendFactor(S.BlendFuncSrcRgb),
|
||||
(BlendingFactorDest)OGLEnumConverter.GetBlendFactor(S.BlendFuncDstRgb),
|
||||
(BlendingFactorSrc) OGLEnumConverter.GetBlendFactor(S.BlendFuncSrcAlpha),
|
||||
(BlendingFactorDest)OGLEnumConverter.GetBlendFactor(S.BlendFuncDstAlpha));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (S.BlendEquationRgb != O.BlendEquationRgb)
|
||||
{
|
||||
GL.BlendEquation(OGLEnumConverter.GetBlendEquation(S.BlendEquationRgb));
|
||||
}
|
||||
|
||||
if (S.BlendFuncSrcRgb != O.BlendFuncSrcRgb ||
|
||||
S.BlendFuncDstRgb != O.BlendFuncDstRgb)
|
||||
{
|
||||
GL.BlendFunc(
|
||||
OGLEnumConverter.GetBlendFactor(S.BlendFuncSrcRgb),
|
||||
OGLEnumConverter.GetBlendFactor(S.BlendFuncDstRgb));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (S.PrimitiveRestartEnabled != O.PrimitiveRestartEnabled)
|
||||
{
|
||||
Enable(EnableCap.PrimitiveRestart, S.PrimitiveRestartEnabled);
|
||||
}
|
||||
|
||||
if (S.PrimitiveRestartEnabled)
|
||||
{
|
||||
if (S.PrimitiveRestartIndex != O.PrimitiveRestartIndex)
|
||||
{
|
||||
GL.PrimitiveRestartIndex(S.PrimitiveRestartIndex);
|
||||
}
|
||||
}
|
||||
|
||||
O = S;
|
||||
}
|
||||
|
||||
private void Enable(EnableCap Cap, bool Enabled)
|
||||
{
|
||||
if (Enabled)
|
||||
{
|
||||
GL.Enable(Cap);
|
||||
}
|
||||
else
|
||||
{
|
||||
GL.Disable(Cap);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -118,99 +118,6 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
return IboCache.TryGetSize(Key, out long Size) && Size == DataSize;
|
||||
}
|
||||
|
||||
public void SetFrontFace(GalFrontFace FrontFace)
|
||||
{
|
||||
GL.FrontFace(OGLEnumConverter.GetFrontFace(FrontFace));
|
||||
}
|
||||
|
||||
public void EnableCullFace()
|
||||
{
|
||||
GL.Enable(EnableCap.CullFace);
|
||||
}
|
||||
|
||||
public void DisableCullFace()
|
||||
{
|
||||
GL.Disable(EnableCap.CullFace);
|
||||
}
|
||||
|
||||
public void SetCullFace(GalCullFace CullFace)
|
||||
{
|
||||
GL.CullFace(OGLEnumConverter.GetCullFace(CullFace));
|
||||
}
|
||||
|
||||
public void EnableDepthTest()
|
||||
{
|
||||
GL.Enable(EnableCap.DepthTest);
|
||||
}
|
||||
|
||||
public void DisableDepthTest()
|
||||
{
|
||||
GL.Disable(EnableCap.DepthTest);
|
||||
}
|
||||
|
||||
public void SetDepthFunction(GalComparisonOp Func)
|
||||
{
|
||||
GL.DepthFunc(OGLEnumConverter.GetDepthFunc(Func));
|
||||
}
|
||||
|
||||
public void SetClearDepth(float Depth)
|
||||
{
|
||||
GL.ClearDepth(Depth);
|
||||
}
|
||||
|
||||
public void EnableStencilTest()
|
||||
{
|
||||
GL.Enable(EnableCap.StencilTest);
|
||||
}
|
||||
|
||||
public void DisableStencilTest()
|
||||
{
|
||||
GL.Disable(EnableCap.StencilTest);
|
||||
}
|
||||
|
||||
public void SetStencilFunction(bool IsFrontFace, GalComparisonOp Func, int Ref, int Mask)
|
||||
{
|
||||
GL.StencilFuncSeparate(
|
||||
IsFrontFace ? StencilFace.Front : StencilFace.Back,
|
||||
OGLEnumConverter.GetStencilFunc(Func),
|
||||
Ref,
|
||||
Mask);
|
||||
}
|
||||
|
||||
public void SetStencilOp(bool IsFrontFace, GalStencilOp Fail, GalStencilOp ZFail, GalStencilOp ZPass)
|
||||
{
|
||||
GL.StencilOpSeparate(
|
||||
IsFrontFace ? StencilFace.Front : StencilFace.Back,
|
||||
OGLEnumConverter.GetStencilOp(Fail),
|
||||
OGLEnumConverter.GetStencilOp(ZFail),
|
||||
OGLEnumConverter.GetStencilOp(ZPass));
|
||||
}
|
||||
|
||||
public void SetStencilMask(bool IsFrontFace, int Mask)
|
||||
{
|
||||
GL.StencilMaskSeparate(IsFrontFace ? StencilFace.Front : StencilFace.Back, Mask);
|
||||
}
|
||||
|
||||
public void SetClearStencil(int Stencil)
|
||||
{
|
||||
GL.ClearStencil(Stencil);
|
||||
}
|
||||
|
||||
public void EnablePrimitiveRestart()
|
||||
{
|
||||
GL.Enable(EnableCap.PrimitiveRestart);
|
||||
}
|
||||
|
||||
public void DisablePrimitiveRestart()
|
||||
{
|
||||
GL.Disable(EnableCap.PrimitiveRestart);
|
||||
}
|
||||
|
||||
public void SetPrimitiveRestartIndex(uint Index)
|
||||
{
|
||||
GL.PrimitiveRestartIndex(Index);
|
||||
}
|
||||
|
||||
public void CreateVbo(long Key, int DataSize, IntPtr HostAddress)
|
||||
{
|
||||
int Handle = GL.GenBuffer();
|
||||
|
|
|
@ -5,28 +5,28 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
|||
{
|
||||
public class OGLRenderer : IGalRenderer
|
||||
{
|
||||
public IGalBlend Blend { get; private set; }
|
||||
|
||||
public IGalFrameBuffer FrameBuffer { get; private set; }
|
||||
|
||||
public IGalRasterizer Rasterizer { get; private set; }
|
||||
|
||||
public IGalShader Shader { get; private set; }
|
||||
|
||||
public IGalPipeline Pipeline { get; private set; }
|
||||
|
||||
public IGalTexture Texture { get; private set; }
|
||||
|
||||
private ConcurrentQueue<Action> ActionsQueue;
|
||||
|
||||
public OGLRenderer()
|
||||
{
|
||||
Blend = new OGLBlend();
|
||||
|
||||
FrameBuffer = new OGLFrameBuffer();
|
||||
|
||||
Rasterizer = new OGLRasterizer();
|
||||
|
||||
Shader = new OGLShader();
|
||||
|
||||
Pipeline = new OGLPipeline();
|
||||
|
||||
Texture = new OGLTexture();
|
||||
|
||||
ActionsQueue = new ConcurrentQueue<Action>();
|
||||
|
|
|
@ -27,6 +27,8 @@ namespace Ryujinx.HLE.Gpu.Engines
|
|||
|
||||
private List<long>[] UploadedKeys;
|
||||
|
||||
private GalPipelineState State;
|
||||
|
||||
public NvGpuEngine3d(NvGpu Gpu)
|
||||
{
|
||||
this.Gpu = Gpu;
|
||||
|
@ -66,6 +68,8 @@ namespace Ryujinx.HLE.Gpu.Engines
|
|||
{
|
||||
UploadedKeys[i] = new List<long>();
|
||||
}
|
||||
|
||||
State = new GalPipelineState();
|
||||
}
|
||||
|
||||
public void CallMethod(NvGpuVmm Vmm, NvGpuPBEntry PBEntry)
|
||||
|
@ -90,14 +94,15 @@ namespace Ryujinx.HLE.Gpu.Engines
|
|||
|
||||
Gpu.Renderer.Shader.BindProgram();
|
||||
|
||||
//Note: Uncomment SetFrontFace SetCullFace when flipping issues are solved
|
||||
//SetFrontFace();
|
||||
//SetCullFace();
|
||||
SetFrontFace();
|
||||
SetCullFace();
|
||||
SetDepth();
|
||||
SetStencil();
|
||||
SetAlphaBlending();
|
||||
SetPrimitiveRestart();
|
||||
|
||||
Gpu.Renderer.Pipeline.Bind(ref State);
|
||||
|
||||
UploadTextures(Vmm, Keys);
|
||||
UploadUniforms(Vmm);
|
||||
UploadVertexArrays(Vmm);
|
||||
|
@ -261,195 +266,83 @@ namespace Ryujinx.HLE.Gpu.Engines
|
|||
}
|
||||
}
|
||||
|
||||
Gpu.Renderer.Rasterizer.SetFrontFace(FrontFace);
|
||||
State.FrontFace = FrontFace;
|
||||
}
|
||||
|
||||
private void SetCullFace()
|
||||
{
|
||||
bool Enable = (ReadRegister(NvGpuEngine3dReg.CullFaceEnable) & 1) != 0;
|
||||
State.CullFaceEnabled = (ReadRegister(NvGpuEngine3dReg.CullFaceEnable) & 1) != 0;
|
||||
|
||||
if (Enable)
|
||||
if (State.CullFaceEnabled)
|
||||
{
|
||||
Gpu.Renderer.Rasterizer.EnableCullFace();
|
||||
State.CullFace = (GalCullFace)ReadRegister(NvGpuEngine3dReg.CullFace);
|
||||
}
|
||||
else
|
||||
{
|
||||
Gpu.Renderer.Rasterizer.DisableCullFace();
|
||||
}
|
||||
|
||||
if (!Enable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GalCullFace CullFace = (GalCullFace)ReadRegister(NvGpuEngine3dReg.CullFace);
|
||||
|
||||
Gpu.Renderer.Rasterizer.SetCullFace(CullFace);
|
||||
}
|
||||
|
||||
private void SetDepth()
|
||||
{
|
||||
float ClearDepth = ReadRegisterFloat(NvGpuEngine3dReg.ClearDepth);
|
||||
State.DepthTestEnabled = (ReadRegister(NvGpuEngine3dReg.DepthTestEnable) & 1) != 0;
|
||||
|
||||
Gpu.Renderer.Rasterizer.SetClearDepth(ClearDepth);
|
||||
State.DepthClear = ReadRegisterFloat(NvGpuEngine3dReg.ClearDepth);
|
||||
|
||||
bool Enable = (ReadRegister(NvGpuEngine3dReg.DepthTestEnable) & 1) != 0;
|
||||
|
||||
if (Enable)
|
||||
if (State.DepthTestEnabled)
|
||||
{
|
||||
Gpu.Renderer.Rasterizer.EnableDepthTest();
|
||||
State.DepthFunc = (GalComparisonOp)ReadRegister(NvGpuEngine3dReg.DepthTestFunction);
|
||||
}
|
||||
else
|
||||
{
|
||||
Gpu.Renderer.Rasterizer.DisableDepthTest();
|
||||
}
|
||||
|
||||
if (!Enable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GalComparisonOp Func = (GalComparisonOp)ReadRegister(NvGpuEngine3dReg.DepthTestFunction);
|
||||
|
||||
Gpu.Renderer.Rasterizer.SetDepthFunction(Func);
|
||||
}
|
||||
|
||||
private void SetStencil()
|
||||
{
|
||||
int ClearStencil = ReadRegister(NvGpuEngine3dReg.ClearStencil);
|
||||
State.StencilTestEnabled = (ReadRegister(NvGpuEngine3dReg.StencilEnable) & 1) != 0;
|
||||
|
||||
Gpu.Renderer.Rasterizer.SetClearStencil(ClearStencil);
|
||||
|
||||
bool Enable = (ReadRegister(NvGpuEngine3dReg.StencilEnable) & 1) != 0;
|
||||
|
||||
if (Enable)
|
||||
State.StencilClear = ReadRegister(NvGpuEngine3dReg.ClearStencil);
|
||||
|
||||
if (State.StencilTestEnabled)
|
||||
{
|
||||
Gpu.Renderer.Rasterizer.EnableStencilTest();
|
||||
State.StencilBackFuncFunc = (GalComparisonOp)ReadRegister(NvGpuEngine3dReg.StencilBackFuncFunc);
|
||||
State.StencilBackFuncRef = ReadRegister(NvGpuEngine3dReg.StencilBackFuncRef);
|
||||
State.StencilBackFuncMask = (uint)ReadRegister(NvGpuEngine3dReg.StencilBackFuncMask);
|
||||
State.StencilBackOpFail = (GalStencilOp)ReadRegister(NvGpuEngine3dReg.StencilBackOpFail);
|
||||
State.StencilBackOpZFail = (GalStencilOp)ReadRegister(NvGpuEngine3dReg.StencilBackOpZFail);
|
||||
State.StencilBackOpZPass = (GalStencilOp)ReadRegister(NvGpuEngine3dReg.StencilBackOpZPass);
|
||||
State.StencilBackMask = (uint)ReadRegister(NvGpuEngine3dReg.StencilBackMask);
|
||||
|
||||
State.StencilFrontFuncFunc = (GalComparisonOp)ReadRegister(NvGpuEngine3dReg.StencilFrontFuncFunc);
|
||||
State.StencilFrontFuncRef = ReadRegister(NvGpuEngine3dReg.StencilFrontFuncRef);
|
||||
State.StencilFrontFuncMask = (uint)ReadRegister(NvGpuEngine3dReg.StencilFrontFuncMask);
|
||||
State.StencilFrontOpFail = (GalStencilOp)ReadRegister(NvGpuEngine3dReg.StencilFrontOpFail);
|
||||
State.StencilFrontOpZFail = (GalStencilOp)ReadRegister(NvGpuEngine3dReg.StencilFrontOpZFail);
|
||||
State.StencilFrontOpZPass = (GalStencilOp)ReadRegister(NvGpuEngine3dReg.StencilFrontOpZPass);
|
||||
State.StencilFrontMask = (uint)ReadRegister(NvGpuEngine3dReg.StencilFrontMask);
|
||||
}
|
||||
else
|
||||
{
|
||||
Gpu.Renderer.Rasterizer.DisableStencilTest();
|
||||
}
|
||||
|
||||
if (!Enable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void SetFaceStencil(
|
||||
bool IsFrontFace,
|
||||
NvGpuEngine3dReg Func,
|
||||
NvGpuEngine3dReg FuncRef,
|
||||
NvGpuEngine3dReg FuncMask,
|
||||
NvGpuEngine3dReg OpFail,
|
||||
NvGpuEngine3dReg OpZFail,
|
||||
NvGpuEngine3dReg OpZPass,
|
||||
NvGpuEngine3dReg Mask)
|
||||
{
|
||||
Gpu.Renderer.Rasterizer.SetStencilFunction(
|
||||
IsFrontFace,
|
||||
(GalComparisonOp)ReadRegister(Func),
|
||||
ReadRegister(FuncRef),
|
||||
ReadRegister(FuncMask));
|
||||
|
||||
Gpu.Renderer.Rasterizer.SetStencilOp(
|
||||
IsFrontFace,
|
||||
(GalStencilOp)ReadRegister(OpFail),
|
||||
(GalStencilOp)ReadRegister(OpZFail),
|
||||
(GalStencilOp)ReadRegister(OpZPass));
|
||||
|
||||
Gpu.Renderer.Rasterizer.SetStencilMask(IsFrontFace, ReadRegister(Mask));
|
||||
}
|
||||
|
||||
SetFaceStencil(false,
|
||||
NvGpuEngine3dReg.StencilBackFuncFunc,
|
||||
NvGpuEngine3dReg.StencilBackFuncRef,
|
||||
NvGpuEngine3dReg.StencilBackFuncMask,
|
||||
NvGpuEngine3dReg.StencilBackOpFail,
|
||||
NvGpuEngine3dReg.StencilBackOpZFail,
|
||||
NvGpuEngine3dReg.StencilBackOpZPass,
|
||||
NvGpuEngine3dReg.StencilBackMask);
|
||||
|
||||
SetFaceStencil(true,
|
||||
NvGpuEngine3dReg.StencilFrontFuncFunc,
|
||||
NvGpuEngine3dReg.StencilFrontFuncRef,
|
||||
NvGpuEngine3dReg.StencilFrontFuncMask,
|
||||
NvGpuEngine3dReg.StencilFrontOpFail,
|
||||
NvGpuEngine3dReg.StencilFrontOpZFail,
|
||||
NvGpuEngine3dReg.StencilFrontOpZPass,
|
||||
NvGpuEngine3dReg.StencilFrontMask);
|
||||
}
|
||||
|
||||
private void SetAlphaBlending()
|
||||
{
|
||||
//TODO: Support independent blend properly.
|
||||
bool Enable = (ReadRegister(NvGpuEngine3dReg.IBlendNEnable) & 1) != 0;
|
||||
State.BlendEnabled = (ReadRegister(NvGpuEngine3dReg.IBlendNEnable) & 1) != 0;
|
||||
|
||||
if (Enable)
|
||||
if (State.BlendEnabled)
|
||||
{
|
||||
Gpu.Renderer.Blend.Enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
Gpu.Renderer.Blend.Disable();
|
||||
}
|
||||
State.BlendSeparateAlpha = (ReadRegister(NvGpuEngine3dReg.IBlendNSeparateAlpha) & 1) != 0;
|
||||
|
||||
if (!Enable)
|
||||
{
|
||||
//If blend is not enabled, then the other values have no effect.
|
||||
//Note that if it is disabled, the register may contain invalid values.
|
||||
return;
|
||||
}
|
||||
|
||||
bool BlendSeparateAlpha = (ReadRegister(NvGpuEngine3dReg.IBlendNSeparateAlpha) & 1) != 0;
|
||||
|
||||
GalBlendEquation EquationRgb = (GalBlendEquation)ReadRegister(NvGpuEngine3dReg.IBlendNEquationRgb);
|
||||
|
||||
GalBlendFactor FuncSrcRgb = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncSrcRgb);
|
||||
GalBlendFactor FuncDstRgb = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncDstRgb);
|
||||
|
||||
if (BlendSeparateAlpha)
|
||||
{
|
||||
GalBlendEquation EquationAlpha = (GalBlendEquation)ReadRegister(NvGpuEngine3dReg.IBlendNEquationAlpha);
|
||||
|
||||
GalBlendFactor FuncSrcAlpha = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncSrcAlpha);
|
||||
GalBlendFactor FuncDstAlpha = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncDstAlpha);
|
||||
|
||||
Gpu.Renderer.Blend.SetSeparate(
|
||||
EquationRgb,
|
||||
EquationAlpha,
|
||||
FuncSrcRgb,
|
||||
FuncDstRgb,
|
||||
FuncSrcAlpha,
|
||||
FuncDstAlpha);
|
||||
}
|
||||
else
|
||||
{
|
||||
Gpu.Renderer.Blend.Set(EquationRgb, FuncSrcRgb, FuncDstRgb);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetPrimitiveRestart()
|
||||
{
|
||||
bool Enable = (ReadRegister(NvGpuEngine3dReg.PrimRestartEnable) & 1) != 0;
|
||||
State.PrimitiveRestartEnabled = (ReadRegister(NvGpuEngine3dReg.PrimRestartEnable) & 1) != 0;
|
||||
|
||||
if (Enable)
|
||||
if (State.PrimitiveRestartEnabled)
|
||||
{
|
||||
Gpu.Renderer.Rasterizer.EnablePrimitiveRestart();
|
||||
State.PrimitiveRestartIndex = (uint)ReadRegister(NvGpuEngine3dReg.PrimRestartIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
Gpu.Renderer.Rasterizer.DisablePrimitiveRestart();
|
||||
}
|
||||
|
||||
if (!Enable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
uint Index = (uint)ReadRegister(NvGpuEngine3dReg.PrimRestartIndex);
|
||||
|
||||
Gpu.Renderer.Rasterizer.SetPrimitiveRestartIndex(Index);
|
||||
}
|
||||
|
||||
private void UploadTextures(NvGpuVmm Vmm, long[] Keys)
|
||||
|
|
Loading…
Add table
Reference in a new issue