S
Silk.NET•5mo ago
Citrus

now the only problem is that I need to

made it working, here is an example for future reference Vortice.VulkanMemoryAllocator
1 Reply
Citrus
Citrus•5mo ago
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public readonly struct VertexPositionColor(in Vector3 position, in Vector4 color)
{
public static unsafe int SizeInBytes => sizeof(VertexPositionColor);

public readonly Vector3 Position = position;
public readonly Vector4 Color = color;
}

public static void InitVma(Vk? vk, Device dev, PhysicalDevice pdev, Instance instance)
{
VmaAllocatorCreateInfo allocatorCreateInfo = new()
{
vulkanApiVersion = VkVersion.Version_1_3,
physicalDevice = pdev.Handle,
device = dev.Handle,
instance = instance.Handle
};

VmaVulkanFunctions functions = default;
Debug.Assert(vk != null, nameof(vk) + " != null");
functions.vkGetInstanceProcAddr = (delegate* unmanaged<VkInstance, sbyte*, IntPtr>)vk.GetInstanceProcAddr(instance, "vkGetInstanceProcAddr").Handle;
functions.vkGetDeviceProcAddr = (delegate* unmanaged<VkDevice, sbyte*, IntPtr>)vk.GetDeviceProcAddr(dev, "vkGetDeviceProcAddr").Handle;

allocatorCreateInfo.pVulkanFunctions = &functions;
VmaAllocator allocator;
vmaCreateAllocator(&allocatorCreateInfo, &allocator).CheckResult();
_allocator = allocator;

ReadOnlySpan<VertexPositionColor> sourceData = new VertexPositionColor[]
{
new(new Vector3(0f, 0.5f, 0.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f)),
new(new Vector3(0.5f, -0.5f, 0.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f)),
new(new Vector3(-0.5f, -0.5f, 0.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f))
};

var vertexBufferSize = (uint)(sourceData.Length * VertexPositionColor.SizeInBytes);

VkBufferCreateInfo bufferInfo = new()
{
size = vertexBufferSize,
usage = VkBufferUsageFlags.TransferSrc,
sharingMode = VkSharingMode.Exclusive
};

VmaAllocationCreateInfo allocationCreateInfo;
allocationCreateInfo.usage = VmaMemoryUsage.Auto;
allocationCreateInfo.flags = VmaAllocationCreateFlags.HostAccessSequentialWrite |
VmaAllocationCreateFlags.Mapped;

if (vmaCreateBuffer(_allocator.GetValueOrDefault(), &bufferInfo, &allocationCreateInfo, out var bufferVortice, out var _allocation) != VkResult.Success)
{
throw new Exception("Failed to create buffer!");
}
//let's try converting to silk and cleaning up after
Buffer buf = new Buffer(bufferVortice.Handle);
vmaDestroyBuffer(_allocator.GetValueOrDefault(), buf.Handle, _allocation);

VmaTotalStatistics stats;
vmaCalculateStatistics(_allocator.GetValueOrDefault(), &stats);

if (stats.total.statistics.allocationBytes > 0)
{
//this should NOT be called. Unless you comment vmaDestroyBuffer
Console.WriteLine($"Total device memory leaked: {stats.total.statistics.allocationBytes} bytes. " +
$"Allocated previously {vertexBufferSize}");
}

vmaDestroyAllocator(_allocator.GetValueOrDefault());
}
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public readonly struct VertexPositionColor(in Vector3 position, in Vector4 color)
{
public static unsafe int SizeInBytes => sizeof(VertexPositionColor);

public readonly Vector3 Position = position;
public readonly Vector4 Color = color;
}

public static void InitVma(Vk? vk, Device dev, PhysicalDevice pdev, Instance instance)
{
VmaAllocatorCreateInfo allocatorCreateInfo = new()
{
vulkanApiVersion = VkVersion.Version_1_3,
physicalDevice = pdev.Handle,
device = dev.Handle,
instance = instance.Handle
};

VmaVulkanFunctions functions = default;
Debug.Assert(vk != null, nameof(vk) + " != null");
functions.vkGetInstanceProcAddr = (delegate* unmanaged<VkInstance, sbyte*, IntPtr>)vk.GetInstanceProcAddr(instance, "vkGetInstanceProcAddr").Handle;
functions.vkGetDeviceProcAddr = (delegate* unmanaged<VkDevice, sbyte*, IntPtr>)vk.GetDeviceProcAddr(dev, "vkGetDeviceProcAddr").Handle;

allocatorCreateInfo.pVulkanFunctions = &functions;
VmaAllocator allocator;
vmaCreateAllocator(&allocatorCreateInfo, &allocator).CheckResult();
_allocator = allocator;

ReadOnlySpan<VertexPositionColor> sourceData = new VertexPositionColor[]
{
new(new Vector3(0f, 0.5f, 0.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f)),
new(new Vector3(0.5f, -0.5f, 0.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f)),
new(new Vector3(-0.5f, -0.5f, 0.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f))
};

var vertexBufferSize = (uint)(sourceData.Length * VertexPositionColor.SizeInBytes);

VkBufferCreateInfo bufferInfo = new()
{
size = vertexBufferSize,
usage = VkBufferUsageFlags.TransferSrc,
sharingMode = VkSharingMode.Exclusive
};

VmaAllocationCreateInfo allocationCreateInfo;
allocationCreateInfo.usage = VmaMemoryUsage.Auto;
allocationCreateInfo.flags = VmaAllocationCreateFlags.HostAccessSequentialWrite |
VmaAllocationCreateFlags.Mapped;

if (vmaCreateBuffer(_allocator.GetValueOrDefault(), &bufferInfo, &allocationCreateInfo, out var bufferVortice, out var _allocation) != VkResult.Success)
{
throw new Exception("Failed to create buffer!");
}
//let's try converting to silk and cleaning up after
Buffer buf = new Buffer(bufferVortice.Handle);
vmaDestroyBuffer(_allocator.GetValueOrDefault(), buf.Handle, _allocation);

VmaTotalStatistics stats;
vmaCalculateStatistics(_allocator.GetValueOrDefault(), &stats);

if (stats.total.statistics.allocationBytes > 0)
{
//this should NOT be called. Unless you comment vmaDestroyBuffer
Console.WriteLine($"Total device memory leaked: {stats.total.statistics.allocationBytes} bytes. " +
$"Allocated previously {vertexBufferSize}");
}

vmaDestroyAllocator(_allocator.GetValueOrDefault());
}
who would like an example of silk.net vma usage 🙂