Add GalPipelineState and IGalPipeline

This commit is contained in:
ReinUsesLisp 2018-07-19 02:51:50 -03:00
parent eeb626947e
commit 06ac1a2b06
10 changed files with 345 additions and 358 deletions

View 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;
}
}

View file

@ -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);
}
}

View file

@ -0,0 +1,7 @@
namespace Ryujinx.Graphics.Gal
{
public interface IGalPipeline
{
void Bind(ref GalPipelineState State);
}
}

View file

@ -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);

View file

@ -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; }
}
}

View file

@ -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));
}
}
}

View 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);
}
}
}
}

View file

@ -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();

View file

@ -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>();

View file

@ -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)