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