From 8e1adb95cf7f67b976f105f4cac26d3ff2986057 Mon Sep 17 00:00:00 2001 From: mpnico Date: Thu, 26 Aug 2021 23:50:28 +0200 Subject: Add support for HLE macros and accelerate MultiDrawElementsIndirectCount #2 (#2557) * Add support for HLE macros and accelerate MultiDrawElementsIndirectCount * Add missing barrier * Fix index buffer count * Add support check for each macro hle before use * Add missing xml doc Co-authored-by: gdkchan --- Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs | 59 +++++++++++++++++++++++ Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs | 21 ++++++++ 2 files changed, 80 insertions(+) (limited to 'Ryujinx.Graphics.Gpu/Engine/Threed') diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs index d58f175d..2443917c 100644 --- a/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs +++ b/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs @@ -26,6 +26,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed private int _instanceIndex; + private const int IndexBufferCountMethodOffset = 0x5f8; + /// /// Creates a new instance of the draw manager. /// @@ -304,6 +306,63 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed _drawState.DrawIndexed = oldDrawIndexed; } + /// + /// Performs a indirect multi-draw, with parameters from a GPU buffer. + /// + /// 3D engine where this method is being called + /// Primitive topology + /// GPU buffer with the draw parameters, such as count, first index, etc + /// GPU buffer with the draw count + /// Maximum number of draws that can be made + /// Distance in bytes between each element on the array + public void MultiDrawIndirectCount( + ThreedClass engine, + int indexCount, + PrimitiveTopology topology, + BufferRange indirectBuffer, + BufferRange parameterBuffer, + int maxDrawCount, + int stride) + { + engine.Write(IndexBufferCountMethodOffset * 4, indexCount); + + _context.Renderer.Pipeline.SetPrimitiveTopology(topology); + _drawState.Topology = topology; + + ConditionalRenderEnabled renderEnable = ConditionalRendering.GetRenderEnable( + _context, + _channel.MemoryManager, + _state.State.RenderEnableAddress, + _state.State.RenderEnableCondition); + + if (renderEnable == ConditionalRenderEnabled.False) + { + _drawState.DrawIndexed = false; + return; + } + + _drawState.FirstIndex = _state.State.IndexBufferState.First; + _drawState.IndexCount = indexCount; + + engine.UpdateState(); + + if (_drawState.DrawIndexed) + { + _context.Renderer.Pipeline.MultiDrawIndexedIndirectCount(indirectBuffer, parameterBuffer, maxDrawCount, stride); + } + else + { + _context.Renderer.Pipeline.MultiDrawIndirectCount(indirectBuffer, parameterBuffer, maxDrawCount, stride); + } + + _drawState.DrawIndexed = false; + + if (renderEnable == ConditionalRenderEnabled.Host) + { + _context.Renderer.Pipeline.EndHostConditionalRendering(); + } + } + /// /// Perform any deferred draws. /// This is used for instanced draws. diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs index 37c8fec2..3d02af96 100644 --- a/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs +++ b/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs @@ -1,4 +1,5 @@ using Ryujinx.Graphics.Device; +using Ryujinx.Graphics.GAL; using Ryujinx.Graphics.Gpu.Engine.InlineToMemory; using System; using System.Collections.Generic; @@ -433,5 +434,25 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed { return 0; } + + /// + /// Performs a indirect multi-draw, with parameters from a GPU buffer. + /// + /// Index Buffer Count + /// Primitive topology + /// GPU buffer with the draw parameters, such as count, first index, etc + /// GPU buffer with the draw count + /// Maximum number of draws that can be made + /// Distance in bytes between each element on the array + public void MultiDrawIndirectCount( + int indexCount, + PrimitiveTopology topology, + BufferRange indirectBuffer, + BufferRange parameterBuffer, + int maxDrawCount, + int stride) + { + _drawManager.MultiDrawIndirectCount(this, indexCount, topology, indirectBuffer, parameterBuffer, maxDrawCount, stride); + } } } -- cgit v1.2.3