Mercurial > games > semicongine
comparison semiconginev2/old/vulkan/descriptor.nim @ 1218:56781cc0fc7c compiletime-tests
did: renamge main package
| author | sam <sam@basx.dev> |
|---|---|
| date | Wed, 17 Jul 2024 21:01:37 +0700 |
| parents | semicongine/old/vulkan/descriptor.nim@a3eb305bcac2 |
| children |
comparison
equal
deleted
inserted
replaced
| 1217:f819a874058f | 1218:56781cc0fc7c |
|---|---|
| 1 import std/enumerate | |
| 2 import std/tables | |
| 3 | |
| 4 import ../core | |
| 5 import ./device | |
| 6 import ./buffer | |
| 7 import ./image | |
| 8 | |
| 9 type | |
| 10 DescriptorType* = enum | |
| 11 Uniform, ImageSampler | |
| 12 Descriptor* = object # "fields" of a DescriptorSetLayout | |
| 13 name*: string | |
| 14 count*: uint32 | |
| 15 stages*: seq[VkShaderStageFlagBits] | |
| 16 case thetype*: DescriptorType | |
| 17 of Uniform: | |
| 18 buffer*: Buffer | |
| 19 offset*: uint64 | |
| 20 size*: uint64 | |
| 21 of ImageSampler: | |
| 22 imageviews*: seq[ImageView] | |
| 23 samplers*: seq[VulkanSampler] | |
| 24 DescriptorSet* = object # "instance" of a DescriptorSetLayout | |
| 25 vk*: VkDescriptorSet | |
| 26 layout*: DescriptorSetLayout | |
| 27 DescriptorSetLayout* = object # "type-description" of a DescriptorSet | |
| 28 device: Device | |
| 29 vk*: VkDescriptorSetLayout | |
| 30 descriptors*: seq[Descriptor] | |
| 31 DescriptorPool* = object # required for allocation of DescriptorSet | |
| 32 device: Device | |
| 33 vk*: VkDescriptorPool | |
| 34 maxSets*: int # maximum number of allocatable descriptor sets | |
| 35 counts*: seq[(VkDescriptorType, uint32)] # maximum number for each descriptor type to allocate | |
| 36 | |
| 37 const DESCRIPTOR_TYPE_MAP = { | |
| 38 Uniform: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, | |
| 39 ImageSampler: VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, | |
| 40 }.toTable | |
| 41 | |
| 42 func vkType(descriptor: Descriptor): VkDescriptorType = | |
| 43 DESCRIPTOR_TYPE_MAP[descriptor.thetype] | |
| 44 | |
| 45 proc CreateDescriptorSetLayout*(device: Device, descriptors: seq[Descriptor]): DescriptorSetLayout = | |
| 46 assert device.vk.Valid | |
| 47 | |
| 48 result.device = device | |
| 49 result.descriptors = descriptors | |
| 50 | |
| 51 var layoutbindings: seq[VkDescriptorSetLayoutBinding] | |
| 52 for i, descriptor in enumerate(descriptors): | |
| 53 layoutbindings.add VkDescriptorSetLayoutBinding( | |
| 54 binding: uint32(i), | |
| 55 descriptorType: descriptor.vkType, | |
| 56 descriptorCount: descriptor.count, | |
| 57 stageFlags: toBits descriptor.stages, | |
| 58 pImmutableSamplers: nil, | |
| 59 ) | |
| 60 var layoutCreateInfo = VkDescriptorSetLayoutCreateInfo( | |
| 61 sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, | |
| 62 bindingCount: uint32(layoutbindings.len), | |
| 63 pBindings: layoutbindings.ToCPointer | |
| 64 ) | |
| 65 checkVkResult vkCreateDescriptorSetLayout(device.vk, addr(layoutCreateInfo), nil, addr(result.vk)) | |
| 66 | |
| 67 proc Destroy*(descriptorSetLayout: var DescriptorSetLayout) = | |
| 68 assert descriptorSetLayout.device.vk.Valid | |
| 69 assert descriptorSetLayout.vk.Valid | |
| 70 descriptorSetLayout.device.vk.vkDestroyDescriptorSetLayout(descriptorSetLayout.vk, nil) | |
| 71 descriptorSetLayout.vk.Reset | |
| 72 | |
| 73 proc CreateDescriptorSetPool*(device: Device, counts: seq[(VkDescriptorType, uint32)], maxSets = 1000): DescriptorPool = | |
| 74 assert device.vk.Valid | |
| 75 | |
| 76 result.device = device | |
| 77 result.maxSets = maxSets | |
| 78 result.counts = counts | |
| 79 | |
| 80 var poolSizes: seq[VkDescriptorPoolSize] | |
| 81 for (thetype, count) in result.counts: | |
| 82 poolSizes.add VkDescriptorPoolSize(thetype: thetype, descriptorCount: count) | |
| 83 var poolInfo = VkDescriptorPoolCreateInfo( | |
| 84 sType: VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, | |
| 85 poolSizeCount: uint32(poolSizes.len), | |
| 86 pPoolSizes: poolSizes.ToCPointer, | |
| 87 maxSets: uint32(result.maxSets), | |
| 88 ) | |
| 89 checkVkResult vkCreateDescriptorPool(result.device.vk, addr(poolInfo), nil, addr(result.vk)) | |
| 90 | |
| 91 proc Reset*(pool: DescriptorPool) = | |
| 92 assert pool.device.vk.Valid | |
| 93 assert pool.vk.Valid | |
| 94 checkVkResult vkResetDescriptorPool(pool.device.vk, pool.vk, VkDescriptorPoolResetFlags(0)) | |
| 95 | |
| 96 proc Destroy*(pool: var DescriptorPool) = | |
| 97 assert pool.device.vk.Valid | |
| 98 assert pool.vk.Valid | |
| 99 pool.device.vk.vkDestroyDescriptorPool(pool.vk, nil) | |
| 100 pool.vk.Reset | |
| 101 | |
| 102 proc AllocateDescriptorSet*(pool: DescriptorPool, layout: DescriptorSetLayout, nframes: int): seq[DescriptorSet] = | |
| 103 assert pool.device.vk.Valid | |
| 104 assert pool.vk.Valid | |
| 105 assert layout.device.vk.Valid | |
| 106 assert layout.vk.Valid | |
| 107 | |
| 108 var layouts: seq[VkDescriptorSetLayout] | |
| 109 var descriptorSets = newSeq[VkDescriptorSet](nframes) | |
| 110 for i in 0 ..< nframes: | |
| 111 layouts.add layout.vk | |
| 112 var allocInfo = VkDescriptorSetAllocateInfo( | |
| 113 sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, | |
| 114 descriptorPool: pool.vk, | |
| 115 descriptorSetCount: uint32(layouts.len), | |
| 116 pSetLayouts: layouts.ToCPointer, | |
| 117 ) | |
| 118 | |
| 119 checkVkResult vkAllocateDescriptorSets(pool.device.vk, addr(allocInfo), descriptorSets.ToCPointer) | |
| 120 for descriptorSet in descriptorSets: | |
| 121 result.add DescriptorSet(vk: descriptorSet, layout: layout) | |
| 122 | |
| 123 proc WriteDescriptorSet*(descriptorSet: DescriptorSet, bindingBase = 0'u32) = | |
| 124 # assumes descriptors of the descriptorSet are arranged interleaved in buffer | |
| 125 assert descriptorSet.layout.device.vk.Valid | |
| 126 assert descriptorSet.layout.vk.Valid | |
| 127 assert descriptorSet.vk.Valid | |
| 128 | |
| 129 var descriptorSetWrites: seq[VkWriteDescriptorSet] | |
| 130 var bufferInfos: seq[VkDescriptorBufferInfo] | |
| 131 | |
| 132 var i = bindingBase | |
| 133 # need to keep this sequence out of the loop, otherwise it will be | |
| 134 # gc-ed before the final update call and pointers are invalid :( | |
| 135 var imgInfos: seq[seq[VkDescriptorImageInfo]] | |
| 136 for descriptor in descriptorSet.layout.descriptors: | |
| 137 if descriptor.thetype == Uniform: | |
| 138 assert descriptor.buffer.vk.Valid | |
| 139 bufferInfos.add VkDescriptorBufferInfo( | |
| 140 buffer: descriptor.buffer.vk, | |
| 141 offset: descriptor.offset, | |
| 142 range: descriptor.size, | |
| 143 ) | |
| 144 descriptorSetWrites.add VkWriteDescriptorSet( | |
| 145 sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, | |
| 146 dstSet: descriptorSet.vk, | |
| 147 dstBinding: i, | |
| 148 dstArrayElement: 0, | |
| 149 descriptorType: descriptor.vkType, | |
| 150 descriptorCount: uint32(descriptor.count), | |
| 151 pBufferInfo: addr bufferInfos[^1], | |
| 152 ) | |
| 153 elif descriptor.thetype == ImageSampler: | |
| 154 var imgInfo: seq[VkDescriptorImageInfo] | |
| 155 for img_i in 0 ..< descriptor.count: | |
| 156 assert descriptor.imageviews[img_i].vk.Valid | |
| 157 assert descriptor.samplers[img_i].vk.Valid | |
| 158 imgInfo.add VkDescriptorImageInfo( | |
| 159 imageLayout: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, | |
| 160 imageView: descriptor.imageviews[img_i].vk, | |
| 161 sampler: descriptor.samplers[img_i].vk, | |
| 162 ) | |
| 163 imgInfos.add imgInfo | |
| 164 descriptorSetWrites.add VkWriteDescriptorSet( | |
| 165 sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, | |
| 166 dstSet: descriptorSet.vk, | |
| 167 dstBinding: i, | |
| 168 dstArrayElement: 0, | |
| 169 descriptorType: descriptor.vkType, | |
| 170 descriptorCount: uint32(descriptor.count), | |
| 171 pImageInfo: imgInfos[^1].ToCPointer, | |
| 172 ) | |
| 173 inc i | |
| 174 descriptorSet.layout.device.vk.vkUpdateDescriptorSets(uint32(descriptorSetWrites.len), descriptorSetWrites.ToCPointer, 0, nil) |
