comparison static_utils.nim @ 1186:52e926efaac5 compiletime-tests

sync from bedroom to office
author sam <sam@basx.dev>
date Sun, 07 Jul 2024 00:36:15 +0700
parents 565fcfde427a
children b14861786b61
comparison
equal deleted inserted replaced
1185:565fcfde427a 1186:52e926efaac5
1 import std/algorithm
1 import std/os 2 import std/os
2 import std/enumerate 3 import std/enumerate
3 import std/hashes 4 import std/hashes
4 import std/macros 5 import std/macros
5 import std/strformat 6 import std/strformat
17 template VertexAttribute {.pragma.} 18 template VertexAttribute {.pragma.}
18 template InstanceAttribute {.pragma.} 19 template InstanceAttribute {.pragma.}
19 template Pass {.pragma.} 20 template Pass {.pragma.}
20 template PassFlat {.pragma.} 21 template PassFlat {.pragma.}
21 template ShaderOutput {.pragma.} 22 template ShaderOutput {.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 BUFFER_ALIGNMENT = 64'u64 # align offsets inside buffers along this alignment 26 const BUFFER_ALIGNMENT = 64'u64 # align offsets inside buffers along this alignment
27 const MEMORY_BLOCK_ALLOCATION_SIZE = 100_000_000'u64 # ca. 100mb per block, seems reasonable
28 const BUFFER_ALLOCATION_SIZE = 9_000_000'u64 # ca. 9mb per block, seems reasonable, can put 10 buffers into one memory block
27 29
28 # some globals that will (likely?) never change during the life time of the engine 30 # some globals that will (likely?) never change during the life time of the engine
29 type 31 type
30 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] 32 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]
31 TextureType = TVec1[uint8] | TVec2[uint8] | TVec3[uint8] | TVec4[uint8] 33 TextureType = TVec1[uint8] | TVec2[uint8] | TVec3[uint8] | TVec4[uint8]
35 fragmentShader: VkShaderModule 37 fragmentShader: VkShaderModule
36 38
37 IndexType = enum 39 IndexType = enum
38 None, UInt8, UInt16, UInt32 40 None, UInt8, UInt16, UInt32
39 41
40 IndirectGPUMemory = object 42 MemoryBlock = object
41 vk: VkDeviceMemory 43 vk: VkDeviceMemory
42 size: uint64 44 size: uint64
43 needsTransfer: bool # usually true 45 rawPointer: pointer # if not nil, this is mapped memory
44 DirectGPUMemory = object 46 offsetNextFree: uint64
45 vk: VkDeviceMemory 47
46 size: uint64 48 BufferType = enum
47 rawPointer: pointer 49 VertexBuffer
48 GPUMemory = IndirectGPUMemory | DirectGPUMemory 50 VertexBufferMapped
49 51 IndexBuffer
50 Buffer[TMemory: GPUMemory] = object 52 IndexBufferMapped
53 UniformBuffer
54 UniformBufferMapped
55 Buffer = object
51 vk: VkBuffer 56 vk: VkBuffer
52 size: uint64 57 size: uint64
53 rawPointer: pointer 58 rawPointer: pointer # if not nil, buffer is using mapped memory
54 Texture[T: TextureType, TMemory: GPUMemory] = object 59 offsetNextFree: uint64
60
61 Texture[T: TextureType] = object
55 vk: VkImage 62 vk: VkImage
56 memory: TMemory 63 memory: MemoryBlock
57 format: VkFormat 64 format: VkFormat
58 imageview: VkImageView 65 imageview: VkImageView
59 sampler: VkSampler 66 sampler: VkSampler
60 offset: uint64 67 offset: uint64
61 size: uint64 68 size: uint64
62 width: uint32 69 width: uint32
63 height: uint32 70 height: uint32
64 data: seq[T] 71 data: seq[T]
65 72
66 GPUArray[T: SupportedGPUType, TMemory: GPUMemory] = object 73 GPUArray[T: SupportedGPUType, TBuffer: static BufferType] = object
67 data: seq[T] 74 data: seq[T]
68 buffer: Buffer[TMemory] 75 buffer: Buffer
69 offset: uint64 76 offset: uint64
70 GPUValue[T: object|array, TMemory: GPUMemory] = object 77 GPUValue[T: object|array, TBuffer: static BufferType] = object
71 data: T 78 data: T
72 buffer: Buffer[TMemory] 79 buffer: Buffer
73 offset: uint64 80 offset: uint64
74 GPUData = GPUArray | GPUValue 81 GPUData = GPUArray | GPUValue
75 82
76 DescriptorSetType = enum 83 DescriptorSetType = enum
77 GlobalSet 84 GlobalSet
82 89
83 Pipeline[TShader] = object 90 Pipeline[TShader] = object
84 vk: VkPipeline 91 vk: VkPipeline
85 layout: VkPipelineLayout 92 layout: VkPipelineLayout
86 descriptorSetLayouts: array[DescriptorSetType, VkDescriptorSetLayout] 93 descriptorSetLayouts: array[DescriptorSetType, VkDescriptorSetLayout]
87 BufferType = enum
88 VertexBuffer, IndexBuffer, UniformBuffer
89 RenderData = object 94 RenderData = object
90 descriptorPool: VkDescriptorPool 95 descriptorPool: VkDescriptorPool
91 # tuple is memory and offset to next free allocation in that memory 96 memory: array[VK_MAX_MEMORY_TYPES.int, seq[MemoryBlock]]
92 indirectMemory: seq[tuple[memory: IndirectGPUMemory, usedOffset: uint64]] 97 buffers: array[BufferType, seq[Buffer]]
93 directMemory: seq[tuple[memory: DirectGPUMemory, usedOffset: uint64]]
94 indirectBuffers: seq[tuple[buffer: Buffer[IndirectGPUMemory], btype: BufferType, usedOffset: uint64]]
95 directBuffers: seq[tuple[buffer: Buffer[DirectGPUMemory], btype: BufferType, usedOffset: uint64]]
96 98
97 func size(texture: Texture): uint64 = 99 func size(texture: Texture): uint64 =
98 texture.data.len * sizeof(elementType(texture.data)) 100 texture.data.len * sizeof(elementType(texture.data))
99 101
100 func depth(texture: Texture): int = 102 func depth(texture: Texture): int =
101 default(elementType(texture.data)).len 103 default(elementType(texture.data)).len
102 104
103 func pointerOffset[T: SomeInteger](p: pointer, offset: T): pointer = 105 func pointerAddOffset[T: SomeInteger](p: pointer, offset: T): pointer =
104 cast[pointer](cast[T](p) + offset) 106 cast[pointer](cast[T](p) + offset)
105 107
108 func usage(bType: BufferType): seq[VkBufferUsageFlagBits] =
109 case bType:
110 of VertexBuffer: @[VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT]
111 of VertexBufferMapped: @[VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT]
112 of IndexBuffer: @[VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT]
113 of IndexBufferMapped: @[VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT]
114 of UniformBuffer: @[VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT]
115 of UniformBufferMapped: @[VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT]
106 116
107 proc GetVkFormat(depth: int, usage: openArray[VkImageUsageFlagBits]): VkFormat = 117 proc GetVkFormat(depth: int, usage: openArray[VkImageUsageFlagBits]): VkFormat =
108 const DEPTH_FORMAT_MAP = [ 118 const DEPTH_FORMAT_MAP = [
109 0: [VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED], 119 0: [VK_FORMAT_UNDEFINED, VK_FORMAT_UNDEFINED],
110 1: [VK_FORMAT_R8_SRGB, VK_FORMAT_R8_UNORM], 120 1: [VK_FORMAT_R8_SRGB, VK_FORMAT_R8_UNORM],
320 return 1 330 return 1
321 331
322 template sType(descriptorSet: DescriptorSet): untyped = 332 template sType(descriptorSet: DescriptorSet): untyped =
323 get(genericParams(typeof(gpuData)), 1) 333 get(genericParams(typeof(gpuData)), 1)
324 334
325 template UsesIndirectMemory(gpuData: GPUData): untyped = 335 template bufferType(gpuData: GPUData): untyped =
326 get(genericParams(typeof(gpuData)), 1) is IndirectGPUMemory 336 get(genericParams(typeof(gpuData)), 1)
327 template UsesDirectMemory(gpuData: GPUData): untyped = 337 func NeedsMapping(bType: BufferType): bool =
328 get(genericParams(typeof(gpuData)), 1) is DirectGPUMemory 338 bType in [VertexBufferMapped, IndexBufferMapped, UniformBufferMapped]
339 template NeedsMapping(gpuData: GPUData): untyped =
340 gpuData.bufferType.NeedsMapping
329 341
330 template size(gpuArray: GPUArray): uint64 = 342 template size(gpuArray: GPUArray): uint64 =
331 (gpuArray.data.len * sizeof(elementType(gpuArray.data))).uint64 343 (gpuArray.data.len * sizeof(elementType(gpuArray.data))).uint64
332 template size(gpuValue: GPUValue): uint64 = 344 template size(gpuValue: GPUValue): uint64 =
333 sizeof(gpuValue.data).uint64 345 sizeof(gpuValue.data).uint64
334 346
335 template rawPointer(gpuArray: GPUArray): pointer = 347 template rawPointer(gpuArray: GPUArray): pointer =
336 addr(gpuArray.data[0]) 348 addr(gpuArray.data[0])
337 template rawPointer(gpuValue: GPUValue): pointer = 349 template rawPointer(gpuValue: GPUValue): pointer =
338 addr(gpuValue.data) 350 addr(gpuValue.data)
339
340 proc RequiredMemorySize(buffer: VkBuffer): uint64 =
341 var req: VkMemoryRequirements
342 vkGetBufferMemoryRequirements(vulkan.device, buffer, addr(req))
343 return req.size
344
345 proc RequiredMemorySize(image: VkImage): uint64 =
346 var req: VkMemoryRequirements
347 vkGetImageMemoryRequirements(vulkan.device, image, addr req)
348 return req.size
349 351
350 proc GetPhysicalDevice(instance: VkInstance): VkPhysicalDevice = 352 proc GetPhysicalDevice(instance: VkInstance): VkPhysicalDevice =
351 var nDevices: uint32 353 var nDevices: uint32
352 checkVkResult vkEnumeratePhysicalDevices(instance, addr(nDevices), nil) 354 checkVkResult vkEnumeratePhysicalDevices(instance, addr(nDevices), nil)
353 var devices = newSeq[VkPhysicalDevice](nDevices) 355 var devices = newSeq[VkPhysicalDevice](nDevices)
369 score = props.limits.maxImageDimension2D 371 score = props.limits.maxImageDimension2D
370 result = pDevice 372 result = pDevice
371 373
372 assert score > 0, "Unable to find integrated or discrete GPU" 374 assert score > 0, "Unable to find integrated or discrete GPU"
373 375
374 376 proc IsMappable(memoryTypeIndex: uint32): bool =
375 proc GetDirectMemoryType(): uint32 =
376 var physicalProperties: VkPhysicalDeviceMemoryProperties 377 var physicalProperties: VkPhysicalDeviceMemoryProperties
377 vkGetPhysicalDeviceMemoryProperties(vulkan.physicalDevice, addr(physicalProperties)) 378 vkGetPhysicalDeviceMemoryProperties(vulkan.physicalDevice, addr(physicalProperties))
378 379 let flags = toEnums(physicalProperties.memoryTypes[memoryTypeIndex].propertyFlags)
379 var biggestHeap: uint64 = 0 380 return VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT in flags
380 result = high(uint32)
381 # try to find host-visible type
382 for i in 0'u32 ..< physicalProperties.memoryTypeCount:
383 let flags = toEnums(physicalProperties.memoryTypes[i].propertyFlags)
384 if VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT in flags:
385 let size = physicalProperties.memoryHeaps[physicalProperties.memoryTypes[i].heapIndex].size
386 if size > biggestHeap:
387 biggestHeap = size
388 result = i
389 assert result != high(uint32), "There is not host visible memory. This is likely a driver bug."
390 381
391 proc GetQueueFamily(pDevice: VkPhysicalDevice, qType: VkQueueFlagBits): uint32 = 382 proc GetQueueFamily(pDevice: VkPhysicalDevice, qType: VkQueueFlagBits): uint32 =
392 var nQueuefamilies: uint32 383 var nQueuefamilies: uint32
393 vkGetPhysicalDeviceQueueFamilyProperties(pDevice, addr nQueuefamilies, nil) 384 vkGetPhysicalDeviceQueueFamilyProperties(pDevice, addr nQueuefamilies, nil)
394 var queuFamilies = newSeq[VkQueueFamilyProperties](nQueuefamilies) 385 var queuFamilies = newSeq[VkQueueFamilyProperties](nQueuefamilies)
400 391
401 proc GetSurfaceFormat(): VkFormat = 392 proc GetSurfaceFormat(): VkFormat =
402 # EVERY windows driver and almost every linux driver should support this 393 # EVERY windows driver and almost every linux driver should support this
403 VK_FORMAT_B8G8R8A8_SRGB 394 VK_FORMAT_B8G8R8A8_SRGB
404 395
405 proc UpdateGPUBuffer(gpuData: GPUData) =
406 if gpuData.size == 0:
407 return
408 when UsesDirectMemory(gpuData):
409 copyMem(pointerOffset(gpuData.buffer.rawPointer, gpuData.offset), gpuData.rawPointer, gpuData.size)
410 else:
411 WithStagingBuffer((gpuData.buffer.vk, gpuData.offset), gpuData.buffer.vk.RequiredMemorySize(), GetDirectMemoryType(), stagingPtr):
412 copyMem(stagingPtr, gpuData.rawPointer, gpuData.size)
413
414 proc UpdateAllGPUBuffers[T](value: T) =
415 for name, fieldvalue in value.fieldPairs():
416 when typeof(fieldvalue) is GPUData:
417 UpdateGPUBuffer(fieldvalue)
418
419 proc InitDescriptorSet( 396 proc InitDescriptorSet(
420 renderData: RenderData, 397 renderData: RenderData,
421 layout: VkDescriptorSetLayout, 398 layout: VkDescriptorSetLayout,
422 descriptorSet: var DescriptorSet, 399 descriptorSet: var DescriptorSet,
423 ) = 400 ) =
424 # santization checks 401 # santization checks
425 for name, value in descriptorSet.data.fieldPairs: 402 for name, value in descriptorSet.data.fieldPairs:
426 when typeof(value) is GPUValue: 403 when typeof(value) is GPUValue:
427 assert value.buffer.vk.Valid 404 assert value.buffer.vk.Valid
428 # TODO: 405 elif typeof(value) is Texture:
429 # when typeof(value) is Texture: 406 assert value.vk.Valid
430 # assert value.texture.vk.Valid 407 assert value.imageview.Valid
431 408 assert value.sampler.Valid
432 # TODO: missing stuff here? only for FiF, but not multiple different sets? 409
433 # allocate 410 # allocate
434 var layouts = newSeqWith(descriptorSet.vk.len, layout) 411 var layouts = newSeqWith(descriptorSet.vk.len, layout)
435 var allocInfo = VkDescriptorSetAllocateInfo( 412 var allocInfo = VkDescriptorSetAllocateInfo(
436 sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 413 sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
437 descriptorPool: renderData.descriptorPool, 414 descriptorPool: renderData.descriptorPool,
894 addr(createInfo), 871 addr(createInfo),
895 nil, 872 nil,
896 addr(result.vk) 873 addr(result.vk)
897 ) 874 )
898 875
899 proc AllocateIndirectMemory(size: uint64): IndirectGPUMemory = 876 proc AllocateNewMemoryBlock(size: uint64, mType: uint32): MemoryBlock =
900 # chooses biggest memory type that has NOT VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT 877 result = MemoryBlock(
901 result.size = size 878 vk: svkAllocateMemory(size, mType),
902 result.needsTransfer = true 879 size: size,
903 880 rawPointer: nil,
904 # find a good memory type 881 offsetNextFree: 0,
905 var physicalProperties: VkPhysicalDeviceMemoryProperties 882 )
906 vkGetPhysicalDeviceMemoryProperties(vulkan.physicalDevice, addr physicalProperties) 883 if mType.IsMappable():
907 884 checkVkResult vkMapMemory(
908 var biggestHeap: uint64 = 0 885 device = vulkan.device,
909 var memoryTypeIndex = high(uint32) 886 memory = result.vk,
910 # try to find non-host-visible type 887 offset = 0'u64,
911 for i in 0'u32 ..< physicalProperties.memoryTypeCount: 888 size = result.size,
912 if not (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT in toEnums(physicalProperties.memoryTypes[i].propertyFlags)): 889 flags = VkMemoryMapFlags(0),
913 let size = physicalProperties.memoryHeaps[physicalProperties.memoryTypes[i].heapIndex].size 890 ppData = addr(result.rawPointer)
914 if size > biggestHeap: 891 )
915 biggestHeap = size 892
916 memoryTypeIndex = i 893 proc FlushAllMemory(renderData: RenderData) =
917 894 var flushRegions = newSeq[VkMappedMemoryRange]()
918 # If we did not found a device-only memory type, let's just take the biggest overall 895 for memoryBlocks in renderData.memory:
919 if memoryTypeIndex == high(uint32): 896 for memoryBlock in memoryBlocks:
920 result.needsTransfer = false 897 if memoryBlock.rawPointer != nil and memoryBlock.offsetNextFree > 0:
921 for i in 0'u32 ..< physicalProperties.memoryTypeCount: 898 flushRegions.add VkMappedMemoryRange(
922 let size = physicalProperties.memoryHeaps[physicalProperties.memoryTypes[i].heapIndex].size 899 sType: VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
923 if size > biggestHeap: 900 memory: memoryBlock.vk,
924 biggestHeap = size 901 size: memoryBlock.offsetNextFree,
925 memoryTypeIndex = i 902 )
926 903 if flushRegions.len > 0:
927 assert memoryTypeIndex != high(uint32), "Unable to find indirect memory type" 904 checkVkResult vkFlushMappedMemoryRanges(vulkan.device, flushRegions.len.uint32, flushRegions.ToCPointer())
928 result.vk = svkAllocateMemory(result.size, memoryTypeIndex) 905
929 906 proc AllocateNewBuffer(renderData: var RenderData, size: uint64, bufferType: BufferType): Buffer =
930 proc AllocateDirectMemory(size: uint64): DirectGPUMemory = 907 result = Buffer(
931 result.size = size 908 vk: svkCreateBuffer(size, bufferType.usage),
932 909 size: size,
933 # find a good memory type 910 rawPointer: nil,
934 var physicalProperties: VkPhysicalDeviceMemoryProperties 911 offsetNextFree: 0,
935 vkGetPhysicalDeviceMemoryProperties(vulkan.physicalDevice, addr physicalProperties) 912 )
936 913 let memoryRequirements = svkGetBufferMemoryRequirements(result.vk)
937 var biggestHeap: uint64 = 0 914 let memoryType = BestMemory(mappable = bufferType.NeedsMapping, filter = memoryRequirements.memoryTypes)
938 var memoryTypeIndex = high(uint32) 915
939 # try to find host-visible type 916 # check if there is an existing allocated memory block that is large enough to be used
940 for i in 0 ..< physicalProperties.memoryTypeCount: 917 var selectedBlockI = -1
941 let flags = toEnums(physicalProperties.memoryTypes[i].propertyFlags) 918 for i in 0 ..< renderData.memory[memoryType].len:
942 if VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT in flags: 919 let memoryBlock = renderData.memory[memoryType][i]
943 let size = physicalProperties.memoryHeaps[physicalProperties.memoryTypes[i].heapIndex].size 920 if memoryBlock.size - alignedTo(memoryBlock.offsetNextFree, memoryRequirements.alignment) >= memoryRequirements.size:
944 if size > biggestHeap: 921 selectedBlockI = i
945 biggestHeap = size 922 break
946 memoryTypeIndex = i 923 # otherwise, allocate a new block of memory and use that
947 924 if selectedBlockI < 0:
948 assert memoryTypeIndex != high(uint32), "Unable to find indirect memory type" 925 selectedBlockI = renderData.memory[memoryType].len
949 result.vk = svkAllocateMemory(result.size, GetDirectMemoryType()) 926 renderData.memory[memoryType].add AllocateNewMemoryBlock(
950 checkVkResult vkMapMemory( 927 size = max(size, MEMORY_BLOCK_ALLOCATION_SIZE),
951 device = vulkan.device, 928 mType = memoryType
952 memory = result.vk, 929 )
953 offset = 0'u64, 930
954 size = result.size, 931 let selectedBlock = renderData.memory[memoryType][selectedBlockI]
955 flags = VkMemoryMapFlags(0), 932 renderData.memory[memoryType][selectedBlockI].offsetNextFree = alignedTo(
956 ppData = addr(result.rawPointer) 933 selectedBlock.offsetNextFree,
957 ) 934 memoryRequirements.alignment,
958 935 )
959 proc AllocateIndirectBuffer(renderData: var RenderData, size: uint64, btype: BufferType) = 936 checkVkResult vkBindBufferMemory(
960 if size == 0: 937 vulkan.device,
938 result.vk,
939 selectedBlock.vk,
940 selectedBlock.offsetNextFree,
941 )
942 result.rawPointer = selectedBlock.rawPointer.pointerAddOffset(selectedBlock.offsetNextFree)
943 renderData.memory[memoryType][selectedBlockI].offsetNextFree += memoryRequirements.size
944
945 proc AssignBuffers[T](renderdata: var RenderData, data: var T) =
946 for name, value in fieldPairs(data):
947 when typeof(value) is GPUData:
948
949 # find buffer that has space
950 var selectedBufferI = -1
951 for i in 0 ..< renderData.buffers[value.bufferType].len:
952 let buffer = renderData.buffers[value.bufferType][i]
953 if buffer.size - alignedTo(buffer.offsetNextFree, BUFFER_ALIGNMENT) >= value.size:
954 selectedBufferI = i
955
956 # otherwise create new buffer
957 if selectedBufferI < 0:
958 selectedBufferI = renderdata.buffers[value.bufferType].len
959 renderdata.buffers[value.bufferType].add renderdata.AllocateNewBuffer(
960 size = max(value.size, BUFFER_ALLOCATION_SIZE),
961 bType = value.bufferType,
962 mappable = value.NeedsMapping,
963 )
964
965 # assigne value
966 let selectedBuffer = renderdata.buffers[value.bufferType][selectedBufferI]
967 renderdata.buffers[value.bufferType][selectedBufferI].offsetNextFree = alignedTo(
968 selectedBuffer.offsetNextFree,
969 BUFFER_ALIGNMENT
970 )
971 value.buffer = selectedBuffer
972 value.offset = renderdata.buffers[value.bufferType][selectedBufferI].offsetNextFree
973 renderdata.buffers[value.bufferType][selectedBufferI].offsetNextFree += value.size
974
975 proc UpdateGPUBuffer(gpuData: GPUData) =
976 if gpuData.size == 0:
961 return 977 return
962 var buffer = Buffer[IndirectGPUMemory](size: size, rawPointer: nil) 978 when NeedsMapping(gpuData):
963 979 copyMem(pointerAddOffset(gpuData.buffer.rawPointer, gpuData.offset), gpuData.rawPointer, gpuData.size)
964 let usageFlags = case btype: 980 else:
965 of VertexBuffer: [VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT] 981 WithStagingBuffer((gpuData.buffer.vk, gpuData.offset), gpuData.buffer.size, stagingPtr):
966 of IndexBuffer: [VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT] 982 copyMem(stagingPtr, gpuData.rawPointer, gpuData.size)
967 of UniformBuffer: [VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT] 983
968 984 proc UpdateAllGPUBuffers[T](value: T) =
969 # iterate through memory areas to find big enough free space 985 for name, fieldvalue in value.fieldPairs():
970 # TODO: dynamically expand memory allocations 986 when typeof(fieldvalue) is GPUData:
971 # TODO: use RequiredMemorySize() 987 UpdateGPUBuffer(fieldvalue)
972 for (memory, usedOffset) in renderData.indirectMemory.mitems: 988
973 if memory.size - usedOffset >= size:
974 # create buffer
975 buffer.vk = svkCreateBuffer(buffer.size, usageFlags)
976 checkVkResult vkBindBufferMemory(vulkan.device, buffer.vk, memory.vk, usedOffset)
977 renderData.indirectBuffers.add (buffer, btype, 0'u64)
978 # update memory area offset
979 usedOffset = alignedTo(usedOffset + size, MEMORY_ALIGNMENT)
980 return
981
982 assert false, "Did not find allocated memory region with enough space"
983
984 proc AllocateDirectBuffer(renderData: var RenderData, size: uint64, btype: BufferType) =
985 if size == 0:
986 return
987
988 var buffer = Buffer[DirectGPUMemory](size: size)
989
990 let usageFlags = case btype:
991 of VertexBuffer: [VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT]
992 of IndexBuffer: [VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT]
993 of UniformBuffer: [VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT]
994
995 # iterate through memory areas to find big enough free space
996 # TODO: dynamically expand memory allocations
997 # TODO: use RequiredMemorySize()
998 for (memory, usedOffset) in renderData.directMemory.mitems:
999 if memory.size - usedOffset >= size:
1000 buffer.vk = svkCreateBuffer(buffer.size, usageFlags)
1001 checkVkResult vkBindBufferMemory(vulkan.device, buffer.vk, memory.vk, usedOffset)
1002 buffer.rawPointer = pointerOffset(memory.rawPointer, usedOffset)
1003 renderData.directBuffers.add (buffer, btype, 0'u64)
1004 # update memory area offset
1005 usedOffset = alignedTo(usedOffset + size, MEMORY_ALIGNMENT)
1006 return
1007
1008 assert false, "Did not find allocated memory region with enough space"
1009 989
1010 proc InitRenderData(descriptorPoolLimit = 1024'u32): RenderData = 990 proc InitRenderData(descriptorPoolLimit = 1024'u32): RenderData =
1011 # allocate descriptor pools 991 # allocate descriptor pools
1012 var poolSizes = [ 992 var poolSizes = [
1013 VkDescriptorPoolSize(thetype: VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, descriptorCount: descriptorPoolLimit), 993 VkDescriptorPoolSize(thetype: VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, descriptorCount: descriptorPoolLimit),
1018 poolSizeCount: poolSizes.len.uint32, 998 poolSizeCount: poolSizes.len.uint32,
1019 pPoolSizes: poolSizes.ToCPointer, 999 pPoolSizes: poolSizes.ToCPointer,
1020 maxSets: descriptorPoolLimit, 1000 maxSets: descriptorPoolLimit,
1021 ) 1001 )
1022 checkVkResult vkCreateDescriptorPool(vulkan.device, addr(poolInfo), nil, addr(result.descriptorPool)) 1002 checkVkResult vkCreateDescriptorPool(vulkan.device, addr(poolInfo), nil, addr(result.descriptorPool))
1023
1024 # allocate some memory
1025 var initialAllocationSize = 1_000_000_000'u64 # TODO: make this more dynamic or something?
1026 result.indirectMemory = @[(memory: AllocateIndirectMemory(size = initialAllocationSize), usedOffset: 0'u64)]
1027 result.directMemory = @[(memory: AllocateDirectMemory(size = initialAllocationSize), usedOffset: 0'u64)]
1028
1029 proc FlushDirectMemory(renderData: RenderData) =
1030 var flushRegions = newSeqOfCap[VkMappedMemoryRange](renderData.directMemory.len)
1031 for entry in renderData.directMemory:
1032 if entry.usedOffset > 0:
1033 flushRegions.add VkMappedMemoryRange(
1034 sType: VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
1035 memory: entry.memory.vk,
1036 size: entry.usedOffset,
1037 )
1038 if flushRegions.len > 0:
1039 checkVkResult vkFlushMappedMemoryRanges(vulkan.device, flushRegions.len.uint32, flushRegions.ToCPointer())
1040
1041 # For the Get*BufferSize:
1042 # BUFFER_ALIGNMENT is just added for a rough estimate, to ensure we have enough space to align when binding
1043 proc GetIndirectBufferSizes[T](data: T): uint64 =
1044 for name, value in fieldPairs(data):
1045 when not hasCustomPragma(value, VertexIndices):
1046 when typeof(value) is GPUData:
1047 when UsesIndirectMemory(value):
1048 result += value.size + BUFFER_ALIGNMENT
1049 proc GetIndirectBufferSizes(data: DescriptorSet): uint64 =
1050 GetIndirectBufferSizes(data.data)
1051 proc GetDirectBufferSizes[T](data: T): uint64 =
1052 for name, value in fieldPairs(data):
1053 when not hasCustomPragma(value, VertexIndices):
1054 when typeof(value) is GPUData:
1055 when UsesDirectMemory(value):
1056 result += value.size + BUFFER_ALIGNMENT
1057 proc GetDirectBufferSizes(data: DescriptorSet): uint64 =
1058 GetDirectBufferSizes(data.data)
1059 proc GetIndirectIndexBufferSizes[T](data: T): uint64 =
1060 for name, value in fieldPairs(data):
1061 when hasCustomPragma(value, VertexIndices):
1062 static: assert typeof(value) is GPUArray, "Index buffers must be of type GPUArray"
1063 static: assert elementType(value.data) is uint8 or elementType(value.data) is uint16 or elementType(value.data) is uint32
1064 when UsesIndirectMemory(value):
1065 result += value.size + BUFFER_ALIGNMENT
1066 proc GetDirectIndexBufferSizes[T](data: T): uint64 =
1067 for name, value in fieldPairs(data):
1068 when hasCustomPragma(value, VertexIndices):
1069 static: assert typeof(value) is GPUArray, "Index buffers must be of type GPUArray"
1070 static: assert elementType(value.data) is uint8 or elementType(value.data) is uint16 or elementType(value.data) is uint32
1071 when UsesDirectMemory(value):
1072 result += value.size + BUFFER_ALIGNMENT
1073
1074 proc AssignIndirectBuffers[T](renderdata: var RenderData, btype: BufferType, data: var T) =
1075 for name, value in fieldPairs(data):
1076 when typeof(value) is GPUData:
1077 when UsesIndirectMemory(value):
1078 # find next buffer of correct type with enough free space
1079 if btype == IndexBuffer == value.hasCustomPragma(VertexIndices):
1080 var foundBuffer = false
1081 for (buffer, bt, offset) in renderData.indirectBuffers.mitems:
1082 if bt == btype and buffer.size - offset >= value.size:
1083 assert not value.buffer.vk.Valid, "GPUData-Buffer has already been assigned"
1084 assert buffer.vk.Valid, "RenderData-Buffer has not yet been created"
1085 value.buffer = buffer
1086 value.offset = offset
1087 offset = alignedTo(offset + value.size, BUFFER_ALIGNMENT)
1088 foundBuffer = true
1089 break
1090 assert foundBuffer, &"Unable to find large enough '{btype}' for '{data}'"
1091 proc AssignIndirectBuffers(renderdata: var RenderData, btype: BufferType, data: var DescriptorSet) =
1092 AssignIndirectBuffers(renderdata, btype, data.data)
1093 proc AssignDirectBuffers[T](renderdata: var RenderData, btype: BufferType, data: var T) =
1094 for name, value in fieldPairs(data):
1095 when typeof(value) is GPUData:
1096 when UsesDirectMemory(value):
1097 # find next buffer of correct type with enough free space
1098 if btype == IndexBuffer == value.hasCustomPragma(VertexIndices):
1099 var foundBuffer = false
1100 for (buffer, bt, offset) in renderData.directBuffers.mitems:
1101 if bt == btype and buffer.size - offset >= value.size:
1102 assert not value.buffer.vk.Valid, "GPUData-Buffer has already been assigned"
1103 assert buffer.vk.Valid, "RenderData-Buffer has not yet been created"
1104 value.buffer = buffer
1105 value.offset = offset
1106 offset = alignedTo(offset + value.size, BUFFER_ALIGNMENT)
1107 foundBuffer = true
1108 break
1109 assert foundBuffer, &"Unable to find large enough '{btype}' for '{data}'"
1110 proc AssignDirectBuffers(renderdata: var RenderData, btype: BufferType, data: var DescriptorSet) =
1111 AssignDirectBuffers(renderdata, btype, data.data)
1112 1003
1113 proc TransitionImageLayout(image: VkImage, oldLayout, newLayout: VkImageLayout) = 1004 proc TransitionImageLayout(image: VkImage, oldLayout, newLayout: VkImageLayout) =
1114 var 1005 var
1115 barrier = VkImageMemoryBarrier( 1006 barrier = VkImageMemoryBarrier(
1116 sType: VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 1007 sType: VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
1211 assert texture.offset == 0 1102 assert texture.offset == 0
1212 const usage = [VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_USAGE_SAMPLED_BIT] 1103 const usage = [VK_IMAGE_USAGE_TRANSFER_DST_BIT, VK_IMAGE_USAGE_SAMPLED_BIT]
1213 1104
1214 texture.format = GetVkFormat(texture.depth, usage = usage) 1105 texture.format = GetVkFormat(texture.depth, usage = usage)
1215 texture.vk = svkCreate2DImage(texture.width, texture.height, texture.format, usage) 1106 texture.vk = svkCreate2DImage(texture.width, texture.height, texture.format, usage)
1216 let size = texture.vk.RequiredMemorySize() 1107 let reqs = texture.vk.svkGetImageMemoryRequirements()
1217 1108
1218 when genericParams(typeof(texture)).get(1) is IndirectGPUMemory: 1109 # TODO
1219 for (memory, usedOffset) in renderData.indirectMemory.mitems: 1110
1220 if memory.size - usedOffset >= size: 1111 for (memory, usedOffset) in renderData.indirectMemory.mitems:
1221 texture.memory = memory 1112 if memory.size - usedOffset >= size:
1222 texture.offset = usedOffset 1113 texture.memory = memory
1223 # update memory area offset 1114 texture.offset = usedOffset
1224 usedOffset = alignedTo(usedOffset + size, MEMORY_ALIGNMENT) 1115 # update memory area offset
1225 break 1116 usedOffset = alignedTo(usedOffset + size, MEMORY_ALIGNMENT)
1226 elif genericParams(typeof(texture)).get(1) is DirectGPUMemory: 1117 break
1227 for (memory, usedOffset) in renderData.directMemory.mitems:
1228 if memory.size - usedOffset >= size:
1229 texture.memory = memory
1230 texture.offset = usedOffset
1231 # update memory area offset
1232 usedOffset = alignedTo(usedOffset + size, MEMORY_ALIGNMENT)
1233 break
1234 1118
1235 checkVkResult vkBindImageMemory( 1119 checkVkResult vkBindImageMemory(
1236 vulkan.device, 1120 vulkan.device,
1237 texture.vk, 1121 texture.vk,
1238 texture.memory.vk, 1122 texture.memory.vk,
1239 texture.offset, 1123 texture.offset,
1240 ) 1124 )
1241 1125
1242 # data transfer and layout transition 1126 # data transfer and layout transition
1243 TransitionImageLayout(texture.vk, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) 1127 TransitionImageLayout(texture.vk, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
1244 WithStagingBuffer((texture.vk, texture.imageview, texture.width, texture.height), size, GetDirectMemoryType(), stagingPtr): 1128 WithStagingBuffer((texture.vk, texture.imageview, texture.width, texture.height), size, stagingPtr):
1245 copyMem(stagingPtr, texture.data.ToCPointer, size) 1129 copyMem(stagingPtr, texture.data.ToCPointer, size)
1246 TransitionImageLayout(texture.vk, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) 1130 TransitionImageLayout(texture.vk, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)
1247 1131
1248 texture.imageview = createImageView(texture.vk, texture.format) 1132 texture.imageview = createImageView(texture.vk, texture.format)
1249 texture.sampler = createSampler() 1133 texture.sampler = createSampler()
1374 import semicongine/vulkan/physicaldevice 1258 import semicongine/vulkan/physicaldevice
1375 import std/options 1259 import std/options
1376 1260
1377 type 1261 type
1378 MeshA = object 1262 MeshA = object
1379 position: GPUArray[Vec3f, IndirectGPUMemory] 1263 position: GPUArray[Vec3f, VertexBuffer]
1380 indices {.VertexIndices.}: GPUArray[uint16, IndirectGPUMemory] 1264 indices: GPUArray[uint16, IndexBuffer]
1381 InstanceA = object 1265 InstanceA = object
1382 rotation: GPUArray[Vec4f, IndirectGPUMemory] 1266 rotation: GPUArray[Vec4f, VertexBuffer]
1383 objPosition: GPUArray[Vec3f, IndirectGPUMemory] 1267 objPosition: GPUArray[Vec3f, VertexBuffer]
1384 MaterialA = object 1268 MaterialA = object
1385 reflection: float32 1269 reflection: float32
1386 baseColor: Vec3f 1270 baseColor: Vec3f
1387 UniformsA = object 1271 UniformsA = object
1388 defaultTexture: Texture[TVec3[uint8], IndirectGPUMemory] 1272 defaultTexture: Texture[TVec3[uint8]]
1389 defaultMaterial: GPUValue[MaterialA, IndirectGPUMemory] 1273 defaultMaterial: GPUValue[MaterialA, UniformBuffer]
1390 materials: GPUValue[array[3, MaterialA], IndirectGPUMemory] 1274 materials: GPUValue[array[3, MaterialA], UniformBuffer]
1391 materialTextures: array[3, Texture[TVec3[uint8], IndirectGPUMemory]] 1275 materialTextures: array[3, Texture[TVec3[uint8]]]
1392 ShaderSettings = object 1276 ShaderSettings = object
1393 gamma: float32 1277 gamma: float32
1394 GlobalsA = object 1278 GlobalsA = object
1395 fontAtlas: Texture[TVec3[uint8], IndirectGPUMemory] 1279 fontAtlas: Texture[TVec3[uint8]]
1396 settings: GPUValue[ShaderSettings, IndirectGPUMemory] 1280 settings: GPUValue[ShaderSettings, UniformBuffer]
1397 1281
1398 ShaderA = object 1282 ShaderA = object
1399 # vertex input 1283 # vertex input
1400 position {.VertexAttribute.}: Vec3f 1284 position {.VertexAttribute.}: Vec3f
1401 objPosition {.InstanceAttribute.}: Vec3f 1285 objPosition {.InstanceAttribute.}: Vec3f
1440 queueFamilyIndex: qfi, 1324 queueFamilyIndex: qfi,
1441 queue: svkGetDeviceQueue(dev, qfi, VK_QUEUE_GRAPHICS_BIT) 1325 queue: svkGetDeviceQueue(dev, qfi, VK_QUEUE_GRAPHICS_BIT)
1442 ) 1326 )
1443 1327
1444 var myMesh1 = MeshA( 1328 var myMesh1 = MeshA(
1445 position: GPUArray[Vec3f, IndirectGPUMemory](data: @[NewVec3f(0, 0, ), NewVec3f(0, 0, ), NewVec3f(0, 0, )]), 1329 position: GPUArray[Vec3f, VertexBuffer](data: @[NewVec3f(0, 0, ), NewVec3f(0, 0, ), NewVec3f(0, 0, )]),
1446 ) 1330 )
1447 var uniforms1 = DescriptorSet[UniformsA, MaterialSet]( 1331 var uniforms1 = DescriptorSet[UniformsA, MaterialSet](
1448 data: UniformsA( 1332 data: UniformsA(
1449 defaultTexture: Texture[TVec3[uint8], IndirectGPUMemory](width: 1, height: 1, data: @[TVec3[uint8]([0'u8, 0'u8, 0'u8])]), 1333 defaultTexture: Texture[TVec3[uint8]](width: 1, height: 1, data: @[TVec3[uint8]([0'u8, 0'u8, 0'u8])]),
1450 materials: GPUValue[array[3, MaterialA], IndirectGPUMemory](data: [ 1334 materials: GPUValue[array[3, MaterialA], UniformBuffer](data: [
1451 MaterialA(reflection: 0, baseColor: NewVec3f(1, 0, 0)), 1335 MaterialA(reflection: 0, baseColor: NewVec3f(1, 0, 0)),
1452 MaterialA(reflection: 0.1, baseColor: NewVec3f(0, 1, 0)), 1336 MaterialA(reflection: 0.1, baseColor: NewVec3f(0, 1, 0)),
1453 MaterialA(reflection: 0.5, baseColor: NewVec3f(0, 0, 1)), 1337 MaterialA(reflection: 0.5, baseColor: NewVec3f(0, 0, 1)),
1454 ]), 1338 ]),
1455 materialTextures: [ 1339 materialTextures: [
1456 Texture[TVec3[uint8], IndirectGPUMemory](width: 1, height: 1, data: @[TVec3[uint8]([0'u8, 0'u8, 0'u8])]), 1340 Texture[TVec3[uint8]](width: 1, height: 1, data: @[TVec3[uint8]([0'u8, 0'u8, 0'u8])]),
1457 Texture[TVec3[uint8], IndirectGPUMemory](width: 1, height: 1, data: @[TVec3[uint8]([0'u8, 0'u8, 0'u8])]), 1341 Texture[TVec3[uint8]](width: 1, height: 1, data: @[TVec3[uint8]([0'u8, 0'u8, 0'u8])]),
1458 Texture[TVec3[uint8], IndirectGPUMemory](width: 1, height: 1, data: @[TVec3[uint8]([0'u8, 0'u8, 0'u8])]), 1342 Texture[TVec3[uint8]](width: 1, height: 1, data: @[TVec3[uint8]([0'u8, 0'u8, 0'u8])]),
1459 ] 1343 ]
1460 ) 1344 )
1461 ) 1345 )
1462 var instances1 = InstanceA( 1346 var instances1 = InstanceA(
1463 rotation: GPUArray[Vec4f, IndirectGPUMemory](data: @[NewVec4f(1, 0, 0, 0.1), NewVec4f(0, 1, 0, 0.1)]), 1347 rotation: GPUArray[Vec4f, VertexBuffer](data: @[NewVec4f(1, 0, 0, 0.1), NewVec4f(0, 1, 0, 0.1)]),
1464 objPosition: GPUArray[Vec3f, IndirectGPUMemory](data: @[NewVec3f(0, 0, 0), NewVec3f(1, 1, 1)]), 1348 objPosition: GPUArray[Vec3f, VertexBuffer](data: @[NewVec3f(0, 0, 0), NewVec3f(1, 1, 1)]),
1465 ) 1349 )
1466 var myGlobals = DescriptorSet[GlobalsA, GlobalSet]( 1350 var myGlobals = DescriptorSet[GlobalsA, GlobalSet](
1467 data: GlobalsA( 1351 data: GlobalsA(
1468 fontAtlas: Texture[TVec3[uint8], IndirectGPUMemory](width: 1, height: 1, data: @[TVec3[uint8]([0'u8, 0'u8, 0'u8])]), 1352 fontAtlas: Texture[TVec3[uint8]](width: 1, height: 1, data: @[TVec3[uint8]([0'u8, 0'u8, 0'u8])]),
1469 settings: GPUValue[ShaderSettings, IndirectGPUMemory](data: ShaderSettings(gamma: 1.0)) 1353 settings: GPUValue[ShaderSettings, UniformBuffer](data: ShaderSettings(gamma: 1.0))
1470 ) 1354 )
1471 ) 1355 )
1472 1356
1473 # setup for rendering (TODO: swapchain & framebuffers) 1357 # setup for rendering (TODO: swapchain & framebuffers)
1474 let renderpass = CreateRenderPass(GetSurfaceFormat()) 1358 let renderpass = CreateRenderPass(GetSurfaceFormat())
1478 let shaderObject = CompileShader(shader) 1362 let shaderObject = CompileShader(shader)
1479 var pipeline1 = CreatePipeline(renderPass = renderpass, shader = shaderObject) 1363 var pipeline1 = CreatePipeline(renderPass = renderpass, shader = shaderObject)
1480 1364
1481 var renderdata = InitRenderData() 1365 var renderdata = InitRenderData()
1482 1366
1483 # buffer allocation
1484 echo "Allocating GPU buffers"
1485
1486 var indirectVertexSizes = 0'u64
1487 indirectVertexSizes += GetIndirectBufferSizes(myMesh1)
1488 indirectVertexSizes += GetIndirectBufferSizes(instances1)
1489 AllocateIndirectBuffer(renderdata, indirectVertexSizes, VertexBuffer)
1490
1491 var directVertexSizes = 0'u64
1492 directVertexSizes += GetDirectBufferSizes(myMesh1)
1493 directVertexSizes += GetDirectBufferSizes(instances1)
1494 AllocateDirectBuffer(renderdata, directVertexSizes, VertexBuffer)
1495
1496 var indirectIndexSizes = 0'u64
1497 indirectIndexSizes += GetIndirectIndexBufferSizes(myMesh1)
1498 AllocateIndirectBuffer(renderdata, indirectIndexSizes, IndexBuffer)
1499
1500 var directIndexSizes = 0'u64
1501 directIndexSizes += GetDirectIndexBufferSizes(myMesh1)
1502 AllocateDirectBuffer(renderdata, directIndexSizes, IndexBuffer)
1503
1504 var indirectUniformSizes = 0'u64
1505 indirectUniformSizes += GetIndirectBufferSizes(uniforms1)
1506 indirectUniformSizes += GetIndirectBufferSizes(myGlobals)
1507 AllocateIndirectBuffer(renderdata, indirectUniformSizes, UniformBuffer)
1508
1509 var directUniformSizes = 0'u64
1510 directUniformSizes += GetDirectBufferSizes(uniforms1)
1511 directUniformSizes += GetDirectBufferSizes(myGlobals)
1512 AllocateDirectBuffer(renderdata, directUniformSizes, UniformBuffer)
1513
1514
1515 # buffer assignment 1367 # buffer assignment
1516 echo "Assigning buffers to GPUData fields" 1368 echo "Assigning buffers to GPUData fields"
1517 1369
1518 # for meshes we do: 1370 renderdata.AssignBuffers(myMesh1)
1519 renderdata.AssignIndirectBuffers(VertexBuffer, myMesh1) 1371 renderdata.AssignBuffers(instances1)
1520 renderdata.AssignDirectBuffers(VertexBuffer, myMesh1) 1372 renderdata.AssignBuffers(myGlobals)
1521 renderdata.AssignIndirectBuffers(IndexBuffer, myMesh1) 1373 renderdata.AssignBuffers(uniforms1)
1522 renderdata.AssignDirectBuffers(IndexBuffer, myMesh1)
1523
1524 # for instances we do:
1525 renderdata.AssignIndirectBuffers(VertexBuffer, instances1)
1526 renderdata.AssignDirectBuffers(VertexBuffer, instances1)
1527
1528 # for uniforms/globals we do:
1529 renderdata.AssignIndirectBuffers(UniformBuffer, uniforms1)
1530 renderdata.AssignDirectBuffers(UniformBuffer, uniforms1)
1531 renderdata.AssignIndirectBuffers(UniformBuffer, myGlobals)
1532 renderdata.AssignDirectBuffers(UniformBuffer, myGlobals)
1533 1374
1534 renderdata.UploadTextures(myGlobals) 1375 renderdata.UploadTextures(myGlobals)
1535 renderdata.UploadTextures(uniforms1) 1376 renderdata.UploadTextures(uniforms1)
1536 1377
1537 # copy everything to GPU 1378 # copy everything to GPU
1538 echo "Copying all data to GPU memory" 1379 echo "Copying all data to GPU memory"
1539 UpdateAllGPUBuffers(myMesh1) 1380 UpdateAllGPUBuffers(myMesh1)
1540 UpdateAllGPUBuffers(instances1) 1381 UpdateAllGPUBuffers(instances1)
1541 UpdateAllGPUBuffers(uniforms1) 1382 UpdateAllGPUBuffers(uniforms1)
1542 UpdateAllGPUBuffers(myGlobals) 1383 UpdateAllGPUBuffers(myGlobals)
1543 renderdata.FlushDirectMemory() 1384 renderdata.FlushAllMemory()
1544 1385
1545 1386
1546 # descriptors 1387 # descriptors
1547 echo "Writing descriptors" 1388 echo "Writing descriptors"
1548 InitDescriptorSet(renderdata, pipeline1.descriptorSetLayouts[GlobalSet], myGlobals) 1389 InitDescriptorSet(renderdata, pipeline1.descriptorSetLayouts[GlobalSet], myGlobals)