From 81d1e16b6bf8d802d58843ce6700c6e09315b792 Mon Sep 17 00:00:00 2001 From: Matthew Waters Date: Fri, 29 Nov 2019 13:45:42 +1100 Subject: [PATCH] vulkan: move fullscreenquad object to library It's useful and extensible enough to be used by us and other elements --- ext/vulkan/meson.build | 3 - ext/vulkan/vkcolorconvert.c | 16 +- ext/vulkan/vkcolorconvert.h | 1 - ext/vulkan/vkelementutils.c | 98 ----------- ext/vulkan/vkelementutils.h | 33 ---- ext/vulkan/vkimageidentity.c | 6 +- ext/vulkan/vkimageidentity.h | 1 - ext/vulkan/vkshader.c | 88 ---------- ext/vulkan/vkshader.h | 31 ---- ext/vulkan/vkviewconvert.c | 13 +- ext/vulkan/vkviewconvert.h | 1 - .../gst/vulkan/gstvkfullscreenquad.c | 182 +++++++++++++++++---- .../gst/vulkan/gstvkfullscreenquad.h | 27 +-- gst-libs/gst/vulkan/gstvkutils.c | 136 +++++++++++++++ gst-libs/gst/vulkan/gstvkutils.h | 9 + gst-libs/gst/vulkan/meson.build | 2 + gst-libs/gst/vulkan/vulkan.h | 20 ++- gst-libs/gst/vulkan/vulkan_fwd.h | 4 + tests/check/libs/vkimage.c | 10 +- 19 files changed, 350 insertions(+), 331 deletions(-) delete mode 100644 ext/vulkan/vkelementutils.c delete mode 100644 ext/vulkan/vkelementutils.h delete mode 100644 ext/vulkan/vkshader.c delete mode 100644 ext/vulkan/vkshader.h rename ext/vulkan/vkfullscreenquad.c => gst-libs/gst/vulkan/gstvkfullscreenquad.c (91%) rename ext/vulkan/vkfullscreenquad.h => gst-libs/gst/vulkan/gstvkfullscreenquad.h (89%) diff --git a/ext/vulkan/meson.build b/ext/vulkan/meson.build index 682da6d..03e50d0 100644 --- a/ext/vulkan/meson.build +++ b/ext/vulkan/meson.build @@ -22,11 +22,8 @@ vulkan_sources = [ 'vkcolorconvert.c', 'vkdownload.c', 'vkdeviceprovider.c', - 'vkelementutils.c', - 'vkfullscreenquad.c', 'vkimageidentity.c', 'vksink.c', - 'vkshader.c', 'vkupload.c', 'vkviewconvert.c', ] diff --git a/ext/vulkan/vkcolorconvert.c b/ext/vulkan/vkcolorconvert.c index 9e14a8a..2c17f3b 100644 --- a/ext/vulkan/vkcolorconvert.c +++ b/ext/vulkan/vkcolorconvert.c @@ -32,8 +32,6 @@ #include #include "vkcolorconvert.h" -#include "vkshader.h" -#include "vkelementutils.h" #include "shaders/identity.vert.h" #include "shaders/swizzle.frag.h" @@ -1154,13 +1152,14 @@ gst_vulkan_color_convert_set_caps (GstBaseTransform * bt, GstCaps * in_caps, } if (!(vert = - _vk_create_shader (vfilter->device, identity_vert, identity_vert_size, - NULL))) { + gst_vulkan_create_shader (vfilter->device, identity_vert, + identity_vert_size, NULL))) { return FALSE; } if (!(frag = - _vk_create_shader (vfilter->device, conv->current_shader->frag_code, - conv->current_shader->frag_size, NULL))) { + gst_vulkan_create_shader (vfilter->device, + conv->current_shader->frag_code, conv->current_shader->frag_size, + NULL))) { gst_vulkan_handle_unref (vert); return FALSE; } @@ -1224,7 +1223,7 @@ gst_vulkan_color_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf, goto error; } in_img_views[i] = - get_or_create_image_view ((GstVulkanImageMemory *) img_mem); + gst_vulkan_get_or_create_image_view ((GstVulkanImageMemory *) img_mem); gst_vulkan_trash_list_add (conv->quad->trash_list, gst_vulkan_trash_list_acquire (conv->quad->trash_list, fence, gst_vulkan_trash_mini_object_unref, @@ -1296,7 +1295,8 @@ gst_vulkan_color_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf, goto error; } render_img_views[i] = - get_or_create_image_view ((GstVulkanImageMemory *) img_mem); + gst_vulkan_get_or_create_image_view ((GstVulkanImageMemory *) + img_mem); gst_vulkan_trash_list_add (conv->quad->trash_list, gst_vulkan_trash_list_acquire (conv->quad->trash_list, fence, gst_vulkan_trash_mini_object_unref, diff --git a/ext/vulkan/vkcolorconvert.h b/ext/vulkan/vkcolorconvert.h index f27734b..8c14381 100644 --- a/ext/vulkan/vkcolorconvert.h +++ b/ext/vulkan/vkcolorconvert.h @@ -24,7 +24,6 @@ #include #include #include -#include "vkfullscreenquad.h" G_BEGIN_DECLS diff --git a/ext/vulkan/vkelementutils.c b/ext/vulkan/vkelementutils.c deleted file mode 100644 index 82f50b5..0000000 --- a/ext/vulkan/vkelementutils.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2019 Matthew Waters - * - * 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 "vkelementutils.h" - -static void -fill_vulkan_image_view_info (VkImage image, VkFormat format, - VkImageViewCreateInfo * info) -{ - /* *INDENT-OFF* */ - *info = (VkImageViewCreateInfo) { - .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - .pNext = NULL, - .image = image, - .format = format, - .viewType = VK_IMAGE_VIEW_TYPE_2D, - .flags = 0, - .components = (VkComponentMapping) { - VK_COMPONENT_SWIZZLE_R, - VK_COMPONENT_SWIZZLE_G, - VK_COMPONENT_SWIZZLE_B, - VK_COMPONENT_SWIZZLE_A - }, - .subresourceRange = (VkImageSubresourceRange) { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, - .baseMipLevel = 0, - .levelCount = 1, - .baseArrayLayer = 0, - .layerCount = 1, - } - }; - /* *INDENT-ON* */ -} - -static gboolean -find_compatible_view (GstVulkanImageView * view, VkImageViewCreateInfo * info) -{ - return view->create_info.image == info->image - && view->create_info.format == info->format - && view->create_info.viewType == info->viewType - && view->create_info.flags == info->flags - && view->create_info.components.r == info->components.r - && view->create_info.components.g == info->components.g - && view->create_info.components.b == info->components.b - && view->create_info.components.a == info->components.a - && view->create_info.subresourceRange.aspectMask == - info->subresourceRange.aspectMask - && view->create_info.subresourceRange.baseMipLevel == - info->subresourceRange.baseMipLevel - && view->create_info.subresourceRange.levelCount == - info->subresourceRange.levelCount - && view->create_info.subresourceRange.levelCount == - info->subresourceRange.levelCount - && view->create_info.subresourceRange.baseArrayLayer == - info->subresourceRange.baseArrayLayer - && view->create_info.subresourceRange.layerCount == - info->subresourceRange.layerCount; -} - -GstVulkanImageView * -get_or_create_image_view (GstVulkanImageMemory * image) -{ - VkImageViewCreateInfo create_info; - GstVulkanImageView *ret = NULL; - - fill_vulkan_image_view_info (image->image, image->create_info.format, - &create_info); - - ret = gst_vulkan_image_memory_find_view (image, - (GstVulkanImageMemoryFindViewFunc) find_compatible_view, &create_info); - if (!ret) { - ret = gst_vulkan_image_view_new (image, &create_info); - gst_vulkan_image_memory_add_view (image, ret); - } - - return ret; -} diff --git a/ext/vulkan/vkelementutils.h b/ext/vulkan/vkelementutils.h deleted file mode 100644 index 1fdc4ea..0000000 --- a/ext/vulkan/vkelementutils.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2019 Matthew Waters - * - * 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 _VK_ELEMENT_UTILS_H_ -#define _VK_ELEMENT_UTILS_H_ - -#include -#include - -G_BEGIN_DECLS - -GstVulkanImageView * get_or_create_image_view (GstVulkanImageMemory * image); - -G_END_DECLS - -#endif diff --git a/ext/vulkan/vkimageidentity.c b/ext/vulkan/vkimageidentity.c index e1c471f..d897217 100644 --- a/ext/vulkan/vkimageidentity.c +++ b/ext/vulkan/vkimageidentity.c @@ -32,8 +32,6 @@ #include #include "vkimageidentity.h" -#include "vkshader.h" -#include "vkelementutils.h" #include "shaders/identity.vert.h" #include "shaders/identity.frag.h" @@ -148,10 +146,10 @@ gst_vulkan_image_identity_start (GstBaseTransform * bt) vk_identity->quad = gst_vulkan_full_screen_quad_new (vfilter->queue); - if (!(vert = _vk_create_shader (vfilter->device, identity_vert, + if (!(vert = gst_vulkan_create_shader (vfilter->device, identity_vert, identity_vert_size, &error))) goto error; - if (!(frag = _vk_create_shader (vfilter->device, identity_frag, + if (!(frag = gst_vulkan_create_shader (vfilter->device, identity_frag, identity_frag_size, &error))) { gst_vulkan_handle_unref (vert); goto error; diff --git a/ext/vulkan/vkimageidentity.h b/ext/vulkan/vkimageidentity.h index c24e5d8..f10994e 100644 --- a/ext/vulkan/vkimageidentity.h +++ b/ext/vulkan/vkimageidentity.h @@ -24,7 +24,6 @@ #include #include #include -#include "vkfullscreenquad.h" G_BEGIN_DECLS diff --git a/ext/vulkan/vkshader.c b/ext/vulkan/vkshader.c deleted file mode 100644 index 54a7862..0000000 --- a/ext/vulkan/vkshader.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2019 Matthew Waters - * - * 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 "vkshader.h" - -#define SPIRV_MAGIC_NUMBER_NE 0x07230203 -#define SPIRV_MAGIC_NUMBER_OE 0x03022307 - -GstVulkanHandle * -_vk_create_shader (GstVulkanDevice * device, gchar * code, gsize size, - GError ** error) -{ - VkShaderModule shader; - VkResult res; - - /* *INDENT-OFF* */ - VkShaderModuleCreateInfo info = { - .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, - .pNext = NULL, - .flags = 0, - .codeSize = size, - .pCode = (guint32 *) code - }; - /* *INDENT-ON* */ - guint32 first_word; - guint32 *new_code = NULL; - - g_return_val_if_fail (size >= 4, VK_NULL_HANDLE); - g_return_val_if_fail (size % 4 == 0, VK_NULL_HANDLE); - - first_word = code[0] | code[1] << 8 | code[2] << 16 | code[3] << 24; - g_return_val_if_fail (first_word == SPIRV_MAGIC_NUMBER_NE - || first_word == SPIRV_MAGIC_NUMBER_OE, VK_NULL_HANDLE); - if (first_word == SPIRV_MAGIC_NUMBER_OE) { - /* endianness swap... */ - guint32 *old_code = (guint32 *) code; - gsize i; - - GST_DEBUG ("performaing endianness conversion on spirv shader of size %" - G_GSIZE_FORMAT, size); - new_code = g_new0 (guint32, size / 4); - - for (i = 0; i < size / 4; i++) { - guint32 old = old_code[i]; - guint32 new = 0; - - new |= (old & 0xff) << 24; - new |= (old & 0xff00) << 8; - new |= (old & 0xff0000) >> 8; - new |= (old & 0xff000000) >> 24; - new_code[i] = new; - } - - first_word = ((guint32 *) new_code)[0]; - g_assert (first_word == SPIRV_MAGIC_NUMBER_NE); - - info.pCode = new_code; - } - - res = vkCreateShaderModule (device->device, &info, NULL, &shader); - g_free (new_code); - if (gst_vulkan_error_to_g_error (res, error, "VkCreateShaderModule") < 0) - return NULL; - - return gst_vulkan_handle_new_wrapped (device, GST_VULKAN_HANDLE_TYPE_SHADER, - (GstVulkanHandleTypedef) shader, gst_vulkan_handle_free_shader, NULL); -} diff --git a/ext/vulkan/vkshader.h b/ext/vulkan/vkshader.h deleted file mode 100644 index b819c48..0000000 --- a/ext/vulkan/vkshader.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * GStreamer - * Copyright (C) 2019 Matthew Waters - * - * 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 _VK_SHADER_H_ -#define _VK_SHADER_H_ - -#include -#include - -G_BEGIN_DECLS - -GstVulkanHandle * _vk_create_shader (GstVulkanDevice * device, gchar * code, gsize size, GError ** error); - -#endif diff --git a/ext/vulkan/vkviewconvert.c b/ext/vulkan/vkviewconvert.c index c37b6d2..dae6bb5 100644 --- a/ext/vulkan/vkviewconvert.c +++ b/ext/vulkan/vkviewconvert.c @@ -32,8 +32,6 @@ #include #include "vkviewconvert.h" -#include "vkshader.h" -#include "vkelementutils.h" #include "shaders/identity.vert.h" #include "shaders/view_convert.frag.h" @@ -1842,12 +1840,12 @@ gst_vulkan_view_convert_start (GstBaseTransform * bt) conv->quad = gst_vulkan_full_screen_quad_new (vfilter->queue); if (!(vert = - _vk_create_shader (vfilter->device, identity_vert, identity_vert_size, - NULL))) { + gst_vulkan_create_shader (vfilter->device, identity_vert, + identity_vert_size, NULL))) { return FALSE; } if (!(frag = - _vk_create_shader (vfilter->device, view_convert_frag, + gst_vulkan_create_shader (vfilter->device, view_convert_frag, view_convert_frag_size, NULL))) { gst_vulkan_handle_unref (vert); return FALSE; @@ -1927,7 +1925,7 @@ gst_vulkan_view_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf, goto error; } in_img_views[i] = - get_or_create_image_view ((GstVulkanImageMemory *) img_mem); + gst_vulkan_get_or_create_image_view ((GstVulkanImageMemory *) img_mem); gst_vulkan_trash_list_add (conv->quad->trash_list, gst_vulkan_trash_list_acquire (conv->quad->trash_list, fence, gst_vulkan_trash_mini_object_unref, @@ -1940,7 +1938,8 @@ gst_vulkan_view_convert_transform (GstBaseTransform * bt, GstBuffer * inbuf, "Output memory must be a GstVulkanImageMemory"); goto error; } - out_img_views[i] = get_or_create_image_view ((GstVulkanImageMemory *) mem); + out_img_views[i] = + gst_vulkan_get_or_create_image_view ((GstVulkanImageMemory *) mem); gst_vulkan_trash_list_add (conv->quad->trash_list, gst_vulkan_trash_list_acquire (conv->quad->trash_list, fence, gst_vulkan_trash_mini_object_unref, diff --git a/ext/vulkan/vkviewconvert.h b/ext/vulkan/vkviewconvert.h index f05f5ac..809301c 100644 --- a/ext/vulkan/vkviewconvert.h +++ b/ext/vulkan/vkviewconvert.h @@ -24,7 +24,6 @@ #include #include #include -#include "vkfullscreenquad.h" G_BEGIN_DECLS diff --git a/ext/vulkan/vkfullscreenquad.c b/gst-libs/gst/vulkan/gstvkfullscreenquad.c similarity index 91% rename from ext/vulkan/vkfullscreenquad.c rename to gst-libs/gst/vulkan/gstvkfullscreenquad.c index 4f35c61..369d264 100644 --- a/ext/vulkan/vkfullscreenquad.c +++ b/gst-libs/gst/vulkan/gstvkfullscreenquad.c @@ -22,13 +22,17 @@ #include "config.h" #endif -#include "vkfullscreenquad.h" -#include "vkelementutils.h" +#include "gstvkfullscreenquad.h" #define GST_CAT_DEFAULT gst_vulkan_full_screen_quad_debug GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT); -typedef struct _GstVulkanFullScreenQuad GstVulkanFullScreenQuad; +/* XXX: privatise this on moving to lib */ +struct Vertex +{ + float x, y, z; + float s, t; +}; struct _GstVulkanFullScreenQuadPrivate { @@ -41,9 +45,6 @@ struct _GstVulkanFullScreenQuadPrivate GstMemory *uniforms; gsize uniform_size; - GstMemory *push_constants; - gsize push_constants_size; - GstVulkanHandle *vert; GstVulkanHandle *frag; }; @@ -739,7 +740,42 @@ clear_uniform_data (GstVulkanFullScreenQuad * self) } static void -destroy_pipeline (GstVulkanFullScreenQuad * self) +clear_index_data (GstVulkanFullScreenQuad * self) +{ + GstVulkanFullScreenQuadPrivate *priv = GET_PRIV (self); + GstVulkanFence *last_fence = + LAST_FENCE_OR_ALWAYS_SIGNALLED (self, self->queue->device); + + if (priv->indices) + gst_vulkan_trash_list_add (self->trash_list, + gst_vulkan_trash_list_acquire (self->trash_list, last_fence, + gst_vulkan_trash_mini_object_unref, + (GstMiniObject *) priv->indices)); + priv->indices = NULL; + priv->n_indices = 0; + + gst_vulkan_fence_unref (last_fence); +} + +static void +clear_vertex_data (GstVulkanFullScreenQuad * self) +{ + GstVulkanFullScreenQuadPrivate *priv = GET_PRIV (self); + GstVulkanFence *last_fence = + LAST_FENCE_OR_ALWAYS_SIGNALLED (self, self->queue->device); + + if (priv->vertices) + gst_vulkan_trash_list_add (self->trash_list, + gst_vulkan_trash_list_acquire (self->trash_list, last_fence, + gst_vulkan_trash_mini_object_unref, + (GstMiniObject *) priv->vertices)); + priv->vertices = NULL; + + gst_vulkan_fence_unref (last_fence); +} + +static void +clear_render_pass (GstVulkanFullScreenQuad * self) { GstVulkanFence *last_fence = LAST_FENCE_OR_ALWAYS_SIGNALLED (self, self->queue->device); @@ -750,18 +786,48 @@ destroy_pipeline (GstVulkanFullScreenQuad * self) gst_vulkan_trash_mini_object_unref, (GstMiniObject *) self->render_pass)); self->render_pass = NULL; + + gst_vulkan_fence_unref (last_fence); +} + +static void +clear_pipeline_layout (GstVulkanFullScreenQuad * self) +{ + GstVulkanFence *last_fence = + LAST_FENCE_OR_ALWAYS_SIGNALLED (self, self->queue->device); + if (self->pipeline_layout) gst_vulkan_trash_list_add (self->trash_list, gst_vulkan_trash_list_acquire (self->trash_list, last_fence, gst_vulkan_trash_mini_object_unref, (GstMiniObject *) self->pipeline_layout)); self->pipeline_layout = NULL; + + gst_vulkan_fence_unref (last_fence); +} + +static void +clear_graphics_pipeline (GstVulkanFullScreenQuad * self) +{ + GstVulkanFence *last_fence = + LAST_FENCE_OR_ALWAYS_SIGNALLED (self, self->queue->device); + if (self->graphics_pipeline) gst_vulkan_trash_list_add (self->trash_list, gst_vulkan_trash_list_acquire (self->trash_list, last_fence, gst_vulkan_trash_mini_object_unref, (GstMiniObject *) self->graphics_pipeline)); self->graphics_pipeline = NULL; + + gst_vulkan_fence_unref (last_fence); +} + +static void +clear_descriptor_set_layout (GstVulkanFullScreenQuad * self) +{ + GstVulkanFence *last_fence = + LAST_FENCE_OR_ALWAYS_SIGNALLED (self, self->queue->device); + if (self->descriptor_set_layout) gst_vulkan_trash_list_add (self->trash_list, gst_vulkan_trash_list_acquire (self->trash_list, last_fence, @@ -770,6 +836,20 @@ destroy_pipeline (GstVulkanFullScreenQuad * self) self->descriptor_set_layout = NULL; gst_vulkan_fence_unref (last_fence); +} + +static void +destroy_pipeline (GstVulkanFullScreenQuad * self) +{ + GstVulkanFence *last_fence = + LAST_FENCE_OR_ALWAYS_SIGNALLED (self, self->queue->device); + + clear_render_pass (self); + clear_pipeline_layout (self); + clear_graphics_pipeline (self); + clear_descriptor_set_layout (self); + + gst_vulkan_fence_unref (last_fence); gst_vulkan_trash_list_gc (self->trash_list); } @@ -807,14 +887,13 @@ gst_vulkan_full_screen_quad_finalize (GObject * object) clear_descriptor_cache (self); clear_shaders (self); clear_uniform_data (self); + clear_index_data (self); + clear_vertex_data (self); gst_vulkan_trash_list_wait (self->trash_list, -1); gst_vulkan_trash_list_gc (self->trash_list); gst_clear_object (&self->trash_list); - gst_clear_mini_object (((GstMiniObject **) & priv->vertices)); - gst_clear_mini_object (((GstMiniObject **) & priv->indices)); - gst_clear_mini_object (((GstMiniObject **) & self->last_fence)); gst_clear_object (&self->queue); @@ -923,6 +1002,47 @@ gst_vulkan_full_screen_quad_set_uniform_buffer (GstVulkanFullScreenQuad * self, return TRUE; } +gboolean +gst_vulkan_full_screen_quad_set_index_buffer (GstVulkanFullScreenQuad * self, + GstMemory * indices, gsize n_indices, GError ** error) +{ + GstVulkanFullScreenQuadPrivate *priv; + + g_return_val_if_fail (GST_IS_VULKAN_FULL_SCREEN_QUAD (self), FALSE); + g_return_val_if_fail (indices == NULL + || gst_is_vulkan_buffer_memory (indices), FALSE); + + priv = GET_PRIV (self); + + clear_index_data (self); + if (indices) { + priv->indices = gst_memory_ref (indices); + priv->n_indices = n_indices; + } + + return TRUE; +} + +gboolean +gst_vulkan_full_screen_quad_set_vertex_buffer (GstVulkanFullScreenQuad * self, + GstMemory * vertices, GError ** error) +{ + GstVulkanFullScreenQuadPrivate *priv; + + g_return_val_if_fail (GST_IS_VULKAN_FULL_SCREEN_QUAD (self), FALSE); + g_return_val_if_fail (vertices == NULL + || gst_is_vulkan_buffer_memory (vertices), FALSE); + + priv = GET_PRIV (self); + + clear_vertex_data (self); + if (vertices) { + priv->vertices = gst_memory_ref (vertices); + } + + return TRUE; +} + static GstVulkanImageMemory * peek_image_from_buffer (GstBuffer * buffer, guint i) { @@ -942,34 +1062,34 @@ ensure_vertex_data (GstVulkanFullScreenQuad * self, GError ** error) sizeof (vertices), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); - } - if (!gst_memory_map (priv->vertices, &map_info, GST_MAP_WRITE)) { - g_set_error_literal (error, GST_VULKAN_ERROR, VK_ERROR_MEMORY_MAP_FAILED, - "Failed to map memory"); - goto failure; - } + if (!gst_memory_map (priv->vertices, &map_info, GST_MAP_WRITE)) { + g_set_error_literal (error, GST_VULKAN_ERROR, VK_ERROR_MEMORY_MAP_FAILED, + "Failed to map memory"); + goto failure; + } - memcpy (map_info.data, vertices, map_info.size); - gst_memory_unmap (priv->vertices, &map_info); + memcpy (map_info.data, vertices, map_info.size); + gst_memory_unmap (priv->vertices, &map_info); + } if (!priv->indices) { priv->indices = gst_vulkan_buffer_memory_alloc (self->queue->device, sizeof (indices), VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); - } - if (!gst_memory_map (priv->indices, &map_info, GST_MAP_WRITE)) { - g_set_error_literal (error, GST_VULKAN_ERROR, VK_ERROR_MEMORY_MAP_FAILED, - "Failed to map memory"); - goto failure; - } + if (!gst_memory_map (priv->indices, &map_info, GST_MAP_WRITE)) { + g_set_error_literal (error, GST_VULKAN_ERROR, VK_ERROR_MEMORY_MAP_FAILED, + "Failed to map memory"); + goto failure; + } - memcpy (map_info.data, indices, map_info.size); - gst_memory_unmap (priv->indices, &map_info); + memcpy (map_info.data, indices, map_info.size); + gst_memory_unmap (priv->indices, &map_info); - priv->n_indices = G_N_ELEMENTS (indices); + priv->n_indices = G_N_ELEMENTS (indices); + } return TRUE; @@ -1080,7 +1200,7 @@ gst_vulkan_full_screen_quad_prepare_draw (GstVulkanFullScreenQuad * self, "Input memory must be a GstVulkanImageMemory"); goto error; } - in_views[i] = get_or_create_image_view (img_mem); + in_views[i] = gst_vulkan_get_or_create_image_view (img_mem); gst_vulkan_trash_list_add (self->trash_list, gst_vulkan_trash_list_acquire (self->trash_list, fence, gst_vulkan_trash_mini_object_unref, @@ -1099,7 +1219,7 @@ gst_vulkan_full_screen_quad_prepare_draw (GstVulkanFullScreenQuad * self, "Output memory must be a GstVulkanImageMemory"); goto error; } - out_views[i] = get_or_create_image_view (img_mem); + out_views[i] = gst_vulkan_get_or_create_image_view (img_mem); gst_vulkan_trash_list_add (self->trash_list, gst_vulkan_trash_list_acquire (self->trash_list, fence, gst_vulkan_trash_mini_object_unref, @@ -1154,7 +1274,7 @@ gst_vulkan_full_screen_quad_fill_command_buffer (GstVulkanFullScreenQuad * self, "Input memory must be a GstVulkanImageMemory"); goto error; } - in_views[i] = get_or_create_image_view (img_mem); + in_views[i] = gst_vulkan_get_or_create_image_view (img_mem); gst_vulkan_trash_list_add (self->trash_list, gst_vulkan_trash_list_acquire (self->trash_list, fence, gst_vulkan_trash_mini_object_unref, (GstMiniObject *) in_views[i])); @@ -1166,7 +1286,7 @@ gst_vulkan_full_screen_quad_fill_command_buffer (GstVulkanFullScreenQuad * self, "Output memory must be a GstVulkanImageMemory"); goto error; } - out_views[i] = get_or_create_image_view (img_mem); + out_views[i] = gst_vulkan_get_or_create_image_view (img_mem); gst_vulkan_trash_list_add (self->trash_list, gst_vulkan_trash_list_acquire (self->trash_list, fence, gst_vulkan_trash_mini_object_unref, diff --git a/ext/vulkan/vkfullscreenquad.h b/gst-libs/gst/vulkan/gstvkfullscreenquad.h similarity index 89% rename from ext/vulkan/vkfullscreenquad.h rename to gst-libs/gst/vulkan/gstvkfullscreenquad.h index f73748c..8cdb218 100644 --- a/ext/vulkan/vkfullscreenquad.h +++ b/gst-libs/gst/vulkan/gstvkfullscreenquad.h @@ -28,6 +28,7 @@ G_BEGIN_DECLS +GST_VULKAN_API GType gst_vulkan_full_screen_quad_get_type (void); #define GST_TYPE_VULKAN_FULL_SCREEN_QUAD (gst_vulkan_full_screen_quad_get_type ()) #define GST_VULKAN_FULL_SCREEN_QUAD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_VULKAN_FULL_SCREEN_QUAD, GstVulkanFullScreenQuad)) @@ -36,17 +37,6 @@ GType gst_vulkan_full_screen_quad_get_type (void); #define GST_IS_VULKAN_FULL_SCREEN_QUAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VULKAN_FULL_SCREEN_QUAD)) #define GST_VULKAN_FULL_SCREEN_QUAD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_VULKAN_FULL_SCREEN_QUAD, GstVulkanFullScreenQuadClass)) -/* XXX: privatise this on moving to lib */ -struct Vertex -{ - float x, y, z; - float s, t; -}; - -typedef struct _GstVulkanFullScreenQuad GstVulkanFullScreenQuad; -typedef struct _GstVulkanFullScreenQuadClass GstVulkanFullScreenQuadClass; -typedef struct _GstVulkanFullScreenQuadPrivate GstVulkanFullScreenQuadPrivate; - struct _GstVulkanFullScreenQuad { GstObject parent; @@ -76,20 +66,35 @@ struct _GstVulkanFullScreenQuadClass GstObjectClass parent_class; }; +GST_VULKAN_API GstVulkanFullScreenQuad * gst_vulkan_full_screen_quad_new (GstVulkanQueue * queue); +GST_VULKAN_API gboolean gst_vulkan_full_screen_quad_set_info (GstVulkanFullScreenQuad * self, GstVideoInfo *in_info, GstVideoInfo * out_info); +GST_VULKAN_API gboolean gst_vulkan_full_screen_quad_set_shaders (GstVulkanFullScreenQuad * self, GstVulkanHandle * vert, GstVulkanHandle * frag); +GST_VULKAN_API gboolean gst_vulkan_full_screen_quad_set_uniform_buffer (GstVulkanFullScreenQuad * self, GstMemory * uniforms, GError ** error); +GST_VULKAN_API +gboolean gst_vulkan_full_screen_quad_set_vertex_buffer (GstVulkanFullScreenQuad * self, GstMemory * vertices, GError ** error); +GST_VULKAN_API +gboolean gst_vulkan_full_screen_quad_set_index_buffer (GstVulkanFullScreenQuad * self, GstMemory * indices, gsize n_indices, GError ** error); +GST_VULKAN_API gboolean gst_vulkan_full_screen_quad_set_input_buffer (GstVulkanFullScreenQuad * self, GstBuffer * buffer, GError ** error); +GST_VULKAN_API gboolean gst_vulkan_full_screen_quad_set_output_buffer (GstVulkanFullScreenQuad * self, GstBuffer * buffer, GError ** error); +GST_VULKAN_API gboolean gst_vulkan_full_screen_quad_prepare_draw (GstVulkanFullScreenQuad * self, GstVulkanFence * fence, GError ** error); +GST_VULKAN_API gboolean gst_vulkan_full_screen_quad_fill_command_buffer (GstVulkanFullScreenQuad * self, GstVulkanCommandBuffer * cmd, GstVulkanFence * fence, GError ** error); +GST_VULKAN_API gboolean gst_vulkan_full_screen_quad_submit (GstVulkanFullScreenQuad * self, GstVulkanCommandBuffer * cmd, GstVulkanFence * fence, GError ** error); +GST_VULKAN_API gboolean gst_vulkan_full_screen_quad_draw (GstVulkanFullScreenQuad * self, GError ** error); +GST_VULKAN_API GstVulkanFence * gst_vulkan_full_screen_quad_get_last_fence (GstVulkanFullScreenQuad * self); G_END_DECLS diff --git a/gst-libs/gst/vulkan/gstvkutils.c b/gst-libs/gst/vulkan/gstvkutils.c index b75417e..812e251 100644 --- a/gst-libs/gst/vulkan/gstvkutils.c +++ b/gst-libs/gst/vulkan/gstvkutils.c @@ -402,3 +402,139 @@ gst_vulkan_handle_context_query (GstElement * element, GstQuery * query, return FALSE; } + +static void +fill_vulkan_image_view_info (VkImage image, VkFormat format, + VkImageViewCreateInfo * info) +{ + /* *INDENT-OFF* */ + *info = (VkImageViewCreateInfo) { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .pNext = NULL, + .image = image, + .format = format, + .viewType = VK_IMAGE_VIEW_TYPE_2D, + .flags = 0, + .components = (VkComponentMapping) { + VK_COMPONENT_SWIZZLE_R, + VK_COMPONENT_SWIZZLE_G, + VK_COMPONENT_SWIZZLE_B, + VK_COMPONENT_SWIZZLE_A + }, + .subresourceRange = (VkImageSubresourceRange) { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = 1, + } + }; + /* *INDENT-ON* */ +} + +static gboolean +find_compatible_view (GstVulkanImageView * view, VkImageViewCreateInfo * info) +{ + return view->create_info.image == info->image + && view->create_info.format == info->format + && view->create_info.viewType == info->viewType + && view->create_info.flags == info->flags + && view->create_info.components.r == info->components.r + && view->create_info.components.g == info->components.g + && view->create_info.components.b == info->components.b + && view->create_info.components.a == info->components.a + && view->create_info.subresourceRange.aspectMask == + info->subresourceRange.aspectMask + && view->create_info.subresourceRange.baseMipLevel == + info->subresourceRange.baseMipLevel + && view->create_info.subresourceRange.levelCount == + info->subresourceRange.levelCount + && view->create_info.subresourceRange.levelCount == + info->subresourceRange.levelCount + && view->create_info.subresourceRange.baseArrayLayer == + info->subresourceRange.baseArrayLayer + && view->create_info.subresourceRange.layerCount == + info->subresourceRange.layerCount; +} + +GstVulkanImageView * +gst_vulkan_get_or_create_image_view (GstVulkanImageMemory * image) +{ + VkImageViewCreateInfo create_info; + GstVulkanImageView *ret = NULL; + + fill_vulkan_image_view_info (image->image, image->create_info.format, + &create_info); + + ret = gst_vulkan_image_memory_find_view (image, + (GstVulkanImageMemoryFindViewFunc) find_compatible_view, &create_info); + if (!ret) { + ret = gst_vulkan_image_view_new (image, &create_info); + gst_vulkan_image_memory_add_view (image, ret); + } + + return ret; +} + +#define SPIRV_MAGIC_NUMBER_NE 0x07230203 +#define SPIRV_MAGIC_NUMBER_OE 0x03022307 + +GstVulkanHandle * +gst_vulkan_create_shader (GstVulkanDevice * device, gchar * code, gsize size, + GError ** error) +{ + VkShaderModule shader; + VkResult res; + + /* *INDENT-OFF* */ + VkShaderModuleCreateInfo info = { + .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, + .pNext = NULL, + .flags = 0, + .codeSize = size, + .pCode = (guint32 *) code + }; + /* *INDENT-ON* */ + guint32 first_word; + guint32 *new_code = NULL; + + g_return_val_if_fail (size >= 4, VK_NULL_HANDLE); + g_return_val_if_fail (size % 4 == 0, VK_NULL_HANDLE); + + first_word = code[0] | code[1] << 8 | code[2] << 16 | code[3] << 24; + g_return_val_if_fail (first_word == SPIRV_MAGIC_NUMBER_NE + || first_word == SPIRV_MAGIC_NUMBER_OE, VK_NULL_HANDLE); + if (first_word == SPIRV_MAGIC_NUMBER_OE) { + /* endianness swap... */ + guint32 *old_code = (guint32 *) code; + gsize i; + + GST_DEBUG ("performaing endianness conversion on spirv shader of size %" + G_GSIZE_FORMAT, size); + new_code = g_new0 (guint32, size / 4); + + for (i = 0; i < size / 4; i++) { + guint32 old = old_code[i]; + guint32 new = 0; + + new |= (old & 0xff) << 24; + new |= (old & 0xff00) << 8; + new |= (old & 0xff0000) >> 8; + new |= (old & 0xff000000) >> 24; + new_code[i] = new; + } + + first_word = ((guint32 *) new_code)[0]; + g_assert (first_word == SPIRV_MAGIC_NUMBER_NE); + + info.pCode = new_code; + } + + res = vkCreateShaderModule (device->device, &info, NULL, &shader); + g_free (new_code); + if (gst_vulkan_error_to_g_error (res, error, "VkCreateShaderModule") < 0) + return NULL; + + return gst_vulkan_handle_new_wrapped (device, GST_VULKAN_HANDLE_TYPE_SHADER, + (GstVulkanHandleTypedef) shader, gst_vulkan_handle_free_shader, NULL); +} diff --git a/gst-libs/gst/vulkan/gstvkutils.h b/gst-libs/gst/vulkan/gstvkutils.h index fc9231c..194650e 100644 --- a/gst-libs/gst/vulkan/gstvkutils.h +++ b/gst-libs/gst/vulkan/gstvkutils.h @@ -52,6 +52,15 @@ gboolean gst_vulkan_run_query (GstElement * el GstQuery * query, GstPadDirection direction); +GST_VULKAN_API +GstVulkanImageView * gst_vulkan_get_or_create_image_view (GstVulkanImageMemory * image); + +GST_VULKAN_API +GstVulkanHandle * gst_vulkan_create_shader (GstVulkanDevice * device, + gchar * code, + gsize size, + GError ** error); + G_END_DECLS #endif /*_VK_UTILS_H_ */ diff --git a/gst-libs/gst/vulkan/meson.build b/gst-libs/gst/vulkan/meson.build index 8b3268e..31cac19 100644 --- a/gst-libs/gst/vulkan/meson.build +++ b/gst-libs/gst/vulkan/meson.build @@ -17,6 +17,7 @@ vulkan_sources = [ 'gstvkerror.c', 'gstvkfence.c', 'gstvkformat.c', + 'gstvkfullscreenquad.c', 'gstvkhandle.c', 'gstvkhandlepool.c', 'gstvkimagememory.c', @@ -49,6 +50,7 @@ vulkan_headers = [ 'gstvkerror.h', 'gstvkfence.h', 'gstvkformat.h', + 'gstvkfullscreenquad.h', 'gstvkhandle.h', 'gstvkhandlepool.h', 'gstvkimagememory.h', diff --git a/gst-libs/gst/vulkan/vulkan.h b/gst-libs/gst/vulkan/vulkan.h index bdf10f4..07e44ab 100644 --- a/gst-libs/gst/vulkan/vulkan.h +++ b/gst-libs/gst/vulkan/vulkan.h @@ -24,16 +24,16 @@ #include #include - -/* helper vulkan objects */ #include #include +#include + +/* vulkan wrapper objects */ #include #include #include #include #include -#include #include #include #include @@ -43,18 +43,22 @@ #include #include #include -#include #include #include -#include #include #include #include -#include -#include -#include /* helper elements */ #include +/* helper vulkan objects */ +#include +#include +#include +#include +#include + +#include + #endif /* __GST_VULKAN_H__ */ diff --git a/gst-libs/gst/vulkan/vulkan_fwd.h b/gst-libs/gst/vulkan/vulkan_fwd.h index f489fc3..8634b28 100644 --- a/gst-libs/gst/vulkan/vulkan_fwd.h +++ b/gst-libs/gst/vulkan/vulkan_fwd.h @@ -108,6 +108,10 @@ typedef struct _GstVulkanTrashListClass GstVulkanTrashListClass; typedef struct _GstVulkanTrash GstVulkanTrash; +typedef struct _GstVulkanFullScreenQuad GstVulkanFullScreenQuad; +typedef struct _GstVulkanFullScreenQuadClass GstVulkanFullScreenQuadClass; +typedef struct _GstVulkanFullScreenQuadPrivate GstVulkanFullScreenQuadPrivate; + G_END_DECLS #endif /* __GST_VULKAN_FWD_H__ */ diff --git a/tests/check/libs/vkimage.c b/tests/check/libs/vkimage.c index ffa13f4..09999b7 100644 --- a/tests/check/libs/vkimage.c +++ b/tests/check/libs/vkimage.c @@ -26,8 +26,6 @@ #include #include #include -#include "../../ext/vulkan/vkelementutils.h" -#include "../../ext/vulkan/vkelementutils.c" static GstVulkanInstance *instance; static GstVulkanDevice *device; @@ -115,7 +113,7 @@ GST_START_TEST (test_image_view_new) gst_video_info_set_format (&v_info, GST_VIDEO_FORMAT_RGBA, 16, 16); vk_mem = create_image_mem (&v_info); - view = get_or_create_image_view (vk_mem); + view = gst_vulkan_get_or_create_image_view (vk_mem); gst_vulkan_image_view_unref (view); gst_memory_unref ((GstMemory *) vk_mem); @@ -132,9 +130,9 @@ GST_START_TEST (test_image_view_get) gst_video_info_set_format (&v_info, GST_VIDEO_FORMAT_RGBA, 16, 16); vk_mem = create_image_mem (&v_info); - view = get_or_create_image_view (vk_mem); + view = gst_vulkan_get_or_create_image_view (vk_mem); gst_vulkan_image_view_unref (view); - view = get_or_create_image_view (vk_mem); + view = gst_vulkan_get_or_create_image_view (vk_mem); gst_vulkan_image_view_unref (view); gst_memory_unref ((GstMemory *) vk_mem); @@ -173,7 +171,7 @@ get_unref_image_view (GstHarnessThread * thread, struct view_stress *stress) GstVulkanImageView *view; mem = g_queue_peek_nth (stress->memories, rand); - view = get_or_create_image_view (mem); + view = gst_vulkan_get_or_create_image_view (mem); gst_vulkan_image_view_unref (view); g_atomic_int_inc (&stress->n_ops); -- 2.7.4