1 object Renderer = 2 val max_uniform_sets : u32 = 16 3 4 type DescriptorSetLayout = 5 val bindings : List<Binding> 6 val object : VkDescriptorSetLayout 7 8 type PipelineLayout = 9 val object : VkPipelineLayout 10 val push_constant_size : u32 11 val push_constant_stages : ShaderStageFlags 12 val descriptor_set_layouts : List<DescriptorSetLayout> 13 14 fun get (index : u32) = descriptor_set_layouts[index] 15 16 object VkPipelineLayout = 17 def create (layouts : List<VkDescriptorSetLayout> 18 push_constant_size : u32 19 push_constant_stages : ShaderStageFlags) = 20 let instance : Instance @auto 21 22 let push_constant_ranges = if push_constant_size <> 0 then 23 [PushConstantRange 24 stage_flags = push_constant_stages 25 offset = 0 26 size = push_constant_size].as_slice 27 else 28 Slice<PushConstantRange>.empty 29 30 let pipeline_layout_create_info = PipelineLayoutCreateInfo 31 type = StructureType/PipelineLayoutCreateInfo 32 next = null 33 flags = PipelineLayoutCreateFlags@zero 34 set_layout_count = layouts.size 35 set_layouts = layouts.as_ptr 36 push_constant_range_count = push_constant_ranges.size 37 push_constant_ranges = push_constant_ranges.ptr 38 39 let mut pipeline_layout = null 40 vk/create_pipeline_layout instance.device pipeline_layout_create_info@ptr 41 null pipeline_layout@mut_ptr 42 |> assert_success 43 44 pipeline_layout 45 46 let get_push_constant (vertex_shader : VertexShader 47 fragment_shader : FragmentShader) : (u32, ShaderStageFlags) = 48 let mut push_constant_size = 0 49 let mut push_constant_stages = ShaderStageFlags@zero 50 51 let f (size : u32) (stages : ShaderStageFlags) = 52 if push_constant_stages == ShaderStageFlags@zero then 53 push_constant_stages = stages 54 push_constant_size = size 55 else 56 assert stages == ShaderStageFlags@zero || push_constant_size == size 57 push_constant_stages |= stages 58 59 f vertex_shader.push_constant_size vertex_shader.push_constant_stages 60 f fragment_shader.push_constant_size fragment_shader.push_constant_stages 61 62 (push_constant_size, push_constant_stages) 63 64 object PipelineLayout = 65 def create (bindings : Slice<Binding> 66 push_constant_size : u32 67 push_constant_stages : ShaderStageFlags) = 68 let instance : Instance @auto 69 70 let set_bindings = List<mut List<Binding>>.new 71 let set_vk_bindings = List<mut List<DescriptorSetLayoutBinding>>.new 72 73 for binding in bindings do 74 while set_vk_bindings.size <= binding.set do 75 set_vk_bindings.add List.new 76 set_bindings.add List.new 77 78 DescriptorSetLayoutBinding 79 binding = binding.binding 80 descriptor_type = binding.descriptor_type 81 descriptor_count = binding.descriptor_count 82 stage_flags = binding.stage_flags 83 immutable_samplers = null 84 |> set_vk_bindings[binding.set].add 85 86 set_bindings[binding.set].add binding 87 88 assert set_vk_bindings.size < Renderer.max_uniform_sets 89 assert set_vk_bindings.size < instance.limits.max_bound_descriptor_sets 90 91 let descriptor_set_layouts = List<DescriptorSetLayout>.new 92 for i = 0 until set_vk_bindings.size do 93 if set_vk_bindings[i].size == 0 then 94 continue 95 96 let descriptor_set_layout_create_info = DescriptorSetLayoutCreateInfo 97 type = StructureType/DescriptorSetLayoutCreateInfo 98 next = null 99 flags = DescriptorSetLayoutCreateFlags@zero 100 binding_count = set_vk_bindings[i].size 101 bindings = set_vk_bindings[i].as_ptr 102 103 let mut layout = null 104 vk/create_descriptor_set_layout instance.device 105 descriptor_set_layout_create_info@ptr 106 null layout@mut_ptr 107 |> assert_success 108 109 set_bindings[i].sort 110 let descriptor_set_layout = DescriptorSetLayout 111 bindings = set_bindings[i] 112 object = layout 113 114 descriptor_set_layouts.add descriptor_set_layout 115 116 let pipeline_layout = 117 let layouts = descriptor_set_layouts.map { _.object } 118 VkPipelineLayout.create layouts push_constant_size 119 push_constant_stages 120 121 PipelineLayout object = pipeline_layout 122 =push_constant_size 123 =push_constant_stages 124 =descriptor_set_layouts 125 126 def compute (shader : ComputeShader) = 127 create shader.metadata.bindings.as_slice 128 shader.push_constant_size 129 shader.push_constant_stages 130 131 def raster (vertex_shader : VertexShader) (fragment_shader : FragmentShader) = 132 let map = Map<(u32, u32), Binding>.new 133 for bindings in [vertex_shader.metadata.bindings 134 fragment_shader.metadata.bindings] do 135 for binding in bindings do 136 if map.try_get (binding.set, binding.binding) ? Some item then 137 item.stage_flags |= binding.stage_flags 138 else 139 map.add (binding.set, binding.binding) binding 140 141 let bindings = map.map { _, v -> v } 142 bindings.sort_by_key { _.binding } 143 144 let (push_constant_size, push_constant_stages) = 145 get_push_constant vertex_shader fragment_shader 146 147 create bindings.as_slice 148 push_constant_size 149 push_constant_stages 150