diff options
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs')
-rw-r--r-- | Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs | 141 |
1 files changed, 109 insertions, 32 deletions
diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs index 5a659f55..cd14259a 100644 --- a/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs +++ b/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs @@ -98,7 +98,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed /// <param name="argument">Method call argument</param> public void DrawEnd(ThreedClass engine, int argument) { - DrawEnd(engine, _state.State.IndexBufferState.First, (int)_state.State.IndexBufferCount); + DrawEnd( + engine, + _state.State.IndexBufferState.First, + (int)_state.State.IndexBufferCount, + _state.State.VertexBufferDrawState.First, + _state.State.VertexBufferDrawState.Count); } /// <summary> @@ -108,7 +113,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed /// <param name="engine">3D engine where this method is being called</param> /// <param name="firstIndex">Index of the first index buffer element used on the draw</param> /// <param name="indexCount">Number of index buffer elements used on the draw</param> - private void DrawEnd(ThreedClass engine, int firstIndex, int indexCount) + /// <param name="drawFirstVertex">Index of the first vertex used on the draw</param> + /// <param name="drawVertexCount">Number of vertices used on the draw</param> + private void DrawEnd(ThreedClass engine, int firstIndex, int indexCount, int drawFirstVertex, int drawVertexCount) { ConditionalRenderEnabled renderEnable = ConditionalRendering.GetRenderEnable( _context, @@ -195,7 +202,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed { var drawState = _state.State.VertexBufferDrawState; - _context.Renderer.Pipeline.Draw(drawState.Count, 1, drawState.First, firstInstance); + _context.Renderer.Pipeline.Draw(drawVertexCount, 1, drawFirstVertex, firstInstance); } _drawState.DrawIndexed = false; @@ -216,16 +223,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed bool incrementInstance = (argument & (1 << 26)) != 0; bool resetInstance = (argument & (1 << 27)) == 0; - if (_state.State.PrimitiveTypeOverrideEnable) - { - PrimitiveTypeOverride typeOverride = _state.State.PrimitiveTypeOverride; - DrawBegin(incrementInstance, resetInstance, typeOverride.Convert()); - } - else - { - PrimitiveType type = (PrimitiveType)(argument & 0xffff); - DrawBegin(incrementInstance, resetInstance, type.Convert()); - } + PrimitiveType type = (PrimitiveType)(argument & 0xffff); + DrawBegin(incrementInstance, resetInstance, type); } /// <summary> @@ -234,8 +233,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed /// </summary> /// <param name="incrementInstance">Indicates if the current instance should be incremented</param> /// <param name="resetInstance">Indicates if the current instance should be set to zero</param> - /// <param name="topology">Primitive topology</param> - private void DrawBegin(bool incrementInstance, bool resetInstance, PrimitiveTopology topology) + /// <param name="primitiveType">Primitive type</param> + private void DrawBegin(bool incrementInstance, bool resetInstance, PrimitiveType primitiveType) { if (incrementInstance) { @@ -248,6 +247,18 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed _instanceIndex = 0; } + PrimitiveTopology topology; + + if (_state.State.PrimitiveTypeOverrideEnable) + { + PrimitiveTypeOverride typeOverride = _state.State.PrimitiveTypeOverride; + topology = typeOverride.Convert(); + } + else + { + topology = primitiveType.Convert(); + } + UpdateTopology(topology); } @@ -276,46 +287,70 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed _drawState.DrawIndexed = true; } + // TODO: Verify if the index type is implied from the method that is called, + // or if it uses the state index type on hardware. + /// <summary> - /// Performs a indexed draw with a low number of index buffer elements. + /// Performs a indexed draw with 8-bit index buffer elements. /// </summary> /// <param name="engine">3D engine where this method is being called</param> /// <param name="argument">Method call argument</param> - public void DrawIndexedSmall(ThreedClass engine, int argument) + public void DrawIndexBuffer8BeginEndInstanceFirst(ThreedClass engine, int argument) { - DrawIndexedSmall(engine, argument, false); + DrawIndexBufferBeginEndInstance(engine, argument, false); } /// <summary> - /// Performs a indexed draw with a low number of index buffer elements. + /// Performs a indexed draw with 16-bit index buffer elements. /// </summary> /// <param name="engine">3D engine where this method is being called</param> /// <param name="argument">Method call argument</param> - public void DrawIndexedSmall2(ThreedClass engine, int argument) + public void DrawIndexBuffer16BeginEndInstanceFirst(ThreedClass engine, int argument) { - DrawIndexedSmall(engine, argument); + DrawIndexBufferBeginEndInstance(engine, argument, false); } /// <summary> - /// Performs a indexed draw with a low number of index buffer elements, + /// Performs a indexed draw with 32-bit index buffer elements. + /// </summary> + /// <param name="engine">3D engine where this method is being called</param> + /// <param name="argument">Method call argument</param> + public void DrawIndexBuffer32BeginEndInstanceFirst(ThreedClass engine, int argument) + { + DrawIndexBufferBeginEndInstance(engine, argument, false); + } + + /// <summary> + /// Performs a indexed draw with 8-bit index buffer elements, /// while also pre-incrementing the current instance value. /// </summary> /// <param name="engine">3D engine where this method is being called</param> /// <param name="argument">Method call argument</param> - public void DrawIndexedSmallIncInstance(ThreedClass engine, int argument) + public void DrawIndexBuffer8BeginEndInstanceSubsequent(ThreedClass engine, int argument) { - DrawIndexedSmall(engine, argument, true); + DrawIndexBufferBeginEndInstance(engine, argument, true); } /// <summary> - /// Performs a indexed draw with a low number of index buffer elements, + /// Performs a indexed draw with 16-bit index buffer elements, + /// while also pre-incrementing the current instance value. + /// </summary> + /// <param name="engine">3D engine where this method is being called</param> + /// <param name="argument">Method call argument</param> + public void DrawIndexBuffer16BeginEndInstanceSubsequent(ThreedClass engine, int argument) + { + DrawIndexBufferBeginEndInstance(engine, argument, true); + } + + /// <summary> + /// Performs a indexed draw with 32-bit index buffer elements, /// while also pre-incrementing the current instance value. /// </summary> /// <param name="engine">3D engine where this method is being called</param> /// <param name="argument">Method call argument</param> - public void DrawIndexedSmallIncInstance2(ThreedClass engine, int argument) + public void DrawIndexBuffer32BeginEndInstanceSubsequent(ThreedClass engine, int argument) { - DrawIndexedSmallIncInstance(engine, argument); + DrawIndexBufferBeginEndInstance(engine, argument, true); } /// <summary> @@ -325,11 +360,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed /// <param name="engine">3D engine where this method is being called</param> /// <param name="argument">Method call argument</param> /// <param name="instanced">True to increment the current instance value, false otherwise</param> - private void DrawIndexedSmall(ThreedClass engine, int argument, bool instanced) + private void DrawIndexBufferBeginEndInstance(ThreedClass engine, int argument, bool instanced) { - PrimitiveTypeOverride typeOverride = _state.State.PrimitiveTypeOverride; - - DrawBegin(instanced, !instanced, typeOverride.Convert()); + DrawBegin(instanced, !instanced, (PrimitiveType)((argument >> 28) & 0xf)); int firstIndex = argument & 0xffff; int indexCount = (argument >> 16) & 0xfff; @@ -339,7 +372,51 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed _drawState.DrawIndexed = true; engine.ForceStateDirty(IndexBufferCountMethodOffset * 4); - DrawEnd(engine, firstIndex, indexCount); + DrawEnd(engine, firstIndex, indexCount, 0, 0); + + _drawState.DrawIndexed = oldDrawIndexed; + } + + /// <summary> + /// Performs a non-indexed draw with the specified topology, index and count. + /// </summary> + /// <param name="engine">3D engine where this method is being called</param> + /// <param name="argument">Method call argument</param> + public void DrawVertexArrayBeginEndInstanceFirst(ThreedClass engine, int argument) + { + DrawVertexArrayBeginEndInstance(engine, argument, false); + } + + /// <summary> + /// Performs a non-indexed draw with the specified topology, index and count, + /// while incrementing the current instance. + /// </summary> + /// <param name="engine">3D engine where this method is being called</param> + /// <param name="argument">Method call argument</param> + public void DrawVertexArrayBeginEndInstanceSubsequent(ThreedClass engine, int argument) + { + DrawVertexArrayBeginEndInstance(engine, argument, true); + } + + /// <summary> + /// Performs a indexed draw with a low number of index buffer elements, + /// while optionally also pre-incrementing the current instance value. + /// </summary> + /// <param name="engine">3D engine where this method is being called</param> + /// <param name="argument">Method call argument</param> + /// <param name="instanced">True to increment the current instance value, false otherwise</param> + private void DrawVertexArrayBeginEndInstance(ThreedClass engine, int argument, bool instanced) + { + DrawBegin(instanced, !instanced, (PrimitiveType)((argument >> 28) & 0xf)); + + int firstVertex = argument & 0xffff; + int vertexCount = (argument >> 16) & 0xfff; + + bool oldDrawIndexed = _drawState.DrawIndexed; + + _drawState.DrawIndexed = false; + + DrawEnd(engine, 0, 0, firstVertex, vertexCount); _drawState.DrawIndexed = oldDrawIndexed; } |