GreemDev-Ryujinx/src/Ryujinx.Graphics.Metal/Program.cs
Isaac Marovitz f00cf8704f Metal: Compute Shaders (#19)
* check for too bix texture bindings

* implement lod query

* print shader stage name

* always have fragment input

* resolve merge conflicts

* fix: lod query

* fix: casting texture coords

* support non-array memories

* use structure types for buffers

* implement compute pipeline cache

* compute dispatch

* improve error message

* rebind compute state

* bind compute textures

* pass local size as an argument to dispatch

* implement texture buffers

* hack: change vertex index to vertex id

* pass support buffer as an argument to every function

* return at the end of function

* fix: certain missing compute bindings

* implement texture base

* improve texture binding system

* remove useless exception

* move texture handle to texture base

* fix: segfault when using disposed textures

---------

Co-authored-by: Samuliak <samuliak77@gmail.com>
Co-authored-by: SamoZ256 <96914946+SamoZ256@users.noreply.github.com>
2024-12-23 21:33:12 -06:00

71 lines
2.4 KiB
C#

using Ryujinx.Common.Logging;
using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Shader;
using SharpMetal.Foundation;
using SharpMetal.Metal;
using System;
using System.Runtime.Versioning;
namespace Ryujinx.Graphics.Metal
{
[SupportedOSPlatform("macos")]
class Program : IProgram
{
private readonly ProgramLinkStatus _status;
public MTLFunction VertexFunction;
public MTLFunction FragmentFunction;
public MTLFunction ComputeFunction;
public Program(ShaderSource[] shaders, MTLDevice device)
{
for (int index = 0; index < shaders.Length; index++)
{
ShaderSource shader = shaders[index];
var libraryError = new NSError(IntPtr.Zero);
var shaderLibrary = device.NewLibrary(StringHelper.NSString(shader.Code), new MTLCompileOptions(IntPtr.Zero), ref libraryError);
if (libraryError != IntPtr.Zero)
{
Logger.Warning?.Print(LogClass.Gpu, $"{shader.Stage} shader linking failed: \n{StringHelper.String(libraryError.LocalizedDescription)}");
_status = ProgramLinkStatus.Failure;
return;
}
switch (shaders[index].Stage)
{
case ShaderStage.Compute:
ComputeFunction = shaderLibrary.NewFunction(StringHelper.NSString("kernelMain"));
break;
case ShaderStage.Vertex:
VertexFunction = shaderLibrary.NewFunction(StringHelper.NSString("vertexMain"));
break;
case ShaderStage.Fragment:
FragmentFunction = shaderLibrary.NewFunction(StringHelper.NSString("fragmentMain"));
break;
default:
Logger.Warning?.Print(LogClass.Gpu, $"Cannot handle stage {shaders[index].Stage}!");
break;
}
}
_status = ProgramLinkStatus.Success;
}
public ProgramLinkStatus CheckProgramLink(bool blocking)
{
return _status;
}
public byte[] GetBinary()
{
return ""u8.ToArray();
}
public void Dispose()
{
VertexFunction.Dispose();
FragmentFunction.Dispose();
ComputeFunction.Dispose();
}
}
}