diff --git a/libweston/backend-drm/drm-gbm.c b/libweston/backend-drm/drm-gbm.c index f3caa035e..9a16bdfc3 100644 --- a/libweston/backend-drm/drm-gbm.c +++ b/libweston/backend-drm/drm-gbm.c @@ -816,13 +816,15 @@ struct drm_fb * drm_output_render_vulkan(struct drm_output_state *state, pixman_region32_t *damage) { struct drm_output *output = state->output; + struct drm_plane_state *pstate = + drm_output_state_get_plane(state, output->scanout_handle->plane); + struct weston_renderer *renderer = output->base.compositor->renderer; struct drm_device *device = output->device; struct linux_dmabuf_memory *dmabuf; struct drm_fb *ret; - output->base.compositor->renderer->repaint_output(&output->base, - damage, - output->renderbuffer[output->current_image]); + renderer->repaint_output(&output->base, damage, + output->renderbuffer[output->current_image]); dmabuf = output->linux_dmabuf_memory[output->current_image]; if (!dmabuf) { @@ -840,6 +842,13 @@ drm_output_render_vulkan(struct drm_output_state *state, pixman_region32_t *dama return NULL; } + pstate->in_fence_fd = renderer->vulkan->create_fence_fd(&output->base); + if (pstate->in_fence_fd < 1) { + weston_log("failed to get fence fd from rendering\n"); + drm_fb_unref(ret); + return NULL; + } + output->current_image = (output->current_image + 1) % ARRAY_LENGTH(output->renderbuffer); return ret; diff --git a/libweston/renderer-vulkan/vulkan-renderer.c b/libweston/renderer-vulkan/vulkan-renderer.c index 5d95858b8..e464c5a80 100644 --- a/libweston/renderer-vulkan/vulkan-renderer.c +++ b/libweston/renderer-vulkan/vulkan-renderer.c @@ -405,35 +405,12 @@ static const struct vulkan_extension_table vulkan_device_ext_table[] = { }, }; -static void -transfer_image_queue_family(VkCommandBuffer cmd_buffer, VkImage image, - uint32_t src_index, uint32_t dst_index) -{ - const VkImageMemoryBarrier barrier = { - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - .newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - .srcAccessMask = 0, - .dstAccessMask = 0, - .image = image, - .subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .subresourceRange.layerCount = 1, - .subresourceRange.levelCount = 1, - .srcQueueFamilyIndex = src_index, - .dstQueueFamilyIndex = dst_index, - }; - - vkCmdPipelineBarrier(cmd_buffer, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - 0, 0, NULL, 0, NULL, 1, &barrier); -} - static void transition_image_layout(VkCommandBuffer cmd_buffer, VkImage image, VkImageLayout old_layout, VkImageLayout new_layout, VkPipelineStageFlags srcs, VkPipelineStageFlags dsts, - VkAccessFlags src_access, VkAccessFlags dst_access) + VkAccessFlags src_access, VkAccessFlags dst_access, + uint32_t src_index, uint32_t dst_index) { const VkImageMemoryBarrier barrier = { .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, @@ -445,8 +422,8 @@ transition_image_layout(VkCommandBuffer cmd_buffer, VkImage image, .subresourceRange.levelCount = 1, .srcAccessMask = src_access, .dstAccessMask = dst_access, - .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .srcQueueFamilyIndex = src_index, + .dstQueueFamilyIndex = dst_index, }; vkCmdPipelineBarrier(cmd_buffer, srcs, dsts, 0, 0, NULL, 0, NULL, 1, &barrier); @@ -1349,8 +1326,9 @@ vulkan_renderer_do_read_pixels(struct vulkan_renderer *vr, transition_image_layout(cmd_buffer, color_attachment, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, VK_ACCESS_TRANSFER_WRITE_BIT); + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, + VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED); copy_sub_image_to_buffer(cmd_buffer, dst_buffer, color_attachment, @@ -1362,8 +1340,9 @@ vulkan_renderer_do_read_pixels(struct vulkan_renderer *vr, transition_image_layout(cmd_buffer, color_attachment, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, VK_ACCESS_TRANSFER_WRITE_BIT); + VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_TRANSFER_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED); // TODO: async implementation of this, remove wait vulkan_renderer_cmd_end_wait(vr, &cmd_buffer); @@ -2374,8 +2353,9 @@ vulkan_renderer_create_swapchain(struct weston_output *output, transition_image_layout(cmd_buffer, swapchain_images[i], VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, VK_ACCESS_TRANSFER_WRITE_BIT); + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + 0, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED); create_image_semaphores(vr, vo, im); @@ -2489,9 +2469,11 @@ vulkan_renderer_repaint_output(struct weston_output *output, if (rb->dmabuf) { // Transfer ownership of the dmabuf to Vulkan assert(vulkan_device_has(vr, EXTENSION_EXT_QUEUE_FAMILY_FOREIGN)); - transfer_image_queue_family(cmd_buffer, im->image, - VK_QUEUE_FAMILY_FOREIGN_EXT, - vr->queue_family); + transition_image_layout(cmd_buffer, im->image, + VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_ACCESS_MEMORY_READ_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_QUEUE_FAMILY_FOREIGN_EXT, vr->queue_family); } const struct weston_size *fb = &vo->fb_size; @@ -2532,9 +2514,11 @@ vulkan_renderer_repaint_output(struct weston_output *output, if (rb->dmabuf) { // Transfer ownership of the dmabuf to DRM assert(vulkan_device_has(vr, EXTENSION_EXT_QUEUE_FAMILY_FOREIGN)); - transfer_image_queue_family(cmd_buffer, im->image, - vr->queue_family, - VK_QUEUE_FAMILY_FOREIGN_EXT); + transition_image_layout(cmd_buffer, im->image, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT, + vr->queue_family, VK_QUEUE_FAMILY_FOREIGN_EXT); } result = vkEndCommandBuffer(cmd_buffer); @@ -2749,8 +2733,9 @@ update_texture_image(struct vulkan_renderer *vr, transition_image_layout(cmd_buffer, texture->image, expected_layout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT); + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, + VK_ACCESS_SHADER_READ_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, + VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED); copy_buffer_to_sub_image(cmd_buffer, texture->staging_buffer, texture->image, buffer_width, buffer_height, pitch, pixel_format->bpp, @@ -2759,7 +2744,8 @@ update_texture_image(struct vulkan_renderer *vr, transition_image_layout(cmd_buffer, texture->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT); + VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, + VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED); result = vkEndCommandBuffer(cmd_buffer); check_vk_success(result, "vkEndCommandBuffer"); @@ -3887,7 +3873,8 @@ vulkan_renderer_create_renderbuffer(struct weston_output *output, transition_image_layout(cmd_buffer, im->image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, VK_ACCESS_TRANSFER_WRITE_BIT); + 0, VK_ACCESS_TRANSFER_WRITE_BIT, + VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED); // Wait here is bad, but this is only on renderbuffer creation vulkan_renderer_cmd_end_wait(vr, &cmd_buffer);