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() |