aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Gpu
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.Gpu')
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/Compute/ComputeClass.cs3
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs31
-rw-r--r--Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs53
-rw-r--r--Ryujinx.Graphics.Gpu/Shader/Cache/CacheHelper.cs21
-rw-r--r--Ryujinx.Graphics.Gpu/Shader/Cache/Definition/GuestGpuAccessorHeader.cs7
-rw-r--r--Ryujinx.Graphics.Gpu/Shader/CachedGpuAccessor.cs27
-rw-r--r--Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs23
-rw-r--r--Ryujinx.Graphics.Gpu/Shader/GpuAccessorState.cs11
-rw-r--r--Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs2
9 files changed, 169 insertions, 9 deletions
diff --git a/Ryujinx.Graphics.Gpu/Engine/Compute/ComputeClass.cs b/Ryujinx.Graphics.Gpu/Engine/Compute/ComputeClass.cs
index 8469f1ae..00015c40 100644
--- a/Ryujinx.Graphics.Gpu/Engine/Compute/ComputeClass.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/Compute/ComputeClass.cs
@@ -129,7 +129,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
_state.State.SetTexHeaderPoolCMaximumIndex,
_state.State.SetBindlessTextureConstantBufferSlotSelect,
false,
- PrimitiveTopology.Points);
+ PrimitiveTopology.Points,
+ default);
ShaderBundle cs = memoryManager.Physical.ShaderCache.GetComputeShader(
_channel,
diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs
index f9d16803..4a5633c9 100644
--- a/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/Threed/StateUpdater.cs
@@ -72,6 +72,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
nameof(ThreedClassState.VertexBufferState),
nameof(ThreedClassState.VertexBufferEndAddress)),
+ new StateUpdateCallbackEntry(UpdateTessellationState,
+ nameof(ThreedClassState.TessOuterLevel),
+ nameof(ThreedClassState.TessInnerLevel),
+ nameof(ThreedClassState.PatchVertices)),
+
new StateUpdateCallbackEntry(UpdateTfBufferState, nameof(ThreedClassState.TfBufferState)),
new StateUpdateCallbackEntry(UpdateUserClipState, nameof(ThreedClassState.ClipDistanceEnable)),
@@ -100,6 +105,10 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
nameof(ThreedClassState.ViewportExtents),
nameof(ThreedClassState.YControl)),
+ new StateUpdateCallbackEntry(UpdatePolygonMode,
+ nameof(ThreedClassState.PolygonModeFront),
+ nameof(ThreedClassState.PolygonModeBack)),
+
new StateUpdateCallbackEntry(UpdateDepthBiasState,
nameof(ThreedClassState.DepthBiasState),
nameof(ThreedClassState.DepthBiasFactor),
@@ -260,6 +269,17 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
}
/// <summary>
+ /// Updates tessellation state based on the guest GPU state.
+ /// </summary>
+ private void UpdateTessellationState()
+ {
+ _context.Renderer.Pipeline.SetPatchParameters(
+ _state.State.PatchVertices,
+ _state.State.TessOuterLevel.ToSpan(),
+ _state.State.TessInnerLevel.ToSpan());
+ }
+
+ /// <summary>
/// Updates transform feedback buffer state based on the guest GPU state.
/// </summary>
private void UpdateTfBufferState()
@@ -545,6 +565,14 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
}
/// <summary>
+ /// Updates polygon mode state based on current GPU state.
+ /// </summary>
+ private void UpdatePolygonMode()
+ {
+ _context.Renderer.Pipeline.SetPolygonMode(_state.State.PolygonModeFront, _state.State.PolygonModeBack);
+ }
+
+ /// <summary>
/// Updates host depth bias (also called polygon offset) state based on current GPU state.
/// </summary>
private void UpdateDepthBiasState()
@@ -949,7 +977,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
_state.State.TexturePoolState.MaximumId,
(int)_state.State.TextureBufferIndex,
_state.State.EarlyZForce,
- _drawState.Topology);
+ _drawState.Topology,
+ _state.State.TessMode);
ShaderBundle gs = _channel.MemoryManager.Physical.ShaderCache.GetGraphicsShader(ref _state.State, _channel, gas, addresses);
diff --git a/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs b/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs
index a6392e3d..58bc0957 100644
--- a/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs
+++ b/Ryujinx.Graphics.Gpu/Engine/Threed/ThreedClassState.cs
@@ -3,6 +3,7 @@ using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Gpu.Engine.InlineToMemory;
using Ryujinx.Graphics.Gpu.Engine.Types;
using Ryujinx.Graphics.Gpu.Image;
+using Ryujinx.Graphics.Shader;
using System;
namespace Ryujinx.Graphics.Gpu.Engine.Threed
@@ -20,6 +21,43 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
}
/// <summary>
+ /// Tessellation mode.
+ /// </summary>
+ struct TessMode
+ {
+#pragma warning disable CS0649
+ public uint Packed;
+#pragma warning restore CS0649
+
+ /// <summary>
+ /// Unpacks the tessellation abstract patch type.
+ /// </summary>
+ /// <returns>Abtract patch type</returns>
+ public TessPatchType UnpackPatchType()
+ {
+ return (TessPatchType)(Packed & 3);
+ }
+
+ /// <summary>
+ /// Unpacks the spacing between tessellated vertices of the patch.
+ /// </summary>
+ /// <returns>Spacing between tessellated vertices</returns>
+ public TessSpacing UnpackSpacing()
+ {
+ return (TessSpacing)((Packed >> 4) & 3);
+ }
+
+ /// <summary>
+ /// Unpacks the primitive winding order.
+ /// </summary>
+ /// <returns>True if clockwise, false if counter-clockwise</returns>
+ public bool UnpackCw()
+ {
+ return (Packed & (1 << 8)) != 0;
+ }
+ }
+
+ /// <summary>
/// Transform feedback buffer state.
/// </summary>
struct TfBufferState
@@ -661,7 +699,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
public Boolean32 EarlyZForce;
public fixed uint Reserved214[45];
public uint SyncpointAction;
- public fixed uint Reserved2CC[44];
+ public fixed uint Reserved2CC[21];
+ public TessMode TessMode;
+ public Array4<float> TessOuterLevel;
+ public Array2<float> TessInnerLevel;
+ public fixed uint Reserved33C[16];
public Boolean32 RasterizeEnable;
public Array4<TfBufferState> TfBufferState;
public fixed uint Reserved400[192];
@@ -679,9 +721,14 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
public float ClearDepthValue;
public fixed uint ReservedD94[3];
public uint ClearStencilValue;
- public fixed uint ReservedDA4[7];
+ public fixed uint ReservedDA4[2];
+ public PolygonMode PolygonModeFront;
+ public PolygonMode PolygonModeBack;
+ public Boolean32 PolygonSmoothEnable;
+ public fixed uint ReservedDB8[2];
public DepthBiasState DepthBiasState;
- public fixed uint ReservedDCC[5];
+ public int PatchVertices;
+ public fixed uint ReservedDD0[4];
public uint TextureBarrier;
public fixed uint ReservedDE4[7];
public Array16<ScissorState> ScissorState;
diff --git a/Ryujinx.Graphics.Gpu/Shader/Cache/CacheHelper.cs b/Ryujinx.Graphics.Gpu/Shader/Cache/CacheHelper.cs
index 33da42db..09107346 100644
--- a/Ryujinx.Graphics.Gpu/Shader/Cache/CacheHelper.cs
+++ b/Ryujinx.Graphics.Gpu/Shader/Cache/CacheHelper.cs
@@ -350,6 +350,26 @@ namespace Ryujinx.Graphics.Gpu.Shader.Cache
}
/// <summary>
+ /// Packs the tessellation parameters from the gpu accessor.
+ /// </summary>
+ /// <param name="gpuAccessor">The gpu accessor</param>
+ /// <returns>The packed tessellation parameters</returns>
+ private static byte GetTessellationModePacked(IGpuAccessor gpuAccessor)
+ {
+ byte value;
+
+ value = (byte)((int)gpuAccessor.QueryTessPatchType() & 3);
+ value |= (byte)(((int)gpuAccessor.QueryTessSpacing() & 3) << 2);
+
+ if (gpuAccessor.QueryTessCw())
+ {
+ value |= 0x10;
+ }
+
+ return value;
+ }
+
+ /// <summary>
/// Create a new instance of <see cref="GuestGpuAccessorHeader"/> from an gpu accessor.
/// </summary>
/// <param name="gpuAccessor">The gpu accessor</param>
@@ -364,6 +384,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.Cache
ComputeLocalMemorySize = gpuAccessor.QueryComputeLocalMemorySize(),
ComputeSharedMemorySize = gpuAccessor.QueryComputeSharedMemorySize(),
PrimitiveTopology = gpuAccessor.QueryPrimitiveTopology(),
+ TessellationModePacked = GetTessellationModePacked(gpuAccessor),
StateFlags = GetGpuStateFlags(gpuAccessor)
};
}
diff --git a/Ryujinx.Graphics.Gpu/Shader/Cache/Definition/GuestGpuAccessorHeader.cs b/Ryujinx.Graphics.Gpu/Shader/Cache/Definition/GuestGpuAccessorHeader.cs
index 610b2da1..2e044750 100644
--- a/Ryujinx.Graphics.Gpu/Shader/Cache/Definition/GuestGpuAccessorHeader.cs
+++ b/Ryujinx.Graphics.Gpu/Shader/Cache/Definition/GuestGpuAccessorHeader.cs
@@ -50,9 +50,14 @@ namespace Ryujinx.Graphics.Gpu.Shader.Cache.Definition
public InputTopology PrimitiveTopology;
/// <summary>
+ /// Tessellation parameters (packed to fit on a byte).
+ /// </summary>
+ public byte TessellationModePacked;
+
+ /// <summary>
/// Unused/reserved.
/// </summary>
- public ushort Reserved2;
+ public byte Reserved2;
/// <summary>
/// GPU boolean state that can influence shader compilation.
diff --git a/Ryujinx.Graphics.Gpu/Shader/CachedGpuAccessor.cs b/Ryujinx.Graphics.Gpu/Shader/CachedGpuAccessor.cs
index 3a52b2fe..21d08823 100644
--- a/Ryujinx.Graphics.Gpu/Shader/CachedGpuAccessor.cs
+++ b/Ryujinx.Graphics.Gpu/Shader/CachedGpuAccessor.cs
@@ -135,6 +135,33 @@ namespace Ryujinx.Graphics.Gpu.Shader
}
/// <summary>
+ /// Queries the tessellation evaluation shader primitive winding order.
+ /// </summary>
+ /// <returns>True if the primitive winding order is clockwise, false if counter-clockwise</returns>
+ public bool QueryTessCw()
+ {
+ return (_header.TessellationModePacked & 0x10) != 0;
+ }
+
+ /// <summary>
+ /// Queries the tessellation evaluation shader abstract patch type.
+ /// </summary>
+ /// <returns>Abstract patch type</returns>
+ public TessPatchType QueryTessPatchType()
+ {
+ return (TessPatchType)(_header.TessellationModePacked & 3);
+ }
+
+ /// <summary>
+ /// Queries the tessellation evaluation shader spacing between tessellated vertices of the patch.
+ /// </summary>
+ /// <returns>Spacing between tessellated vertices of the patch</returns>
+ public TessSpacing QueryTessSpacing()
+ {
+ return (TessSpacing)((_header.TessellationModePacked >> 2) & 3);
+ }
+
+ /// <summary>
/// Gets the texture descriptor for a given texture on the pool.
/// </summary>
/// <param name="handle">Index of the texture (this is the word offset of the handle in the constant buffer)</param>
diff --git a/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs b/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs
index 50e24b97..64604a99 100644
--- a/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs
+++ b/Ryujinx.Graphics.Gpu/Shader/GpuAccessor.cs
@@ -168,11 +168,32 @@ namespace Ryujinx.Graphics.Gpu.Shader
PrimitiveTopology.TriangleFan => InputTopology.Triangles,
PrimitiveTopology.TrianglesAdjacency or
PrimitiveTopology.TriangleStripAdjacency => InputTopology.TrianglesAdjacency,
- _ => InputTopology.Points,
+ PrimitiveTopology.Patches => _state.TessellationMode.UnpackPatchType() == TessPatchType.Isolines
+ ? InputTopology.Lines
+ : InputTopology.Triangles,
+ _ => InputTopology.Points
};
}
/// <summary>
+ /// Queries the tessellation evaluation shader primitive winding order.
+ /// </summary>
+ /// <returns>True if the primitive winding order is clockwise, false if counter-clockwise</returns>
+ public bool QueryTessCw() => _state.TessellationMode.UnpackCw();
+
+ /// <summary>
+ /// Queries the tessellation evaluation shader abstract patch type.
+ /// </summary>
+ /// <returns>Abstract patch type</returns>
+ public TessPatchType QueryTessPatchType() => _state.TessellationMode.UnpackPatchType();
+
+ /// <summary>
+ /// Queries the tessellation evaluation shader spacing between tessellated vertices of the patch.
+ /// </summary>
+ /// <returns>Spacing between tessellated vertices of the patch</returns>
+ public TessSpacing QueryTessSpacing() => _state.TessellationMode.UnpackSpacing();
+
+ /// <summary>
/// Gets the texture descriptor for a given texture on the pool.
/// </summary>
/// <param name="handle">Index of the texture (this is the word offset of the handle in the constant buffer)</param>
diff --git a/Ryujinx.Graphics.Gpu/Shader/GpuAccessorState.cs b/Ryujinx.Graphics.Gpu/Shader/GpuAccessorState.cs
index 8d817113..ebbf3b69 100644
--- a/Ryujinx.Graphics.Gpu/Shader/GpuAccessorState.cs
+++ b/Ryujinx.Graphics.Gpu/Shader/GpuAccessorState.cs
@@ -1,4 +1,5 @@
using Ryujinx.Graphics.GAL;
+using Ryujinx.Graphics.Gpu.Engine.Threed;
namespace Ryujinx.Graphics.Gpu.Shader
{
@@ -33,6 +34,11 @@ namespace Ryujinx.Graphics.Gpu.Shader
public PrimitiveTopology Topology { get; }
/// <summary>
+ /// Tessellation mode.
+ /// </summary>
+ public TessMode TessellationMode { get; }
+
+ /// <summary>
/// Creates a new instance of the GPU accessor state.
/// </summary>
/// <param name="texturePoolGpuVa">GPU virtual address of the texture pool</param>
@@ -40,18 +46,21 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// <param name="textureBufferIndex">Constant buffer slot where the texture handles are located</param>
/// <param name="earlyZForce">Early Z force enable</param>
/// <param name="topology">Primitive topology</param>
+ /// <param name="tessellationMode">Tessellation mode</param>
public GpuAccessorState(
ulong texturePoolGpuVa,
int texturePoolMaximumId,
int textureBufferIndex,
bool earlyZForce,
- PrimitiveTopology topology)
+ PrimitiveTopology topology,
+ TessMode tessellationMode)
{
TexturePoolGpuVa = texturePoolGpuVa;
TexturePoolMaximumId = texturePoolMaximumId;
TextureBufferIndex = textureBufferIndex;
EarlyZForce = earlyZForce;
Topology = topology;
+ TessellationMode = tessellationMode;
}
}
} \ No newline at end of file
diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
index e69e7dcb..f2180820 100644
--- a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
+++ b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
@@ -40,7 +40,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// <summary>
/// Version of the codegen (to be changed when codegen or guest format change).
/// </summary>
- private const ulong ShaderCodeGenVersion = 2702;
+ private const ulong ShaderCodeGenVersion = 2534;
// Progress reporting helpers
private volatile int _shaderCount;