Mercurial > games > semicongine
comparison static_utils.nim @ 1177:4ef959278451 compiletime-tests
sync from bedroom to office
| author | sam <sam@basx.dev> | 
|---|---|
| date | Sun, 30 Jun 2024 06:40:33 +0700 | 
| parents | 511c9f7cd1da | 
| children | ec4ff70299f2 | 
   comparison
  equal
  deleted
  inserted
  replaced
| 1176:511c9f7cd1da | 1177:4ef959278451 | 
|---|---|
| 17 template VertexAttribute* {.pragma.} | 17 template VertexAttribute* {.pragma.} | 
| 18 template InstanceAttribute* {.pragma.} | 18 template InstanceAttribute* {.pragma.} | 
| 19 template Pass* {.pragma.} | 19 template Pass* {.pragma.} | 
| 20 template PassFlat* {.pragma.} | 20 template PassFlat* {.pragma.} | 
| 21 template ShaderOutput* {.pragma.} | 21 template ShaderOutput* {.pragma.} | 
| 22 template VertexIndices*{.pragma.} | |
| 22 | 23 | 
| 23 const INFLIGHTFRAMES = 2'u32 | 24 const INFLIGHTFRAMES = 2'u32 | 
| 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 | |
| 24 | 27 | 
| 25 type | 28 type | 
| 26 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] | 
| 27 ShaderObject*[TShader] = object | 30 ShaderObject*[TShader] = object | 
| 28 vertexShader: VkShaderModule | 31 vertexShader: VkShaderModule | 
| 199 None, UInt8, UInt16, UInt32 | 202 None, UInt8, UInt16, UInt32 | 
| 200 | 203 | 
| 201 IndirectGPUMemory = object | 204 IndirectGPUMemory = object | 
| 202 vk: VkDeviceMemory | 205 vk: VkDeviceMemory | 
| 203 size: uint64 | 206 size: uint64 | 
| 207 needsTransfer: bool # usually true | |
| 204 DirectGPUMemory = object | 208 DirectGPUMemory = object | 
| 205 vk: VkDeviceMemory | 209 vk: VkDeviceMemory | 
| 206 size: uint64 | 210 size: uint64 | 
| 207 data: pointer | 211 data: pointer | 
| 212 needsFlush: bool # usually true | |
| 208 GPUMemory = IndirectGPUMemory | DirectGPUMemory | 213 GPUMemory = IndirectGPUMemory | DirectGPUMemory | 
| 209 | 214 | 
| 210 Buffer[TMemory: GPUMemory] = object | 215 Buffer[TMemory: GPUMemory] = object | 
| 211 vk: VkBuffer | 216 vk: VkBuffer | 
| 212 memory*: TMemory | |
| 213 offset: uint64 | 217 offset: uint64 | 
| 214 size: uint64 | 218 size: uint64 | 
| 215 | 219 | 
| 216 GPUArray[T: SupportedGPUType, TMemory: GPUMemory] = object | 220 GPUArray[T: SupportedGPUType, TMemory: GPUMemory] = object | 
| 217 data: seq[T] | 221 data: seq[T] | 
| 238 pipeline: VkPipeline | 242 pipeline: VkPipeline | 
| 239 layout: VkPipelineLayout | 243 layout: VkPipelineLayout | 
| 240 descriptorSetLayout: VkDescriptorSetLayout | 244 descriptorSetLayout: VkDescriptorSetLayout | 
| 241 RenderData = object | 245 RenderData = object | 
| 242 descriptorPool: VkDescriptorPool | 246 descriptorPool: VkDescriptorPool | 
| 243 indirectMemory: seq[IndirectGPUMemory] | 247 # tuple is memory and offset to next free allocation in that memory | 
| 244 nextFreeIndirectMemoryOffset: seq[uint64] | 248 indirectMemory: seq[tuple[memory: IndirectGPUMemory, nextFree: uint64]] | 
| 249 directMemory: seq[tuple[memory: DirectGPUMemory, nextFree: uint64]] | |
| 245 indirectBuffers: seq[Buffer[IndirectGPUMemory]] | 250 indirectBuffers: seq[Buffer[IndirectGPUMemory]] | 
| 246 directMemory: seq[DirectGPUMemory] | |
| 247 nextFreeDirectMemoryOffset: seq[uint64] | |
| 248 directBuffers: seq[Buffer[DirectGPUMemory]] | 251 directBuffers: seq[Buffer[DirectGPUMemory]] | 
| 252 | |
| 253 template IsDirectMemory(gpuArray: GPUArray): untyped = | |
| 254 get(genericParams(typeof(gpuArray)), 1) is DirectGPUMemory | |
| 255 template IsDirectMemory(gpuValue: GPUValue): untyped = | |
| 256 get(genericParams(typeof(gpuValue)), 1) is DirectGPUMemory | |
| 249 | 257 | 
| 250 converter toVkIndexType(indexType: IndexType): VkIndexType = | 258 converter toVkIndexType(indexType: IndexType): VkIndexType = | 
| 251 case indexType: | 259 case indexType: | 
| 252 of None: VK_INDEX_TYPE_NONE_KHR | 260 of None: VK_INDEX_TYPE_NONE_KHR | 
| 253 of UInt8: VK_INDEX_TYPE_UINT8_EXT | 261 of UInt8: VK_INDEX_TYPE_UINT8_EXT | 
| 472 var layoutCreateInfo = VkDescriptorSetLayoutCreateInfo( | 480 var layoutCreateInfo = VkDescriptorSetLayoutCreateInfo( | 
| 473 sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, | 481 sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, | 
| 474 bindingCount: uint32(layoutbindings.len), | 482 bindingCount: uint32(layoutbindings.len), | 
| 475 pBindings: layoutbindings.ToCPointer | 483 pBindings: layoutbindings.ToCPointer | 
| 476 ) | 484 ) | 
| 477 result.descriptorSetLayout: VkDescriptorSetLayout | |
| 478 checkVkResult vkCreateDescriptorSetLayout(device, addr(layoutCreateInfo), nil, addr(result.descriptorSetLayout)) | 485 checkVkResult vkCreateDescriptorSetLayout(device, addr(layoutCreateInfo), nil, addr(result.descriptorSetLayout)) | 
| 479 let pipelineLayoutInfo = VkPipelineLayoutCreateInfo( | 486 let pipelineLayoutInfo = VkPipelineLayoutCreateInfo( | 
| 480 sType: VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, | 487 sType: VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, | 
| 481 setLayoutCount: 1, | 488 setLayoutCount: 1, | 
| 482 pSetLayouts: addr(result.descriptorSetLayout), | 489 pSetLayouts: addr(result.descriptorSetLayout), | 
| 609 addr(createInfo), | 616 addr(createInfo), | 
| 610 nil, | 617 nil, | 
| 611 addr(result.pipeline) | 618 addr(result.pipeline) | 
| 612 ) | 619 ) | 
| 613 | 620 | 
| 614 proc AllocateIndirectMemory(device: VkDevice, pDevice: VkPhysicalDevice, allocationSize: uint64): IndirectGPUMemory = | 621 proc AllocateIndirectMemory(device: VkDevice, pDevice: VkPhysicalDevice, size: uint64): IndirectGPUMemory = | 
| 615 # chooses biggest memory type that has NOT VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | 622 # chooses biggest memory type that has NOT VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | 
| 616 result.size = allocationSize | 623 result.size = size | 
| 624 result.needsTransfer = true | |
| 617 | 625 | 
| 618 # find a good memory type | 626 # find a good memory type | 
| 619 var physicalProperties: VkPhysicalDeviceMemoryProperties | 627 var physicalProperties: VkPhysicalDeviceMemoryProperties | 
| 620 vkGetPhysicalDeviceMemoryProperties(pDevice, addr physicalProperties) | 628 vkGetPhysicalDeviceMemoryProperties(pDevice, addr physicalProperties) | 
| 621 | 629 | 
| 622 var biggestHeap: uint64 = -1 | 630 var biggestHeap: uint64 = 0 | 
| 623 var memoryTypeIndex = -1 | 631 var memoryTypeIndex = high(uint32) | 
| 624 # try to find non-host-visible type | 632 # try to find non-host-visible type | 
| 625 for i in 0 ..< physicalProperties.memoryTypeCount: | 633 for i in 0'u32 ..< physicalProperties.memoryTypeCount: | 
| 626 if VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT not in toEnums(physicalProperties.memoryTypes[i].propertyFlags) | 634 if not (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT in toEnums(physicalProperties.memoryTypes[i].propertyFlags)): | 
| 627 let size = physicalProperties.memoryHeaps[physicalProperties.memoryTypes[i].heapIndex].size | 635 let size = physicalProperties.memoryHeaps[physicalProperties.memoryTypes[i].heapIndex].size | 
| 628 if size > biggestHeap: | 636 if size > biggestHeap: | 
| 629 biggest = size | 637 biggestHeap = size | 
| 630 memoryTypeIndex = i | 638 memoryTypeIndex = i | 
| 631 | 639 | 
| 632 # If we did not found a device-only memory type, let's just take the biggest overall | 640 # If we did not found a device-only memory type, let's just take the biggest overall | 
| 633 if memoryTypeIndex < 0: | 641 if memoryTypeIndex == high(uint32): | 
| 634 for i in 0 ..< physicalProperties.memoryTypeCount: | 642 result.needsTransfer = false | 
| 635 let size = physicalProperties.memoryHeaps[physicalProperties.memoryTypes[i].heapIndex].size | 643 for i in 0'u32 ..< physicalProperties.memoryTypeCount: | 
| 636 if size > biggestHeap: | 644 let size = physicalProperties.memoryHeaps[physicalProperties.memoryTypes[i].heapIndex].size | 
| 637 biggest = size | 645 if size > biggestHeap: | 
| 638 memoryTypeIndex = i | 646 biggestHeap = size | 
| 639 | 647 memoryTypeIndex = i | 
| 640 assert memoryTypeIndex >= 0, "Unable to find indirect memory type" | 648 | 
| 649 assert memoryTypeIndex != high(uint32), "Unable to find indirect memory type" | |
| 641 var allocationInfo = VkMemoryAllocateInfo( | 650 var allocationInfo = VkMemoryAllocateInfo( | 
| 642 sType: VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, | 651 sType: VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, | 
| 643 allocationSize: initialAllocationSize, | 652 allocationSize: result.size, | 
| 644 memoryTypeIndex: memoryTypeIndex, | 653 memoryTypeIndex: memoryTypeIndex, | 
| 645 ) | 654 ) | 
| 646 checkVkResult vkAllocateMemory( | 655 checkVkResult vkAllocateMemory( | 
| 647 device, | 656 device, | 
| 648 addr allocationInfo, | 657 addr allocationInfo, | 
| 649 nil, | 658 nil, | 
| 650 addr result.vk | 659 addr result.vk | 
| 651 ) | 660 ) | 
| 652 | 661 | 
| 653 proc AllocateDirectMemory(device: VkDevice, allocationSize: uint64): DirectGPUMemory = | 662 proc AllocateDirectMemory(device: VkDevice, pDevice: VkPhysicalDevice, size: uint64): DirectGPUMemory = | 
| 654 result.size = allocationSize | 663 result.size = size | 
| 664 result.needsFlush = true | |
| 655 | 665 | 
| 656 # find a good memory type | 666 # find a good memory type | 
| 657 var physicalProperties: VkPhysicalDeviceMemoryProperties | 667 var physicalProperties: VkPhysicalDeviceMemoryProperties | 
| 658 vkGetPhysicalDeviceMemoryProperties(pDevice, addr physicalProperties) | 668 vkGetPhysicalDeviceMemoryProperties(pDevice, addr physicalProperties) | 
| 659 | 669 | 
| 660 var biggestHeap: uint64 = -1 | 670 var biggestHeap: uint64 = 0 | 
| 661 var memoryTypeIndex = -1 | 671 var memoryTypeIndex = high(uint32) | 
| 662 # try to find host-visible type | 672 # try to find host-visible type | 
| 663 for i in 0 ..< physicalProperties.memoryTypeCount: | 673 for i in 0 ..< physicalProperties.memoryTypeCount: | 
| 664 if VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT in toEnums(physicalProperties.memoryTypes[i].propertyFlags) | 674 let flags = toEnums(physicalProperties.memoryTypes[i].propertyFlags) | 
| 675 if VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT in flags: | |
| 665 let size = physicalProperties.memoryHeaps[physicalProperties.memoryTypes[i].heapIndex].size | 676 let size = physicalProperties.memoryHeaps[physicalProperties.memoryTypes[i].heapIndex].size | 
| 666 if size > biggestHeap: | 677 if size > biggestHeap: | 
| 667 biggest = size | 678 biggestHeap = size | 
| 668 memoryTypeIndex = i | 679 memoryTypeIndex = i | 
| 669 | 680 result.needsFlush = not (VK_MEMORY_PROPERTY_HOST_COHERENT_BIT in flags) | 
| 670 assert memoryTypeIndex >= 0, "Unable to find direct (aka host-visible) memory type" | 681 | 
| 682 assert memoryTypeIndex != high(uint32), "Unable to find indirect memory type" | |
| 671 var allocationInfo = VkMemoryAllocateInfo( | 683 var allocationInfo = VkMemoryAllocateInfo( | 
| 672 sType: VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, | 684 sType: VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, | 
| 673 allocationSize: initialAllocationSize, | 685 allocationSize: result.size, | 
| 674 memoryTypeIndex: memoryTypeIndex, | 686 memoryTypeIndex: memoryTypeIndex, | 
| 675 ) | 687 ) | 
| 676 checkVkResult vkAllocateMemory( | 688 checkVkResult vkAllocateMemory( | 
| 677 device, | 689 device, | 
| 678 addr allocationInfo, | 690 addr allocationInfo, | 
| 679 nil, | 691 nil, | 
| 680 addr result.vk | 692 addr result.vk | 
| 681 ) | 693 ) | 
| 682 checkVkResult result.device.vk.vkMapMemory( | 694 checkVkResult vkMapMemory( | 
| 695 device = device, | |
| 683 memory = result.vk, | 696 memory = result.vk, | 
| 684 offset = 0'u64, | 697 offset = 0'u64, | 
| 685 size = result.size, | 698 size = result.size, | 
| 686 flags = VkMemoryMapFlags(0), | 699 flags = VkMemoryMapFlags(0), | 
| 687 ppData = addr(result.data) | 700 ppData = addr(result.data) | 
| 688 ) | 701 ) | 
| 689 | 702 | 
| 690 proc InitRenderData(device: VkDevice, descriptorPoolLimit = 1024): RenderData = | 703 proc AllocateIndirectBuffer(device: VkDevice, renderData: var RenderData, size: uint64, usage: openArray[VkBufferUsageFlagBits]) = | 
| 704 assert size > 0, "Buffer sizes must be larger than 0" | |
| 705 var buffer = Buffer[IndirectGPUMemory](size: size) | |
| 706 | |
| 707 # iterate through memory areas to find big enough free space | |
| 708 for (memory, offset) in renderData.indirectMemory.mitems: | |
| 709 if memory.size - offset >= size: | |
| 710 buffer.offset = offset | |
| 711 # create buffer | |
| 712 var createInfo = VkBufferCreateInfo( | |
| 713 sType: VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, | |
| 714 flags: VkBufferCreateFlags(0), | |
| 715 size: buffer.size, | |
| 716 usage: toBits(@usage & @[VK_BUFFER_USAGE_TRANSFER_DST_BIT]), # ensure we can transfer to this buffer | |
| 717 sharingMode: VK_SHARING_MODE_EXCLUSIVE, | |
| 718 ) | |
| 719 checkVkResult vkCreateBuffer( | |
| 720 device = device, | |
| 721 pCreateInfo = addr createInfo, | |
| 722 pAllocator = nil, | |
| 723 pBuffer = addr(buffer.vk) | |
| 724 ) | |
| 725 checkVkResult vkBindBufferMemory(device, buffer.vk, memory.vk, buffer.offset) | |
| 726 renderData.indirectBuffers.add buffer | |
| 727 # update memory area offset | |
| 728 offset = offset + size | |
| 729 if offset mod MEMORY_ALIGNMENT != 0: | |
| 730 offset = offset + MEMORY_ALIGNMENT - (offset mod MEMORY_ALIGNMENT) | |
| 731 return | |
| 732 | |
| 733 assert false, "Did not find allocated memory region with enough space" | |
| 734 | |
| 735 proc AllocateDirectBuffer(device: VkDevice, renderData: var RenderData, size: uint64, usage: openArray[VkBufferUsageFlagBits]) = | |
| 736 assert size > 0, "Buffer sizes must be larger than 0" | |
| 737 var buffer = Buffer[DirectGPUMemory](size: size) | |
| 738 | |
| 739 # iterate through memory areas to find big enough free space | |
| 740 for (memory, offset) in renderData.directMemory.mitems: | |
| 741 if memory.size - offset >= size: | |
| 742 buffer.offset = offset | |
| 743 # create buffer | |
| 744 var createInfo = VkBufferCreateInfo( | |
| 745 sType: VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, | |
| 746 flags: VkBufferCreateFlags(0), | |
| 747 size: buffer.size, | |
| 748 usage: toBits(usage), | |
| 749 sharingMode: VK_SHARING_MODE_EXCLUSIVE, | |
| 750 ) | |
| 751 checkVkResult vkCreateBuffer( | |
| 752 device = device, | |
| 753 pCreateInfo = addr createInfo, | |
| 754 pAllocator = nil, | |
| 755 pBuffer = addr(buffer.vk) | |
| 756 ) | |
| 757 checkVkResult vkBindBufferMemory(device, buffer.vk, memory.vk, buffer.offset) | |
| 758 renderData.directBuffers.add buffer | |
| 759 # update memory area offset | |
| 760 offset = offset + size | |
| 761 if offset mod MEMORY_ALIGNMENT != 0: | |
| 762 offset = offset + MEMORY_ALIGNMENT - (offset mod MEMORY_ALIGNMENT) | |
| 763 return | |
| 764 | |
| 765 assert false, "Did not find allocated memory region with enough space" | |
| 766 | |
| 767 proc InitRenderData(device: VkDevice, pDevice: VkPhysicalDevice, descriptorPoolLimit = 1024'u32): RenderData = | |
| 691 # allocate descriptor pools | 768 # allocate descriptor pools | 
| 692 var poolSizes = [ | 769 var poolSizes = [ | 
| 693 VkDescriptorPoolSize(thetype: VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, descriptorCount: descriptorPoolLimit) | 770 VkDescriptorPoolSize(thetype: VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, descriptorCount: descriptorPoolLimit), | 
| 694 VkDescriptorPoolSize(thetype: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, descriptorCount: descriptorPoolLimit) | 771 VkDescriptorPoolSize(thetype: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, descriptorCount: descriptorPoolLimit), | 
| 695 ] | 772 ] | 
| 696 var poolInfo = VkDescriptorPoolCreateInfo( | 773 var poolInfo = VkDescriptorPoolCreateInfo( | 
| 697 sType: VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, | 774 sType: VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, | 
| 698 poolSizeCount: poolSizes.len.uint32, | 775 poolSizeCount: poolSizes.len.uint32, | 
| 699 pPoolSizes: poolSizes.ToCPointer, | 776 pPoolSizes: poolSizes.ToCPointer, | 
| 700 maxSets: descriptorPoolLimit, | 777 maxSets: descriptorPoolLimit, | 
| 701 ) | 778 ) | 
| 702 checkVkResult vkCreateDescriptorPool(device, addr(poolInfo), nil, addr(result.descriptorPool)) | 779 checkVkResult vkCreateDescriptorPool(device, addr(poolInfo), nil, addr(result.descriptorPool)) | 
| 703 | 780 | 
| 704 # allocate some memory | 781 # allocate some memory | 
| 705 var initialAllocationSize: 1_000_000_000 # TODO: make this more dynamic or something | 782 var initialAllocationSize = 1_000_000_000'u64 # TODO: make this more dynamic or something | 
| 706 result.indirectMemory = @[AllocateIndirectMemory(device, size=initialAllocationSize)] | 783 result.indirectMemory = @[(AllocateIndirectMemory(device, pDevice, size = initialAllocationSize), 0'u64)] | 
| 707 result.nextFreeIndirectMemoryOffset = @[0'u64] | 784 result.directMemory = @[(AllocateDirectMemory(device, pDevice, size = initialAllocationSize), 0'u64)] | 
| 708 result.directMemory = @[AllocateDirectMemory(device, size=initialAllocationSize)] | 785 | 
| 709 result.nextFreeDirectMemoryOffset = @[0'u64] | 786 proc GetIndirectBufferSizes[T](data: T): uint64 = | 
| 710 | 787 # return buffer sizes for direct and indirect buffers | 
| 711 proc WriteDescriptors[TShader](device: VkDevice, pipeline: Pipeline[TShader]) = | 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): | |
| 790 when not hasCustomPragma(value, VertexIndices) | |
| 791 when typeof(value) is GPUArray: | |
| 792 if not IsDirectMemory(value): | |
| 793 result += (value.data.len * sizeof(elementType(value.data))).uint64 + 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 = | |
| 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): | |
| 801 when not hasCustomPragma(value, VertexIndices) | |
| 802 when typeof(value) is GPUArray: | |
| 803 if IsDirectMemory(value): | |
| 804 result += (value.data.len * sizeof(elementType(value.data))).uint64 + 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 = | |
| 810 for name, value in fieldPairs(data): | |
| 811 when hasCustomPragma(value, VertexIndices): | |
| 812 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 | |
| 814 if not IsDirectMemory(value): | |
| 815 result += (value.data.len * sizeof(elementType(value.data))).uint64 + BUFFER_ALIGNMENT | |
| 816 | |
| 817 proc GetDirectIndexBufferSizes[T](data: T): uint64 = | |
| 818 for name, value in fieldPairs(data): | |
| 819 when hasCustomPragma(value, VertexIndices): | |
| 820 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 | |
| 822 if IsDirectMemory(value): | |
| 823 result += (value.data.len * sizeof(elementType(value.data))).uint64 + BUFFER_ALIGNMENT | |
| 824 | |
| 825 | |
| 826 proc WriteDescriptors[TShader](device: VkDevice, descriptorSets: array[INFLIGHTFRAMES.int, VkDescriptorSet]) = | |
| 712 var descriptorSetWrites: seq[VkWriteDescriptorSet] | 827 var descriptorSetWrites: seq[VkWriteDescriptorSet] | 
| 713 # map (buffer + offset + range) to descriptor | 828 # map (buffer + offset + range) to descriptor | 
| 714 # map (texture) to descriptor | 829 # map (texture) to descriptor | 
| 715 ForDescriptorFields(default(TShader), fieldName, descriptorType, descriptorCount, descriptorBindingNumber): | 830 ForDescriptorFields(default(TShader), fieldName, descriptorType, descriptorCount, descriptorBindingNumber): | 
| 716 for frameInFlight in 0 ..< pipeline.descriptorSets.len: | 831 for frameInFlight in 0 ..< descriptorSets.len: | 
| 717 if descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: | 832 when descriptorType == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: | 
| 718 # TODO | 833 # TODO | 
| 719 let bufferInfo = VkDescriptorBufferInfo( | 834 let bufferInfo = VkDescriptorBufferInfo( | 
| 720 buffer: VkBuffer(0), | 835 buffer: VkBuffer(0), | 
| 721 offset: 0, | 836 offset: 0, | 
| 722 range: 1, | 837 range: 1, | 
| 723 ) | 838 ) | 
| 724 descriptorSetWrites.add VkWriteDescriptorSet( | 839 descriptorSetWrites.add VkWriteDescriptorSet( | 
| 725 sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, | 840 sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, | 
| 726 dstSet: pipeline.descriptorSets[frameInFlight], | 841 dstSet: descriptorSets[frameInFlight], | 
| 727 dstBinding: descriptorBindingNumber, | 842 dstBinding: descriptorBindingNumber, | 
| 728 dstArrayElement: uint32(0), | 843 dstArrayElement: uint32(0), | 
| 729 descriptorType: descriptorType, | 844 descriptorType: descriptorType, | 
| 730 descriptorCount: descriptorCount, | 845 descriptorCount: descriptorCount, | 
| 731 pImageInfo: nil, | 846 pImageInfo: nil, | 
| 738 imageView: VkImageView(0), | 853 imageView: VkImageView(0), | 
| 739 imageLayout: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, | 854 imageLayout: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, | 
| 740 ) | 855 ) | 
| 741 descriptorSetWrites.add VkWriteDescriptorSet( | 856 descriptorSetWrites.add VkWriteDescriptorSet( | 
| 742 sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, | 857 sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, | 
| 743 dstSet: pipeline.descriptorSets[frameInFlight], | 858 dstSet: descriptorSets[frameInFlight], | 
| 744 dstBinding: descriptorBindingNumber, | 859 dstBinding: descriptorBindingNumber, | 
| 745 dstArrayElement: uint32(0), | 860 dstArrayElement: uint32(0), | 
| 746 descriptorType: descriptorType, | 861 descriptorType: descriptorType, | 
| 747 descriptorCount: descriptorCount, | 862 descriptorCount: descriptorCount, | 
| 748 pImageInfo: addr(imageInfo), | 863 pImageInfo: addr(imageInfo), | 
| 749 pBufferInfo: nil, | 864 pBufferInfo: nil, | 
| 750 ) | 865 ) | 
| 751 vkUpdateDescriptorSets(device, uint32(descriptorSetWrites.len), descriptorSetWrites.ToCPointer, 0, nil) | 866 vkUpdateDescriptorSets(device, uint32(descriptorSetWrites.len), descriptorSetWrites.ToCPointer, 0, nil) | 
| 752 | 867 | 
| 753 proc CreateRenderable[TMesh, TInstance]( | |
| 754 mesh: TMesh, | |
| 755 instance: TInstance, | |
| 756 ): Renderable[TMesh, TInstance] = | |
| 757 result.indexType = None | |
| 758 | |
| 759 proc Bind[T](pipeline: Pipeline[T], commandBuffer: VkCommandBuffer, currentFrameInFlight: int) = | 868 proc Bind[T](pipeline: Pipeline[T], commandBuffer: VkCommandBuffer, currentFrameInFlight: int) = | 
| 760 let a = pipeline.descriptorSets | |
| 761 commandBuffer.vkCmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipeline) | 869 commandBuffer.vkCmdBindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipeline) | 
| 762 if a[currentFrameInFlight] != VkDescriptorSet(0): | 870 #[ | 
| 763 commandBuffer.vkCmdBindDescriptorSets( | 871 commandBuffer.vkCmdBindDescriptorSets( | 
| 764 VK_PIPELINE_BIND_POINT_GRAPHICS, | 872 VK_PIPELINE_BIND_POINT_GRAPHICS, | 
| 765 pipeline.layout, | 873 pipeline.layout, | 
| 766 0, | 874 0, | 
| 767 1, | 875 1, | 
| 768 addr pipeline.descriptorSets[currentFrameInFlight], | 876 addr pipeline.descriptorSets[currentFrameInFlight], | 
| 769 0, | 877 0, | 
| 770 nil, | 878 nil, | 
| 771 ) | 879 ) | 
| 772 | 880 ]# | 
| 773 proc AssertCompatible(TShader, TMesh, TInstance, TGlobals: typedesc) = | 881 | 
| 882 proc AssertCompatible(TShader, TMesh, TInstance, TUniforms, TGlobals: typedesc) = | |
| 774 # assert seq-fields of TMesh|TInstance == seq-fields of TShader | 883 # assert seq-fields of TMesh|TInstance == seq-fields of TShader | 
| 775 # assert normal fields of TMesh|Globals == normal fields of TShaderDescriptors | 884 # assert normal fields of TMesh|Globals == normal fields of TShaderDescriptors | 
| 776 for inputName, inputValue in default(TShader).fieldPairs: | 885 for inputName, inputValue in default(TShader).fieldPairs: | 
| 777 var foundField = false | 886 var foundField = false | 
| 778 | 887 | 
| 798 foundField = true | 907 foundField = true | 
| 799 assert foundField, "Shader input '" & tt.name(TShader) & "." & inputName & ": " & tt.name(typeof(inputValue)) & "' not found in '" & tt.name(TInstance) & "'" | 908 assert foundField, "Shader input '" & tt.name(TShader) & "." & inputName & ": " & tt.name(typeof(inputValue)) & "' not found in '" & tt.name(TInstance) & "'" | 
| 800 | 909 | 
| 801 # Texture | 910 # Texture | 
| 802 elif typeof(inputValue) is Texture: | 911 elif typeof(inputValue) is Texture: | 
| 803 for meshName, meshValue in default(TMesh).fieldPairs: | 912 for uniformName, uniformValue in default(TUniforms).fieldPairs: | 
| 804 when meshName == inputName: | 913 when uniformName == inputName: | 
| 805 assert foundField == false, "Shader input '" & tt.name(TShader) & "." & inputName & "' has been found more than once" | 914 assert foundField == false, "Shader input '" & tt.name(TShader) & "." & inputName & "' has been found more than once" | 
| 806 assert typeof(meshValue) is typeof(inputValue), "Shader input " & tt.name(TShader) & "." & inputName & " is of type '" & tt.name(typeof(inputValue)) & "' but mesh attribute is of type '" & tt.name(elementType(meshValue)) & "'" | 915 assert typeof(uniformValue) is typeof(inputValue), "Shader input " & tt.name(TShader) & "." & inputName & " is of type '" & tt.name(typeof(inputValue)) & "' but uniform attribute is of type '" & tt.name(typeof(uniformValue)) & "'" | 
| 807 foundField = true | 916 foundField = true | 
| 808 for globalName, globalValue in default(TGlobals).fieldPairs: | 917 for globalName, globalValue in default(TGlobals).fieldPairs: | 
| 809 when globalName == inputName: | 918 when globalName == inputName: | 
| 810 assert foundField == false, "Shader input '" & tt.name(TShader) & "." & inputName & "' has been found more than once" | 919 assert foundField == false, "Shader input '" & tt.name(TShader) & "." & inputName & "' has been found more than once" | 
| 811 assert typeof(globalValue) 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)) & "'" | 920 assert typeof(globalValue) 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)) & "'" | 
| 812 foundField = true | 921 foundField = true | 
| 813 assert foundField, "Shader input '" & tt.name(TShader) & "." & inputName & ": " & tt.name(typeof(inputValue)) & "' not found in '" & tt.name(TMesh) & "|" & tt.name(TGlobals) & "'" | 922 assert foundField, "Shader input '" & tt.name(TShader) & "." & inputName & ": " & tt.name(typeof(inputValue)) & "' not found in '" & tt.name(TMesh) & "|" & tt.name(TGlobals) & "'" | 
| 814 | 923 | 
| 815 # Uniform block | 924 # Uniform block | 
| 816 elif typeof(inputValue) is object: | 925 elif typeof(inputValue) is object: | 
| 817 for meshName, meshValue in default(TMesh).fieldPairs: | 926 for uniformName, uniformValue in default(TUniforms).fieldPairs: | 
| 818 when meshName == inputName: | 927 when uniformName == inputName: | 
| 819 assert meshValue is GPUValue, "Mesh attribute '" & meshName & "' must be of type 'GPUValue' but is of type " & tt.name(typeof(meshValue)) | 928 assert uniformValue is GPUValue, "global attribute '" & uniformName & "' must be of type 'GPUValue' but is of type " & tt.name(typeof(uniformValue)) | 
| 820 assert foundField == false, "Shader input '" & tt.name(TShader) & "." & inputName & "' has been found more than once" | 929 assert foundField == false, "Shader input '" & tt.name(TShader) & "." & inputName & "' has been found more than once" | 
| 821 assert typeof(meshValue.data) is typeof(inputValue), "Shader input " & tt.name(TShader) & "." & inputName & " is of type '" & tt.name(typeof(inputValue)) & "' but mesh attribute is of type '" & tt.name(elementType(meshValue.data)) & "'" | 930 assert typeof(uniformValue.data) is typeof(inputValue), "Shader input " & tt.name(TShader) & "." & inputName & " is of type '" & tt.name(typeof(inputValue)) & "' but uniform attribute is of type '" & tt.name(typeof(uniformValue.data)) & "'" | 
| 822 foundField = true | 931 foundField = true | 
| 823 for globalName, globalValue in default(TGlobals).fieldPairs: | 932 for globalName, globalValue in default(TGlobals).fieldPairs: | 
| 824 when globalName == inputName: | 933 when globalName == inputName: | 
| 825 assert globalValue is GPUValue, "global attribute '" & globalName & "' must be of type 'GPUValue' but is of type " & tt.name(typeof(globalValue)) | 934 assert globalValue is GPUValue, "global attribute '" & globalName & "' must be of type 'GPUValue' but is of type " & tt.name(typeof(globalValue)) | 
| 826 assert foundField == false, "Shader input '" & tt.name(TShader) & "." & inputName & "' has been found more than once" | 935 assert foundField == false, "Shader input '" & tt.name(TShader) & "." & inputName & "' has been found more than once" | 
| 831 # array | 940 # array | 
| 832 elif typeof(inputValue) is array: | 941 elif typeof(inputValue) is array: | 
| 833 | 942 | 
| 834 # texture-array | 943 # texture-array | 
| 835 when elementType(inputValue) is Texture: | 944 when elementType(inputValue) is Texture: | 
| 836 for meshName, meshValue in default(TMesh).fieldPairs: | 945 for uniformName, uniformValue in default(TUniforms).fieldPairs: | 
| 837 when meshName == inputName: | 946 when uniformName == inputName: | 
| 838 assert foundField == false, "Shader input '" & tt.name(TShader) & "." & inputName & "' has been found more than once" | 947 assert foundField == false, "Shader input '" & tt.name(TShader) & "." & inputName & "' has been found more than once" | 
| 839 assert typeof(meshValue) is typeof(inputValue), "Shader input " & tt.name(TShader) & "." & inputName & " is of type '" & tt.name(typeof(inputValue)) & "' but mesh attribute is of type '" & tt.name(elementType(meshValue)) & "'" | 948 assert typeof(uniformValue) is typeof(inputValue), "Shader input " & tt.name(TShader) & "." & inputName & " is of type '" & tt.name(typeof(inputValue)) & "' but uniform attribute is of type '" & tt.name(typeof(uniformValue)) & "'" | 
| 840 foundField = true | 949 foundField = true | 
| 841 for globalName, globalValue in default(TGlobals).fieldPairs: | 950 for globalName, globalValue in default(TGlobals).fieldPairs: | 
| 842 when globalName == inputName: | 951 when globalName == inputName: | 
| 843 assert foundField == false, "Shader input '" & tt.name(TShader) & "." & inputName & "' has been found more than once" | 952 assert foundField == false, "Shader input '" & tt.name(TShader) & "." & inputName & "' has been found more than once" | 
| 844 assert typeof(globalValue) 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)) & "'" | 953 assert typeof(globalValue) 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)) & "'" | 
| 845 foundField = true | 954 foundField = true | 
| 846 assert foundField, "Shader input '" & tt.name(TShader) & "." & inputName & ": " & tt.name(typeof(inputValue)) & "' not found in '" & tt.name(TMesh) & "|" & tt.name(TGlobals) & "'" | 955 assert foundField, "Shader input '" & tt.name(TShader) & "." & inputName & ": " & tt.name(typeof(inputValue)) & "' not found in '" & tt.name(TMesh) & "|" & tt.name(TGlobals) & "'" | 
| 847 | 956 | 
| 848 # uniform-block array | 957 # uniform-block array | 
| 849 elif elementType(inputValue) is object: | 958 elif elementType(inputValue) is object: | 
| 850 for meshName, meshValue in default(TMesh).fieldPairs: | 959 for uniformName, uniformValue in default(TUniforms).fieldPairs: | 
| 851 when meshName == inputName: | 960 when uniformName == inputName: | 
| 852 assert meshValue is GPUValue, "Mesh attribute '" & meshName & "' must be of type 'GPUValue' but is of type " & tt.name(typeof(meshValue)) | 961 assert uniformValue is GPUValue, "global attribute '" & uniformName & "' must be of type 'GPUValue' but is of type " & tt.name(typeof(uniformValue)) | 
| 853 assert foundField == false, "Shader input '" & tt.name(TShader) & "." & inputName & "' has been found more than once" | 962 assert foundField == false, "Shader input '" & tt.name(TShader) & "." & inputName & "' has been found more than once" | 
| 854 assert typeof(meshValue.data) is typeof(inputValue), "Shader input " & tt.name(TShader) & "." & inputName & " is of type '" & tt.name(typeof(inputValue)) & "' but mesh attribute is of type '" & tt.name(elementType(meshValue.data)) & "'" | 963 assert typeof(uniformValue.data) is typeof(inputValue), "Shader input " & tt.name(TShader) & "." & inputName & " is of type '" & tt.name(typeof(inputValue)) & "' but uniform attribute is of type '" & tt.name(typeof(uniformValue.data)) & "'" | 
| 855 foundField = true | 964 foundField = true | 
| 856 for globalName, globalValue in default(TGlobals).fieldPairs: | 965 for globalName, globalValue in default(TGlobals).fieldPairs: | 
| 857 when globalName == inputName: | 966 when globalName == inputName: | 
| 858 assert globalValue is GPUValue, "global attribute '" & globalName & "' must be of type 'GPUValue' but is of type " & tt.name(typeof(globalValue)) | 967 assert globalValue is GPUValue, "global attribute '" & globalName & "' must be of type 'GPUValue' but is of type " & tt.name(typeof(globalValue)) | 
| 859 assert foundField == false, "Shader input '" & tt.name(TShader) & "." & inputName & "' has been found more than once" | 968 assert foundField == false, "Shader input '" & tt.name(TShader) & "." & inputName & "' has been found more than once" | 
| 860 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)) & "'" | 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)) & "'" | 
| 861 foundField = true | 970 foundField = true | 
| 862 assert foundField, "Shader input '" & tt.name(TShader) & "." & inputName & ": " & tt.name(typeof(inputValue)) & "' not found in '" & tt.name(TMesh) & "|" & tt.name(TGlobals) & "'" | 971 assert foundField, "Shader input '" & tt.name(TShader) & "." & inputName & ": " & tt.name(typeof(inputValue)) & "' not found in '" & tt.name(TMesh) & "|" & tt.name(TGlobals) & "'" | 
| 863 | 972 | 
| 864 | 973 | 
| 865 proc Render[TShader, TMesh, TInstance, TGlobals]( | 974 proc Render[TShader, TMesh, TInstance, TUniforms, TGlobals]( | 
| 866 pipeline: Pipeline[TShader], | 975 pipeline: Pipeline[TShader], | 
| 867 renderable: Renderable[TMesh, TInstance], | 976 renderable: Renderable[TMesh, TInstance], | 
| 977 uniforms: TUniforms, | |
| 868 globals: TGlobals, | 978 globals: TGlobals, | 
| 869 commandBuffer: VkCommandBuffer, | 979 commandBuffer: VkCommandBuffer, | 
| 870 ) = | 980 ) = | 
| 871 static: AssertCompatible(TShader, TMesh, TInstance, TGlobals) | 981 static: AssertCompatible(TShader, TMesh, TInstance, TUniforms, TGlobals) | 
| 872 if renderable.vertexBuffers.len > 0: | 982 if renderable.vertexBuffers.len > 0: | 
| 873 commandBuffer.vkCmdBindVertexBuffers( | 983 commandBuffer.vkCmdBindVertexBuffers( | 
| 874 firstBinding = 0'u32, | 984 firstBinding = 0'u32, | 
| 875 bindingCount = uint32(renderable.vertexBuffers.len), | 985 bindingCount = uint32(renderable.vertexBuffers.len), | 
| 876 pBuffers = renderable.vertexBuffers.ToCPointer(), | 986 pBuffers = renderable.vertexBuffers.ToCPointer(), | 
| 903 import semicongine/vulkan/device | 1013 import semicongine/vulkan/device | 
| 904 import semicongine/vulkan/physicaldevice | 1014 import semicongine/vulkan/physicaldevice | 
| 905 import std/options | 1015 import std/options | 
| 906 | 1016 | 
| 907 type | 1017 type | 
| 1018 MeshA = object | |
| 1019 position: GPUArray[Vec3f, IndirectGPUMemory] | |
| 1020 indices {.VertexIndices.}: GPUArray[uint16, IndirectGPUMemory] | |
| 1021 InstanceA = object | |
| 1022 rotation: GPUArray[Vec4f, IndirectGPUMemory] | |
| 1023 objPosition: GPUArray[Vec3f, IndirectGPUMemory] | |
| 908 MaterialA = object | 1024 MaterialA = object | 
| 909 reflection: float32 | 1025 reflection: float32 | 
| 910 baseColor: Vec3f | 1026 baseColor: Vec3f | 
| 911 ShaderSettings = object | |
| 912 brightness: float32 | |
| 913 MeshA = object | |
| 914 position: GPUArray[Vec3f, IndirectGPUMemory] | |
| 915 InstanceA = object | |
| 916 rotation: GPUArray[Vec4f, IndirectGPUMemory] | |
| 917 objPosition: GPUArray[Vec3f, IndirectGPUMemory] | |
| 918 UniformsA = object | 1027 UniformsA = object | 
| 919 materials: GPUValue[array[3, MaterialA], IndirectGPUMemory] | 1028 materials: GPUValue[array[3, MaterialA], IndirectGPUMemory] | 
| 920 materialTextures: array[3, Texture] | 1029 materialTextures: array[3, Texture] | 
| 1030 ShaderSettings = object | |
| 1031 brightness: float32 | |
| 921 GlobalsA = object | 1032 GlobalsA = object | 
| 922 fontAtlas: Texture | 1033 fontAtlas: Texture | 
| 923 settings: GPUValue[ShaderSettings, IndirectGPUMemory] | 1034 settings: GPUValue[ShaderSettings, IndirectGPUMemory] | 
| 924 | 1035 | 
| 925 ShaderA = object | 1036 ShaderA = object | 
| 988 # shaders | 1099 # shaders | 
| 989 const shader = ShaderA() | 1100 const shader = ShaderA() | 
| 990 let shaderObject = dev.vk.CompileShader(shader) | 1101 let shaderObject = dev.vk.CompileShader(shader) | 
| 991 var pipeline1 = CreatePipeline(dev.vk, renderPass = renderpass, shaderObject) | 1102 var pipeline1 = CreatePipeline(dev.vk, renderPass = renderpass, shaderObject) | 
| 992 | 1103 | 
| 993 var renderdata = InitRenderData(dev.vk) | 1104 var renderdata = InitRenderData(dev.vk, dev.physicalDevice.vk) | 
| 994 | 1105 | 
| 995 # create descriptor sets | 1106 # create descriptor sets | 
| 1107 #[ | |
| 996 var descriptorSets: array[INFLIGHTFRAMES.int, VkDescriptorSet] | 1108 var descriptorSets: array[INFLIGHTFRAMES.int, VkDescriptorSet] | 
| 997 var layouts = newSeqWith(descriptorSets.len, pipeline.descriptorSetLayout) | 1109 var layouts = newSeqWith(descriptorSets.len, pipeline.descriptorSetLayout) | 
| 998 var allocInfo = VkDescriptorSetAllocateInfo( | 1110 var allocInfo = VkDescriptorSetAllocateInfo( | 
| 999 sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, | 1111 sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, | 
| 1000 descriptorPool: pool, | 1112 descriptorPool: pool, | 
| 1001 descriptorSetCount: uint32(layouts.len), | 1113 descriptorSetCount: uint32(layouts.len), | 
| 1002 pSetLayouts: layouts.ToCPointer, | 1114 pSetLayouts: layouts.ToCPointer, | 
| 1003 ) | 1115 ) | 
| 1004 checkVkResult vkAllocateDescriptorSets(device, addr(allocInfo), descriptorSets.ToCPointer) | 1116 checkVkResult vkAllocateDescriptorSets(device, addr(allocInfo), descriptorSets.ToCPointer) | 
| 1005 | 1117 ]# | 
| 1006 | 1118 | 
| 1007 #[ | 1119 #[ | 
| 1008 # TODO: probably here: allocate renderables, uniform buffers & textures | 1120 # TODO: | 
| 1009 let meshBuffers: seq[(bool, uint64)] = GetBufferSizes[MeshA](item = myMesh1) | 1121 # | 
| 1010 let instanceBuffers: seq[(bool, uint64)] = GetBufferSizes[InstanceA](item = instances1) | 1122 # assign indirect buffers to vertex data, can happen through the GPUArray/GPUValue-wrappers, they know buffers | 
| 1011 let globalBuffers: seq[(bool, uint64)] = GetBufferSizes[Globals](item = myGlobals) | 1123 # assign direct buffers to vertex data | 
| 1012 var myRenderable = CreateRenderable() | 1124 # assign indirect buffers to uniform data | 
| 1013 UploadTextures[MeshA]() | 1125 # assign direct buffers to uniform data | 
| 1014 UploadTextures[Globals]() | 1126 # | 
| 1127 # upload all textures | |
| 1128 # write descriptors for textures and uniform buffers | |
| 1129 # | |
| 1015 ]# | 1130 ]# | 
| 1016 var myRenderable: Renderable[MeshA, InstanceA] | 1131 var myRenderable: Renderable[MeshA, InstanceA] | 
| 1017 | 1132 | 
| 1133 var | |
| 1134 indirectVertexSizes = 0'u64 | |
| 1135 directVertexSizes = 0'u64 | |
| 1136 indirectIndexSizes = 0'u64 | |
| 1137 directIndexSizes = 0'u64 | |
| 1138 indirectUniformSizes = 0'u64 | |
| 1139 directUniformSizes = 0'u64 | |
| 1140 | |
| 1141 indirectVertexSizes += GetIndirectBufferSizes(myMesh1) | |
| 1142 indirectVertexSizes += GetIndirectBufferSizes(instances1) | |
| 1143 if indirectVertexSizes > 0: | |
| 1144 AllocateIndirectBuffer(dev.vk, renderdata, indirectVertexSizes, [VK_BUFFER_USAGE_VERTEX_BUFFER_BIT]) | |
| 1145 | |
| 1146 directVertexSizes += GetDirectBufferSizes(myMesh1) | |
| 1147 directVertexSizes += GetDirectBufferSizes(instances1) | |
| 1148 if directVertexSizes > 0: | |
| 1149 AllocateDirectBuffer(dev.vk, renderdata, directVertexSizes, [VK_BUFFER_USAGE_VERTEX_BUFFER_BIT]) | |
| 1150 | |
| 1151 indirectIndexSizes += GetIndirectIndexBufferSizes(myMesh1) | |
| 1152 if indirectIndexSizes > 0: | |
| 1153 AllocateIndirectBuffer(dev.vk, renderdata, indirectIndexSizes, [VK_BUFFER_USAGE_INDEX_BUFFER_BIT]) | |
| 1154 | |
| 1155 directIndexSizes += GetDirectIndexBufferSizes(myMesh1) | |
| 1156 if directIndexSizes > 0: | |
| 1157 AllocateIndirectBuffer(dev.vk, renderdata, directIndexSizes, [VK_BUFFER_USAGE_INDEX_BUFFER_BIT]) | |
| 1158 | |
| 1159 indirectUniformSizes += GetIndirectBufferSizes(uniforms1) | |
| 1160 indirectUniformSizes += GetIndirectBufferSizes(myGlobals) | |
| 1161 if indirectUniformSizes > 0: | |
| 1162 AllocateIndirectBuffer(dev.vk, renderdata, indirectUniformSizes, [VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT]) | |
| 1163 | |
| 1164 directUniformSizes += GetDirectBufferSizes(uniforms1) | |
| 1165 directUniformSizes += GetDirectBufferSizes(myGlobals) | |
| 1166 if directUniformSizes > 0: | |
| 1167 AllocateDirectBuffer(dev.vk, renderdata, directUniformSizes, [VK_BUFFER_USAGE_VERTEX_BUFFER_BIT]) | |
| 1168 | |
| 1018 # descriptors | 1169 # descriptors | 
| 1019 WriteDescriptors(dev.vk, pipeline1) | 1170 # WriteDescriptors(dev.vk, pipeline1) | 
| 1020 | 1171 | 
| 1021 # command buffer | 1172 # command buffer | 
| 1022 var | 1173 var | 
| 1023 commandBufferPool: VkCommandPool | 1174 commandBufferPool: VkCommandPool | 
| 1024 cmdBuffers: array[INFLIGHTFRAMES.int, VkCommandBuffer] | 1175 cmdBuffers: array[INFLIGHTFRAMES.int, VkCommandBuffer] | 
| 1086 block: | 1237 block: | 
| 1087 Bind(pipeline1, cmd, currentFrameInFlight = currentFrameInFlight) | 1238 Bind(pipeline1, cmd, currentFrameInFlight = currentFrameInFlight) | 
| 1088 | 1239 | 
| 1089 # render object, will be loop | 1240 # render object, will be loop | 
| 1090 block: | 1241 block: | 
| 1091 Render(pipeline1, myRenderable, myGlobals, cmd) | 1242 Render(pipeline1, myRenderable, uniforms1, myGlobals, cmd) | 
| 1092 | 1243 | 
| 1093 vkCmdEndRenderPass(cmd) | 1244 vkCmdEndRenderPass(cmd) | 
| 1094 checkVkResult cmd.vkEndCommandBuffer() | 1245 checkVkResult cmd.vkEndCommandBuffer() | 
