vulkan: implement proper descriptor set handling
authorMatthew Waters <matthew@centricular.com>
Wed, 6 Nov 2019 11:19:42 +0000 (22:19 +1100)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Thu, 7 Nov 2019 20:01:57 +0000 (20:01 +0000)
The major functionality gain this provides is proper reference counting
for a descriptor set.  Overall this allows us to create descriptor sets
when they are needed (or reused from a cache) without violating any of
vulkan's object synchronisation requirements.

As there are a fixed number of sets available in a pool, the number of
descriptors in elements is currently hardcoded to 32.  This can be extended
in a future change to create pools on the fly if that limit is ever overrun.

18 files changed:
ext/vulkan/vkcolorconvert.c
ext/vulkan/vkcolorconvert.h
ext/vulkan/vkfullscreenrender.c
ext/vulkan/vkfullscreenrender.h
ext/vulkan/vkimageidentity.c
ext/vulkan/vkimageidentity.h
ext/vulkan/vkviewconvert.c
ext/vulkan/vkviewconvert.h
gst-libs/gst/vulkan/gstvkdescriptorcache-private.h [new file with mode: 0644]
gst-libs/gst/vulkan/gstvkdescriptorcache.c [new file with mode: 0644]
gst-libs/gst/vulkan/gstvkdescriptorcache.h [new file with mode: 0644]
gst-libs/gst/vulkan/gstvkdescriptorpool.c [new file with mode: 0644]
gst-libs/gst/vulkan/gstvkdescriptorpool.h [new file with mode: 0644]
gst-libs/gst/vulkan/gstvkdescriptorset.c [new file with mode: 0644]
gst-libs/gst/vulkan/gstvkdescriptorset.h [new file with mode: 0644]
gst-libs/gst/vulkan/meson.build
gst-libs/gst/vulkan/vulkan.h
gst-libs/gst/vulkan/vulkan_fwd.h

index 4668132..02699b9 100644 (file)
@@ -48,7 +48,7 @@
 GST_DEBUG_CATEGORY (gst_debug_vulkan_color_convert);
 #define GST_CAT_DEFAULT gst_debug_vulkan_color_convert
 
-#define N_SHADER_INFO (8*16)
+#define N_SHADER_INFO (8*4*4)
 static shader_info shader_infos[N_SHADER_INFO];
 
 #define PUSH_CONSTANT_RANGE_NULL_INIT (VkPushConstantRange) { \
@@ -494,9 +494,27 @@ convert_info_new (GstVideoInfo * in_info, GstVideoInfo * out_info)
   return conv;
 }
 
+static GstVulkanDescriptorSet *
+_create_descriptor_set (GstVulkanColorConvert * conv)
+{
+  GstVulkanFullScreenRender *render = GST_VULKAN_FULL_SCREEN_RENDER (conv);
+  GstVulkanDescriptorSet *ret;
+  GError *error = NULL;
+
+  ret = gst_vulkan_descriptor_cache_acquire (conv->descriptor_pool, &error);
+  if (!ret) {
+    GST_ERROR_OBJECT (render, "Failed to create framebuffer: %s",
+        error->message);
+    g_clear_error (&error);
+    return NULL;
+  }
+
+  return ret;
+}
+
 static void
-update_descriptor_set (GstVulkanColorConvert * conv, VkImageView * views,
-    guint n_views)
+update_descriptor_set (GstVulkanColorConvert * conv,
+    VkDescriptorSet descriptor_set, VkImageView * views, guint n_views)
 {
   GstVulkanFullScreenRender *render = GST_VULKAN_FULL_SCREEN_RENDER (conv);
   VkDescriptorBufferInfo buffer_info;
@@ -518,7 +536,7 @@ update_descriptor_set (GstVulkanColorConvert * conv, VkImageView * views,
     writes[i] = (VkWriteDescriptorSet) {
         .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
         .pNext = NULL,
-        .dstSet = conv->descriptor_set,
+        .dstSet = descriptor_set,
         .dstBinding = i,
         .dstArrayElement = 0,
         .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
@@ -537,7 +555,7 @@ update_descriptor_set (GstVulkanColorConvert * conv, VkImageView * views,
     writes[i] = (VkWriteDescriptorSet) {
         .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
         .pNext = NULL,
-        .dstSet = conv->descriptor_set,
+        .dstSet = descriptor_set,
         .dstBinding = i,
         .dstArrayElement = 0,
         .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
@@ -703,9 +721,11 @@ calculate_reorder_indexes (GstVideoFormat in_format,
 static gboolean
 swizzle_rgb_update_command_state (GstVulkanColorConvert * conv,
     VkCommandBuffer cmd, shader_info * sinfo,
-    GstVulkanImageView ** in_views, GstVulkanImageView ** out_views)
+    GstVulkanImageView ** in_views, GstVulkanImageView ** out_views,
+    GstVulkanFence * fence)
 {
   GstVulkanFullScreenRender *render = GST_VULKAN_FULL_SCREEN_RENDER (conv);
+  GstVulkanDescriptorSet *descriptor_set;
   gint reorder[8];
 
   calculate_reorder_indexes (GST_VIDEO_INFO_FORMAT (&render->in_info),
@@ -715,9 +735,14 @@ swizzle_rgb_update_command_state (GstVulkanColorConvert * conv,
   vkCmdPushConstants (cmd, render->pipeline_layout,
       VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof (reorder),
       (const void *) reorder);
-  update_descriptor_set (conv, &in_views[0]->view, 1);
+  descriptor_set = _create_descriptor_set (conv);
+  update_descriptor_set (conv, descriptor_set->set, &in_views[0]->view, 1);
   vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
-      render->pipeline_layout, 0, 1, &conv->descriptor_set, 0, NULL);
+      render->pipeline_layout, 0, 1, &descriptor_set->set, 0, NULL);
+
+  gst_vulkan_trash_list_add (render->trash_list,
+      gst_vulkan_trash_new_mini_object_unref (gst_vulkan_fence_ref
+          (fence), (GstMiniObject *) descriptor_set));
 
   return TRUE;
 }
@@ -742,16 +767,17 @@ struct YUVUpdateData
 static gboolean
 yuv_to_rgb_update_command_state (GstVulkanColorConvert * conv,
     VkCommandBuffer cmd, shader_info * sinfo, GstVulkanImageView ** in_views,
-    GstVulkanImageView ** out_views)
+    GstVulkanImageView ** out_views, GstVulkanFence * fence)
 {
   GstVulkanFullScreenRender *render = GST_VULKAN_FULL_SCREEN_RENDER (conv);
+  VkImageView views[GST_VIDEO_MAX_PLANES];
+  GstVulkanDescriptorSet *descriptor_set;
+  int i;
 
   if (!GPOINTER_TO_INT (sinfo->user_data)) {
     struct YUVUpdateData data;
     ConvertInfo *conv_info;
     GstMapInfo map_info;
-    VkImageView views[GST_VIDEO_MAX_PLANES];
-    int i;
 
     calculate_reorder_indexes (GST_VIDEO_INFO_FORMAT (&render->in_info),
         in_views, GST_VIDEO_INFO_FORMAT (&render->out_info),
@@ -773,15 +799,20 @@ yuv_to_rgb_update_command_state (GstVulkanColorConvert * conv,
     memcpy (map_info.data, &data, sizeof (data));
     gst_memory_unmap (conv->uniform, &map_info);
 
-    for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&render->in_info); i++)
-      views[i] = in_views[i]->view;
-
-    update_descriptor_set (conv, views,
-        GST_VIDEO_INFO_N_PLANES (&render->in_info));
     sinfo->user_data = GINT_TO_POINTER (1);
   }
+
+  for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&render->in_info); i++)
+    views[i] = in_views[i]->view;
+  descriptor_set = _create_descriptor_set (conv);
+  update_descriptor_set (conv, descriptor_set->set, views,
+      GST_VIDEO_INFO_N_PLANES (&render->in_info));
   vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
-      render->pipeline_layout, 0, 1, &conv->descriptor_set, 0, NULL);
+      render->pipeline_layout, 0, 1, &descriptor_set->set, 0, NULL);
+
+  gst_vulkan_trash_list_add (render->trash_list,
+      gst_vulkan_trash_new_mini_object_unref (gst_vulkan_fence_ref
+          (fence), (GstMiniObject *) descriptor_set));
 
   return TRUE;
 }
@@ -1402,32 +1433,36 @@ gst_vulkan_color_convert_start (GstBaseTransform * bt)
   return TRUE;
 }
 
-static VkDescriptorPool
+static GstVulkanDescriptorCache *
 _create_descriptor_pool (GstVulkanColorConvert * conv)
 {
   GstVulkanFullScreenRender *render = GST_VULKAN_FULL_SCREEN_RENDER (conv);
+  gsize max_sets = 32;          /* FIXME: don't hardcode this! */
 
   /* *INDENT-OFF* */
   VkDescriptorPoolSize pool_sizes[] = {
       {
           .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
-          .descriptorCount = GST_VIDEO_INFO_N_PLANES (&render->in_info),
+          .descriptorCount = max_sets * GST_VIDEO_INFO_N_PLANES (&render->in_info),
       },
       {
           .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
-          .descriptorCount = 1
+          .descriptorCount = max_sets
       },
   };
 
   VkDescriptorPoolCreateInfo pool_info = {
       .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
       .pNext = NULL,
+      .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
       .poolSizeCount = G_N_ELEMENTS (pool_sizes),
       .pPoolSizes = pool_sizes,
-      .maxSets = 1
+      .maxSets = max_sets
   };
   /* *INDENT-ON* */
   VkDescriptorPool pool;
+  GstVulkanDescriptorPool *ret;
+  GstVulkanDescriptorCache *cache;
   GError *error = NULL;
   VkResult err;
 
@@ -1440,38 +1475,12 @@ _create_descriptor_pool (GstVulkanColorConvert * conv)
     return VK_NULL_HANDLE;
   }
 
-  return pool;
-}
+  ret = gst_vulkan_descriptor_pool_new_wrapped (render->device, pool, max_sets);
+  cache =
+      gst_vulkan_descriptor_cache_new (ret, 1, &render->descriptor_set_layout);
+  gst_object_unref (ret);
 
-static VkDescriptorSet
-_create_descriptor_set (GstVulkanColorConvert * conv)
-{
-  GstVulkanFullScreenRender *render = GST_VULKAN_FULL_SCREEN_RENDER (conv);
-
-  /* *INDENT-OFF* */
-  VkDescriptorSetAllocateInfo alloc_info = {
-      .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
-      .pNext = NULL,
-      .descriptorPool = conv->descriptor_pool,
-      .descriptorSetCount = 1,
-      .pSetLayouts = &render->descriptor_set_layout
-  };
-  /* *INDENT-ON* */
-  VkDescriptorSet descriptor;
-  GError *error = NULL;
-  VkResult err;
-
-  err =
-      vkAllocateDescriptorSets (render->device->device, &alloc_info,
-      &descriptor);
-  if (gst_vulkan_error_to_g_error (err, &error, "vkAllocateDescriptorSets") < 0) {
-    GST_ERROR_OBJECT (conv, "Failed to allocate descriptor: %s",
-        error->message);
-    g_clear_error (&error);
-    return VK_NULL_HANDLE;
-  }
-
-  return descriptor;
+  return cache;
 }
 
 static gboolean
@@ -1501,8 +1510,6 @@ gst_vulkan_color_convert_set_caps (GstBaseTransform * bt, GstCaps * in_caps,
   GstVulkanFence *last_fence;
   int i;
 
-  conv->current_shader = NULL;
-
   if (!gst_video_info_from_caps (&in_info, in_caps))
     return FALSE;
   if (!gst_video_info_from_caps (&out_info, out_caps))
@@ -1539,10 +1546,9 @@ gst_vulkan_color_convert_set_caps (GstBaseTransform * bt, GstCaps * in_caps,
 
   if (conv->descriptor_pool)
     gst_vulkan_trash_list_add (render->trash_list,
-        gst_vulkan_trash_new_free_descriptor_pool (gst_vulkan_fence_ref
-            (last_fence), conv->descriptor_pool));
-  conv->descriptor_set = VK_NULL_HANDLE;
-  conv->descriptor_pool = VK_NULL_HANDLE;
+        gst_vulkan_trash_new_object_unref (gst_vulkan_fence_ref
+            (last_fence), (GstObject *) conv->descriptor_pool));
+  conv->descriptor_pool = NULL;
   if (conv->uniform)
     gst_vulkan_trash_list_add (render->trash_list,
         gst_vulkan_trash_new_mini_object_unref (gst_vulkan_fence_ref
@@ -1557,8 +1563,6 @@ gst_vulkan_color_convert_set_caps (GstBaseTransform * bt, GstCaps * in_caps,
 
   if (!(conv->descriptor_pool = _create_descriptor_pool (conv)))
     return FALSE;
-  if (!(conv->descriptor_set = _create_descriptor_set (conv)))
-    return FALSE;
 
   if (!_create_uniform_buffer (conv))
     return FALSE;
@@ -1582,10 +1586,9 @@ gst_vulkan_color_convert_stop (GstBaseTransform * bt)
 
     if (conv->descriptor_pool)
       gst_vulkan_trash_list_add (render->trash_list,
-          gst_vulkan_trash_new_free_descriptor_pool (gst_vulkan_fence_ref
-              (last_fence), conv->descriptor_pool));
-    conv->descriptor_set = VK_NULL_HANDLE;
-    conv->descriptor_pool = VK_NULL_HANDLE;
+          gst_vulkan_trash_new_object_unref (gst_vulkan_fence_ref
+              (last_fence), (GstObject *) conv->descriptor_pool));
+    conv->descriptor_pool = NULL;
     if (conv->sampler)
       gst_vulkan_trash_list_add (render->trash_list,
           gst_vulkan_trash_new_free_sampler (gst_vulkan_fence_ref
@@ -1818,7 +1821,7 @@ gst_vulkan_color_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
   }
 
   conv->current_shader->cmd_state_update (conv, cmd_buf->cmd,
-      conv->current_shader, in_img_views, render_img_views);
+      conv->current_shader, in_img_views, render_img_views, fence);
   if (!gst_vulkan_full_screen_render_fill_command_buffer (render, cmd_buf->cmd,
           framebuffer)) {
     g_set_error (&error, GST_VULKAN_ERROR, GST_VULKAN_FAILED,
index b39e01b..227dc39 100644 (file)
@@ -41,7 +41,7 @@ typedef struct _GstVulkanColorConvertClass GstVulkanColorConvertClass;
 
 typedef struct _shader_info shader_info;
 
-typedef gboolean (*CommandStateUpdate) (GstVulkanColorConvert * conv, VkCommandBuffer cmd, shader_info * sinfo, GstVulkanImageView ** src_views, GstVulkanImageView ** dest_views);
+typedef gboolean (*CommandStateUpdate) (GstVulkanColorConvert * conv, VkCommandBuffer cmd, shader_info * sinfo, GstVulkanImageView ** src_views, GstVulkanImageView ** dest_views, GstVulkanFence * fence);
 
 struct _shader_info
 {
@@ -63,8 +63,7 @@ struct _GstVulkanColorConvert
   GstVulkanCommandPool             *cmd_pool;
 
   VkSampler                         sampler;
-  VkDescriptorPool                  descriptor_pool;
-  VkDescriptorSet                   descriptor_set;
+  GstVulkanDescriptorCache         *descriptor_pool;
 
   VkShaderModule                    vert_module;
   VkShaderModule                    frag_module;
index 5cc14ee..f554f8c 100644 (file)
@@ -445,7 +445,7 @@ _create_pipeline_layout (GstVulkanFullScreenRender * render)
       .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
       .pNext = NULL,
       .setLayoutCount = 1,
-      .pSetLayouts = &render->descriptor_set_layout,
+      .pSetLayouts = (VkDescriptorSetLayout *) &render->descriptor_set_layout->handle,
       .pushConstantRangeCount = n_constants,
       .pPushConstantRanges = constants,
   };
@@ -514,7 +514,7 @@ _create_render_pass (GstVulkanFullScreenRender * render)
   return render_pass;
 }
 
-static VkDescriptorSetLayout
+static GstVulkanHandle *
 _create_descriptor_set_layout (GstVulkanFullScreenRender * render)
 {
   GstVulkanFullScreenRenderClass *render_class =
@@ -532,6 +532,7 @@ _create_descriptor_set_layout (GstVulkanFullScreenRender * render)
   };
   /* *INDENT-ON* */
   VkDescriptorSetLayout descriptor_set_layout;
+  GstVulkanHandle *ret;
   VkResult err;
   GError *error = NULL;
 
@@ -546,7 +547,12 @@ _create_descriptor_set_layout (GstVulkanFullScreenRender * render)
     return VK_NULL_HANDLE;
   }
 
-  return descriptor_set_layout;
+  ret = gst_vulkan_handle_new_wrapped (render->device,
+      GST_VULKAN_HANDLE_TYPE_DESCRIPTOR_SET_LAYOUT,
+      (GstVulkanHandleTypedef) descriptor_set_layout,
+      gst_vulkan_handle_free_descriptor_set_layout, NULL);
+
+  return ret;
 }
 
 static gboolean
@@ -571,9 +577,9 @@ gst_vulkan_full_screen_render_set_caps (GstBaseTransform * bt,
 
   if (render->descriptor_set_layout) {
     gst_vulkan_trash_list_add (render->trash_list,
-        gst_vulkan_trash_new_free_descriptor_set_layout (gst_vulkan_fence_ref
-            (last_fence), render->descriptor_set_layout));
-    render->descriptor_set_layout = VK_NULL_HANDLE;
+        gst_vulkan_trash_new_mini_object_unref (gst_vulkan_fence_ref
+            (last_fence), (GstMiniObject *) render->descriptor_set_layout));
+    render->descriptor_set_layout = NULL;
   }
   if (render->pipeline_layout) {
     gst_vulkan_trash_list_add (render->trash_list,
@@ -774,9 +780,9 @@ gst_vulkan_full_screen_render_stop (GstBaseTransform * bt)
             (last_fence), render->render_pass));
     render->render_pass = VK_NULL_HANDLE;
     gst_vulkan_trash_list_add (render->trash_list,
-        gst_vulkan_trash_new_free_descriptor_set_layout (gst_vulkan_fence_ref
-            (last_fence), render->descriptor_set_layout));
-    render->descriptor_set_layout = VK_NULL_HANDLE;
+        gst_vulkan_trash_new_mini_object_unref (gst_vulkan_fence_ref
+            (last_fence), (GstMiniObject *) render->descriptor_set_layout));
+    render->descriptor_set_layout = NULL;
 
     gst_vulkan_fence_unref (last_fence);
 
index 9a61491..1e01812 100644 (file)
@@ -66,7 +66,7 @@ struct _GstVulkanFullScreenRender
   VkRenderPass          render_pass;
   VkPipelineLayout      pipeline_layout;
   VkPipeline            graphics_pipeline;
-  VkDescriptorSetLayout descriptor_set_layout;
+  GstVulkanHandle      *descriptor_set_layout;
 
   GstMemory            *vertices;
   GstMemory            *indices;
index e7f700c..3354bad 100644 (file)
@@ -276,16 +276,17 @@ static VkAttachmentDescription
   return color_attachments;
 }
 
-static VkDescriptorPool
+static GstVulkanDescriptorCache *
 _create_descriptor_pool (GstVulkanImageIdentity * vk_identity)
 {
   GstVulkanFullScreenRender *render =
       GST_VULKAN_FULL_SCREEN_RENDER (vk_identity);
+  guint max_sets = 32;          /* FIXME: Don't hardcode this! */
 
   /* *INDENT-OFF* */
   VkDescriptorPoolSize pool_sizes = {
       .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
-      .descriptorCount = 1
+      .descriptorCount = max_sets
   };
 
   VkDescriptorPoolCreateInfo pool_info = {
@@ -293,10 +294,12 @@ _create_descriptor_pool (GstVulkanImageIdentity * vk_identity)
       .pNext = NULL,
       .poolSizeCount = 1,
       .pPoolSizes = &pool_sizes,
-      .maxSets = 1
+      .maxSets = max_sets
   };
   /* *INDENT-ON* */
   VkDescriptorPool pool;
+  GstVulkanDescriptorPool *ret;
+  GstVulkanDescriptorCache *cache;
   GError *error = NULL;
   VkResult err;
 
@@ -306,42 +309,15 @@ _create_descriptor_pool (GstVulkanImageIdentity * vk_identity)
     GST_ERROR_OBJECT (render, "Failed to create descriptor pool: %s",
         error->message);
     g_clear_error (&error);
-    return VK_NULL_HANDLE;
+    return NULL;
   }
 
-  return pool;
-}
-
-static VkDescriptorSet
-_create_descriptor_set (GstVulkanImageIdentity * vk_identity)
-{
-  GstVulkanFullScreenRender *render =
-      GST_VULKAN_FULL_SCREEN_RENDER (vk_identity);
-
-  /* *INDENT-OFF* */
-  VkDescriptorSetAllocateInfo alloc_info = {
-      .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
-      .pNext = NULL,
-      .descriptorPool = vk_identity->descriptor_pool,
-      .descriptorSetCount = 1,
-      .pSetLayouts = &render->descriptor_set_layout
-  };
-  /* *INDENT-ON* */
-  VkDescriptorSet descriptor;
-  GError *error = NULL;
-  VkResult err;
-
-  err =
-      vkAllocateDescriptorSets (render->device->device, &alloc_info,
-      &descriptor);
-  if (gst_vulkan_error_to_g_error (err, &error, "vkAllocateDescriptorSets") < 0) {
-    GST_ERROR_OBJECT (vk_identity, "Failed to allocate descriptor: %s",
-        error->message);
-    g_clear_error (&error);
-    return VK_NULL_HANDLE;
-  }
+  ret = gst_vulkan_descriptor_pool_new_wrapped (render->device, pool, max_sets);
+  cache =
+      gst_vulkan_descriptor_cache_new (ret, 1, &render->descriptor_set_layout);
+  gst_object_unref (ret);
 
-  return descriptor;
+  return cache;
 }
 
 static gboolean
@@ -361,18 +337,16 @@ gst_vulkan_image_identity_set_caps (GstBaseTransform * bt, GstCaps * in_caps,
   else
     last_fence = gst_vulkan_fence_new_always_signalled (render->device);
 
-  gst_vulkan_trash_list_add (render->trash_list,
-      gst_vulkan_trash_new_free_descriptor_pool (gst_vulkan_fence_ref
-          (last_fence), vk_identity->descriptor_pool));
-  vk_identity->descriptor_set = VK_NULL_HANDLE;
-  vk_identity->descriptor_pool = VK_NULL_HANDLE;
+  if (vk_identity->descriptor_pool)
+    gst_vulkan_trash_list_add (render->trash_list,
+        gst_vulkan_trash_new_object_unref (gst_vulkan_fence_ref
+            (last_fence), (GstObject *) vk_identity->descriptor_pool));
+  vk_identity->descriptor_pool = NULL;
 
   gst_vulkan_fence_unref (last_fence);
 
   if (!(vk_identity->descriptor_pool = _create_descriptor_pool (vk_identity)))
     return FALSE;
-  if (!(vk_identity->descriptor_set = _create_descriptor_set (vk_identity)))
-    return FALSE;
 
   return TRUE;
 }
@@ -446,15 +420,13 @@ gst_vulkan_image_identity_stop (GstBaseTransform * bt)
     else
       last_fence = gst_vulkan_fence_new_always_signalled (render->device);
 
-    if (vk_identity->descriptor_pool)
-      gst_vulkan_trash_list_add (render->trash_list,
-          gst_vulkan_trash_new_free_descriptor_pool (gst_vulkan_fence_ref
-              (render->last_fence), vk_identity->descriptor_pool));
-    vk_identity->descriptor_pool = VK_NULL_HANDLE;
-    if (vk_identity->sampler)
-      gst_vulkan_trash_list_add (render->trash_list,
-          gst_vulkan_trash_new_free_sampler (gst_vulkan_fence_ref
-              (render->last_fence), vk_identity->sampler));
+    gst_vulkan_trash_list_add (render->trash_list,
+        gst_vulkan_trash_new_object_unref (gst_vulkan_fence_ref
+            (last_fence), (GstObject *) vk_identity->descriptor_pool));
+    vk_identity->descriptor_pool = NULL;
+    gst_vulkan_trash_list_add (render->trash_list,
+        gst_vulkan_trash_new_free_sampler (gst_vulkan_fence_ref
+            (last_fence), vk_identity->sampler));
     vk_identity->sampler = VK_NULL_HANDLE;
 
     gst_vulkan_fence_unref (last_fence);
@@ -468,7 +440,8 @@ gst_vulkan_image_identity_stop (GstBaseTransform * bt)
 }
 
 static void
-update_descriptor_set (GstVulkanImageIdentity * vk_identity, VkImageView view)
+update_descriptor_set (GstVulkanImageIdentity * vk_identity,
+    VkDescriptorSet set, VkImageView view)
 {
   GstVulkanFullScreenRender *render =
       GST_VULKAN_FULL_SCREEN_RENDER (vk_identity);
@@ -483,7 +456,7 @@ update_descriptor_set (GstVulkanImageIdentity * vk_identity, VkImageView view)
   VkWriteDescriptorSet writes = {
       .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
       .pNext = NULL,
-      .dstSet = vk_identity->descriptor_set,
+      .dstSet = set,
       .dstBinding = 0,
       .dstArrayElement = 0,
       .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
@@ -541,6 +514,7 @@ gst_vulkan_image_identity_transform (GstBaseTransform * bt, GstBuffer * inbuf,
   GstVulkanImageMemory *in_img_mem, *out_img_mem;
   GstVulkanImageView *in_img_view, *out_img_view;
   GstVulkanFence *fence = NULL;
+  GstVulkanDescriptorSet *set;
   GstMemory *in_mem, *out_mem;
   VkFramebuffer framebuffer;
   GstVulkanCommandBuffer *cmd_buf;
@@ -579,8 +553,12 @@ gst_vulkan_image_identity_transform (GstBaseTransform * bt, GstBuffer * inbuf,
     if (!(vk_identity->cmd_pool =
             gst_vulkan_queue_create_command_pool (render->queue, &error)))
       goto error;
-    update_descriptor_set (vk_identity, in_img_view->view);
   }
+  if (!(set =
+          gst_vulkan_descriptor_cache_acquire (vk_identity->descriptor_pool,
+              &error)))
+    goto error;
+  update_descriptor_set (vk_identity, set->set, in_img_view->view);
 
   if (!(cmd_buf =
           gst_vulkan_command_pool_create (vk_identity->cmd_pool, &error)))
@@ -666,7 +644,7 @@ gst_vulkan_image_identity_transform (GstBaseTransform * bt, GstBuffer * inbuf,
   }
 
   vkCmdBindDescriptorSets (cmd_buf->cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
-      render->pipeline_layout, 0, 1, &vk_identity->descriptor_set, 0, NULL);
+      render->pipeline_layout, 0, 1, &set->set, 0, NULL);
   if (!gst_vulkan_full_screen_render_fill_command_buffer (render, cmd_buf->cmd,
           framebuffer))
     goto unlock_error;
@@ -677,6 +655,9 @@ gst_vulkan_image_identity_transform (GstBaseTransform * bt, GstBuffer * inbuf,
     goto error;
 
   gst_vulkan_trash_list_add (render->trash_list,
+      gst_vulkan_trash_new_mini_object_unref (gst_vulkan_fence_ref (fence),
+          GST_MINI_OBJECT_CAST (set)));
+  gst_vulkan_trash_list_add (render->trash_list,
       gst_vulkan_trash_new_free_framebuffer (gst_vulkan_fence_ref (fence),
           framebuffer));
   gst_vulkan_trash_list_add (render->trash_list,
index 2856ae4..5ab1de4 100644 (file)
@@ -44,8 +44,7 @@ struct _GstVulkanImageIdentity
   GstVulkanCommandPool             *cmd_pool;
 
   VkSampler                         sampler;
-  VkDescriptorPool                  descriptor_pool;
-  VkDescriptorSet                   descriptor_set;
+  GstVulkanDescriptorCache         *descriptor_pool;
 
   VkDescriptorSetLayoutBinding      sampler_layout_binding;
   VkDescriptorSetLayoutCreateInfo   layout_info;
index 37efda3..cd1d64e 100644 (file)
@@ -292,8 +292,8 @@ calculate_reorder_indexes (GstVideoFormat in_format,
 }
 
 static void
-update_descriptor_set (GstVulkanViewConvert * conv, VkImageView * views,
-    guint n_views)
+update_descriptor_set (GstVulkanViewConvert * conv,
+    VkDescriptorSet descriptor_set, VkImageView * views, guint n_views)
 {
   GstVulkanFullScreenRender *render = GST_VULKAN_FULL_SCREEN_RENDER (conv);
   VkDescriptorBufferInfo buffer_info;
@@ -315,7 +315,7 @@ update_descriptor_set (GstVulkanViewConvert * conv, VkImageView * views,
     writes[i] = (VkWriteDescriptorSet) {
         .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
         .pNext = NULL,
-        .dstSet = conv->descriptor_set,
+        .dstSet = descriptor_set,
         .dstBinding = i,
         .dstArrayElement = 0,
         .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
@@ -333,7 +333,7 @@ update_descriptor_set (GstVulkanViewConvert * conv, VkImageView * views,
   writes[i] = (VkWriteDescriptorSet) {
       .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
       .pNext = NULL,
-      .dstSet = conv->descriptor_set,
+      .dstSet = descriptor_set,
       .dstBinding = i,
       .dstArrayElement = 0,
       .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
@@ -487,12 +487,31 @@ _update_uniform (GstVulkanViewConvert * conv, GstVulkanImageView ** in_views,
   return TRUE;
 }
 
+static GstVulkanDescriptorSet *
+_create_descriptor_set (GstVulkanViewConvert * conv)
+{
+  GstVulkanFullScreenRender *render = GST_VULKAN_FULL_SCREEN_RENDER (conv);
+  GstVulkanDescriptorSet *ret;
+  GError *error = NULL;
+
+  ret = gst_vulkan_descriptor_cache_acquire (conv->descriptor_pool, &error);
+  if (!ret) {
+    GST_ERROR_OBJECT (render, "Failed to create framebuffer: %s",
+        error->message);
+    g_clear_error (&error);
+    return NULL;
+  }
+
+  return ret;
+}
+
 static gboolean
 view_convert_update_command_state (GstVulkanViewConvert * conv,
     VkCommandBuffer cmd, GstVulkanImageView ** in_views,
-    GstVulkanImageView ** out_views)
+    GstVulkanImageView ** out_views, GstVulkanFence * fence)
 {
   GstVulkanFullScreenRender *render = GST_VULKAN_FULL_SCREEN_RENDER (conv);
+  GstVulkanDescriptorSet *set;
   VkImageView views[GST_VIDEO_MAX_PLANES];
   int i;
 
@@ -504,12 +523,17 @@ view_convert_update_command_state (GstVulkanViewConvert * conv,
   if (!conv->descriptor_up_to_date) {
     if (!_update_uniform (conv, in_views, out_views, views))
       return FALSE;
-    update_descriptor_set (conv, views,
-        GST_VIDEO_INFO_N_PLANES (&render->in_info) * 2);
   }
+  set = _create_descriptor_set (conv);
+  update_descriptor_set (conv, set->set, views,
+      GST_VIDEO_INFO_N_PLANES (&render->in_info) * 2);
 
   vkCmdBindDescriptorSets (cmd, VK_PIPELINE_BIND_POINT_GRAPHICS,
-      render->pipeline_layout, 0, 1, &conv->descriptor_set, 0, NULL);
+      render->pipeline_layout, 0, 1, &set->set, 0, NULL);
+
+  gst_vulkan_trash_list_add (render->trash_list,
+      gst_vulkan_trash_new_mini_object_unref (gst_vulkan_fence_ref
+          (fence), (GstMiniObject *) set));
 
   return TRUE;
 }
@@ -2012,20 +2036,21 @@ gst_vulkan_view_convert_start (GstBaseTransform * bt)
   return TRUE;
 }
 
-static VkDescriptorPool
+static GstVulkanDescriptorCache *
 _create_descriptor_pool (GstVulkanViewConvert * conv)
 {
   GstVulkanFullScreenRender *render = GST_VULKAN_FULL_SCREEN_RENDER (conv);
+  guint max_sets = 32;          /* FIXME: don't hardcode this! */
 
   /* *INDENT-OFF* */
   VkDescriptorPoolSize pool_sizes[] = {
       {
           .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
-          .descriptorCount = GST_VIDEO_INFO_N_PLANES (&render->in_info) * 2,
+          .descriptorCount = max_sets * GST_VIDEO_INFO_N_PLANES (&render->in_info) * 2,
       },
       {
           .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
-          .descriptorCount = 1
+          .descriptorCount = max_sets
       },
   };
 
@@ -2034,10 +2059,12 @@ _create_descriptor_pool (GstVulkanViewConvert * conv)
       .pNext = NULL,
       .poolSizeCount = G_N_ELEMENTS (pool_sizes),
       .pPoolSizes = pool_sizes,
-      .maxSets = 1
+      .maxSets = max_sets
   };
   /* *INDENT-ON* */
   VkDescriptorPool pool;
+  GstVulkanDescriptorPool *ret;
+  GstVulkanDescriptorCache *cache;
   GError *error = NULL;
   VkResult err;
 
@@ -2050,38 +2077,12 @@ _create_descriptor_pool (GstVulkanViewConvert * conv)
     return VK_NULL_HANDLE;
   }
 
-  return pool;
-}
-
-static VkDescriptorSet
-_create_descriptor_set (GstVulkanViewConvert * conv)
-{
-  GstVulkanFullScreenRender *render = GST_VULKAN_FULL_SCREEN_RENDER (conv);
+  ret = gst_vulkan_descriptor_pool_new_wrapped (render->device, pool, 32);
+  cache =
+      gst_vulkan_descriptor_cache_new (ret, 1, &render->descriptor_set_layout);
+  gst_object_unref (ret);
 
-  /* *INDENT-OFF* */
-  VkDescriptorSetAllocateInfo alloc_info = {
-      .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
-      .pNext = NULL,
-      .descriptorPool = conv->descriptor_pool,
-      .descriptorSetCount = 1,
-      .pSetLayouts = &render->descriptor_set_layout
-  };
-  /* *INDENT-ON* */
-  VkDescriptorSet descriptor;
-  GError *error = NULL;
-  VkResult err;
-
-  err =
-      vkAllocateDescriptorSets (render->device->device, &alloc_info,
-      &descriptor);
-  if (gst_vulkan_error_to_g_error (err, &error, "vkAllocateDescriptorSets") < 0) {
-    GST_ERROR_OBJECT (conv, "Failed to allocate descriptor: %s",
-        error->message);
-    g_clear_error (&error);
-    return VK_NULL_HANDLE;
-  }
-
-  return descriptor;
+  return cache;
 }
 
 static gboolean
@@ -2114,10 +2115,9 @@ gst_vulkan_view_convert_set_caps (GstBaseTransform * bt, GstCaps * in_caps,
 
   if (conv->descriptor_pool)
     gst_vulkan_trash_list_add (render->trash_list,
-        gst_vulkan_trash_new_free_descriptor_pool (gst_vulkan_fence_ref
-            (last_fence), conv->descriptor_pool));
-  conv->descriptor_set = VK_NULL_HANDLE;
-  conv->descriptor_pool = VK_NULL_HANDLE;
+        gst_vulkan_trash_new_object_unref (gst_vulkan_fence_ref
+            (last_fence), (GstObject *) conv->descriptor_pool));
+  conv->descriptor_pool = NULL;
   if (conv->uniform)
     gst_vulkan_trash_list_add (render->trash_list,
         gst_vulkan_trash_new_mini_object_unref (gst_vulkan_fence_ref
@@ -2132,8 +2132,6 @@ gst_vulkan_view_convert_set_caps (GstBaseTransform * bt, GstCaps * in_caps,
 
   if (!(conv->descriptor_pool = _create_descriptor_pool (conv)))
     return FALSE;
-  if (!(conv->descriptor_set = _create_descriptor_set (conv)))
-    return FALSE;
 
   if (!_create_uniform_buffer (conv))
     return FALSE;
@@ -2159,10 +2157,9 @@ gst_vulkan_view_convert_stop (GstBaseTransform * bt)
 
     if (conv->descriptor_pool)
       gst_vulkan_trash_list_add (render->trash_list,
-          gst_vulkan_trash_new_free_descriptor_pool (gst_vulkan_fence_ref
-              (last_fence), conv->descriptor_pool));
-    conv->descriptor_set = VK_NULL_HANDLE;
-    conv->descriptor_pool = VK_NULL_HANDLE;
+          gst_vulkan_trash_new_object_unref (gst_vulkan_fence_ref
+              (last_fence), (GstObject *) conv->descriptor_pool));
+    conv->descriptor_pool = NULL;
     if (conv->sampler)
       gst_vulkan_trash_list_add (render->trash_list,
           gst_vulkan_trash_new_free_sampler (gst_vulkan_fence_ref
@@ -2370,7 +2367,7 @@ gst_vulkan_view_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf,
   }
 
   view_convert_update_command_state (conv, cmd_buf->cmd, in_img_views,
-      out_img_views);
+      out_img_views, fence);
 
   if (!gst_vulkan_full_screen_render_fill_command_buffer (render, cmd_buf->cmd,
           framebuffer)) {
index 370d89d..d95808c 100644 (file)
@@ -51,8 +51,7 @@ struct _GstVulkanViewConvert
   GstVulkanCommandPool             *cmd_pool;
 
   VkSampler                         sampler;
-  VkDescriptorPool                  descriptor_pool;
-  VkDescriptorSet                   descriptor_set;
+  GstVulkanDescriptorCache         *descriptor_pool;
 
   VkShaderModule                    vert_module;
   VkShaderModule                    frag_module;
diff --git a/gst-libs/gst/vulkan/gstvkdescriptorcache-private.h b/gst-libs/gst/vulkan/gstvkdescriptorcache-private.h
new file mode 100644 (file)
index 0000000..9c0d50b
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * GStreamer
+ * Copyright (C) 2019 Matthew Waters <matthew@centricular.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_VULKAN_DESCRIPTOR_CACHE_PRIVATE_H__
+#define __GST_VULKAN_DESCRIPTOR_CACHE_PRIVATE_H__
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+void        gst_vulkan_descriptor_cache_release_set     (GstVulkanDescriptorCache * cache,
+                                                         GstVulkanDescriptorSet * set);
+
+G_END_DECLS
+
+#endif /* __GST_VULKAN_COMMAND_POOL_PRIVATE_H__ */
diff --git a/gst-libs/gst/vulkan/gstvkdescriptorcache.c b/gst-libs/gst/vulkan/gstvkdescriptorcache.c
new file mode 100644 (file)
index 0000000..fe50556
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * GStreamer
+ * Copyright (C) 2019 Matthew Waters <matthew@centricular.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gstvkdescriptorcache.h"
+#include "gstvkdescriptorcache-private.h"
+
+/**
+ * SECTION:vkdescriptorcache
+ * @title: GstVulkanDescriptorCache
+ * @short_description: Vulkan descriptor cache
+ * @see_also: #GstVulkanDevice
+ */
+
+#define GET_PRIV(cache) G_TYPE_INSTANCE_GET_PRIVATE(cache, GST_TYPE_VULKAN_DESCRIPTOR_CACHE, GstVulkanDescriptorCachePrivate)
+
+#define GST_CAT_DEFAULT gst_vulkan_descriptor_cache_debug
+GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
+
+struct _GstVulkanDescriptorCachePrivate
+{
+  guint n_layouts;
+  GstVulkanHandle **layouts;
+
+  GQueue *available;
+  gsize outstanding;
+};
+
+#define parent_class gst_vulkan_descriptor_cache_parent_class
+G_DEFINE_TYPE_WITH_CODE (GstVulkanDescriptorCache, gst_vulkan_descriptor_cache,
+    GST_TYPE_OBJECT, G_ADD_PRIVATE (GstVulkanDescriptorCache);
+    GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT,
+        "vulkancommandcache", 0, "Vulkan Command Cache"));
+
+static void gst_vulkan_descriptor_cache_finalize (GObject * object);
+
+static void
+gst_vulkan_descriptor_cache_init (GstVulkanDescriptorCache * cache)
+{
+  GstVulkanDescriptorCachePrivate *priv = GET_PRIV (cache);
+
+  priv->available = g_queue_new ();
+}
+
+static void
+gst_vulkan_descriptor_cache_class_init (GstVulkanDescriptorCacheClass *
+    device_class)
+{
+  GObjectClass *gobject_class = (GObjectClass *) device_class;
+
+  gobject_class->finalize = gst_vulkan_descriptor_cache_finalize;
+}
+
+static void
+do_free_set (GstVulkanHandle * handle)
+{
+  gst_vulkan_handle_unref (handle);
+}
+
+static void
+gst_vulkan_descriptor_cache_finalize (GObject * object)
+{
+  GstVulkanDescriptorCache *cache = GST_VULKAN_DESCRIPTOR_CACHE (object);
+  GstVulkanDescriptorCachePrivate *priv = GET_PRIV (cache);
+  guint i;
+
+  if (priv->outstanding > 0)
+    g_critical
+        ("Destroying a Vulkan descriptor cache that has outstanding descriptors!");
+
+  for (i = 0; i < priv->n_layouts; i++)
+    gst_vulkan_handle_unref (priv->layouts[i]);
+  g_free (priv->layouts);
+
+  g_queue_free_full (priv->available, (GDestroyNotify) do_free_set);
+  priv->available = NULL;
+
+  gst_clear_object (&cache->pool);
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+/**
+ * gst_vulkan_descriptor_cache_new:
+ * @pool: a #GstVulkanDescriptorPool
+ * @n_layouts: number of @layouts
+ * @layouts: list of #GstVulkanHandle containing descriptor set layouts
+ *
+ * Returns: (transfer full): a new #GstVulkanDescriptorCache
+ *
+ * Since: 1.18
+ */
+GstVulkanDescriptorCache *
+gst_vulkan_descriptor_cache_new (GstVulkanDescriptorPool * pool,
+    guint n_layouts, GstVulkanHandle ** layouts)
+{
+  GstVulkanDescriptorCache *ret;
+  GstVulkanDescriptorCachePrivate *priv;
+  guint i;
+
+  g_return_val_if_fail (GST_IS_VULKAN_DESCRIPTOR_POOL (pool), NULL);
+
+  ret = g_object_new (GST_TYPE_VULKAN_DESCRIPTOR_CACHE, NULL);
+  ret->pool = gst_object_ref (pool);
+
+  priv = GET_PRIV (ret);
+  priv->n_layouts = n_layouts;
+  priv->layouts = g_new0 (GstVulkanHandle *, n_layouts);
+  for (i = 0; i < n_layouts; i++)
+    priv->layouts[i] = gst_vulkan_handle_ref (layouts[i]);
+
+  gst_object_ref_sink (ret);
+
+  return ret;
+}
+
+/**
+ * gst_vulkan_descriptor_cache_acquire:
+ * @cache: a #GstVulkanDescriptorCache
+ * @error: a #GError
+ *
+ * Returns: a new #GstVulkanDescriptorSet
+ *
+ * Since: 1.18
+ */
+GstVulkanDescriptorSet *
+gst_vulkan_descriptor_cache_acquire (GstVulkanDescriptorCache * cache,
+    GError ** error)
+{
+  GstVulkanDescriptorSet *set = NULL;
+  GstVulkanDescriptorCachePrivate *priv;
+
+  g_return_val_if_fail (GST_IS_VULKAN_DESCRIPTOR_CACHE (cache), NULL);
+
+  priv = GET_PRIV (cache);
+
+  GST_OBJECT_LOCK (cache);
+  set = g_queue_pop_head (priv->available);
+  GST_OBJECT_UNLOCK (cache);
+
+  if (!set)
+    set = gst_vulkan_descriptor_pool_create (cache->pool, priv->n_layouts,
+        priv->layouts, error);
+  if (!set)
+    return NULL;
+
+  GST_OBJECT_LOCK (cache);
+  priv->outstanding++;
+  GST_OBJECT_UNLOCK (cache);
+
+  set->cache = gst_object_ref (cache);
+  return set;
+}
+
+void
+gst_vulkan_descriptor_cache_release_set (GstVulkanDescriptorCache * cache,
+    GstVulkanDescriptorSet * set)
+{
+  GstVulkanDescriptorCachePrivate *priv;
+
+  g_return_if_fail (GST_IS_VULKAN_DESCRIPTOR_CACHE (cache));
+  g_return_if_fail (set != NULL);
+
+  priv = GET_PRIV (cache);
+
+  GST_OBJECT_LOCK (cache);
+  g_queue_push_tail (priv->available, set);
+  priv->outstanding--;
+  GST_OBJECT_UNLOCK (cache);
+
+  /* decrease the refcount that the set had to us */
+  gst_clear_object (&set->cache);
+}
diff --git a/gst-libs/gst/vulkan/gstvkdescriptorcache.h b/gst-libs/gst/vulkan/gstvkdescriptorcache.h
new file mode 100644 (file)
index 0000000..02d9a67
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * GStreamer
+ * Copyright (C) 2019 Matthew Waters <matthew@centricular.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_VULKAN_DESCRIPTOR_CACHE_H__
+#define __GST_VULKAN_DESCRIPTOR_CACHE_H__
+
+#include <gst/vulkan/gstvkqueue.h>
+
+#define GST_TYPE_VULKAN_DESCRIPTOR_CACHE         (gst_vulkan_descriptor_cache_get_type())
+#define GST_VULKAN_DESCRIPTOR_CACHE(o)           (G_TYPE_CHECK_INSTANCE_CAST((o), GST_TYPE_VULKAN_DESCRIPTOR_CACHE, GstVulkanDescriptorCache))
+#define GST_VULKAN_DESCRIPTOR_CACHE_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), GST_TYPE_VULKAN_DESCRIPTOR_CACHE, GstVulkanDescriptorCacheClass))
+#define GST_IS_VULKAN_DESCRIPTOR_CACHE(o)        (G_TYPE_CHECK_INSTANCE_TYPE((o), GST_TYPE_VULKAN_DESCRIPTOR_CACHE))
+#define GST_IS_VULKAN_DESCRIPTOR_CACHE_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE((k), GST_TYPE_VULKAN_DESCRIPTOR_CACHE))
+#define GST_VULKAN_DESCRIPTOR_CACHE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_TYPE_VULKAN_DESCRIPTOR_CACHE, GstVulkanDescriptorCacheClass))
+GST_VULKAN_API
+GType gst_vulkan_descriptor_cache_get_type       (void);
+
+struct _GstVulkanDescriptorCache
+{
+  GstObject                     parent;
+
+  GstVulkanDescriptorPool      *pool;
+};
+
+struct _GstVulkanDescriptorCacheClass
+{
+  GstObjectClass parent_class;
+};
+
+GST_VULKAN_API
+GstVulkanDescriptorCache *   gst_vulkan_descriptor_cache_new            (GstVulkanDescriptorPool * pool,
+                                                                         guint n_layouts,
+                                                                         GstVulkanHandle ** layouts);
+
+GST_VULKAN_API
+GstVulkanDescriptorSet *    gst_vulkan_descriptor_cache_acquire         (GstVulkanDescriptorCache * cache,
+                                                                         GError ** error);
+
+#endif /* __GST_VULKAN_DESCRIPTOR_CACHE_H__ */
diff --git a/gst-libs/gst/vulkan/gstvkdescriptorpool.c b/gst-libs/gst/vulkan/gstvkdescriptorpool.c
new file mode 100644 (file)
index 0000000..1964bd5
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * GStreamer
+ * Copyright (C) 2019 Matthew Waters <matthew@centricular.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gstvkdescriptorpool.h"
+
+/**
+ * SECTION:vkdescriptorpool
+ * @title: GstVulkanDescriptorPool
+ * @short_description: Vulkan descriptor pool
+ * @see_also: #GstVulkanDevice
+ */
+
+#define GET_PRIV(pool) G_TYPE_INSTANCE_GET_PRIVATE(pool, GST_TYPE_VULKAN_DESCRIPTOR_POOL, GstVulkanDescriptorPoolPrivate)
+
+#define GST_CAT_DEFAULT gst_vulkan_descriptor_pool_debug
+GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
+
+struct _GstVulkanDescriptorPoolPrivate
+{
+  gsize max_sets;
+  gsize outstanding;
+};
+
+#define parent_class gst_vulkan_descriptor_pool_parent_class
+G_DEFINE_TYPE_WITH_CODE (GstVulkanDescriptorPool, gst_vulkan_descriptor_pool,
+    GST_TYPE_OBJECT, G_ADD_PRIVATE (GstVulkanDescriptorPool);
+    GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT,
+        "vulkancommandpool", 0, "Vulkan Command Pool"));
+
+static void gst_vulkan_descriptor_pool_finalize (GObject * object);
+
+static void
+gst_vulkan_descriptor_pool_init (GstVulkanDescriptorPool * pool)
+{
+}
+
+static void
+gst_vulkan_descriptor_pool_class_init (GstVulkanDescriptorPoolClass *
+    device_class)
+{
+  GObjectClass *gobject_class = (GObjectClass *) device_class;
+
+  gobject_class->finalize = gst_vulkan_descriptor_pool_finalize;
+}
+
+static void
+gst_vulkan_descriptor_pool_finalize (GObject * object)
+{
+  GstVulkanDescriptorPool *pool = GST_VULKAN_DESCRIPTOR_POOL (object);
+  GstVulkanDescriptorPoolPrivate *priv = GET_PRIV (pool);
+
+#if 0
+  /* FIXME: track these correctly */
+  if (priv->outstanding > 0)
+    g_critical
+        ("Destroying a Vulkan descriptor pool that has outstanding descriptors!");
+#endif
+
+  if (pool->pool)
+    vkDestroyDescriptorPool (pool->device->device, pool->pool, NULL);
+  pool->pool = VK_NULL_HANDLE;
+
+  gst_clear_object (&pool->device);
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+/**
+ * gst_vulkan_descriptor_pool_new_wrapped:
+ * @device: a #GstVulkanDevice
+ * @pool: (transfer full): a #VkDescriptorPool
+ *
+ * Returns: (transfer full): a new #GstVulkanDescriptorPool
+ *
+ * Since: 1.18
+ */
+GstVulkanDescriptorPool *
+gst_vulkan_descriptor_pool_new_wrapped (GstVulkanDevice * device,
+    VkDescriptorPool pool, gsize max_sets)
+{
+  GstVulkanDescriptorPool *ret;
+  GstVulkanDescriptorPoolPrivate *priv;
+
+  g_return_val_if_fail (GST_IS_VULKAN_DEVICE (device), NULL);
+  g_return_val_if_fail (pool != VK_NULL_HANDLE, NULL);
+  g_return_val_if_fail (max_sets > 0, NULL);
+
+  ret = g_object_new (GST_TYPE_VULKAN_DESCRIPTOR_POOL, NULL);
+  ret->device = gst_object_ref (device);
+  ret->pool = pool;
+
+  priv = GET_PRIV (ret);
+  priv->max_sets = max_sets;
+
+  gst_object_ref_sink (ret);
+
+  return ret;
+}
+
+/**
+ * gst_vulkan_descriptor_pool_get_device
+ * @pool: a #GstVulkanDescriptorPool
+ *
+ * Returns: (transfer full): the parent #GstVulkanDevice for this descriptor pool
+ *
+ * Since: 1.18
+ */
+GstVulkanDevice *
+gst_vulkan_descriptor_pool_get_device (GstVulkanDescriptorPool * pool)
+{
+  g_return_val_if_fail (GST_IS_VULKAN_DESCRIPTOR_POOL (pool), NULL);
+
+  return pool->device ? gst_object_ref (pool->device) : NULL;
+}
+
+/**
+ * gst_vulkan_descriptor_pool_get_max_sets:
+ * @pool: a #GstVulkanDescriptorPool
+ *
+ * Returns: the maximum number of sets allocatable from @pool
+ */
+gsize
+gst_vulkan_descriptor_pool_get_max_sets (GstVulkanDescriptorPool * pool)
+{
+  GstVulkanDescriptorPoolPrivate *priv;
+
+  g_return_val_if_fail (GST_IS_VULKAN_DESCRIPTOR_POOL (pool), 0);
+
+  priv = GET_PRIV (pool);
+
+  return priv->max_sets;
+}
+
+static GstVulkanDescriptorSet *
+descriptor_set_alloc (GstVulkanDescriptorPool * pool, guint n_layouts,
+    GstVulkanHandle ** layouts, GError ** error)
+{
+  VkDescriptorSetLayout *vk_layouts;
+  VkDescriptorSetAllocateInfo alloc_info;
+  GstVulkanDescriptorSet *set;
+  VkDescriptorSet descriptor;
+  VkResult err;
+  guint i;
+
+  vk_layouts = g_alloca (n_layouts * sizeof (VkDescriptorSetLayout));
+  for (i = 0; i < n_layouts; i++)
+    vk_layouts[i] = (VkDescriptorSetLayout) layouts[i]->handle;
+
+  /* *INDENT-OFF* */
+  alloc_info = (VkDescriptorSetAllocateInfo) {
+      .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
+      .pNext = NULL,
+      .descriptorPool = pool->pool,
+      .descriptorSetCount = n_layouts,
+      .pSetLayouts = vk_layouts
+  };
+  /* *INDENT-ON* */
+
+  err =
+      vkAllocateDescriptorSets (pool->device->device, &alloc_info, &descriptor);
+  if (gst_vulkan_error_to_g_error (err, error, "vkAllocateDescriptorSets") < 0)
+    return NULL;
+
+  set =
+      gst_vulkan_descriptor_set_new_wrapped (pool, descriptor, n_layouts,
+      layouts);
+  GST_LOG_OBJECT (pool, "created descriptor set %p", set);
+
+  return set;
+}
+
+/**
+ * gst_vulkan_descriptor_pool_create:
+ * @pool: a #GstVulkanDescriptorPool
+ * @error: a #GError
+ *
+ * Returns: a new #GstVulkanDescriptorSet
+ *
+ * Since: 1.18
+ */
+GstVulkanDescriptorSet *
+gst_vulkan_descriptor_pool_create (GstVulkanDescriptorPool * pool,
+    guint n_layouts, GstVulkanHandle ** layouts, GError ** error)
+{
+  GstVulkanDescriptorSet *cmd = NULL;
+  GstVulkanDescriptorPoolPrivate *priv;
+
+  g_return_val_if_fail (GST_IS_VULKAN_DESCRIPTOR_POOL (pool), NULL);
+  g_return_val_if_fail (n_layouts > 0, NULL);
+  g_return_val_if_fail (layouts != NULL, NULL);
+
+  priv = GET_PRIV (pool);
+
+  GST_OBJECT_LOCK (pool);
+  priv->outstanding++;
+  if (priv->outstanding >= priv->max_sets) {
+    g_warning ("%s: Attempt was made to allocate more descriptor sets than are "
+        "available", GST_OBJECT_NAME (pool));
+    priv->outstanding--;
+    GST_OBJECT_UNLOCK (pool);
+    return NULL;
+  }
+  GST_OBJECT_UNLOCK (pool);
+
+  cmd = descriptor_set_alloc (pool, n_layouts, layouts, error);
+  if (!cmd)
+    return NULL;
+
+  return cmd;
+}
diff --git a/gst-libs/gst/vulkan/gstvkdescriptorpool.h b/gst-libs/gst/vulkan/gstvkdescriptorpool.h
new file mode 100644 (file)
index 0000000..b2e6840
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * GStreamer
+ * Copyright (C) 2019 Matthew Waters <matthew@centricular.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_VULKAN_DESCRIPTOR_POOL_H__
+#define __GST_VULKAN_DESCRIPTOR_POOL_H__
+
+#include <gst/vulkan/gstvkqueue.h>
+
+#define GST_TYPE_VULKAN_DESCRIPTOR_POOL         (gst_vulkan_descriptor_pool_get_type())
+#define GST_VULKAN_DESCRIPTOR_POOL(o)           (G_TYPE_CHECK_INSTANCE_CAST((o), GST_TYPE_VULKAN_DESCRIPTOR_POOL, GstVulkanDescriptorPool))
+#define GST_VULKAN_DESCRIPTOR_POOL_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), GST_TYPE_VULKAN_DESCRIPTOR_POOL, GstVulkanDescriptorPoolClass))
+#define GST_IS_VULKAN_DESCRIPTOR_POOL(o)        (G_TYPE_CHECK_INSTANCE_TYPE((o), GST_TYPE_VULKAN_DESCRIPTOR_POOL))
+#define GST_IS_VULKAN_DESCRIPTOR_POOL_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE((k), GST_TYPE_VULKAN_DESCRIPTOR_POOL))
+#define GST_VULKAN_DESCRIPTOR_POOL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), GST_TYPE_VULKAN_DESCRIPTOR_POOL, GstVulkanDescriptorPoolClass))
+GST_VULKAN_API
+GType gst_vulkan_descriptor_pool_get_type       (void);
+
+struct _GstVulkanDescriptorPool
+{
+  GstObject parent;
+
+  GstVulkanDevice *device;
+
+  VkDescriptorPool pool; /* hides a pointer */
+};
+
+struct _GstVulkanDescriptorPoolClass
+{
+  GstObjectClass parent_class;
+};
+
+GST_VULKAN_API
+GstVulkanDescriptorPool *   gst_vulkan_descriptor_pool_new_wrapped      (GstVulkanDevice * device,
+                                                                         VkDescriptorPool pool,
+                                                                         gsize max_sets);
+
+GST_VULKAN_API
+GstVulkanDevice *           gst_vulkan_descriptor_pool_get_device       (GstVulkanDescriptorPool * pool);
+
+GST_VULKAN_API
+GstVulkanDescriptorSet *    gst_vulkan_descriptor_pool_create           (GstVulkanDescriptorPool * pool,
+                                                                         guint n_layouts,
+                                                                         GstVulkanHandle **layouts,
+                                                                         GError ** error);
+GST_VULKAN_API
+gsize                       gst_vulkan_descriptor_pool_get_max_sets     (GstVulkanDescriptorPool * pool);
+
+#endif /* __GST_VULKAN_DESCRIPTOR_POOL_H__ */
diff --git a/gst-libs/gst/vulkan/gstvkdescriptorset.c b/gst-libs/gst/vulkan/gstvkdescriptorset.c
new file mode 100644 (file)
index 0000000..a2adacc
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * GStreamer
+ * Copyright (C) 2019 Matthew Waters <matthew@centricular.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * SECTION:vulkandescriptorset
+ * @title: vulkandescriptorset
+ *
+ * vulkandescriptorset holds information about a descriptor set.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "gstvkdescriptorset.h"
+#include "gstvkdescriptorpool.h"
+#include "gstvkdescriptorcache.h"
+#include "gstvkdescriptorcache-private.h"
+
+#define GST_CAT_DEFAULT gst_debug_vulkan_descriptor_set
+GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
+
+static void
+init_debug (void)
+{
+  static volatile gsize _init = 0;
+
+  if (g_once_init_enter (&_init)) {
+    GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "vulkandescriptorset", 0,
+        "Vulkan descriptor set");
+    g_once_init_leave (&_init, 1);
+  }
+}
+
+static gboolean
+gst_vulkan_descriptor_set_dispose (GstVulkanDescriptorSet * set)
+{
+  GstVulkanDescriptorCache *cache;
+
+  /* no pool, do free */
+  if ((cache = set->cache) == NULL)
+    return TRUE;
+
+  /* keep the buffer alive */
+  gst_vulkan_descriptor_set_ref (set);
+  /* return the buffer to the pool */
+  gst_vulkan_descriptor_cache_release_set (cache, set);
+
+  return FALSE;
+}
+
+static void
+gst_vulkan_descriptor_set_free (GstVulkanDescriptorSet * set)
+{
+  guint i;
+
+  g_assert (set->cache == NULL);
+
+  GST_TRACE ("Freeing %p", set);
+
+  for (i = 0; i < set->n_layouts; i++)
+    gst_vulkan_handle_unref (set->layouts[i]);
+  g_free (set->layouts);
+
+  vkFreeDescriptorSets (set->pool->device->device, set->pool->pool, 1,
+      &set->set);
+
+  gst_clear_object (&set->pool);
+
+  g_free (set);
+}
+
+static void
+gst_vulkan_descriptor_set_init (GstVulkanDescriptorSet * set,
+    GstVulkanDescriptorPool * pool, VkDescriptorSet desc_set, guint n_layouts,
+    GstVulkanHandle ** layouts)
+{
+  guint i;
+
+  set->pool = gst_object_ref (pool);
+  set->set = desc_set;
+  set->n_layouts = n_layouts;
+  set->layouts = g_new0 (GstVulkanHandle *, n_layouts);
+  for (i = 0; i < n_layouts; i++)
+    set->layouts[i] = gst_vulkan_handle_ref (layouts[i]);
+
+  init_debug ();
+
+  GST_TRACE ("new %p", set);
+
+  gst_mini_object_init (&set->parent, 0, GST_TYPE_VULKAN_DESCRIPTOR_SET,
+      NULL, (GstMiniObjectDisposeFunction) gst_vulkan_descriptor_set_dispose,
+      (GstMiniObjectFreeFunction) gst_vulkan_descriptor_set_free);
+}
+
+/**
+ * gst_vulkan_descriptor_set_new_wrapped:
+ * @set: a VkDescriptorSet
+ *
+ * Returns: (transfer full): a new #GstVulkanDescriptorSet
+ */
+GstVulkanDescriptorSet *
+gst_vulkan_descriptor_set_new_wrapped (GstVulkanDescriptorPool * pool,
+    VkDescriptorSet set, guint n_layouts, GstVulkanHandle ** layouts)
+{
+  GstVulkanDescriptorSet *ret;
+
+  g_return_val_if_fail (GST_IS_VULKAN_DESCRIPTOR_POOL (pool), NULL);
+  g_return_val_if_fail (set != VK_NULL_HANDLE, NULL);
+  g_return_val_if_fail (n_layouts > 0, NULL);
+  g_return_val_if_fail (layouts != NULL, NULL);
+
+  ret = g_new0 (GstVulkanDescriptorSet, 1);
+  gst_vulkan_descriptor_set_init (ret, pool, set, n_layouts, layouts);
+
+  return ret;
+}
+
+GST_DEFINE_MINI_OBJECT_TYPE (GstVulkanDescriptorSet, gst_vulkan_descriptor_set);
diff --git a/gst-libs/gst/vulkan/gstvkdescriptorset.h b/gst-libs/gst/vulkan/gstvkdescriptorset.h
new file mode 100644 (file)
index 0000000..8f10f00
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * GStreamer
+ * Copyright (C) 2019 Matthew Waters <matthew@centricular.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_VULKAN_DESCRIPTOR_SET_H__
+#define __GST_VULKAN_DESCRIPTOR_SET_H__
+
+#include <gst/gst.h>
+
+#include <gst/vulkan/vulkan_fwd.h>
+#include <gst/vulkan/gstvkapi.h>
+
+G_BEGIN_DECLS
+
+GST_VULKAN_API
+GType gst_vulkan_descriptor_set_get_type (void);
+#define GST_TYPE_VULKAN_DESCRIPTOR_SET (gst_vulkan_descriptor_set_get_type ())
+
+typedef struct _GstVulkanDescriptorSet GstVulkanDescriptorSet;
+
+struct _GstVulkanDescriptorSet
+{
+  GstMiniObject             parent;
+
+  VkDescriptorSet           set;
+
+  /* <protected> */
+  GstVulkanDescriptorPool  *pool;
+  GstVulkanDescriptorCache *cache;
+
+  guint                     n_layouts;
+  GstVulkanHandle         **layouts;
+
+  GMutex                    lock;
+};
+
+/**
+ * gst_vulkan_descriptor_set_ref: (skip)
+ * @set: a #GstVulkanDescriptorSet.
+ *
+ * Increases the refcount of the given buffer by one.
+ *
+ * Returns: (transfer full): @buf
+ */
+static inline GstVulkanDescriptorSet* gst_vulkan_descriptor_set_ref(GstVulkanDescriptorSet* set);
+static inline GstVulkanDescriptorSet *
+gst_vulkan_descriptor_set_ref (GstVulkanDescriptorSet * set)
+{
+  return (GstVulkanDescriptorSet *) gst_mini_object_ref (GST_MINI_OBJECT_CAST (set));
+}
+
+/**
+ * gst_vulkan_descriptor_set_unref: (skip)
+ * @set: (transfer full): a #GstVulkanDescriptorSet.
+ *
+ * Decreases the refcount of the buffer. If the refcount reaches 0, the buffer
+ * will be freed.
+ */
+static inline void gst_vulkan_descriptor_set_unref(GstVulkanDescriptorSet* set);
+static inline void
+gst_vulkan_descriptor_set_unref (GstVulkanDescriptorSet * set)
+{
+  gst_mini_object_unref (GST_MINI_OBJECT_CAST (set));
+}
+
+/**
+ * gst_clear_vulkan_descriptor_set: (skip)
+ * @set_ptr: a pointer to a #GstVulkanDescriptorSet reference
+ *
+ * Clears a reference to a #GstVulkanDescriptorSet.
+ *
+ * @buf_ptr must not be %NULL.
+ *
+ * If the reference is %NULL then this function does nothing. Otherwise, the
+ * reference count of the descriptor set is decreased and the pointer is set
+ * to %NULL.
+ *
+ * Since: 1.16
+ */
+static inline void
+gst_clear_vulkan_descriptor_set (GstVulkanDescriptorSet ** set_ptr)
+{
+  gst_clear_mini_object ((GstMiniObject **) set_ptr);
+}
+
+#define gst_vulkan_descriptor_set_lock(set) g_mutex_lock (&((set)->lock))
+#define gst_vulkan_descriptor_set_unlock(set) g_mutex_unlock (&((set)->lock))
+
+GST_VULKAN_API
+GstVulkanDescriptorSet *    gst_vulkan_descriptor_set_new_wrapped       (GstVulkanDescriptorPool * pool,
+                                                                         VkDescriptorSet set,
+                                                                         guint n_layouts,
+                                                                         GstVulkanHandle ** layouts);
+
+G_END_DECLS
+
+#endif /* _GST_VULKAN_DESCRIPTOR_SET_H_ */
index 22906b4..ca6809d 100644 (file)
@@ -8,6 +8,9 @@ vulkan_sources = [
   'gstvkbufferpool.c',
   'gstvkcommandbuffer.c',
   'gstvkcommandpool.c',
+  'gstvkdescriptorcache.c',
+  'gstvkdescriptorset.c',
+  'gstvkdescriptorpool.c',
   'gstvkdevice.c',
   'gstvkdebug.c',
   'gstvkdisplay.c',
@@ -35,6 +38,9 @@ vulkan_headers = [
   'gstvkbufferpool.h',
   'gstvkcommandbuffer.h',
   'gstvkcommandpool.h',
+  'gstvkdescriptorcache.h',
+  'gstvkdescriptorset.h',
+  'gstvkdescriptorpool.h',
   'gstvkdebug.h',
   'gstvkdevice.h',
   'gstvkdisplay.h',
index 30fec89..d123714 100644 (file)
@@ -45,6 +45,9 @@
 #include <gst/vulkan/gstvkutils.h>
 #include <gst/vulkan/gstvkcommandbuffer.h>
 #include <gst/vulkan/gstvkcommandpool.h>
+#include <gst/vulkan/gstvkdescriptorcache.h>
+#include <gst/vulkan/gstvkdescriptorset.h>
+#include <gst/vulkan/gstvkdescriptorpool.h>
 #include <gst/vulkan/gstvkhandle.h>
 #include <gst/vulkan/gstvktrash.h>
 #include <gst/vulkan/gstvkswapper.h>
index e4926bf..9e94a44 100644 (file)
@@ -46,6 +46,18 @@ typedef struct _GstVulkanCommandPoolPrivate GstVulkanCommandPoolPrivate;
 
 typedef struct _GstVulkanCommandBuffer GstVulkanCommandBuffer;
 
+typedef struct _GstVulkanDescriptorSet GstVulkanDescriptorSet;
+typedef struct _GstVulkanDescriptorSetClass GstVulkanDescriptorSetClass;
+typedef struct _GstVulkanDescriptorSetPrivate GstVulkanDescriptorSetPrivate;
+
+typedef struct _GstVulkanDescriptorPool GstVulkanDescriptorPool;
+typedef struct _GstVulkanDescriptorPoolClass GstVulkanDescriptorPoolClass;
+typedef struct _GstVulkanDescriptorPoolPrivate GstVulkanDescriptorPoolPrivate;
+
+typedef struct _GstVulkanDescriptorCache GstVulkanDescriptorCache;
+typedef struct _GstVulkanDescriptorCacheClass GstVulkanDescriptorCacheClass;
+typedef struct _GstVulkanDescriptorCachePrivate GstVulkanDescriptorCachePrivate;
+
 typedef struct _GstVulkanDisplay GstVulkanDisplay;
 typedef struct _GstVulkanDisplayClass GstVulkanDisplayClass;
 typedef struct _GstVulkanDisplayPrivate GstVulkanDisplayPrivate;