Fix Geometry/TFB on compute, Buffer Textures, add Window Resizing (#28)
This commit is contained in:
parent
e02df72323
commit
edceb1607f
28 changed files with 280 additions and 92 deletions
18
src/Ryujinx.Graphics.GAL/ComputeSize.cs
Normal file
18
src/Ryujinx.Graphics.GAL/ComputeSize.cs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
namespace Ryujinx.Graphics.GAL
|
||||||
|
{
|
||||||
|
public readonly struct ComputeSize
|
||||||
|
{
|
||||||
|
public readonly static ComputeSize VtgAsCompute = new ComputeSize(32, 32, 1);
|
||||||
|
|
||||||
|
public readonly int X;
|
||||||
|
public readonly int Y;
|
||||||
|
public readonly int Z;
|
||||||
|
|
||||||
|
public ComputeSize(int x, int y, int z)
|
||||||
|
{
|
||||||
|
X = x;
|
||||||
|
Y = y;
|
||||||
|
Z = z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -339,6 +339,84 @@ namespace Ryujinx.Graphics.GAL
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get bytes per element for this format.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">Texture format</param>
|
||||||
|
/// <returns>Byte size for an element of this format (pixel, vertex attribute, etc)</returns>
|
||||||
|
public static int GetBytesPerElement(this Format format)
|
||||||
|
{
|
||||||
|
int scalarSize = format.GetScalarSize();
|
||||||
|
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case Format.R8G8Unorm:
|
||||||
|
case Format.R8G8Snorm:
|
||||||
|
case Format.R8G8Uint:
|
||||||
|
case Format.R8G8Sint:
|
||||||
|
case Format.R8G8Uscaled:
|
||||||
|
case Format.R8G8Sscaled:
|
||||||
|
case Format.R16G16Float:
|
||||||
|
case Format.R16G16Unorm:
|
||||||
|
case Format.R16G16Snorm:
|
||||||
|
case Format.R16G16Uint:
|
||||||
|
case Format.R16G16Sint:
|
||||||
|
case Format.R16G16Uscaled:
|
||||||
|
case Format.R16G16Sscaled:
|
||||||
|
case Format.R32G32Float:
|
||||||
|
case Format.R32G32Uint:
|
||||||
|
case Format.R32G32Sint:
|
||||||
|
case Format.R32G32Uscaled:
|
||||||
|
case Format.R32G32Sscaled:
|
||||||
|
return 2 * scalarSize;
|
||||||
|
|
||||||
|
case Format.R8G8B8Unorm:
|
||||||
|
case Format.R8G8B8Snorm:
|
||||||
|
case Format.R8G8B8Uint:
|
||||||
|
case Format.R8G8B8Sint:
|
||||||
|
case Format.R8G8B8Uscaled:
|
||||||
|
case Format.R8G8B8Sscaled:
|
||||||
|
case Format.R16G16B16Float:
|
||||||
|
case Format.R16G16B16Unorm:
|
||||||
|
case Format.R16G16B16Snorm:
|
||||||
|
case Format.R16G16B16Uint:
|
||||||
|
case Format.R16G16B16Sint:
|
||||||
|
case Format.R16G16B16Uscaled:
|
||||||
|
case Format.R16G16B16Sscaled:
|
||||||
|
case Format.R32G32B32Float:
|
||||||
|
case Format.R32G32B32Uint:
|
||||||
|
case Format.R32G32B32Sint:
|
||||||
|
case Format.R32G32B32Uscaled:
|
||||||
|
case Format.R32G32B32Sscaled:
|
||||||
|
return 3 * scalarSize;
|
||||||
|
|
||||||
|
case Format.R8G8B8A8Unorm:
|
||||||
|
case Format.R8G8B8A8Snorm:
|
||||||
|
case Format.R8G8B8A8Uint:
|
||||||
|
case Format.R8G8B8A8Sint:
|
||||||
|
case Format.R8G8B8A8Srgb:
|
||||||
|
case Format.R8G8B8A8Uscaled:
|
||||||
|
case Format.R8G8B8A8Sscaled:
|
||||||
|
case Format.B8G8R8A8Unorm:
|
||||||
|
case Format.B8G8R8A8Srgb:
|
||||||
|
case Format.R16G16B16A16Float:
|
||||||
|
case Format.R16G16B16A16Unorm:
|
||||||
|
case Format.R16G16B16A16Snorm:
|
||||||
|
case Format.R16G16B16A16Uint:
|
||||||
|
case Format.R16G16B16A16Sint:
|
||||||
|
case Format.R16G16B16A16Uscaled:
|
||||||
|
case Format.R16G16B16A16Sscaled:
|
||||||
|
case Format.R32G32B32A32Float:
|
||||||
|
case Format.R32G32B32A32Uint:
|
||||||
|
case Format.R32G32B32A32Sint:
|
||||||
|
case Format.R32G32B32A32Uscaled:
|
||||||
|
case Format.R32G32B32A32Sscaled:
|
||||||
|
return 4 * scalarSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return scalarSize;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if the texture format is a depth or depth-stencil format.
|
/// Checks if the texture format is a depth or depth-stencil format.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace Ryujinx.Graphics.GAL
|
||||||
|
|
||||||
void CopyBuffer(BufferHandle source, BufferHandle destination, int srcOffset, int dstOffset, int size);
|
void CopyBuffer(BufferHandle source, BufferHandle destination, int srcOffset, int dstOffset, int size);
|
||||||
|
|
||||||
void DispatchCompute(int groupsX, int groupsY, int groupsZ, int groupSizeX, int groupSizeY, int groupSizeZ);
|
void DispatchCompute(int groupsX, int groupsY, int groupsZ);
|
||||||
|
|
||||||
void Draw(int vertexCount, int instanceCount, int firstVertex, int firstInstance);
|
void Draw(int vertexCount, int instanceCount, int firstVertex, int firstInstance);
|
||||||
void DrawIndexed(
|
void DrawIndexed(
|
||||||
|
|
|
@ -6,23 +6,17 @@ namespace Ryujinx.Graphics.GAL.Multithreading.Commands
|
||||||
private int _groupsX;
|
private int _groupsX;
|
||||||
private int _groupsY;
|
private int _groupsY;
|
||||||
private int _groupsZ;
|
private int _groupsZ;
|
||||||
private int _groupSizeX;
|
|
||||||
private int _groupSizeY;
|
|
||||||
private int _groupSizeZ;
|
|
||||||
|
|
||||||
public void Set(int groupsX, int groupsY, int groupsZ, int groupSizeX, int groupSizeY, int groupSizeZ)
|
public void Set(int groupsX, int groupsY, int groupsZ)
|
||||||
{
|
{
|
||||||
_groupsX = groupsX;
|
_groupsX = groupsX;
|
||||||
_groupsY = groupsY;
|
_groupsY = groupsY;
|
||||||
_groupsZ = groupsZ;
|
_groupsZ = groupsZ;
|
||||||
_groupSizeX = groupSizeX;
|
|
||||||
_groupSizeY = groupSizeY;
|
|
||||||
_groupSizeZ = groupSizeZ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Run(ref DispatchComputeCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
public static void Run(ref DispatchComputeCommand command, ThreadedRenderer threaded, IRenderer renderer)
|
||||||
{
|
{
|
||||||
renderer.Pipeline.DispatchCompute(command._groupsX, command._groupsY, command._groupsZ, command._groupSizeX, command._groupSizeY, command._groupSizeZ);
|
renderer.Pipeline.DispatchCompute(command._groupsX, command._groupsY, command._groupsZ);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,9 +63,9 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DispatchCompute(int groupsX, int groupsY, int groupsZ, int groupSizeX, int groupSizeY, int groupSizeZ)
|
public void DispatchCompute(int groupsX, int groupsY, int groupsZ)
|
||||||
{
|
{
|
||||||
_renderer.New<DispatchComputeCommand>().Set(groupsX, groupsY, groupsZ, groupSizeX, groupSizeY, groupSizeZ);
|
_renderer.New<DispatchComputeCommand>().Set(groupsX, groupsY, groupsZ);
|
||||||
_renderer.QueueCommand();
|
_renderer.QueueCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,23 +4,22 @@ namespace Ryujinx.Graphics.GAL
|
||||||
{
|
{
|
||||||
public int FragmentOutputMap { get; }
|
public int FragmentOutputMap { get; }
|
||||||
public ResourceLayout ResourceLayout { get; }
|
public ResourceLayout ResourceLayout { get; }
|
||||||
|
public ComputeSize ComputeLocalSize { get; }
|
||||||
public ProgramPipelineState? State { get; }
|
public ProgramPipelineState? State { get; }
|
||||||
public bool FromCache { get; set; }
|
public bool FromCache { get; set; }
|
||||||
|
|
||||||
public ShaderInfo(int fragmentOutputMap, ResourceLayout resourceLayout, ProgramPipelineState state, bool fromCache = false)
|
public ShaderInfo(
|
||||||
|
int fragmentOutputMap,
|
||||||
|
ResourceLayout resourceLayout,
|
||||||
|
ComputeSize computeLocalSize,
|
||||||
|
ProgramPipelineState? state,
|
||||||
|
bool fromCache = false)
|
||||||
{
|
{
|
||||||
FragmentOutputMap = fragmentOutputMap;
|
FragmentOutputMap = fragmentOutputMap;
|
||||||
ResourceLayout = resourceLayout;
|
ResourceLayout = resourceLayout;
|
||||||
|
ComputeLocalSize = computeLocalSize;
|
||||||
State = state;
|
State = state;
|
||||||
FromCache = fromCache;
|
FromCache = fromCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ShaderInfo(int fragmentOutputMap, ResourceLayout resourceLayout, bool fromCache = false)
|
|
||||||
{
|
|
||||||
FragmentOutputMap = fragmentOutputMap;
|
|
||||||
ResourceLayout = resourceLayout;
|
|
||||||
State = null;
|
|
||||||
FromCache = fromCache;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,7 +200,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
||||||
|
|
||||||
_channel.BufferManager.CommitComputeBindings();
|
_channel.BufferManager.CommitComputeBindings();
|
||||||
|
|
||||||
_context.Renderer.Pipeline.DispatchCompute(qmd.CtaRasterWidth, qmd.CtaRasterHeight, qmd.CtaRasterDepth, qmd.CtaThreadDimension0, qmd.CtaThreadDimension1, qmd.CtaThreadDimension2);
|
_context.Renderer.Pipeline.DispatchCompute(qmd.CtaRasterWidth, qmd.CtaRasterHeight, qmd.CtaRasterDepth);
|
||||||
|
|
||||||
_3dEngine.ForceShaderUpdate();
|
_3dEngine.ForceShaderUpdate();
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
format.GetBytesPerElement(),
|
||||||
format,
|
format,
|
||||||
DepthStencilMode.Depth,
|
DepthStencilMode.Depth,
|
||||||
Target.TextureBuffer,
|
Target.TextureBuffer,
|
||||||
|
|
|
@ -211,10 +211,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
|
||||||
_context.Renderer.Pipeline.DispatchCompute(
|
_context.Renderer.Pipeline.DispatchCompute(
|
||||||
BitUtils.DivRoundUp(_count, ComputeLocalSize),
|
BitUtils.DivRoundUp(_count, ComputeLocalSize),
|
||||||
BitUtils.DivRoundUp(_instanceCount, ComputeLocalSize),
|
BitUtils.DivRoundUp(_instanceCount, ComputeLocalSize),
|
||||||
1,
|
1);
|
||||||
ComputeLocalSize,
|
|
||||||
ComputeLocalSize,
|
|
||||||
ComputeLocalSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -263,10 +260,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
|
||||||
_context.Renderer.Pipeline.DispatchCompute(
|
_context.Renderer.Pipeline.DispatchCompute(
|
||||||
BitUtils.DivRoundUp(primitivesCount, ComputeLocalSize),
|
BitUtils.DivRoundUp(primitivesCount, ComputeLocalSize),
|
||||||
BitUtils.DivRoundUp(_instanceCount, ComputeLocalSize),
|
BitUtils.DivRoundUp(_instanceCount, ComputeLocalSize),
|
||||||
_geometryAsCompute.Info.ThreadsPerInputPrimitive,
|
_geometryAsCompute.Info.ThreadsPerInputPrimitive);
|
||||||
ComputeLocalSize,
|
|
||||||
ComputeLocalSize,
|
|
||||||
ComputeLocalSize);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -392,7 +392,8 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
||||||
context,
|
context,
|
||||||
shaders,
|
shaders,
|
||||||
specState.PipelineState,
|
specState.PipelineState,
|
||||||
specState.TransformFeedbackDescriptors != null);
|
specState.TransformFeedbackDescriptors != null,
|
||||||
|
specState.ComputeState.GetLocalSize());
|
||||||
|
|
||||||
IProgram hostProgram;
|
IProgram hostProgram;
|
||||||
|
|
||||||
|
|
|
@ -490,7 +490,12 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
||||||
{
|
{
|
||||||
ShaderSource[] shaderSources = new ShaderSource[compilation.TranslatedStages.Length];
|
ShaderSource[] shaderSources = new ShaderSource[compilation.TranslatedStages.Length];
|
||||||
|
|
||||||
ShaderInfoBuilder shaderInfoBuilder = new(_context, compilation.SpecializationState.TransformFeedbackDescriptors != null);
|
ref GpuChannelComputeState computeState = ref compilation.SpecializationState.ComputeState;
|
||||||
|
|
||||||
|
ShaderInfoBuilder shaderInfoBuilder = new(
|
||||||
|
_context,
|
||||||
|
compilation.SpecializationState.TransformFeedbackDescriptors != null,
|
||||||
|
computeLocalSize: computeState.GetLocalSize());
|
||||||
|
|
||||||
for (int index = 0; index < compilation.TranslatedStages.Length; index++)
|
for (int index = 0; index < compilation.TranslatedStages.Length; index++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
using Ryujinx.Graphics.GAL;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Gpu.Shader
|
namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -61,5 +63,14 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
SharedMemorySize = sharedMemorySize;
|
SharedMemorySize = sharedMemorySize;
|
||||||
HasUnalignedStorageBuffer = hasUnalignedStorageBuffer;
|
HasUnalignedStorageBuffer = hasUnalignedStorageBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the local group size of the shader in a GAL compatible struct.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Local group size</returns>
|
||||||
|
public ComputeSize GetLocalSize()
|
||||||
|
{
|
||||||
|
return new ComputeSize(LocalSizeX, LocalSizeY, LocalSizeZ);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -224,7 +224,10 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
TranslatedShader translatedShader = TranslateShader(_dumper, channel, translatorContext, cachedGuestCode, asCompute: false);
|
TranslatedShader translatedShader = TranslateShader(_dumper, channel, translatorContext, cachedGuestCode, asCompute: false);
|
||||||
|
|
||||||
ShaderSource[] shaderSourcesArray = new ShaderSource[] { CreateShaderSource(translatedShader.Program) };
|
ShaderSource[] shaderSourcesArray = new ShaderSource[] { CreateShaderSource(translatedShader.Program) };
|
||||||
ShaderInfo info = ShaderInfoBuilder.BuildForCompute(_context, translatedShader.Program.Info);
|
ShaderInfo info = ShaderInfoBuilder.BuildForCompute(
|
||||||
|
_context,
|
||||||
|
translatedShader.Program.Info,
|
||||||
|
computeState.GetLocalSize());
|
||||||
IProgram hostProgram = _context.Renderer.CreateProgram(shaderSourcesArray, info);
|
IProgram hostProgram = _context.Renderer.CreateProgram(shaderSourcesArray, info);
|
||||||
|
|
||||||
cpShader = new CachedShaderProgram(hostProgram, specState, translatedShader.Shader);
|
cpShader = new CachedShaderProgram(hostProgram, specState, translatedShader.Shader);
|
||||||
|
|
|
@ -22,6 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
ResourceStages.Geometry;
|
ResourceStages.Geometry;
|
||||||
|
|
||||||
private readonly GpuContext _context;
|
private readonly GpuContext _context;
|
||||||
|
private readonly ComputeSize _computeLocalSize;
|
||||||
|
|
||||||
private int _fragmentOutputMap;
|
private int _fragmentOutputMap;
|
||||||
|
|
||||||
|
@ -39,9 +40,11 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
/// <param name="context">GPU context that owns the shaders that will be added to the builder</param>
|
/// <param name="context">GPU context that owns the shaders that will be added to the builder</param>
|
||||||
/// <param name="tfEnabled">Indicates if the graphics shader is used with transform feedback enabled</param>
|
/// <param name="tfEnabled">Indicates if the graphics shader is used with transform feedback enabled</param>
|
||||||
/// <param name="vertexAsCompute">Indicates that the vertex shader will be emulated on a compute shader</param>
|
/// <param name="vertexAsCompute">Indicates that the vertex shader will be emulated on a compute shader</param>
|
||||||
public ShaderInfoBuilder(GpuContext context, bool tfEnabled, bool vertexAsCompute = false)
|
/// <param name="computeLocalSize">Indicates the local thread size for a compute shader</param>
|
||||||
|
public ShaderInfoBuilder(GpuContext context, bool tfEnabled, bool vertexAsCompute = false, ComputeSize computeLocalSize = default)
|
||||||
{
|
{
|
||||||
_context = context;
|
_context = context;
|
||||||
|
_computeLocalSize = computeLocalSize;
|
||||||
|
|
||||||
_fragmentOutputMap = -1;
|
_fragmentOutputMap = -1;
|
||||||
|
|
||||||
|
@ -361,14 +364,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
|
|
||||||
ResourceLayout resourceLayout = new(descriptors.AsReadOnly(), usages.AsReadOnly());
|
ResourceLayout resourceLayout = new(descriptors.AsReadOnly(), usages.AsReadOnly());
|
||||||
|
|
||||||
if (pipeline.HasValue)
|
return new ShaderInfo(_fragmentOutputMap, resourceLayout, _computeLocalSize, pipeline, fromCache);
|
||||||
{
|
|
||||||
return new ShaderInfo(_fragmentOutputMap, resourceLayout, pipeline.Value, fromCache);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return new ShaderInfo(_fragmentOutputMap, resourceLayout, fromCache);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -378,14 +374,16 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
/// <param name="programs">Shaders from the disk cache</param>
|
/// <param name="programs">Shaders from the disk cache</param>
|
||||||
/// <param name="pipeline">Optional pipeline for background compilation</param>
|
/// <param name="pipeline">Optional pipeline for background compilation</param>
|
||||||
/// <param name="tfEnabled">Indicates if the graphics shader is used with transform feedback enabled</param>
|
/// <param name="tfEnabled">Indicates if the graphics shader is used with transform feedback enabled</param>
|
||||||
|
/// <param name="computeLocalSize">Compute local thread size</param>
|
||||||
/// <returns>Shader information</returns>
|
/// <returns>Shader information</returns>
|
||||||
public static ShaderInfo BuildForCache(
|
public static ShaderInfo BuildForCache(
|
||||||
GpuContext context,
|
GpuContext context,
|
||||||
IEnumerable<CachedShaderStage> programs,
|
IEnumerable<CachedShaderStage> programs,
|
||||||
ProgramPipelineState? pipeline,
|
ProgramPipelineState? pipeline,
|
||||||
bool tfEnabled)
|
bool tfEnabled,
|
||||||
|
ComputeSize computeLocalSize)
|
||||||
{
|
{
|
||||||
ShaderInfoBuilder builder = new(context, tfEnabled);
|
ShaderInfoBuilder builder = new(context, tfEnabled, computeLocalSize: computeLocalSize);
|
||||||
|
|
||||||
foreach (CachedShaderStage program in programs)
|
foreach (CachedShaderStage program in programs)
|
||||||
{
|
{
|
||||||
|
@ -403,11 +401,12 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="context">GPU context that owns the shader</param>
|
/// <param name="context">GPU context that owns the shader</param>
|
||||||
/// <param name="info">Compute shader information</param>
|
/// <param name="info">Compute shader information</param>
|
||||||
|
/// <param name="computeLocalSize">Compute local thread size</param>
|
||||||
/// <param name="fromCache">True if the compute shader comes from a disk cache, false otherwise</param>
|
/// <param name="fromCache">True if the compute shader comes from a disk cache, false otherwise</param>
|
||||||
/// <returns>Shader information</returns>
|
/// <returns>Shader information</returns>
|
||||||
public static ShaderInfo BuildForCompute(GpuContext context, ShaderProgramInfo info, bool fromCache = false)
|
public static ShaderInfo BuildForCompute(GpuContext context, ShaderProgramInfo info, ComputeSize computeLocalSize, bool fromCache = false)
|
||||||
{
|
{
|
||||||
ShaderInfoBuilder builder = new(context, tfEnabled: false, vertexAsCompute: false);
|
ShaderInfoBuilder builder = new(context, tfEnabled: false, vertexAsCompute: false, computeLocalSize: computeLocalSize);
|
||||||
|
|
||||||
builder.AddStageInfo(info);
|
builder.AddStageInfo(info);
|
||||||
|
|
||||||
|
@ -424,7 +423,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
/// <returns>Shader information</returns>
|
/// <returns>Shader information</returns>
|
||||||
public static ShaderInfo BuildForVertexAsCompute(GpuContext context, ShaderProgramInfo info, bool tfEnabled, bool fromCache = false)
|
public static ShaderInfo BuildForVertexAsCompute(GpuContext context, ShaderProgramInfo info, bool tfEnabled, bool fromCache = false)
|
||||||
{
|
{
|
||||||
ShaderInfoBuilder builder = new(context, tfEnabled, vertexAsCompute: true);
|
ShaderInfoBuilder builder = new(context, tfEnabled, vertexAsCompute: true, computeLocalSize: ComputeSize.VtgAsCompute);
|
||||||
|
|
||||||
builder.AddStageInfo(info, vertexAsCompute: true);
|
builder.AddStageInfo(info, vertexAsCompute: true);
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
public readonly PrimitiveTopology Topology => _currentState.Topology;
|
public readonly PrimitiveTopology Topology => _currentState.Topology;
|
||||||
public readonly Texture[] RenderTargets => _currentState.RenderTargets;
|
public readonly Texture[] RenderTargets => _currentState.RenderTargets;
|
||||||
public readonly Texture DepthStencil => _currentState.DepthStencil;
|
public readonly Texture DepthStencil => _currentState.DepthStencil;
|
||||||
|
public readonly ComputeSize ComputeLocalSize => _currentState.ComputeProgram.ComputeLocalSize;
|
||||||
|
|
||||||
// RGBA32F is the biggest format
|
// RGBA32F is the biggest format
|
||||||
private const int ZeroBufferSize = 4 * 4;
|
private const int ZeroBufferSize = 4 * 4;
|
||||||
|
@ -811,6 +812,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
Logger.Warning?.Print(LogClass.Gpu, $"Texture binding ({binding}) must be <= {Constants.MaxTexturesPerStage}");
|
Logger.Warning?.Print(LogClass.Gpu, $"Texture binding ({binding}) must be <= {Constants.MaxTexturesPerStage}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (stage)
|
switch (stage)
|
||||||
{
|
{
|
||||||
case ShaderStage.Fragment:
|
case ShaderStage.Fragment:
|
||||||
|
@ -852,10 +854,14 @@ namespace Ryujinx.Graphics.Metal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateTextureAndSampler(ShaderStage stage, ulong binding, TextureBase texture, MTLSamplerState sampler)
|
public void UpdateTextureAndSampler(ShaderStage stage, ulong binding, TextureBase texture, Sampler sampler)
|
||||||
{
|
{
|
||||||
UpdateTexture(stage, binding, texture);
|
UpdateTexture(stage, binding, texture);
|
||||||
UpdateSampler(stage, binding, sampler);
|
|
||||||
|
if (sampler != null)
|
||||||
|
{
|
||||||
|
UpdateSampler(stage, binding, sampler.GetSampler());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly void SetDepthStencilState(MTLRenderCommandEncoder renderCommandEncoder)
|
private readonly void SetDepthStencilState(MTLRenderCommandEncoder renderCommandEncoder)
|
||||||
|
|
|
@ -65,7 +65,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
_programStrideChange = new Program(
|
_programStrideChange = new Program(
|
||||||
[
|
[
|
||||||
new ShaderSource(strideChangeSource, ShaderStage.Compute, TargetLanguage.Msl)
|
new ShaderSource(strideChangeSource, ShaderStage.Compute, TargetLanguage.Msl)
|
||||||
], device);
|
], device, new ComputeSize(64, 1, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string ReadMsl(string fileName)
|
private static string ReadMsl(string fileName)
|
||||||
|
@ -260,7 +260,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
_pipeline.SetStorageBuffers(1, sbRanges);
|
_pipeline.SetStorageBuffers(1, sbRanges);
|
||||||
|
|
||||||
_pipeline.SetProgram(_programStrideChange);
|
_pipeline.SetProgram(_programStrideChange);
|
||||||
_pipeline.DispatchCompute(1 + elems / ConvertElementsPerWorkgroup, 1, 1, 64, 1, 1);
|
_pipeline.DispatchCompute(1 + elems / ConvertElementsPerWorkgroup, 1, 1);
|
||||||
|
|
||||||
// Restore previous state
|
// Restore previous state
|
||||||
_pipeline.SwapState(null);
|
_pipeline.SwapState(null);
|
||||||
|
|
|
@ -92,7 +92,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
public IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info)
|
public IProgram CreateProgram(ShaderSource[] shaders, ShaderInfo info)
|
||||||
{
|
{
|
||||||
return new Program(shaders, _device);
|
return new Program(shaders, _device, info.ComputeLocalSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ISampler CreateSampler(SamplerCreateInfo info)
|
public ISampler CreateSampler(SamplerCreateInfo info)
|
||||||
|
@ -104,7 +104,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
{
|
{
|
||||||
if (info.Target == Target.TextureBuffer)
|
if (info.Target == Target.TextureBuffer)
|
||||||
{
|
{
|
||||||
return new TextureBuffer(this, info);
|
return new TextureBuffer(_device, this, _pipeline, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Texture(_device, this, _pipeline, info);
|
return new Texture(_device, this, _pipeline, info);
|
||||||
|
|
|
@ -347,13 +347,15 @@ namespace Ryujinx.Graphics.Metal
|
||||||
BufferHolder.Copy(this, Cbs, srcBuffer, dstBuffer, srcOffset, dstOffset, size);
|
BufferHolder.Copy(this, Cbs, srcBuffer, dstBuffer, srcOffset, dstOffset, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DispatchCompute(int groupsX, int groupsY, int groupsZ, int groupSizeX, int groupSizeY, int groupSizeZ)
|
public void DispatchCompute(int groupsX, int groupsY, int groupsZ)
|
||||||
{
|
{
|
||||||
var computeCommandEncoder = GetOrCreateComputeEncoder(true);
|
var computeCommandEncoder = GetOrCreateComputeEncoder(true);
|
||||||
|
|
||||||
|
ComputeSize localSize = _encoderStateManager.ComputeLocalSize;
|
||||||
|
|
||||||
computeCommandEncoder.DispatchThreadgroups(
|
computeCommandEncoder.DispatchThreadgroups(
|
||||||
new MTLSize { width = (ulong)groupsX, height = (ulong)groupsY, depth = (ulong)groupsZ },
|
new MTLSize { width = (ulong)groupsX, height = (ulong)groupsY, depth = (ulong)groupsZ },
|
||||||
new MTLSize { width = (ulong)groupSizeX, height = (ulong)groupSizeY, depth = (ulong)groupSizeZ });
|
new MTLSize { width = (ulong)localSize.X, height = (ulong)localSize.Y, depth = (ulong)localSize.Z });
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Draw(int vertexCount, int instanceCount, int firstVertex, int firstInstance)
|
public void Draw(int vertexCount, int instanceCount, int firstVertex, int firstInstance)
|
||||||
|
@ -658,12 +660,11 @@ namespace Ryujinx.Graphics.Metal
|
||||||
{
|
{
|
||||||
if (texture is TextureBase tex)
|
if (texture is TextureBase tex)
|
||||||
{
|
{
|
||||||
if (sampler is Sampler samp)
|
if (sampler == null || sampler is Sampler)
|
||||||
{
|
{
|
||||||
var mtlSampler = samp.GetSampler();
|
|
||||||
var index = (ulong)binding;
|
var index = (ulong)binding;
|
||||||
|
|
||||||
_encoderStateManager.UpdateTextureAndSampler(stage, index, tex, mtlSampler);
|
_encoderStateManager.UpdateTextureAndSampler(stage, index, tex, (Sampler)sampler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,13 +15,16 @@ namespace Ryujinx.Graphics.Metal
|
||||||
public MTLFunction VertexFunction;
|
public MTLFunction VertexFunction;
|
||||||
public MTLFunction FragmentFunction;
|
public MTLFunction FragmentFunction;
|
||||||
public MTLFunction ComputeFunction;
|
public MTLFunction ComputeFunction;
|
||||||
|
public ComputeSize ComputeLocalSize { get; }
|
||||||
|
|
||||||
private HashTableSlim<PipelineUid, MTLRenderPipelineState> _graphicsPipelineCache;
|
private HashTableSlim<PipelineUid, MTLRenderPipelineState> _graphicsPipelineCache;
|
||||||
private MTLComputePipelineState? _computePipelineCache;
|
private MTLComputePipelineState? _computePipelineCache;
|
||||||
private bool _firstBackgroundUse;
|
private bool _firstBackgroundUse;
|
||||||
|
|
||||||
public Program(ShaderSource[] shaders, MTLDevice device)
|
public Program(ShaderSource[] shaders, MTLDevice device, ComputeSize computeLocalSize = default)
|
||||||
{
|
{
|
||||||
|
ComputeLocalSize = computeLocalSize;
|
||||||
|
|
||||||
for (int index = 0; index < shaders.Length; index++)
|
for (int index = 0; index < shaders.Length; index++)
|
||||||
{
|
{
|
||||||
ShaderSource shader = shaders[index];
|
ShaderSource shader = shaders[index];
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
|
using Ryujinx.Graphics.GAL;
|
||||||
using SharpMetal.Foundation;
|
using SharpMetal.Foundation;
|
||||||
using SharpMetal.Metal;
|
using SharpMetal.Metal;
|
||||||
using System;
|
using System;
|
||||||
|
@ -249,6 +250,27 @@ namespace Ryujinx.Graphics.Metal
|
||||||
return pipelineState;
|
return pipelineState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static MTLComputePipelineDescriptor CreateComputeDescriptor(Program program)
|
||||||
|
{
|
||||||
|
ComputeSize localSize = program.ComputeLocalSize;
|
||||||
|
|
||||||
|
uint maxThreads = (uint)(localSize.X * localSize.Y * localSize.Z);
|
||||||
|
|
||||||
|
if (maxThreads == 0)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException($"Local thread size for compute cannot be 0 in any dimension.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var descriptor = new MTLComputePipelineDescriptor
|
||||||
|
{
|
||||||
|
ComputeFunction = program.ComputeFunction,
|
||||||
|
MaxTotalThreadsPerThreadgroup = maxThreads,
|
||||||
|
ThreadGroupSizeIsMultipleOfThreadExecutionWidth = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
return descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
public static MTLComputePipelineState CreateComputePipeline(MTLDevice device, Program program)
|
public static MTLComputePipelineState CreateComputePipeline(MTLDevice device, Program program)
|
||||||
{
|
{
|
||||||
if (program.TryGetComputePipeline(out var pipelineState))
|
if (program.TryGetComputePipeline(out var pipelineState))
|
||||||
|
@ -256,8 +278,10 @@ namespace Ryujinx.Graphics.Metal
|
||||||
return pipelineState;
|
return pipelineState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using MTLComputePipelineDescriptor descriptor = CreateComputeDescriptor(program);
|
||||||
|
|
||||||
var error = new NSError(IntPtr.Zero);
|
var error = new NSError(IntPtr.Zero);
|
||||||
pipelineState = device.NewComputePipelineState(program.ComputeFunction, ref error);
|
pipelineState = device.NewComputePipelineState(descriptor, MTLPipelineOption.None, 0, ref error);
|
||||||
if (error != IntPtr.Zero)
|
if (error != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
Logger.Error?.PrintMsg(LogClass.Gpu, $"Failed to create Compute Pipeline State: {StringHelper.String(error.LocalizedDescription)}");
|
Logger.Error?.PrintMsg(LogClass.Gpu, $"Failed to create Compute Pipeline State: {StringHelper.String(error.LocalizedDescription)}");
|
||||||
|
|
|
@ -37,7 +37,9 @@ namespace Ryujinx.Graphics.Metal
|
||||||
descriptor.Swizzle = GetSwizzle(info, descriptor.PixelFormat);
|
descriptor.Swizzle = GetSwizzle(info, descriptor.PixelFormat);
|
||||||
|
|
||||||
_mtlTexture = _device.NewTexture(descriptor);
|
_mtlTexture = _device.NewTexture(descriptor);
|
||||||
|
|
||||||
MtlFormat = pixelFormat;
|
MtlFormat = pixelFormat;
|
||||||
|
descriptor.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Texture(MTLDevice device, MetalRenderer renderer, Pipeline pipeline, TextureCreateInfo info, MTLTexture sourceTexture, int firstLayer, int firstLevel) : base(device, renderer, pipeline, info)
|
public Texture(MTLDevice device, MetalRenderer renderer, Pipeline pipeline, TextureCreateInfo info, MTLTexture sourceTexture, int firstLayer, int firstLevel) : base(device, renderer, pipeline, info)
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace Ryujinx.Graphics.Metal
|
||||||
return _mtlTexture;
|
return _mtlTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Release()
|
public virtual void Release()
|
||||||
{
|
{
|
||||||
Dispose();
|
Dispose();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,27 +7,54 @@ using System.Runtime.Versioning;
|
||||||
namespace Ryujinx.Graphics.Metal
|
namespace Ryujinx.Graphics.Metal
|
||||||
{
|
{
|
||||||
[SupportedOSPlatform("macos")]
|
[SupportedOSPlatform("macos")]
|
||||||
class TextureBuffer : ITexture
|
class TextureBuffer : TextureBase, ITexture
|
||||||
{
|
{
|
||||||
private readonly MetalRenderer _renderer;
|
private MTLTextureDescriptor _descriptor;
|
||||||
|
|
||||||
private BufferHandle _bufferHandle;
|
private BufferHandle _bufferHandle;
|
||||||
private int _offset;
|
private int _offset;
|
||||||
private int _size;
|
private int _size;
|
||||||
|
|
||||||
private int _bufferCount;
|
private int _bufferCount;
|
||||||
|
|
||||||
public int Width { get; }
|
public TextureBuffer(MTLDevice device, MetalRenderer renderer, Pipeline pipeline, TextureCreateInfo info) : base(device, renderer, pipeline, info)
|
||||||
public int Height { get; }
|
|
||||||
|
|
||||||
public MTLPixelFormat MtlFormat { get; }
|
|
||||||
|
|
||||||
public TextureBuffer(MetalRenderer renderer, TextureCreateInfo info)
|
|
||||||
{
|
{
|
||||||
_renderer = renderer;
|
MTLPixelFormat pixelFormat = FormatTable.GetFormat(Info.Format);
|
||||||
Width = info.Width;
|
|
||||||
Height = info.Height;
|
_descriptor = new MTLTextureDescriptor
|
||||||
MtlFormat = FormatTable.GetFormat(info.Format);
|
{
|
||||||
|
PixelFormat = pixelFormat,
|
||||||
|
Usage = MTLTextureUsage.Unknown,
|
||||||
|
TextureType = MTLTextureType.TextureBuffer,
|
||||||
|
Width = (ulong)Info.Width,
|
||||||
|
Height = (ulong)Info.Height,
|
||||||
|
};
|
||||||
|
|
||||||
|
MtlFormat = pixelFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RebuildStorage()
|
||||||
|
{
|
||||||
|
// Find the parent buffer, and try to build a texture from it.
|
||||||
|
|
||||||
|
// TODO: texture uses should register read/write usage on the assigned buffer.
|
||||||
|
Auto<DisposableBuffer> bufferAuto = _renderer.BufferManager.GetBuffer(_bufferHandle, false);
|
||||||
|
|
||||||
|
if (_mtlTexture.NativePtr != 0)
|
||||||
|
{
|
||||||
|
_mtlTexture.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bufferAuto == null)
|
||||||
|
{
|
||||||
|
_mtlTexture = default;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DisposableBuffer buffer = bufferAuto.Get(_pipeline.Cbs, _offset, _size);
|
||||||
|
|
||||||
|
_descriptor.Width = (uint)(_size / Info.BytesPerPixel);
|
||||||
|
_mtlTexture = buffer.Value.NewTexture(_descriptor, (ulong)_offset, (ulong)_size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CopyTo(ITexture destination, int firstLayer, int firstLevel)
|
public void CopyTo(ITexture destination, int firstLayer, int firstLevel)
|
||||||
|
@ -65,11 +92,6 @@ namespace Ryujinx.Graphics.Metal
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Release()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetData(IMemoryOwner<byte> data)
|
public void SetData(IMemoryOwner<byte> data)
|
||||||
{
|
{
|
||||||
_renderer.SetBufferData(_bufferHandle, _offset, data.Memory.Span);
|
_renderer.SetBufferData(_bufferHandle, _offset, data.Memory.Span);
|
||||||
|
@ -101,7 +123,14 @@ namespace Ryujinx.Graphics.Metal
|
||||||
_size = buffer.Size;
|
_size = buffer.Size;
|
||||||
_bufferCount = _renderer.BufferManager.BufferCount;
|
_bufferCount = _renderer.BufferManager.BufferCount;
|
||||||
|
|
||||||
Release();
|
RebuildStorage();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Release()
|
||||||
|
{
|
||||||
|
_descriptor.Dispose();
|
||||||
|
|
||||||
|
base.Release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,10 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
private int _width;
|
private int _width;
|
||||||
private int _height;
|
private int _height;
|
||||||
|
|
||||||
|
private int _requestedWidth;
|
||||||
|
private int _requestedHeight;
|
||||||
|
|
||||||
// private bool _vsyncEnabled;
|
// private bool _vsyncEnabled;
|
||||||
private AntiAliasing _currentAntiAliasing;
|
private AntiAliasing _currentAntiAliasing;
|
||||||
private bool _updateEffect;
|
private bool _updateEffect;
|
||||||
|
@ -35,10 +39,26 @@ namespace Ryujinx.Graphics.Metal
|
||||||
_metalLayer = metalLayer;
|
_metalLayer = metalLayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback)
|
private unsafe void ResizeIfNeeded()
|
||||||
|
{
|
||||||
|
if (_requestedWidth != 0 && _requestedHeight != 0)
|
||||||
|
{
|
||||||
|
// TODO: This is actually a CGSize, but there is no overload for that, so fill the first two fields of rect with the size.
|
||||||
|
var rect = new NSRect(_requestedWidth, _requestedHeight, 0, 0);
|
||||||
|
|
||||||
|
ObjectiveC.objc_msgSend(_metalLayer, "setDrawableSize:", rect);
|
||||||
|
|
||||||
|
_requestedWidth = 0;
|
||||||
|
_requestedHeight = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public unsafe void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback)
|
||||||
{
|
{
|
||||||
if (_renderer.Pipeline is Pipeline pipeline && texture is Texture tex)
|
if (_renderer.Pipeline is Pipeline pipeline && texture is Texture tex)
|
||||||
{
|
{
|
||||||
|
ResizeIfNeeded();
|
||||||
|
|
||||||
var drawable = new CAMetalDrawable(ObjectiveC.IntPtr_objc_msgSend(_metalLayer, "nextDrawable"));
|
var drawable = new CAMetalDrawable(ObjectiveC.IntPtr_objc_msgSend(_metalLayer, "nextDrawable"));
|
||||||
|
|
||||||
_width = (int)drawable.Texture.Width;
|
_width = (int)drawable.Texture.Width;
|
||||||
|
@ -114,7 +134,8 @@ namespace Ryujinx.Graphics.Metal
|
||||||
|
|
||||||
public void SetSize(int width, int height)
|
public void SetSize(int width, int height)
|
||||||
{
|
{
|
||||||
// Ignore
|
_requestedWidth = width;
|
||||||
|
_requestedHeight = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ChangeVSyncMode(bool vsyncEnabled)
|
public void ChangeVSyncMode(bool vsyncEnabled)
|
||||||
|
|
|
@ -205,7 +205,7 @@ namespace Ryujinx.Graphics.OpenGL
|
||||||
Buffer.Copy(source, destination, srcOffset, dstOffset, size);
|
Buffer.Copy(source, destination, srcOffset, dstOffset, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DispatchCompute(int groupsX, int groupsY, int groupsZ, int groupSizeX, int groupSizeY, int groupSizeZ)
|
public void DispatchCompute(int groupsX, int groupsY, int groupsZ)
|
||||||
{
|
{
|
||||||
if (!_program.IsLinked)
|
if (!_program.IsLinked)
|
||||||
{
|
{
|
||||||
|
|
|
@ -241,7 +241,7 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Msl
|
||||||
var textureTypeName = texture.Type.ToMslTextureType();
|
var textureTypeName = texture.Type.ToMslTextureType();
|
||||||
argBufferPointers[texture.Binding] = $"{textureTypeName} tex_{texture.Name};";
|
argBufferPointers[texture.Binding] = $"{textureTypeName} tex_{texture.Name};";
|
||||||
|
|
||||||
if (!texture.Separate)
|
if (!texture.Separate && texture.Type != SamplerType.TextureBuffer)
|
||||||
{
|
{
|
||||||
argBufferPointers[Defaults.MaxTexturesPerStage + texture.Binding] = $"sampler samp_{texture.Name};";
|
argBufferPointers[Defaults.MaxTexturesPerStage + texture.Binding] = $"sampler samp_{texture.Name};";
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
using Ryujinx.Graphics.Shader.Translation;
|
using Ryujinx.Graphics.Shader.Translation;
|
||||||
|
@ -861,7 +861,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_pipeline.SetStorageBuffers(1, sbRanges);
|
_pipeline.SetStorageBuffers(1, sbRanges);
|
||||||
|
|
||||||
_pipeline.SetProgram(_programStrideChange);
|
_pipeline.SetProgram(_programStrideChange);
|
||||||
_pipeline.DispatchCompute(1 + elems / ConvertElementsPerWorkgroup, 1, 1, 0, 0, 0);
|
_pipeline.DispatchCompute(1 + elems / ConvertElementsPerWorkgroup, 1, 1);
|
||||||
|
|
||||||
_pipeline.Finish(gd, cbs);
|
_pipeline.Finish(gd, cbs);
|
||||||
}
|
}
|
||||||
|
@ -1044,7 +1044,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
int dispatchX = (Math.Min(srcView.Info.Width, dstView.Info.Width) + 31) / 32;
|
int dispatchX = (Math.Min(srcView.Info.Width, dstView.Info.Width) + 31) / 32;
|
||||||
int dispatchY = (Math.Min(srcView.Info.Height, dstView.Info.Height) + 31) / 32;
|
int dispatchY = (Math.Min(srcView.Info.Height, dstView.Info.Height) + 31) / 32;
|
||||||
|
|
||||||
_pipeline.DispatchCompute(dispatchX, dispatchY, 1, 0, 0, 0);
|
_pipeline.DispatchCompute(dispatchX, dispatchY, 1);
|
||||||
|
|
||||||
if (srcView != src)
|
if (srcView != src)
|
||||||
{
|
{
|
||||||
|
@ -1170,7 +1170,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_pipeline.SetTextureAndSamplerIdentitySwizzle(ShaderStage.Compute, 0, srcView, null);
|
_pipeline.SetTextureAndSamplerIdentitySwizzle(ShaderStage.Compute, 0, srcView, null);
|
||||||
_pipeline.SetImage(ShaderStage.Compute, 0, dstView.GetView(format));
|
_pipeline.SetImage(ShaderStage.Compute, 0, dstView.GetView(format));
|
||||||
|
|
||||||
_pipeline.DispatchCompute(dispatchX, dispatchY, 1, 0, 0, 0);
|
_pipeline.DispatchCompute(dispatchX, dispatchY, 1);
|
||||||
|
|
||||||
if (srcView != src)
|
if (srcView != src)
|
||||||
{
|
{
|
||||||
|
@ -1582,7 +1582,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_pipeline.SetStorageBuffers(stackalloc[] { new BufferAssignment(3, patternScoped.Range) });
|
_pipeline.SetStorageBuffers(stackalloc[] { new BufferAssignment(3, patternScoped.Range) });
|
||||||
|
|
||||||
_pipeline.SetProgram(_programConvertIndirectData);
|
_pipeline.SetProgram(_programConvertIndirectData);
|
||||||
_pipeline.DispatchCompute(1, 1, 1, 0, 0, 0);
|
_pipeline.DispatchCompute(1, 1, 1);
|
||||||
|
|
||||||
BufferHolder.InsertBufferBarrier(
|
BufferHolder.InsertBufferBarrier(
|
||||||
gd,
|
gd,
|
||||||
|
@ -1684,7 +1684,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
_pipeline.SetStorageBuffers(1, sbRanges);
|
_pipeline.SetStorageBuffers(1, sbRanges);
|
||||||
|
|
||||||
_pipeline.SetProgram(_programConvertD32S8ToD24S8);
|
_pipeline.SetProgram(_programConvertD32S8ToD24S8);
|
||||||
_pipeline.DispatchCompute(1 + inSize / ConvertElementsPerWorkgroup, 1, 1, 0, 0, 0);
|
_pipeline.DispatchCompute(1 + inSize / ConvertElementsPerWorkgroup, 1, 1);
|
||||||
|
|
||||||
_pipeline.Finish(gd, cbs);
|
_pipeline.Finish(gd, cbs);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
using Silk.NET.Vulkan;
|
using Silk.NET.Vulkan;
|
||||||
using System;
|
using System;
|
||||||
|
@ -295,7 +295,7 @@ namespace Ryujinx.Graphics.Vulkan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DispatchCompute(int groupsX, int groupsY, int groupsZ, int groupSizeX, int groupSizeY, int groupSizeZ)
|
public void DispatchCompute(int groupsX, int groupsY, int groupsZ)
|
||||||
{
|
{
|
||||||
if (!_program.IsLinked)
|
if (!_program.IsLinked)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue