| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | /** | ||
| 2 | * Copyright (C) 2025 Niklas Haas | ||
| 3 | * | ||
| 4 | * This file is part of FFmpeg. | ||
| 5 | * | ||
| 6 | * FFmpeg is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (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 | ||
| 14 | * GNU General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License along | ||
| 17 | * with FFmpeg; if not, write to the Free Software Foundation, Inc., | ||
| 18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <string.h> | ||
| 22 | |||
| 23 | #include "libavutil/avassert.h" | ||
| 24 | #include "libavutil/mem_internal.h" | ||
| 25 | #include "libavutil/refstruct.h" | ||
| 26 | |||
| 27 | #include "libswscale/filters.h" | ||
| 28 | #include "libswscale/ops_dispatch.h" | ||
| 29 | #include "libswscale/uops.h" | ||
| 30 | #include "libswscale/uops_macros.h" | ||
| 31 | |||
| 32 | #include "checkasm.h" | ||
| 33 | |||
| 34 | enum { | ||
| 35 | MAX_UOPS = 3, /* read, op, write */ | ||
| 36 | NB_PLANES = 4, | ||
| 37 | PIXELS = 64, | ||
| 38 | LINES = 16, | ||
| 39 | }; | ||
| 40 | |||
| 41 | typedef struct Test { | ||
| 42 | const char *name; | ||
| 43 | SwsUOp uops[MAX_UOPS]; | ||
| 44 | int num_uops; | ||
| 45 | |||
| 46 | /* Extra metadata for the test harness */ | ||
| 47 | SwsPixelType type_in; /* data format to fill */ | ||
| 48 | SwsPixelType type_out; /* data format to compare */ | ||
| 49 | SwsCompMask planes_in; /* planes to fill */ | ||
| 50 | SwsCompMask planes_out; /* planes to compare */ | ||
| 51 | int pixel_bits_in; /* read pixel stride */ | ||
| 52 | int pixel_bits_out; /* write pixel stride */ | ||
| 53 | unsigned ranges[NB_PLANES]; /* pixel range to fill */ | ||
| 54 | } Test; | ||
| 55 | |||
| 56 | #define FMT(fmt, ...) tprintf((char[256]) {0}, 256, fmt, __VA_ARGS__) | ||
| 57 | 3963 | static const char *tprintf(char buf[], size_t size, const char *fmt, ...) | |
| 58 | { | ||
| 59 | va_list ap; | ||
| 60 | 3963 | va_start(ap, fmt); | |
| 61 | 3963 | vsnprintf(buf, size, fmt, ap); | |
| 62 | 3963 | va_end(ap); | |
| 63 | 3963 | return buf; | |
| 64 | } | ||
| 65 | |||
| 66 | 4315496 | static float rndf(void) | |
| 67 | { | ||
| 68 | union { uint32_t u; float f; } x; | ||
| 69 | do { | ||
| 70 | 4349562 | x.u = rnd(); | |
| 71 |
2/2✓ Branch 0 taken 34066 times.
✓ Branch 1 taken 4315496 times.
|
4349562 | } while (!isnormal(x.f)); |
| 72 | 4315496 | return x.f; | |
| 73 | } | ||
| 74 | |||
| 75 | 3150 | static SwsPixel constpx(SwsPixelType type, int val) | |
| 76 | { | ||
| 77 |
1/5✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3150 times.
✗ Branch 4 not taken.
|
3150 | switch (type) { |
| 78 | ✗ | case SWS_PIXEL_U8: return (SwsPixel) { .u8 = val }; | |
| 79 | ✗ | case SWS_PIXEL_U16: return (SwsPixel) { .u16 = val }; | |
| 80 | ✗ | case SWS_PIXEL_U32: return (SwsPixel) { .u32 = val }; | |
| 81 | 3150 | case SWS_PIXEL_F32: return (SwsPixel) { .f32 = val }; | |
| 82 | ✗ | default: return (SwsPixel) {0}; | |
| 83 | } | ||
| 84 | } | ||
| 85 | |||
| 86 | 90342 | static SwsPixel rndpx(SwsPixelType type) | |
| 87 | { | ||
| 88 |
4/5✓ Branch 0 taken 798 times.
✓ Branch 1 taken 700 times.
✓ Branch 2 taken 420 times.
✓ Branch 3 taken 88424 times.
✗ Branch 4 not taken.
|
90342 | switch (type) { |
| 89 | 798 | case SWS_PIXEL_U8: return (SwsPixel) { .u8 = rnd() & 0xFF }; | |
| 90 | 700 | case SWS_PIXEL_U16: return (SwsPixel) { .u16 = rnd() & 0xFFFF }; | |
| 91 | 420 | case SWS_PIXEL_U32: return (SwsPixel) { .u32 = rnd() }; | |
| 92 | 88424 | case SWS_PIXEL_F32: return (SwsPixel) { .f32 = rndf() }; | |
| 93 | ✗ | default: return (SwsPixel) {0}; | |
| 94 | } | ||
| 95 | } | ||
| 96 | |||
| 97 | 1121 | static void fill32f(float *line, int num, unsigned range) | |
| 98 | { | ||
| 99 | 1121 | const float scale = (float) range / UINT32_MAX; | |
| 100 |
2/2✓ Branch 0 taken 4591616 times.
✓ Branch 1 taken 1121 times.
|
4592737 | for (int i = 0; i < num; i++) |
| 101 |
2/2✓ Branch 0 taken 364544 times.
✓ Branch 1 taken 4227072 times.
|
4591616 | line[i] = range ? scale * rnd() : rndf(); |
| 102 | 1121 | } | |
| 103 | |||
| 104 | 2735 | static void fill32(uint32_t *line, int num, unsigned range) | |
| 105 | { | ||
| 106 |
2/2✓ Branch 0 taken 11202560 times.
✓ Branch 1 taken 2735 times.
|
11205295 | for (int i = 0; i < num; i++) |
| 107 |
4/4✓ Branch 0 taken 425984 times.
✓ Branch 1 taken 10776576 times.
✓ Branch 2 taken 393216 times.
✓ Branch 3 taken 32768 times.
|
11202560 | line[i] = (range && range < UINT_MAX) ? rnd() % (range + 1) : rnd(); |
| 108 | 2735 | } | |
| 109 | |||
| 110 | 1166 | static void fill16(uint16_t *line, int num, unsigned range) | |
| 111 | { | ||
| 112 |
2/2✓ Branch 0 taken 1064 times.
✓ Branch 1 taken 102 times.
|
1166 | if (!range) { |
| 113 | 1064 | fill32((uint32_t *) line, AV_CEIL_RSHIFT(num, 1), 0); | |
| 114 | } else { | ||
| 115 |
2/2✓ Branch 0 taken 835584 times.
✓ Branch 1 taken 102 times.
|
835686 | for (int i = 0; i < num; i++) |
| 116 | 835584 | line[i] = rnd() % (range + 1); | |
| 117 | } | ||
| 118 | 1166 | } | |
| 119 | |||
| 120 | 1304 | static void fill8(uint8_t *line, int num, unsigned range) | |
| 121 | { | ||
| 122 |
2/2✓ Branch 0 taken 1181 times.
✓ Branch 1 taken 123 times.
|
1304 | if (!range) { |
| 123 | 1181 | fill32((uint32_t *) line, AV_CEIL_RSHIFT(num, 2), 0); | |
| 124 | } else { | ||
| 125 |
2/2✓ Branch 0 taken 2015232 times.
✓ Branch 1 taken 123 times.
|
2015355 | for (int i = 0; i < num; i++) |
| 126 | 2015232 | line[i] = rnd() % (range + 1); | |
| 127 | } | ||
| 128 | 1304 | } | |
| 129 | |||
| 130 | 13244 | static SwsPixelType pixel_type_to_int(const SwsPixelType type) | |
| 131 | { | ||
| 132 |
3/4✓ Branch 0 taken 2170 times.
✓ Branch 1 taken 2562 times.
✓ Branch 2 taken 8512 times.
✗ Branch 3 not taken.
|
13244 | switch (ff_sws_pixel_type_size(type)) { |
| 133 | 2170 | case 1: return SWS_PIXEL_U8; | |
| 134 | 2562 | case 2: return SWS_PIXEL_U16; | |
| 135 | 8512 | case 4: return SWS_PIXEL_U32; | |
| 136 | ✗ | default: break; | |
| 137 | } | ||
| 138 | |||
| 139 | ✗ | av_unreachable("Invalid pixel type!"); | |
| 140 | return SWS_PIXEL_NONE; | ||
| 141 | } | ||
| 142 | |||
| 143 | 10165 | static void check_compiled(const Test *test, | |
| 144 | const SwsCompiledOp *comp_ref, | ||
| 145 | const SwsCompiledOp *comp_new) | ||
| 146 | { | ||
| 147 | /** | ||
| 148 | * We can't use `check_func()` alone because the actual function pointer | ||
| 149 | * may be a wrapper or entry point shared by multiple implementations. | ||
| 150 | * Solve it by hashing in the active CPU flags as well. | ||
| 151 | */ | ||
| 152 | 10165 | uintptr_t id = (uintptr_t) comp_new->func; | |
| 153 | 10165 | id ^= (id << 6) + (id >> 2) + 0x9e3779b97f4a7c15 + comp_new->cpu_flags; | |
| 154 |
2/2✓ Branch 1 taken 8810 times.
✓ Branch 2 taken 1355 times.
|
10165 | if (!check_key(id, "%s", test->name)) |
| 155 | 8810 | return; | |
| 156 | |||
| 157 | 1355 | declare_func(void, const SwsOpExec *, const void *, int bx, int y, int bx_end, int y_end); | |
| 158 | |||
| 159 | static DECLARE_ALIGNED_64(char, src0)[NB_PLANES][LINES][PIXELS * sizeof(uint32_t[4])]; | ||
| 160 | static DECLARE_ALIGNED_64(char, src1)[NB_PLANES][LINES][PIXELS * sizeof(uint32_t[4])]; | ||
| 161 | static DECLARE_ALIGNED_64(char, dst0)[NB_PLANES][LINES][PIXELS * sizeof(uint32_t[4])]; | ||
| 162 | static DECLARE_ALIGNED_64(char, dst1)[NB_PLANES][LINES][PIXELS * sizeof(uint32_t[4])]; | ||
| 163 | |||
| 164 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1355 times.
|
1355 | av_assert0(PIXELS % comp_new->block_size == 0); |
| 165 |
2/2✓ Branch 0 taken 5420 times.
✓ Branch 1 taken 1355 times.
|
6775 | for (int p = 0; p < NB_PLANES; p++) { |
| 166 | 5420 | void *plane = src0[p]; | |
| 167 |
2/2✓ Branch 0 taken 1339 times.
✓ Branch 1 taken 4081 times.
|
5420 | if (!SWS_COMP_TEST(test->planes_in, p)) { |
| 168 | 1339 | memset(plane, 0, sizeof(src0[p])); | |
| 169 | 1339 | continue; | |
| 170 | } | ||
| 171 | |||
| 172 |
4/5✓ Branch 0 taken 1304 times.
✓ Branch 1 taken 1166 times.
✓ Branch 2 taken 490 times.
✓ Branch 3 taken 1121 times.
✗ Branch 4 not taken.
|
4081 | switch (test->type_in) { |
| 173 | 1304 | case SWS_PIXEL_U8: | |
| 174 | 1304 | fill8(plane, sizeof(src0[p]) / sizeof(uint8_t), test->ranges[p]); | |
| 175 | 1304 | break; | |
| 176 | 1166 | case SWS_PIXEL_U16: | |
| 177 | 1166 | fill16(plane, sizeof(src0[p]) / sizeof(uint16_t), test->ranges[p]); | |
| 178 | 1166 | break; | |
| 179 | 490 | case SWS_PIXEL_U32: | |
| 180 | 490 | fill32(plane, sizeof(src0[p]) / sizeof(uint32_t), test->ranges[p]); | |
| 181 | 490 | break; | |
| 182 | 1121 | case SWS_PIXEL_F32: | |
| 183 | 1121 | fill32f(plane, sizeof(src0[p]) / sizeof(uint32_t), test->ranges[p]); | |
| 184 | 1121 | break; | |
| 185 | } | ||
| 186 | } | ||
| 187 | |||
| 188 | 1355 | memcpy(src1, src0, sizeof(src0)); | |
| 189 | 1355 | memset(dst0, 0, sizeof(dst0)); | |
| 190 | 1355 | memset(dst1, 0, sizeof(dst1)); | |
| 191 | |||
| 192 | 1355 | const int read_size = PIXELS * test->pixel_bits_in >> 3; | |
| 193 | 1355 | const int write_size = PIXELS * test->pixel_bits_out >> 3; | |
| 194 | |||
| 195 | 1355 | SwsOpExec exec = {0}; | |
| 196 | 1355 | exec.width = PIXELS; | |
| 197 | 1355 | exec.height = exec.slice_h = LINES; | |
| 198 |
2/2✓ Branch 0 taken 5420 times.
✓ Branch 1 taken 1355 times.
|
6775 | for (int i = 0; i < NB_PLANES; i++) { |
| 199 | 5420 | exec.in_stride[i] = sizeof(src0[i][0]); | |
| 200 | 5420 | exec.out_stride[i] = sizeof(dst0[i][0]); | |
| 201 | 5420 | exec.in_bump[i] = exec.in_stride[i] - read_size; | |
| 202 | 5420 | exec.out_bump[i] = exec.out_stride[i] - write_size; | |
| 203 | } | ||
| 204 | |||
| 205 | int32_t in_bump_y[LINES]; | ||
| 206 | int32_t in_offset_x[PIXELS]; | ||
| 207 | 1355 | const SwsUOp *read_op = &test->uops[0]; | |
| 208 |
4/4✓ Branch 0 taken 3 times.
✓ Branch 1 taken 240 times.
✓ Branch 2 taken 336 times.
✓ Branch 3 taken 776 times.
|
1355 | switch (read_op->uop) { |
| 209 | 3 | case SWS_UOP_READ_PALETTE: | |
| 210 | 3 | exec.in_bump[1] = exec.in_stride[1] = 0; | |
| 211 | static_assert(sizeof(src0[1]) >= sizeof(uint32_t[256]), "palette plane too small"); | ||
| 212 | 3 | break; | |
| 213 | 240 | case SWS_UOP_READ_PLANAR_FV: { | |
| 214 | 240 | const int *offsets = read_op->data.kernel->offsets; | |
| 215 |
2/2✓ Branch 0 taken 3600 times.
✓ Branch 1 taken 240 times.
|
3840 | for (int y = 0; y < LINES - 1; y++) |
| 216 | 3600 | in_bump_y[y] = offsets[y + 1] - offsets[y] - 1; | |
| 217 | 240 | in_bump_y[LINES - 1] = 0; | |
| 218 | 240 | exec.in_bump_y = in_bump_y; | |
| 219 | 240 | break; | |
| 220 | } | ||
| 221 | 336 | case SWS_UOP_READ_PLANAR_FH: { | |
| 222 | 336 | const int *offsets = read_op->data.kernel->offsets; | |
| 223 |
2/2✓ Branch 0 taken 21504 times.
✓ Branch 1 taken 336 times.
|
21840 | for (int x = 0; x < PIXELS; x++) |
| 224 | 21504 | in_offset_x[x] = offsets[x] * test->pixel_bits_in >> 3; | |
| 225 | 336 | exec.in_offset_x = in_offset_x; | |
| 226 | } | ||
| 227 | } | ||
| 228 | |||
| 229 |
2/2✓ Branch 0 taken 5420 times.
✓ Branch 1 taken 1355 times.
|
6775 | for (int i = 0; i < NB_PLANES; i++) { |
| 230 | 5420 | exec.in[i] = (void *) src0[i]; | |
| 231 | 5420 | exec.out[i] = (void *) dst0[i]; | |
| 232 | 5420 | exec.block_size_in[i] = comp_ref->block_size * test->pixel_bits_in >> 3; | |
| 233 | 5420 | exec.block_size_out[i] = comp_ref->block_size * test->pixel_bits_out >> 3; | |
| 234 | } | ||
| 235 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 1355 times.
|
1355 | checkasm_call(comp_ref->func, &exec, comp_ref->priv, 0, 0, PIXELS / comp_ref->block_size, LINES); |
| 236 | |||
| 237 |
2/2✓ Branch 0 taken 5420 times.
✓ Branch 1 taken 1355 times.
|
6775 | for (int i = 0; i < NB_PLANES; i++) { |
| 238 | 5420 | exec.in[i] = (void *) src1[i]; | |
| 239 | 5420 | exec.out[i] = (void *) dst1[i]; | |
| 240 | 5420 | exec.block_size_in[i] = comp_new->block_size * test->pixel_bits_in >> 3; | |
| 241 | 5420 | exec.block_size_out[i] = comp_new->block_size * test->pixel_bits_out >> 3; | |
| 242 | } | ||
| 243 | 1355 | checkasm_call_checked(comp_new->func, &exec, comp_new->priv, 0, 0, PIXELS / comp_new->block_size, LINES); | |
| 244 | |||
| 245 |
2/2✓ Branch 0 taken 5420 times.
✓ Branch 1 taken 1355 times.
|
6775 | for (int i = 0; i < NB_PLANES; i++) { |
| 246 |
2/2✓ Branch 0 taken 1457 times.
✓ Branch 1 taken 3963 times.
|
5420 | if (!SWS_COMP_TEST(test->planes_out, i)) |
| 247 | 1457 | continue; | |
| 248 | |||
| 249 | 3963 | const char *desc = FMT("%s[%d]", test->name, i); | |
| 250 | 3963 | const int stride = sizeof(dst0[i][0]); | |
| 251 |
4/5✓ Branch 0 taken 726 times.
✓ Branch 1 taken 704 times.
✓ Branch 2 taken 451 times.
✓ Branch 3 taken 2082 times.
✗ Branch 4 not taken.
|
3963 | switch (test->type_out) { |
| 252 | 726 | case SWS_PIXEL_U8: | |
| 253 | 726 | checkasm_check(uint8_t, (void *) dst0[i], stride, | |
| 254 | (void *) dst1[i], stride, | ||
| 255 | write_size, LINES, desc); | ||
| 256 | 726 | break; | |
| 257 | 704 | case SWS_PIXEL_U16: | |
| 258 | 704 | checkasm_check(uint16_t, (void *) dst0[i], stride, | |
| 259 | (void *) dst1[i], stride, | ||
| 260 | write_size >> 1, LINES, desc); | ||
| 261 | 704 | break; | |
| 262 | 451 | case SWS_PIXEL_U32: | |
| 263 | 451 | checkasm_check(uint32_t, (void *) dst0[i], stride, | |
| 264 | (void *) dst1[i], stride, | ||
| 265 | write_size >> 2, LINES, desc); | ||
| 266 | 451 | break; | |
| 267 | 2082 | case SWS_PIXEL_F32: | |
| 268 | 2082 | checkasm_check(float_ulp, (void *) dst0[i], stride, | |
| 269 | (void *) dst1[i], stride, | ||
| 270 | write_size >> 2, LINES, desc, 0); | ||
| 271 | 2082 | break; | |
| 272 | } | ||
| 273 | } | ||
| 274 | |||
| 275 |
1/18✗ Branch 1 not taken.
✓ Branch 2 taken 1355 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
✗ Branch 54 not taken.
✗ Branch 55 not taken.
✗ Branch 59 not taken.
✗ Branch 60 not taken.
|
1355 | bench(comp_new->func, &exec, comp_new->priv, 0, 0, PIXELS / comp_new->block_size, LINES); |
| 276 | } | ||
| 277 | |||
| 278 | 8960 | static void run_test(const Test *test) | |
| 279 | { | ||
| 280 | 8960 | SwsContext *ctx = sws_alloc_context(); | |
| 281 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8960 times.
|
8960 | if (!ctx) |
| 282 | ✗ | return; | |
| 283 | 8960 | ctx->flags = SWS_BITEXACT; | |
| 284 | |||
| 285 | /* Generate dummy uop list on-stack */ | ||
| 286 | 8960 | SwsUOpList oplist = { | |
| 287 | 8960 | .ops = (SwsUOp *) test->uops, | |
| 288 | 8960 | .num_ops = test->num_uops, | |
| 289 | |||
| 290 | /* Less efficient, but works universally */ | ||
| 291 | .planes_in = SWS_COMP_ALL, | ||
| 292 | .planes_out = SWS_COMP_ALL, | ||
| 293 | }; | ||
| 294 | |||
| 295 |
2/2✓ Branch 0 taken 22204 times.
✓ Branch 1 taken 8960 times.
|
31164 | for (int i = 0; i < test->num_uops; i++) { |
| 296 | 22204 | const int pixel_size = ff_sws_pixel_type_size(test->uops[i].type); | |
| 297 |
2/2✓ Branch 0 taken 12026 times.
✓ Branch 1 taken 10178 times.
|
22204 | if (pixel_size > oplist.pixel_size_max) |
| 298 | 12026 | oplist.pixel_size_max = pixel_size; | |
| 299 | } | ||
| 300 | |||
| 301 | static const SwsOpBackend *backend_ref; | ||
| 302 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8959 times.
|
8960 | if (!backend_ref) { |
| 303 |
1/2✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
|
3 | for (int n = 0; ff_sws_op_backends[n]; n++) { |
| 304 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
|
3 | if (!strcmp(ff_sws_op_backends[n]->name, "c")) { |
| 305 | 1 | backend_ref = ff_sws_op_backends[n]; | |
| 306 | 1 | break; | |
| 307 | } | ||
| 308 | } | ||
| 309 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | av_assert0(backend_ref); |
| 310 | } | ||
| 311 | |||
| 312 | /* Always compile `ops` using the C backend as a reference */ | ||
| 313 | 8960 | SwsCompiledOp comp_ref = {0}; | |
| 314 | 8960 | int ret = backend_ref->compile_uops(ctx, &oplist, &comp_ref); | |
| 315 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8960 times.
|
8960 | if (ret < 0) { |
| 316 | ✗ | av_assert0(ret != AVERROR(ENOTSUP)); | |
| 317 | ✗ | fail(); | |
| 318 | ✗ | goto done; | |
| 319 | } | ||
| 320 | |||
| 321 | /* Check with the C backend to establish a reference */ | ||
| 322 | 8960 | check_compiled(test, &comp_ref, &comp_ref); | |
| 323 | |||
| 324 | /* Iterate over every other backend, and test it against the C reference */ | ||
| 325 |
2/2✓ Branch 0 taken 26880 times.
✓ Branch 1 taken 8960 times.
|
35840 | for (int n = 0; ff_sws_op_backends[n]; n++) { |
| 326 | 26880 | const SwsOpBackend *backend = ff_sws_op_backends[n]; | |
| 327 |
3/4✓ Branch 0 taken 26880 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8960 times.
✓ Branch 3 taken 17920 times.
|
26880 | if (backend->hw_format != AV_PIX_FMT_NONE || backend == backend_ref) |
| 328 | 25675 | continue; | |
| 329 |
2/2✓ Branch 0 taken 8960 times.
✓ Branch 1 taken 8960 times.
|
17920 | if (!backend->compile_uops) |
| 330 | 8960 | continue; | |
| 331 | |||
| 332 | 8960 | SwsCompiledOp comp_new = {0}; | |
| 333 | 8960 | int ret = backend->compile_uops(ctx, &oplist, &comp_new); | |
| 334 |
2/2✓ Branch 0 taken 7755 times.
✓ Branch 1 taken 1205 times.
|
8960 | if (ret == AVERROR(ENOTSUP)) { |
| 335 | 7755 | continue; | |
| 336 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1205 times.
|
1205 | } else if (ret < 0) { |
| 337 | ✗ | fail(); | |
| 338 | ✗ | goto done; | |
| 339 | } | ||
| 340 | |||
| 341 | /* Distinguish backends from each other even with same CPU flags */ | ||
| 342 | 1205 | checkasm_set_func_variant("%s_%s", backend->name, checkasm_get_cpu_suffix()); | |
| 343 | 1205 | check_compiled(test, &comp_ref, &comp_new); | |
| 344 | 1205 | ff_sws_compiled_op_unref(&comp_new); | |
| 345 | } | ||
| 346 | |||
| 347 | 8960 | done: | |
| 348 | 8960 | ff_sws_compiled_op_unref(&comp_ref); | |
| 349 | 8960 | sws_free_context(&ctx); | |
| 350 | } | ||
| 351 | |||
| 352 | 8960 | static void check_uop(const char *name, const SwsUOp *uop, | |
| 353 | SwsCompMask mask_in, SwsCompMask mask_out, | ||
| 354 | const unsigned ranges[NB_PLANES]) | ||
| 355 | { | ||
| 356 | 8960 | Test t = { | |
| 357 | .name = name, | ||
| 358 | 8960 | .type_in = uop->type, | |
| 359 | 8960 | .type_out = uop->type, | |
| 360 | }; | ||
| 361 | |||
| 362 |
4/4✓ Branch 0 taken 7700 times.
✓ Branch 1 taken 7420 times.
✓ Branch 2 taken 6160 times.
✓ Branch 3 taken 1540 times.
|
15120 | for (int i = 0; ranges && i < NB_PLANES; i++) |
| 363 | 6160 | t.ranges[i] = ranges[i]; | |
| 364 | |||
| 365 | /* uops with non-standard output type conversions */ | ||
| 366 |
7/8✓ Branch 0 taken 98 times.
✓ Branch 1 taken 182 times.
✓ Branch 2 taken 126 times.
✓ Branch 3 taken 266 times.
✓ Branch 4 taken 70 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4032 times.
✓ Branch 7 taken 4186 times.
|
8960 | switch (uop->uop) { |
| 367 | 98 | case SWS_UOP_TO_U8: t.type_out = SWS_PIXEL_U8; break; | |
| 368 | 182 | case SWS_UOP_TO_U16: t.type_out = SWS_PIXEL_U16; break; | |
| 369 | 126 | case SWS_UOP_TO_U32: t.type_out = SWS_PIXEL_U32; break; | |
| 370 | 266 | case SWS_UOP_TO_F32: t.type_out = SWS_PIXEL_F32; break; | |
| 371 | 70 | case SWS_UOP_EXPAND_PAIR: t.type_out = SWS_PIXEL_U16; break; | |
| 372 | ✗ | case SWS_UOP_EXPAND_QUAD: t.type_out = SWS_PIXEL_U32; break; | |
| 373 | 4032 | case SWS_UOP_READ_PLANAR_FH: | |
| 374 | case SWS_UOP_READ_PLANAR_FV: | ||
| 375 | 4032 | t.type_out = uop->par.filter.type; | |
| 376 | 4032 | break; | |
| 377 | } | ||
| 378 | |||
| 379 | /* Set up read/write metadata for rw uops */ | ||
| 380 | 8960 | const int bits_in = ff_sws_pixel_type_size(t.type_in) * 8; | |
| 381 | 8960 | const int bits_out = ff_sws_pixel_type_size(t.type_out) * 8; | |
| 382 |
10/10✓ Branch 0 taken 4186 times.
✓ Branch 1 taken 168 times.
✓ Branch 2 taken 126 times.
✓ Branch 3 taken 126 times.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 14 times.
✓ Branch 6 taken 14 times.
✓ Branch 7 taken 14 times.
✓ Branch 8 taken 14 times.
✓ Branch 9 taken 4284 times.
|
8960 | switch (uop->uop) { |
| 383 | 4186 | case SWS_UOP_READ_PLANAR: | |
| 384 | case SWS_UOP_READ_PLANAR_FH: | ||
| 385 | case SWS_UOP_READ_PLANAR_FV: | ||
| 386 | 4186 | t.planes_in = uop->mask; | |
| 387 | 4186 | t.pixel_bits_in = bits_in; | |
| 388 | 4186 | break; | |
| 389 | 168 | case SWS_UOP_WRITE_PLANAR: | |
| 390 | 168 | t.planes_out = uop->mask; | |
| 391 | 168 | t.pixel_bits_out = bits_out; | |
| 392 | 168 | break; | |
| 393 | 126 | case SWS_UOP_READ_PACKED: | |
| 394 | 126 | t.planes_in = SWS_COMP_ELEMS(1); | |
| 395 | 126 | t.pixel_bits_in = bits_in * SWS_COMP_COUNT(uop->mask); | |
| 396 | 126 | break; | |
| 397 | 126 | case SWS_UOP_WRITE_PACKED: | |
| 398 | 126 | t.planes_out = SWS_COMP_ELEMS(1); | |
| 399 | 126 | t.pixel_bits_out = bits_out * SWS_COMP_COUNT(uop->mask); | |
| 400 | 126 | break; | |
| 401 | 14 | case SWS_UOP_READ_NIBBLE: | |
| 402 | 14 | t.planes_in = SWS_COMP_ELEMS(1); | |
| 403 | 14 | t.pixel_bits_in = 4; | |
| 404 | 14 | break; | |
| 405 | 14 | case SWS_UOP_WRITE_NIBBLE: | |
| 406 | 14 | t.planes_out = SWS_COMP_ELEMS(1); | |
| 407 | 14 | t.pixel_bits_out = 4; | |
| 408 | 14 | break; | |
| 409 | 14 | case SWS_UOP_READ_BIT: | |
| 410 | 14 | t.planes_in = SWS_COMP_ELEMS(1); | |
| 411 | 14 | t.pixel_bits_in = 1; | |
| 412 | 14 | break; | |
| 413 | 14 | case SWS_UOP_WRITE_BIT: | |
| 414 | 14 | t.planes_out = SWS_COMP_ELEMS(1); | |
| 415 | 14 | t.pixel_bits_out = 1; | |
| 416 | 14 | break; | |
| 417 | 14 | case SWS_UOP_READ_PALETTE: | |
| 418 | 14 | t.planes_in = SWS_COMP_ELEMS(2); | |
| 419 | 14 | t.pixel_bits_in = 8; /* size of index */ | |
| 420 | 14 | break; | |
| 421 | } | ||
| 422 | |||
| 423 | /* Add read uop if needed */ | ||
| 424 |
2/2✓ Branch 0 taken 4606 times.
✓ Branch 1 taken 4354 times.
|
8960 | if (!t.planes_in) { |
| 425 | 4606 | t.planes_in = mask_in; | |
| 426 | 4606 | t.pixel_bits_in = bits_in; | |
| 427 | 4606 | t.uops[t.num_uops++] = (SwsUOp) { | |
| 428 | 4606 | .type = pixel_type_to_int(t.type_in), | |
| 429 | .uop = SWS_UOP_READ_PLANAR, | ||
| 430 | .mask = SWS_COMP_ALL, /* extra planes are zero'd */ | ||
| 431 | }; | ||
| 432 | } | ||
| 433 | |||
| 434 | /* Add the UOp itself */ | ||
| 435 | 8960 | t.uops[t.num_uops++] = *uop; | |
| 436 | |||
| 437 | /* Add write uop if needed */ | ||
| 438 |
2/2✓ Branch 0 taken 8638 times.
✓ Branch 1 taken 322 times.
|
8960 | if (!t.planes_out) { |
| 439 | 8638 | t.planes_out = mask_out; | |
| 440 | 8638 | t.pixel_bits_out = bits_out; | |
| 441 | 8638 | t.uops[t.num_uops++] = (SwsUOp) { | |
| 442 | 8638 | .type = pixel_type_to_int(t.type_out), | |
| 443 | .uop = SWS_UOP_WRITE_PLANAR, | ||
| 444 | .mask = SWS_COMP_ALL, /* extra planes are ignored */ | ||
| 445 | }; | ||
| 446 | } | ||
| 447 | |||
| 448 | 8960 | run_test(&t); | |
| 449 | 8960 | } | |
| 450 | |||
| 451 | 2058 | static void check_range(const char *name, const SwsUOp *uop, | |
| 452 | const unsigned ranges[NB_PLANES]) | ||
| 453 | { | ||
| 454 | /* Test all planes to ensure data remains untouched */ | ||
| 455 | 2058 | check_uop(name, uop, SWS_COMP_ALL, SWS_COMP_ALL, ranges); | |
| 456 | 2058 | } | |
| 457 | |||
| 458 | 1834 | static void check_simple(const char *name, const SwsUOp *uop) | |
| 459 | { | ||
| 460 | 1834 | check_range(name, uop, NULL); | |
| 461 | 1834 | } | |
| 462 | |||
| 463 | 112 | static void check_scalar(const char *name, SwsUOp *uop) | |
| 464 | { | ||
| 465 | 112 | uop->data.scalar = rndpx(uop->type); | |
| 466 | 112 | check_simple(name, uop); | |
| 467 | 112 | } | |
| 468 | |||
| 469 | 686 | static void check_vec4(const char *name, SwsUOp *uop) | |
| 470 | { | ||
| 471 |
2/2✓ Branch 0 taken 2744 times.
✓ Branch 1 taken 686 times.
|
3430 | for (int i = 0; i < 4; i++) |
| 472 | 2744 | uop->data.vec4[i] = rndpx(uop->type); | |
| 473 | |||
| 474 | 686 | check_simple(name, uop); | |
| 475 | 686 | } | |
| 476 | |||
| 477 | #define MK_RANGES(R) ((const unsigned[]) { R, R, R, R }) | ||
| 478 | |||
| 479 | 4354 | static void check_read(const char *name, SwsUOp *uop) | |
| 480 | { | ||
| 481 | 4354 | check_uop(name, uop, uop->mask, uop->mask, NULL); | |
| 482 | 4354 | } | |
| 483 | |||
| 484 | 322 | static void check_write(const char *name, const SwsUOp *uop) | |
| 485 | { | ||
| 486 |
2/2✓ Branch 0 taken 308 times.
✓ Branch 1 taken 14 times.
|
322 | const int frac = uop->uop == SWS_UOP_WRITE_BIT ? 3 : |
| 487 | 308 | uop->uop == SWS_UOP_WRITE_NIBBLE ? 1 : 0; | |
| 488 | 322 | const int bits = 8 >> frac; | |
| 489 | 322 | const unsigned range = (1 << bits) - 1; | |
| 490 | 322 | check_uop(name, uop, uop->mask, uop->mask, MK_RANGES(range)); | |
| 491 | 322 | } | |
| 492 | |||
| 493 | 336 | static void check_filter(const char *name, SwsUOp *uop) | |
| 494 | { | ||
| 495 | 336 | const bool is_vert = uop->uop == SWS_UOP_READ_PLANAR_FV; | |
| 496 | |||
| 497 | 672 | SwsFilterParams par = { | |
| 498 | .scaler_params = { SWS_PARAM_DEFAULT, SWS_PARAM_DEFAULT }, | ||
| 499 |
2/2✓ Branch 0 taken 168 times.
✓ Branch 1 taken 168 times.
|
336 | .dst_size = is_vert ? LINES : PIXELS, |
| 500 | }; | ||
| 501 | |||
| 502 | 336 | const SwsScaler scalers[] = { | |
| 503 | SWS_SCALE_POINT, | ||
| 504 | SWS_SCALE_SINC, | ||
| 505 | }; | ||
| 506 | |||
| 507 |
2/2✓ Branch 0 taken 672 times.
✓ Branch 1 taken 336 times.
|
1008 | for (int s = 0; s < FF_ARRAY_ELEMS(scalers); s++) { |
| 508 | 672 | par.scaler = scalers[s]; | |
| 509 | |||
| 510 |
2/2✓ Branch 0 taken 4032 times.
✓ Branch 1 taken 672 times.
|
4704 | for (par.src_size = 1; par.src_size <= par.dst_size; par.src_size <<= 1) { |
| 511 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 4032 times.
|
4032 | if (ff_sws_filter_generate(NULL, &par, &uop->data.kernel) < 0) { |
| 512 | ✗ | fail(); | |
| 513 | ✗ | return; | |
| 514 | } | ||
| 515 | |||
| 516 | char desc[256]; | ||
| 517 | 4032 | snprintf(desc, sizeof(desc), "%s_%s_%d", name, | |
| 518 | 4032 | uop->data.kernel->name, par.src_size); | |
| 519 | |||
| 520 | 4032 | check_read(desc, uop); | |
| 521 | 4032 | av_refstruct_unref(&uop->data.kernel); | |
| 522 | } | ||
| 523 | } | ||
| 524 | } | ||
| 525 | |||
| 526 | 1232 | static void check_swizzle(const char *name, const SwsUOp *uop) | |
| 527 | { | ||
| 528 | /* Only check data equality in needed components; since the others | ||
| 529 | * could either remain untouched or contain garbage */ | ||
| 530 | 1232 | check_uop(name, uop, SWS_COMP_ALL, uop->mask, NULL); | |
| 531 | 1232 | } | |
| 532 | |||
| 533 | 28 | static void check_expand_bit(const char *name, const SwsUOp *uop) | |
| 534 | { | ||
| 535 | 28 | check_range(name, uop, MK_RANGES(1)); | |
| 536 | 28 | } | |
| 537 | |||
| 538 | 742 | static void check_cast(const char *name, const SwsUOp *uop) | |
| 539 | { | ||
| 540 | SwsPixelType dst; | ||
| 541 |
5/7✓ Branch 0 taken 98 times.
✓ Branch 1 taken 182 times.
✓ Branch 2 taken 126 times.
✓ Branch 3 taken 266 times.
✓ Branch 4 taken 70 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
742 | switch (uop->uop) { |
| 542 | 98 | case SWS_UOP_TO_U8: dst = SWS_PIXEL_U8; break; | |
| 543 | 182 | case SWS_UOP_TO_U16: dst = SWS_PIXEL_U16; break; | |
| 544 | 126 | case SWS_UOP_TO_U32: dst = SWS_PIXEL_U32; break; | |
| 545 | 266 | case SWS_UOP_TO_F32: dst = SWS_PIXEL_F32; break; | |
| 546 | 70 | case SWS_UOP_EXPAND_PAIR: dst = SWS_PIXEL_U16; break; | |
| 547 | ✗ | case SWS_UOP_EXPAND_QUAD: dst = SWS_PIXEL_U32; break; | |
| 548 | ✗ | default: return; | |
| 549 | } | ||
| 550 | |||
| 551 | 742 | const int isize = ff_sws_pixel_type_size(uop->type); | |
| 552 | 742 | const int osize = ff_sws_pixel_type_size(dst); | |
| 553 | 742 | unsigned range = UINT32_MAX >> (32 - osize * 8); | |
| 554 |
4/4✓ Branch 0 taken 364 times.
✓ Branch 1 taken 378 times.
✓ Branch 2 taken 56 times.
✓ Branch 3 taken 308 times.
|
742 | if (isize < osize || !ff_sws_pixel_type_is_int(dst)) |
| 555 | 434 | range = 0; | |
| 556 | |||
| 557 | 742 | check_uop(name, uop, uop->mask, uop->mask, MK_RANGES(range)); | |
| 558 | } | ||
| 559 | |||
| 560 | 140 | static void check_scale(const char *name, SwsUOp *uop) | |
| 561 | { | ||
| 562 | 140 | const int bits = ff_sws_pixel_type_size(uop->type) * 8; | |
| 563 | 140 | const unsigned max = UINT32_MAX >> (32 - bits); | |
| 564 | 140 | SwsPixel scale = uop->data.scalar = rndpx(uop->type); | |
| 565 | 140 | unsigned range = 0; | |
| 566 | |||
| 567 | /* Ensure the result won't exceed the value range */ | ||
| 568 |
4/4✓ Branch 0 taken 14 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 70 times.
|
140 | switch (uop->type) { |
| 569 |
1/2✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
|
14 | case SWS_PIXEL_U8: range = max / (scale.u8 ? scale.u8 : 1); break; |
| 570 |
1/2✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
|
28 | case SWS_PIXEL_U16: range = max / (scale.u16 ? scale.u16 : 1); break; |
| 571 |
1/2✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
|
28 | case SWS_PIXEL_U32: range = max / (scale.u32 ? scale.u32 : 1); break; |
| 572 | } | ||
| 573 | |||
| 574 | 140 | check_range(name, uop, MK_RANGES(range)); | |
| 575 | 140 | } | |
| 576 | |||
| 577 | 140 | static void check_unpack(const char *name, const SwsUOp *uop) | |
| 578 | { | ||
| 579 | 140 | const uint8_t *pat = uop->par.pack.pattern; | |
| 580 | 140 | const int total = pat[0] + pat[1] + pat[2] + pat[3]; | |
| 581 | 140 | const unsigned range = UINT32_MAX >> (32 - total); | |
| 582 | |||
| 583 | 140 | check_uop(name, uop, SWS_COMP(0), uop->mask, MK_RANGES(range)); | |
| 584 | 140 | } | |
| 585 | |||
| 586 | 112 | static void check_pack(const char *name, const SwsUOp *uop) | |
| 587 | { | ||
| 588 | 112 | const uint8_t *pat = uop->par.pack.pattern; | |
| 589 | 112 | const unsigned ranges[4] = { | |
| 590 | 112 | (1 << pat[0]) - 1, (1 << pat[1]) - 1, | |
| 591 | 112 | (1 << pat[2]) - 1, (1 << pat[3]) - 1, | |
| 592 | }; | ||
| 593 | |||
| 594 | 112 | check_uop(name, uop, uop->mask, SWS_COMP(0), ranges); | |
| 595 | 112 | } | |
| 596 | |||
| 597 | 224 | static void check_linear(const char *name, SwsUOp *uop) | |
| 598 | { | ||
| 599 | 224 | const SwsLinearUOp *par = &uop->par.lin; | |
| 600 |
2/2✓ Branch 0 taken 896 times.
✓ Branch 1 taken 224 times.
|
1120 | for (int i = 0; i < 4; i++) { |
| 601 |
2/2✓ Branch 0 taken 4480 times.
✓ Branch 1 taken 896 times.
|
5376 | for (int j = 0; j < 5; j++) { |
| 602 |
2/2✓ Branch 0 taken 3108 times.
✓ Branch 1 taken 1372 times.
|
4480 | if (par->zero & SWS_MASK(i, j)) |
| 603 | 3108 | uop->data.mat4[i][j] = constpx(uop->type, 0); | |
| 604 |
2/2✓ Branch 0 taken 42 times.
✓ Branch 1 taken 1330 times.
|
1372 | else if (par->one & SWS_MASK(i, j)) |
| 605 | 42 | uop->data.mat4[i][j] = constpx(uop->type, 1); | |
| 606 | else | ||
| 607 | 1330 | uop->data.mat4[i][j] = rndpx(uop->type); | |
| 608 | } | ||
| 609 | } | ||
| 610 | |||
| 611 | 224 | check_simple(name, uop); | |
| 612 | 224 | } | |
| 613 | |||
| 614 | 336 | static void check_dither(const char *name, SwsUOp *uop) | |
| 615 | { | ||
| 616 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 336 times.
|
336 | av_assert0(!ff_sws_pixel_type_is_int(uop->type)); |
| 617 | |||
| 618 | 336 | const int size = 1 << uop->par.dither.size_log2; | |
| 619 | 336 | const int height = ff_sws_dither_height(&uop->par.dither); | |
| 620 | 336 | SwsPixel *matrix = av_refstruct_allocz(size * height * sizeof(*matrix)); | |
| 621 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 336 times.
|
336 | if (!matrix) { |
| 622 | ✗ | fail(); | |
| 623 | ✗ | return; | |
| 624 | } | ||
| 625 | |||
| 626 |
2/2✓ Branch 0 taken 86016 times.
✓ Branch 1 taken 336 times.
|
86352 | for (int i = 0; i < size * size; i++) |
| 627 | 86016 | matrix[i] = rndpx(uop->type); | |
| 628 | 336 | memcpy(matrix + size * size, matrix, | |
| 629 | 336 | size * (height - size) * sizeof(*matrix)); | |
| 630 | |||
| 631 | 336 | uop->data.ptr = matrix; | |
| 632 | 336 | check_simple(name, uop); | |
| 633 | |||
| 634 | 336 | av_refstruct_unref(&matrix); | |
| 635 | } | ||
| 636 | |||
| 637 | 56 | static void check_lut_3d(const char *name, SwsUOp *uop) | |
| 638 | { | ||
| 639 | 56 | SwsLut3D *lut3d = ff_sws_lut3d_alloc(); | |
| 640 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
|
56 | if (!lut3d) { |
| 641 | ✗ | fail(); | |
| 642 | ✗ | return; | |
| 643 | } | ||
| 644 | |||
| 645 | 56 | checkasm_init(&lut3d->input, sizeof(lut3d->input)); | |
| 646 | |||
| 647 |
2/2✓ Branch 0 taken 28 times.
✓ Branch 1 taken 28 times.
|
56 | if (uop->par.lut3d.dynamic) { |
| 648 | 28 | checkasm_init(&lut3d->tone_map, sizeof(lut3d->tone_map)); | |
| 649 | 28 | checkasm_init(&lut3d->output, sizeof(lut3d->output)); | |
| 650 | 28 | lut3d->dynamic = true; | |
| 651 | |||
| 652 | /* Prevent out-of-bounds read from IPT values with abs(PT) > 0.5 */ | ||
| 653 |
2/2✓ Branch 0 taken 7224 times.
✓ Branch 1 taken 28 times.
|
7252 | for (int i = 0; i < FF_ARRAY_ELEMS(lut3d->tone_map); i++) |
| 654 | 7224 | lut3d->tone_map[i].y = FFMIN(lut3d->tone_map[i].y, 1 << 15); | |
| 655 | } | ||
| 656 | |||
| 657 | 56 | uop->data.lut3d = lut3d; | |
| 658 | 56 | check_range(name, uop, MK_RANGES(INPUT_LUT_SIZE - 1)); | |
| 659 | |||
| 660 | 56 | av_refstruct_unref(&lut3d); | |
| 661 | } | ||
| 662 | |||
| 663 | #define CHECK_FUNCTION(CHECK, NAME, ...) \ | ||
| 664 | CHECK(#NAME, &(SwsUOp) { __VA_ARGS__ }); | ||
| 665 | |||
| 666 | #define CHECK_FOR(UOP, CHECK) \ | ||
| 667 | SWS_FOR_STRUCT(U8, UOP, CHECK_FUNCTION, CHECK) \ | ||
| 668 | SWS_FOR_STRUCT(U16, UOP, CHECK_FUNCTION, CHECK) \ | ||
| 669 | SWS_FOR_STRUCT(U32, UOP, CHECK_FUNCTION, CHECK) \ | ||
| 670 | SWS_FOR_STRUCT(F32, UOP, CHECK_FUNCTION, CHECK) \ | ||
| 671 | report(#UOP) | ||
| 672 | |||
| 673 | 14 | void checkasm_check_sw_ops(void) | |
| 674 | { | ||
| 675 | 14 | CHECK_FOR(READ_PLANAR, check_read); | |
| 676 | 14 | CHECK_FOR(READ_PLANAR_FH, check_filter); | |
| 677 | 14 | CHECK_FOR(READ_PLANAR_FV, check_filter); | |
| 678 | 14 | CHECK_FOR(READ_PACKED, check_read); | |
| 679 | 14 | CHECK_FOR(READ_NIBBLE, check_read); | |
| 680 | 14 | CHECK_FOR(READ_BIT, check_read); | |
| 681 | 14 | CHECK_FOR(READ_PALETTE, check_read); | |
| 682 | 14 | CHECK_FOR(WRITE_PLANAR, check_write); | |
| 683 | 14 | CHECK_FOR(WRITE_PACKED, check_write); | |
| 684 | 14 | CHECK_FOR(WRITE_NIBBLE, check_write); | |
| 685 | 14 | CHECK_FOR(WRITE_BIT, check_write); | |
| 686 | 14 | CHECK_FOR(PERMUTE, check_swizzle); | |
| 687 | 14 | CHECK_FOR(COPY, check_swizzle); | |
| 688 | 14 | CHECK_FOR(SWAP_BYTES, check_simple); | |
| 689 | 14 | CHECK_FOR(EXPAND_BIT, check_expand_bit); | |
| 690 | 14 | CHECK_FOR(EXPAND_PAIR, check_cast); | |
| 691 | 14 | CHECK_FOR(EXPAND_QUAD, check_cast); | |
| 692 | 14 | CHECK_FOR(TO_U8, check_cast); | |
| 693 | 14 | CHECK_FOR(TO_U16, check_cast); | |
| 694 | 14 | CHECK_FOR(TO_U32, check_cast); | |
| 695 | 14 | CHECK_FOR(TO_F32, check_cast); | |
| 696 | 14 | CHECK_FOR(SCALE, check_scale); | |
| 697 | 14 | CHECK_FOR(ADD, check_scalar); | |
| 698 | 14 | CHECK_FOR(MIN, check_vec4); | |
| 699 | 14 | CHECK_FOR(MAX, check_vec4); | |
| 700 | 14 | CHECK_FOR(UNPACK, check_unpack); | |
| 701 | 14 | CHECK_FOR(PACK, check_pack); | |
| 702 | 14 | CHECK_FOR(LSHIFT, check_simple); | |
| 703 | 14 | CHECK_FOR(RSHIFT, check_simple); | |
| 704 | 14 | CHECK_FOR(CLEAR, check_vec4); | |
| 705 | 14 | CHECK_FOR(LINEAR, check_linear); | |
| 706 | 14 | CHECK_FOR(DITHER, check_dither); | |
| 707 | 14 | CHECK_FOR(LUT_3D, check_lut_3d); | |
| 708 | 14 | } | |
| 709 |