FFmpeg
Loading...
Searching...
No Matches
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
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
52typedef struct SPICtx {
53 uint8_t *dst;
55 int off;
57
59 int id;
60} SPICtx;
61
62static 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
72static 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
86static 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
100static 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
108static 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
119static 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
125static 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
133static int spi_get_id(SPICtx *spi)
134{
135 return spi->id++;
136}
137
138static int spi_strl(const char *str)
139{
140 return FFALIGN(strlen(str) + 1, 4) >> 2;
141}
142
143/* Template: Single source */
144static 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) \
150static 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 */
156static 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) \
165static 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 */
171static 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) \
181static 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 */
187static 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) \
194static 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 */
200static 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) \
210static 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 */
217static 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) \
228static 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 */
235static 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 */
248static 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 */
258static 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 */
270static 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 */
285static 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
297OP_RES1SRC(OpImageQuerySize, 104)
298
299OP_RES1SRC(OpConvertFToU, 109)
300OP_RES1SRC(OpConvertFToS, 110)
301OP_RES1SRC(OpConvertSToF, 111)
302OP_RES1SRC(OpConvertUToF, 112)
303OP_RES1SRC(OpBitcast, 124)
304
305OP_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
323OP_RES2SRC(OpIAdd, 128)
324OP_RES2SRC(OpFAdd, 129)
325OP_RES2SRC(OpIMul, 132)
326OP_RES2SRC(OpFMul, 133)
327OP_RES2SRC(OpVectorTimesScalar, 142)
328OP_RES2SRC(OpMatrixTimesVector, 145)
329OP_RES2SRC(OpDot, 148)
330
331OP_RES2SRC(OpIEqual, 170)
332OP_RES2SRC(OpINotEqual, 171)
333OP_RES2SRC(OpUGreaterThan, 172)
334OP_RES2SRC(OpSGreaterThan, 173)
335OP_RES2SRC(OpUGreaterThanEqual, 174)
336OP_RES2SRC(OpSGreaterThanEqual, 175)
337OP_RES2SRC(OpULessThan, 176)
338OP_RES2SRC(OpSLessThan, 177)
339OP_RES2SRC(OpULessThanEqual, 178)
340OP_RES2SRC(OpSLessThanEqual, 179)
341
342OP_RES2SRC(OpShiftRightLogical, 194)
343OP_RES2SRC(OpShiftLeftLogical, 196)
344
345OP_RES2SRC(OpBitwiseAnd, 199)
346OP_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
372static 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
384static 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
391static 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
397static 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
405static 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
415static 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
423static 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
430static 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
438OP_UNTYPEDRES2SRC(OpTypeInt, 21)
439OP_UNTYPEDRES1SRC(OpTypeFloat, 22)
440OP_UNTYPEDRES2SRC(OpTypeVector, 23)
441OP_UNTYPEDRES2SRC(OpTypeMatrix, 24)
442
443static 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
453static 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
470static 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
480static 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
488static 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
498static 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
509static 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
520static 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
527static inline void spi_OpReturn(SPICtx *spi)
528{
529 spi_write_u32(spi, (1 << 16) | 253);
530}
531
532static inline void spi_OpFunctionEnd(SPICtx *spi)
533{
534 spi_write_u32(spi, (1 << 16) | 56);
535}
536
537static 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
549static 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
557static 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
565static 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
574static 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
584static 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
590static 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
596static 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
602static 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
608static 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
622static 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
634static 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
642static 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
656static 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
669static 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 */
static double val(void *priv, double ch)
Definition aeval.c:77
simple assert() macros that are a bit more flexible than ISO C assert().
static const uint8_t *BS_FUNC align(BSCTX *bc)
Skip bits to a byte boundary.
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define f(width, name)
Definition cbs_vp8.c:236
#define s(width, name)
Definition cbs_vp9.c:198
long long int64_t
Definition coverity.c:34
enum AVCodecID id
Definition dts2pts.c:607
#define AV_WL32(p, v)
#define u(width, name, range_min, range_max)
Definition cbs_apv.c:68
#define FFALIGN(x, a)
Definition macros.h:78
const char * name
Definition qsvenc.c:142
const uint8_t * code
Definition spdifenc.c:433
static int spi_OpTypeFunction(SPICtx *spi, int return_type_id, const int *args, int nb_args)
Definition spvasm.h:498
static void spi_init(SPICtx *spi, uint8_t *spv_buf, int buf_len)
Definition spvasm.h:86
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
static int spi_OpVariable(SPICtx *spi, int var_id, int ptr_type_id, SpvStorageClass storage_class, int initializer_id)
Definition spvasm.h:537
static int spi_OpConstantUInt(SPICtx *spi, int type_id, uint32_t val)
Definition spvasm.h:565
static void spi_OpCapability(SPICtx *spi, SpvCapability capability)
Definition spvasm.h:119
static void spi_OpMemoryModel(SPICtx *spi, SpvAddressingModel addressing_model, SpvMemoryModel memory_model)
Definition spvasm.h:125
static int spi_OpConstantDouble(SPICtx *spi, int type_id, double val)
Definition spvasm.h:602
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
static int spi_OpConstantFalse(SPICtx *spi)
Definition spvasm.h:557
static void spi_OpFunctionEnd(SPICtx *spi)
Definition spvasm.h:532
static void spi_OpReturn(SPICtx *spi)
Definition spvasm.h:527
static int spi_OpImageRead(SPICtx *spi, int result_type_id, int img_id, int pos_id, SpvImageOperandsMask image_operands)
Definition spvasm.h:656
static int spi_OpTypeRuntimeArray(SPICtx *spi, int element_type_id)
Definition spvasm.h:480
static int spi_OpTypeArray(SPICtx *spi, int element_type_id, int id, int length_id)
Definition spvasm.h:470
#define OP_UNTYPEDRES2SRC(name, code)
Definition spvasm.h:209
static void spi_op_1src(SPICtx *spi, int code, int src1_id)
Definition spvasm.h:144
static void spi_OpBranchConditional(SPICtx *spi, int cond_id, int true_label, int false_label, uint32_t branch_weights)
Definition spvasm.h:642
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
#define OP_UNTYPEDRES1SRC(name, code)
Definition spvasm.h:164
static int spi_OpTypeFloatEnc(SPICtx *spi, int width, SpvFPEncoding floating_point_encoding)
Definition spvasm.h:443
static int spi_OpConstantFloat(SPICtx *spi, int type_id, float val)
Definition spvasm.h:596
static int spi_op_untypedres_1src(SPICtx *spi, int code, int id, int src1_id)
Definition spvasm.h:156
static void spi_op_2src(SPICtx *spi, int code, int src1_id, int src2_id)
Definition spvasm.h:187
static int spi_OpConstantInt64(SPICtx *spi, int type_id, int64_t val)
Definition spvasm.h:590
static int spi_OpLoad(SPICtx *spi, int result_type_id, int ptr_id, SpvMemoryAccessMask memory_access, int align)
Definition spvasm.h:608
static void spi_OpExecutionMode(SPICtx *spi, int entry_point_id, SpvExecutionMode mode, int *s, int nb_s)
Definition spvasm.h:405
static void spi_put_str(SPICtx *spi, const char *str)
Definition spvasm.h:72
static int spi_OpConstantInt(SPICtx *spi, int type_id, int val)
Definition spvasm.h:584
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
#define OP_RES2SRC(name, code)
Definition spvasm.h:227
static int spi_OpConstantUInt64(SPICtx *spi, int type_id, uint64_t val)
Definition spvasm.h:574
static void spi_OpName(SPICtx *spi, int target_id, const char *name)
Definition spvasm.h:384
static int spi_end(SPICtx *spi)
Definition spvasm.h:100
static int spi_OpLabel(SPICtx *spi, int label_id)
Definition spvasm.h:520
#define OP_RES1SRC(name, code)
Definition spvasm.h:180
static int spi_op_res_1src(SPICtx *spi, int code, int id, int type_id, int src1_id)
Definition spvasm.h:171
static void spi_OpStore(SPICtx *spi, int ptr_id, int obj_id, SpvMemoryAccessMask memory_access, int align)
Definition spvasm.h:622
static int spi_OpUndef(SPICtx *spi, int type_id)
Definition spvasm.h:415
static int spi_OpTypeBool(SPICtx *spi)
Definition spvasm.h:430
static int spi_OpTypePointer(SPICtx *spi, SpvStorageClass storage_class, int type_id)
Definition spvasm.h:488
static void spi_OpFunction(SPICtx *spi, int fn_id, int result_type_id, SpvFunctionControlMask function_control, int function_type_id)
Definition spvasm.h:509
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
static void spi_write_u32(SPICtx *spi, uint32_t v)
Definition spvasm.h:62
static int spi_op_untypedres_2src(SPICtx *spi, int code, int id, int src1_id, int src2_id)
Definition spvasm.h:200
#define OP_1SRC(name, code)
Definition spvasm.h:149
static int spi_reserve(SPICtx *spi, int len)
Definition spvasm.h:108
static int spi_get_id(SPICtx *spi)
Definition spvasm.h:133
static int spi_strl(const char *str)
Definition spvasm.h:138
static void spi_OpExtension(SPICtx *spi, const char *name)
Definition spvasm.h:391
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
static int spi_OpExtInstImport(SPICtx *spi, const char *name)
Definition spvasm.h:397
static void spi_OpSelectionMerge(SPICtx *spi, int merge_block, SpvSelectionControlMask selection_control)
Definition spvasm.h:634
static int spi_OpEntryPoint(SPICtx *spi, SpvExecutionModel execution_model, const char *name, const int *args, int nb_args)
Definition spvasm.h:372
static void spi_op_untypedres_list(SPICtx *spi, int code, int id, const int *args, int nb_args)
Definition spvasm.h:248
static int spi_OpTypeVoid(SPICtx *spi)
Definition spvasm.h:423
static int spi_OpConstantTrue(SPICtx *spi)
Definition spvasm.h:549
static void spi_OpImageWrite(SPICtx *spi, int img_id, int pos_id, int src_id, SpvImageOperandsMask image_operands)
Definition spvasm.h:669
int off
Definition spvasm.h:55
int id
Definition spvasm.h:59
int bool_type_id
Definition spvasm.h:58
uint8_t * dst
Definition spvasm.h:53
int overwrite
Definition spvasm.h:56
int dst_size
Definition spvasm.h:54
Definition swscale.c:71
#define width
Definition dsp.h:89
int dim
int len