Mercurial > games > semicongine
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/semiconginev2/old/vulkan/descriptor.nim Wed Jul 17 21:01:37 2024 +0700 @@ -0,0 +1,174 @@ +import std/enumerate +import std/tables + +import ../core +import ./device +import ./buffer +import ./image + +type + DescriptorType* = enum + Uniform, ImageSampler + Descriptor* = object # "fields" of a DescriptorSetLayout + name*: string + count*: uint32 + stages*: seq[VkShaderStageFlagBits] + case thetype*: DescriptorType + of Uniform: + buffer*: Buffer + offset*: uint64 + size*: uint64 + of ImageSampler: + imageviews*: seq[ImageView] + samplers*: seq[VulkanSampler] + DescriptorSet* = object # "instance" of a DescriptorSetLayout + vk*: VkDescriptorSet + layout*: DescriptorSetLayout + DescriptorSetLayout* = object # "type-description" of a DescriptorSet + device: Device + vk*: VkDescriptorSetLayout + descriptors*: seq[Descriptor] + DescriptorPool* = object # required for allocation of DescriptorSet + device: Device + vk*: VkDescriptorPool + maxSets*: int # maximum number of allocatable descriptor sets + counts*: seq[(VkDescriptorType, uint32)] # maximum number for each descriptor type to allocate + +const DESCRIPTOR_TYPE_MAP = { + Uniform: VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + ImageSampler: VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, +}.toTable + +func vkType(descriptor: Descriptor): VkDescriptorType = + DESCRIPTOR_TYPE_MAP[descriptor.thetype] + +proc CreateDescriptorSetLayout*(device: Device, descriptors: seq[Descriptor]): DescriptorSetLayout = + assert device.vk.Valid + + result.device = device + result.descriptors = descriptors + + var layoutbindings: seq[VkDescriptorSetLayoutBinding] + for i, descriptor in enumerate(descriptors): + layoutbindings.add VkDescriptorSetLayoutBinding( + binding: uint32(i), + descriptorType: descriptor.vkType, + descriptorCount: descriptor.count, + stageFlags: toBits descriptor.stages, + pImmutableSamplers: nil, + ) + var layoutCreateInfo = VkDescriptorSetLayoutCreateInfo( + sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + bindingCount: uint32(layoutbindings.len), + pBindings: layoutbindings.ToCPointer + ) + checkVkResult vkCreateDescriptorSetLayout(device.vk, addr(layoutCreateInfo), nil, addr(result.vk)) + +proc Destroy*(descriptorSetLayout: var DescriptorSetLayout) = + assert descriptorSetLayout.device.vk.Valid + assert descriptorSetLayout.vk.Valid + descriptorSetLayout.device.vk.vkDestroyDescriptorSetLayout(descriptorSetLayout.vk, nil) + descriptorSetLayout.vk.Reset + +proc CreateDescriptorSetPool*(device: Device, counts: seq[(VkDescriptorType, uint32)], maxSets = 1000): DescriptorPool = + assert device.vk.Valid + + result.device = device + result.maxSets = maxSets + result.counts = counts + + var poolSizes: seq[VkDescriptorPoolSize] + for (thetype, count) in result.counts: + poolSizes.add VkDescriptorPoolSize(thetype: thetype, descriptorCount: count) + var poolInfo = VkDescriptorPoolCreateInfo( + sType: VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + poolSizeCount: uint32(poolSizes.len), + pPoolSizes: poolSizes.ToCPointer, + maxSets: uint32(result.maxSets), + ) + checkVkResult vkCreateDescriptorPool(result.device.vk, addr(poolInfo), nil, addr(result.vk)) + +proc Reset*(pool: DescriptorPool) = + assert pool.device.vk.Valid + assert pool.vk.Valid + checkVkResult vkResetDescriptorPool(pool.device.vk, pool.vk, VkDescriptorPoolResetFlags(0)) + +proc Destroy*(pool: var DescriptorPool) = + assert pool.device.vk.Valid + assert pool.vk.Valid + pool.device.vk.vkDestroyDescriptorPool(pool.vk, nil) + pool.vk.Reset + +proc AllocateDescriptorSet*(pool: DescriptorPool, layout: DescriptorSetLayout, nframes: int): seq[DescriptorSet] = + assert pool.device.vk.Valid + assert pool.vk.Valid + assert layout.device.vk.Valid + assert layout.vk.Valid + + var layouts: seq[VkDescriptorSetLayout] + var descriptorSets = newSeq[VkDescriptorSet](nframes) + for i in 0 ..< nframes: + layouts.add layout.vk + var allocInfo = VkDescriptorSetAllocateInfo( + sType: VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, + descriptorPool: pool.vk, + descriptorSetCount: uint32(layouts.len), + pSetLayouts: layouts.ToCPointer, + ) + + checkVkResult vkAllocateDescriptorSets(pool.device.vk, addr(allocInfo), descriptorSets.ToCPointer) + for descriptorSet in descriptorSets: + result.add DescriptorSet(vk: descriptorSet, layout: layout) + +proc WriteDescriptorSet*(descriptorSet: DescriptorSet, bindingBase = 0'u32) = + # assumes descriptors of the descriptorSet are arranged interleaved in buffer + assert descriptorSet.layout.device.vk.Valid + assert descriptorSet.layout.vk.Valid + assert descriptorSet.vk.Valid + + var descriptorSetWrites: seq[VkWriteDescriptorSet] + var bufferInfos: seq[VkDescriptorBufferInfo] + + var i = bindingBase + # need to keep this sequence out of the loop, otherwise it will be + # gc-ed before the final update call and pointers are invalid :( + var imgInfos: seq[seq[VkDescriptorImageInfo]] + for descriptor in descriptorSet.layout.descriptors: + if descriptor.thetype == Uniform: + assert descriptor.buffer.vk.Valid + bufferInfos.add VkDescriptorBufferInfo( + buffer: descriptor.buffer.vk, + offset: descriptor.offset, + range: descriptor.size, + ) + descriptorSetWrites.add VkWriteDescriptorSet( + sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + dstSet: descriptorSet.vk, + dstBinding: i, + dstArrayElement: 0, + descriptorType: descriptor.vkType, + descriptorCount: uint32(descriptor.count), + pBufferInfo: addr bufferInfos[^1], + ) + elif descriptor.thetype == ImageSampler: + var imgInfo: seq[VkDescriptorImageInfo] + for img_i in 0 ..< descriptor.count: + assert descriptor.imageviews[img_i].vk.Valid + assert descriptor.samplers[img_i].vk.Valid + imgInfo.add VkDescriptorImageInfo( + imageLayout: VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + imageView: descriptor.imageviews[img_i].vk, + sampler: descriptor.samplers[img_i].vk, + ) + imgInfos.add imgInfo + descriptorSetWrites.add VkWriteDescriptorSet( + sType: VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + dstSet: descriptorSet.vk, + dstBinding: i, + dstArrayElement: 0, + descriptorType: descriptor.vkType, + descriptorCount: uint32(descriptor.count), + pImageInfo: imgInfos[^1].ToCPointer, + ) + inc i + descriptorSet.layout.device.vk.vkUpdateDescriptorSets(uint32(descriptorSetWrites.len), descriptorSetWrites.ToCPointer, 0, nil)