611 lines · 19.7 KB · C
RawDownload
/* * 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_H#define AVUTIL_VULKAN_H #define VK_NO_PROTOTYPES #include <stdatomic.h> #include "thread.h"#include "pixdesc.h"#include "bprint.h"#include "hwcontext.h"#include "vulkan_functions.h"#include "hwcontext_vulkan.h" /* GLSL management macros */#define INDENT(N) INDENT_##N#define INDENT_0#define INDENT_1 INDENT_0 "    "#define INDENT_2 INDENT_1 INDENT_1#define INDENT_3 INDENT_2 INDENT_1#define INDENT_4 INDENT_3 INDENT_1#define INDENT_5 INDENT_4 INDENT_1#define INDENT_6 INDENT_5 INDENT_1#define C(N, S)          INDENT(N) #S "\n" #define GLSLC(N, S)                     \    do {                                \        av_bprintf(&shd->src, C(N, S)); \    } while (0) #define GLSLA(...)                          \    do {                                    \        av_bprintf(&shd->src, __VA_ARGS__); \    } while (0) #define GLSLF(N, S, ...)                             \    do {                                             \        av_bprintf(&shd->src, C(N, S), __VA_ARGS__); \    } while (0) #define GLSLD(D)                                        \    do {                                                \        av_bprintf(&shd->src, "\n");                    \        av_bprint_append_data(&shd->src, D, strlen(D)); \        av_bprintf(&shd->src, "\n");                    \    } while (0) /* Helper, pretty much every Vulkan return value needs to be checked */#define RET(x)                                                                 \    do {                                                                       \        if ((err = (x)) < 0)                                                   \            goto fail;                                                         \    } while (0) #define DUP_SAMPLER(x) { x, x, x, x } typedef struct FFVulkanDescriptorSetBinding {    const char         *name;    VkDescriptorType    type;    const char         *mem_layout;  /* Storage images (rgba8, etc.) and buffers (std430, etc.) */    const char         *mem_quali;   /* readonly, writeonly, etc. */    const char         *buf_content; /* For buffers */    uint32_t            dimensions;  /* Needed for e.g. sampler%iD */    uint32_t            elems;       /* 0 - scalar, 1 or more - vector */    VkShaderStageFlags  stages;    VkSampler           samplers[4]; /* Sampler to use for all elems */} FFVulkanDescriptorSetBinding; typedef struct FFVkBuffer {    VkBuffer buf;    VkDeviceMemory mem;    VkMemoryPropertyFlagBits flags;    size_t size;    VkDeviceAddress address;     /* Local use only */    VkPipelineStageFlags2 stage;    VkAccessFlags2 access;     /* Only valid when allocated via ff_vk_get_pooled_buffer with HOST_VISIBLE */    uint8_t *mapped_mem;} FFVkBuffer; typedef struct FFVkExecContext {    uint32_t idx;    const struct FFVkExecPool *parent;    pthread_mutex_t lock;    int had_submission;     /* Queue for the execution context */    VkQueue queue;    int qf;    int qi;     /* Command buffer for the context */    VkCommandBuffer buf;     /* Fence for the command buffer */    VkFence fence;     /* Opaque data, untouched, free to use by users */    void *opaque;     void *query_data;    int query_idx;     /* Buffer dependencies */    AVBufferRef **buf_deps;    int nb_buf_deps;    unsigned int buf_deps_alloc_size;     /* Frame dependencies */    AVFrame **frame_deps;    unsigned int frame_deps_alloc_size;    int nb_frame_deps;     /* Software frame dependencies */    AVFrame **sw_frame_deps;    unsigned int sw_frame_deps_alloc_size;    int nb_sw_frame_deps;     VkSemaphoreSubmitInfo *sem_wait;    unsigned int sem_wait_alloc;    int sem_wait_cnt;     VkSemaphoreSubmitInfo *sem_sig;    unsigned int sem_sig_alloc;    int sem_sig_cnt;     uint64_t **sem_sig_val_dst;    unsigned int sem_sig_val_dst_alloc;    int sem_sig_val_dst_cnt;     uint8_t *frame_locked;    unsigned int frame_locked_alloc_size;     VkAccessFlagBits *access_dst;    unsigned int access_dst_alloc;     VkImageLayout *layout_dst;    unsigned int layout_dst_alloc;     uint32_t *queue_family_dst;    unsigned int queue_family_dst_alloc;     uint8_t *frame_update;    unsigned int frame_update_alloc_size;} FFVkExecContext; typedef struct FFVulkanDescriptorSet {    /* Descriptor buffer */    VkDeviceSize layout_size;    VkDeviceSize aligned_size; /* descriptorBufferOffsetAlignment */    VkBufferUsageFlags usage;     VkDescriptorSetLayoutBinding *binding;    VkDeviceSize *binding_offset;    int nb_bindings;     /* Descriptor set is shared between all submissions */    int singular;} FFVulkanDescriptorSet; typedef struct FFVulkanShader {    /* Name for id/debugging purposes */    const char *name;     /* Shader text */    AVBPrint src;     /* Compute shader local group sizes */    int lg_size[3];     /* Shader bind point/type */    VkPipelineStageFlags stage;    VkPipelineBindPoint bind_point;     /* Creation info */    VkPipelineShaderStageRequiredSubgroupSizeCreateInfo subgroup_info;     /* Base shader object */    VkShaderEXT object;    VkPipeline pipeline;     /* Pipeline layout */    VkPipelineLayout pipeline_layout;     /* Push consts */    VkPushConstantRange *push_consts;    int push_consts_num;     /* Descriptor sets */    FFVulkanDescriptorSet *desc_set;    int nb_descriptor_sets;     /* Descriptor buffer */    VkDescriptorSetLayout *desc_layout;    uint32_t *bound_buffer_indices;     /* Descriptor pool */    int use_push;    VkDescriptorPoolSize *desc_pool_size;    int nb_desc_pool_size;} FFVulkanShader; typedef struct FFVulkanDescriptorSetData {    /* Descriptor buffer */    FFVkBuffer buf;    uint8_t *desc_mem;} FFVulkanDescriptorSetData; typedef struct FFVulkanShaderData {    /* Shader to which this data belongs to */    FFVulkanShader *shd;    int nb_descriptor_sets;     /* Descriptor buffer */    FFVulkanDescriptorSetData *desc_set_buf;    VkDescriptorBufferBindingInfoEXT *desc_bind;     /* Descriptor pools */    VkDescriptorSet *desc_sets;    VkDescriptorPool desc_pool;} FFVulkanShaderData; typedef struct FFVkExecPool {    FFVkExecContext *contexts;    atomic_uint_least64_t idx;     VkCommandPool cmd_buf_pool;    VkCommandBuffer *cmd_bufs;    int pool_size;     VkQueryPool query_pool;    void *query_data;    int query_results;    int query_statuses;    int query_64bit;    int query_status_stride;    int nb_queries;    size_t qd_size;     /* Registered shaders' data */    FFVulkanShaderData *reg_shd;    int nb_reg_shd;} FFVkExecPool; typedef struct FFVulkanContext {    const AVClass *class;    void *log_parent;     FFVulkanFunctions     vkfn;    FFVulkanExtensions    extensions;    VkPhysicalDeviceProperties2 props;    VkPhysicalDeviceVulkan11Properties props_11;    VkPhysicalDeviceDriverProperties driver_props;    VkPhysicalDeviceMemoryProperties mprops;    VkPhysicalDeviceExternalMemoryHostPropertiesEXT hprops;    VkPhysicalDeviceDescriptorBufferPropertiesEXT desc_buf_props;    VkPhysicalDeviceSubgroupSizeControlProperties subgroup_props;    VkPhysicalDeviceCooperativeMatrixPropertiesKHR coop_matrix_props;    VkPhysicalDeviceOpticalFlowPropertiesNV optical_flow_props;    VkQueueFamilyQueryResultStatusPropertiesKHR *query_props;    VkQueueFamilyVideoPropertiesKHR *video_props;    VkQueueFamilyProperties2 *qf_props;    int tot_nb_qfs;     VkCooperativeMatrixPropertiesKHR *coop_mat_props;    uint32_t coop_mat_props_nb;     VkPhysicalDeviceShaderAtomicFloatFeaturesEXT atomic_float_feats;    VkPhysicalDeviceVulkan12Features feats_12;    VkPhysicalDeviceFeatures2 feats;     AVBufferRef           *device_ref;    AVHWDeviceContext     *device;    AVVulkanDeviceContext *hwctx;     AVBufferRef           *input_frames_ref;    AVBufferRef           *frames_ref;    AVHWFramesContext     *frames;    AVVulkanFramesContext *hwfc;     uint32_t               qfs[64];    int                    nb_qfs;     /* Properties */    int                 output_width;    int                output_height;    enum AVPixelFormat output_format;    enum AVPixelFormat  input_format;} FFVulkanContext; static inline int ff_vk_count_images(AVVkFrame *f){    int cnt = 0;    while (cnt < FF_ARRAY_ELEMS(f->img) && f->img[cnt])        cnt++;     return cnt;} static inline const void *ff_vk_find_struct(const void *chain, VkStructureType stype){    const VkBaseInStructure *in = chain;    while (in) {        if (in->sType == stype)            return in;         in = in->pNext;    }     return NULL;} static inline void ff_vk_link_struct(void *chain, const void *in){    VkBaseOutStructure *out = chain;    while (out->pNext)        out = out->pNext;     out->pNext = (void *)in;} /* Identity mapping - r = r, b = b, g = g, a = a */extern const VkComponentMapping ff_comp_identity_map; /** * Initializes the AVClass, in case this context is not used * as the main user's context. * May use either a frames context reference, or a device context reference. */int ff_vk_init(FFVulkanContext *s, void *log_parent,               AVBufferRef *device_ref, AVBufferRef *frames_ref); /** * Converts Vulkan return values to strings */const char *ff_vk_ret2str(VkResult res); /** * Returns 1 if pixfmt is a usable RGB format. */int ff_vk_mt_is_np_rgb(enum AVPixelFormat pix_fmt); /** * Get the aspect flag for a plane from an image. */VkImageAspectFlags ff_vk_aspect_flag(AVFrame *f, int p); /** * Returns the format to use for images in shaders. */enum FFVkShaderRepFormat {    /* Native format with no conversion. May require casting. */    FF_VK_REP_NATIVE = 0,    /* Float conversion of the native format. */    FF_VK_REP_FLOAT,    /* Signed integer version of the native format */    FF_VK_REP_INT,    /* Unsigned integer version of the native format */    FF_VK_REP_UINT,};const char *ff_vk_shader_rep_fmt(enum AVPixelFormat pix_fmt,                                 enum FFVkShaderRepFormat rep_fmt); /** * Loads props/mprops/driver_props */int ff_vk_load_props(FFVulkanContext *s); /** * Chooses an appropriate QF. */AVVulkanDeviceQueueFamily *ff_vk_qf_find(FFVulkanContext *s,                                         VkQueueFlagBits dev_family,                                         VkVideoCodecOperationFlagBitsKHR vid_ops); /** * Allocates/frees an execution pool. * If used in a multi-threaded context, there must be at least as many contexts * as there are threads. * ff_vk_exec_pool_init_desc() MUST be called if ff_vk_exec_descriptor_set_add() * has been called. */int ff_vk_exec_pool_init(FFVulkanContext *s, AVVulkanDeviceQueueFamily *qf,                         FFVkExecPool *pool, int nb_contexts,                         int nb_queries, VkQueryType query_type, int query_64bit,                         const void *query_create_pnext);void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool); /** * Retrieve an execution pool. Threadsafe. */FFVkExecContext *ff_vk_exec_get(FFVulkanContext *s, FFVkExecPool *pool); /** * Performs nb_queries queries and returns their results and statuses. * 64_BIT and WITH_STATUS flags are ignored as 64_BIT must be specified via * query_64bit in ff_vk_exec_pool_init() and WITH_STATUS is always enabled. */VkResult ff_vk_exec_get_query(FFVulkanContext *s, FFVkExecContext *e,                              void **data, VkQueryResultFlagBits flags); /** * Start/submit/wait an execution. * ff_vk_exec_start() always waits on a submission, so using ff_vk_exec_wait() * is not necessary (unless using it is just better). */int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e);int ff_vk_exec_submit(FFVulkanContext *s, FFVkExecContext *e);void ff_vk_exec_wait(FFVulkanContext *s, FFVkExecContext *e); /** * Execution dependency management. * Can attach buffers to executions that will only be unref'd once the * buffer has finished executing. * Adding a frame dep will *lock the frame*, until either the dependencies * are discarded, the execution is submitted, or a failure happens. * update_frame will update the frame's properties before it is unlocked, * only if submission was successful. */int ff_vk_exec_add_dep_buf(FFVulkanContext *s, FFVkExecContext *e,                           AVBufferRef **deps, int nb_deps, int ref);int ff_vk_exec_add_dep_bool_sem(FFVulkanContext *s, FFVkExecContext *e,                                VkSemaphore *sem, int nb,                                VkPipelineStageFlagBits2 stage,                                int wait); /* Ownership transferred if !wait */int ff_vk_exec_add_dep_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f,                             VkPipelineStageFlagBits2 wait_stage,                             VkPipelineStageFlagBits2 signal_stage);int ff_vk_exec_add_dep_sw_frame(FFVulkanContext *s, FFVkExecContext *e,                                AVFrame *f);void ff_vk_exec_update_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f,                             VkImageMemoryBarrier2 *bar, uint32_t *nb_img_bar);int ff_vk_exec_mirror_sem_value(FFVulkanContext *s, FFVkExecContext *e,                                VkSemaphore *dst, uint64_t *dst_val,                                AVFrame *f);void ff_vk_exec_discard_deps(FFVulkanContext *s, FFVkExecContext *e); /** * Create an imageview and add it as a dependency to an execution. */int ff_vk_create_imageviews(FFVulkanContext *s, FFVkExecContext *e,                            VkImageView views[AV_NUM_DATA_POINTERS],                            AVFrame *f, enum FFVkShaderRepFormat rep_fmt); void ff_vk_frame_barrier(FFVulkanContext *s, FFVkExecContext *e,                         AVFrame *pic, VkImageMemoryBarrier2 *bar, int *nb_bar,                         VkPipelineStageFlags src_stage,                         VkPipelineStageFlags dst_stage,                         VkAccessFlagBits     new_access,                         VkImageLayout        new_layout,                         uint32_t             new_qf); /** * Memory/buffer/image allocation helpers. */int ff_vk_alloc_mem(FFVulkanContext *s, VkMemoryRequirements *req,                    VkMemoryPropertyFlagBits req_flags, void *alloc_extension,                    VkMemoryPropertyFlagBits *mem_flags, VkDeviceMemory *mem);int ff_vk_create_buf(FFVulkanContext *s, FFVkBuffer *buf, size_t size,                     void *pNext, void *alloc_pNext,                     VkBufferUsageFlags usage, VkMemoryPropertyFlagBits flags);int ff_vk_create_avbuf(FFVulkanContext *s, AVBufferRef **ref, size_t size,                       void *pNext, void *alloc_pNext,                       VkBufferUsageFlags usage, VkMemoryPropertyFlagBits flags); /** * Buffer management code. */int ff_vk_map_buffers(FFVulkanContext *s, FFVkBuffer **buf, uint8_t *mem[],                      int nb_buffers, int invalidate);int ff_vk_unmap_buffers(FFVulkanContext *s, FFVkBuffer **buf, int nb_buffers,                        int flush); static inline int ff_vk_map_buffer(FFVulkanContext *s, FFVkBuffer *buf, uint8_t **mem,                                   int invalidate){    return ff_vk_map_buffers(s, (FFVkBuffer *[]){ buf }, mem,                             1, invalidate);}

Lines 1–500 of 611.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t