VulkanBufferHelper.cs 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. using System;
  2. using System.Runtime.CompilerServices;
  3. using Silk.NET.Vulkan;
  4. using SilkNetDemo;
  5. using Buffer = Silk.NET.Vulkan.Buffer;
  6. using SystemBuffer = System.Buffer;
  7. namespace GpuInterop.VulkanDemo;
  8. static class VulkanBufferHelper
  9. {
  10. public unsafe static void AllocateBuffer<T>(VulkanContext vk,
  11. BufferUsageFlags bufferUsageFlags,
  12. out Buffer buffer, out DeviceMemory memory,
  13. Span<T> initialData) where T:unmanaged
  14. {
  15. var api = vk.Api;
  16. var device = vk.Device;
  17. var size = Unsafe.SizeOf<T>() * initialData.Length;
  18. var bufferInfo = new BufferCreateInfo()
  19. {
  20. SType = StructureType.BufferCreateInfo,
  21. Size = (ulong)size,
  22. Usage = bufferUsageFlags,
  23. SharingMode = SharingMode.Exclusive
  24. };
  25. api.CreateBuffer(device, bufferInfo, null, out buffer).ThrowOnError();
  26. api.GetBufferMemoryRequirements(device, buffer, out var memoryRequirements);
  27. var physicalDevice = vk.PhysicalDevice;
  28. var memoryAllocateInfo = new MemoryAllocateInfo
  29. {
  30. SType = StructureType.MemoryAllocateInfo,
  31. AllocationSize = memoryRequirements.Size,
  32. MemoryTypeIndex = (uint)FindSuitableMemoryTypeIndex(api,
  33. physicalDevice,
  34. memoryRequirements.MemoryTypeBits,
  35. MemoryPropertyFlags.HostCoherentBit |
  36. MemoryPropertyFlags.HostVisibleBit)
  37. };
  38. api.AllocateMemory(device, memoryAllocateInfo, null, out memory).ThrowOnError();
  39. api.BindBufferMemory(device, buffer, memory, 0);
  40. UpdateBufferMemory(vk, memory, initialData);
  41. }
  42. public static unsafe void UpdateBufferMemory<T>(VulkanContext vk, DeviceMemory memory,
  43. Span<T> data) where T : unmanaged
  44. {
  45. var api = vk.Api;
  46. var device = vk.Device;
  47. var size = data.Length * Unsafe.SizeOf<T>();
  48. void* pointer = null;
  49. api.MapMemory(device, memory, 0, (ulong)size, 0, ref pointer);
  50. data.CopyTo(new Span<T>(pointer, size));
  51. api.UnmapMemory(device, memory);
  52. }
  53. private static int FindSuitableMemoryTypeIndex(Vk api, PhysicalDevice physicalDevice, uint memoryTypeBits,
  54. MemoryPropertyFlags flags)
  55. {
  56. api.GetPhysicalDeviceMemoryProperties(physicalDevice, out var properties);
  57. for (var i = 0; i < properties.MemoryTypeCount; i++)
  58. {
  59. var type = properties.MemoryTypes[i];
  60. if ((memoryTypeBits & (1 << i)) != 0 && type.PropertyFlags.HasFlag(flags)) return i;
  61. }
  62. return -1;
  63. }
  64. }