Simple GPU fixes ()

* 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
Ryujinx.Graphics.GAL
Ryujinx.Graphics.Gpu
Ryujinx.Graphics.OpenGL

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

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

@ -108,6 +108,11 @@ namespace Ryujinx.Graphics.Gpu.Engine
UpdateShaderState(state);
}
if (state.QueryModified(MethodOffset.RasterizeEnable))
{
UpdateRasterizerState(state);
}
if (state.QueryModified(MethodOffset.RtColorState,
MethodOffset.RtDepthStencilState,
MethodOffset.RtControl,
@ -211,6 +216,16 @@ namespace Ryujinx.Graphics.Gpu.Engine
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>
/// Ensures that the bindings are visible to the host GPU.
/// Note: this actually performs the binding using the host graphics API.

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

@ -53,11 +53,11 @@ namespace Ryujinx.Graphics.Gpu.State
public static TableItem[] Table = new TableItem[]
{
new TableItem(MethodOffset.RtColorState, typeof(RtColorState), 8),
new TableItem(MethodOffset.ViewportTransform, typeof(ViewportTransform), 8),
new TableItem(MethodOffset.ViewportExtents, typeof(ViewportExtents), 8),
new TableItem(MethodOffset.ViewportTransform, typeof(ViewportTransform), Constants.TotalViewports),
new TableItem(MethodOffset.ViewportExtents, typeof(ViewportExtents), Constants.TotalViewports),
new TableItem(MethodOffset.VertexBufferDrawState, typeof(VertexBufferDrawState), 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.RtDepthStencilState, typeof(RtDepthStencilState), 1),
new TableItem(MethodOffset.VertexAttribState, typeof(VertexAttribState), 16),

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

@ -10,6 +10,8 @@ namespace Ryujinx.Graphics.OpenGL
{
private Program _program;
private bool _rasterizerDiscard;
private VertexArray _vertexArray;
private Framebuffer _framebuffer;
@ -31,14 +33,13 @@ namespace Ryujinx.Graphics.OpenGL
private uint[] _componentMasks;
private readonly bool[] _scissorEnable;
private bool _scissor0Enable = false;
internal Pipeline()
{
_rasterizerDiscard = false;
_clipOrigin = ClipOrigin.LowerLeft;
_clipDepthMode = ClipDepthMode.NegativeOneToOne;
_scissorEnable = new bool[8];
}
public void Barrier()
@ -644,6 +645,20 @@ namespace Ryujinx.Graphics.OpenGL
_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)
{
_componentMasks = (uint[])componentMasks.Clone();
@ -697,7 +712,10 @@ namespace Ryujinx.Graphics.OpenGL
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)
@ -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, index);
}
GL.Enable(IndexedEnableCap.ScissorTest, 0);
}
}
public void RestoreRasterizerDiscard()
{
if (_rasterizerDiscard)
{
GL.Enable(EnableCap.RasterizerDiscard);
}
}

@ -41,7 +41,8 @@ namespace Ryujinx.Graphics.OpenGL
GL.ReadBuffer(ReadBufferMode.ColorAttachment0);
GL.DrawBuffer(DrawBufferMode.ColorAttachment0);
GL.Disable(EnableCap.ScissorTest);
GL.Disable(EnableCap.RasterizerDiscard);
GL.Disable(IndexedEnableCap.ScissorTest, 0);
GL.BlitFramebuffer(
srcRegion.X1,
@ -58,7 +59,8 @@ namespace Ryujinx.Graphics.OpenGL
GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, oldReadFramebufferHandle);
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)

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