From patchwork Thu Sep 12 05:16:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Petro Mozil X-Patchwork-Id: 51541 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:612c:14c:b0:48e:c0f8:d0de with SMTP id h12csp750932vqi; Thu, 12 Sep 2024 00:44:14 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCUk+mLuqhn5rLiwdoSu1UX2Tl2Wz6+Sk5sQOF1ZkdY2NbcMRMYpJlf0cUsraqLc0I1EnBm/S9Mp+xDPVhGpuvya@gmail.com X-Google-Smtp-Source: AGHT+IFCh6z6Vdsc014/0JjHCwqlOyXxEQAJ3YHMjPoXPyPzPeMOtM7ben/wfSu3wrGTJi0QaUge X-Received: by 2002:a2e:b8ca:0:b0:2f7:77ff:d739 with SMTP id 38308e7fff4ca-2f787edf5ffmr8936091fa.26.1726127054117; Thu, 12 Sep 2024 00:44:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1726127054; cv=none; d=google.com; s=arc-20240605; b=fRNLjUOnjg+sVruY0mo1HZOJRIAIfMQR9SzQe00e3UEsMuJL0vIY01OFbjYe9/f6m9 eRy/7g6eEodrRS/1+/QyXNpNjqVuwa4C8xn00scAQzrdIb1ZTk4rIoG8oHisSEs9lrj6 bRytVsieysWGD/rgdpezpwtKaBI0B1uG+Mvn+9+vMoRGW+Yewt/S15OB6ar4FpFf+jQi MOrS67MBATBxB7/65xfMQPjEsrY1Mq03xvzbXKFVmaSo9u9A+gFFJMdZ54SLaf0+yC0n TUJCxkwM0drLiW3x+mKv6VzJRaV6M2CsItXMU3o14oCSv8O6p7o0MfJJqSkYtYboqRf9 7FPA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:message-id:date:to:from :dkim-signature:delivered-to; bh=bjMzCASFoUyGcUp97OwjehymbFB1pMPmAH/8T0+HsdI=; fh=m/VMXocG8Ut50td6LydymovRbX/ovRMjrhDjlJBrApg=; b=aF/K7AuWdH5rGHwMwn5Eoe6IfnnpHyMvHN0/MXdIf+5Qs+Jmd7hQLdvRtK1pPEi+kd eplagOxaBreVfF0TnYTmtJH0+d2AoX/+ab6EDUf/o8XYWlzy9v0ZAxky7IEbPuMH3vkv wzh9ZXoWkTU6R/MimkjpK547HvSMb6XK3UEA+kqybYe4pjubmQ54R1a1Nb3MZ2ePyJxq D3T5/K5svLRkzrOf+PuZCdRPz71DDxmEVGH1VQrZCF+TN+nUhfEB8OOPCY48lP375I/w MS+OX+/BsKHPG8q+Q6fGbW6lQ+QzZJpjyM9xtFmtCTyAtUsOxYer3NEKNAWMyCVVWtvH csUg==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20230601 header.b=gHq8l65S; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; dara=fail header.i=@gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id 38308e7fff4ca-2f77b600251si10730011fa.546.2024.09.12.00.44.13; Thu, 12 Sep 2024 00:44:14 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20230601 header.b=gHq8l65S; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com; dara=fail header.i=@gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 163D868DBC2; Thu, 12 Sep 2024 08:18:12 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ej1-f41.google.com (mail-ej1-f41.google.com [209.85.218.41]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 3CEE168D676 for ; Thu, 12 Sep 2024 08:18:05 +0300 (EEST) Received: by mail-ej1-f41.google.com with SMTP id a640c23a62f3a-a8a897bd4f1so70651966b.3 for ; Wed, 11 Sep 2024 22:18:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1726118284; x=1726723084; darn=ffmpeg.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=u77wqZl1vDeZaHDJOXp1hy7z9dAispm8mutkfsP3AkE=; b=gHq8l65Sg+IfQjG1sASVfjt7Kz/wGhpcgZs7WUW/gZ7yiUSiYY8TCcFFdlckeCJO2K 2ieJ8h06K8lPkxnX2Vhpo4kfg+RO93fzlg8HUoAkg3N5P1ChwbeqpYtLqqPajfhf3MHn XK/nTqRMtDkXuDP02fNGVJK7NVsu/Enfr1qlaSDOo2f8OrFbztSWaG6T+VOdgboeYa/o Zq17IY3Mt6lrezNPjpug5ACL3h67qjtcOJWFQVh7VolDhH0wYIhQUJqVAP8rvmCw3Ek6 Izm4aUYCcjLozJqENaOPZPy38tlB8Nf7SIhjbaYMfxJ0MdnQcyQqsFkuhA2Z6baxLfya 6Yfw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1726118284; x=1726723084; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=u77wqZl1vDeZaHDJOXp1hy7z9dAispm8mutkfsP3AkE=; b=tvvCXRdbOkMEs5FQ/9pd7zMO5E6U9ZvtPiYFrSH4+D1e83AD6vVetVeVz03zwadQlu s4cOtDzNwfmErlUzLuV5tsvRKdPRi5CRIbL6aeS06DySlObfEqQ8mcPvnxc8GiB5o90s 9jVnYfbGp77jl9DvsDm27PtcEr9tUWOTFh5B7UJRA80qhLz0L31vMEjk8kedLVSq48wL B+TlD/p+aGH2AWpvA35QyHhV/z4mi2XMnFi3R6tjt9+NurJkMTGv9iJpoucFil7nHV1L lcYhJ+ZRgZgl3zUpWzLUmcAnS1idaaMUqSpl2G69Nh2JAgqwJPxp2NvtHfecTtonGo+S s70A== X-Gm-Message-State: AOJu0Yzd17E9nltfVhPSVEXcRBqDIXLdxYR8icC+t6vgrBRSEz3h+Bij xE3CKwzeNrvoTAXDGjZ7tBdf6tMX2DDEg7ceESKT+5Ie5KGxEcZmmTYrkZIf X-Received: by 2002:a17:907:1b20:b0:a86:7e7f:69ab with SMTP id a640c23a62f3a-a90294f3dafmr148825066b.15.1726118283076; Wed, 11 Sep 2024 22:18:03 -0700 (PDT) Received: from localhost.localdomain (176-106-196-191.point.lviv.ua. [176.106.196.191]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a8d25d40b2esm698069566b.194.2024.09.11.22.18.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Sep 2024 22:18:02 -0700 (PDT) From: Petro Mozil To: ffmpeg-devel@ffmpeg.org Date: Thu, 12 Sep 2024 08:16:19 +0300 Message-ID: <20240912051619.133812-2-mozil.petryk@gmail.com> X-Mailer: git-send-email 2.46.0 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/2] lavu: Move vulkan_spirv to libavutil X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: Petro Mozil Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: djCe6fojX5P8 Lynne has pushed multiple changes to vulkan usage in FFmpeg, this is the patch with those changes. Main one is the move to ff_vk_init. Signed-off-by: Petro Mozil --- libavcodec/Makefile | 4 + libavcodec/vulkan_glslang.c | 19 +++ libavcodec/vulkan_shaderc.c | 19 +++ libavcodec/vulkan_spirv.h | 24 +++ libavfilter/vulkan_glslang.c | 266 +------------------------------- libavfilter/vulkan_shaderc.c | 111 +------------- libavfilter/vulkan_spirv.h | 23 +-- libavutil/Makefile | 4 + libavutil/vulkan_glslang.c | 283 +++++++++++++++++++++++++++++++++++ libavutil/vulkan_shaderc.c | 128 ++++++++++++++++ libavutil/vulkan_spirv.h | 45 ++++++ 11 files changed, 529 insertions(+), 397 deletions(-) create mode 100644 libavcodec/vulkan_glslang.c create mode 100644 libavcodec/vulkan_shaderc.c create mode 100644 libavcodec/vulkan_spirv.h create mode 100644 libavutil/vulkan_glslang.c create mode 100644 libavutil/vulkan_shaderc.c create mode 100644 libavutil/vulkan_spirv.h diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 1d27e554c8..b6243bbc82 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -995,6 +995,10 @@ OBJS-$(CONFIG_VIDEOTOOLBOX) += videotoolbox.o OBJS-$(CONFIG_VDPAU) += vdpau.o OBJS-$(CONFIG_VULKAN) += vulkan.o vulkan_video.o +# vulkan libs +OBJS-$(CONFIG_LIBGLSLANG) += vulkan_glslang.o +OBJS-$(CONFIG_LIBSHADERC) += vulkan_shaderc.o + OBJS-$(CONFIG_AV1_D3D11VA_HWACCEL) += dxva2_av1.o OBJS-$(CONFIG_AV1_DXVA2_HWACCEL) += dxva2_av1.o OBJS-$(CONFIG_AV1_D3D12VA_HWACCEL) += dxva2_av1.o d3d12va_av1.o diff --git a/libavcodec/vulkan_glslang.c b/libavcodec/vulkan_glslang.c new file mode 100644 index 0000000000..9aa41567a3 --- /dev/null +++ b/libavcodec/vulkan_glslang.c @@ -0,0 +1,19 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/vulkan_glslang.c" diff --git a/libavcodec/vulkan_shaderc.c b/libavcodec/vulkan_shaderc.c new file mode 100644 index 0000000000..9f60bf4dfd --- /dev/null +++ b/libavcodec/vulkan_shaderc.c @@ -0,0 +1,19 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/vulkan_shaderc.c" diff --git a/libavcodec/vulkan_spirv.h b/libavcodec/vulkan_spirv.h new file mode 100644 index 0000000000..a8aa10d46a --- /dev/null +++ b/libavcodec/vulkan_spirv.h @@ -0,0 +1,24 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_VULKAN_SPIRV_H +#define AVCODEC_VULKAN_SPIRV_H + +#include "libavutil/vulkan_spirv.h" + +#endif diff --git a/libavfilter/vulkan_glslang.c b/libavfilter/vulkan_glslang.c index 845a530ee0..9aa41567a3 100644 --- a/libavfilter/vulkan_glslang.c +++ b/libavfilter/vulkan_glslang.c @@ -16,268 +16,4 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include - -#include -#include - -#include "vulkan_spirv.h" -#include "libavutil/mem.h" -#include "libavutil/avassert.h" - -static pthread_mutex_t glslc_mutex = PTHREAD_MUTEX_INITIALIZER; -static int glslc_refcount = 0; - -static const glslang_resource_t glslc_resource_limits = { - .max_lights = 32, - .max_clip_planes = 6, - .max_texture_units = 32, - .max_texture_coords = 32, - .max_vertex_attribs = 64, - .max_vertex_uniform_components = 4096, - .max_varying_floats = 64, - .max_vertex_texture_image_units = 32, - .max_combined_texture_image_units = 80, - .max_texture_image_units = 32, - .max_fragment_uniform_components = 4096, - .max_draw_buffers = 32, - .max_vertex_uniform_vectors = 128, - .max_varying_vectors = 8, - .max_fragment_uniform_vectors = 16, - .max_vertex_output_vectors = 16, - .max_fragment_input_vectors = 15, - .min_program_texel_offset = -8, - .max_program_texel_offset = 7, - .max_clip_distances = 8, - .max_compute_work_group_count_x = 65535, - .max_compute_work_group_count_y = 65535, - .max_compute_work_group_count_z = 65535, - .max_compute_work_group_size_x = 1024, - .max_compute_work_group_size_y = 1024, - .max_compute_work_group_size_z = 64, - .max_compute_uniform_components = 1024, - .max_compute_texture_image_units = 16, - .max_compute_image_uniforms = 8, - .max_compute_atomic_counters = 8, - .max_compute_atomic_counter_buffers = 1, - .max_varying_components = 60, - .max_vertex_output_components = 64, - .max_geometry_input_components = 64, - .max_geometry_output_components = 128, - .max_fragment_input_components = 128, - .max_image_units = 8, - .max_combined_image_units_and_fragment_outputs = 8, - .max_combined_shader_output_resources = 8, - .max_image_samples = 0, - .max_vertex_image_uniforms = 0, - .max_tess_control_image_uniforms = 0, - .max_tess_evaluation_image_uniforms = 0, - .max_geometry_image_uniforms = 0, - .max_fragment_image_uniforms = 8, - .max_combined_image_uniforms = 8, - .max_geometry_texture_image_units = 16, - .max_geometry_output_vertices = 256, - .max_geometry_total_output_components = 1024, - .max_geometry_uniform_components = 1024, - .max_geometry_varying_components = 64, - .max_tess_control_input_components = 128, - .max_tess_control_output_components = 128, - .max_tess_control_texture_image_units = 16, - .max_tess_control_uniform_components = 1024, - .max_tess_control_total_output_components = 4096, - .max_tess_evaluation_input_components = 128, - .max_tess_evaluation_output_components = 128, - .max_tess_evaluation_texture_image_units = 16, - .max_tess_evaluation_uniform_components = 1024, - .max_tess_patch_components = 120, - .max_patch_vertices = 32, - .max_tess_gen_level = 64, - .max_viewports = 16, - .max_vertex_atomic_counters = 0, - .max_tess_control_atomic_counters = 0, - .max_tess_evaluation_atomic_counters = 0, - .max_geometry_atomic_counters = 0, - .max_fragment_atomic_counters = 8, - .max_combined_atomic_counters = 8, - .max_atomic_counter_bindings = 1, - .max_vertex_atomic_counter_buffers = 0, - .max_tess_control_atomic_counter_buffers = 0, - .max_tess_evaluation_atomic_counter_buffers = 0, - .max_geometry_atomic_counter_buffers = 0, - .max_fragment_atomic_counter_buffers = 1, - .max_combined_atomic_counter_buffers = 1, - .max_atomic_counter_buffer_size = 16384, - .max_transform_feedback_buffers = 4, - .max_transform_feedback_interleaved_components = 64, - .max_cull_distances = 8, - .max_combined_clip_and_cull_distances = 8, - .max_samples = 4, - .max_mesh_output_vertices_nv = 256, - .max_mesh_output_primitives_nv = 512, - .max_mesh_work_group_size_x_nv = 32, - .max_mesh_work_group_size_y_nv = 1, - .max_mesh_work_group_size_z_nv = 1, - .max_task_work_group_size_x_nv = 32, - .max_task_work_group_size_y_nv = 1, - .max_task_work_group_size_z_nv = 1, - .max_mesh_view_count_nv = 4, - .maxDualSourceDrawBuffersEXT = 1, - - .limits = { - .non_inductive_for_loops = 1, - .while_loops = 1, - .do_while_loops = 1, - .general_uniform_indexing = 1, - .general_attribute_matrix_vector_indexing = 1, - .general_varying_indexing = 1, - .general_sampler_indexing = 1, - .general_variable_indexing = 1, - .general_constant_matrix_vector_indexing = 1, - } -}; - -static int glslc_shader_compile(FFVkSPIRVCompiler *ctx, void *avctx, - FFVkSPIRVShader *shd, uint8_t **data, - size_t *size, const char *entrypoint, - void **opaque) -{ - const char *messages; - glslang_shader_t *glslc_shader; - glslang_program_t *glslc_program; - - static const glslang_stage_t glslc_stage[] = { - [VK_SHADER_STAGE_VERTEX_BIT] = GLSLANG_STAGE_VERTEX, - [VK_SHADER_STAGE_FRAGMENT_BIT] = GLSLANG_STAGE_FRAGMENT, - [VK_SHADER_STAGE_COMPUTE_BIT] = GLSLANG_STAGE_COMPUTE, - }; - - const glslang_input_t glslc_input = { - .language = GLSLANG_SOURCE_GLSL, - .stage = glslc_stage[shd->shader.stage], - .client = GLSLANG_CLIENT_VULKAN, - /* GLSLANG_TARGET_VULKAN_1_2 before 11.6 resulted in targeting 1.0 */ -#if (((GLSLANG_VERSION_MAJOR) > 11) || ((GLSLANG_VERSION_MAJOR) == 11 && \ - (((GLSLANG_VERSION_MINOR) > 6) || ((GLSLANG_VERSION_MINOR) == 6 && \ - ((GLSLANG_VERSION_PATCH) > 0))))) - .client_version = GLSLANG_TARGET_VULKAN_1_2, - .target_language_version = GLSLANG_TARGET_SPV_1_5, -#else - .client_version = GLSLANG_TARGET_VULKAN_1_1, - .target_language_version = GLSLANG_TARGET_SPV_1_3, -#endif - .target_language = GLSLANG_TARGET_SPV, - .code = shd->src.str, - .default_version = 460, - .default_profile = GLSLANG_NO_PROFILE, - .force_default_version_and_profile = false, - .forward_compatible = false, - .messages = GLSLANG_MSG_DEFAULT_BIT, - .resource = &glslc_resource_limits, - }; - - av_assert0(glslc_refcount); - - *opaque = NULL; - - if (!(glslc_shader = glslang_shader_create(&glslc_input))) - return AVERROR(ENOMEM); - - if (!glslang_shader_preprocess(glslc_shader, &glslc_input)) { - ff_vk_shader_print(avctx, shd, AV_LOG_WARNING); - av_log(avctx, AV_LOG_ERROR, "Unable to preprocess shader: %s (%s)!\n", - glslang_shader_get_info_log(glslc_shader), - glslang_shader_get_info_debug_log(glslc_shader)); - glslang_shader_delete(glslc_shader); - return AVERROR(EINVAL); - } - - if (!glslang_shader_parse(glslc_shader, &glslc_input)) { - ff_vk_shader_print(avctx, shd, AV_LOG_WARNING); - av_log(avctx, AV_LOG_ERROR, "Unable to parse shader: %s (%s)!\n", - glslang_shader_get_info_log(glslc_shader), - glslang_shader_get_info_debug_log(glslc_shader)); - glslang_shader_delete(glslc_shader); - return AVERROR(EINVAL); - } - - if (!(glslc_program = glslang_program_create())) { - glslang_shader_delete(glslc_shader); - return AVERROR(EINVAL); - } - - glslang_program_add_shader(glslc_program, glslc_shader); - - if (!glslang_program_link(glslc_program, GLSLANG_MSG_SPV_RULES_BIT | - GLSLANG_MSG_VULKAN_RULES_BIT)) { - ff_vk_shader_print(avctx, shd, AV_LOG_WARNING); - av_log(avctx, AV_LOG_ERROR, "Unable to link shader: %s (%s)!\n", - glslang_program_get_info_log(glslc_program), - glslang_program_get_info_debug_log(glslc_program)); - glslang_program_delete(glslc_program); - glslang_shader_delete(glslc_shader); - return AVERROR(EINVAL); - } - - glslang_program_SPIRV_generate(glslc_program, glslc_input.stage); - - messages = glslang_program_SPIRV_get_messages(glslc_program); - if (messages) { - ff_vk_shader_print(avctx, shd, AV_LOG_WARNING); - av_log(avctx, AV_LOG_WARNING, "%s\n", messages); - } else { - ff_vk_shader_print(avctx, shd, AV_LOG_VERBOSE); - } - - glslang_shader_delete(glslc_shader); - - *size = glslang_program_SPIRV_get_size(glslc_program) * sizeof(unsigned int); - *data = (void *)glslang_program_SPIRV_get_ptr(glslc_program); - *opaque = glslc_program; - - return 0; -} - -static void glslc_shader_free(FFVkSPIRVCompiler *ctx, void **opaque) -{ - if (!opaque || !*opaque) - return; - - av_assert0(glslc_refcount); - glslang_program_delete(*opaque); - *opaque = NULL; -} - -static void glslc_uninit(FFVkSPIRVCompiler **ctx) -{ - if (!ctx || !*ctx) - return; - - pthread_mutex_lock(&glslc_mutex); - if (glslc_refcount && (--glslc_refcount == 0)) - glslang_finalize_process(); - pthread_mutex_unlock(&glslc_mutex); - - av_freep(ctx); -} - -FFVkSPIRVCompiler *ff_vk_glslang_init(void) -{ - FFVkSPIRVCompiler *ret = av_mallocz(sizeof(*ret)); - if (!ret) - return NULL; - - ret->compile_shader = glslc_shader_compile; - ret->free_shader = glslc_shader_free; - ret->uninit = glslc_uninit; - - pthread_mutex_lock(&glslc_mutex); - if (!glslc_refcount++) { - if (!glslang_initialize_process()) { - av_freep(&ret); - glslc_refcount--; - } - } - pthread_mutex_unlock(&glslc_mutex); - - return ret; -} +#include "libavutil/vulkan_glslang.c" diff --git a/libavfilter/vulkan_shaderc.c b/libavfilter/vulkan_shaderc.c index 9e8a3d17ac..9f60bf4dfd 100644 --- a/libavfilter/vulkan_shaderc.c +++ b/libavfilter/vulkan_shaderc.c @@ -16,113 +16,4 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include - -#include "libavutil/mem.h" -#include "vulkan_spirv.h" - -static int shdc_shader_compile(FFVkSPIRVCompiler *ctx, void *avctx, - FFVkSPIRVShader *shd, uint8_t **data, - size_t *size, const char *entrypoint, - void **opaque) -{ - int loglevel, err, warn, ret; - const char *status, *message; - shaderc_compilation_result_t res; - static const char *shdc_result[] = { - [shaderc_compilation_status_success] = "success", - [shaderc_compilation_status_invalid_stage] = "invalid stage", - [shaderc_compilation_status_compilation_error] = "error", - [shaderc_compilation_status_internal_error] = "internal error", - [shaderc_compilation_status_null_result_object] = "no result", - [shaderc_compilation_status_invalid_assembly] = "invalid assembly", - }; - static const shaderc_shader_kind shdc_kind[] = { - [VK_SHADER_STAGE_VERTEX_BIT] = shaderc_glsl_vertex_shader, - [VK_SHADER_STAGE_FRAGMENT_BIT] = shaderc_glsl_fragment_shader, - [VK_SHADER_STAGE_COMPUTE_BIT] = shaderc_glsl_compute_shader, - }; - - shaderc_compile_options_t opts = shaderc_compile_options_initialize(); - *opaque = NULL; - if (!opts) - return AVERROR(ENOMEM); - - shaderc_compile_options_set_target_env(opts, shaderc_target_env_vulkan, - shaderc_env_version_vulkan_1_2); - shaderc_compile_options_set_target_spirv(opts, shaderc_spirv_version_1_5); - shaderc_compile_options_set_generate_debug_info(opts); - shaderc_compile_options_set_optimization_level(opts, - shaderc_optimization_level_performance); - - res = shaderc_compile_into_spv((shaderc_compiler_t)ctx->priv, - shd->src.str, strlen(shd->src.str), - shdc_kind[shd->shader.stage], - shd->name, entrypoint, opts); - shaderc_compile_options_release(opts); - - ret = shaderc_result_get_compilation_status(res); - err = shaderc_result_get_num_errors(res); - warn = shaderc_result_get_num_warnings(res); - message = shaderc_result_get_error_message(res); - - if (ret != shaderc_compilation_status_success && !err) - err = 1; - - loglevel = err ? AV_LOG_ERROR : warn ? AV_LOG_WARNING : AV_LOG_VERBOSE; - - ff_vk_shader_print(avctx, shd, loglevel); - if (message && (err || warn)) - av_log(avctx, loglevel, "%s\n", message); - status = ret < FF_ARRAY_ELEMS(shdc_result) ? shdc_result[ret] : "unknown"; - av_log(avctx, loglevel, "shaderc compile status '%s' (%d errors, %d warnings)\n", - status, err, warn); - - if (err > 0) - return AVERROR(EINVAL); - - *data = (uint8_t *)shaderc_result_get_bytes(res); - *size = shaderc_result_get_length(res); - *opaque = res; - - return 0; -} - -static void shdc_shader_free(FFVkSPIRVCompiler *ctx, void **opaque) -{ - if (!opaque || !*opaque) - return; - - shaderc_result_release((shaderc_compilation_result_t)*opaque); - *opaque = NULL; -} - -static void shdc_uninit(FFVkSPIRVCompiler **ctx) -{ - FFVkSPIRVCompiler *s; - - if (!ctx || !*ctx) - return; - - s = *ctx; - - shaderc_compiler_release((shaderc_compiler_t)s->priv); - av_freep(ctx); -} - -FFVkSPIRVCompiler *ff_vk_shaderc_init(void) -{ - FFVkSPIRVCompiler *ret = av_mallocz(sizeof(*ret)); - if (!ret) - return NULL; - - ret->compile_shader = shdc_shader_compile; - ret->free_shader = shdc_shader_free; - ret->uninit = shdc_uninit; - - ret->priv = (void *)shaderc_compiler_initialize(); - if (!ret->priv) - av_freep(&ret); - - return ret; -} +#include "libavutil/vulkan_shaderc.c" diff --git a/libavfilter/vulkan_spirv.h b/libavfilter/vulkan_spirv.h index 5638cd9696..f7b7743883 100644 --- a/libavfilter/vulkan_spirv.h +++ b/libavfilter/vulkan_spirv.h @@ -19,27 +19,6 @@ #ifndef AVFILTER_VULKAN_SPIRV_H #define AVFILTER_VULKAN_SPIRV_H -#include "libavutil/vulkan.h" +#include "libavutil/vulkan_spirv.h" -#include "vulkan.h" -#include "config.h" - -typedef struct FFVkSPIRVCompiler { - void *priv; - int (*compile_shader)(struct FFVkSPIRVCompiler *ctx, void *avctx, - struct FFVkSPIRVShader *shd, uint8_t **data, - size_t *size, const char *entrypoint, void **opaque); - void (*free_shader)(struct FFVkSPIRVCompiler *ctx, void **opaque); - void (*uninit)(struct FFVkSPIRVCompiler **ctx); -} FFVkSPIRVCompiler; - -#if CONFIG_LIBGLSLANG -FFVkSPIRVCompiler *ff_vk_glslang_init(void); -#define ff_vk_spirv_init ff_vk_glslang_init #endif -#if CONFIG_LIBSHADERC -FFVkSPIRVCompiler *ff_vk_shaderc_init(void); -#define ff_vk_spirv_init ff_vk_shaderc_init -#endif - -#endif /* AVFILTER_VULKAN_H */ diff --git a/libavutil/Makefile b/libavutil/Makefile index 6e6fa8d800..36c05276a1 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -208,6 +208,10 @@ OBJS-$(CONFIG_VULKAN) += hwcontext_vulkan.o vulkan.o OBJS-$(!CONFIG_VULKAN) += hwcontext_stub.o +# vulkan libs +OBJS-$(CONFIG_LIBGLSLANG) += vulkan_glslang.o +OBJS-$(CONFIG_LIBSHADERC) += vulkan_shaderc.o + OBJS += $(COMPAT_OBJS:%=../compat/%) # Windows resource file diff --git a/libavutil/vulkan_glslang.c b/libavutil/vulkan_glslang.c new file mode 100644 index 0000000000..845a530ee0 --- /dev/null +++ b/libavutil/vulkan_glslang.c @@ -0,0 +1,283 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include + +#include "vulkan_spirv.h" +#include "libavutil/mem.h" +#include "libavutil/avassert.h" + +static pthread_mutex_t glslc_mutex = PTHREAD_MUTEX_INITIALIZER; +static int glslc_refcount = 0; + +static const glslang_resource_t glslc_resource_limits = { + .max_lights = 32, + .max_clip_planes = 6, + .max_texture_units = 32, + .max_texture_coords = 32, + .max_vertex_attribs = 64, + .max_vertex_uniform_components = 4096, + .max_varying_floats = 64, + .max_vertex_texture_image_units = 32, + .max_combined_texture_image_units = 80, + .max_texture_image_units = 32, + .max_fragment_uniform_components = 4096, + .max_draw_buffers = 32, + .max_vertex_uniform_vectors = 128, + .max_varying_vectors = 8, + .max_fragment_uniform_vectors = 16, + .max_vertex_output_vectors = 16, + .max_fragment_input_vectors = 15, + .min_program_texel_offset = -8, + .max_program_texel_offset = 7, + .max_clip_distances = 8, + .max_compute_work_group_count_x = 65535, + .max_compute_work_group_count_y = 65535, + .max_compute_work_group_count_z = 65535, + .max_compute_work_group_size_x = 1024, + .max_compute_work_group_size_y = 1024, + .max_compute_work_group_size_z = 64, + .max_compute_uniform_components = 1024, + .max_compute_texture_image_units = 16, + .max_compute_image_uniforms = 8, + .max_compute_atomic_counters = 8, + .max_compute_atomic_counter_buffers = 1, + .max_varying_components = 60, + .max_vertex_output_components = 64, + .max_geometry_input_components = 64, + .max_geometry_output_components = 128, + .max_fragment_input_components = 128, + .max_image_units = 8, + .max_combined_image_units_and_fragment_outputs = 8, + .max_combined_shader_output_resources = 8, + .max_image_samples = 0, + .max_vertex_image_uniforms = 0, + .max_tess_control_image_uniforms = 0, + .max_tess_evaluation_image_uniforms = 0, + .max_geometry_image_uniforms = 0, + .max_fragment_image_uniforms = 8, + .max_combined_image_uniforms = 8, + .max_geometry_texture_image_units = 16, + .max_geometry_output_vertices = 256, + .max_geometry_total_output_components = 1024, + .max_geometry_uniform_components = 1024, + .max_geometry_varying_components = 64, + .max_tess_control_input_components = 128, + .max_tess_control_output_components = 128, + .max_tess_control_texture_image_units = 16, + .max_tess_control_uniform_components = 1024, + .max_tess_control_total_output_components = 4096, + .max_tess_evaluation_input_components = 128, + .max_tess_evaluation_output_components = 128, + .max_tess_evaluation_texture_image_units = 16, + .max_tess_evaluation_uniform_components = 1024, + .max_tess_patch_components = 120, + .max_patch_vertices = 32, + .max_tess_gen_level = 64, + .max_viewports = 16, + .max_vertex_atomic_counters = 0, + .max_tess_control_atomic_counters = 0, + .max_tess_evaluation_atomic_counters = 0, + .max_geometry_atomic_counters = 0, + .max_fragment_atomic_counters = 8, + .max_combined_atomic_counters = 8, + .max_atomic_counter_bindings = 1, + .max_vertex_atomic_counter_buffers = 0, + .max_tess_control_atomic_counter_buffers = 0, + .max_tess_evaluation_atomic_counter_buffers = 0, + .max_geometry_atomic_counter_buffers = 0, + .max_fragment_atomic_counter_buffers = 1, + .max_combined_atomic_counter_buffers = 1, + .max_atomic_counter_buffer_size = 16384, + .max_transform_feedback_buffers = 4, + .max_transform_feedback_interleaved_components = 64, + .max_cull_distances = 8, + .max_combined_clip_and_cull_distances = 8, + .max_samples = 4, + .max_mesh_output_vertices_nv = 256, + .max_mesh_output_primitives_nv = 512, + .max_mesh_work_group_size_x_nv = 32, + .max_mesh_work_group_size_y_nv = 1, + .max_mesh_work_group_size_z_nv = 1, + .max_task_work_group_size_x_nv = 32, + .max_task_work_group_size_y_nv = 1, + .max_task_work_group_size_z_nv = 1, + .max_mesh_view_count_nv = 4, + .maxDualSourceDrawBuffersEXT = 1, + + .limits = { + .non_inductive_for_loops = 1, + .while_loops = 1, + .do_while_loops = 1, + .general_uniform_indexing = 1, + .general_attribute_matrix_vector_indexing = 1, + .general_varying_indexing = 1, + .general_sampler_indexing = 1, + .general_variable_indexing = 1, + .general_constant_matrix_vector_indexing = 1, + } +}; + +static int glslc_shader_compile(FFVkSPIRVCompiler *ctx, void *avctx, + FFVkSPIRVShader *shd, uint8_t **data, + size_t *size, const char *entrypoint, + void **opaque) +{ + const char *messages; + glslang_shader_t *glslc_shader; + glslang_program_t *glslc_program; + + static const glslang_stage_t glslc_stage[] = { + [VK_SHADER_STAGE_VERTEX_BIT] = GLSLANG_STAGE_VERTEX, + [VK_SHADER_STAGE_FRAGMENT_BIT] = GLSLANG_STAGE_FRAGMENT, + [VK_SHADER_STAGE_COMPUTE_BIT] = GLSLANG_STAGE_COMPUTE, + }; + + const glslang_input_t glslc_input = { + .language = GLSLANG_SOURCE_GLSL, + .stage = glslc_stage[shd->shader.stage], + .client = GLSLANG_CLIENT_VULKAN, + /* GLSLANG_TARGET_VULKAN_1_2 before 11.6 resulted in targeting 1.0 */ +#if (((GLSLANG_VERSION_MAJOR) > 11) || ((GLSLANG_VERSION_MAJOR) == 11 && \ + (((GLSLANG_VERSION_MINOR) > 6) || ((GLSLANG_VERSION_MINOR) == 6 && \ + ((GLSLANG_VERSION_PATCH) > 0))))) + .client_version = GLSLANG_TARGET_VULKAN_1_2, + .target_language_version = GLSLANG_TARGET_SPV_1_5, +#else + .client_version = GLSLANG_TARGET_VULKAN_1_1, + .target_language_version = GLSLANG_TARGET_SPV_1_3, +#endif + .target_language = GLSLANG_TARGET_SPV, + .code = shd->src.str, + .default_version = 460, + .default_profile = GLSLANG_NO_PROFILE, + .force_default_version_and_profile = false, + .forward_compatible = false, + .messages = GLSLANG_MSG_DEFAULT_BIT, + .resource = &glslc_resource_limits, + }; + + av_assert0(glslc_refcount); + + *opaque = NULL; + + if (!(glslc_shader = glslang_shader_create(&glslc_input))) + return AVERROR(ENOMEM); + + if (!glslang_shader_preprocess(glslc_shader, &glslc_input)) { + ff_vk_shader_print(avctx, shd, AV_LOG_WARNING); + av_log(avctx, AV_LOG_ERROR, "Unable to preprocess shader: %s (%s)!\n", + glslang_shader_get_info_log(glslc_shader), + glslang_shader_get_info_debug_log(glslc_shader)); + glslang_shader_delete(glslc_shader); + return AVERROR(EINVAL); + } + + if (!glslang_shader_parse(glslc_shader, &glslc_input)) { + ff_vk_shader_print(avctx, shd, AV_LOG_WARNING); + av_log(avctx, AV_LOG_ERROR, "Unable to parse shader: %s (%s)!\n", + glslang_shader_get_info_log(glslc_shader), + glslang_shader_get_info_debug_log(glslc_shader)); + glslang_shader_delete(glslc_shader); + return AVERROR(EINVAL); + } + + if (!(glslc_program = glslang_program_create())) { + glslang_shader_delete(glslc_shader); + return AVERROR(EINVAL); + } + + glslang_program_add_shader(glslc_program, glslc_shader); + + if (!glslang_program_link(glslc_program, GLSLANG_MSG_SPV_RULES_BIT | + GLSLANG_MSG_VULKAN_RULES_BIT)) { + ff_vk_shader_print(avctx, shd, AV_LOG_WARNING); + av_log(avctx, AV_LOG_ERROR, "Unable to link shader: %s (%s)!\n", + glslang_program_get_info_log(glslc_program), + glslang_program_get_info_debug_log(glslc_program)); + glslang_program_delete(glslc_program); + glslang_shader_delete(glslc_shader); + return AVERROR(EINVAL); + } + + glslang_program_SPIRV_generate(glslc_program, glslc_input.stage); + + messages = glslang_program_SPIRV_get_messages(glslc_program); + if (messages) { + ff_vk_shader_print(avctx, shd, AV_LOG_WARNING); + av_log(avctx, AV_LOG_WARNING, "%s\n", messages); + } else { + ff_vk_shader_print(avctx, shd, AV_LOG_VERBOSE); + } + + glslang_shader_delete(glslc_shader); + + *size = glslang_program_SPIRV_get_size(glslc_program) * sizeof(unsigned int); + *data = (void *)glslang_program_SPIRV_get_ptr(glslc_program); + *opaque = glslc_program; + + return 0; +} + +static void glslc_shader_free(FFVkSPIRVCompiler *ctx, void **opaque) +{ + if (!opaque || !*opaque) + return; + + av_assert0(glslc_refcount); + glslang_program_delete(*opaque); + *opaque = NULL; +} + +static void glslc_uninit(FFVkSPIRVCompiler **ctx) +{ + if (!ctx || !*ctx) + return; + + pthread_mutex_lock(&glslc_mutex); + if (glslc_refcount && (--glslc_refcount == 0)) + glslang_finalize_process(); + pthread_mutex_unlock(&glslc_mutex); + + av_freep(ctx); +} + +FFVkSPIRVCompiler *ff_vk_glslang_init(void) +{ + FFVkSPIRVCompiler *ret = av_mallocz(sizeof(*ret)); + if (!ret) + return NULL; + + ret->compile_shader = glslc_shader_compile; + ret->free_shader = glslc_shader_free; + ret->uninit = glslc_uninit; + + pthread_mutex_lock(&glslc_mutex); + if (!glslc_refcount++) { + if (!glslang_initialize_process()) { + av_freep(&ret); + glslc_refcount--; + } + } + pthread_mutex_unlock(&glslc_mutex); + + return ret; +} diff --git a/libavutil/vulkan_shaderc.c b/libavutil/vulkan_shaderc.c new file mode 100644 index 0000000000..9e8a3d17ac --- /dev/null +++ b/libavutil/vulkan_shaderc.c @@ -0,0 +1,128 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "libavutil/mem.h" +#include "vulkan_spirv.h" + +static int shdc_shader_compile(FFVkSPIRVCompiler *ctx, void *avctx, + FFVkSPIRVShader *shd, uint8_t **data, + size_t *size, const char *entrypoint, + void **opaque) +{ + int loglevel, err, warn, ret; + const char *status, *message; + shaderc_compilation_result_t res; + static const char *shdc_result[] = { + [shaderc_compilation_status_success] = "success", + [shaderc_compilation_status_invalid_stage] = "invalid stage", + [shaderc_compilation_status_compilation_error] = "error", + [shaderc_compilation_status_internal_error] = "internal error", + [shaderc_compilation_status_null_result_object] = "no result", + [shaderc_compilation_status_invalid_assembly] = "invalid assembly", + }; + static const shaderc_shader_kind shdc_kind[] = { + [VK_SHADER_STAGE_VERTEX_BIT] = shaderc_glsl_vertex_shader, + [VK_SHADER_STAGE_FRAGMENT_BIT] = shaderc_glsl_fragment_shader, + [VK_SHADER_STAGE_COMPUTE_BIT] = shaderc_glsl_compute_shader, + }; + + shaderc_compile_options_t opts = shaderc_compile_options_initialize(); + *opaque = NULL; + if (!opts) + return AVERROR(ENOMEM); + + shaderc_compile_options_set_target_env(opts, shaderc_target_env_vulkan, + shaderc_env_version_vulkan_1_2); + shaderc_compile_options_set_target_spirv(opts, shaderc_spirv_version_1_5); + shaderc_compile_options_set_generate_debug_info(opts); + shaderc_compile_options_set_optimization_level(opts, + shaderc_optimization_level_performance); + + res = shaderc_compile_into_spv((shaderc_compiler_t)ctx->priv, + shd->src.str, strlen(shd->src.str), + shdc_kind[shd->shader.stage], + shd->name, entrypoint, opts); + shaderc_compile_options_release(opts); + + ret = shaderc_result_get_compilation_status(res); + err = shaderc_result_get_num_errors(res); + warn = shaderc_result_get_num_warnings(res); + message = shaderc_result_get_error_message(res); + + if (ret != shaderc_compilation_status_success && !err) + err = 1; + + loglevel = err ? AV_LOG_ERROR : warn ? AV_LOG_WARNING : AV_LOG_VERBOSE; + + ff_vk_shader_print(avctx, shd, loglevel); + if (message && (err || warn)) + av_log(avctx, loglevel, "%s\n", message); + status = ret < FF_ARRAY_ELEMS(shdc_result) ? shdc_result[ret] : "unknown"; + av_log(avctx, loglevel, "shaderc compile status '%s' (%d errors, %d warnings)\n", + status, err, warn); + + if (err > 0) + return AVERROR(EINVAL); + + *data = (uint8_t *)shaderc_result_get_bytes(res); + *size = shaderc_result_get_length(res); + *opaque = res; + + return 0; +} + +static void shdc_shader_free(FFVkSPIRVCompiler *ctx, void **opaque) +{ + if (!opaque || !*opaque) + return; + + shaderc_result_release((shaderc_compilation_result_t)*opaque); + *opaque = NULL; +} + +static void shdc_uninit(FFVkSPIRVCompiler **ctx) +{ + FFVkSPIRVCompiler *s; + + if (!ctx || !*ctx) + return; + + s = *ctx; + + shaderc_compiler_release((shaderc_compiler_t)s->priv); + av_freep(ctx); +} + +FFVkSPIRVCompiler *ff_vk_shaderc_init(void) +{ + FFVkSPIRVCompiler *ret = av_mallocz(sizeof(*ret)); + if (!ret) + return NULL; + + ret->compile_shader = shdc_shader_compile; + ret->free_shader = shdc_shader_free; + ret->uninit = shdc_uninit; + + ret->priv = (void *)shaderc_compiler_initialize(); + if (!ret->priv) + av_freep(&ret); + + return ret; +} diff --git a/libavutil/vulkan_spirv.h b/libavutil/vulkan_spirv.h new file mode 100644 index 0000000000..622fe68f95 --- /dev/null +++ b/libavutil/vulkan_spirv.h @@ -0,0 +1,45 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_VULKAN_SPIRV_H +#define AVUTIL_VULKAN_SPIRV_H + +#include "libavutil/vulkan.h" + +#include "config.h" +#include "vulkan.h" + +typedef struct FFVkSPIRVCompiler { + void *priv; + int (*compile_shader)(struct FFVkSPIRVCompiler *ctx, void *avctx, + struct FFVkSPIRVShader *shd, uint8_t **data, + size_t *size, const char *entrypoint, void **opaque); + void (*free_shader)(struct FFVkSPIRVCompiler *ctx, void **opaque); + void (*uninit)(struct FFVkSPIRVCompiler **ctx); +} FFVkSPIRVCompiler; + +#if CONFIG_LIBGLSLANG +FFVkSPIRVCompiler *ff_vk_glslang_init(void); +#define ff_vk_spirv_init ff_vk_glslang_init +#endif +#if CONFIG_LIBSHADERC +FFVkSPIRVCompiler *ff_vk_shaderc_init(void); +#define ff_vk_spirv_init ff_vk_shaderc_init +#endif + +#endif /* AVFILTER_VULKAN_H */