Mercurial > games > semicongine
comparison src/zamikongine/buffer.nim @ 480:14e5151f68d1
did: introduce scene graph, meshs and generic vertex buffers
| author | Sam <sam@basx.dev> |
|---|---|
| date | Mon, 09 Jan 2023 11:04:19 +0700 |
| parents | |
| children | b1b05d4efb52 |
comparison
equal
deleted
inserted
replaced
| 479:16842d15319a | 480:14e5151f68d1 |
|---|---|
| 1 import ./vulkan | |
| 2 import ./vulkan_helpers | |
| 3 | |
| 4 type | |
| 5 BufferType* = enum | |
| 6 None = 0 | |
| 7 TransferSrc = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | |
| 8 TransferDst = VK_BUFFER_USAGE_TRANSFER_DST_BIT | |
| 9 IndexBuffer = VK_BUFFER_USAGE_INDEX_BUFFER_BIT | |
| 10 VertexBuffer = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | |
| 11 Buffer* = object | |
| 12 device*: VkDevice | |
| 13 vkBuffer*: VkBuffer | |
| 14 size*: uint64 | |
| 15 memoryRequirements*: VkMemoryRequirements | |
| 16 memory*: VkDeviceMemory | |
| 17 bufferTypes*: set[BufferType] | |
| 18 | |
| 19 proc trash*(buffer: var Buffer) = | |
| 20 assert int64(buffer.vkBuffer) != 0 | |
| 21 assert int64(buffer.memory) != 0 | |
| 22 vkDestroyBuffer(buffer.device, buffer.vkBuffer, nil) | |
| 23 buffer.vkBuffer = VkBuffer(0) | |
| 24 vkFreeMemory(buffer.device, buffer.memory, nil) | |
| 25 buffer.memory = VkDeviceMemory(0) | |
| 26 | |
| 27 proc findMemoryType(buffer: Buffer, physicalDevice: VkPhysicalDevice, properties: VkMemoryPropertyFlags): uint32 = | |
| 28 var physicalProperties: VkPhysicalDeviceMemoryProperties | |
| 29 vkGetPhysicalDeviceMemoryProperties(physicalDevice, addr(physicalProperties)) | |
| 30 | |
| 31 for i in 0'u32 ..< physicalProperties.memoryTypeCount: | |
| 32 if bool(buffer.memoryRequirements.memoryTypeBits and (1'u32 shl i)) and (uint32(physicalProperties.memoryTypes[i].propertyFlags) and uint32(properties)) == uint32(properties): | |
| 33 return i | |
| 34 | |
| 35 proc InitBuffer*( | |
| 36 device: VkDevice, | |
| 37 physicalDevice: VkPhysicalDevice, | |
| 38 size: uint64, | |
| 39 bufferTypes: set[BufferType], | |
| 40 properties: set[VkMemoryPropertyFlagBits] | |
| 41 ): Buffer = | |
| 42 result = Buffer(device: device, size: size, bufferTypes: bufferTypes) | |
| 43 var usageFlags = 0 | |
| 44 for usage in bufferTypes: | |
| 45 usageFlags = ord(usageFlags) or ord(usage) | |
| 46 var bufferInfo = VkBufferCreateInfo( | |
| 47 sType: VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, | |
| 48 size: VkDeviceSize(result.size), | |
| 49 usage: VkBufferUsageFlags(usageFlags), | |
| 50 sharingMode: VK_SHARING_MODE_EXCLUSIVE, | |
| 51 ) | |
| 52 checkVkResult vkCreateBuffer(result.device, addr(bufferInfo), nil, addr(result.vkBuffer)) | |
| 53 vkGetBufferMemoryRequirements(result.device, result.vkBuffer, addr(result.memoryRequirements)) | |
| 54 | |
| 55 var memoryProperties = 0'u32 | |
| 56 for prop in properties: | |
| 57 memoryProperties = memoryProperties or uint32(prop) | |
| 58 | |
| 59 var allocInfo = VkMemoryAllocateInfo( | |
| 60 sType: VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, | |
| 61 allocationSize: result.memoryRequirements.size, | |
| 62 memoryTypeIndex: result.findMemoryType(physicalDevice, VkMemoryPropertyFlags(memoryProperties)) | |
| 63 ) | |
| 64 checkVkResult result.device.vkAllocateMemory(addr(allocInfo), nil, addr(result.memory)) | |
| 65 checkVkResult result.device.vkBindBufferMemory(result.vkBuffer, result.memory, VkDeviceSize(0)) | |
| 66 | |
| 67 | |
| 68 template withMapping*(buffer: Buffer, data: pointer, body: untyped): untyped = | |
| 69 checkVkResult vkMapMemory(buffer.device, buffer.memory, offset=VkDeviceSize(0), VkDeviceSize(buffer.size), VkMemoryMapFlags(0), addr(data)) | |
| 70 body | |
| 71 vkUnmapMemory(buffer.device, buffer.memory) | |
| 72 | |
| 73 | |
| 74 proc copyBuffer*(commandPool: VkCommandPool, queue: VkQueue, src, dst: Buffer, size: uint64) = | |
| 75 assert uint64(src.device) == uint64(dst.device) | |
| 76 var | |
| 77 allocInfo = VkCommandBufferAllocateInfo( | |
| 78 sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, | |
| 79 level: VK_COMMAND_BUFFER_LEVEL_PRIMARY, | |
| 80 commandPool: commandPool, | |
| 81 commandBufferCount: 1, | |
| 82 ) | |
| 83 commandBuffer: VkCommandBuffer | |
| 84 checkVkResult vkAllocateCommandBuffers(src.device, addr(allocInfo), addr(commandBuffer)) | |
| 85 | |
| 86 var beginInfo = VkCommandBufferBeginInfo( | |
| 87 sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, | |
| 88 flags: VkCommandBufferUsageFlags(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT), | |
| 89 ) | |
| 90 checkVkResult vkBeginCommandBuffer(commandBuffer, addr(beginInfo)) | |
| 91 var copyRegion = VkBufferCopy(size: VkDeviceSize(size)) | |
| 92 vkCmdCopyBuffer(commandBuffer, src.vkBuffer, dst.vkBuffer, 1, addr(copyRegion)) | |
| 93 checkVkResult vkEndCommandBuffer(commandBuffer) | |
| 94 | |
| 95 var submitInfo = VkSubmitInfo( | |
| 96 sType: VK_STRUCTURE_TYPE_SUBMIT_INFO, | |
| 97 commandBufferCount: 1, | |
| 98 pCommandBuffers: addr(commandBuffer), | |
| 99 ) | |
| 100 | |
| 101 checkVkResult vkQueueSubmit(queue, 1, addr(submitInfo), VkFence(0)) | |
| 102 checkVkResult vkQueueWaitIdle(queue) | |
| 103 vkFreeCommandBuffers(src.device, commandPool, 1, addr(commandBuffer)) |
