arzeth / cdmpv

Upscaler for Linux which uses a nested display server over MPV. Recommended for VNs.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

cdmpv (Nested Display server over MPV)

Image quality is much better than Magpie.
"c" in "cdmpv" is because I used to think that "Child display server" is the more appropriate term.
But now I am very accustomed to "cdmpv" (and it's easier to enter), so I keep it so.
You can upscale even 800x600 to 5K.
Or crop 800x600 to 16:9 at a certain position and then upscale.

Games that grab mouse movements don't work, i.e. you can't play Quake with cdmpv.
That's because TigerVNC and UltraVNC (IIRC) don't support mouse movements, they send/receive only mouse's absolute position.
Therefore, it's recommended to play VNs with cdmpv.

I developed cdmpv because Magpie doesn't work with Wine.

And since I want more FPS,
and play without a nested display server,
and also want to play SC2 at 70-75 fps when the original FPS drops to 46 in big fights because my Ryzen 2600 is not enough,
now I am developing the overengineered ultrafast (upscaling only changed regions, switching upscalers on-the-fly to achieve target fps, potentially zero-copy) upscaler/first-in-the-world-universal-upframerater without using MPV and with using a proxy window instead of nested X11. It will probably be ready in February 2022.
In other words, cdmpv is a temporary measure.

I didn't test cdmpv on other computers, so tell me if it doesn't work.

Read everything below (especially the Hotkeys section) in order to use it.

How good can it upscale?

Example 1

Original (800x600, lossless .webp)
https://arzet.cf/scr/wanko_origHeight600.webp

Upscaled (2880x2160, 5.6MB lossless .webp) (Hotkey: w+w+w, low FPS on GTX 1660 Super)
https://arzet.cf/scr/wanko_upscaledHeight2160.webp

Requirements

Linux (or probably FreeBSD/etc.).
Ability to launch MPV using X11 (Xwayland is ok).

Terminology

X11=xorg. It is a display server. The other one in Wayland.
Host X11
Guest X11=Child X11=Nested X11=X11 in X11/Xwayland
VNC
WM=Window Manager.
MPV is a video player (also audio and images), it's used here for upscaling and displaying the result.
i3 as a WM in nested X11.
FFmpeg for capturing what's inside nested X11.

Don't forget to calibrate your monitor

http://www.lagom.nl/lcd-test/contrast.php
http://www.lagom.nl/lcd-test/black.php
http://www.lagom.nl/lcd-test/white.php
And especially sharpness (make sure that browser zoom is 100%): http://www.lagom.nl/lcd-test/sharpness.php

How to use:

Go to vndb.org, see the resolution of a screenshot of the game (e.g. The Fruit of Grisaia uses 1024x576).

./cdmpv.sh {GUEST_RES} ( {GUEST_REFRESH_RATE = nested x11's fps = emulated display refresh rate} ({UPSCALED_FPS = how many frames per second should MPV upscale}))
./cdmpv.sh 1024x576 60 30
./cdmpv.sh 1024x576 74.5 74.5
./cdmpv.sh 1024x576 160 160/3 # If your monitor is 160 Hz
./cdmpv.sh 1024x576 30
./cdmpv.sh 1024x576

#Bad: ./cdmpv.sh 1280x720 29.97 29.97
#Bad: ./cdmpv.sh 1280x720 29.97002997002997003 29.97 #(because what you actually want is ~0.02997002997002997003 which is also impossible to write)
#Good: ./cdmpv.sh 1280x720 29.97002997002997003 30/1001 #(useful for displays running at 60/1001 Hz=~59.94005994005994006 Hz)
# 29.97002997002997003 here is for the nested X11, 30/1001 is for FFmpeg.


If you accidentally specify even 1px more, the upscaled result is far worse. If you specify 30px more than needed, then almost nothing will be upscaled because neural networks are not trained to upscale already upscaled images.
Inside nested X11, play games in fullscreen. The VNC Viewer itself could be even a window.

If the VNC viewer has fully grabbed your input, then press F11 to show the context menu, then disable "Full screen".
GUEST_REFRESH_RATE is the guest X11's virtual (fake) display's refresh rate. Rarely gameplay in VNs is broken or becomes too fast when >60 Hz.
default GUEST_REFRESH_RATE is 60
default UPSCALED_FPS is 30
For ultra low-latency, change --interpolation from yes to no in x11wid.sh (command arguments override all file configs).
Although I suspect that interpolation is already (forcefully) disabled because no --video-sync=display-resample
which I didn't specify because it stops rendering.

By default MPV uses the config provided here in ./mpvcfg/ instead of yours in $HOME/.config/mpv/
because there is at least 20% chance that your config is bad for this use case.
You can change that by setting MPV__CONFIG_DIR to $HOME/.config/mpv (use $HOME instead of ~ just in case) in config.sh

i3 WM launched in the nested X11 uses the i3-child-config file from here.

Why is VNC needed?

It is the only way to control a nested X11.
By the way, I'll probably soon add an alternative script that uses kwin_wayland instead of X11/Xvnc.

Dependencies to use cdmpv

1) Install VNC server and client

Arch Linux:

sudo pacman -S tigervnc gtk-vnc

Debian, Ubuntu, Mint, etc.:

sudo apt install tigervnc-viewer tigervnc-standalone-server gvncviewer

Fedora:

sudo dnf install tigervnc tigervnc-server

OpenSUSE:

sudo dnf install tigervnc xorg-x11-Xvnc

Arch Linux's tigervnc package has both Xvnc (that's VNC server with startx) and vncviewer.
TigerVNC's vncviewer is not used because its vncviewer either

  1. aggressively tries to resize the guest X11 to the host resolution
  2. shows unscaled 1280x720 guest in the center of the screen on 1920x1080 host. We need the same mouse area as the MPV window.


*If you don't need low FPS and playing backwards every 1000ms, then compile TigerVNC with my one-line patch*
Currently the only *easy* way to do that is if you use Arch Linux (or other distro that can create packages from PKGBUILD).
(the PKGBUILD is in this repo)
cd PKGBUILDS/tigervnc
makepkg -si

Now it is installed. It was patched with dontpaint.patch (1-2 lines) from the same folder.
With this patch, the VNC server will send only the very first frame to the VNC client. So if you killall mpv, then you would still see the xfce4-terminal.

According to my experience,
every time you upgrade xorg-server (even if it is a minor version),
you should recompile this package.

2) Install all other needed packages

Arch Linux:

sudo pacman -S mpv i3-wm ffmpeg perl gcc dmenu bemenu bemenu-x11 dunst xfce4-terminal xorg-setxkbmap xorg-xset xorg-xrandr xdotool xorg-xdpyinfo scrot libwebp terminus-font wmctrl calc

Debian, Ubuntu, Mint, etc.:

sudo apt install mpv i3 ffmpeg perl gcc libx11-dev suckless-tools dunst xfce4-terminal x11-xkb-utils x11-xserver-utils x11-utils xdotool scrot webp xfonts-terminus wmctrl apcalc

Common packages for OpenSUSE and Fedora:

sudo dnf install mpv i3 ffmpeg perl gcc dmenu bemenu dunst xfce4-terminal setxkbmap xset xrandr xdotool xdpyinfo scrot libwebp-tools wmctrl calc

Only Fedora:

sudo dnf install terminus-fonts-console

Only OpenSUSE:

sudo dnf install terminus-bitmap-fonts

I am not sure if I specified enough packages needed to compile autocutsel in all distros.

Environment variable: MP

Since in most VNs nothing moves,
we don't need to upscale the 99.9-100% similar frame 10000 times.

By default MP=2
MP=0 disables mpdecimate.
The higher MP, the more aggressive params are supplied to mpdecimate filter.
Maximum MP can be 8 MP=4 ./cdmpv 1280x720 60 30 or if you don't want to restart your already game

killall mpv
MP=4 ./x11wid.sh

Actually no, in many VNs there is an animated icon in the dialog window,
which causes to rerender everything (BTW, my future upscaler upscales only changed regions),
so if you don't want your GPU's fan to be 100%, then increase MP.

Environment variable: C

See the code in x11wid.sh, there is code only for 800x600
By default C=0
C can also be 1 or 2 or 3
If C==1 then crop resolution 800x550, crop top=25px
If C==2 then crop resolution 800x460, crop top=30px
If C==3 then crop resolution 800x450, crop top=70px
FFmpeg crops, not mpv (although mpv can too, with vf, but then I would need sed copied input.conf...)

Why crop? Because in old games there's unused space in the bottom.

BTW, you can also Ctrl+Up/Down/Left/Light; zoom is ctrl+u, ctrl+shift+u.
Note that if you zoom with MPV, MPV will still upscale the whole image and the output resolution won't change (exception: SSimSuperRes, which is a POSTKERNEL shader).

MP=4 C=2 ./x11wid.sh

So when you need the bottom part (e.g. to save the game; the Log button),
then either

  1. Ctrl+Up/Down (but remember how many times you pressed)
  2. Close x11wid.sh (or killall mpv if you still haven't launched it separately outside of cdmpv.sh) and start ./x11wid.sh with different C.

MPV's hotkeys (read it!!!)

I am probably the only one in the world that benchmarked all possible shaders chains
(I blacklisted some of low-quality patterns, so that it would not take years)
on 2 images and 2 resolutions (800x450→1920x1080, 1280x720→1920x1080),
I'll publish my script and results in .json later,
my benchmark script primarily uses ssim (Alexkral/AviSynthAiUpscale#3, code by igv),
but also dssim (AUR: dssim-git).

Most shader chains that are in input.conf are optimized for 1920x1080 (or probably 2560x1440) screen because my monitor is 1920x1080.
All shaders upscale images 2x times (1280x720→2560x1440) except when it is explicitly written 3x or 4x in their file name.
So their results need to be downscaled afterwards at the final stage if the result has higher resolution than your screen's.
Only SSimSuperRes (by igv) and MPV's built-in upscalers (scale= in mpv.conf) can upscale to any arbitrary resolution (1.223x, etc.).
If the upscaled result image is the same size as your screen, then the sharpener is needed (~~/shaders/igv/SSimDownscaler.glsl) or Light_Soft shader ~~/shaders/Anime4K_Restore_CNN_Light_Soft_VL-YYY-half.glsl (or not -half), test yourself. Sometimes they are already included (especially in case of Anime4K CNN Upscalers that produces lines that are thicker than needed).
So if you have 4k/5k display, then add additional Anime4K -UL or -UL-YYY or -L variant or ~~/shaders/superxbr.glsl (it's like lanczos but lines are much smoother) at the end of string in input.conf if your GPU allows it and it isn't there already.

If you are at the same terminal's tab where you launched cdmpv.sh,
then that means you can control MPV with your keyboard (because cdmpv.sh launches cdmpvTempBgTasks.sh in bg which launches x11wid.sh in bg).
Or you can killall mpv, create a new tab in host X11/Wayland and ./x11wid.sh.

Every hotkey in input.conf cycles through 1-5 shaders.
If it is written "press 2 three times", but you accidentally press it four times, press 0 (uses either SSimSuperRes or SSimDownscaler) or shift+0 (uses nothing), then repeat what you wanted.

When you switch a shader chain, you'll see a message in the MPV's log (it is written to stdout, it is not written to a file).
To switch a shader chain, you should press a key, then wait while it renders a new frame with it (up to 2 seconds unless they aren't in your shader cache because you never used them),
then go back to the terminal to look if you got the correct "glsl-shaders"

Shader cache is stored in ~/.config/mpv/shader_cache (you can change that in config.sh)
Shaders are compiled by CPU of course.
The heaviest shaders are compiled ~20 seconds on Ryzen 2600.
You get blue screen when shader compilation failed or not enough VRAM to use a shader chain.

Hotkeys are specified in input.conf.
Every time you launch x11wid.sh, it copies input.conf and removes all ctrl+ (because ctrl+ hotkeys conflict with the terminal's).

This shader chain is used by default at every launch for all resolutions. 2x upscaling (e.g. 1280x720→2560x1440) and very high FPS, smooth lines, no ringing. Disadvantages: blurred BG, very similar colors are blended, no small details (e.g. grain disappears from hair in Daitoshokan no Hitsujikai); lines are thicker (than the original) without Anime4K_Restore. The hotkey: press one time a.

~~/shaders/Anime4K_Clamp_Highlights.glsl:~~/shaders/Anime4K_Upscale_CNN_x2_ULF-KrigBilateral.glsl:~~/shaders/Anime4K_Restore_CNN_Light_S-YYY-half.glsl:~~/shaders/igv/SSimSuperRes.glsl

For (a + 1% better colors) use o.

The faster shader chain is o+o

~~/shaders/Anime4K_Clamp_Highlights.glsl:~~/shaders/Anime4K_Upscale_CNN_x2_ULF-KrigBilateral.glsl:~~/shaders/igv/SSimSuperRes.glsl

It is used by default when
input resolution is > 1579 but (output resolution / input resolution) ≤ 1.23.
E.g. for 1600x900 → 1920x1080.

The even faster shader chain is o+o+o (the only one here with color distortions):

~~/shaders/Anime4K_Clamp_Highlights.glsl:~~/shaders/Anime4K_Upscale_CNN_x2_ULF.glsl:~~/shaders/igv/SSimSuperRes.glsl

The fastest shader chain is 0 which is just:

~~/shaders/igv/SSimSuperRes.glsl

BTW, SSimSuperRes gets used only when previous upscalers didn't upscale the image big enough.

No shader chain is shift+0 (MPV's built-in lanczos shader will be used for upscaling).

Press one time e if you want the same as a, but 4x upscaling.

~~/shaders/igv/KrigBilateral.glsl:~~/shaders/Anime4K_Clamp_Highlights-LUMA-first-init.glsl:~~/shaders/Anime4K_Upscale_CNN_x2_UL-LUMA.glsl:~~/shaders/Anime4K_Clamp_Highlights-LUMA-apply.glsl:~~/shaders/Anime4K_Restore_CNN_Light_Soft_S.glsl:~~/shaders/Anime4K_Upscale_CNN_x2_M.glsl:~~/shaders/igv/SSimSuperRes.glsl

e+e is better than e but slower.
e has significantly less details than a.
e+e has less details than a.

Anime4K CNN Upscaler (+a, +e/+e+e) is the best for Kimagure Temptation because it fixes aliasing which is caused by the VN itself badly downscaling the animated hair.




Press one time 2 if you play Vampire's Melody (original is 1920x1080) because the animated sprite seems to be a lossy video (I also tried downscaling before upscaling but the result is worse).

~~/shaders/Anime4K_Restore_CNN_Light_Soft_VL-YYY.glsl:~~/shaders/igv/SSimSuperRes.glsl


Press two times 2 if you play the 1920x1080 game at 1920x1080 screen, and when a character's face is near, you see sprites are low-resolution, in this case you need this:
~~/shaders/Anime4K_Restore_CNN_Light_Soft_VL-YYY-half.glsl:~~/shaders/igv/SSimSuperRes.glsl

or in some cases just ./cdmpv 1280x720 60 60 for this game, although somes VNs use very bad cheap downscaling when the output resolution is lower than original (Kinkoi on Unity, at least the early version)... or less likely it's a bug in Wine.

Press three times 2 if you play Monkey!¡ because the original has mega aliasing.

~~/shaders/Anime4K_Restore_CNN_Moderate_Soft_VL-YYY.glsl:~~/shaders/igv/SSimSuperRes.glsl


For Wanko to Kurasou (800x600->4K) press three or four times shift+q (depending on FPS and tastes).
If that's too slow, then press two times e (or a for a 1920x1080 monitor).

Press
y (less details but less pixelated)
or shift+y (less details but less pixelated and almost no color noise)
or f (no pixelation)
if you play the old version of YU-NO.

Press one time shift+q (good for 800x600 → 1920x/2560x; the best for Sugar * Style 1280x720→1920x1080)

~~/shaders/igv/KrigBilateral.glsl:~~/shaders/Anime4K_Clamp_Highlights-LUMA-first-init.glsl:~~/shaders/Anime4K_Upscale_GAN_x3_VL-LUMA.glsl:~~/shaders/Anime4K_Clamp_Highlights-LUMA-apply.glsl:~~/shaders/igv/SSimSuperRes.glsl

Sometimes w is the best (e.g. Koikari Love for Hire), but sometimes it has ringing especially in fonts.

~~/shaders/igv/KrigBilateral.glsl::~~/shaders/avisynth/mpv user shaders/LineArt/3x/AiUpscale_HQ_3x_LineArtFCla.glsl:~~/shaders/Anime4K_Restore_CNN_Light_VL-YYY.glsl:~~/shaders/igv/SSimSuperRes.glsl

Or rarely n is better (same as w but without Restore). The Restore shaders fix some ringing for AiUpscale.
Also lines are aliased (in other words, ladder) for some VNs with AiUpscale, which doesn't show up on SSIM test, but we humans see it.

MPV's hotkeys for reparing the image BEFORE upscaling (read it too!!!)

Many VNs used very bad/cheap downscaling algos (i.e. bicubic, bilinear or even nearest-neighbor) instead of good algos like lanczos (there are probably variations of lanczos DS, at least the MPV/libplacebo's one is good) or ginseng (both lanczos and ginseng are very similar), catmull_rom or spline16 (both are very similar).
In Palette's Saku Saku you can see aliasing (lines are ladders), especially for far away chars.
Maybe all Kirikiri games (files are .xp3) suffer from having a bad DS algo, I don't know.

Other VNs use low-res character sprites, which is not noticable only when a character is far.
Even 2022's VNs still have this issue, like the 1920x1080 3-lang edition (released in 2022-01 by NekoNyan) of Hello Lady.
NOTE: all of the following hotkeys in this list work only for those upscalers whose hotkey is either a (2x), e+e (4x), o (2x+more details but noise), o+o (same as a but 3% better colors), o+o+o (same as a but sacrifices colors for speed), J (slow 3x). If you try to use it with other upscalers (LUMA upscalers), then it would be reparing after upscaling which is already is in shader chains.
Hotkeys (you can have only one type of repairing):
2 Disable repairing
@ Heavy repairing (Anime4K_Restore_CNN_Moderate_Soft_M-YYY.glsl). Not always recommended.
3 Heavy repairing (Anime4K_Restore_CNN_Moderate_Soft_M-YYY-percent75.glsl). Not always recommended (but recommended for A Clockwork Ley-Line).
# Medium repairing (Anime4K_Restore_CNN_Moderate_Soft_M-YYY-half.glsl).
4 Low repairing (Anime4K_Restore_CNN_Light_Soft_M-YYY-percent70.glsl).
$ Very low repairing (Anime4K_Restore_CNN_Light_Soft_M-YYY-half.glsl).
5 (rare) If the input has very heavy aliasing and you need a high FPS (Anime4K_Restore_CNN_Light_Soft_S-YYY.glsl).
% low FPS, sometimes less details (Anime4K_Restore_CNN_Light_Soft_VL-YYY.glsl). (5 and % are recommended for HARUKAZE's Monkeys!¡, A Clockwork Ley-Line)
Use the above hotkeys AFTER pressing a hotkey for upscaling algos (btw, if you prefer the default upscale algo, then, obviously, don't press); otherwise, if you press "3" then "a", then you would get no repairing, because "a" clears all previous shaders.

About new shaders

Anime4K shaders are optimized for x264 videos, i.e. videos with all kinds of artifacts.
Also I think they are trained on JPEG q=95 (jpeg_factor=95 in https://github.com/bloc97/Anime4K/blob/master/tensorflow/Train_Model.ipynb)
But in most VNs sprites are lossless and backgrounds are like JPEG q≈95.
Anime4K Upscale shaders are very bad for background, they think all details are noise so just blur everything.
But Anime4K Restore shaders barely do so.

When input is lossless, Anime4K_Restore_CNN_*-YYY.glsl (MAIN shaders) is better, than non--YYY because black lines don't become red. It takes RGB input, but changes only the Y channel.
Generated by

u=YYY ./resluma.sh Anime4K_Restore_CNN_*

Anime4K_Clamp_Highlights-LUMA-first-init.glsl
Anime4K_Clamp_Highlights-LUMA-apply.glsl
Usage for these two see in input.conf

Anime4K_*-LUMA.glsl are for use before LUMA shaders. But because they originally supposed to also take non-black-and-white input (i.e. U and V channels = chroma), results are a little bit worse. The exception is GAN_x3_VL.
Generated by

./upluma.sh Anime4K_Upscale*

Because with Anime4K_Upscale_CNN_x2_* everything was a little (e.g. Red 40/255 → 54/255) more red (unless Anime4K_Upscale_CNN_x2_L is used), I created
Anime4K_Upscale_CNN_x2_ULF-KrigBilateral.glsl
Although the input is still RGB, only Y channel and U channel are upscaled by Anime4K, while V is upscaled by KrigBilateral embedded in the same file.
It requires a little more VRAM (to store both the upscaled image and also the original image).
V channel only is because there's something wrong with upscaling U channel. FIXME!
+o uses a little bit slower Anime4K_Upscale_CNN_x2_ULF-slowerKrigBilateral-noise.glsl that doesn't damage background images. +o has the best SSIM possible for Anime4K CNN upscale shaders.

If a shader file has F at the end, then that means that this shader will be forcefully (no //!WHEN) used even the input resolution is bigger than display resolution.
If a shader file has Cla at the end, then that means Anime4K_Clamp_Highlights.glsl is embedded.
FCla = F + Cla

avisynth/mpv user shaders/LineArt/3x/AiUpscale_HQ_3x_LineArtFCla.glsl has many additional changes to fight ringing.
avisynth/mpv user shaders/LineArt/3x/AiUpscale_HQ_3x_LineArtFCla.orig.glsl is without those changes (n two times or w four times)

AiUpscale_HQ_4x_LineArt is worse than _3x, at least for 2D,
althought a few details are better, so I didn't include int

Screenshots

DISPLAY=:44 scrot to save original unupscaled image as .png.
Press s in MPV's CLI to save unupscaled image as .png to /tmp/
Press shift+s in MPV's CLI to save upscaled image as .png to /tmp/

About shaders

When 1280x720→1920x1080, then AiUpscale_HQ_3x_LineArt has much better SSIM than AiUpscale_HQ_2x_LineArt for 2D sprites, but the overall SSIM is worse (~0.00234 vs ~0.00263) because background images are not very anime.
Anime4K_Clamp_Highlights.glsl is needed because upscalers accidentally create very bright micro areas.
Anime4K_Upscale_CNN_ hates small details, so I fixed this by prenoising the chroma and then replacing the Anime4K CNN's chroma with KrigBilateral's (both U and V) that is supplied the original chroma. The file is Anime4K_Upscale_CNN_x2_ULF-slowerKrigBilateral-noise.glsl
TsubaUP is good for everything except 2D (especially hair is bad).
FSRCNNX is kinda like TsubaUP but slower but upscales hair better.
I tested only VNs, but FSRCNNX_x2_56-16-4-1.glsl is always worse than _16, so I didn't include it.
The latest revision of SSimDownscaler.glsl does something bad to eyes,
so the previous 2021-10-08 revision is used that I named SSimDownscaler_oct8.glsl
nnedi3-nns128-win8x6.hook is very bad, so not even included.
Anime4K_Upscale_GAN_x4_UUL.glsl (two U) thins lines too much. Probably it was created for ancient anime videos.
Anime4K_Upscale_GAN_x4_UL.glsl is not worth if I remember correctly.

ravu-zoom-* damages geometry, so not included. And FSRCNNX is simply better.

Anime4K*Restore*UL work only on Vulkan, and is not used because too slow and sometimes worse than VL.

(POSTKERNEL stage is used right before MPV downscales the image with the algo chosen in dscale. MPV downscales only when needed.

SSimDownscaler (POSTKERNEL stage shader) is a sharpener. If the image is not going to be downscaled afterwards by MPV, then this shader is not used because it would introduce many artifacts.
SSimSuperRes.glsl (POSTKERNEL stage shader) is a fast upscaler without neural networks.

Tips

  1. https://www.reddit.com/r/visualnovels/comments/lh10yb/getting_movies_to_work_in_visual_novels_on_linux/ (also read all comments)

  2. Disable auto cursor move (i.e. you click "Save game", and your mouse moves to the "Yes" button) in the game menu
    because the game runs in nested X11
    and it sends the mouse move command only to the nested X11,
    so the next time you move your mouse,
    your nested X11's mouse position reverts to the host's one.

wine explorer /desktop=cdmpv,$YOURGUESTRESOLUTION or wine explorer /desktop=cdmpv,$YOURGUESTRESOLUTION game.exe
enables wine's own virtual desktop just for current session (doesn't add nor overwrite [Software\\Wine\\Explorer\\Desktops] in your $WINEPREFIX/user.reg), which is sometimes needed because i3 is a tiling window manager, i.e. when you have one window, its size is fullscreen, but if you open a second window, both windows would get automatically the same size—half of the screen each. You can press Win+W or Win+Space or Win+Shift+Space to control that.
One wineprefix can have multiple of them.

  1. If you want Steam to be in host X11/Wayland but you want the game to be in nested X11, then go into game's options -> command arguments -> env DISLPAY=:44 %command%

  2. Black screen in Saku Saku Cherry Blossoms and flickering in Grisaia, Himawari, Ikinari Anata ni Koishiteiru
    If you have graphical glitches, then use dgVoodoo2 (see the below section).
    If you still have graphical glitches or crashes when a video starts to play, then use dgVoodoo2 (you can read about it in the "Alternative to cdmpv" section) AND software rendering AND uninstalled DXVK, which is 100% performance-wise enough for VNs:

__GLX_VENDOR_LIBRARY_NAME=mesa LIBGL_ALWAYS_SOFTWARE=1 VK_ICD_FILENAMES=/usr/share/vulkan/icd.d/lvp_icd.x86_64.json MESA_LOADER_DRIVER_OVERRIDE=zink


If an .exe file says a strange error as soon as you launch it, then that's because you set STAGING_WRITECOPY=1 somewhere (env|grep STAGING or .bashrc/.zshrc).

BTW, when using NVIDIA GPU (I don't know about other GPUs) inside *nested* X11 there is a problem with glxinfo (fails to start every 5th time) and videos (they either always fail or never) in some VNs:
E.g. Akeiro Kaikitan as soon as it tries to play a video, the wine process finishes with X11 error (`BadAlloc (insufficient resources for operation)`, opcodes: `150 (GLX), 5 (X_GLXMakeCurrent), 0, 42`)
Also I found out that Akeiro Kaikitan saves the read messages only after manually exiting the whole game, not when returning to main menu.
The workaround for this is the same as above but probably only __GLX_VENDOR_LIBRARY_NAME=mesa is enough, i.e. using software rendering, but dgVoodoo2 is not necessary.
__GLX_VENDOR_LIBRARY_NAME=mesa applies only to OpenGL; so if you see the DXVK log, then your GPU is used.
Also you can use that env variable for the entire X11: ``` __GLX_VENDOR_LIBRARY_NAME=mesa ./cdmpv.sh 1280x720 60 25 ```

Uninstall DXVK:

/usr/share/dxvk/setup_dxvk.sh uninstall

Install DXVK:

/usr/share/dxvk/setup_dxvk.sh install --with-d3d10 --symlink

Don't forget about WINEPREFIX=

  1. In one case (Schatten) as soon as you start it, there's a unskippable video which is displayed black and played for 1 minute.

  2. Use wine-tkg. If you use Arch Linux, then add chaotic-aur repo.

dgVoodoo 2 (Freeware, not Open Source)

http://dege.freeweb.hu/dgVoodoo2/dgVoodoo2/#latest-stable-version (no https)

The dgVoodoo 2's .exe is a GUI for creating dgVoodoo.conf. You don't need to use it.
Copy D3D8.dll, D3D9.dll (maybe also D3DImm.dll, DDraw.dll) from %dgVoodoo2UnpackedPath%/MS/x86/ into the folder containing game's .exe.
The game will automatically use the files.
BTW, you can replace all .dlls in $WINEPREFIX/.wine/drive_c/windows/syswow64/ (but pay attention to upper/lower case, so that you would not have d3d9.dll AND D3D9.dll), but I don't know what Valve's VAC would think about that. I had to do that for The Fruit of Grisaia (though I still needed dgVoodoo.conf).

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Use dgVoodoo-ini/createDgVoodooConf.sh VN_origWidth_in_px VN_origHeight_in_px 60 60 to create your own dgVoodoo.conf.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Current Algorithm of ./cdmpv.sh

  1. If PREFER_AUTOCUTSEL=1 (default) in config.sh, then for reliable copy clipboard from nested X11 to host X11 (didn't test this feautre on Wayland), patched autocutsel is automatically compiled if it wasn't compiled yet.
    It is needed because the VNC protocol by default supports only ASCII. There are some hacks in TigerVNC (both server and client) but sometimes it forgets to send update to the host.
  2. Cache all executable files into RAM (useful for HDD).
  3. Launch ./cdmpvTempBgTasks.sh in background
  4. Launch TigerVNC's Xvnc which provides a guest (child) X11 server (X11 in X11/Wayland) and a VNC server. 4..) After launcing Xvnc there is no more code to execute in ./cdmpv.sh but cdmpv.sh is still active because it executes Xvnc
  5. cdmpvTempBgTasks.sh: Launch i3 in the guest X11, the i3 uses i3-child-config file from the same folder as cdmpv.sh. I chose to use i3 as a WM for a guest X11 because it allows to easily remove any borders and panels, uses little RAM, easily configurable.
  6. cdmpvTempBgTasks.sh: Launch TigerVNC's vncviewer. Don't forget that it should be patched.
  7. cdmpvTempBgTasks.sh: Execute ./x11wid.sh. It launches ffmpeg that grabs guest X11's screen which it pipes to mpv.
    mpv is launched with --wid={vncviewer's window id} which makes mpv a child window of the VNC client.
    You look at mpv but all keyboard & mouse control goes to vncviewer.
    So if mpv crashes or you updated one of .glsl or .conf, then killall mpv, then ./x11wid.sh.
    You can 100% safely Ctrl+c x11wid.sh.
    If you decide to change FPS without restarting cdmpv.sh, then ./x11wid.sh 30 or edit .env-of-current-process and then ./x11wid.sh
    If you specify too high FPS for your GPU then you would get high latency for unknown reason.

If you want to close cdmpv.sh, then Ctrl+c it and it will automatically kill all the processes it spawned.

Former Deprecated Algorithm (read this only if you are curious)

  1. Host must be X11, preferably i3 WM. If you have a login screen, and there is a button that says "Wayland session", then you have Wayland instead of X11.
  2. No compositor (i.e., no xfwm, metacity, compiz, KWin). Or, if you already use picom (compton), then see what you need to change in your config.
  3. After launching need to wait 20 seconds (because that's how many sleeps are in the scripts).
  4. if no i3 or if AUTOSWITCH is unset or 0, then print the instruction, then sleep for 3 seconds.
  5. Launch TigerVNC's Xvnc which provides a guest (child) X11 server (X11 in X11) and a VNC server.
    BTW, killall Xvnc kills the guest X11 just like killall i3 kills all browsers and etc.
  6. Launch i3 in the guest X11, the i3 uses i3-child-config file from the same folder as cdmpv.sh. I chose to use i3 as a WM for a guest X11 because it allows to easily remove any borders and panels, uses little RAM, easily configurable.
  7. Launch ffmpeg that grabs guest X11's screen and redirects it to /dev/video8 (rawvideo->rawvideo, no videocodecs) with the help of V4L2. By the way, you can change /dev/video8 in the config.sh file.
  8. if i3 and AUTOSWITCH={non-zero number}, then switch to the virtual desktop {number} (counting from 1).
  9. Spawn the gtkvncviewer. gtkvncviewer launches in fullscreen and changes the guest X11 resolution to the maximum it can fit (gtkvncviewer has no whatsoever options, so this behavior cannot be disabled).
  10. Spawn mpv using the config from dir here (not yours) whose input is a fake web camera /dev/video8.
  11. Switch mpv into a window mode, and set the window size to the largest available.
  12. Switch gtkvncviewer into a window mode, and resize it to a resolution larger than the real monitor's resolution. Otherwise gtkvncviewer would resize (xrandr) the guest X11 resolution every time, which would also break ffmpeg -f x11grab.
  13. Move gtkvncviewer to the position where only one row of pixels (e.g. w=1920px, h=1px) of its menu can be seen and clicked.
    That 1 pixel row is useful, because sometimes you'll need to ungrab the keyboard: move your mouse to the very top and then use your keyboard. Only 1 pixel row because otherwise the displayed-by-mpv cursor and the actual cursor should be in one position.
  14. Launch picom (former compton. Arch Linux's picom package provides a symlink compton->picom).
    We need it to make gtkvncviewer 100% transparent.
  15. Focus on gtkvncviewer.
    In the end you actually see mpv but control gtkvncviewer.
    Step 11 is needed because I couldn't find a way to display mpv always above gtkvncviewer AND ban focus grabbing for mpv.

My failed attempts with VMs, the guest is Windows 10 x64, the host is Linux

I couldn't run Magpie in VirtualBox. Maybe because VirtualBox GPU Driver supports only DirectX 9.
I could run Magpie in VMware Workstation 16.1.2, but in most games FPS is very low with Anime4K and ACNet.
The FPS is low (8), but for some reason my CPU Load is only 33% and GPU load is very low. I tried experimenting with number of cores, nice level, etc.
Of course I installed the VM guest drivers.
Virtualization is enabled in UEFI and VMware. Motherboard: MSI B450M PRO-M2 MAX (MS-7B84).
On the other hand some software can cause 100% load (nvtop) to GTX 1660 Super in VMware, so it's not software acceleration.
If I force CPU powersave mode (max clock rate decrease from 3550 to 1550 MHz), then FPS in VMware is 3 or 4, not 8.
Note that I have only one RAM module (16 GB@3000MHz).
And when FPS is low, sound stutters every ~200 ms. And when I just play the game in VMware without Magpie, FPS is good, but every ~40 secs, sound stutters for 2-3 seconds.
Maybe problems with VMware are because I use the evil NVIDIA proprietary driver.

Alternatives with far worse upscaling

lanczos-3 by dgVoodoo 2

Use the above "dgVoodoo2" section but change Resolution to e.g. 1920x1080@144.
Then just launch the game with Wine without any cdmpv's scripts.

Alternative to this method for proprietary NVIDIA Linux users

Before I started using this hacky VNC approach, I had been using everywhere DXVK +

__GL_SHARPEN_VALUE=90 __GL_SHARPEN_IGNORE_FILM_GRAIN=90

Although the prefix is __GL_, they apply to Vulkan too.
Some VNs like Shinigami no Kiss Wa Wakare no Aji and Wanko to Kurasou somehow don't use DirectX (they use DirectDraw I think), so no sharpening is there (and dgVoodoo 2 doesn't work too).

How dgVoodoo.conf differs from the original default file:

Resampling from bilinear to lanzcos-3
FullscreenAttributes = to FullscreenAttributes = Fake
FPSLimit = 0 to FPSLimit = 144 (if your monitor is 144 Hz)
AppControlledScreenMode to false
DisableAltEnterToToggleScreenMode to false
In [DirectX]: Resolution = unforced to Resolution = 1920x1080@144 (NOTE: it should remain unforced if you don't use dgVoodoo's upscaling)
In [DirectX]: VRAM = 256 to VRAM = 512
dgVoodooWatermark to true to check if dgVoodoo 2 is being used.
Then change it back to false if all is OK.
Detailed info on all options: https://www.pcgamingwiki.com/wiki/DgVoodoo_2

TODO: Sway as nested display server instead of i3 WM

Problem 1

Sway is compatible with i3 WM, but how to check if we run Wayland?
If I go here, https://unix.stackexchange.com/questions/202891/how-to-know-whether-wayland-or-x11-is-being-used
all commands' result is tty for me (I use startx to start i3).
One answer says to check WAYLAND_DISPLAY and DISPLAY variables... hm...

Problem 2

xdotool's replacements wtype and https://github.com/ReimuNotMoe/ydotool
don't seem to support commands: windowstate, windowsize, windowmove, get_desktop.
One of Wayland's (security) features is nobody has right to know what is in other windows.

But maybe i3-msg/swaymsg have commands similar to xdotool's? Need to check.

Problem 3

If the host is Wayland, can a guest be X11? I don't know, but I guess 99%.
But if a guest would be Wayland-based, then we need to replace Xvnc with something (wayvnc?).

Problem 4

ffmpeg -f x11grab doesn't work.
I guess -f kmsgrab probably just grabs the screen that is displayed on the real monitor, not tested.
Maybe somehow use ffmpeg with pipewire?
The only way to grab a window's contents on Wayland I know is to use OBS (but I didn't test):

Lessons learned

Which downscaling algorithm is used is very important.
There are very different emotions from a picture depending
on which dscaler was used: mitchell, catmull_rom, lanczos, etc.
catmull_rom (short: catrom) and lanczos are the best.
(though I didn't compare lanczos vs ginseng which are very similar to each other).
Bicubic is trash, by the way.
catmull_rom also somehow hides AiUpscale's ringing.
ewa_lanczos* give too blurry picture.
I use feh to look at how much info is lost and how smooth are lines.

Also I made an experiment:
I downscaled an 1920x1080 original image to 1280x720 with every dscaler, then upscaled them back with one upscaler.
I am lazy to find my result file, but lanczos and catmull_rom are the best (or it was spline16/36/64 with almost the same score, I forgot).

At least for 2D.

License

Everything that *I* did in cdmpv is under CC0 (Public Domain).
Everything that was not done by me is obviously under other licenses.

My other related projects

sugoi-web Web Frontend for Sugoi-Japanese-Translator (offline & better than DeepL).

About

Upscaler for Linux which uses a nested display server over MPV. Recommended for VNs.


Languages

Language:GLSL 99.4%Language:Shell 0.4%Language:C 0.2%Language:Ruby 0.0%Language:M4 0.0%Language:Makefile 0.0%