FFmpeg
Loading...
Searching...
No Matches
uops_tmpl.h
Go to the documentation of this file.
1/**
2 * Copyright (C) 2026 Niklas Haas
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_UOPS_TMPL_H
22#define SWSCALE_UOPS_TMPL_H
23
24/**
25 * Helper macros for the C-based backend.
26 *
27 * To use these macros, `pixel_t` should be defined as the type of pixels.
28 */
29
30#include <assert.h>
31#include <float.h>
32#include <stdint.h>
33
35#include "libavutil/sanitizer.h"
36
37#include "ops_chain.h"
38#include "uops_macros.h"
39
40#ifndef SWS_BLOCK_SIZE
41# define SWS_BLOCK_SIZE 32
42#endif
43
44typedef union block_t {
49} block_t;
50
51#define SIZEOF_BLOCK (sizeof(pixel_t) * SWS_BLOCK_SIZE)
52
53/**
54 * Internal context holding per-iter execution data. The data pointers will be
55 * directly incremented by the corresponding read/write functions.
56 */
57typedef struct SwsOpIter {
58 uintptr_t in[4];
59 uintptr_t out[4];
60 int x, y;
61
62 /* Link back to per-slice execution context */
64} SwsOpIter;
65
66/* UBSan checks inside the loop body defeat the vectorizer, so do not ask
67 * for it in those builds. Clang warns for every loop otherwise. */
68#if HAVE_UBSAN
69# define SWS_LOOP
70#elif defined(__clang__)
71# define SWS_LOOP AV_PRAGMA(clang loop vectorize(assume_safety))
72#elif defined(__GNUC__)
73# define SWS_LOOP AV_PRAGMA(GCC ivdep)
74#else
75# define SWS_LOOP
76#endif
77
78/* Miscellaneous helpers */
79#define bitfn2(name, ext) name ## _ ## ext
80#define bitfn(name, ext) bitfn2(name, ext)
81#define fn(name) bitfn(name, PX)
82
83#define bump_ptr(ptr, bump) ((pixel_t *) ((uintptr_t) (ptr) + (bump)))
84
85/* Helpers for dealing with component masks */
86#define X SWS_COMP_TEST(mask, 0)
87#define Y SWS_COMP_TEST(mask, 1)
88#define Z SWS_COMP_TEST(mask, 2)
89#define W SWS_COMP_TEST(mask, 3)
90
91/* Helper macros to make writing common function signatures less painful */
92#define DECL_FUNC(NAME, ...) \
93 av_always_inline static void \
94 fn(NAME)(SwsOpIter *restrict iter, const SwsOpImpl *restrict impl, \
95 pixel_t *restrict x, pixel_t *restrict y, \
96 pixel_t *restrict z, pixel_t *restrict w, \
97 __VA_ARGS__)
98
99#define DECL_READ(NAME, ...) \
100 DECL_FUNC(NAME, __VA_ARGS__, \
101 const pixel_t *restrict in0, const pixel_t *restrict in1, \
102 const pixel_t *restrict in2, const pixel_t *restrict in3) \
103
104#define DECL_WRITE(NAME, ...) \
105 DECL_FUNC(NAME, __VA_ARGS__, \
106 pixel_t *restrict out0, pixel_t *restrict out1, \
107 pixel_t *restrict out2, pixel_t *restrict out3) \
108
109#define CALL(NAME, ...) fn(NAME)(iter, impl, x, y, z, w, __VA_ARGS__)
110
111/* Helper macro to call into the next continuation with a given type */
112#define CONTINUE(...) \
113 ((void (*)(SwsOpIter *, const SwsOpImpl *, \
114 void *restrict x, void *restrict y, \
115 void *restrict z, void *restrict w)) impl->cont) \
116 (iter, &impl[1], __VA_ARGS__)
117
118/* Helper macros for common op setup code */
119#define DECL_SETUP(NAME, PARAMS, OUT) \
120 av_unused static int fn(NAME)(const SwsImplParams *PARAMS, \
121 SwsImplResult *OUT)
122
123/* Helper macro for declaring kernel entry points */
124#define DECL_IMPL(FUNC, NAME, TYPE, UOP, ...) \
125 av_flatten static void NAME##_c(SwsOpIter *restrict iter, \
126 const SwsOpImpl *restrict impl, \
127 void *restrict x, void *restrict y, \
128 void *restrict z, void *restrict w) \
129 { \
130 CALL(FUNC, __VA_ARGS__); \
131 }
132
133#define DECL_IMPL_READ(...) \
134 DECL_IMPL(__VA_ARGS__, \
135 (const pixel_t *) iter->in[0], (const pixel_t *) iter->in[1], \
136 (const pixel_t *) iter->in[2], (const pixel_t *) iter->in[3])
137
138#define DECL_IMPL_WRITE(...) \
139 DECL_IMPL(__VA_ARGS__, \
140 (pixel_t *) iter->out[0], (pixel_t *) iter->out[1], \
141 (pixel_t *) iter->out[2], (pixel_t *) iter->out[3])
142
143#define REF_ENTRY(DUMMY, NAME, ...) &uop_##NAME,
144#define DECL_ENTRY(SETUP, NAME, ...) \
145 static const SwsUOpEntry uop_##NAME = { \
146 .func = (SwsFuncPtr) NAME##_c, \
147 __VA_ARGS__, \
148 SETUP \
149 };
150
151#endif
Macro definitions for various function/variable attributes.
Copyright (C) 2026 Niklas Haas.
Internal context holding per-iter execution data.
Definition uops_tmpl.h:57
uintptr_t in[4]
Definition uops_tmpl.h:58
const SwsOpExec * exec
Definition uops_tmpl.h:63
uintptr_t out[4]
Definition uops_tmpl.h:59
uint32_t u32[SWS_BLOCK_SIZE]
Definition uops_tmpl.h:47
float f32[SWS_BLOCK_SIZE]
Definition uops_tmpl.h:48
uint16_t u16[SWS_BLOCK_SIZE]
Definition uops_tmpl.h:46
uint8_t u8[SWS_BLOCK_SIZE]
Definition uops_tmpl.h:45
#define SWS_BLOCK_SIZE
Copyright (C) 2026 Niklas Haas.
Definition uops_tmpl.h:41