aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2020-04-21 20:35:28 -0300
committerGitHub <noreply@github.com>2020-04-22 09:35:28 +1000
commit03711dd7b5d44e20fb45c728803ea6b9599dec87 (patch)
tree2930956a377d9f79df2750aa06ce1f1928cd30e6 /Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
parent4738113f293ac2477a553225a24b6c489c6855f1 (diff)
Implement SULD shader instruction (#1117)
* Implement SULD shader instruction * Some nits
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs')
-rw-r--r--Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs151
1 files changed, 132 insertions, 19 deletions
diff --git a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
index 7ad00f32..6bbc3b11 100644
--- a/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
+++ b/Ryujinx.Graphics.Gpu/Shader/ShaderCache.cs
@@ -50,6 +50,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// <remarks>
/// This automatically translates, compiles and adds the code to the cache if not present.
/// </remarks>
+ /// <param name="state">Current GPU state</param>
/// <param name="gpuVa">GPU virtual address of the binary shader code</param>
/// <param name="localSizeX">Local group size X of the computer shader</param>
/// <param name="localSizeY">Local group size Y of the computer shader</param>
@@ -58,6 +59,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// <param name="sharedMemorySize">Shared memory size of the compute shader</param>
/// <returns>Compiled compute shader code</returns>
public ComputeShader GetComputeShader(
+ GpuState state,
ulong gpuVa,
int localSizeX,
int localSizeY,
@@ -79,6 +81,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
}
CachedShader shader = TranslateComputeShader(
+ state,
gpuVa,
localSizeX,
localSizeY,
@@ -241,6 +244,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// <summary>
/// Translates the binary Maxwell shader code to something that the host API accepts.
/// </summary>
+ /// <param name="state">Current GPU state</param>
/// <param name="gpuVa">GPU virtual address of the binary shader code</param>
/// <param name="localSizeX">Local group size X of the computer shader</param>
/// <param name="localSizeY">Local group size Y of the computer shader</param>
@@ -249,6 +253,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// <param name="sharedMemorySize">Shared memory size of the compute shader</param>
/// <returns>Compiled compute shader code</returns>
private CachedShader TranslateComputeShader(
+ GpuState state,
ulong gpuVa,
int localSizeX,
int localSizeY,
@@ -265,12 +270,20 @@ namespace Ryujinx.Graphics.Gpu.Shader
{
return info switch
{
- QueryInfoName.ComputeLocalSizeX => localSizeX,
- QueryInfoName.ComputeLocalSizeY => localSizeY,
- QueryInfoName.ComputeLocalSizeZ => localSizeZ,
- QueryInfoName.ComputeLocalMemorySize => localMemorySize,
- QueryInfoName.ComputeSharedMemorySize => sharedMemorySize,
- _ => QueryInfoCommon(info)
+ QueryInfoName.ComputeLocalSizeX
+ => localSizeX,
+ QueryInfoName.ComputeLocalSizeY
+ => localSizeY,
+ QueryInfoName.ComputeLocalSizeZ
+ => localSizeZ,
+ QueryInfoName.ComputeLocalMemorySize
+ => localMemorySize,
+ QueryInfoName.ComputeSharedMemorySize
+ => sharedMemorySize,
+ QueryInfoName.TextureFormat
+ => (int)QueryComputeTextureFormat(state, index),
+ _
+ => QueryInfoCommon(info)
};
}
@@ -317,10 +330,16 @@ namespace Ryujinx.Graphics.Gpu.Shader
{
return info switch
{
- QueryInfoName.IsTextureBuffer => Convert.ToInt32(QueryIsTextureBuffer(state, (int)stage - 1, index)),
- QueryInfoName.IsTextureRectangle => Convert.ToInt32(QueryIsTextureRectangle(state, (int)stage - 1, index)),
- QueryInfoName.PrimitiveTopology => (int)GetPrimitiveTopology(),
- _ => QueryInfoCommon(info)
+ QueryInfoName.IsTextureBuffer
+ => Convert.ToInt32(QueryIsTextureBuffer(state, (int)stage - 1, index)),
+ QueryInfoName.IsTextureRectangle
+ => Convert.ToInt32(QueryIsTextureRectangle(state, (int)stage - 1, index)),
+ QueryInfoName.PrimitiveTopology
+ => (int)QueryPrimitiveTopology(),
+ QueryInfoName.TextureFormat
+ => (int)QueryGraphicsTextureFormat(state, (int)stage - 1, index),
+ _
+ => QueryInfoCommon(info)
};
}
@@ -378,7 +397,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// This is required by geometry shaders.
/// </summary>
/// <returns>Primitive topology</returns>
- private InputTopology GetPrimitiveTopology()
+ private InputTopology QueryPrimitiveTopology()
{
switch (_context.Methods.PrimitiveType)
{
@@ -414,7 +433,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// <returns>True if the texture is a buffer texture, false otherwise</returns>
private bool QueryIsTextureBuffer(GpuState state, int stageIndex, int index)
{
- return GetTextureDescriptor(state, stageIndex, index).UnpackTextureTarget() == TextureTarget.TextureBuffer;
+ return GetGraphicsTextureDescriptor(state, stageIndex, index).UnpackTextureTarget() == TextureTarget.TextureBuffer;
}
/// <summary>
@@ -428,7 +447,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
/// <returns>True if the texture is a rectangle texture, false otherwise</returns>
private bool QueryIsTextureRectangle(GpuState state, int stageIndex, int index)
{
- var descriptor = GetTextureDescriptor(state, stageIndex, index);
+ var descriptor = GetGraphicsTextureDescriptor(state, stageIndex, index);
TextureTarget target = descriptor.UnpackTextureTarget();
@@ -439,15 +458,106 @@ namespace Ryujinx.Graphics.Gpu.Shader
}
/// <summary>
- /// Gets the texture descriptor for a given texture on the pool.
+ /// Queries the format of a given texture.
+ /// </summary>
+ /// <param name="state">Current GPU state</param>
+ /// <param name="index">Index of the texture (this is the shader "fake" handle)</param>
+ /// <returns>The texture format</returns>
+ private TextureFormat QueryComputeTextureFormat(GpuState state, int index)
+ {
+ return QueryTextureFormat(GetComputeTextureDescriptor(state, index));
+ }
+
+ /// <summary>
+ /// Queries the format of a given texture.
/// </summary>
/// <param name="state">Current GPU state</param>
/// <param name="stageIndex">Index of the shader stage</param>
/// <param name="index">Index of the texture (this is the shader "fake" handle)</param>
+ /// <returns>The texture format</returns>
+ private TextureFormat QueryGraphicsTextureFormat(GpuState state, int stageIndex, int index)
+ {
+ return QueryTextureFormat(GetGraphicsTextureDescriptor(state, stageIndex, index));
+ }
+
+ /// <summary>
+ /// Queries the format of a given texture.
+ /// </summary>
+ /// <param name="descriptor">Descriptor of the texture from the texture pool</param>
+ /// <returns>The texture format</returns>
+ private static TextureFormat QueryTextureFormat(TextureDescriptor descriptor)
+ {
+ if (!FormatTable.TryGetTextureFormat(descriptor.UnpackFormat(), descriptor.UnpackSrgb(), out FormatInfo formatInfo))
+ {
+ return TextureFormat.Unknown;
+ }
+
+ return formatInfo.Format switch
+ {
+ Format.R8Unorm => TextureFormat.R8Unorm,
+ Format.R8Snorm => TextureFormat.R8Snorm,
+ Format.R8Uint => TextureFormat.R8Uint,
+ Format.R8Sint => TextureFormat.R8Sint,
+ Format.R16Float => TextureFormat.R16Float,
+ Format.R16Unorm => TextureFormat.R16Unorm,
+ Format.R16Snorm => TextureFormat.R16Snorm,
+ Format.R16Uint => TextureFormat.R16Uint,
+ Format.R16Sint => TextureFormat.R16Sint,
+ Format.R32Float => TextureFormat.R32Float,
+ Format.R32Uint => TextureFormat.R32Uint,
+ Format.R32Sint => TextureFormat.R32Sint,
+ Format.R8G8Unorm => TextureFormat.R8G8Unorm,
+ Format.R8G8Snorm => TextureFormat.R8G8Snorm,
+ Format.R8G8Uint => TextureFormat.R8G8Uint,
+ Format.R8G8Sint => TextureFormat.R8G8Sint,
+ Format.R16G16Float => TextureFormat.R16G16Float,
+ Format.R16G16Unorm => TextureFormat.R16G16Unorm,
+ Format.R16G16Snorm => TextureFormat.R16G16Snorm,
+ Format.R16G16Uint => TextureFormat.R16G16Uint,
+ Format.R16G16Sint => TextureFormat.R16G16Sint,
+ Format.R32G32Float => TextureFormat.R32G32Float,
+ Format.R32G32Uint => TextureFormat.R32G32Uint,
+ Format.R32G32Sint => TextureFormat.R32G32Sint,
+ Format.R8G8B8A8Unorm => TextureFormat.R8G8B8A8Unorm,
+ Format.R8G8B8A8Snorm => TextureFormat.R8G8B8A8Snorm,
+ Format.R8G8B8A8Uint => TextureFormat.R8G8B8A8Uint,
+ Format.R8G8B8A8Sint => TextureFormat.R8G8B8A8Sint,
+ Format.R16G16B16A16Float => TextureFormat.R16G16B16A16Float,
+ Format.R16G16B16A16Unorm => TextureFormat.R16G16B16A16Unorm,
+ Format.R16G16B16A16Snorm => TextureFormat.R16G16B16A16Snorm,
+ Format.R16G16B16A16Uint => TextureFormat.R16G16B16A16Uint,
+ Format.R16G16B16A16Sint => TextureFormat.R16G16B16A16Sint,
+ Format.R32G32B32A32Float => TextureFormat.R32G32B32A32Float,
+ Format.R32G32B32A32Uint => TextureFormat.R32G32B32A32Uint,
+ Format.R32G32B32A32Sint => TextureFormat.R32G32B32A32Sint,
+ Format.R10G10B10A2Unorm => TextureFormat.R10G10B10A2Unorm,
+ Format.R10G10B10A2Uint => TextureFormat.R10G10B10A2Uint,
+ Format.R11G11B10Float => TextureFormat.R11G11B10Float,
+ _ => TextureFormat.Unknown
+ };
+ }
+
+ /// <summary>
+ /// Gets the texture descriptor for a given texture on the pool.
+ /// </summary>
+ /// <param name="state">Current GPU state</param>
+ /// <param name="handle">Index of the texture (this is the shader "fake" handle)</param>
+ /// <returns>Texture descriptor</returns>
+ private TextureDescriptor GetComputeTextureDescriptor(GpuState state, int handle)
+ {
+ return _context.Methods.TextureManager.GetComputeTextureDescriptor(state, handle);
+ }
+
+ /// <summary>
+ /// Gets the texture descriptor for a given texture on the pool.
+ /// </summary>
+ /// <param name="state">Current GPU state</param>
+ /// <param name="stageIndex">Index of the shader stage</param>
+ /// <param name="handle">Index of the texture (this is the shader "fake" handle)</param>
/// <returns>Texture descriptor</returns>
- private TextureDescriptor GetTextureDescriptor(GpuState state, int stageIndex, int index)
+ private TextureDescriptor GetGraphicsTextureDescriptor(GpuState state, int stageIndex, int handle)
{
- return _context.Methods.TextureManager.GetGraphicsTextureDescriptor(state, stageIndex, index);
+ return _context.Methods.TextureManager.GetGraphicsTextureDescriptor(state, stageIndex, handle);
}
/// <summary>
@@ -459,9 +569,12 @@ namespace Ryujinx.Graphics.Gpu.Shader
{
return info switch
{
- QueryInfoName.StorageBufferOffsetAlignment => _context.Capabilities.StorageBufferOffsetAlignment,
- QueryInfoName.SupportsNonConstantTextureOffset => Convert.ToInt32(_context.Capabilities.SupportsNonConstantTextureOffset),
- _ => 0
+ QueryInfoName.StorageBufferOffsetAlignment
+ => _context.Capabilities.StorageBufferOffsetAlignment,
+ QueryInfoName.SupportsNonConstantTextureOffset
+ => Convert.ToInt32(_context.Capabilities.SupportsNonConstantTextureOffset),
+ _
+ => 0
};
}