25 #define FN_CREATING(ctx, type, shortname, array, num) \ 26 static av_always_inline type *create_ ##shortname(ctx *dctx) \ 28 type **array, *sctx = av_mallocz(sizeof(*sctx)); \ 32 array = av_realloc_array(dctx->array, sizeof(*dctx->array), dctx->num + 1);\ 38 dctx->array = array; \ 39 dctx->array[dctx->num++] = sctx; \ 45 .r = VK_COMPONENT_SWIZZLE_IDENTITY,
46 .g = VK_COMPONENT_SWIZZLE_IDENTITY,
47 .b = VK_COMPONENT_SWIZZLE_IDENTITY,
48 .a = VK_COMPONENT_SWIZZLE_IDENTITY,
54 #define CASE(VAL) case VAL: return #VAL 62 CASE(VK_ERROR_OUT_OF_HOST_MEMORY);
63 CASE(VK_ERROR_OUT_OF_DEVICE_MEMORY);
64 CASE(VK_ERROR_INITIALIZATION_FAILED);
65 CASE(VK_ERROR_DEVICE_LOST);
66 CASE(VK_ERROR_MEMORY_MAP_FAILED);
67 CASE(VK_ERROR_LAYER_NOT_PRESENT);
68 CASE(VK_ERROR_EXTENSION_NOT_PRESENT);
69 CASE(VK_ERROR_FEATURE_NOT_PRESENT);
70 CASE(VK_ERROR_INCOMPATIBLE_DRIVER);
71 CASE(VK_ERROR_TOO_MANY_OBJECTS);
72 CASE(VK_ERROR_FORMAT_NOT_SUPPORTED);
73 CASE(VK_ERROR_FRAGMENTED_POOL);
74 CASE(VK_ERROR_SURFACE_LOST_KHR);
75 CASE(VK_ERROR_NATIVE_WINDOW_IN_USE_KHR);
76 CASE(VK_SUBOPTIMAL_KHR);
77 CASE(VK_ERROR_OUT_OF_DATE_KHR);
78 CASE(VK_ERROR_INCOMPATIBLE_DISPLAY_KHR);
79 CASE(VK_ERROR_VALIDATION_FAILED_EXT);
80 CASE(VK_ERROR_INVALID_SHADER_NV);
81 CASE(VK_ERROR_OUT_OF_POOL_MEMORY);
82 CASE(VK_ERROR_INVALID_EXTERNAL_HANDLE);
83 CASE(VK_ERROR_NOT_PERMITTED_EXT);
84 default:
return "Unknown error";
90 VkMemoryPropertyFlagBits req_flags,
void *alloc_extension,
91 VkMemoryPropertyFlagBits *mem_flags, VkDeviceMemory *mem)
95 VkPhysicalDeviceProperties props;
96 VkPhysicalDeviceMemoryProperties mprops;
99 VkMemoryAllocateInfo alloc_info = {
100 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
101 .pNext = alloc_extension,
105 vkGetPhysicalDeviceMemoryProperties(s->
hwctx->
phys_dev, &mprops);
108 if (req_flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
109 req->size =
FFALIGN(req->size, props.limits.minMemoryMapAlignment);
111 alloc_info.allocationSize = req->size;
115 for (
int i = 0;
i < mprops.memoryTypeCount;
i++) {
117 if (!(req->memoryTypeBits & (1 <<
i)))
121 if ((mprops.memoryTypes[
i].propertyFlags & req_flags) != req_flags)
135 alloc_info.memoryTypeIndex =
index;
139 if (ret != VK_SUCCESS) {
145 *mem_flags |= mprops.memoryTypes[
index].propertyFlags;
151 VkBufferUsageFlags
usage, VkMemoryPropertyFlagBits
flags)
158 VkBufferCreateInfo buf_spawn = {
159 .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
162 .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
167 VkBufferMemoryRequirementsInfo2 req_desc = {
168 .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,
170 VkMemoryDedicatedAllocateInfo ded_alloc = {
171 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
174 VkMemoryDedicatedRequirements ded_req = {
175 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
177 VkMemoryRequirements2 req = {
178 .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
183 if (ret != VK_SUCCESS) {
189 req_desc.buffer = buf->
buf;
191 vkGetBufferMemoryRequirements2(s->
hwctx->
act_dev, &req_desc, &req);
194 use_ded_mem = ded_req.prefersDedicatedAllocation |
195 ded_req.requiresDedicatedAllocation;
197 ded_alloc.buffer = buf->
buf;
199 err =
vk_alloc_mem(avctx, &req.memoryRequirements, flags,
200 use_ded_mem ? &ded_alloc : (
void *)ded_alloc.pNext,
206 if (ret != VK_SUCCESS) {
216 int nb_buffers,
int invalidate)
220 VkMappedMemoryRange *inval_list =
NULL;
223 for (
int i = 0;
i < nb_buffers;
i++) {
225 VK_WHOLE_SIZE, 0, (
void **)&mem[i]);
226 if (ret != VK_SUCCESS) {
236 for (
int i = 0;
i < nb_buffers;
i++) {
237 const VkMappedMemoryRange ival_buf = {
238 .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
239 .memory = buf[
i].
mem,
240 .size = VK_WHOLE_SIZE,
242 if (buf[
i].
flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)
245 (++inval_count)*
sizeof(*inval_list));
248 inval_list[inval_count - 1] = ival_buf;
252 ret = vkInvalidateMappedMemoryRanges(s->
hwctx->
act_dev, inval_count,
254 if (ret != VK_SUCCESS) {
270 VkMappedMemoryRange *flush_list =
NULL;
274 for (
int i = 0;
i < nb_buffers;
i++) {
275 const VkMappedMemoryRange flush_buf = {
276 .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
277 .memory = buf[
i].
mem,
278 .size = VK_WHOLE_SIZE,
280 if (buf[
i].
flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)
283 (++flush_count)*
sizeof(*flush_list));
286 flush_list[flush_count - 1] = flush_buf;
291 ret = vkFlushMappedMemoryRanges(s->
hwctx->
act_dev, flush_count,
293 if (ret != VK_SUCCESS) {
300 for (
int i = 0;
i < nb_buffers;
i++)
312 if (buf->
buf != VK_NULL_HANDLE)
314 if (buf->
mem != VK_NULL_HANDLE)
319 int offset,
int size, VkShaderStageFlagBits stage)
321 VkPushConstantRange *pc;
329 memset(pc, 0,
sizeof(*pc));
331 pc->stageFlags = stage;
349 .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
350 .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
351 .queueFamilyIndex = queue_family,
353 VkCommandBufferAllocateInfo cbuf_create = {
354 .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
355 .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
356 .commandBufferCount = nb_queues,
374 if (
ret != VK_SUCCESS) {
380 cbuf_create.commandPool = e->
pool;
384 if (
ret != VK_SUCCESS) {
390 for (
int i = 0;
i < nb_queues;
i++) {
423 VkCommandBufferBeginInfo cmd_start = {
424 .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
425 .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
430 VkFenceCreateInfo fence_spawn = {
431 .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
435 if (ret != VK_SUCCESS) {
449 if (ret != VK_SUCCESS) {
465 AVFrame *
frame, VkPipelineStageFlagBits in_wait_dst_flag)
505 (q->nb_frame_deps + 1) *
sizeof(*dst));
513 if (!q->frame_deps[q->nb_frame_deps]) {
528 VkSubmitInfo s_info = {
529 .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
530 .commandBufferCount = 1,
537 .pSignalSemaphores = e->
sem_sig,
542 if (ret != VK_SUCCESS) {
548 ret = vkQueueSubmit(q->
queue, 1, &s_info, q->
fence);
549 if (ret != VK_SUCCESS) {
568 if (!deps || !nb_deps)
578 for (
int i = 0;
i < nb_deps;
i++) {
644 "hardware frames context on the input.\n");
649 if (avctx->
inputs[0] != inlink)
728 if (!output_frames_ref) {
742 "frames: %d.\n", err);
775 VkSamplerCreateInfo sampler_info = {
776 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
778 .minFilter = sampler_info.magFilter,
779 .mipmapMode = unnorm_coords ? VK_SAMPLER_MIPMAP_MODE_NEAREST :
780 VK_SAMPLER_MIPMAP_MODE_LINEAR,
781 .addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE,
782 .addressModeV = sampler_info.addressModeU,
783 .addressModeW = sampler_info.addressModeU,
784 .anisotropyEnable = VK_FALSE,
785 .compareOp = VK_COMPARE_OP_NEVER,
786 .borderColor = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK,
787 .unnormalizedCoordinates = unnorm_coords,
790 VkSampler *sampler = create_sampler(s);
796 if (
ret != VK_SUCCESS) {
820 const int high = desc->
comp[0].
depth > 8;
821 return high ?
"rgba16f" :
"rgba8";
837 VkImageView *v, VkImage
img, VkFormat fmt,
838 const VkComponentMapping
map)
843 VkImageViewCreateInfo imgview_spawn = {
844 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
847 .viewType = VK_IMAGE_VIEW_TYPE_2D,
850 .subresourceRange = {
851 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
863 if (ret != VK_SUCCESS) {
889 const
char *
name, VkShaderStageFlags stage)
897 shd->
shader.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
898 shd->
shader.stage = stage;
903 GLSLC(0, #define IS_WITHIN(v1, v2) ((v1.x < v2.x) && (v1.y < v2.y)) );
917 "local_size_y = %i, local_size_z = %i) in;\n\n",
924 const char *p = shd->
src.str;
925 const char *start = p;
930 for (
int i = 0;
i < strlen(p);
i++) {
938 av_log(avctx, prio,
"Shader %s: \n%s", shd->
name, buf.str);
943 const char *entrypoint)
947 VkShaderModuleCreateInfo shader_create;
956 shd->
shader.pName = entrypoint;
974 shader_create.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
975 shader_create.pNext =
NULL;
976 shader_create.codeSize = res->
size;
977 shader_create.flags = 0;
978 shader_create.pCode = res->
data;
987 if (ret != VK_SUCCESS) {
994 shd->
name, shader_create.codeSize);
1007 [VK_DESCRIPTOR_TYPE_SAMPLER] = {
sizeof(VkDescriptorImageInfo),
"sampler", 1, 0, 0, 0, },
1008 [VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE] = {
sizeof(VkDescriptorImageInfo),
"texture", 1, 0, 1, 0, },
1009 [VK_DESCRIPTOR_TYPE_STORAGE_IMAGE] = {
sizeof(VkDescriptorImageInfo),
"image", 1, 1, 1, 0, },
1010 [VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT] = {
sizeof(VkDescriptorImageInfo),
"subpassInput", 1, 0, 0, 0, },
1011 [VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER] = {
sizeof(VkDescriptorImageInfo),
"sampler", 1, 0, 1, 0, },
1012 [VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER] = {
sizeof(VkDescriptorBufferInfo),
NULL, 1, 0, 0, 1, },
1013 [VK_DESCRIPTOR_TYPE_STORAGE_BUFFER] = {
sizeof(VkDescriptorBufferInfo),
"buffer", 0, 1, 0, 1, },
1014 [VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC] = {
sizeof(VkDescriptorBufferInfo),
NULL, 1, 0, 0, 1, },
1015 [VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC] = {
sizeof(VkDescriptorBufferInfo),
"buffer", 0, 1, 0, 1, },
1016 [VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER] = {
sizeof(VkBufferView),
"samplerBuffer", 1, 0, 0, 0, },
1017 [VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER] = {
sizeof(VkBufferView),
"imageBuffer", 1, 0, 0, 0, },
1022 int num,
int only_print_to_shader)
1025 VkDescriptorSetLayout *
layout;
1028 if (only_print_to_shader)
1037 memset(layout, 0,
sizeof(*layout));
1040 VkDescriptorSetLayoutCreateInfo desc_create_layout = { 0 };
1041 VkDescriptorSetLayoutBinding *desc_binding;
1043 desc_binding =
av_mallocz(
sizeof(*desc_binding)*num);
1047 for (
int i = 0;
i < num;
i++) {
1048 desc_binding[
i].binding =
i;
1049 desc_binding[
i].descriptorType = desc[
i].
type;
1050 desc_binding[
i].descriptorCount =
FFMAX(desc[
i].elems, 1);
1051 desc_binding[
i].stageFlags = desc[
i].
stages;
1052 desc_binding[
i].pImmutableSamplers = desc[
i].
samplers;
1055 desc_create_layout.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
1056 desc_create_layout.pBindings = desc_binding;
1057 desc_create_layout.bindingCount = num;
1059 ret = vkCreateDescriptorSetLayout(s->
hwctx->
act_dev, &desc_create_layout,
1062 if (ret != VK_SUCCESS) {
1070 for (
int i = 0;
i < num;
i++) {
1089 VkDescriptorUpdateTemplateCreateInfo *dt;
1090 VkDescriptorUpdateTemplateEntry *des_entries;
1093 des_entries =
av_mallocz(num*
sizeof(VkDescriptorUpdateTemplateEntry));
1097 for (
int i = 0;
i < num;
i++) {
1098 des_entries[
i].dstBinding =
i;
1099 des_entries[
i].descriptorType = desc[
i].
type;
1100 des_entries[
i].descriptorCount =
FFMAX(desc[
i].elems, 1);
1101 des_entries[
i].dstArrayElement = 0;
1113 memset(dt, 0,
sizeof(*dt));
1115 dt->sType = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO;
1116 dt->templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET;
1117 dt->descriptorSetLayout = *
layout;
1118 dt->pDescriptorUpdateEntries = des_entries;
1119 dt->descriptorUpdateEntryCount = num;
1126 for (
int i = 0;
i < num;
i++) {
1130 if (desc[
i].mem_layout)
1131 GLSLA(
", %s", desc[
i].mem_layout);
1144 GLSLA(
"%iD", desc[i].dimensions);
1150 else if (desc[i].elems > 0)
1151 GLSLA(
"[%i]", desc[i].elems);
1172 VkShaderStageFlagBits stage,
int offset,
1177 stage, offset, size, src);
1188 VkDescriptorPoolCreateInfo pool_create_info = {
1189 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
1195 ret = vkCreateDescriptorPool(s->
hwctx->
act_dev, &pool_create_info,
1198 if (ret != VK_SUCCESS) {
1206 VkDescriptorSetAllocateInfo alloc_info = {
1207 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1217 ret = vkAllocateDescriptorSets(s->
hwctx->
act_dev, &alloc_info,
1219 if (ret != VK_SUCCESS) {
1227 VkPipelineLayoutCreateInfo spawn_pipeline_layout = {
1228 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1235 ret = vkCreatePipelineLayout(s->
hwctx->
act_dev, &spawn_pipeline_layout,
1239 if (ret != VK_SUCCESS) {
1247 VkDescriptorUpdateTemplateCreateInfo *desc_template_info;
1257 ret = vkCreateDescriptorUpdateTemplate(s->
hwctx->
act_dev,
1261 av_free((
void *)desc_template_info->pDescriptorUpdateEntries);
1262 if (ret != VK_SUCCESS) {
1278 return create_pipeline(avctx->priv);
1287 VkComputePipelineCreateInfo pipe = {
1288 .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
1293 if (pl->
shaders[i]->
shader.stage & VK_SHADER_STAGE_COMPUTE_BIT) {
1303 ret = vkCreateComputePipelines(s->
hwctx->
act_dev, VK_NULL_HANDLE, 1, &pipe,
1305 if (ret != VK_SUCCESS) {
1311 pl->
bind_point = VK_PIPELINE_BIND_POINT_COMPUTE;
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
int ff_vk_add_exec_dep(AVFilterContext *avctx, FFVkExecContext *e, AVFrame *frame, VkPipelineStageFlagBits in_wait_dst_flag)
Adds a frame as a queue dependency.
ptrdiff_t const GLvoid GLenum usage
static enum AVPixelFormat pix_fmt
int ff_vk_init_pipeline_layout(AVFilterContext *avctx, VulkanPipeline *pl)
Initializes the pipeline layout after all shaders and descriptor sets have been finished.
void av_bprintf(AVBPrint *buf, const char *fmt,...)
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it...
int ff_vk_add_descriptor_set(AVFilterContext *avctx, VulkanPipeline *pl, SPIRVShader *shd, VulkanDescriptorSetBinding *desc, int num, int only_print_to_shader)
Adds a descriptor set to the shader and registers them in the pipeline.
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
This structure describes decoded (raw) audio or video data.
void ff_vk_filter_uninit(AVFilterContext *avctx)
VkPipelineShaderStageCreateInfo shader
ptrdiff_t const GLvoid * data
static void flush(AVCodecContext *avctx)
const char * ff_vk_shader_rep_fmt(enum AVPixelFormat pixfmt)
Gets the glsl format string for a pixel format.
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
VkDescriptorPoolSize * pool_size_desc
packed RGB 8:8:8, 24bpp, RGBRGB...
VkDescriptorUpdateTemplateCreateInfo * desc_template_info
int ff_vk_init_compute_pipeline(AVFilterContext *avctx, VulkanPipeline *pl)
Initializes a compute pipeline.
#define AV_PIX_FMT_RGBA64
int h
agreed upon image height
#define FN_CREATING(ctx, type, shortname, array, num)
VkDescriptorUpdateTemplate * desc_template
int ff_vk_create_imageview(AVFilterContext *avctx, FFVkExecContext *e, VkImageView *v, VkImage img, VkFormat fmt, const VkComponentMapping map)
Create an imageview.
int ff_vk_filter_config_output(AVFilterLink *outlink)
int width
The allocated dimensions of the frames in this pool.
AVBufferRef * hw_device_ctx
For filters which will create hardware frames, sets the device the filter should create them in...
VkDevice act_dev
Active device.
int ff_vk_start_exec_recording(AVFilterContext *avctx, FFVkExecContext *e)
Begin recording to the command buffer.
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
packed BGR 8:8:8, 32bpp, XBGRXBGR... X=unused/undefined
if it could not because there are no more frames
int av_bprint_finalize(AVBPrint *buf, char **ret_str)
Finalize a print buffer.
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame...
VkPushConstantRange * push_consts
AVFilterLink ** inputs
array of pointers to input links
static void destroy_imageview(void *opaque, uint8_t *data)
VkPipelineStageFlagBits * sem_wait_dst
int ff_vk_add_push_constant(AVFilterContext *avctx, VulkanPipeline *pl, int offset, int size, VkShaderStageFlagBits stage)
Define a push constant for a given stage into a pipeline.
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
packed RGB 8:8:8, 32bpp, RGBXRGBX... X=unused/undefined
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
void ff_vk_set_compute_shader_sizes(AVFilterContext *avctx, SPIRVShader *shd, int local_size[3])
Writes the workgroup size for a shader.
int ff_vk_filter_init(AVFilterContext *avctx)
static cqueue * cqueue_create(int size, int max_size)
packed ABGR 8:8:8:8, 32bpp, ABGRABGR...
void av_bprint_append_data(AVBPrint *buf, const char *data, unsigned size)
Append data to a print buffer.
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
#define AV_LOG_VERBOSE
Detailed information.
VulkanPipeline * bound_pl
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
static int vk_alloc_mem(AVFilterContext *avctx, VkMemoryRequirements *req, VkMemoryPropertyFlagBits req_flags, void *alloc_extension, VkMemoryPropertyFlagBits *mem_flags, VkDeviceMemory *mem)
int ff_vk_unmap_buffers(AVFilterContext *avctx, FFVkBuffer *buf, int nb_buffers, int flush)
Unmaps the buffer from userspace.
A link between two filters.
#define fc(width, name, range_min, range_max)
int ff_vk_filter_query_formats(AVFilterContext *avctx)
General lavfi IO functions.
const VkSampler * samplers
enum AVPixelFormat input_format
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
#define AV_BPRINT_SIZE_UNLIMITED
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
void av_bprint_init(AVBPrint *buf, unsigned size_init, unsigned size_max)
packed BGRA 8:8:8:8, 32bpp, BGRABGRA...
void * priv
private data for use by the filter
int ff_vk_create_buf(AVFilterContext *avctx, FFVkBuffer *buf, size_t size, VkBufferUsageFlags usage, VkMemoryPropertyFlagBits flags)
Create a VkBuffer with the specified parameters.
AVBufferRef * av_buffer_create(uint8_t *data, int size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
unsigned int scratch_size
void glslang_uninit(void)
VulkanPipeline ** pipelines
packed RGBA 8:8:8:8, 32bpp, RGBARGBA...
int w
agreed upon image width
static void free_pipeline(VulkanFilterContext *s, VulkanPipeline *pl)
VkSampler * ff_vk_init_sampler(AVFilterContext *avctx, int unnorm_coords, VkFilter filt)
Create a Vulkan sampler, will be auto-freed in ff_vk_filter_uninit()
AVBufferRef * hw_frames_ctx
For hwaccel pixel formats, this should be a reference to the AVHWFramesContext describing the frames...
int ff_vk_create_exec_ctx(AVFilterContext *avctx, FFVkExecContext **ctx)
Init an execution context for command recording and queue submission.
int ff_vk_submit_exec_queue(AVFilterContext *avctx, FFVkExecContext *e)
Submits a command buffer to the queue for execution.
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
VkDescriptorSet * desc_set
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
void ff_vk_free_buf(AVFilterContext *avctx, FFVkBuffer *buf)
Frees a buffer.
VkMemoryPropertyFlagBits flags
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
packed RGB 8:8:8, 24bpp, BGRBGR...
AVFilterContext * src
source filter
AVFrame * av_frame_clone(const AVFrame *src)
Create a new frame that references the same data as src.
void ff_vk_bind_pipeline_exec(AVFilterContext *avctx, FFVkExecContext *e, VulkanPipeline *pl)
Add a command to bind the completed pipeline and its descriptor sets.
GLSlangResult * glslang_compile(const char *glsl, enum GLSlangStage stage)
static int vulkan_filter_set_frames(AVFilterContext *avctx, AVBufferRef *frames)
const VkComponentMapping ff_comp_identity_map
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
int ff_vk_compile_shader(AVFilterContext *avctx, SPIRVShader *shd, const char *entrypoint)
Compiles the shader, entrypoint must be set to "main".
uint8_t * data
The data buffer.
int ff_vk_mt_is_np_rgb(enum AVPixelFormat pix_fmt)
Returns 1 if the image is any sort of supported RGB.
static const struct @324 planes[]
const char * ff_vk_ret2str(VkResult res)
Converts Vulkan return values to strings.
SPIRVShader * ff_vk_init_shader(AVFilterContext *avctx, VulkanPipeline *pl, const char *name, VkShaderStageFlags stage)
Inits a shader for a specific pipeline.
AVVulkanDeviceContext * hwctx
This struct describes a set or pool of "hardware" frames (i.e.
VulkanPipeline * ff_vk_create_pipeline(AVFilterContext *avctx)
Inits a pipeline.
packed BGR 8:8:8, 32bpp, BGRXBGRX... X=unused/undefined
VkShaderStageFlags stages
const VDPAUPixFmtMap * map
VkPipelineLayout pipeline_layout
VkCommandBuffer ff_vk_get_exec_buf(AVFilterContext *avctx, FFVkExecContext *e)
Gets the command buffer to use for this submission from the exe context.
void ff_vk_discard_exec_deps(AVFilterContext *avctx, FFVkExecContext *e)
Discards all queue dependencies.
static enum AVPixelFormat pix_fmts[]
#define AV_PIX_FMT_BGR565
#define flags(name, subs,...)
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
A reference to a data buffer.
VkDescriptorSetLayout * desc_layout
static const int8_t filt[NUMTAPS *2]
VkSemaphore sem[AV_NUM_DATA_POINTERS]
Synchronization semaphores.
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
enum AVPixelFormat output_format
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
int ff_vk_map_buffers(AVFilterContext *avctx, FFVkBuffer *buf, uint8_t *mem[], int nb_buffers, int invalidate)
Maps the buffer to userspace.
void ff_vk_update_push_exec(AVFilterContext *avctx, FFVkExecContext *e, VkShaderStageFlagBits stage, int offset, size_t size, void *src)
Updates push constants.
int ff_vk_filter_config_output_inplace(AVFilterLink *outlink)
VkDescriptorPool desc_pool
AVFilterContext * dst
dest filter
int ff_vk_filter_config_input(AVFilterLink *inlink)
enum AVPixelFormat pixfmt
VkPhysicalDevice phys_dev
Physical device.
#define AV_PIX_FMT_RGB565
static void print_shader(AVFilterContext *avctx, SPIRVShader *shd, int prio)
AVHWDeviceContext * device
VkPipelineBindPoint bind_point
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
int depth
Number of bits in the component.
static int create_exec_ctx(AVHWFramesContext *hwfc, VulkanExecCtx *cmd, int queue_family_index, int num_queues)
static void free_exec_ctx(VulkanFilterContext *s, FFVkExecContext *e)
FFVkExecContext ** exec_ctx
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
#define AVERROR_EXTERNAL
Generic error in an external library.
AVPixelFormat
Pixel format.
static int vulkan_filter_set_device(AVFilterContext *avctx, AVBufferRef *device)
int ff_vk_add_dep_exec_ctx(AVFilterContext *avctx, FFVkExecContext *e, AVBufferRef **deps, int nb_deps)
Adds a generic AVBufferRef as a queue depenency.
static void print(AVTreeNode *t, int depth)
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel layout
const VkAllocationCallbacks * alloc
Custom memory allocator, else NULL.
void ff_vk_update_descriptor_set(AVFilterContext *avctx, VulkanPipeline *pl, int set_id)
Updates a descriptor set via the updaters defined.