Mercurial > games > semicongine
annotate src/semicongine/vulkan/buffer.nim @ 153:c6f6757e8126
add: more logging
author | Sam <sam@basx.dev> |
---|---|
date | Thu, 27 Apr 2023 20:55:02 +0700 |
parents | a46923cb0790 |
children | de04cf5c2558 |
rev | line source |
---|---|
113
7b695fb335ed
did: first final implementation of scene-graph <-> pipeline connection, not working yet
Sam <sam@basx.dev>
parents:
112
diff
changeset
|
1 import std/strformat |
7b695fb335ed
did: first final implementation of scene-graph <-> pipeline connection, not working yet
Sam <sam@basx.dev>
parents:
112
diff
changeset
|
2 import std/typetraits |
112
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
3 import std/sequtils |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
4 import std/tables |
153 | 5 import std/logging |
112
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
6 |
89 | 7 import ./api |
94 | 8 import ./device |
112
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
9 import ./memory |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
10 import ./physicaldevice |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
11 import ./commandbuffer |
89 | 12 |
13 type | |
105
4059aa0d689b
add: descriptors, better swapchain implementation
Sam <sam@basx.dev>
parents:
97
diff
changeset
|
14 Buffer* = object |
4059aa0d689b
add: descriptors, better swapchain implementation
Sam <sam@basx.dev>
parents:
97
diff
changeset
|
15 device*: Device |
4059aa0d689b
add: descriptors, better swapchain implementation
Sam <sam@basx.dev>
parents:
97
diff
changeset
|
16 vk*: VkBuffer |
4059aa0d689b
add: descriptors, better swapchain implementation
Sam <sam@basx.dev>
parents:
97
diff
changeset
|
17 size*: uint64 |
112
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
18 usage*: seq[VkBufferUsageFlagBits] |
120 | 19 case memoryAllocated*: bool |
112
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
20 of false: discard |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
21 of true: |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
22 memory*: DeviceMemory |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
23 |
124
cb9e27a30165
fix: completely overhole buffer handling for drawing, fix shit
Sam <sam@basx.dev>
parents:
120
diff
changeset
|
24 proc `==`*(a, b: Buffer): bool = |
cb9e27a30165
fix: completely overhole buffer handling for drawing, fix shit
Sam <sam@basx.dev>
parents:
120
diff
changeset
|
25 a.vk == b.vk |
cb9e27a30165
fix: completely overhole buffer handling for drawing, fix shit
Sam <sam@basx.dev>
parents:
120
diff
changeset
|
26 |
120 | 27 func `$`*(buffer: Buffer): string = |
28 &"Buffer(vk: {buffer.vk}, size: {buffer.size}, usage: {buffer.usage})" | |
113
7b695fb335ed
did: first final implementation of scene-graph <-> pipeline connection, not working yet
Sam <sam@basx.dev>
parents:
112
diff
changeset
|
29 |
120 | 30 |
151 | 31 proc allocateMemory(buffer: var Buffer, preferVRAM: bool, requiresMapping: bool, autoFlush: bool) = |
120 | 32 assert buffer.device.vk.valid |
33 assert buffer.memoryAllocated == false | |
113
7b695fb335ed
did: first final implementation of scene-graph <-> pipeline connection, not working yet
Sam <sam@basx.dev>
parents:
112
diff
changeset
|
34 |
120 | 35 var flags: seq[VkMemoryPropertyFlagBits] |
151 | 36 if requiresMapping: |
37 flags.add VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | |
38 | |
39 if preferVRAM and buffer.device.hasMemoryWith(flags & @[VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT]): | |
120 | 40 flags.add VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
151 | 41 |
42 if autoFlush and buffer.device.hasMemoryWith(flags & @[VK_MEMORY_PROPERTY_HOST_COHERENT_BIT]): | |
120 | 43 flags.add VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
113
7b695fb335ed
did: first final implementation of scene-graph <-> pipeline connection, not working yet
Sam <sam@basx.dev>
parents:
112
diff
changeset
|
44 |
120 | 45 buffer.memoryAllocated = true |
153 | 46 debug "Allocating memory for buffer: ", buffer.size, " bytes ", flags |
112
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
47 buffer.memory = buffer.device.allocate(buffer.size, flags) |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
48 checkVkResult buffer.device.vk.vkBindBufferMemory(buffer.vk, buffer.memory.vk, VkDeviceSize(0)) |
120 | 49 |
89 | 50 |
51 # currently no support for extended structure and concurrent/shared use | |
52 # (shardingMode = VK_SHARING_MODE_CONCURRENT not supported) | |
112
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
53 proc createBuffer*( |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
54 device: Device, |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
55 size: uint64, |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
56 usage: openArray[VkBufferUsageFlagBits], |
151 | 57 preferVRAM: bool, |
58 requiresMapping: bool, | |
120 | 59 autoFlush=true, |
112
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
60 ): Buffer = |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
61 assert device.vk.valid |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
62 assert size > 0 |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
63 |
89 | 64 result.device = device |
65 result.size = size | |
112
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
66 result.usage = usage.toSeq |
151 | 67 if not (requiresMapping or VK_BUFFER_USAGE_TRANSFER_DST_BIT in result.usage): |
120 | 68 result.usage.add VK_BUFFER_USAGE_TRANSFER_DST_BIT |
89 | 69 var createInfo = VkBufferCreateInfo( |
70 sType: VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, | |
120 | 71 flags: VkBufferCreateFlags(0), |
89 | 72 size: size, |
73 usage: toBits(usage), | |
74 sharingMode: VK_SHARING_MODE_EXCLUSIVE, | |
75 ) | |
76 | |
77 checkVkResult vkCreateBuffer( | |
94 | 78 device=device.vk, |
89 | 79 pCreateInfo=addr createInfo, |
80 pAllocator=nil, | |
81 pBuffer=addr result.vk | |
82 ) | |
151 | 83 result.allocateMemory(preferVRAM, requiresMapping, autoFlush) |
89 | 84 |
112
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
85 |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
86 proc copy*(src, dst: Buffer) = |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
87 assert src.device.vk.valid |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
88 assert dst.device.vk.valid |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
89 assert src.device == dst.device |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
90 assert src.size == dst.size |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
91 assert VK_BUFFER_USAGE_TRANSFER_SRC_BIT in src.usage |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
92 assert VK_BUFFER_USAGE_TRANSFER_DST_BIT in dst.usage |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
93 |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
94 var queue: Queue |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
95 for q in src.device.queues.values: |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
96 if q.family.canDoTransfer: |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
97 queue = q |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
98 if not queue.vk.valid: |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
99 raise newException(Exception, "No queue that supports buffer transfer") |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
100 |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
101 var |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
102 commandBufferPool = src.device.createCommandBufferPool(family=queue.family, nBuffers=1) |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
103 commandBuffer = commandBufferPool.buffers[0] |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
104 |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
105 beginInfo = VkCommandBufferBeginInfo( |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
106 sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
107 flags: VkCommandBufferUsageFlags(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT), |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
108 ) |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
109 copyRegion = VkBufferCopy(size: VkDeviceSize(src.size)) |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
110 checkVkResult commandBuffer.vkBeginCommandBuffer(addr(beginInfo)) |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
111 commandBuffer.vkCmdCopyBuffer(src.vk, dst.vk, 1, addr(copyRegion)) |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
112 checkVkResult commandBuffer.vkEndCommandBuffer() |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
113 |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
114 var submitInfo = VkSubmitInfo( |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
115 sType: VK_STRUCTURE_TYPE_SUBMIT_INFO, |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
116 commandBufferCount: 1, |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
117 pCommandBuffers: addr(commandBuffer), |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
118 ) |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
119 checkVkResult queue.vk.vkQueueSubmit(1, addr(submitInfo), VkFence(0)) |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
120 checkVkResult queue.vk.vkQueueWaitIdle() |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
121 commandBufferPool.destroy() |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
122 |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
123 proc destroy*(buffer: var Buffer) = |
94 | 124 assert buffer.device.vk.valid |
125 assert buffer.vk.valid | |
120 | 126 if buffer.memoryAllocated: |
112
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
127 assert buffer.memory.vk.valid |
0c5a74885796
did: real implementation of buffer and memory, getting closer to collect shit for drawing per pipeline
Sam <sam@basx.dev>
parents:
105
diff
changeset
|
128 buffer.memory.free |
94 | 129 buffer.device.vk.vkDestroyBuffer(buffer.vk, nil) |
120 | 130 buffer.vk.reset |
131 | |
132 proc setData*(dst: Buffer, src: pointer, size: uint64, bufferOffset=0'u64) = | |
133 assert bufferOffset + size <= dst.size | |
134 if dst.memory.canMap: | |
135 copyMem(cast[pointer](cast[uint64](dst.memory.data) + bufferOffset), src, size) | |
136 if dst.memory.needsFlushing: | |
137 dst.memory.flush() | |
138 else: # use staging buffer, slower but required if memory is not host visible | |
151 | 139 var stagingBuffer = dst.device.createBuffer(size, [VK_BUFFER_USAGE_TRANSFER_SRC_BIT], preferVRAM=false, requiresMapping=true, autoFlush=true) |
120 | 140 stagingBuffer.setData(src, size, 0) |
141 stagingBuffer.copy(dst) | |
142 stagingBuffer.destroy() | |
143 | |
144 proc setData*[T: seq](dst: Buffer, src: ptr T, offset=0'u64) = | |
145 dst.setData(src, sizeof(get(genericParams(T), 0)) * src[].len, offset=offset) | |
146 | |
147 proc setData*[T](dst: Buffer, src: ptr T, offset=0'u64) = | |
148 dst.setData(src, sizeof(T), offset=offset) | |
149 |