class CopyOperation(Destroyable): def __init__(self, device, queue_index): super(CopyOperation, self).__init__() self.device = device self.queue_index = queue_index self.fence = Fence(self.device, signalled=False) command_pool_create_info = vk.VkCommandPoolCreateInfo( flags=vk.VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex=queue_index) self.command_pool_handle = vk.vkCreateCommandPool( self.device.handle, command_pool_create_info, None) allocation_info = vk.VkCommandBufferAllocateInfo( commandPool=self.command_pool_handle, commandBufferCount=1, level=vk.VK_COMMAND_BUFFER_LEVEL_PRIMARY) self.command_buffer_handle = vk.vkAllocateCommandBuffers( self.device.handle, allocation_info)[0] def _destroy(self): vk.vkDestroyCommandPool(self.device.handle, self.command_pool_handle, None) self.fence.destroy() def record(self, src_buffer, dst_buffer): vk.vkBeginCommandBuffer( self.command_buffer_handle, vk.VkCommandBufferBeginInfo( flags=vk.VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT)) region = vk.VkBufferCopy(0, 0, src_buffer.get_size()) vk.vkCmdCopyBuffer(self.command_buffer_handle, src_buffer.handle, dst_buffer.handle, 1, [region]) vk.vkEndCommandBuffer(self.command_buffer_handle) def run(self): queue_handle = self.device.get_queue_handle(QueueType.COMPUTE) submit_info = vk.VkSubmitInfo( pCommandBuffers=[self.command_buffer_handle]) vk.vkQueueSubmit(queue_handle, 1, [submit_info], self.fence.handle) def wait(self): vk.vkWaitForFences(self.device.handle, 1, [self.fence.handle], True, TIMEOUT_FOREVER) vk.vkResetFences(self.device.handle, 1, [self.fence.handle]) def run_and_wait(self): self.run() self.wait()
def __init__(self, device, queue_index): super(CopyOperation, self).__init__() self.device = device self.queue_index = queue_index self.fence = Fence(self.device, signalled=False) command_pool_create_info = vk.VkCommandPoolCreateInfo(flags=vk.VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex=queue_index) self.command_pool_handle = vk.vkCreateCommandPool(self.device.handle, command_pool_create_info, None) allocation_info = vk.VkCommandBufferAllocateInfo(commandPool=self.command_pool_handle, commandBufferCount=1, level=vk.VK_COMMAND_BUFFER_LEVEL_PRIMARY) self.command_buffer_handle = vk.vkAllocateCommandBuffers(self.device.handle, allocation_info)[0]
def __init__(self, device, pipeline, queue_index): super(ShaderOperation, self).__init__() self.device = device self.pipeline = pipeline self.queue_index = queue_index self.event = Event(self.device) self.fence = Fence(self.device, signalled=False) self.pipeline.allocate_descriptor_sets() self.pipeline.update_descriptor_sets() # VK_COMMAND_POOL_CREATE_TRANSIENT_BIT command_pool_create_info = vk.VkCommandPoolCreateInfo(flags=vk.VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex=queue_index) self.command_pool_handle = vk.vkCreateCommandPool(self.device.handle, command_pool_create_info, None) allocate_info = vk.VkCommandBufferAllocateInfo(commandPool=self.command_pool_handle, level=vk.VK_COMMAND_BUFFER_LEVEL_PRIMARY, commandBufferCount=1) self.command_buffer_handle = vk.vkAllocateCommandBuffers(self.device.handle, allocate_info)[0]
class ShaderOperation(Destroyable): def __init__(self, device, pipeline, queue_index): super(ShaderOperation, self).__init__() self.device = device self.pipeline = pipeline self.queue_index = queue_index self.event = Event(self.device) self.fence = Fence(self.device, signalled=False) self.pipeline.allocate_descriptor_sets() self.pipeline.update_descriptor_sets() # VK_COMMAND_POOL_CREATE_TRANSIENT_BIT command_pool_create_info = vk.VkCommandPoolCreateInfo(flags=vk.VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex=queue_index) self.command_pool_handle = vk.vkCreateCommandPool(self.device.handle, command_pool_create_info, None) allocate_info = vk.VkCommandBufferAllocateInfo(commandPool=self.command_pool_handle, level=vk.VK_COMMAND_BUFFER_LEVEL_PRIMARY, commandBufferCount=1) self.command_buffer_handle = vk.vkAllocateCommandBuffers(self.device.handle, allocate_info)[0] def _destroy(self): vk.vkDestroyCommandPool(self.device.handle, self.command_pool_handle, None) self.event.destroy() self.fence.destroy() def record(self, count_x, count_y, count_z, wait_events=()): vk.vkBeginCommandBuffer(self.command_buffer_handle, vk.VkCommandBufferBeginInfo(flags=vk.VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT)) vk.vkCmdBindPipeline(self.command_buffer_handle, vk.VK_PIPELINE_BIND_POINT_COMPUTE, self.pipeline.handle) vk.vkCmdBindDescriptorSets(self.command_buffer_handle, vk.VK_PIPELINE_BIND_POINT_COMPUTE, self.pipeline.get_pipeline_layout_handle(), firstSet=0, descriptorSetCount=1, pDescriptorSets=[self.pipeline.get_descriptor_set_handle()], dynamicOffsetCount=0, pDynamicOffsets=None) vk.vkCmdResetEvent(self.command_buffer_handle, self.event.handle, vk.VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT) if len(wait_events) > 0: # https://stackoverflow.com/questions/45680135/pipeline-barriers-across-multiple-shaders vk.vkCmdWaitEvents(self.command_buffer_handle, len(wait_events), [event.handle for event in wait_events], srcStageMask=vk.VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, dstStageMask=vk.VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, memoryBarrierCount=0, pMemoryBarriers=None, bufferMemoryBarrierCount=0, pBufferMemoryBarriers=None, imageMemoryBarrierCount=0, pImageMemoryBarriers=None) # vk.vkCmdPushConstants() vk.vkCmdDispatch(self.command_buffer_handle, count_x, count_y, count_z) vk.vkCmdSetEvent(self.command_buffer_handle, self.event.handle, vk.VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT) vk.vkEndCommandBuffer(self.command_buffer_handle) def run(self): queue_handle = self.device.get_queue_handle(QueueType.COMPUTE) submit_info = vk.VkSubmitInfo(pCommandBuffers=[self.command_buffer_handle]) vk.vkQueueSubmit(queue_handle, 1, [submit_info], self.fence.handle) def wait(self): vk.vkWaitForFences(self.device.handle, 1, [self.fence.handle], True, TIMEOUT_FOREVER) vk.vkResetFences(self.device.handle, 1, [self.fence.handle]) def run_and_wait(self): self.run() self.wait()