Skip to content

Latest commit

 

History

History
305 lines (305 loc) · 9.76 KB

File metadata and controls

305 lines (305 loc) · 9.76 KB
namespace VMASharp.Metadata
{
  public interface IBlockMetadata
  {
    long Size { get; }
    int AllocationCount { get; }
    long SumFreeSize { get; }
    long UnusedRangeSizeMax { get; }
    bool IsEmpty { get; }
    void Validate();
    void CalcAllocationStatInfo(out StatInfo outInfo);
    void AddPoolStats(ref PoolStats stats);
    bool TryCreateAllocationRequest(in AllocationContext context, out AllocationRequest request);
    bool MakeRequestedAllocationsLost(
      int currentFrame,
      int frameInUseCount,
      ref AllocationRequest request);
    int MakeAllocationsLost(int currentFrame, int frameInUseCount);
    void CheckCorruption(nuint blockDataPointer);
    void Alloc(
      in AllocationRequest request,
      SuballocationType type,
      long allocSize,
      BlockAllocation allocation);
    void Free(BlockAllocation allocation);
    void FreeAtOffset(long offset);
  }
}
namespace VMASharp
{
  public abstract class Allocation : IDisposable
  {
    public long Size { get; }
    public int MemoryTypeIndex { get; }
    public abstract DeviceMemory DeviceMemory { get; }
    public abstract long Offset { get; internal set; }
    public object? UserData { get; set; }
    public abstract nint MappedData { get; }
    public void Dispose();
    public Result BindBufferMemory(Buffer buffer);
    public Result BindBufferMemory(Buffer buffer, long allocationLocalOffset, nint pNext);
    public Result BindBufferMemory(Buffer buffer, long allocationLocalOffset, void* pNext = null);
    public Result BindImageMemory(Image image);
    public Result BindImageMemory(Image image, long allocationLocalOffset, nint pNext);
    public Result BindImageMemory(Image image, long allocationLocalOffset, void* pNext = null);
    public bool TouchAllocation();
    public Result Flush(long offset, long size);
    public Result Invalidate(long offset, long size);
    public abstract nint Map();
    public abstract void Unmap();
    public bool TryGetMemory<T>(out Memory<T> memory) where T : unmanaged;
    public bool TryGetSpan<T>(out Span<T> span) where T : unmanaged;
  }
  public struct AllocationBudget
  {
    public long BlockBytes;
    public long AllocationBytes;
    public long Usage;
    public long Budget;
    public AllocationBudget(long blockBytes, long allocationBytes, long usage, long budget);
  }
  public struct AllocationContext
  {
    public int CurrentFrame;
    public int FrameInUseCount;
    public long BufferImageGranularity;
    public long AllocationSize;
    public long AllocationAlignment;
    public AllocationStrategyFlags Strategy;
    public SuballocationType SuballocationType;
    public bool CanMakeOtherLost;
    public AllocationContext(
      int currentFrame,
      int framesInUse,
      long bufferImageGranularity,
      long allocationSize,
      long allocationAlignment,
      AllocationStrategyFlags strategy,
      SuballocationType suballocType,
      bool canMakeOtherLost);
  }
  [Flags]
  public enum AllocationCreateFlags
  {
    DedicatedMemory = 1,
    NeverAllocate = 2,
    Mapped = 4,
    CanBecomeLost = 8,
    CanMakeOtherLost = 16, // 0x00000010
    UpperAddress = 64, // 0x00000040
    DontBind = 128, // 0x00000080
    WithinBudget = 256, // 0x00000100
  }
  public struct AllocationCreateInfo
  {
    public AllocationCreateFlags Flags;
    public AllocationStrategyFlags Strategy;
    public MemoryUsage Usage;
    public MemoryPropertyFlags? RequiredFlags;
    public MemoryPropertyFlags? PreferredFlags;
    public uint MemoryTypeBits;
    public VulkanMemoryPool? Pool;
    public object? UserData;
    public AllocationCreateInfo(
      AllocationCreateFlags flags = (AllocationCreateFlags) 0,
      AllocationStrategyFlags strategy = (AllocationStrategyFlags) 0,
      MemoryUsage usage = MemoryUsage.Unknown,
      MemoryPropertyFlags? requiredFlags = 0,
      MemoryPropertyFlags? preferredFlags = 0,
      uint memoryTypeBits = 0,
      VulkanMemoryPool? pool = null,
      object? userData = null);
  }
  public class AllocationException : VulkanResultException
  {
    public AllocationException(string message);
    public AllocationException(string message, Exception? innerException);
    public AllocationException(Result res);
    public AllocationException(string message, Result res);
  }
  public struct AllocationPoolCreateInfo
  {
    public int MemoryTypeIndex;
    public PoolCreateFlags Flags;
    public long BlockSize;
    public int MinBlockCount;
    public int MaxBlockCount;
    public int FrameInUseCount;
    public Func<long, IBlockMetadata>? AllocationAlgorithmCreate;
    public AllocationPoolCreateInfo(
      int memoryTypeIndex,
      PoolCreateFlags flags = (PoolCreateFlags) 0,
      long blockSize = 0,
      int minBlockCount = 0,
      int maxBlockCount = 0,
      int frameInUseCount = 0,
      Func<long, IBlockMetadata>? allocationAlgorithemCreate = null);
  }
  public struct AllocationRequest
  {
    public const long LostAllocationCost = 1048576;
    public long Offset;
    public long SumFreeSize;
    public long SumItemSize;
    public long ItemsToMakeLostCount;
    public object Item;
    public object CustomData;
    public AllocationRequestType Type;
    public readonly long CalcCost();
  }
  public enum AllocationRequestType
  {
    Normal,
    UpperAddress
  }
  [Flags]
  public enum AllocationStrategyFlags
  {
    BestFit = 1,
    WorstFit = 2,
    FirstFit = 4,
    MinMemory = BestFit, // 0x00000001
    MinTime = FirstFit, // 0x00000004
    MinFragmentation = WorstFit, // 0x00000002
  }
  [Flags]
  public enum AllocatorCreateFlags
  {
    ExternallySyncronized = 1,
    ExtMemoryBudget = 8,
    AMDDeviceCoherentMemory = 16, // 0x00000010
    BufferDeviceAddress = 32, // 0x00000020
  }
  public sealed class BlockAllocation : Allocation
  {
    public override DeviceMemory DeviceMemory { get; }
    public override long Offset { get; internal set; }
    public override nint MappedData { get; }
    public override nint Map();
    public override void Unmap();
  }
  public class MapMemoryException : VulkanResultException
  {
    public MapMemoryException(string message);
    public MapMemoryException(Result res);
    public MapMemoryException(string message, Result res);
  }
  public enum MemoryUsage
  {
    Unknown,
    GPU_Only,
    CPU_Only,
    CPU_To_GPU,
    GPU_To_CPU,
    CPU_Copy,
    GPU_LazilyAllocated,
  }
  [Flags]
  public enum PoolCreateFlags
  {
    IgnoreBufferImageGranularity = 1,
    LinearAlgorithm = 16, // 0x00000010
    BuddyAlgorithm = 32, // 0x00000020
  }
  public struct PoolStats
  {
    public long Size;
    public long UnusedSize;
    public int AllocationCount;
    public int UnusedRangeCount;
    public long UnusedRangeSizeMax;
    public int BlockCount;
  }
  public struct StatInfo
  {
    public int BlockCount;
    public int AllocationCount;
    public int UnusedRangeCount;
    public long UsedBytes;
    public long UnusedBytes;
    public long AllocationSizeMin;
    public long AllocationSizeAvg;
    public long AllocationSizeMax;
    public long UnusedRangeSizeMin;
    public long UnusedRangeSizeAvg;
    public long UnusedRangeSizeMax;
  }
  public class Stats
  {
    public readonly StatInfo[] MemoryType;
    public readonly StatInfo[] MemoryHeap;
    public StatInfo Total;
  }
  public enum SuballocationType
  {
    Free,
    Unknown,
    Buffer,
    Image_Unknown,
    Image_Linear,
    Image_Optimal,
  }
  public class ValidationFailedException : ApplicationException
  {
  }
  public sealed class VulkanMemoryAllocator : IDisposable
  {
    public Device Device { get; }
    public VulkanMemoryAllocator(in VulkanMemoryAllocatorCreateInfo createInfo);
    public int CurrentFrameIndex { get; set; }
    public void Dispose();
    public ref readonly Silk.NET.Vulkan.PhysicalDeviceProperties PhysicalDeviceProperties { get; }
    public ref readonly PhysicalDeviceMemoryProperties MemoryProperties { get; }
    public MemoryPropertyFlags GetMemoryTypeProperties(int memoryTypeIndex);
    public int? FindMemoryTypeIndex(uint memoryTypeBits, in AllocationCreateInfo allocInfo);
    public int? FindMemoryTypeIndexForBufferInfo(
      in BufferCreateInfo bufferInfo,
      in AllocationCreateInfo allocInfo);
    public int? FindMemoryTypeIndexForImageInfo(
      in ImageCreateInfo imageInfo,
      in AllocationCreateInfo allocInfo);
    public Allocation AllocateMemory(
      in MemoryRequirements requirements,
      in AllocationCreateInfo createInfo);
    public Allocation AllocateMemoryForBuffer(
      Buffer buffer,
      in AllocationCreateInfo createInfo,
      bool BindToBuffer = false);
    public Allocation AllocateMemoryForImage(
      Image image,
      in AllocationCreateInfo createInfo,
      bool BindToImage = false);
    public Result CheckCorruption(uint memoryTypeBits);
    public Buffer CreateBuffer(
      in BufferCreateInfo bufferInfo,
      in AllocationCreateInfo allocInfo,
      out Allocation allocation);
    public Image CreateImage(
      in ImageCreateInfo imageInfo,
      in AllocationCreateInfo allocInfo,
      out Allocation allocation);
    public void FreeMemory(Allocation allocation);
    public Stats CalculateStats();
    public VulkanMemoryPool CreatePool(in AllocationPoolCreateInfo createInfo);
  }
  public sealed class VulkanMemoryPool : IDisposable
  {
    public VulkanMemoryAllocator Allocator { get; }
    public string Name { get; set; }
    public void Dispose();
    public int MakeAllocationsLost();
    public Result CheckForCorruption();
    public void GetPoolStats(out PoolStats stats);
  }
  public class VulkanResultException : ApplicationException
  {
    public readonly Silk.NET.Vulkan.Result? Result;
    public VulkanResultException(string message);
    public VulkanResultException(string message, Exception? innerException);
    public VulkanResultException(Silk.NET.Vulkan.Result res);
    public VulkanResultException(string message, Silk.NET.Vulkan.Result res);
  }
}