92 lines
3.8 KiB
C#
92 lines
3.8 KiB
C#
|
using RefreshCS;
|
|||
|
using System;
|
|||
|
using System.IO;
|
|||
|
using System.Runtime.InteropServices;
|
|||
|
|
|||
|
namespace Nerfed.Runtime.Graphics;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Compute pipelines perform arbitrary parallel processing on input data.
|
|||
|
/// </summary>
|
|||
|
public class ComputePipeline : RefreshResource
|
|||
|
{
|
|||
|
protected override Action<IntPtr, IntPtr> ReleaseFunction => Refresh.Refresh_ReleaseComputePipeline;
|
|||
|
|
|||
|
public uint ReadOnlyStorageTextureCount { get; }
|
|||
|
public uint ReadOnlyStorageBufferCount { get; }
|
|||
|
public uint ReadWriteStorageTextureCount { get; }
|
|||
|
public uint ReadWriteStorageBufferCount { get; }
|
|||
|
public uint UniformBufferCount { get; }
|
|||
|
|
|||
|
public ComputePipeline(
|
|||
|
GraphicsDevice device,
|
|||
|
string filePath,
|
|||
|
string entryPointName,
|
|||
|
in ComputePipelineCreateInfo computePipelineCreateInfo
|
|||
|
) : base(device)
|
|||
|
{
|
|||
|
using FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
|
|||
|
Handle = CreateFromStream(device, stream, entryPointName, computePipelineCreateInfo);
|
|||
|
|
|||
|
ReadOnlyStorageTextureCount = computePipelineCreateInfo.ReadOnlyStorageTextureCount;
|
|||
|
ReadOnlyStorageBufferCount = computePipelineCreateInfo.ReadOnlyStorageBufferCount;
|
|||
|
ReadWriteStorageTextureCount = computePipelineCreateInfo.ReadWriteStorageTextureCount;
|
|||
|
ReadWriteStorageBufferCount = computePipelineCreateInfo.ReadWriteStorageBufferCount;
|
|||
|
UniformBufferCount = computePipelineCreateInfo.UniformBufferCount;
|
|||
|
}
|
|||
|
|
|||
|
public ComputePipeline(
|
|||
|
GraphicsDevice device,
|
|||
|
Stream stream,
|
|||
|
string entryPointName,
|
|||
|
in ComputePipelineCreateInfo computePipelineCreateInfo
|
|||
|
) : base(device)
|
|||
|
{
|
|||
|
Handle = CreateFromStream(device, stream, entryPointName, computePipelineCreateInfo);
|
|||
|
|
|||
|
ReadOnlyStorageTextureCount = computePipelineCreateInfo.ReadOnlyStorageTextureCount;
|
|||
|
ReadOnlyStorageBufferCount = computePipelineCreateInfo.ReadOnlyStorageBufferCount;
|
|||
|
ReadWriteStorageTextureCount = computePipelineCreateInfo.ReadWriteStorageTextureCount;
|
|||
|
ReadWriteStorageBufferCount = computePipelineCreateInfo.ReadWriteStorageBufferCount;
|
|||
|
UniformBufferCount = computePipelineCreateInfo.UniformBufferCount;
|
|||
|
}
|
|||
|
|
|||
|
private static unsafe nint CreateFromStream(
|
|||
|
GraphicsDevice device,
|
|||
|
Stream stream,
|
|||
|
string entryPointName,
|
|||
|
in ComputePipelineCreateInfo computePipelineCreateInfo
|
|||
|
) {
|
|||
|
byte* bytecodeBuffer = (byte*) NativeMemory.Alloc((nuint) stream.Length);
|
|||
|
Span<byte> bytecodeSpan = new Span<byte>(bytecodeBuffer, (int) stream.Length);
|
|||
|
stream.ReadExactly(bytecodeSpan);
|
|||
|
|
|||
|
Refresh.ComputePipelineCreateInfo refreshPipelineCreateInfo;
|
|||
|
refreshPipelineCreateInfo.Code = bytecodeBuffer;
|
|||
|
refreshPipelineCreateInfo.CodeSize = (nuint) stream.Length;
|
|||
|
refreshPipelineCreateInfo.EntryPointName = entryPointName;
|
|||
|
refreshPipelineCreateInfo.Format = (Refresh.ShaderFormat) computePipelineCreateInfo.ShaderFormat;
|
|||
|
refreshPipelineCreateInfo.ReadOnlyStorageTextureCount = computePipelineCreateInfo.ReadOnlyStorageTextureCount;
|
|||
|
refreshPipelineCreateInfo.ReadOnlyStorageBufferCount = computePipelineCreateInfo.ReadOnlyStorageBufferCount;
|
|||
|
refreshPipelineCreateInfo.ReadWriteStorageTextureCount = computePipelineCreateInfo.ReadWriteStorageTextureCount;
|
|||
|
refreshPipelineCreateInfo.ReadWriteStorageBufferCount = computePipelineCreateInfo.ReadWriteStorageBufferCount;
|
|||
|
refreshPipelineCreateInfo.UniformBufferCount = computePipelineCreateInfo.UniformBufferCount;
|
|||
|
refreshPipelineCreateInfo.ThreadCountX = computePipelineCreateInfo.ThreadCountX;
|
|||
|
refreshPipelineCreateInfo.ThreadCountY = computePipelineCreateInfo.ThreadCountY;
|
|||
|
refreshPipelineCreateInfo.ThreadCountZ = computePipelineCreateInfo.ThreadCountZ;
|
|||
|
|
|||
|
IntPtr computePipelineHandle = Refresh.Refresh_CreateComputePipeline(
|
|||
|
device.Handle,
|
|||
|
refreshPipelineCreateInfo
|
|||
|
);
|
|||
|
|
|||
|
if (computePipelineHandle == nint.Zero)
|
|||
|
{
|
|||
|
throw new Exception("Could not create compute pipeline!");
|
|||
|
}
|
|||
|
|
|||
|
NativeMemory.Free(bytecodeBuffer);
|
|||
|
return computePipelineHandle;
|
|||
|
}
|
|||
|
}
|