1 type BarrierFlags = flags 2 | Raster 3 | Compute 4 | Transfer 5 6 def has_transfer = contains Transfer 7 def has_raster = contains Raster 8 def has_compute = contains Compute 9 10 let get_flags (buffer : Buffer 11 post_barrier : BarrierFlags) : (PipelineStageFlags, AccessFlags) = 12 let mut stage_mask = PipelineStageFlags@zero 13 let mut access_mask = AccessFlags@zero 14 if post_barrier.has_transfer then 15 stage_mask = PipelineStageFlags/Transfer 16 access_mask = AccessFlags/TransferWrite 17 18 case buffer.type of 19 BufferType/Vertex -> 20 stage_mask |= PipelineStageFlags/VertexInput 21 access_mask |= AccessFlags/VertexAttributeRead 22 if buffer.usage.contains BufferUsageFlags/StorageBuffer then 23 if post_barrier.has_raster then 24 access_mask |= AccessFlags/ShaderRead | AccessFlags/ShaderWrite 25 stage_mask |= PipelineStageFlags/VertexShader 26 | PipelineStageFlags/FragmentShader 27 28 if post_barrier.has_compute then 29 access_mask |= AccessFlags/ShaderRead | AccessFlags/ShaderWrite 30 stage_mask |= PipelineStageFlags/ComputeShader 31 32 BufferType/Index -> 33 stage_mask |= PipelineStageFlags/VertexInput 34 access_mask |= AccessFlags/IndexRead 35 36 BufferType/Uniform -> 37 if post_barrier.has_raster then 38 stage_mask |= PipelineStageFlags/VertexShader 39 | PipelineStageFlags/FragmentShader 40 41 if post_barrier.has_compute then 42 stage_mask |= PipelineStageFlags/ComputeShader 43 44 access_mask |= AccessFlags/UniformRead 45 46 BufferType/Image -> 47 if post_barrier.has_raster then 48 stage_mask |= PipelineStageFlags/VertexShader 49 | PipelineStageFlags/FragmentShader 50 51 access_mask |= AccessFlags/ShaderRead 52 53 if post_barrier.has_compute then 54 stage_mask |= PipelineStageFlags/ComputeShader 55 access_mask |= AccessFlags/ShaderRead 56 57 BufferType/Storage -> 58 if post_barrier.has_raster then 59 stage_mask |= PipelineStageFlags/VertexShader 60 | PipelineStageFlags/FragmentShader 61 62 access_mask |= AccessFlags/ShaderRead | AccessFlags/ShaderWrite 63 64 if post_barrier.has_compute then 65 stage_mask |= PipelineStageFlags/ComputeShader 66 access_mask |= AccessFlags/ShaderRead | AccessFlags/ShaderWrite 67 68 if buffer.usage.contains BufferUsageFlags/IndirectBuffer then 69 stage_mask |= PipelineStageFlags/DrawIndirect 70 access_mask |= AccessFlags/IndirectCommandRead 71 72 if stage_mask == PipelineStageFlags@zero then 73 stage_mask = PipelineStageFlags/BottomOfPipe 74 75 (stage_mask, access_mask) 76 77 type Buffer 78 def update<T> self (data : Slice<T>) (post_barrier : BarrierFlags) = 79 let command_buffer : CommandBuffer @auto 80 81 let size = sizeof T * data.size 82 assert size <= self.size 83 84 let target = Target/Buffer self.object 85 buffer/write target data.ptr size 32 86 87 let (stage_mask, access_flags) = get_flags self post_barrier 88 89 let barrier = BufferMemoryBarrier 90 type = StructureType/BufferMemoryBarrier 91 next = null 92 src_access_mask = AccessFlags/TransferWrite 93 dst_access_mask = access_flags 94 src_queue_family_index = Vk.queue_family_ignored 95 dst_queue_family_index = Vk.queue_family_ignored 96 buffer = self.object 97 offset = 0 98 size = data.size as u64 99 100 vk/cmd_pipeline_barrier command_buffer.object PipelineStageFlags/Transfer 101 stage_mask DependencyFlags@zero 0 null 1 102 barrier@ptr 0 null 103 104 def update_single<T> (data : ptr T) (post_barrier : BarrierFlags) = 105 let slice = Slice<T> data 1 106 update slice post_barrier 107