Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
815 commits
Select commit Hold shift + click to select a range
a38101e
Merge PR #2611: Export frame rate list shows 119.88 and 120
aiongg Oct 31, 2026
c8b461b
Integration: #2611 port frame rate options to export_mode/settings.rs
aiongg Oct 31, 2026
a87829f
Merge PR #3121: perf(av1): cheaper dequantisation per transform block
aiongg Oct 31, 2026
cc4d8fe
Merge PR #3122: refactor(av1): narrow the public header API to what c…
aiongg Oct 31, 2026
1ac971c
Merge PR #2513: Fix tooltips showing stale default shortcuts after ke…
aiongg Oct 31, 2026
49c1e2e
Merge PR #3167: h264: implicit 32/32 bi-prediction weights as the rou…
aiongg Oct 31, 2026
e560b27
Merge PR #3168: h264: cheaper deblocking boundary-strength derivation
aiongg Oct 31, 2026
3050c3b
Merge PR #3179: perf(h264): DC-only inverse transform for blocks with…
aiongg Oct 31, 2026
7bd3ff9
Merge PR #3181: h264: Decoder::reset keeps the thread pool and cancel…
aiongg Oct 31, 2026
326c5da
Merge PR #3182: hevc: table-driven intra availability
aiongg Oct 31, 2026
4e2bef5
Merge PR #3183: h264: const-generic MC kernels, i16 first pass, inlin…
aiongg Oct 31, 2026
603dcf4
Merge PR #1765: Project panel: Select All / Deselect All from the mac…
aiongg Oct 31, 2026
29ef846
Integration: #1765 drop the Project-focus select-all blocks from keys…
aiongg Oct 31, 2026
f2cd5f0
Merge PR #2391: #1422: Matroska audio without a decoder is labelled u…
aiongg Oct 31, 2026
7825748
Merge PR #2104: fix(engine): enable Reveal Nested and Join Through Ed…
aiongg Oct 31, 2026
09e1a91
Merge PR #3585: Timeline: double-clicking a marker opens an Edit Mark…
aiongg Oct 31, 2026
b9ee5d3
Merge PR #3615: media-browser: list AAF and OMF documents, which File…
aiongg Oct 31, 2026
99a6598
Merge PR #2404: #1758: every Audio Track Mixer insert can be edited
aiongg Oct 31, 2026
4847dc6
Merge PR #3720: Source monitor: no Move range hand until both In and …
aiongg Oct 31, 2026
d9a4c5c
Integration: #1970 cap dotted legs, finite screen points, test
aiongg Oct 31, 2026
352b788
Merge PR #2706: fix(export): lock export settings and cancel active j…
aiongg Oct 31, 2026
7a87cd9
Merge PR #2541: #2537: the header workspace menu saves, resets and ed…
aiongg Oct 31, 2026
f189bda
Merge PR #1156: i18n: add Czech (cs) interface language
aiongg Oct 31, 2026
73e6db0
Merge PR #1597: timeline, panels: only the primary button starts a ge…
aiongg Oct 31, 2026
08e2719
Merge PR #1760: Effect Controls: the keyframe right-click menu follow…
aiongg Oct 31, 2026
2509657
Merge PR #2409: #1265: the demo project's sound has no hiss
aiongg Oct 31, 2026
a7abbad
Merge PR #3136: audio-dsp: filter channel pairs together in the settl…
aiongg Oct 31, 2026
26c0323
Merge PR #3137: audio-dsp: remix analysis with sparse mel weights and…
aiongg Oct 31, 2026
24819fb
Merge PR #3138: audio-dsp: step the resampler's source position inste…
aiongg Oct 31, 2026
a1ef2b6
Merge PR #3139: audio-dsp: wrap LFO phases and delay-line indices wit…
aiongg Oct 31, 2026
4a32148
Merge PR #2768: #2749: Export starts on Source In/Out when the sequen…
aiongg Oct 31, 2026
c4a2676
Merge PR #2088: fix(ui): Clip > Rename… opens a rename dialog
aiongg Oct 31, 2026
983f8bb
Merge PR #2197: fix(timeline): snap moved and trimmed captions like c…
aiongg Oct 31, 2026
b7ab719
Merge PR #3140: audio-dsp: vectorisable true-peak interpolator
aiongg Oct 31, 2026
1eb8896
Merge PR #3141: audio-dsp: defer convolution reverb impulse rebuild t…
aiongg Oct 31, 2026
57ca57b
Merge PR #3053: gpu: export on the high-performance GPU, and read sta…
aiongg Oct 31, 2026
a1b41d4
Merge PR #3142: audio-dsp: faster FFT kernel (contiguous twiddles, ch…
aiongg Oct 31, 2026
a6478be
Merge PR #3143: audio-dsp: cheaper gain math in the dynamics effects
aiongg Oct 31, 2026
a97611d
Merge PR #1619: timeline: preview carried transitions on the track th…
aiongg Oct 31, 2026
64f3de1
Merge PR #2542: #2538: an audio track's Mute / Solo buttons stay insi…
aiongg Oct 31, 2026
8be6a8a
Merge PR #3144: audio-dsp: recover filter state after a NaN or infini…
aiongg Oct 31, 2026
13320da
Merge PR #2108: fix(ui): disable the Project panel's Clear and Automa…
aiongg Oct 31, 2026
51d4cc1
Merge PR #3146: audio-dsp: one sin_cos per peak region in the pitch s…
aiongg Oct 31, 2026
7c2c208
Merge PR #3328: Select All in a text field selects its text, not the …
aiongg Oct 31, 2026
551be12
Integration: #3053 keep native_instance() in export adapter request
aiongg Oct 31, 2026
bb0157f
Merge PR #3481: Properties: the arrow keys move the caret in a number…
aiongg Oct 31, 2026
904d719
Merge PR #1860: #1675: keyframes on a Frame Hold clip go where the pl…
aiongg Oct 31, 2026
08fef0c
Integration: #1860 properties panel keyframe time uses effect_time_at
aiongg Oct 31, 2026
d3aaf93
Merge PR #1623: timeline: drop transitions when an edit moves their c…
aiongg Oct 31, 2026
353c55e
Merge PR #1865: #1381: the Warp Stabilizer analyses a clip a block of…
aiongg Oct 31, 2026
f29dd4b
Merge PR #2038: Import: EDL / FCP7 XML / FCPXML / OTIO / AAF / OMF la…
aiongg Oct 31, 2026
d7979f7
Merge PR #2127: Ignore unusable M2 speeds in EDL import
aiongg Oct 31, 2026
9b745e7
Merge PR #3707: Select the whole value when a single-line text field …
aiongg Oct 31, 2026
929fd4f
Merge PR #1628: timeline: right-clicking the ruler opens the ruler's …
aiongg Oct 31, 2026
bbb46e0
Merge PR #1638: timeline: the waveform fills the clip on a compact au…
aiongg Oct 31, 2026
29a98f5
Merge PR #1710: i18n: add Polish interface language
aiongg Oct 31, 2026
1958587
Merge PR #2202: fix: make clip duration editable in Speed/Duration di…
aiongg Oct 31, 2026
8fce33e
Merge PR #2248: Ignore out-of-range AUD channels in EDL import
aiongg Oct 31, 2026
fc34f88
Merge PR #1883: effects.apply adds the effect at the end of the clip'…
aiongg Oct 31, 2026
d9462a1
Integration: #2202 drop contributors/people.toml hunk and the screens…
aiongg Oct 31, 2026
8b86167
Merge PR #2363: #2186: Shift-click selects several graphic layers on …
aiongg Oct 31, 2026
406f633
Merge PR #2252: fix(interchange): FCPXML zero frameDuration no longer…
aiongg Oct 31, 2026
55a601d
Merge PR #3066: frame: convert full-size 8-bit Y'CbCr row by row, 28 …
aiongg Oct 31, 2026
75a6836
Merge PR #3308: #2633: a press on the ruler closes no audio stream, a…
aiongg Oct 31, 2026
d98fa91
Merge PR #1654: ui: keep the waveform anchored while a remix drag pre…
aiongg Oct 31, 2026
82779c6
Merge PR #2389: #1878: list fonts activated through third-party font …
aiongg Oct 31, 2026
eca8fb9
Integration: #1654 port Remix preview edited item to timeline/interac…
aiongg Oct 31, 2026
19db881
Merge PR #3255: platform: VideoToolbox export takes the RGBA pictures…
aiongg Oct 31, 2026
87ed20c
Merge PR #2559: #2295: the status bar's text can be selected and copied
aiongg Oct 31, 2026
187edcb
Merge PR #3264: aac: memoise the encoder's per-band work across rate-…
aiongg Oct 31, 2026
4910b1a
Merge PR #3274: mxf writer: write pictures directly, sound read curso…
aiongg Oct 31, 2026
f085749
Merge PR #3475: fix(export): a failed encoder factory does not stop t…
aiongg Oct 31, 2026
af32054
Merge PR #3685: ProRes encoder: rate control starts from the previous…
aiongg Oct 31, 2026
124c6ff
Merge PR #2282: fix(interchange): absurd frame rates and start timeco…
aiongg Oct 31, 2026
da9642a
Merge PR #3723: Export: background jobs read their own copy of each f…
aiongg Oct 31, 2026
a463980
Merge PR #2413: #2402: Transcribe is shown disabled when the build ha…
aiongg Oct 31, 2026
7b34f88
Merge PR #3204: h264enc: SATD on the half-pel plane, const sad8, fixe…
aiongg Oct 31, 2026
9264cdc
Merge PR #3206: h264enc: byte-wise CABAC renormalisation
aiongg Oct 31, 2026
a9785f6
Merge PR #3208: h264enc: branch-free u32 quantisation
aiongg Oct 31, 2026
0135f20
Merge PR #1924: Effect Controls: the keyframe menu's interpolation ap…
aiongg Oct 31, 2026
f3f1d78
Merge PR #3691: h264enc: pay back single-pass VBR/CBR overshoot withi…
aiongg Oct 31, 2026
ef4c9aa
Merge PR #3729: Media: the per-frame growing-files check no longer li…
aiongg Oct 31, 2026
9a15cb6
Merge PR #1788: #1780: the trim cursor stays while an edge is dragged
aiongg Oct 31, 2026
829bb84
Integration: #1788 port trim-cursor-while-dragging to timeline/intera…
aiongg Oct 31, 2026
97be098
Merge PR #2132: #1903: timeline.move refuses a clip listed twice (it …
aiongg Oct 31, 2026
3acf987
Merge PR #2151: fix(timeline): preview every track a Project drop fil…
aiongg Oct 31, 2026
4bfde06
Integration: #2282 port tests to tests/it layout
aiongg Oct 31, 2026
c366220
Merge PR #3119: Font pickers scan the system fonts before taking the …
aiongg Oct 31, 2026
6741240
Integration: #2151 keep drop_targets doc comment on drop_targets
aiongg Oct 31, 2026
5583d4a
Merge PR #3245: Preserve Unicode names in graphics template export id…
aiongg Oct 31, 2026
9a721c4
Merge PR #1693: fix(linux): add an "All files" filter to the Open Pro…
aiongg Oct 31, 2026
21b1a96
Merge PR #2010: fix(macos): Edit menu copy and paste go to the graphi…
aiongg Oct 31, 2026
3226bbd
Merge PR #2138: fix(gpu): FXC compiles the effect stage, so DX12 keep…
aiongg Oct 31, 2026
16efff4
Merge PR #2139: fix(gpu): Intel Gen 9 to Gen 11 integrated graphics d…
aiongg Oct 31, 2026
d7483c0
Merge PR #3566: Tests: split the NVENC error test so clippy's complex…
aiongg Oct 31, 2026
367e42f
Merge PR #3580: Platform: the macOS and Windows encode tests build again
aiongg Oct 31, 2026
70eafa5
Merge PR #3683: platform: macOS test fixes (boxed MediaClip, HEVC pro…
aiongg Oct 31, 2026
7c6ddd2
Merge PR #3731: ime: read the viewport id outside the context lock
aiongg Oct 31, 2026
d57d6af
Merge PR #3407: timeline: Track Select Forward/Backward selects and m…
aiongg Oct 31, 2026
5054344
Merge PR #3690: Graphics: document what Responsive Design – Time remaps
aiongg Oct 31, 2026
d289e98
Merge PR #2232: fix(timeline): Track Select tools skip locked tracks …
aiongg Oct 31, 2026
14e35c6
Integration: #2232 Track Select skips locked tracks in timeline/inter…
aiongg Oct 31, 2026
0caf86c
Merge PR #2365: fix(engine): timeline.slip by i64::MIN clamps instead…
aiongg Oct 31, 2026
9827770
Merge PR #2050: project: a moved auto point counts as modified
aiongg Oct 31, 2026
5636973
Integration: #2050 port the auto point fix to project/track.rs and it…
aiongg Oct 31, 2026
3c072ed
Merge PR #2568: FilmcraftApp::toast is gone; engine toasts reach the …
aiongg Oct 31, 2026
5b83f33
Merge PR #1930: i18n: Swedish (sv) interface translation
aiongg Oct 31, 2026
5fceea5
Merge PR #1992: i18n: clarify 11 Korean editing terms
aiongg Oct 31, 2026
5df5a22
Integration: #3690 draw the hint button with the Info icon instead of…
aiongg Oct 31, 2026
6d057b8
Merge PR #2640: #2623: Sequence and Markers menu toggles show their c…
aiongg Oct 31, 2026
9c4e5b6
Merge PR #2704: fix(ui): submit clip dialogs on Enter key (#2659)
aiongg Oct 31, 2026
f7d34e8
Merge PR #2100: #776: Corner Pin gets corner handles on the Program m…
aiongg Oct 31, 2026
a3f66a1
Merge PR #2660: #2419: Bokeh Blur runs on the GPU
aiongg Oct 31, 2026
fd2a79f
Merge PR #3434: Use default interpolation for keyframes added before …
aiongg Oct 31, 2026
6cd7e22
Merge PR #1679: #1644: save dialogs add the file's extension and ask …
aiongg Oct 31, 2026
2bbab85
Merge PR #3483: fix(sequence): clamp a new transition's duration to w…
aiongg Oct 31, 2026
19625c6
Merge PR #3696: Effects panel: Set as Default Transition
aiongg Oct 31, 2026
db1963c
Merge PR #2829: Span workspace dropdown highlights full width
aiongg Oct 31, 2026
790bc2a
Merge PR #1902: #1885: Proxy ▸ Create Proxies… from the item menu tak…
aiongg Oct 31, 2026
a88b0ff
Merge PR #1960: #1910: Interpret Footage from the item menu takes the…
aiongg Oct 31, 2026
4725b07
Merge PR #2153: #2094: the Lumetri shadow lift no longer amplifies ne…
aiongg Oct 31, 2026
5806f39
Integration: #1960 use #1902's menu_targets instead of a duplicate in…
aiongg Oct 31, 2026
9026a2e
Merge PR #3701: Graphics: gradient stops can carry opacity
aiongg Oct 31, 2026
20ea282
Merge PR #2284: fix(interchange): a huge duration times a speed satur…
aiongg Oct 31, 2026
8dd29cf
Merge PR #3702: UI: Thai fallback font for file and clip names
aiongg Oct 31, 2026
7e60802
Merge PR #2288: i18n: Russian covers the whole interface
aiongg Oct 31, 2026
7747db0
Merge PR #2247: Read every digit of numbers longer than 20 digits ind…
aiongg Oct 31, 2026
b766baa
Merge PR #2089: fix(ui): Close All Projects asks to save unsaved changes
aiongg Oct 31, 2026
0a23898
Merge PR #2974: fix(captions): VTT parse decodes the writer's cue-tex…
aiongg Oct 31, 2026
caec297
Merge PR #2240: Clarify the first-launch demo project name
aiongg Oct 31, 2026
f319ff9
Merge PR #3389: #3357: caption track font style
aiongg Oct 31, 2026
0e9d0b1
Merge PR #2403: #2195: relative media URLs in imported timelines are …
aiongg Oct 31, 2026
ded4b14
Integration: #2089 restore the closing brace of the merged test file
aiongg Oct 31, 2026
c7319c8
Merge PR #2381: Read currency amounts with a scale word as scale then…
aiongg Oct 31, 2026
7235965
Merge PR #3486: fix(#issue3): loop button highlights when looping is …
aiongg Oct 31, 2026
763d047
Merge PR #3693: Panels: a floating panel's menu opens in its own window
aiongg Oct 31, 2026
51454a2
Merge PR #2470: #2416: Edit Marker dialog (name, comment, duration, c…
aiongg Oct 31, 2026
5ca47f9
Merge PR #2393: #1123: Effect Controls' LUT rows pick a LUT
aiongg Oct 31, 2026
b9eb9fb
Merge PR #2847: fix(interchange): bound subclip parent resolution to …
aiongg Oct 31, 2026
2e06d51
Merge PR #2410: fix(tts-text): a currency amount past the digit cap i…
aiongg Oct 31, 2026
c11c0e7
Merge PR #1118: fix: シーケンス配置時の自動文字起こしを実行 #903
aiongg Oct 31, 2026
e541a31
Integration: #2847 sort the support import for rustfmt
aiongg Oct 31, 2026
0c5256c
Merge PR #2437: #2211: Quit ▸ Save on a new project saves and quits w…
aiongg Oct 31, 2026
9961be3
Integration: #2437 drop the engine project_generation hunks and use S…
aiongg Oct 31, 2026
104005b
Merge PR #3052: Fix FCPXML slideshow imports and missing-media relink…
aiongg Oct 31, 2026
407a86d
Merge PR #2408: #1658: Lumetri curves grow with the panel and every i…
aiongg Oct 31, 2026
0a55c5e
Integration: #2470 use Session::document_epoch instead of a second pr…
aiongg Oct 31, 2026
4354323
Merge PR #2738: Link Media: Offline All is saved, so reopening the pr…
aiongg Oct 31, 2026
e5e3c2b
Merge PR #2984: Recovery: retain durable journals and contain autosav…
aiongg Oct 31, 2026
1e62308
Merge PR #3462: interchange: reject overflowing EDL fields without le…
aiongg Oct 31, 2026
a6a5cda
Merge PR #1440: #1436: mpegts: H.264/HEVC units are access units; H.2…
aiongg Oct 31, 2026
5b839a4
Merge PR #2007: fix: satisfy clippy::nonminimal_bool on Rust 1.96
aiongg Oct 31, 2026
59695f2
Merge PR #2344: i18n: Turkish (tr) interface catalog (#1377)
aiongg Oct 31, 2026
b2f5d2e
Merge PR #2136: #2024: dialog commands the engine defaults can be bou…
aiongg Oct 31, 2026
42801a3
Merge PR #2699: Lumetri: Luma vs Sat and Sat vs Sat stop wrapping; hu…
aiongg Oct 31, 2026
f484bc8
Merge PR #2533: fix(timeline): a press hits only the track rows of it…
aiongg Oct 31, 2026
e3ff736
Merge PR #2729: i18n(ja): native macOS app menu labels
aiongg Oct 31, 2026
831872b
Integration: #2533 port row_at pane check to timeline/layout.rs; keep…
aiongg Oct 31, 2026
9e9f79c
Integration: #1440 move the BDAV comment back above its m2ts_h264_lpc…
aiongg Oct 31, 2026
9bae3a8
Merge PR #1707: mpegts/avi: drop redundant PES header check and doubl…
aiongg Oct 31, 2026
4017e31
Merge PR #2587: test: handle concurrent fixture publication on Windows
aiongg Oct 31, 2026
6f4f383
Merge PR #2705: #2489: an imported shortcut set is always listed; .ky…
aiongg Oct 31, 2026
59883c2
Merge PR #3733: tests: a_single_frame_source_range waits for the wall…
aiongg Oct 31, 2026
985ffb2
Merge PR #1718: cfb: reject NUL in entry names, checked sector arithm…
aiongg Oct 31, 2026
246044c
Merge PR #2710: #2682: Lumetri curves get automation elements; regres…
aiongg Oct 31, 2026
c3a2478
Merge PR #1555: fix(control): sequence.settings without params report…
aiongg Oct 31, 2026
797fdb6
Merge PR #2972: Update ru.tsv (both entries already present from #228…
aiongg Oct 31, 2026
c721f81
Merge PR #2539: #2536: a middle-button drag scrolls the audio tracks …
aiongg Oct 31, 2026
e16d36b
Integration: #2539 port Pan audio/start_a to timeline.rs and timeline…
aiongg Oct 31, 2026
228515e
Merge PR #1829: fix(codecs): read the frame rate phone clips average …
aiongg Oct 31, 2026
a8ccc00
Merge PR #3446: i18n(fr): translate the 8 interface strings still in …
aiongg Oct 31, 2026
43c771b
Merge PR #3649: i18n(ja): translate the update check strings
aiongg Oct 31, 2026
a47e67d
Integration: #1829 doc comment back above its test
aiongg Oct 31, 2026
8b24f02
Merge PR #2546: ui: zoom scroll bar handles show the horizontal resiz…
aiongg Oct 31, 2026
2da779d
Integration: #2546 port zoom thumb handle cursor to timeline/scrollba…
aiongg Oct 31, 2026
790c074
Merge PR #3435: lumetri: a plain click places a point on the curve (#…
aiongg Oct 31, 2026
d53045a
Merge PR #3352: test: wait for the condition in two timing-sensitive …
aiongg Oct 31, 2026
2a501fa
Merge PR #2116: feat(media): import PSD files as their flattened comp…
aiongg Oct 31, 2026
edc0fcc
Integration: #1829 drop the stray empty doc line
aiongg Oct 31, 2026
be41097
Merge PR #2302: AVI: recover the video when its idx1 entries are damaged
aiongg Oct 31, 2026
fb123b2
Integration: #2302 drop the contributors/people.toml entry
aiongg Oct 31, 2026
525b5e5
Merge PR #3225: matroska: preserve PTS semantics in the lacing oracle
aiongg Oct 31, 2026
8bd945b
Integration: #3225 drop the crates/matroska/README.md hunk
aiongg Oct 31, 2026
7327492
Merge PR #3276: mxf: faster decode_pcm, AES3 read_pcm no longer decod…
aiongg Oct 31, 2026
d9a147f
Merge PR #3695: Color: add a Three-Way Color Corrector
aiongg Oct 31, 2026
5cc4e21
Merge PR #3279: mxf: adaptive read window while walking KLVs at open …
aiongg Oct 31, 2026
2f4e59c
Integration: #3695 three-way colour corrector takes GPU op id 36 (32 …
aiongg Oct 31, 2026
a51fcaa
Merge PR #3681: ogg: charge bad-CRC page reads to the recovery budget
aiongg Oct 31, 2026
8f16aea
Merge PR #3714: bs: Add Bosnian (bs) to the interface languages
aiongg Oct 31, 2026
6ea1166
Merge PR #1412: #1411: docs/gaps.md: remove entries for features that…
aiongg Oct 31, 2026
99663bf
Merge PR #1957: render: Transform with its own shutter angle stays on…
aiongg Oct 31, 2026
e2e0c96
Merge PR #1419: #1418: parity docs: correct entries outdated by merge…
aiongg Oct 31, 2026
abeac16
Merge PR #1423: #1421: roadmap.md and gaps.md G14: mark shipped codec…
aiongg Oct 31, 2026
1629892
Merge PR #3093: docs(platform): update FFI architecture decision to m…
aiongg Oct 31, 2026
ba5d3ab
Merge PR #3516: docs(#2645): document numpad key limitation and worka…
aiongg Oct 31, 2026
e930e08
Merge PR #3718: docs: transcripts: word bounds are only moved across …
aiongg Oct 31, 2026
8103209
Merge PR #2612: Clip Mismatch Warning: a first clip that doesn't matc…
aiongg Oct 31, 2026
5d1a49d
Merge PR #2921: edit: ripple sync-locked captions with deleted items …
aiongg Oct 31, 2026
fa7dafb
Merge PR #3247: Preserve Reverse Speed when reopening the clip dialog
aiongg Oct 31, 2026
a589de7
Integration: #3093 ADR links point at the platform backend files
aiongg Oct 31, 2026
9d0faf7
Integration: #3247 keep a legacy negative speed reversed when the cli…
aiongg Oct 31, 2026
09f99fc
Integration: #3516 numpad section states the limitation and the 0 bin…
aiongg Oct 31, 2026
138bb1b
Merge PR #2438: #1142: no 60 Hz polling for queued frames, no media f…
aiongg Oct 31, 2026
077e8b6
Integration: #2438 port the lib.rs hunks to app.rs and app/frame.rs
aiongg Oct 31, 2026
856089e
Merge PR #3251: Settings: Selection Follows Playhead persists across …
aiongg Oct 31, 2026
624248a
Integration: #3251 re-apply the selection_follows_playhead pref in se…
aiongg Oct 31, 2026
3734513
Merge PR #2666: #1673: the Program monitor keeps playing while a valu…
aiongg Oct 31, 2026
9626e44
Merge PR #3473: Keep a clip's transitions when copying and pasting it
aiongg Oct 31, 2026
ca2bf2d
Merge PR #3583: Timeline: the box selection stays on the clips while …
aiongg Oct 31, 2026
f59572e
Integration: #3583 keep marquee_clips doc comment on marquee_clips
aiongg Oct 31, 2026
a63eaa9
Merge PR #3582: Trim: a graphic, still or adjustment layer extends fr…
aiongg Oct 31, 2026
52178b9
Integration: #2666 port the monitor hunks to draw_picture and thread …
aiongg Oct 31, 2026
30f24cd
Merge PR #3376: codecs: the rayon deadlock test fails 120 s after the…
aiongg Oct 31, 2026
e76e30a
Merge PR #1636: timeline: a transition on a compact track fills the t…
aiongg Oct 31, 2026
c2ac002
Merge PR #3684: Render Effects In to Out renders only red segments, l…
aiongg Oct 31, 2026
59ca8b9
Integration: #1636 use transition_top in the merged transition draw loop
aiongg Oct 31, 2026
1f9aff1
Merge PR #1866: perf: Warp Stabilizer works out the corrections of a …
aiongg Oct 31, 2026
0642cee
Merge PR #1649: scrub bars: dragging the playhead keeps the audio str…
aiongg Oct 31, 2026
7066519
Merge PR #2497: Enable subsequences in Source Playback
aiongg Oct 31, 2026
3777d57
Integration: #2497 test subsequence playback in the Source monitor wi…
aiongg Oct 31, 2026
a2fafd9
Merge integration track codec1
aiongg Oct 31, 2026
c4e9bb6
Merge integration track codec2
aiongg Oct 31, 2026
b583037
Merge integration track audio
aiongg Oct 31, 2026
bf1a400
Merge integration track export
aiongg Oct 31, 2026
69ed33a
Merge integration track io
aiongg Oct 31, 2026
bf0386b
Merge integration track sys
aiongg Oct 31, 2026
8595147
Merge integration track i18n
aiongg Oct 31, 2026
d896953
Merge PR #3461: captions: reject unparseable MCC timecode fields
aiongg Oct 31, 2026
06cbb02
Merge PR #3664: Preserve multiline WebVTT cue identifiers
aiongg Oct 31, 2026
29c2634
Merge PR #3665: Reject out-of-range EBU STL timecodes
aiongg Oct 31, 2026
d6b1265
Merge integration track text
aiongg Oct 31, 2026
0160875
Merge integration track fx
aiongg Oct 31, 2026
5f845f4
Merge integration track ui1
aiongg Oct 31, 2026
a9d15b9
Merge integration track ui2
aiongg Oct 31, 2026
199cb8d
Merge integration track ui3
aiongg Oct 31, 2026
9f7a9d6
Merge integration track timeline
aiongg Oct 31, 2026
f29309c
Integration: #3122 pass the OBU layer ids to skip_buffer_removal_time…
aiongg Oct 31, 2026
1750d02
Integration: #3066 close the one-source-pixel branch of the Yuv8 conv…
aiongg Oct 31, 2026
8a01ebd
Integration: #2847 #2282 adapt the interchange tests to the 7-argumen…
aiongg Oct 31, 2026
d813a86
Integration: #3389 #3391 fix the ruler menu braces and the caption pa…
aiongg Oct 31, 2026
a26c029
Integration: use BandSettings in the settled EQ pairing test
aiongg Oct 31, 2026
b00fd73
Integration: adopt egui 0.37 names in code the tracks added (Role, Id…
aiongg Oct 31, 2026
89ee11a
Integration: satisfy clippy (craft_ui::ComboBox in the FX choice, mov…
aiongg Oct 31, 2026
d143562
Integration: #2633 route stop_for_scrub through transport_running
aiongg Oct 31, 2026
79796c1
Integration: #2050 leave the auto-point comparison as it was (placed …
aiongg Oct 31, 2026
f65e2bc
Integration: #1864 #2922 #2434 adapt tests: reserved proxy outputs ex…
aiongg Oct 31, 2026
e029825
Integration: tests and dialogs meet the merged PRs (clip mismatch off…
aiongg Oct 31, 2026
1d523fb
Integration: keep the app's SaveAs matches in step with the dialog's …
aiongg Oct 31, 2026
dfb5fe7
Integration: wasm32 builds: media_queue is native-only, the sequence …
aiongg Oct 31, 2026
562f550
Merge main into backlog-r1
aiongg Oct 31, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
7 changes: 6 additions & 1 deletion ATTRIBUTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,17 @@ iconography, images or other Adobe assets; open licences only; every asset attri

| Asset | Author | Source | Licence |
|---|---|---|---|
| `crates/ui-egui/src/i18n/sv.tsv` | FilmCraft contributors | Original work: clean-room Swedish interface translations | MIT OR Apache-2.0 |
| `crates/ui-egui/src/i18n/it.tsv` | FilmCraft contributors | Original work: clean-room Italian interface translations | MIT OR Apache-2.0 |
| `crates/ui-egui/src/i18n/tr.tsv` | FilmCraft contributors | Original work: clean-room Turkish interface translations | MIT OR Apache-2.0 |
| `crates/ui-egui/src/i18n/id.tsv` | FilmCraft contributors | Original work: clean-room Indonesian interface translations | MIT OR Apache-2.0 |
| `crates/ui-egui/src/i18n/ko.tsv` | FilmCraft contributors | Original work: clean-room Korean interface translations | MIT OR Apache-2.0 |
| `crates/ui-egui/src/i18n/cs.tsv` | FilmCraft contributors | Original work: AI-assisted Czech interface translations; not yet proofread by a native speaker | MIT OR Apache-2.0 |
| `crates/ui-egui/src/i18n/fr.tsv` | FilmCraft contributors | Original work: clean-room French interface translations | MIT OR Apache-2.0 |
| `crates/ui-egui/src/i18n/pl.tsv` | FilmCraft contributors | Original work: clean-room Polish interface translations | MIT OR Apache-2.0 |
| `crates/ui-egui/src/i18n/pt-br.tsv` | FilmCraft contributors | Original work: clean-room Brazilian Portuguese interface translations | MIT OR Apache-2.0 |
| `crates/ui-egui/src/i18n/ru.tsv` | FilmCraft contributors | Original work: clean-room Russian interface translations | MIT OR Apache-2.0 |
| `crates/ui-egui/src/i18n/bs.tsv` | FilmCraft contributors | Original work: AI-assisted clean-room Bosnian interface translations, not yet native-reviewed | MIT OR Apache-2.0 |
| `crates/ui-egui/src/i18n/ru.tsv` | FilmCraft contributors | Original work: clean-room Russian interface translation (full catalog) | MIT OR Apache-2.0 |
| `crates/ui-egui/src/i18n/uk.tsv` | FilmCraft contributors | Original work: clean-room Ukrainian interface translations | MIT OR Apache-2.0 |
| `assets/fonts/Inter-Regular.ttf` | The Inter Project Authors | https://github.com/rsms/inter | OFL-1.1 (`assets/fonts/OFL-Inter.txt`) |
| `assets/fonts/Inter-Medium.ttf` | The Inter Project Authors | https://github.com/rsms/inter | OFL-1.1 (`assets/fonts/OFL-Inter.txt`) |
Expand Down
12 changes: 9 additions & 3 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

**Stage: alpha** · next: beta, ~19 points of ready-for-real-work and ~400–700 h away, plus opening Premiere's `.prproj` ([why](docs/target-app-parity.md#stage); passes the [core-workflow gate](docs/roadmap.md#alpha-gate))

> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-22 · **Change:** minor (ProRes alpha final-run conformance and native macOS validation) · **Target:** Adobe Premiere Pro 2026 (26.5.2)
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-22 · **Change:** minor (ProRes alpha final-run conformance and native macOS validation; language table: Czech, #1156) · **Target:** Adobe Premiere Pro 2026 (26.5.2)

Progress toward parity with Adobe Premiere Pro. This page is the summary; the detail is in
[docs/target-app-parity.md](docs/target-app-parity.md) (assessment, methodology, calibration),
Expand Down Expand Up @@ -72,7 +72,7 @@ Evidence for every row: [docs/target-app-parity.md](docs/target-app-parity.md#by

## Languages

Premiere ships 10 interface languages. Measured from our catalogs (3,498 strings):
Premiere ships 10 interface languages. Measured from our catalogs (3,593 strings, last measured 2026-10-19):

| Language | Status | Strings |
|---|---|---|
Expand All @@ -85,12 +85,15 @@ Premiere ships 10 interface languages. Measured from our catalogs (3,498 strings
| Portuguese (Brazil) | partial (whole interface; native review welcome) | ~100% |
| Indonesian | partial (whole interface; native review welcome) | ~100% |
| Italian | partial (whole interface; native review welcome) | ~100% |
| Bosnian | partial (whole interface; AI-assisted, native review welcome) | ~100% |
| Korean | partial (whole interface; needs an installed Hangul font; native review welcome) | ~100% |
| Czech | partial (whole interface; native review needed) | 100% |
| Russian | partial (whole interface; native review welcome) | ~100% |
| Japanese | partial (whole interface) | 99.7% |
| German | partial (whole interface; menus native-reviewed, the rest welcome) | ~100% |
| Vietnamese | none | 0% |

Also shipped: Ukrainian (menus only, 10%). Detail: [docs/localization-parity.md](docs/localization-parity.md).
Also shipped: Swedish (whole interface; native review welcome, ~100%), Ukrainian (menus only, 10%) and Polish (whole interface; AI-drafted, native review welcome). Detail: [docs/localization-parity.md](docs/localization-parity.md).

## Upcoming

Expand All @@ -109,6 +112,7 @@ Ranked; detail and "done when" in [docs/roadmap.md](docs/roadmap.md) and [docs/g

- **2026-10-22:** ProRes 4444 / XQ alpha slices include the final singleton run code required by RDD 36:2022. Six HD fixtures rejected by native macOS decoding now pass; syntax regression tests cover final runs and slice widths ([details](crates/prores/README.md#alpha-bitstream-conformance), EffectCraft #293).

- **2026-10-20:** the on/off items of the Sequence and Markers menus (Snap in Timeline, Linked Selection, Selection Follows Playhead, Show Through Edits, Ripple Sequence Markers, Copy Paste Includes Sequence Markers) show their checkmark, so choosing one visibly turns it on or off (#2623)
- **2026-10-12:** Transform's motion-blur shutter on adjustment layers uses the sequence frame rate instead of 24 fps, so a 360° shutter in a 60 fps sequence spans one frame, not 2.5 (#1088)
- **2026-10-10 (changed media):** Settings ▸ Media ▸ Automatically refresh growing files works: media files that change on disk while the project is open (a recording still being written, a render written over the file a clip uses) are read again every *Refresh growing files every* seconds and as soon as the window comes back to the front: the new length, picture and identity, without an undo step (`media.refreshChanged`, `media_watch`).
- **2026-10-10 (re-measure):** full parity re-measure against Premiere Pro 26.5.2: menu label diff 338 / 366 (92%), installed bundle listings (10 UI languages, exporter and codec frameworks), 188 open issues. Breadth ~86% (file formats now counted), ready ~55%, stage **alpha**; progress docs reorganized ([target-app-parity](docs/target-app-parity.md), [gaps](docs/gaps.md), [roadmap](docs/roadmap.md), [codec](docs/codec-parity.md), [file-format](docs/file-format-parity.md), [hardware](docs/hardware-parity.md), [UI](docs/ui-parity.md), [localization](docs/localization-parity.md)).
Expand Down Expand Up @@ -169,6 +173,8 @@ Ranked; detail and "done when" in [docs/roadmap.md](docs/roadmap.md) and [docs/g
| Date | Change | Summary |
|---|---|---|
| 2026-10-22 | minor | ProRes alpha: write the final singleton run code; 4444/XQ HD clips that failed native macOS decoding now decode, with syntax regression tests (EffectCraft #293) |
| 2026-10-19 | minor | Language table: Czech (#1156, 100%) |
| 2026-10-20 | trivial | Progress log: checkmarks on the Sequence and Markers menu toggles (#2623) |
| 2026-10-13 | minor | Language table: German covers the whole interface (~100%) |
| 2026-10-12 | trivial | Progress log: Transform shutter on adjustment layers (#1088) |
| 2026-10-11 | minor | Language table: German ships the menus (#630, 10.6%) |
Expand Down
50 changes: 38 additions & 12 deletions apps/filmcraft/src/audio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,32 @@ impl Note {
}
}

/// Whether the settings name a sample rate the device does not already run at, so its supported
/// configurations have to be listed. `0` is the settings' "device default".
fn needs_rate_search(default_rate: u32, want: u32) -> bool {
want != 0 && want != default_rate
}

/// The stream configuration the settings ask for, falling back to the device default.
///
/// Listing a device's configurations means probing every format and rate in the driver:
/// 150-215 ms on WASAPI (measured), while opening the stream itself costs ~20 ms warm (0.5-1 s
/// from a cold audio engine). So the list is only asked for when the settings name a rate the
/// device does not already run at (#2633).
fn stream_config(hw: &AudioHardwarePrefs, document_rate: Option<u32>, dev: &cpal::Device) -> Result<cpal::SupportedStreamConfig, String> {
let default = dev.default_output_config().map_err(|e| e.to_string())?;
let want = if hw.force_document_rate { document_rate.unwrap_or(hw.sample_rate) } else { hw.sample_rate };
if !needs_rate_search(default.sample_rate().0, want) {
return Ok(default);
}
let exact = dev.supported_output_configs().ok().and_then(|it| {
it.filter(|c| c.channels() > 0 && (c.min_sample_rate().0..=c.max_sample_rate().0).contains(&want))
.max_by_key(|c| (c.channels() == default.channels(), c.sample_format() == cpal::SampleFormat::F32, c.sample_format() == default.sample_format()))
.and_then(|c| c.try_with_sample_rate(cpal::SampleRate(want)))
});
Ok(exact.unwrap_or(default))
}

/// The host named in the settings (empty or unknown = the default host).
fn host(name: &str) -> cpal::Host {
if !name.is_empty()
Expand Down Expand Up @@ -158,18 +184,9 @@ impl CpalOut {
}
}

/// The stream configuration the settings ask for, falling back to the device default.
/// The stream configuration the settings ask for (see [`stream_config`]).
fn config(&self, dev: &cpal::Device) -> Result<cpal::SupportedStreamConfig, String> {
let default = dev.default_output_config().map_err(|e| e.to_string())?;
let want = if self.hw.force_document_rate { self.document_rate.unwrap_or(self.hw.sample_rate) } else { self.hw.sample_rate };
let exact = dev.supported_output_configs().ok().and_then(|it| {
it.filter(|c| c.channels() > 0 && (c.min_sample_rate().0..=c.max_sample_rate().0).contains(&want))
.max_by_key(|c| {
(c.channels() == default.channels(), c.sample_format() == cpal::SampleFormat::F32, c.sample_format() == default.sample_format())
})
.and_then(|c| c.try_with_sample_rate(cpal::SampleRate(want)))
});
Ok(exact.unwrap_or(default))
stream_config(&self.hw, self.document_rate, dev)
}

fn converted_stream<T>(&self, dev: &cpal::Device, config: &cpal::StreamConfig, fill: Arc<Mutex<Fill>>) -> Result<cpal::Stream, cpal::BuildStreamError>
Expand Down Expand Up @@ -328,7 +345,7 @@ impl Watchdog {
// An error that arrives with the stream still consuming samples is only a hiccup.
self.pending_error |= errored;
let stalled = now.saturating_sub(self.seen.1) >= STALL_RESTART;
if !lost && !(self.pending_error && stalled) {
if !(lost || (self.pending_error && stalled)) {
return Verdict::Healthy;
}
self.restarts.retain(|t| now.saturating_sub(*t) < RESTART_WINDOW);
Expand Down Expand Up @@ -472,6 +489,15 @@ mod tests {
assert!(!Note::NoDevice.text().is_empty());
}

/// #2633: the rate search costs ~190 ms on WASAPI, so the device default is taken as is.
#[test]
fn the_device_default_rate_is_used_without_listing_every_configuration() {
assert!(!needs_rate_search(48_000, 48_000), "the settings ask for the rate the device runs at");
assert!(!needs_rate_search(44_100, 0), "0 is the device default");
assert!(needs_rate_search(48_000, 44_100), "another rate has to be searched for");
assert!(needs_rate_search(48_000, 96_000));
}

#[test]
fn integer_conversion_clips_and_preserves_interleaved_channels() {
let mut signed = [0_i16; 8];
Expand Down
40 changes: 39 additions & 1 deletion apps/filmcraft/src/audio_in.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,32 @@ pub struct CpalIn {
stop: Option<mpsc::Sender<()>>,
worker: Option<std::thread::JoinHandle<()>>,
error: Arc<Mutex<Option<String>>>,
/// Frames of `buf` already measured by [`AudioInput::take_peaks`].
metered: usize,
}

impl CpalIn {
pub fn new(host: &str) -> Self {
Self { host: host.to_string(), buf: Arc::default(), stop: None, worker: None, error: Arc::default() }
Self { host: host.to_string(), buf: Arc::default(), stop: None, worker: None, error: Arc::default(), metered: 0 }
}
}

/// At most this many trailing frames are measured per meter poll (2 s at 48 kHz), so a meter that
/// was not polled for a while doesn't scan the whole take.
const PEAK_WINDOW: usize = 96_000;

/// Per-channel peak of the frames from `from` on (only the last [`PEAK_WINDOW`]), and the new
/// measured position; no peaks when nothing new arrived.
fn peaks(buf: &[Vec<f32>], from: usize) -> (Vec<f32>, usize) {
let len = buf.first().map_or(0, Vec::len);
let start = from.max(len.saturating_sub(PEAK_WINDOW));
if start >= len {
return (Vec::new(), len);
}
let peaks = buf.iter().map(|c| c.get(start..).unwrap_or_default().iter().fold(0f32, |m, s| m.max(s.abs()))).collect();
(peaks, len)
}

fn host(name: &str) -> cpal::Host {
if !name.is_empty()
&& let Some(id) = cpal::available_hosts().into_iter().find(|h| h.name() == name)
Expand Down Expand Up @@ -114,6 +132,7 @@ impl AudioInput for CpalIn {
fn start(&mut self, name: &str, sample_rate: u32) -> Result<InputFormat, String> {
self.stop();
lock(&self.buf).clear();
self.metered = 0;
*lock(&self.error) = None;
let (host_name, name) = (self.host.clone(), name.to_string());
let buf = self.buf.clone();
Expand Down Expand Up @@ -188,15 +207,22 @@ impl AudioInput for CpalIn {
}
fn read(&mut self, frames: usize) -> Vec<Vec<f32>> {
let mut b = lock(&self.buf);
self.metered = self.metered.saturating_sub(b.first().map_or(0, |c| frames.min(c.len())));
b.iter_mut()
.map(|c| {
let n = frames.min(c.len());
c.drain(..n).collect()
})
.collect()
}
fn take_peaks(&mut self) -> Vec<f32> {
let (p, metered) = peaks(&lock(&self.buf), self.metered);
self.metered = metered;
p
}
fn discard(&mut self) {
lock(&self.buf).iter_mut().for_each(Vec::clear);
self.metered = 0;
}
fn error(&self) -> Option<String> {
lock(&self.error).clone()
Expand Down Expand Up @@ -241,6 +267,18 @@ mod tests {
assert!(lock(&error).is_none());
}

#[test]
fn peaks_measure_only_new_frames_and_stop_when_nothing_arrives() {
let buf = vec![vec![0.1, -0.8, 0.2], vec![0.0, 0.3, -0.4]];
let (p, at) = peaks(&buf, 0);
assert_eq!((p, at), (vec![0.8, 0.4], 3));
assert_eq!(peaks(&buf, 3), (Vec::new(), 3), "nothing new: no peaks");
assert_eq!(peaks(&buf, 2).0, [0.2, 0.4], "only frames from the measured position");
assert_eq!(peaks(&[], 5), (Vec::new(), 0));
let long = vec![[vec![1.0], vec![0.25; PEAK_WINDOW]].concat()];
assert_eq!(peaks(&long, 0).0, [0.25], "only the trailing window is scanned");
}

#[test]
fn invalid_input_is_reported_without_panicking_or_appending() {
let buf = Mutex::new(Vec::new());
Expand Down
27 changes: 26 additions & 1 deletion apps/filmcraft/src/file_filters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
//! as `shot.MP4` or `shot.Mp4` would be hidden. The helper appends one bracket pattern per
//! extension (`mp4` -> `[mM][pP]4`) after the literal extensions, which stay first so save
//! dialogs keep their normal default suffix. macOS and Windows dialogs already ignore case
//! and receive the plain list.
//! and receive the plain list. The Open Project dialog also offers [`all_files`] beside the
//! project filter, so a project stays openable where the system MIME database does not
//! know `.fcproj` and the project filter matches nothing (#1644).

pub fn extensions(exts: &[&str]) -> Vec<String> {
let extensions: Vec<_> = exts.iter().map(|ext| (*ext).to_owned()).collect();
Expand Down Expand Up @@ -37,6 +39,15 @@ pub fn extensions(exts: &[&str]) -> Vec<String> {
extensions
}

/// Extensions for an "All files" filter: a single `*` and nothing else. rfd's XDG portal
/// backend special-cases `*` into the glob `*` (its GTK and Zenity backends build `*.*`),
/// so every file shows — including a saved project on a system whose shared-mime-info
/// package never registered `.fcproj`, where the "FilmCraft Project" filter hides them
/// all and the dialog offers no other way to reach the file (#1644).
pub fn all_files() -> Vec<String> {
extensions(&["*"])
}

#[cfg(test)]
mod tests {
use super::extensions;
Expand All @@ -55,6 +66,20 @@ mod tests {
}
}

#[test]
fn all_files_filter_admits_every_file() {
// One entry only: the `*` the backends turn into a match-everything glob (the XDG
// portal backend sends `*` itself; GTK/Zenity send `*.*`). Build the globs the way
// the portal backend does and check the files the project filter hid in #1644 —
// and everything else — are admitted.
assert_eq!(super::all_files(), ["*"]);
let filters: Vec<_> =
super::all_files().iter().map(|ext| if ext == "*" { ext.clone() } else { format!("*.{ext}") }).map(|g| glob::Pattern::new(&g).unwrap()).collect();
for name in ["project.fcproj", "Project.FCPROJ", "my film.filmcraft", "clip.mp4", "notes.txt", "noextension"] {
assert!(filters.iter().any(|f| f.matches(name)), "All files hides {name}");
}
}

#[test]
fn save_filters_keep_the_literal_default_extension() {
assert_eq!(extensions(&["mp4", "mov"]).first().map(String::as_str), Some("mp4"));
Expand Down
7 changes: 3 additions & 4 deletions apps/filmcraft/src/graphics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -444,9 +444,8 @@ fn apply_for(options: &mut NativeOptions, mode: Mode, backend_override: Option<B
// includes GL. Creating that backend can crash inside AMD's atio6axx.dll before adapter
// selection or any Rust error handling runs, so the window never appears. Choosing an
// adapter afterwards is too late: only leaving GL out of the instance avoids it. Keep
// Vulkan and DX12 both: forcing DX12 alone sends shaders through FXC (which rejects
// fx.wgsl, silently falling back to the CPU) and leaves machines without DX12 with no
// backend at all.
// Vulkan and DX12 both: forcing DX12 alone leaves machines without DX12 with no backend
// at all.
Mode::Default if windows => {
create.instance_descriptor.backends = backend_override.unwrap_or(Backends::PRIMARY);
// wgpu's own choice of adapter, except for a GPU that Windows lists through two
Expand All @@ -458,7 +457,7 @@ fn apply_for(options: &mut NativeOptions, mode: Mode, backend_override: Option<B
Some(Arc::new(move |adapters: &[wgpu::Adapter], surface: Option<&wgpu::Surface<'_>>| filmcraft_gpu::adapter::pick(adapters, surface, power)));
}
Mode::Default => {}
// Without Vulkan, whose driver is what crashes; GPU effects may fall back to the CPU.
// Without Vulkan, whose driver is what crashes.
Mode::Dx12 => create.instance_descriptor.backends = Backends::DX12,
Mode::Software => {
create.instance_descriptor.backends = software_backends(windows);
Expand Down
Loading
Loading