56 Assembly integration
Ronald S. Bultje edited this page 2026-08-28 13:49:34 +00:00

This page will try to keep track of the process and status of assembly writing. This isn't meant to cover any architecture specifically, but more a starting point for all of them.

Process

Like in dav1d, dav2d requires a few pre-conditions before a function can be optimized using hand-written assembly:

  • well-tested and final (not behaviourally changing) C code.
  • the C code needs to be split out in a DSP module: a .c file with an associated .h header and an _dsp_init() function that assigns function pointers for different architectures / instruction sets based on cpuflags (which are usually runtime-detected).
  • a unit test for the C function(s) that exposes size and value constraints - written in checkasm - and tests each of the optimized functions against the C function to ensure identical output. If the test existed in dav1d, this usually means you need to test more sizes. For example, 64x4 is a valid transform size in AV2 but not in AV1, and 64x8 is a valid block size in AV2 but not in AV1.
  • once these pre-conditions are met, we can write assembly. The assembly status should be tracked per platform / instruction set, and that's probably better managed outside this page. We expect to initially focus on aarch64 and avx2.

Status

Right now, the following code is "final" and split out properly:

  • entropy decoding (code: src/msac.c, unit test: tests/checkasm/msac.c):
    • decode_symbol_adapt4/8;
    • decode_bool(s)_bypass;
    • decode_unary_bypass.
  • intra prediction (code: src/ipred_tmpl.c, unit test: tests/checkasm/ipred.c:
    • dc(_top/left/128) - including ibp;
    • h/v;
    • paeth;
    • smooth(_h/v);
    • palette;
    • z1-3, including mrl_idx, multi-mrl & ibp;
    • dip;
    • cfl (!590)
    • mhccp (!756)
    • TODO: unit tests need to be updated for more block sizes (e.g. 32x4, 64x4/8, 8x64, 4x32/64 for luma) and to explicitly test unaligned stores (except on 64xN). (!537)
    • it would be nice if the alpha/beta derivation (used for implicit CfL and intrabc/morph) could be split out into e.g. ipred_tmpl.c and SIMD-optimized.
  • (primary) inverse transforms (code: src/itx_tmpl.c, unit test: tests/checkasm/itx.c):
    • TODO: unit tests will need to be updated to explicitly test unaligned stores. (4b3f736942)
    • cctx (!504)
  • secondary transform (code: src/stx_tmpl.c; no checkasm tests yet);
  • motion compensation (code: src/mc_tmpl.c; unit test: tests/checkasm.mc.c):
    • 8-tap/bilinear put/prep and scaled put-prep;
    • avg, w_avg, mask, w_mask;
    • warp8x8(t);
    • blend;
    • emu_edge;
    • morph;
    • opfl/refinemv/sad8x8;
    • ext_warp4x4{,t};
    • unit tests need to be updated to explicitly test unaligned stores (except on 64xN).
    • dav2d will need 4x{8,16,32,64}, {8,16,32}x{4,8,16,32,64} and 64x{8,16,32,64} - possibly also 2xN/Nx2 for chroma.
    • dav2d will do prediction at the 64x64 level, so support for w=128/h=128 can be removed if porting existing asm from dav1d.
    • dual-filter is gone compared to AV1, so that can be removed if porting existing asm from dav1d.
    • it would be nice if gen_mask() in recon_tmpl.c could be split out into a bitdepth-agnostic file and SIMD-optimized. (!721)
  • refmvs:
    • splat_*_mv() (!670, !678)
    • temporal slice loading (dav2d_refmvs_load_tmvs() and sub-functions called from there)
  • Postfilters:
    • for deblock, our recommendation is to hold off until delta-q and segmentation have been implemented. These will likely require design modifications (e.g. making q_thr and side_thr arrays, similar to level in AV1). There's also the question of lossless segments, which would make filters one-sided on edges.
    • vectorize the deblock setup functions. these functions initialize the thresholds for deblock. (!727)
    • cdef should be same as AV1, so we'll likely use the same design, although improvements have been suggested.
    • ccso (prep: !728, add: !737)
    • restoration (!738; chroma: !831)
    • gdf (!739)
    • film grain tests needs to be adjusted to run on 16x16 (in addition to 32x32) block sizes. (!638)

Specific arch sub-pages

If you have questions on how to start, please jump on IRC and talk to us.