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) { \
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;
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,
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,
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),
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;
}
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),
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;
}
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;
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
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))
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
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;
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
}
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,
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
{
GstVulkanCommandPool *cmd_pool;
VkSampler sampler;
- VkDescriptorPool descriptor_pool;
- VkDescriptorSet descriptor_set;
+ GstVulkanDescriptorCache *descriptor_pool;
VkShaderModule vert_module;
VkShaderModule frag_module;
.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,
};
return render_pass;
}
-static VkDescriptorSetLayout
+static GstVulkanHandle *
_create_descriptor_set_layout (GstVulkanFullScreenRender * render)
{
GstVulkanFullScreenRenderClass *render_class =
};
/* *INDENT-ON* */
VkDescriptorSetLayout descriptor_set_layout;
+ GstVulkanHandle *ret;
VkResult err;
GError *error = NULL;
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
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,
(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);
VkRenderPass render_pass;
VkPipelineLayout pipeline_layout;
VkPipeline graphics_pipeline;
- VkDescriptorSetLayout descriptor_set_layout;
+ GstVulkanHandle *descriptor_set_layout;
GstMemory *vertices;
GstMemory *indices;
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 = {
.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;
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
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;
}
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);
}
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);
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,
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;
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)))
}
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;
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,
GstVulkanCommandPool *cmd_pool;
VkSampler sampler;
- VkDescriptorPool descriptor_pool;
- VkDescriptorSet descriptor_set;
+ GstVulkanDescriptorCache *descriptor_pool;
VkDescriptorSetLayoutBinding sampler_layout_binding;
VkDescriptorSetLayoutCreateInfo layout_info;
}
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;
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,
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,
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;
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;
}
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
},
};
.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;
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
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
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;
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
}
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)) {
GstVulkanCommandPool *cmd_pool;
VkSampler sampler;
- VkDescriptorPool descriptor_pool;
- VkDescriptorSet descriptor_set;
+ GstVulkanDescriptorCache *descriptor_pool;
VkShaderModule vert_module;
VkShaderModule frag_module;
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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);
--- /dev/null
+/*
+ * 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_ */
'gstvkbufferpool.c',
'gstvkcommandbuffer.c',
'gstvkcommandpool.c',
+ 'gstvkdescriptorcache.c',
+ 'gstvkdescriptorset.c',
+ 'gstvkdescriptorpool.c',
'gstvkdevice.c',
'gstvkdebug.c',
'gstvkdisplay.c',
'gstvkbufferpool.h',
'gstvkcommandbuffer.h',
'gstvkcommandpool.h',
+ 'gstvkdescriptorcache.h',
+ 'gstvkdescriptorset.h',
+ 'gstvkdescriptorpool.h',
'gstvkdebug.h',
'gstvkdevice.h',
'gstvkdisplay.h',
#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>
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;