forked from Mirror/Ryujinx
GL: Implement more Point parameters (#1399)
* Fix GL_INVALID_VALUE on glPointSize calls * Implement more of Point primitive state * Use existing Origin enum
This commit is contained in:
parent
1c84b683c2
commit
723ae240dc
5 changed files with 49 additions and 7 deletions
|
@ -50,7 +50,7 @@ namespace Ryujinx.Graphics.GAL
|
||||||
|
|
||||||
void SetOrigin(Origin origin);
|
void SetOrigin(Origin origin);
|
||||||
|
|
||||||
void SetPointSize(float size);
|
void SetPointParameters(float size, bool isProgramPointSize, bool enablePointSprite, Origin origin);
|
||||||
|
|
||||||
void SetPrimitiveRestart(bool enable, int index);
|
void SetPrimitiveRestart(bool enable, int index);
|
||||||
|
|
||||||
|
|
|
@ -224,9 +224,12 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
UpdateVertexAttribState(state);
|
UpdateVertexAttribState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.QueryModified(MethodOffset.PointSize))
|
if (state.QueryModified(MethodOffset.PointSize,
|
||||||
|
MethodOffset.VertexProgramPointSize,
|
||||||
|
MethodOffset.PointSpriteEnable,
|
||||||
|
MethodOffset.PointCoordReplace))
|
||||||
{
|
{
|
||||||
UpdatePointSizeState(state);
|
UpdatePointState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.QueryModified(MethodOffset.PrimitiveRestartState))
|
if (state.QueryModified(MethodOffset.PrimitiveRestartState))
|
||||||
|
@ -703,11 +706,16 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||||
/// Updates host point size based on guest GPU state.
|
/// Updates host point size based on guest GPU state.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="state">Current GPU state</param>
|
/// <param name="state">Current GPU state</param>
|
||||||
private void UpdatePointSizeState(GpuState state)
|
private void UpdatePointState(GpuState state)
|
||||||
{
|
{
|
||||||
float size = state.Get<float>(MethodOffset.PointSize);
|
float size = state.Get<float>(MethodOffset.PointSize);
|
||||||
|
bool isProgramPointSize = state.Get<Boolean32>(MethodOffset.VertexProgramPointSize);
|
||||||
|
bool enablePointSprite = state.Get<Boolean32>(MethodOffset.PointSpriteEnable);
|
||||||
|
|
||||||
|
// TODO: Need to figure out a way to map PointCoordReplace enable bit.
|
||||||
|
Origin origin = (state.Get<int>(MethodOffset.PointCoordReplace) & 4) == 0 ? Origin.LowerLeft : Origin.UpperLeft;
|
||||||
|
|
||||||
_context.Renderer.Pipeline.SetPointSize(size);
|
_context.Renderer.Pipeline.SetPointParameters(size, isProgramPointSize, enablePointSprite, origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -173,6 +173,11 @@ namespace Ryujinx.Graphics.Gpu.State
|
||||||
{
|
{
|
||||||
Set(MethodOffset.BlendState, index, BlendState.Default);
|
Set(MethodOffset.BlendState, index, BlendState.Default);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Default Point Parameters
|
||||||
|
memory[(int)MethodOffset.PointSpriteEnable] = 1;
|
||||||
|
memory[(int)MethodOffset.PointSize] = 0x3F800000; // 1.0f
|
||||||
|
memory[(int)MethodOffset.PointCoordReplace] = 0x8; // Enable
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -73,6 +73,7 @@ namespace Ryujinx.Graphics.Gpu.State
|
||||||
FirstInstance = 0x50e,
|
FirstInstance = 0x50e,
|
||||||
ClipDistanceEnable = 0x544,
|
ClipDistanceEnable = 0x544,
|
||||||
PointSize = 0x546,
|
PointSize = 0x546,
|
||||||
|
PointSpriteEnable = 0x548,
|
||||||
ResetCounter = 0x54c,
|
ResetCounter = 0x54c,
|
||||||
RtDepthStencilEnable = 0x54e,
|
RtDepthStencilEnable = 0x54e,
|
||||||
ConditionState = 0x554,
|
ConditionState = 0x554,
|
||||||
|
@ -84,6 +85,7 @@ namespace Ryujinx.Graphics.Gpu.State
|
||||||
RtMsaaMode = 0x574,
|
RtMsaaMode = 0x574,
|
||||||
VbElementU32 = 0x57a,
|
VbElementU32 = 0x57a,
|
||||||
VbElementU16 = 0x57c,
|
VbElementU16 = 0x57c,
|
||||||
|
PointCoordReplace = 0x581,
|
||||||
ShaderBaseAddress = 0x582,
|
ShaderBaseAddress = 0x582,
|
||||||
DrawEnd = 0x585,
|
DrawEnd = 0x585,
|
||||||
DrawBegin = 0x586,
|
DrawBegin = 0x586,
|
||||||
|
@ -92,6 +94,7 @@ namespace Ryujinx.Graphics.Gpu.State
|
||||||
IndexBufferCount = 0x5f8,
|
IndexBufferCount = 0x5f8,
|
||||||
DepthBiasClamp = 0x61f,
|
DepthBiasClamp = 0x61f,
|
||||||
VertexBufferInstanced = 0x620,
|
VertexBufferInstanced = 0x620,
|
||||||
|
VertexProgramPointSize = 0x644,
|
||||||
FaceState = 0x646,
|
FaceState = 0x646,
|
||||||
ViewportTransformEnable = 0x64b,
|
ViewportTransformEnable = 0x64b,
|
||||||
ViewVolumeClipControl = 0x64f,
|
ViewVolumeClipControl = 0x64f,
|
||||||
|
|
|
@ -700,9 +700,35 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
SetOrigin(clipOrigin);
|
SetOrigin(clipOrigin);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPointSize(float size)
|
public void SetPointParameters(float size, bool isProgramPointSize, bool enablePointSprite, Origin origin)
|
||||||
{
|
{
|
||||||
GL.PointSize(size);
|
// GL_POINT_SPRITE was deprecated in core profile 3.2+ and causes GL_INVALID_ENUM when set.
|
||||||
|
// As we don't know if the current context is core or compat, it's safer to keep this code.
|
||||||
|
if (enablePointSprite)
|
||||||
|
{
|
||||||
|
GL.Enable(EnableCap.PointSprite);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GL.Disable(EnableCap.PointSprite);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isProgramPointSize)
|
||||||
|
{
|
||||||
|
GL.Enable(EnableCap.ProgramPointSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GL.Disable(EnableCap.ProgramPointSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
GL.PointParameter(origin == Origin.LowerLeft
|
||||||
|
? PointSpriteCoordOriginParameter.LowerLeft
|
||||||
|
: PointSpriteCoordOriginParameter.UpperLeft);
|
||||||
|
|
||||||
|
// Games seem to set point size to 0 which generates a GL_INVALID_VALUE
|
||||||
|
// From the spec, GL_INVALID_VALUE is generated if size is less than or equal to 0.
|
||||||
|
GL.PointSize(Math.Max(float.Epsilon, size));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPrimitiveRestart(bool enable, int index)
|
public void SetPrimitiveRestart(bool enable, int index)
|
||||||
|
|
Loading…
Reference in a new issue