FFmpeg
spvasm.h
Go to the documentation of this file.
1 /**
2  * Copyright (C) 2026 Lynne
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #ifndef SWSCALE_VULKAN_SPVASM_H
22 #define SWSCALE_VULKAN_SPVASM_H
23 
24 #include <stdint.h>
25 #include <string.h>
26 #include "config.h"
27 
28 #include "libavutil/intreadwrite.h"
29 #include "libavutil/avassert.h"
30 
31 #if HAVE_SPIRV_HEADERS_SPIRV_H
32 #include <spirv-headers/spirv.h>
33 #include <spirv-headers/GLSL.std.450.h>
34 #endif
35 
36 #if HAVE_SPIRV_UNIFIED1_SPIRV_H
37 #include <spirv/unified1/spirv.h>
38 #include <spirv/unified1/GLSL.std.450.h>
39 #endif
40 
41 /* COUNT_ARGS: counts variadic macro arguments, including zero.
42  * The sentinel 0 is prepended so the compound literal is never empty,
43  * making this valid in strict C11. */
44 #define COUNT_ARGS_IMPL(...) (sizeof((int[]){__VA_ARGS__}) / sizeof(int))
45 #define COUNT_ARGS(...) (COUNT_ARGS_IMPL(0, __VA_ARGS__) - 1)
46 
47 /* SPI_ARGS: produces a (const int *, int) pair for the _arr helper functions.
48  * When __VA_ARGS__ is empty the array literal is (int[]){0} and nb is 0,
49  * so the pointer exists but is never dereferenced. */
50 #define SPI_ARGS(...) ((int[]){0, __VA_ARGS__}) + 1, COUNT_ARGS(__VA_ARGS__)
51 
52 typedef struct SPICtx {
53  uint8_t *dst;
54  int dst_size;
55  int off;
56  int overwrite;
57 
59  int id;
60 } SPICtx;
61 
62 static inline void spi_write_u32(SPICtx *spi, uint32_t v)
63 {
64  if ((spi->off + 4) > spi->dst_size) {
65  spi->overwrite += 4;
66  } else {
67  AV_WL32(&spi->dst[spi->off], v);
68  spi->off += 4;
69  }
70 }
71 
72 static void spi_put_str(SPICtx *spi, const char *str)
73 {
74  if ((spi->off + strlen(str) + 4) > spi->dst_size) {
75  spi->overwrite += strlen(str) + 4;
76  return;
77  }
78 
79  for (int i = 0; i < strlen(str) + 1; i++)
80  spi->dst[spi->off++] = str[i];
81  int padding = (4 - (spi->off & 3)) & 3;
82  for (int i = 0; i < padding; i++)
83  spi->dst[spi->off++] = 0;
84 }
85 
86 static inline void spi_init(SPICtx *spi, uint8_t *spv_buf, int buf_len)
87 {
88  spi->id = 1;
89  spi->off = 0;
90  spi->overwrite = 0;
91  spi->dst = spv_buf;
92  spi->dst_size = buf_len;
93  spi_write_u32(spi, SpvMagicNumber);
94  spi_write_u32(spi, (1 << 16) | (6 << 8)); /* version */
95  spi_write_u32(spi, 0); /* generator */
96  spi_write_u32(spi, 0); /* last bound ID + 1, rewritten */
97  spi_write_u32(spi, 0); /* schema */
98 }
99 
100 static inline int spi_end(SPICtx *spi)
101 {
102  if (spi->overwrite)
103  return -spi->overwrite;
104  AV_WL32(spi->dst + 3*4, spi->id);
105  return spi->off;
106 }
107 
108 static inline int spi_reserve(SPICtx *spi, int len)
109 {
110  int off = spi->off;
111  if ((off + len) > spi->dst_size) {
112  spi->overwrite += len;
113  return 0;
114  }
115  spi->off += len;
116  return off;
117 }
118 
119 static inline void spi_OpCapability(SPICtx *spi, SpvCapability capability)
120 {
121  spi_write_u32(spi, (2 << 16) | 17);
122  spi_write_u32(spi, capability);
123 }
124 
125 static inline void spi_OpMemoryModel(SPICtx *spi, SpvAddressingModel addressing_model,
126  SpvMemoryModel memory_model)
127 {
128  spi_write_u32(spi, (3 << 16) | 14);
129  spi_write_u32(spi, addressing_model);
130  spi_write_u32(spi, memory_model);
131 }
132 
133 static int spi_get_id(SPICtx *spi)
134 {
135  return spi->id++;
136 }
137 
138 static int spi_strl(const char *str)
139 {
140  return FFALIGN(strlen(str) + 1, 4) >> 2;
141 }
142 
143 /* Template: Single source */
144 static inline void spi_op_1src(SPICtx *spi, int code, int src1_id)
145 {
146  spi_write_u32(spi, (2 << 16) | code);
147  spi_write_u32(spi, src1_id);
148 }
149 #define OP_1SRC(name, code) \
150 static inline void spi_ ## name(SPICtx *spi, int src1_id) \
151 { \
152  spi_op_1src(spi, code, src1_id); \
153 }
154 
155 /* Template: Single source, untyped result */
156 static inline int spi_op_untypedres_1src(SPICtx *spi, int code, int id,
157  int src1_id)
158 {
159  spi_write_u32(spi, (3 << 16) | code);
160  spi_write_u32(spi, id);
161  spi_write_u32(spi, src1_id);
162  return id;
163 }
164 #define OP_UNTYPEDRES1SRC(name, code) \
165 static inline int spi_ ## name(SPICtx *spi, int src1_id) \
166 { \
167  return spi_op_untypedres_1src(spi, code, spi_get_id(spi), src1_id); \
168 }
169 
170 /* Template: Single source, typed result */
171 static inline int spi_op_res_1src(SPICtx *spi, int code, int id, int type_id,
172  int src1_id)
173 {
174  spi_write_u32(spi, (4 << 16) | code);
175  spi_write_u32(spi, type_id);
176  spi_write_u32(spi, id);
177  spi_write_u32(spi, src1_id);
178  return id;
179 }
180 #define OP_RES1SRC(name, code) \
181 static inline int spi_ ## name(SPICtx *spi, int type_id, int src1_id) \
182 { \
183  return spi_op_res_1src(spi, code, spi_get_id(spi), type_id, src1_id); \
184 }
185 
186 /* Template: Two sources */
187 static inline void spi_op_2src(SPICtx *spi, int code, int src1_id, int src2_id)
188 {
189  spi_write_u32(spi, (3 << 16) | code);
190  spi_write_u32(spi, src1_id);
191  spi_write_u32(spi, src2_id);
192 }
193 #define OP_2SRC(name, code) \
194 static inline void spi_ ## name(SPICtx *spi, int src1_id, int src2_id) \
195 { \
196  spi_op_2src(spi, code, src1_id, src2_id); \
197 }
198 
199 /* Template: Two sources, untyped result */
200 static inline int spi_op_untypedres_2src(SPICtx *spi, int code, int id,
201  int src1_id, int src2_id)
202 {
203  spi_write_u32(spi, (4 << 16) | code);
204  spi_write_u32(spi, id);
205  spi_write_u32(spi, src1_id);
206  spi_write_u32(spi, src2_id);
207  return id;
208 }
209 #define OP_UNTYPEDRES2SRC(name, code) \
210 static inline int spi_ ## name(SPICtx *spi, int src1_id, int src2_id) \
211 { \
212  return spi_op_untypedres_2src(spi, code, spi_get_id(spi), \
213  src1_id, src2_id); \
214 }
215 
216 /* Template: Two sources, typed result */
217 static inline int spi_op_res_2src(SPICtx *spi, int code, int id, int type_id,
218  int src1_id, int src2_id)
219 {
220  spi_write_u32(spi, (5 << 16) | code);
221  spi_write_u32(spi, type_id);
222  spi_write_u32(spi, id);
223  spi_write_u32(spi, src1_id);
224  spi_write_u32(spi, src2_id);
225  return id;
226 }
227 #define OP_RES2SRC(name, code) \
228 static inline int spi_ ## name(SPICtx *spi, int type_id, int src1_id, int src2_id) \
229 { \
230  return spi_op_res_2src(spi, code, spi_get_id(spi), type_id, \
231  src1_id, src2_id); \
232 }
233 
234 /* Template: Single source, typed result, list */
235 static inline int spi_op_res_1src_list(SPICtx *spi, int code, int id, int type_id,
236  int src1_id, const int *args, int nb_args)
237 {
238  spi_write_u32(spi, ((4 + nb_args) << 16) | code);
239  spi_write_u32(spi, type_id);
240  spi_write_u32(spi, id);
241  spi_write_u32(spi, src1_id);
242  for (int i = 0; i < nb_args; i++)
243  spi_write_u32(spi, args[i]);
244  return id;
245 }
246 
247 /* Template: No sources, untyped result, list */
248 static inline void spi_op_untypedres_list(SPICtx *spi, int code,
249  int id, const int *args, int nb_args)
250 {
251  spi_write_u32(spi, ((2 + nb_args) << 16) | code);
252  spi_write_u32(spi, id);
253  for (int i = 0; i < nb_args; i++)
254  spi_write_u32(spi, args[i]);
255 }
256 
257 /* Template: Two sources, list */
258 static inline void spi_op_2src_list(SPICtx *spi, int code,
259  int src1_id, int src2_id,
260  const int *args, int nb_args)
261 {
262  spi_write_u32(spi, ((3 + nb_args) << 16) | code);
263  spi_write_u32(spi, src1_id);
264  spi_write_u32(spi, src2_id);
265  for (int i = 0; i < nb_args; i++)
266  spi_write_u32(spi, args[i]);
267 }
268 
269 /* Template: Two sources, typed result, list */
270 static inline int spi_op_res_2src_list(SPICtx *spi, int code, int id, int type_id,
271  int src1_id, int src2_id,
272  const int *args, int nb_args)
273 {
274  spi_write_u32(spi, ((5 + nb_args) << 16) | code);
275  spi_write_u32(spi, type_id);
276  spi_write_u32(spi, id);
277  spi_write_u32(spi, src1_id);
278  spi_write_u32(spi, src2_id);
279  for (int i = 0; i < nb_args; i++)
280  spi_write_u32(spi, args[i]);
281  return id;
282 }
283 
284 /* Template: Three sources, list */
285 static inline void spi_op_3src_list(SPICtx *spi, int code, int src1_id,
286  int src2_id, int src3_id,
287  const int *args, int nb_args)
288 {
289  spi_write_u32(spi, ((4 + nb_args) << 16) | code);
290  spi_write_u32(spi, src1_id);
291  spi_write_u32(spi, src2_id);
292  spi_write_u32(spi, src3_id);
293  for (int i = 0; i < nb_args; i++)
294  spi_write_u32(spi, args[i]);
295 }
296 
297 OP_RES1SRC(OpImageQuerySize, 104)
298 
299 OP_RES1SRC(OpConvertFToU, 109)
300 OP_RES1SRC(OpConvertFToS, 110)
301 OP_RES1SRC(OpConvertSToF, 111)
302 OP_RES1SRC(OpConvertUToF, 112)
303 OP_RES1SRC(OpBitcast, 124)
304 
305 OP_RES1SRC(OpAny, 154)
306 
307 #define spi_OpConstantComposite(spi, res_type, src, ...) \
308  spi_op_res_1src_list(spi, 44, spi_get_id(spi), res_type, src, \
309  SPI_ARGS(__VA_ARGS__))
310 
311 #define spi_OpAccessChain(spi, res_type, ptr_id, ...) \
312  spi_op_res_1src_list(spi, 65, spi_get_id(spi), res_type, ptr_id, \
313  SPI_ARGS(__VA_ARGS__))
314 
315 #define spi_OpCompositeConstruct(spi, res_type, src, ...) \
316  spi_op_res_1src_list(spi, 80, spi_get_id(spi), res_type, src, \
317  SPI_ARGS(__VA_ARGS__))
318 
319 #define spi_OpCompositeExtract(spi, res_type, src, ...) \
320  spi_op_res_1src_list(spi, 81, spi_get_id(spi), res_type, src, \
321  SPI_ARGS(__VA_ARGS__))
322 
323 OP_RES2SRC(OpIAdd, 128)
324 OP_RES2SRC(OpFAdd, 129)
325 OP_RES2SRC(OpIMul, 132)
326 OP_RES2SRC(OpFMul, 133)
327 OP_RES2SRC(OpVectorTimesScalar, 142)
328 OP_RES2SRC(OpMatrixTimesVector, 145)
329 OP_RES2SRC(OpDot, 148)
330 
331 OP_RES2SRC(OpIEqual, 170)
332 OP_RES2SRC(OpINotEqual, 171)
333 OP_RES2SRC(OpUGreaterThan, 172)
334 OP_RES2SRC(OpSGreaterThan, 173)
335 OP_RES2SRC(OpUGreaterThanEqual, 174)
336 OP_RES2SRC(OpSGreaterThanEqual, 175)
337 OP_RES2SRC(OpULessThan, 176)
338 OP_RES2SRC(OpSLessThan, 177)
339 OP_RES2SRC(OpULessThanEqual, 178)
340 OP_RES2SRC(OpSLessThanEqual, 179)
341 
342 OP_RES2SRC(OpShiftRightLogical, 194)
343 OP_RES2SRC(OpShiftLeftLogical, 196)
344 
345 OP_RES2SRC(OpBitwiseAnd, 199)
346 OP_1SRC(OpReturnValue, 254)
347 
348 #define spi_OpExtInst(spi, res_type, instr_id, set_id, ...) \
349  spi_op_res_2src_list(spi, 12, spi_get_id(spi), res_type, instr_id, set_id, \
350  SPI_ARGS(__VA_ARGS__))
351 
352 #define spi_OpTypeStruct(spi, id, ...) \
353  spi_op_untypedres_list(spi, 30, id, \
354  SPI_ARGS(__VA_ARGS__))
355 
356 #define spi_OpDecorate(spi, target, deco, ...) \
357  spi_op_2src_list(spi, 71, target, deco, \
358  SPI_ARGS(__VA_ARGS__))
359 
360 #define spi_OpMemberDecorate(spi, type, target, deco, ...) \
361  spi_op_3src_list(spi, 72, type, target, deco, \
362  SPI_ARGS(__VA_ARGS__))
363 
364 #define spi_OpVectorShuffle(spi, res_type, src1, src2, ...) \
365  spi_op_res_2src_list(spi, 79, spi_get_id(spi), res_type, src1, src2, \
366  SPI_ARGS(__VA_ARGS__))
367 
368 #define spi_OpCompositeInsert(spi, res_type, src1, src2, ...) \
369  spi_op_res_2src_list(spi, 82, spi_get_id(spi), res_type, src1, src2, \
370  SPI_ARGS(__VA_ARGS__))
371 
372 static inline int spi_OpEntryPoint(SPICtx *spi, SpvExecutionModel execution_model,
373  const char *name, const int *args, int nb_args)
374 {
375  spi_write_u32(spi, (((3 + nb_args) + spi_strl(name)) << 16) | 15);
376  spi_write_u32(spi, execution_model);
377  spi_write_u32(spi, spi->id);
378  spi_put_str(spi, name);
379  for (int i = 0; i < nb_args; i++)
380  spi_write_u32(spi, args[i]);
381  return spi_get_id(spi);
382 }
383 
384 static inline void spi_OpName(SPICtx *spi, int target_id, const char *name)
385 {
386  spi_write_u32(spi, ((2 + spi_strl(name)) << 16) | 5);
387  spi_write_u32(spi, target_id);
388  spi_put_str(spi, name);
389 }
390 
391 static inline void spi_OpExtension(SPICtx *spi, const char *name)
392 {
393  spi_write_u32(spi, ((1 + spi_strl(name)) << 16) | 10);
394  spi_put_str(spi, name);
395 }
396 
397 static inline int spi_OpExtInstImport(SPICtx *spi, const char *name)
398 {
399  spi_write_u32(spi, ((2 + spi_strl(name)) << 16) | 11);
400  spi_write_u32(spi, spi->id);
401  spi_put_str(spi, name);
402  return spi_get_id(spi);
403 }
404 
405 static inline void spi_OpExecutionMode(SPICtx *spi, int entry_point_id,
406  SpvExecutionMode mode, int *s, int nb_s)
407 {
408  spi_write_u32(spi, ((3 + nb_s) << 16) | 16);
409  spi_write_u32(spi, entry_point_id);
410  spi_write_u32(spi, mode);
411  for (int i = 0; i < nb_s; i++)
412  spi_write_u32(spi, s[i]);
413 }
414 
415 static inline int spi_OpUndef(SPICtx *spi, int type_id)
416 {
417  spi_write_u32(spi, (3 << 16) | 1);
418  spi_write_u32(spi, type_id);
419  spi_write_u32(spi, spi->id);
420  return spi_get_id(spi);
421 }
422 
423 static inline int spi_OpTypeVoid(SPICtx *spi)
424 {
425  spi_write_u32(spi, (2 << 16) | 19);
426  spi_write_u32(spi, spi->id);
427  return spi_get_id(spi);
428 }
429 
430 static inline int spi_OpTypeBool(SPICtx *spi)
431 {
432  spi_write_u32(spi, (2 << 16) | 20);
433  spi_write_u32(spi, spi->id);
434  spi->bool_type_id = spi->id;
435  return spi_get_id(spi);
436 }
437 
438 OP_UNTYPEDRES2SRC(OpTypeInt, 21)
439 OP_UNTYPEDRES1SRC(OpTypeFloat, 22)
440 OP_UNTYPEDRES2SRC(OpTypeVector, 23)
441 OP_UNTYPEDRES2SRC(OpTypeMatrix, 24)
442 
443 static inline int spi_OpTypeFloatEnc(SPICtx *spi, int width,
444  SpvFPEncoding floating_point_encoding)
445 {
446  spi_write_u32(spi, (4 << 16) | 22);
447  spi_write_u32(spi, spi->id);
448  spi_write_u32(spi, width);
449  spi_write_u32(spi, floating_point_encoding);
450  return spi_get_id(spi);
451 }
452 
453 static inline int spi_OpTypeImage(SPICtx *spi, int sampled_type_id, SpvDim dim,
454  int depth, int arrayed, int ms, int sampled,
455  SpvImageFormat image_format)
456 {
457  spi_write_u32(spi, (9 << 16) | 25);
458  spi_write_u32(spi, spi->id);
459  spi_write_u32(spi, sampled_type_id);
460  spi_write_u32(spi, dim - 1);
461  spi_write_u32(spi, depth);
462  spi_write_u32(spi, arrayed);
463  spi_write_u32(spi, ms);
464  spi_write_u32(spi, sampled);
465  spi_write_u32(spi, image_format);
466  /* TODO: if implementing kernel mode, write an access qualifier here */
467  return spi_get_id(spi);
468 }
469 
470 static inline int spi_OpTypeArray(SPICtx *spi, int element_type_id, int id,
471  int length_id)
472 {
473  spi_write_u32(spi, (4 << 16) | 28);
474  spi_write_u32(spi, id);
475  spi_write_u32(spi, element_type_id);
476  spi_write_u32(spi, length_id);
477  return id;
478 }
479 
480 static inline int spi_OpTypeRuntimeArray(SPICtx *spi, int element_type_id)
481 {
482  spi_write_u32(spi, (3 << 16) | 29);
483  spi_write_u32(spi, spi->id);
484  spi_write_u32(spi, element_type_id);
485  return spi_get_id(spi);
486 }
487 
488 static inline int spi_OpTypePointer(SPICtx *spi, SpvStorageClass storage_class,
489  int type_id)
490 {
491  spi_write_u32(spi, (4 << 16) | 32);
492  spi_write_u32(spi, spi->id);
493  spi_write_u32(spi, storage_class);
494  spi_write_u32(spi, type_id);
495  return spi_get_id(spi);
496 }
497 
498 static inline int spi_OpTypeFunction(SPICtx *spi, int return_type_id,
499  const int *args, int nb_args)
500 {
501  spi_write_u32(spi, ((3 + nb_args) << 16) | 33);
502  spi_write_u32(spi, spi->id);
503  spi_write_u32(spi, return_type_id);
504  for (int i = 0; i < nb_args; i++)
505  spi_write_u32(spi, args[i]);
506  return spi_get_id(spi);
507 }
508 
509 static inline void spi_OpFunction(SPICtx *spi, int fn_id, int result_type_id,
510  SpvFunctionControlMask function_control,
511  int function_type_id)
512 {
513  spi_write_u32(spi, (5 << 16) | 54);
514  spi_write_u32(spi, result_type_id);
515  spi_write_u32(spi, fn_id);
516  spi_write_u32(spi, function_control);
517  spi_write_u32(spi, function_type_id);
518 }
519 
520 static inline int spi_OpLabel(SPICtx *spi, int label_id)
521 {
522  spi_write_u32(spi, (2 << 16) | 248);
523  spi_write_u32(spi, label_id);
524  return label_id;
525 }
526 
527 static inline void spi_OpReturn(SPICtx *spi)
528 {
529  spi_write_u32(spi, (1 << 16) | 253);
530 }
531 
532 static inline void spi_OpFunctionEnd(SPICtx *spi)
533 {
534  spi_write_u32(spi, (1 << 16) | 56);
535 }
536 
537 static inline int spi_OpVariable(SPICtx *spi, int var_id, int ptr_type_id,
538  SpvStorageClass storage_class, int initializer_id)
539 {
540  spi_write_u32(spi, ((4 + !!initializer_id) << 16) | 59);
541  spi_write_u32(spi, ptr_type_id);
542  spi_write_u32(spi, var_id);
543  spi_write_u32(spi, storage_class);
544  if (initializer_id)
545  spi_write_u32(spi, initializer_id);
546  return var_id;
547 }
548 
549 static inline int spi_OpConstantTrue(SPICtx *spi)
550 {
551  spi_write_u32(spi, (3 << 16) | 41);
552  spi_write_u32(spi, spi->bool_type_id);
553  spi_write_u32(spi, spi->id);
554  return spi_get_id(spi);
555 }
556 
557 static inline int spi_OpConstantFalse(SPICtx *spi)
558 {
559  spi_write_u32(spi, (3 << 16) | 42);
560  spi_write_u32(spi, spi->bool_type_id);
561  spi_write_u32(spi, spi->id);
562  return spi_get_id(spi);
563 }
564 
565 static inline int spi_OpConstantUInt(SPICtx *spi, int type_id, uint32_t val)
566 {
567  spi_write_u32(spi, (4 << 16) | 43);
568  spi_write_u32(spi, type_id);
569  spi_write_u32(spi, spi->id);
570  spi_write_u32(spi, val);
571  return spi_get_id(spi);
572 }
573 
574 static inline int spi_OpConstantUInt64(SPICtx *spi, int type_id, uint64_t val)
575 {
576  spi_write_u32(spi, (5 << 16) | 43);
577  spi_write_u32(spi, type_id);
578  spi_write_u32(spi, spi->id);
579  spi_write_u32(spi, val & UINT32_MAX);
580  spi_write_u32(spi, val >> 32);
581  return spi_get_id(spi);
582 }
583 
584 static inline int spi_OpConstantInt(SPICtx *spi, int type_id, int val)
585 {
586  uint32_t vu = (union { int i; uint32_t u; }){val}.u;
587  return spi_OpConstantUInt(spi, type_id, vu);
588 }
589 
590 static inline int spi_OpConstantInt64(SPICtx *spi, int type_id, int64_t val)
591 {
592  uint64_t vu = (union { int64_t i; uint64_t u; }){val}.u;
593  return spi_OpConstantUInt64(spi, type_id, vu);
594 }
595 
596 static inline int spi_OpConstantFloat(SPICtx *spi, int type_id, float val)
597 {
598  uint32_t vu = (union { float f; uint32_t u; }){val}.u;
599  return spi_OpConstantUInt(spi, type_id, vu);
600 }
601 
602 static inline int spi_OpConstantDouble(SPICtx *spi, int type_id, double val)
603 {
604  uint64_t vu = (union { double d; uint64_t u; }){val}.u;
605  return spi_OpConstantUInt64(spi, type_id, vu);
606 }
607 
608 static inline int spi_OpLoad(SPICtx *spi, int result_type_id, int ptr_id,
609  SpvMemoryAccessMask memory_access, int align)
610 {
611  int is_aligned = !!(memory_access & SpvMemoryAccessAlignedMask);
612  spi_write_u32(spi, ((5 + is_aligned) << 16) | 61);
613  spi_write_u32(spi, result_type_id);
614  spi_write_u32(spi, spi->id);
615  spi_write_u32(spi, ptr_id);
616  spi_write_u32(spi, memory_access);
617  if (is_aligned)
618  spi_write_u32(spi, align);
619  return spi_get_id(spi);
620 }
621 
622 static inline void spi_OpStore(SPICtx *spi, int ptr_id, int obj_id,
623  SpvMemoryAccessMask memory_access, int align)
624 {
625  int is_aligned = !!(memory_access & SpvMemoryAccessAlignedMask);
626  spi_write_u32(spi, ((4 + is_aligned) << 16) | 62);
627  spi_write_u32(spi, ptr_id);
628  spi_write_u32(spi, obj_id);
629  spi_write_u32(spi, memory_access);
630  if (is_aligned)
631  spi_write_u32(spi, align);
632 }
633 
634 static inline void spi_OpSelectionMerge(SPICtx *spi, int merge_block,
635  SpvSelectionControlMask selection_control)
636 {
637  spi_write_u32(spi, (3 << 16) | 247);
638  spi_write_u32(spi, merge_block);
639  spi_write_u32(spi, selection_control);
640 }
641 
642 static inline void spi_OpBranchConditional(SPICtx *spi, int cond_id,
643  int true_label, int false_label,
644  uint32_t branch_weights)
645 {
646  spi_write_u32(spi, ((4 + 2*(!!branch_weights)) << 16) | 250);
647  spi_write_u32(spi, cond_id);
648  spi_write_u32(spi, true_label);
649  spi_write_u32(spi, false_label);
650  if (branch_weights) {
651  spi_write_u32(spi, branch_weights >> 16);
652  spi_write_u32(spi, branch_weights & UINT16_MAX);
653  }
654 }
655 
656 static inline int spi_OpImageRead(SPICtx *spi, int result_type_id, int img_id,
657  int pos_id, SpvImageOperandsMask image_operands)
658 {
659  spi_write_u32(spi, (5 + (!!image_operands) << 16) | 98);
660  spi_write_u32(spi, result_type_id);
661  spi_write_u32(spi, spi->id);
662  spi_write_u32(spi, img_id);
663  spi_write_u32(spi, pos_id);
664  if (image_operands)
665  spi_write_u32(spi, image_operands);
666  return spi_get_id(spi);
667 }
668 
669 static inline void spi_OpImageWrite(SPICtx *spi, int img_id, int pos_id,
670  int src_id, SpvImageOperandsMask image_operands)
671 {
672  spi_write_u32(spi, (4 + (!!image_operands) << 16) | 99);
673  spi_write_u32(spi, img_id);
674  spi_write_u32(spi, pos_id);
675  spi_write_u32(spi, src_id);
676  if (image_operands)
677  spi_write_u32(spi, image_operands);
678 }
679 
680 #endif /* SWSCALE_VULKAN_SPVASM_H */
spi_OpExecutionMode
static void spi_OpExecutionMode(SPICtx *spi, int entry_point_id, SpvExecutionMode mode, int *s, int nb_s)
Definition: spvasm.h:405
name
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 default minimum maximum flags name is the option name
Definition: writing_filters.txt:88
spi_op_2src_list
static void spi_op_2src_list(SPICtx *spi, int code, int src1_id, int src2_id, const int *args, int nb_args)
Definition: spvasm.h:258
spi_OpConstantInt
static int spi_OpConstantInt(SPICtx *spi, int type_id, int val)
Definition: spvasm.h:584
spi_end
static int spi_end(SPICtx *spi)
Definition: spvasm.h:100
spi_OpVariable
static int spi_OpVariable(SPICtx *spi, int var_id, int ptr_type_id, SpvStorageClass storage_class, int initializer_id)
Definition: spvasm.h:537
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:422
spi_OpTypeFunction
static int spi_OpTypeFunction(SPICtx *spi, int return_type_id, const int *args, int nb_args)
Definition: spvasm.h:498
spi_op_2src
static void spi_op_2src(SPICtx *spi, int code, int src1_id, int src2_id)
Definition: spvasm.h:187
spi_OpConstantFalse
static int spi_OpConstantFalse(SPICtx *spi)
Definition: spvasm.h:557
int64_t
long long int64_t
Definition: coverity.c:34
spi_OpConstantUInt
static int spi_OpConstantUInt(SPICtx *spi, int type_id, uint32_t val)
Definition: spvasm.h:565
mode
Definition: swscale.c:65
spi_op_res_1src
static int spi_op_res_1src(SPICtx *spi, int code, int id, int type_id, int src1_id)
Definition: spvasm.h:171
spi_OpFunctionEnd
static void spi_OpFunctionEnd(SPICtx *spi)
Definition: spvasm.h:532
u
#define u(width, name, range_min, range_max)
Definition: cbs_apv.c:68
SPICtx::dst
uint8_t * dst
Definition: spvasm.h:53
OP_1SRC
#define OP_1SRC(name, code)
Definition: spvasm.h:149
spi_OpConstantTrue
static int spi_OpConstantTrue(SPICtx *spi)
Definition: spvasm.h:549
SPICtx::overwrite
int overwrite
Definition: spvasm.h:56
SPICtx
Definition: spvasm.h:52
val
static double val(void *priv, double ch)
Definition: aeval.c:77
spi_OpTypeBool
static int spi_OpTypeBool(SPICtx *spi)
Definition: spvasm.h:430
OP_UNTYPEDRES1SRC
#define OP_UNTYPEDRES1SRC(name, code)
Definition: spvasm.h:164
avassert.h
spi_reserve
static int spi_reserve(SPICtx *spi, int len)
Definition: spvasm.h:108
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
spi_init
static void spi_init(SPICtx *spi, uint8_t *spv_buf, int buf_len)
Definition: spvasm.h:86
spi_OpFunction
static void spi_OpFunction(SPICtx *spi, int fn_id, int result_type_id, SpvFunctionControlMask function_control, int function_type_id)
Definition: spvasm.h:509
OP_UNTYPEDRES2SRC
#define OP_UNTYPEDRES2SRC(name, code)
Definition: spvasm.h:209
spi_OpMemoryModel
static void spi_OpMemoryModel(SPICtx *spi, SpvAddressingModel addressing_model, SpvMemoryModel memory_model)
Definition: spvasm.h:125
spi_OpLabel
static int spi_OpLabel(SPICtx *spi, int label_id)
Definition: spvasm.h:520
spi_op_1src
static void spi_op_1src(SPICtx *spi, int code, int src1_id)
Definition: spvasm.h:144
SPICtx::id
int id
Definition: spvasm.h:59
SPICtx::off
int off
Definition: spvasm.h:55
spi_OpUndef
static int spi_OpUndef(SPICtx *spi, int type_id)
Definition: spvasm.h:415
spi_OpBranchConditional
static void spi_OpBranchConditional(SPICtx *spi, int cond_id, int true_label, int false_label, uint32_t branch_weights)
Definition: spvasm.h:642
spi_OpTypeFloatEnc
static int spi_OpTypeFloatEnc(SPICtx *spi, int width, SpvFPEncoding floating_point_encoding)
Definition: spvasm.h:443
spi_OpTypeImage
static int spi_OpTypeImage(SPICtx *spi, int sampled_type_id, SpvDim dim, int depth, int arrayed, int ms, int sampled, SpvImageFormat image_format)
Definition: spvasm.h:453
spi_OpEntryPoint
static int spi_OpEntryPoint(SPICtx *spi, SpvExecutionModel execution_model, const char *name, const int *args, int nb_args)
Definition: spvasm.h:372
SPICtx::dst_size
int dst_size
Definition: spvasm.h:54
spi_strl
static int spi_strl(const char *str)
Definition: spvasm.h:138
spi_OpSelectionMerge
static void spi_OpSelectionMerge(SPICtx *spi, int merge_block, SpvSelectionControlMask selection_control)
Definition: spvasm.h:634
f
f
Definition: af_crystalizer.c:122
OP_RES2SRC
#define OP_RES2SRC(name, code)
Definition: spvasm.h:227
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
spi_op_untypedres_list
static void spi_op_untypedres_list(SPICtx *spi, int code, int id, const int *args, int nb_args)
Definition: spvasm.h:248
spi_OpName
static void spi_OpName(SPICtx *spi, int target_id, const char *name)
Definition: spvasm.h:384
align
static const uint8_t *BS_FUNC() align(BSCTX *bc)
Skip bits to a byte boundary.
Definition: bitstream_template.h:419
spi_OpTypeArray
static int spi_OpTypeArray(SPICtx *spi, int element_type_id, int id, int length_id)
Definition: spvasm.h:470
spi_OpConstantInt64
static int spi_OpConstantInt64(SPICtx *spi, int type_id, int64_t val)
Definition: spvasm.h:590
spi_OpExtInstImport
static int spi_OpExtInstImport(SPICtx *spi, const char *name)
Definition: spvasm.h:397
spi_OpExtension
static void spi_OpExtension(SPICtx *spi, const char *name)
Definition: spvasm.h:391
spi_op_untypedres_1src
static int spi_op_untypedres_1src(SPICtx *spi, int code, int id, int src1_id)
Definition: spvasm.h:156
spi_get_id
static int spi_get_id(SPICtx *spi)
Definition: spvasm.h:133
code
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some it can consider them to be part of the FIFO and delay acknowledging a status change accordingly Example code
Definition: filter_design.txt:178
spi_OpImageWrite
static void spi_OpImageWrite(SPICtx *spi, int img_id, int pos_id, int src_id, SpvImageOperandsMask image_operands)
Definition: spvasm.h:669
len
int len
Definition: vorbis_enc_data.h:426
spi_op_untypedres_2src
static int spi_op_untypedres_2src(SPICtx *spi, int code, int id, int src1_id, int src2_id)
Definition: spvasm.h:200
spi_OpConstantDouble
static int spi_OpConstantDouble(SPICtx *spi, int type_id, double val)
Definition: spvasm.h:602
SPICtx::bool_type_id
int bool_type_id
Definition: spvasm.h:58
spi_OpConstantUInt64
static int spi_OpConstantUInt64(SPICtx *spi, int type_id, uint64_t val)
Definition: spvasm.h:574
dim
int dim
Definition: vorbis_enc_data.h:425
OP_RES1SRC
#define OP_RES1SRC(name, code)
Definition: spvasm.h:180
spi_op_3src_list
static void spi_op_3src_list(SPICtx *spi, int code, int src1_id, int src2_id, int src3_id, const int *args, int nb_args)
Definition: spvasm.h:285
spi_OpTypeVoid
static int spi_OpTypeVoid(SPICtx *spi)
Definition: spvasm.h:423
spi_OpStore
static void spi_OpStore(SPICtx *spi, int ptr_id, int obj_id, SpvMemoryAccessMask memory_access, int align)
Definition: spvasm.h:622
spi_op_res_1src_list
static int spi_op_res_1src_list(SPICtx *spi, int code, int id, int type_id, int src1_id, const int *args, int nb_args)
Definition: spvasm.h:235
id
enum AVCodecID id
Definition: dts2pts.c:550
spi_OpReturn
static void spi_OpReturn(SPICtx *spi)
Definition: spvasm.h:527
spi_OpImageRead
static int spi_OpImageRead(SPICtx *spi, int result_type_id, int img_id, int pos_id, SpvImageOperandsMask image_operands)
Definition: spvasm.h:656
spi_OpCapability
static void spi_OpCapability(SPICtx *spi, SpvCapability capability)
Definition: spvasm.h:119
spi_OpConstantFloat
static int spi_OpConstantFloat(SPICtx *spi, int type_id, float val)
Definition: spvasm.h:596
spi_OpLoad
static int spi_OpLoad(SPICtx *spi, int result_type_id, int ptr_id, SpvMemoryAccessMask memory_access, int align)
Definition: spvasm.h:608
spi_OpTypePointer
static int spi_OpTypePointer(SPICtx *spi, SpvStorageClass storage_class, int type_id)
Definition: spvasm.h:488
spi_op_res_2src
static int spi_op_res_2src(SPICtx *spi, int code, int id, int type_id, int src1_id, int src2_id)
Definition: spvasm.h:217
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
spi_write_u32
static void spi_write_u32(SPICtx *spi, uint32_t v)
Definition: spvasm.h:62
spi_op_res_2src_list
static int spi_op_res_2src_list(SPICtx *spi, int code, int id, int type_id, int src1_id, int src2_id, const int *args, int nb_args)
Definition: spvasm.h:270
spi_OpTypeRuntimeArray
static int spi_OpTypeRuntimeArray(SPICtx *spi, int element_type_id)
Definition: spvasm.h:480
spi_put_str
static void spi_put_str(SPICtx *spi, const char *str)
Definition: spvasm.h:72
width
#define width
Definition: dsp.h:89