What Developers Should Know About Writing VapourSynth Filters and Using Vulkan

Updated

VapourSynth filters are written as plugins that receive and return frames through the core's frame and resource model, and Vulkan enters the picture as a GPU processing and memory-sharing backend. If you are writing a filter that stays on the CPU, you do not need Vulkan at all; if you want GPU uploads or interop with external GPU consumers, you need to understand the exportable-memory behavior described on vapoursynth.com, including the platform differences fixed in R81. The site's own framing—"Video processing and unsolicited code criticism"—signals that its developer material is opinionated and low-level rather than a polished API tutorial.

What the site actually covers for developers

The vapoursynth.com page lists these sections, which map directly to what a filter author needs:

Section What it addresses
General structure for users How the application and script layer is organized
Resource management and performance quirks How frames and memory are handled, and where performance behaves unexpectedly
The internal frame structure The frame representation your filter reads and writes
Writing filters and Vulkan usage Filter authoring plus GPU/Vulkan integration

The site does not present a pricing or licensing model on this page, so do not assume the tooling is free or that downloads require no account—those details are simply not stated in the available material.

Writing a filter: the mental model

A VapourSynth filter is a processing node in a graph. The core passes frames to your filter, your filter produces output frames, and the core manages when those frames are released. Two consequences follow:

  • Respect the frame lifecycle. Because resource management is handled by the core and the site explicitly flags "performance quirks," a filter that holds references to frames longer than needed can stall the graph or inflate memory use. Release frames when your processing for that frame is done.
  • Work against the internal frame structure. Your filter should read and write the frame layout the core defines rather than assuming a particular external buffer format. The "internal frame structure" section is the reference for that layout.

A concrete scenario: you want a filter that applies a per-frame color adjustment. The input is a clip; your filter receives each frame, reads its planes according to the internal frame structure, writes adjusted values into an output frame, and returns it. The expected result is a new clip node that can be chained into further filters. The common sticking point is lifetime—if you cache frames across calls for "speed," you are working against the core's resource management rather than with it.

Where Vulkan fits

Vulkan in VapourSynth is about GPU-side processing and, importantly, memory export/import so that GPU work can be shared with other consumers. The R81 release notes on the site are the most specific developer-facing information available:

  • R81 fixes "most issues and Vulkan API misunderstandings from R80," yielding working exportable memory and faster GPU uploads. If you are building on Vulkan interop, target R81 or later rather than R80.
  • Exportable memory behaves differently by platform. On Windows, you can only export the same memory once; exporting it again produces "weird behavior." On *nix systems, the same memory can be exported an unlimited number of times.
  • Imported memory is accounted differently. On Windows, the same exported memory counts twice toward a process's VRAM usage when imported.

These are the kind of details, the site notes, that "nobody will tell you"—so build your tests around them rather than discovering them in production.

Practical implications for your filter

  • If your filter exports GPU memory for an external consumer, design for a single export per allocation on Windows and treat re-export as unsupported there.
  • Budget VRAM with the Windows double-counting in mind; a buffer that looks like it fits may not once imported.
  • If you support both platforms, keep the export path behind a platform check rather than assuming uniform behavior.

Choosing an approach

Use CPU-only filter logic when your processing is not GPU-bound and you want the simplest lifecycle to reason about. Use Vulkan-backed processing when GPU uploads or external GPU interop are the point—and in that case, pin your minimum version to R81, test export behavior separately on Windows and *nix, and verify VRAM headroom under the Windows accounting rule. The site's release note is the authoritative statement for these behaviors; treat any older guidance as superseded.