gpu: sync dmabufs via semaphores
This ensures both that we signal a semaphore for a dmabuf when we export an image and that we import semaphores for dmabufs and wait on them. Fixes Vulkan node-editor displaying the Vulkan renderer in the sidebar.
This commit is contained in:
@@ -47,6 +47,8 @@ typedef enum {
|
||||
GDK_VULKAN_FEATURE_DESCRIPTOR_INDEXING = 1 << 2,
|
||||
GDK_VULKAN_FEATURE_DYNAMIC_INDEXING = 1 << 3,
|
||||
GDK_VULKAN_FEATURE_NONUNIFORM_INDEXING = 1 << 4,
|
||||
GDK_VULKAN_FEATURE_SEMAPHORE_EXPORT = 1 << 5,
|
||||
GDK_VULKAN_FEATURE_SEMAPHORE_IMPORT = 1 << 6,
|
||||
} GdkVulkanFeatures;
|
||||
|
||||
/* Tracks information about the device grab on this display */
|
||||
|
||||
@@ -39,6 +39,8 @@ static const GdkDebugKey gsk_vulkan_feature_keys[] = {
|
||||
{ "descriptor-indexing", GDK_VULKAN_FEATURE_DESCRIPTOR_INDEXING, "Force slow descriptor set layout codepath" },
|
||||
{ "dynamic-indexing", GDK_VULKAN_FEATURE_DYNAMIC_INDEXING, "Hardcode small number of buffer and texure arrays" },
|
||||
{ "nonuniform-indexing", GDK_VULKAN_FEATURE_NONUNIFORM_INDEXING, "Split draw calls to ensure uniform texture accesses" },
|
||||
{ "semaphore-export", GDK_VULKAN_FEATURE_SEMAPHORE_EXPORT, "Disable sync of exported dmabufs" },
|
||||
{ "semaphore-import", GDK_VULKAN_FEATURE_SEMAPHORE_IMPORT, "Disable sync of imported dmabufs" },
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -562,8 +564,17 @@ physical_device_check_features (VkPhysicalDevice device,
|
||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
|
||||
.pNext = &ycbcr_features
|
||||
};
|
||||
VkExternalSemaphoreProperties semaphore_props = {
|
||||
.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES,
|
||||
};
|
||||
|
||||
vkGetPhysicalDeviceFeatures2 (device, &features);
|
||||
vkGetPhysicalDeviceExternalSemaphoreProperties (device,
|
||||
&(VkPhysicalDeviceExternalSemaphoreInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
|
||||
.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
|
||||
},
|
||||
&semaphore_props);
|
||||
|
||||
*out_features = 0;
|
||||
|
||||
@@ -591,6 +602,15 @@ physical_device_check_features (VkPhysicalDevice device,
|
||||
physical_device_supports_extension (device, VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME))
|
||||
*out_features |= GDK_VULKAN_FEATURE_DMABUF;
|
||||
|
||||
if (physical_device_supports_extension (device, VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME))
|
||||
{
|
||||
if (semaphore_props.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT)
|
||||
*out_features |= GDK_VULKAN_FEATURE_SEMAPHORE_EXPORT;
|
||||
|
||||
if (semaphore_props.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_IMPORTABLE_BIT)
|
||||
*out_features |= GDK_VULKAN_FEATURE_SEMAPHORE_IMPORT;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1450,6 +1470,8 @@ gdk_display_create_vulkan_device (GdkDisplay *display,
|
||||
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME);
|
||||
g_ptr_array_add (device_extensions, (gpointer) VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME);
|
||||
}
|
||||
if (features & (GDK_VULKAN_FEATURE_SEMAPHORE_IMPORT | GDK_VULKAN_FEATURE_SEMAPHORE_EXPORT))
|
||||
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME);
|
||||
if (physical_device_supports_extension (devices[i], VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME))
|
||||
g_ptr_array_add (device_extensions, (gpointer) VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME);
|
||||
|
||||
|
||||
@@ -59,6 +59,7 @@ gsk_gpu_blit_op_vk_command (GskGpuOp *op,
|
||||
src_layout != VK_IMAGE_LAYOUT_GENERAL)
|
||||
{
|
||||
gsk_vulkan_image_transition (GSK_VULKAN_IMAGE (self->src_image),
|
||||
state->semaphores,
|
||||
state->vk_command_buffer,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
@@ -72,6 +73,7 @@ gsk_gpu_blit_op_vk_command (GskGpuOp *op,
|
||||
dest_layout != VK_IMAGE_LAYOUT_GENERAL)
|
||||
{
|
||||
gsk_vulkan_image_transition (GSK_VULKAN_IMAGE (self->dest_image),
|
||||
state->semaphores,
|
||||
state->vk_command_buffer,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
|
||||
@@ -8,11 +8,17 @@
|
||||
#include "gskgpuprintprivate.h"
|
||||
#ifdef GDK_RENDERING_VULKAN
|
||||
#include "gskvulkanbufferprivate.h"
|
||||
#include "gskvulkanframeprivate.h"
|
||||
#include "gskvulkanimageprivate.h"
|
||||
#endif
|
||||
|
||||
#include "gdk/gdkdmabuftextureprivate.h"
|
||||
#include "gdk/gdkglcontextprivate.h"
|
||||
|
||||
#ifdef HAVE_DMABUF
|
||||
#include <linux/dma-buf.h>
|
||||
#endif
|
||||
|
||||
typedef struct _GskGpuDownloadOp GskGpuDownloadOp;
|
||||
|
||||
typedef void (* GdkGpuDownloadOpCreateFunc) (GskGpuDownloadOp *);
|
||||
@@ -28,6 +34,9 @@ struct _GskGpuDownloadOp
|
||||
|
||||
GdkTexture *texture;
|
||||
GskGpuBuffer *buffer;
|
||||
#ifdef GDK_RENDERING_VULKAN
|
||||
VkSemaphore vk_semaphore;
|
||||
#endif
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -59,6 +68,40 @@ gsk_gpu_download_op_print (GskGpuOp *op,
|
||||
}
|
||||
|
||||
#ifdef GDK_RENDERING_VULKAN
|
||||
/* The code needs to run here because vkGetSemaphoreFdKHR() may
|
||||
* only be called after the semaphore has been submitted via
|
||||
* vkQueueSubmit().
|
||||
*/
|
||||
static void
|
||||
gsk_gpu_download_op_vk_sync_semaphore (GskGpuDownloadOp *self)
|
||||
{
|
||||
PFN_vkGetSemaphoreFdKHR func_vkGetSemaphoreFdKHR;
|
||||
GdkDisplay *display;
|
||||
int fd, sync_file_fd;
|
||||
|
||||
/* Don't look at where I store my variables plz */
|
||||
display = gdk_dmabuf_texture_get_display (GDK_DMABUF_TEXTURE (self->texture));
|
||||
fd = gdk_dmabuf_texture_get_dmabuf (GDK_DMABUF_TEXTURE (self->texture))->planes[0].fd;
|
||||
func_vkGetSemaphoreFdKHR = (PFN_vkGetSemaphoreFdKHR) vkGetDeviceProcAddr (display->vk_device, "vkGetSemaphoreFdKHR");
|
||||
|
||||
/* vkGetSemaphoreFdKHR implicitly resets the semaphore.
|
||||
* But who cares, we're about to delete it. */
|
||||
if (GSK_VK_CHECK (func_vkGetSemaphoreFdKHR, display->vk_device,
|
||||
&(VkSemaphoreGetFdInfoKHR) {
|
||||
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR,
|
||||
.semaphore = self->vk_semaphore,
|
||||
.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
|
||||
},
|
||||
&sync_file_fd) == VK_SUCCESS)
|
||||
{
|
||||
gdk_dmabuf_import_sync_file (fd, DMA_BUF_SYNC_WRITE, sync_file_fd);
|
||||
|
||||
close (sync_file_fd);
|
||||
}
|
||||
|
||||
vkDestroySemaphore (display->vk_device, self->vk_semaphore, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_download_op_vk_create (GskGpuDownloadOp *self)
|
||||
{
|
||||
@@ -93,7 +136,31 @@ gsk_gpu_download_op_vk_command (GskGpuOp *op,
|
||||
#ifdef HAVE_DMABUF
|
||||
self->texture = gsk_vulkan_image_to_dmabuf_texture (GSK_VULKAN_IMAGE (self->image));
|
||||
if (self->texture)
|
||||
return op->next;
|
||||
{
|
||||
GskVulkanDevice *device = GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame));
|
||||
VkDevice vk_device = gsk_vulkan_device_get_vk_device (device);
|
||||
|
||||
gsk_gpu_device_cache_texture_image (GSK_GPU_DEVICE (device), self->texture, gsk_gpu_frame_get_timestamp (frame), self->image);
|
||||
|
||||
if (gsk_vulkan_device_has_feature (device, GDK_VULKAN_FEATURE_SEMAPHORE_EXPORT))
|
||||
{
|
||||
GSK_VK_CHECK (vkCreateSemaphore, vk_device,
|
||||
&(VkSemaphoreCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
|
||||
.pNext = &(VkExportSemaphoreCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
|
||||
.handleTypes = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
|
||||
},
|
||||
},
|
||||
NULL,
|
||||
&self->vk_semaphore);
|
||||
gsk_vulkan_semaphores_add_signal (state->semaphores, self->vk_semaphore);
|
||||
|
||||
self->create_func = gsk_gpu_download_op_vk_sync_semaphore;
|
||||
}
|
||||
|
||||
return op->next;
|
||||
}
|
||||
#endif
|
||||
|
||||
width = gsk_gpu_image_get_width (self->image);
|
||||
@@ -103,6 +170,7 @@ gsk_gpu_download_op_vk_command (GskGpuOp *op,
|
||||
height * stride);
|
||||
|
||||
gsk_vulkan_image_transition (GSK_VULKAN_IMAGE (self->image),
|
||||
state->semaphores,
|
||||
state->vk_command_buffer,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
|
||||
@@ -58,6 +58,7 @@ gsk_gpu_mipmap_op_vk_command (GskGpuOp *op,
|
||||
|
||||
/* optimize me: only transition mipmap layers 1..n, but not 0 */
|
||||
gsk_vulkan_image_transition (image,
|
||||
state->semaphores,
|
||||
state->vk_command_buffer,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
|
||||
@@ -39,6 +39,7 @@ struct _GskVulkanCommandState
|
||||
VkCommandBuffer vk_command_buffer;
|
||||
|
||||
GskVulkanDescriptors *desc;
|
||||
GskVulkanSemaphores *semaphores;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -88,11 +88,11 @@ gsk_gpu_render_pass_op_do_barriers (GskGpuRenderPassOp *self,
|
||||
state->desc = GSK_VULKAN_DESCRIPTORS (shader->desc);
|
||||
}
|
||||
desc = shader->desc;
|
||||
gsk_vulkan_descriptors_transition (GSK_VULKAN_DESCRIPTORS (desc), state->vk_command_buffer);
|
||||
gsk_vulkan_descriptors_transition (GSK_VULKAN_DESCRIPTORS (desc), state->semaphores, state->vk_command_buffer);
|
||||
}
|
||||
|
||||
if (desc == NULL)
|
||||
gsk_vulkan_descriptors_transition (state->desc, state->vk_command_buffer);
|
||||
gsk_vulkan_descriptors_transition (state->desc, state->semaphores, state->vk_command_buffer);
|
||||
}
|
||||
|
||||
static GskGpuOp *
|
||||
|
||||
@@ -18,6 +18,7 @@ typedef struct _GskGpuOpClass GskGpuOpClass;
|
||||
typedef struct _GskGpuShaderOp GskGpuShaderOp;
|
||||
typedef struct _GskGpuShaderOpClass GskGpuShaderOpClass;
|
||||
typedef struct _GskVulkanDescriptors GskVulkanDescriptors;
|
||||
typedef struct _GskVulkanSemaphores GskVulkanSemaphores;
|
||||
|
||||
typedef enum {
|
||||
GSK_GPU_IMAGE_EXTERNAL = (1 << 0),
|
||||
|
||||
@@ -130,6 +130,7 @@ gsk_gpu_upload_op_vk_command_with_area (GskGpuOp *op,
|
||||
},
|
||||
0, NULL);
|
||||
gsk_vulkan_image_transition (image,
|
||||
state->semaphores,
|
||||
state->vk_command_buffer,
|
||||
VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
|
||||
@@ -26,6 +26,7 @@ gsk_vulkan_descriptors_get_pipeline_layout (GskVulkanDescriptors *self)
|
||||
|
||||
void
|
||||
gsk_vulkan_descriptors_transition (GskVulkanDescriptors *self,
|
||||
GskVulkanSemaphores *semaphores,
|
||||
VkCommandBuffer vk_command_buffer)
|
||||
{
|
||||
GskGpuDescriptors *desc = GSK_GPU_DESCRIPTORS (self);
|
||||
@@ -34,6 +35,7 @@ gsk_vulkan_descriptors_transition (GskVulkanDescriptors *self,
|
||||
for (i = 0; i < gsk_gpu_descriptors_get_n_images (desc); i++)
|
||||
{
|
||||
gsk_vulkan_image_transition (GSK_VULKAN_IMAGE (gsk_gpu_descriptors_get_image (desc, i)),
|
||||
semaphores,
|
||||
vk_command_buffer,
|
||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
|
||||
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
|
||||
|
||||
@@ -35,6 +35,7 @@ GType gsk_vulkan_descriptors_get_type
|
||||
GskVulkanPipelineLayout * gsk_vulkan_descriptors_get_pipeline_layout (GskVulkanDescriptors *self);
|
||||
|
||||
void gsk_vulkan_descriptors_transition (GskVulkanDescriptors *self,
|
||||
GskVulkanSemaphores *semaphores,
|
||||
VkCommandBuffer vk_command_buffer);
|
||||
void gsk_vulkan_descriptors_bind (GskVulkanDescriptors *self,
|
||||
GskVulkanDescriptors *previous,
|
||||
|
||||
@@ -20,6 +20,27 @@
|
||||
#define GDK_ARRAY_NO_MEMSET 1
|
||||
#include "gdk/gdkarrayimpl.c"
|
||||
|
||||
#define GDK_ARRAY_NAME gsk_semaphores
|
||||
#define GDK_ARRAY_TYPE_NAME GskSemaphores
|
||||
#define GDK_ARRAY_ELEMENT_TYPE VkSemaphore
|
||||
#define GDK_ARRAY_PREALLOC 16
|
||||
#define GDK_ARRAY_NO_MEMSET 1
|
||||
#include "gdk/gdkarrayimpl.c"
|
||||
|
||||
#define GDK_ARRAY_NAME gsk_pipeline_stages
|
||||
#define GDK_ARRAY_TYPE_NAME GskPipelineStages
|
||||
#define GDK_ARRAY_ELEMENT_TYPE VkPipelineStageFlags
|
||||
#define GDK_ARRAY_PREALLOC 16
|
||||
#define GDK_ARRAY_NO_MEMSET 1
|
||||
#include "gdk/gdkarrayimpl.c"
|
||||
|
||||
struct _GskVulkanSemaphores
|
||||
{
|
||||
GskSemaphores wait_semaphores;
|
||||
GskPipelineStages wait_stages;
|
||||
GskSemaphores signal_semaphores;
|
||||
};
|
||||
|
||||
struct _GskVulkanFrame
|
||||
{
|
||||
GskGpuFrame parent_instance;
|
||||
@@ -265,6 +286,7 @@ gsk_vulkan_frame_submit (GskGpuFrame *frame,
|
||||
GskGpuOp *op)
|
||||
{
|
||||
GskVulkanFrame *self = GSK_VULKAN_FRAME (frame);
|
||||
GskVulkanSemaphores semaphores;
|
||||
GskVulkanCommandState state;
|
||||
|
||||
if (gsk_descriptors_get_size (&self->descriptors) == 0)
|
||||
@@ -287,10 +309,16 @@ gsk_vulkan_frame_submit (GskGpuFrame *frame,
|
||||
},
|
||||
(VkDeviceSize[1]) { 0 });
|
||||
|
||||
gsk_semaphores_init (&semaphores.wait_semaphores);
|
||||
gsk_pipeline_stages_init (&semaphores.wait_stages);
|
||||
gsk_semaphores_init (&semaphores.signal_semaphores);
|
||||
|
||||
state.vk_command_buffer = self->vk_command_buffer;
|
||||
state.vk_render_pass = VK_NULL_HANDLE;
|
||||
state.vk_format = VK_FORMAT_UNDEFINED;
|
||||
state.desc = GSK_VULKAN_DESCRIPTORS (gsk_descriptors_get (&self->descriptors, 0));
|
||||
state.semaphores = &semaphores;
|
||||
|
||||
gsk_vulkan_descriptors_bind (GSK_VULKAN_DESCRIPTORS (gsk_descriptors_get (&self->descriptors, 0)),
|
||||
NULL,
|
||||
state.vk_command_buffer);
|
||||
@@ -308,8 +336,17 @@ gsk_vulkan_frame_submit (GskGpuFrame *frame,
|
||||
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
|
||||
.commandBufferCount = 1,
|
||||
.pCommandBuffers = &self->vk_command_buffer,
|
||||
.pWaitSemaphores = gsk_semaphores_get_data (&semaphores.wait_semaphores),
|
||||
.pWaitDstStageMask = gsk_pipeline_stages_get_data (&semaphores.wait_stages),
|
||||
.waitSemaphoreCount = gsk_semaphores_get_size (&semaphores.wait_semaphores),
|
||||
.pSignalSemaphores = gsk_semaphores_get_data (&semaphores.signal_semaphores),
|
||||
.signalSemaphoreCount = gsk_semaphores_get_size (&semaphores.signal_semaphores),
|
||||
},
|
||||
self->vk_fence);
|
||||
|
||||
gsk_semaphores_clear (&semaphores.wait_semaphores);
|
||||
gsk_pipeline_stages_clear (&semaphores.wait_stages);
|
||||
gsk_semaphores_clear (&semaphores.signal_semaphores);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -376,3 +413,19 @@ gsk_vulkan_frame_get_vk_fence (GskVulkanFrame *self)
|
||||
return self->vk_fence;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_vulkan_semaphores_add_wait (GskVulkanSemaphores *self,
|
||||
VkSemaphore semaphore,
|
||||
VkPipelineStageFlags stage)
|
||||
{
|
||||
gsk_semaphores_append (&self->wait_semaphores, semaphore);
|
||||
gsk_pipeline_stages_append (&self->wait_stages, stage);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_vulkan_semaphores_add_signal (GskVulkanSemaphores *self,
|
||||
VkSemaphore semaphore)
|
||||
{
|
||||
gsk_semaphores_append (&self->signal_semaphores, semaphore);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,5 +12,10 @@ G_DECLARE_FINAL_TYPE (GskVulkanFrame, gsk_vulkan_frame, GSK, VULKAN_FRAME, GskGp
|
||||
|
||||
VkFence gsk_vulkan_frame_get_vk_fence (GskVulkanFrame *self) G_GNUC_PURE;
|
||||
|
||||
void gsk_vulkan_semaphores_add_wait (GskVulkanSemaphores *self,
|
||||
VkSemaphore semaphore,
|
||||
VkPipelineStageFlags stage);
|
||||
void gsk_vulkan_semaphores_add_signal (GskVulkanSemaphores *self,
|
||||
VkSemaphore semaphore);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "gskvulkanimageprivate.h"
|
||||
|
||||
#include "gskvulkanbufferprivate.h"
|
||||
#include "gskvulkanframeprivate.h"
|
||||
#include "gskvulkanmemoryprivate.h"
|
||||
|
||||
#include "gdk/gdkdisplayprivate.h"
|
||||
@@ -13,6 +14,9 @@
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_DMABUF
|
||||
#include <linux/dma-buf.h>
|
||||
#endif
|
||||
|
||||
struct _GskVulkanImage
|
||||
{
|
||||
@@ -28,6 +32,7 @@ struct _GskVulkanImage
|
||||
VkFramebuffer vk_framebuffer;
|
||||
VkImageView vk_framebuffer_image_view;
|
||||
VkSampler vk_sampler;
|
||||
VkSemaphore vk_semaphore;
|
||||
|
||||
VkPipelineStageFlags vk_pipeline_stage;
|
||||
VkImageLayout vk_image_layout;
|
||||
@@ -1221,6 +1226,32 @@ gsk_vulkan_image_new_for_dmabuf (GskVulkanDevice *device,
|
||||
},
|
||||
&requirements);
|
||||
|
||||
if (gsk_vulkan_device_has_feature (device, GDK_VULKAN_FEATURE_SEMAPHORE_IMPORT))
|
||||
{
|
||||
int sync_file_fd = gdk_dmabuf_export_sync_file (fd, DMA_BUF_SYNC_READ);
|
||||
if (sync_file_fd >= 0)
|
||||
{
|
||||
PFN_vkImportSemaphoreFdKHR func_vkImportSemaphoreFdKHR;
|
||||
func_vkImportSemaphoreFdKHR = (PFN_vkImportSemaphoreFdKHR) vkGetDeviceProcAddr (vk_device, "vkImportSemaphoreFdKHR");
|
||||
|
||||
GSK_VK_CHECK (vkCreateSemaphore, vk_device,
|
||||
&(VkSemaphoreCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
|
||||
},
|
||||
NULL,
|
||||
&self->vk_semaphore);
|
||||
|
||||
GSK_VK_CHECK (func_vkImportSemaphoreFdKHR, vk_device,
|
||||
&(VkImportSemaphoreFdInfoKHR) {
|
||||
.sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR,
|
||||
.handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
|
||||
.flags = VK_SEMAPHORE_IMPORT_TEMPORARY_BIT,
|
||||
.semaphore = self->vk_semaphore,
|
||||
.fd = sync_file_fd,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
gsk_vulkan_alloc (self->allocator,
|
||||
requirements.memoryRequirements.size,
|
||||
requirements.memoryRequirements.alignment,
|
||||
@@ -1440,6 +1471,8 @@ gsk_vulkan_image_to_dmabuf_texture (GskVulkanImage *self)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gsk_gpu_image_toggle_ref_texture (GSK_GPU_IMAGE (self), texture);
|
||||
|
||||
return texture;
|
||||
}
|
||||
#endif
|
||||
@@ -1481,6 +1514,9 @@ gsk_vulkan_image_finalize (GObject *object)
|
||||
if (self->vk_image_view != VK_NULL_HANDLE)
|
||||
vkDestroyImageView (device, self->vk_image_view, NULL);
|
||||
|
||||
if (self->vk_semaphore != VK_NULL_HANDLE)
|
||||
vkDestroySemaphore (device, self->vk_semaphore, NULL);
|
||||
|
||||
/* memory is NULL for for_swapchain() images, where we don't own
|
||||
* the VkImage */
|
||||
if (self->allocator)
|
||||
@@ -1610,6 +1646,7 @@ gsk_vulkan_image_set_vk_image_layout (GskVulkanImage *self,
|
||||
|
||||
void
|
||||
gsk_vulkan_image_transition (GskVulkanImage *self,
|
||||
GskVulkanSemaphores *semaphores,
|
||||
VkCommandBuffer command_buffer,
|
||||
VkPipelineStageFlags stage,
|
||||
VkImageLayout image_layout,
|
||||
@@ -1620,6 +1657,12 @@ gsk_vulkan_image_transition (GskVulkanImage *self,
|
||||
self->vk_access == access)
|
||||
return;
|
||||
|
||||
if (self->vk_pipeline_stage == VK_IMAGE_LAYOUT_UNDEFINED &&
|
||||
self->vk_semaphore)
|
||||
{
|
||||
gsk_vulkan_semaphores_add_wait (semaphores, self->vk_semaphore, stage);
|
||||
}
|
||||
|
||||
vkCmdPipelineBarrier (command_buffer,
|
||||
self->vk_pipeline_stage,
|
||||
stage,
|
||||
|
||||
@@ -52,6 +52,7 @@ void gsk_vulkan_image_set_vk_image_layout (GskVulk
|
||||
VkImageLayout image_layout,
|
||||
VkAccessFlags access);
|
||||
void gsk_vulkan_image_transition (GskVulkanImage *self,
|
||||
GskVulkanSemaphores *semaphores,
|
||||
VkCommandBuffer command_buffer,
|
||||
VkPipelineStageFlags stage,
|
||||
VkImageLayout image_layout,
|
||||
|
||||
Reference in New Issue
Block a user