comparison static_utils.nim @ 1178:ec4ff70299f2 compiletime-tests

sync from bedroom to office
author sam <sam@basx.dev>
date Mon, 01 Jul 2024 19:16:09 +0700
parents 4ef959278451
children e1830f9b8af4
comparison
equal deleted inserted replaced
1177:4ef959278451 1178:ec4ff70299f2
21 template ShaderOutput* {.pragma.} 21 template ShaderOutput* {.pragma.}
22 template VertexIndices*{.pragma.} 22 template VertexIndices*{.pragma.}
23 23
24 const INFLIGHTFRAMES = 2'u32 24 const INFLIGHTFRAMES = 2'u32
25 const MEMORY_ALIGNMENT = 65536'u64 # Align buffers inside memory along this alignment 25 const MEMORY_ALIGNMENT = 65536'u64 # Align buffers inside memory along this alignment
26 const BUFFERALIGNMENT = 64'u64 # align offsets inside buffers along this alignment 26 const BUFFER_ALIGNMENT = 64'u64 # align offsets inside buffers along this alignment
27 27
28 type 28 type
29 SupportedGPUType* = float32 | float64 | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64 | TVec2[int32] | TVec2[int64] | TVec3[int32] | TVec3[int64] | TVec4[int32] | TVec4[int64] | TVec2[uint32] | TVec2[uint64] | TVec3[uint32] | TVec3[uint64] | TVec4[uint32] | TVec4[uint64] | TVec2[float32] | TVec2[float64] | TVec3[float32] | TVec3[float64] | TVec4[float32] | TVec4[float64] | TMat2[float32] | TMat2[float64] | TMat23[float32] | TMat23[float64] | TMat32[float32] | TMat32[float64] | TMat3[float32] | TMat3[float64] | TMat34[float32] | TMat34[float64] | TMat43[float32] | TMat43[float64] | TMat4[float32] | TMat4[float64] 29 SupportedGPUType* = float32 | float64 | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64 | TVec2[int32] | TVec2[int64] | TVec3[int32] | TVec3[int64] | TVec4[int32] | TVec4[int64] | TVec2[uint32] | TVec2[uint64] | TVec3[uint32] | TVec3[uint64] | TVec4[uint32] | TVec4[uint64] | TVec2[float32] | TVec2[float64] | TVec3[float32] | TVec3[float64] | TVec4[float32] | TVec4[float64] | TMat2[float32] | TMat2[float64] | TMat23[float32] | TMat23[float64] | TMat32[float32] | TMat32[float64] | TMat3[float32] | TMat3[float64] | TMat34[float32] | TMat34[float64] | TMat43[float32] | TMat43[float64] | TMat4[float32] | TMat4[float64]
30 ShaderObject*[TShader] = object 30 ShaderObject*[TShader] = object
31 vertexShader: VkShaderModule 31 vertexShader: VkShaderModule
32 fragmentShader: VkShaderModule 32 fragmentShader: VkShaderModule
33
34 func alignedTo[T: SomeInteger](value: T, alignment: T) =
35 let remainder = value mod alignment
36 if remainder == 0:
37 return value
38 else:
39 return value + alignment - remainder
33 40
34 func VkType[T: SupportedGPUType](value: T): VkFormat = 41 func VkType[T: SupportedGPUType](value: T): VkFormat =
35 when T is float32: VK_FORMAT_R32_SFLOAT 42 when T is float32: VK_FORMAT_R32_SFLOAT
36 elif T is float64: VK_FORMAT_R64_SFLOAT 43 elif T is float64: VK_FORMAT_R64_SFLOAT
37 elif T is int8: VK_FORMAT_R8_SINT 44 elif T is int8: VK_FORMAT_R8_SINT
211 data: pointer 218 data: pointer
212 needsFlush: bool # usually true 219 needsFlush: bool # usually true
213 GPUMemory = IndirectGPUMemory | DirectGPUMemory 220 GPUMemory = IndirectGPUMemory | DirectGPUMemory
214 221
215 Buffer[TMemory: GPUMemory] = object 222 Buffer[TMemory: GPUMemory] = object
223 memory: TMemory
216 vk: VkBuffer 224 vk: VkBuffer
217 offset: uint64 225 offset: uint64
218 size: uint64 226 size: uint64
219 227
220 GPUArray[T: SupportedGPUType, TMemory: GPUMemory] = object 228 GPUArray[T: SupportedGPUType, TMemory: GPUMemory] = object
223 offset: uint64 231 offset: uint64
224 GPUValue[T: object|array, TMemory: GPUMemory] = object 232 GPUValue[T: object|array, TMemory: GPUMemory] = object
225 data: T 233 data: T
226 buffer: Buffer[TMemory] 234 buffer: Buffer[TMemory]
227 offset: uint64 235 offset: uint64
228 236 GPUData = GPUArray | GPUValue
229 Renderable[TMesh, TInstance] = object
230 vertexBuffers: seq[VkBuffer]
231 bufferOffsets: seq[VkDeviceSize]
232 instanceCount: uint32
233 case indexType: IndexType
234 of None:
235 vertexCount: uint32
236 else:
237 indexBuffer: VkBuffer
238 indexCount: uint32
239 indexBufferOffset: VkDeviceSize
240 237
241 Pipeline[TShader] = object 238 Pipeline[TShader] = object
242 pipeline: VkPipeline 239 pipeline: VkPipeline
243 layout: VkPipelineLayout 240 layout: VkPipelineLayout
244 descriptorSetLayout: VkDescriptorSetLayout 241 descriptorSetLayout: VkDescriptorSetLayout
242 BufferType = enum
243 VertexBuffer, IndexBuffer, UniformBuffer
245 RenderData = object 244 RenderData = object
246 descriptorPool: VkDescriptorPool 245 descriptorPool: VkDescriptorPool
247 # tuple is memory and offset to next free allocation in that memory 246 # tuple is memory and offset to next free allocation in that memory
248 indirectMemory: seq[tuple[memory: IndirectGPUMemory, nextFree: uint64]] 247 indirectMemory: seq[tuple[memory: IndirectGPUMemory, nextFree: uint64]]
249 directMemory: seq[tuple[memory: DirectGPUMemory, nextFree: uint64]] 248 directMemory: seq[tuple[memory: DirectGPUMemory, nextFree: uint64]]
250 indirectBuffers: seq[Buffer[IndirectGPUMemory]] 249 indirectBuffers: seq[tuple[buffer: Buffer[IndirectGPUMemory], btype: BufferType, nextFree: uint64]]
251 directBuffers: seq[Buffer[DirectGPUMemory]] 250 directBuffers: seq[tuple[buffer: Buffer[DirectGPUMemory], btype: BufferType, nextFree: uint64]]
252 251
253 template IsDirectMemory(gpuArray: GPUArray): untyped = 252 template UsesIndirectMemory(gpuData: GPUData): untyped =
254 get(genericParams(typeof(gpuArray)), 1) is DirectGPUMemory 253 get(genericParams(typeof(gpuData)), 1) is IndirectGPUMemory
255 template IsDirectMemory(gpuValue: GPUValue): untyped = 254 template UsesDirectMemory(gpuData: GPUData): untyped =
256 get(genericParams(typeof(gpuValue)), 1) is DirectGPUMemory 255 get(genericParams(typeof(gpuData)), 1) is DirectGPUMemory
256
257 template size(gpuArray: GPUArray): uint64 =
258 result += (gpuArray.data.len * sizeof(elementType(gpuArray.data))).uint64
259 template size(gpuValue: GPUValue): uint64 =
260 result += sizeof(gpuValue.data).uint64
261
262 proc GetPhysicalDevice(): VkPhysicalDevice =
263 var nDevices: uint32
264 checkVkResult vkEnumeratePhysicalDevices(instance.vk, addr(nDevices), nil)
265 var devices = newSeq[VkPhysicalDevice](nDevices)
266 checkVkResult vkEnumeratePhysicalDevices(instance.vk, addr(nDevices), devices.ToCPointer)
267
268 var score = 0
269 for pDevice in devices:
270 var props: VkPhysicalDeviceProperties
271 vkGetPhysicalDeviceProperties(pDevice, addr(props))
272 if props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU and props.maxImageDimension2D > score:
273 score = props.maxImageDimension2D
274 result = pDevice
275
276 if score == 0
277 for pDevice in devices:
278 var props: VkPhysicalDeviceProperties
279 vkGetPhysicalDeviceProperties(pDevice, addr(props))
280 if props.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU and props.maxImageDimension2D > score:
281 score = props.maxImageDimension2D
282 result = pDevice
283
284 assert score > 0, "Unable to find integrated or discrete GPU"
285
286
287 proc GetDirectMemoryTypeIndex()
288 var physicalProperties: VkPhysicalDeviceMemoryProperties
289 checkVkResult vkGetPhysicalDeviceMemoryProperties(GetPhysicalDevice(), addr physicalProperties)
290
291 var biggestHeap: uint64 = 0
292 result = high(uint32)
293 # try to find host-visible type
294 for i in 0 ..< physicalProperties.memoryTypeCount:
295 let flags = toEnums(physicalProperties.memoryTypes[i].propertyFlags)
296 if VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT in flags:
297 let size = physicalProperties.memoryHeaps[physicalProperties.memoryTypes[i].heapIndex].size
298 if size > biggestHeap:
299 biggestHeap = size
300 result = i
301 assert result != high(uint32), "There is not host visible memory. This is likely a driver bug."
302
303 proc GetQueueFamily(device: VkDevice, qType = VK_QUEUE_GRAPHICS_BIT): VkQueue =
304 assert device.vk.Valid
305 var nQueuefamilies: uint32
306 checkVkResult vkGetPhysicalDeviceQueueFamilyProperties(device.vk, addr nQueuefamilies, nil)
307 var queuFamilies = newSeq[VkQueueFamilyProperties](nQueuefamilies)
308 checkVkResult vkGetPhysicalDeviceQueueFamilyProperties(device.vk, addr nQueuefamilies, queuFamilies.ToCPointer)
309 for i in 0 ..< nQueuefamilies:
310 if qType in toEnums(queuFamilies[i].queueFlags):
311 return i
312 assert false, &"Queue of type {qType} not found"
313
314 proc GetQueue(device: VkDevice, qType = VK_QUEUE_GRAPHICS_BIT): VkQueue =
315 checkVkResult vkGetDeviceQueue(
316 device,
317 GetQueueFamily(device, qType),
318 0,
319 addr(result),
320 )
321
322 #[
323 TODO: Finish this, allow fore easy access to main format
324 proc GetSurfaceFormat*(device: PhysicalDevice): VkFormat =
325 var n_formats: uint32
326 checkVkResult vkGetPhysicalDeviceSurfaceFormatsKHR(device.vk, device.surface, addr(n_formats), nil)
327 result = newSeq[VkSurfaceFormatKHR](n_formats)
328 checkVkResult vkGetPhysicalDeviceSurfaceFormatsKHR(device.vk, device.surface, addr(n_formats), result.ToCPointer)
329 ]#
330
331 template WithSingleUseCommandBuffer*(device: VkDevice, cmd, body: untyped): untyped =
332 # TODO? This is super slow, because we call vkQueueWaitIdle
333 block:
334 var commandBufferPool: VkCommandPool
335 createInfo = VkCommandPoolCreateInfo(
336 sType: VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
337 flags: toBits [VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT],
338 queueFamilyIndex: GetQueueFamily(device),
339 )
340 checkVkResult vkCreateCommandPool(device, addr createInfo, nil, addr(commandBufferPool))
341 var
342 `cmd` {.inject.}: VkCommandBuffer
343 allocInfo = VkCommandBufferAllocateInfo(
344 sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
345 commandPool: commandBufferPool,
346 level: VK_COMMAND_BUFFER_LEVEL_PRIMARY,
347 commandBufferCount: 1,
348 )
349 checkVkResult device.vk.vkAllocateCommandBuffers(addr allocInfo, addr(`cmd`))
350 beginInfo = VkCommandBufferBeginInfo(
351 sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
352 flags: VkCommandBufferUsageFlags(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT),
353 )
354 checkVkResult `cmd`.vkBeginCommandBuffer(addr beginInfo)
355
356 body
357
358 checkVkResult `cmd`.vkEndCommandBuffer()
359 var submitInfo = VkSubmitInfo(
360 sType: VK_STRUCTURE_TYPE_SUBMIT_INFO,
361 commandBufferCount: 1,
362 pCommandBuffers: addr(`cmd`),
363 )
364 checkVkResult vkQueueSubmit(GetQueue(), 1, addr submitInfo, VkFence(0))
365 checkVkResult vkQueueWaitIdle(GetQueue()) # because we want to destroy the commandbuffer pool
366 vkDestroyCommandPool(device, commandBufferPool, nil)
367
368
369 proc UpdateGPUBuffer*(device: VkDevice, gpuData: GPUArray) =
370 when UsesDirectMemory(gpuData):
371 copyMem(cast[pointer](cast[uint64](gpuData.buffer.memory.data) + gpuData.buffer.offset + gpuData.offset), addr(gpuData.data[0]), gpuData.size)
372 else:
373 var
374 stagingBuffer: VkBuffer
375 createInfo = VkBufferCreateInfo(
376 sType: VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
377 flags: VkBufferCreateFlags(0),
378 size: gpuData.size,
379 usage: toBits([VK_BUFFER_USAGE_TRANSFER_SRC_BIT]),
380 sharingMode: VK_SHARING_MODE_EXCLUSIVE,
381 )
382 checkVkResult vkCreateBuffer(
383 device = device,
384 pCreateInfo = addr(createInfo),
385 pAllocator = nil,
386 pBuffer = addr(stagingBuffer),
387 )
388 var
389 stagingMemory: VkDeviceMemory
390 stagingPtr: pointer
391 memoryAllocationInfo = VkMemoryAllocateInfo(
392 sType: VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
393 allocationSize: gpuData.size,
394 memoryTypeIndex: GetDirectMemoryTypeIndex(),
395 )
396 checkVkResult vkAllocateMemory(
397 device,
398 addr(memoryAllocationInfo),
399 nil,
400 addr(stagingMemory),
401 )
402 checkVkResult vkBindBufferMemory(device, stagingBuffer, stagingMemory, 0)
403 checkVkResult vkMapMemory(
404 device = device,
405 memory = stagingMemory,
406 offset = 0'u64,
407 size = VK_WHOLE_SIZE,
408 flags = VkMemoryMapFlags(0),
409 ppData = stagingPtr
410 )
411 copyMem(stagingPtr, addr(gpuData.data[0]), gpuData.size)
412 var stagingRange = VkMappedMemoryRange(
413 sType: VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
414 memory: stagingMemory,
415 size: VK_WHOLE_SIZE,
416 )
417 checkVkResult vkFlushMappedMemoryRanges(device, 1, addr(stagingRange))
418
419 WithSingleUseCommandBuffer(device, commandBuffer):
420 var copyRegion = VkBufferCopy(size: gpuData.size)
421 vkCmdCopyBuffer(commandBuffer, stagingBuffer, gpuData.buffer.vk, 1, addr(copyRegion))
422
423 checkVkResult vkDestroyBuffer(device, stagingBuffer, nil)
424 checkVkResult vkFreeMemory(device, stagingMemory, nil)
257 425
258 converter toVkIndexType(indexType: IndexType): VkIndexType = 426 converter toVkIndexType(indexType: IndexType): VkIndexType =
259 case indexType: 427 case indexType:
260 of None: VK_INDEX_TYPE_NONE_KHR 428 of None: VK_INDEX_TYPE_NONE_KHR
261 of UInt8: VK_INDEX_TYPE_UINT8_EXT 429 of UInt8: VK_INDEX_TYPE_UINT8_EXT
623 result.size = size 791 result.size = size
624 result.needsTransfer = true 792 result.needsTransfer = true
625 793
626 # find a good memory type 794 # find a good memory type
627 var physicalProperties: VkPhysicalDeviceMemoryProperties 795 var physicalProperties: VkPhysicalDeviceMemoryProperties
628 vkGetPhysicalDeviceMemoryProperties(pDevice, addr physicalProperties) 796 checkVkResult vkGetPhysicalDeviceMemoryProperties(pDevice, addr physicalProperties)
629 797
630 var biggestHeap: uint64 = 0 798 var biggestHeap: uint64 = 0
631 var memoryTypeIndex = high(uint32) 799 var memoryTypeIndex = high(uint32)
632 # try to find non-host-visible type 800 # try to find non-host-visible type
633 for i in 0'u32 ..< physicalProperties.memoryTypeCount: 801 for i in 0'u32 ..< physicalProperties.memoryTypeCount:
663 result.size = size 831 result.size = size
664 result.needsFlush = true 832 result.needsFlush = true
665 833
666 # find a good memory type 834 # find a good memory type
667 var physicalProperties: VkPhysicalDeviceMemoryProperties 835 var physicalProperties: VkPhysicalDeviceMemoryProperties
668 vkGetPhysicalDeviceMemoryProperties(pDevice, addr physicalProperties) 836 checkVkResult vkGetPhysicalDeviceMemoryProperties(pDevice, addr physicalProperties)
669 837
670 var biggestHeap: uint64 = 0 838 var biggestHeap: uint64 = 0
671 var memoryTypeIndex = high(uint32) 839 var memoryTypeIndex = high(uint32)
672 # try to find host-visible type 840 # try to find host-visible type
673 for i in 0 ..< physicalProperties.memoryTypeCount: 841 for i in 0 ..< physicalProperties.memoryTypeCount:
681 849
682 assert memoryTypeIndex != high(uint32), "Unable to find indirect memory type" 850 assert memoryTypeIndex != high(uint32), "Unable to find indirect memory type"
683 var allocationInfo = VkMemoryAllocateInfo( 851 var allocationInfo = VkMemoryAllocateInfo(
684 sType: VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, 852 sType: VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
685 allocationSize: result.size, 853 allocationSize: result.size,
686 memoryTypeIndex: memoryTypeIndex, 854 memoryTypeIndex: FindDirectMemoryTypeIndex(pDevice),
687 ) 855 )
688 checkVkResult vkAllocateMemory( 856 checkVkResult vkAllocateMemory(
689 device, 857 device,
690 addr allocationInfo, 858 addr allocationInfo,
691 nil, 859 nil,
698 size = result.size, 866 size = result.size,
699 flags = VkMemoryMapFlags(0), 867 flags = VkMemoryMapFlags(0),
700 ppData = addr(result.data) 868 ppData = addr(result.data)
701 ) 869 )
702 870
703 proc AllocateIndirectBuffer(device: VkDevice, renderData: var RenderData, size: uint64, usage: openArray[VkBufferUsageFlagBits]) = 871 proc AllocateIndirectBuffer(device: VkDevice, renderData: var RenderData, size: uint64, btype: BufferType) =
704 assert size > 0, "Buffer sizes must be larger than 0" 872 assert size > 0, "Buffer sizes must be larger than 0"
705 var buffer = Buffer[IndirectGPUMemory](size: size) 873 var buffer = Buffer[IndirectGPUMemory](size: size)
874
875 let usageFlags = case btype:
876 of VertexBuffer: [VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT]
877 of IndexBuffer: [VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT]
878 of UniformBuffer: [VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT]
706 879
707 # iterate through memory areas to find big enough free space 880 # iterate through memory areas to find big enough free space
708 for (memory, offset) in renderData.indirectMemory.mitems: 881 for (memory, offset) in renderData.indirectMemory.mitems:
709 if memory.size - offset >= size: 882 if memory.size - offset >= size:
710 buffer.offset = offset 883 buffer.offset = offset
711 # create buffer 884 # create buffer
712 var createInfo = VkBufferCreateInfo( 885 var createInfo = VkBufferCreateInfo(
713 sType: VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, 886 sType: VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
714 flags: VkBufferCreateFlags(0), 887 flags: VkBufferCreateFlags(0),
715 size: buffer.size, 888 size: buffer.size,
716 usage: toBits(@usage & @[VK_BUFFER_USAGE_TRANSFER_DST_BIT]), # ensure we can transfer to this buffer 889 usage: toBits(usageFlags),
717 sharingMode: VK_SHARING_MODE_EXCLUSIVE, 890 sharingMode: VK_SHARING_MODE_EXCLUSIVE,
718 ) 891 )
719 checkVkResult vkCreateBuffer( 892 checkVkResult vkCreateBuffer(
720 device = device, 893 device = device,
721 pCreateInfo = addr createInfo, 894 pCreateInfo = addr createInfo,
722 pAllocator = nil, 895 pAllocator = nil,
723 pBuffer = addr(buffer.vk) 896 pBuffer = addr(buffer.vk)
724 ) 897 )
725 checkVkResult vkBindBufferMemory(device, buffer.vk, memory.vk, buffer.offset) 898 checkVkResult vkBindBufferMemory(device, buffer.vk, memory.vk, buffer.offset)
726 renderData.indirectBuffers.add buffer 899 renderData.indirectBuffers.add (buffer, btype, 0'u64)
727 # update memory area offset 900 # update memory area offset
728 offset = offset + size 901 offset = alignedTo(offset + size, MEMORY_ALIGNMENT)
729 if offset mod MEMORY_ALIGNMENT != 0:
730 offset = offset + MEMORY_ALIGNMENT - (offset mod MEMORY_ALIGNMENT)
731 return 902 return
732 903
733 assert false, "Did not find allocated memory region with enough space" 904 assert false, "Did not find allocated memory region with enough space"
734 905
735 proc AllocateDirectBuffer(device: VkDevice, renderData: var RenderData, size: uint64, usage: openArray[VkBufferUsageFlagBits]) = 906 proc AllocateDirectBuffer(device: VkDevice, renderData: var RenderData, size: uint64, btype: BufferType) =
736 assert size > 0, "Buffer sizes must be larger than 0" 907 assert size > 0, "Buffer sizes must be larger than 0"
737 var buffer = Buffer[DirectGPUMemory](size: size) 908 var buffer = Buffer[DirectGPUMemory](size: size)
909
910 let usageFlags = case btype:
911 of VertexBuffer: [VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT]
912 of IndexBuffer: [VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT]
913 of UniformBuffer: [VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT]
738 914
739 # iterate through memory areas to find big enough free space 915 # iterate through memory areas to find big enough free space
740 for (memory, offset) in renderData.directMemory.mitems: 916 for (memory, offset) in renderData.directMemory.mitems:
741 if memory.size - offset >= size: 917 if memory.size - offset >= size:
742 buffer.offset = offset 918 buffer.offset = offset
743 # create buffer 919 # create buffer
744 var createInfo = VkBufferCreateInfo( 920 var createInfo = VkBufferCreateInfo(
745 sType: VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, 921 sType: VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
746 flags: VkBufferCreateFlags(0), 922 flags: VkBufferCreateFlags(0),
747 size: buffer.size, 923 size: buffer.size,
748 usage: toBits(usage), 924 usage: toBits(usageFlags),
749 sharingMode: VK_SHARING_MODE_EXCLUSIVE, 925 sharingMode: VK_SHARING_MODE_EXCLUSIVE,
750 ) 926 )
751 checkVkResult vkCreateBuffer( 927 checkVkResult vkCreateBuffer(
752 device = device, 928 device = device,
753 pCreateInfo = addr createInfo, 929 pCreateInfo = addr createInfo,
754 pAllocator = nil, 930 pAllocator = nil,
755 pBuffer = addr(buffer.vk) 931 pBuffer = addr(buffer.vk)
756 ) 932 )
757 checkVkResult vkBindBufferMemory(device, buffer.vk, memory.vk, buffer.offset) 933 checkVkResult vkBindBufferMemory(device, buffer.vk, memory.vk, buffer.offset)
758 renderData.directBuffers.add buffer 934 renderData.directBuffers.add (buffer, btype, 0'u64)
759 # update memory area offset 935 # update memory area offset
760 offset = offset + size 936 offset = alignedTo(offset + size, MEMORY_ALIGNMENT)
761 if offset mod MEMORY_ALIGNMENT != 0:
762 offset = offset + MEMORY_ALIGNMENT - (offset mod MEMORY_ALIGNMENT)
763 return 937 return
764 938
765 assert false, "Did not find allocated memory region with enough space" 939 assert false, "Did not find allocated memory region with enough space"
766 940
767 proc InitRenderData(device: VkDevice, pDevice: VkPhysicalDevice, descriptorPoolLimit = 1024'u32): RenderData = 941 proc InitRenderData(device: VkDevice, pDevice: VkPhysicalDevice, descriptorPoolLimit = 1024'u32): RenderData =
781 # allocate some memory 955 # allocate some memory
782 var initialAllocationSize = 1_000_000_000'u64 # TODO: make this more dynamic or something 956 var initialAllocationSize = 1_000_000_000'u64 # TODO: make this more dynamic or something
783 result.indirectMemory = @[(AllocateIndirectMemory(device, pDevice, size = initialAllocationSize), 0'u64)] 957 result.indirectMemory = @[(AllocateIndirectMemory(device, pDevice, size = initialAllocationSize), 0'u64)]
784 result.directMemory = @[(AllocateDirectMemory(device, pDevice, size = initialAllocationSize), 0'u64)] 958 result.directMemory = @[(AllocateDirectMemory(device, pDevice, size = initialAllocationSize), 0'u64)]
785 959
960 # For the Get*BufferSize:
961 # BUFFER_ALIGNMENT is just added for a rough estimate, to ensure we have enough space to align when binding
786 proc GetIndirectBufferSizes[T](data: T): uint64 = 962 proc GetIndirectBufferSizes[T](data: T): uint64 =
787 # return buffer sizes for direct and indirect buffers
788 # BUFFER_ALIGNMENT is just added for a rough estimate, to ensure we have enough space to align when binding
789 for name, value in fieldPairs(data): 963 for name, value in fieldPairs(data):
790 when not hasCustomPragma(value, VertexIndices) 964 when not hasCustomPragma(value, VertexIndices):
791 when typeof(value) is GPUArray: 965 when typeof(value) is GPUData:
792 if not IsDirectMemory(value): 966 when UsesIndirectMemory(value):
793 result += (value.data.len * sizeof(elementType(value.data))).uint64 + BUFFER_ALIGNMENT 967 result += value.size + BUFFER_ALIGNMENT
794 when typeof(value) is GPUValue:
795 if not IsDirectMemory(value):
796 result += sizeof(value.data).uint64 + BUFFER_ALIGNMENT
797 proc GetDirectBufferSizes[T](data: T): uint64 = 968 proc GetDirectBufferSizes[T](data: T): uint64 =
798 # return buffer sizes for direct and indirect buffers
799 # BUFFER_ALIGNMENT is just added for a rough estimate, to ensure we have enough space to align when binding
800 for name, value in fieldPairs(data): 969 for name, value in fieldPairs(data):
801 when not hasCustomPragma(value, VertexIndices) 970 when not hasCustomPragma(value, VertexIndices):
802 when typeof(value) is GPUArray: 971 when typeof(value) is GPUData:
803 if IsDirectMemory(value): 972 when UsesDirectMemory(value):
804 result += (value.data.len * sizeof(elementType(value.data))).uint64 + BUFFER_ALIGNMENT 973 result += value.size + BUFFER_ALIGNMENT
805 when typeof(value) is GPUValue:
806 if IsDirectMemory(value):
807 result += sizeof(value.data).uint64 + BUFFER_ALIGNMENT
808
809 proc GetIndirectIndexBufferSizes[T](data: T): uint64 = 974 proc GetIndirectIndexBufferSizes[T](data: T): uint64 =
810 for name, value in fieldPairs(data): 975 for name, value in fieldPairs(data):
811 when hasCustomPragma(value, VertexIndices): 976 when hasCustomPragma(value, VertexIndices):
812 static: assert typeof(value) is GPUArray, "Index buffers must be of type GPUArray" 977 static: assert typeof(value) is GPUArray, "Index buffers must be of type GPUArray"
813 static: assert elementType(value.data) is uint8 or elementType(value.data) is uint16 or elementType(value.data) is uint32 978 static: assert elementType(value.data) is uint8 or elementType(value.data) is uint16 or elementType(value.data) is uint32
814 if not IsDirectMemory(value): 979 when UsesIndirectMemory(value):
815 result += (value.data.len * sizeof(elementType(value.data))).uint64 + BUFFER_ALIGNMENT 980 result += value.size + BUFFER_ALIGNMENT
816
817 proc GetDirectIndexBufferSizes[T](data: T): uint64 = 981 proc GetDirectIndexBufferSizes[T](data: T): uint64 =
818 for name, value in fieldPairs(data): 982 for name, value in fieldPairs(data):
819 when hasCustomPragma(value, VertexIndices): 983 when hasCustomPragma(value, VertexIndices):
820 static: assert typeof(value) is GPUArray, "Index buffers must be of type GPUArray" 984 static: assert typeof(value) is GPUArray, "Index buffers must be of type GPUArray"
821 static: assert elementType(value.data) is uint8 or elementType(value.data) is uint16 or elementType(value.data) is uint32 985 static: assert elementType(value.data) is uint8 or elementType(value.data) is uint16 or elementType(value.data) is uint32
822 if IsDirectMemory(value): 986 when UsesDirectMemory(value):
823 result += (value.data.len * sizeof(elementType(value.data))).uint64 + BUFFER_ALIGNMENT 987 result += value.size + BUFFER_ALIGNMENT
824 988
989 proc AssignIndirectBuffers[T](data: T, renderdata: var RenderData, btype: BufferType) =
990 for name, value in fieldPairs(data):
991 when typeof(value) is GPUData:
992 when UsesIndirectMemory(value):
993 # find next buffer of correct type with enough free space
994 var foundBuffer = false
995 for (buffer, bt, offset) in renderData.indirectBuffers.mitems:
996 if bt == btype and buffer.size - offset >= size:
997 assert not value.buffer.vk.Valid, "GPUData-Buffer has already been assigned"
998 assert buffer.vk.Valid, "RenderData-Buffer has not yet been created"
999 value.buffer = buffer
1000 value.offset = offset
1001 offset = alignedTo(offset + value.size, BUFFER_ALIGNMENT)
1002 foundBuffer = true
1003 break
1004 assert foundBuffer, &"Unable to find large enough '{btype}' for '{data}'"
1005 proc AssignDirectBuffers[T](data: T, renderdata: var RenderData, btype: BufferType) =
1006 for name, value in fieldPairs(data):
1007 when typeof(value) is GPUData:
1008 when UsesDirectMemory(value):
1009 # find next buffer of correct type with enough free space
1010 var foundBuffer = false
1011 for (buffer, bt, offset) in renderData.directBuffers.mitems:
1012 if bt == btype and buffer.size - offset >= size:
1013 assert not value.buffer.vk.Valid, "GPUData-Buffer has already been assigned"
1014 assert buffer.vk.Valid, "RenderData-Buffer has not yet been created"
1015 value.buffer = buffer
1016 value.offset = offset
1017 offset = alignedTo(offset + value.size, BUFFER_ALIGNMENT)
1018 foundBuffer = true
1019 break
1020 assert foundBuffer, &"Unable to find large enough '{btype}' for '{data}'"
825 1021
826 proc WriteDescriptors[TShader](device: VkDevice, descriptorSets: array[INFLIGHTFRAMES.int, VkDescriptorSet]) = 1022 proc WriteDescriptors[TShader](device: VkDevice, descriptorSets: array[INFLIGHTFRAMES.int, VkDescriptorSet]) =
827 var descriptorSetWrites: seq[VkWriteDescriptorSet] 1023 var descriptorSetWrites: seq[VkWriteDescriptorSet]
828 # map (buffer + offset + range) to descriptor 1024 # map (buffer + offset + range) to descriptor
829 # map (texture) to descriptor 1025 # map (texture) to descriptor
861 descriptorType: descriptorType, 1057 descriptorType: descriptorType,
862 descriptorCount: descriptorCount, 1058 descriptorCount: descriptorCount,
863 pImageInfo: addr(imageInfo), 1059 pImageInfo: addr(imageInfo),
864 pBufferInfo: nil, 1060 pBufferInfo: nil,
865 ) 1061 )
866 vkUpdateDescriptorSets(device, uint32(descriptorSetWrites.len), descriptorSetWrites.ToCPointer, 0, nil) 1062 checkVkResult vkUpdateDescriptorSets(device, uint32(descriptorSetWrites.len), descriptorSetWrites.ToCPointer, 0, nil)
867 1063
868 proc Bind[T](pipeline: Pipeline[T], commandBuffer: VkCommandBuffer, currentFrameInFlight: int) = 1064 proc Bind[T](pipeline: Pipeline[T], commandBuffer: VkCommandBuffer, currentFrameInFlight: int) =
869 commandBuffer.vkCmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipeline) 1065 commandBuffer.vkCmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipeline)
870 #[ 1066 #[
871 commandBuffer.vkCmdBindDescriptorSets( 1067 commandBuffer.vkCmdBindDescriptorSets(
969 assert typeof(globalValue.data) is typeof(inputValue), "Shader input " & tt.name(TShader) & "." & inputName & " is of type '" & tt.name(typeof(inputValue)) & "' but global attribute is of type '" & tt.name(typeof(globalValue.data)) & "'" 1165 assert typeof(globalValue.data) is typeof(inputValue), "Shader input " & tt.name(TShader) & "." & inputName & " is of type '" & tt.name(typeof(inputValue)) & "' but global attribute is of type '" & tt.name(typeof(globalValue.data)) & "'"
970 foundField = true 1166 foundField = true
971 assert foundField, "Shader input '" & tt.name(TShader) & "." & inputName & ": " & tt.name(typeof(inputValue)) & "' not found in '" & tt.name(TMesh) & "|" & tt.name(TGlobals) & "'" 1167 assert foundField, "Shader input '" & tt.name(TShader) & "." & inputName & ": " & tt.name(typeof(inputValue)) & "' not found in '" & tt.name(TMesh) & "|" & tt.name(TGlobals) & "'"
972 1168
973 1169
974 proc Render[TShader, TMesh, TInstance, TUniforms, TGlobals]( 1170 proc Render[TShader, TUniforms, TGlobals, TMesh, TInstance](
1171 commandBuffer: VkCommandBuffer,
975 pipeline: Pipeline[TShader], 1172 pipeline: Pipeline[TShader],
976 renderable: Renderable[TMesh, TInstance],
977 uniforms: TUniforms, 1173 uniforms: TUniforms,
978 globals: TGlobals, 1174 globals: TGlobals,
979 commandBuffer: VkCommandBuffer, 1175 mesh: TMesh,
1176 instances: TInstance,
980 ) = 1177 ) =
981 static: AssertCompatible(TShader, TMesh, TInstance, TUniforms, TGlobals) 1178 static: AssertCompatible(TShader, TMesh, TInstance, TUniforms, TGlobals)
1179 #[
982 if renderable.vertexBuffers.len > 0: 1180 if renderable.vertexBuffers.len > 0:
983 commandBuffer.vkCmdBindVertexBuffers( 1181 commandBuffer.vkCmdBindVertexBuffers(
984 firstBinding = 0'u32, 1182 firstBinding = 0'u32,
985 bindingCount = uint32(renderable.vertexBuffers.len), 1183 bindingCount = uint32(renderable.vertexBuffers.len),
986 pBuffers = renderable.vertexBuffers.ToCPointer(), 1184 pBuffers = renderable.vertexBuffers.ToCPointer(),
1004 vertexCount = renderable.vertexCount, 1202 vertexCount = renderable.vertexCount,
1005 instanceCount = renderable.instanceCount, 1203 instanceCount = renderable.instanceCount,
1006 firstVertex = 0, 1204 firstVertex = 0,
1007 firstInstance = 0 1205 firstInstance = 0
1008 ) 1206 )
1207 ]#
1009 1208
1010 when isMainModule: 1209 when isMainModule:
1011 import semicongine/platform/window 1210 import semicongine/platform/window
1012 import semicongine/vulkan/instance 1211 import semicongine/vulkan/instance
1013 import semicongine/vulkan/device 1212 import semicongine/vulkan/device
1053 vertexCode: string = "void main() {}" 1252 vertexCode: string = "void main() {}"
1054 fragmentCode: string = "void main() {}" 1253 fragmentCode: string = "void main() {}"
1055 1254
1056 let w = CreateWindow("test2") 1255 let w = CreateWindow("test2")
1057 putEnv("VK_LAYER_ENABLES", "VALIDATION_CHECK_ENABLE_VENDOR_SPECIFIC_AMD,VALIDATION_CHECK_ENABLE_VENDOR_SPECIFIC_NVIDIA,VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXTVK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT,VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT") 1256 putEnv("VK_LAYER_ENABLES", "VALIDATION_CHECK_ENABLE_VENDOR_SPECIFIC_AMD,VALIDATION_CHECK_ENABLE_VENDOR_SPECIFIC_NVIDIA,VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXTVK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT,VK_VALIDATION_FEATURE_ENABLE_SYNCHRONIZATION_VALIDATION_EXT")
1058 let i = w.CreateInstance( 1257 let vulkan = w.CreateInstance(
1059 vulkanVersion = VK_MAKE_API_VERSION(0, 1, 3, 0), 1258 vulkanVersion = VK_MAKE_API_VERSION(0, 1, 3, 0),
1060 instanceExtensions = @[], 1259 instanceExtensions = @[],
1061 layers = @["VK_LAYER_KHRONOS_validation"], 1260 layers = @["VK_LAYER_KHRONOS_validation"],
1062 ) 1261 )
1063 1262
1064 let selectedPhysicalDevice = i.GetPhysicalDevices().FilterBestGraphics() 1263 let dev = vulkan.CreateDevice(
1065 let dev = i.CreateDevice( 1264 GetPhysicalDevice(),
1066 selectedPhysicalDevice,
1067 enabledExtensions = @[], 1265 enabledExtensions = @[],
1068 selectedPhysicalDevice.FilterForGraphicsPresentationQueues() 1266 [GetQueueFamily()],
1069 ) 1267 )
1070 let frameWidth = 100'u32 1268 let frameWidth = 100'u32
1071 let frameHeight = 100'u32 1269 let frameHeight = 100'u32
1072 1270
1073 var myMesh1 = MeshA( 1271 var myMesh1 = MeshA(
1092 var myGlobals: GlobalsA 1290 var myGlobals: GlobalsA
1093 1291
1094 # setup for rendering (TODO: swapchain & framebuffers) 1292 # setup for rendering (TODO: swapchain & framebuffers)
1095 1293
1096 # renderpass 1294 # renderpass
1097 let renderpass = dev.vk.CreateRenderPass(dev.physicalDevice.GetSurfaceFormats().FilterSurfaceFormat().format) 1295 let renderpass = CreateRenderPass(dev.vk, dev.physicalDevice.GetSurfaceFormats().FilterSurfaceFormat().format)
1098 1296
1099 # shaders 1297 # shaders
1100 const shader = ShaderA() 1298 const shader = ShaderA()
1101 let shaderObject = dev.vk.CompileShader(shader) 1299 let shaderObject = dev.vk.CompileShader(shader)
1102 var pipeline1 = CreatePipeline(dev.vk, renderPass = renderpass, shaderObject) 1300 var pipeline1 = CreatePipeline(device = dev.vk, renderPass = renderpass, shader = shaderObject)
1103 1301
1104 var renderdata = InitRenderData(dev.vk, dev.physicalDevice.vk) 1302 var renderdata = InitRenderData(dev.vk, dev.physicalDevice.vk)
1105 1303
1106 # create descriptor sets 1304 # create descriptor sets
1107 #[ 1305 #[
1126 # 1324 #
1127 # upload all textures 1325 # upload all textures
1128 # write descriptors for textures and uniform buffers 1326 # write descriptors for textures and uniform buffers
1129 # 1327 #
1130 ]# 1328 ]#
1131 var myRenderable: Renderable[MeshA, InstanceA] 1329
1132 1330 # buffer allocation
1133 var 1331 var
1134 indirectVertexSizes = 0'u64 1332 indirectVertexSizes = 0'u64
1135 directVertexSizes = 0'u64 1333 directVertexSizes = 0'u64
1136 indirectIndexSizes = 0'u64 1334 indirectIndexSizes = 0'u64
1137 directIndexSizes = 0'u64 1335 directIndexSizes = 0'u64
1139 directUniformSizes = 0'u64 1337 directUniformSizes = 0'u64
1140 1338
1141 indirectVertexSizes += GetIndirectBufferSizes(myMesh1) 1339 indirectVertexSizes += GetIndirectBufferSizes(myMesh1)
1142 indirectVertexSizes += GetIndirectBufferSizes(instances1) 1340 indirectVertexSizes += GetIndirectBufferSizes(instances1)
1143 if indirectVertexSizes > 0: 1341 if indirectVertexSizes > 0:
1144 AllocateIndirectBuffer(dev.vk, renderdata, indirectVertexSizes, [VK_BUFFER_USAGE_VERTEX_BUFFER_BIT]) 1342 AllocateIndirectBuffer(dev.vk, renderdata, indirectVertexSizes, VertexBuffer)
1145 1343
1146 directVertexSizes += GetDirectBufferSizes(myMesh1) 1344 directVertexSizes += GetDirectBufferSizes(myMesh1)
1147 directVertexSizes += GetDirectBufferSizes(instances1) 1345 directVertexSizes += GetDirectBufferSizes(instances1)
1148 if directVertexSizes > 0: 1346 if directVertexSizes > 0:
1149 AllocateDirectBuffer(dev.vk, renderdata, directVertexSizes, [VK_BUFFER_USAGE_VERTEX_BUFFER_BIT]) 1347 AllocateDirectBuffer(dev.vk, renderdata, directVertexSizes, VertexBuffer)
1150 1348
1151 indirectIndexSizes += GetIndirectIndexBufferSizes(myMesh1) 1349 indirectIndexSizes += GetIndirectIndexBufferSizes(myMesh1)
1152 if indirectIndexSizes > 0: 1350 if indirectIndexSizes > 0:
1153 AllocateIndirectBuffer(dev.vk, renderdata, indirectIndexSizes, [VK_BUFFER_USAGE_INDEX_BUFFER_BIT]) 1351 AllocateIndirectBuffer(dev.vk, renderdata, indirectIndexSizes, IndexBuffer)
1154 1352
1155 directIndexSizes += GetDirectIndexBufferSizes(myMesh1) 1353 directIndexSizes += GetDirectIndexBufferSizes(myMesh1)
1156 if directIndexSizes > 0: 1354 if directIndexSizes > 0:
1157 AllocateIndirectBuffer(dev.vk, renderdata, directIndexSizes, [VK_BUFFER_USAGE_INDEX_BUFFER_BIT]) 1355 AllocateDirectBuffer(dev.vk, renderdata, directIndexSizes, IndexBuffer)
1158 1356
1159 indirectUniformSizes += GetIndirectBufferSizes(uniforms1) 1357 indirectUniformSizes += GetIndirectBufferSizes(uniforms1)
1160 indirectUniformSizes += GetIndirectBufferSizes(myGlobals) 1358 indirectUniformSizes += GetIndirectBufferSizes(myGlobals)
1161 if indirectUniformSizes > 0: 1359 if indirectUniformSizes > 0:
1162 AllocateIndirectBuffer(dev.vk, renderdata, indirectUniformSizes, [VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT]) 1360 AllocateIndirectBuffer(dev.vk, renderdata, indirectUniformSizes, UniformBuffer)
1163 1361
1164 directUniformSizes += GetDirectBufferSizes(uniforms1) 1362 directUniformSizes += GetDirectBufferSizes(uniforms1)
1165 directUniformSizes += GetDirectBufferSizes(myGlobals) 1363 directUniformSizes += GetDirectBufferSizes(myGlobals)
1166 if directUniformSizes > 0: 1364 if directUniformSizes > 0:
1167 AllocateDirectBuffer(dev.vk, renderdata, directUniformSizes, [VK_BUFFER_USAGE_VERTEX_BUFFER_BIT]) 1365 AllocateDirectBuffer(dev.vk, renderdata, directUniformSizes, UniformBuffer)
1366
1367 # buffer assignment
1368
1369 AssignIndirectBuffers(data = myMesh1, renderdata = RenderData, btype = VertexBuffer)
1370 AssignDirectBuffers(data = myMesh1, renderdata = RenderData, btype = VertexBuffer)
1371 AssignIndirectBuffers(data = myMesh1, renderdata = RenderData, btype = IndexBuffer)
1372 AssignDirectBuffers(data = myMesh1, renderdata = RenderData, btype = IndexBuffer)
1373
1374 AssignIndirectBuffers(data = instances1, renderdata = RenderData, btype = VertexBuffer)
1375 AssignDirectBuffers(data = instances1, renderdata = RenderData, btype = VertexBuffer)
1376
1377 AssignIndirectBuffers(data = uniforms1, renderdata = RenderData, btype = UniformBuffer)
1378 AssignDirectBuffers(data = uniforms1, renderdata = RenderData, btype = UniformBuffer)
1379 AssignIndirectBuffers(data = myGlobals, renderdata = RenderData, btype = UniformBuffer)
1380 AssignDirectBuffers(data = myGlobals, renderdata = RenderData, btype = UniformBuffer)
1381
1382 UpdateGPUBuffer()
1168 1383
1169 # descriptors 1384 # descriptors
1170 # WriteDescriptors(dev.vk, pipeline1) 1385 # WriteDescriptors(dev.vk, pipeline1)
1171 1386
1172 # command buffer 1387 # command buffer
1173 var 1388 var
1174 commandBufferPool: VkCommandPool 1389 commandBufferPool: VkCommandPool
1175 cmdBuffers: array[INFLIGHTFRAMES.int, VkCommandBuffer]
1176 createInfo = VkCommandPoolCreateInfo( 1390 createInfo = VkCommandPoolCreateInfo(
1177 sType: VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, 1391 sType: VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
1178 flags: toBits [VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT], 1392 flags: toBits [VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT],
1179 queueFamilyIndex: dev.FirstGraphicsQueue().get().family.index, 1393 queueFamilyIndex: GetQueueFamily(dev.vk),
1180 ) 1394 )
1181 checkVkResult vkCreateCommandPool(dev.vk, addr createInfo, nil, addr commandBufferPool) 1395 checkVkResult vkCreateCommandPool(dev.vk, addr createInfo, nil, addr commandBufferPool)
1182 var allocInfo = VkCommandBufferAllocateInfo( 1396 var
1183 sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, 1397 cmdBuffers: array[INFLIGHTFRAMES.int, VkCommandBuffer]
1184 commandPool: commandBufferPool, 1398 allocInfo = VkCommandBufferAllocateInfo(
1185 level: VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1399 sType: VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
1186 commandBufferCount: INFLIGHTFRAMES, 1400 commandPool: commandBufferPool,
1187 ) 1401 level: VK_COMMAND_BUFFER_LEVEL_PRIMARY,
1402 commandBufferCount: INFLIGHTFRAMES,
1403 )
1188 checkVkResult vkAllocateCommandBuffers(dev.vk, addr allocInfo, cmdBuffers.ToCPointer) 1404 checkVkResult vkAllocateCommandBuffers(dev.vk, addr allocInfo, cmdBuffers.ToCPointer)
1189 1405
1190 # start command buffer 1406 # start command buffer
1191 block: 1407 block:
1192 let 1408 let
1205 var 1421 var
1206 clearColors = [VkClearValue(color: VkClearColorValue(float32: [0, 0, 0, 0]))] 1422 clearColors = [VkClearValue(color: VkClearColorValue(float32: [0, 0, 0, 0]))]
1207 renderPassInfo = VkRenderPassBeginInfo( 1423 renderPassInfo = VkRenderPassBeginInfo(
1208 sType: VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, 1424 sType: VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
1209 renderPass: renderpass, 1425 renderPass: renderpass,
1210 framebuffer: currentFramebuffer, 1426 framebuffer: currentFramebuffer, # TODO
1211 renderArea: VkRect2D( 1427 renderArea: VkRect2D(
1212 offset: VkOffset2D(x: 0, y: 0), 1428 offset: VkOffset2D(x: 0, y: 0),
1213 extent: VkExtent2D(width: frameWidth, height: frameHeight), 1429 extent: VkExtent2D(width: frameWidth, height: frameHeight),
1214 ), 1430 ),
1215 clearValueCount: uint32(clearColors.len), 1431 clearValueCount: uint32(clearColors.len),
1225 ) 1441 )
1226 scissor = VkRect2D( 1442 scissor = VkRect2D(
1227 offset: VkOffset2D(x: 0, y: 0), 1443 offset: VkOffset2D(x: 0, y: 0),
1228 extent: VkExtent2D(width: frameWidth, height: frameHeight) 1444 extent: VkExtent2D(width: frameWidth, height: frameHeight)
1229 ) 1445 )
1230 vkCmdBeginRenderPass(cmd, addr(renderPassInfo), VK_SUBPASS_CONTENTS_INLINE) 1446 checkVkResult vkCmdBeginRenderPass(cmd, addr(renderPassInfo), VK_SUBPASS_CONTENTS_INLINE)
1231 1447
1232 # setup viewport 1448 # setup viewport
1233 vkCmdSetViewport(cmd, firstViewport = 0, viewportCount = 1, addr(viewport)) 1449 vkCmdSetViewport(cmd, firstViewport = 0, viewportCount = 1, addr(viewport))
1234 vkCmdSetScissor(cmd, firstScissor = 0, scissorCount = 1, addr(scissor)) 1450 vkCmdSetScissor(cmd, firstScissor = 0, scissorCount = 1, addr(scissor))
1235 1451
1237 block: 1453 block:
1238 Bind(pipeline1, cmd, currentFrameInFlight = currentFrameInFlight) 1454 Bind(pipeline1, cmd, currentFrameInFlight = currentFrameInFlight)
1239 1455
1240 # render object, will be loop 1456 # render object, will be loop
1241 block: 1457 block:
1242 Render(pipeline1, myRenderable, uniforms1, myGlobals, cmd) 1458 Render(cmd, pipeline1, uniforms1, myGlobals, myMesh1, instances1)
1243 1459
1244 vkCmdEndRenderPass(cmd) 1460 vkCmdEndRenderPass(cmd)
1245 checkVkResult cmd.vkEndCommandBuffer() 1461 checkVkResult cmd.vkEndCommandBuffer()