mirror of
https://gitlab.freedesktop.org/pipewire/pipewire
synced 2024-10-14 20:02:38 +00:00
vulkan: Complete vulkan_pass
vulkan_pass now contains everything required for a single blit pass.
This commit is contained in:
parent
11ff1471e9
commit
c223e02d9b
|
@ -479,6 +479,7 @@ static int clear_buffers(struct impl *this, struct port *port)
|
|||
spa_log_debug(this->log, "%p: clear buffers", this);
|
||||
lock_renderer(this);
|
||||
spa_vulkan_blit_use_buffers(&this->state, &this->state.streams[port->stream_id], 0, &port->current_format, 0, NULL);
|
||||
spa_vulkan_blit_clear_pass(&this->state, &this->pass);
|
||||
unlock_renderer(this);
|
||||
port->n_buffers = 0;
|
||||
spa_list_init(&port->empty);
|
||||
|
@ -649,6 +650,8 @@ impl_node_port_use_buffers(void *object,
|
|||
}
|
||||
spa_vulkan_blit_use_buffers(&this->state, &this->state.streams[port->stream_id], flags, &port->current_format, n_buffers, buffers);
|
||||
port->n_buffers = n_buffers;
|
||||
if (n_buffers > 0)
|
||||
spa_vulkan_blit_init_pass(&this->state, &this->pass);
|
||||
unlock_renderer(this);
|
||||
|
||||
return 0;
|
||||
|
@ -737,8 +740,6 @@ static int impl_node_process(void *object)
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
spa_vulkan_blit_init_pass(&this->state, &this->pass);
|
||||
|
||||
b = &inport->buffers[inio->buffer_id];
|
||||
this->pass.in_stream_id = SPA_DIRECTION_INPUT;
|
||||
this->pass.in_buffer_id = b->id;
|
||||
|
@ -753,8 +754,7 @@ static int impl_node_process(void *object)
|
|||
spa_log_debug(this->log, "filter into %d", b->id);
|
||||
|
||||
spa_vulkan_blit_process(&this->state, &this->pass);
|
||||
spa_vulkan_blit_clear_pass(&this->state, &this->pass);
|
||||
|
||||
spa_vulkan_blit_reset_pass(&this->state, &this->pass);
|
||||
|
||||
b->outbuf->datas[0].chunk->offset = 0;
|
||||
b->outbuf->datas[0].chunk->size = b->outbuf->datas[0].maxsize;
|
||||
|
|
|
@ -524,6 +524,7 @@ static int clear_buffers(struct impl *this, struct port *port)
|
|||
spa_log_debug(this->log, "%p: clear buffers", this);
|
||||
lock_renderer(this);
|
||||
spa_vulkan_blit_use_buffers(&this->state, &this->state.streams[port->stream_id], 0, &port->current_format, 0, NULL);
|
||||
spa_vulkan_blit_clear_pass(&this->state, &this->pass);
|
||||
unlock_renderer(this);
|
||||
port->n_buffers = 0;
|
||||
spa_list_init(&port->empty);
|
||||
|
@ -746,6 +747,8 @@ impl_node_port_use_buffers(void *object,
|
|||
}
|
||||
spa_vulkan_blit_use_buffers(&this->state, &this->state.streams[port->stream_id], flags, &port->current_format, n_buffers, buffers);
|
||||
port->n_buffers = n_buffers;
|
||||
if (n_buffers > 0)
|
||||
spa_vulkan_blit_init_pass(&this->state, &this->pass);
|
||||
unlock_renderer(this);
|
||||
|
||||
return 0;
|
||||
|
@ -834,8 +837,6 @@ static int impl_node_process(void *object)
|
|||
return -EBUSY;
|
||||
}
|
||||
|
||||
spa_vulkan_blit_init_pass(&this->state, &this->pass);
|
||||
|
||||
b = &inport->buffers[inio->buffer_id];
|
||||
this->pass.in_stream_id = SPA_DIRECTION_INPUT;
|
||||
this->pass.in_buffer_id = b->id;
|
||||
|
@ -850,7 +851,7 @@ static int impl_node_process(void *object)
|
|||
spa_log_debug(this->log, "filter into %d", b->id);
|
||||
|
||||
spa_vulkan_blit_process(&this->state, &this->pass);
|
||||
spa_vulkan_blit_clear_pass(&this->state, &this->pass);
|
||||
spa_vulkan_blit_reset_pass(&this->state, &this->pass);
|
||||
|
||||
b->outbuf->datas[0].chunk->offset = 0;
|
||||
b->outbuf->datas[0].chunk->size = b->outbuf->datas[0].maxsize;
|
||||
|
|
|
@ -50,7 +50,7 @@ static int runImportSHMBuffers(struct vulkan_blit_state *s, struct vulkan_pass *
|
|||
.size.height = p->dim.height,
|
||||
.copies = &pass->in_copy,
|
||||
};
|
||||
CHECK(vulkan_write_pixels(&s->base, &writeInfo, &s->staging_buffer));
|
||||
CHECK(vulkan_write_pixels(&s->base, &writeInfo, &pass->in_staging_buffer));
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -122,7 +122,7 @@ static int runCommandBuffer(struct vulkan_blit_state *s, struct vulkan_pass *pas
|
|||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||
.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
|
||||
};
|
||||
VK_CHECK_RESULT(vkBeginCommandBuffer(s->commandBuffer, &beginInfo));
|
||||
VK_CHECK_RESULT(vkBeginCommandBuffer(pass->commandBuffer, &beginInfo));
|
||||
|
||||
uint32_t i;
|
||||
struct vulkan_stream *stream_input = &s->streams[pass->in_stream_id];
|
||||
|
@ -132,7 +132,7 @@ static int runCommandBuffer(struct vulkan_blit_state *s, struct vulkan_pass *pas
|
|||
VkImage dst_image = stream_output->buffers[pass->out_buffer_id].image;
|
||||
|
||||
if (stream_input->buffer_type == SPA_DATA_MemPtr) {
|
||||
vkCmdCopyBufferToImage(s->commandBuffer, s->staging_buffer.buffer, src_image,
|
||||
vkCmdCopyBufferToImage(pass->commandBuffer, pass->in_staging_buffer.buffer, src_image,
|
||||
VK_IMAGE_LAYOUT_GENERAL, 1, &pass->in_copy);
|
||||
|
||||
VkImageMemoryBarrier copy_barrier = {
|
||||
|
@ -149,7 +149,7 @@ static int runCommandBuffer(struct vulkan_blit_state *s, struct vulkan_pass *pas
|
|||
.subresourceRange.layerCount = 1,
|
||||
};
|
||||
|
||||
vkCmdPipelineBarrier(s->commandBuffer,
|
||||
vkCmdPipelineBarrier(pass->commandBuffer,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
0, 0, NULL, 0, NULL,
|
||||
|
@ -180,7 +180,7 @@ static int runCommandBuffer(struct vulkan_blit_state *s, struct vulkan_pass *pas
|
|||
spa_log_trace_fp(s->log, "Blitting from (%p, %d, %d) %d,%dx%d,%d to (%p, %d, %d) %d,%dx%d,%d",
|
||||
stream_input, pass->in_buffer_id, stream_input->direction, 0, 0, stream_input->dim.width, stream_input->dim.height,
|
||||
stream_output, pass->out_buffer_id, stream_output->direction, 0, 0, stream_output->dim.width, stream_output->dim.height);
|
||||
vkCmdBlitImage(s->commandBuffer, src_image, VK_IMAGE_LAYOUT_GENERAL,
|
||||
vkCmdBlitImage(pass->commandBuffer, src_image, VK_IMAGE_LAYOUT_GENERAL,
|
||||
dst_image, VK_IMAGE_LAYOUT_GENERAL,
|
||||
1, &imageBlitRegion, VK_FILTER_NEAREST);
|
||||
|
||||
|
@ -244,42 +244,30 @@ static int runCommandBuffer(struct vulkan_blit_state *s, struct vulkan_pass *pas
|
|||
}
|
||||
}
|
||||
|
||||
vkCmdPipelineBarrier(s->commandBuffer,
|
||||
vkCmdPipelineBarrier(pass->commandBuffer,
|
||||
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
VK_PIPELINE_STAGE_2_TRANSFER_BIT,
|
||||
0, 0, NULL, 0, NULL,
|
||||
s->n_streams, acquire_barrier);
|
||||
|
||||
vkCmdPipelineBarrier(s->commandBuffer,
|
||||
vkCmdPipelineBarrier(pass->commandBuffer,
|
||||
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
|
||||
0, 0, NULL, 0, NULL,
|
||||
s->n_streams, release_barrier);
|
||||
|
||||
VK_CHECK_RESULT(vkEndCommandBuffer(s->commandBuffer));
|
||||
VK_CHECK_RESULT(vkEndCommandBuffer(pass->commandBuffer));
|
||||
|
||||
VK_CHECK_RESULT(vkResetFences(s->base.device, 1, &s->fence));
|
||||
|
||||
if (s->pipelineSemaphore == VK_NULL_HANDLE) {
|
||||
VkExportSemaphoreCreateInfo export_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
|
||||
.handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
|
||||
};
|
||||
VkSemaphoreCreateInfo semaphore_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
|
||||
.pNext = &export_info,
|
||||
};
|
||||
VK_CHECK_RESULT(vkCreateSemaphore(s->base.device, &semaphore_info, NULL, &s->pipelineSemaphore));
|
||||
}
|
||||
VK_CHECK_RESULT(vkResetFences(s->base.device, 1, &pass->fence));
|
||||
|
||||
semaphore_signal_info[semaphore_signal_info_len++] = (VkSemaphoreSubmitInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
|
||||
.semaphore = s->pipelineSemaphore,
|
||||
.semaphore = pass->pipelineSemaphore,
|
||||
};
|
||||
|
||||
VkCommandBufferSubmitInfoKHR commandBufferInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO,
|
||||
.commandBuffer = s->commandBuffer,
|
||||
.commandBuffer = pass->commandBuffer,
|
||||
};
|
||||
|
||||
const VkSubmitInfo2KHR submitInfo = {
|
||||
|
@ -291,12 +279,12 @@ static int runCommandBuffer(struct vulkan_blit_state *s, struct vulkan_pass *pas
|
|||
.signalSemaphoreInfoCount = semaphore_signal_info_len,
|
||||
.pSignalSemaphoreInfos = semaphore_signal_info,
|
||||
};
|
||||
VK_CHECK_RESULT(vkQueueSubmit2KHR(s->base.queue, 1, &submitInfo, s->fence));
|
||||
VK_CHECK_RESULT(vkQueueSubmit2KHR(s->base.queue, 1, &submitInfo, pass->fence));
|
||||
s->started = true;
|
||||
|
||||
VkSemaphoreGetFdInfoKHR get_fence_fd_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
|
||||
.semaphore = s->pipelineSemaphore,
|
||||
.semaphore = pass->pipelineSemaphore,
|
||||
.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
|
||||
};
|
||||
VK_CHECK_RESULT(vkGetSemaphoreFdKHR(s->base.device, &get_fence_fd_info, &pass->sync_fd));
|
||||
|
@ -314,10 +302,7 @@ static void clear_buffers(struct vulkan_blit_state *s, struct vulkan_stream *p)
|
|||
}
|
||||
p->n_buffers = 0;
|
||||
p->buffer_type = SPA_DATA_Invalid;
|
||||
if (p->direction == SPA_DIRECTION_INPUT) {
|
||||
vulkan_staging_buffer_destroy(&s->base, &s->staging_buffer);
|
||||
s->staging_buffer.buffer = VK_NULL_HANDLE;
|
||||
}
|
||||
p->maxsize = 0;
|
||||
}
|
||||
|
||||
static void clear_streams(struct vulkan_blit_state *s)
|
||||
|
@ -406,6 +391,7 @@ int spa_vulkan_blit_use_buffers(struct vulkan_blit_state *s, struct vulkan_strea
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
p->maxsize = SPA_MAX(p->maxsize, buffers[i]->datas[0].maxsize);
|
||||
externalBufferInfo.usage = p->direction == SPA_DIRECTION_OUTPUT
|
||||
? VK_IMAGE_USAGE_TRANSFER_DST_BIT
|
||||
: VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
|
||||
|
@ -442,13 +428,6 @@ int spa_vulkan_blit_use_buffers(struct vulkan_blit_state *s, struct vulkan_strea
|
|||
p->spa_buffers[i] = buffers[i];
|
||||
p->n_buffers++;
|
||||
}
|
||||
if (p->direction == SPA_DIRECTION_INPUT && p->buffer_type == SPA_DATA_MemPtr) {
|
||||
ret = vulkan_staging_buffer_create(&s->base, buffers[0]->datas[0].maxsize, &s->staging_buffer);
|
||||
if (ret < 0) {
|
||||
spa_log_error(s->log, "Failed to create staging buffer");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -504,6 +483,7 @@ static int vulkan_stream_init(struct vulkan_stream *stream, enum spa_direction d
|
|||
{
|
||||
spa_zero(*stream);
|
||||
stream->direction = direction;
|
||||
stream->maxsize = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -516,6 +496,42 @@ int spa_vulkan_blit_init_pass(struct vulkan_blit_state *s, struct vulkan_pass *p
|
|||
|
||||
pass->sync_fd = -1;
|
||||
|
||||
CHECK(vulkan_fence_create(&s->base, &pass->fence));
|
||||
CHECK(vulkan_commandBuffer_create(&s->base, s->commandPool, &pass->commandBuffer));
|
||||
|
||||
VkExportSemaphoreCreateInfo export_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
|
||||
.handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
|
||||
};
|
||||
VkSemaphoreCreateInfo semaphore_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
|
||||
.pNext = &export_info,
|
||||
};
|
||||
VK_CHECK_RESULT(vkCreateSemaphore(s->base.device, &semaphore_info, NULL, &pass->pipelineSemaphore));
|
||||
|
||||
for (uint32_t i = 0; i < s->n_streams; i++) {
|
||||
struct vulkan_stream *p = &s->streams[i];
|
||||
|
||||
if (p->direction == SPA_DIRECTION_OUTPUT || p->buffer_type != SPA_DATA_MemPtr)
|
||||
continue;
|
||||
vulkan_staging_buffer_create(&s->base, p->maxsize, &pass->in_staging_buffer);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int spa_vulkan_blit_reset_pass(struct vulkan_blit_state *s, struct vulkan_pass *pass)
|
||||
{
|
||||
pass->in_buffer_id = SPA_ID_INVALID;
|
||||
pass->in_stream_id = SPA_ID_INVALID;
|
||||
pass->out_buffer_id = SPA_ID_INVALID;
|
||||
pass->out_stream_id = SPA_ID_INVALID;
|
||||
|
||||
if (pass->sync_fd != -1) {
|
||||
close(pass->sync_fd);
|
||||
pass->sync_fd = -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -531,6 +547,15 @@ int spa_vulkan_blit_clear_pass(struct vulkan_blit_state *s, struct vulkan_pass *
|
|||
pass->sync_fd = -1;
|
||||
}
|
||||
|
||||
vkDestroyFence(s->base.device, pass->fence, NULL);
|
||||
pass->fence = VK_NULL_HANDLE;
|
||||
vkFreeCommandBuffers(s->base.device, s->commandPool, 1, &pass->commandBuffer);
|
||||
pass->commandBuffer = VK_NULL_HANDLE;
|
||||
vkDestroySemaphore(s->base.device, pass->pipelineSemaphore, NULL);
|
||||
pass->pipelineSemaphore = VK_NULL_HANDLE;
|
||||
vulkan_staging_buffer_destroy(&s->base, &pass->in_staging_buffer);
|
||||
pass->in_staging_buffer.buffer = VK_NULL_HANDLE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -543,9 +568,7 @@ int spa_vulkan_blit_init_stream(struct vulkan_blit_state *s, struct vulkan_strea
|
|||
int spa_vulkan_blit_prepare(struct vulkan_blit_state *s)
|
||||
{
|
||||
if (!s->prepared) {
|
||||
CHECK(vulkan_fence_create(&s->base, &s->fence));
|
||||
CHECK(vulkan_commandPool_create(&s->base, &s->commandPool));
|
||||
CHECK(vulkan_commandBuffer_create(&s->base, s->commandPool, &s->commandBuffer));
|
||||
s->prepared = true;
|
||||
}
|
||||
return 0;
|
||||
|
@ -555,7 +578,6 @@ int spa_vulkan_blit_unprepare(struct vulkan_blit_state *s)
|
|||
{
|
||||
if (s->prepared) {
|
||||
vkDestroyCommandPool(s->base.device, s->commandPool, NULL);
|
||||
vkDestroyFence(s->base.device, s->fence, NULL);
|
||||
s->prepared = false;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -22,6 +22,11 @@ struct vulkan_pass {
|
|||
uint32_t out_stream_id;
|
||||
|
||||
VkBufferImageCopy in_copy;
|
||||
struct vulkan_staging_buffer in_staging_buffer;
|
||||
|
||||
VkCommandBuffer commandBuffer;
|
||||
VkSemaphore pipelineSemaphore;
|
||||
VkFence fence;
|
||||
|
||||
int sync_fd;
|
||||
};
|
||||
|
@ -32,6 +37,7 @@ struct vulkan_stream {
|
|||
enum spa_data_type buffer_type;
|
||||
struct spa_rectangle dim;
|
||||
uint32_t bpp;
|
||||
uint32_t maxsize;
|
||||
|
||||
struct vulkan_buffer buffers[MAX_BUFFERS];
|
||||
struct spa_buffer *spa_buffers[MAX_BUFFERS];
|
||||
|
@ -47,11 +53,7 @@ struct vulkan_blit_state {
|
|||
struct vulkan_format_infos formatInfosDSP;
|
||||
|
||||
VkCommandPool commandPool;
|
||||
VkCommandBuffer commandBuffer;
|
||||
struct vulkan_staging_buffer staging_buffer;
|
||||
|
||||
VkFence fence;
|
||||
VkSemaphore pipelineSemaphore;
|
||||
unsigned int initialized:1;
|
||||
unsigned int prepared:1;
|
||||
unsigned int started:1;
|
||||
|
@ -61,6 +63,7 @@ struct vulkan_blit_state {
|
|||
};
|
||||
|
||||
int spa_vulkan_blit_init_pass(struct vulkan_blit_state *s, struct vulkan_pass *pass);
|
||||
int spa_vulkan_blit_reset_pass(struct vulkan_blit_state *s, struct vulkan_pass *pass);
|
||||
int spa_vulkan_blit_clear_pass(struct vulkan_blit_state *s, struct vulkan_pass *pass);
|
||||
|
||||
int spa_vulkan_blit_init_stream(struct vulkan_blit_state *s, struct vulkan_stream *stream, enum spa_direction,
|
||||
|
|
Loading…
Reference in a new issue