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);
|
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 CreateVbo(long Key, int DataSize, IntPtr HostAddress);
|
||||||
|
|
||||||
void CreateIbo(long Key, int DataSize, IntPtr HostAddress);
|
void CreateIbo(long Key, int DataSize, IntPtr HostAddress);
|
||||||
|
|
|
@ -8,14 +8,14 @@ namespace Ryujinx.Graphics.Gal
|
||||||
|
|
||||||
void RunActions();
|
void RunActions();
|
||||||
|
|
||||||
IGalBlend Blend { get; }
|
|
||||||
|
|
||||||
IGalFrameBuffer FrameBuffer { get; }
|
IGalFrameBuffer FrameBuffer { get; }
|
||||||
|
|
||||||
IGalRasterizer Rasterizer { get; }
|
IGalRasterizer Rasterizer { get; }
|
||||||
|
|
||||||
IGalShader Shader { get; }
|
IGalShader Shader { get; }
|
||||||
|
|
||||||
|
IGalPipeline Pipeline { get; }
|
||||||
|
|
||||||
IGalTexture Texture { 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;
|
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)
|
public void CreateVbo(long Key, int DataSize, IntPtr HostAddress)
|
||||||
{
|
{
|
||||||
int Handle = GL.GenBuffer();
|
int Handle = GL.GenBuffer();
|
||||||
|
|
|
@ -5,28 +5,28 @@ namespace Ryujinx.Graphics.Gal.OpenGL
|
||||||
{
|
{
|
||||||
public class OGLRenderer : IGalRenderer
|
public class OGLRenderer : IGalRenderer
|
||||||
{
|
{
|
||||||
public IGalBlend Blend { get; private set; }
|
|
||||||
|
|
||||||
public IGalFrameBuffer FrameBuffer { get; private set; }
|
public IGalFrameBuffer FrameBuffer { get; private set; }
|
||||||
|
|
||||||
public IGalRasterizer Rasterizer { get; private set; }
|
public IGalRasterizer Rasterizer { get; private set; }
|
||||||
|
|
||||||
public IGalShader Shader { get; private set; }
|
public IGalShader Shader { get; private set; }
|
||||||
|
|
||||||
|
public IGalPipeline Pipeline { get; private set; }
|
||||||
|
|
||||||
public IGalTexture Texture { get; private set; }
|
public IGalTexture Texture { get; private set; }
|
||||||
|
|
||||||
private ConcurrentQueue<Action> ActionsQueue;
|
private ConcurrentQueue<Action> ActionsQueue;
|
||||||
|
|
||||||
public OGLRenderer()
|
public OGLRenderer()
|
||||||
{
|
{
|
||||||
Blend = new OGLBlend();
|
|
||||||
|
|
||||||
FrameBuffer = new OGLFrameBuffer();
|
FrameBuffer = new OGLFrameBuffer();
|
||||||
|
|
||||||
Rasterizer = new OGLRasterizer();
|
Rasterizer = new OGLRasterizer();
|
||||||
|
|
||||||
Shader = new OGLShader();
|
Shader = new OGLShader();
|
||||||
|
|
||||||
|
Pipeline = new OGLPipeline();
|
||||||
|
|
||||||
Texture = new OGLTexture();
|
Texture = new OGLTexture();
|
||||||
|
|
||||||
ActionsQueue = new ConcurrentQueue<Action>();
|
ActionsQueue = new ConcurrentQueue<Action>();
|
||||||
|
|
|
@ -27,6 +27,8 @@ namespace Ryujinx.HLE.Gpu.Engines
|
||||||
|
|
||||||
private List<long>[] UploadedKeys;
|
private List<long>[] UploadedKeys;
|
||||||
|
|
||||||
|
private GalPipelineState State;
|
||||||
|
|
||||||
public NvGpuEngine3d(NvGpu Gpu)
|
public NvGpuEngine3d(NvGpu Gpu)
|
||||||
{
|
{
|
||||||
this.Gpu = Gpu;
|
this.Gpu = Gpu;
|
||||||
|
@ -66,6 +68,8 @@ namespace Ryujinx.HLE.Gpu.Engines
|
||||||
{
|
{
|
||||||
UploadedKeys[i] = new List<long>();
|
UploadedKeys[i] = new List<long>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
State = new GalPipelineState();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CallMethod(NvGpuVmm Vmm, NvGpuPBEntry PBEntry)
|
public void CallMethod(NvGpuVmm Vmm, NvGpuPBEntry PBEntry)
|
||||||
|
@ -90,14 +94,15 @@ namespace Ryujinx.HLE.Gpu.Engines
|
||||||
|
|
||||||
Gpu.Renderer.Shader.BindProgram();
|
Gpu.Renderer.Shader.BindProgram();
|
||||||
|
|
||||||
//Note: Uncomment SetFrontFace SetCullFace when flipping issues are solved
|
SetFrontFace();
|
||||||
//SetFrontFace();
|
SetCullFace();
|
||||||
//SetCullFace();
|
|
||||||
SetDepth();
|
SetDepth();
|
||||||
SetStencil();
|
SetStencil();
|
||||||
SetAlphaBlending();
|
SetAlphaBlending();
|
||||||
SetPrimitiveRestart();
|
SetPrimitiveRestart();
|
||||||
|
|
||||||
|
Gpu.Renderer.Pipeline.Bind(ref State);
|
||||||
|
|
||||||
UploadTextures(Vmm, Keys);
|
UploadTextures(Vmm, Keys);
|
||||||
UploadUniforms(Vmm);
|
UploadUniforms(Vmm);
|
||||||
UploadVertexArrays(Vmm);
|
UploadVertexArrays(Vmm);
|
||||||
|
@ -261,195 +266,83 @@ namespace Ryujinx.HLE.Gpu.Engines
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Gpu.Renderer.Rasterizer.SetFrontFace(FrontFace);
|
State.FrontFace = FrontFace;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetCullFace()
|
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()
|
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 (State.DepthTestEnabled)
|
||||||
|
|
||||||
if (Enable)
|
|
||||||
{
|
{
|
||||||
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()
|
private void SetStencil()
|
||||||
{
|
{
|
||||||
int ClearStencil = ReadRegister(NvGpuEngine3dReg.ClearStencil);
|
State.StencilTestEnabled = (ReadRegister(NvGpuEngine3dReg.StencilEnable) & 1) != 0;
|
||||||
|
|
||||||
Gpu.Renderer.Rasterizer.SetClearStencil(ClearStencil);
|
State.StencilClear = ReadRegister(NvGpuEngine3dReg.ClearStencil);
|
||||||
|
|
||||||
bool Enable = (ReadRegister(NvGpuEngine3dReg.StencilEnable) & 1) != 0;
|
if (State.StencilTestEnabled)
|
||||||
|
|
||||||
if (Enable)
|
|
||||||
{
|
{
|
||||||
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()
|
private void SetAlphaBlending()
|
||||||
{
|
{
|
||||||
//TODO: Support independent blend properly.
|
//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();
|
State.BlendSeparateAlpha = (ReadRegister(NvGpuEngine3dReg.IBlendNSeparateAlpha) & 1) != 0;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Gpu.Renderer.Blend.Disable();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Enable)
|
State.BlendEquationRgb = (GalBlendEquation)ReadRegister(NvGpuEngine3dReg.IBlendNEquationRgb);
|
||||||
{
|
State.BlendFuncSrcRgb = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncSrcRgb);
|
||||||
//If blend is not enabled, then the other values have no effect.
|
State.BlendFuncDstRgb = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncDstRgb);
|
||||||
//Note that if it is disabled, the register may contain invalid values.
|
State.BlendEquationAlpha = (GalBlendEquation)ReadRegister(NvGpuEngine3dReg.IBlendNEquationAlpha);
|
||||||
return;
|
State.BlendFuncSrcAlpha = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncSrcAlpha);
|
||||||
}
|
State.BlendFuncDstAlpha = (GalBlendFactor)ReadRegister(NvGpuEngine3dReg.IBlendNFuncDstAlpha);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetPrimitiveRestart()
|
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)
|
private void UploadTextures(NvGpuVmm Vmm, long[] Keys)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue