1     type DescriptorSet =
2         val descriptor_set : VkDescriptorSet
3         val sampled_images : List<Image>
4         val storage_images : List<Image>
5     
6         def discard = ()
7     
8     type DescriptorSetState = struct
9         descriptor_set : DescriptorSet
10        bound : bool
11    
12    object DescriptorSetState =
13        val default = DescriptorSetState
14            descriptor_set = null
15            bound = false
16    
17    type<K, V> Slice<(K, V) key value>
18        def get (key : K) =
19            for i = 0 until size do
20                if self[i].key == key then return Some self[i].value
21    
22            None
23    
24    object DescriptorSet =
25        def create (instance : Instance
26                    descriptor_pool_cache : DescriptorPoolCache
27                    default_sampler : VkSampler
28                    binding_resources : Slice<(String, OneMany<Resource>)>
29                    layout : DescriptorSetLayout) =
30            let writes = List<WriteDescriptorSet>.new
31            let mut counts = DescriptorCounts@zero
32            let buffers = List<DescriptorBufferInfo>.new
33            let images = List<DescriptorImageInfo>.new
34            let sampled_images = List<Image>.new
35            let storage_images = List<Image>.new
36    
37            for binding in layout.bindings do
38                let maybe_resources = binding_resources.get binding.name
39                if maybe_resources.is_none then
40                    fail "no resource for binding ${binding.binding}"
41    
42                let resources = maybe_resources.unwrap
43                assert resources.size == binding.descriptor_count
44    
45                let mut image_info : ptr DescriptorImageInfo = null
46                let mut buffer_info : ptr DescriptorBufferInfo = null
47                let get_image_info (resource : Resource)
48                                   (descriptor_type : DescriptorType) =
49                    let (image, sampler, image_layout) = case resource of
50                        sampler : VkSampler -> (Image@null, sampler, ImageLayout/Undefined)
51                        Resource/ImageSampler image sampler ->
52                            (image, sampler, ImageLayout/ShaderReadOnlyOptimal)
53    
54                        image : Image ->
55                            let image_layout = case descriptor_type of
56                                DescriptorType/SampledImage
57                                | DescriptorType/CombinedImageSampler ->
58                                    ImageLayout/ShaderReadOnlyOptimal
59    
60                                DescriptorType/StorageImage -> ImageLayout/General
61                                else -> fail
62    
63                            let sampler =
64                                if descriptor_type == DescriptorType/CombinedImageSampler
65                                then default_sampler
66                                else VkSampler@zero
67    
68                            (image, sampler, image_layout)
69    
70                        else -> fail
71    
72                    let descriptor_image_info = DescriptorImageInfo
73                        =sampler
74                        image_view = image.view
75                        =image_layout
76    
77                    (image, descriptor_image_info)
78    
79                case binding.descriptor_type of
80                    DescriptorType/Sampler
81                    | DescriptorType/CombinedImageSampler
82                    | DescriptorType/SampledImage
83                    | DescriptorType/StorageImage ->
84                        let index = images.size
85                        for resource in resources do
86                            let (image, info) =
87                                get_image_info resource binding.descriptor_type
88    
89                            if image <> null then
90                                case binding.descriptor_type of
91                                    DescriptorType/CombinedImageSampler
92                                    | DescriptorType/SampledImage ->
93                                        if image.usage.contains ImageUsageFlags/Storage then
94                                            sampled_images.add image
95    
96                                    DescriptorType/StorageImage ->
97                                        if image.usage.contains ImageUsageFlags/Sampled then
98                                            storage_images.add image
99    
100                                   else -> fail
101   
102                           images.add info
103   
104                       image_info = images.as_ptr + index
105   
106                   DescriptorType/UniformBuffer | DescriptorType/StorageBuffer ->
107                       let index = buffers.size
108                       buffers.add resources[0].buffer.info
109                       buffer_info = buffers.as_ptr + index
110   
111                   else -> fail
112   
113               writes.add (WriteDescriptorSet
114                               type = StructureType/WriteDescriptorSet
115                               next = null
116                               dst_set = null
117                               dst_binding = binding.binding
118                               dst_array_element = 0
119                               descriptor_count = binding.descriptor_count
120                               descriptor_type = binding.descriptor_type
121                               =image_info
122                               =buffer_info
123                               texel_buffer_view = null)
124   
125               counts[binding.descriptor_type] += resources.size as u16
126   
127           let descriptor_pool = descriptor_pool_cache.get counts
128           let set_layout = layout.object
129           let descriptor_set_allocate_info = DescriptorSetAllocateInfo
130               type = StructureType/DescriptorSetAllocateInfo
131               next = null
132               =descriptor_pool
133               descriptor_set_count = 1
134               set_layouts = set_layout@ptr
135   
136           let mut descriptor_set = null
137           vk/allocate_descriptor_sets instance.device descriptor_set_allocate_info@ptr
138                                       descriptor_set@mut_ptr
139           if writes.size > 0 then
140               for i = 0 until writes.size do
141                   writes[i].dst_set = descriptor_set
142   
143               vk/update_descriptor_sets instance.device writes.size
144                                         writes.as_ptr 0 null
145   
146           DescriptorSet =descriptor_set =sampled_images =storage_images
147   
148   typealias States = [DescriptorSetState; Renderer.max_uniform_sets]
149   
150   def bind_descriptor_sets (command_buffer : VkCommandBuffer
151                             pipeline_bind_point : PipelineBindPoint
152                             pipeline_layout : VkPipelineLayout
153                             descriptor_set_states : mut ref States) =
154       for i = 0 until Renderer.max_uniform_sets do
155           let set = descriptor_set_states[mut_ref i]
156           if not set.bound && set.descriptor_set <> null then
157               vk/cmd_bind_descriptor_sets command_buffer pipeline_bind_point
158                                           pipeline_layout i 1
159                                           set.descriptor_set.descriptor_set@ptr
160                                           0 null
161               set.bound = true
162