devkitPro / citro3d

Homebrew PICA200 GPU wrapper library for Nintendo 3DS
zlib License
244 stars 34 forks source link

Poor Frame Pacing With Framerates Under 60 #66

Open Wyatt-James opened 1 month ago

Wyatt-James commented 1 month ago

Bug Report

What's the issue you encountered?

Citro3D's frame presentation logic can cause judder when the game's target frame rate is under 60 because it does not take into account on which vertical blank each frame should actually be presented. This means that, depending on how long the frame takes to render, the frame can be presented on any vertical interrupt.

For instance, at 30FPS, if we assume frames should only be presented on even vertical interrupts, they may land on odd interrupts due to the rendering being slightly faster or significantly slower than anticipated while still maintaining 30fps.

How can the issue be reproduced?

Unfortunately, exact reproduction steps are difficult to give. Create a program with C3D_FrameRate set to 30 and render frames that vary between <16ms and >16ms, measured from CPU frame start to GPU render finish. The judder should become apparent.

Environment?

Windows 10 x64 with WSL2 Ubuntu 22.04 LTS, old 3DS XL. DevkitPro official release devkitpro/devkitarm:20240202

Additional context?

A fix could potentially require triple-buffering to remain performant, and how to handle slowdown would require some consideration. It is likely wise to make this an opt-in feature, semi-independent of the C3D_FrameRate setting.

Wyatt-James commented 1 month ago

I rewrote this issue to fix a poor word choice and I cleaned things up slightly.