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:
mageven 2020-07-21 06:29:13 +05:30 committed by GitHub
parent 1c84b683c2
commit 723ae240dc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 49 additions and 7 deletions

View file

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

View file

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

View file

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

View file

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

View file

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