aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Gpu/Engine
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2022-08-04 18:30:08 -0300
committerGitHub <noreply@github.com>2022-08-04 21:30:08 +0000
commit1080f64df9abd7af7ed762668e4fc9a300ae30f2 (patch)
treedc6c882fe3254c9966b916f29e3783de0c61f2b2 /Ryujinx.Graphics.Gpu/Engine
parentc48a75979fad2cf7909f128e265086ff83c2ba55 (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.cs35
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/MME/MacroHLEFunctionName.cs2
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/MME/MacroHLETable.cs9
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/Threed/DrawManager.cs20
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClass.cs11
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>