18
|
1 import ./vulkan
|
|
2 import ./vulkan_helpers
|
|
3
|
|
4 type
|
|
5 BufferType* = enum
|
|
6 VertexBuffer = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT
|
|
7 Buffer* = object
|
|
8 device*: VkDevice
|
|
9 vkBuffer*: VkBuffer
|
|
10 size*: uint64
|
|
11 memoryRequirements*: VkMemoryRequirements
|
|
12 memory*: VkDeviceMemory
|
|
13
|
|
14 proc findMemoryType(buffer: Buffer, physicalDevice: VkPhysicalDevice, properties: VkMemoryPropertyFlags): uint32 =
|
|
15 var physicalProperties: VkPhysicalDeviceMemoryProperties
|
|
16 vkGetPhysicalDeviceMemoryProperties(physicalDevice, addr(physicalProperties))
|
|
17
|
|
18 for i in 0'u32 ..< physicalProperties.memoryTypeCount:
|
|
19 if bool(buffer.memoryRequirements.memoryTypeBits and (1'u32 shl i)) and (uint32(physicalProperties.memoryTypes[i].propertyFlags) and uint32(properties)) == uint32(properties):
|
|
20 return i
|
|
21
|
|
22 proc InitBuffer*(device: VkDevice, physicalDevice: VkPhysicalDevice, size: uint64, bufferType: BufferType): Buffer =
|
|
23 result.device = device
|
|
24 result.size = size
|
|
25 var bufferInfo = VkBufferCreateInfo(
|
|
26 sType: VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
|
27 size: VkDeviceSize(result.size),
|
|
28 usage: VkBufferUsageFlags(bufferType),
|
|
29 sharingMode: VK_SHARING_MODE_EXCLUSIVE,
|
|
30
|
|
31 )
|
|
32 checkVkResult vkCreateBuffer(result.device, addr(bufferInfo), nil, addr(result.vkBuffer))
|
|
33 vkGetBufferMemoryRequirements(result.device, result.vkBuffer, addr(result.memoryRequirements))
|
|
34
|
|
35 var allocInfo = VkMemoryAllocateInfo(
|
|
36 sType: VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
|
37 allocationSize: result.memoryRequirements.size,
|
|
38 memoryTypeIndex: result.findMemoryType(
|
|
39 physicalDevice,
|
|
40 VkMemoryPropertyFlags(uint32(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) or uint32(VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
|
|
41 )
|
|
42 )
|
|
43 checkVkResult result.device.vkAllocateMemory(addr(allocInfo), nil, addr(result.memory))
|
|
44 checkVkResult result.device.vkBindBufferMemory(result.vkBuffer, result.memory, VkDeviceSize(0))
|
|
45
|
|
46
|
|
47 template withMapping*(buffer: Buffer, data: pointer, body: untyped): untyped =
|
|
48 checkVkResult buffer.device.vkMapMemory(buffer.memory, offset=VkDeviceSize(0), VkDeviceSize(buffer.size), VkMemoryMapFlags(0), addr(data));
|
|
49 body
|
|
50 buffer.device.vkUnmapMemory(buffer.memory);
|
|
51
|
|
52
|
|
53 proc `=copy`(a: var Buffer, b: Buffer){.error.}
|
|
54
|
|
55 proc `=destroy`*(buffer: var Buffer) =
|
|
56 vkDestroyBuffer(buffer.device, buffer.vkBuffer, nil)
|
|
57 vkFreeMemory(buffer.device, buffer.memory, nil);
|