Simple GPU fixes (#1093)

* Implement RasterizeEnable

* Match viewport count to hardware

* Simplify ScissorTest tracking around Blits

* Disable RasterizerDiscard around Blits and track its state

* Read RasterizeEnable reg as bool and add doc
This commit is contained in:
mageven 2020-04-07 14:49:45 +05:30 committed by GitHub
parent e99e6d0ad1
commit 468d8f841f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 66 additions and 18 deletions

View file

@ -48,6 +48,8 @@ namespace Ryujinx.Graphics.GAL
void SetProgram(IProgram program); void SetProgram(IProgram program);
void SetRasterizerDiscard(bool discard);
void SetRenderTargetColorMasks(uint[] componentMask); void SetRenderTargetColorMasks(uint[] componentMask);
void SetRenderTargets(ITexture[] colors, ITexture depthStencil); void SetRenderTargets(ITexture[] colors, ITexture depthStencil);

View file

@ -53,6 +53,6 @@ namespace Ryujinx.Graphics.Gpu
/// <summary> /// <summary>
/// Maximum number of viewports. /// Maximum number of viewports.
/// </summary> /// </summary>
public const int TotalViewports = 8; public const int TotalViewports = 16;
} }
} }

View file

@ -108,6 +108,11 @@ namespace Ryujinx.Graphics.Gpu.Engine
UpdateShaderState(state); UpdateShaderState(state);
} }
if (state.QueryModified(MethodOffset.RasterizeEnable))
{
UpdateRasterizerState(state);
}
if (state.QueryModified(MethodOffset.RtColorState, if (state.QueryModified(MethodOffset.RtColorState,
MethodOffset.RtDepthStencilState, MethodOffset.RtDepthStencilState,
MethodOffset.RtControl, MethodOffset.RtControl,
@ -211,6 +216,16 @@ namespace Ryujinx.Graphics.Gpu.Engine
CommitBindings(); CommitBindings();
} }
/// <summary>
/// Updates Rasterizer primitive discard state based on guest gpu state.
/// </summary>
/// <param name="state">Current GPU state</param>
private void UpdateRasterizerState(GpuState state)
{
Boolean32 enable = state.Get<Boolean32>(MethodOffset.RasterizeEnable);
_context.Renderer.Pipeline.SetRasterizerDiscard(!enable);
}
/// <summary> /// <summary>
/// Ensures that the bindings are visible to the host GPU. /// Ensures that the bindings are visible to the host GPU.
/// Note: this actually performs the binding using the host graphics API. /// Note: this actually performs the binding using the host graphics API.

View file

@ -117,6 +117,9 @@ namespace Ryujinx.Graphics.Gpu.State
/// </summary> /// </summary>
private void InitializeDefaultState() private void InitializeDefaultState()
{ {
// Enable Rasterizer
_backingMemory[(int)MethodOffset.RasterizeEnable] = 1;
// Depth ranges. // Depth ranges.
for (int index = 0; index < 8; index++) for (int index = 0; index < 8; index++)
{ {

View file

@ -53,11 +53,11 @@ namespace Ryujinx.Graphics.Gpu.State
public static TableItem[] Table = new TableItem[] public static TableItem[] Table = new TableItem[]
{ {
new TableItem(MethodOffset.RtColorState, typeof(RtColorState), 8), new TableItem(MethodOffset.RtColorState, typeof(RtColorState), 8),
new TableItem(MethodOffset.ViewportTransform, typeof(ViewportTransform), 8), new TableItem(MethodOffset.ViewportTransform, typeof(ViewportTransform), Constants.TotalViewports),
new TableItem(MethodOffset.ViewportExtents, typeof(ViewportExtents), 8), new TableItem(MethodOffset.ViewportExtents, typeof(ViewportExtents), Constants.TotalViewports),
new TableItem(MethodOffset.VertexBufferDrawState, typeof(VertexBufferDrawState), 1), new TableItem(MethodOffset.VertexBufferDrawState, typeof(VertexBufferDrawState), 1),
new TableItem(MethodOffset.DepthBiasState, typeof(DepthBiasState), 1), new TableItem(MethodOffset.DepthBiasState, typeof(DepthBiasState), 1),
new TableItem(MethodOffset.ScissorState, typeof(ScissorState), 8), new TableItem(MethodOffset.ScissorState, typeof(ScissorState), Constants.TotalViewports),
new TableItem(MethodOffset.StencilBackMasks, typeof(StencilBackMasks), 1), new TableItem(MethodOffset.StencilBackMasks, typeof(StencilBackMasks), 1),
new TableItem(MethodOffset.RtDepthStencilState, typeof(RtDepthStencilState), 1), new TableItem(MethodOffset.RtDepthStencilState, typeof(RtDepthStencilState), 1),
new TableItem(MethodOffset.VertexAttribState, typeof(VertexAttribState), 16), new TableItem(MethodOffset.VertexAttribState, typeof(VertexAttribState), 16),

View file

@ -16,6 +16,7 @@ namespace Ryujinx.Graphics.Gpu.State
DispatchParamsAddress = 0xad, DispatchParamsAddress = 0xad,
Dispatch = 0xaf, Dispatch = 0xaf,
CopyBuffer = 0xc0, CopyBuffer = 0xc0,
RasterizeEnable = 0xdf,
CopyBufferParams = 0x100, CopyBufferParams = 0x100,
CopyBufferSwizzle = 0x1c2, CopyBufferSwizzle = 0x1c2,
CopyBufferDstTexture = 0x1c3, CopyBufferDstTexture = 0x1c3,

View file

@ -10,6 +10,8 @@ namespace Ryujinx.Graphics.OpenGL
{ {
private Program _program; private Program _program;
private bool _rasterizerDiscard;
private VertexArray _vertexArray; private VertexArray _vertexArray;
private Framebuffer _framebuffer; private Framebuffer _framebuffer;
@ -31,14 +33,13 @@ namespace Ryujinx.Graphics.OpenGL
private uint[] _componentMasks; private uint[] _componentMasks;
private readonly bool[] _scissorEnable; private bool _scissor0Enable = false;
internal Pipeline() internal Pipeline()
{ {
_rasterizerDiscard = false;
_clipOrigin = ClipOrigin.LowerLeft; _clipOrigin = ClipOrigin.LowerLeft;
_clipDepthMode = ClipDepthMode.NegativeOneToOne; _clipDepthMode = ClipDepthMode.NegativeOneToOne;
_scissorEnable = new bool[8];
} }
public void Barrier() public void Barrier()
@ -644,6 +645,20 @@ namespace Ryujinx.Graphics.OpenGL
_program.Bind(); _program.Bind();
} }
public void SetRasterizerDiscard(bool discard)
{
if (discard)
{
GL.Enable(EnableCap.RasterizerDiscard);
}
else
{
GL.Disable(EnableCap.RasterizerDiscard);
}
_rasterizerDiscard = discard;
}
public void SetRenderTargetColorMasks(uint[] componentMasks) public void SetRenderTargetColorMasks(uint[] componentMasks)
{ {
_componentMasks = (uint[])componentMasks.Clone(); _componentMasks = (uint[])componentMasks.Clone();
@ -697,7 +712,10 @@ namespace Ryujinx.Graphics.OpenGL
GL.Disable(IndexedEnableCap.ScissorTest, index); GL.Disable(IndexedEnableCap.ScissorTest, index);
} }
_scissorEnable[index] = enable; if (index == 0)
{
_scissor0Enable = enable;
}
} }
public void SetScissor(int index, int x, int y, int width, int height) public void SetScissor(int index, int x, int y, int width, int height)
@ -959,14 +977,19 @@ namespace Ryujinx.Graphics.OpenGL
} }
} }
public void RestoreScissorEnable() public void RestoreScissor0Enable()
{ {
for (int index = 0; index < 8; index++) if (_scissor0Enable)
{ {
if (_scissorEnable[index]) GL.Enable(IndexedEnableCap.ScissorTest, 0);
{ }
GL.Enable(IndexedEnableCap.ScissorTest, index); }
}
public void RestoreRasterizerDiscard()
{
if (_rasterizerDiscard)
{
GL.Enable(EnableCap.RasterizerDiscard);
} }
} }

View file

@ -41,7 +41,8 @@ namespace Ryujinx.Graphics.OpenGL
GL.ReadBuffer(ReadBufferMode.ColorAttachment0); GL.ReadBuffer(ReadBufferMode.ColorAttachment0);
GL.DrawBuffer(DrawBufferMode.ColorAttachment0); GL.DrawBuffer(DrawBufferMode.ColorAttachment0);
GL.Disable(EnableCap.ScissorTest); GL.Disable(EnableCap.RasterizerDiscard);
GL.Disable(IndexedEnableCap.ScissorTest, 0);
GL.BlitFramebuffer( GL.BlitFramebuffer(
srcRegion.X1, srcRegion.X1,
@ -58,7 +59,8 @@ namespace Ryujinx.Graphics.OpenGL
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, oldReadFramebufferHandle); GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, oldReadFramebufferHandle);
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, oldDrawFramebufferHandle); GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, oldDrawFramebufferHandle);
((Pipeline)_renderer.Pipeline).RestoreScissorEnable(); ((Pipeline)_renderer.Pipeline).RestoreScissor0Enable();
((Pipeline)_renderer.Pipeline).RestoreRasterizerDiscard();
} }
private static void Attach(FramebufferTarget target, Format format, int handle) private static void Attach(FramebufferTarget target, Format format, int handle)

View file

@ -59,7 +59,8 @@ namespace Ryujinx.Graphics.OpenGL
GL.ReadBuffer(ReadBufferMode.ColorAttachment0); GL.ReadBuffer(ReadBufferMode.ColorAttachment0);
GL.Disable(EnableCap.ScissorTest); GL.Disable(EnableCap.RasterizerDiscard);
GL.Disable(IndexedEnableCap.ScissorTest, 0);
GL.Clear(ClearBufferMask.ColorBufferBit); GL.Clear(ClearBufferMask.ColorBufferBit);
@ -126,7 +127,8 @@ namespace Ryujinx.Graphics.OpenGL
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, oldReadFramebufferHandle); GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, oldReadFramebufferHandle);
GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, oldDrawFramebufferHandle); GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, oldDrawFramebufferHandle);
((Pipeline)_renderer.Pipeline).RestoreScissorEnable(); ((Pipeline)_renderer.Pipeline).RestoreScissor0Enable();
((Pipeline)_renderer.Pipeline).RestoreRasterizerDiscard();
} }
private int GetCopyFramebufferHandleLazy() private int GetCopyFramebufferHandleLazy()