1 object Vk = 2 val queue_family_ignored : u32 = 0xFFFFFFFF 3 4 object ImageSubresourceRange = 5 val default = ImageSubresourceRange 6 aspect_mask = ImageAspectFlags/Color 7 base_mip_level = 0 8 level_count = 1 9 base_array_layer = 0 10 layer_count = 1 11 12 object ImageMemoryBarrier = 13 val default = ImageMemoryBarrier 14 type = StructureType/ImageMemoryBarrier 15 next = null 16 src_access_mask = AccessFlags@zero 17 dst_access_mask = AccessFlags@zero 18 old_layout = ImageLayout/Undefined 19 new_layout = ImageLayout/Undefined 20 image = null 21 src_queue_family_index = Vk.queue_family_ignored 22 dst_queue_family_index = Vk.queue_family_ignored 23 subresource_range = ImageSubresourceRange.default 24 25 def generate_mipmaps (physical_device : VkPhysicalDevice 26 command_buffer : VkCommandBuffer 27 image : VkImage 28 image_format : VkFormat 29 width : u32 30 height : u32 31 mip_levels : u32 32 layer_count : u32) = 33 let mut format_properties = FormatProperties@zero 34 vk/get_physical_device_format_properties physical_device image_format 35 format_properties@mut_ptr 36 37 if not format_properties.optimal_tiling_features.contains 38 FormatFeatureFlags/SampledImageFilterLinear 39 then 40 fail "image format does not support linear blitting" 41 42 let mut barrier = ImageMemoryBarrier 43 =image 44 subresource_range = ImageSubresourceRange 45 =layer_count 46 f@ ImageSubresourceRange.default 47 48 f@ ImageMemoryBarrier.default 49 50 let mut mip_width = width as i32 51 let mut mip_height = height as i32 52 53 for i = 1 until mip_levels do 54 barrier.subresource_range.base_mip_level = i - 1 55 old_layout = ImageLayout/TransferDstOptimal 56 new_layout = ImageLayout/TransferSrcOptimal 57 src_access_mask = AccessFlags/TransferWrite 58 dst_access_mask = AccessFlags/TransferRead 59 60 vk/cmd_pipeline_barrier command_buffer PipelineStageFlags/Transfer 61 PipelineStageFlags/Transfer DependencyFlags@zero 62 0 null 0 null 1 barrier@ptr 63 64 let blit = ImageBlit 65 src_offset1 = Offset3D.new 66 src_offset2 = Offset3D mip_width mip_height 1 67 src_subresource = ImageSubresourceLayers 68 aspect_mask = ImageAspectFlags/Color 69 mip_level = i - 1 70 base_array_layer = 0 71 layer_count = 1 72 73 dst_offset1 = Offset3D.new 74 dst_offset2 = Offset3D 75 x = if mip_width > 1 then mip_width / 2 else 1 76 y = if mip_height > 1 then mip_height / 2 else 1 77 z = 1 78 79 dst_subresource = ImageSubresourceLayers 80 aspect_mask = ImageAspectFlags/Color 81 mip_level = i 82 base_array_layer = 0 83 layer_count = 1 84 85 vk/cmd_blit_image command_buffer image ImageLayout/TransferSrcOptimal 86 image ImageLayout/TransferDstOptimal 1 blit@ptr 87 VkFilter/Linear 88 89 barrier.old_layout = ImageLayout/TransferSrcOptimal 90 new_layout = ImageLayout/ShaderReadOnlyOptimal 91 src_access_mask = AccessFlags/TransferRead 92 dst_access_mask = AccessFlags/ShaderRead 93 94 vk/cmd_pipeline_barrier command_buffer PipelineStageFlags/Transfer 95 PipelineStageFlags/FragmentShader 96 DependencyFlags@zero 0 null 0 null 1 barrier@ptr 97 98 if mip_height > 1 then 99 mip_height = mip_height / 2 100 101 if mip_width > 1 then 102 mip_width = mip_width / 2 103 104 barrier.subresource_range.base_mip_level = mip_levels - 1 105 old_layout = ImageLayout/TransferDstOptimal 106 new_layout = ImageLayout/ShaderReadOnlyOptimal 107 src_access_mask = AccessFlags/TransferWrite 108 dst_access_mask = AccessFlags/ShaderRead 109 110 vk/cmd_pipeline_barrier command_buffer PipelineStageFlags/Transfer 111 PipelineStageFlags/FragmentShader DependencyFlags@zero 112 0 null 0 null 1 barrier@ptr 113