30#if HAVE_SPIRV_HEADERS_SPIRV_H || HAVE_SPIRV_UNIFIED1_SPIRV_H
54 if (
s->vkctx.device_ref &&
s->vkctx.device_ref->data != dev_ref->
data) {
57 }
else if (
s->vkctx.device_ref &&
s->vkctx.device_ref->data == dev_ref->
data) {
78 return s ?
s->vkctx.device_ref :
NULL;
81#define MAX_DITHER_BUFS 4
82#define MAX_FILT_BUFS 4
83#define MAX_DATA_BUFS (MAX_DITHER_BUFS + MAX_FILT_BUFS*4)
107 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
108 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT);
110 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
111 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT);
119 0, 0, VK_IMAGE_LAYOUT_GENERAL, VK_NULL_HANDLE);
121 0, 1, VK_IMAGE_LAYOUT_GENERAL, VK_NULL_HANDLE);
124 VkImageMemoryBarrier2 img_bar[8];
126 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
127 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
128 VK_ACCESS_SHADER_READ_BIT,
129 VK_IMAGE_LAYOUT_GENERAL,
130 VK_QUEUE_FAMILY_IGNORED);
132 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
133 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
134 VK_ACCESS_SHADER_WRITE_BIT,
135 VK_IMAGE_LAYOUT_GENERAL,
136 VK_QUEUE_FAMILY_IGNORED);
137 vk->CmdPipelineBarrier2(ec->
buf, &(VkDependencyInfo) {
138 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
139 .pImageMemoryBarriers = img_bar,
140 .imageMemoryBarrierCount = nb_img_bar,
146 VK_SHADER_STAGE_COMPUTE_BIT,
147 0,
sizeof(field), &field);
152 vk->CmdDispatch(ec->
buf,
153 FFALIGN(
dst->width, p->shd.lg_size[0])/p->shd.lg_size[0],
154 FFALIGN(
dst->height, p->shd.lg_size[1])/p->shd.lg_size[1],
166 for (
int i = 0;
i < p->nb_data_bufs;
i++)
181 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
182 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
183 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
189 (uint8_t **)&weights_data, 0);
215 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
216 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
217 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT);
226 for (
int i = 0;
i <
size;
i++) {
227 for (
int j = 0; j <
size; j++) {
246 for (
int n = 0; n < ops->
num_ops; n++) {
251 &p->data_bufs[p->nb_data_bufs]);
258 &p->data_bufs[p->nb_data_bufs]);
266 &p->data_bufs[p->nb_data_bufs]);
276 for (
int i = 0;
i < p->nb_data_bufs;
i++)
281#if HAVE_SPIRV_HEADERS_SPIRV_H || HAVE_SPIRV_UNIFIED1_SPIRV_H
311typedef struct SPIRVIDs {
345 int linear_deco_off[16];
346 int linear_deco_ops[16];
350 int dither_ptr_elem_id;
358 int out_img_array_id;
373 int push_const_struct_id;
374 int push_const_ptr_id;
375 int push_const_elem_ptr_id;
376 int push_const_var_id;
402 3 +
id->nb_dither_bufs +
id->nb_filter_bufs +
403 (
id->interlaced ? 1 : 0));
407 if (
id->interlaced) {
410 SpvDecorationOffset, 0);
415 SpvBuiltInGlobalInvocationId);
427 for (
int i = 0;
i <
id->nb_dither_bufs;
i++) {
431 id->dither[
i].size*
sizeof(
float));
436 id->dither[
i].binding);
439 for (
int i = 0;
i <
id->nb_filter_bufs;
i++) {
440 struct FilterData *
f = &
id->filt[
i];
444 f->filter_size*
sizeof(
float));
450 f->num_weights*
sizeof(
float));
459 for (
int n = 0; n < ops->
num_ops; n++) {
466 for (
int j = 0; j < 4; j++) {
467 nb_ops += !!
op->lin.m[j][0].num;
468 nb_ops +=
op->lin.m[j][0].num &&
op->lin.m[j][4].num;
469 for (
int i = 1;
i < 4;
i++) {
470 nb_ops += !!
op->lin.m[j][
i].num;
471 nb_ops +=
op->lin.m[j][
i].num &&
472 (
op->lin.m[j][0].num ||
op->lin.m[j][4].num);
476 id->linear_deco_off[
id->nb_linear_ops] =
spi_reserve(spi, nb_ops*4*3);
477 id->linear_deco_ops[
id->nb_linear_ops] = nb_ops;
484 SPICtx *spi, SPIRVIDs *
id)
490 id->u32_type = spi_OpTypeInt(spi, 32, 0);
491 id->i32_type = spi_OpTypeInt(spi, 32, 1);
493 id->f32_type = spi_OpTypeFloat(spi, 32);
497 id->bvec2_type = spi_OpTypeVector(spi,
id->b_type, 2);
498 id->u32vec2_type = spi_OpTypeVector(spi, u32_type, 2);
499 id->i32vec2_type = spi_OpTypeVector(spi,
id->i32_type, 2);
501 id->u32vec3_type = spi_OpTypeVector(spi, u32_type, 3);
503 id->u32vec4_type = spi_OpTypeVector(spi, u32_type, 4);
504 id->f32vec4_type = spi_OpTypeVector(spi, f32_type, 4);
505 id->f32mat4_type = spi_OpTypeMatrix(spi,
id->f32vec4_type, 4);
511 for (
int i = 0;
i < 5;
i++)
515 id->nb_const_ids = 0;
516 for (
int n = 0; n < ops->
num_ops; n++) {
528 id->const_ids[
id->nb_const_ids++] =
tmp;
532 for (
int i = 0;
i < 4;
i++) {
538 id->const_ids[
id->nb_const_ids++] =
542 id->const_ids[
id->nb_const_ids++] =
552 id->const_ids[
id->nb_const_ids++] =
tmp;
558 float q =
op->scale.factor.num/(
float)
op->scale.factor.den;
568 id->const_ids[
id->nb_const_ids++] =
tmp;
573 for (
int i = 0;
i < 4;
i++) {
576 if (!
op->clamp.limit[
i].den) {
585 id->const_ids[
id->nb_const_ids++] =
tmp;
589 for (
int i = 0;
i < 4;
i++) {
590 if (
op->dither.y_offset[
i] < 0)
593 id->const_ids[
id->nb_const_ids++] =
tmp;
599 for (
int i = 0;
i < 4;
i++) {
600 for (
int j = 0; j < 4; j++) {
604 id->const_ids[
id->nb_const_ids++] =
608 id->const_ids[
id->nb_const_ids - 4],
609 id->const_ids[
id->nb_const_ids - 3],
610 id->const_ids[
id->nb_const_ids - 2],
611 id->const_ids[
id->nb_const_ids - 1]);
612 id->const_ids[
id->nb_const_ids++] =
tmp;
616 id->const_ids[
id->nb_const_ids - 5*4 + 4],
617 id->const_ids[
id->nb_const_ids - 5*3 + 4],
618 id->const_ids[
id->nb_const_ids - 5*2 + 4],
619 id->const_ids[
id->nb_const_ids - 5*1 + 4]);
620 id->const_ids[
id->nb_const_ids++] =
tmp;
622 for (
int i = 0;
i < 4;
i++) {
624 id->const_ids[
id->nb_const_ids++] =
629 id->const_ids[
id->nb_const_ids - 4],
630 id->const_ids[
id->nb_const_ids - 3],
631 id->const_ids[
id->nb_const_ids - 2],
632 id->const_ids[
id->nb_const_ids - 1]);
633 id->const_ids[
id->nb_const_ids++] =
tmp;
643static void define_shader_bindings(
const SwsOpList *ops,
SPICtx *spi, SPIRVIDs *
id,
644 int in_img_count,
int out_img_count)
649 struct DitherData *
dither =
id->dither;
650 for (
int i = 0;
i <
id->nb_dither_bufs;
i++) {
659 SpvStorageClassUniform, 0);
663 id->filt_o_ptr_id = 0;
664 if (
id->nb_filter_bufs)
668 for (
int i = 0;
i <
id->nb_filter_bufs;
i++) {
669 struct FilterData *
f = &
id->filt[
i];
680 SpvStorageClassUniform, 0);
684 for (
int t = 1; t <
f->filter_size; t++)
694 id->f32_type :
id->u32_type,
695 2, 0, 0, 0, 2, SpvImageFormatUnknown);
697 id->u32_cid[out_img_count]);
700 id->in_img_array_id = 0;
706 id->in_img_type = match ?
id->out_img_type :
709 id->f32_type :
id->u32_type,
710 2, 0, 0, 0, 2, SpvImageFormatUnknown);
712 id->u32_cid[in_img_count]);
719 id->out_img_array_id);
727 id->in_img_array_id);
734 SpvStorageClassInput, 0);
737 SpvStorageClassUniformConstant, 0);
740 SpvStorageClassUniformConstant, 0);
742 if (
id->interlaced) {
745 id->push_const_struct_id);
749 SpvStorageClassPushConstant, 0);
753static int insert_vmat_linear(
const SwsOp *
op,
SPICtx *spi, SPIRVIDs *
id,
754 int data,
int const_off)
756 data = spi_OpMatrixTimesVector(spi,
id->f32vec4_type,
757 id->const_ids[const_off + 4*5],
759 return spi_OpFAdd(spi,
id->f32vec4_type,
760 id->const_ids[const_off + 4*5 + 1 + 4],
data);
763static int insert_bitexact_linear(
const SwsOp *
op,
SPICtx *spi, SPIRVIDs *
id,
764 int data,
int linear_ops_idx,
int const_off)
767 int type_v =
op->type ==
SWS_PIXEL_F32 ?
id->f32vec4_type :
id->u32vec4_type;
776 spi->
off =
id->linear_deco_off[linear_ops_idx];
777 for (
int i = 0;
i <
id->linear_deco_ops[linear_ops_idx];
i++)
782 for (
int j = 0; j < 4; j++) {
784 if (
op->lin.m[j][0].num)
785 res[j] = spi_OpFMul(spi, type_s,
tmp[0],
786 id->const_ids[const_off + j*5 + 0]);
788 if (
op->lin.m[j][0].num &&
op->lin.m[j][4].num)
789 res[j] = spi_OpFAdd(spi, type_s,
790 id->const_ids[const_off + 4*5 + 1 + j], res[j]);
791 else if (
op->lin.m[j][4].num)
792 res[j] =
id->const_ids[const_off + 4*5 + 1 + j];
794 for (
int i = 1;
i < 4;
i++) {
795 if (!
op->lin.m[j][
i].num)
798 int v = spi_OpFMul(spi, type_s,
tmp[
i],
799 id->const_ids[const_off + j*5 +
i]);
800 if (
op->lin.m[j][0].num ||
op->lin.m[j][4].num)
801 res[j] = spi_OpFAdd(spi, type_s, res[j], v);
808 res[0], res[1], res[2], res[3]);
811static int read_filtered(
SPICtx *spi, SPIRVIDs *
id,
const SwsOpList *ops,
812 const SwsOp *
op,
const struct FilterData *
f,
813 const int *in_img,
int gid,
int gi2)
819 const int read_vtype = src_float ?
id->f32vec4_type :
id->u32vec4_type;
826 id->u32_cid[1], axis);
827 int o =
spi_OpLoad(spi,
id->i32_type, o_ptr, SpvMemoryAccessMaskNone, 0);
835 if (src_interlaced && is_h) {
836 pos_y = spi_OpShiftLeftLogical(spi,
id->i32_type, pos_y,
id->u32_cid[1]);
837 pos_y = spi_OpIAdd(spi,
id->i32_type, pos_y,
id->field_i32);
841 int acc_s[4] = {
id->f32_0,
id->f32_0,
id->f32_0,
id->f32_0 };
842 int acc_v =
id->f32_0;
845 id->f32_0,
id->f32_0,
846 id->f32_0,
id->f32_0);
848 for (
int t = 0; t <
f->filter_size; t++) {
851 id->u32_cid[0], axis,
852 f->tap_const_base + t);
854 SpvMemoryAccessMaskNone, 0);
857 int c = t ? spi_OpIAdd(spi,
id->i32_type, o,
f->tap_const_base + t) : o;
860 if (src_interlaced && !is_h) {
861 c = spi_OpShiftLeftLogical(spi,
id->i32_type,
c,
id->u32_cid[1]);
862 c = spi_OpIAdd(spi,
id->i32_type,
c,
id->field_i32);
869 int px = spi_OpImageRead(spi, read_vtype,
870 in_img[ops->plane_src[0]], coord,
871 SpvImageOperandsMaskNone);
873 px = spi_OpConvertUToF(spi, id->f32vec4_type, px);
874 px = spi_OpVectorTimesScalar(spi, id->f32vec4_type, px, w);
875 acc_v = spi_OpFAdd(spi, id->f32vec4_type, acc_v, px);
877 for (int e = 0; e < op->rw.elems; e++) {
878 int px = spi_OpImageRead(spi, read_vtype,
879 in_img[ops->plane_src[e]], coord,
880 SpvImageOperandsMaskNone);
882 px = spi_OpCompositeExtract(spi, id->f32_type, px, 0);
884 px = spi_OpCompositeExtract(spi, id->u32_type, px, 0);
885 px = spi_OpConvertUToF(spi, id->f32_type, px);
887 px = spi_OpFMul(spi, id->f32_type, w, px);
888 acc_s[e] = spi_OpFAdd(spi, id->f32_type, acc_s[e], px);
896 acc_s[0], acc_s[1], acc_s[2], acc_s[3]);
901static int rw_op_img_count(
const SwsOp *
op,
const uint8_t *
planes)
912 uint8_t spvbuf[1024*16];
913 SPICtx spi_context = { 0 }, *spi = &spi_context;
914 SPIRVIDs spid_data = { 0 }, *
id = &spid_data;
915 spi_init(spi, spvbuf,
sizeof(spvbuf));
918 p->interlaced =
id->interlaced;
921 (uint32_t []) { 32, 32, 1 }, 0);
926 VK_SHADER_STAGE_COMPUTE_BIT);
930 int out_img_count = rw_op_img_count(op_w, ops->
plane_dst);
934 int in_img_count = op_r ? rw_op_img_count(op_r, ops->
plane_src) : 0;
940 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
941 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
945 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
946 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
964 id->nb_dither_bufs = 0;
965 id->nb_filter_bufs = 0;
966 int nb_data_bufs = 0;
967 for (
int n = 0; n < ops->
num_ops; n++) {
974 struct DitherData *d = &
id->dither[
id->nb_dither_bufs++];
975 d->size = 1 <<
op->dither.size_log2;
980 d->binding = nb_data_bufs;
986 struct FilterData *
f = &
id->filt[
id->nb_filter_bufs++];
987 f->filter =
op->rw.filter.op;
996 f->binding = nb_data_bufs;
1002 id->in_vars[3 + nb_data_bufs] = var_id;
1004 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1005 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1012 if (
id->interlaced) {
1015 id->in_vars[3 +
id->nb_dither_bufs +
id->nb_filter_bufs] =
1016 id->push_const_var_id;
1020 define_shader_header(sws, shd, ops, spi,
id);
1021 define_shader_consts(sws, ops, spi,
id);
1022 define_shader_bindings(ops, spi,
id, in_img_count, out_img_count);
1029 int in_img[4] = { 0 };
1030 for (
int i = 0;
i < in_img_count;
i++) {
1033 id->in_vars[1],
id->u32_cid[
i]);
1035 SpvMemoryAccessMaskNone, 0);
1039 int out_img[4] = { 0 };
1040 for (
int i = 0;
i < out_img_count;
i++) {
1042 id->in_vars[2],
id->u32_cid[
i]);
1044 SpvMemoryAccessMaskNone, 0);
1049 SpvMemoryAccessMaskNone, 0);
1053 int gi2 = spi_OpBitcast(spi,
id->i32vec2_type, gid);
1058 int dst_gid = gid, dst_gi2 = gi2;
1060 if (
id->interlaced) {
1062 id->push_const_var_id,
1064 int field_u32 =
spi_OpLoad(spi,
id->u32_type, field_u32_ptr,
1065 SpvMemoryAccessMaskNone, 0);
1066 id->field_i32 = spi_OpBitcast(spi,
id->i32_type, field_u32);
1068 int img_y_i32 = spi_OpShiftLeftLogical(spi,
id->i32_type,
1071 img_y_i32 = spi_OpIAdd(spi,
id->i32_type, img_y_i32,
id->field_i32);
1076 int mapped_gid = spi_OpBitcast(spi,
id->u32vec2_type, mapped_gi2);
1079 src_gid = mapped_gid;
1081 dst_gid = mapped_gid;
1082 dst_gi2 = mapped_gi2;
1087 int img1_s = spi_OpImageQuerySize(spi,
id->i32vec2_type, out_img[0]);
1088 int scmp = spi_OpSGreaterThanEqual(spi,
id->bvec2_type, dst_gi2, img1_s);
1089 scmp = spi_OpAny(spi,
id->b_type, scmp);
1104 id->f32_p,
id->f32_p,
1105 id->f32_p,
id->f32_p);
1108 id->u32_p,
id->u32_p,
1109 id->u32_p,
id->u32_p);
1112 int nb_const_ids = 0;
1113 int nb_dither_bufs = 0;
1114 int nb_linear_ops = 0;
1115 int nb_filter_used = 0;
1118 for (
int n = 0; n < ops->
num_ops; n++) {
1121 op->convert.to :
op->type;
1123 id->f32vec4_type :
id->u32vec4_type;
1125 id->f32_type :
id->u32_type;
1127 id->f32_p :
id->u32_p;
1133 }
else if (
op->rw.filter.op) {
1135 data = read_filtered(spi,
id, ops,
op,
1136 &
id->filt[nb_filter_used++],
1140 src_gid, SpvImageOperandsMaskNone);
1143 for (
int i = 0;
i <
op->rw.elems;
i++) {
1146 SpvImageOperandsMaskNone);
1156 if (
op->rw.frac ||
op->rw.filter.op) {
1160 SpvImageOperandsMaskNone);
1162 for (
int i = 0;
i <
op->rw.elems;
i++) {
1166 SpvImageOperandsMaskNone);
1171 for (
int i = 0;
i < 4;
i++) {
1175 id->const_ids[nb_const_ids++],
1188 data = spi_OpIMul(spi, type_v,
data,
id->const_ids[nb_const_ids++]);
1190 data = spi_OpConvertFToU(spi, type_v,
data);
1192 data = spi_OpConvertUToF(spi, type_v,
data);
1195 data = spi_OpShiftLeftLogical(spi, type_v,
data,
1196 id->const_ids[nb_const_ids++]);
1199 data = spi_OpShiftRightLogical(spi, type_v,
data,
1200 id->const_ids[nb_const_ids++]);
1204 data = spi_OpFMul(spi, type_v,
data,
1205 id->const_ids[nb_const_ids++]);
1207 data = spi_OpIMul(spi, type_v,
data,
1208 id->const_ids[nb_const_ids++]);
1213 op->op ==
SWS_OP_MIN ? GLSLstd450FMin : GLSLstd450FMax :
1214 op->op ==
SWS_OP_MIN ? GLSLstd450UMin : GLSLstd450UMax;
1215 for (
int i = 0;
i < 4;
i++) {
1216 if (!
op->clamp.limit[
i].den)
1220 tmp,
id->const_ids[nb_const_ids++]);
1226 int did = nb_dither_bufs++;
1229 x_id = spi_OpBitwiseAnd(spi,
id->u32_type, x_id,
1230 id->dither[did].mask_id);
1231 for (
int i = 0;
i < 4;
i++) {
1232 if (
op->dither.y_offset[
i] < 0)
1235 int y_id = spi_OpIAdd(spi,
id->u32_type, y_pos,
1236 id->const_ids[nb_const_ids++]);
1237 y_id = spi_OpBitwiseAnd(spi,
id->u32_type, y_id,
1238 id->dither[did].mask_id);
1241 id->dither[did].id,
id->u32_cid[0],
1244 SpvMemoryAccessMaskNone, 0);
1247 tmp = spi_OpFAdd(spi, type_s,
tmp,
val);
1254 data = insert_bitexact_linear(
op, spi,
id,
data, nb_linear_ops, nb_const_ids);
1256 data = insert_vmat_linear(
op, spi,
id,
data, nb_const_ids);
1258 nb_const_ids += 5*5 + 1;
1309#if HAVE_SPIRV_HEADERS_SPIRV_H || HAVE_SPIRV_UNIFIED1_SPIRV_H
1310 err = add_ops_spirv(sws, p,
s, ops, &p->shd);
1319 for (
int i = 0;
i < p->nb_data_bufs;
i++)
1321 1,
i, 0, &p->data_bufs[
i],
1322 0, VK_WHOLE_SIZE, VK_FORMAT_UNDEFINED);
1338#if HAVE_SPIRV_HEADERS_SPIRV_H || HAVE_SPIRV_UNIFIED1_SPIRV_H
1348 .compile = compile_spirv,
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
static double val(void *priv, double ch)
static const int8_t filt[NUMTAPS *2]
#define av_assert0(cond)
assert() equivalent, that is always enabled.
#define i(width, name, range_min, range_max)
#define AV_NUM_DATA_POINTERS
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
@ SWS_BACKEND_SPIRV
Vulkan SPIR-V backend.
static int op(uint8_t **dst, const uint8_t *dst_end, GetByteContext *gb, int pixel, int count, int *x, int width, int linesize)
Perform decode operation.
void ff_vk_shader_update_img_array(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd, AVFrame *f, VkImageView *views, int set, int binding, VkImageLayout layout, VkSampler sampler)
Update a descriptor in a buffer with an image array.
int ff_vk_shader_load(FFVulkanShader *shd, VkPipelineStageFlags stage, VkSpecializationInfo *spec, uint32_t wg_size[3], uint32_t required_subgroup_size)
Initialize a shader object.
void ff_vk_shader_add_descriptor_set(FFVulkanContext *s, FFVulkanShader *shd, const FFVulkanDescriptorSetBinding *desc, int nb, int singular)
Add descriptor to a shader.
void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool)
int ff_vk_create_buf(FFVulkanContext *s, FFVkBuffer *buf, size_t size, void *pNext, void *alloc_pNext, VkBufferUsageFlags usage, VkMemoryPropertyFlagBits flags)
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)
Allocates/frees an execution pool.
void ff_vk_exec_wait(FFVulkanContext *s, FFVkExecContext *e)
int ff_vk_shader_add_push_const(FFVulkanShader *shd, int offset, int size, VkShaderStageFlagBits stage)
Add/update push constants for execution.
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
int ff_vk_init(FFVulkanContext *s, void *log_parent, AVBufferRef *device_ref, AVBufferRef *frames_ref)
Initializes the AVClass, in case this context is not used as the main user's context.
void ff_vk_free_buf(FFVulkanContext *s, FFVkBuffer *buf)
void ff_vk_frame_barrier(FFVulkanContext *s, FFVkExecContext *e, AVFrame *pic, VkImageMemoryBarrier2 *bar, int *nb_bar, VkPipelineStageFlags2 src_stage, VkPipelineStageFlags2 dst_stage, VkAccessFlagBits2 new_access, VkImageLayout new_layout, uint32_t new_qf)
int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
Start/submit/wait an execution.
int ff_vk_create_imageviews(FFVulkanContext *s, FFVkExecContext *e, VkImageView views[AV_NUM_DATA_POINTERS], AVFrame *f, enum FFVkShaderRepFormat rep_fmt)
Create an imageview and add it as a dependency to an execution.
void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd)
Free a shader.
int ff_vk_shader_register_exec(FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd)
Register a shader with an exec pool.
FFVkExecContext * ff_vk_exec_get(FFVulkanContext *s, FFVkExecPool *pool)
Retrieve an execution pool.
int ff_vk_exec_submit(FFVulkanContext *s, FFVkExecContext *e)
void ff_vk_exec_bind_shader(FFVulkanContext *s, FFVkExecContext *e, const FFVulkanShader *shd)
Bind a shader.
int ff_vk_shader_update_desc_buffer(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd, int set, int bind, int elem, FFVkBuffer *buf, VkDeviceSize offset, VkDeviceSize len, VkFormat fmt)
Update a descriptor in a buffer with a buffer.
AVVulkanDeviceQueueFamily * ff_vk_qf_find(FFVulkanContext *s, VkQueueFlagBits dev_family, VkVideoCodecOperationFlagBitsKHR vid_ops)
Chooses an appropriate QF.
int ff_vk_shader_link(FFVulkanContext *s, FFVulkanShader *shd, const char *spirv, size_t spirv_len, const char *entrypoint)
Link a shader into an executable.
int ff_vk_exec_add_dep_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f, VkPipelineStageFlagBits2 wait_stage, VkPipelineStageFlagBits2 signal_stage)
void ff_vk_shader_update_push_const(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd, VkShaderStageFlagBits stage, int offset, size_t size, void *src)
Update push constant in a shader.
@ SWS_FILTER_SCALE
14-bit coefficients are picked to fit comfortably within int16_t for efficient SIMD processing (e....
static const struct @257111027162314367033347246032313251342043035002 planes[]
Memory handling functions.
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
const SwsOp * ff_sws_op_list_input(const SwsOpList *ops)
Returns the input operation for a given op list, or NULL if there is none (e.g.
int ff_sws_rw_op_planes(const SwsOp *op)
Return the number of planes involved in a read/write operation.
const SwsOp * ff_sws_op_list_output(const SwsOpList *ops)
Returns the output operation for a given op list, or NULL if there is none.
SwsOpType
Copyright (C) 2025 Niklas Haas.
@ SWS_RW_PLANAR
Note: 1-component reads are either SWS_RW_PLANAR or SWS_RW_PACKED, depending on the underlying interp...
static AVRational64 ff_sws_pixel_expand(SwsPixelType from, SwsPixelType to)
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
#define AV_PIX_FMT_X2BGR10
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
void * av_refstruct_ref(void *obj)
Create a new reference to an object managed via this API, i.e.
static void * av_refstruct_alloc_ext(size_t size, unsigned flags, void *opaque, void(*free_cb)(AVRefStructOpaque opaque, void *obj))
A wrapper around av_refstruct_alloc_ext_c() for the common case of a non-const qualified opaque.
#define FF_ARRAY_ELEMS(a)
static int spi_OpTypeFunction(SPICtx *spi, int return_type_id, const int *args, int nb_args)
static void spi_init(SPICtx *spi, uint8_t *spv_buf, int buf_len)
static int spi_OpVariable(SPICtx *spi, int var_id, int ptr_type_id, SpvStorageClass storage_class, int initializer_id)
static int spi_OpConstantUInt(SPICtx *spi, int type_id, uint32_t val)
static void spi_OpCapability(SPICtx *spi, SpvCapability capability)
static void spi_OpMemoryModel(SPICtx *spi, SpvAddressingModel addressing_model, SpvMemoryModel memory_model)
#define spi_OpCompositeExtract(spi, res_type, src,...)
#define spi_OpExtInst(spi, res_type, instr_id, set_id,...)
static void spi_OpFunctionEnd(SPICtx *spi)
static void spi_OpReturn(SPICtx *spi)
static int spi_OpImageRead(SPICtx *spi, int result_type_id, int img_id, int pos_id, SpvImageOperandsMask image_operands)
static int spi_OpTypeArray(SPICtx *spi, int element_type_id, int id, int length_id)
#define spi_OpMemberDecorate(spi, type, target, deco,...)
#define spi_OpTypeStruct(spi, id,...)
#define spi_OpDecorate(spi, target, deco,...)
static void spi_OpBranchConditional(SPICtx *spi, int cond_id, int true_label, int false_label, uint32_t branch_weights)
static int spi_OpTypeImage(SPICtx *spi, int sampled_type_id, SpvDim dim, int depth, int arrayed, int ms, int sampled, SpvImageFormat image_format)
static int spi_OpConstantFloat(SPICtx *spi, int type_id, float val)
#define spi_OpConstantComposite(spi, res_type, src,...)
static int spi_OpLoad(SPICtx *spi, int result_type_id, int ptr_id, SpvMemoryAccessMask memory_access, int align)
static void spi_OpExecutionMode(SPICtx *spi, int entry_point_id, SpvExecutionMode mode, int *s, int nb_s)
static int spi_OpConstantInt(SPICtx *spi, int type_id, int val)
static int spi_end(SPICtx *spi)
static int spi_OpLabel(SPICtx *spi, int label_id)
#define spi_OpAccessChain(spi, res_type, ptr_id,...)
static int spi_OpUndef(SPICtx *spi, int type_id)
static int spi_OpTypeBool(SPICtx *spi)
static int spi_OpTypePointer(SPICtx *spi, SpvStorageClass storage_class, int type_id)
#define spi_OpCompositeConstruct(spi, res_type, src,...)
static void spi_OpFunction(SPICtx *spi, int fn_id, int result_type_id, SpvFunctionControlMask function_control, int function_type_id)
#define spi_OpCompositeInsert(spi, res_type, src1, src2,...)
#define spi_OpVectorShuffle(spi, res_type, src1, src2,...)
static int spi_reserve(SPICtx *spi, int len)
static int spi_get_id(SPICtx *spi)
static int spi_OpExtInstImport(SPICtx *spi, const char *name)
static void spi_OpSelectionMerge(SPICtx *spi, int merge_block, SpvSelectionControlMask selection_control)
static int spi_OpEntryPoint(SPICtx *spi, SpvExecutionModel execution_model, const char *name, const int *args, int nb_args)
static int spi_OpTypeVoid(SPICtx *spi)
static void spi_OpImageWrite(SPICtx *spi, int img_id, int pos_id, int src_id, SpvImageOperandsMask image_operands)
A reference to a data buffer.
uint8_t * data
The data buffer.
This structure describes decoded (raw) audio or video data.
64-bit Rational number (pair of numerator and denominator).
Copyright (C) 2026 Lynne.
Main external API structure.
unsigned flags
Bitmask of SWS_*.
Represents a computed filter kernel.
int * weights
The computed look-up table (LUT).
int filter_size
The number of source texels to convolve over for each row.
int * offsets
The computed source pixel positions for each row of the filter.
Represents a view into a single field of frame data.
Helper struct for representing a list of operations.
Represents a single filter pass in the scaling graph.
FFVkBuffer data_bufs[MAX_DATA_BUFS]
enum FFVkShaderRepFormat src_rep
enum FFVkShaderRepFormat dst_rep
static SwsInternal * sws_internal(const SwsContext *sws)
void(* filter)(uint8_t *src, ptrdiff_t stride, int qscale)
RefStruct is an API for creating reference-counted objects with minimal overhead.
#define SWS_COMP_TEST(mask, X)
static av_const bool ff_sws_pixel_type_is_int(SwsPixelType type)
static const uint16_t dither[8][8]
static void process(NormalizeContext *s, AVFrame *in, AVFrame *out)
AVBufferRef * ff_sws_vk_device_ref(SwsContext *sws)
Returns the Vulkan device reference associated with sws, or NULL if Vulkan has not been initialized f...
static int compile(SwsContext *sws, const SwsOpList *ops, SwsCompiledOp *out)
static int create_filter_buf(FFVulkanOpsCtx *s, VulkanPriv *p, const SwsFilterWeights *wd, FFVkBuffer *buf)
static void ff_sws_vk_uninit(AVRefStructOpaque opaque, void *obj)
Copyright (C) 2026 Lynne.
static void free_fn(void *priv)
static void process(const SwsFrame *dst, const SwsFrame *src, int y, int h, const SwsPass *pass)
static int create_dither_buf(FFVulkanOpsCtx *s, VulkanPriv *p, const SwsDitherOp *dd, FFVkBuffer *buf)
int ff_sws_vk_init(SwsContext *sws, AVBufferRef *dev_ref)
static int create_bufs(FFVulkanOpsCtx *s, VulkanPriv *p, const SwsOpList *ops)
FFVkShaderRepFormat
Returns the format to use for images in shaders.
static int ff_vk_unmap_buffer(FFVulkanContext *s, FFVkBuffer *buf, int flush)
static int ff_vk_map_buffer(FFVulkanContext *s, FFVkBuffer *buf, uint8_t **mem, int invalidate)