From 6e681fc98d9fb1846f371fb541512d94bcaabe30 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 31 May 2022 09:53:08 +0200 Subject: [PATCH] vulkan: more improvements --- spa/plugins/vulkan/vulkan-compute-filter.c | 46 ++++++++++++++++------ spa/plugins/vulkan/vulkan-utils.c | 37 +++++++++++++---- spa/plugins/vulkan/vulkan-utils.h | 2 +- 3 files changed, 65 insertions(+), 20 deletions(-) diff --git a/spa/plugins/vulkan/vulkan-compute-filter.c b/spa/plugins/vulkan/vulkan-compute-filter.c index 84f9d3a5e..9ffccaf6d 100644 --- a/spa/plugins/vulkan/vulkan-compute-filter.c +++ b/spa/plugins/vulkan/vulkan-compute-filter.c @@ -177,7 +177,7 @@ static inline void reuse_buffer(struct impl *this, struct port *port, uint32_t i struct buffer *b = &port->buffers[id]; if (SPA_FLAG_IS_SET(b->flags, BUFFER_FLAG_OUT)) { - spa_log_trace(this->log, NAME " %p: reuse buffer %d", this, id); + spa_log_info(this->log, NAME " %p: reuse buffer %d", this, id); SPA_FLAG_CLEAR(b->flags, BUFFER_FLAG_OUT); spa_list_append(&port->empty, &b->link); @@ -415,6 +415,7 @@ static int clear_buffers(struct impl *this, struct port *port) { if (port->n_buffers > 0) { spa_log_debug(this->log, NAME " %p: clear buffers", this); + spa_vulkan_stop(&this->state); spa_vulkan_use_buffers(&this->state, &this->state.streams[port->stream_id], 0, 0, NULL); port->n_buffers = 0; spa_list_init(&port->empty); @@ -455,7 +456,6 @@ static int port_set_format(struct impl *this, struct port *port, port->current_format = info; port->have_format = true; - spa_vulkan_prepare(&this->state); } port->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS; @@ -525,6 +525,7 @@ impl_node_port_use_buffers(void *object, b->flags = 0; b->h = spa_buffer_find_meta_data(buffers[i], SPA_META_Header, sizeof(*b->h)); + spa_log_info(this->log, "%p: %d:%d add buffer %p", port, direction, port_id, b); spa_list_append(&port->empty, &b->link); } spa_vulkan_use_buffers(&this->state, &this->state.streams[port->stream_id], flags, n_buffers, buffers); @@ -578,9 +579,22 @@ static int impl_node_process(void *object) struct impl *this = object; struct port *inport, *outport; struct spa_io_buffers *inio, *outio; + struct buffer *b; spa_return_val_if_fail(this != NULL, -EINVAL); + inport = &this->port[SPA_DIRECTION_INPUT]; + inio = inport->io; + spa_return_val_if_fail(inio != NULL, -EIO); + + if (inio->status != SPA_STATUS_HAVE_DATA) + return inio->status; + + if (inio->buffer_id >= inport->n_buffers) { + inio->status = -EINVAL; + return -EINVAL; + } + outport = &this->port[SPA_DIRECTION_OUTPUT]; outio = outport->io; spa_return_val_if_fail(outio != NULL, -EIO); @@ -593,17 +607,24 @@ static int impl_node_process(void *object) outio->buffer_id = SPA_ID_INVALID; } - inport = &this->port[SPA_DIRECTION_INPUT]; - inio = inport->io; + if (spa_list_is_empty(&outport->empty)) { + spa_log_error(this->log, NAME " %p: out of buffers", this); + return -EPIPE; + } + b = &inport->buffers[inio->buffer_id]; + this->state.streams[0].pending_buffer_id = b->id; - if (inio->status != SPA_STATUS_HAVE_DATA) - return inio->status; + b = spa_list_first(&outport->empty, struct buffer, link); + spa_list_remove(&b->link); + this->state.streams[1].pending_buffer_id = b->id; - outio->buffer_id = inio->buffer_id; + spa_vulkan_process(&this->state); + + outio->buffer_id = b->id; outio->status = SPA_STATUS_HAVE_DATA; inio->status = SPA_STATUS_NEED_DATA; - return SPA_STATUS_HAVE_DATA; + return SPA_STATUS_NEED_DATA | SPA_STATUS_HAVE_DATA; } static const struct spa_node_methods impl_node = { @@ -672,6 +693,7 @@ impl_init(const struct spa_handle_factory *factory, this = (struct impl *) handle; this->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log); + this->state.log = this->log; spa_hook_list_init(&this->hooks); @@ -707,6 +729,8 @@ impl_init(const struct spa_handle_factory *factory, port->params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, 0); port->info.params = port->params; port->info.n_params = 5; + spa_vulkan_init_stream(&this->state, &this->state.streams[0], + SPA_DIRECTION_INPUT, NULL); spa_list_init(&port->empty); spa_list_init(&port->ready); @@ -727,13 +751,11 @@ impl_init(const struct spa_handle_factory *factory, port->info.n_params = 5; spa_list_init(&port->empty); spa_list_init(&port->ready); - - this->state.log = this->log; - spa_vulkan_init_stream(&this->state, &this->state.streams[0], - SPA_DIRECTION_INPUT, NULL); spa_vulkan_init_stream(&this->state, &this->state.streams[1], SPA_DIRECTION_OUTPUT, NULL); + this->state.n_streams = 2; + spa_vulkan_prepare(&this->state); return 0; } diff --git a/spa/plugins/vulkan/vulkan-utils.c b/spa/plugins/vulkan/vulkan-utils.c index d6c87a82f..1908e0315 100644 --- a/spa/plugins/vulkan/vulkan-utils.c +++ b/spa/plugins/vulkan/vulkan-utils.c @@ -93,7 +93,7 @@ static int vkresult_to_errno(VkResult result) VkResult _result = (f); \ int _res = -vkresult_to_errno(_result); \ if (_result != VK_SUCCESS) { \ - spa_log_debug(s->log, "error: %d (%s)", _result, spa_strerror(_res)); \ + spa_log_error(s->log, "error: %d (%s)", _result, spa_strerror(_res)); \ return _res; \ } \ } @@ -111,12 +111,25 @@ static int createInstance(struct vulkan_state *s) static const char * const extensions[] = { VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME }; + static const char * const layers[] = { + "VK_LAYER_KHRONOS_validation", + }; + uint32_t i, layerCount; + vkEnumerateInstanceLayerProperties(&layerCount, NULL); + + VkLayerProperties availableLayers[layerCount]; + vkEnumerateInstanceLayerProperties(&layerCount, availableLayers); + + for (i = 0; i < layerCount; i++) + spa_log_info(s->log, "%s", availableLayers[i].layerName); const VkInstanceCreateInfo createInfo = { .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, .pApplicationInfo = &applicationInfo, .enabledExtensionCount = 1, .ppEnabledExtensionNames = extensions, + .enabledLayerCount = 1, + .ppEnabledLayerNames = layers, }; VK_CHECK_RESULT(vkCreateInstance(&createInfo, NULL, &s->instance)); @@ -229,12 +242,12 @@ static int createDescriptors(struct vulkan_state *s) .poolSizeCount = 1, .pPoolSizes = &descriptorPoolSize, }; - VkDescriptorSetLayoutBinding descriptorSetLayoutBinding[s->n_streams]; VK_CHECK_RESULT(vkCreateDescriptorPool(s->device, &descriptorPoolCreateInfo, NULL, &s->descriptorPool)); + VkDescriptorSetLayoutBinding descriptorSetLayoutBinding[s->n_streams]; for (i = 0; i < s->n_streams; i++) { descriptorSetLayoutBinding[i] = (VkDescriptorSetLayoutBinding) { .binding = i, @@ -261,7 +274,7 @@ static int createDescriptors(struct vulkan_state *s) VK_CHECK_RESULT(vkAllocateDescriptorSets(s->device, &descriptorSetAllocateInfo, - s->descriptorSet)); + &s->descriptorSet)); return 0; } @@ -289,7 +302,7 @@ static int updateDescriptors(struct vulkan_state *s) }; writeDescriptorSet[i] = (VkWriteDescriptorSet) { .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .dstSet = s->descriptorSet[i], + .dstSet = s->descriptorSet, .dstBinding = i, .descriptorCount = 1, .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, @@ -342,7 +355,7 @@ static VkShaderModule createShaderModule(struct vulkan_state *s, const char* sha static int createComputePipeline(struct vulkan_state *s, const char *shader_file) { static const VkPushConstantRange range = { - .stageFlags = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, + .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, .offset = 0, .size = sizeof(struct push_constants) }; @@ -416,7 +429,7 @@ static int runCommandBuffer(struct vulkan_state *s) s->pipelineLayout, VK_SHADER_STAGE_COMPUTE_BIT, 0, sizeof(struct push_constants), (const void *) &s->constants); vkCmdBindDescriptorSets(s->commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, - s->pipelineLayout, 0, s->n_streams, s->descriptorSet, 0, NULL); + s->pipelineLayout, 0, 1, &s->descriptorSet, 0, NULL); vkCmdDispatch(s->commandBuffer, (uint32_t)ceil(s->constants.width / (float)WORKGROUP_SIZE), @@ -470,12 +483,21 @@ int spa_vulkan_use_buffers(struct vulkan_state *s, struct vulkan_stream *p, uint p->bufferSize = s->constants.width * s->constants.height * sizeof(struct pixel); for (i = 0; i < n_buffers; i++) { - const VkBufferCreateInfo bufferCreateInfo = { + VkExternalMemoryBufferCreateInfo extInfo; + VkBufferCreateInfo bufferCreateInfo = { .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .size = p->bufferSize, .usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, .sharingMode = VK_SHARING_MODE_EXCLUSIVE, }; + if (!(flags & SPA_NODE_BUFFERS_FLAG_ALLOC)) { + extInfo = (VkExternalMemoryBufferCreateInfo) { + .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO, + .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, + }; + bufferCreateInfo.pNext = &extInfo; + } + VK_CHECK_RESULT(vkCreateBuffer(s->device, &bufferCreateInfo, NULL, &p->buffers[i].buffer)); @@ -566,6 +588,7 @@ int spa_vulkan_unprepare(struct vulkan_state *s) vkDestroyPipelineLayout(s->device, s->pipelineLayout, NULL); vkDestroyPipeline(s->device, s->pipeline, NULL); vkDestroyCommandPool(s->device, s->commandPool, NULL); + vkDestroyFence(s->device, s->fence, NULL); vkDestroyDevice(s->device, NULL); vkDestroyInstance(s->instance, NULL); s->prepared = false; diff --git a/spa/plugins/vulkan/vulkan-utils.h b/spa/plugins/vulkan/vulkan-utils.h index 0adfa5601..4b9a888c7 100644 --- a/spa/plugins/vulkan/vulkan-utils.h +++ b/spa/plugins/vulkan/vulkan-utils.h @@ -64,7 +64,7 @@ struct vulkan_state { VkDescriptorSetLayout descriptorSetLayout; uint32_t n_streams; - VkDescriptorSet descriptorSet[MAX_STREAMS]; + VkDescriptorSet descriptorSet; struct vulkan_stream streams[MAX_STREAMS]; };