diff --git a/subprojects/gst-plugins-bad/tests/check/libs/vkformat.c b/subprojects/gst-plugins-bad/tests/check/libs/vkformat.c new file mode 100644 index 0000000000..a4ca27205c --- /dev/null +++ b/subprojects/gst-plugins-bad/tests/check/libs/vkformat.c @@ -0,0 +1,113 @@ +/* GStreamer + * + * Copyright (C) 2023 Igalia, S.L. + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +static GstVulkanInstance *instance; +static GstVulkanDevice *device; + +static void +setup (void) +{ + instance = gst_vulkan_instance_new (); + fail_unless (gst_vulkan_instance_open (instance, NULL)); + device = gst_vulkan_device_new_with_index (instance, 0); + fail_unless (gst_vulkan_device_open (device, NULL)); +} + +static void +teardown (void) +{ + gst_object_unref (instance); + gst_object_unref (device); +} + +GST_START_TEST (test_format_from_video_info_2) +{ + GstVulkanPhysicalDevice *phy_dev = device->physical_device; + GstVideoInfo vinfo; + VkFormat vk_fmts[GST_VIDEO_MAX_PLANES]; + int n_imgs; + VkImageUsageFlags supported_usage; + + fail_unless (gst_video_info_set_format (&vinfo, GST_VIDEO_FORMAT_NV12, 620, + 480)); + + fail_unless (gst_vulkan_format_from_video_info_2 (phy_dev, &vinfo, + VK_IMAGE_TILING_OPTIMAL, TRUE, vk_fmts, &n_imgs, &supported_usage)); + + fail_unless (n_imgs == 2 && vk_fmts[0] == VK_FORMAT_R8_UNORM + && vk_fmts[1] == VK_FORMAT_R8G8_UNORM); + + fail_unless (gst_vulkan_format_from_video_info_2 (phy_dev, &vinfo, + VK_IMAGE_TILING_LINEAR, FALSE, vk_fmts, &n_imgs, &supported_usage)); + + fail_unless (n_imgs == 1 && vk_fmts[0] == VK_FORMAT_G8_B8R8_2PLANE_420_UNORM); + + fail_unless (gst_video_info_set_format (&vinfo, GST_VIDEO_FORMAT_RGBA, 620, + 480)); + + fail_unless (gst_vulkan_format_from_video_info_2 (phy_dev, &vinfo, + VK_IMAGE_TILING_LINEAR, TRUE, vk_fmts, &n_imgs, &supported_usage)); + + fail_unless (n_imgs == 1 && vk_fmts[0] == VK_FORMAT_R8G8B8A8_UNORM); + + fail_unless (gst_video_info_set_format (&vinfo, GST_VIDEO_FORMAT_RGBA, 620, + 480)); + fail_unless (gst_video_colorimetry_from_string + (&GST_VIDEO_INFO_COLORIMETRY (&vinfo), "smpte240m")); + + fail_unless (gst_vulkan_format_from_video_info_2 (phy_dev, &vinfo, + VK_IMAGE_TILING_LINEAR, TRUE, vk_fmts, &n_imgs, &supported_usage)); + + fail_unless (n_imgs == 1 && vk_fmts[0] == VK_FORMAT_R8G8B8A8_SRGB); +} + +GST_END_TEST; + +static Suite * +vkformat_suite (void) +{ + Suite *s = suite_create ("vkmemory"); + TCase *tc_basic = tcase_create ("general"); + gboolean have_instance; + + suite_add_tcase (s, tc_basic); + tcase_add_checked_fixture (tc_basic, setup, teardown); + + /* FIXME: CI doesn't have a software vulkan renderer (and none exists currently) */ + instance = gst_vulkan_instance_new (); + have_instance = gst_vulkan_instance_open (instance, NULL); + gst_object_unref (instance); + if (have_instance) { + tcase_add_test (tc_basic, test_format_from_video_info_2); + } + + return s; +} + + +GST_CHECK_MAIN (vkformat); diff --git a/subprojects/gst-plugins-bad/tests/check/libs/vkimagebufferpool.c b/subprojects/gst-plugins-bad/tests/check/libs/vkimagebufferpool.c new file mode 100644 index 0000000000..437b43d56a --- /dev/null +++ b/subprojects/gst-plugins-bad/tests/check/libs/vkimagebufferpool.c @@ -0,0 +1,225 @@ +/* GStreamer + * + * Copyright (C) 2023 Igalia, S.L. + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +static GstVulkanInstance *instance; +static GstVulkanDevice *device; +static GstVulkanQueue *queue = NULL; + +static gboolean +_choose_queue (GstVulkanDevice * device, GstVulkanQueue * _queue, gpointer data) +{ +#if GST_VULKAN_HAVE_VIDEO_EXTENSIONS + guint flags = + device->physical_device->queue_family_props[_queue->family].queueFlags; + + if ((flags & VK_QUEUE_COMPUTE_BIT) != 0) { + gst_object_replace ((GstObject **) & queue, GST_OBJECT_CAST (_queue)); + return FALSE; + } +#endif + + return TRUE; +} + +static void +setup (void) +{ + instance = gst_vulkan_instance_new (); + fail_unless (gst_vulkan_instance_open (instance, NULL)); + device = gst_vulkan_device_new_with_index (instance, 0); + fail_unless (gst_vulkan_device_open (device, NULL)); + + gst_vulkan_device_foreach_queue (device, _choose_queue, NULL); + fail_unless (GST_IS_VULKAN_QUEUE (queue)); +} + +static void +teardown (void) +{ + gst_clear_object (&queue); + gst_object_unref (device); + gst_object_unref (instance); +} + +static GstBufferPool * +create_buffer_pool (const char *format, VkImageUsageFlags usage, + GstCaps * dec_caps) +{ + GstCaps *caps; + GstBufferPool *pool; + GstStructure *config; + + caps = gst_caps_new_simple ("video/x-raw", "format", G_TYPE_STRING, format, + "width", G_TYPE_INT, 1024, "height", G_TYPE_INT, 780, NULL); + gst_caps_set_features_simple (caps, + gst_caps_features_new (GST_CAPS_FEATURE_MEMORY_VULKAN_IMAGE, NULL)); + + pool = gst_vulkan_image_buffer_pool_new (device); + + config = gst_buffer_pool_get_config (pool); + + gst_buffer_pool_config_set_params (config, caps, 1024, 1, 0); + gst_caps_unref (caps); + + gst_vulkan_image_buffer_pool_config_set_allocation_params (config, + usage, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); + + if (dec_caps) + gst_vulkan_image_buffer_pool_config_set_decode_caps (config, dec_caps); + + fail_unless (gst_buffer_pool_set_config (pool, config)); + gst_buffer_pool_set_active (pool, TRUE); + + return pool; +} + +GST_START_TEST (test_image) +{ + GstBufferPool *pool; + GstFlowReturn ret; + GstBuffer *buffer = NULL; + + pool = create_buffer_pool ("NV12", 0, NULL); + + ret = gst_buffer_pool_acquire_buffer (pool, &buffer, NULL); + fail_unless (ret == GST_FLOW_OK); + gst_buffer_unref (buffer); + + gst_buffer_pool_set_active (pool, FALSE); + gst_object_unref (pool); +} + +GST_END_TEST; + +#if GST_VULKAN_HAVE_VIDEO_EXTENSIONS +GST_START_TEST (test_vulkan_profiles) +{ + GstCaps *caps; + /* *INDENT-OFF* */ + GstVulkanVideoProfile profile2 = { { 0, }, }, profile = { + .profile = { + .sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR, + .pNext = &profile.codec, + .videoCodecOperation = VK_VIDEO_CODEC_OPERATION_DECODE_H265_BIT_KHR, + .chromaSubsampling = VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR, + .chromaBitDepth = VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR, + .lumaBitDepth = VK_VIDEO_COMPONENT_BIT_DEPTH_10_BIT_KHR, + }, + .codec.h265 = { + .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H265_PROFILE_INFO_KHR, + .stdProfileIdc = STD_VIDEO_H265_PROFILE_IDC_MAIN_10, + } + }; + /* *INDENT-ON* */ + + caps = gst_vulkan_video_profile_to_caps (&profile); + fail_unless (caps); + + fail_unless (gst_vulkan_video_profile_from_caps (&profile2, caps)); + fail_unless (profile2.profile.sType + == VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR); + fail_unless (profile2.profile.videoCodecOperation + == profile.profile.videoCodecOperation); + fail_unless (profile2.codec.h265.stdProfileIdc + == profile.codec.h265.stdProfileIdc); +} + +GST_END_TEST; + +GST_START_TEST (test_decoding_image) +{ + GstBufferPool *pool; + GstCaps *dec_caps; + GstBuffer *buffer = NULL; + GstFlowReturn ret; + /* *INDENT-OFF* */ + GstVulkanVideoProfile profile = { + .profile = { + .sType = VK_STRUCTURE_TYPE_VIDEO_PROFILE_INFO_KHR, + .pNext = &profile.codec, + .videoCodecOperation = VK_VIDEO_CODEC_OPERATION_DECODE_H264_BIT_KHR, + .chromaSubsampling = VK_VIDEO_CHROMA_SUBSAMPLING_420_BIT_KHR, + .chromaBitDepth = VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR, + .lumaBitDepth = VK_VIDEO_COMPONENT_BIT_DEPTH_8_BIT_KHR, + }, + .codec.h264 = { + .sType = VK_STRUCTURE_TYPE_VIDEO_DECODE_H264_PROFILE_INFO_KHR, + .stdProfileIdc = STD_VIDEO_H264_PROFILE_IDC_MAIN, + .pictureLayout = VK_VIDEO_DECODE_H264_PICTURE_LAYOUT_PROGRESSIVE_KHR, + } + }; + /* *INDENT-ON* */ + + if (!queue) + return; + + dec_caps = gst_vulkan_video_profile_to_caps (&profile); + fail_unless (dec_caps); + + pool = create_buffer_pool ("NV12", VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR, + dec_caps); + + gst_caps_unref (dec_caps); + + ret = gst_buffer_pool_acquire_buffer (pool, &buffer, NULL); + fail_unless (ret == GST_FLOW_OK); + gst_buffer_unref (buffer); + + gst_buffer_pool_set_active (pool, FALSE); + gst_object_unref (pool); +} + +GST_END_TEST; +#endif + +static Suite * +vkimagebufferpool_suite (void) +{ + Suite *s = suite_create ("vkimagebufferpool"); + TCase *tc_basic = tcase_create ("general"); + gboolean have_instance; + + suite_add_tcase (s, tc_basic); + tcase_add_checked_fixture (tc_basic, setup, teardown); + + /* FIXME: CI doesn't have a software vulkan renderer (and none exists currently) */ + instance = gst_vulkan_instance_new (); + have_instance = gst_vulkan_instance_open (instance, NULL); + gst_object_unref (instance); + if (have_instance) { + tcase_add_test (tc_basic, test_image); +#if GST_VULKAN_HAVE_VIDEO_EXTENSIONS + tcase_add_test (tc_basic, test_decoding_image); + tcase_add_test (tc_basic, test_vulkan_profiles); +#endif + } + + return s; +} + +GST_CHECK_MAIN (vkimagebufferpool); diff --git a/subprojects/gst-plugins-bad/tests/check/meson.build b/subprojects/gst-plugins-bad/tests/check/meson.build index 0c4568ca69..f8e96f72f8 100644 --- a/subprojects/gst-plugins-bad/tests/check/meson.build +++ b/subprojects/gst-plugins-bad/tests/check/meson.build @@ -93,6 +93,7 @@ base_tests = [ [['libs/av1parser.c'], false, [gstcodecparsers_dep]], [['libs/h264bitwriter.c'], false, [gstcodecparsers_dep]], [['libs/h265bitwriter.c'], false, [gstcodecparsers_dep]], + [['libs/vkformat.c'], not gstvulkan_dep.found(), [gstvulkan_dep]], [['libs/vkmemory.c'], not gstvulkan_dep.found(), [gstvulkan_dep]], [['elements/vkcolorconvert.c'], not gstvulkan_dep.found(), [gstvulkan_dep]], [['libs/vkwindow.c'], not gstvulkan_dep.found(), [gstvulkan_dep]], @@ -101,6 +102,7 @@ base_tests = [ [['libs/vkcommandpool.c'], not gstvulkan_dep.found(), [gstvulkan_dep]], [['libs/vkimage.c'], not gstvulkan_dep.found(), [gstvulkan_dep]], [['libs/vkinstance.c'], not gstvulkan_dep.found(), [gstvulkan_dep]], + [['libs/vkimagebufferpool.c'], not gstvulkan_dep.found(), [gstvulkan_dep]], [['libs/d3d11device.cpp'], not gstd3d11_dep.found(), [gstd3d11_dep]], [['libs/cudamemory.c'], not gstcuda_dep.found(), [gstcuda_dep, gstcuda_stub_dep]], ]