diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2022-08-04 18:30:08 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-08-04 21:30:08 +0000 |
| commit | 1080f64df9abd7af7ed762668e4fc9a300ae30f2 (patch) | |
| tree | dc6c882fe3254c9966b916f29e3783de0c61f2b2 /Ryujinx.Graphics.Gpu/Engine | |
| parent | c48a75979fad2cf7909f128e265086ff83c2ba55 (diff) | |
Implement HLE macros for render target clears (#3528)
* Implement HLE macros for render target clears
* Add constants for the offsets
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Engine')
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Engine/MME/MacroHLE.cs | 35 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Engine/MME/MacroHLEFunctionName.cs | 2 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Engine/MME/MacroHLETable.cs | 9 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs | 20 | ||||
| -rw-r--r-- | Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs | 11 |
5 files changed, 72 insertions, 5 deletions
diff --git a/Ryujinx.Graphics.Gpu/Engine/MME/MacroHLE.cs b/Ryujinx.Graphics.Gpu/Engine/MME/MacroHLE.cs index 05f3df0e..5f238a71 100644 --- a/Ryujinx.Graphics.Gpu/Engine/MME/MacroHLE.cs +++ b/Ryujinx.Graphics.Gpu/Engine/MME/MacroHLE.cs @@ -12,6 +12,10 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME /// </summary> class MacroHLE : IMacroEE { + private const int ColorLayerCountOffset = 0x818; + private const int ColorStructSize = 0x40; + private const int ZetaLayerCountOffset = 0x1230; + private readonly GPFifoProcessor _processor; private readonly MacroHLEFunctionName _functionName; @@ -45,6 +49,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME { switch (_functionName) { + case MacroHLEFunctionName.ClearColor: + ClearColor(state, arg0); + break; + case MacroHLEFunctionName.ClearDepthStencil: + ClearDepthStencil(state, arg0); + break; case MacroHLEFunctionName.MultiDrawElementsIndirectCount: MultiDrawElementsIndirectCount(state, arg0); break; @@ -54,6 +64,31 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME } /// <summary> + /// Clears one bound color target. + /// </summary> + /// <param name="state">GPU state at the time of the call</param> + /// <param name="arg0">First argument of the call</param> + private void ClearColor(IDeviceState state, int arg0) + { + int index = (arg0 >> 6) & 0xf; + int layerCount = state.Read(ColorLayerCountOffset + index * ColorStructSize); + + _processor.ThreedClass.Clear(arg0, layerCount); + } + + /// <summary> + /// Clears the current depth-stencil target. + /// </summary> + /// <param name="state">GPU state at the time of the call</param> + /// <param name="arg0">First argument of the call</param> + private void ClearDepthStencil(IDeviceState state, int arg0) + { + int layerCount = state.Read(ZetaLayerCountOffset); + + _processor.ThreedClass.Clear(arg0, layerCount); + } + + /// <summary> /// Performs a indirect multi-draw, with parameters from a GPU buffer. /// </summary> /// <param name="state">GPU state at the time of the call</param> diff --git a/Ryujinx.Graphics.Gpu/Engine/MME/MacroHLEFunctionName.cs b/Ryujinx.Graphics.Gpu/Engine/MME/MacroHLEFunctionName.cs index 60354a9b..4cce07fa 100644 --- a/Ryujinx.Graphics.Gpu/Engine/MME/MacroHLEFunctionName.cs +++ b/Ryujinx.Graphics.Gpu/Engine/MME/MacroHLEFunctionName.cs @@ -6,6 +6,8 @@ enum MacroHLEFunctionName { None, + ClearColor, + ClearDepthStencil, MultiDrawElementsIndirectCount } } diff --git a/Ryujinx.Graphics.Gpu/Engine/MME/MacroHLETable.cs b/Ryujinx.Graphics.Gpu/Engine/MME/MacroHLETable.cs index 77d041ad..c5d98848 100644 --- a/Ryujinx.Graphics.Gpu/Engine/MME/MacroHLETable.cs +++ b/Ryujinx.Graphics.Gpu/Engine/MME/MacroHLETable.cs @@ -46,12 +46,19 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME private static readonly TableEntry[] Table = new TableEntry[] { + new TableEntry(MacroHLEFunctionName.ClearColor, new Hash128(0xA9FB28D1DC43645A, 0xB177E5D2EAE67FB0), 0x28), + new TableEntry(MacroHLEFunctionName.ClearDepthStencil, new Hash128(0x1B96CB77D4879F4F, 0x8557032FE0C965FB), 0x24), new TableEntry(MacroHLEFunctionName.MultiDrawElementsIndirectCount, new Hash128(0x890AF57ED3FB1C37, 0x35D0C95C61F5386F), 0x19C) }; private static bool IsMacroHLESupported(Capabilities caps, MacroHLEFunctionName name) { - if (name == MacroHLEFunctionName.MultiDrawElementsIndirectCount) + if (name == MacroHLEFunctionName.ClearColor || + name == MacroHLEFunctionName.ClearDepthStencil) + { + return true; + } + else if (name == MacroHLEFunctionName.MultiDrawElementsIndirectCount) { return caps.SupportsIndirectParameters; } diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs index e6a64205..0791feef 100644 --- a/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs +++ b/Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs @@ -487,12 +487,24 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed /// <summary> /// Clears the current color and depth-stencil buffers. - /// Which buffers should be cleared is also specified on the argument. + /// Which buffers should be cleared can also be specified with the argument. /// </summary> /// <param name="engine">3D engine where this method is being called</param> /// <param name="argument">Method call argument</param> public void Clear(ThreedClass engine, int argument) { + Clear(engine, argument, 1); + } + + /// <summary> + /// Clears the current color and depth-stencil buffers. + /// Which buffers should be cleared can also specified with the arguments. + /// </summary> + /// <param name="engine">3D engine where this method is being called</param> + /// <param name="argument">Method call argument</param> + /// <param name="layerCount">For array and 3D textures, indicates how many layers should be cleared</param> + public void Clear(ThreedClass engine, int argument, int layerCount) + { ConditionalRenderEnabled renderEnable = ConditionalRendering.GetRenderEnable( _context, _channel.MemoryManager, @@ -507,7 +519,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed int index = (argument >> 6) & 0xf; int layer = (argument >> 10) & 0x3ff; - engine.UpdateRenderTargetState(useControl: false, layered: layer != 0, singleUse: index); + engine.UpdateRenderTargetState(useControl: false, layered: layer != 0 || layerCount > 1, singleUse: index); // If there is a mismatch on the host clip region and the one explicitly defined by the guest // on the screen scissor state, then we need to force only one texture to be bound to avoid @@ -578,7 +590,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed bool clearDepth = (argument & 1) != 0; bool clearStencil = (argument & 2) != 0; - uint componentMask = (uint)((argument >> 2) & 0xf); if (componentMask != 0) @@ -587,7 +598,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed ColorF color = new ColorF(clearColor.Red, clearColor.Green, clearColor.Blue, clearColor.Alpha); - _context.Renderer.Pipeline.ClearRenderTargetColor(index, layer, componentMask, color); + _context.Renderer.Pipeline.ClearRenderTargetColor(index, layer, layerCount, componentMask, color); } if (clearDepth || clearStencil) @@ -609,6 +620,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed _context.Renderer.Pipeline.ClearRenderTargetDepthStencil( layer, + layerCount, depthValue, clearDepth, stencilValue, diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs index 95763910..8e222e71 100644 --- a/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs +++ b/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs @@ -498,6 +498,17 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed } /// <summary> + /// Clears the current color and depth-stencil buffers. + /// Which buffers should be cleared can also specified with the arguments. + /// </summary> + /// <param name="argument">Method call argument</param> + /// <param name="layerCount">For array and 3D textures, indicates how many layers should be cleared</param> + public void Clear(int argument, int layerCount) + { + _drawManager.Clear(this, argument, layerCount); + } + + /// <summary> /// Performs a indirect multi-draw, with parameters from a GPU buffer. /// </summary> /// <param name="indexCount">Index Buffer Count</param> |
