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:
parent
e99e6d0ad1
commit
468d8f841f
9 changed files with 66 additions and 18 deletions
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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.
|
||||||
|
|
|
@ -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++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,15 +977,20 @@ 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in a new issue