Implement SULD shader instruction (#1117)

* Implement SULD shader instruction

* Some nits
This commit is contained in:
gdkchan 2020-04-21 20:35:28 -03:00 committed by GitHub
parent 4738113f29
commit 03711dd7b5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 620 additions and 109 deletions

View file

@ -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>Texture descriptor</returns>
private TextureDescriptor GetTextureDescriptor(GpuState state, int stageIndex, int index)
/// <returns>The texture format</returns>
private TextureFormat QueryGraphicsTextureFormat(GpuState state, int stageIndex, int index)
{
return _context.Methods.TextureManager.GetGraphicsTextureDescriptor(state, stageIndex, 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 GetGraphicsTextureDescriptor(GpuState state, int stageIndex, int handle)
{
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
};
}